summaryrefslogtreecommitdiff
path: root/lib/KeyRing/Types.hs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/KeyRing/Types.hs')
-rw-r--r--lib/KeyRing/Types.hs125
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 #-}
4module KeyRing.Types where 4module KeyRing.Types where
5 5
6import Data.Bits
6import Data.Char (isLower,toLower) 7import Data.Char (isLower,toLower)
7import Data.Functor 8import Data.Functor
8import Data.List (groupBy,find) 9import Data.List (groupBy,find,isInfixOf)
9import Data.Map as Map (Map) 10import Data.Map as Map (Map)
10import qualified Data.Map as Map 11import qualified Data.Map as Map
11import Data.Maybe (maybeToList) 12import Data.Maybe (maybeToList,isJust,fromJust,mapMaybe)
12import Data.OpenPGP 13import Data.OpenPGP
13import Data.OpenPGP.Util 14import Data.OpenPGP.Util
14import Data.Time.Clock 15import Data.Time.Clock
@@ -335,9 +336,9 @@ isSecretKey (SecretKeyPacket {}) = True
335isSecretKey _ = False 336isSecretKey _ = False
336 337
337 338
338isUserID :: Packet -> Bool 339isUserID :: Packet -> Maybe String
339isUserID (UserIDPacket {}) = True 340isUserID (UserIDPacket str) = Just str
340isUserID _ = False 341isUserID _ = Nothing
341 342
342isTrust :: Packet -> Bool 343isTrust :: Packet -> Bool
343isTrust (TrustPacket {}) = True 344isTrust (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
412secretToPublic :: Packet -> Packet
413secretToPublic 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 }
424secretToPublic pkt = pkt
425
426seek_key :: KeySpec -> [Packet] -> ([Packet],[Packet])
427seek_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
434seek_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
451seek_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
463usageString :: PGPKeyFlags -> String
464usageString 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
483usage :: SignatureSubpacket -> Maybe String
484usage (NotationDataPacket
485 { human_readable = True
486 , notation_name = "usage@"
487 , notation_value = u
488 }) = Just u
489usage _ = Nothing
490
491data 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.
511keyflags :: SignatureSubpacket -> Maybe PGPKeyFlags
512keyflags 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
524keyflags _ = Nothing
525