summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-07-04 21:09:48 -0400
committerJoe Crayne <joe@jerkface.net>2019-07-04 21:09:48 -0400
commitbeed56fec5bbef22f198fd99e05873080313bdae (patch)
tree16f72de0666cfec1de1708ff4c4ea6990847ed46
parent730cf4755596090a214075e05e92d70f3f6ea69e (diff)
WIP: cv25519 & ed25519 support.
-rw-r--r--Data/OpenPGP.hs19
1 files changed, 10 insertions, 9 deletions
diff --git a/Data/OpenPGP.hs b/Data/OpenPGP.hs
index a297c34..35298c8 100644
--- a/Data/OpenPGP.hs
+++ b/Data/OpenPGP.hs
@@ -344,9 +344,9 @@ public_key_fields RSA_E = public_key_fields RSA
344public_key_fields RSA_S = public_key_fields RSA 344public_key_fields RSA_S = public_key_fields RSA
345public_key_fields ELGAMAL = ['p', 'g', 'y'] 345public_key_fields ELGAMAL = ['p', 'g', 'y']
346public_key_fields DSA = ['p', 'q', 'g', 'y'] 346public_key_fields DSA = ['p', 'q', 'g', 'y']
347public_key_fields ECDSA = ['c','l','x', 'y'] -- TODO: These probably need special fingerprint handling. 347public_key_fields ECDSA = ['c','l','x', 'y', 'f']
348public_key_fields Ed25519 = ['c','l','x', 'y'] -- TODO: These probably need special fingerprint handling. 348public_key_fields Ed25519 = ['c','l','x', 'y', 'f']
349public_key_fields ECC = ['c','l','x', 'y'] -- TODO: These probably need special fingerprint handling. 349public_key_fields ECC = ['c','l','x', 'y', 'f']
350public_key_fields alg = error ("Unknown key fields for "++show alg) -- Nothing in the spec. Maybe empty 350public_key_fields alg = error ("Unknown key fields for "++show alg) -- Nothing in the spec. Maybe empty
351 351
352-- http://tools.ietf.org/html/rfc4880#section-5.5.3 352-- http://tools.ietf.org/html/rfc4880#section-5.5.3
@@ -420,17 +420,18 @@ eccOID SecretKeyPacket { key = k } = lookup 'c' k >>= \(MPI oid) -> Just (snd $
420eccOID _ = Nothing 420eccOID _ = Nothing
421 421
422encode_public_key_material :: Packet -> [B.ByteString] 422encode_public_key_material :: Packet -> [B.ByteString]
423encode_public_key_material k | key_algorithm k == ECDSA = do 423encode_public_key_material k | key_algorithm k `elem` [ECDSA,Ed25519] = do
424 -- http://tools.ietf.org/html/rfc6637 424 -- http://tools.ietf.org/html/rfc6637
425 c <- maybeToList $ lookup 'c' (key k) 425 c <- maybeToList $ lookup 'c' (key k)
426 MPI l <- maybeToList $ lookup 'l' (key k) 426 MPI l <- maybeToList $ lookup 'l' (key k)
427 MPI x <- maybeToList $ lookup 'x' (key k) 427 MPI x <- maybeToList $ lookup 'x' (key k)
428 MPI y <- maybeToList $ lookup 'y' (key k) 428 MPI y <- maybeToList $ lookup 'y' (key k)
429 MPI flag <- maybeToList $ lookup 'f' (key k)
429 let (bitlen,oid) = B.splitAt 2 (encode c) 430 let (bitlen,oid) = B.splitAt 2 (encode c)
430 len16 = decode bitlen :: Word16 431 len16 = decode bitlen :: Word16
431 (fullbytes,rembits) = len16 `quotRem` 8 432 (fullbytes,rembits) = len16 `quotRem` 8
432 len8 = fromIntegral (fullbytes + if rembits/=0 then 1 else 0) :: Word8 433 len8 = fromIntegral (fullbytes + if rembits/=0 then 1 else 0) :: Word8
433 xy = 4*(4^l) + x*(2^l) + y 434 xy = flag*(4^l) + x*(2^l) + y -- flag could be 0x04 or 0x40
434 [ len8 `B.cons` oid, encode (MPI xy) ] 435 [ len8 `B.cons` oid, encode (MPI xy) ]
435encode_public_key_material k = map (encode . (key k !)) (public_key_fields $ key_algorithm k) 436encode_public_key_material k = map (encode . (key k !)) (public_key_fields $ key_algorithm k)
436 437
@@ -445,9 +446,9 @@ decode_public_key_material algorithm | algorithm `elem` [ECDSA, Ed25519] = do
445 let integerBytesize i = fromIntegral $ LZ.length (encode (MPI i)) - 2 446 let integerBytesize i = fromIntegral $ LZ.length (encode (MPI i)) - 2
446 width = ( integerBytesize xy - 1 ) `div` 2 447 width = ( integerBytesize xy - 1 ) `div` 2
447 (fx,y) = xy `quotRem` (256^width) 448 (fx,y) = xy `quotRem` (256^width)
448 x = fx `rem` (256^width) 449 (flag,x) = fx `quotRem` (256^width)
449 l = width*8 450 l = width*8
450 return [('c',oid), ('l',MPI l), ('x',MPI x), ('y',MPI y)] 451 return [('c',oid), ('l',MPI l), ('x',MPI x), ('y',MPI y), ('f',MPI flag)]
451decode_public_key_material ECC = do 452decode_public_key_material ECC = do
452 -- http://tools.ietf.org/html/rfc6637 (9) Algorithm-Specific Fields for ECDH keys: 453 -- http://tools.ietf.org/html/rfc6637 (9) Algorithm-Specific Fields for ECDH keys:
453 oidlen <- get :: Get Word8 454 oidlen <- get :: Get Word8
@@ -462,9 +463,9 @@ decode_public_key_material ECC = do
462 let integerBytesize i = fromIntegral $ LZ.length (encode (MPI i)) - 2 463 let integerBytesize i = fromIntegral $ LZ.length (encode (MPI i)) - 2
463 width = ( integerBytesize xy - 1 ) `div` 2 464 width = ( integerBytesize xy - 1 ) `div` 2
464 (fx,y) = xy `quotRem` (256^width) 465 (fx,y) = xy `quotRem` (256^width)
465 x = fx `rem` (256^width) 466 (flag,x) = fx `quotRem` (256^width)
466 l = width*8 467 l = width*8
467 return [('c',oid), ('l',MPI l), ('x',MPI x), ('y',MPI y)] 468 return [('c',oid), ('l',MPI l), ('x',MPI x), ('y',MPI y), ('f',MPI flag)]
468decode_public_key_material algorithm = mapM (\f -> fmap ((,)f) get) (public_key_fields algorithm) 469decode_public_key_material algorithm = mapM (\f -> fmap ((,)f) get) (public_key_fields algorithm)
469 470
470put_packet :: Packet -> (B.ByteString, Word8) 471put_packet :: Packet -> (B.ByteString, Word8)