[RSA] remove hashdescr in favor of just specifying the algorithm directly
The extra information is embedded in the HashAlgorithmASN1 class that allow a digest to ASN1 structured.
This commit is contained in:
parent
9cc4ffdd04
commit
a9df2a2180
@ -1,101 +0,0 @@
|
|||||||
-- |
|
|
||||||
-- Module : Crypto.PubKey.HashDescr
|
|
||||||
-- License : BSD-style
|
|
||||||
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
|
|
||||||
-- Stability : experimental
|
|
||||||
-- Portability : Good
|
|
||||||
--
|
|
||||||
-- Standard digests wrapped in ASN1 structure
|
|
||||||
--
|
|
||||||
module Crypto.PubKey.HashDescr
|
|
||||||
(
|
|
||||||
-- * Types
|
|
||||||
HashDescr
|
|
||||||
, runHashDescr
|
|
||||||
-- * List of known hash description
|
|
||||||
, hashDescrMD2
|
|
||||||
, hashDescrMD5
|
|
||||||
, hashDescrSHA1
|
|
||||||
, hashDescrSHA224
|
|
||||||
, hashDescrSHA256
|
|
||||||
, hashDescrSHA384
|
|
||||||
, hashDescrSHA512
|
|
||||||
, hashDescrRIPEMD160
|
|
||||||
) where
|
|
||||||
|
|
||||||
import Data.Word
|
|
||||||
import Crypto.Hash
|
|
||||||
import qualified Crypto.Internal.ByteArray as B
|
|
||||||
|
|
||||||
--
|
|
||||||
-- ** Hack **
|
|
||||||
--
|
|
||||||
-- this happens to not need a real ASN1 encoder, because
|
|
||||||
-- thanks to the digest being a specific size AND
|
|
||||||
-- that the digest data is the last bytes in the encoding,
|
|
||||||
-- this allows to just prepend the right prefix to the
|
|
||||||
-- computed digest, to make it in the expected and valid shape.
|
|
||||||
--
|
|
||||||
-- Otherwise the expected structure is in the following form:
|
|
||||||
--
|
|
||||||
-- Start Sequence
|
|
||||||
-- ,Start Sequence
|
|
||||||
-- ,OID oid
|
|
||||||
-- ,Null
|
|
||||||
-- ,End Sequence
|
|
||||||
-- ,OctetString digest
|
|
||||||
-- ,End Sequence
|
|
||||||
|
|
||||||
hashDescr :: (B.ByteArray ba, HashAlgorithm hashAlg)
|
|
||||||
=> hashAlg -- ^ hash algorithm to use
|
|
||||||
-> [Word8] -- ^ the raw DER encoded ASN1 description of hash algorithm followed by the digest to be filled
|
|
||||||
-> HashDescr hashAlg ba
|
|
||||||
hashDescr hashAlg preASN1Descr =
|
|
||||||
HashDescr (\input -> B.pack preASN1Descr `B.append` B.convert (hashWith hashAlg input))
|
|
||||||
|
|
||||||
-- | A hash methods to generate a ASN.1 structure digest
|
|
||||||
data HashDescr hashAlg ba = HashDescr { unHashDescr :: ba -> ba }
|
|
||||||
|
|
||||||
-- | Run the digest function on some input and get the raw bytes
|
|
||||||
runHashDescr :: (HashAlgorithm hashAlg, B.ByteArray ba) => HashDescr hashAlg ba -> ba -> ba
|
|
||||||
runHashDescr h = unHashDescr h
|
|
||||||
|
|
||||||
-- | Describe the MD2 hashing algorithm
|
|
||||||
hashDescrMD2 :: B.ByteArray ba => HashDescr MD2 ba
|
|
||||||
hashDescrMD2 =
|
|
||||||
hashDescr MD2 [0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x02,0x05,0x00,0x04,0x10]
|
|
||||||
|
|
||||||
-- | Describe the MD5 hashing algorithm
|
|
||||||
hashDescrMD5 :: B.ByteArray ba => HashDescr MD5 ba
|
|
||||||
hashDescrMD5 =
|
|
||||||
hashDescr MD5 [0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x04,0x10]
|
|
||||||
|
|
||||||
-- | Describe the SHA1 hashing algorithm
|
|
||||||
hashDescrSHA1 :: B.ByteArray ba => HashDescr SHA1 ba
|
|
||||||
hashDescrSHA1 =
|
|
||||||
hashDescr SHA1 [0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x05,0x00,0x04,0x14]
|
|
||||||
|
|
||||||
-- | Describe the SHA224 hashing algorithm
|
|
||||||
hashDescrSHA224 :: B.ByteArray ba => HashDescr SHA224 ba
|
|
||||||
hashDescrSHA224 =
|
|
||||||
hashDescr SHA224 [0x30,0x2d,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04,0x05,0x00,0x04,0x1c]
|
|
||||||
|
|
||||||
-- | Describe the SHA256 hashing algorithm
|
|
||||||
hashDescrSHA256 :: B.ByteArray ba => HashDescr SHA256 ba
|
|
||||||
hashDescrSHA256 =
|
|
||||||
hashDescr SHA256 [0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x04,0x20]
|
|
||||||
|
|
||||||
-- | Describe the SHA384 hashing algorithm
|
|
||||||
hashDescrSHA384 :: B.ByteArray ba => HashDescr SHA384 ba
|
|
||||||
hashDescrSHA384 =
|
|
||||||
hashDescr SHA384 [0x30,0x41,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,0x04,0x30]
|
|
||||||
|
|
||||||
-- | Describe the SHA512 hashing algorithm
|
|
||||||
hashDescrSHA512 :: B.ByteArray ba => HashDescr SHA512 ba
|
|
||||||
hashDescrSHA512 =
|
|
||||||
hashDescr SHA512 [0x30,0x51,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,0x00,0x04,0x40]
|
|
||||||
|
|
||||||
-- | Describe the RIPEMD160 hashing algorithm
|
|
||||||
hashDescrRIPEMD160 :: B.ByteArray ba => HashDescr RIPEMD160 ba
|
|
||||||
hashDescrRIPEMD160 =
|
|
||||||
hashDescr RIPEMD160 [0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x24,0x03,0x02,0x01,0x05,0x00,0x04,0x14]
|
|
||||||
@ -19,6 +19,8 @@ module Crypto.PubKey.RSA.PKCS15
|
|||||||
-- * public key operations
|
-- * public key operations
|
||||||
, encrypt
|
, encrypt
|
||||||
, verify
|
, verify
|
||||||
|
-- * hash ASN1 description
|
||||||
|
, HashAlgorithmASN1
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Crypto.Random.Types
|
import Crypto.Random.Types
|
||||||
@ -26,14 +28,59 @@ import Crypto.PubKey.Internal (and')
|
|||||||
import Crypto.PubKey.RSA.Types
|
import Crypto.PubKey.RSA.Types
|
||||||
import Crypto.PubKey.RSA.Prim
|
import Crypto.PubKey.RSA.Prim
|
||||||
import Crypto.PubKey.RSA (generateBlinder)
|
import Crypto.PubKey.RSA (generateBlinder)
|
||||||
import Crypto.PubKey.HashDescr
|
import Crypto.Hash
|
||||||
import Crypto.Hash (HashAlgorithm)
|
|
||||||
|
|
||||||
import Data.ByteString (ByteString)
|
import Data.ByteString (ByteString)
|
||||||
|
import Data.Word
|
||||||
|
|
||||||
import Crypto.Internal.ByteArray (ByteArray, Bytes)
|
import Crypto.Internal.ByteArray (ByteArray, Bytes)
|
||||||
import qualified Crypto.Internal.ByteArray as B
|
import qualified Crypto.Internal.ByteArray as B
|
||||||
|
|
||||||
|
-- | A specialized class for hash algorithm that can product
|
||||||
|
-- a ASN1 wrapped description the algorithm plus the content
|
||||||
|
-- of the digest.
|
||||||
|
class HashAlgorithm hashAlg => HashAlgorithmASN1 hashAlg where
|
||||||
|
hashDigestASN1 :: ByteArray out => Digest hashAlg -> out
|
||||||
|
|
||||||
|
instance HashAlgorithmASN1 MD2 where
|
||||||
|
hashDigestASN1 = addDigestPrefix [0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x02,0x05,0x00,0x04,0x10]
|
||||||
|
instance HashAlgorithmASN1 MD5 where
|
||||||
|
hashDigestASN1 = addDigestPrefix [0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x04,0x10]
|
||||||
|
instance HashAlgorithmASN1 SHA1 where
|
||||||
|
hashDigestASN1 = addDigestPrefix [0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x05,0x00,0x04,0x14]
|
||||||
|
instance HashAlgorithmASN1 SHA224 where
|
||||||
|
hashDigestASN1 = addDigestPrefix [0x30,0x2d,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04,0x05,0x00,0x04,0x1c]
|
||||||
|
instance HashAlgorithmASN1 SHA256 where
|
||||||
|
hashDigestASN1 = addDigestPrefix [0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x04,0x20]
|
||||||
|
instance HashAlgorithmASN1 SHA384 where
|
||||||
|
hashDigestASN1 = addDigestPrefix [0x30,0x41,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,0x04,0x30]
|
||||||
|
instance HashAlgorithmASN1 SHA512 where
|
||||||
|
hashDigestASN1 = addDigestPrefix [0x30,0x51,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,0x00,0x04,0x40]
|
||||||
|
instance HashAlgorithmASN1 RIPEMD160 where
|
||||||
|
hashDigestASN1 = addDigestPrefix [0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x24,0x03,0x02,0x01,0x05,0x00,0x04,0x14]
|
||||||
|
|
||||||
|
--
|
||||||
|
-- ** Hack **
|
||||||
|
--
|
||||||
|
-- this happens to not need a real ASN1 encoder, because
|
||||||
|
-- thanks to the digest being a specific size AND
|
||||||
|
-- that the digest data is the last bytes in the encoding,
|
||||||
|
-- this allows to just prepend the right prefix to the
|
||||||
|
-- computed digest, to make it in the expected and valid shape.
|
||||||
|
--
|
||||||
|
-- Otherwise the expected structure is in the following form:
|
||||||
|
--
|
||||||
|
-- Start Sequence
|
||||||
|
-- ,Start Sequence
|
||||||
|
-- ,OID oid
|
||||||
|
-- ,Null
|
||||||
|
-- ,End Sequence
|
||||||
|
-- ,OctetString digest
|
||||||
|
-- ,End Sequence
|
||||||
|
addDigestPrefix :: ByteArray out => [Word8] -> Digest hashAlg -> out
|
||||||
|
addDigestPrefix prefix digest =
|
||||||
|
B.pack prefix `B.append` B.convert digest
|
||||||
|
|
||||||
-- | This produce a standard PKCS1.5 padding for encryption
|
-- | This produce a standard PKCS1.5 padding for encryption
|
||||||
pad :: (MonadRandom m, ByteArray message) => Int -> message -> m (Either Error message)
|
pad :: (MonadRandom m, ByteArray message) => Int -> message -> m (Either Error message)
|
||||||
pad len m
|
pad len m
|
||||||
@ -116,40 +163,40 @@ encrypt pk m = do
|
|||||||
-- information from the timing of the operation, the blinder can be set to None.
|
-- information from the timing of the operation, the blinder can be set to None.
|
||||||
--
|
--
|
||||||
-- If unsure always set a blinder or use signSafer
|
-- If unsure always set a blinder or use signSafer
|
||||||
sign :: HashAlgorithm hashAlg
|
sign :: HashAlgorithmASN1 hashAlg
|
||||||
=> Maybe Blinder -- ^ optional blinder
|
=> Maybe Blinder -- ^ optional blinder
|
||||||
-> HashDescr hashAlg ByteString -- ^ hash descriptor
|
-> hashAlg -- ^ hash algorithm
|
||||||
-> PrivateKey -- ^ private key
|
-> PrivateKey -- ^ private key
|
||||||
-> ByteString -- ^ message to sign
|
-> ByteString -- ^ message to sign
|
||||||
-> Either Error ByteString
|
-> Either Error ByteString
|
||||||
sign blinder hashDescr pk m = dp blinder pk `fmap` makeSignature hashDescr (private_size pk) m
|
sign blinder hashDescr pk m = dp blinder pk `fmap` makeSignature hashDescr (private_size pk) m
|
||||||
|
|
||||||
-- | sign message using the private key and by automatically generating a blinder.
|
-- | sign message using the private key and by automatically generating a blinder.
|
||||||
signSafer :: (HashAlgorithm hashAlg, MonadRandom m)
|
signSafer :: (HashAlgorithmASN1 hashAlg, MonadRandom m)
|
||||||
=> HashDescr hashAlg ByteString -- ^ Hash descriptor
|
=> hashAlg -- ^ Hash algorithm
|
||||||
-> PrivateKey -- ^ private key
|
-> PrivateKey -- ^ private key
|
||||||
-> ByteString -- ^ message to sign
|
-> ByteString -- ^ message to sign
|
||||||
-> m (Either Error ByteString)
|
-> m (Either Error ByteString)
|
||||||
signSafer hashDescr pk m = do
|
signSafer hashAlg pk m = do
|
||||||
blinder <- generateBlinder (private_n pk)
|
blinder <- generateBlinder (private_n pk)
|
||||||
return (sign (Just blinder) hashDescr pk m)
|
return (sign (Just blinder) hashAlg pk m)
|
||||||
|
|
||||||
-- | verify message with the signed message
|
-- | verify message with the signed message
|
||||||
verify :: HashAlgorithm hashAlg
|
verify :: HashAlgorithmASN1 hashAlg
|
||||||
=> HashDescr hashAlg ByteString
|
=> hashAlg
|
||||||
-> PublicKey
|
-> PublicKey
|
||||||
-> ByteString
|
-> ByteString
|
||||||
-> ByteString
|
-> ByteString
|
||||||
-> Bool
|
-> Bool
|
||||||
verify hashDescr pk m sm =
|
verify hashAlg pk m sm =
|
||||||
case makeSignature hashDescr (public_size pk) m of
|
case makeSignature hashAlg (public_size pk) m of
|
||||||
Left _ -> False
|
Left _ -> False
|
||||||
Right s -> s == (ep pk sm)
|
Right s -> s == (ep pk sm)
|
||||||
|
|
||||||
-- | make signature digest, used in 'sign' and 'verify'
|
-- | make signature digest, used in 'sign' and 'verify'
|
||||||
makeSignature :: HashAlgorithm hashAlg
|
makeSignature :: HashAlgorithmASN1 hashAlg
|
||||||
=> HashDescr hashAlg ByteString
|
=> hashAlg
|
||||||
-> Int
|
-> Int
|
||||||
-> ByteString
|
-> ByteString
|
||||||
-> Either Error ByteString
|
-> Either Error ByteString
|
||||||
makeSignature hashDescr klen m = padSignature klen (runHashDescr hashDescr m)
|
makeSignature hashAlg klen m = padSignature klen (hashDigestASN1 $ hashWith hashAlg m)
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
Name: cryptonite
|
Name: cryptonite
|
||||||
Version: 0.2
|
Version: 0.3
|
||||||
Synopsis: Cryptography Primitives sink
|
Synopsis: Cryptography Primitives sink
|
||||||
Description:
|
Description:
|
||||||
A repository of cryptographic primitives.
|
A repository of cryptographic primitives.
|
||||||
@ -93,7 +93,6 @@ Library
|
|||||||
Crypto.Hash.IO
|
Crypto.Hash.IO
|
||||||
Crypto.Hash.Algorithms
|
Crypto.Hash.Algorithms
|
||||||
Crypto.PubKey.Curve25519
|
Crypto.PubKey.Curve25519
|
||||||
Crypto.PubKey.HashDescr
|
|
||||||
Crypto.PubKey.MaskGenFunction
|
Crypto.PubKey.MaskGenFunction
|
||||||
Crypto.PubKey.DH
|
Crypto.PubKey.DH
|
||||||
Crypto.PubKey.DSA
|
Crypto.PubKey.DSA
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user