{-# OPTIONS_HADDOCK hide #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE RankNTypes #-}
module Network.TLS.Crypto
    ( HashContext
    , HashCtx
    , hashInit
    , hashUpdate
    , hashUpdateSSL
    , hashFinal

    , module Network.TLS.Crypto.DH
    , module Network.TLS.Crypto.IES
    , module Network.TLS.Crypto.Types

    -- * Hash
    , hash
    , Hash(..)
    , hashName
    , hashDigestSize
    , hashBlockSize

    -- * key exchange generic interface
    , PubKey(..)
    , PrivKey(..)
    , PublicKey
    , PrivateKey
    , SignatureParams(..)
    , isKeyExchangeSignatureKey
    , findKeyExchangeSignatureAlg
    , findFiniteFieldGroup
    , findEllipticCurveGroup
    , kxEncrypt
    , kxDecrypt
    , kxSign
    , kxVerify
    , kxCanUseRSApkcs1
    , kxCanUseRSApss
    , kxSupportedPrivKeyEC
    , KxError(..)
    , RSAEncoding(..)
    ) where

import qualified Crypto.Hash as H
import qualified Data.ByteString as B
import qualified Data.ByteArray as B (convert)
import Crypto.Error
import Crypto.Number.Basic (numBits)
import Crypto.Random
import qualified Crypto.ECC as ECDSA
import qualified Crypto.PubKey.DH as DH
import qualified Crypto.PubKey.DSA as DSA
import qualified Crypto.PubKey.ECC.ECDSA as ECDSA_ECC
import qualified Crypto.PubKey.ECC.Types as ECC
import qualified Crypto.PubKey.ECDSA as ECDSA
import qualified Crypto.PubKey.Ed25519 as Ed25519
import qualified Crypto.PubKey.Ed448 as Ed448
import qualified Crypto.PubKey.RSA as RSA
import qualified Crypto.PubKey.RSA.PKCS15 as RSA
import qualified Crypto.PubKey.RSA.PSS as PSS

import Data.X509 (PrivKey(..), PubKey(..), PrivKeyEC(..), PubKeyEC(..),
                  SerializedPoint(..))
import Data.X509.EC (ecPrivKeyCurveName, ecPubKeyCurveName, unserializePoint)
import Network.TLS.Crypto.DH
import Network.TLS.Crypto.IES
import Network.TLS.Crypto.Types
import Network.TLS.Imports

import Data.ASN1.Types
import Data.ASN1.Encoding
import Data.ASN1.BinaryEncoding (DER(..), BER(..))

import Data.Proxy

{-# DEPRECATED PublicKey "use PubKey" #-}
type PublicKey = PubKey
{-# DEPRECATED PrivateKey "use PrivKey" #-}
type PrivateKey = PrivKey

data KxError =
      RSAError RSA.Error
    | KxUnsupported
    deriving (Int -> KxError -> ShowS
[KxError] -> ShowS
KxError -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [KxError] -> ShowS
$cshowList :: [KxError] -> ShowS
show :: KxError -> String
$cshow :: KxError -> String
showsPrec :: Int -> KxError -> ShowS
$cshowsPrec :: Int -> KxError -> ShowS
Show)

isKeyExchangeSignatureKey :: KeyExchangeSignatureAlg -> PubKey -> Bool
isKeyExchangeSignatureKey :: KeyExchangeSignatureAlg -> PubKey -> Bool
isKeyExchangeSignatureKey = KeyExchangeSignatureAlg -> PubKey -> Bool
f
  where
    f :: KeyExchangeSignatureAlg -> PubKey -> Bool
f KeyExchangeSignatureAlg
KX_RSA   (PubKeyRSA     PublicKey
_)   = Bool
True
    f KeyExchangeSignatureAlg
KX_DSS   (PubKeyDSA     PublicKey
_)   = Bool
True
    f KeyExchangeSignatureAlg
KX_ECDSA (PubKeyEC      PubKeyEC
_)   = Bool
True
    f KeyExchangeSignatureAlg
KX_ECDSA (PubKeyEd25519 PublicKey
_)   = Bool
True
    f KeyExchangeSignatureAlg
KX_ECDSA (PubKeyEd448   PublicKey
_)   = Bool
True
    f KeyExchangeSignatureAlg
_        PubKey
_                   = Bool
False

findKeyExchangeSignatureAlg :: (PubKey, PrivKey) -> Maybe KeyExchangeSignatureAlg
findKeyExchangeSignatureAlg :: (PubKey, PrivKey) -> Maybe KeyExchangeSignatureAlg
findKeyExchangeSignatureAlg (PubKey, PrivKey)
keyPair =
    case (PubKey, PrivKey)
keyPair of
        (PubKeyRSA     PublicKey
_, PrivKeyRSA      PrivateKey
_)  -> forall a. a -> Maybe a
Just KeyExchangeSignatureAlg
KX_RSA
        (PubKeyDSA     PublicKey
_, PrivKeyDSA      PrivateKey
_)  -> forall a. a -> Maybe a
Just KeyExchangeSignatureAlg
KX_DSS
        (PubKeyEC      PubKeyEC
_, PrivKeyEC       PrivKeyEC
_)  -> forall a. a -> Maybe a
Just KeyExchangeSignatureAlg
KX_ECDSA
        (PubKeyEd25519 PublicKey
_, PrivKeyEd25519  SecretKey
_)  -> forall a. a -> Maybe a
Just KeyExchangeSignatureAlg
KX_ECDSA
        (PubKeyEd448   PublicKey
_, PrivKeyEd448    SecretKey
_)  -> forall a. a -> Maybe a
Just KeyExchangeSignatureAlg
KX_ECDSA
        (PubKey, PrivKey)
_                                     -> forall a. Maybe a
Nothing

findFiniteFieldGroup :: DH.Params -> Maybe Group
findFiniteFieldGroup :: Params -> Maybe Group
findFiniteFieldGroup Params
params = forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup (Params -> (Integer, Integer)
pg Params
params) [((Integer, Integer), Group)]
table
  where
    pg :: Params -> (Integer, Integer)
pg (DH.Params Integer
p Integer
g Int
_) = (Integer
p, Integer
g)

    table :: [((Integer, Integer), Group)]
table = [ (Params -> (Integer, Integer)
pg Params
prms, Group
grp) | Group
grp <- [Group]
availableFFGroups
                             , let Just Params
prms = Group -> Maybe Params
dhParamsForGroup Group
grp
            ]

findEllipticCurveGroup :: PubKeyEC -> Maybe Group
findEllipticCurveGroup :: PubKeyEC -> Maybe Group
findEllipticCurveGroup PubKeyEC
ecPub =
    case PubKeyEC -> Maybe CurveName
ecPubKeyCurveName PubKeyEC
ecPub of
        Just CurveName
ECC.SEC_p256r1 -> forall a. a -> Maybe a
Just Group
P256
        Just CurveName
ECC.SEC_p384r1 -> forall a. a -> Maybe a
Just Group
P384
        Just CurveName
ECC.SEC_p521r1 -> forall a. a -> Maybe a
Just Group
P521
        Maybe CurveName
_                   -> forall a. Maybe a
Nothing

-- functions to use the hidden class.
hashInit :: Hash -> HashContext
hashInit :: Hash -> HashContext
hashInit Hash
MD5      = ContextSimple -> HashContext
HashContext forall a b. (a -> b) -> a -> b
$ forall alg. HashAlgorithm alg => Context alg -> ContextSimple
ContextSimple (forall a. HashAlgorithm a => Context a
H.hashInit :: H.Context H.MD5)
hashInit Hash
SHA1     = ContextSimple -> HashContext
HashContext forall a b. (a -> b) -> a -> b
$ forall alg. HashAlgorithm alg => Context alg -> ContextSimple
ContextSimple (forall a. HashAlgorithm a => Context a
H.hashInit :: H.Context H.SHA1)
hashInit Hash
SHA224   = ContextSimple -> HashContext
HashContext forall a b. (a -> b) -> a -> b
$ forall alg. HashAlgorithm alg => Context alg -> ContextSimple
ContextSimple (forall a. HashAlgorithm a => Context a
H.hashInit :: H.Context H.SHA224)
hashInit Hash
SHA256   = ContextSimple -> HashContext
HashContext forall a b. (a -> b) -> a -> b
$ forall alg. HashAlgorithm alg => Context alg -> ContextSimple
ContextSimple (forall a. HashAlgorithm a => Context a
H.hashInit :: H.Context H.SHA256)
hashInit Hash
SHA384   = ContextSimple -> HashContext
HashContext forall a b. (a -> b) -> a -> b
$ forall alg. HashAlgorithm alg => Context alg -> ContextSimple
ContextSimple (forall a. HashAlgorithm a => Context a
H.hashInit :: H.Context H.SHA384)
hashInit Hash
SHA512   = ContextSimple -> HashContext
HashContext forall a b. (a -> b) -> a -> b
$ forall alg. HashAlgorithm alg => Context alg -> ContextSimple
ContextSimple (forall a. HashAlgorithm a => Context a
H.hashInit :: H.Context H.SHA512)
hashInit Hash
SHA1_MD5 = Context SHA1 -> Context MD5 -> HashContext
HashContextSSL forall a. HashAlgorithm a => Context a
H.hashInit forall a. HashAlgorithm a => Context a
H.hashInit

hashUpdate :: HashContext -> B.ByteString -> HashCtx
hashUpdate :: HashContext -> ByteString -> HashContext
hashUpdate (HashContext (ContextSimple Context alg
h)) ByteString
b = ContextSimple -> HashContext
HashContext forall a b. (a -> b) -> a -> b
$ forall alg. HashAlgorithm alg => Context alg -> ContextSimple
ContextSimple (forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
Context a -> ba -> Context a
H.hashUpdate Context alg
h ByteString
b)
hashUpdate (HashContextSSL Context SHA1
sha1Ctx Context MD5
md5Ctx) ByteString
b =
    Context SHA1 -> Context MD5 -> HashContext
HashContextSSL (forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
Context a -> ba -> Context a
H.hashUpdate Context SHA1
sha1Ctx ByteString
b) (forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
Context a -> ba -> Context a
H.hashUpdate Context MD5
md5Ctx ByteString
b)

hashUpdateSSL :: HashCtx
              -> (B.ByteString,B.ByteString) -- ^ (for the md5 context, for the sha1 context)
              -> HashCtx
hashUpdateSSL :: HashContext -> (ByteString, ByteString) -> HashContext
hashUpdateSSL (HashContext ContextSimple
_) (ByteString, ByteString)
_ = forall a. HasCallStack => String -> a
error String
"internal error: update SSL without a SSL Context"
hashUpdateSSL (HashContextSSL Context SHA1
sha1Ctx Context MD5
md5Ctx) (ByteString
b1,ByteString
b2) =
    Context SHA1 -> Context MD5 -> HashContext
HashContextSSL (forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
Context a -> ba -> Context a
H.hashUpdate Context SHA1
sha1Ctx ByteString
b2) (forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
Context a -> ba -> Context a
H.hashUpdate Context MD5
md5Ctx ByteString
b1)

hashFinal :: HashCtx -> B.ByteString
hashFinal :: HashContext -> ByteString
hashFinal (HashContext (ContextSimple Context alg
h)) = forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert forall a b. (a -> b) -> a -> b
$ forall a. HashAlgorithm a => Context a -> Digest a
H.hashFinalize Context alg
h
hashFinal (HashContextSSL Context SHA1
sha1Ctx Context MD5
md5Ctx) =
    [ByteString] -> ByteString
B.concat [forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert (forall a. HashAlgorithm a => Context a -> Digest a
H.hashFinalize Context MD5
md5Ctx), forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert (forall a. HashAlgorithm a => Context a -> Digest a
H.hashFinalize Context SHA1
sha1Ctx)]

data Hash = MD5 | SHA1 | SHA224 | SHA256 | SHA384 | SHA512 | SHA1_MD5
    deriving (Int -> Hash -> ShowS
[Hash] -> ShowS
Hash -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Hash] -> ShowS
$cshowList :: [Hash] -> ShowS
show :: Hash -> String
$cshow :: Hash -> String
showsPrec :: Int -> Hash -> ShowS
$cshowsPrec :: Int -> Hash -> ShowS
Show,Hash -> Hash -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Hash -> Hash -> Bool
$c/= :: Hash -> Hash -> Bool
== :: Hash -> Hash -> Bool
$c== :: Hash -> Hash -> Bool
Eq)

data HashContext =
      HashContext ContextSimple
    | HashContextSSL (H.Context H.SHA1) (H.Context H.MD5)

instance Show HashContext where
    show :: HashContext -> String
show HashContext
_ = String
"hash-context"

data ContextSimple = forall alg . H.HashAlgorithm alg => ContextSimple (H.Context alg)

type HashCtx = HashContext

hash :: Hash -> B.ByteString -> B.ByteString
hash :: Hash -> ByteString -> ByteString
hash Hash
MD5 ByteString
b      = forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
H.hash :: B.ByteString -> H.Digest H.MD5) forall a b. (a -> b) -> a -> b
$ ByteString
b
hash Hash
SHA1 ByteString
b     = forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
H.hash :: B.ByteString -> H.Digest H.SHA1) forall a b. (a -> b) -> a -> b
$ ByteString
b
hash Hash
SHA224 ByteString
b   = forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
H.hash :: B.ByteString -> H.Digest H.SHA224) forall a b. (a -> b) -> a -> b
$ ByteString
b
hash Hash
SHA256 ByteString
b   = forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
H.hash :: B.ByteString -> H.Digest H.SHA256) forall a b. (a -> b) -> a -> b
$ ByteString
b
hash Hash
SHA384 ByteString
b   = forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
H.hash :: B.ByteString -> H.Digest H.SHA384) forall a b. (a -> b) -> a -> b
$ ByteString
b
hash Hash
SHA512 ByteString
b   = forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
H.hash :: B.ByteString -> H.Digest H.SHA512) forall a b. (a -> b) -> a -> b
$ ByteString
b
hash Hash
SHA1_MD5 ByteString
b =
    [ByteString] -> ByteString
