summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2020-05-16 07:44:58 -0400
committerJoe Crayne <joe@jerkface.net>2020-05-19 11:59:17 -0400
commit52973c2c26fc2d3c529f0a11329c9784f87b3c72 (patch)
treee0ee8a701a30f616ea1e3ff014334e0b5bbedcab
parent1e97c0b23cf96110e0c9ba3f9776dbb4b278bfd7 (diff)
Encode v5 keys (draft-ietf-openpgp-rfc4880bis-09).
-rw-r--r--Data/OpenPGP.hs56
1 files changed, 42 insertions, 14 deletions
diff --git a/Data/OpenPGP.hs b/Data/OpenPGP.hs
index a151e7b..cc97cd6 100644
--- a/Data/OpenPGP.hs
+++ b/Data/OpenPGP.hs
@@ -465,7 +465,13 @@ encode_public_key_material k | key_algorithm k `elem` [ECDSA,Ed25519,ECC] = do
465 MPI y <- maybeToList $ lookup 'y' (key k) 465 MPI y <- maybeToList $ lookup 'y' (key k)
466 let xy = flag*(4^l) + x*(2^l) + y 466 let xy = flag*(4^l) + x*(2^l) + y
467 [ oid, encode (MPI xy), eccstuff ] 467 [ oid, encode (MPI xy), eccstuff ]
468encode_public_key_material k = map (encode . (key k !)) (public_key_fields $ key_algorithm k) 468encode_public_key_material k | Just fs <- known_public_key_fields (key_algorithm k) =
469 map (encode . (key k !)) fs
470encode_public_key_material k =
471 -- encoding of a v5 opaque public key
472 let MPI opaque = key k ! 'L'
473 in [runPut . putByteString . integerToBS $ opaque]
474
469 475
470getEllipticCurvePublicKey :: Get [(Char,MPI)] 476getEllipticCurvePublicKey :: Get [(Char,MPI)]
471getEllipticCurvePublicKey = do 477getEllipticCurvePublicKey = do
@@ -568,26 +574,43 @@ put_packet (OnePassSignaturePacket { version = version,
568put_packet (SecretKeyPacket { version = version, timestamp = timestamp, 574put_packet (SecretKeyPacket { version = version, timestamp = timestamp,
569 key_algorithm = algorithm, key = key, 575 key_algorithm = algorithm, key = key,
570 s2k_useage = s2k_useage, s2k = s2k, 576 s2k_useage = s2k_useage, s2k = s2k,
577 aead_algorithm = aead_algorithm,
571 symmetric_algorithm = symmetric_algorithm, 578 symmetric_algorithm = symmetric_algorithm,
572 encrypted_data = encrypted_data, 579 encrypted_data = encrypted_data,
573 is_subkey = is_subkey }) = 580 is_subkey = is_subkey }) =
574 (B.concat $ p : 581 flip (,) (if is_subkey then 7 else 5) $ B.concat $ concat
575 (if s2k_useage `elem` [254,255] then 582 [ [p,s2kbyte]
576 [encode s2k_useage, encode symmetric_algorithm, encode s2k] 583 , if version == 5
577 else 584 then [ B.singleton (fromIntegral $ sum $ map B.length s2k_stuff) ]
578 [encode symmetric_algorithm] 585 else []
579 ) ++ 586 , s2k_stuff
580 (if symmetric_algorithm /= Unencrypted then 587 , if version == 5
588 then [ encode (fromIntegral (sum $ map B.length key_stuff) :: Word32) ]
589 else []
590 , key_stuff
591 , if symmetric_algorithm == Unencrypted
592 then [ encode (checksum $ B.concat s) ]
593 else []
594 ]
595 where
596 (s2kbyte,s2k_stuff) = case s2k_useage of
597 u | u `elem` [254,255]
598 -> (encode s2k_useage, [encode symmetric_algorithm, encode s2k])
599 253 | Just aead <- aead_algorithm
600 -> (encode s2k_useage, [encode symmetric_algorithm, encode aead, encode s2k])
601 _ -> (encode symmetric_algorithm, [])
602 key_stuff =
603 if symmetric_algorithm /= Unencrypted then
581 -- For V3 keys, the "encrypted data" has an unencrypted checksum 604 -- For V3 keys, the "encrypted data" has an unencrypted checksum
582 -- of the unencrypted MPIs on the end 605 -- of the unencrypted MPIs on the end
583 [encrypted_data] 606 [encrypted_data]
584 else s ++ 607 else s
585 [encode $ checksum $ B.concat s]),
586 if is_subkey then 7 else 5)
587 where
588 p = fst (put_packet $ 608 p = fst (put_packet $
589 PublicKeyPacket version timestamp algorithm key False Nothing) 609 PublicKeyPacket version timestamp algorithm key False Nothing)
590 s = map (encode . (key !)) (secret_key_fields algorithm) 610 s = case known_secret_key_fields algorithm of
611 Nothing | Just (MPI opaque) <- lookup 'R' key
612 -> [ runPut (putByteString (integerToBS opaque)) ]
613 Just fs -> map (encode . (key !)) fs
591put_packet p@(PublicKeyPacket { version = v, timestamp = timestamp, 614put_packet p@(PublicKeyPacket { version = v, timestamp = timestamp,
592 key_algorithm = algorithm, key = key, 615 key_algorithm = algorithm, key = key,
593 is_subkey = is_subkey }) 616 is_subkey = is_subkey })
@@ -598,10 +621,15 @@ put_packet p@(PublicKeyPacket { version = v, timestamp = timestamp,
598 encode v3_days, 621 encode v3_days,
599 encode algorithm 622 encode algorithm
600 ] ++ material) 623 ] ++ material)
601 _ -> 624 4 ->
602 final (B.concat $ [ 625 final (B.concat $ [
603 B.singleton 4, encode timestamp, encode algorithm 626 B.singleton 4, encode timestamp, encode algorithm
604 ] ++ material) 627 ] ++ material)
628 5 ->
629 final (B.concat $ [
630 B.singleton 5, encode timestamp, encode algorithm,
631 encode (fromIntegral (sum $ map B.length material) :: Word32)
632 ] ++ material)
605 where 633 where
606 Just v3_days = v3_days_of_validity p 634 Just v3_days = v3_days_of_validity p
607 final x = (x, if is_subkey then 14 else 6) 635 final x = (x, if is_subkey then 14 else 6)