summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kiki.hs220
1 files changed, 110 insertions, 110 deletions
diff --git a/kiki.hs b/kiki.hs
index bc45991..2ac6450 100644
--- a/kiki.hs
+++ b/kiki.hs
@@ -164,7 +164,7 @@ instance ASN1Object RSAPrivateKey where
164 where 164 where
165 notend (End Sequence) = False 165 notend (End Sequence) = False
166 notend _ = True 166 notend _ = True
167 privkey = RSAPrivateKey 167 privkey = RSAPrivateKey
168 { rsaN = MPI n 168 { rsaN = MPI n
169 , rsaE = MPI e 169 , rsaE = MPI e
170 , rsaD = MPI d 170 , rsaD = MPI d
@@ -204,7 +204,7 @@ secretToPublic pkt@(SecretKeyPacket {}) =
204 , key_algorithm = key_algorithm pkt 204 , key_algorithm = key_algorithm pkt
205 , key = let seckey = key pkt 205 , key = let seckey = key pkt
206 pubs = public_key_fields (key_algorithm pkt) 206 pubs = public_key_fields (key_algorithm pkt)
207 in filter (\(k,v) -> k `elem` pubs) seckey 207 in filter (\(k,v) -> k `elem` pubs) seckey
208 , is_subkey = is_subkey pkt 208 , is_subkey = is_subkey pkt
209 , v3_days_of_validity = Nothing 209 , v3_days_of_validity = Nothing
210 } 210 }
@@ -309,7 +309,7 @@ verifyBindingsEx pkts = bicat . unzip $ do
309 309
310getBindings :: 310getBindings ::
311 [Packet] 311 [Packet]
312 -> 312 ->
313 ( [([Packet],[SignatureOver])] -- ^ other signatures with key sets 313 ( [([Packet],[SignatureOver])] -- ^ other signatures with key sets
314 -- that were used for the verifications 314 -- that were used for the verifications
315 , [(Word8, 315 , [(Word8,
@@ -329,7 +329,7 @@ getBindings pkts = (sigs,bindings)
329 i <- map signature_issuer (signatures_over b) 329 i <- map signature_issuer (signatures_over b)
330 i <- maybeToList i 330 i <- maybeToList i
331 who <- maybeToList $ find_key fingerprint (Message keys) i 331 who <- maybeToList $ find_key fingerprint (Message keys) i
332 let (code,claimants) = 332 let (code,claimants) =
333 case () of 333 case () of
334 _ | who == topkey b -> (1,[]) 334 _ | who == topkey b -> (1,[])
335 _ | who == subkey b -> (2,[]) 335 _ | who == subkey b -> (2,[])
@@ -380,7 +380,7 @@ parseUID str = UserIDRecord {
380 } 380 }
381 where 381 where
382 text = T.pack str 382 text = T.pack str
383 (T.strip-> realname, T.dropAround isBracket-> email) 383 (T.strip-> realname, T.dropAround isBracket-> email)
384 = T.break (=='<') text 384 = T.break (=='<') text
385 (user, T.tail-> hostname) = T.break (=='@') email 385 (user, T.tail-> hostname) = T.break (=='@') email
386 ( T.reverse -> topdomain, 386 ( T.reverse -> topdomain,
@@ -390,7 +390,7 @@ parseUID str = UserIDRecord {
390 390
391derToBase32 = map toLower . Base32.encode . S.unpack . SHA1.hashlazy 391derToBase32 = map toLower . Base32.encode . S.unpack . SHA1.hashlazy
392 392
393fpmatch grip key = 393fpmatch grip key =
394 (==) Nothing 394 (==) Nothing
395 (fmap (backend (fingerprint key)) grip >>= guard . not) 395 (fmap (backend (fingerprint key)) grip >>= guard . not)
396 where 396 where
@@ -404,7 +404,7 @@ listKeysFiltered grips pkts = do
404 defaultkind (k:_) hs = k 404 defaultkind (k:_) hs = k
405 defaultkind [] hs = maybe "subkey" 405 defaultkind [] hs = maybe "subkey"
406 id 406 id
407 ( listToMaybe 407 ( listToMaybe
408 . mapMaybe (fmap usageString . keyflags) 408 . mapMaybe (fmap usageString . keyflags)
409 $ hs) 409 $ hs)
410 kinds = map (\(_,_,k,h,_)->defaultkind k h) as 410 kinds = map (\(_,_,k,h,_)->defaultkind k h) as
@@ -430,12 +430,12 @@ listKeysFiltered grips pkts = do
430 torhash = maybe "" id $ derToBase32 <$> derRSA sub 430 torhash = maybe "" id $ derToBase32 <$> derRSA sub
431 concat [ " " 431 concat [ " "
432 -- , grip top 432 -- , grip top
433 , (if not (null claimants) 433 , (if not (null claimants)
434 then trace ("claimants: "++show (map fingerprint claimants)) 434 then trace ("claimants: "++show (map fingerprint claimants))
435 else id) ar 435 else id) ar
436 , formkind 436 , formkind
437 , " " 437 , " "
438 , fingerprint sub 438 , fingerprint sub
439 -- , " " ++ torhash 439 -- , " " ++ torhash
440 , "\n" ] 440 , "\n" ]
441 -- ++ ppShow hashed 441 -- ++ ppShow hashed
@@ -454,7 +454,7 @@ listKeysFiltered grips pkts = do
454 i <- maybeToList $ signature_issuer sig_over 454 i <- maybeToList $ signature_issuer sig_over
455 maybeToList $ find_key (matchpr i) (Message keys) (reverse (take 16 (reverse i))) 455 maybeToList $ find_key (matchpr i) (Message keys) (reverse (take 16 (reverse i)))
456 (primary,secondary) = partition (==top) issuers 456 (primary,secondary) = partition (==top) issuers
457 457
458 -- trace ("PRIMARY: "++show (map fingerprint primary)) $ return () 458 -- trace ("PRIMARY: "++show (map fingerprint primary)) $ return ()
459 -- trace ("SECONDARY: "++show (map fingerprint secondary)) $ return () 459 -- trace ("SECONDARY: "++show (map fingerprint secondary)) $ return ()
460 guard (not (null primary)) 460 guard (not (null primary))
@@ -475,7 +475,7 @@ listKeysFiltered grips pkts = do
475 ++ map (\k -> " " ++ "^ signed: " ++ fingerprint k) secondary 475 ++ map (\k -> " " ++ "^ signed: " ++ fingerprint k) secondary
476 (_,sigs) = unzip certs 476 (_,sigs) = unzip certs
477 "master-key " ++ fingerprint top ++ "\n" ++ uid ++" ...\n" ++ subkeys ++ "\n" 477 "master-key " ++ fingerprint top ++ "\n" ++ uid ++" ...\n" ++ subkeys ++ "\n"
478 478
479 479
480data PGPKeyFlags = 480data PGPKeyFlags =
481 Special 481 Special
@@ -496,7 +496,7 @@ data PGPKeyFlags =
496 | VouchSignEncrypt 496 | VouchSignEncrypt
497 deriving (Eq,Show,Read,Enum) 497 deriving (Eq,Show,Read,Enum)
498 498
499usageString flgs = 499usageString flgs =
500 case flgs of 500 case flgs of
501 Special -> "special" 501 Special -> "special"
502 Vouch -> "vouch" -- signkey 502 Vouch -> "vouch" -- signkey
@@ -518,7 +518,7 @@ usageString flgs =
518 518
519keyflags flgs@(KeyFlagsPacket {}) = 519keyflags flgs@(KeyFlagsPacket {}) =
520 Just . toEnum $ 520 Just . toEnum $
521 ( bit 0x1 certify_keys 521 ( bit 0x1 certify_keys
522 .|. bit 0x2 sign_data 522 .|. bit 0x2 sign_data
523 .|. bit 0x4 encrypt_communication 523 .|. bit 0x4 encrypt_communication
524 .|. bit 0x8 encrypt_storage ) :: Maybe PGPKeyFlags 524 .|. bit 0x8 encrypt_storage ) :: Maybe PGPKeyFlags
@@ -543,7 +543,7 @@ todo = error "unimplemented"
543 543
544-- TODO: switch to System.Environment.lookupEnv 544-- TODO: switch to System.Environment.lookupEnv
545-- when linking against newer base libraries. 545-- when linking against newer base libraries.
546lookupEnv var = 546lookupEnv var =
547 handleIO_ (return Nothing) $ fmap Just (getEnv var) 547 handleIO_ (return Nothing) $ fmap Just (getEnv var)
548 548
549unmaybe def = fmap (maybe def id) 549unmaybe def = fmap (maybe def id)
@@ -574,7 +574,7 @@ lockFiles fs = do
574 ls <- mapM dolock fs 574 ls <- mapM dolock fs
575 let (lks, fails) = partition (isJust . fst) ls 575 let (lks, fails) = partition (isJust . fst) ls
576 return (map (\(lk,f)->(fromJust lk,f)) lks, map snd fails) 576 return (map (\(lk,f)->(fromJust lk,f)) lks, map snd fails)
577 577
578unlockFiles lks = forM_ lks $ \lk -> dotlock_release lk 578unlockFiles lks = forM_ lks $ \lk -> dotlock_release lk
579 579
580parseOptionFile fname = do 580parseOptionFile fname = do
@@ -585,11 +585,11 @@ parseOptionFile fname = do
585 return ys 585 return ys
586 586
587{- 587{-
588options_from_file :: 588options_from_file ::
589 (forall a. [String] -> Term a -> IO (Either EvalExit a)) 589 (forall a. [String] -> Term a -> IO (Either EvalExit a))
590 -> Term b 590 -> Term b
591 -> (String,String,Term (Maybe String)) 591 -> (String,String,Term (Maybe String))
592 -> ([String],Term (Maybe String)) 592 -> ([String],Term (Maybe String))
593 -> IO [String] 593 -> IO [String]
594options_from_file unwrapCmd term (homevar,appdir,home) (optfile_alts,options_file) = doit 594options_from_file unwrapCmd term (homevar,appdir,home) (optfile_alts,options_file) = doit
595 where 595 where
@@ -606,11 +606,11 @@ options_from_file unwrapCmd term (homevar,appdir,home) (optfile_alts,options_fil
606 doit = do 606 doit = do
607 args <- getArgs 607 args <- getArgs
608 {- 608 {-
609 let wants_help = 609 let wants_help =
610 not . null $ filter cryForHelp args 610 not . null $ filter cryForHelp args
611 where cryForHelp "--help" = True 611 where cryForHelp "--help" = True
612 cryForHelp "--version" = True 612 cryForHelp "--version" = True
613 cryForHelp x = 613 cryForHelp x =
614 and (zipWith (==) x "--help=") 614 and (zipWith (==) x "--help=")
615 -} 615 -}
616 (o,h) <- do 616 (o,h) <- do
@@ -618,8 +618,8 @@ options_from_file unwrapCmd term (homevar,appdir,home) (optfile_alts,options_fil
618 case val of 618 case val of
619 Left e -> return (Nothing,Nothing) 619 Left e -> return (Nothing,Nothing)
620 Right (o,h) -> (o,) <$> h 620 Right (o,h) -> (o,) <$> h
621 ofile <- fmap listToMaybe . flip (maybe (return [])) h $ \h -> 621 ofile <- fmap listToMaybe . flip (maybe (return [])) h $ \h ->
622 let optfiles = map (second ((h++"/")++)) 622 let optfiles = map (second ((h++"/")++))
623 (maybe optfile_alts' (:[]) o') 623 (maybe optfile_alts' (:[]) o')
624 optfile_alts' = zip (False:repeat True) optfile_alts 624 optfile_alts' = zip (False:repeat True) optfile_alts
625 o' = fmap (False,) o 625 o' = fmap (False,) o
@@ -666,11 +666,11 @@ runChoiceWithOptionsFile (realterm,ti) choices = do
666 q <- evalChoice as (realterm , ti) choices 666 q <- evalChoice as (realterm , ti) choices
667 q 667 q
668 where 668 where
669 unwrapCmd args t = 669 unwrapCmd args t =
670 unwrapChoice args (realterm <:> t,ti) (map (neuter t) choices) 670 unwrapChoice args (realterm <:> t,ti) (map (neuter t) choices)
671 neuter term (t,ti) = (t <:> term, ti) 671 neuter term (t,ti) = (t <:> term, ti)
672 672
673data Command = 673data Command =
674 List 674 List
675 | Autosign 675 | Autosign
676 deriving (Eq,Show,Read,Enum) 676 deriving (Eq,Show,Read,Enum)
@@ -678,12 +678,12 @@ data Command =
678capitolizeFirstLetter (x:xs) = toUpper x : xs 678capitolizeFirstLetter (x:xs) = toUpper x : xs
679capitolizeFirstLetter xs = xs 679capitolizeFirstLetter xs = xs
680 680
681instance ArgVal Command where 681instance ArgVal Command where
682 converter = 682 converter =
683 ( maybe (Left $ text "unknown command") Right 683 ( maybe (Left $ text "unknown command") Right
684 . fmap fst . listToMaybe . reads 684 . fmap fst . listToMaybe . reads
685 . capitolizeFirstLetter . map toLower 685 . capitolizeFirstLetter . map toLower
686 , text . map toLower . show 686 , text . map toLower . show
687 ) 687 )
688class AutoMaybe a 688class AutoMaybe a
689instance AutoMaybe Command 689instance AutoMaybe Command
@@ -697,7 +697,7 @@ toRight f (Right x) = Right (f x)
697toRight f (Left y) = Left y 697toRight f (Left y) = Left y
698 698
699cmd :: Term Command 699cmd :: Term Command
700cmd = required . pos 0 Nothing $ posInfo 700cmd = required . pos 0 Nothing $ posInfo
701 { posName = "command" 701 { posName = "command"
702 , posDoc = "What action to perform." 702 , posDoc = "What action to perform."
703 } 703 }
@@ -707,9 +707,9 @@ infixr 2 <:>
707 707
708selectAction cmd actions = actions !! fromEnum cmd 708selectAction cmd actions = actions !! fromEnum cmd
709 709
710cmdInfo :: ArgVal cmd => 710cmdInfo :: ArgVal cmd =>
711 cmd -> String -> Term a -> (cmd, (Term a, TermInfo)) 711 cmd -> String -> Term a -> (cmd, (Term a, TermInfo))
712cmdInfo cmd doc action = 712cmdInfo cmd doc action =
713 ( cmd 713 ( cmd
714 , ( action 714 , ( action
715 , defTI { termName = print cmd 715 , defTI { termName = print cmd
@@ -731,7 +731,7 @@ multiCommand ::
731 -> [(Command, (Term a, TermInfo))] 731 -> [(Command, (Term a, TermInfo))]
732 -> ( (Term a, TermInfo) 732 -> ( (Term a, TermInfo)
733 , [(Term a, TermInfo)] ) 733 , [(Term a, TermInfo)] )
734multiCommand ti choices = 734multiCommand ti choices =
735 ( ( selectAction <$> cmd <*> sequenceA (map strip choices) 735 ( ( selectAction <$> cmd <*> sequenceA (map strip choices)
736 , ti ) 736 , ti )
737 , map snd choices ) 737 , map snd choices )
@@ -763,7 +763,7 @@ readKeyFromFile False "PEM" fname = do
763 -- putStrLn $ "rsa = "++ show rsa 763 -- putStrLn $ "rsa = "++ show rsa
764 return . Message $ do 764 return . Message $ do
765 rsa <- maybeToList rsa 765 rsa <- maybeToList rsa
766 return $ SecretKeyPacket 766 return $ SecretKeyPacket
767 { version = 4 767 { version = 4
768 , timestamp = toEnum (fromEnum timestamp) 768 , timestamp = toEnum (fromEnum timestamp)
769 , key_algorithm = RSA 769 , key_algorithm = RSA
@@ -784,12 +784,12 @@ readKeyFromFile False "PEM" fname = do
784 } 784 }
785readKeyFromFile is_public fmt filename = error ("unimplemented key type: "++fmt) 785readKeyFromFile is_public fmt filename = error ("unimplemented key type: "++fmt)
786 786
787getPassphrase cmd = 787getPassphrase cmd =
788 case passphrase_fd cmd of 788 case passphrase_fd cmd of
789 Just fd -> do pwh <- fdToHandle (toEnum fd) 789 Just fd -> do pwh <- fdToHandle (toEnum fd)
790 fmap trimCR $ S.hGetContents pwh 790 fmap trimCR $ S.hGetContents pwh
791 Nothing -> return "" 791 Nothing -> return ""
792 792
793 793
794#define HOMEOPTION (def &= explicit &= name "homedir" &= typDir ) 794#define HOMEOPTION (def &= explicit &= name "homedir" &= typDir )
795 795
@@ -882,14 +882,14 @@ merge db filename (Message ps) = foldl mergeit db qs
882 mergeit :: KeyDB -> (Packet,Packet,(Packet,Map.Map FilePath Packet)) -> KeyDB 882 mergeit :: KeyDB -> (Packet,Packet,(Packet,Map.Map FilePath Packet)) -> KeyDB
883 mergeit db (top,sub,ptt@(p,trustmap)) | isKey top = Map.alter update (keykey top) db 883 mergeit db (top,sub,ptt@(p,trustmap)) | isKey top = Map.alter update (keykey top) db
884 where 884 where
885 update v | isKey p && not (is_subkey p) 885 update v | isKey p && not (is_subkey p)
886 = case v of 886 = case v of
887 Nothing -> Just $ KeyData (asMapped p) [] Map.empty Map.empty 887 Nothing -> Just $ KeyData (asMapped p) [] Map.empty Map.empty
888 Just (KeyData key sigs uids subkeys) | keykey (packet key) == keykey p 888 Just (KeyData key sigs uids subkeys) | keykey (packet key) == keykey p
889 -> Just $ KeyData ( MappedPacket (minimumBy keycomp [packet key,p]) 889 -> Just $ KeyData ( MappedPacket (minimumBy keycomp [packet key,p])
890 (Map.insert filename originNil (locations key)) ) 890 (Map.insert filename originNil (locations key)) )
891 sigs 891 sigs
892 uids 892 uids
893 subkeys 893 subkeys
894 _ -> error . concat $ ["Unexpected master key merge error: " 894 _ -> error . concat $ ["Unexpected master key merge error: "
895 ,show (fingerprint top, fingerprint p)] 895 ,show (fingerprint top, fingerprint p)]
@@ -900,8 +900,8 @@ merge db filename (Message ps) = foldl mergeit db qs
900 update (Just (KeyData key sigs uids subkeys)) 900 update (Just (KeyData key sigs uids subkeys))
901 = case sub of 901 = case sub of
902 MarkerPacket -> Just $ KeyData key (mergeSig ptt sigs) uids subkeys 902 MarkerPacket -> Just $ KeyData key (mergeSig ptt sigs) uids subkeys
903 UserIDPacket {} -> Just $ KeyData key 903 UserIDPacket {} -> Just $ KeyData key
904 sigs 904 sigs
905 (Map.alter (mergeUidSig ptt) (uidkey sub) uids) 905 (Map.alter (mergeUidSig ptt) (uidkey sub) uids)
906 subkeys 906 subkeys
907 _ | isKey sub -> Just $ KeyData key 907 _ | isKey sub -> Just $ KeyData key
@@ -925,29 +925,29 @@ merge db filename (Message ps) = foldl mergeit db qs
925 mergeUid p _ = error $ "Unable to merge into UID record: " ++whatP p 925 mergeUid p _ = error $ "Unable to merge into UID record: " ++whatP p
926 926
927 whatP (a,_) = concat . take 1 . words . show $ a 927 whatP (a,_) = concat . take 1 . words . show $ a
928 928
929 929
930 mergeSig :: (Packet,TrustMap) -> [SigAndTrust] -> [SigAndTrust] 930 mergeSig :: (Packet,TrustMap) -> [SigAndTrust] -> [SigAndTrust]
931 mergeSig sig sigs = 931 mergeSig sig sigs =
932 let (xs,ys) = break (isSameSig sig) sigs 932 let (xs,ys) = break (isSameSig sig) sigs
933 first f (x,y) = (f x,y) 933 first f (x,y) = (f x,y)
934 in if null ys 934 in if null ys
935 then sigs++[first asMapped sig] 935 then sigs++[first asMapped sig]
936 else let y:ys'=ys 936 else let y:ys'=ys
937 in xs ++ (mergeSameSig sig y : ys') 937 in xs ++ (mergeSameSig sig y : ys')
938
939 938
940 isSameSig (a,_) (MappedPacket b _,_) | isSignaturePacket a && isSignaturePacket b = 939
940 isSameSig (a,_) (MappedPacket b _,_) | isSignaturePacket a && isSignaturePacket b =
941 a { unhashed_subpackets=[] } == b { unhashed_subpackets = [] } 941 a { unhashed_subpackets=[] } == b { unhashed_subpackets = [] }
942 isSameSig (a,_) (MappedPacket b _,_) = a==b 942 isSameSig (a,_) (MappedPacket b _,_) = a==b
943 943
944 mergeSameSig :: (Packet,TrustMap) -> (MappedPacket,TrustMap) -> (MappedPacket, TrustMap) 944 mergeSameSig :: (Packet,TrustMap) -> (MappedPacket,TrustMap) -> (MappedPacket, TrustMap)
945 mergeSameSig (a,ta) (MappedPacket b locs,tb) | isSignaturePacket a && isSignaturePacket b = 945 mergeSameSig (a,ta) (MappedPacket b locs,tb) | isSignaturePacket a && isSignaturePacket b =
946 ( MappedPacket (b { unhashed_subpackets = 946 ( MappedPacket (b { unhashed_subpackets =
947 foldl mergeItem (unhashed_subpackets b) (unhashed_subpackets a) }) 947 foldl mergeItem (unhashed_subpackets b) (unhashed_subpackets a) })
948 (Map.insert filename originNil locs) 948 (Map.insert filename originNil locs)
949 , tb `Map.union` ta ) 949 , tb `Map.union` ta )
950 950
951 where 951 where
952 mergeItem ys x = if x `elem` ys then ys else ys++[x] 952 mergeItem ys x = if x `elem` ys then ys else ys++[x]
953 953
@@ -957,14 +957,14 @@ merge db filename (Message ps) = foldl mergeit db qs
957 mergeUidSig sig Nothing = Just [asSigAndTrust sig] 957 mergeUidSig sig Nothing = Just [asSigAndTrust sig]
958 958
959 mergeSubSig sig (Just (SubKey key sigs)) = Just $ SubKey key (mergeSig sig sigs) 959 mergeSubSig sig (Just (SubKey key sigs)) = Just $ SubKey key (mergeSig sig sigs)
960 mergeSubSig sig Nothing = error $ 960 mergeSubSig sig Nothing = error $
961 "Unable to merge subkey signature: "++(words (show sig) >>= take 1) 961 "Unable to merge subkey signature: "++(words (show sig) >>= take 1)
962 962
963flattenKeys :: Bool -> KeyDB -> Message 963flattenKeys :: Bool -> KeyDB -> Message
964flattenKeys isPublic db = Message $ concatMap flattenTop (prefilter . Map.assocs $ db) 964flattenKeys isPublic db = Message $ concatMap flattenTop (prefilter . Map.assocs $ db)
965 where 965 where
966 flattenTop (_,(KeyData key sigs uids subkeys)) = 966 flattenTop (_,(KeyData key sigs uids subkeys)) =
967 unk key : ( concatMap flattenUid (Map.assocs uids) 967 unk key : ( concatMap flattenUid (Map.assocs uids)
968 ++ concatMap flattenSub (Map.assocs subkeys)) 968 ++ concatMap flattenSub (Map.assocs subkeys))
969 969
970 flattenUid (str,sigs) = UserIDPacket str : concatMap unsig sigs 970 flattenUid (str,sigs) = UserIDPacket str : concatMap unsig sigs
@@ -972,13 +972,13 @@ flattenKeys isPublic db = Message $ concatMap flattenTop (prefilter . Map.assocs
972 flattenSub (_,SubKey key sigs) = unk key: concatMap unsig sigs 972 flattenSub (_,SubKey key sigs) = unk key: concatMap unsig sigs
973 973
974 unk = (if isPublic then secretToPublic else id) . packet 974 unk = (if isPublic then secretToPublic else id) . packet
975 unsig (sig,trustmap) = [packet sig]++ take 1 (Map.elems $ Map.filterWithKey f trustmap) 975 unsig (sig,trustmap) = [packet sig]++ take 1 (Map.elems $ Map.filterWithKey f trustmap)
976 where 976 where
977 f "%secring" _ = not isPublic 977 f "%secring" _ = not isPublic
978 f _ _ = isPublic 978 f _ _ = isPublic
979 979
980 prefilter = if isPublic then id else filter isSecret 980 prefilter = if isPublic then id else filter isSecret
981 where 981 where
982 isSecret (_,(KeyData 982 isSecret (_,(KeyData
983 (MappedPacket { packet=(SecretKeyPacket {})}) 983 (MappedPacket { packet=(SecretKeyPacket {})})
984 _ 984 _
@@ -988,7 +988,7 @@ flattenKeys isPublic db = Message $ concatMap flattenTop (prefilter . Map.assocs
988 988
989writeOutKeyrings db = return () -- TODO 989writeOutKeyrings db = return () -- TODO
990 990
991data Arguments = 991data Arguments =
992 Cross_Merge { homedir :: Maybe FilePath 992 Cross_Merge { homedir :: Maybe FilePath
993 , passphrase_fd :: Maybe Int 993 , passphrase_fd :: Maybe Int
994 , files :: [FilePath] 994 , files :: [FilePath]
@@ -999,9 +999,9 @@ data Arguments =
999 999
1000main = do 1000main = do
1001 dotlock_init 1001 dotlock_init
1002 args <- cmdArgs $ modes 1002 args <- cmdArgs $ modes
1003 [ Cross_Merge HOMEOPTION 1003 [ Cross_Merge HOMEOPTION
1004 (def &= opt ("passphrase"::String) 1004 (def &= opt ("passphrase"::String)
1005 &= typ "FD" 1005 &= typ "FD"
1006 &= (help . concat) ["file descriptor from " 1006 &= (help . concat) ["file descriptor from "
1007 ,"which to read passphrase"]) 1007 ,"which to read passphrase"])
@@ -1040,13 +1040,13 @@ main = do
1040 let o = Nothing 1040 let o = Nothing
1041 h = Just homedir 1041 h = Just homedir
1042 args = ["hi"] 1042 args = ["hi"]
1043 ofile <- fmap listToMaybe . flip (maybe (return [])) h $ \h -> 1043 ofile <- fmap listToMaybe . flip (maybe (return [])) h $ \h ->
1044 let optfiles = map (second ((h++"/")++)) 1044 let optfiles = map (second ((h++"/")++))
1045 (maybe optfile_alts' (:[]) o') 1045 (maybe optfile_alts' (:[]) o')
1046 optfile_alts' = zip (False:repeat True) optfile_alts 1046 optfile_alts' = zip (False:repeat True) optfile_alts
1047 o' = fmap (False,) o 1047 o' = fmap (False,) o
1048 in filterM (doesFileExist . snd) optfiles 1048 in filterM (doesFileExist . snd) optfiles
1049 args <- flip (maybe $ return []) ofile $ 1049 args <- flip (maybe $ return []) ofile $
1050 \(forgive,fname) -> parseOptionFile fname 1050 \(forgive,fname) -> parseOptionFile fname
1051 let config = map (topair . words) args 1051 let config = map (topair . words) args
1052 where topair (x:xs) = (x,xs) 1052 where topair (x:xs) = (x,xs)
@@ -1055,8 +1055,8 @@ main = do
1055 getPGPEnviron cmd = do 1055 getPGPEnviron cmd = do
1056 (homedir,secring,pubring,grip) <- getHomeDir cmd 1056 (homedir,secring,pubring,grip) <- getHomeDir cmd
1057 (Message sec) <- readPacketsFromFile secring 1057 (Message sec) <- readPacketsFromFile secring
1058 let (keys,_) = partition (\k -> case k of 1058 let (keys,_) = partition (\k -> case k of
1059 { SecretKeyPacket {} -> True 1059 { SecretKeyPacket {} -> True
1060 ; _ -> False }) 1060 ; _ -> False })
1061 sec 1061 sec
1062 return (homedir,sec, grip `mplus` fmap fingerprint (listToMaybe keys)) 1062 return (homedir,sec, grip `mplus` fmap fingerprint (listToMaybe keys))
@@ -1068,15 +1068,15 @@ main = do
1068 let torhash = maybe "" id $ derToBase32 <$> derRSA sub 1068 let torhash = maybe "" id $ derToBase32 <$> derRSA sub
1069 return (top,(torhash,sub)) 1069 return (top,(torhash,sub))
1070 1070
1071 uidScan pub = scanl (\(mkey,u) w -> 1071 uidScan pub = scanl (\(mkey,u) w ->
1072 case () of 1072 case () of
1073 _ | isMasterKey w -> (w,u) 1073 _ | isMasterKey w -> (w,u)
1074 _ | isUserID w -> (mkey,w) 1074 _ | isUserID w -> (mkey,w)
1075 _ | otherwise -> (mkey,u) 1075 _ | otherwise -> (mkey,u)
1076 ) 1076 )
1077 (w0,w0) 1077 (w0,w0)
1078 ws 1078 ws
1079 where 1079 where
1080 w0:ws = pub 1080 w0:ws = pub
1081 1081
1082 signSelfAuthTorKeys selfkey g sec grip timestamp xs = ys 1082 signSelfAuthTorKeys selfkey g sec grip timestamp xs = ys
@@ -1102,10 +1102,10 @@ main = do
1102 then sigs 1102 then sigs
1103 {- 1103 {-
1104 else trace ( "key params: "++params (fromJust selfkey)++"\n" 1104 else trace ( "key params: "++params (fromJust selfkey)++"\n"
1105 ++traceSig (topkey new_sig) 1105 ++traceSig (topkey new_sig)
1106 (user_id new_sig) 1106 (user_id new_sig)
1107 (signatures_over new_sig)) 1107 (signatures_over new_sig))
1108 sigs 1108 sigs
1109 ++ {- map modsig -} (signatures_over new_sig) 1109 ++ {- map modsig -} (signatures_over new_sig)
1110 -} 1110 -}
1111 else sigs ++ signatures_over new_sig 1111 else sigs ++ signatures_over new_sig
@@ -1160,10 +1160,10 @@ main = do
1160 flip (maybe (error "No working key?")) grip $ \grip -> do 1160 flip (maybe (error "No working key?")) grip $ \grip -> do
1161 pw <- getPassphrase cmd 1161 pw <- getPassphrase cmd
1162 let (pre, wk:subs) = seek_key (KeyGrip grip) sec 1162 let (pre, wk:subs) = seek_key (KeyGrip grip) sec
1163 wkun = if symmetric_algorithm wk == Unencrypted 1163 wkun = if symmetric_algorithm wk == Unencrypted
1164 then Just wk 1164 then Just wk
1165 else do 1165 else do
1166 k <- decryptSecretKey pw wk 1166 k <- decryptSecretKey pw wk
1167 guard (symmetric_algorithm k == Unencrypted) 1167 guard (symmetric_algorithm k == Unencrypted)
1168 return k 1168 return k
1169 flip (maybe (error "Bad passphrase?")) wkun$ \wkun -> do 1169 flip (maybe (error "Bad passphrase?")) wkun$ \wkun -> do
@@ -1177,10 +1177,10 @@ main = do
1177 marked = zipWith doit keyed pub 1177 marked = zipWith doit keyed pub
1178 doit (mkey,u) packet = (isTorID packet, (mkey,u,packet)) 1178 doit (mkey,u) packet = (isTorID packet, (mkey,u,packet))
1179 where 1179 where
1180 isTorID (UserIDPacket str) = 1180 isTorID (UserIDPacket str) =
1181 and [ uid_topdomain parsed == "onion" 1181 and [ uid_topdomain parsed == "onion"
1182 , uid_realname parsed `elem` ["","Anonymous"] 1182 , uid_realname parsed `elem` ["","Anonymous"]
1183 , uid_user parsed == "root" 1183 , uid_user parsed == "root"
1184 , fmap (match . fst) (lookup mkey torbindings) 1184 , fmap (match . fst) (lookup mkey torbindings)
1185 == Just True ] 1185 == Just True ]
1186 where parsed = parseUID str 1186 where parsed = parseUID str
@@ -1195,7 +1195,7 @@ main = do
1195 timestamp <- now 1195 timestamp <- now
1196 -- timestamp <- epochTime 1196 -- timestamp <- epochTime
1197 let xs:xss = groupBy (\_ (b,_)->not b) marked 1197 let xs:xss = groupBy (\_ (b,_)->not b) marked
1198 pub' = map (snd . cleanup) xs 1198 pub' = map (snd . cleanup) xs
1199 ++ concatMap (signSelfAuthTorKeys (Just wkun) (g::SystemRandom) sec grip timestamp) 1199 ++ concatMap (signSelfAuthTorKeys (Just wkun) (g::SystemRandom) sec grip timestamp)
1200 (map (map cleanup) xss) 1200 (map (map cleanup) xss)
1201 cleanup (_,(topkey,_,pkt)) = (topkey,pkt) 1201 cleanup (_,(topkey,_,pkt)) = (topkey,pkt)
@@ -1222,7 +1222,7 @@ main = do
1222 ) <- getPGPEnviron cmd 1222 ) <- getPGPEnviron cmd
1223 p <- case files cmd of 1223 p <- case files cmd of
1224 [] -> return sec 1224 [] -> return sec
1225 fs -> do 1225 fs -> do
1226 ms <- mapM readPacketsFromFile fs 1226 ms <- mapM readPacketsFromFile fs
1227 let unwrap (Message ps) = ps 1227 let unwrap (Message ps) = ps
1228 return (concatMap unwrap ms) 1228 return (concatMap unwrap ms)
@@ -1333,10 +1333,10 @@ main = do
1333 flip (maybe (error "No working key?")) grip $ \grip -> do 1333 flip (maybe (error "No working key?")) grip $ \grip -> do
1334 1334
1335 let (pre, wk:subs) = seek_key (KeyGrip grip) sec 1335 let (pre, wk:subs) = seek_key (KeyGrip grip) sec
1336 wkun = if symmetric_algorithm wk == Unencrypted 1336 wkun = if symmetric_algorithm wk == Unencrypted
1337 then Just wk 1337 then Just wk
1338 else do 1338 else do
1339 k <- decryptSecretKey pw wk 1339 k <- decryptSecretKey pw wk
1340 guard (symmetric_algorithm k == Unencrypted) 1340 guard (symmetric_algorithm k == Unencrypted)
1341 return k 1341 return k
1342 1342
@@ -1365,15 +1365,15 @@ main = do
1365 torkey <- parsedkey 1365 torkey <- parsedkey
1366 if key_usage cmd /= "tor" 1366 if key_usage cmd /= "tor"
1367 then uids 1367 then uids
1368 else let ps = makeTorUID (g::SystemRandom) 1368 else let ps = makeTorUID (g::SystemRandom)
1369 timestamp 1369 timestamp
1370 wkun 1370 wkun
1371 (keyFlags wkun uids) 1371 (keyFlags wkun uids)
1372 wk 1372 wk
1373 torkey 1373 torkey
1374 toruid = head ps 1374 toruid = head ps
1375 in if toruid `elem` uids then uids else uids ++ ps 1375 in if toruid `elem` uids then uids else uids ++ ps
1376 if not (null pks) 1376 if not (null pks)
1377 then existingKey (prepk,pks) remainder wkun wk parsedkey (key_usage cmd) pre uids' subkeys (output cmd) grip 1377 then existingKey (prepk,pks) remainder wkun wk parsedkey (key_usage cmd) pre uids' subkeys (output cmd) grip
1378 else newKey wkun wk parsedkey (key_usage cmd) pre uids' subkeys (output cmd) grip 1378 else newKey wkun wk parsedkey (key_usage cmd) pre uids' subkeys (output cmd) grip
1379 1379
@@ -1402,8 +1402,8 @@ existingKey (prepk,pks) remainder wkun wk parsedkey tag pre uids subkeys output_
1402 (mysigs,notmines) = partition (endsWith grip . maybe "%bad%" id . signature_issuer) 1402 (mysigs,notmines) = partition (endsWith grip . maybe "%bad%" id . signature_issuer)
1403 trailsigs 1403 trailsigs
1404 endsWith big small = drop (length big - length small) big == small 1404 endsWith big small = drop (length big - length small) big == small
1405 vs = map (\sig -> 1405 vs = map (\sig ->
1406 (sig, map (verify (Message [wk])) 1406 (sig, map (verify (Message [wk]))
1407 (signatures $ Message [wk,pk,sig]))) 1407 (signatures $ Message [wk,pk,sig])))
1408 mysigs 1408 mysigs
1409 (verified,unverified) = partition (not . null . snd) vs 1409 (verified,unverified) = partition (not . null . snd) vs
@@ -1437,7 +1437,7 @@ existingKey (prepk,pks) remainder wkun wk parsedkey tag pre uids subkeys output_
1437 (es,qs) = partition isExpiration ps 1437 (es,qs) = partition isExpiration ps
1438 stamp = listToMaybe . sortBy (comparing Down) $ 1438 stamp = listToMaybe . sortBy (comparing Down) $
1439 map unwrap cs where unwrap (SignatureCreationTimePacket x) = x 1439 map unwrap cs where unwrap (SignatureCreationTimePacket x) = x
1440 exp = listToMaybe $ sort $ 1440 exp = listToMaybe $ sort $
1441 map unwrap es where unwrap (SignatureExpirationTimePacket x) = x 1441 map unwrap es where unwrap (SignatureExpirationTimePacket x) = x
1442 expires = liftA2 (+) stamp exp 1442 expires = liftA2 (+) stamp exp
1443 if fmap ( (< timestamp) . fromIntegral) expires == Just True then do 1443 if fmap ( (< timestamp) . fromIntegral) expires == Just True then do
@@ -1463,15 +1463,15 @@ existingKey (prepk,pks) remainder wkun wk parsedkey tag pre uids subkeys output_
1463 sig' = sig { hashed_subpackets = times ++ [notation] ++ qs } 1463 sig' = sig { hashed_subpackets = times ++ [notation] ++ qs }
1464 1464
1465 -- noop let sec' = pre ++ [wk] ++ uids ++ subkeys 1465 -- noop let sec' = pre ++ [wk] ++ uids ++ subkeys
1466 sec' = pre 1466 sec' = pre
1467 ++ [wk] 1467 ++ [wk]
1468 ++ uids 1468 ++ uids
1469 ++ prepk 1469 ++ prepk
1470 ++ [pk] 1470 ++ [pk]
1471 ++ signatures_over new_sig 1471 ++ signatures_over new_sig
1472 ++ map fst vs 1472 ++ map fst vs
1473 ++ map fst unverified 1473 ++ map fst unverified
1474 ++ notmines 1474 ++ notmines
1475 ++ trail' 1475 ++ trail'
1476 ++ remainder 1476 ++ remainder
1477 putStrLn $ "Adding usage@="++tag 1477 putStrLn $ "Adding usage@="++tag
@@ -1505,8 +1505,8 @@ newKey wkun wk parsedkey tag pre uids subkeys output_file grip = do
1505 timestamp 1505 timestamp
1506 (g::SystemRandom) 1506 (g::SystemRandom)
1507 1507
1508 hashed0 = 1508 hashed0 =
1509 [ KeyFlagsPacket 1509 [ KeyFlagsPacket
1510 { certify_keys = False 1510 { certify_keys = False
1511 , sign_data = False 1511 , sign_data = False
1512 , encrypt_communication = False 1512 , encrypt_communication = False
@@ -1527,9 +1527,9 @@ newKey wkun wk parsedkey tag pre uids subkeys output_file grip = do
1527 back_sig = fst $ sign (Message parsedkey) 1527 back_sig = fst $ sign (Message parsedkey)
1528 (SubkeySignature wk 1528 (SubkeySignature wk
1529 (head parsedkey) 1529 (head parsedkey)
1530 (sigpackets 0x19 1530 (sigpackets 0x19
1531 hashed0 1531 hashed0
1532 [IssuerPacket subgrip])) 1532 [IssuerPacket subgrip]))
1533 SHA1 1533 SHA1
1534 subgrip 1534 subgrip
1535 timestamp 1535 timestamp
@@ -1554,10 +1554,10 @@ newKey wkun wk parsedkey tag pre uids subkeys output_file grip = do
1554 -} 1554 -}
1555 1555
1556 return () 1556 return ()
1557
1558 1557
1559 1558
1560groupBindings pub = 1559
1560groupBindings pub =
1561 let (sigs,bindings) = getBindings pub 1561 let (sigs,bindings) = getBindings pub
1562 bindings' = accBindings bindings 1562 bindings' = accBindings bindings
1563 code (c,(m,s),_,_,_) = (fingerprint_material m,-c) 1563 code (c,(m,s),_,_,_) = (fingerprint_material m,-c)
@@ -1573,7 +1573,7 @@ isTopKey p@(PublicKeyPacket {}) | not (is_subkey p) = True
1573isTopKey _ = False 1573isTopKey _ = False
1574 1574
1575seek_key :: KeySpec -> [Packet] -> ([Packet],[Packet]) 1575seek_key :: KeySpec -> [Packet] -> ([Packet],[Packet])
1576seek_key (KeyGrip grip) sec = (pre, subs) 1576seek_key (KeyGrip grip) sec = (pre, subs)
1577 where 1577 where
1578 (pre,subs) = break pred sec 1578 (pre,subs) = break pred sec
1579 pred p@(SecretKeyPacket {}) = matchpr grip p == grip 1579 pred p@(SecretKeyPacket {}) = matchpr grip p == grip
@@ -1581,24 +1581,24 @@ seek_key (KeyGrip grip) sec = (pre, subs)
1581 pred _ = False 1581 pred _ = False
1582 1582
1583seek_key (KeyTag key tag) ps = if null bs 1583seek_key (KeyTag key tag) ps = if null bs
1584 then (ps,[]) 1584 then (ps,[])
1585 else if null qs 1585 else if null qs
1586 then let (as',bs') = seek_key (KeyTag key tag) (tail bs) 1586 then let (as',bs') = seek_key (KeyTag key tag) (tail bs)
1587 in (as ++ (head bs:as'), bs') 1587 in (as ++ (head bs:as'), bs')
1588 else (reverse (tail qs), head qs : reverse rs ++ bs) 1588 else (reverse (tail qs), head qs : reverse rs ++ bs)
1589 where 1589 where
1590 (as,bs) = break (\p -> isSignaturePacket p 1590 (as,bs) = break (\p -> isSignaturePacket p
1591 && has_tag tag p 1591 && has_tag tag p
1592 && isJust (signature_issuer p) 1592 && isJust (signature_issuer p)
1593 && matchpr (fromJust $ signature_issuer p) key == fromJust (signature_issuer p) ) 1593 && matchpr (fromJust $ signature_issuer p) key == fromJust (signature_issuer p) )
1594 ps 1594 ps
1595 (rs,qs) = break isKey (reverse as) 1595 (rs,qs) = break isKey (reverse as)
1596 1596
1597 has_tag tag p = tag `elem` mapMaybe usage (hashed_subpackets p) 1597 has_tag tag p = tag `elem` mapMaybe usage (hashed_subpackets p)
1598 || tag `elem` map usageString (mapMaybe keyflags (hashed_subpackets p)) 1598 || tag `elem` map usageString (mapMaybe keyflags (hashed_subpackets p))
1599 1599
1600seek_key (KeyUidMatch pat) ps = if null bs 1600seek_key (KeyUidMatch pat) ps = if null bs
1601 then (ps,[]) 1601 then (ps,[])
1602 else if null qs 1602 else if null qs
1603 then let (as',bs') = seek_key (KeyUidMatch pat) (tail bs) 1603 then let (as',bs') = seek_key (KeyUidMatch pat) (tail bs)
1604 in (as ++ (head bs:as'), bs') 1604 in (as ++ (head bs:as'), bs')
@@ -1610,7 +1610,7 @@ seek_key (KeyUidMatch pat) ps = if null bs
1610 1610
1611 uidStr (UserIDPacket s) = s 1611 uidStr (UserIDPacket s) = s
1612 uidStr _ = "" 1612 uidStr _ = ""
1613 1613
1614groupTops ps = groupBy (\_ b -> not (isTopKey b)) ps 1614groupTops ps = groupBy (\_ b -> not (isTopKey b)) ps
1615 1615
1616 1616
@@ -1625,7 +1625,7 @@ torsig g topk wkun uid timestamp extras
1625 = sign (Message [wkun]) 1625 = sign (Message [wkun])
1626 (CertificationSignature (secretToPublic topk) 1626 (CertificationSignature (secretToPublic topk)
1627 uid 1627 uid
1628 (sigpackets 0x13 1628 (sigpackets 0x13
1629 subpackets 1629 subpackets
1630 subpackets_unh)) 1630 subpackets_unh))
1631 SHA1 1631 SHA1
@@ -1646,7 +1646,7 @@ torsig g topk wkun uid timestamp extras
1646 -- regex = username ++ "@" ++ hostname 1646 -- regex = username ++ "@" ++ hostname
1647 -- username = "[a-zA-Z0-9.][-a-zA-Z0-9.]*\\$?" :: String 1647 -- username = "[a-zA-Z0-9.][-a-zA-Z0-9.]*\\$?" :: String
1648 hostname = subdomain' pu ++ "\\." ++ topdomain' pu 1648 hostname = subdomain' pu ++ "\\." ++ topdomain' pu
1649 pu = parseUID uidstr where UserIDPacket uidstr = uid 1649 pu = parseUID uidstr where UserIDPacket uidstr = uid
1650 subdomain' = escape . T.unpack . uid_subdomain 1650 subdomain' = escape . T.unpack . uid_subdomain
1651 topdomain' = escape . T.unpack . uid_topdomain 1651 topdomain' = escape . T.unpack . uid_topdomain
1652 escape s = concatMap echar s 1652 escape s = concatMap echar s
@@ -1671,7 +1671,7 @@ sigpackets typ hashed unhashed = return $
1671 SHA1 1671 SHA1
1672 hashed 1672 hashed
1673 unhashed 1673 unhashed
1674 0 -- Word16 -- Left 16 bits of the signed hash value 1674 0 -- Word16 -- Left 16 bits of the signed hash value
1675 [] -- [MPI] 1675 [] -- [MPI]
1676 1676
1677keyFlags wkun uids = keyFlags0 wkun (filter isSignaturePacket uids) 1677keyFlags wkun uids = keyFlags0 wkun (filter isSignaturePacket uids)
@@ -1686,7 +1686,7 @@ keyFlags0 wkun uidsigs = concat
1686 , preferredhash 1686 , preferredhash
1687 , preferredcomp 1687 , preferredcomp
1688 , features ] 1688 , features ]
1689 1689
1690 where 1690 where
1691 subs = concatMap hashed_subpackets uidsigs 1691 subs = concatMap hashed_subpackets uidsigs
1692 keyflags = filterOr isflags subs $ 1692 keyflags = filterOr isflags subs $