summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2013-12-13 04:03:01 -0500
committerjoe <joe@jerkface.net>2013-12-13 04:03:01 -0500
commit89c2b6b175ecf805fdd9e823726b8eec4774c78b (patch)
tree6e04e0cfa171c0ff670f8080e6167fdb5dba57c8
parent8c56ffda40444e777d5442135dd75b6858ff0843 (diff)
Adapted to IO-based inteface pgpSign to reduce dependency on
random number generator interface.
-rw-r--r--kiki.hs182
1 files changed, 97 insertions, 85 deletions
diff --git a/kiki.hs b/kiki.hs
index d468774..bc8b61b 100644
--- a/kiki.hs
+++ b/kiki.hs
@@ -23,7 +23,8 @@ import Control.Monad
23import qualified Text.Show.Pretty as PP 23import qualified Text.Show.Pretty as PP
24import Text.PrettyPrint as PP hiding ((<>)) 24import Text.PrettyPrint as PP hiding ((<>))
25import Data.List 25import Data.List
26import Data.OpenPGP.CryptoAPI (verify,fingerprint,sign,decryptSecretKey) 26-- import Data.OpenPGP.CryptoAPI (verify,fingerprint,sign,decryptSecretKey)
27import OpenPGP
27import Data.Ord 28import Data.Ord
28import Data.Maybe 29import Data.Maybe
29import Data.Bits 30import Data.Bits
@@ -34,7 +35,7 @@ import qualified Codec.Binary.Base64 as Base64
34import qualified Crypto.Hash.SHA1 as SHA1 35import qualified Crypto.Hash.SHA1 as SHA1
35import Data.Char (toLower) 36import Data.Char (toLower)
36import qualified Crypto.PubKey.RSA as RSA 37import qualified Crypto.PubKey.RSA as RSA
37import Crypto.Random (newGenIO,SystemRandom) 38-- import Crypto.Random (newGenIO,SystemRandom)
38import Data.ASN1.Types 39import Data.ASN1.Types
39import Data.ASN1.Encoding 40import Data.ASN1.Encoding
40import Data.ASN1.BinaryEncoding 41import Data.ASN1.BinaryEncoding
@@ -55,6 +56,7 @@ import ControlMaybe
55import Data.Char 56import Data.Char
56import Control.Arrow (first,second) 57import Control.Arrow (first,second)
57import Data.Traversable hiding (mapM,forM) 58import Data.Traversable hiding (mapM,forM)
59import qualified Data.Traversable as Traversable (mapM,forM)
58import System.Console.CmdArgs 60import System.Console.CmdArgs
59-- import System.Posix.Time 61-- import System.Posix.Time
60import Data.Time.Clock.POSIX 62import Data.Time.Clock.POSIX
@@ -1406,11 +1408,14 @@ doImport doDecrypt db (fname,subspec,ms,_) = do
1406 flip (flip maybe $ const $ return uids) has_torid $ do 1408 flip (flip maybe $ const $ return uids) has_torid $ do
1407 wkun <- doDecrypt (packet top) 1409 wkun <- doDecrypt (packet top)
1408 flip (maybe $ error "Bad passphrase?") wkun $ \wkun -> do 1410 flip (maybe $ error "Bad passphrase?") wkun $ \wkun -> do
1409 g <- newGenIO :: IO SystemRandom
1410 timestamp <- now
1411 let keyflags = keyFlags wkun (map packet $ flattenAllUids fname True uids) 1411 let keyflags = keyFlags wkun (map packet $ flattenAllUids fname True uids)
1412 uid = UserIDPacket idstr 1412 uid = UserIDPacket idstr
1413 sig_ov = fst $ torsig g (packet top) wkun uid timestamp keyflags 1413 -- sig_ov = fst $ torsig g (packet top) wkun uid timestamp keyflags
1414 tor_ov = torSigOver (packet top) wkun uid keyflags
1415 sig_ov <- pgpSign (Message [wkun])
1416 tor_ov
1417 SHA1
1418 (fingerprint wkun)
1414 flip (maybe $ warn "Failed to make signature" >> return uids) 1419 flip (maybe $ warn "Failed to make signature" >> return uids)
1415 (listToMaybe $ signatures_over sig_ov) 1420 (listToMaybe $ signatures_over sig_ov)
1416 $ \sig -> do 1421 $ \sig -> do
@@ -1441,8 +1446,6 @@ makeSig doDecrypt top fname subkey_p tag mbsig = do
1441 let wk = packet top 1446 let wk = packet top
1442 wkun <- doDecrypt wk 1447 wkun <- doDecrypt wk
1443 flip (maybe $ error "Bad passphrase?") wkun $ \wkun -> do 1448 flip (maybe $ error "Bad passphrase?") wkun $ \wkun -> do
1444 g <- newGenIO :: IO SystemRandom
1445 timestamp <- now
1446 let grip = fingerprint wk 1449 let grip = fingerprint wk
1447 addOrigin new_sig = do 1450 addOrigin new_sig = do
1448 flip (maybe $ error "Failed to make signature.") 1451 flip (maybe $ error "Failed to make signature.")
@@ -1450,21 +1453,8 @@ makeSig doDecrypt top fname subkey_p tag mbsig = do
1450 $ \new_sig -> do 1453 $ \new_sig -> do
1451 let mp' = MappedPacket new_sig (Map.singleton fname (origin new_sig (-1))) 1454 let mp' = MappedPacket new_sig (Map.singleton fname (origin new_sig (-1)))
1452 return (mp', Map.empty) 1455 return (mp', Map.empty)
1453 newSig = do 1456 parsedkey = [packet $ subkey_p]
1454 let parsedkey = [packet $ subkey_p] 1457 hashed0 =
1455 new_sig = fst $ sign (Message [wkun])
1456 (SubkeySignature wk
1457 (head parsedkey)
1458 (sigpackets 0x18
1459 hashed0
1460 ( IssuerPacket (fingerprint wk)
1461 : map EmbeddedSignaturePacket (signatures_over back_sig))))
1462 SHA1
1463 grip
1464 timestamp
1465 (g::SystemRandom)
1466
1467 hashed0 =
1468 [ KeyFlagsPacket 1458 [ KeyFlagsPacket
1469 { certify_keys = False 1459 { certify_keys = False
1470 , sign_data = False 1460 , sign_data = False
@@ -1478,22 +1468,31 @@ makeSig doDecrypt top fname subkey_p tag mbsig = do
1478 , notation_name = "usage@" 1468 , notation_name = "usage@"
1479 , notation_value = tag 1469 , notation_value = tag
1480 } 1470 }
1481 , SignatureCreationTimePacket (fromIntegral timestamp) 1471 -- implicitly added:
1472 -- , SignatureCreationTimePacket (fromIntegral timestamp)
1482 ] 1473 ]
1483 1474 subgrip = fingerprint (head parsedkey)
1484 subgrip = fingerprint (head parsedkey) 1475
1485 1476 back_sig <- pgpSign (Message parsedkey)
1486 back_sig = fst $ sign (Message parsedkey) 1477 (SubkeySignature wk
1487 (SubkeySignature wk 1478 (head parsedkey)
1488 (head parsedkey) 1479 (sigpackets 0x19
1489 (sigpackets 0x19 1480 hashed0
1490 hashed0 1481 [IssuerPacket subgrip]))
1491 [IssuerPacket subgrip])) 1482 SHA1
1492 SHA1 1483 subgrip
1493 subgrip 1484 let unhashed0 = ( IssuerPacket (fingerprint wk)
1494 timestamp 1485 : map EmbeddedSignaturePacket (signatures_over back_sig))
1495 (g::SystemRandom) 1486
1496 addOrigin new_sig 1487 new_sig <- pgpSign (Message [wkun])
1488 (SubkeySignature wk
1489 (head parsedkey)
1490 (sigpackets 0x18
1491 hashed0
1492 unhashed0))
1493 SHA1
1494 grip
1495 let newSig = addOrigin new_sig
1497 flip (maybe newSig) mbsig $ \(mp,trustmap) -> do 1496 flip (maybe newSig) mbsig $ \(mp,trustmap) -> do
1498 let sig = packet mp 1497 let sig = packet mp
1499 isCreation (SignatureCreationTimePacket {}) = True 1498 isCreation (SignatureCreationTimePacket {}) = True
@@ -1507,19 +1506,12 @@ makeSig doDecrypt top fname subkey_p tag mbsig = do
1507 exp = listToMaybe $ sort $ 1506 exp = listToMaybe $ sort $
1508 map unwrap es where unwrap (SignatureExpirationTimePacket x) = x 1507 map unwrap es where unwrap (SignatureExpirationTimePacket x) = x
1509 expires = liftA2 (+) stamp exp 1508 expires = liftA2 (+) stamp exp
1509 timestamp <- now
1510 if fmap ( (< timestamp) . fromIntegral) expires == Just True then do 1510 if fmap ( (< timestamp) . fromIntegral) expires == Just True then do
1511 warn $ "Unable to update expired signature" 1511 warn $ "Unable to update expired signature"
1512 return (mp,trustmap) 1512 return (mp,trustmap)
1513 else do 1513 else do
1514 let new_sig = fst $ sign (Message [wkun]) 1514 let times = (:) (SignatureExpirationTimePacket (fromIntegral timestamp))
1515 (SubkeySignature wk
1516 (packet subkey_p)
1517 [sig'] )
1518 SHA1
1519 (fingerprint wk)
1520 timestamp
1521 (g::SystemRandom)
1522 times = (:) (SignatureExpirationTimePacket (fromIntegral timestamp))
1523 $ maybeToList $ do 1515 $ maybeToList $ do
1524 e <- expires 1516 e <- expires
1525 return $ SignatureExpirationTimePacket (e - fromIntegral timestamp) 1517 return $ SignatureExpirationTimePacket (e - fromIntegral timestamp)
@@ -1528,6 +1520,12 @@ makeSig doDecrypt top fname subkey_p tag mbsig = do
1528 , notation_value = tag 1520 , notation_value = tag
1529 , human_readable = True } 1521 , human_readable = True }
1530 sig' = sig { hashed_subpackets = times ++ [notation] ++ qs } 1522 sig' = sig { hashed_subpackets = times ++ [notation] ++ qs }
1523 new_sig <- pgpSign (Message [wkun])
1524 (SubkeySignature wk
1525 (packet subkey_p)
1526 [sig'] )
1527 SHA1
1528 (fingerprint wk)
1531 addOrigin new_sig 1529 addOrigin new_sig
1532 1530
1533signature_time ov = case if null cs then ds else cs of 1531signature_time ov = case if null cs then ds else cs of
@@ -1765,12 +1763,13 @@ main = do
1765 return $ undata (snd elm) 1763 return $ undata (snd elm)
1766 1764
1767 undata (KeyData p _ _ _) = packet p 1765 undata (KeyData p _ _ _) = packet p
1768 g <- newGenIO 1766 -- g <- newGenIO
1769 stamp <- now 1767 -- stamp <- now
1770 wkun <- flip (maybe $ return Nothing) wk $ \wk -> do 1768 wkun <- flip (maybe $ return Nothing) wk $ \wk -> do
1771 wkun <- decrypt wk 1769 wkun <- decrypt wk
1772 maybe (error $ "Bad passphrase?") (return . Just) wkun 1770 maybe (error $ "Bad passphrase?") (return . Just) wkun
1773 return . snd $ Map.mapAccum (signTorIds stamp wkun keys) g use_db 1771 -- return . snd $ Map.mapAccum (signTorIds stamp wkun keys) g use_db
1772 Traversable.mapM (signTorIds wkun keys) use_db
1774 ret_db <- return $ fmap (const use_db) ret_db 1773 ret_db <- return $ fmap (const use_db) ret_db
1775 1774
1776 flip (maybe $ return ()) ret_db . const $ do 1775 flip (maybe $ return ()) ret_db . const $ do
@@ -1854,28 +1853,25 @@ main = do
1854 where 1853 where
1855 w0:ws = pub 1854 w0:ws = pub
1856 1855
1857 signTorIds timestamp selfkey keys 1856 signTorIds selfkey keys kd@(KeyData k ksigs umap submap) = do
1858 g kd@(KeyData k ksigs umap submap) = (g', KeyData k ksigs umap' submap) 1857 umap' <- Traversable.mapM signIfTor (Map.mapWithKey (,) umap)
1858 return (KeyData k ksigs umap' submap) :: IO KeyData
1859 where 1859 where
1860 _ = g :: SystemRandom
1861 mkey = packet k 1860 mkey = packet k
1862 (g',umap') = Map.mapAccumWithKey signIfTor g umap 1861 signIfTor (str,ps) =
1863 signIfTor g str ps = if isTorID str then {- trace (unlines 1862 if isTorID str
1864 [ "Found tor id: " 1863 then do
1865 ++show (str,fmap fingerprint selfkey) 1864 let uidxs0 = map packet $ flattenUid "" True (str,ps)
1866 , "additional = " ++ intercalate "," (map showPacket additional) 1865 -- addition<- signSelfAuthTorKeys' selfkey g keys grip timestamp mkey uidxs0
1867 ]) -} 1866 additional <- signSelfAuthTorKeys' selfkey keys grip mkey uidxs0
1868 (g',ps') 1867 let ps' = ( map ( (,tmap) . flip MappedPacket om) additional
1869 else (g,ps) 1868 ++ fst ps
1870 where 1869 , Map.union om (snd ps) )
1871 uidxs0 = map packet $ flattenUid "" True (str,ps) 1870 om = Map.singleton "--autosign" (origin p (-1)) where p = UserIDPacket str
1872 om = Map.singleton "--autosign" (origin p (-1)) where p = UserIDPacket str 1871 tmap = Map.empty
1873 tmap = Map.empty 1872 return ps'
1874 ps' = ( map ( (,tmap) . flip MappedPacket om) additional 1873 else return ps
1875 ++ fst ps 1874
1876 , Map.union om (snd ps) )
1877
1878 (uidxs, additional, xs'',g') = signSelfAuthTorKeys' selfkey g keys grip timestamp mkey uidxs0
1879 torbindings = getTorKeys (map packet $ flattenTop "" True kd) 1875 torbindings = getTorKeys (map packet $ flattenTop "" True kd)
1880 isTorID str = and [ uid_topdomain parsed == "onion" 1876 isTorID str = and [ uid_topdomain parsed == "onion"
1881 , uid_realname parsed `elem` ["","Anonymous"] 1877 , uid_realname parsed `elem` ["","Anonymous"]
@@ -1888,6 +1884,7 @@ main = do
1888 subdom = Char8.unpack subdom0 1884 subdom = Char8.unpack subdom0
1889 len = T.length (uid_subdomain parsed) 1885 len = T.length (uid_subdomain parsed)
1890 1886
1887 {-
1891 signSelfAuthTorKeys selfkey g sec grip timestamp xs = ys 1888 signSelfAuthTorKeys selfkey g sec grip timestamp xs = ys
1892 where 1889 where
1893 keys = filter isKey sec 1890 keys = filter isKey sec
@@ -1895,8 +1892,16 @@ main = do
1895 uidxs0 = map snd xs 1892 uidxs0 = map snd xs
1896 (uidxs, additional, xs'',g') = signSelfAuthTorKeys' selfkey g keys grip timestamp mainpubkey uidxs0 1893 (uidxs, additional, xs'',g') = signSelfAuthTorKeys' selfkey g keys grip timestamp mainpubkey uidxs0
1897 ys = uidxs++ additional++xs'' 1894 ys = uidxs++ additional++xs''
1895 -}
1898 1896
1899 signSelfAuthTorKeys' selfkey g keys grip timestamp mainpubkey (uid:xs') = (uid:sigs,additional,xs'',g') 1897 signSelfAuthTorKeys' selfkey keys grip mainpubkey (uid:xs') = do
1898 new_sig <- let wkun = fromJust selfkey
1899 tor_ov = torSigOver mainpubkey wkun uid flgs
1900 in pgpSign (Message [wkun])
1901 tor_ov
1902 SHA1
1903 (fingerprint wkun)
1904 return (additional new_sig) -- (uid:sigs,additional,xs'',g')
1900 where 1905 where
1901 (sigs, xs'') = span isSignaturePacket xs' 1906 (sigs, xs'') = span isSignaturePacket xs'
1902 overs sig = signatures $ Message (keys++[mainpubkey,uid,sig]) 1907 overs sig = signatures $ Message (keys++[mainpubkey,uid,sig])
@@ -1921,7 +1926,7 @@ main = do
1921 . (== keykey whosign) 1926 . (== keykey whosign)
1922 . keykey)) 1927 . keykey))
1923 vs 1928 vs
1924 additional = do 1929 additional new_sig = do
1925 guard $ {- trace (unlines $ [ "selfsigs = "++show (map ((\(_,_,k)->fingerprint k)) selfsigs) 1930 guard $ {- trace (unlines $ [ "selfsigs = "++show (map ((\(_,_,k)->fingerprint k)) selfsigs)
1926 , " for mainkey = "++fingerprint mainpubkey] ) 1931 , " for mainkey = "++fingerprint mainpubkey] )
1927 -} 1932 -}
@@ -1952,7 +1957,14 @@ main = do
1952 flgs = if keykey mainpubkey == keykey (fromJust selfkey) 1957 flgs = if keykey mainpubkey == keykey (fromJust selfkey)
1953 then keyFlags0 mainpubkey (map (\(x,_,_)->x) selfsigs) 1958 then keyFlags0 mainpubkey (map (\(x,_,_)->x) selfsigs)
1954 else [] 1959 else []
1955 (new_sig,g') = torsig g mainpubkey (fromJust selfkey) uid timestamp flgs 1960 -- (new_sig,g') = todo g mainpubkey (fromJust selfkey) uid timestamp flgs
1961 {-
1962 new_sig <- let wkun = fromJust selfkey
1963 in pgpSign (Message [wkun])
1964 tor_ov
1965 SHA1
1966 (fingerprint wkun)
1967 -}
1956 1968
1957 -- ys = uid:sigs++ additional++xs'' 1969 -- ys = uid:sigs++ additional++xs''
1958 1970
@@ -2204,6 +2216,7 @@ isSameKey a b = sort (key apub) == sort (key bpub)
2204 apub = secretToPublic a 2216 apub = secretToPublic a
2205 bpub = secretToPublic b 2217 bpub = secretToPublic b
2206 2218
2219{-
2207existingKey (prepk,pks) remainder wkun wk parsedkey tag pre uids subkeys output_file grip = do 2220existingKey (prepk,pks) remainder wkun wk parsedkey tag pre uids subkeys output_file grip = do
2208 -- putStrLn "Key already present." 2221 -- putStrLn "Key already present."
2209 let pk:trail = pks 2222 let pk:trail = pks
@@ -2353,6 +2366,7 @@ newKey wkun wk parsedkey tag pre uids subkeys output_file grip = do
2353 -} 2366 -}
2354 2367
2355 return () 2368 return ()
2369-}
2356 2370
2357 2371
2358 2372
@@ -2447,27 +2461,25 @@ seek_key (KeyUidMatch pat) ps = if null bs
2447groupTops ps = groupBy (\_ b -> not (isTopKey b)) ps 2461groupTops ps = groupBy (\_ b -> not (isTopKey b)) ps
2448 2462
2449 2463
2464{-
2450makeTorUID g timestamp wkun keyflags topkey torkey = uid:signatures_over sig 2465makeTorUID g timestamp wkun keyflags topkey torkey = uid:signatures_over sig
2451 where 2466 where
2452 torhash sub = maybe "" id $ derToBase32 <$> derRSA sub 2467 torhash sub = maybe "" id $ derToBase32 <$> derRSA sub
2453 s = "Anonymous <root@" ++ take 16 (torhash torkey) ++ ".onion>" 2468 s = "Anonymous <root@" ++ take 16 (torhash torkey) ++ ".onion>"
2454 uid = UserIDPacket s 2469 uid = UserIDPacket s
2455 sig = fst $ torsig g topkey wkun uid timestamp keyflags 2470 sig = fst $ torsig g topkey wkun uid timestamp keyflags
2471-}
2456 2472
2457torsig g topk wkun uid timestamp extras 2473-- torsig g topk wkun uid timestamp extras = todo
2458 = sign (Message [wkun]) 2474torSigOver topk wkun uid extras
2459 (CertificationSignature (secretToPublic topk) 2475 = CertificationSignature (secretToPublic topk)
2460 uid 2476 uid
2461 (sigpackets 0x13 2477 (sigpackets 0x13
2462 subpackets 2478 subpackets
2463 subpackets_unh)) 2479 subpackets_unh)
2464 SHA1
2465 (fingerprint wkun) {- (fromJust wkgrip) -}
2466 timestamp
2467 g
2468 where 2480 where
2469 subpackets = [ SignatureCreationTimePacket (fromIntegral timestamp) ] 2481 subpackets = -- implicit: [ SignatureCreationTimePacket (fromIntegral timestamp) ]
2470 ++ tsign 2482 tsign
2471 ++ extras 2483 ++ extras
2472 subpackets_unh = [IssuerPacket (fingerprint wkun)] 2484 subpackets_unh = [IssuerPacket (fingerprint wkun)]
2473 tsign = if keykey wkun == keykey topk 2485 tsign = if keykey wkun == keykey topk