B.concat [forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert (ByteString -> Digest MD5
md5Hash ByteString
b), forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert (ByteString -> Digest SHA1
sha1Hash ByteString
b)]
  where
    sha1Hash :: B.ByteString -> H.Digest H.SHA1
    sha1Hash :: ByteString -> Digest SHA1
sha1Hash = forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
H.hash
    md5Hash :: B.ByteString -> H.Digest H.MD5
    md5Hash :: ByteString -> Digest MD5
md5Hash = forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
H.hash

hashName :: Hash -> String
hashName :: Hash -> String
hashName = forall a. Show a => a -> String
show

-- | Digest size in bytes.
hashDigestSize :: Hash -> Int
hashDigestSize :: Hash -> Int
hashDigestSize Hash
MD5    = Int
16
hashDigestSize Hash
SHA1   = Int
20
hashDigestSize Hash
SHA224 = Int
28
hashDigestSize Hash
SHA256 = Int
32
hashDigestSize Hash
SHA384 = Int
48
hashDigestSize Hash
SHA512 = Int
64
hashDigestSize Hash
SHA1_MD5 = Int
36

hashBlockSize :: Hash -> Int
hashBlockSize :: Hash -> Int
hashBlockSize Hash
MD5    = Int
64
hashBlockSize Hash
SHA1   = Int
64
hashBlockSize Hash
SHA224 = Int
64
hashBlockSize Hash
SHA256 = Int
64
hashBlockSize Hash
SHA384 = Int
128
hashBlockSize Hash
SHA512 = Int
128
hashBlockSize Hash
SHA1_MD5 = Int
64

