-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/

-- | Serialization of cryptographic data types
--   
--   Haskell implementation of PKCS #8, PKCS #12 and CMS (Cryptographic
--   Message Syntax).
@package cryptostore
@version 0.3.1.0

-- | Error data type.
module Crypto.Store.Error

-- | Error type in cryptostore.
data StoreError

-- | Wraps a cryptonite error
CryptoError :: CryptoError -> StoreError

-- | Wraps an RSA crypto error
RSAError :: Error -> StoreError

-- | Error while decoding ASN.1 content
DecodingError :: ASN1Error -> StoreError

-- | Error while parsing an ASN.1 object
ParseFailure :: String -> StoreError

-- | Unable to decrypt, incorrect key or password?
DecryptionFailed :: StoreError

-- | MAC verification failed, incorrect key or password?
BadContentMAC :: StoreError

-- | Checksum verification failed, incorrect key or password?
BadChecksum :: StoreError

-- | Digest verification failed
DigestMismatch :: StoreError

-- | Signature verification failed
SignatureNotVerified :: StoreError

-- | Some condition is not met about input to algorithm
InvalidInput :: String -> StoreError

-- | Some condition is not met about input password
InvalidPassword :: String -> StoreError

-- | Some condition is not met about algorithm parameters
InvalidParameter :: String -> StoreError

-- | The algorithm expects another public key type
UnexpectedPublicKeyType :: StoreError

-- | The algorithm expects another private key type
UnexpectedPrivateKeyType :: StoreError

-- | Returned when the type of recipient info does not match the consumer
--   function
RecipientTypeMismatch :: StoreError

-- | The certificate provided does not match any encrypted key found
RecipientKeyNotFound :: StoreError

-- | No recipient info is available in the enveloped data
NoRecipientInfoFound :: StoreError

-- | No recipient info could be used with the consumer function
NoRecipientInfoMatched :: StoreError

-- | Only anonymous public key is supported
UnsupportedOriginatorFormat :: StoreError

-- | The elliptic curve used is not supported
UnsupportedEllipticCurve :: StoreError

-- | The algorithm requires a named elliptic curve
NamedCurveRequired :: StoreError

-- | Turn a CryptoFailed into a StoreError.
fromCryptoFailable :: CryptoFailable a -> Either StoreError a
instance GHC.Classes.Eq Crypto.Store.Error.StoreError
instance GHC.Show.Show Crypto.Store.Error.StoreError

-- | Triple-DES Key Wrap (RFC 3217)
--   
--   Should be used with a cipher from module
--   Crypto.Cipher.TripleDES.
module Crypto.Store.KeyWrap.TripleDES

-- | Wrap a Triple-DES key with the specified Triple-DES cipher.
--   
--   Input must be 24 bytes. A fresh IV should be generated randomly for
--   each invocation.
wrap :: (BlockCipher cipher, ByteArray ba) => cipher -> IV cipher -> ba -> Either StoreError ba

-- | Unwrap an encrypted Triple-DES key with the specified Triple-DES
--   cipher.
unwrap :: (BlockCipher cipher, ByteArray ba) => cipher -> ba -> Either StoreError ba

-- | RC2 Key Wrap (RFC 3217)
--   
--   Should be used with a cipher from module
--   Crypto.Store.Cipher.RC2.
module Crypto.Store.KeyWrap.RC2

-- | Wrap an RC2 key with the specified RC2 cipher.
--   
--   Input must be between 0 and 255 bytes. A fresh IV should be generated
--   randomly for each invocation.
wrap :: (MonadRandom m, BlockCipher cipher, ByteArray ba) => cipher -> IV cipher -> ba -> m (Either StoreError ba)

-- | Wrap an RC2 key with the specified RC2 cipher, using the given source
--   of random padding data.
--   
--   Input must be between 0 and 255 bytes. A fresh IV should be generated
--   randomly for each invocation.
wrap' :: (ByteArray ba, BlockCipher cipher) => (StoreError -> result) -> ((ba -> ba) -> Int -> result) -> cipher -> IV cipher -> ba -> result

-- | Unwrap an encrypted RC2 key with the specified RC2 cipher.
unwrap :: (BlockCipher cipher, ByteArray ba) => cipher -> ba -> Either StoreError ba

-- | AES Key Wrap (RFC 3394) and Extended Key Wrap (RFC 5649)
--   
--   Should be used with a cipher from module Crypto.Cipher.AES.
module Crypto.Store.KeyWrap.AES

-- | Wrap a key with the specified AES cipher.
wrap :: (BlockCipher aes, ByteArray ba) => aes -> ba -> Either StoreError ba

-- | Unwrap an encrypted key with the specified AES cipher.
unwrap :: (BlockCipher aes, ByteArray ba) => aes -> ba -> Either StoreError ba

-- | Pad and wrap a key with the specified AES cipher.
wrapPad :: (BlockCipher aes, ByteArray ba) => aes -> ba -> Either StoreError ba

-- | Unwrap and unpad an encrypted key with the specified AES cipher.
unwrapPad :: (BlockCipher aes, ByteArray ba) => aes -> ba -> Either StoreError ba

-- | Implementation of RC2 block cipher, a legacy algorithm providing weak
--   security. Use only for compatibility with software requiring this
--   cipher and data which is not sensitive.
module Crypto.Store.Cipher.RC2

-- | RC2 block cipher. Key is between 8 and 1024 bits.
data RC2

-- | Build a RC2 cipher with the specified effective key length (in bits).
rc2WithEffectiveKeyLength :: ByteArrayAccess key => Int -> key -> CryptoFailable RC2
instance Crypto.Cipher.Types.Base.Cipher Crypto.Store.Cipher.RC2.RC2
instance Crypto.Cipher.Types.Block.BlockCipher Crypto.Store.Cipher.RC2.RC2

-- | Password-Based Cryptography, aka PKCS #5.
module Crypto.Store.PKCS5

-- | A password stored as a sequence of UTF-8 bytes.
--   
--   Some key-derivation functions add restrictions to what characters are
--   supported.
--   
--   The data type provides a special value emptyNotTerminated that
--   is used as alternate representation of empty passwords on some systems
--   and that produces encryption results different than an empty
--   bytearray.
--   
--   Conversion to/from a regular sequence of bytes is possible with
--   functions toProtectionPassword and
--   fromProtectionPassword.
--   
--   Beware: the fromString implementation correctly handles
--   multi-byte characters, so here is not equivalent to the
--   ByteString counterpart.
data ProtectionPassword

-- | A value denoting an empty password, but having a special encoding when
--   deriving a symmetric key on some systems, like the certificate export
--   wizard on Windows.
--   
--   This value is different from toProtectionPassword ""
--   and can be tried when decrypting content with a password known to be
--   empty.
emptyNotTerminated :: ProtectionPassword

-- | Extract the UTF-8 bytes in a password value.
fromProtectionPassword :: ProtectionPassword -> ByteString

-- | Build a password value from a sequence of UTF-8 bytes.
--   
--   When the password is empty, the special value
--   emptyNotTerminated may be tried as well.
toProtectionPassword :: ByteString -> ProtectionPassword

-- | Encrypted content.
type EncryptedContent = ByteString

-- | Content encrypted with a Password-Based Encryption Scheme (PBES).
--   
--   The content will usually be the binary representation of an ASN.1
--   object, however the transformation may be applied to any bytestring.
data PKCS5
PKCS5 :: EncryptionScheme -> EncryptedContent -> PKCS5

-- | Scheme used to encrypt content
[encryptionAlgorithm] :: PKCS5 -> EncryptionScheme

-- | Encrypted content
[encryptedData] :: PKCS5 -> EncryptedContent

-- | Encrypt a bytestring with the specified encryption scheme and
--   password.
encrypt :: EncryptionScheme -> ProtectionPassword -> ByteString -> Either StoreError PKCS5

-- | Decrypt the PKCS #5 content with the specified password.
decrypt :: PKCS5 -> ProtectionPassword -> Either StoreError ByteString

-- | Password-Based Encryption Scheme (PBES).
data EncryptionScheme

-- | PBES2
PBES2 :: PBES2Parameter -> EncryptionScheme

-- | pbeWithMD5AndDES-CBC
PBE_MD5_DES_CBC :: PBEParameter -> EncryptionScheme

-- | pbeWithSHA1AndDES-CBC
PBE_SHA1_DES_CBC :: PBEParameter -> EncryptionScheme

-- | pbeWithSHAAnd128BitRC4
PBE_SHA1_RC4_128 :: PBEParameter -> EncryptionScheme

-- | pbeWithSHAAnd40BitRC4
PBE_SHA1_RC4_40 :: PBEParameter -> EncryptionScheme

-- | pbeWithSHAAnd3-KeyTripleDES-CBC
PBE_SHA1_DES_EDE3_CBC :: PBEParameter -> EncryptionScheme

-- | pbeWithSHAAnd2-KeyTripleDES-CBC
PBE_SHA1_DES_EDE2_CBC :: PBEParameter -> EncryptionScheme

-- | pbeWithSHAAnd128BitRC2-CBC
PBE_SHA1_RC2_128 :: PBEParameter -> EncryptionScheme

-- | pbewithSHAAnd40BitRC2-CBC
PBE_SHA1_RC2_40 :: PBEParameter -> EncryptionScheme

-- | PBES1 parameters.
data PBEParameter
PBEParameter :: Salt -> Int -> PBEParameter

-- | 8-octet salt value
[pbeSalt] :: PBEParameter -> Salt

-- | Iteration count
[pbeIterationCount] :: PBEParameter -> Int

-- | PBES2 parameters.
data PBES2Parameter
PBES2Parameter :: KeyDerivationFunc -> ContentEncryptionParams -> PBES2Parameter

-- | Key derivation function
[pbes2KDF] :: PBES2Parameter -> KeyDerivationFunc

-- | Underlying encryption scheme
[pbes2EScheme] :: PBES2Parameter -> ContentEncryptionParams

-- | Key derivation algorithm and associated parameters.
data KeyDerivationFunc

-- | Key derivation with PBKDF2
PBKDF2 :: Salt -> Int -> Maybe Int -> PBKDF2_PRF -> KeyDerivationFunc

-- | Salt value
[pbkdf2Salt] :: KeyDerivationFunc -> Salt

-- | Iteration count
[pbkdf2IterationCount] :: KeyDerivationFunc -> Int

-- | Optional key length
[pbkdf2KeyLength] :: KeyDerivationFunc -> Maybe Int

-- | Pseudorandom function
[pbkdf2Prf] :: KeyDerivationFunc -> PBKDF2_PRF

-- | Key derivation with Scrypt
Scrypt :: Salt -> Word64 -> Int -> Int -> Maybe Int -> KeyDerivationFunc

-- | Salt value
[scryptSalt] :: KeyDerivationFunc -> Salt

-- | N value
[scryptN] :: KeyDerivationFunc -> Word64

-- | R value
[scryptR] :: KeyDerivationFunc -> Int

-- | P value
[scryptP] :: KeyDerivationFunc -> Int

-- | Optional key length
[scryptKeyLength] :: KeyDerivationFunc -> Maybe Int

-- | Pseudorandom function used for PBKDF2.
data PBKDF2_PRF

-- | hmacWithSHA1
PBKDF2_SHA1 :: PBKDF2_PRF

