summaryrefslogtreecommitdiff
path: root/Data/OpenPGP/Util/Sign.hs
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2013-12-15 22:06:29 -0500
committerjoe <joe@jerkface.net>2013-12-15 22:06:29 -0500
commit395f75c6b7f66d313b4d44be4ed1317f9d7c7042 (patch)
treef66e931fb49cca89a0faa5bcc6a66c52418505a0 /Data/OpenPGP/Util/Sign.hs
parent8dd042382eb2a676bac6cd266268ef4d3ed2b390 (diff)
Adapted to new ecc solutoin for OpenPGP-Haskell
Diffstat (limited to 'Data/OpenPGP/Util/Sign.hs')
-rw-r--r--Data/OpenPGP/Util/Sign.hs143
1 files changed, 76 insertions, 67 deletions
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
17import qualified Crypto.PubKey.DSA as Vincent.DSA 17import qualified Crypto.PubKey.DSA as Vincent.DSA
18import qualified Crypto.PubKey.RSA as Vincent.RSA 18import qualified Crypto.PubKey.RSA as Vincent.RSA
19import qualified Crypto.PubKey.RSA.PKCS15 as Vincent.RSA 19import qualified Crypto.PubKey.RSA.PKCS15 as Vincent.RSA
20import qualified Crypto.PubKey.ECC.ECDSA as Vincent.ECDSA
20 21
21import Data.OpenPGP.Util.Base 22import Data.OpenPGP.Util.Base
22 23
24privateECDSAkey :: OpenPGP.Packet -> Vincent.ECDSA.PrivateKey
25privateECDSAkey k = Vincent.ECDSA.PrivateKey curve d
26 where
27 d = keyParam 'd' k
28 curve = curveFromOID (keyParam 'c' k)
23 29
24privateDSAkey :: OpenPGP.Packet -> Vincent.DSA.PrivateKey 30privateDSAkey :: OpenPGP.Packet -> Vincent.DSA.PrivateKey
25privateDSAkey k = Vincent.DSA.PrivateKey 31privateDSAkey 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.
48unsafeSign :: (Vincent.CPRG g) => -- CryptoRandomGen g) => 54unsafeSign :: (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)
56unsafeSign keys over hsh keyid timestamp g = (over {OpenPGP.signatures_over = [sig]}, g') 62unsafeSign 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