{- key exchange methods encrypt and decrypt for each supported algorithm -}

generalizeRSAError :: Either RSA.Error a -> Either KxError a
generalizeRSAError :: forall a. Either Error a -> Either KxError a
generalizeRSAError (Left Error
e)  = forall a b. a -> Either a b
Left (Error -> KxError
RSAError Error
e)
generalizeRSAError (Right a
x) = forall a b. b -> Either a b
Right a
x

kxEncrypt :: MonadRandom r => PublicKey -> ByteString -> r (Either KxError ByteString)
kxEncrypt :: forall (r :: * -> *).
MonadRandom r =>
PubKey -> ByteString -> r (Either KxError ByteString)
kxEncrypt (PubKeyRSA PublicKey
pk) ByteString
b = forall a. Either Error a -> Either KxError a
generalizeRSAError forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
MonadRandom m =>
PublicKey -> ByteString -> m (Either Error ByteString)
RSA.encrypt PublicKey
pk ByteString
b
kxEncrypt PubKey
_              ByteString
_ = forall (m :: * -> *) a. Monad m => a -> m a
return (forall a b. a -> Either a b
Left KxError
KxUnsupported)

kxDecrypt :: MonadRandom r => PrivateKey -> ByteString -> r (Either KxError ByteString)
kxDecrypt :: forall (r :: * -> *).
MonadRandom r =>
PrivKey -> ByteString -> r (Either KxError ByteString)
kxDecrypt (PrivKeyRSA PrivateKey
pk) ByteString
b = forall a. Either Error a -> Either KxError a
generalizeRSAError forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
MonadRandom m =>
PrivateKey -> ByteString -> m (Either Error ByteString)
RSA.decryptSafer PrivateKey
pk ByteString
b
kxDecrypt PrivKey
_               ByteString
_ = forall (m :: * -> *) a. Monad m => a -> m a
return (forall a b. a -> Either a b
Left KxError
KxUnsupported)

data RSAEncoding = RSApkcs1 | RSApss deriving (Int -> RSAEncoding -> ShowS
[RSAEncoding] -> ShowS
RSAEncoding -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RSAEncoding] -> ShowS
$cshowList :: [RSAEncoding] -> ShowS
show :: RSAEncoding -> String
$cshow :: RSAEncoding -> String
showsPrec :: Int -> RSAEncoding -> ShowS
$cshowsPrec :: Int -> RSAEncoding -> ShowS
Show,RSAEncoding -> RSAEncoding -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RSAEncoding -> RSAEncoding -> Bool
$c/= :: RSAEncoding -> RSAEncoding -> Bool
== :: RSAEncoding -> RSAEncoding -> Bool
$c== :: RSAEncoding -> RSAEncoding -> Bool
Eq)

-- | Test the RSASSA-PKCS1 length condition described in RFC 8017 section 9.2,
-- i.e. @emLen >= tLen + 11@.  Lengths are in bytes.
kxCanUseRSApkcs1 :: RSA.PublicKey -> Hash -> Bool
kxCanUseRSApkcs1 :: PublicKey -> Hash -> Bool
kxCanUseRSApkcs1 PublicKey
pk Hash
h = PublicKey -> Int
RSA.public_size PublicKey
pk forall a. Ord a => a -> a -> Bool
>= Int
tLen forall a. Num a => a -> a -> a
+ Int
11
  where
    tLen :: Int
tLen = forall {a}. Num a => Hash -> a
prefixSize Hash
h forall a. Num a => a -> a -> a
+ Hash -> Int
hashDigestSize Hash
h

    prefixSize :: Hash -> a
prefixSize Hash
MD5    = a
18
    prefixSize Hash
SHA1   = a
15
    prefixSize Hash
SHA224 = a
19
    prefixSize Hash
SHA256 = a
19
    prefixSize Hash
SHA384 = a
19
    prefixSize Hash
SHA512 = a
19
    prefixSize Hash
_      = forall a. HasCallStack => String -> a
error (forall a. Show a => a -> String
show Hash
h forall a. [a] -> [a] -> [a]
++ String
" is not supported for RSASSA-PKCS1")