-- | hmacWithSHA256
PBKDF2_SHA256 :: PBKDF2_PRF

-- | hmacWithSHA512
PBKDF2_SHA512 :: PBKDF2_PRF

-- | Salt value used for key derivation.
type Salt = ByteString

-- | Generate a random salt with the specified length in bytes. To be most
--   effective, the length should be at least 8 bytes.
generateSalt :: MonadRandom m => Int -> m Salt

-- | Content encryption algorithm with associated parameters (i.e. the
--   initialization vector).
--   
--   A value can be generated with generateEncryptionParams.
data ContentEncryptionParams

-- | Cipher and mode of operation for content encryption.
data ContentEncryptionAlg

-- | Electronic Codebook
ECB :: ContentEncryptionCipher c -> ContentEncryptionAlg

-- | Cipher Block Chaining
CBC :: ContentEncryptionCipher c -> ContentEncryptionAlg

-- | RC2 in CBC mode
CBC_RC2 :: ContentEncryptionAlg

-- | Cipher Feedback
CFB :: ContentEncryptionCipher c -> ContentEncryptionAlg

-- | Counter
CTR :: ContentEncryptionCipher c -> ContentEncryptionAlg

-- | CMS content encryption cipher.
data ContentEncryptionCipher cipher

-- | DES
[DES] :: ContentEncryptionCipher DES

-- | Triple-DES with 2 keys used in alternative direction
[DES_EDE2] :: ContentEncryptionCipher DES_EDE2

-- | Triple-DES with 3 keys used in alternative direction
[DES_EDE3] :: ContentEncryptionCipher DES_EDE3

-- | AES with 128-bit key
[AES128] :: ContentEncryptionCipher AES128

-- | AES with 192-bit key
[AES192] :: ContentEncryptionCipher AES192

-- | AES with 256-bit key
[AES256] :: ContentEncryptionCipher AES256

-- | CAST5 (aka CAST-128) with key between 40 and 128 bits
[CAST5] :: ContentEncryptionCipher CAST5

-- | Camellia with 128-bit key
[Camellia128] :: ContentEncryptionCipher Camellia128

-- | Generate random parameters for the specified content encryption
--   algorithm.
generateEncryptionParams :: MonadRandom m => ContentEncryptionAlg -> m ContentEncryptionParams

-- | Get the content encryption algorithm.
getContentEncryptionAlg :: ContentEncryptionParams -> ContentEncryptionAlg

-- | Encrypt a bytestring with the specified encryption scheme and
--   password.
pbEncrypt :: EncryptionScheme -> ByteString -> ProtectionPassword -> Either StoreError EncryptedContent

-- | Decrypt an encrypted bytestring with the specified encryption scheme
--   and password.
pbDecrypt :: EncryptionScheme -> EncryptedContent -> ProtectionPassword -> Either StoreError ByteString
instance GHC.Classes.Eq Crypto.Store.PKCS5.PBES2Parameter
instance GHC.Show.Show Crypto.Store.PKCS5.PBES2Parameter
instance GHC.Classes.Eq Crypto.Store.PKCS5.EncryptionScheme
instance GHC.Show.Show Crypto.Store.PKCS5.EncryptionScheme
instance GHC.Classes.Eq Crypto.Store.PKCS5.PKCS5
instance GHC.Show.Show Crypto.Store.PKCS5.PKCS5
instance Crypto.Store.ASN1.Generate.ASN1Elem e => Crypto.Store.CMS.Util.ProduceASN1Object e Crypto.Store.PKCS5.PKCS5
instance GHC.Base.Monoid e => Crypto.Store.CMS.Util.ParseASN1Object e Crypto.Store.PKCS5.PKCS5
instance Data.ASN1.Types.ASN1Object Crypto.Store.PKCS5.PKCS5
instance Crypto.Store.CMS.Util.AlgorithmId Crypto.Store.PKCS5.EncryptionScheme
instance Crypto.Store.ASN1.Generate.ASN1Elem e => Crypto.Store.CMS.Util.ProduceASN1Object e Crypto.Store.PKCS5.EncryptionScheme
instance GHC.Base.Monoid e => Crypto.Store.CMS.Util.ParseASN1Object e Crypto.Store.PKCS5.EncryptionScheme
instance Crypto.Store.ASN1.Generate.ASN1Elem e => Crypto.Store.CMS.Util.ProduceASN1Object e Crypto.Store.PKCS5.PBES2Parameter
instance GHC.Base.Monoid e => Crypto.Store.CMS.Util.ParseASN1Object e Crypto.Store.PKCS5.PBES2Parameter
instance Crypto.Store.CMS.Util.Enumerable Crypto.Store.PKCS5.EncryptionSchemeType
instance Data.ASN1.OID.OIDable Crypto.Store.PKCS5.EncryptionSchemeType
instance Data.ASN1.OID.OIDNameable Crypto.Store.PKCS5.EncryptionSchemeType

-- | Private-Key Information Syntax, aka PKCS #8.
--   
--   Presents an API similar to Data.X509.Memory and
--   Data.X509.File but allows to write private keys and provides
--   support for password-based encryption.
--   
--   Functions to read a private key return an object wrapped in the
--   OptProtected data type.
--   
--   Functions related to public keys, certificates and CRLs are available
--   from Crypto.Store.X509.
module Crypto.Store.PKCS8

-- | Read private keys from a PEM file.
readKeyFile :: FilePath -> IO [OptProtected PrivKey]

-- | Read private keys from a bytearray in PEM format.
readKeyFileFromMemory :: ByteString -> [OptProtected PrivKey]

-- | Read a private key from a PEM element and add it to the
--   accumulator list.
pemToKey :: [Maybe (OptProtected PrivKey)] -> PEM -> [Maybe (OptProtected PrivKey)]

-- | Write unencrypted private keys to a PEM file.
writeKeyFile :: PrivateKeyFormat -> FilePath -> [PrivKey] -> IO ()

-- | Write unencrypted private keys to a bytearray in PEM format.
writeKeyFileToMemory :: PrivateKeyFormat -> [PrivKey] -> ByteString

-- | Generate an unencrypted PEM for a private key.
keyToPEM :: PrivateKeyFormat -> PrivKey -> PEM

-- | Write a PKCS #8 encrypted private key to a PEM file.
--   
--   If multiple keys need to be stored in the same file, use functions
--   encryptKeyToPEM and writePEMs.
--   
--   Fresh EncryptionScheme parameters should be generated for each
--   key to encrypt.
writeEncryptedKeyFile :: FilePath -> EncryptionScheme -> ProtectionPassword -> PrivKey -> IO (Either StoreError ())

-- | Write a PKCS #8 encrypted private key to a bytearray in PEM format.
--   
--   If multiple keys need to be stored in the same bytearray, use
--   functions encryptKeyToPEM and pemWriteBS or
--   pemWriteLBS.
--   
--   Fresh EncryptionScheme parameters should be generated for each
--   key to encrypt.
writeEncryptedKeyFileToMemory :: EncryptionScheme -> ProtectionPassword -> PrivKey -> Either StoreError ByteString

-- | Generate a PKCS #8 encrypted PEM for a private key.
--   
--   Fresh EncryptionScheme parameters should be generated for each
--   key to encrypt.
encryptKeyToPEM :: EncryptionScheme -> ProtectionPassword -> PrivKey -> Either StoreError PEM

-- | Private-key serialization format.
--   
--   Encryption in traditional format is not supported currently.
data PrivateKeyFormat

-- | SSLeay compatible
TraditionalFormat :: PrivateKeyFormat

-- | PKCS #8
PKCS8Format :: PrivateKeyFormat

-- | A key associated with format. Allows to implement ASN1Object
--   instances.
data FormattedKey a
FormattedKey :: PrivateKeyFormat -> a -> FormattedKey a

-- | A password stored as a sequence of UTF-8 bytes.
--   
--   Some key-derivation functions add restrictions to what characters are
--   supported.
--   
--   The data type provides a special value emptyNotTerminated that
--   is used as alternate representation of empty passwords on some systems
--   and that produces encryption results different than an empty
--   bytearray.
--   
--   Conversion to/from a regular sequence of bytes is possible with
--   functions toProtectionPassword and
--   fromProtectionPassword.
--   
--   Beware: the fromString implementation correctly handles
--   multi-byte characters, so here is not equivalent to the
--   ByteString counterpart.
data ProtectionPassword

-- | A value denoting an empty password, but having a special encoding when
--   deriving a symmetric key on some systems, like the certificate export
--   wizard on Windows.
--   
--   This value is different from toProtectionPassword ""
--   and can be tried when decrypting content with a password known to be
--   empty.
emptyNotTerminated :: ProtectionPassword

-- | Extract the UTF-8 bytes in a password value.
fromProtectionPassword :: ProtectionPassword -> ByteString

-- | Build a password value from a sequence of UTF-8 bytes.
--   
--   When the password is empty, the special value
--   emptyNotTerminated may be tried as well.
toProtectionPassword :: ByteString -> ProtectionPassword

-- | Data type for objects that are possibly protected with a password.
data OptProtected a

-- | Value is unprotected
Unprotected :: a -> OptProtected a

-- | Value is protected with a password
Protected :: (ProtectionPassword -> Either StoreError a) -> OptProtected a

-- | Try to recover an OptProtected content using the specified
--   password.
recover :: ProtectionPassword -> OptProtected a -> Either StoreError a

-- | Try to recover an OptProtected content in an applicative
--   context. The applicative password is used if necessary.
--   
--   
--   import qualified Data.ByteString as B
--   import           Crypto.Store.PKCS8
--   
--   [encryptedKey] <- readKeyFile "privkey.pem"
--   let askForPassword = putStr "Please enter password: " >> B.getLine
--   result <- recoverA (toProtectionPassword <$> askForPassword) encryptedKey
--   case result of
--       Left err  -> putStrLn $ "Unable to recover key: " ++ show err
--       Right key -> print key
--   
recoverA :: Applicative f => f ProtectionPassword -> OptProtected a -> f (Either StoreError a)

-- | Read a PEM file from disk.
readPEMs :: FilePath -> IO [PEM]

