diff options
author | joe <joe@jerkface.net> | 2014-04-14 21:35:25 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2014-04-14 21:35:25 -0400 |
commit | db0e17c179453e22cbadfb8b514d2e7efede170d (patch) | |
tree | 04d852a98afe43aa7d73bb0a2a89ebdc5d44c198 /kiki.hs | |
parent | 294cda407d82c6b98b63ac21fea3b937ed1c4bb5 (diff) |
moved more code from kiki.hs to KeyRing.hs for buildKeyDB
Diffstat (limited to 'kiki.hs')
-rw-r--r-- | kiki.hs | 396 |
1 files changed, 0 insertions, 396 deletions
@@ -108,61 +108,6 @@ unprefix c spec = if null (snd p) then swap p else (fst p, tail (snd p)) | |||
108 | where p = break (==c) spec | 108 | where p = break (==c) spec |
109 | 109 | ||
110 | 110 | ||
111 | data RSAPublicKey = RSAKey MPI MPI deriving (Eq,Show) | ||
112 | data PKCS8_RSAPublicKey = RSAKey8 MPI MPI deriving Show | ||
113 | |||
114 | pkcs8 (RSAKey n e) = RSAKey8 n e | ||
115 | |||
116 | instance ASN1Object RSAPublicKey where | ||
117 | -- PKCS #1 RSA Public Key | ||
118 | toASN1 (RSAKey (MPI n) (MPI e)) | ||
119 | = \xs -> Start Sequence | ||
120 | : IntVal n | ||
121 | : IntVal e | ||
122 | : End Sequence | ||
123 | : xs | ||
124 | fromASN1 _ = | ||
125 | Left "fromASN1: RSAPublicKey: unexpected format" | ||
126 | |||
127 | instance ASN1Object PKCS8_RSAPublicKey where | ||
128 | |||
129 | -- PKCS #8 Public key data | ||
130 | toASN1 (RSAKey8 (MPI n) (MPI e)) | ||
131 | = \xs -> Start Sequence | ||
132 | : Start Sequence | ||
133 | : OID [1,2,840,113549,1,1,1] | ||
134 | : End Sequence | ||
135 | : BitString (toBitArray bs 0) | ||
136 | : End Sequence | ||
137 | : xs | ||
138 | where | ||
139 | pubkey = Start Sequence : IntVal n : IntVal e : End Sequence : [] | ||
140 | bs = encodeASN1' DER pubkey | ||
141 | |||
142 | fromASN1 (Start Sequence:IntVal modulus:IntVal pubexp:End Sequence:xs) = | ||
143 | Right (RSAKey8 (MPI modulus) (MPI pubexp) , xs) | ||
144 | fromASN1 (Start Sequence:Start Sequence:OID [1,2,840,113549,1,1,1]:End Sequence:BitString b:End Sequence:xs) = | ||
145 | case decodeASN1' DER bs of | ||
146 | Right as -> fromASN1 as | ||
147 | Left e -> Left ("fromASN1: RSAPublicKey: "++show e) | ||
148 | where | ||
149 | BitArray _ bs = b | ||
150 | |||
151 | fromASN1 _ = | ||
152 | Left "fromASN1: RSAPublicKey: unexpected format" | ||
153 | |||
154 | data RSAPrivateKey = RSAPrivateKey | ||
155 | { rsaN :: MPI | ||
156 | , rsaE :: MPI | ||
157 | , rsaD :: MPI | ||
158 | , rsaP :: MPI | ||
159 | , rsaQ :: MPI | ||
160 | , rsaDmodP1 :: MPI | ||
161 | , rsaDmodQminus1 :: MPI | ||
162 | , rsaCoefficient :: MPI | ||
163 | } | ||
164 | deriving Show | ||
165 | |||
166 | {- | 111 | {- |
167 | RSAPrivateKey ::= SEQUENCE { | 112 | RSAPrivateKey ::= SEQUENCE { |
168 | version Version, | 113 | version Version, |
@@ -240,21 +185,6 @@ decode_sshrsa bs = do | |||
240 | return rsakey | 185 | return rsakey |
241 | 186 | ||
242 | 187 | ||
243 | rsaKeyFromPacket :: Packet -> Maybe RSAPublicKey | ||
244 | rsaKeyFromPacket p@(PublicKeyPacket {}) = do | ||
245 | n <- lookup 'n' $ key p | ||
246 | e <- lookup 'e' $ key p | ||
247 | return $ RSAKey n e | ||
248 | rsaKeyFromPacket p@(SecretKeyPacket {}) = do | ||
249 | n <- lookup 'n' $ key p | ||
250 | e <- lookup 'e' $ key p | ||
251 | return $ RSAKey n e | ||
252 | rsaKeyFromPacket _ = Nothing | ||
253 | |||
254 | derRSA rsa = do | ||
255 | k <- rsaKeyFromPacket rsa | ||
256 | return $ encodeASN1 DER (toASN1 k []) | ||
257 | |||
258 | rsaPrivateKeyFromPacket :: Packet -> Maybe RSAPrivateKey | 188 | rsaPrivateKeyFromPacket :: Packet -> Maybe RSAPrivateKey |
259 | rsaPrivateKeyFromPacket pkt@(SecretKeyPacket {}) = do | 189 | rsaPrivateKeyFromPacket pkt@(SecretKeyPacket {}) = do |
260 | -- public fields... | 190 | -- public fields... |
@@ -295,20 +225,6 @@ getPackets = do | |||
295 | -} | 225 | -} |
296 | 226 | ||
297 | 227 | ||
298 | secretToPublic pkt@(SecretKeyPacket {}) = | ||
299 | PublicKeyPacket { version = version pkt | ||
300 | , timestamp = timestamp pkt | ||
301 | , key_algorithm = key_algorithm pkt | ||
302 | -- , ecc_curve = ecc_curve pkt | ||
303 | , key = let seckey = key pkt | ||
304 | pubs = public_key_fields (key_algorithm pkt) | ||
305 | in filter (\(k,v) -> k `elem` pubs) seckey | ||
306 | , is_subkey = is_subkey pkt | ||
307 | , v3_days_of_validity = Nothing | ||
308 | } | ||
309 | secretToPublic pkt = pkt | ||
310 | |||
311 | |||
312 | extractPEM typ pem = dta | 228 | extractPEM typ pem = dta |
313 | where | 229 | where |
314 | dta = case ys of | 230 | dta = case ys of |
@@ -446,38 +362,6 @@ accBindings bs = as | |||
446 | = (ac .|. bc,p,akind++bkind,ahashed++bhashed,aclaimaints++bclaimaints) | 362 | = (ac .|. bc,p,akind++bkind,ahashed++bhashed,aclaimaints++bclaimaints) |
447 | 363 | ||
448 | 364 | ||
449 | data UserIDRecord = UserIDRecord { | ||
450 | uid_full :: String, | ||
451 | uid_realname :: T.Text, | ||
452 | uid_user :: T.Text, | ||
453 | uid_subdomain :: T.Text, | ||
454 | uid_topdomain :: T.Text | ||
455 | } | ||
456 | deriving Show | ||
457 | |||
458 | isBracket '<' = True | ||
459 | isBracket '>' = True | ||
460 | isBracket _ = False | ||
461 | |||
462 | parseUID str = UserIDRecord { | ||
463 | uid_full = str, | ||
464 | uid_realname = realname, | ||
465 | uid_user = user, | ||
466 | uid_subdomain = subdomain, | ||
467 | uid_topdomain = topdomain | ||
468 | } | ||
469 | where | ||
470 | text = T.pack str | ||
471 | (T.strip-> realname, T.dropAround isBracket-> email) | ||
472 | = T.break (=='<') text | ||
473 | (user, T.drop 1-> hostname) = T.break (=='@') email | ||
474 | ( T.reverse -> topdomain, | ||
475 | T.reverse . T.drop 1 -> subdomain) | ||
476 | = T.break (=='.') . T.reverse $ hostname | ||
477 | |||
478 | |||
479 | derToBase32 = map toLower . Base32.encode . S.unpack . SHA1.hashlazy | ||
480 | |||
481 | fpmatch grip key = | 365 | fpmatch grip key = |
482 | (==) Nothing | 366 | (==) Nothing |
483 | (fmap (backend (fingerprint key)) grip >>= guard . not) | 367 | (fmap (backend (fingerprint key)) grip >>= guard . not) |
@@ -882,8 +766,6 @@ is40digitHex xs = ys == xs && length ys==40 | |||
882 | | 'a' <= c && c <= 'f' = True | 766 | | 'a' <= c && c <= 'f' = True |
883 | ishex c = False | 767 | ishex c = False |
884 | 768 | ||
885 | torhash key = maybe "" id $ derToBase32 <$> derRSA key | ||
886 | |||
887 | flattenKeys :: Bool -> KeyDB -> Message | 769 | flattenKeys :: Bool -> KeyDB -> Message |
888 | flattenKeys isPublic db = Message $ concatMap (map packet . flattenTop "" isPublic . snd) (prefilter . Map.assocs $ db) | 770 | flattenKeys isPublic db = Message $ concatMap (map packet . flattenTop "" isPublic . snd) (prefilter . Map.assocs $ db) |
889 | where | 771 | where |
@@ -897,22 +779,12 @@ flattenKeys isPublic db = Message $ concatMap (map packet . flattenTop "" isPubl | |||
897 | isSecret _ = False | 779 | isSecret _ = False |
898 | 780 | ||
899 | 781 | ||
900 | concatSort fname getp f = concat . sortByHint fname getp . map f | ||
901 | |||
902 | flattenTop :: FilePath -> Bool -> KeyData -> [MappedPacket] | 782 | flattenTop :: FilePath -> Bool -> KeyData -> [MappedPacket] |
903 | flattenTop fname ispub (KeyData key sigs uids subkeys) = | 783 | flattenTop fname ispub (KeyData key sigs uids subkeys) = |
904 | unk ispub key : | 784 | unk ispub key : |
905 | ( flattenAllUids fname ispub uids | 785 | ( flattenAllUids fname ispub uids |
906 | ++ concatSort fname head (flattenSub fname ispub) (Map.elems subkeys)) | 786 | ++ concatSort fname head (flattenSub fname ispub) (Map.elems subkeys)) |
907 | 787 | ||
908 | flattenAllUids :: FilePath -> Bool -> Map.Map String ([SigAndTrust],OriginMap) -> [MappedPacket] | ||
909 | flattenAllUids fname ispub uids = | ||
910 | concatSort fname head (flattenUid fname ispub) (Map.assocs uids) | ||
911 | |||
912 | flattenUid :: FilePath -> Bool -> (String,([SigAndTrust],OriginMap)) -> [MappedPacket] | ||
913 | flattenUid fname ispub (str,(sigs,om)) = | ||
914 | (mappedPacket "" $ UserIDPacket str) {locations=om} : concatSort fname head (unsig fname ispub) sigs | ||
915 | |||
916 | flattenSub :: FilePath -> Bool -> SubKey -> [MappedPacket] | 788 | flattenSub :: FilePath -> Bool -> SubKey -> [MappedPacket] |
917 | flattenSub fname ispub (SubKey key sigs) = unk ispub key: concatSort fname head (unsig fname ispub) sigs | 789 | flattenSub fname ispub (SubKey key sigs) = unk ispub key: concatSort fname head (unsig fname ispub) sigs |
918 | 790 | ||
@@ -920,14 +792,6 @@ unk :: Bool -> MappedPacket -> MappedPacket | |||
920 | unk isPublic = if isPublic then toPacket secretToPublic else id | 792 | unk isPublic = if isPublic then toPacket secretToPublic else id |
921 | where toPacket f mp@(MappedPacket {packet=p}) = mp {packet=(f p)} | 793 | where toPacket f mp@(MappedPacket {packet=p}) = mp {packet=(f p)} |
922 | 794 | ||
923 | unsig :: FilePath -> Bool -> SigAndTrust -> [MappedPacket] | ||
924 | unsig fname isPublic (sig,trustmap) = | ||
925 | [sig]++ map (asMapped (-1)) ( take 1 . Map.elems $ Map.filterWithKey f trustmap) | ||
926 | where | ||
927 | f n _ = n==fname -- && trace ("fname=n="++show n) True | ||
928 | asMapped n p = let m = mappedPacket fname p | ||
929 | in m { locations = fmap (\x->x {originalNum=n}) (locations m) } | ||
930 | |||
931 | ifSecret (SecretKeyPacket {}) t f = t | 795 | ifSecret (SecretKeyPacket {}) t f = t |
932 | ifSecret _ t f = f | 796 | ifSecret _ t f = f |
933 | 797 | ||
@@ -940,11 +804,6 @@ showPacket p | isKey p = (if is_subkey p | |||
940 | | otherwise = showPacket0 p | 804 | | otherwise = showPacket0 p |
941 | showPacket0 p = concat . take 1 $ words (show p) | 805 | showPacket0 p = concat . take 1 $ words (show p) |
942 | 806 | ||
943 | sortByHint fname f = sortBy (comparing gethint) | ||
944 | where | ||
945 | gethint = maybe defnum originalNum . Map.lookup fname . locations . f | ||
946 | defnum = -1 | ||
947 | |||
948 | keyMappedPacket (KeyData k _ _ _) = k | 807 | keyMappedPacket (KeyData k _ _ _) = k |
949 | 808 | ||
950 | writeOutKeyrings :: Map.Map FilePath t -> KeyDB -> IO () | 809 | writeOutKeyrings :: Map.Map FilePath t -> KeyDB -> IO () |
@@ -1160,15 +1019,6 @@ parseSpec grip spec = (topspec,subspec) | |||
1160 | "" | top=="" && is40digitHex sub -> Nothing | 1019 | "" | top=="" && is40digitHex sub -> Nothing |
1161 | "" -> listToMaybe sub >> Just sub | 1020 | "" -> listToMaybe sub >> Just sub |
1162 | 1021 | ||
1163 | splitAtMinBy comp xs = minimumBy comp' xxs | ||
1164 | where | ||
1165 | xxs = zip (inits xs) (tails xs) | ||
1166 | comp' (_,as) (_,bs) = compM (listToMaybe as) (listToMaybe bs) | ||
1167 | compM (Just a) (Just b) = comp a b | ||
1168 | compM Nothing mb = GT | ||
1169 | compM _ _ = LT | ||
1170 | |||
1171 | |||
1172 | -- | systemEnv | 1022 | -- | systemEnv |
1173 | -- This is like System.Process.system except that it lets you set | 1023 | -- This is like System.Process.system except that it lets you set |
1174 | -- some environment variables. | 1024 | -- some environment variables. |
@@ -1239,34 +1089,6 @@ doExport doDecrypt (db,use_db) (fname,subspec,ms,cmd) = | |||
1239 | writeKeyToFile False "PEM" fname pun | 1089 | writeKeyToFile False "PEM" fname pun |
1240 | return (db,use_db) | 1090 | return (db,use_db) |
1241 | 1091 | ||
1242 | findTag tag wk subkey subsigs = (xs',minsig,ys') | ||
1243 | where | ||
1244 | vs = map (\sig -> | ||
1245 | (sig, do | ||
1246 | sig <- Just (packet . fst $ sig) | ||
1247 | guard (isSignaturePacket sig) | ||
1248 | guard $ flip isSuffixOf | ||
1249 | (fingerprint wk) | ||
1250 | . maybe "%bad%" id | ||
1251 | . signature_issuer | ||
1252 | $ sig | ||
1253 | listToMaybe $ | ||
1254 | map (signature_time . verify (Message [wk])) | ||
1255 | (signatures $ Message [wk,subkey,sig]))) | ||
1256 | subsigs | ||
1257 | (xs,ys) = splitAtMinBy (comparing (Down . snd)) vs | ||
1258 | xs' = map fst xs | ||
1259 | ys' = map fst $ if isNothing minsig then ys else drop 1 ys | ||
1260 | minsig = do | ||
1261 | (sig,ov) <- listToMaybe ys | ||
1262 | ov | ||
1263 | let hs = filter (\p->isNotation p && notation_name p=="usage@") | ||
1264 | (hashed_subpackets . packet . fst $ sig) | ||
1265 | ks = map notation_value hs | ||
1266 | isNotation (NotationDataPacket {}) = True | ||
1267 | isNotation _ = False | ||
1268 | return (tag `elem` ks, sig) | ||
1269 | |||
1270 | {- | 1092 | {- |
1271 | applyCurve curve x = x*x*x + x*a + b where (a,b)=(geta curve,getb curve) | 1093 | applyCurve curve x = x*x*x + x*a + b where (a,b)=(geta curve,getb curve) |
1272 | 1094 | ||
@@ -1426,175 +1248,6 @@ doImport doDecrypt db (fname,subspec,ms,_) = do | |||
1426 | $ error "Key specification is ambiguous." | 1248 | $ error "Key specification is ambiguous." |
1427 | doImportG doDecrypt db m0 tag fname key | 1249 | doImportG doDecrypt db m0 tag fname key |
1428 | 1250 | ||
1429 | doImportG doDecrypt db m0 tag fname key = do | ||
1430 | let error s = do | ||
1431 | warn s | ||
1432 | exitFailure | ||
1433 | let kk = head m0 | ||
1434 | Just (KeyData top topsigs uids subs) = Map.lookup kk db | ||
1435 | subkk = keykey key | ||
1436 | (is_new, subkey) = maybe (True, SubKey (mappedPacket fname key) | ||
1437 | []) | ||
1438 | ( (False,) . addOrigin ) | ||
1439 | (Map.lookup subkk subs) | ||
1440 | where | ||
1441 | addOrigin (SubKey mp sigs) = | ||
1442 | let mp' = mp | ||
1443 | { locations = Map.insert fname | ||
1444 | (origin (packet mp) (-1)) | ||
1445 | (locations mp) } | ||
1446 | in SubKey mp' sigs | ||
1447 | subs' = Map.insert subkk subkey subs | ||
1448 | |||
1449 | istor = do | ||
1450 | guard (tag == "tor") | ||
1451 | return $ "Anonymous <root@" ++ take 16 (torhash key) ++ ".onion>" | ||
1452 | |||
1453 | uids' <- flip (maybe $ return uids) istor $ \idstr -> do | ||
1454 | let has_torid = do | ||
1455 | -- TODO: check for omitted real name field | ||
1456 | (sigtrusts,om) <- Map.lookup idstr uids | ||
1457 | listToMaybe $ do | ||
1458 | s <- (signatures $ Message (packet top:UserIDPacket idstr:map (packet . fst) sigtrusts)) | ||
1459 | signatures_over $ verify (Message [packet top]) s | ||
1460 | flip (flip maybe $ const $ return uids) has_torid $ do | ||
1461 | wkun <- doDecrypt (packet top) | ||
1462 | flip (maybe $ error "Bad passphrase?") wkun $ \wkun -> do | ||
1463 | let keyflags = keyFlags wkun (map packet $ flattenAllUids fname True uids) | ||
1464 | uid = UserIDPacket idstr | ||
1465 | -- sig_ov = fst $ torsig g (packet top) wkun uid timestamp keyflags | ||
1466 | tor_ov = torSigOver (packet top) wkun uid keyflags | ||
1467 | sig_ov <- pgpSign (Message [wkun]) | ||
1468 | tor_ov | ||
1469 | SHA1 | ||
1470 | (fingerprint wkun) | ||
1471 | flip (maybe $ warn "Failed to make signature" >> return uids) | ||
1472 | (sig_ov >>= listToMaybe . signatures_over) | ||
1473 | $ \sig -> do | ||
1474 | let om = Map.singleton fname (origin sig (-1)) | ||
1475 | trust = Map.empty | ||
1476 | return $ Map.insert idstr ([( (mappedPacket fname sig) {locations=om} | ||
1477 | ,trust)],om) uids | ||
1478 | |||
1479 | let SubKey subkey_p subsigs = subkey | ||
1480 | wk = packet top | ||
1481 | (xs',minsig,ys') = findTag tag wk key subsigs | ||
1482 | doInsert mbsig db = do | ||
1483 | sig' <- makeSig doDecrypt top fname subkey_p tag mbsig | ||
1484 | warn $ fname ++ ": yield SignaturePacket" | ||
1485 | let subs' = Map.insert subkk | ||
1486 | (SubKey subkey_p $ xs'++[sig']++ys') | ||
1487 | subs | ||
1488 | return $ Map.insert kk (KeyData top topsigs uids' subs') db | ||
1489 | when is_new (warn $ fname ++ ": yield SecretKeyPacket "++show (fmap fst minsig,fingerprint key)) | ||
1490 | case minsig of | ||
1491 | Nothing -> doInsert Nothing db -- we need to create a new sig | ||
1492 | Just (True,sig) -> -- we can deduce is_new == False | ||
1493 | -- we may need to add a tor id | ||
1494 | return $ Map.insert kk (KeyData top topsigs uids' subs') db | ||
1495 | Just (False,sig) -> doInsert (Just sig) db -- We have a sig, but is missing usage@ tag | ||
1496 | |||
1497 | |||
1498 | makeSig doDecrypt top fname subkey_p tag mbsig = do | ||
1499 | let wk = packet top | ||
1500 | wkun <- doDecrypt wk | ||
1501 | flip (maybe $ error "Bad passphrase?") wkun $ \wkun -> do | ||
1502 | let grip = fingerprint wk | ||
1503 | addOrigin new_sig = do | ||
1504 | flip (maybe $ error "Failed to make signature.") | ||
1505 | (new_sig >>= listToMaybe . signatures_over) | ||
1506 | $ \new_sig -> do | ||
1507 | let mp' = mappedPacket fname new_sig | ||
1508 | return (mp', Map.empty) | ||
1509 | parsedkey = [packet $ subkey_p] | ||
1510 | hashed0 = | ||
1511 | [ KeyFlagsPacket | ||
1512 | { certify_keys = False | ||
1513 | , sign_data = False | ||
1514 | , encrypt_communication = False | ||
1515 | , encrypt_storage = False | ||
1516 | , split_key = False | ||
1517 | , authentication = True | ||
1518 | , group_key = False } | ||
1519 | , NotationDataPacket | ||
1520 | { human_readable = True | ||
1521 | , notation_name = "usage@" | ||
1522 | , notation_value = tag | ||
1523 | } | ||
1524 | -- implicitly added: | ||
1525 | -- , SignatureCreationTimePacket (fromIntegral timestamp) | ||
1526 | ] | ||
1527 | subgrip = fingerprint (head parsedkey) | ||
1528 | |||
1529 | back_sig <- pgpSign (Message parsedkey) | ||
1530 | (SubkeySignature wk | ||
1531 | (head parsedkey) | ||
1532 | (sigpackets 0x19 | ||
1533 | hashed0 | ||
1534 | [IssuerPacket subgrip])) | ||
1535 | (if key_algorithm (head parsedkey)==ECDSA | ||
1536 | then SHA256 | ||
1537 | else SHA1) | ||
1538 | subgrip | ||
1539 | let iss = IssuerPacket (fingerprint wk) | ||
1540 | cons_iss back_sig = iss : map EmbeddedSignaturePacket (signatures_over back_sig) | ||
1541 | unhashed0 = maybe [iss] cons_iss back_sig | ||
1542 | |||
1543 | new_sig <- pgpSign (Message [wkun]) | ||
1544 | (SubkeySignature wk | ||
1545 | (head parsedkey) | ||
1546 | (sigpackets 0x18 | ||
1547 | hashed0 | ||
1548 | unhashed0)) | ||
1549 | SHA1 | ||
1550 | grip | ||
1551 | let newSig = addOrigin new_sig | ||
1552 | flip (maybe newSig) mbsig $ \(mp,trustmap) -> do | ||
1553 | let sig = packet mp | ||
1554 | isCreation (SignatureCreationTimePacket {}) = True | ||
1555 | isCreation _ = False | ||
1556 | isExpiration (SignatureExpirationTimePacket {}) = True | ||
1557 | isExpiration _ = False | ||
1558 | (cs,ps) = partition isCreation (hashed_subpackets sig) | ||
1559 | (es,qs) = partition isExpiration ps | ||
1560 | stamp = listToMaybe . sortBy (comparing Down) $ | ||
1561 | map unwrap cs where unwrap (SignatureCreationTimePacket x) = x | ||
1562 | exp = listToMaybe $ sort $ | ||
1563 | map unwrap es where unwrap (SignatureExpirationTimePacket x) = x | ||
1564 | expires = liftA2 (+) stamp exp | ||
1565 | timestamp <- now | ||
1566 | if fmap ( (< timestamp) . fromIntegral) expires == Just True then do | ||
1567 | warn $ "Unable to update expired signature" | ||
1568 | return (mp,trustmap) | ||
1569 | else do | ||
1570 | let times = (:) (SignatureExpirationTimePacket (fromIntegral timestamp)) | ||
1571 | $ maybeToList $ do | ||
1572 | e <- expires | ||
1573 | return $ SignatureExpirationTimePacket (e - fromIntegral timestamp) | ||
1574 | notation = NotationDataPacket | ||
1575 | { notation_name = "usage@" | ||
1576 | , notation_value = tag | ||
1577 | , human_readable = True } | ||
1578 | sig' = sig { hashed_subpackets = times ++ [notation] ++ qs } | ||
1579 | new_sig <- pgpSign (Message [wkun]) | ||
1580 | (SubkeySignature wk | ||
1581 | (packet subkey_p) | ||
1582 | [sig'] ) | ||
1583 | SHA1 | ||
1584 | (fingerprint wk) | ||
1585 | addOrigin new_sig | ||
1586 | |||
1587 | signature_time ov = case if null cs then ds else cs of | ||
1588 | [] -> minBound | ||
1589 | xs -> last (sort xs) | ||
1590 | where | ||
1591 | ps = signatures_over ov | ||
1592 | ss = filter isSignaturePacket ps | ||
1593 | cs = concatMap (concatMap creationTime . hashed_subpackets) ss | ||
1594 | ds = concatMap (concatMap creationTime . unhashed_subpackets) ss | ||
1595 | creationTime (SignatureCreationTimePacket t) = [t] | ||
1596 | creationTime _ = [] | ||
1597 | |||
1598 | -- We return into IO in case we want to make a signature here. | 1251 | -- We return into IO in case we want to make a signature here. |
1599 | setHostnames :: (SockAddr -> Bool) -> Hosts.Hosts -> KeyData -> IO KeyData | 1252 | setHostnames :: (SockAddr -> Bool) -> Hosts.Hosts -> KeyData -> IO KeyData |
1600 | setHostnames pred hosts kd@(KeyData topmp topsigs uids subs) = | 1253 | setHostnames pred hosts kd@(KeyData topmp topsigs uids subs) = |
@@ -2358,52 +2011,3 @@ makeTorUID g timestamp wkun keyflags topkey torkey = uid:signatures_over sig | |||
2358 | sig = fst $ torsig g topkey wkun uid timestamp keyflags | 2011 | sig = fst $ torsig g topkey wkun uid timestamp keyflags |
2359 | -} | 2012 | -} |
2360 | 2013 | ||
2361 | -- torsig g topk wkun uid timestamp extras = todo | ||
2362 | torSigOver topk wkun uid extras | ||
2363 | = CertificationSignature (secretToPublic topk) | ||
2364 | uid | ||
2365 | (sigpackets 0x13 | ||
2366 | subpackets | ||
2367 | subpackets_unh) | ||
2368 | where | ||
2369 | subpackets = -- implicit: [ SignatureCreationTimePacket (fromIntegral timestamp) ] | ||
2370 | tsign | ||
2371 | ++ extras | ||
2372 | subpackets_unh = [IssuerPacket (fingerprint wkun)] | ||
2373 | tsign = if keykey wkun == keykey topk | ||
2374 | then [] -- tsign doesnt make sense for self-signatures | ||
2375 | else [ TrustSignaturePacket 1 120 | ||
2376 | , RegularExpressionPacket regex] | ||
2377 | -- <[^>]+[@.]asdf\.nowhere>$ | ||
2378 | regex = "<[^>]+[@.]"++hostname++">$" | ||
2379 | -- regex = username ++ "@" ++ hostname | ||
2380 | -- username = "[a-zA-Z0-9.][-a-zA-Z0-9.]*\\$?" :: String | ||
2381 | hostname = subdomain' pu ++ "\\." ++ topdomain' pu | ||
2382 | pu = parseUID uidstr where UserIDPacket uidstr = uid | ||
2383 | subdomain' = escape . T.unpack . uid_subdomain | ||
2384 | topdomain' = escape . T.unpack . uid_topdomain | ||
2385 | escape s = concatMap echar s | ||
2386 | where | ||
2387 | echar '|' = "\\|" | ||
2388 | echar '*' = "\\*" | ||
2389 | echar '+' = "\\+" | ||
2390 | echar '?' = "\\?" | ||
2391 | echar '.' = "\\." | ||
2392 | echar '^' = "\\^" | ||
2393 | echar '$' = "\\$" | ||
2394 | echar '\\' = "\\\\" | ||
2395 | echar '[' = "\\[" | ||
2396 | echar ']' = "\\]" | ||
2397 | echar c = [c] | ||
2398 | |||
2399 | sigpackets typ hashed unhashed = return $ | ||
2400 | signaturePacket | ||
2401 | 4 -- version | ||
2402 | typ -- 0x18 subkey binding sig, or 0x19 back-signature | ||
2403 | RSA | ||
2404 | SHA1 | ||
2405 | hashed | ||
2406 | unhashed | ||
2407 | 0 -- Word16 -- Left 16 bits of the signed hash value | ||
2408 | [] -- [MPI] | ||
2409 | |||