diff options
author | joe <joe@jerkface.net> | 2013-12-15 22:06:29 -0500 |
---|---|---|
committer | joe <joe@jerkface.net> | 2013-12-15 22:06:29 -0500 |
commit | 395f75c6b7f66d313b4d44be4ed1317f9d7c7042 (patch) | |
tree | f66e931fb49cca89a0faa5bcc6a66c52418505a0 /Data | |
parent | 8dd042382eb2a676bac6cd266268ef4d3ed2b390 (diff) |
Adapted to new ecc solutoin for OpenPGP-Haskell
Diffstat (limited to 'Data')
-rw-r--r-- | Data/OpenPGP/Util/Base.hs | 16 | ||||
-rw-r--r-- | Data/OpenPGP/Util/Sign.hs | 143 | ||||
-rw-r--r-- | Data/OpenPGP/Util/Verify.hs | 23 |
3 files changed, 115 insertions, 67 deletions
diff --git a/Data/OpenPGP/Util/Base.hs b/Data/OpenPGP/Util/Base.hs index 802d503..aaa02c7 100644 --- a/Data/OpenPGP/Util/Base.hs +++ b/Data/OpenPGP/Util/Base.hs | |||
@@ -14,6 +14,8 @@ import Crypto.Hash.SHA224 as SHA224 | |||
14 | import Crypto.Hash.RIPEMD160 as RIPEMD160 | 14 | import Crypto.Hash.RIPEMD160 as RIPEMD160 |
15 | import qualified Crypto.PubKey.RSA as Vincent.RSA | 15 | import qualified Crypto.PubKey.RSA as Vincent.RSA |
16 | import Crypto.PubKey.HashDescr as Vincent | 16 | import Crypto.PubKey.HashDescr as Vincent |
17 | import qualified Crypto.Types.PubKey.ECC as Vincent.ECDSA | ||
18 | import qualified Crypto.Types.PubKey.ECDSA as Vincent.ECDSA | ||
17 | 19 | ||
18 | import Data.OpenPGP.Util.Fingerprint (fingerprint) | 20 | import Data.OpenPGP.Util.Fingerprint (fingerprint) |
19 | 21 | ||
@@ -25,6 +27,20 @@ hashBySymbol OpenPGP.SHA512 = SHA512.hashlazy | |||
25 | hashBySymbol OpenPGP.SHA224 = SHA224.hashlazy | 27 | hashBySymbol OpenPGP.SHA224 = SHA224.hashlazy |
26 | hashBySymbol OpenPGP.RIPEMD160 = RIPEMD160.hashlazy | 28 | hashBySymbol OpenPGP.RIPEMD160 = RIPEMD160.hashlazy |
27 | 29 | ||
30 | curveFromOID :: Integer -> Vincent.ECDSA.Curve | ||
31 | curveFromOID 0x2a8648ce3d030107 = Vincent.ECDSA.getCurveByName Vincent.ECDSA.SEC_p256r1 -- NIST P-256 | ||
32 | curveFromOID 0x2B81040022 = Vincent.ECDSA.getCurveByName Vincent.ECDSA.SEC_p384r1 -- NIST P-384 | ||
33 | curveFromOID 0x2B81040023 = Vincent.ECDSA.getCurveByName Vincent.ECDSA.SEC_p521r1 -- NIST P-521 | ||
34 | curveFromOID 0x2b8104000a = Vincent.ECDSA.getCurveByName Vincent.ECDSA.SEC_p256k1 -- bitcoin curve | ||
35 | curveFromOID n = error $ "Unknown curve: "++ show n | ||
36 | |||
37 | ecdsaKey k = Vincent.ECDSA.PublicKey curve (Vincent.ECDSA.Point x y) | ||
38 | where | ||
39 | x = keyParam 'x' k | ||
40 | y = keyParam 'y' k | ||
41 | curve = curveFromOID (keyParam 'c' k) | ||
42 | |||
43 | |||
28 | toStrictBS :: LZ.ByteString -> BS.ByteString | 44 | toStrictBS :: LZ.ByteString -> BS.ByteString |
29 | toStrictBS = BS.concat . LZ.toChunks | 45 | toStrictBS = BS.concat . LZ.toChunks |
30 | 46 | ||
diff --git a/Data/OpenPGP/Util/Sign.hs b/Data/OpenPGP/Util/Sign.hs index e492f95..4a6eb4f 100644 --- a/Data/OpenPGP/Util/Sign.hs +++ b/Data/OpenPGP/Util/Sign.hs | |||
@@ -17,9 +17,15 @@ import qualified Crypto.Random as Vincent | |||
17 | import qualified Crypto.PubKey.DSA as Vincent.DSA | 17 | import qualified Crypto.PubKey.DSA as Vincent.DSA |
18 | import qualified Crypto.PubKey.RSA as Vincent.RSA | 18 | import qualified Crypto.PubKey.RSA as Vincent.RSA |
19 | import qualified Crypto.PubKey.RSA.PKCS15 as Vincent.RSA | 19 | import qualified Crypto.PubKey.RSA.PKCS15 as Vincent.RSA |
20 | import qualified Crypto.PubKey.ECC.ECDSA as Vincent.ECDSA | ||
20 | 21 | ||
21 | import Data.OpenPGP.Util.Base | 22 | import Data.OpenPGP.Util.Base |
22 | 23 | ||
24 | privateECDSAkey :: OpenPGP.Packet -> Vincent.ECDSA.PrivateKey | ||
25 | privateECDSAkey k = Vincent.ECDSA.PrivateKey curve d | ||
26 | where | ||
27 | d = keyParam 'd' k | ||
28 | curve = curveFromOID (keyParam 'c' k) | ||
23 | 29 | ||
24 | privateDSAkey :: OpenPGP.Packet -> Vincent.DSA.PrivateKey | 30 | privateDSAkey :: OpenPGP.Packet -> Vincent.DSA.PrivateKey |
25 | privateDSAkey k = Vincent.DSA.PrivateKey | 31 | privateDSAkey k = Vincent.DSA.PrivateKey |
@@ -46,74 +52,77 @@ privateRSAkey k = | |||
46 | -- Operation is unsafe in that it silently re-uses "random" bytes when | 52 | -- Operation is unsafe in that it silently re-uses "random" bytes when |
47 | -- entropy runs out. Use pgpSign for a safer interface. | 53 | -- entropy runs out. Use pgpSign for a safer interface. |
48 | unsafeSign :: (Vincent.CPRG g) => -- CryptoRandomGen g) => | 54 | unsafeSign :: (Vincent.CPRG g) => -- CryptoRandomGen g) => |
49 | OpenPGP.Message -- ^ SecretKeys, one of which will be used | 55 | OpenPGP.Message -- ^ SecretKeys, one of which will be used |
50 | -> OpenPGP.SignatureOver -- ^ Data to sign, and optional signature packet | 56 | -> OpenPGP.SignatureOver -- ^ Data to sign, and optional signature packet |
51 | -> OpenPGP.HashAlgorithm -- ^ HashAlgorithm to use in signature | 57 | -> OpenPGP.HashAlgorithm -- ^ HashAlgorithm to use in signature |
52 | -> String -- ^ KeyID of key to choose | 58 | -> String -- ^ KeyID of key to choose |
53 | -> Integer -- ^ Timestamp for signature (unless sig supplied) | 59 | -> Integer -- ^ Timestamp for signature (unless sig supplied) |
54 | -> g -- ^ Random number generator | 60 | -> g -- ^ Random number generator |
55 | -> (OpenPGP.SignatureOver, g) | 61 | -> (OpenPGP.SignatureOver, g) |
56 | unsafeSign keys over hsh keyid timestamp g = (over {OpenPGP.signatures_over = [sig]}, g') | 62 | unsafeSign keys over hsh keyid timestamp g = (over {OpenPGP.signatures_over = [sig]}, g') |
57 | where | 63 | where |
58 | (final, g') = case OpenPGP.key_algorithm sig of | 64 | (final, g') = case OpenPGP.key_algorithm sig of |
59 | OpenPGP.DSA -> ([dsaR, dsaS], dsaG) | 65 | OpenPGP.DSA -> ([dsaR, dsaS], dsaG) |
60 | kalgo | kalgo `elem` [OpenPGP.RSA,OpenPGP.RSA_S] -> ([toNum rsaFinal], g) | 66 | OpenPGP.ECDSA -> ([ecdsaR,ecdsaS],ecdsaG) |
61 | | otherwise -> | 67 | kalgo | kalgo `elem` [OpenPGP.RSA,OpenPGP.RSA_S] -> ([toNum rsaFinal], g) |
62 | error ("Unsupported key algorithm " ++ show kalgo ++ "in sign") | 68 | | otherwise -> |
63 | (Vincent.DSA.Signature dsaR dsaS,dsaG) = let k' = privateDSAkey k in | 69 | error ("Unsupported key algorithm " ++ show kalgo ++ " in sign") |
64 | Vincent.DSA.sign g k' (dsaTruncate k' . bhash) dta | 70 | (Vincent.DSA.Signature dsaR dsaS,dsaG) = let k' = privateDSAkey k in |
65 | (Right rsaFinal,_) = Vincent.RSA.signSafer g desc (privateRSAkey k) dta | 71 | Vincent.DSA.sign g k' (dsaTruncate k' . bhash) dta |
66 | dsaTruncate (Vincent.DSA.PrivateKey (Vincent.DSA.Params _ _ q) _) = BS.take (integerBytesize q) | 72 | (Vincent.ECDSA.Signature ecdsaR ecdsaS,ecdsaG) = let k' = privateECDSAkey k in |
67 | dta = toStrictBS $ encode over `LZ.append` OpenPGP.trailer sig | 73 | Vincent.ECDSA.sign g k' bhash dta |
68 | sig = findSigOrDefault (listToMaybe $ OpenPGP.signatures_over over) | 74 | (Right rsaFinal,_) = Vincent.RSA.signSafer g desc (privateRSAkey k) dta |
69 | -- padding = emsa_pkcs1_v1_5_hash_padding hsh | 75 | dsaTruncate (Vincent.DSA.PrivateKey (Vincent.DSA.Params _ _ q) _) = BS.take (integerBytesize q) |
70 | desc = hashAlgoDesc hsh | 76 | dta = toStrictBS $ encode over `LZ.append` OpenPGP.trailer sig |
71 | bhash = hashBySymbol hsh . toLazyBS | 77 | sig = findSigOrDefault (listToMaybe $ OpenPGP.signatures_over over) |
72 | toNum = BS.foldl (\a b -> a `shiftL` 8 .|. fromIntegral b) 0 | 78 | -- padding = emsa_pkcs1_v1_5_hash_padding hsh |
73 | Just k = find_key keys keyid | 79 | desc = hashAlgoDesc hsh |
74 | 80 | bhash = hashBySymbol hsh . toLazyBS | |
75 | -- Either a SignaturePacket was found, or we need to make one | 81 | toNum = BS.foldl (\a b -> a `shiftL` 8 .|. fromIntegral b) 0 |
76 | findSigOrDefault (Just s) = OpenPGP.signaturePacket | 82 | Just k = find_key keys keyid |
77 | (OpenPGP.version s) | 83 | |
78 | (OpenPGP.signature_type s) | 84 | -- Either a SignaturePacket was found, or we need to make one |
79 | (OpenPGP.key_algorithm k) -- force to algo of key | 85 | findSigOrDefault (Just s) = OpenPGP.signaturePacket |
80 | hsh -- force hash algorithm | 86 | (OpenPGP.version s) |
81 | (OpenPGP.hashed_subpackets s) | 87 | (OpenPGP.signature_type s) |
82 | (OpenPGP.unhashed_subpackets s) | 88 | (OpenPGP.key_algorithm k) -- force to algo of key |
83 | (OpenPGP.hash_head s) | 89 | hsh -- force hash algorithm |
84 | (map OpenPGP.MPI final) | 90 | (OpenPGP.hashed_subpackets s) |
85 | findSigOrDefault Nothing = OpenPGP.signaturePacket | 91 | (OpenPGP.unhashed_subpackets s) |
86 | 4 | 92 | (OpenPGP.hash_head s) |
87 | defaultStype | 93 | (map OpenPGP.MPI final) |
88 | (OpenPGP.key_algorithm k) -- force to algo of key | 94 | findSigOrDefault Nothing = OpenPGP.signaturePacket |
89 | hsh | 95 | 4 |
90 | ([ | 96 | defaultStype |
91 | -- Do we really need to pass in timestamp just for the default? | 97 | (OpenPGP.key_algorithm k) -- force to algo of key |
92 | OpenPGP.SignatureCreationTimePacket $ fromIntegral timestamp, | 98 | hsh |
93 | OpenPGP.IssuerPacket $ fingerprint k | 99 | ([ |
94 | ] ++ (case over of | 100 | -- Do we really need to pass in timestamp just for the default? |
95 | OpenPGP.KeySignature {} -> [OpenPGP.KeyFlagsPacket { | 101 | OpenPGP.SignatureCreationTimePacket $ fromIntegral timestamp, |
96 | OpenPGP.certify_keys = True, | 102 | OpenPGP.IssuerPacket $ fingerprint k |
97 | OpenPGP.sign_data = True, | 103 | ] ++ (case over of |
98 | OpenPGP.encrypt_communication = False, | 104 | OpenPGP.KeySignature {} -> [OpenPGP.KeyFlagsPacket { |
99 | OpenPGP.encrypt_storage = False, | 105 | OpenPGP.certify_keys = True, |
100 | OpenPGP.split_key = False, | 106 | OpenPGP.sign_data = True, |
101 | OpenPGP.authentication = False, | 107 | OpenPGP.encrypt_communication = False, |
102 | OpenPGP.group_key = False | 108 | OpenPGP.encrypt_storage = False, |
103 | }] | 109 | OpenPGP.split_key = False, |
104 | _ -> [] | 110 | OpenPGP.authentication = False, |
105 | )) | 111 | OpenPGP.group_key = False |
106 | [] | 112 | }] |
107 | 0 -- TODO | 113 | _ -> [] |
108 | (map OpenPGP.MPI final) | 114 | )) |
109 | 115 | [] | |
110 | defaultStype = case over of | 116 | 0 -- TODO |
111 | OpenPGP.DataSignature ld _ | 117 | (map OpenPGP.MPI final) |
112 | | OpenPGP.format ld == 'b' -> 0x00 | 118 | |
113 | | otherwise -> 0x01 | 119 | defaultStype = case over of |
114 | OpenPGP.KeySignature {} -> 0x1F | 120 | OpenPGP.DataSignature ld _ |
115 | OpenPGP.SubkeySignature {} -> 0x18 | 121 | | OpenPGP.format ld == 'b' -> 0x00 |
116 | OpenPGP.CertificationSignature {} -> 0x13 | 122 | | otherwise -> 0x01 |
123 | OpenPGP.KeySignature {} -> 0x1F | ||
124 | OpenPGP.SubkeySignature {} -> 0x18 | ||
125 | OpenPGP.CertificationSignature {} -> 0x13 | ||
117 | 126 | ||
118 | 127 | ||
119 | 128 | ||
diff --git a/Data/OpenPGP/Util/Verify.hs b/Data/OpenPGP/Util/Verify.hs index 2367570..b42e664 100644 --- a/Data/OpenPGP/Util/Verify.hs +++ b/Data/OpenPGP/Util/Verify.hs | |||
@@ -1,5 +1,7 @@ | |||
1 | {-# LANGUAGE OverloadedStrings #-} | ||
1 | module Data.OpenPGP.Util.Verify where | 2 | module Data.OpenPGP.Util.Verify where |
2 | 3 | ||
4 | import Debug.Trace | ||
3 | import qualified Data.OpenPGP as OpenPGP | 5 | import qualified Data.OpenPGP as OpenPGP |
4 | import Data.Maybe | 6 | import Data.Maybe |
5 | import Data.Binary (encode) | 7 | import Data.Binary (encode) |
@@ -9,6 +11,8 @@ import qualified Data.ByteString.Lazy as LZ | |||
9 | 11 | ||
10 | import qualified Crypto.PubKey.DSA as Vincent.DSA | 12 | import qualified Crypto.PubKey.DSA as Vincent.DSA |
11 | import qualified Crypto.PubKey.RSA.PKCS15 as Vincent.RSA | 13 | import qualified Crypto.PubKey.RSA.PKCS15 as Vincent.RSA |
14 | import qualified Crypto.PubKey.ECC.ECDSA as Vincent.ECDSA | ||
15 | -- import Math.NumberTheory.Moduli | ||
12 | 16 | ||
13 | import Data.OpenPGP.Util.Base | 17 | import Data.OpenPGP.Util.Base |
14 | 18 | ||
@@ -19,6 +23,14 @@ dsaKey k = Vincent.DSA.PublicKey | |||
19 | (keyParam 'y' k) | 23 | (keyParam 'y' k) |
20 | 24 | ||
21 | 25 | ||
26 | {- | ||
27 | applyCurve :: Vincent.ECDSA.CurveCommon -> Integer -> Integer | ||
28 | applyCurve curve x = x*x*x + x*a + b | ||
29 | where | ||
30 | a = Vincent.ECDSA.ecc_a curve | ||
31 | b = Vincent.ECDSA.ecc_b curve | ||
32 | -} | ||
33 | |||
22 | -- | Verify a message signature | 34 | -- | Verify a message signature |
23 | verify :: | 35 | verify :: |
24 | OpenPGP.Message -- ^ Keys that may have made the signature | 36 | OpenPGP.Message -- ^ Keys that may have made the signature |
@@ -35,17 +47,28 @@ verifyOne keys sig over = fmap (const sig) $ maybeKey >>= verification >>= guard | |||
35 | where | 47 | where |
36 | verification = case OpenPGP.key_algorithm sig of | 48 | verification = case OpenPGP.key_algorithm sig of |
37 | OpenPGP.DSA -> dsaVerify | 49 | OpenPGP.DSA -> dsaVerify |
50 | OpenPGP.ECDSA -> ecdsaVerify | ||
38 | alg | alg `elem` [OpenPGP.RSA,OpenPGP.RSA_S] -> rsaVerify | 51 | alg | alg `elem` [OpenPGP.RSA,OpenPGP.RSA_S] -> rsaVerify |
39 | | otherwise -> const Nothing | 52 | | otherwise -> const Nothing |
40 | dsaVerify k = let k' = dsaKey k in | 53 | dsaVerify k = let k' = dsaKey k in |
41 | Just $ Vincent.DSA.verify (dsaTruncate k' . bhash) k' dsaSig over | 54 | Just $ Vincent.DSA.verify (dsaTruncate k' . bhash) k' dsaSig over |
55 | ecdsaVerify k = let k' = ecdsaKey k | ||
56 | r = Just $ Vincent.ECDSA.verify bhash k' ecdsaSig over | ||
57 | in r -- trace ("ecdsaVerify: "++show r) r | ||
42 | rsaVerify k = Just $ Vincent.RSA.verify desc (rsaKey k) over rsaSig | 58 | rsaVerify k = Just $ Vincent.RSA.verify desc (rsaKey k) over rsaSig |
43 | [rsaSig] = map (toStrictBS . LZ.drop 2 . encode) (OpenPGP.signature sig) | 59 | [rsaSig] = map (toStrictBS . LZ.drop 2 . encode) (OpenPGP.signature sig) |
44 | dsaSig = let [OpenPGP.MPI r, OpenPGP.MPI s] = OpenPGP.signature sig in | 60 | dsaSig = let [OpenPGP.MPI r, OpenPGP.MPI s] = OpenPGP.signature sig in |
45 | Vincent.DSA.Signature r s | 61 | Vincent.DSA.Signature r s |
62 | ecdsaSig = let [OpenPGP.MPI r, OpenPGP.MPI s] = OpenPGP.signature sig in | ||
63 | Vincent.ECDSA.Signature r s | ||
46 | dsaTruncate (Vincent.DSA.PublicKey (Vincent.DSA.Params _ _ q) _) = BS.take (integerBytesize q) | 64 | dsaTruncate (Vincent.DSA.PublicKey (Vincent.DSA.Params _ _ q) _) = BS.take (integerBytesize q) |
65 | {- | ||
66 | ecdsaTruncate (Vincent.ECDSA.PublicKey _ (Vincent.ECDSA.Point x y)) = BS.take (integerBytesize x | ||
67 | + integerBytesize y ) | ||
68 | -} | ||
47 | bhash = hashBySymbol hash_algo . toLazyBS | 69 | bhash = hashBySymbol hash_algo . toLazyBS |
48 | desc = hashAlgoDesc hash_algo | 70 | desc = hashAlgoDesc hash_algo |
49 | hash_algo = OpenPGP.hash_algorithm sig | 71 | hash_algo = OpenPGP.hash_algorithm sig |
50 | maybeKey = OpenPGP.signature_issuer sig >>= find_key keys | 72 | maybeKey = OpenPGP.signature_issuer sig >>= find_key keys |
73 | -- in trace ("maybeKey="++show (fmap OpenPGP.key_algorithm r)) r | ||
51 | 74 | ||