diff options
author | joe <joe@jerkface.net> | 2016-08-26 01:21:22 -0400 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2019-07-01 09:19:55 -0400 |
commit | 7909c13a18e260af68819be7444829f799cb7c38 (patch) | |
tree | 3cb6f79309555b5638d2fe71af1c3a219a4d7f8b | |
parent | becfa261ce50d9976c3720aaacd06e48488300af (diff) |
WIP: support for cryptonite.
-rw-r--r-- | Data/OpenPGP/Util/Base.hs | 65 | ||||
-rw-r--r-- | Data/OpenPGP/Util/DecryptSecretKey.hs | 67 | ||||
-rw-r--r-- | Data/OpenPGP/Util/Fingerprint.hs | 20 | ||||
-rw-r--r-- | Data/OpenPGP/Util/Gen.hs | 67 | ||||
-rw-r--r-- | Data/OpenPGP/Util/Sign.hs | 31 | ||||
-rw-r--r-- | Data/OpenPGP/Util/Verify.hs | 30 | ||||
-rw-r--r-- | openpgp-util.cabal | 35 | ||||
-rw-r--r-- | tests/suite.hs | 11 |
8 files changed, 246 insertions, 80 deletions
diff --git a/Data/OpenPGP/Util/Base.hs b/Data/OpenPGP/Util/Base.hs index ed0e32c..c1088d8 100644 --- a/Data/OpenPGP/Util/Base.hs +++ b/Data/OpenPGP/Util/Base.hs | |||
@@ -1,10 +1,22 @@ | |||
1 | {-# LANGUAGE CPP #-} | ||
2 | {-# LANGUAGE ExistentialQuantification #-} | ||
3 | {-# LANGUAGE ConstraintKinds #-} | ||
1 | module Data.OpenPGP.Util.Base where | 4 | module Data.OpenPGP.Util.Base where |
2 | 5 | ||
3 | import qualified Data.ByteString as BS | 6 | import qualified Data.ByteString as BS |
4 | import qualified Data.ByteString.Lazy as LZ | 7 | import qualified Data.ByteString.Lazy as LZ |
5 | import Data.Binary (encode) | 8 | import Data.Binary (encode) |
9 | import Data.Word | ||
6 | 10 | ||
7 | import Data.OpenPGP as OpenPGP | 11 | import Data.OpenPGP as OpenPGP |
12 | #if defined(VERSION_cryptonite) | ||
13 | import Crypto.Hash | ||
14 | import Crypto.Hash.Algorithms as Vincent | ||
15 | import qualified Crypto.PubKey.ECC.Types as Vincent.ECDSA | ||
16 | import qualified Data.ByteArray as Bytes | ||
17 | import qualified Crypto.PubKey.ECC.ECDSA as Vincent.ECDSA | ||
18 | import Crypto.PubKey.RSA.PKCS15 (HashAlgorithmASN1) | ||
19 | #else | ||
8 | import Crypto.Hash.MD5 as MD5 | 20 | import Crypto.Hash.MD5 as MD5 |
9 | import Crypto.Hash.SHA1 as SHA1 | 21 | import Crypto.Hash.SHA1 as SHA1 |
10 | import Crypto.Hash.SHA256 as SHA256 | 22 | import Crypto.Hash.SHA256 as SHA256 |
@@ -12,13 +24,34 @@ import Crypto.Hash.SHA384 as SHA384 | |||
12 | import Crypto.Hash.SHA512 as SHA512 | 24 | import Crypto.Hash.SHA512 as SHA512 |
13 | import Crypto.Hash.SHA224 as SHA224 | 25 | import Crypto.Hash.SHA224 as SHA224 |
14 | import Crypto.Hash.RIPEMD160 as RIPEMD160 | 26 | import Crypto.Hash.RIPEMD160 as RIPEMD160 |
15 | import qualified Crypto.PubKey.RSA as Vincent.RSA | ||
16 | import Crypto.PubKey.HashDescr as Vincent | 27 | import Crypto.PubKey.HashDescr as Vincent |
17 | import qualified Crypto.Types.PubKey.ECC as Vincent.ECDSA | 28 | import qualified Crypto.Types.PubKey.ECC as Vincent.ECDSA |
18 | import qualified Crypto.Types.PubKey.ECDSA as Vincent.ECDSA | 29 | import qualified Crypto.Types.PubKey.ECDSA as Vincent.ECDSA |
30 | #endif | ||
31 | import qualified Crypto.PubKey.RSA as Vincent.RSA | ||
32 | import qualified Crypto.Random as Vincent | ||
19 | 33 | ||
20 | import Data.OpenPGP.Util.Fingerprint (fingerprint) | 34 | import Data.OpenPGP.Util.Fingerprint (fingerprint) |
21 | 35 | ||
36 | #if defined(VERSION_cryptonite) | ||
37 | import Data.Hourglass | ||
38 | import System.Hourglass | ||
39 | import Control.Arrow (second) | ||
40 | import Data.Binary (decode) | ||
41 | #else | ||
42 | import qualified Data.Time.Clock.POSIX | ||
43 | #endif | ||
44 | |||
45 | hashBySymbol :: OpenPGP.HashAlgorithm -> LZ.ByteString -> BS.ByteString | ||
46 | #if defined(VERSION_cryptonite) | ||
47 | hashBySymbol OpenPGP.MD5 x = Bytes.convert (hashlazy x :: Digest MD5) | ||
48 | hashBySymbol OpenPGP.SHA1 x = Bytes.convert (hashlazy x :: Digest SHA1) | ||
49 | hashBySymbol OpenPGP.SHA256 x = Bytes.convert (hashlazy x :: Digest SHA256) | ||
50 | hashBySymbol OpenPGP.SHA384 x = Bytes.convert (hashlazy x :: Digest SHA384) | ||
51 | hashBySymbol OpenPGP.SHA512 x = Bytes.convert (hashlazy x :: Digest SHA512) | ||
52 | hashBySymbol OpenPGP.SHA224 x = Bytes.convert (hashlazy x :: Digest SHA224) | ||
53 | hashBySymbol OpenPGP.RIPEMD160 x = Bytes.convert (hashlazy x :: Digest RIPEMD160) | ||
54 | #else | ||
22 | hashBySymbol OpenPGP.MD5 = MD5.hashlazy | 55 | hashBySymbol OpenPGP.MD5 = MD5.hashlazy |
23 | hashBySymbol OpenPGP.SHA1 = SHA1.hashlazy | 56 | hashBySymbol OpenPGP.SHA1 = SHA1.hashlazy |
24 | hashBySymbol OpenPGP.SHA256 = SHA256.hashlazy | 57 | hashBySymbol OpenPGP.SHA256 = SHA256.hashlazy |
@@ -26,6 +59,7 @@ hashBySymbol OpenPGP.SHA384 = SHA384.hashlazy | |||
26 | hashBySymbol OpenPGP.SHA512 = SHA512.hashlazy | 59 | hashBySymbol OpenPGP.SHA512 = SHA512.hashlazy |
27 | hashBySymbol OpenPGP.SHA224 = SHA224.hashlazy | 60 | hashBySymbol OpenPGP.SHA224 = SHA224.hashlazy |
28 | hashBySymbol OpenPGP.RIPEMD160 = RIPEMD160.hashlazy | 61 | hashBySymbol OpenPGP.RIPEMD160 = RIPEMD160.hashlazy |
62 | #endif | ||
29 | 63 | ||
30 | curveFromOID :: Integer -> Vincent.ECDSA.Curve | 64 | curveFromOID :: Integer -> Vincent.ECDSA.Curve |
31 | curveFromOID 0x2a8648ce3d030107 = Vincent.ECDSA.getCurveByName Vincent.ECDSA.SEC_p256r1 -- NIST P-256 | 65 | curveFromOID 0x2a8648ce3d030107 = Vincent.ECDSA.getCurveByName Vincent.ECDSA.SEC_p256r1 -- NIST P-256 |
@@ -74,6 +108,17 @@ rsaKey k = | |||
74 | 108 | ||
75 | -- http://tools.ietf.org/html/rfc3447#page-43 | 109 | -- http://tools.ietf.org/html/rfc3447#page-43 |
76 | -- http://tools.ietf.org/html/rfc4880#section-5.2.2 | 110 | -- http://tools.ietf.org/html/rfc4880#section-5.2.2 |
111 | #if defined(VERSION_cryptonite) | ||
112 | data HashDescr = forall hashAlg. HashAlgorithmASN1 hashAlg => HashDescr hashAlg | ||
113 | |||
114 | hashAlgoDesc OpenPGP.MD5 = HashDescr Vincent.MD5 | ||
115 | hashAlgoDesc OpenPGP.SHA1 = HashDescr Vincent.SHA1 | ||
116 | hashAlgoDesc OpenPGP.RIPEMD160 = HashDescr Vincent.RIPEMD160 | ||
117 | hashAlgoDesc OpenPGP.SHA256 = HashDescr Vincent.SHA256 | ||
118 | hashAlgoDesc OpenPGP.SHA384 = HashDescr Vincent.SHA384 | ||
119 | hashAlgoDesc OpenPGP.SHA512 = HashDescr Vincent.SHA512 | ||
120 | hashAlgoDesc OpenPGP.SHA224 = HashDescr Vincent.SHA224 | ||
121 | #else | ||
77 | hashAlgoDesc OpenPGP.MD5 = Vincent.hashDescrMD5 | 122 | hashAlgoDesc OpenPGP.MD5 = Vincent.hashDescrMD5 |
78 | hashAlgoDesc OpenPGP.SHA1 = Vincent.hashDescrSHA1 | 123 | hashAlgoDesc OpenPGP.SHA1 = Vincent.hashDescrSHA1 |
79 | hashAlgoDesc OpenPGP.RIPEMD160 = Vincent.hashDescrRIPEMD160 | 124 | hashAlgoDesc OpenPGP.RIPEMD160 = Vincent.hashDescrRIPEMD160 |
@@ -81,7 +126,25 @@ hashAlgoDesc OpenPGP.SHA256 = Vincent.hashDescrSHA256 | |||
81 | hashAlgoDesc OpenPGP.SHA384 = Vincent.hashDescrSHA384 | 126 | hashAlgoDesc OpenPGP.SHA384 = Vincent.hashDescrSHA384 |
82 | hashAlgoDesc OpenPGP.SHA512 = Vincent.hashDescrSHA512 | 127 | hashAlgoDesc OpenPGP.SHA512 = Vincent.hashDescrSHA512 |
83 | hashAlgoDesc OpenPGP.SHA224 = Vincent.hashDescrSHA224 | 128 | hashAlgoDesc OpenPGP.SHA224 = Vincent.hashDescrSHA224 |
129 | #endif | ||
84 | hashAlgoDesc _ = | 130 | hashAlgoDesc _ = |
85 | error "Unsupported HashAlgorithm in hashAlgoDesc" | 131 | error "Unsupported HashAlgorithm in hashAlgoDesc" |
86 | 132 | ||
87 | 133 | ||
134 | currentTime :: Integral b => IO b | ||
135 | #if defined(VERSION_hourglass) | ||
136 | currentTime = fromIntegral . toSeconds <$> dateCurrent | ||
137 | where | ||
138 | toSeconds vincentTime = t | ||
139 | where (Elapsed (Seconds t)) = timeGetElapsed vincentTime | ||
140 | #else | ||
141 | currentTime = floor <$> Data.Time.Clock.POSIX.getPOSIXTime | ||
142 | #endif | ||
143 | |||
144 | |||
145 | #if defined(VERSION_cryptonite) | ||
146 | type RG = Vincent.DRG | ||
147 | #else | ||
148 | type RG = Vincent.CPRG | ||
149 | #endif | ||
150 | |||
diff --git a/Data/OpenPGP/Util/DecryptSecretKey.hs b/Data/OpenPGP/Util/DecryptSecretKey.hs index 9b63c8e..01728d3 100644 --- a/Data/OpenPGP/Util/DecryptSecretKey.hs +++ b/Data/OpenPGP/Util/DecryptSecretKey.hs | |||
@@ -21,24 +21,29 @@ import Control.Exception as Exception (IOException(..),catch) | |||
21 | import Data.Binary.Put (runPut) | 21 | import Data.Binary.Put (runPut) |
22 | import Control.Applicative ( (<$>) ) | 22 | import Control.Applicative ( (<$>) ) |
23 | 23 | ||
24 | import Crypto.Hash.SHA1 as SHA1 | ||
25 | |||
26 | import qualified Crypto.Cipher.AES as Vincent | 24 | import qualified Crypto.Cipher.AES as Vincent |
27 | import qualified Crypto.Cipher.Blowfish as Vincent | 25 | import qualified Crypto.Cipher.Blowfish as Vincent |
28 | 26 | ||
29 | import qualified Crypto.Cipher.Types as Vincent | 27 | import qualified Crypto.Cipher.Types as Vincent |
28 | |||
29 | #if defined(VERSION_cryptonite) | ||
30 | import qualified Data.ByteArray as Bytes | ||
31 | import Crypto.Hash.Algorithms | ||
32 | import Crypto.Hash | ||
33 | import Crypto.Error | ||
34 | #else | ||
30 | import qualified Data.Byteable as Vincent | 35 | import qualified Data.Byteable as Vincent |
36 | import Crypto.Hash.SHA1 as SHA1 | ||
37 | #endif | ||
31 | 38 | ||
32 | import qualified Crypto.Random as Vincent | 39 | import qualified Crypto.Random as Vincent |
33 | 40 | ||
34 | import Crypto.Cipher.Cast5 (CAST5_128) | 41 | import Crypto.Cipher.Cast5 (CAST5_128) |
35 | import Crypto.Cipher.ThomasToVincent | 42 | import Crypto.Cipher.ThomasToVincent |
36 | import Data.OpenPGP.Util.Base (toStrictBS,toLazyBS,hashBySymbol) | 43 | import Data.OpenPGP.Util.Base |
44 | import Data.OpenPGP.Util.Gen (makeGen) | ||
37 | 45 | ||
38 | 46 | data Enciphered = | |
39 | |||
40 | |||
41 | data Enciphered = | ||
42 | EncipheredWithIV !LZ.ByteString -- initial vector is appended to front of ByteString | 47 | EncipheredWithIV !LZ.ByteString -- initial vector is appended to front of ByteString |
43 | | EncipheredZeroIV !LZ.ByteString -- initial vector is zero, ByteString contains only the block | 48 | | EncipheredZeroIV !LZ.ByteString -- initial vector is zero, ByteString contains only the block |
44 | 49 | ||
@@ -47,9 +52,13 @@ withIV f (EncipheredWithIV s) = f iv bs | |||
47 | where | 52 | where |
48 | Just iv = Vincent.makeIV (toStrictBS ivbs) | 53 | Just iv = Vincent.makeIV (toStrictBS ivbs) |
49 | (ivbs,bs) = LZ.splitAt (fromIntegral ivlen) s | 54 | (ivbs,bs) = LZ.splitAt (fromIntegral ivlen) s |
55 | #if defined(VERSION_cryptonite) | ||
56 | ivlen = Bytes.length iv | ||
57 | #else | ||
50 | ivlen = Vincent.byteableLength z | 58 | ivlen = Vincent.byteableLength z |
51 | z = Vincent.nullIV | ||
52 | _ = Vincent.constEqBytes z iv | 59 | _ = Vincent.constEqBytes z iv |
60 | z = Vincent.nullIV | ||
61 | #endif | ||
53 | withIV f (EncipheredZeroIV s) = f Vincent.nullIV s | 62 | withIV f (EncipheredZeroIV s) = f Vincent.nullIV s |
54 | 63 | ||
55 | decryptSecretKey :: | 64 | decryptSecretKey :: |
@@ -76,11 +85,17 @@ decryptSecretKey pass k@(OpenPGP.SecretKeyPacket { | |||
76 | (OpenPGP.secret_key_fields kalgo)) material | 85 | (OpenPGP.secret_key_fields kalgo)) material |
77 | (material, chk) = LZ.splitAt (LZ.length decd - chkSize) decd | 86 | (material, chk) = LZ.splitAt (LZ.length decd - chkSize) decd |
78 | (chkSize, chkF) | 87 | (chkSize, chkF) |
79 | | OpenPGP.s2k_useage k == 254 = (20, SHA1.hash . toStrictBS) | 88 | | OpenPGP.s2k_useage k == 254 = (20, sha1 . toStrictBS) |
80 | | otherwise = (2, toStrictBS . encode . checksum . toStrictBS) | 89 | | otherwise = (2, toStrictBS . encode . checksum . toStrictBS) |
81 | -- Words16s are written as 2 bytes in big-endian (network) order | 90 | -- Words16s are written as 2 bytes in big-endian (network) order |
82 | decd = withS2K simpleUnCFB salgo s2k (toLazyBS pass) (EncipheredWithIV encd) | 91 | decd = withS2K simpleUnCFB salgo s2k (toLazyBS pass) (EncipheredWithIV encd) |
83 | 92 | ||
93 | #if defined(VERSION_cryptonite) | ||
94 | sha1 x = Bytes.convert (hash x :: Digest SHA1) | ||
95 | #else | ||
96 | sha1 = SHA1.hash | ||
97 | #endif | ||
98 | |||
84 | decryptSecretKey _ _ = Nothing | 99 | decryptSecretKey _ _ = Nothing |
85 | 100 | ||
86 | checksum :: BS.ByteString -> Word16 | 101 | checksum :: BS.ByteString -> Word16 |
@@ -111,7 +126,8 @@ withS2K codec OpenPGP.AES128 s2k s = withIV $ codec (string2key s2k s :: Vince | |||
111 | withS2K codec OpenPGP.AES192 s2k s = withIV $ codec (string2key s2k s :: Vincent.AES192) | 126 | withS2K codec OpenPGP.AES192 s2k s = withIV $ codec (string2key s2k s :: Vincent.AES192) |
112 | withS2K codec OpenPGP.AES256 s2k s = withIV $ codec (string2key s2k s :: Vincent.AES256) | 127 | withS2K codec OpenPGP.AES256 s2k s = withIV $ codec (string2key s2k s :: Vincent.AES256) |
113 | withS2K codec OpenPGP.Blowfish s2k s = withIV $ codec (string2key s2k s :: Vincent.Blowfish128) | 128 | withS2K codec OpenPGP.Blowfish s2k s = withIV $ codec (string2key s2k s :: Vincent.Blowfish128) |
114 | withS2K codec OpenPGP.CAST5 s2k s = withIV $ codec (string2key s2k s :: ThomasToVincent CAST5_128) | 129 | -- TODO: cast5 support |
130 | -- withS2K codec OpenPGP.CAST5 s2k s = withIV $ codec (string2key s2k s :: ThomasToVincent CAST5_128) | ||
115 | withS2K codec algo _ _ = error $ "Unsupported symmetric algorithm : " ++ show algo ++ " in Data.OpenPGP.CryptoAPI.withS2K" | 131 | withS2K codec algo _ _ = error $ "Unsupported symmetric algorithm : " ++ show algo ++ " in Data.OpenPGP.CryptoAPI.withS2K" |
116 | 132 | ||
117 | withS2K' :: OpenPGP.SymmetricAlgorithm -> OpenPGP.S2K -> LZ.ByteString | 133 | withS2K' :: OpenPGP.SymmetricAlgorithm -> OpenPGP.S2K -> LZ.ByteString |
@@ -120,21 +136,27 @@ withS2K' OpenPGP.AES128 s2k s f = f (string2key s2k s :: Vincent.AES128) | |||
120 | withS2K' OpenPGP.AES192 s2k s f = f (string2key s2k s :: Vincent.AES192) | 136 | withS2K' OpenPGP.AES192 s2k s f = f (string2key s2k s :: Vincent.AES192) |
121 | withS2K' OpenPGP.AES256 s2k s f = f (string2key s2k s :: Vincent.AES256) | 137 | withS2K' OpenPGP.AES256 s2k s f = f (string2key s2k s :: Vincent.AES256) |
122 | withS2K' OpenPGP.Blowfish s2k s f = f (string2key s2k s :: Vincent.Blowfish128) | 138 | withS2K' OpenPGP.Blowfish s2k s f = f (string2key s2k s :: Vincent.Blowfish128) |
123 | withS2K' OpenPGP.CAST5 s2k s f = f (string2key s2k s :: ThomasToVincent CAST5_128) | 139 | -- TODO: cast5 support |
140 | -- withS2K' OpenPGP.CAST5 s2k s f = f (string2key s2k s :: ThomasToVincent CAST5_128) | ||
124 | 141 | ||
125 | -- decryption codec for withS2K | 142 | -- decryption codec for withS2K |
126 | simpleUnCFB :: (Vincent.BlockCipher k) => k -> Vincent.IV k -> LZ.ByteString -> LZ.ByteString | 143 | simpleUnCFB :: (Vincent.BlockCipher k) => k -> Vincent.IV k -> LZ.ByteString -> LZ.ByteString |
127 | simpleUnCFB k iv = padThenUnpad k (toLazyBS . Vincent.cfbDecrypt k iv . toStrictBS) | 144 | simpleUnCFB k iv = padThenUnpad k (toLazyBS . Vincent.cfbDecrypt k iv . toStrictBS) |
128 | 145 | ||
129 | simpleCFB :: (Vincent.BlockCipher k, Vincent.CPRG g) => g -> k -> LZ.ByteString -> (LZ.ByteString, g) | 146 | simpleCFB :: (Vincent.BlockCipher k, RG g) => g -> k -> LZ.ByteString -> (LZ.ByteString, g) |
130 | simpleCFB g k bs = ( padThenUnpad k (LZ.fromChunks . (ivbs:) . (:[]) . Vincent.cfbEncrypt k iv . toStrictBS) bs | 147 | simpleCFB g k bs = ( padThenUnpad k (LZ.fromChunks . (ivbs:) . (:[]) . Vincent.cfbEncrypt k iv . toStrictBS) bs |
131 | , g' ) | 148 | , g' ) |
132 | where | 149 | where |
133 | Just iv = Vincent.makeIV ivbs | 150 | Just iv = Vincent.makeIV ivbs |
151 | #if defined(VERSION_cryptonite) | ||
152 | (ivbs,g') = Vincent.randomBytesGenerate ivlen g | ||
153 | ivlen = Bytes.length iv | ||
154 | #else | ||
155 | z = Vincent.nullIV | ||
134 | (ivbs,g') = Vincent.cprgGenerate ivlen g | 156 | (ivbs,g') = Vincent.cprgGenerate ivlen g |
135 | ivlen = Vincent.byteableLength z | 157 | ivlen = Vincent.byteableLength z |
136 | z = Vincent.nullIV | ||
137 | _ = Vincent.constEqBytes z iv | 158 | _ = Vincent.constEqBytes z iv |
159 | #endif | ||
138 | 160 | ||
139 | -- Apply a function f to a zero-padded bytestring s to a multiple | 161 | -- Apply a function f to a zero-padded bytestring s to a multiple |
140 | -- of the blocksize for cyper k. | 162 | -- of the blocksize for cyper k. |
@@ -147,12 +169,28 @@ padThenUnpad k f s = dropPadEnd (f padded) | |||
147 | padAmount = blksize - (LZ.length s `mod` blksize) | 169 | padAmount = blksize - (LZ.length s `mod` blksize) |
148 | blksize = fromIntegral $ Vincent.blockSize k | 170 | blksize = fromIntegral $ Vincent.blockSize k |
149 | 171 | ||
172 | {- | ||
173 | Data/OpenPGP/Util/DecryptSecretKey.hs:172:20: | ||
174 | Couldn't match expected type ‘k’ | ||
175 | with actual type ‘cryptonite-0.15:Crypto.Error.Types.CryptoFailable | ||
176 | cipher0’ | ||
177 | ‘k’ is a rigid type variable bound by | ||
178 | the type signature for | ||
179 | string2key :: Vincent.BlockCipher k => | ||
180 | OpenPGP.S2K -> LZ.ByteString -> k | ||
181 | at Data/OpenPGP/Util/DecryptSecretKey.hs:171:15 | ||
182 | -} | ||
150 | string2key :: (Vincent.BlockCipher k) => OpenPGP.S2K -> LZ.ByteString -> k | 183 | string2key :: (Vincent.BlockCipher k) => OpenPGP.S2K -> LZ.ByteString -> k |
151 | string2key s2k s = cipher | 184 | string2key s2k s = cipher |
152 | where | 185 | where |
186 | #if defined(VERSION_cryptonite) | ||
187 | CryptoPassed cipher = Vincent.cipherInit k | ||
188 | k = toStrictBS $ LZ.take ksize $ OpenPGP.string2key hashBySymbol s2k s | ||
189 | #else | ||
153 | cipher = Vincent.cipherInit k | 190 | cipher = Vincent.cipherInit k |
154 | Right k = Vincent.makeKey $ toStrictBS $ | 191 | Right k = Vincent.makeKey $ toStrictBS $ |
155 | LZ.take ksize $ OpenPGP.string2key hashBySymbol s2k s | 192 | LZ.take ksize $ OpenPGP.string2key hashBySymbol s2k s |
193 | #endif | ||
156 | ksize = case Vincent.cipherKeySize cipher of | 194 | ksize = case Vincent.cipherKeySize cipher of |
157 | Vincent.KeySizeFixed n -> fromIntegral n | 195 | Vincent.KeySizeFixed n -> fromIntegral n |
158 | Vincent.KeySizeEnum xs -> error $ "Unknown key size in string2key" | 196 | Vincent.KeySizeEnum xs -> error $ "Unknown key size in string2key" |
@@ -164,8 +202,7 @@ catchIO_ a h = Exception.catch a (\(_ :: IOException) -> h) | |||
164 | encryptSecretKey :: BS.ByteString -> OpenPGP.S2K -> OpenPGP.SymmetricAlgorithm -> OpenPGP.Packet -> IO (Maybe OpenPGP.Packet) | 202 | encryptSecretKey :: BS.ByteString -> OpenPGP.S2K -> OpenPGP.SymmetricAlgorithm -> OpenPGP.Packet -> IO (Maybe OpenPGP.Packet) |
165 | encryptSecretKey passphrase s2k salgo plain = do | 203 | encryptSecretKey passphrase s2k salgo plain = do |
166 | flip catchIO_ (return Nothing) $ do | 204 | flip catchIO_ (return Nothing) $ do |
167 | g <- fmap Vincent.cprgCreate $ Vincent.createEntropyPool | 205 | g <- makeGen Nothing |
168 | let _ = g :: Vincent.SystemRNG | ||
169 | return $ Just | 206 | return $ Just |
170 | plain { OpenPGP.key = [ x | x <- OpenPGP.key plain | 207 | plain { OpenPGP.key = [ x | x <- OpenPGP.key plain |
171 | , fst x `elem` OpenPGP.public_key_fields (OpenPGP.key_algorithm plain) ] | 208 | , fst x `elem` OpenPGP.public_key_fields (OpenPGP.key_algorithm plain) ] |
diff --git a/Data/OpenPGP/Util/Fingerprint.hs b/Data/OpenPGP/Util/Fingerprint.hs index 538688b..20b6e72 100644 --- a/Data/OpenPGP/Util/Fingerprint.hs +++ b/Data/OpenPGP/Util/Fingerprint.hs | |||
@@ -1,3 +1,4 @@ | |||
1 | {-# LANGUAGE CPP #-} | ||
1 | module Data.OpenPGP.Util.Fingerprint (fingerprint) where | 2 | module Data.OpenPGP.Util.Fingerprint (fingerprint) where |
2 | 3 | ||
3 | import qualified Data.OpenPGP as OpenPGP | 4 | import qualified Data.OpenPGP as OpenPGP |
@@ -7,17 +8,32 @@ import Data.Char (toUpper) | |||
7 | import Data.Word (Word8) | 8 | import Data.Word (Word8) |
8 | import Numeric (showHex) | 9 | import Numeric (showHex) |
9 | 10 | ||
11 | #if defined(VERSION_cryptonite) | ||
12 | import Crypto.Hash.Algorithms | ||
13 | import Crypto.Hash | ||
14 | import qualified Data.ByteArray as Bytes | ||
15 | #else | ||
10 | import Crypto.Hash.MD5 as MD5 | 16 | import Crypto.Hash.MD5 as MD5 |
11 | import Crypto.Hash.SHA1 as SHA1 | 17 | import Crypto.Hash.SHA1 as SHA1 |
18 | #endif | ||
12 | 19 | ||
13 | -- | Generate a key fingerprint from a PublicKeyPacket or SecretKeyPacket | 20 | -- | Generate a key fingerprint from a PublicKeyPacket or SecretKeyPacket |
14 | -- <http://tools.ietf.org/html/rfc4880#section-12.2> | 21 | -- <http://tools.ietf.org/html/rfc4880#section-12.2> |
15 | fingerprint :: OpenPGP.Packet -> String | 22 | fingerprint :: OpenPGP.Packet -> String |
16 | fingerprint p | 23 | fingerprint p |
17 | | OpenPGP.version p == 4 = hexify $ SHA1.hashlazy material | 24 | | OpenPGP.version p == 4 = hexify $ sha1 material |
18 | | OpenPGP.version p `elem` [2, 3] = hexify $ MD5.hashlazy material | 25 | | OpenPGP.version p `elem` [2, 3] = hexify $ md5 material |
19 | | otherwise = error "Unsupported Packet version or type in fingerprint" | 26 | | otherwise = error "Unsupported Packet version or type in fingerprint" |
20 | where | 27 | where |
28 | |||
29 | #if defined(VERSION_cryptonite) | ||
30 | sha1 x = Bytes.convert (hashlazy x :: Digest SHA1) | ||
31 | md5 x = Bytes.convert (hashlazy x :: Digest MD5) | ||
32 | #else | ||
33 | sha1 = SHA1.hashlazy | ||
34 | md5 = MD5.hashlazy | ||
35 | #endif | ||
36 | |||
21 | material = LZ.concat $ OpenPGP.fingerprint_material p | 37 | material = LZ.concat $ OpenPGP.fingerprint_material p |
22 | 38 | ||
23 | hexify = map toUpper . hexString . BS.unpack | 39 | hexify = map toUpper . hexString . BS.unpack |
diff --git a/Data/OpenPGP/Util/Gen.hs b/Data/OpenPGP/Util/Gen.hs index b64517f..c5d0159 100644 --- a/Data/OpenPGP/Util/Gen.hs +++ b/Data/OpenPGP/Util/Gen.hs | |||
@@ -8,13 +8,17 @@ import Control.Applicative | |||
8 | import qualified Data.ByteString.Lazy as B | 8 | import qualified Data.ByteString.Lazy as B |
9 | import qualified Data.ByteString as S | 9 | import qualified Data.ByteString as S |
10 | 10 | ||
11 | import qualified Crypto.Random as Vincent | 11 | import Crypto.Random as Vincent |
12 | import qualified Crypto.PubKey.DSA as Vincent.DSA | 12 | import qualified Crypto.PubKey.DSA as Vincent.DSA |
13 | import qualified Crypto.PubKey.RSA as Vincent.RSA | 13 | import qualified Crypto.PubKey.RSA as Vincent.RSA |
14 | import qualified Crypto.PubKey.RSA.PKCS15 as Vincent.RSA | 14 | import qualified Crypto.PubKey.RSA.PKCS15 as Vincent.RSA |
15 | import qualified Crypto.PubKey.ECC.ECDSA as Vincent.ECDSA | 15 | import qualified Crypto.PubKey.ECC.ECDSA as Vincent.ECDSA |
16 | #if defined(VERSION_cryptonite) | ||
17 | import Control.Arrow (second) | ||
18 | import Data.Binary | ||
19 | #endif | ||
16 | 20 | ||
17 | import qualified Data.Time.Clock.POSIX | 21 | import Data.OpenPGP.Util.Base |
18 | 22 | ||
19 | data GenerateKeyParams = GenRSA Int -- keysize | 23 | data GenerateKeyParams = GenRSA Int -- keysize |
20 | | GenDSA (Maybe DSAParams) | 24 | | GenDSA (Maybe DSAParams) |
@@ -34,20 +38,10 @@ genKeyAlg (GenDSA _) = DSA | |||
34 | -- | Generate a secret key pgp packet from system entropy. | 38 | -- | Generate a secret key pgp packet from system entropy. |
35 | generateKey :: GenerateKeyParams -> IO Packet | 39 | generateKey :: GenerateKeyParams -> IO Packet |
36 | generateKey params = do | 40 | generateKey params = do |
37 | now <- currentTimeWord32 | 41 | now <- currentTime |
38 | g <- makeGen Nothing | 42 | g <- makeGen Nothing |
39 | let (fields,g') = generateKey' params g | 43 | let (fields,g') = generateKey' params g |
40 | return $ buildPacket (genKeyAlg params) now fields | 44 | return $ buildPacket (genKeyAlg params) now fields |
41 | |||
42 | #if defined(VERSION_crypto_random) | ||
43 | type RNG = Vincent.SystemRNG | ||
44 | |||
45 | makeGen :: Maybe FilePath -> IO RNG | ||
46 | makeGen noisefile = do | ||
47 | pool <- fromMaybe Vincent.createEntropyPool $ do | ||
48 | path <- noisefile | ||
49 | Just $ Vincent.createTestEntropyPool `fmap` S.readFile path | ||
50 | return (Vincent.cprgCreate pool :: Vincent.SystemRNG) | ||
51 | 45 | ||
52 | rsaFields priv = [ ('n', MPI $ Vincent.RSA.public_n (Vincent.RSA.private_pub priv)) | 46 | rsaFields priv = [ ('n', MPI $ Vincent.RSA.public_n (Vincent.RSA.private_pub priv)) |
53 | , ('e', MPI $ Vincent.RSA.public_e (Vincent.RSA.private_pub priv)) | 47 | , ('e', MPI $ Vincent.RSA.public_e (Vincent.RSA.private_pub priv)) |
@@ -66,6 +60,17 @@ dsaFields priv = [ ('p', MPI p) | |||
66 | g = Vincent.DSA.params_g $ Vincent.DSA.private_params priv | 60 | g = Vincent.DSA.params_g $ Vincent.DSA.private_params priv |
67 | p = Vincent.DSA.params_p $ Vincent.DSA.private_params priv | 61 | p = Vincent.DSA.params_p $ Vincent.DSA.private_params priv |
68 | 62 | ||
63 | |||
64 | #if defined(VERSION_crypto_random) | ||
65 | type RNG = Vincent.SystemRNG | ||
66 | |||
67 | makeGen :: Maybe FilePath -> IO RNG | ||
68 | makeGen noisefile = do | ||
69 | pool <- fromMaybe Vincent.createEntropyPool $ do | ||
70 | path <- noisefile | ||
71 | Just $ Vincent.createTestEntropyPool `fmap` S.readFile path | ||
72 | return (Vincent.cprgCreate pool :: Vincent.SystemRNG) | ||
73 | |||
69 | generateKey' :: GenerateKeyParams -> RNG -> ([(Char,MPI)],RNG) | 74 | generateKey' :: GenerateKeyParams -> RNG -> ([(Char,MPI)],RNG) |
70 | generateKey' (GenRSA keysize) g = | 75 | generateKey' (GenRSA keysize) g = |
71 | let -- http://crypto.stackexchange.com/questions/3110/impacts-of-not-using-rsa-exponent-of-65537 | 76 | let -- http://crypto.stackexchange.com/questions/3110/impacts-of-not-using-rsa-exponent-of-65537 |
@@ -93,33 +98,27 @@ makeGen :: Maybe FilePath -> IO RNG | |||
93 | makeGen noisefile = do | 98 | makeGen noisefile = do |
94 | drg <- fromMaybe (Left <$> getSystemDRG) $ do | 99 | drg <- fromMaybe (Left <$> getSystemDRG) $ do |
95 | path <- noisefile | 100 | path <- noisefile |
96 | Just $ Right . drgNewTest . decodeSeed <$> L.readFile path | 101 | Just $ Right . drgNewTest . decodeSeed <$> B.readFile path |
97 | return $ RNG drg | 102 | return $ RNG drg |
98 | where | 103 | where |
99 | decodeSeed :: L.ByteString -> (Word64, Word64, Word64, Word64, Word64) | 104 | decodeSeed :: B.ByteString -> (Word64, Word64, Word64, Word64, Word64) |
100 | decodeSeed bs | L.null bs = (0,0,0,0,0) | 105 | decodeSeed bs | B.null bs = (0,0,0,0,0) |
101 | | otherwise = decode $ L.cycle bs | 106 | | otherwise = decode $ B.cycle bs |
102 | |||
103 | instance MonadRandom DB where | ||
104 | getRandomBytes n = DB 4 $ \DBParams { dbRNG=rngv } _ -> do | ||
105 | bs <- modifyMVar rngv (return . swap . randomBytesGenerate n) | ||
106 | return $ Right bs | ||
107 | 107 | ||
108 | generateKey' :: GenerateKeyParams -> RNG -> (PrivateKey,RNG) | 108 | generateKey' :: GenerateKeyParams -> RNG -> ([(Char,MPI)],RNG) |
109 | generateKey' (GenRSA keysize) g = | 109 | generateKey' (GenRSA keysize) g = |
110 | let rsa_exponent = 65537 | 110 | let rsa_exponent = 65537 |
111 | ((_,priv),g') = withDRG g $ RSA.generate keysize rsa_exponent | 111 | ((_,priv),g') = withDRG g $ Vincent.RSA.generate keysize rsa_exponent |
112 | in ( PrivateRSA priv, g' ) | 112 | in ( rsaFields priv, g' ) |
113 | generateKey' (GenDSA mbparams) g = | 113 | generateKey' (GenDSA mbparams) g = |
114 | let dsa_params = fromMaybe defaultDSAParams mbparams | 114 | let dsa_params = maybe defaultDSAParams vincent mbparams |
115 | (priv,g') = withDRG g $ DSA.generatePrivate dsa_params | 115 | vincent (DSAParams p g q) = Vincent.DSA.Params p g q |
116 | in ( PrivateDSA (DSA.PrivateKey dsa_params priv), g' ) | 116 | (priv,g') = withDRG g $ Vincent.DSA.generatePrivate dsa_params |
117 | in ( dsaFields (Vincent.DSA.PrivateKey dsa_params priv), g' ) | ||
117 | 118 | ||
118 | #endif | 119 | #endif |
119 | 120 | ||
120 | 121 | ||
121 | currentTimeWord32 :: IO Word32 | ||
122 | currentTimeWord32 = floor <$> Data.Time.Clock.POSIX.getPOSIXTime | ||
123 | 122 | ||
124 | buildPacket :: KeyAlgorithm -> Word32 -> [(Char,MPI)] -> Packet | 123 | buildPacket :: KeyAlgorithm -> Word32 -> [(Char,MPI)] -> Packet |
125 | buildPacket alg stamp fields = | 124 | buildPacket alg stamp fields = |
@@ -133,7 +132,7 @@ buildPacket alg stamp fields = | |||
133 | symmetric_algorithm = Unencrypted :: SymmetricAlgorithm, | 132 | symmetric_algorithm = Unencrypted :: SymmetricAlgorithm, |
134 | encrypted_data = B.empty :: B.ByteString, | 133 | encrypted_data = B.empty :: B.ByteString, |
135 | is_subkey = True :: Bool | 134 | is_subkey = True :: Bool |
136 | } | 135 | } |
137 | 136 | ||
138 | defaultDSAParams :: Vincent.DSA.Params | 137 | defaultDSAParams :: Vincent.DSA.Params |
139 | defaultDSAParams = Vincent.DSA.Params | 138 | defaultDSAParams = Vincent.DSA.Params |
diff --git a/Data/OpenPGP/Util/Sign.hs b/Data/OpenPGP/Util/Sign.hs index 466f05c..8663a0d 100644 --- a/Data/OpenPGP/Util/Sign.hs +++ b/Data/OpenPGP/Util/Sign.hs | |||
@@ -1,4 +1,5 @@ | |||
1 | {-# LANGUAGE ScopedTypeVariables #-} | 1 | {-# LANGUAGE ScopedTypeVariables #-} |
2 | {-# LANGUAGE CPP #-} | ||
2 | module Data.OpenPGP.Util.Sign where | 3 | module Data.OpenPGP.Util.Sign where |
3 | 4 | ||
4 | import qualified Data.OpenPGP as OpenPGP | 5 | import qualified Data.OpenPGP as OpenPGP |
@@ -8,10 +9,16 @@ import qualified Data.ByteString as BS | |||
8 | import qualified Data.ByteString.Lazy as LZ | 9 | import qualified Data.ByteString.Lazy as LZ |
9 | import Data.Bits ( (.|.), shiftL ) | 10 | import Data.Bits ( (.|.), shiftL ) |
10 | import Control.Applicative ( (<$>) ) | 11 | import Control.Applicative ( (<$>) ) |
12 | #if defined(VERSION_cryptonite) | ||
13 | import Data.Hourglass | ||
14 | import System.Hourglass | ||
15 | #else | ||
11 | import Data.Time.Clock.POSIX | 16 | import Data.Time.Clock.POSIX |
17 | #endif | ||
12 | import Control.Exception as Exception (IOException(..),catch) | 18 | import Control.Exception as Exception (IOException(..),catch) |
13 | 19 | ||
14 | import Data.OpenPGP.Util.Fingerprint (fingerprint) | 20 | import Data.OpenPGP.Util.Fingerprint (fingerprint) |
21 | import Data.OpenPGP.Util.Gen | ||
15 | 22 | ||
16 | import qualified Crypto.Random as Vincent | 23 | import qualified Crypto.Random as Vincent |
17 | import qualified Crypto.PubKey.DSA as Vincent.DSA | 24 | import qualified Crypto.PubKey.DSA as Vincent.DSA |
@@ -44,14 +51,12 @@ privateRSAkey k = | |||
44 | q = keyParam 'q' k | 51 | q = keyParam 'q' k |
45 | pubkey = rsaKey k | 52 | pubkey = rsaKey k |
46 | 53 | ||
47 | |||
48 | |||
49 | -- | Make a signature | 54 | -- | Make a signature |
50 | -- | 55 | -- |
51 | -- In order to set more options on a signature, pass in a signature packet. | 56 | -- In order to set more options on a signature, pass in a signature packet. |
52 | -- Operation is unsafe in that it silently re-uses "random" bytes when | 57 | -- Operation is unsafe in that it silently re-uses "random" bytes when |
53 | -- entropy runs out. Use pgpSign for a safer interface. | 58 | -- entropy runs out. Use pgpSign for a safer interface. |
54 | unsafeSign :: (Vincent.CPRG g) => -- CryptoRandomGen g) => | 59 | unsafeSign :: (RG g) => -- CryptoRandomGen g) => |
55 | OpenPGP.Message -- ^ SecretKeys, one of which will be used | 60 | OpenPGP.Message -- ^ SecretKeys, one of which will be used |
56 | -> OpenPGP.SignatureOver -- ^ Data to sign, and optional signature packet | 61 | -> OpenPGP.SignatureOver -- ^ Data to sign, and optional signature packet |
57 | -> OpenPGP.HashAlgorithm -- ^ HashAlgorithm to use in signature | 62 | -> OpenPGP.HashAlgorithm -- ^ HashAlgorithm to use in signature |
@@ -67,11 +72,22 @@ unsafeSign keys over hsh keyid timestamp g = (over {OpenPGP.signatures_over = [s | |||
67 | kalgo | kalgo `elem` [OpenPGP.RSA,OpenPGP.RSA_S] -> ([toNum rsaFinal], g) | 72 | kalgo | kalgo `elem` [OpenPGP.RSA,OpenPGP.RSA_S] -> ([toNum rsaFinal], g) |
68 | | otherwise -> | 73 | | otherwise -> |
69 | error ("Unsupported key algorithm " ++ show kalgo ++ " in sign") | 74 | error ("Unsupported key algorithm " ++ show kalgo ++ " in sign") |
75 | #if defined(VERSION_cryptonite) | ||
76 | (Vincent.DSA.Signature dsaR dsaS,dsaG) = let k' = privateDSAkey k in | ||
77 | case desc of | ||
78 | HashDescr h -> Vincent.withDRG g $ Vincent.DSA.sign k' h dta -- XXX: What happend to dsaTruncate ? | ||
79 | (Vincent.ECDSA.Signature ecdsaR ecdsaS,ecdsaG) = let k' = privateECDSAkey k in | ||
80 | case desc of | ||
81 | HashDescr h -> Vincent.withDRG g $ Vincent.ECDSA.sign k' h dta | ||
82 | (Right rsaFinal,_) = case desc of | ||
83 | HashDescr h -> Vincent.withDRG g $ Vincent.RSA.signSafer (Just h) (privateRSAkey k) dta | ||
84 | #else | ||
70 | (Vincent.DSA.Signature dsaR dsaS,dsaG) = let k' = privateDSAkey k in | 85 | (Vincent.DSA.Signature dsaR dsaS,dsaG) = let k' = privateDSAkey k in |
71 | Vincent.DSA.sign g k' (dsaTruncate k' . bhash) dta | 86 | Vincent.DSA.sign g k' (dsaTruncate k' . bhash) dta |
72 | (Vincent.ECDSA.Signature ecdsaR ecdsaS,ecdsaG) = let k' = privateECDSAkey k in | 87 | (Vincent.ECDSA.Signature ecdsaR ecdsaS,ecdsaG) = let k' = privateECDSAkey k in |
73 | Vincent.ECDSA.sign g k' bhash dta | 88 | Vincent.ECDSA.sign g k' bhash dta |
74 | (Right rsaFinal,_) = Vincent.RSA.signSafer g desc (privateRSAkey k) dta | 89 | (Right rsaFinal,_) = Vincent.RSA.signSafer g desc (privateRSAkey k) dta |
90 | #endif | ||
75 | dsaTruncate (Vincent.DSA.PrivateKey (Vincent.DSA.Params _ _ q) _) = BS.take (integerBytesize q) | 91 | dsaTruncate (Vincent.DSA.PrivateKey (Vincent.DSA.Params _ _ q) _) = BS.take (integerBytesize q) |
76 | dta = toStrictBS $ encode over `LZ.append` OpenPGP.trailer sig | 92 | dta = toStrictBS $ encode over `LZ.append` OpenPGP.trailer sig |
77 | sig = findSigOrDefault (listToMaybe $ OpenPGP.signatures_over over) | 93 | sig = findSigOrDefault (listToMaybe $ OpenPGP.signatures_over over) |
@@ -126,8 +142,6 @@ unsafeSign keys over hsh keyid timestamp g = (over {OpenPGP.signatures_over = [s | |||
126 | 142 | ||
127 | 143 | ||
128 | 144 | ||
129 | now = floor <$> Data.Time.Clock.POSIX.getPOSIXTime | ||
130 | |||
131 | stampit timestamp sig = sig { OpenPGP.hashed_subpackets = hashed' } | 145 | stampit timestamp sig = sig { OpenPGP.hashed_subpackets = hashed' } |
132 | where | 146 | where |
133 | hashed_stamps = filter isStamp (OpenPGP.hashed_subpackets sig) | 147 | hashed_stamps = filter isStamp (OpenPGP.hashed_subpackets sig) |
@@ -150,10 +164,11 @@ pgpSign :: | |||
150 | -> IO (Maybe OpenPGP.SignatureOver) | 164 | -> IO (Maybe OpenPGP.SignatureOver) |
151 | pgpSign seckeys dta hash_algo keyid = | 165 | pgpSign seckeys dta hash_algo keyid = |
152 | handleIO_ (return Nothing) $ do | 166 | handleIO_ (return Nothing) $ do |
153 | timestamp <- now | 167 | timestamp <- currentTime |
154 | -- g <- Thomas.newGenIO :: IO Thomas.SystemRandom | 168 | -- g <- Thomas.newGenIO :: IO Thomas.SystemRandom |
155 | g <- fmap Vincent.cprgCreate $ Vincent.createEntropyPool | 169 | -- g <- fmap Vincent.cprgCreate $ Vincent.createEntropyPool |
156 | let _ = g :: Vincent.SystemRNG | 170 | g <- makeGen Nothing |
171 | let _ = g :: RNG | ||
157 | let sigs = map (stampit timestamp) $ OpenPGP.signatures_over dta | 172 | let sigs = map (stampit timestamp) $ OpenPGP.signatures_over dta |
158 | dta' = dta { OpenPGP.signatures_over = sigs } | 173 | dta' = dta { OpenPGP.signatures_over = sigs } |
159 | let (r,g') = unsafeSign seckeys dta' hash_algo keyid timestamp g | 174 | let (r,g') = unsafeSign seckeys dta' hash_algo keyid timestamp g |
diff --git a/Data/OpenPGP/Util/Verify.hs b/Data/OpenPGP/Util/Verify.hs index b42e664..fd83485 100644 --- a/Data/OpenPGP/Util/Verify.hs +++ b/Data/OpenPGP/Util/Verify.hs | |||
@@ -1,4 +1,5 @@ | |||
1 | {-# LANGUAGE OverloadedStrings #-} | 1 | {-# LANGUAGE OverloadedStrings #-} |
2 | {-# LANGUAGE CPP #-} | ||
2 | module Data.OpenPGP.Util.Verify where | 3 | module Data.OpenPGP.Util.Verify where |
3 | 4 | ||
4 | import Debug.Trace | 5 | import Debug.Trace |
@@ -13,6 +14,9 @@ import qualified Crypto.PubKey.DSA as Vincent.DSA | |||
13 | import qualified Crypto.PubKey.RSA.PKCS15 as Vincent.RSA | 14 | import qualified Crypto.PubKey.RSA.PKCS15 as Vincent.RSA |
14 | import qualified Crypto.PubKey.ECC.ECDSA as Vincent.ECDSA | 15 | import qualified Crypto.PubKey.ECC.ECDSA as Vincent.ECDSA |
15 | -- import Math.NumberTheory.Moduli | 16 | -- import Math.NumberTheory.Moduli |
17 | #if !defined(VERSION_cryptonite) | ||
18 | import Crypto.PubKey.HashDescr | ||
19 | #endif | ||
16 | 20 | ||
17 | import Data.OpenPGP.Util.Base | 21 | import Data.OpenPGP.Util.Base |
18 | 22 | ||
@@ -50,12 +54,30 @@ verifyOne keys sig over = fmap (const sig) $ maybeKey >>= verification >>= guard | |||
50 | OpenPGP.ECDSA -> ecdsaVerify | 54 | OpenPGP.ECDSA -> ecdsaVerify |
51 | alg | alg `elem` [OpenPGP.RSA,OpenPGP.RSA_S] -> rsaVerify | 55 | alg | alg `elem` [OpenPGP.RSA,OpenPGP.RSA_S] -> rsaVerify |
52 | | otherwise -> const Nothing | 56 | | otherwise -> const Nothing |
53 | dsaVerify k = let k' = dsaKey k in | 57 | |
58 | #if defined(VERSION_cryptonite) | ||
59 | dsaVerify k = let k' = dsaKey k in | ||
60 | -- XXX: What happened to dsaTruncate? | ||
61 | Just $ case desc of HashDescr h -> Vincent.DSA.verify h k' dsaSig over | ||
62 | #else | ||
63 | dsaVerify k = let k' = dsaKey k in | ||
54 | Just $ Vincent.DSA.verify (dsaTruncate k' . bhash) k' dsaSig over | 64 | Just $ Vincent.DSA.verify (dsaTruncate k' . bhash) k' dsaSig over |
65 | #endif | ||
66 | |||
55 | ecdsaVerify k = let k' = ecdsaKey k | 67 | ecdsaVerify k = let k' = ecdsaKey k |
68 | #if defined(VERSION_cryptonite) | ||
69 | r = Just $ case desc of | ||
70 | HashDescr h -> Vincent.ECDSA.verify h k' ecdsaSig over | ||
71 | #else | ||
56 | r = Just $ Vincent.ECDSA.verify bhash k' ecdsaSig over | 72 | r = Just $ Vincent.ECDSA.verify bhash k' ecdsaSig over |
73 | #endif | ||
57 | in r -- trace ("ecdsaVerify: "++show r) r | 74 | in r -- trace ("ecdsaVerify: "++show r) r |
75 | #if defined(VERSION_cryptonite) | ||
76 | rsaVerify k = Just $ case desc of | ||
77 | HashDescr h -> Vincent.RSA.verify (Just h) (rsaKey k) over rsaSig | ||
78 | #else | ||
58 | rsaVerify k = Just $ Vincent.RSA.verify desc (rsaKey k) over rsaSig | 79 | rsaVerify k = Just $ Vincent.RSA.verify desc (rsaKey k) over rsaSig |
80 | #endif | ||
59 | [rsaSig] = map (toStrictBS . LZ.drop 2 . encode) (OpenPGP.signature sig) | 81 | [rsaSig] = map (toStrictBS . LZ.drop 2 . encode) (OpenPGP.signature sig) |
60 | dsaSig = let [OpenPGP.MPI r, OpenPGP.MPI s] = OpenPGP.signature sig in | 82 | dsaSig = let [OpenPGP.MPI r, OpenPGP.MPI s] = OpenPGP.signature sig in |
61 | Vincent.DSA.Signature r s | 83 | Vincent.DSA.Signature r s |
@@ -66,7 +88,11 @@ verifyOne keys sig over = fmap (const sig) $ maybeKey >>= verification >>= guard | |||
66 | ecdsaTruncate (Vincent.ECDSA.PublicKey _ (Vincent.ECDSA.Point x y)) = BS.take (integerBytesize x | 88 | ecdsaTruncate (Vincent.ECDSA.PublicKey _ (Vincent.ECDSA.Point x y)) = BS.take (integerBytesize x |
67 | + integerBytesize y ) | 89 | + integerBytesize y ) |
68 | -} | 90 | -} |
69 | bhash = hashBySymbol hash_algo . toLazyBS | 91 | #if defined(VERSION_cryptonite) |
92 | -- bhash = case desc of HashDescr alg -> alg | ||
93 | #else | ||
94 | bhash = hashFunction desc | ||
95 | #endif | ||
70 | desc = hashAlgoDesc hash_algo | 96 | desc = hashAlgoDesc hash_algo |
71 | hash_algo = OpenPGP.hash_algorithm sig | 97 | hash_algo = OpenPGP.hash_algorithm sig |
72 | maybeKey = OpenPGP.signature_issuer sig >>= find_key keys | 98 | maybeKey = OpenPGP.signature_issuer sig >>= find_key keys |
diff --git a/openpgp-util.cabal b/openpgp-util.cabal index b62195b..45248d4 100644 --- a/openpgp-util.cabal +++ b/openpgp-util.cabal | |||
@@ -116,6 +116,9 @@ extra-source-files: | |||
116 | tests/data/uncompressed-ops-dsa-sha384.txt.gpg, | 116 | tests/data/uncompressed-ops-dsa-sha384.txt.gpg, |
117 | tests/data/uncompressed-ops-rsa.gpg | 117 | tests/data/uncompressed-ops-rsa.gpg |
118 | 118 | ||
119 | Flag cryptonite | ||
120 | Description: Use newer cryptonite-based libraries. | ||
121 | Default: True | ||
119 | 122 | ||
120 | library | 123 | library |
121 | exposed-modules: | 124 | exposed-modules: |
@@ -133,28 +136,34 @@ library | |||
133 | base == 4.*, | 136 | base == 4.*, |
134 | transformers, | 137 | transformers, |
135 | bytestring, | 138 | bytestring, |
136 | time >= 1.4, | ||
137 | binary >= 0.5.1.0, | 139 | binary >= 0.5.1.0, |
138 | crypto-random >= 0.0.7, | 140 | cipher-cast5, |
139 | cryptohash >= 0.7.5, | ||
140 | crypto-pubkey >= 0.2.3, | ||
141 | crypto-pubkey-types >= 0.4.1, | ||
142 | cipher-cast5 -any, | ||
143 | byteable, | ||
144 | crypto-cipher-types >= 0.0.7, | ||
145 | cipher-blowfish, | ||
146 | cipher-aes >= 0.2.5, | ||
147 | utf8-string, | 141 | utf8-string, |
148 | zlib, | 142 | zlib, |
149 | bzlib | 143 | bzlib |
150 | 144 | ||
145 | if flag(cryptonite) | ||
146 | build-depends: | ||
147 | hourglass, | ||
148 | memory, | ||
149 | cryptonite | ||
150 | else | ||
151 | build-depends: | ||
152 | time >= 1.4, | ||
153 | byteable, | ||
154 | cipher-aes >= 0.2.5, | ||
155 | cipher-blowfish, | ||
156 | crypto-cipher-types >= 0.0.7, | ||
157 | crypto-random >= 0.0.7, | ||
158 | cryptohash >= 0.7.5, | ||
159 | crypto-pubkey >= 0.2.3, | ||
160 | crypto-pubkey-types >= 0.4.1 | ||
161 | |||
162 | |||
151 | test-suite tests | 163 | test-suite tests |
152 | type: exitcode-stdio-1.0 | 164 | type: exitcode-stdio-1.0 |
153 | main-is: tests/suite.hs | 165 | main-is: tests/suite.hs |
154 | 166 | ||
155 | other-modules: | ||
156 | Data.OpenPGP.Arbitrary | ||
157 | |||
158 | build-depends: | 167 | build-depends: |
159 | base == 4.*, | 168 | base == 4.*, |
160 | bytestring, | 169 | bytestring, |
diff --git a/tests/suite.hs b/tests/suite.hs index cb4f4aa..7af9be0 100644 --- a/tests/suite.hs +++ b/tests/suite.hs | |||
@@ -5,7 +5,7 @@ import Test.Framework.Providers.QuickCheck2 | |||
5 | import Test.HUnit hiding (Test) | 5 | import Test.HUnit hiding (Test) |
6 | 6 | ||
7 | import Data.Word | 7 | import Data.Word |
8 | import Data.OpenPGP.Arbitrary () | 8 | -- import Data.OpenPGP.Arbitrary () |
9 | import qualified Data.OpenPGP as OpenPGP | 9 | import qualified Data.OpenPGP as OpenPGP |
10 | import qualified Data.OpenPGP.Internal as OpenPGP | 10 | import qualified Data.OpenPGP.Internal as OpenPGP |
11 | 11 | ||
@@ -146,10 +146,11 @@ tests = | |||
146 | testCase "uncompressed-ops-dsa-sha384.txt.gpg" (testSerialization "uncompressed-ops-dsa-sha384.txt.gpg"), | 146 | testCase "uncompressed-ops-dsa-sha384.txt.gpg" (testSerialization "uncompressed-ops-dsa-sha384.txt.gpg"), |
147 | testCase "uncompressed-ops-rsa.gpg" (testSerialization "uncompressed-ops-rsa.gpg"), | 147 | testCase "uncompressed-ops-rsa.gpg" (testSerialization "uncompressed-ops-rsa.gpg"), |
148 | testCase "3F5BBA0B0694BEB6000005-002.sig" (testSerialization "3F5BBA0B0694BEB6000005-002.sig"), | 148 | testCase "3F5BBA0B0694BEB6000005-002.sig" (testSerialization "3F5BBA0B0694BEB6000005-002.sig"), |
149 | testCase "3F5BBA0B0694BEB6000017-002.sig" (testSerialization "3F5BBA0B0694BEB6000017-002.sig"), | 149 | testCase "3F5BBA0B0694BEB6000017-002.sig" (testSerialization "3F5BBA0B0694BEB6000017-002.sig") |
150 | testProperty "MPI encode/decode" prop_MPI_serialization_loop, | 150 | -- TODO |
151 | testProperty "S2K encode/decode" prop_S2K_serialization_loop, | 151 | -- testProperty "MPI encode/decode" prop_MPI_serialization_loop, |
152 | testProperty "SignatureSubpacket encode/decode" prop_SignatureSubpacket_serialization_loop | 152 | -- testProperty "S2K encode/decode" prop_S2K_serialization_loop, |
153 | -- testProperty "SignatureSubpacket encode/decode" prop_SignatureSubpacket_serialization_loop | ||
153 | ], | 154 | ], |
154 | testGroup "S2K count" [ | 155 | testGroup "S2K count" [ |
155 | testProperty "S2K count encode reverses decode" prop_s2k_count | 156 | testProperty "S2K count encode reverses decode" prop_s2k_count |