    {-# OPTIONS_HADDOCK hide #-}
    {-# LANGUAGE ExistentialQuantification #-}
    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
        , 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.PubKey.DH as DH
    import qualified Crypto.PubKey.DSA as DSA
    import qualified Crypto.PubKey.ECC.ECDSA as ECDSA
    import qualified Crypto.PubKey.ECC.Types as ECC
    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(..), PubKeyEC(..))
    import Data.X509.EC (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(..))

    {-# 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
    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 KX_RSA   (PubKeyRSA     _)   = Bool
    True
        f KX_DSS   (PubKeyDSA     _)   = Bool
    True
        f KX_ECDSA (PubKeyEC      _)   = Bool
    True
        f KX_ECDSA (PubKeyEd25519 _)   = Bool
    True
        f KX_ECDSA (PubKeyEd448   _)   = Bool
    True
        f _        _                   = Bool
    False

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

    findFiniteFieldGroup :: DH.Params -> Maybe Group
    findFiniteFieldGroup :: Params -> Maybe Group
    findFiniteFieldGroup params :: 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 p :: Integer
    p g :: Integer
    g _) = (Integer
    p, Integer
    g)

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

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

    -- functions to use the hidden class.
    hashInit :: Hash -> HashContext
    hashInit :: Hash -> HashContext
    hashInit 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 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 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 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 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 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 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 h :: Context alg
    h)) b :: 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 sha1Ctx :: Context SHA1
    sha1Ctx md5Ctx :: Context MD5
    md5Ctx) b :: 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 _) _ = String -> HashContext
    forall a. HasCallStack => String -> a
    error "internal error: update SSL without a SSL Context"
    hashUpdateSSL (HashContextSSL sha1Ctx :: Context SHA1
    sha1Ctx md5Ctx :: Context MD5
    md5Ctx) (b1 :: ByteString
    b1,b2 :: 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 h :: 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 sha1Ctx :: Context SHA1
    sha1Ctx md5Ctx :: 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
    showList :: [Hash] -> ShowS
    $cshowList :: [Hash] -> ShowS
    show :: Hash -> String
    $cshow :: Hash -> String
    showsPrec :: Int -> Hash -> ShowS
    $cshowsPrec :: Int -> Hash -> ShowS
    Show,Hash -> Hash -> Bool
    (Hash -> Hash -> Bool) -> (Hash -> Hash -> Bool) -> Eq Hash
    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 _ = "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 MD5 b :: 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 SHA1 b :: 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 SHA224 b :: 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 SHA256 b :: 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 SHA384 b :: 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 SHA512 b :: 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 SHA1_MD5 b :: 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

    hashDigestSize :: Hash -> Int
    hashDigestSize :: Hash -> Int
    hashDigestSize MD5    = 16
    hashDigestSize SHA1   = 20
    hashDigestSize SHA224 = 28
    hashDigestSize SHA256 = 32
    hashDigestSize SHA384 = 48
    hashDigestSize SHA512 = 64
    hashDigestSize SHA1_MD5 = 36

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

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

    generalizeRSAError :: Either RSA.Error a -> Either KxError a
    generalizeRSAError :: Either Error a -> Either KxError a
    generalizeRSAError (Left e :: Error
    e)  = KxError -> Either KxError a
    forall a b. a -> Either a b
    Left (Error -> KxError
    RSAError Error
    e)
    generalizeRSAError (Right x :: 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 :: PubKey -> ByteString -> r (Either KxError ByteString)
    kxEncrypt (PubKeyRSA pk :: PublicKey
    pk) b :: 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 _              _ = Either KxError ByteString -> r (Either KxError ByteString)
    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 :: PrivKey -> ByteString -> r (Either KxError ByteString)
    kxDecrypt (PrivKeyRSA pk :: PrivateKey
    pk) b :: 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 _               _ = Either KxError ByteString -> r (Either KxError ByteString)
    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
    showList :: [RSAEncoding] -> ShowS
    $cshowList :: [RSAEncoding] -> ShowS
    show :: RSAEncoding -> String
    $cshow :: RSAEncoding -> String
    showsPrec :: Int -> RSAEncoding -> ShowS
    $cshowsPrec :: Int -> RSAEncoding -> ShowS
    Show,RSAEncoding -> RSAEncoding -> Bool
    (RSAEncoding -> RSAEncoding -> Bool)
    -> (RSAEncoding -> RSAEncoding -> Bool) -> Eq RSAEncoding
    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 pk :: PublicKey
    pk h :: 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
    + 11
      where
        tLen :: Int
    tLen = Hash -> Int
    forall p. Num p => Hash -> p
    prefixSize Hash
    h Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Hash -> Int
    hashDigestSize Hash
    h

        prefixSize :: Hash -> p
    prefixSize MD5    = 18
        prefixSize SHA1   = 15
        prefixSize SHA224 = 19
        prefixSize SHA256 = 19
        prefixSize SHA384 = 19
        prefixSize SHA512 = 19
        prefixSize _      = String -> p
    forall a. HasCallStack => String -> a
    error (Hash -> String
    forall a. Show a => a -> String
    show Hash
    h String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ " 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 pk :: PublicKey
    pk h :: Hash
    h = Integer -> Int
    numBits (PublicKey -> Integer
    RSA.public_n PublicKey
    pk) Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= 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
    + 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
    (Int -> SignatureParams -> ShowS)
    -> (SignatureParams -> String)
    -> ([SignatureParams] -> ShowS)
    -> Show SignatureParams
    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
    (SignatureParams -> SignatureParams -> Bool)
    -> (SignatureParams -> SignatureParams -> Bool)
    -> Eq SignatureParams
    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 pk :: PublicKey
    pk) (RSAParams alg :: Hash
    alg RSApkcs1) msg :: ByteString
    msg sign :: ByteString
    sign   = Hash -> PublicKey -> ByteString -> ByteString -> Bool
    rsaVerifyHash Hash
    alg PublicKey
    pk ByteString
    msg ByteString
    sign
    kxVerify (PubKeyRSA pk :: PublicKey
    pk) (RSAParams alg :: Hash
    alg RSApss)   msg :: ByteString
    msg sign :: ByteString
    sign   = Hash -> PublicKey -> ByteString -> ByteString -> Bool
    rsapssVerifyHash Hash
    alg PublicKey
    pk ByteString
    msg ByteString
    sign
    kxVerify (PubKeyDSA pk :: PublicKey
    pk) DSSParams                msg :: ByteString
    msg signBS :: ByteString
    signBS =

        case ByteString -> Maybe Signature
    dsaToSignature ByteString
    signBS of
            Just sig :: 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
            _        -> Bool
    False
      where
            dsaToSignature :: ByteString -> Maybe DSA.Signature
            dsaToSignature :: ByteString -> Maybe Signature
    dsaToSignature b :: ByteString
    b =
                case BER -> ByteString -> Either ASN1Error [ASN1]
    forall a.
    ASN1Decoding a =>
    a -> ByteString -> Either ASN1Error [ASN1]
    decodeASN1' BER
    BER ByteString
    b of
                    Left _     -> Maybe Signature
    forall a. Maybe a
    Nothing
                    Right asn1 :: [ASN1]
    asn1 ->
                        case [ASN1]
    asn1 of
                            Start Sequence:IntVal r :: Integer
    r:IntVal s :: Integer
    s:End Sequence:_ ->
                                Signature -> Maybe Signature
    forall a. a -> Maybe a
    Just Signature :: Integer -> Integer -> Signature
    DSA.Signature { sign_r :: Integer
    DSA.sign_r = Integer
    r, sign_s :: Integer
    DSA.sign_s = Integer
    s }
                            _ ->
                                Maybe Signature
    forall a. Maybe a
    Nothing
    kxVerify (PubKeyEC key :: PubKeyEC
    key) (ECDSAParams alg :: Hash
    alg) msg :: ByteString
    msg sigBS :: 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
    $ do
        -- get the curve name and the public key data
        let pubBS :: SerializedPoint
    pubBS = PubKeyEC -> SerializedPoint
    pubkeyEC_pub PubKeyEC
    key
        CurveName
    curveName <- PubKeyEC -> Maybe CurveName
    ecPubKeyCurveName PubKeyEC
    key
        -- decode the signature
        Signature
    signature <- case BER -> ByteString -> Either ASN1Error [ASN1]
    forall a.
    ASN1Decoding a =>
    a -> ByteString -> Either ASN1Error [ASN1]
    decodeASN1' BER
    BER ByteString
    sigBS of
            Left _ -> Maybe Signature
    forall a. Maybe a
    Nothing
            Right [Start Sequence,IntVal r :: Integer
    r,IntVal s :: Integer
    s,End Sequence] -> Signature -> Maybe Signature
    forall a. a -> Maybe a
    Just (Signature -> Maybe Signature) -> Signature -> Maybe Signature
    forall a b. (a -> b) -> a -> b
    $ Integer -> Integer -> Signature
    ECDSA.Signature Integer
    r Integer
    s
            Right _ -> Maybe Signature
    forall a. Maybe a
    Nothing

        -- decode the public key related to the curve
        let curve :: Curve
    curve = CurveName -> Curve
    ECC.getCurveByName CurveName
    curveName
        PublicKey
    pubkey <- Curve -> PublicPoint -> PublicKey
    ECDSA.PublicKey Curve
    curve (PublicPoint -> PublicKey) -> Maybe PublicPoint -> Maybe PublicKey
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Curve -> SerializedPoint -> Maybe PublicPoint
    unserializePoint Curve
    curve SerializedPoint
    pubBS

        PublicKey -> Signature -> ByteString -> Bool
    verifyF <- case Hash
    alg of
                        MD5    -> (PublicKey -> Signature -> ByteString -> Bool)
    -> Maybe (PublicKey -> Signature -> ByteString -> Bool)
    forall a. a -> Maybe a
    Just (MD5 -> PublicKey -> Signature -> ByteString -> Bool
    forall msg hash.
    (ByteArrayAccess msg, HashAlgorithm hash) =>
    hash -> PublicKey -> Signature -> msg -> Bool
    ECDSA.verify MD5
    H.MD5)
                        SHA1   -> (PublicKey -> Signature -> ByteString -> Bool)
    -> Maybe (PublicKey -> Signature -> ByteString -> Bool)
    forall a. a -> Maybe a
    Just (SHA1 -> PublicKey -> Signature -> ByteString -> Bool
    forall msg hash.
    (ByteArrayAccess msg, HashAlgorithm hash) =>
    hash -> PublicKey -> Signature -> msg -> Bool
    ECDSA.verify SHA1
    H.SHA1)
                        SHA224 -> (PublicKey -> Signature -> ByteString -> Bool)
    -> Maybe (PublicKey -> Signature -> ByteString -> Bool)
    forall a. a -> Maybe a
    Just (SHA224 -> PublicKey -> Signature -> ByteString -> Bool
    forall msg hash.
    (ByteArrayAccess msg, HashAlgorithm hash) =>
    hash -> PublicKey -> Signature -> msg -> Bool
    ECDSA.verify SHA224
    H.SHA224)
                        SHA256 -> (PublicKey -> Signature -> ByteString -> Bool)
    -> Maybe (PublicKey -> Signature -> ByteString -> Bool)
    forall a. a -> Maybe a
    Just (SHA256 -> PublicKey -> Signature -> ByteString -> Bool
    forall msg hash.
    (ByteArrayAccess msg, HashAlgorithm hash) =>
    hash -> PublicKey -> Signature -> msg -> Bool
    ECDSA.verify SHA256
    H.SHA256)
                        SHA384 -> (PublicKey -> Signature -> ByteString -> Bool)
    -> Maybe (PublicKey -> Signature -> ByteString -> Bool)
    forall a. a -> Maybe a
    Just (SHA384 -> PublicKey -> Signature -> ByteString -> Bool
    forall msg hash.
    (ByteArrayAccess msg, HashAlgorithm hash) =>
    hash -> PublicKey -> Signature -> msg -> Bool
    ECDSA.verify SHA384
    H.SHA384)
                        SHA512 -> (PublicKey -> Signature -> ByteString -> Bool)
    -> Maybe (PublicKey -> Signature -> ByteString -> Bool)
    forall a. a -> Maybe a
    Just (SHA512 -> PublicKey -> Signature -> ByteString -> Bool
    forall msg hash.
    (ByteArrayAccess msg, HashAlgorithm hash) =>
    hash -> PublicKey -> Signature -> msg -> Bool
    ECDSA.verify SHA512
    H.SHA512)
                        _      -> Maybe (PublicKey -> Signature -> ByteString -> Bool)
    forall a. Maybe a
    Nothing
        Bool -> Maybe Bool
    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
    kxVerify (PubKeyEd25519 key :: PublicKey
    key) Ed25519Params msg :: ByteString
    msg sigBS :: ByteString
    sigBS =
        case ByteString -> CryptoFailable Signature
    forall ba. ByteArrayAccess ba => ba -> CryptoFailable Signature
    Ed25519.signature ByteString
    sigBS of
            CryptoPassed sig :: Signature
    sig -> PublicKey -> ByteString -> Signature -> Bool
    forall ba.
    ByteArrayAccess ba =>
    PublicKey -> ba -> Signature -> Bool
    Ed25519.verify PublicKey
    key ByteString
    msg Signature
    sig
            _                -> Bool
    False
    kxVerify (PubKeyEd448 key :: PublicKey
    key) Ed448Params msg :: ByteString
    msg sigBS :: ByteString
    sigBS =
        case ByteString -> CryptoFailable Signature
    forall ba. ByteArrayAccess ba => ba -> CryptoFailable Signature
    Ed448.signature ByteString
    sigBS of
            CryptoPassed sig :: Signature
    sig -> PublicKey -> ByteString -> Signature -> Bool
    forall ba.
    ByteArrayAccess ba =>
    PublicKey -> ba -> Signature -> Bool
    Ed448.verify PublicKey
    key ByteString
    msg Signature
    sig
            _                -> Bool
    False
    kxVerify _              _         _   _    = Bool
    False

    -- Sign the given message using the private key.
    --
    kxSign :: MonadRandom r
           => PrivateKey
           -> PublicKey
           -> SignatureParams
           -> ByteString
           -> r (Either KxError ByteString)
    kxSign :: PrivKey
    -> PubKey
    -> SignatureParams
    -> ByteString
    -> r (Either KxError ByteString)
    kxSign (PrivKeyRSA pk :: PrivateKey
    pk) (PubKeyRSA _) (RSAParams hashAlg :: Hash
    hashAlg RSApkcs1) msg :: 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 pk :: PrivateKey
    pk) (PubKeyRSA _) (RSAParams hashAlg :: Hash
    hashAlg RSApss) msg :: 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 pk :: PrivateKey
    pk) (PubKeyDSA _) DSSParams msg :: 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 (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 sign :: 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 (PrivKeyEd25519 pk :: SecretKey
    pk) (PubKeyEd25519 pub :: PublicKey
    pub) Ed25519Params msg :: ByteString
    msg =
        Either KxError ByteString -> r (Either KxError ByteString)
    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 pk :: SecretKey
    pk) (PubKeyEd448 pub :: PublicKey
    pub) Ed448Params msg :: ByteString
    msg =
        Either KxError ByteString -> r (Either KxError ByteString)
    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 _ _ _ _ =
        Either KxError ByteString -> r (Either KxError ByteString)
    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 :: Hash -> PrivateKey -> ByteString -> m (Either Error ByteString)
    rsaSignHash SHA1_MD5 pk :: PrivateKey
    pk msg :: 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 MD5 pk :: PrivateKey
    pk msg :: 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 SHA1 pk :: PrivateKey
    pk msg :: 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 SHA224 pk :: PrivateKey
    pk msg :: 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 SHA256 pk :: PrivateKey
    pk msg :: 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 SHA384 pk :: PrivateKey
    pk msg :: 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 SHA512 pk :: PrivateKey
    pk msg :: 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 :: Hash -> PrivateKey -> ByteString -> m (Either Error ByteString)
    rsapssSignHash SHA256 pk :: PrivateKey
    pk msg :: 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 SHA384 pk :: PrivateKey
    pk msg :: 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 SHA512 pk :: PrivateKey
    pk msg :: 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 _ _ _         = String -> m (Either Error ByteString)
    forall a. HasCallStack => String -> a
    error "rsapssSignHash: unsupported hash"

    rsaVerifyHash :: Hash -> RSA.PublicKey -> ByteString -> ByteString -> Bool
    rsaVerifyHash :: Hash -> PublicKey -> ByteString -> ByteString -> Bool
    rsaVerifyHash SHA1_MD5 = Maybe MD5 -> PublicKey -> ByteString -> ByteString -> Bool
    forall hashAlg.
    HashAlgorithmASN1 hashAlg =>
    Maybe hashAlg -> PublicKey -> ByteString -> ByteString -> Bool
    RSA.verify Maybe MD5
    noHash
    rsaVerifyHash 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 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 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 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 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 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 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 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 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 _      = String -> PublicKey -> ByteString -> ByteString -> Bool
    forall a. HasCallStack => String -> a
    error "rsapssVerifyHash: unsupported hash"

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