diff options
Diffstat (limited to 'lib/KeyRing/Types.hs')
-rw-r--r-- | lib/KeyRing/Types.hs | 125 |
1 files changed, 120 insertions, 5 deletions
diff --git a/lib/KeyRing/Types.hs b/lib/KeyRing/Types.hs index 3c1f0a5..4a0b34e 100644 --- a/lib/KeyRing/Types.hs +++ b/lib/KeyRing/Types.hs | |||
@@ -3,12 +3,13 @@ | |||
3 | {-# LANGUAGE PatternSynonyms #-} | 3 | {-# LANGUAGE PatternSynonyms #-} |
4 | module KeyRing.Types where | 4 | module KeyRing.Types where |
5 | 5 | ||
6 | import Data.Bits | ||
6 | import Data.Char (isLower,toLower) | 7 | import Data.Char (isLower,toLower) |
7 | import Data.Functor | 8 | import Data.Functor |
8 | import Data.List (groupBy,find) | 9 | import Data.List (groupBy,find,isInfixOf) |
9 | import Data.Map as Map (Map) | 10 | import Data.Map as Map (Map) |
10 | import qualified Data.Map as Map | 11 | import qualified Data.Map as Map |
11 | import Data.Maybe (maybeToList) | 12 | import Data.Maybe (maybeToList,isJust,fromJust,mapMaybe) |
12 | import Data.OpenPGP | 13 | import Data.OpenPGP |
13 | import Data.OpenPGP.Util | 14 | import Data.OpenPGP.Util |
14 | import Data.Time.Clock | 15 | import Data.Time.Clock |
@@ -335,9 +336,9 @@ isSecretKey (SecretKeyPacket {}) = True | |||
335 | isSecretKey _ = False | 336 | isSecretKey _ = False |
336 | 337 | ||
337 | 338 | ||
338 | isUserID :: Packet -> Bool | 339 | isUserID :: Packet -> Maybe String |
339 | isUserID (UserIDPacket {}) = True | 340 | isUserID (UserIDPacket str) = Just str |
340 | isUserID _ = False | 341 | isUserID _ = Nothing |
341 | 342 | ||
342 | isTrust :: Packet -> Bool | 343 | isTrust :: Packet -> Bool |
343 | isTrust (TrustPacket {}) = True | 344 | isTrust (TrustPacket {}) = True |
@@ -408,3 +409,117 @@ data SingleKeySpec = FingerprintMatch String | |||
408 | | WorkingKeyMatch | 409 | | WorkingKeyMatch |
409 | deriving (Show,Eq,Ord) | 410 | deriving (Show,Eq,Ord) |
410 | 411 | ||
412 | secretToPublic :: Packet -> Packet | ||
413 | secretToPublic pkt@(SecretKeyPacket {}) = | ||
414 | PublicKeyPacket { version = version pkt | ||
415 | , timestamp = timestamp pkt | ||
416 | , key_algorithm = key_algorithm pkt | ||
417 | -- , ecc_curve = ecc_curve pkt | ||
418 | , key = let seckey = key pkt | ||
419 | pubs = public_key_fields (key_algorithm pkt) | ||
420 | in filter (\(k,v) -> k `elem` pubs) seckey | ||
421 | , is_subkey = is_subkey pkt | ||
422 | , v3_days_of_validity = Nothing | ||
423 | } | ||
424 | secretToPublic pkt = pkt | ||
425 | |||
426 | seek_key :: KeySpec -> [Packet] -> ([Packet],[Packet]) | ||
427 | seek_key (KeyGrip grip) sec = (pre, subs) | ||
428 | where | ||
429 | (pre,subs) = break pred sec | ||
430 | pred p@(SecretKeyPacket {}) = matchpr grip p == grip | ||
431 | pred p@(PublicKeyPacket {}) = matchpr grip p == grip | ||
432 | pred _ = False | ||
433 | |||
434 | seek_key (KeyTag key tag) ps | ||
435 | | null bs = (ps, []) | ||
436 | | null qs = | ||
437 | let (as', bs') = seek_key (KeyTag key tag) (tail bs) in | ||
438 | (as ++ (head bs : as'), bs') | ||
439 | | otherwise = (reverse (tail qs), head qs : reverse rs ++ bs) | ||
440 | where | ||
441 | (as,bs) = break (\p -> isSignaturePacket p | ||
442 | && has_tag tag p | ||
443 | && isJust (signature_issuer p) | ||
444 | && matchpr (fromJust $ signature_issuer p) key == fromJust (signature_issuer p) ) | ||
445 | ps | ||
446 | (rs,qs) = break isKey (reverse as) | ||
447 | |||
448 | has_tag tag p = tag `elem` mapMaybe usage (hashed_subpackets p) | ||
449 | || tag `elem` map usageString (mapMaybe keyflags (hashed_subpackets p)) | ||
450 | |||
451 | seek_key (KeyUidMatch pat) ps | ||
452 | | null bs = (ps, []) | ||
453 | | null qs = let (as', bs') = seek_key (KeyUidMatch pat) (tail bs) in | ||
454 | (as ++ (head bs : as'), bs') | ||
455 | | otherwise = (reverse (tail qs), head qs : reverse rs ++ bs) | ||
456 | where | ||
457 | (as,bs) = break (isInfixOf pat . uidStr) ps | ||
458 | (rs,qs) = break isKey (reverse as) | ||
459 | |||
460 | uidStr (UserIDPacket s) = s | ||
461 | uidStr _ = "" | ||
462 | |||
463 | usageString :: PGPKeyFlags -> String | ||
464 | usageString flgs = | ||
465 | case flgs of | ||
466 | Special -> "special" | ||
467 | Vouch -> "vouch" -- signkey | ||
468 | Sign -> "sign" | ||
469 | VouchSign -> "vouch-sign" | ||
470 | Communication -> "communication" | ||
471 | VouchCommunication -> "vouch-communication" | ||
472 | SignCommunication -> "sign-communication" | ||
473 | VouchSignCommunication -> "vouch-sign-communication" | ||
474 | Storage -> "storage" | ||
475 | VouchStorage -> "vouch-storage" | ||
476 | SignStorage -> "sign-storage" | ||
477 | VouchSignStorage -> "vouch-sign-storage" | ||
478 | Encrypt -> "encrypt" | ||
479 | VouchEncrypt -> "vouch-encrypt" | ||
480 | SignEncrypt -> "sign-encrypt" | ||
481 | VouchSignEncrypt -> "vouch-sign-encrypt" | ||
482 | |||
483 | usage :: SignatureSubpacket -> Maybe String | ||
484 | usage (NotationDataPacket | ||
485 | { human_readable = True | ||
486 | , notation_name = "usage@" | ||
487 | , notation_value = u | ||
488 | }) = Just u | ||
489 | usage _ = Nothing | ||
490 | |||
491 | data PGPKeyFlags = | ||
492 | Special | ||
493 | | Vouch -- 0001 C -- Signkey | ||
494 | | Sign -- 0010 S | ||
495 | | VouchSign -- 0011 | ||
496 | | Communication -- 0100 E | ||
497 | | VouchCommunication -- 0101 | ||
498 | | SignCommunication -- 0110 | ||
499 | | VouchSignCommunication -- 0111 | ||
500 | | Storage -- 1000 E | ||
501 | | VouchStorage -- 1001 | ||
502 | | SignStorage -- 1010 | ||
503 | | VouchSignStorage -- 1011 | ||
504 | | Encrypt -- 1100 E | ||
505 | | VouchEncrypt -- 1101 | ||
506 | | SignEncrypt -- 1110 | ||
507 | | VouchSignEncrypt -- 1111 | ||
508 | deriving (Eq,Show,Read,Enum) | ||
509 | |||
510 | -- XXX keyFlags and keyflags are different functions. | ||
511 | keyflags :: SignatureSubpacket -> Maybe PGPKeyFlags | ||
512 | keyflags flgs@(KeyFlagsPacket {}) = | ||
513 | Just . toEnum $ | ||
514 | ( bit 0x1 certify_keys | ||
515 | .|. bit 0x2 sign_data | ||
516 | .|. bit 0x4 encrypt_communication | ||
517 | .|. bit 0x8 encrypt_storage ) :: Maybe PGPKeyFlags | ||
518 | -- other flags: | ||
519 | -- split_key | ||
520 | -- authentication (ssh-client) | ||
521 | -- group_key | ||
522 | where | ||
523 | bit v f = if f flgs then v else 0 | ||
524 | keyflags _ = Nothing | ||
525 | |||