-- | Write a PEM file to disk.
writePEMs :: FilePath -> [PEM] -> IO ()
instance GHC.Classes.Eq Crypto.Store.PKCS8.PrivateKeyFormat
instance GHC.Show.Show Crypto.Store.PKCS8.PrivateKeyFormat
instance GHC.Classes.Eq a => GHC.Classes.Eq (Crypto.Store.PKCS8.FormattedKey a)
instance GHC.Show.Show a => GHC.Show.Show (Crypto.Store.PKCS8.FormattedKey a)
instance GHC.Base.Functor Crypto.Store.PKCS8.FormattedKey
instance (Crypto.Store.CMS.Util.ProduceASN1Object e (Crypto.Store.PKCS8.Traditional a), Crypto.Store.CMS.Util.ProduceASN1Object e (Crypto.Store.PKCS8.Modern a)) => Crypto.Store.CMS.Util.ProduceASN1Object e (Crypto.Store.PKCS8.FormattedKey a)
instance (GHC.Base.Monoid e, Crypto.Store.CMS.Util.ParseASN1Object e (Crypto.Store.PKCS8.Traditional a), Crypto.Store.CMS.Util.ParseASN1Object e (Crypto.Store.PKCS8.Modern a)) => Crypto.Store.CMS.Util.ParseASN1Object e (Crypto.Store.PKCS8.FormattedKey a)
instance Data.ASN1.Types.ASN1Object (Crypto.Store.PKCS8.FormattedKey Data.X509.PrivateKey.PrivKey)
instance Data.ASN1.Types.ASN1Object (Crypto.Store.PKCS8.FormattedKey Crypto.PubKey.RSA.Types.PrivateKey)
instance Data.ASN1.Types.ASN1Object (Crypto.Store.PKCS8.FormattedKey Crypto.PubKey.DSA.KeyPair)
instance Data.ASN1.Types.ASN1Object (Crypto.Store.PKCS8.FormattedKey Data.X509.PrivateKey.PrivKeyEC)
instance GHC.Base.Functor Crypto.Store.PKCS8.Modern
instance Crypto.Store.ASN1.Generate.ASN1Elem e => Crypto.Store.CMS.Util.ProduceASN1Object e (Crypto.Store.PKCS8.Modern Data.X509.PrivateKey.PrivKey)
instance GHC.Base.Monoid e => Crypto.Store.CMS.Util.ParseASN1Object e (Crypto.Store.PKCS8.Modern Data.X509.PrivateKey.PrivKey)
instance Crypto.Store.ASN1.Generate.ASN1Elem e => Crypto.Store.CMS.Util.ProduceASN1Object e (Crypto.Store.PKCS8.Modern Crypto.PubKey.RSA.Types.PrivateKey)
instance GHC.Base.Monoid e => Crypto.Store.CMS.Util.ParseASN1Object e (Crypto.Store.PKCS8.Modern Crypto.PubKey.RSA.Types.PrivateKey)
instance Crypto.Store.ASN1.Generate.ASN1Elem e => Crypto.Store.CMS.Util.ProduceASN1Object e (Crypto.Store.PKCS8.Modern Crypto.PubKey.DSA.KeyPair)
instance GHC.Base.Monoid e => Crypto.Store.CMS.Util.ParseASN1Object e (Crypto.Store.PKCS8.Modern Crypto.PubKey.DSA.KeyPair)
instance Crypto.Store.ASN1.Generate.ASN1Elem e => Crypto.Store.CMS.Util.ProduceASN1Object e (Crypto.Store.PKCS8.Modern Data.X509.PrivateKey.PrivKeyEC)
instance GHC.Base.Monoid e => Crypto.Store.CMS.Util.ParseASN1Object e (Crypto.Store.PKCS8.Modern Data.X509.PrivateKey.PrivKeyEC)
instance Crypto.Store.ASN1.Generate.ASN1Elem e => Crypto.Store.CMS.Util.ProduceASN1Object e (Crypto.Store.PKCS8.Modern Crypto.PubKey.Curve25519.SecretKey)
instance GHC.Base.Monoid e => Crypto.Store.CMS.Util.ParseASN1Object e (Crypto.Store.PKCS8.Modern Crypto.PubKey.Curve25519.SecretKey)
instance Crypto.Store.ASN1.Generate.ASN1Elem e => Crypto.Store.CMS.Util.ProduceASN1Object e (Crypto.Store.PKCS8.Modern Crypto.PubKey.Curve448.SecretKey)
instance GHC.Base.Monoid e => Crypto.Store.CMS.Util.ParseASN1Object e (Crypto.Store.PKCS8.Modern Crypto.PubKey.Curve448.SecretKey)
instance Crypto.Store.ASN1.Generate.ASN1Elem e => Crypto.Store.CMS.Util.ProduceASN1Object e (Crypto.Store.PKCS8.Modern Crypto.PubKey.Ed25519.SecretKey)
instance GHC.Base.Monoid e => Crypto.Store.CMS.Util.ParseASN1Object e (Crypto.Store.PKCS8.Modern Crypto.PubKey.Ed25519.SecretKey)
instance Crypto.Store.ASN1.Generate.ASN1Elem e => Crypto.Store.CMS.Util.ProduceASN1Object e (Crypto.Store.PKCS8.Modern Crypto.PubKey.Ed448.SecretKey)
instance GHC.Base.Monoid e => Crypto.Store.CMS.Util.ParseASN1Object e (Crypto.Store.PKCS8.Modern Crypto.PubKey.Ed448.SecretKey)
instance Crypto.Store.ASN1.Generate.ASN1Elem e => Crypto.Store.CMS.Util.ProduceASN1Object e (Crypto.Store.PKCS8.Traditional Data.X509.PrivateKey.PrivKey)
instance GHC.Base.Monoid e => Crypto.Store.CMS.Util.ParseASN1Object e (Crypto.Store.PKCS8.Traditional Data.X509.PrivateKey.PrivKey)
instance Crypto.Store.ASN1.Generate.ASN1Elem e => Crypto.Store.CMS.Util.ProduceASN1Object e (Crypto.Store.PKCS8.Traditional Crypto.PubKey.RSA.Types.PrivateKey)
instance GHC.Base.Monoid e => Crypto.Store.CMS.Util.ParseASN1Object e (Crypto.Store.PKCS8.Traditional Crypto.PubKey.RSA.Types.PrivateKey)
instance Crypto.Store.ASN1.Generate.ASN1Elem e => Crypto.Store.CMS.Util.ProduceASN1Object e (Crypto.Store.PKCS8.Traditional Crypto.PubKey.DSA.KeyPair)
instance GHC.Base.Monoid e => Crypto.Store.CMS.Util.ParseASN1Object e (Crypto.Store.PKCS8.Traditional Crypto.PubKey.DSA.KeyPair)
instance Crypto.Store.ASN1.Generate.ASN1Elem e => Crypto.Store.CMS.Util.ProduceASN1Object e (Crypto.Store.PKCS8.Traditional Data.X509.PrivateKey.PrivKeyEC)
instance GHC.Base.Monoid e => Crypto.Store.CMS.Util.ParseASN1Object e (Crypto.Store.PKCS8.Traditional Data.X509.PrivateKey.PrivKeyEC)
instance GHC.Base.Functor Crypto.Store.PKCS8.OptProtected

-- | Cryptographic Message Syntax
--   
--   
--   
- RFC 5652: Cryptographic Message Syntax (CMS)
--   
- RFC 3370: Cryptographic Message Syntax (CMS)
--   Algorithms
--   
- RFC 3560: Use of the RSAES-OAEP Key Transport Algorithm in
--   the Cryptographic Message Syntax (CMS)
--   
- RFC 4056: Use of the RSASSA-PSS Signature Algorithm in
--   Cryptographic Message Syntax (CMS)
--   
- RFC 3565: Use of the Advanced Encryption Standard (AES)
--   Encryption Algorithm in Cryptographic Message Syntax (CMS)
--   
- RFC 5753: Use of Elliptic Curve Cryptography (ECC)
--   Algorithms in Cryptographic Message Syntax (CMS)
--   
- RFC 5754: Using SHA2 Algorithms with Cryptographic Message
--   Syntax
--   
- RFC 3211: Password-based Encryption for CMS
--   
- RFC 5083: Cryptographic Message Syntax (CMS)
--   Authenticated-Enveloped-Data Content Type
--   
- RFC 5084: Using AES-CCM and AES-GCM Authenticated
--   Encryption in the Cryptographic Message Syntax (CMS)
--   
- RFC 6476: Using Message Authentication Code (MAC)
--   Encryption in the Cryptographic Message Syntax (CMS)
--   
- RFC 8103: Using ChaCha20-Poly1305 Authenticated Encryption
--   in the Cryptographic Message Syntax (CMS)
--   
- RFC 8418: Use of the Elliptic Curve Diffie-Hellman Key
--   Agreement Algorithm with X25519 and X448 in the Cryptographic Message
--   Syntax (CMS)
--   
- RFC 8419: Use of Edwards-Curve Digital Signature Algorithm
--   (EdDSA) Signatures in the Cryptographic Message Syntax (CMS)
--   
- RFC 8702: Use of the SHAKE One-Way Hash Functions in the
--   Cryptographic Message Syntax (CMS)
--   
module Crypto.Store.CMS

-- | CMS content information type.
data ContentType

-- | Arbitrary octet string
DataType :: ContentType

-- | Signed content info
SignedDataType :: ContentType

-- | Enveloped content info
EnvelopedDataType :: ContentType

-- | Content info with associated digest
DigestedDataType :: ContentType

-- | Encrypted content info
EncryptedDataType :: ContentType

-- | Authenticated content info
AuthenticatedDataType :: ContentType

-- | Authenticated-enveloped content info
AuthEnvelopedDataType :: ContentType

-- | CMS content information.
data ContentInfo

-- | Arbitrary octet string
DataCI :: ByteString -> ContentInfo

-- | Signed content info
SignedDataCI :: SignedData (Encap EncapsulatedContent) -> ContentInfo

-- | Enveloped content info
EnvelopedDataCI :: EnvelopedData (Encap EncryptedContent) -> ContentInfo

-- | Content info with associated digest
DigestedDataCI :: DigestedData (Encap EncapsulatedContent) -> ContentInfo

-- | Encrypted content info
EncryptedDataCI :: EncryptedData (Encap EncryptedContent) -> ContentInfo

-- | Authenticatedcontent info
AuthenticatedDataCI :: AuthenticatedData (Encap EncapsulatedContent) -> ContentInfo

-- | Authenticated-enveloped content info
AuthEnvelopedDataCI :: AuthEnvelopedData (Encap EncryptedContent) -> ContentInfo

-- | Get the type of a content info.
getContentType :: ContentInfo -> ContentType

-- | Read content info elements from a PEM file.
readCMSFile :: FilePath -> IO [ContentInfo]

-- | Read content info elements from a bytearray in PEM format.
readCMSFileFromMemory :: ByteString -> [ContentInfo]

-- | Read a content info from a bytearray in BER format.
berToContentInfo :: ByteString -> Either StoreError ContentInfo

-- | Read a content info from a PEM element and add it to the
--   accumulator list.
pemToContentInfo :: [Maybe ContentInfo] -> PEM -> [Maybe ContentInfo]

-- | Write content info elements to a PEM file.
writeCMSFile :: FilePath -> [ContentInfo] -> IO ()

-- | Write content info elements to a bytearray in PEM format.
writeCMSFileToMemory :: [ContentInfo] -> ByteString

-- | Generate a bytearray in DER format for a content info.
contentInfoToDER :: ContentInfo -> ByteString

-- | Generate PEM for a content info.
contentInfoToPEM :: ContentInfo -> PEM

-- | Denote the state of encapsulated content in a CMS data structure. This
--   type is isomorphic to Maybe.
data Encap a

-- | Content is stored externally to the structure
Detached :: Encap a

-- | Content is stored inside the CMS struture
Attached :: a -> Encap a

-- | Fold over an Encap value. This is similar to function
--   maybe. If the content is detached, the first argument is
--   returned. Otherwise the second argument is applied to the content.
fromEncap :: b -> (a -> b) -> Encap a -> b

-- | Class of data structures with inner content that may be stored
--   externally. This class has instances for each CMS content type
--   containing other encapsulated or encrypted content info.
--   
--   Functions fromAttached and fromDetached are used to
--   introspect encapsulation state (attached or detached), and recover a
--   data structure with actionable content.
--   
--   Functions toAttachedCI and toDetachedCI are needed to
--   decide about the outer encapsulation state and build a
--   ContentInfo.
class Encapsulates struct