-- | Test the RSASSA-PSS length condition described in RFC 8017 section 9.1.1,
-- i.e. @emBits >= 8hLen + 8sLen + 9@.  Lengths are in bits.
kxCanUseRSApss :: RSA.PublicKey -> Hash -> Bool
kxCanUseRSApss :: PublicKey -> Hash -> Bool
kxCanUseRSApss PublicKey
pk Hash
h = Integer -> Int
numBits (PublicKey -> Integer
RSA.public_n PublicKey
pk) forall a. Ord a => a -> a -> Bool
>= Int
16 forall a. Num a => a -> a -> a
* Hash -> Int
hashDigestSize Hash
h forall a. Num a => a -> a -> a
+ Int
10

-- Signature algorithm and associated parameters.
--
-- FIXME add RSAPSSParams
data SignatureParams =
      RSAParams      Hash RSAEncoding
    | DSSParams
    | ECDSAParams    Hash
    | Ed25519Params
    | Ed448Params
    deriving (Int -> SignatureParams -> ShowS
[SignatureParams] -> ShowS
SignatureParams -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SignatureParams] -> ShowS
$cshowList :: [SignatureParams] -> ShowS
show :: SignatureParams -> String
$cshow :: SignatureParams -> String
showsPrec :: Int -> SignatureParams -> ShowS
$cshowsPrec :: Int -> SignatureParams -> ShowS
Show,SignatureParams -> SignatureParams -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SignatureParams -> SignatureParams -> Bool
$c/= :: SignatureParams -> SignatureParams -> Bool
== :: SignatureParams -> SignatureParams -> Bool
$c== :: SignatureParams -> SignatureParams -> Bool
Eq)

-- Verify that the signature matches the given message, using the
-- public key.
--

kxVerify :: PublicKey -> SignatureParams -> ByteString -> ByteString -> Bool
kxVerify :: PubKey -> SignatureParams -> ByteString -> ByteString -> Bool
kxVerify (PubKeyRSA PublicKey
pk) (RSAParams Hash
alg RSAEncoding
RSApkcs1) ByteString
msg ByteString
sign   = Hash -> PublicKey -> ByteString -> ByteString -> Bool
rsaVerifyHash Hash
alg PublicKey
pk ByteString
msg ByteString
sign
kxVerify (PubKeyRSA PublicKey
pk) (RSAParams Hash
alg RSAEncoding
RSApss)   ByteString
msg ByteString
sign   = Hash -> PublicKey -> ByteString -> ByteString -> Bool
rsapssVerifyHash Hash
alg PublicKey
pk ByteString
msg ByteString
sign
kxVerify (PubKeyDSA PublicKey
pk) SignatureParams
DSSParams                ByteString
msg ByteString
signBS =

    case ByteString -> Maybe Signature
dsaToSignature ByteString
signBS of
        Just Signature
sig -> forall msg hash.
(ByteArrayAccess msg, HashAlgorithm hash) =>
hash -> PublicKey -> Signature -> msg -> Bool
DSA.verify SHA1
H.SHA1 PublicKey
pk Signature
sig ByteString
msg
        Maybe Signature
_        -> Bool
False
  where
        dsaToSignature :: ByteString -> Maybe DSA.Signature
        dsaToSignature :: ByteString -> Maybe Signature
dsaToSignature ByteString
b =
            case forall a.
ASN1Decoding a =>
a -> ByteString -> Either ASN1Error [ASN1]
decodeASN1' BER
BER ByteString
b of
                Left ASN1Error
_     -> forall a. Maybe a
Nothing
                Right [ASN1]
asn1 ->
                    case [ASN1]
asn1 of
                        Start ASN1ConstructionType
Sequence:IntVal Integer
r:IntVal Integer
s:End ASN1ConstructionType
Sequence:[ASN1]
_ ->
                            forall a. a -> Maybe a
Just DSA.Signature { sign_r :: Integer
DSA.sign_r = Integer
r, sign_s :: Integer
DSA.sign_s = Integer
s }
                        [ASN1]
_ ->
                            forall a. Maybe a
Nothing
kxVerify (PubKeyEC PubKeyEC
key) (ECDSAParams Hash
alg) ByteString
msg ByteString
sigBS =
    forall a. a -> Maybe a -> a
fromMaybe Bool
False forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => m (m a) -> m a
join forall a b. (a -> b) -> a -> b
$
        forall a.
PubKeyEC
-> (forall curve.
    EllipticCurveECDSA curve =>
    Proxy curve -> PublicKey curve -> a)
-> (PublicKey -> a)
-> a
-> Maybe a
withPubKeyEC PubKeyEC
key forall {curve} {proxy :: * -> *}.
EllipticCurveECDSA curve =>
proxy curve -> Point curve -> Maybe Bool
verifyProxy PublicKey -> Maybe Bool
verifyClassic forall a. Maybe a
Nothing
  where
    decodeSignatureASN1 :: (Integer -> Integer -> a) -> Maybe a
decodeSignatureASN1 Integer -> Integer -> a
buildRS =
        case forall a.
ASN1Decoding a =>
a -> ByteString -> Either ASN1Error [ASN1]
decodeASN1' BER
BER ByteString
sigBS of
            Left ASN1Error
_  -> forall a. Maybe a
Nothing
            Right [Start ASN1ConstructionType
Sequence,IntVal Integer
r,IntVal Integer
s,End ASN1ConstructionType
Sequence] ->
                forall a. a -> Maybe a
Just (Integer -> Integer -> a
buildRS Integer
r Integer
s)
            Right [ASN1]
_ -> forall a. Maybe a
Nothing
    verifyProxy :: proxy curve -> Point curve -> Maybe Bool
verifyProxy proxy curve
prx Point curve
pubkey = do
        (Integer, Integer)
rs <- forall {a}. (Integer -> Integer -> a) -> Maybe a
decodeSignatureASN1 (,)
        Signature curve
signature <- forall a. CryptoFailable a -> Maybe a
maybeCryptoError forall a b. (a -> b) -> a -> b
$ forall curve (proxy :: * -> *).
EllipticCurveECDSA curve =>
proxy curve
-> (Integer, Integer) -> CryptoFailable (Signature curve)
ECDSA.signatureFromIntegers proxy curve
prx (Integer, Integer)
rs
        Point curve -> Signature curve -> ByteString -> Bool
verifyF <- forall a. (forall hash. HashAlgorithm hash => hash -> a) -> Maybe a
withAlg (forall curve msg hash (proxy :: * -> *).
(EllipticCurveECDSA curve, ByteArrayAccess msg,
 HashAlgorithm hash) =>
proxy curve
-> hash -> PublicKey curve -> Signature curve -> msg -> Bool
ECDSA.verify proxy curve
prx)
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Point curve -> Signature curve -> ByteString -> Bool
verifyF Point curve
pubkey Signature curve
signature ByteString
msg
    verifyClassic :: PublicKey -> Maybe Bool
verifyClassic PublicKey
pubkey = do
        Signature
