diff options
author | joe <joe@jerkface.net> | 2013-12-13 04:03:01 -0500 |
---|---|---|
committer | joe <joe@jerkface.net> | 2013-12-13 04:03:01 -0500 |
commit | 89c2b6b175ecf805fdd9e823726b8eec4774c78b (patch) | |
tree | 6e04e0cfa171c0ff670f8080e6167fdb5dba57c8 | |
parent | 8c56ffda40444e777d5442135dd75b6858ff0843 (diff) |
Adapted to IO-based inteface pgpSign to reduce dependency on
random number generator interface.
-rw-r--r-- | kiki.hs | 182 |
1 files changed, 97 insertions, 85 deletions
@@ -23,7 +23,8 @@ import Control.Monad | |||
23 | import qualified Text.Show.Pretty as PP | 23 | import qualified Text.Show.Pretty as PP |
24 | import Text.PrettyPrint as PP hiding ((<>)) | 24 | import Text.PrettyPrint as PP hiding ((<>)) |
25 | import Data.List | 25 | import Data.List |
26 | import Data.OpenPGP.CryptoAPI (verify,fingerprint,sign,decryptSecretKey) | 26 | -- import Data.OpenPGP.CryptoAPI (verify,fingerprint,sign,decryptSecretKey) |
27 | import OpenPGP | ||
27 | import Data.Ord | 28 | import Data.Ord |
28 | import Data.Maybe | 29 | import Data.Maybe |
29 | import Data.Bits | 30 | import Data.Bits |
@@ -34,7 +35,7 @@ import qualified Codec.Binary.Base64 as Base64 | |||
34 | import qualified Crypto.Hash.SHA1 as SHA1 | 35 | import qualified Crypto.Hash.SHA1 as SHA1 |
35 | import Data.Char (toLower) | 36 | import Data.Char (toLower) |
36 | import qualified Crypto.PubKey.RSA as RSA | 37 | import qualified Crypto.PubKey.RSA as RSA |
37 | import Crypto.Random (newGenIO,SystemRandom) | 38 | -- import Crypto.Random (newGenIO,SystemRandom) |
38 | import Data.ASN1.Types | 39 | import Data.ASN1.Types |
39 | import Data.ASN1.Encoding | 40 | import Data.ASN1.Encoding |
40 | import Data.ASN1.BinaryEncoding | 41 | import Data.ASN1.BinaryEncoding |
@@ -55,6 +56,7 @@ import ControlMaybe | |||
55 | import Data.Char | 56 | import Data.Char |
56 | import Control.Arrow (first,second) | 57 | import Control.Arrow (first,second) |
57 | import Data.Traversable hiding (mapM,forM) | 58 | import Data.Traversable hiding (mapM,forM) |
59 | import qualified Data.Traversable as Traversable (mapM,forM) | ||
58 | import System.Console.CmdArgs | 60 | import System.Console.CmdArgs |
59 | -- import System.Posix.Time | 61 | -- import System.Posix.Time |
60 | import Data.Time.Clock.POSIX | 62 | import 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 | ||
1533 | signature_time ov = case if null cs then ds else cs of | 1531 | signature_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 | {- | ||
2207 | existingKey (prepk,pks) remainder wkun wk parsedkey tag pre uids subkeys output_file grip = do | 2220 | existingKey (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 | |||
2447 | groupTops ps = groupBy (\_ b -> not (isTopKey b)) ps | 2461 | groupTops ps = groupBy (\_ b -> not (isTopKey b)) ps |
2448 | 2462 | ||
2449 | 2463 | ||
2464 | {- | ||
2450 | makeTorUID g timestamp wkun keyflags topkey torkey = uid:signatures_over sig | 2465 | makeTorUID 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 | ||
2457 | torsig g topk wkun uid timestamp extras | 2473 | -- torsig g topk wkun uid timestamp extras = todo |
2458 | = sign (Message [wkun]) | 2474 | torSigOver 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 |