-- | Return True when the encapsulated content is attached.
isAttached :: Encapsulates struct => struct (Encap a) -> Bool

-- | Unwrap the encapsulation, assuming the inner content is inside the
--   data structure. The monadic computation fails if the content was
--   detached.
fromAttached :: (MonadFail m, Encapsulates struct) => struct (Encap a) -> m (struct a)

-- | Transform the data structure into a content info, keeping the
--   encapsulated content attached. May be applied to structures with
--   EncapsulatedContent or EncryptedContent.
toAttachedCI :: Encapsulates struct => struct ByteString -> ContentInfo

-- | Return True when the encapsulated content is detached.
isDetached :: Encapsulates struct => struct (Encap a) -> Bool

-- | Recover the original data structure from a detached encapsulation and
--   the external content. The monadic computation fails if the content was
--   attached.
fromDetached :: (MonadFail m, Encapsulates struct) => b -> struct (Encap a) -> m (struct b)

-- | Transform the data structure into a content info, detaching the
--   encapsulated content. May be applied to structures with
--   EncapsulatedContent or EncryptedContent.
toDetachedCI :: Encapsulates struct => struct ByteString -> (ByteString, ContentInfo)

-- | Signature value.
type SignatureValue = ByteString

-- | CMS signature algorithms and associated parameters.
data SignatureAlg
RSAAnyHash :: SignatureAlg
RSA :: DigestAlgorithm -> SignatureAlg
RSAPSS :: PSSParams -> SignatureAlg
DSA :: DigestAlgorithm -> SignatureAlg
ECDSA :: DigestAlgorithm -> SignatureAlg
Ed25519 :: SignatureAlg
Ed448 :: SignatureAlg

-- | Encapsulated content.
type EncapsulatedContent = ByteString

-- | Signed content information.
data SignedData content
SignedData :: [DigestAlgorithm] -> ContentType -> content -> [CertificateChoice] -> [RevocationInfoChoice] -> [SignerInfo] -> SignedData content

-- | Digest algorithms
[sdDigestAlgorithms] :: SignedData content -> [DigestAlgorithm]

-- | Inner content type
[sdContentType] :: SignedData content -> ContentType

-- | Encapsulated content
[sdEncapsulatedContent] :: SignedData content -> content

-- | The collection of certificates
[sdCertificates] :: SignedData content -> [CertificateChoice]

-- | The collection of CRLs
[sdCRLs] :: SignedData content -> [RevocationInfoChoice]

-- | Per-signer information
[sdSignerInfos] :: SignedData content -> [SignerInfo]

-- | Function able to produce a SignerInfo.
type ProducerOfSI m = ContentType -> ByteString -> m (Either StoreError (SignerInfo, [CertificateChoice], [RevocationInfoChoice]))

-- | Function able to consume a SignerInfo.
type ConsumerOfSI m = ContentType -> ByteString -> SignerInfo -> [CertificateChoice] -> [RevocationInfoChoice] -> m Bool

-- | Add a signed-data layer on the specified content info. The content is
--   processed by one or several ProducerOfSI functions to create
--   signer info elements.
signData :: Applicative f => [ProducerOfSI f] -> ContentInfo -> f (Either StoreError (SignedData EncapsulatedContent))

-- | Verify a signed content info using the specified ConsumerOfSI
--   function. Verification of at least one signer info must be successful
--   in order to return the inner content info.
verifySignedData :: Monad m => ConsumerOfSI m -> SignedData EncapsulatedContent -> m (Either StoreError ContentInfo)

-- | Information related to a signer of a SignedData. An element
--   contains the signature material that was produced.
data SignerInfo
SignerInfo :: SignerIdentifier -> DigestAlgorithm -> [Attribute] -> SignatureAlg -> SignatureValue -> [Attribute] -> SignerInfo

-- | Identifier of the signer certificate
[siSignerId] :: SignerInfo -> SignerIdentifier

-- | Digest algorithm used for the signature
[siDigestAlgorithm] :: SignerInfo -> DigestAlgorithm

-- | Optional signed attributes
[siSignedAttrs] :: SignerInfo -> [Attribute]

-- | Algorithm used for signature
[siSignatureAlg] :: SignerInfo -> SignatureAlg

-- | The signature value
[siSignature] :: SignerInfo -> SignatureValue

-- | Optional unsigned attributes
[siUnsignedAttrs] :: SignerInfo -> [Attribute]

-- | Union type related to identification of the signer certificate.
data SignerIdentifier

-- | Issuer and Serial Number
SignerIASN :: IssuerAndSerialNumber -> SignerIdentifier

-- | Subject Key Identifier
SignerSKI :: ByteString -> SignerIdentifier

-- | Identification of a certificate using the issuer DN and serial number.
data IssuerAndSerialNumber
IssuerAndSerialNumber :: DistinguishedName -> Integer -> IssuerAndSerialNumber

-- | Distinguished name of the certificate issuer
[iasnIssuer] :: IssuerAndSerialNumber -> DistinguishedName

-- | Issuer-specific certificate serial number
[iasnSerial] :: IssuerAndSerialNumber -> Integer

-- | Create a signer info with the specified signature algorithm and
--   credentials.
--   
--   Two lists of optional attributes can be provided. The attributes will
--   be part of message signature when provided in the first list.
--   
--   When the first list of attributes is provided, even empty list,
--   signature is computed from a digest of the content. When the list of
--   attributes is Nothing, no intermediate digest is used and the
--   signature is computed from the full message.
certSigner :: MonadRandom m => SignatureAlg -> PrivKey -> CertificateChain -> Maybe [Attribute] -> [Attribute] -> ProducerOfSI m

-- | Verify that the signature was produced from the specified public key.
--   Ignores all certificates and CRLs contained in the signed data.
withPublicKey :: Applicative f => PubKey -> ConsumerOfSI f

-- | Verify that the signature is valid with one of the X.509 certificates
--   contained in the signed data, but does not validate that the
--   certificates are valid. All transmitted certificates are implicitely
--   trusted and all CRLs are ignored.
withSignerKey :: Applicative f => ConsumerOfSI f

-- | Verify that the signature is valid with one of the X.509 certificates
--   contained in the signed data, and verify that the signer certificate
--   is valid using the validation function supplied. All CRLs are ignored.
withSignerCertificate :: Applicative f => (Maybe DateTime -> CertificateChain -> f Bool) -> ConsumerOfSI f

-- | Encrypted key.
type EncryptedKey = ByteString

-- | Key encryption algorithm with associated parameters (i.e. the
--   underlying encryption algorithm).
data KeyEncryptionParams

-- | PWRI-KEK key wrap algorithm
PWRIKEK :: ContentEncryptionParams -> KeyEncryptionParams

-- | AES-128 key wrap
AES128_WRAP :: KeyEncryptionParams

-- | AES-192 key wrap
AES192_WRAP :: KeyEncryptionParams

-- | AES-256 key wrap
AES256_WRAP :: KeyEncryptionParams

-- | AES-128 extended key wrap
AES128_WRAP_PAD :: KeyEncryptionParams

-- | AES-192 extended key wrap
AES192_WRAP_PAD :: KeyEncryptionParams

-- | AES-256 extended key wrap
AES256_WRAP_PAD :: KeyEncryptionParams

-- | Triple-DES key wrap
DES_EDE3_WRAP :: KeyEncryptionParams

-- | RC2 key wrap with effective key length
RC2_WRAP :: Int -> KeyEncryptionParams

-- | Key transport algorithm with associated parameters.
data KeyTransportParams

-- | RSAES-PKCS1
RSAES :: KeyTransportParams

-- | RSAES-OAEP
RSAESOAEP :: OAEPParams -> KeyTransportParams

-- | Key agreement algorithm with associated parameters.
data KeyAgreementParams

-- | 1-Pass D-H with Stardard ECDH
StdDH :: KeyAgreementKDF -> KeyEncryptionParams -> KeyAgreementParams

-- | 1-Pass D-H with Cofactor ECDH
CofactorDH :: KeyAgreementKDF -> KeyEncryptionParams -> KeyAgreementParams

-- | Key derivation function used for key agreement.
data KeyAgreementKDF

-- | ANSI-X9.63-KDF key derivation function
KA_X963_KDF :: DigestProxy hashAlg -> KeyAgreementKDF

-- | Extract-and-Expand HMAC-based key derivation function
KA_HKDF :: DigestProxy hashAlg -> KeyAgreementKDF

-- | Information for a recipient of an EnvelopedData. An element
--   contains the content-encryption key in encrypted form.
data RecipientInfo

-- | Recipient using key transport
KTRI :: KTRecipientInfo -> RecipientInfo

-- | Recipient using key agreement
KARI :: KARecipientInfo -> RecipientInfo

-- | Recipient using key encryption
KEKRI :: KEKRecipientInfo -> RecipientInfo

-- | Recipient using password-based protection
PasswordRI :: PasswordRecipientInfo -> RecipientInfo

-- | Enveloped content information.
data EnvelopedData content
EnvelopedData :: OriginatorInfo -> [RecipientInfo] -> ContentType -> ContentEncryptionParams -> content -> [Attribute] -> EnvelopedData content

-- | Optional information about the originator
[evOriginatorInfo] :: EnvelopedData content -> OriginatorInfo

-- | Information for recipients, allowing to decrypt the content
[evRecipientInfos] :: EnvelopedData content -> [RecipientInfo]

-- | Inner content type
[evContentType] :: EnvelopedData content -> ContentType

-- | Encryption algorithm
[evContentEncryptionParams] :: EnvelopedData content -> ContentEncryptionParams

-- | Encrypted content info
[evEncryptedContent] :: EnvelopedData content -> content

-- | Optional unprotected attributes
[evUnprotectedAttrs] :: EnvelopedData content -> [Attribute]

-- | Function able to produce a RecipientInfo.
type ProducerOfRI m = ContentEncryptionKey -> m (Either StoreError RecipientInfo)

-- | Function able to consume a RecipientInfo.
type ConsumerOfRI m = RecipientInfo -> m (Either StoreError ContentEncryptionKey)

-- | Add an enveloped-data layer on the specified content info. The content
--   is encrypted with specified key and algorithm. The key is then
--   processed by one or several ProducerOfRI functions to create
--   recipient info elements.
--   
--   Some optional attributes can be added but will not be encrypted.
envelopData :: Applicative f => OriginatorInfo -> ContentEncryptionKey -> ContentEncryptionParams -> [ProducerOfRI f] -> [Attribute] -> ContentInfo -> f (Either StoreError (EnvelopedData EncryptedContent))

-- | Recover an enveloped content info using the specified
--   ConsumerOfRI function.
openEnvelopedData :: Monad m => ConsumerOfRI m -> EnvelopedData EncryptedContent -> m (Either StoreError ContentInfo)

-- | Recipient using key transport.
data KTRecipientInfo
KTRecipientInfo :: RecipientIdentifier -> KeyTransportParams -> EncryptedKey -> KTRecipientInfo

-- | identifier of recipient
[ktRid] :: KTRecipientInfo -> RecipientIdentifier