signature <- forall {a}. (Integer -> Integer -> a) -> Maybe a
decodeSignatureASN1 Integer -> Integer -> Signature
ECDSA_ECC.Signature
        PublicKey -> Signature -> ByteString -> Bool
verifyF <- forall a. (forall hash. HashAlgorithm hash => hash -> a) -> Maybe a
withAlg forall msg hash.
(ByteArrayAccess msg, HashAlgorithm hash) =>
hash -> PublicKey -> Signature -> msg -> Bool
ECDSA_ECC.verify
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ PublicKey -> Signature -> ByteString -> Bool
verifyF PublicKey
pubkey Signature
signature ByteString
msg
    withAlg :: (forall hash . H.HashAlgorithm hash => hash -> a) -> Maybe a
    withAlg :: forall a. (forall hash. HashAlgorithm hash => hash -> a) -> Maybe a
withAlg forall hash. HashAlgorithm hash => hash -> a
f = case Hash
alg of
                    Hash
MD5    -> forall a. a -> Maybe a
Just (forall hash. HashAlgorithm hash => hash -> a
f MD5
H.MD5)
                    Hash
SHA1   -> forall a. a -> Maybe a
Just (forall hash. HashAlgorithm hash => hash -> a
f SHA1
H.SHA1)
                    Hash
SHA224 -> forall a. a -> Maybe a
Just (forall hash. HashAlgorithm hash => hash -> a
f SHA224
H.SHA224)
                    Hash
SHA256 -> forall a. a -> Maybe a
Just (forall hash. HashAlgorithm hash => hash -> a
f SHA256
H.SHA256)
                    Hash
SHA384 -> forall a. a -> Maybe a
Just (forall hash. HashAlgorithm hash => hash -> a
f SHA384
H.SHA384)
                    Hash
SHA512 -> forall a. a -> Maybe a
Just (forall hash. HashAlgorithm hash => hash -> a
f SHA512
H.SHA512)
                    Hash
_      -> forall a. Maybe a
Nothing
kxVerify (PubKeyEd25519 PublicKey
key) SignatureParams
Ed25519Params ByteString
msg ByteString
sigBS =
    case forall ba. ByteArrayAccess ba => ba -> CryptoFailable Signature
Ed25519.signature ByteString
sigBS of
        CryptoPassed Signature
sig -> forall ba.
ByteArrayAccess ba =>
PublicKey -> ba -> Signature -> Bool
Ed25519.verify PublicKey
key ByteString
msg Signature
sig
        CryptoFailable Signature
_                -> Bool
False
kxVerify (PubKeyEd448 PublicKey
key) SignatureParams
Ed448Params ByteString
msg ByteString
sigBS =
    case forall ba. ByteArrayAccess ba => ba -> CryptoFailable Signature
Ed448.signature ByteString
sigBS of
        CryptoPassed Signature
sig -> forall ba.
ByteArrayAccess ba =>
PublicKey -> ba -> Signature -> Bool
Ed448.verify PublicKey
key ByteString
msg Signature
sig
        CryptoFailable Signature
_                -> Bool
False
kxVerify PubKey
_              SignatureParams
_         ByteString
_   ByteString
_    = Bool
False

-- Sign the given message using the private key.
--
kxSign :: MonadRandom r
       => PrivateKey
       -> PublicKey
       -> SignatureParams
       -> ByteString
       -> r (Either KxError ByteString)
kxSign :: forall (r :: * -> *).
MonadRandom r =>
PrivKey
-> PubKey
-> SignatureParams
-> ByteString
-> r (Either KxError ByteString)
kxSign (PrivKeyRSA PrivateKey
pk) (PubKeyRSA PublicKey
_) (RSAParams Hash
hashAlg RSAEncoding
RSApkcs1) ByteString
msg =
    forall a. Either Error a -> Either KxError a
generalizeRSAError forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
MonadRandom m =>
Hash -> PrivateKey -> ByteString -> m (Either Error ByteString)
rsaSignHash Hash
hashAlg PrivateKey
pk ByteString
msg
kxSign (PrivKeyRSA PrivateKey
pk) (PubKeyRSA PublicKey
_) (RSAParams Hash
hashAlg RSAEncoding
RSApss) ByteString
msg =
    forall a. Either Error a -> Either KxError a
generalizeRSAError forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
MonadRandom m =>
Hash -> PrivateKey -> ByteString -> m (Either Error ByteString)
rsapssSignHash Hash
hashAlg PrivateKey
pk ByteString
msg
kxSign (PrivKeyDSA PrivateKey
pk) (PubKeyDSA PublicKey
_) SignatureParams
DSSParams ByteString
msg = do
    Signature
sign <- forall msg hash (m :: * -> *).
(ByteArrayAccess msg, HashAlgorithm hash, MonadRandom m) =>
PrivateKey -> hash -> msg -> m Signature
DSA.sign PrivateKey
pk SHA1
H.SHA1 ByteString
msg
    forall (m :: * -> *) a. Monad m => a -> m a
return (forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ forall a. ASN1Encoding a => a -> [ASN1] -> ByteString
encodeASN1' DER
DER forall a b. (a -> b) -> a -> b
$ Signature -> [ASN1]
dsaSequence Signature
sign)
  where dsaSequence :: Signature -> [ASN1]
dsaSequence Signature
sign = [ASN1ConstructionType -> ASN1
Start ASN1ConstructionType
Sequence,Integer -> ASN1
IntVal (Signature -> Integer
DSA.sign_r Signature
sign),Integer -> ASN1
IntVal (Signature -> Integer
DSA.sign_s Signature
sign),ASN1ConstructionType -> ASN1
End ASN1ConstructionType
Sequence]
kxSign (PrivKeyEC PrivKeyEC
pk) (PubKeyEC PubKeyEC
_) (ECDSAParams Hash
hashAlg) ByteString
msg =
    case forall a.
PrivKeyEC
-> (forall curve.
    EllipticCurveECDSA curve =>
    Proxy curve -> PrivateKey curve -> a)
-> (CurveName -> a)
-> a
-> Maybe a
withPrivKeyEC PrivKeyEC
pk forall {m :: * -> *} {curve} {proxy :: * -> *}.
(MonadRandom m, EllipticCurveECDSA curve) =>
proxy curve
-> Scalar curve -> m (Either KxError (Integer, Integer))
doSign (forall a b. a -> b -> a
const forall {b}. r (Either KxError b)
unsupported) forall {b}. r (Either KxError b)
unsupported of
        Maybe (r (Either KxError (Integer, Integer)))
Nothing  -> forall {b}. r (Either KxError b)
unsupported
        Just r (Either KxError (Integer, Integer))
run -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Integer, Integer) -> ByteString
encode forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> r (Either KxError (Integer, Integer))
run
  where encode :: (Integer, Integer) -> ByteString
