diff options
Diffstat (limited to 'Data/OpenPGP/Util')
-rw-r--r-- | Data/OpenPGP/Util/Cv25519.hs | 14 | ||||
-rw-r--r-- | Data/OpenPGP/Util/Decrypt.hs | 53 | ||||
-rw-r--r-- | Data/OpenPGP/Util/DecryptSecretKey.hs | 40 | ||||
-rw-r--r-- | Data/OpenPGP/Util/Gen.hs | 11 |
4 files changed, 74 insertions, 44 deletions
diff --git a/Data/OpenPGP/Util/Cv25519.hs b/Data/OpenPGP/Util/Cv25519.hs index 4900b2f..d5ac641 100644 --- a/Data/OpenPGP/Util/Cv25519.hs +++ b/Data/OpenPGP/Util/Cv25519.hs | |||
@@ -26,7 +26,7 @@ import qualified Crypto.PubKey.Curve25519 as Cv25519 | |||
26 | import Crypto.Error | 26 | import Crypto.Error |
27 | import Crypto.Cipher.AES | 27 | import Crypto.Cipher.AES |
28 | import Crypto.Cipher.Types | 28 | import Crypto.Cipher.Types |
29 | import Data.OpenPGP.Util.DecryptSecretKey -- (withS2K, simpleUnCFB, Enciphered(..)) | 29 | import Data.OpenPGP.Util.Decrypt -- (withS2K, simpleUnCFB, Enciphered(..)) |
30 | 30 | ||
31 | import Crypto.JOSE.AESKW | 31 | import Crypto.JOSE.AESKW |
32 | 32 | ||
@@ -229,3 +229,15 @@ decryptMessage ecdhkey asym encdta = do | |||
229 | b1 = BL.drop (2 + fromIntegral blksize) b0 | 229 | b1 = BL.drop (2 + fromIntegral blksize) b0 |
230 | (_,_, Message ps) <- either (const Nothing) Just $ decodeOrFail b1 | 230 | (_,_, Message ps) <- either (const Nothing) Just $ decodeOrFail b1 |
231 | return ps | 231 | return ps |
232 | |||
233 | importSecretCv25519 :: Cv25519.SecretKey -> [(Char,MPI)] | ||
234 | importSecretCv25519 k = | ||
235 | [ ('c', MPI oid_cv25519) | ||
236 | , ('l', MPI 128) | ||
237 | , ('n', MPI pub) | ||
238 | , ('f', MPI 0x40) | ||
239 | , ('d', MPI sec) | ||
240 | ] | ||
241 | where | ||
242 | pub = getBigNum $ BA.convert $ Cv25519.toPublic k | ||
243 | sec = getBigNumLE $ BA.convert k | ||
diff --git a/Data/OpenPGP/Util/Decrypt.hs b/Data/OpenPGP/Util/Decrypt.hs new file mode 100644 index 0000000..84bead5 --- /dev/null +++ b/Data/OpenPGP/Util/Decrypt.hs | |||
@@ -0,0 +1,53 @@ | |||
1 | {-# LANGUAGE RankNTypes, CPP #-} | ||
2 | module Data.OpenPGP.Util.Decrypt where | ||
3 | |||
4 | import qualified Data.ByteString.Lazy as LZ | ||
5 | import Crypto.Error | ||
6 | import qualified Crypto.Cipher.AES as Vincent | ||
7 | import qualified Crypto.Cipher.Blowfish as Vincent | ||
8 | import qualified Crypto.Cipher.Types as Vincent | ||
9 | import Crypto.Cipher.Cast5 (CAST5_128) | ||
10 | import Crypto.Cipher.ThomasToVincent | ||
11 | import qualified Data.OpenPGP as OpenPGP | ||
12 | import Data.OpenPGP.Util.Base | ||
13 | |||
14 | |||
15 | -- decryption codec for withS2K | ||
16 | simpleUnCFB :: (Vincent.BlockCipher k) => k -> Vincent.IV k -> LZ.ByteString -> LZ.ByteString | ||
17 | simpleUnCFB k iv = padThenUnpad k (toLazyBS . Vincent.cfbDecrypt k iv . toStrictBS) | ||
18 | |||
19 | withS2K' :: OpenPGP.SymmetricAlgorithm -> Maybe OpenPGP.S2K -> LZ.ByteString | ||
20 | -> (forall b. Vincent.BlockCipher b => b -> x) -> x | ||
21 | withS2K' OpenPGP.AES128 s2k s f = f (string2key s2k s :: Vincent.AES128) | ||
22 | withS2K' OpenPGP.AES192 s2k s f = f (string2key s2k s :: Vincent.AES192) | ||
23 | withS2K' OpenPGP.AES256 s2k s f = f (string2key s2k s :: Vincent.AES256) | ||
24 | withS2K' OpenPGP.Blowfish s2k s f = f (string2key s2k s :: Vincent.Blowfish128) | ||
25 | withS2K' OpenPGP.CAST5 s2k s f = f (string2key s2k s :: ThomasToVincent CAST5_128) | ||
26 | |||
27 | string2key :: (Vincent.BlockCipher k) => Maybe OpenPGP.S2K -> LZ.ByteString -> k | ||
28 | string2key ms2k s = cipher | ||
29 | where | ||
30 | #if defined(VERSION_cryptonite) | ||
31 | CryptoPassed cipher = Vincent.cipherInit k | ||
32 | k = toStrictBS $ LZ.take ksize $ maybe s (\s2k -> OpenPGP.string2key hashBySymbol s2k s) ms2k | ||
33 | #else | ||
34 | cipher = Vincent.cipherInit k | ||
35 | Right k = Vincent.makeKey $ toStrictBS $ | ||
36 | LZ.take ksize $ maybe s (\s2k -> OpenPGP.string2key hashBySymbol s2k s) ms2k | ||
37 | #endif | ||
38 | ksize = case Vincent.cipherKeySize cipher of | ||
39 | Vincent.KeySizeFixed n -> fromIntegral n | ||
40 | Vincent.KeySizeEnum xs -> error $ "Unknown key size in string2key" | ||
41 | Vincent.KeySizeRange min max -> error $ "Unknown key size range in string2key" | ||
42 | |||
43 | -- Apply a function f to a zero-padded bytestring s to a multiple | ||
44 | -- of the blocksize for cyper k. | ||
45 | -- Then drop the same number of bytes from the result of f. | ||
46 | padThenUnpad :: (Vincent.BlockCipher k) => k -> (LZ.ByteString -> LZ.ByteString) -> LZ.ByteString -> LZ.ByteString | ||
47 | padThenUnpad k f s = dropPadEnd (f padded) | ||
48 | where | ||
49 | dropPadEnd s = LZ.take (LZ.length s - padAmount) s | ||
50 | padded = s `LZ.append` LZ.replicate padAmount 0 | ||
51 | padAmount = blksize - (LZ.length s `mod` blksize) | ||
52 | blksize = fromIntegral $ Vincent.blockSize k | ||
53 | |||
diff --git a/Data/OpenPGP/Util/DecryptSecretKey.hs b/Data/OpenPGP/Util/DecryptSecretKey.hs index a637b29..57dd8c3 100644 --- a/Data/OpenPGP/Util/DecryptSecretKey.hs +++ b/Data/OpenPGP/Util/DecryptSecretKey.hs | |||
@@ -27,6 +27,7 @@ import qualified Crypto.Cipher.AES as Vincent | |||
27 | import qualified Crypto.Cipher.Blowfish as Vincent | 27 | import qualified Crypto.Cipher.Blowfish as Vincent |
28 | 28 | ||
29 | import qualified Crypto.Cipher.Types as Vincent | 29 | import qualified Crypto.Cipher.Types as Vincent |
30 | import Data.OpenPGP.Util.Decrypt | ||
30 | 31 | ||
31 | #if defined(VERSION_cryptonite) | 32 | #if defined(VERSION_cryptonite) |
32 | import qualified Data.ByteArray as Bytes | 33 | import qualified Data.ByteArray as Bytes |
@@ -131,18 +132,6 @@ withS2K codec OpenPGP.Blowfish s2k s = withIV $ codec (string2key s2k s :: Vince | |||
131 | withS2K codec OpenPGP.CAST5 s2k s = withIV $ codec (string2key s2k s :: ThomasToVincent CAST5_128) | 132 | withS2K codec OpenPGP.CAST5 s2k s = withIV $ codec (string2key s2k s :: ThomasToVincent CAST5_128) |
132 | withS2K codec algo _ _ = error $ "Unsupported symmetric algorithm : " ++ show algo ++ " in Data.OpenPGP.CryptoAPI.withS2K" | 133 | withS2K codec algo _ _ = error $ "Unsupported symmetric algorithm : " ++ show algo ++ " in Data.OpenPGP.CryptoAPI.withS2K" |
133 | 134 | ||
134 | withS2K' :: OpenPGP.SymmetricAlgorithm -> Maybe OpenPGP.S2K -> LZ.ByteString | ||
135 | -> (forall b. Vincent.BlockCipher b => b -> x) -> x | ||
136 | withS2K' OpenPGP.AES128 s2k s f = f (string2key s2k s :: Vincent.AES128) | ||
137 | withS2K' OpenPGP.AES192 s2k s f = f (string2key s2k s :: Vincent.AES192) | ||
138 | withS2K' OpenPGP.AES256 s2k s f = f (string2key s2k s :: Vincent.AES256) | ||
139 | withS2K' OpenPGP.Blowfish s2k s f = f (string2key s2k s :: Vincent.Blowfish128) | ||
140 | withS2K' OpenPGP.CAST5 s2k s f = f (string2key s2k s :: ThomasToVincent CAST5_128) | ||
141 | |||
142 | -- decryption codec for withS2K | ||
143 | simpleUnCFB :: (Vincent.BlockCipher k) => k -> Vincent.IV k -> LZ.ByteString -> LZ.ByteString | ||
144 | simpleUnCFB k iv = padThenUnpad k (toLazyBS . Vincent.cfbDecrypt k iv . toStrictBS) | ||
145 | |||
146 | simpleCFB :: forall k g. (Vincent.BlockCipher k, RG g) => g -> k -> LZ.ByteString -> (LZ.ByteString, g) | 135 | simpleCFB :: forall k g. (Vincent.BlockCipher k, RG g) => g -> k -> LZ.ByteString -> (LZ.ByteString, g) |
147 | simpleCFB g k bs = ( padThenUnpad k (LZ.fromChunks . (ivbs:) . (:[]) . Vincent.cfbEncrypt k iv . toStrictBS) bs | 136 | simpleCFB g k bs = ( padThenUnpad k (LZ.fromChunks . (ivbs:) . (:[]) . Vincent.cfbEncrypt k iv . toStrictBS) bs |
148 | , g' ) | 137 | , g' ) |
@@ -158,33 +147,6 @@ simpleCFB g k bs = ( padThenUnpad k (LZ.fromChunks . (ivbs:) . (:[]) . Vincent.c | |||
158 | _ = Vincent.constEqBytes z iv | 147 | _ = Vincent.constEqBytes z iv |
159 | #endif | 148 | #endif |
160 | 149 | ||
161 | -- Apply a function f to a zero-padded bytestring s to a multiple | ||
162 | -- of the blocksize for cyper k. | ||
163 | -- Then drop the same number of bytes from the result of f. | ||
164 | padThenUnpad :: (Vincent.BlockCipher k) => k -> (LZ.ByteString -> LZ.ByteString) -> LZ.ByteString -> LZ.ByteString | ||
165 | padThenUnpad k f s = dropPadEnd (f padded) | ||
166 | where | ||
167 | dropPadEnd s = LZ.take (LZ.length s - padAmount) s | ||
168 | padded = s `LZ.append` LZ.replicate padAmount 0 | ||
169 | padAmount = blksize - (LZ.length s `mod` blksize) | ||
170 | blksize = fromIntegral $ Vincent.blockSize k | ||
171 | |||
172 | string2key :: (Vincent.BlockCipher k) => Maybe OpenPGP.S2K -> LZ.ByteString -> k | ||
173 | string2key ms2k s = cipher | ||
174 | where | ||
175 | #if defined(VERSION_cryptonite) | ||
176 | CryptoPassed cipher = Vincent.cipherInit k | ||
177 | k = toStrictBS $ LZ.take ksize $ maybe s (\s2k -> OpenPGP.string2key hashBySymbol s2k s) ms2k | ||
178 | #else | ||
179 | cipher = Vincent.cipherInit k | ||
180 | Right k = Vincent.makeKey $ toStrictBS $ | ||
181 | LZ.take ksize $ maybe s (\s2k -> OpenPGP.string2key hashBySymbol s2k s) ms2k | ||
182 | #endif | ||
183 | ksize = case Vincent.cipherKeySize cipher of | ||
184 | Vincent.KeySizeFixed n -> fromIntegral n | ||
185 | Vincent.KeySizeEnum xs -> error $ "Unknown key size in string2key" | ||
186 | Vincent.KeySizeRange min max -> error $ "Unknown key size range in string2key" | ||
187 | |||
188 | catchIO_ :: IO a -> IO a -> IO a | 150 | catchIO_ :: IO a -> IO a -> IO a |
189 | catchIO_ a h = Exception.catch a (\(_ :: IOException) -> h) | 151 | catchIO_ a h = Exception.catch a (\(_ :: IOException) -> h) |
190 | 152 | ||
diff --git a/Data/OpenPGP/Util/Gen.hs b/Data/OpenPGP/Util/Gen.hs index ca3c684..c33ef1e 100644 --- a/Data/OpenPGP/Util/Gen.hs +++ b/Data/OpenPGP/Util/Gen.hs | |||
@@ -14,7 +14,9 @@ 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) | 16 | #if defined(VERSION_cryptonite) |
17 | import qualified Crypto.PubKey.Curve25519 as Cv25519 | ||
17 | import qualified Crypto.PubKey.Ed25519 as Ed25519 | 18 | import qualified Crypto.PubKey.Ed25519 as Ed25519 |
19 | import Data.OpenPGP.Util.Cv25519 | ||
18 | import Data.OpenPGP.Util.Ed25519 | 20 | import Data.OpenPGP.Util.Ed25519 |
19 | import Control.Arrow (second) | 21 | import Control.Arrow (second) |
20 | import Data.Binary | 22 | import Data.Binary |
@@ -25,6 +27,7 @@ import Data.OpenPGP.Util.Base | |||
25 | data GenerateKeyParams = GenRSA Int -- keysize | 27 | data GenerateKeyParams = GenRSA Int -- keysize |
26 | | GenDSA (Maybe DSAParams) | 28 | | GenDSA (Maybe DSAParams) |
27 | | GenEd25519 | 29 | | GenEd25519 |
30 | | GenCv25519 | ||
28 | deriving (Eq,Ord,Show) | 31 | deriving (Eq,Ord,Show) |
29 | 32 | ||
30 | data DSAParams = DSAParams | 33 | data DSAParams = DSAParams |
@@ -121,10 +124,10 @@ generateKey' (GenDSA mbparams) g = | |||
121 | generateKey' (GenEd25519 {}) g = withDRG g $ do | 124 | generateKey' (GenEd25519 {}) g = withDRG g $ do |
122 | k <- Ed25519.generateSecretKey | 125 | k <- Ed25519.generateSecretKey |
123 | return $ importSecretEd25519 k | 126 | return $ importSecretEd25519 k |
124 | -- file:///usr/share/doc/libghc-cryptonite-doc/html/Crypto-PubKey-Ed25519.html#v:generateSecretKey | 127 | generateKey' (GenCv25519 {}) g = withDRG g $ do |
125 | -- generateSecretKey :: MonadRandom m => m SecretKey | 128 | k <- Cv25519.generateSecretKey |
126 | -- n = public key used to verify signatures. | 129 | return $ importSecretCv25519 k |
127 | -- public_key_fields Ed25519 = ['c','l','x', 'y', 'n', 'f'] | 130 | |
128 | 131 | ||
129 | #endif | 132 | #endif |
130 | 133 | ||