{-# 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