{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE RankNTypes #-}
{-# OPTIONS_HADDOCK hide #-}

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.ECC as ECDSA
import Crypto.Error
import qualified Crypto.Hash as H
import Crypto.Number.Basic (numBits)
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 Crypto.Random
import qualified Data.ByteArray as B (convert)
import qualified Data.ByteString as B

import Data.X509 (
    PrivKey (..),
    PrivKeyEC (..),
    PubKey (..),
    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.BinaryEncoding (BER (..), DER (..))
import Data.ASN1.Encoding
import Data.ASN1.Types

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
(Int -> KxError -> ShowS)
-> (KxError -> String) -> ([KxError] -> ShowS) -> Show KxError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> KxError -> ShowS
showsPrec :: Int -> KxError -> ShowS
$cshow :: KxError -> String
show :: KxError -> String
$cshowList :: [KxError] -> ShowS
showList :: [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_DSA (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
_) -> KeyExchangeSignatureAlg -> Maybe KeyExchangeSignatureAlg
forall a. a -> Maybe a
Just KeyExchangeSignatureAlg
KX_RSA
        (PubKeyDSA PublicKey
_, PrivKeyDSA PrivateKey
_) -> KeyExchangeSignatureAlg -> Maybe KeyExchangeSignatureAlg
forall a. a -> Maybe a
Just KeyExchangeSignatureAlg
KX_DSA
        (PubKeyEC PubKeyEC
_, PrivKeyEC PrivKeyEC
_) -> KeyExchangeSignatureAlg -> Maybe KeyExchangeSignatureAlg
forall a. a -> Maybe a
Just KeyExchangeSignatureAlg
KX_ECDSA
        (PubKeyEd25519 PublicKey
_, PrivKeyEd25519 SecretKey
_) -> KeyExchangeSignatureAlg -> Maybe KeyExchangeSignatureAlg
forall a. a -> Maybe a
Just KeyExchangeSignatureAlg
KX_ECDSA
        (PubKeyEd448 PublicKey
_, PrivKeyEd448 SecretKey
_) -> KeyExchangeSignatureAlg -> Maybe KeyExchangeSignatureAlg
forall a. a -> Maybe a
Just KeyExchangeSignatureAlg
KX_ECDSA
        (PubKey, PrivKey)
_ -> Maybe KeyExchangeSignatureAlg
forall a. Maybe a
Nothing

findFiniteFieldGroup :: DH.Params -> Maybe Group
findFiniteFieldGroup :: Params -> Maybe Group
findFiniteFieldGroup Params
params = (Integer, Integer) -> [((Integer, Integer), Group)] -> Maybe Group
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 prms :: Params
prms = Maybe Params -> Params
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe Params -> Params) -> Maybe Params -> Params
forall a b. (a -> b) -> a -> b
$ 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 -> Group -> Maybe Group
forall a. a -> Maybe a
Just Group
P256
        Just CurveName
ECC.SEC_p384r1 -> Group -> Maybe Group
forall a. a -> Maybe a
Just Group
P384
        Just CurveName
ECC.SEC_p521r1 -> Group -> Maybe Group
forall a. a -> Maybe a
Just Group
P521
        Maybe CurveName
_ -> Maybe Group
forall a. Maybe a
Nothing

-- functions to use the hidden class.
hashInit :: Hash -> HashContext
hashInit :: Hash -> HashContext
hashInit Hash
MD5 = ContextSimple -> HashContext
HashContext (ContextSimple -> HashContext) -> ContextSimple -> HashContext
forall a b. (a -> b) -> a -> b
$ Context MD5 -> ContextSimple
forall alg. HashAlgorithm alg => Context alg -> ContextSimple
ContextSimple (Context MD5
forall a. HashAlgorithm a => Context a
H.hashInit :: H.Context H.MD5)
hashInit Hash
SHA1 = ContextSimple -> HashContext
HashContext (ContextSimple -> HashContext) -> ContextSimple -> HashContext
forall a b. (a -> b) -> a -> b
$ Context SHA1 -> ContextSimple
forall alg. HashAlgorithm alg => Context alg -> ContextSimple
ContextSimple (Context SHA1
forall a. HashAlgorithm a => Context a
H.hashInit :: H.Context H.SHA1)
hashInit Hash
SHA224 = ContextSimple -> HashContext
HashContext (ContextSimple -> HashContext) -> ContextSimple -> HashContext
forall a b. (a -> b) -> a -> b
$ Context SHA224 -> ContextSimple
forall alg. HashAlgorithm alg => Context alg -> ContextSimple
ContextSimple (Context SHA224
forall a. HashAlgorithm a => Context a
H.hashInit :: H.Context H.SHA224)
hashInit Hash
SHA256 = ContextSimple -> HashContext
HashContext (ContextSimple -> HashContext) -> ContextSimple -> HashContext
forall a b. (a -> b) -> a -> b
$ Context SHA256 -> ContextSimple
forall alg. HashAlgorithm alg => Context alg -> ContextSimple
ContextSimple (Context SHA256
forall a. HashAlgorithm a => Context a
H.hashInit :: H.Context H.SHA256)
hashInit Hash
SHA384 = ContextSimple -> HashContext
HashContext (ContextSimple -> HashContext) -> ContextSimple -> HashContext
forall a b. (a -> b) -> a -> b
$ Context SHA384 -> ContextSimple
forall alg. HashAlgorithm alg => Context alg -> ContextSimple
ContextSimple (Context SHA384
forall a. HashAlgorithm a => Context a
H.hashInit :: H.Context H.SHA384)
hashInit Hash
SHA512 = ContextSimple -> HashContext
HashContext (ContextSimple -> HashContext) -> ContextSimple -> HashContext
forall a b. (a -> b) -> a -> b
$ Context SHA512 -> ContextSimple
forall alg. HashAlgorithm alg => Context alg -> ContextSimple
ContextSimple (Context SHA512
forall a. HashAlgorithm a => Context a
H.hashInit :: H.Context H.SHA512)
hashInit Hash
SHA1_MD5 = Context SHA1 -> Context MD5 -> HashContext
HashContextSSL Context SHA1
forall a. HashAlgorithm a => Context a
H.hashInit Context MD5
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 (ContextSimple -> HashContext) -> ContextSimple -> HashContext
forall a b. (a -> b) -> a -> b
$ Context alg -> ContextSimple
forall alg. HashAlgorithm alg => Context alg -> ContextSimple
ContextSimple (Context alg -> ByteString -> Context alg
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 (Context SHA1 -> ByteString -> Context SHA1
forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
Context a -> ba -> Context a
H.hashUpdate Context SHA1
sha1Ctx ByteString
b) (Context MD5 -> ByteString -> Context MD5
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)
_ = String -> HashContext
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 (Context SHA1 -> ByteString -> Context SHA1
forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
Context a -> ba -> Context a
H.hashUpdate Context SHA1
sha1Ctx ByteString
b2) (Context MD5 -> ByteString -> Context MD5
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)) = Digest alg -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert (Digest alg -> ByteString) -> Digest alg -> ByteString
forall a b. (a -> b) -> a -> b
$ Context alg -> Digest alg
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 [Digest MD5 -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert (Context MD5 -> Digest MD5
forall a. HashAlgorithm a => Context a -> Digest a
H.hashFinalize Context MD5
md5Ctx), Digest SHA1 -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert (Context SHA1 -> Digest SHA1
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
(Int -> Hash -> ShowS)
-> (Hash -> String) -> ([Hash] -> ShowS) -> Show Hash
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Hash -> ShowS
showsPrec :: Int -> Hash -> ShowS
$cshow :: Hash -> String
show :: Hash -> String
$cshowList :: [Hash] -> ShowS
showList :: [Hash] -> ShowS
Show, Hash -> Hash -> Bool
(Hash -> Hash -> Bool) -> (Hash -> Hash -> Bool) -> Eq Hash
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Hash -> Hash -> Bool
== :: Hash -> Hash -> Bool
$c/= :: Hash -> Hash -> Bool
/= :: 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 = Digest MD5 -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert (Digest MD5 -> ByteString)
-> (ByteString -> Digest MD5) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> Digest MD5
forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
H.hash :: B.ByteString -> H.Digest H.MD5) (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ ByteString
b
hash Hash
SHA1 ByteString
b = Digest SHA1 -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert (Digest SHA1 -> ByteString)
-> (ByteString -> Digest SHA1) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> Digest SHA1
forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
H.hash :: B.ByteString -> H.Digest H.SHA1) (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ ByteString
b
hash Hash
SHA224 ByteString
b = Digest SHA224 -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert (Digest SHA224 -> ByteString)
-> (ByteString -> Digest SHA224) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> Digest SHA224
forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
H.hash :: B.ByteString -> H.Digest H.SHA224) (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ ByteString
b
hash Hash
SHA256 ByteString
b = Digest SHA256 -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert (Digest SHA256 -> ByteString)
-> (ByteString -> Digest SHA256) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> Digest SHA256
forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
H.hash :: B.ByteString -> H.Digest H.SHA256) (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ ByteString
b
hash Hash
SHA384 ByteString
b = Digest SHA384 -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert (Digest SHA384 -> ByteString)
-> (ByteString -> Digest SHA384) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> Digest SHA384
forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
H.hash :: B.ByteString -> H.Digest H.SHA384) (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ ByteString
b
hash Hash
SHA512 ByteString
b = Digest SHA512 -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert (Digest SHA512 -> ByteString)
-> (ByteString -> Digest SHA512) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> Digest SHA512
forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
H.hash :: B.ByteString -> H.Digest H.SHA512) (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ ByteString
b
hash Hash
SHA1_MD5 ByteString
b =
    [ByteString] -> ByteString
B.concat [Digest MD5 -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert (ByteString -> Digest MD5
md5Hash ByteString
b), Digest SHA1 -> ByteString
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 = ByteString -> Digest SHA1
forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
H.hash
    md5Hash :: B.ByteString -> H.Digest H.MD5
    md5Hash :: ByteString -> Digest MD5
md5Hash = ByteString -> Digest MD5
forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
H.hash

hashName :: Hash -> String
hashName :: Hash -> String
hashName = Hash -> String
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) = KxError -> Either KxError a
forall a b. a -> Either a b
Left (Error -> KxError
RSAError Error
e)
generalizeRSAError (Right a
x) = a -> Either KxError a
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 = Either Error ByteString -> Either KxError ByteString
forall a. Either Error a -> Either KxError a
generalizeRSAError (Either Error ByteString -> Either KxError ByteString)
-> r (Either Error ByteString) -> r (Either KxError ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PublicKey -> ByteString -> r (Either Error ByteString)
forall (m :: * -> *).
MonadRandom m =>
PublicKey -> ByteString -> m (Either Error ByteString)
RSA.encrypt PublicKey
pk ByteString
b
kxEncrypt PubKey
_ ByteString
_ = Either KxError ByteString -> r (Either KxError ByteString)
forall a. a -> r a
forall (m :: * -> *) a. Monad m => a -> m a
return (KxError -> Either KxError ByteString
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 = Either Error ByteString -> Either KxError ByteString
forall a. Either Error a -> Either KxError a
generalizeRSAError (Either Error ByteString -> Either KxError ByteString)
-> r (Either Error ByteString) -> r (Either KxError ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PrivateKey -> ByteString -> r (Either Error ByteString)
forall (m :: * -> *).
MonadRandom m =>
PrivateKey -> ByteString -> m (Either Error ByteString)
RSA.decryptSafer PrivateKey
pk ByteString
b
kxDecrypt PrivKey
_ ByteString
_ = Either KxError ByteString -> r (Either KxError ByteString)
forall a. a -> r a
forall (m :: * -> *) a. Monad m => a -> m a
return (KxError -> Either KxError ByteString
forall a b. a -> Either a b
Left KxError
KxUnsupported)

data RSAEncoding = RSApkcs1 | RSApss deriving (Int -> RSAEncoding -> ShowS
[RSAEncoding] -> ShowS
RSAEncoding -> String
(Int -> RSAEncoding -> ShowS)
-> (RSAEncoding -> String)
-> ([RSAEncoding] -> ShowS)
-> Show RSAEncoding
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> RSAEncoding -> ShowS
showsPrec :: Int -> RSAEncoding -> ShowS
$cshow :: RSAEncoding -> String
show :: RSAEncoding -> String
$cshowList :: [RSAEncoding] -> ShowS
showList :: [RSAEncoding] -> ShowS
Show, RSAEncoding -> RSAEncoding -> Bool
(RSAEncoding -> RSAEncoding -> Bool)
-> (RSAEncoding -> RSAEncoding -> Bool) -> Eq RSAEncoding
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: RSAEncoding -> RSAEncoding -> Bool
== :: RSAEncoding -> RSAEncoding -> Bool
$c/= :: RSAEncoding -> RSAEncoding -> Bool
/= :: 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 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
tLen Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
11
  where
    tLen :: Int
tLen = Hash -> Int
forall {a}. Num a => Hash -> a
prefixSize Hash
h Int -> Int -> Int
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
_ = String -> a
forall a. HasCallStack => String -> a
error (Hash -> String
forall a. Show a => a -> String
show Hash
h String -> ShowS
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) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
16 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Hash -> Int
hashDigestSize Hash
h Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
10

-- Signature algorithm and associated parameters.
--
-- FIXME add RSAPSSParams
data SignatureParams
    = RSAParams Hash RSAEncoding
    | DSAParams
    | ECDSAParams Hash
    | Ed25519Params
    | Ed448Params
    deriving (Int -> SignatureParams -> ShowS
[SignatureParams] -> ShowS
SignatureParams -> String
(Int -> SignatureParams -> ShowS)
-> (SignatureParams -> String)
-> ([SignatureParams] -> ShowS)
-> Show SignatureParams
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SignatureParams -> ShowS
showsPrec :: Int -> SignatureParams -> ShowS
$cshow :: SignatureParams -> String
show :: SignatureParams -> String
$cshowList :: [SignatureParams] -> ShowS
showList :: [SignatureParams] -> ShowS
Show, SignatureParams -> SignatureParams -> Bool
(SignatureParams -> SignatureParams -> Bool)
-> (SignatureParams -> SignatureParams -> Bool)
-> Eq SignatureParams
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SignatureParams -> SignatureParams -> Bool
== :: SignatureParams -> SignatureParams -> Bool
$c/= :: SignatureParams -> SignatureParams -> Bool
/= :: 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
DSAParams ByteString
msg ByteString
signBS =
    case ByteString -> Maybe Signature
dsaToSignature ByteString
signBS of
        Just Signature
sig -> SHA1 -> PublicKey -> Signature -> ByteString -> Bool
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 BER -> ByteString -> Either ASN1Error [ASN1]
forall a.
ASN1Decoding a =>
a -> ByteString -> Either ASN1Error [ASN1]
decodeASN1' BER
BER ByteString
b of
            Left ASN1Error
_ -> Maybe Signature
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]
_ ->
                        Signature -> Maybe Signature
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]
_ ->
                        Maybe Signature
forall a. Maybe a
Nothing
kxVerify (PubKeyEC PubKeyEC
key) (ECDSAParams Hash
alg) ByteString
msg ByteString
sigBS =
    Bool -> Maybe Bool -> Bool
forall a. a -> Maybe a -> a
fromMaybe Bool
False (Maybe Bool -> Bool) -> Maybe Bool -> Bool
forall a b. (a -> b) -> a -> b
$
        Maybe (Maybe Bool) -> Maybe Bool
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (Maybe (Maybe Bool) -> Maybe Bool)
-> Maybe (Maybe Bool) -> Maybe Bool
forall a b. (a -> b) -> a -> b
$
            PubKeyEC
-> (forall curve.
    EllipticCurveECDSA curve =>
    Proxy curve -> PublicKey curve -> Maybe Bool)
-> (PublicKey -> Maybe Bool)
-> Maybe Bool
-> Maybe (Maybe Bool)
forall a.
PubKeyEC
-> (forall curve.
    EllipticCurveECDSA curve =>
    Proxy curve -> PublicKey curve -> a)
-> (PublicKey -> a)
-> a
-> Maybe a
withPubKeyEC PubKeyEC
key Proxy curve -> Point curve -> Maybe Bool
forall curve.
EllipticCurveECDSA curve =>
Proxy curve -> PublicKey curve -> Maybe Bool
forall {curve} {proxy :: * -> *}.
EllipticCurveECDSA curve =>
proxy curve -> Point curve -> Maybe Bool
verifyProxy PublicKey -> Maybe Bool
verifyClassic Maybe Bool
forall a. Maybe a
Nothing
  where
    decodeSignatureASN1 :: (Integer -> Integer -> a) -> Maybe a
decodeSignatureASN1 Integer -> Integer -> a
buildRS =
        case BER -> ByteString -> Either ASN1Error [ASN1]
forall a.
ASN1Decoding a =>
a -> ByteString -> Either ASN1Error [ASN1]
decodeASN1' BER
BER ByteString
sigBS of
            Left ASN1Error
_ -> Maybe a
forall a. Maybe a
Nothing
            Right [Start ASN1ConstructionType
Sequence, IntVal Integer
r, IntVal Integer
s, End ASN1ConstructionType
Sequence] ->
                a -> Maybe a
forall a. a -> Maybe a
Just (Integer -> Integer -> a
buildRS Integer
r Integer
s)
            Right [ASN1]
_ -> Maybe a
forall a. Maybe a
Nothing
    verifyProxy :: proxy curve -> Point curve -> Maybe Bool
verifyProxy proxy curve
prx Point curve
pubkey = do
        (Integer, Integer)
rs <- (Integer -> Integer -> (Integer, Integer))
-> Maybe (Integer, Integer)
forall {a}. (Integer -> Integer -> a) -> Maybe a
decodeSignatureASN1 (,)
        Signature curve
signature <- CryptoFailable (Signature curve) -> Maybe (Signature curve)
forall a. CryptoFailable a -> Maybe a
maybeCryptoError (CryptoFailable (Signature curve) -> Maybe (Signature curve))
-> CryptoFailable (Signature curve) -> Maybe (Signature curve)
forall a b. (a -> b) -> a -> b
$ proxy curve
-> (Integer, Integer) -> CryptoFailable (Signature curve)
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 hash.
 HashAlgorithm hash =>
 hash -> Point curve -> Signature curve -> ByteString -> Bool)
-> Maybe (Point curve -> Signature curve -> ByteString -> Bool)
forall a. (forall hash. HashAlgorithm hash => hash -> a) -> Maybe a
withAlg (proxy curve
-> hash -> Point curve -> Signature curve -> ByteString -> Bool
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)
        Bool -> Maybe Bool
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> Maybe Bool) -> Bool -> Maybe Bool
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 <- (Integer -> Integer -> Signature) -> Maybe Signature
forall {a}. (Integer -> Integer -> a) -> Maybe a
decodeSignatureASN1 Integer -> Integer -> Signature
ECDSA_ECC.Signature
        PublicKey -> Signature -> ByteString -> Bool
verifyF <- (forall hash.
 HashAlgorithm hash =>
 hash -> PublicKey -> Signature -> ByteString -> Bool)
-> Maybe (PublicKey -> Signature -> ByteString -> Bool)
forall a. (forall hash. HashAlgorithm hash => hash -> a) -> Maybe a
withAlg hash -> PublicKey -> Signature -> ByteString -> Bool
forall hash.
HashAlgorithm hash =>
hash -> PublicKey -> Signature -> ByteString -> Bool
forall msg hash.
(ByteArrayAccess msg, HashAlgorithm hash) =>
hash -> PublicKey -> Signature -> msg -> Bool
ECDSA_ECC.verify
        Bool -> Maybe Bool
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> Maybe Bool) -> Bool -> Maybe Bool
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 -> a -> Maybe a
forall a. a -> Maybe a
Just (MD5 -> a
forall hash. HashAlgorithm hash => hash -> a
f MD5
H.MD5)
        Hash
SHA1 -> a -> Maybe a
forall a. a -> Maybe a
Just (SHA1 -> a
forall hash. HashAlgorithm hash => hash -> a
f SHA1
H.SHA1)
        Hash
SHA224 -> a -> Maybe a
forall a. a -> Maybe a
Just (SHA224 -> a
forall hash. HashAlgorithm hash => hash -> a
f SHA224
H.SHA224)
        Hash
SHA256 -> a -> Maybe a
forall a. a -> Maybe a
Just (SHA256 -> a
forall hash. HashAlgorithm hash => hash -> a
f SHA256
H.SHA256)
        Hash
SHA384 -> a -> Maybe a
forall a. a -> Maybe a
Just (SHA384 -> a
forall hash. HashAlgorithm hash => hash -> a
f SHA384
H.SHA384)
        Hash
SHA512 -> a -> Maybe a
forall a. a -> Maybe a
Just (SHA512 -> a
forall hash. HashAlgorithm hash => hash -> a
f SHA512
H.SHA512)
        Hash
_ -> Maybe a
forall a. Maybe a
Nothing
kxVerify (PubKeyEd25519 PublicKey
key) SignatureParams
Ed25519Params ByteString
msg ByteString
sigBS =
    case ByteString -> CryptoFailable Signature
forall ba. ByteArrayAccess ba => ba -> CryptoFailable Signature
Ed25519.signature ByteString
sigBS of
        CryptoPassed Signature
sig -> PublicKey -> ByteString -> Signature -> Bool
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 ByteString -> CryptoFailable Signature
forall ba. ByteArrayAccess ba => ba -> CryptoFailable Signature
Ed448.signature ByteString
sigBS of
        CryptoPassed Signature
sig -> PublicKey -> ByteString -> Signature -> Bool
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 =
    Either Error ByteString -> Either KxError ByteString
forall a. Either Error a -> Either KxError a
generalizeRSAError (Either Error ByteString -> Either KxError ByteString)
-> r (Either Error ByteString) -> r (Either KxError ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Hash -> PrivateKey -> ByteString -> r (Either Error ByteString)
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 =
    Either Error ByteString -> Either KxError ByteString
forall a. Either Error a -> Either KxError a
generalizeRSAError (Either Error ByteString -> Either KxError ByteString)
-> r (Either Error ByteString) -> r (Either KxError ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Hash -> PrivateKey -> ByteString -> r (Either Error ByteString)
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
DSAParams ByteString
msg = do
    Signature
sign <- PrivateKey -> SHA1 -> ByteString -> r Signature
forall msg hash (m :: * -> *).
(ByteArrayAccess msg, HashAlgorithm hash, MonadRandom m) =>
PrivateKey -> hash -> msg -> m Signature
DSA.sign PrivateKey
pk SHA1
H.SHA1 ByteString
msg
    Either KxError ByteString -> r (Either KxError ByteString)
forall a. a -> r a
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> Either KxError ByteString
forall a b. b -> Either a b
Right (ByteString -> Either KxError ByteString)
-> ByteString -> Either KxError ByteString
forall a b. (a -> b) -> a -> b
$ DER -> [ASN1] -> ByteString
forall a. ASN1Encoding a => a -> [ASN1] -> ByteString
encodeASN1' DER
DER ([ASN1] -> ByteString) -> [ASN1] -> ByteString
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 PrivKeyEC
-> (forall curve.
    EllipticCurveECDSA curve =>
    Proxy curve
    -> PrivateKey curve -> r (Either KxError (Integer, Integer)))
-> (CurveName -> r (Either KxError (Integer, Integer)))
-> r (Either KxError (Integer, Integer))
-> Maybe (r (Either KxError (Integer, Integer)))
forall a.
PrivKeyEC
-> (forall curve.
    EllipticCurveECDSA curve =>
    Proxy curve -> PrivateKey curve -> a)
-> (CurveName -> a)
-> a
-> Maybe a
withPrivKeyEC PrivKeyEC
pk Proxy curve
-> Scalar curve -> r (Either KxError (Integer, Integer))
forall curve.
EllipticCurveECDSA curve =>
Proxy curve
-> PrivateKey curve -> r (Either KxError (Integer, Integer))
forall {m :: * -> *} {curve} {proxy :: * -> *}.
(MonadRandom m, EllipticCurveECDSA curve) =>
proxy curve
-> Scalar curve -> m (Either KxError (Integer, Integer))
doSign (r (Either KxError (Integer, Integer))
-> CurveName -> r (Either KxError (Integer, Integer))
forall a b. a -> b -> a
const r (Either KxError (Integer, Integer))
forall {b}. r (Either KxError b)
unsupported) r (Either KxError (Integer, Integer))
forall {b}. r (Either KxError b)
unsupported of
        Maybe (r (Either KxError (Integer, Integer)))
Nothing -> r (Either KxError ByteString)
forall {b}. r (Either KxError b)
unsupported
        Just r (Either KxError (Integer, Integer))
run -> ((Integer, Integer) -> ByteString)
-> Either KxError (Integer, Integer) -> Either KxError ByteString
forall a b. (a -> b) -> Either KxError a -> Either KxError b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Integer, Integer) -> ByteString
encode (Either KxError (Integer, Integer) -> Either KxError ByteString)
-> r (Either KxError (Integer, Integer))
-> r (Either KxError ByteString)
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) =
        DER -> [ASN1] -> ByteString
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 <- proxy curve
-> Hash
-> Scalar curve
-> ByteString
-> m (Maybe (Signature curve))
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
        Either KxError (Integer, Integer)
-> m (Either KxError (Integer, Integer))
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either KxError (Integer, Integer)
 -> m (Either KxError (Integer, Integer)))
-> Either KxError (Integer, Integer)
-> m (Either KxError (Integer, Integer))
forall a b. (a -> b) -> a -> b
$ case Maybe (Signature curve)
msig of
            Maybe (Signature curve)
Nothing -> KxError -> Either KxError (Integer, Integer)
forall a b. a -> Either a b
Left KxError
KxUnsupported
            Just Signature curve
sign -> (Integer, Integer) -> Either KxError (Integer, Integer)
forall a b. b -> Either a b
Right (proxy curve -> Signature curve -> (Integer, Integer)
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 = Either KxError b -> r (Either KxError b)
forall a. a -> r a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either KxError b -> r (Either KxError b))
-> Either KxError b -> r (Either KxError b)
forall a b. (a -> b) -> a -> b
$ KxError -> Either KxError b
forall a b. a -> Either a b
Left KxError
KxUnsupported
kxSign (PrivKeyEd25519 SecretKey
pk) (PubKeyEd25519 PublicKey
pub) SignatureParams
Ed25519Params ByteString
msg =
    Either KxError ByteString -> r (Either KxError ByteString)
forall a. a -> r a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either KxError ByteString -> r (Either KxError ByteString))
-> Either KxError ByteString -> r (Either KxError ByteString)
forall a b. (a -> b) -> a -> b
$ ByteString -> Either KxError ByteString
forall a b. b -> Either a b
Right (ByteString -> Either KxError ByteString)
-> ByteString -> Either KxError ByteString
forall a b. (a -> b) -> a -> b
$ Signature -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert (Signature -> ByteString) -> Signature -> ByteString
forall a b. (a -> b) -> a -> b
$ SecretKey -> PublicKey -> ByteString -> Signature
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 =
    Either KxError ByteString -> r (Either KxError ByteString)
forall a. a -> r a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either KxError ByteString -> r (Either KxError ByteString))
-> Either KxError ByteString -> r (Either KxError ByteString)
forall a b. (a -> b) -> a -> b
$ ByteString -> Either KxError ByteString
forall a b. b -> Either a b
Right (ByteString -> Either KxError ByteString)
-> ByteString -> Either KxError ByteString
forall a b. (a -> b) -> a -> b
$ Signature -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert (Signature -> ByteString) -> Signature -> ByteString
forall a b. (a -> b) -> a -> b
$ SecretKey -> PublicKey -> ByteString -> Signature
forall ba.
ByteArrayAccess ba =>
SecretKey -> PublicKey -> ba -> Signature
Ed448.sign SecretKey
pk PublicKey
pub ByteString
msg
kxSign PrivKey
_ PubKey
_ SignatureParams
_ ByteString
_ =
    Either KxError ByteString -> r (Either KxError ByteString)
forall a. a -> r a
forall (m :: * -> *) a. Monad m => a -> m a
return (KxError -> Either KxError ByteString
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 = Maybe MD5
-> PrivateKey -> ByteString -> m (Either Error ByteString)
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 = Maybe MD5
-> PrivateKey -> ByteString -> m (Either Error ByteString)
forall hashAlg (m :: * -> *).
(HashAlgorithmASN1 hashAlg, MonadRandom m) =>
Maybe hashAlg
-> PrivateKey -> ByteString -> m (Either Error ByteString)
RSA.signSafer (MD5 -> Maybe MD5
forall a. a -> Maybe a
Just MD5
H.MD5) PrivateKey
pk ByteString
msg
rsaSignHash Hash
SHA1 PrivateKey
pk ByteString
msg = Maybe SHA1
-> PrivateKey -> ByteString -> m (Either Error ByteString)
forall hashAlg (m :: * -> *).
(HashAlgorithmASN1 hashAlg, MonadRandom m) =>
Maybe hashAlg
-> PrivateKey -> ByteString -> m (Either Error ByteString)
RSA.signSafer (SHA1 -> Maybe SHA1
forall a. a -> Maybe a
Just SHA1
H.SHA1) PrivateKey
pk ByteString
msg
rsaSignHash Hash
SHA224 PrivateKey
pk ByteString
msg = Maybe SHA224
-> PrivateKey -> ByteString -> m (Either Error ByteString)
forall hashAlg (m :: * -> *).
(HashAlgorithmASN1 hashAlg, MonadRandom m) =>
Maybe hashAlg
-> PrivateKey -> ByteString -> m (Either Error ByteString)
RSA.signSafer (SHA224 -> Maybe SHA224
forall a. a -> Maybe a
Just SHA224
H.SHA224) PrivateKey
pk ByteString
msg
rsaSignHash Hash
SHA256 PrivateKey
pk ByteString
msg = Maybe SHA256
-> PrivateKey -> ByteString -> m (Either Error ByteString)
forall hashAlg (m :: * -> *).
(HashAlgorithmASN1 hashAlg, MonadRandom m) =>
Maybe hashAlg
-> PrivateKey -> ByteString -> m (Either Error ByteString)
RSA.signSafer (SHA256 -> Maybe SHA256
forall a. a -> Maybe a
Just SHA256
H.SHA256) PrivateKey
pk ByteString
msg
rsaSignHash Hash
SHA384 PrivateKey
pk ByteString
msg = Maybe SHA384
-> PrivateKey -> ByteString -> m (Either Error ByteString)
forall hashAlg (m :: * -> *).
(HashAlgorithmASN1 hashAlg, MonadRandom m) =>
Maybe hashAlg
-> PrivateKey -> ByteString -> m (Either Error ByteString)
RSA.signSafer (SHA384 -> Maybe SHA384
forall a. a -> Maybe a
Just SHA384
H.SHA384) PrivateKey
pk ByteString
msg
rsaSignHash Hash
SHA512 PrivateKey
pk ByteString
msg = Maybe SHA512
-> PrivateKey -> ByteString -> m (Either Error ByteString)
forall hashAlg (m :: * -> *).
(HashAlgorithmASN1 hashAlg, MonadRandom m) =>
Maybe hashAlg
-> PrivateKey -> ByteString -> m (Either Error ByteString)
RSA.signSafer (SHA512 -> Maybe SHA512
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 = PSSParams SHA256 ByteString ByteString
-> PrivateKey -> ByteString -> m (Either Error ByteString)
forall hash (m :: * -> *).
(HashAlgorithm hash, MonadRandom m) =>
PSSParams hash ByteString ByteString
-> PrivateKey -> ByteString -> m (Either Error ByteString)
PSS.signSafer (SHA256 -> PSSParams SHA256 ByteString ByteString
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 = PSSParams SHA384 ByteString ByteString
-> PrivateKey -> ByteString -> m (Either Error ByteString)
forall hash (m :: * -> *).
(HashAlgorithm hash, MonadRandom m) =>
PSSParams hash ByteString ByteString
-> PrivateKey -> ByteString -> m (Either Error ByteString)
PSS.signSafer (SHA384 -> PSSParams SHA384 ByteString ByteString
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 = PSSParams SHA512 ByteString ByteString
-> PrivateKey -> ByteString -> m (Either Error ByteString)
forall hash (m :: * -> *).
(HashAlgorithm hash, MonadRandom m) =>
PSSParams hash ByteString ByteString
-> PrivateKey -> ByteString -> m (Either Error ByteString)
PSS.signSafer (SHA512 -> PSSParams SHA512 ByteString ByteString
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
_ = String -> m (Either Error 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 = Maybe MD5 -> PublicKey -> ByteString -> ByteString -> Bool
forall hashAlg.
HashAlgorithmASN1 hashAlg =>
Maybe hashAlg -> PublicKey -> ByteString -> ByteString -> Bool
RSA.verify Maybe MD5
noHash
rsaVerifyHash Hash
MD5 = Maybe MD5 -> PublicKey -> ByteString -> ByteString -> Bool
forall hashAlg.
HashAlgorithmASN1 hashAlg =>
Maybe hashAlg -> PublicKey -> ByteString -> ByteString -> Bool
RSA.verify (MD5 -> Maybe MD5
forall a. a -> Maybe a
Just MD5
H.MD5)
rsaVerifyHash Hash
SHA1 = Maybe SHA1 -> PublicKey -> ByteString -> ByteString -> Bool
forall hashAlg.
HashAlgorithmASN1 hashAlg =>
Maybe hashAlg -> PublicKey -> ByteString -> ByteString -> Bool
RSA.verify (SHA1 -> Maybe SHA1
forall a. a -> Maybe a
Just SHA1
H.SHA1)
rsaVerifyHash Hash
SHA224 = Maybe SHA224 -> PublicKey -> ByteString -> ByteString -> Bool
forall hashAlg.
HashAlgorithmASN1 hashAlg =>
Maybe hashAlg -> PublicKey -> ByteString -> ByteString -> Bool
RSA.verify (SHA224 -> Maybe SHA224
forall a. a -> Maybe a
Just SHA224
H.SHA224)
rsaVerifyHash Hash
SHA256 = Maybe SHA256 -> PublicKey -> ByteString -> ByteString -> Bool
forall hashAlg.
HashAlgorithmASN1 hashAlg =>
Maybe hashAlg -> PublicKey -> ByteString -> ByteString -> Bool
RSA.verify (SHA256 -> Maybe SHA256
forall a. a -> Maybe a
Just SHA256
H.SHA256)
rsaVerifyHash Hash
SHA384 = Maybe SHA384 -> PublicKey -> ByteString -> ByteString -> Bool
forall hashAlg.
HashAlgorithmASN1 hashAlg =>
Maybe hashAlg -> PublicKey -> ByteString -> ByteString -> Bool
RSA.verify (SHA384 -> Maybe SHA384
forall a. a -> Maybe a
Just SHA384
H.SHA384)
rsaVerifyHash Hash
SHA512 = Maybe SHA512 -> PublicKey -> ByteString -> ByteString -> Bool
forall hashAlg.
HashAlgorithmASN1 hashAlg =>
Maybe hashAlg -> PublicKey -> ByteString -> ByteString -> Bool
RSA.verify (SHA512 -> Maybe SHA512
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 = PSSParams SHA256 ByteString ByteString
-> PublicKey -> ByteString -> ByteString -> Bool
forall hash.
HashAlgorithm hash =>
PSSParams hash ByteString ByteString
-> PublicKey -> ByteString -> ByteString -> Bool
PSS.verify (SHA256 -> PSSParams SHA256 ByteString ByteString
forall seed output hash.
(ByteArrayAccess seed, ByteArray output, HashAlgorithm hash) =>
hash -> PSSParams hash seed output
PSS.defaultPSSParams SHA256
H.SHA256)
rsapssVerifyHash Hash
SHA384 = PSSParams SHA384 ByteString ByteString
-> PublicKey -> ByteString -> ByteString -> Bool
forall hash.
HashAlgorithm hash =>
PSSParams hash ByteString ByteString
-> PublicKey -> ByteString -> ByteString -> Bool
PSS.verify (SHA384 -> PSSParams SHA384 ByteString ByteString
forall seed output hash.
(ByteArrayAccess seed, ByteArray output, HashAlgorithm hash) =>
hash -> PSSParams hash seed output
PSS.defaultPSSParams SHA384
H.SHA384)
rsapssVerifyHash Hash
SHA512 = PSSParams SHA512 ByteString ByteString
-> PublicKey -> ByteString -> ByteString -> Bool
forall hash.
HashAlgorithm hash =>
PSSParams hash ByteString ByteString
-> PublicKey -> ByteString -> ByteString -> Bool
PSS.verify (SHA512 -> PSSParams SHA512 ByteString ByteString
forall seed output hash.
(ByteArrayAccess seed, ByteArray output, HashAlgorithm hash) =>
hash -> PSSParams hash seed output
PSS.defaultPSSParams SHA512
H.SHA512)
rsapssVerifyHash Hash
_ = String -> PublicKey -> ByteString -> ByteString -> Bool
forall a. HasCallStack => String -> a
error String
"rsapssVerifyHash: unsupported hash"

noHash :: Maybe H.MD5
noHash :: Maybe MD5
noHash = Maybe MD5
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 = Signature curve -> Maybe (Signature curve)
forall a. a -> Maybe a
Just (Signature curve -> Maybe (Signature curve))
-> m (Signature curve) -> m (Maybe (Signature curve))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> proxy curve
-> Scalar curve -> SHA1 -> ByteString -> m (Signature curve)
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 = Signature curve -> Maybe (Signature curve)
forall a. a -> Maybe a
Just (Signature curve -> Maybe (Signature curve))
-> m (Signature curve) -> m (Maybe (Signature curve))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> proxy curve
-> Scalar curve -> SHA224 -> ByteString -> m (Signature curve)
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 = Signature curve -> Maybe (Signature curve)
forall a. a -> Maybe a
Just (Signature curve -> Maybe (Signature curve))
-> m (Signature curve) -> m (Maybe (Signature curve))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> proxy curve
-> Scalar curve -> SHA256 -> ByteString -> m (Signature curve)
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 = Signature curve -> Maybe (Signature curve)
forall a. a -> Maybe a
Just (Signature curve -> Maybe (Signature curve))
-> m (Signature curve) -> m (Maybe (Signature curve))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> proxy curve
-> Scalar curve -> SHA384 -> ByteString -> m (Signature curve)
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 = Signature curve -> Maybe (Signature curve)
forall a. a -> Maybe a
Just (Signature curve -> Maybe (Signature curve))
-> m (Signature curve) -> m (Maybe (Signature curve))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> proxy curve
-> Scalar curve -> SHA512 -> ByteString -> m (Signature curve)
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
_ = Maybe (Signature curve) -> m (Maybe (Signature curve))
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Signature curve)
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 -> a -> Maybe a
forall a. a -> Maybe a
Just a
whenUnknown
        Just CurveName
ECC.SEC_p256r1 ->
            CryptoFailable a -> Maybe a
forall a. CryptoFailable a -> Maybe a
maybeCryptoError (CryptoFailable a -> Maybe a) -> CryptoFailable a -> Maybe a
forall a b. (a -> b) -> a -> b
$ Proxy Curve_P256R1 -> PublicKey Curve_P256R1 -> a
forall curve.
EllipticCurveECDSA curve =>
Proxy curve -> PublicKey curve -> a
withProxy Proxy Curve_P256R1
p256 (Point -> a) -> CryptoFailable Point -> CryptoFailable a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Proxy Curve_P256R1
-> ByteString -> CryptoFailable (PublicKey Curve_P256R1)
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 (PublicKey -> a) -> (Point -> PublicKey) -> Point -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Curve -> Point -> PublicKey
ECDSA_ECC.PublicKey Curve
curve (Point -> a) -> Maybe Point -> Maybe a
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 -> a -> Maybe a
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.
            CryptoFailable a -> Maybe a
forall a. CryptoFailable a -> Maybe a
maybeCryptoError (CryptoFailable a -> Maybe a) -> CryptoFailable a -> Maybe a
forall a b. (a -> b) -> a -> b
$ Proxy Curve_P256R1 -> PrivateKey Curve_P256R1 -> a
forall curve.
EllipticCurveECDSA curve =>
Proxy curve -> PrivateKey curve -> a
withProxy Proxy Curve_P256R1
p256 (Scalar -> a) -> CryptoFailable Scalar -> CryptoFailable a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Proxy Curve_P256R1
-> Integer -> CryptoFailable (PrivateKey Curve_P256R1)
forall curve (proxy :: * -> *).
EllipticCurveBasepointArith curve =>
proxy curve -> Integer -> CryptoFailable (Scalar curve)
forall (proxy :: * -> *).
proxy Curve_P256R1
-> Integer -> CryptoFailable (PrivateKey Curve_P256R1)
ECDSA.scalarFromInteger Proxy Curve_P256R1
p256 Integer
d
        Just CurveName
curveName -> a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> a -> Maybe a
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 = Proxy Curve_P256R1
forall {k} (t :: k). Proxy t
Proxy