summaryrefslogtreecommitdiff
path: root/lib/KeyRing/BuildKeyDB.hs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/KeyRing/BuildKeyDB.hs')
-rw-r--r--lib/KeyRing/BuildKeyDB.hs57
1 files changed, 33 insertions, 24 deletions
diff --git a/lib/KeyRing/BuildKeyDB.hs b/lib/KeyRing/BuildKeyDB.hs
index 44952de..57647b0 100644
--- a/lib/KeyRing/BuildKeyDB.hs
+++ b/lib/KeyRing/BuildKeyDB.hs
@@ -36,6 +36,7 @@ import qualified Data.Map as Map
36import Data.Maybe 36import Data.Maybe
37import Data.OpenPGP 37import Data.OpenPGP
38import Data.OpenPGP.Util (GenerateKeyParams (..), fingerprint, generateKey, pgpSign, verify) 38import Data.OpenPGP.Util (GenerateKeyParams (..), fingerprint, generateKey, pgpSign, verify)
39import GHC.Stack
39 40
40 41
41import Data.Time.Clock (UTCTime) 42import Data.Time.Clock (UTCTime)
@@ -171,7 +172,7 @@ buildKeyDB ctx grip0 keyring = do
171 trans f (info,ps) = do 172 trans f (info,ps) = do
172 let manip = combineTransforms (transforms info) 173 let manip = combineTransforms (transforms info)
173 rt1 = rt0 { rtKeyDB = merge emptyKeyDB f ps } 174 rt1 = rt0 { rtKeyDB = merge emptyKeyDB f ps }
174 acc = Just Sec /= Map.lookup f accs 175 -- acc = Just Sec /= Map.lookup f accs
175 r <- performManipulations doDecrypt rt1 mwk manip 176 r <- performManipulations doDecrypt rt1 mwk manip
176 try r $ \(rt2,report) -> do 177 try r $ \(rt2,report) -> do
177 return $ KikiSuccess (report,rtKeyDB rt2) 178 return $ KikiSuccess (report,rtKeyDB rt2)
@@ -390,6 +391,7 @@ doImportG transcode db m0 tags fname key = do
390 , rrs ) 391 , rrs )
391 -} 392 -}
392 let go (Just kd@(KeyData top topsigs uids subs)) = insertSubkey transcode kk kd tags fname key 393 let go (Just kd@(KeyData top topsigs uids subs)) = insertSubkey transcode kk kd tags fname key
394 go Nothing = pure NoWorkingKey
393 transmuteAt go kk db 395 transmuteAt go kk db
394 396
395 397
@@ -413,27 +415,27 @@ parseSpec wkgrip spec =
413 if not slashed 415 if not slashed
414 then 416 then
415 case prespec of 417 case prespec of
416 AnyMatch -> (KeyGrip "", Nothing) 418 AnyMatch -> (KeyFP 0 "", Nothing)
417 EmptyMatch -> error "Bad key spec." 419 EmptyMatch -> error "Bad key spec."
418 WorkingKeyMatch -> (KeyGrip wkgrip, Nothing) 420 WorkingKeyMatch -> (KeyFP 0 wkgrip, Nothing)
419 SubstringMatch (Just KeyTypeField) tag -> (KeyGrip wkgrip, Just tag) 421 SubstringMatch (Just KeyTypeField) tag -> (KeyFP 0 wkgrip, Just tag)
420 SubstringMatch Nothing str -> (KeyGrip wkgrip, Just str) 422 SubstringMatch Nothing str -> (KeyFP 0 wkgrip, Just str)
421 SubstringMatch (Just UserIDField) ustr -> (KeyUidMatch ustr, Nothing) 423 SubstringMatch (Just UserIDField) ustr -> (KeyUidMatch ustr, Nothing)
422 FingerprintMatch fp -> (KeyGrip fp, Nothing) 424 FingerprintMatch ver fp -> (KeyFP ver fp, Nothing)
423 else 425 else
424 case (prespec,postspec) of 426 case (prespec,postspec) of
425 (FingerprintMatch fp, SubstringMatch st t) 427 (FingerprintMatch ver fp, SubstringMatch st t)
426 | st /= Just UserIDField -> (KeyGrip fp, Just t) 428 | st /= Just UserIDField -> (KeyFP ver fp, Just t)
427 (SubstringMatch mt u, _) 429 (SubstringMatch mt u, _)
428 | postspec `elem` [AnyMatch,EmptyMatch] 430 | postspec `elem` [AnyMatch,EmptyMatch]
429 && mt /= Just KeyTypeField -> (KeyUidMatch u, Nothing) 431 && mt /= Just KeyTypeField -> (KeyUidMatch u, Nothing)
430 (SubstringMatch mt u, SubstringMatch st t) 432 (SubstringMatch mt u, SubstringMatch st t)
431 | mt /= Just KeyTypeField 433 | mt /= Just KeyTypeField
432 && st /= Just UserIDField -> (KeyUidMatch u, Just t) 434 && st /= Just UserIDField -> (KeyUidMatch u, Just t)
433 (FingerprintMatch _,FingerprintMatch _) -> error "todo: support fp:/fp: spec" 435 (FingerprintMatch _ _,FingerprintMatch _ _) -> error "todo: support fp:/fp: spec"
434 (_,FingerprintMatch fp) -> error "todo: support /fp: spec" 436 (_,FingerprintMatch _ fp) -> error "todo: support /fp: spec"
435 (FingerprintMatch fp,_) -> error "todo: support fp:/ spec" 437 (FingerprintMatch _ fp,_) -> error "todo: support fp:/ spec"
436 _ -> error "Bad key spec." 438 _ -> error "Bad key spec."
437 where 439 where
438 (preslash,slashon) = break (=='/') spec 440 (preslash,slashon) = break (=='/') spec
439 slashed = not $ null $ take 1 slashon 441 slashed = not $ null $ take 1 slashon
@@ -522,6 +524,7 @@ generateInternals transcode mwk db gens = do
522 transmuteAt (go kk) kk db 524 transmuteAt (go kk) kk db
523 where 525 where
524 go kk (Just kd0) = foldM (generateSubkey transcode) (KikiSuccess (kd0,[])) gens 526 go kk (Just kd0) = foldM (generateSubkey transcode) (KikiSuccess (kd0,[])) gens
527 go kk Nothing = error "generateInternals: Key not found."
525 528
526mergeHostFiles :: KeyRingOperation -> KeyDB -> InputFileContext 529mergeHostFiles :: KeyRingOperation -> KeyDB -> InputFileContext
527 -> IO 530 -> IO
@@ -588,7 +591,7 @@ readInputFileL ctx inp = do
588 hs <- mapM (`openFile` ReadMode) fname 591 hs <- mapM (`openFile` ReadMode) fname
589 fmap L.concat $ mapM (hGetContentsN oneMeg) hs 592 fmap L.concat $ mapM (hGetContentsN oneMeg) hs
590 593
591getInputFileTime :: InputFileContext -> InputFile -> IO CTime 594getInputFileTime :: HasCallStack => InputFileContext -> InputFile -> IO CTime
592getInputFileTime ctx (Pipe fdr fdw) = do 595getInputFileTime ctx (Pipe fdr fdw) = do
593 mt <- handleIO_ (return Nothing) $ Just <$> modificationTime <$> getFdStatus fdr 596 mt <- handleIO_ (return Nothing) $ Just <$> modificationTime <$> getFdStatus fdr
594 maybe tryw return mt 597 maybe tryw return mt
@@ -602,6 +605,8 @@ getInputFileTime ctx (FileDesc fd) = do
602getInputFileTime ctx (resolveInputFile ctx -> [fname]) = do 605getInputFileTime ctx (resolveInputFile ctx -> [fname]) = do
603 handleIO_ (error $ fname++": modificaiton time?") $ 606 handleIO_ (error $ fname++": modificaiton time?") $
604 modificationTime <$> getFileStatus fname 607 modificationTime <$> getFileStatus fname
608getInputFileTime ctx arg = error $ "getInputFileTime: Invalid argument: " ++ show arg
609
605 610
606slurpWIPKeys :: Posix.EpochTime -> L.ByteString -> ( [(Word8,Packet)], [L.ByteString]) 611slurpWIPKeys :: Posix.EpochTime -> L.ByteString -> ( [(Word8,Packet)], [L.ByteString])
607slurpWIPKeys stamp "" = ([],[]) 612slurpWIPKeys stamp "" = ([],[])
@@ -763,14 +768,15 @@ parseSingleSpec "-" = WorkingKeyMatch
763parseSingleSpec "" = EmptyMatch 768parseSingleSpec "" = EmptyMatch
764parseSingleSpec ('t':':':tag) = SubstringMatch (Just KeyTypeField) tag 769parseSingleSpec ('t':':':tag) = SubstringMatch (Just KeyTypeField) tag
765parseSingleSpec ('u':':':tag) = SubstringMatch (Just UserIDField) tag 770parseSingleSpec ('u':':':tag) = SubstringMatch (Just UserIDField) tag
766parseSingleSpec ('c':':':tag) = SubstringMatch (Just GroupIDField) tag 771-- parseSingleSpec ('c':':':tag) = SubstringMatch (Just GroupIDField) tag
767parseSingleSpec ('f':'p':':':fp) = FingerprintMatch fp 772parseSingleSpec ('f':'p':':':fp) = FingerprintMatch 0 fp
768parseSingleSpec str 773parseSingleSpec str
769 | is40digitHex str = FingerprintMatch str 774 | Just 40 <- isHexDigits str = FingerprintMatch 4 str
770 | otherwise = SubstringMatch Nothing str 775 | Just 64 <- isHexDigits str = FingerprintMatch 5 str
776 | otherwise = SubstringMatch Nothing str
771 777
772is40digitHex :: [Char] -> Bool 778isHexDigits :: [Char] -> Maybe Int
773is40digitHex xs = ys == xs && length ys==40 779isHexDigits xs = guard (ys == xs) >> Just (length ys)
774 where 780 where
775 ys = filter ishex xs 781 ys = filter ishex xs
776 ishex c | '0' <= c && c <= '9' = True 782 ishex c | '0' <= c && c <= '9' = True
@@ -779,9 +785,9 @@ is40digitHex xs = ys == xs && length ys==40
779 ishex c = False 785 ishex c = False
780 786
781matchSpec :: KeySpec -> KeyData -> Bool 787matchSpec :: KeySpec -> KeyData -> Bool
782matchSpec (KeyGrip grip) (KeyData p _ _ _) 788matchSpec (KeyFP ver grip) (KeyData p _ _ _)
783 | matchpr grip (packet p)==grip = True 789 = let mg = matchpr ver grip (packet p)
784 | otherwise = False 790 in mg == grip
785 791
786matchSpec (KeyTag key tag) (KeyData _ sigs _ _) = not . null $ filter match ps 792matchSpec (KeyTag key tag) (KeyData _ sigs _ _) = not . null $ filter match ps
787 where 793 where
@@ -791,7 +797,7 @@ matchSpec (KeyTag key tag) (KeyData _ sigs _ _) = not . null $ filter match ps
791 && has_issuer key p 797 && has_issuer key p
792 has_issuer key p = isJust $ do 798 has_issuer key p = isJust $ do
793 issuer <- signature_issuer p 799 issuer <- signature_issuer p
794 guard $ matchpr issuer key == issuer 800 guard $ matchpr 0 issuer key == issuer
795 has_tag tag p = tag `elem` mapMaybe usage (hashed_subpackets p) 801 has_tag tag p = tag `elem` mapMaybe usage (hashed_subpackets p)
796 || tag `elem` map usageString (mapMaybe keyflags (hashed_subpackets p)) 802 || tag `elem` map usageString (mapMaybe keyflags (hashed_subpackets p))
797 803
@@ -907,7 +913,7 @@ getHostnames (KeyData topmp _ uids subs) = Hostnames addr onames othernames Noth
907 913
908hasFingerDress :: KeyDB -> SockAddr -> Bool 914hasFingerDress :: KeyDB -> SockAddr -> Bool
909hasFingerDress db addr | socketFamily addr/=AF_INET6 = False 915hasFingerDress db addr | socketFamily addr/=AF_INET6 = False
910hasFingerDress db addr = pre=="fd" && isJust (selectPublicKey (KeyGrip g',Nothing) db) 916hasFingerDress db addr = pre=="fd" && isJust (selectPublicKey (KeyFP 0 g',Nothing) db)
911 where 917 where
912 (pre,g) = splitAt 2 $ filter (/=':') $ Hosts.inet_ntop addr 918 (pre,g) = splitAt 2 $ filter (/=':') $ Hosts.inet_ntop addr
913 g' = map toUpper g 919 g' = map toUpper g
@@ -1012,6 +1018,7 @@ decode_btc_key timestamp str = do
1012 ] 1018 ]
1013 , s2k_useage = 0 1019 , s2k_useage = 0
1014 , s2k = S2K 100 "" 1020 , s2k = S2K 100 ""
1021 , aead_algorithm = Nothing
1015 , symmetric_algorithm = Unencrypted 1022 , symmetric_algorithm = Unencrypted
1016 , encrypted_data = "" 1023 , encrypted_data = ""
1017 , is_subkey = True 1024 , is_subkey = True
@@ -1205,6 +1212,7 @@ readSecretDNSFile fname = do
1205 _ -> RSA 1212 _ -> RSA
1206 case alg of 1213 case alg of
1207 RSA -> return $ rsaToPGP stamp $ fromJust $ extractRSAKeyFields kvs 1214 RSA -> return $ rsaToPGP stamp $ fromJust $ extractRSAKeyFields kvs
1215 _ -> return $ error $ "readSecretDNSFile: " ++ show alg ++ " unimplemented."
1208 1216
1209spemPacket :: SecretPEMData -> Maybe Packet 1217spemPacket :: SecretPEMData -> Maybe Packet
1210spemPacket (PEMPacket p) = Just p 1218spemPacket (PEMPacket p) = Just p
@@ -1310,6 +1318,7 @@ rsaToPGP stamp rsa = SecretKeyPacket
1310 -- , ecc_curve = def 1318 -- , ecc_curve = def
1311 , s2k_useage = 0 1319 , s2k_useage = 0
1312 , s2k = S2K 100 "" 1320 , s2k = S2K 100 ""
1321 , aead_algorithm = Nothing
1313 , symmetric_algorithm = Unencrypted 1322 , symmetric_algorithm = Unencrypted
1314 , encrypted_data = "" 1323 , encrypted_data = ""
1315 , is_subkey = True 1324 , is_subkey = True