encode (Integer
r, Integer
s) = forall a. ASN1Encoding a => a -> [ASN1] -> ByteString
encodeASN1' DER
DER
            [ ASN1ConstructionType -> ASN1
Start ASN1ConstructionType
Sequence, Integer -> ASN1
IntVal Integer
r, Integer -> ASN1
IntVal Integer
s, ASN1ConstructionType -> ASN1
End ASN1ConstructionType
Sequence ]
        doSign :: proxy curve
-> Scalar curve -> m (Either KxError (Integer, Integer))
doSign proxy curve
prx Scalar curve
privkey = do
            Maybe (Signature curve)
msig <- forall (m :: * -> *) curve (proxy :: * -> *).
(MonadRandom m, EllipticCurveECDSA curve) =>
proxy curve
-> Hash
-> Scalar curve
-> ByteString
-> m (Maybe (Signature curve))
ecdsaSignHash proxy curve
prx Hash
hashAlg Scalar curve
privkey ByteString
msg
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ case Maybe (Signature curve)
msig of
                         Maybe (Signature curve)
Nothing   -> forall a b. a -> Either a b
Left KxError
KxUnsupported
                         Just Signature curve
sign -> forall a b. b -> Either a b
Right (forall curve (proxy :: * -> *).
EllipticCurveECDSA curve =>
proxy curve -> Signature curve -> (Integer, Integer)
ECDSA.signatureToIntegers proxy curve
prx Signature curve
sign)
        unsupported :: r (Either KxError b)
unsupported = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. a -> Either a b
Left KxError
KxUnsupported
kxSign (PrivKeyEd25519 SecretKey
pk) (PubKeyEd25519 PublicKey
pub) SignatureParams
Ed25519Params ByteString
msg =
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert forall a b. (a -> b) -> a -> b
$ forall ba.
ByteArrayAccess ba =>
SecretKey -> PublicKey -> ba -> Signature
Ed25519.sign SecretKey
pk PublicKey
pub ByteString
msg
kxSign (PrivKeyEd448 SecretKey
pk) (PubKeyEd448 PublicKey
pub) SignatureParams
Ed448Params ByteString
msg =
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert forall a b. (a -> b) -> a -> b
$ forall ba.
ByteArrayAccess ba =>
SecretKey -> PublicKey -> ba -> Signature
Ed448.sign SecretKey
pk PublicKey
pub ByteString
msg
kxSign PrivKey
_ PubKey
_ SignatureParams
_ ByteString
_ =
    forall (m :: * -> *) a. Monad m => a -> m a
return (forall a b. a -> Either a b
Left KxError
KxUnsupported)

rsaSignHash :: MonadRandom m => Hash -> RSA.PrivateKey -> ByteString -> m (Either RSA.Error ByteString)
rsaSignHash :: forall (m :: * -> *).
MonadRandom m =>
Hash -> PrivateKey -> ByteString -> m (Either Error ByteString)
rsaSignHash Hash
SHA1_MD5 PrivateKey
pk ByteString
msg = forall hashAlg (m :: * -> *).
(HashAlgorithmASN1 hashAlg, MonadRandom m) =>
Maybe hashAlg
-> PrivateKey -> ByteString -> m (Either Error ByteString)
RSA.signSafer Maybe MD5
noHash PrivateKey
pk ByteString
msg
rsaSignHash Hash
MD5 PrivateKey
pk ByteString
msg      = forall hashAlg (m :: * -> *).
(HashAlgorithmASN1 hashAlg, MonadRandom m) =>
Maybe hashAlg
-> PrivateKey -> ByteString -> m (Either Error ByteString)
RSA.signSafer (forall a. a -> Maybe a
Just MD5
H.MD5) PrivateKey
pk ByteString
msg
rsaSignHash Hash
SHA1 PrivateKey
pk ByteString
msg     = forall hashAlg (m :: * -> *).
(HashAlgorithmASN1 hashAlg, MonadRandom m) =>
Maybe hashAlg
-> PrivateKey -> ByteString -> m (Either Error ByteString)
RSA.signSafer (forall a. a -> Maybe a
Just SHA1
H.SHA1) PrivateKey
pk ByteString
msg
rsaSignHash Hash
SHA224 PrivateKey
pk ByteString
msg   = forall hashAlg (m :: * -> *).
(HashAlgorithmASN1 hashAlg, MonadRandom m) =>
Maybe hashAlg
-> PrivateKey -> ByteString -> m (Either Error ByteString)
RSA.signSafer (forall a. a -> Maybe a
Just SHA224
H.SHA224) PrivateKey
pk ByteString
msg
rsaSignHash Hash
SHA256 PrivateKey
pk ByteString
msg   = forall hashAlg (m :: * -> *).
(HashAlgorithmASN1 hashAlg, MonadRandom m) =>
Maybe hashAlg
-> PrivateKey -> ByteString -> m (Either Error ByteString)
RSA.signSafer (forall a. a -> Maybe a
Just SHA256
H.SHA256) PrivateKey
pk ByteString
msg
rsaSignHash Hash
SHA384 PrivateKey
pk ByteString
msg   = forall hashAlg (m :: * -> *).
(HashAlgorithmASN1 hashAlg, MonadRandom m) =>
Maybe hashAlg
-> PrivateKey -> ByteString -> m (Either Error ByteString)
RSA.signSafer (forall a. a -> Maybe a
Just SHA384
H.SHA384) PrivateKey
pk ByteString
msg
rsaSignHash Hash
SHA512 PrivateKey
pk ByteString
msg   = forall hashAlg (m :: * -> *).
(HashAlgorithmASN1 hashAlg, MonadRandom m) =>
Maybe hashAlg
-> PrivateKey -> ByteString -> m (Either Error ByteString)
RSA.signSafer (forall a. a -> Maybe a
Just SHA512
H.SHA512) PrivateKey
pk ByteString
msg