-- | key transport algorithm
[ktKeyTransportParams] :: KTRecipientInfo -> KeyTransportParams

-- | encrypted content-encryption key
[ktEncryptedKey] :: KTRecipientInfo -> EncryptedKey

-- | Union type related to identification of the recipient.
data RecipientIdentifier

-- | Issuer and Serial Number
RecipientIASN :: IssuerAndSerialNumber -> RecipientIdentifier

-- | Subject Key Identifier
RecipientSKI :: ByteString -> RecipientIdentifier

-- | Generate a Key Transport recipient from a certificate and desired
--   algorithm. The recipient will contain certificate identifier.
--   
--   This function can be used as parameter to envelopData.
forKeyTransRecipient :: MonadRandom m => SignedCertificate -> KeyTransportParams -> ProducerOfRI m

-- | Use a Key Transport recipient, knowing the private key.
--   
--   This function can be used as parameter to openEnvelopedData.
withRecipientKeyTrans :: MonadRandom m => PrivKey -> ConsumerOfRI m

-- | Recipient using key agreement.
data KARecipientInfo
KARecipientInfo :: OriginatorIdentifierOrKey -> Maybe UserKeyingMaterial -> KeyAgreementParams -> [RecipientEncryptedKey] -> KARecipientInfo

-- | identifier of orginator or anonymous key
[kaOriginator] :: KARecipientInfo -> OriginatorIdentifierOrKey

-- | user keying material
[kaUkm] :: KARecipientInfo -> Maybe UserKeyingMaterial

-- | key agreement algorithm
[kaKeyAgreementParams] :: KARecipientInfo -> KeyAgreementParams

-- | encrypted content-encryption key for one or multiple recipients
[kaRecipientEncryptedKeys] :: KARecipientInfo -> [RecipientEncryptedKey]

-- | Union type related to identification of the originator.
data OriginatorIdentifierOrKey

-- | Issuer and Serial Number
OriginatorIASN :: IssuerAndSerialNumber -> OriginatorIdentifierOrKey

-- | Subject Key Identifier
OriginatorSKI :: ByteString -> OriginatorIdentifierOrKey

-- | Anonymous public key
OriginatorPublic :: OriginatorPublicKey -> OriginatorIdentifierOrKey

-- | Originator public key used for key-agreement. Contrary to
--   PubKey the domain parameters are not used and may be left
--   empty.
data OriginatorPublicKey

-- | Encrypted key for a recipient in a key-agreement RI.
data RecipientEncryptedKey
RecipientEncryptedKey :: KeyAgreeRecipientIdentifier -> EncryptedKey -> RecipientEncryptedKey

-- | identifier of recipient
[rekRid] :: RecipientEncryptedKey -> KeyAgreeRecipientIdentifier

-- | encrypted content-encryption key
[rekEncryptedKey] :: RecipientEncryptedKey -> EncryptedKey

-- | Union type related to identification of a key-agreement recipient.
data KeyAgreeRecipientIdentifier

-- | Issuer and Serial Number
KeyAgreeRecipientIASN :: IssuerAndSerialNumber -> KeyAgreeRecipientIdentifier

-- | Key identifier
KeyAgreeRecipientKI :: KeyIdentifier -> KeyAgreeRecipientIdentifier

-- | User keying material.
type UserKeyingMaterial = ByteString

-- | Generate a Key Agreement recipient from a certificate and desired
--   algorithm. The recipient info will contain an ephemeral public key.
--   
--   This function can be used as parameter to envelopData.
--   
--   To avoid decreasing the security strength, Key Encryption parameters
--   should use a key size equal or greater than the content encryption
--   key.
forKeyAgreeRecipient :: MonadRandom m => SignedCertificate -> KeyAgreementParams -> ProducerOfRI m

-- | Use a Key Agreement recipient, knowing the recipient private key. The
--   recipient certificate is also required to locate which encrypted key
--   to use.
--   
--   This function can be used as parameter to openEnvelopedData.
withRecipientKeyAgree :: MonadRandom m => PrivKey -> SignedCertificate -> ConsumerOfRI m

-- | Recipient using key encryption.
data KEKRecipientInfo
KEKRecipientInfo :: KeyIdentifier -> KeyEncryptionParams -> EncryptedKey -> KEKRecipientInfo

-- | identifier of key encryption key
[kekId] :: KEKRecipientInfo -> KeyIdentifier

-- | key encryption algorithm
[kekKeyEncryptionParams] :: KEKRecipientInfo -> KeyEncryptionParams

-- | encrypted content-encryption key
[kekEncryptedKey] :: KEKRecipientInfo -> EncryptedKey

-- | Key identifier and optional attributes.
data KeyIdentifier
KeyIdentifier :: ByteString -> Maybe DateTime -> Maybe OtherKeyAttribute -> KeyIdentifier

-- | identifier of the key
[keyIdentifier] :: KeyIdentifier -> ByteString

-- | optional timestamp
[keyDate] :: KeyIdentifier -> Maybe DateTime

-- | optional information
[keyOther] :: KeyIdentifier -> Maybe OtherKeyAttribute

-- | Additional information in a KeyIdentifier.
data OtherKeyAttribute
OtherKeyAttribute :: OID -> [ASN1] -> OtherKeyAttribute

-- | attribute identifier
[keyAttrId] :: OtherKeyAttribute -> OID

-- | attribute value
[keyAttr] :: OtherKeyAttribute -> [ASN1]

-- | Key used for key encryption.
type KeyEncryptionKey = ByteString

-- | Generate a Key Encryption Key recipient from a key encryption key and
--   desired algorithm. The recipient may identify the KEK that was used
--   with the supplied identifier.
--   
--   This function can be used as parameter to envelopData.
--   
--   To avoid decreasing the security strength, Key Encryption parameters
--   should use a key size equal or greater than the content encryption
--   key.
forKeyRecipient :: MonadRandom m => KeyEncryptionKey -> KeyIdentifier -> KeyEncryptionParams -> ProducerOfRI m

-- | Use a Key Encryption Key recipient, knowing the key encryption key.
--   
--   This function can be used as parameter to openEnvelopedData.
withRecipientKey :: Applicative f => KeyEncryptionKey -> ConsumerOfRI f

-- | Recipient using password-based protection.
data PasswordRecipientInfo
PasswordRecipientInfo :: KeyDerivationFunc -> KeyEncryptionParams -> EncryptedKey -> PasswordRecipientInfo

-- | function to derive key
[priKeyDerivationFunc] :: PasswordRecipientInfo -> KeyDerivationFunc

-- | key encryption algorithm
[priKeyEncryptionParams] :: PasswordRecipientInfo -> KeyEncryptionParams

-- | encrypted content-encryption key
[priEncryptedKey] :: PasswordRecipientInfo -> EncryptedKey

-- | Generate a password recipient from a password.
--   
--   This function can be used as parameter to envelopData.
forPasswordRecipient :: MonadRandom m => Password -> KeyDerivationFunc -> KeyEncryptionParams -> ProducerOfRI m

-- | Use a password recipient, knowing the password.
--   
--   This function can be used as parameter to openEnvelopedData.
withRecipientPassword :: Applicative f => Password -> ConsumerOfRI f

-- | CMS digest proxy. Acts like Proxy, i.e. provides a hash
--   algorithm as type parameter. The GADT constructors map to known
--   algorithms.
data DigestProxy hashAlg

-- | MD2
[MD2] :: DigestProxy MD2

-- | MD4
[MD4] :: DigestProxy MD4

-- | MD5
[MD5] :: DigestProxy MD5

-- | SHA-1
[SHA1] :: DigestProxy SHA1

-- | SHA-224
[SHA224] :: DigestProxy SHA224

-- | SHA-256
[SHA256] :: DigestProxy SHA256

-- | SHA-384
[SHA384] :: DigestProxy SHA384

-- | SHA-512
[SHA512] :: DigestProxy SHA512

-- | SHAKE128 (256 bits)
[SHAKE128_256] :: DigestProxy (SHAKE128 256)

-- | SHAKE256 (512 bits)
[SHAKE256_512] :: DigestProxy (SHAKE256 512)

-- | SHAKE128 (variable size)
[SHAKE128] :: KnownNat n => Proxy n -> DigestProxy (SHAKE128 n)

-- | SHAKE256 (variable size)
[SHAKE256] :: KnownNat n => Proxy n -> DigestProxy (SHAKE256 n)

-- | CMS digest algorithm.
data DigestAlgorithm
DigestAlgorithm :: DigestProxy hashAlg -> DigestAlgorithm

-- | Digested content information.
data DigestedData content
DigestedData :: DigestProxy hashAlg -> ContentType -> content -> Digest hashAlg -> DigestedData content

-- | Digest algorithm
[ddDigestAlgorithm] :: DigestedData content -> DigestProxy hashAlg

-- | Inner content type
[ddContentType] :: DigestedData content -> ContentType

-- | Encapsulated content
[ddEncapsulatedContent] :: DigestedData content -> content

-- | Digest value
[ddDigest] :: DigestedData content -> Digest hashAlg

-- | Add a digested-data layer on the specified content info.
digestData :: DigestAlgorithm -> ContentInfo -> DigestedData EncapsulatedContent

-- | Return the inner content info but only if the digest is valid.
digestVerify :: DigestedData EncapsulatedContent -> Either StoreError ContentInfo

-- | Key used for content encryption.
type ContentEncryptionKey = ByteString

-- | CMS content encryption cipher.
data ContentEncryptionCipher cipher

-- | DES
[DES] :: ContentEncryptionCipher DES

-- | Triple-DES with 2 keys used in alternative direction
[DES_EDE2] :: ContentEncryptionCipher DES_EDE2

-- | Triple-DES with 3 keys used in alternative direction
[DES_EDE3] :: ContentEncryptionCipher DES_EDE3

-- | AES with 128-bit key
[AES128] :: ContentEncryptionCipher AES128

-- | AES with 192-bit key
[AES192] :: ContentEncryptionCipher AES192

-- | AES with 256-bit key
[AES256] :: ContentEncryptionCipher AES256

-- | CAST5 (aka CAST-128) with key between 40 and 128 bits
[CAST5] :: ContentEncryptionCipher CAST5

-- | Camellia with 128-bit key
[Camellia128] :: ContentEncryptionCipher Camellia128

-- | Cipher and mode of operation for content encryption.
data ContentEncryptionAlg

-- | Electronic Codebook
ECB :: ContentEncryptionCipher c -> ContentEncryptionAlg

-- | Cipher Block Chaining
CBC :: ContentEncryptionCipher c -> ContentEncryptionAlg

-- | RC2 in CBC mode
CBC_RC2 :: ContentEncryptionAlg

-- | Cipher Feedback
CFB :: ContentEncryptionCipher c -> ContentEncryptionAlg

-- | Counter
CTR :: ContentEncryptionCipher c -> ContentEncryptionAlg

-- | Content encryption algorithm with associated parameters (i.e. the
--   initialization vector).
--   
--   A value can be generated with generateEncryptionParams.
data ContentEncryptionParams

-- | Encrypted content.
type EncryptedContent = ByteString

-- | Encrypted content information.
data EncryptedData content
EncryptedData :: ContentType -> ContentEncryptionParams -> content -> [Attribute] -> EncryptedData content

