diff options
Diffstat (limited to 'lib/KeyRing/BuildKeyDB.hs')
-rw-r--r-- | lib/KeyRing/BuildKeyDB.hs | 57 |
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 | |||
36 | import Data.Maybe | 36 | import Data.Maybe |
37 | import Data.OpenPGP | 37 | import Data.OpenPGP |
38 | import Data.OpenPGP.Util (GenerateKeyParams (..), fingerprint, generateKey, pgpSign, verify) | 38 | import Data.OpenPGP.Util (GenerateKeyParams (..), fingerprint, generateKey, pgpSign, verify) |
39 | import GHC.Stack | ||
39 | 40 | ||
40 | 41 | ||
41 | import Data.Time.Clock (UTCTime) | 42 | import 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 | ||
526 | mergeHostFiles :: KeyRingOperation -> KeyDB -> InputFileContext | 529 | mergeHostFiles :: 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 | ||
591 | getInputFileTime :: InputFileContext -> InputFile -> IO CTime | 594 | getInputFileTime :: HasCallStack => InputFileContext -> InputFile -> IO CTime |
592 | getInputFileTime ctx (Pipe fdr fdw) = do | 595 | getInputFileTime 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 | |||
602 | getInputFileTime ctx (resolveInputFile ctx -> [fname]) = do | 605 | getInputFileTime 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 |
608 | getInputFileTime ctx arg = error $ "getInputFileTime: Invalid argument: " ++ show arg | ||
609 | |||
605 | 610 | ||
606 | slurpWIPKeys :: Posix.EpochTime -> L.ByteString -> ( [(Word8,Packet)], [L.ByteString]) | 611 | slurpWIPKeys :: Posix.EpochTime -> L.ByteString -> ( [(Word8,Packet)], [L.ByteString]) |
607 | slurpWIPKeys stamp "" = ([],[]) | 612 | slurpWIPKeys stamp "" = ([],[]) |
@@ -763,14 +768,15 @@ parseSingleSpec "-" = WorkingKeyMatch | |||
763 | parseSingleSpec "" = EmptyMatch | 768 | parseSingleSpec "" = EmptyMatch |
764 | parseSingleSpec ('t':':':tag) = SubstringMatch (Just KeyTypeField) tag | 769 | parseSingleSpec ('t':':':tag) = SubstringMatch (Just KeyTypeField) tag |
765 | parseSingleSpec ('u':':':tag) = SubstringMatch (Just UserIDField) tag | 770 | parseSingleSpec ('u':':':tag) = SubstringMatch (Just UserIDField) tag |
766 | parseSingleSpec ('c':':':tag) = SubstringMatch (Just GroupIDField) tag | 771 | -- parseSingleSpec ('c':':':tag) = SubstringMatch (Just GroupIDField) tag |
767 | parseSingleSpec ('f':'p':':':fp) = FingerprintMatch fp | 772 | parseSingleSpec ('f':'p':':':fp) = FingerprintMatch 0 fp |
768 | parseSingleSpec str | 773 | parseSingleSpec 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 | ||
772 | is40digitHex :: [Char] -> Bool | 778 | isHexDigits :: [Char] -> Maybe Int |
773 | is40digitHex xs = ys == xs && length ys==40 | 779 | isHexDigits 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 | ||
781 | matchSpec :: KeySpec -> KeyData -> Bool | 787 | matchSpec :: KeySpec -> KeyData -> Bool |
782 | matchSpec (KeyGrip grip) (KeyData p _ _ _) | 788 | matchSpec (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 | ||
786 | matchSpec (KeyTag key tag) (KeyData _ sigs _ _) = not . null $ filter match ps | 792 | matchSpec (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 | ||
908 | hasFingerDress :: KeyDB -> SockAddr -> Bool | 914 | hasFingerDress :: KeyDB -> SockAddr -> Bool |
909 | hasFingerDress db addr | socketFamily addr/=AF_INET6 = False | 915 | hasFingerDress db addr | socketFamily addr/=AF_INET6 = False |
910 | hasFingerDress db addr = pre=="fd" && isJust (selectPublicKey (KeyGrip g',Nothing) db) | 916 | hasFingerDress 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 | ||
1209 | spemPacket :: SecretPEMData -> Maybe Packet | 1217 | spemPacket :: SecretPEMData -> Maybe Packet |
1210 | spemPacket (PEMPacket p) = Just p | 1218 | spemPacket (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 |