summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2013-11-26 01:32:57 -0500
committerjoe <joe@jerkface.net>2013-11-26 01:32:57 -0500
commitc8be274e825f073c12e914577867c405456ac279 (patch)
tree13057d956b7df8e9a9636ee97c24a2160be63764
parent01ea3657d4c0f6078434166781d991076abd2faa (diff)
Preserve TrustPackets accross merges.
-rw-r--r--kiki.hs105
1 files changed, 72 insertions, 33 deletions
diff --git a/kiki.hs b/kiki.hs
index 034f58d..059fc50 100644
--- a/kiki.hs
+++ b/kiki.hs
@@ -227,6 +227,9 @@ isEmbeddedSignature _ = False
227isCertificationSig (CertificationSignature {}) = True 227isCertificationSig (CertificationSignature {}) = True
228isCertificationSig _ = True 228isCertificationSig _ = True
229 229
230isTrust (TrustPacket {}) = True
231isTrust _ = False
232
230issuer (IssuerPacket issuer) = Just issuer 233issuer (IssuerPacket issuer) = Just issuer
231issuer _ = Nothing 234issuer _ = Nothing
232backsig (EmbeddedSignaturePacket s) = Just s 235backsig (EmbeddedSignaturePacket s) = Just s
@@ -783,6 +786,9 @@ data Arguments =
783 { homedir :: Maybe FilePath 786 { homedir :: Maybe FilePath
784 , files :: [FilePath] 787 , files :: [FilePath]
785 } 788 }
789 | Merge { homedir :: Maybe FilePath
790 , files :: [FilePath]
791 }
786 | DumpPackets { homedir :: Maybe FilePath 792 | DumpPackets { homedir :: Maybe FilePath
787 , marshal_test :: String 793 , marshal_test :: String
788 , files :: [FilePath] } 794 , files :: [FilePath] }
@@ -817,22 +823,31 @@ is40digitHex xs = ys == xs && length ys==40
817 ishex c = False 823 ishex c = False
818 824
819scanPackets [] = [] 825scanPackets [] = []
820scanPackets (p:ps) = scanl doit (doit (MarkerPacket,MarkerPacket,MarkerPacket) p) ps 826scanPackets (p:ps) = scanl doit (doit (MarkerPacket,MarkerPacket,ret MarkerPacket) p) ps
821 where 827 where
822 doit (top,sub,_) p = 828 ret p = (p,Nothing,Nothing)
829 doit (top,sub,prev) p =
823 case p of 830 case p of
824 _ | isKey p && not (is_subkey p) -> (p,MarkerPacket,p) 831 _ | isKey p && not (is_subkey p) -> (p,MarkerPacket,ret p)
825 _ | isKey p && is_subkey p -> (top,p,p) 832 _ | isKey p && is_subkey p -> (top,p,ret p)
826 _ | isUserID p -> (top,p,p) 833 _ | isUserID p -> (top,p,ret p)
827 _ | otherwise -> (top,sub,p) 834 _ | isTrust p -> (top,sub,updateTrust top sub prev p)
835 _ | otherwise -> (top,sub,ret p)
828 836
837 updateTrust top (PublicKeyPacket {}) (pre,a,b) p = (pre,a,Just p)
838 updateTrust (PublicKeyPacket {}) _ (pre,a,b) p = (pre,a,Just p)
839 updateTrust _ _ (pre,a,b) p = (pre,Just p,b)
829 840
830 841
842type SigAndTrust = ( Packet
843 , Maybe Packet -- secret trust packet
844 , Maybe Packet) -- public trust packet
845
831type KeyKey = [Char8.ByteString] 846type KeyKey = [Char8.ByteString]
832data SubKey = SubKey Packet [Packet] 847data SubKey = SubKey Packet [SigAndTrust]
833data KeyData = KeyData Packet -- main key 848data KeyData = KeyData Packet -- main key
834 [Packet] -- sigs on main key 849 [SigAndTrust] -- sigs on main key
835 (Map.Map String [Packet]) -- uids 850 (Map.Map String [SigAndTrust]) -- uids
836 (Map.Map KeyKey SubKey) -- subkeys 851 (Map.Map KeyKey SubKey) -- subkeys
837 852
838type KeyDB = Map.Map KeyKey KeyData 853type KeyDB = Map.Map KeyKey KeyData
@@ -866,8 +881,8 @@ merge :: Map.Map KeyKey KeyData -> Message -> Map.Map KeyKey KeyData
866merge db (Message ps) = foldl mergeit db qs 881merge db (Message ps) = foldl mergeit db qs
867 where 882 where
868 qs = scanPackets ps 883 qs = scanPackets ps
869 mergeit db (_,_,TrustPacket {}) = db -- Filter TrustPackets 884 -- mergeit db (_,_,TrustPacket {}) = db -- Filter TrustPackets
870 mergeit db (top,sub,p) | isKey top = Map.alter update (keykey top) db 885 mergeit db (top,sub,ptt@(p,sectrust,pubtrust)) | isKey top = Map.alter update (keykey top) db
871 where 886 where
872 update v | isKey p && not (is_subkey p) 887 update v | isKey p && not (is_subkey p)
873 = case v of 888 = case v of
@@ -879,18 +894,18 @@ merge db (Message ps) = foldl mergeit db qs
879 update (Just (KeyData key sigs uids subkeys)) | isKey p && is_subkey p 894 update (Just (KeyData key sigs uids subkeys)) | isKey p && is_subkey p
880 = Just $ KeyData key sigs uids (Map.alter (mergeSubkey p) (keykey p) subkeys) 895 = Just $ KeyData key sigs uids (Map.alter (mergeSubkey p) (keykey p) subkeys)
881 update (Just (KeyData key sigs uids subkeys)) | isUserID p 896 update (Just (KeyData key sigs uids subkeys)) | isUserID p
882 = Just $ KeyData key sigs (Map.alter (mergeUid p) (uidkey p) uids) subkeys 897 = Just $ KeyData key sigs (Map.alter (mergeUid ptt) (uidkey p) uids) subkeys
883 update (Just (KeyData key sigs uids subkeys)) 898 update (Just (KeyData key sigs uids subkeys))
884 = case sub of 899 = case sub of
885 MarkerPacket -> Just $ KeyData key (mergeSig p sigs) uids subkeys 900 MarkerPacket -> Just $ KeyData key (mergeSig ptt sigs) uids subkeys
886 UserIDPacket {} -> Just $ KeyData key 901 UserIDPacket {} -> Just $ KeyData key
887 sigs 902 sigs
888 (Map.alter (mergeUidSig p) (uidkey sub) uids) 903 (Map.alter (mergeUidSig ptt) (uidkey sub) uids)
889 subkeys 904 subkeys
890 _ | isKey sub -> Just $ KeyData key 905 _ | isKey sub -> Just $ KeyData key
891 sigs 906 sigs
892 uids 907 uids
893 (Map.alter (mergeSubSig p) (keykey sub) subkeys) 908 (Map.alter (mergeSubSig ptt) (keykey sub) subkeys)
894 _ -> error $ "Unexpected PGP packet 1: "++(words (show p) >>= take 1) 909 _ -> error $ "Unexpected PGP packet 1: "++(words (show p) >>= take 1)
895 update _ = error $ "Unexpected PGP packet 2: "++(words (show p) >>= take 1) 910 update _ = error $ "Unexpected PGP packet 2: "++(words (show p) >>= take 1)
896 911
@@ -900,11 +915,11 @@ merge db (Message ps) = foldl mergeit db qs
900 mergeSubkey p (Just (SubKey key sigs)) = Just $ 915 mergeSubkey p (Just (SubKey key sigs)) = Just $
901 SubKey (minimumBy subcomp [key,p]) sigs 916 SubKey (minimumBy subcomp [key,p]) sigs
902 917
903 mergeUid (UserIDPacket s) Nothing = Just [] 918 mergeUid (UserIDPacket s,_,_) Nothing = Just []
904 mergeUid (UserIDPacket s) (Just sigs) = Just sigs 919 mergeUid (UserIDPacket s,_,_) (Just sigs) = Just sigs
905 mergeUid p _ = error $ "Unable to merge into UID record: " ++whatP p 920 mergeUid p _ = error $ "Unable to merge into UID record: " ++whatP p
906 921
907 whatP = concat . take 1 . words . show 922 whatP (a,_,_) = concat . take 1 . words . show $ a
908 923
909 924
910 mergeSig sig sigs = 925 mergeSig sig sigs =
@@ -915,14 +930,16 @@ merge db (Message ps) = foldl mergeit db qs
915 in xs ++ (mergeSameSig sig y : ys') 930 in xs ++ (mergeSameSig sig y : ys')
916 931
917 932
918 isSameSig a b | isSignaturePacket a && isSignaturePacket b = 933 isSameSig (a,_,_) (b,_,_) | isSignaturePacket a && isSignaturePacket b =
919 a { unhashed_subpackets=[] } == b { unhashed_subpackets = [] } 934 a { unhashed_subpackets=[] } == b { unhashed_subpackets = [] }
920 isSameSig a b = a==b 935 isSameSig (a,_,_) (b,_,_) = a==b
921 936
922 mergeSameSig a b | isSignaturePacket a && isSignaturePacket b = 937 mergeSameSig (a,sa,pa) (b,sb,pb) | isSignaturePacket a && isSignaturePacket b =
923 b { unhashed_subpackets = 938 ( b { unhashed_subpackets =
924 foldl mergeItem (unhashed_subpackets b) (unhashed_subpackets a) 939 foldl mergeItem (unhashed_subpackets b) (unhashed_subpackets a) }
925 } 940 , sb `mplus` sa
941 , pb `mplus` pa )
942
926 where 943 where
927 mergeItem ys x = if x `elem` ys then ys else ys++[x] 944 mergeItem ys x = if x `elem` ys then ys else ys++[x]
928 945
@@ -935,16 +952,23 @@ merge db (Message ps) = foldl mergeit db qs
935 mergeSubSig sig Nothing = error $ 952 mergeSubSig sig Nothing = error $
936 "Unable to merge subkey signature: "++(words (show sig) >>= take 1) 953 "Unable to merge subkey signature: "++(words (show sig) >>= take 1)
937 954
938flattenKeys :: Map.Map KeyKey KeyData -> Message 955flattenKeys :: Bool -> Map.Map KeyKey KeyData -> Message
939flattenKeys db = Message $ concatMap flattenTop (Map.assocs db) 956flattenKeys isPublic db = Message $ concatMap flattenTop (prefilter . Map.assocs $ db)
940 where 957 where
941 flattenTop (_,(KeyData key sigs uids subkeys)) = 958 flattenTop (_,(KeyData key sigs uids subkeys)) =
942 key : ( concatMap flattenUid (Map.assocs uids) 959 unk key : ( concatMap flattenUid (Map.assocs uids)
943 ++ concatMap flattenSub (Map.assocs subkeys)) 960 ++ concatMap flattenSub (Map.assocs subkeys))
944 961
945 flattenUid (str,sigs) = UserIDPacket str : sigs 962 flattenUid (str,sigs) = UserIDPacket str : concatMap unsig sigs
946 963
947 flattenSub (_,SubKey key sigs) = key:sigs 964 flattenSub (_,SubKey key sigs) = unk key: concatMap unsig sigs
965
966 unk k = if isPublic then secretToPublic k else k
967 unsig (sig,sectrust,pubtrust) = [sig]++maybeToList (if isPublic then pubtrust else sectrust)
968
969 prefilter = if isPublic then id else filter isSecret
970 where isSecret (_,(KeyData (SecretKeyPacket {}) _ _ _)) = True
971 isSecret _ = False
948 972
949{- 973{-
950merge db (Message ps) = scanl mergeit db qs 974merge db (Message ps) = scanl mergeit db qs
@@ -1008,7 +1032,10 @@ main = do
1008 &= help "Extract a public subkey to stdout." 1032 &= help "Extract a public subkey to stdout."
1009 , MergeSecrets HOMEOPTION 1033 , MergeSecrets HOMEOPTION
1010 (def &= args &= typFile) 1034 (def &= args &= typFile)
1011 &= help "Merge multiple keyrings to stdout." 1035 &= help "Merge multiple secret keyrings to stdout."
1036 , Merge HOMEOPTION
1037 (def &= args &= typFile)
1038 &= help "Merge multiple keyrings to stdout. Secrets are filtered."
1012 , DumpPackets HOMEOPTION 1039 , DumpPackets HOMEOPTION
1013 (def &= opt ("n" ::String)) 1040 (def &= opt ("n" ::String))
1014 (def &= args &= typFile) 1041 (def &= args &= typFile)
@@ -1284,7 +1311,19 @@ main = do
1284 let db = merge Map.empty (Message sec) 1311 let db = merge Map.empty (Message sec)
1285 ms <- mapM readPacketsFromFile (files cmd) 1312 ms <- mapM readPacketsFromFile (files cmd)
1286 let db' = foldl' merge db ms 1313 let db' = foldl' merge db ms
1287 m = flattenKeys db' 1314 m = flattenKeys False db'
1315 L.putStr (encode m)
1316 return ()
1317
1318 doCmd cmd@(Merge {}) = do
1319 ( homedir -- e3ozbhvej4jvlu43.onion/gpg/gnupghome
1320 , sec -- e3ozbhvej4jvlu43.onion/gpg/gnupghome/secring.gpg
1321 , grip -- Just "AD1CA892FCF4ED9829C762269BDEA5B4D5643321"
1322 ) <- getPGPEnviron cmd
1323 let db = merge Map.empty (Message sec)
1324 ms <- mapM readPacketsFromFile (files cmd)
1325 let db' = foldl' merge db ms
1326 m = flattenKeys True db'
1288 L.putStr (encode m) 1327 L.putStr (encode m)
1289 return () 1328 return ()
1290 1329
@@ -1309,7 +1348,7 @@ main = do
1309 ms <- mapM readPacketsFromFile files 1348 ms <- mapM readPacketsFromFile files
1310 let db = merge Map.empty (Message sec) 1349 let db = merge Map.empty (Message sec)
1311 db' = foldl' merge db ms 1350 db' = foldl' merge db ms
1312 m = flattenKeys db' 1351 m = flattenKeys True db'
1313 Message allpkts = m 1352 Message allpkts = m
1314 1353
1315 let topspec = case () of 1354 let topspec = case () of