-- | Inner content type
[edContentType] :: EncryptedData content -> ContentType

-- | Encryption algorithm
[edContentEncryptionParams] :: EncryptedData content -> ContentEncryptionParams

-- | Encrypted content info
[edEncryptedContent] :: EncryptedData content -> content

-- | Optional unprotected attributes
[edUnprotectedAttrs] :: EncryptedData content -> [Attribute]

-- | Generate random parameters for the specified content encryption
--   algorithm.
generateEncryptionParams :: MonadRandom m => ContentEncryptionAlg -> m ContentEncryptionParams

-- | Generate random RC2 parameters with the specified effective key length
--   (in bits).
generateRC2EncryptionParams :: MonadRandom m => Int -> m ContentEncryptionParams

-- | Get the content encryption algorithm.
getContentEncryptionAlg :: ContentEncryptionParams -> ContentEncryptionAlg

-- | Add an encrypted-data layer on the specified content info. The content
--   is encrypted with specified key and algorithm.
--   
--   Some optional attributes can be added but will not be encrypted.
encryptData :: ContentEncryptionKey -> ContentEncryptionParams -> [Attribute] -> ContentInfo -> Either StoreError (EncryptedData EncryptedContent)

-- | Decrypt an encrypted content info using the specified key.
decryptData :: ContentEncryptionKey -> EncryptedData EncryptedContent -> Either StoreError ContentInfo

-- | Key used for authentication.
type AuthenticationKey = ContentEncryptionKey

-- | Message Authentication Code (MAC) Algorithm.
data MACAlgorithm
HMAC :: DigestProxy hashAlg -> MACAlgorithm
KMAC_SHAKE128 :: Proxy n -> ByteString -> MACAlgorithm
KMAC_SHAKE256 :: Proxy n -> ByteString -> MACAlgorithm

-- | Message authentication code. Equality is time constant.
type MessageAuthenticationCode = AuthTag

-- | Authenticated content information.
data AuthenticatedData content
AuthenticatedData :: OriginatorInfo -> [RecipientInfo] -> MACAlgorithm -> Maybe DigestAlgorithm -> ContentType -> content -> [Attribute] -> MessageAuthenticationCode -> [Attribute] -> AuthenticatedData content

-- | Optional information about the originator
[adOriginatorInfo] :: AuthenticatedData content -> OriginatorInfo

-- | Information for recipients, allowing to authenticate the content
[adRecipientInfos] :: AuthenticatedData content -> [RecipientInfo]

-- | MAC algorithm
[adMACAlgorithm] :: AuthenticatedData content -> MACAlgorithm

-- | Optional digest algorithm
[adDigestAlgorithm] :: AuthenticatedData content -> Maybe DigestAlgorithm

-- | Inner content type
[adContentType] :: AuthenticatedData content -> ContentType

-- | Encapsulated content
[adEncapsulatedContent] :: AuthenticatedData content -> content

-- | Optional authenticated attributes
[adAuthAttrs] :: AuthenticatedData content -> [Attribute]

-- | Message authentication code
[adMAC] :: AuthenticatedData content -> MessageAuthenticationCode

-- | Optional unauthenticated attributes
[adUnauthAttrs] :: AuthenticatedData content -> [Attribute]

-- | Add an authenticated-data layer on the specified content info. The
--   content is MACed with the specified key and algorithms. The key is
--   then processed by one or several ProducerOfRI functions to
--   create recipient info elements.
--   
--   Two lists of optional attributes can be provided. The attributes will
--   be part of message authentication when provided in the first list.
generateAuthenticatedData :: Applicative f => OriginatorInfo -> AuthenticationKey -> MACAlgorithm -> Maybe DigestAlgorithm -> [ProducerOfRI f] -> [Attribute] -> [Attribute] -> ContentInfo -> f (Either StoreError (AuthenticatedData EncapsulatedContent))

-- | Verify the integrity of an authenticated content info using the
--   specified ConsumerOfRI function. The inner content info is
--   returned only if the MAC could be verified.
verifyAuthenticatedData :: Monad m => ConsumerOfRI m -> AuthenticatedData EncapsulatedContent -> m (Either StoreError ContentInfo)

-- | Cipher and mode of operation for authenticated-content encryption.
data AuthContentEncryptionAlg

-- | authEnc with 128-bit key
AUTH_ENC_128 :: AuthContentEncryptionAlg

-- | authEnc with 256-bit key
AUTH_ENC_256 :: AuthContentEncryptionAlg

-- | ChaCha20-Poly1305 Authenticated Encryption
CHACHA20_POLY1305 :: AuthContentEncryptionAlg

-- | Counter with CBC-MAC
CCM :: ContentEncryptionCipher c -> AuthContentEncryptionAlg

-- | Galois Counter Mode
GCM :: ContentEncryptionCipher c -> AuthContentEncryptionAlg

-- | Authenticated-content encryption algorithm with associated parameters
--   (i.e. the nonce).
--   
--   A value can be generated with functions
--   generateAuthEnc128Params, generateAuthEnc256Params,
--   generateChaChaPoly1305Params, generateCCMParams and
--   generateGCMParams.
data AuthContentEncryptionParams

-- | Authenticated-enveloped content information.
data AuthEnvelopedData content
AuthEnvelopedData :: OriginatorInfo -> [RecipientInfo] -> ContentType -> ASN1ObjectExact AuthContentEncryptionParams -> content -> [Attribute] -> MessageAuthenticationCode -> [Attribute] -> AuthEnvelopedData content

-- | Optional information about the originator
[aeOriginatorInfo] :: AuthEnvelopedData content -> OriginatorInfo

-- | Information for recipients, allowing to decrypt the content
[aeRecipientInfos] :: AuthEnvelopedData content -> [RecipientInfo]

-- | Inner content type
[aeContentType] :: AuthEnvelopedData content -> ContentType

-- | Encryption algorithm
[aeContentEncryptionParams] :: AuthEnvelopedData content -> ASN1ObjectExact AuthContentEncryptionParams

-- | Encrypted content info
[aeEncryptedContent] :: AuthEnvelopedData content -> content

-- | Optional authenticated attributes
[aeAuthAttrs] :: AuthEnvelopedData content -> [Attribute]

-- | Message authentication code
[aeMAC] :: AuthEnvelopedData content -> MessageAuthenticationCode

-- | Optional unauthenticated attributes
[aeUnauthAttrs] :: AuthEnvelopedData content -> [Attribute]

-- | Generate random AUTH_ENC_128 parameters with the specified
--   algorithms.
generateAuthEnc128Params :: MonadRandom m => PBKDF2_PRF -> ContentEncryptionAlg -> MACAlgorithm -> m AuthContentEncryptionParams

-- | Generate random AUTH_ENC_256 parameters with the specified
--   algorithms.
generateAuthEnc256Params :: MonadRandom m => PBKDF2_PRF -> ContentEncryptionAlg -> MACAlgorithm -> m AuthContentEncryptionParams

-- | Generate random CHACHA20_POLY1305 parameters.
generateChaChaPoly1305Params :: MonadRandom m => m AuthContentEncryptionParams

-- | Generate random CCM parameters for the specified cipher.
generateCCMParams :: (MonadRandom m, BlockCipher c) => ContentEncryptionCipher c -> CCM_M -> CCM_L -> m AuthContentEncryptionParams

-- | Generate random GCM parameters for the specified cipher.
generateGCMParams :: (MonadRandom m, BlockCipher c) => ContentEncryptionCipher c -> Int -> m AuthContentEncryptionParams

-- | Add an authenticated-enveloped-data layer on the specified content
--   info. The content is encrypted with specified key and algorithm. The
--   key is then processed by one or several ProducerOfRI functions
--   to create recipient info elements.
--   
--   Some attributes can be added but will not be encrypted. The attributes
--   will be part of message authentication when provided in the first
--   list.
authEnvelopData :: Applicative f => OriginatorInfo -> ContentEncryptionKey -> AuthContentEncryptionParams -> [ProducerOfRI f] -> [Attribute] -> [Attribute] -> ContentInfo -> f (Either StoreError (AuthEnvelopedData EncryptedContent))

-- | Recover an authenticated-enveloped content info using the specified
--   ConsumerOfRI function.
openAuthEnvelopedData :: Monad m => ConsumerOfRI m -> AuthEnvelopedData EncryptedContent -> m (Either StoreError ContentInfo)

-- | Salt value used for key derivation.
type Salt = ByteString

-- | Generate a random salt with the specified length in bytes. To be most
--   effective, the length should be at least 8 bytes.
generateSalt :: MonadRandom m => Int -> m Salt

-- | Key derivation algorithm and associated parameters.
data KeyDerivationFunc

-- | Key derivation with PBKDF2
PBKDF2 :: Salt -> Int -> Maybe Int -> PBKDF2_PRF -> KeyDerivationFunc

-- | Salt value
[pbkdf2Salt] :: KeyDerivationFunc -> Salt

-- | Iteration count
[pbkdf2IterationCount] :: KeyDerivationFunc -> Int

-- | Optional key length
[pbkdf2KeyLength] :: KeyDerivationFunc -> Maybe Int

-- | Pseudorandom function
[pbkdf2Prf] :: KeyDerivationFunc -> PBKDF2_PRF

-- | Key derivation with Scrypt
Scrypt :: Salt -> Word64 -> Int -> Int -> Maybe Int -> KeyDerivationFunc

-- | Salt value
[scryptSalt] :: KeyDerivationFunc -> Salt

-- | N value
[scryptN] :: KeyDerivationFunc -> Word64

-- | R value
[scryptR] :: KeyDerivationFunc -> Int

-- | P value
[scryptP] :: KeyDerivationFunc -> Int

-- | Optional key length
[scryptKeyLength] :: KeyDerivationFunc -> Maybe Int

-- | Pseudorandom function used for PBKDF2.
data PBKDF2_PRF

-- | hmacWithSHA1
PBKDF2_SHA1 :: PBKDF2_PRF

-- | hmacWithSHA256
PBKDF2_SHA256 :: PBKDF2_PRF

-- | hmacWithSHA512
PBKDF2_SHA512 :: PBKDF2_PRF

-- | Algorithms that are based on a secret key. This includes ciphers but
--   also MAC algorithms.
class HasKeySize params

-- | Get a specification of the key sizes allowed by the algorithm.
getKeySizeSpecifier :: HasKeySize params => params -> KeySizeSpecifier

-- | Generate a random key suitable for the specified algorithm. This uses
--   the maximum size allowed by the parameters.
generateKey :: (HasKeySize params, MonadRandom m, ByteArray key) => params -> m key

-- | Mask Generation Functions (MGF) and associated parameters.
newtype MaskGenerationFunc
MGF1 :: DigestAlgorithm -> MaskGenerationFunc

-- | Encryption parameters for RSAES-OAEP.
data OAEPParams
OAEPParams :: DigestAlgorithm -> MaskGenerationFunc -> OAEPParams

-- | Hash function
[oaepHashAlgorithm] :: OAEPParams -> DigestAlgorithm

-- | Mask generation function
[oaepMaskGenAlgorithm] :: OAEPParams -> MaskGenerationFunc

-- | Signature parameters for RSASSA-PSS.
data PSSParams
PSSParams :: DigestAlgorithm -> MaskGenerationFunc -> Int -> PSSParams