rsapssSignHash :: MonadRandom m => Hash -> RSA.PrivateKey -> ByteString -> m (Either RSA.Error ByteString)
rsapssSignHash :: forall (m :: * -> *).
MonadRandom m =>
Hash -> PrivateKey -> ByteString -> m (Either Error ByteString)
rsapssSignHash Hash
SHA256 PrivateKey
pk ByteString
msg = forall hash (m :: * -> *).
(HashAlgorithm hash, MonadRandom m) =>
PSSParams hash ByteString ByteString
-> PrivateKey -> ByteString -> m (Either Error ByteString)
PSS.signSafer (forall seed output hash.
(ByteArrayAccess seed, ByteArray output, HashAlgorithm hash) =>
hash -> PSSParams hash seed output
PSS.defaultPSSParams SHA256
H.SHA256) PrivateKey
pk ByteString
msg
rsapssSignHash Hash
SHA384 PrivateKey
pk ByteString
msg = forall hash (m :: * -> *).
(HashAlgorithm hash, MonadRandom m) =>
PSSParams hash ByteString ByteString
-> PrivateKey -> ByteString -> m (Either Error ByteString)
PSS.signSafer (forall seed output hash.
(ByteArrayAccess seed, ByteArray output, HashAlgorithm hash) =>
hash -> PSSParams hash seed output
PSS.defaultPSSParams SHA384
H.SHA384) PrivateKey
pk ByteString
msg
rsapssSignHash Hash
SHA512 PrivateKey
pk ByteString
msg = forall hash (m :: * -> *).
(HashAlgorithm hash, MonadRandom m) =>
PSSParams hash ByteString ByteString
-> PrivateKey -> ByteString -> m (Either Error ByteString)
PSS.signSafer (forall seed output hash.
(ByteArrayAccess seed, ByteArray output, HashAlgorithm hash) =>
hash -> PSSParams hash seed output
PSS.defaultPSSParams SHA512
H.SHA512) PrivateKey
pk ByteString
msg
rsapssSignHash Hash
_ PrivateKey
_ ByteString
_         = forall a. HasCallStack => String -> a
error String
"rsapssSignHash: unsupported hash"

rsaVerifyHash :: Hash -> RSA.PublicKey -> ByteString -> ByteString -> Bool
rsaVerifyHash :: Hash -> PublicKey -> ByteString -> ByteString -> Bool
rsaVerifyHash Hash
SHA1_MD5 = forall hashAlg.
HashAlgorithmASN1 hashAlg =>
Maybe hashAlg -> PublicKey -> ByteString -> ByteString -> Bool
RSA.verify Maybe MD5
noHash
rsaVerifyHash Hash
MD5      = forall hashAlg.
HashAlgorithmASN1 hashAlg =>
Maybe hashAlg -> PublicKey -> ByteString -> ByteString -> Bool
RSA.verify (forall a. a -> Maybe a
Just MD5
H.MD5)
rsaVerifyHash Hash
SHA1     = forall hashAlg.
HashAlgorithmASN1 hashAlg =>
Maybe hashAlg -> PublicKey -> ByteString -> ByteString -> Bool
RSA.verify (forall a. a -> Maybe a
Just SHA1
H.SHA1)
rsaVerifyHash Hash
SHA224   = forall hashAlg.
HashAlgorithmASN1 hashAlg =>
Maybe hashAlg -> PublicKey -> ByteString -> ByteString -> Bool
RSA.verify (forall a. a -> Maybe a
Just SHA224
H.SHA224)
rsaVerifyHash Hash
SHA256   = forall hashAlg.
HashAlgorithmASN1 hashAlg =>
Maybe hashAlg -> PublicKey -> ByteString -> ByteString -> Bool
RSA.verify (forall a. a -> Maybe a
Just SHA256
H.SHA256)
rsaVerifyHash Hash
SHA384   = forall hashAlg.
HashAlgorithmASN1 hashAlg =>
Maybe hashAlg -> PublicKey -> ByteString -> ByteString -> Bool
RSA.verify (forall a. a -> Maybe a
Just SHA384
H.SHA384)
rsaVerifyHash Hash
SHA512   = forall hashAlg.
HashAlgorithmASN1 hashAlg =>
Maybe hashAlg -> PublicKey -> ByteString -> ByteString -> Bool
RSA.verify (forall a. a -> Maybe a
Just SHA512
H.SHA512)

rsapssVerifyHash :: Hash -> RSA.PublicKey -> ByteString -> ByteString -> Bool
rsapssVerifyHash :: Hash -> PublicKey -> ByteString -> ByteString -> Bool
rsapssVerifyHash Hash
SHA256 = forall hash.
HashAlgorithm hash =>
PSSParams hash ByteString ByteString
-> PublicKey -> ByteString -> ByteString -> Bool
PSS.verify (forall seed output hash.
(ByteArrayAccess seed, ByteArray output, HashAlgorithm hash) =>
hash -> PSSParams hash seed output
PSS.defaultPSSParams SHA256
H.SHA256)
rsapssVerifyHash Hash
SHA384 = forall hash.
HashAlgorithm hash =>
PSSParams hash ByteString ByteString
-> PublicKey -> ByteString -> ByteString -> Bool
PSS.verify (forall seed output hash.
(ByteArrayAccess seed, ByteArray output, HashAlgorithm hash) =>
hash -> PSSParams hash seed output
PSS.defaultPSSParams SHA384
H.SHA384)
rsapssVerifyHash Hash
SHA512 = forall hash.
HashAlgorithm hash =>
PSSParams hash ByteString ByteString
-> PublicKey -> ByteString -> ByteString -> Bool
PSS.verify (forall seed output hash.
(ByteArrayAccess seed, ByteArray output, HashAlgorithm hash) =>
hash -> PSSParams hash seed output
PSS.defaultPSSParams SHA512
H.SHA512)
rsapssVerifyHash Hash
_      = forall a. HasCallStack => String -> a
error String
"rsapssVerifyHash: unsupported hash"

noHash :: Maybe H.MD5
noHash :: Maybe MD5
noHash = forall a. Maybe a
Nothing

ecdsaSignHash :: (MonadRandom m, ECDSA.EllipticCurveECDSA curve)
              => proxy curve -> Hash -> ECDSA.Scalar curve -> ByteString -> m (Maybe (ECDSA.Signature curve))
ecdsaSignHash :: forall (m :: * -> *) curve (proxy :: * -> *).
(MonadRandom m, EllipticCurveECDSA curve) =>
proxy curve
-> Hash
-> Scalar curve
-> ByteString
-> m (Maybe (Signature curve))
ecdsaSignHash proxy curve
prx Hash
SHA1   Scalar curve
pk ByteString
msg   = forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall curve (m :: * -> *) msg hash (proxy :: * -> *).
(EllipticCurveECDSA curve, MonadRandom m, ByteArrayAccess msg,
 HashAlgorithm hash) =>
proxy curve
-> PrivateKey curve -> hash -> msg -> m (Signature curve)
ECDSA.sign proxy curve
prx Scalar curve
pk SHA1
H.SHA1   ByteString
msg
ecdsaSignHash proxy curve
prx Hash
SHA224 Scalar curve
pk ByteString
msg   = forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall curve (m :: * -> *) msg hash (proxy :: * -> *).
(EllipticCurveECDSA curve, MonadRandom m, ByteArrayAccess msg,
 HashAlgorithm hash) =>