-- | Hash function
[pssHashAlgorithm] :: PSSParams -> DigestAlgorithm

-- | Mask generation function
[pssMaskGenAlgorithm] :: PSSParams -> MaskGenerationFunc

-- | Length of the salt in bytes
[pssSaltLength] :: PSSParams -> Int

-- | An attribute extending the parent structure with arbitrary data.
data Attribute
Attribute :: OID -> [ASN1] -> Attribute

-- | Attribute type
[attrType] :: Attribute -> OID

-- | Attribute values
[attrValues] :: Attribute -> [ASN1]

-- | Return the values for the first attribute with the specified type.
findAttribute :: OID -> [Attribute] -> Maybe [ASN1]

-- | Add or replace an attribute in a list of attributes.
setAttribute :: OID -> [ASN1] -> [Attribute] -> [Attribute]

-- | Filter a list of attributes based on a predicate applied to attribute
--   type.
filterAttributes :: (OID -> Bool) -> [Attribute] -> [Attribute]

-- | Return the value of the signingTime attribute.
getSigningTimeAttr :: [Attribute] -> Maybe DateTime

-- | Add or replace the signingTime attribute in a list of
--   attributes.
setSigningTimeAttr :: DateTime -> [Attribute] -> [Attribute]

-- | Add or replace the signingTime attribute in a list of
--   attributes with the current time. This is equivalent to calling
--   setSigningTimeAttr with the result of dateCurrent.
setSigningTimeAttrCurrent :: MonadIO m => [Attribute] -> m [Attribute]

-- | Information about the originator of the content info, to be used when
--   a key management algorithm requires this information.
data OriginatorInfo
OriginatorInfo :: [CertificateChoice] -> [RevocationInfoChoice] -> OriginatorInfo

-- | The collection of certificates
[originatorCerts] :: OriginatorInfo -> [CertificateChoice]

-- | The collection of CRLs
[originatorCRLs] :: OriginatorInfo -> [RevocationInfoChoice]

-- | Union type related to certificate formats.
data CertificateChoice

-- | X.509 certificate
CertificateCertificate :: SignedCertificate -> CertificateChoice

-- | Other format
CertificateOther :: OtherCertificateFormat -> CertificateChoice

-- | Certificate information in a format not supported natively.
data OtherCertificateFormat
OtherCertificateFormat :: OID -> [ASN1] -> OtherCertificateFormat

-- | Format identifier
[otherCertFormat] :: OtherCertificateFormat -> OID

-- | ASN.1 values using this format
[otherCertValues] :: OtherCertificateFormat -> [ASN1]

-- | Union type related to revocation info formats.
data RevocationInfoChoice

-- | A CRL, ARL, Delta CRL, or an ACRL
RevocationInfoCRL :: SignedCRL -> RevocationInfoChoice

-- | Other format
RevocationInfoOther :: OtherRevocationInfoFormat -> RevocationInfoChoice

-- | Revocation information in a format not supported natively.
data OtherRevocationInfoFormat
OtherRevocationInfoFormat :: OID -> [ASN1] -> OtherRevocationInfoFormat

-- | Format identifier
[otherRevInfoFormat] :: OtherRevocationInfoFormat -> OID

-- | ASN.1 values using this format
[otherRevInfoValues] :: OtherRevocationInfoFormat -> [ASN1]

-- | An ASN.1 object associated with the raw data it was parsed from.
data ASN1ObjectExact a

-- | Personal Information Exchange Syntax, aka PKCS #12.
--   
--   Only password integrity mode and password privacy modes are supported.
module Crypto.Store.PKCS12

-- | Parameters used for password integrity mode.
type IntegrityParams = (DigestAlgorithm, PBEParameter)

-- | Read a PKCS #12 file from disk.
readP12File :: FilePath -> IO (Either StoreError (OptAuthenticated PKCS12))

-- | Read a PKCS #12 file from a bytearray in BER format.
readP12FileFromMemory :: ByteString -> Either StoreError (OptAuthenticated PKCS12)

-- | Write a PKCS #12 file to disk.
writeP12File :: FilePath -> IntegrityParams -> ProtectionPassword -> PKCS12 -> IO (Either StoreError ())

-- | Write a PKCS #12 file to a bytearray in DER format.
writeP12FileToMemory :: IntegrityParams -> ProtectionPassword -> PKCS12 -> Either StoreError ByteString

-- | Write a PKCS #12 file without integrity protection to disk.
writeUnprotectedP12File :: FilePath -> PKCS12 -> IO ()

-- | Write a PKCS #12 file without integrity protection to a bytearray in
--   DER format.
writeUnprotectedP12FileToMemory :: PKCS12 -> ByteString

-- | PKCS #12 privacy wrapper, adding optional encryption to
--   SafeContents. ASN.1 equivalent is AuthenticatedSafe.
--   
--   The semigroup interface allows to combine multiple pieces encrypted
--   separately but they should all derive from the same password to be
--   readable by unPKCS12 and most other software.
data PKCS12

-- | Read the contents of a PKCS #12. The same privacy password will be
--   used for all content elements.
--   
--   This convenience function returns a Protected value as soon as
--   one element at least is encrypted. This does not mean all elements
--   were actually protected in the input. If detailed view is required
--   then function unPKCS12' is also available.
unPKCS12 :: PKCS12 -> OptProtected [SafeContents]

-- | Read the contents of a PKCS #12.
unPKCS12' :: PKCS12 -> [OptProtected SafeContents]

-- | Build a PKCS #12 without encryption. Usage scenario is when private
--   keys are already encrypted with PKCS8ShroudedKeyBag.
unencrypted :: SafeContents -> PKCS12

-- | Build a PKCS #12 encrypted with the specified scheme and password.
encrypted :: EncryptionScheme -> ProtectionPassword -> SafeContents -> Either StoreError PKCS12

-- | Content objects stored in a PKCS #12.
newtype SafeContents
SafeContents :: [SafeBag] -> SafeContents
[unSafeContents] :: SafeContents -> [SafeBag]

-- | Main bag type in a PKCS #12.
type SafeBag = Bag SafeInfo

-- | Polymorphic PKCS #12 bag parameterized by the payload data type.
data Bag info
Bag :: info -> [Attribute] -> Bag info

-- | bag payload
[bagInfo] :: Bag info -> info

-- | attributes providing additional information
[bagAttributes] :: Bag info -> [Attribute]

-- | Main bag payload in PKCS #12 contents.
data SafeInfo

-- | unencrypted private key
KeyBag :: FormattedKey PrivKey -> SafeInfo

-- | encrypted private key
PKCS8ShroudedKeyBag :: PKCS5 -> SafeInfo

-- | certificate
CertBag :: Bag CertInfo -> SafeInfo

-- | CRL
CRLBag :: Bag CRLInfo -> SafeInfo

-- | arbitrary secret
SecretBag :: [ASN1] -> SafeInfo

-- | safe contents embeded recursively
SafeContentsBag :: SafeContents -> SafeInfo

-- | Certificate bags. Only X.509 certificates are supported.
newtype CertInfo
CertX509 :: SignedCertificate -> CertInfo

-- | CRL bags. Only X.509 CRLs are supported.
newtype CRLInfo
CRLX509 :: SignedCRL -> CRLInfo

-- | An attribute extending the parent structure with arbitrary data.
data Attribute
Attribute :: OID -> [ASN1] -> Attribute

-- | Attribute type
[attrType] :: Attribute -> OID

-- | Attribute values
[attrValues] :: Attribute -> [ASN1]

-- | Return all private keys contained in the safe contents.
getSafeKeys :: SafeContents -> [OptProtected PrivKey]

-- | Return all private keys contained in the safe content list. All
--   shrouded private keys must derive from the same password.
--   
--   This convenience function returns a Protected value as soon as
--   one key at least is encrypted. This does not mean all keys were
--   actually protected in the input. If detailed view is required then
--   function getSafeKeys is available.
getAllSafeKeys :: [SafeContents] -> OptProtected [PrivKey]

-- | Return all X.509 certificates contained in the safe contents.
getSafeX509Certs :: SafeContents -> [SignedCertificate]

-- | Return all X.509 certificates contained in the safe content list.
getAllSafeX509Certs :: [SafeContents] -> [SignedCertificate]

-- | Return all X.509 CRLs contained in the safe contents.
getSafeX509CRLs :: SafeContents -> [SignedCRL]

-- | Return all X.509 CRLs contained in the safe content list.
getAllSafeX509CRLs :: [SafeContents] -> [SignedCRL]

-- | Return the values for the first attribute with the specified type.
findAttribute :: OID -> [Attribute] -> Maybe [ASN1]

-- | Add or replace an attribute in a list of attributes.
setAttribute :: OID -> [ASN1] -> [Attribute] -> [Attribute]

-- | Filter a list of attributes based on a predicate applied to attribute
--   type.
filterAttributes :: (OID -> Bool) -> [Attribute] -> [Attribute]

-- | Return the value of the friendlyName attribute.
getFriendlyName :: [Attribute] -> Maybe String

-- | Add or replace the friendlyName attribute in a list of
--   attributes.
setFriendlyName :: String -> [Attribute] -> [Attribute]

-- | Return the value of the localKeyId attribute.
getLocalKeyId :: [Attribute] -> Maybe ByteString

-- | Add or replace the localKeyId attribute in a list of
--   attributes.
setLocalKeyId :: ByteString -> [Attribute] -> [Attribute]

-- | Build a PKCS12 value containing a private key and certificate
--   chain. Distinct encryption is applied for both. Encrypting the
--   certificate chain is optional.
--   
--   Note: advice is to always generate fresh and independent
--   EncryptionScheme values so that the salt is not reused twice in
--   the encryption process.
fromCredential :: Maybe EncryptionScheme -> EncryptionScheme -> ProtectionPassword -> (CertificateChain, PrivKey) -> Either StoreError PKCS12

-- | Build a PKCS12 value containing a private key and certificate
--   chain identified with the specified friendly name. Distinct encryption
--   is applied for private key and certificates. Encrypting the
--   certificate chain is optional.
--   
--   Note: advice is to always generate fresh and independent
--   EncryptionScheme values so that the salt is not reused twice in
--   the encryption process.
fromNamedCredential :: String -> Maybe EncryptionScheme -> EncryptionScheme -> ProtectionPassword -> (CertificateChain, PrivKey) -> Either StoreError PKCS12

-- | Extract the private key and certificate chain from a PKCS12
--   value. A credential is returned when the structure contains exactly
--   one private key and at least one X.509 certificate.
toCredential :: PKCS12 -> OptProtected (Maybe (CertificateChain, PrivKey))

-- | Extract a private key and certificate chain with the specified
--   friendly name from a PKCS12 value. A credential is returned
--   when the structure contains exactly one private key and one X.509
--   certificate with the name.
toNamedCredential :: String -> PKCS12 -> OptProtected (Maybe (CertificateChain, PrivKey))

-- | A password stored as a sequence of UTF-8 bytes.
--   
--   Some key-derivation functions add restrictions to what characters are
--   supported.
--   
--   Beware: fromString truncates multi-byte characters. If the
--   string may contain non-ASCII characters, prefer instead
--   fromProtectionPassword . fromString.
type Password = ByteString

-- | Data type for objects that are possibly authenticated with a password.
--   
--   Content is verified and retrieved by providing a Password
--   value. When verification is successful, a value of type
--   ProtectionPassword is also returned and this value can be fed
--   to an inner decryption layer that needs the same password (usual case
--   for PKCS #12).
data OptAuthenticated a

-- | Value is not authenticated
Unauthenticated :: a -> OptAuthenticated a

-- | Value is authenticated with a password
Authenticated :: (Password -> Either StoreError (ProtectionPassword, a)) -> OptAuthenticated a

-- | Try to recover an OptAuthenticated content using the specified
--   password.
--   
--   When successful, the content is returned, as well as the password
--   converted to type ProtectionPassword. This password value can
--   then be fed to the inner decryption layer when both passwords are
--   known to be same (usual case for PKCS #12).
recoverAuthenticated :: Password -> OptAuthenticated a -> Either StoreError (ProtectionPassword, a)

-- | A password stored as a sequence of UTF-8 bytes.
--   
--   Some key-derivation functions add restrictions to what characters are
--   supported.
--   
--   The data type provides a special value emptyNotTerminated that
--   is used as alternate representation of empty passwords on some systems
--   and that produces encryption results different than an empty
--   bytearray.
--   
--   Conversion to/from a regular sequence of bytes is possible with
--   functions toProtectionPassword and
--   fromProtectionPassword.
--   
--   Beware: the fromString implementation correctly handles
--   multi-byte characters, so here is not equivalent to the
--   ByteString counterpart.
data ProtectionPassword

-- | A value denoting an empty password, but having a special encoding when
--   deriving a symmetric key on some systems, like the certificate export
--   wizard on Windows.
--   
--   This value is different from toProtectionPassword ""
--   and can be tried when decrypting content with a password known to be
--   empty.
emptyNotTerminated :: ProtectionPassword

-- | Extract the UTF-8 bytes in a password value.
fromProtectionPassword :: ProtectionPassword -> ByteString

-- | Build a password value from a sequence of UTF-8 bytes.
--   
--   When the password is empty, the special value
--   emptyNotTerminated may be tried as well.
toProtectionPassword :: ByteString -> ProtectionPassword

-- | Data type for objects that are possibly protected with a password.
data OptProtected a

-- | Value is unprotected
Unprotected :: a -> OptProtected a

-- | Value is protected with a password
Protected :: (ProtectionPassword -> Either StoreError a) -> OptProtected a

-- | Try to recover an OptProtected content using the specified
--   password.
recover :: ProtectionPassword -> OptProtected a -> Either StoreError a

-- | Try to recover an OptProtected content in an applicative
--   context. The applicative password is used if necessary.
--   
--   
--   import qualified Data.ByteString as B
--   import           Crypto.Store.PKCS8
--   
--   [encryptedKey] <- readKeyFile "privkey.pem"
--   let askForPassword = putStr "Please enter password: " >> B.getLine
--   result <- recoverA (toProtectionPassword <$> askForPassword) encryptedKey
--   case result of
--       Left err  -> putStrLn $ "Unable to recover key: " ++ show err
--       Right key -> print key
--   
recoverA :: Applicative f => f ProtectionPassword -> OptProtected a -> f (Either StoreError a)
instance GHC.Classes.Eq Crypto.Store.PKCS12.MacData
instance GHC.Show.Show Crypto.Store.PKCS12.MacData
instance GHC.Classes.Eq Crypto.Store.PKCS12.PFX
instance GHC.Show.Show Crypto.Store.PKCS12.PFX
instance GHC.Classes.Eq info => GHC.Classes.Eq (Crypto.Store.PKCS12.Bag info)
instance GHC.Show.Show info => GHC.Show.Show (Crypto.Store.PKCS12.Bag info)
instance GHC.Classes.Eq Crypto.Store.PKCS12.CertType
instance GHC.Show.Show Crypto.Store.PKCS12.CertType
instance GHC.Classes.Eq Crypto.Store.PKCS12.CertInfo
instance GHC.Show.Show Crypto.Store.PKCS12.CertInfo
instance GHC.Classes.Eq Crypto.Store.PKCS12.CRLType
instance GHC.Show.Show Crypto.Store.PKCS12.CRLType
instance GHC.Classes.Eq Crypto.Store.PKCS12.CRLInfo
instance GHC.Show.Show Crypto.Store.PKCS12.CRLInfo
instance GHC.Classes.Eq Crypto.Store.PKCS12.SafeType
instance GHC.Show.Show Crypto.Store.PKCS12.SafeType
instance GHC.Classes.Eq Crypto.Store.PKCS12.SafeInfo
instance GHC.Show.Show Crypto.Store.PKCS12.SafeInfo
instance GHC.Classes.Eq Crypto.Store.PKCS12.SafeContents
instance GHC.Show.Show Crypto.Store.PKCS12.SafeContents
instance GHC.Classes.Eq Crypto.Store.PKCS12.ASElement
instance GHC.Show.Show Crypto.Store.PKCS12.ASElement
instance GHC.Classes.Eq Crypto.Store.PKCS12.PKCS12
instance GHC.Show.Show Crypto.Store.PKCS12.PKCS12
instance GHC.Base.Functor Crypto.Store.PKCS12.SamePassword
instance GHC.Base.Applicative Crypto.Store.PKCS12.SamePassword
instance GHC.Base.Monad Crypto.Store.PKCS12.SamePassword
instance GHC.Base.Semigroup Crypto.Store.PKCS12.PKCS12
instance Crypto.Store.CMS.Util.ProduceASN1Object Crypto.Store.ASN1.Generate.ASN1P Crypto.Store.PKCS12.PKCS12
instance Crypto.Store.CMS.Util.ParseASN1Object [Data.ASN1.Types.Lowlevel.ASN1Event] Crypto.Store.PKCS12.PKCS12
instance Crypto.Store.ASN1.Generate.ASN1Elem e => Crypto.Store.CMS.Util.ProduceASN1Object e Crypto.Store.PKCS12.ASElement
instance GHC.Base.Monoid e => Crypto.Store.CMS.Util.ParseASN1Object e Crypto.Store.PKCS12.ASElement
instance Crypto.Store.PKCS12.BagInfo Crypto.Store.PKCS12.SafeInfo
instance Crypto.Store.ASN1.Generate.ASN1Elem e => Crypto.Store.CMS.Util.ProduceASN1Object e Crypto.Store.PKCS12.SafeContents
instance GHC.Base.Monoid e => Crypto.Store.CMS.Util.ParseASN1Object e Crypto.Store.PKCS12.SafeContents
instance Crypto.Store.CMS.Util.Enumerable Crypto.Store.PKCS12.SafeType
instance Data.ASN1.OID.OIDable Crypto.Store.PKCS12.SafeType
instance Data.ASN1.OID.OIDNameable Crypto.Store.PKCS12.SafeType
instance Crypto.Store.PKCS12.BagInfo Crypto.Store.PKCS12.CRLInfo
instance Crypto.Store.CMS.Util.Enumerable Crypto.Store.PKCS12.CRLType
instance Data.ASN1.OID.OIDable Crypto.Store.PKCS12.CRLType
instance Data.ASN1.OID.OIDNameable Crypto.Store.PKCS12.CRLType
instance Crypto.Store.PKCS12.BagInfo Crypto.Store.PKCS12.CertInfo
instance Crypto.Store.CMS.Util.Enumerable Crypto.Store.PKCS12.CertType
instance Data.ASN1.OID.OIDable Crypto.Store.PKCS12.CertType
instance Data.ASN1.OID.OIDNameable Crypto.Store.PKCS12.CertType
instance (Crypto.Store.ASN1.Generate.ASN1Elem e, Crypto.Store.PKCS12.BagInfo info, Data.ASN1.OID.OIDable (Crypto.Store.PKCS12.BagType info)) => Crypto.Store.CMS.Util.ProduceASN1Object e (Crypto.Store.PKCS12.Bag info)
instance (GHC.Base.Monoid e, Crypto.Store.PKCS12.BagInfo info, Data.ASN1.OID.OIDNameable (Crypto.Store.PKCS12.BagType info)) => Crypto.Store.CMS.Util.ParseASN1Object e (Crypto.Store.PKCS12.Bag info)
instance Crypto.Store.CMS.Util.ProduceASN1Object Crypto.Store.ASN1.Generate.ASN1P Crypto.Store.PKCS12.PFX
instance Crypto.Store.CMS.Util.ParseASN1Object [Data.ASN1.Types.Lowlevel.ASN1Event] Crypto.Store.PKCS12.PFX
instance Crypto.Store.ASN1.Generate.ASN1Elem e => Crypto.Store.CMS.Util.ProduceASN1Object e Crypto.Store.PKCS12.MacData
instance GHC.Base.Monoid e => Crypto.Store.CMS.Util.ParseASN1Object e Crypto.Store.PKCS12.MacData
instance GHC.Base.Functor Crypto.Store.PKCS12.OptAuthenticated

-- | Public keys, certificates and CRLs.
--   
--   Presents an API similar to Data.X509.Memory and
--   Data.X509.File but provides support for public-key files and
--   allows to write objects.
--   
--   Functions related to private keys are available from
--   Crypto.Store.PKCS8.
module Crypto.Store.X509

-- | Class of signed objects convertible to PEM.
class (ASN1Object a, Eq a, Show a) => SignedObject a

-- | Read public keys from a PEM file.
readPubKeyFile :: FilePath -> IO [PubKey]

-- | Read public keys from a bytearray in PEM format.
readPubKeyFileFromMemory :: ByteString -> [PubKey]

-- | Read a public key from a PEM element and add it to the
--   accumulator list.
pemToPubKey :: [Maybe PubKey] -> PEM -> [Maybe PubKey]

-- | Write public keys to a PEM file.
writePubKeyFile :: FilePath -> [PubKey] -> IO ()

-- | Write public keys to a bytearray in PEM format.
writePubKeyFileToMemory :: [PubKey] -> ByteString

-- | Generate a PEM for a public key.
pubKeyToPEM :: PubKey -> PEM

-- | Read signed objects from a PEM file (only one type at a time).
readSignedObject :: SignedObject a => FilePath -> IO [SignedExact a]

-- | Read signed objects from a bytearray in PEM format (only one type at a
--   time).
readSignedObjectFromMemory :: SignedObject a => ByteString -> [SignedExact a]

-- | Write signed objects to a PEM file.
writeSignedObject :: SignedObject a => FilePath -> [SignedExact a] -> IO ()

-- | Write signed objects to a bytearray in PEM format.
writeSignedObjectToMemory :: SignedObject a => [SignedExact a] -> ByteString

-- | Read a PEM file from disk.
readPEMs :: FilePath -> IO [PEM]

-- | Write a PEM file to disk.
writePEMs :: FilePath -> [PEM] -> IO ()
instance Crypto.Store.ASN1.Generate.ASN1Elem e => Crypto.Store.CMS.Util.ProduceASN1Object e Crypto.Store.X509.RSAPublicKey
instance GHC.Base.Monoid e => Crypto.Store.CMS.Util.ParseASN1Object e Crypto.Store.X509.RSAPublicKey
instance Crypto.Store.X509.SignedObject Data.X509.Cert.Certificate
instance Crypto.Store.X509.SignedObject Data.X509.CRL.CRL