proxy curve
-> PrivateKey curve -> hash -> msg -> m (Signature curve)
ECDSA.sign proxy curve
prx Scalar curve
pk SHA224
H.SHA224 ByteString
msg
ecdsaSignHash proxy curve
prx Hash
SHA256 Scalar curve
pk ByteString
msg   = forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall curve (m :: * -> *) msg hash (proxy :: * -> *).
(EllipticCurveECDSA curve, MonadRandom m, ByteArrayAccess msg,
 HashAlgorithm hash) =>
proxy curve
-> PrivateKey curve -> hash -> msg -> m (Signature curve)
ECDSA.sign proxy curve
prx Scalar curve
pk SHA256
H.SHA256 ByteString
msg
ecdsaSignHash proxy curve
prx Hash
SHA384 Scalar curve
pk ByteString
msg   = forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall curve (m :: * -> *) msg hash (proxy :: * -> *).
(EllipticCurveECDSA curve, MonadRandom m, ByteArrayAccess msg,
 HashAlgorithm hash) =>
proxy curve
-> PrivateKey curve -> hash -> msg -> m (Signature curve)
ECDSA.sign proxy curve
prx Scalar curve
pk SHA384
H.SHA384 ByteString
msg
ecdsaSignHash proxy curve
prx Hash
SHA512 Scalar curve
pk ByteString
msg   = forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall curve (m :: * -> *) msg hash (proxy :: * -> *).
(EllipticCurveECDSA curve, MonadRandom m, ByteArrayAccess msg,
 HashAlgorithm hash) =>
proxy curve
-> PrivateKey curve -> hash -> msg -> m (Signature curve)
ECDSA.sign proxy curve
prx Scalar curve
pk SHA512
H.SHA512 ByteString
msg
ecdsaSignHash proxy curve
_   Hash
_      Scalar curve
_  ByteString
_     = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing

-- Currently we generate ECDSA signatures in constant time for P256 only.
kxSupportedPrivKeyEC :: PrivKeyEC -> Bool
kxSupportedPrivKeyEC :: PrivKeyEC -> Bool
kxSupportedPrivKeyEC PrivKeyEC
privkey =
    case PrivKeyEC -> Maybe CurveName
ecPrivKeyCurveName PrivKeyEC
privkey of
        Just CurveName
ECC.SEC_p256r1 -> Bool
True
        Maybe CurveName
_                   -> Bool
False

-- Perform a public-key operation with a parameterized ECC implementation when
-- available, otherwise fallback to the classic ECC implementation.
withPubKeyEC :: PubKeyEC
             -> (forall curve . ECDSA.EllipticCurveECDSA curve => Proxy curve -> ECDSA.PublicKey curve -> a)
             -> (ECDSA_ECC.PublicKey -> a)
             -> a
             -> Maybe a
withPubKeyEC :: forall a.
PubKeyEC
-> (forall curve.
    EllipticCurveECDSA curve =>
    Proxy curve -> PublicKey curve -> a)
-> (PublicKey -> a)
-> a
-> Maybe a
withPubKeyEC PubKeyEC
pubkey forall curve.
EllipticCurveECDSA curve =>
Proxy curve -> PublicKey curve -> a
withProxy PublicKey -> a
withClassic a
whenUnknown =
    case PubKeyEC -> Maybe CurveName
ecPubKeyCurveName PubKeyEC
pubkey of
        Maybe CurveName
Nothing             -> forall a. a -> Maybe a
Just a
whenUnknown
        Just CurveName
ECC.SEC_p256r1 ->
            forall a. CryptoFailable a -> Maybe a
maybeCryptoError forall a b. (a -> b) -> a -> b
$ forall curve.
EllipticCurveECDSA curve =>
Proxy curve -> PublicKey curve -> a
withProxy Proxy Curve_P256R1
p256 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall curve bs (proxy :: * -> *).
(EllipticCurve curve, ByteArray bs) =>
proxy curve -> bs -> CryptoFailable (PublicKey curve)
ECDSA.decodePublic Proxy Curve_P256R1
p256 ByteString
bs
        Just CurveName
curveName      ->
            let curve :: Curve
curve = CurveName -> Curve
ECC.getCurveByName CurveName
curveName
                pub :: Maybe Point
pub   = Curve -> SerializedPoint -> Maybe Point
unserializePoint Curve
curve SerializedPoint
pt
             in PublicKey -> a
withClassic forall b c a. (b -> c) -> (a -> b) -> a -> c
. Curve -> Point -> PublicKey
ECDSA_ECC.PublicKey Curve
curve forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Point
pub
  where pt :: SerializedPoint
pt@(SerializedPoint ByteString
bs) = PubKeyEC -> SerializedPoint
pubkeyEC_pub PubKeyEC
pubkey

-- Perform a private-key operation with a parameterized ECC implementation when
-- available.  Calls for an unsupported curve can be prevented with
-- kxSupportedEcPrivKey.
withPrivKeyEC :: PrivKeyEC
              -> (forall curve . ECDSA.EllipticCurveECDSA curve => Proxy curve -> ECDSA.PrivateKey curve -> a)
              -> (ECC.CurveName -> a)
              -> a
              -> Maybe a
withPrivKeyEC :: forall a.
PrivKeyEC
-> (forall curve.
    EllipticCurveECDSA curve =>
    Proxy curve -> PrivateKey curve -> a)
-> (CurveName -> a)
-> a
-> Maybe a
withPrivKeyEC PrivKeyEC
privkey forall curve.
EllipticCurveECDSA curve =>
Proxy curve -> PrivateKey curve -> a
withProxy CurveName -> a
withUnsupported a
whenUnknown =
    case PrivKeyEC -> Maybe CurveName
ecPrivKeyCurveName PrivKeyEC
privkey of
        Maybe CurveName
Nothing             -> forall a. a -> Maybe a
Just a
whenUnknown
        Just CurveName
ECC.SEC_p256r1 ->
            -- Private key should rather be stored as bytearray and converted
            -- using ECDSA.decodePrivate, unfortunately the data type chosen in
            -- x509 was Integer.
            forall a. CryptoFailable a -> Maybe a
maybeCryptoError forall a b. (a -> b) -> a -> b
$ forall curve.
EllipticCurveECDSA curve =>
Proxy curve -> PrivateKey curve -> a
withProxy Proxy Curve_P256R1
p256 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall curve (proxy :: * -> *).
EllipticCurveBasepointArith curve =>
proxy curve -> Integer -> CryptoFailable (Scalar curve)
ECDSA.scalarFromInteger Proxy Curve_P256R1
p256 Integer
d
        Just CurveName
curveName      -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ CurveName -> a
withUnsupported CurveName
curveName
  where d :: Integer
d = PrivKeyEC -> Integer
privkeyEC_priv PrivKeyEC
privkey

p256 :: Proxy ECDSA.Curve_P256R1
p256 :: Proxy Curve_P256R1
p256 = forall {k} (t :: k). Proxy t
Proxy