-- |
-- Module      : Data.Store.PKCS5
-- License     : BSD-style
-- Maintainer  : Olivier Chéron <olivier.cheron@gmail.com>
-- Stability   : experimental
-- Portability : unknown
--
-- Password-Based Cryptography, aka PKCS #5.
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
module Crypto.Store.PKCS5
    ( ProtectionPassword
    , emptyNotTerminated
    , fromProtectionPassword
    , toProtectionPassword
    , EncryptedContent
    -- * High-level API
    , PKCS5(..)
    , encrypt
    , decrypt
    -- * Encryption schemes
    , EncryptionScheme(..)
    , PBEParameter(..)
    , PBES2Parameter(..)
    -- * Key derivation
    , KeyDerivationFunc(..)
    , PBKDF2_PRF(..)
    , Salt
    , generateSalt
    -- * Content encryption
    , ContentEncryptionParams
    , ContentEncryptionAlg(..)
    , ContentEncryptionCipher(..)
    , generateEncryptionParams
    , getContentEncryptionAlg
    -- * Low-level API
    , pbEncrypt
    , pbDecrypt
    ) where

import           Data.ASN1.Types
import           Data.ByteString (ByteString)
import           Data.Maybe (fromMaybe)

import Crypto.Store.ASN1.Parse
import Crypto.Store.ASN1.Generate
import Crypto.Store.CMS.Algorithms
import Crypto.Store.CMS.Encrypted
import Crypto.Store.CMS.Util
import Crypto.Store.Error
import Crypto.Store.PKCS5.PBES1

data EncryptionSchemeType = Type_PBES2
                          | Type_PBE_MD5_DES_CBC
                          | Type_PBE_SHA1_DES_CBC
                          | Type_PBE_SHA1_RC4_128
                          | Type_PBE_SHA1_RC4_40
                          | Type_PBE_SHA1_DES_EDE3_CBC
                          | Type_PBE_SHA1_DES_EDE2_CBC
                          | Type_PBE_SHA1_RC2_128
                          | Type_PBE_SHA1_RC2_40

instance Enumerable EncryptionSchemeType where
    values :: [EncryptionSchemeType]
values = [ EncryptionSchemeType
Type_PBES2
             , EncryptionSchemeType
Type_PBE_MD5_DES_CBC
             , EncryptionSchemeType
Type_PBE_SHA1_DES_CBC
             , EncryptionSchemeType
Type_PBE_SHA1_RC4_128
             , EncryptionSchemeType
Type_PBE_SHA1_RC4_40
             , EncryptionSchemeType
Type_PBE_SHA1_DES_EDE3_CBC
             , EncryptionSchemeType
Type_PBE_SHA1_DES_EDE2_CBC
             , EncryptionSchemeType
Type_PBE_SHA1_RC2_128
             , EncryptionSchemeType
Type_PBE_SHA1_RC2_40
             ]

instance OIDable EncryptionSchemeType where
    getObjectID :: EncryptionSchemeType -> OID
getObjectID EncryptionSchemeType
Type_PBES2                 = [Integer
1,Integer
2,Integer
840,Integer
113549,Integer
1,Integer
5,Integer
13]
    getObjectID EncryptionSchemeType
Type_PBE_MD5_DES_CBC       = [Integer
1,Integer
2,Integer
840,Integer
113549,Integer
1,Integer
5,Integer
3]
    getObjectID EncryptionSchemeType
Type_PBE_SHA1_DES_CBC      = [Integer
1,Integer
2,Integer
840,Integer
113549,Integer
1,Integer
5,Integer
10]
    getObjectID EncryptionSchemeType
Type_PBE_SHA1_RC4_128      = [Integer
1,Integer
2,Integer
840,Integer
113549,Integer
1,Integer
12,Integer
1,Integer
1]
    getObjectID EncryptionSchemeType
Type_PBE_SHA1_RC4_40       = [Integer
1,Integer
2,Integer
840,Integer
113549,Integer
1,Integer
12,Integer
1,Integer
2]
    getObjectID EncryptionSchemeType
Type_PBE_SHA1_DES_EDE3_CBC = [Integer
1,Integer
2,Integer
840,Integer
113549,Integer
1,Integer
12,Integer
1,Integer
3]
    getObjectID EncryptionSchemeType
Type_PBE_SHA1_DES_EDE2_CBC = [Integer
1,Integer
2,Integer
840,Integer
113549,Integer
1,Integer
12,Integer
1,Integer
4]
    getObjectID EncryptionSchemeType
Type_PBE_SHA1_RC2_128      = [Integer
1,Integer
2,Integer
840,Integer
113549,Integer
1,Integer
12,Integer
1,Integer
5]
    getObjectID EncryptionSchemeType
Type_PBE_SHA1_RC2_40       = [Integer
1,Integer
2,Integer
840,Integer
113549,Integer
1,Integer
12,Integer
1,Integer
6]

instance OIDNameable EncryptionSchemeType where
    fromObjectID :: OID -> Maybe EncryptionSchemeType
fromObjectID OID
oid = OIDNameableWrapper EncryptionSchemeType -> EncryptionSchemeType
forall a. OIDNameableWrapper a -> a
unOIDNW (OIDNameableWrapper EncryptionSchemeType -> EncryptionSchemeType)
-> Maybe (OIDNameableWrapper EncryptionSchemeType)
-> Maybe EncryptionSchemeType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> OID -> Maybe (OIDNameableWrapper EncryptionSchemeType)
forall a. OIDNameable a => OID -> Maybe a
fromObjectID OID
oid

-- | Password-Based Encryption Scheme (PBES).
data EncryptionScheme = PBES2 PBES2Parameter               -- ^ PBES2
                      | PBE_MD5_DES_CBC PBEParameter       -- ^ pbeWithMD5AndDES-CBC
                      | PBE_SHA1_DES_CBC PBEParameter      -- ^ pbeWithSHA1AndDES-CBC
                      | PBE_SHA1_RC4_128 PBEParameter      -- ^ pbeWithSHAAnd128BitRC4
                      | PBE_SHA1_RC4_40 PBEParameter       -- ^ pbeWithSHAAnd40BitRC4
                      | PBE_SHA1_DES_EDE3_CBC PBEParameter -- ^ pbeWithSHAAnd3-KeyTripleDES-CBC
                      | PBE_SHA1_DES_EDE2_CBC PBEParameter -- ^ pbeWithSHAAnd2-KeyTripleDES-CBC
                      | PBE_SHA1_RC2_128 PBEParameter      -- ^ pbeWithSHAAnd128BitRC2-CBC
                      | PBE_SHA1_RC2_40 PBEParameter       -- ^ pbewithSHAAnd40BitRC2-CBC
                      deriving (Int -> EncryptionScheme -> ShowS
[EncryptionScheme] -> ShowS
EncryptionScheme -> String
(Int -> EncryptionScheme -> ShowS)
-> (EncryptionScheme -> String)
-> ([EncryptionScheme] -> ShowS)
-> Show EncryptionScheme
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> EncryptionScheme -> ShowS
showsPrec :: Int -> EncryptionScheme -> ShowS
$cshow :: EncryptionScheme -> String
show :: EncryptionScheme -> String
$cshowList :: [EncryptionScheme] -> ShowS
showList :: [EncryptionScheme] -> ShowS
Show,EncryptionScheme -> EncryptionScheme -> Bool
(EncryptionScheme -> EncryptionScheme -> Bool)
-> (EncryptionScheme -> EncryptionScheme -> Bool)
-> Eq EncryptionScheme
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: EncryptionScheme -> EncryptionScheme -> Bool
== :: EncryptionScheme -> EncryptionScheme -> Bool
$c/= :: EncryptionScheme -> EncryptionScheme -> Bool
/= :: EncryptionScheme -> EncryptionScheme -> Bool
Eq)

-- | PBES2 parameters.
data PBES2Parameter = PBES2Parameter
    { PBES2Parameter -> KeyDerivationFunc
pbes2KDF     :: KeyDerivationFunc       -- ^ Key derivation function
    , PBES2Parameter -> ContentEncryptionParams
pbes2EScheme :: ContentEncryptionParams -- ^ Underlying encryption scheme
    }
    deriving (Int -> PBES2Parameter -> ShowS
[PBES2Parameter] -> ShowS
PBES2Parameter -> String
(Int -> PBES2Parameter -> ShowS)
-> (PBES2Parameter -> String)
-> ([PBES2Parameter] -> ShowS)
-> Show PBES2Parameter
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PBES2Parameter -> ShowS
showsPrec :: Int -> PBES2Parameter -> ShowS
$cshow :: PBES2Parameter -> String
show :: PBES2Parameter -> String
$cshowList :: [PBES2Parameter] -> ShowS
showList :: [PBES2Parameter] -> ShowS
Show,PBES2Parameter -> PBES2Parameter -> Bool
(PBES2Parameter -> PBES2Parameter -> Bool)
-> (PBES2Parameter -> PBES2Parameter -> Bool) -> Eq PBES2Parameter
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PBES2Parameter -> PBES2Parameter -> Bool
== :: PBES2Parameter -> PBES2Parameter -> Bool
$c/= :: PBES2Parameter -> PBES2Parameter -> Bool
/= :: PBES2Parameter -> PBES2Parameter -> Bool
Eq)

instance ASN1Elem e => ProduceASN1Object e PBES2Parameter where
    asn1s :: PBES2Parameter -> ASN1Stream e
asn1s PBES2Parameter{KeyDerivationFunc
ContentEncryptionParams
pbes2KDF :: PBES2Parameter -> KeyDerivationFunc
pbes2EScheme :: PBES2Parameter -> ContentEncryptionParams
pbes2KDF :: KeyDerivationFunc
pbes2EScheme :: ContentEncryptionParams
..} =
        let kdFunc :: ASN1Stream e
kdFunc  = ASN1ConstructionType -> KeyDerivationFunc -> ASN1Stream e
forall e param.
(ASN1Elem e, AlgorithmId param, OIDable (AlgorithmType param)) =>
ASN1ConstructionType -> param -> ASN1Stream e
algorithmASN1S ASN1ConstructionType
Sequence KeyDerivationFunc
pbes2KDF
            eScheme :: ASN1Stream e
eScheme = ContentEncryptionParams -> ASN1Stream e
forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
asn1s ContentEncryptionParams
pbes2EScheme
         in ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container ASN1ConstructionType
Sequence (ASN1Stream e
kdFunc ASN1Stream e -> ASN1Stream e -> ASN1Stream e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
eScheme)

instance Monoid e => ParseASN1Object e PBES2Parameter where
    parse :: ParseASN1 e PBES2Parameter
parse = ASN1ConstructionType
-> ParseASN1 e PBES2Parameter -> ParseASN1 e PBES2Parameter
forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
onNextContainer ASN1ConstructionType
Sequence (ParseASN1 e PBES2Parameter -> ParseASN1 e PBES2Parameter)
-> ParseASN1 e PBES2Parameter -> ParseASN1 e PBES2Parameter
forall a b. (a -> b) -> a -> b
$ do
        KeyDerivationFunc
kdFunc  <- ASN1ConstructionType -> ParseASN1 e KeyDerivationFunc
forall e param.
(Monoid e, AlgorithmId param, OIDNameable (AlgorithmType param)) =>
ASN1ConstructionType -> ParseASN1 e param
parseAlgorithm ASN1ConstructionType
Sequence
        ContentEncryptionParams
eScheme <- ParseASN1 e ContentEncryptionParams
forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse
        case KeyDerivationFunc -> Maybe Int
kdfKeyLength KeyDerivationFunc
kdFunc of
            Maybe Int
Nothing -> () -> ParseASN1 e ()
forall a. a -> ParseASN1 e a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
            Just Int
sz
                | ContentEncryptionParams -> Int -> Bool
forall params. HasKeySize params => params -> Int -> Bool
validateKeySize ContentEncryptionParams
eScheme Int
sz -> () -> ParseASN1 e ()
forall a. a -> ParseASN1 e a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
                | Bool
otherwise -> String -> ParseASN1 e ()
forall e a. String -> ParseASN1 e a
throwParseError String
"PBES2Parameter: parsed key length incompatible with encryption scheme"
        PBES2Parameter -> ParseASN1 e PBES2Parameter
forall a. a -> ParseASN1 e a
forall (m :: * -> *) a. Monad m => a -> m a
return PBES2Parameter { pbes2KDF :: KeyDerivationFunc
pbes2KDF = KeyDerivationFunc
kdFunc, pbes2EScheme :: ContentEncryptionParams
pbes2EScheme = ContentEncryptionParams
eScheme }

instance AlgorithmId EncryptionScheme where
    type AlgorithmType EncryptionScheme = EncryptionSchemeType
    algorithmName :: EncryptionScheme -> String
algorithmName EncryptionScheme
_  = String
"encryption scheme"

    algorithmType :: EncryptionScheme -> AlgorithmType EncryptionScheme
algorithmType (PBES2 PBES2Parameter
_)                 = AlgorithmType EncryptionScheme
EncryptionSchemeType
Type_PBES2
    algorithmType (PBE_MD5_DES_CBC PBEParameter
_)       = AlgorithmType EncryptionScheme
EncryptionSchemeType
Type_PBE_MD5_DES_CBC
    algorithmType (PBE_SHA1_DES_CBC PBEParameter
_)      = AlgorithmType EncryptionScheme
EncryptionSchemeType
Type_PBE_SHA1_DES_CBC
    algorithmType (PBE_SHA1_RC4_128 PBEParameter
_)      = AlgorithmType EncryptionScheme
EncryptionSchemeType
Type_PBE_SHA1_RC4_128
    algorithmType (PBE_SHA1_RC4_40 PBEParameter
_)       = AlgorithmType EncryptionScheme
EncryptionSchemeType
Type_PBE_SHA1_RC4_40
    algorithmType (PBE_SHA1_DES_EDE3_CBC PBEParameter
_) = AlgorithmType EncryptionScheme
EncryptionSchemeType
Type_PBE_SHA1_DES_EDE3_CBC
    algorithmType (PBE_SHA1_DES_EDE2_CBC PBEParameter
_) = AlgorithmType EncryptionScheme
EncryptionSchemeType
Type_PBE_SHA1_DES_EDE2_CBC
    algorithmType (PBE_SHA1_RC2_128 PBEParameter
_)      = AlgorithmType EncryptionScheme
EncryptionSchemeType
Type_PBE_SHA1_RC2_128
    algorithmType (PBE_SHA1_RC2_40 PBEParameter
_)       = AlgorithmType EncryptionScheme
EncryptionSchemeType
Type_PBE_SHA1_RC2_40

    parameterASN1S :: forall e. ASN1Elem e => EncryptionScheme -> ASN1Stream e
parameterASN1S (PBES2 PBES2Parameter
p)                 = PBES2Parameter -> ASN1Stream e
forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
asn1s PBES2Parameter
p
    parameterASN1S (PBE_MD5_DES_CBC PBEParameter
p)       = PBEParameter -> ASN1Stream e
forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
asn1s PBEParameter
p
    parameterASN1S (PBE_SHA1_DES_CBC PBEParameter
p)      = PBEParameter -> ASN1Stream e
forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
asn1s PBEParameter
p
    parameterASN1S (PBE_SHA1_RC4_128 PBEParameter
p)      = PBEParameter -> ASN1Stream e
forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
asn1s PBEParameter
p
    parameterASN1S (PBE_SHA1_RC4_40 PBEParameter
p)       = PBEParameter -> ASN1Stream e
forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
asn1s PBEParameter
p
    parameterASN1S (PBE_SHA1_DES_EDE3_CBC PBEParameter
p) = PBEParameter -> ASN1Stream e
forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
asn1s PBEParameter
p
    parameterASN1S (PBE_SHA1_DES_EDE2_CBC PBEParameter
p) = PBEParameter -> ASN1Stream e
forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
asn1s PBEParameter
p
    parameterASN1S (PBE_SHA1_RC2_128 PBEParameter
p)      = PBEParameter -> ASN1Stream e
forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
asn1s PBEParameter
p
    parameterASN1S (PBE_SHA1_RC2_40 PBEParameter
p)       = PBEParameter -> ASN1Stream e
forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
asn1s PBEParameter
p

    parseParameter :: forall e.
Monoid e =>
AlgorithmType EncryptionScheme -> ParseASN1 e EncryptionScheme
parseParameter AlgorithmType EncryptionScheme
EncryptionSchemeType
Type_PBES2                 = PBES2Parameter -> EncryptionScheme
PBES2 (PBES2Parameter -> EncryptionScheme)
-> ParseASN1 e PBES2Parameter -> ParseASN1 e EncryptionScheme
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParseASN1 e PBES2Parameter
forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse
    parseParameter AlgorithmType EncryptionScheme
EncryptionSchemeType
Type_PBE_MD5_DES_CBC       = PBEParameter -> EncryptionScheme
PBE_MD5_DES_CBC (PBEParameter -> EncryptionScheme)
-> ParseASN1 e PBEParameter -> ParseASN1 e EncryptionScheme
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParseASN1 e PBEParameter
forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse
    parseParameter AlgorithmType EncryptionScheme
EncryptionSchemeType
Type_PBE_SHA1_DES_CBC      = PBEParameter -> EncryptionScheme
PBE_SHA1_DES_CBC (PBEParameter -> EncryptionScheme)
-> ParseASN1 e PBEParameter -> ParseASN1 e EncryptionScheme
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParseASN1 e PBEParameter
forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse
    parseParameter AlgorithmType EncryptionScheme
EncryptionSchemeType
Type_PBE_SHA1_RC4_128      = PBEParameter -> EncryptionScheme
PBE_SHA1_RC4_128 (PBEParameter -> EncryptionScheme)
-> ParseASN1 e PBEParameter -> ParseASN1 e EncryptionScheme
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParseASN1 e PBEParameter
forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse
    parseParameter AlgorithmType EncryptionScheme
EncryptionSchemeType
Type_PBE_SHA1_RC4_40       = PBEParameter -> EncryptionScheme
PBE_SHA1_RC4_40 (PBEParameter -> EncryptionScheme)
-> ParseASN1 e PBEParameter -> ParseASN1 e EncryptionScheme
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParseASN1 e PBEParameter
forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse
    parseParameter AlgorithmType EncryptionScheme
EncryptionSchemeType
Type_PBE_SHA1_DES_EDE3_CBC = PBEParameter -> EncryptionScheme
PBE_SHA1_DES_EDE3_CBC (PBEParameter -> EncryptionScheme)
-> ParseASN1 e PBEParameter -> ParseASN1 e EncryptionScheme
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParseASN1 e PBEParameter
forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse
    parseParameter AlgorithmType EncryptionScheme
EncryptionSchemeType
Type_PBE_SHA1_DES_EDE2_CBC = PBEParameter -> EncryptionScheme
PBE_SHA1_DES_EDE2_CBC (PBEParameter -> EncryptionScheme)
-> ParseASN1 e PBEParameter -> ParseASN1 e EncryptionScheme
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParseASN1 e PBEParameter
forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse
    parseParameter AlgorithmType EncryptionScheme
EncryptionSchemeType
Type_PBE_SHA1_RC2_128      = PBEParameter -> EncryptionScheme
PBE_SHA1_RC2_128 (PBEParameter -> EncryptionScheme)
-> ParseASN1 e PBEParameter -> ParseASN1 e EncryptionScheme
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParseASN1 e PBEParameter
forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse
    parseParameter AlgorithmType EncryptionScheme
EncryptionSchemeType
Type_PBE_SHA1_RC2_40       = PBEParameter -> EncryptionScheme
PBE_SHA1_RC2_40 (PBEParameter -> EncryptionScheme)
-> ParseASN1 e PBEParameter -> ParseASN1 e EncryptionScheme
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParseASN1 e PBEParameter
forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse

instance ASN1Elem e => ProduceASN1Object e EncryptionScheme where
    asn1s :: EncryptionScheme -> ASN1Stream e
asn1s = ASN1ConstructionType -> EncryptionScheme -> ASN1Stream e
forall e param.
(ASN1Elem e, AlgorithmId param, OIDable (AlgorithmType param)) =>
ASN1ConstructionType -> param -> ASN1Stream e
algorithmASN1S ASN1ConstructionType
Sequence

instance Monoid e => ParseASN1Object e EncryptionScheme where
    parse :: ParseASN1 e EncryptionScheme
parse = ASN1ConstructionType -> ParseASN1 e EncryptionScheme
forall e param.
(Monoid e, AlgorithmId param, OIDNameable (AlgorithmType param)) =>
ASN1ConstructionType -> ParseASN1 e param
parseAlgorithm ASN1ConstructionType
Sequence


-- High-level API

-- | 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
    { PKCS5 -> EncryptionScheme
encryptionAlgorithm :: EncryptionScheme -- ^ Scheme used to encrypt content
    , PKCS5 -> ByteString
encryptedData       :: EncryptedContent -- ^ Encrypted content
    }
    deriving (Int -> PKCS5 -> ShowS
[PKCS5] -> ShowS
PKCS5 -> String
(Int -> PKCS5 -> ShowS)
-> (PKCS5 -> String) -> ([PKCS5] -> ShowS) -> Show PKCS5
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PKCS5 -> ShowS
showsPrec :: Int -> PKCS5 -> ShowS
$cshow :: PKCS5 -> String
show :: PKCS5 -> String
$cshowList :: [PKCS5] -> ShowS
showList :: [PKCS5] -> ShowS
Show,PKCS5 -> PKCS5 -> Bool
(PKCS5 -> PKCS5 -> Bool) -> (PKCS5 -> PKCS5 -> Bool) -> Eq PKCS5
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PKCS5 -> PKCS5 -> Bool
== :: PKCS5 -> PKCS5 -> Bool
$c/= :: PKCS5 -> PKCS5 -> Bool
/= :: PKCS5 -> PKCS5 -> Bool
Eq)

instance ASN1Elem e => ProduceASN1Object e PKCS5 where
    asn1s :: PKCS5 -> ASN1Stream e
asn1s PKCS5{ByteString
EncryptionScheme
encryptionAlgorithm :: PKCS5 -> EncryptionScheme
encryptedData :: PKCS5 -> ByteString
encryptionAlgorithm :: EncryptionScheme
encryptedData :: ByteString
..} = ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container ASN1ConstructionType
Sequence (ASN1Stream e
alg ASN1Stream e -> ASN1Stream e -> ASN1Stream e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
bs)
      where alg :: ASN1Stream e
alg = EncryptionScheme -> ASN1Stream e
forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
asn1s EncryptionScheme
encryptionAlgorithm
            bs :: ASN1Stream e
bs  = ByteString -> ASN1Stream e
forall e. ASN1Elem e => ByteString -> ASN1Stream e
gOctetString ByteString
encryptedData

instance Monoid e => ParseASN1Object e PKCS5 where
    parse :: ParseASN1 e PKCS5
parse = ASN1ConstructionType -> ParseASN1 e PKCS5 -> ParseASN1 e PKCS5
forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
onNextContainer ASN1ConstructionType
Sequence (ParseASN1 e PKCS5 -> ParseASN1 e PKCS5)
-> ParseASN1 e PKCS5 -> ParseASN1 e PKCS5
forall a b. (a -> b) -> a -> b
$ do
        EncryptionScheme
alg <- ParseASN1 e EncryptionScheme
forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse
        OctetString ByteString
bs <- ParseASN1 e ASN1
forall e. Monoid e => ParseASN1 e ASN1
getNext
        PKCS5 -> ParseASN1 e PKCS5
forall a. a -> ParseASN1 e a
forall (m :: * -> *) a. Monad m => a -> m a
return PKCS5 { encryptionAlgorithm :: EncryptionScheme
encryptionAlgorithm = EncryptionScheme
alg, encryptedData :: ByteString
encryptedData = ByteString
bs }

instance ASN1Object PKCS5 where
    toASN1 :: PKCS5 -> ASN1S
toASN1   = PKCS5 -> ASN1S
forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
asn1s
    fromASN1 :: [ASN1] -> Either String (PKCS5, [ASN1])
fromASN1 = ParseASN1 () PKCS5 -> [ASN1] -> Either String (PKCS5, [ASN1])
forall a. ParseASN1 () a -> [ASN1] -> Either String (a, [ASN1])
runParseASN1State ParseASN1 () PKCS5
forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse

-- | Encrypt a bytestring with the specified encryption scheme and password.
encrypt :: EncryptionScheme -> ProtectionPassword -> ByteString -> Either StoreError PKCS5
encrypt :: EncryptionScheme
-> ProtectionPassword -> ByteString -> Either StoreError PKCS5
encrypt EncryptionScheme
alg ProtectionPassword
pwd ByteString
bs = ByteString -> PKCS5
build (ByteString -> PKCS5)
-> Either StoreError ByteString -> Either StoreError PKCS5
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> EncryptionScheme
-> ByteString -> ProtectionPassword -> Either StoreError ByteString
pbEncrypt EncryptionScheme
alg ByteString
bs ProtectionPassword
pwd
  where
    build :: ByteString -> PKCS5
build ByteString
ed = ByteString
ed ByteString -> PKCS5 -> PKCS5
forall a b. a -> b -> b
`seq` PKCS5 { encryptionAlgorithm :: EncryptionScheme
encryptionAlgorithm = EncryptionScheme
alg, encryptedData :: ByteString
encryptedData = ByteString
ed }

-- | Decrypt the PKCS #5 content with the specified password.
decrypt :: PKCS5 -> ProtectionPassword -> Either StoreError ByteString
decrypt :: PKCS5 -> ProtectionPassword -> Either StoreError ByteString
decrypt PKCS5
obj = EncryptionScheme
-> ByteString -> ProtectionPassword -> Either StoreError ByteString
pbDecrypt (PKCS5 -> EncryptionScheme
encryptionAlgorithm PKCS5
obj) (PKCS5 -> ByteString
encryptedData PKCS5
obj)


-- Encryption Schemes

-- | Encrypt a bytestring with the specified encryption scheme and password.
pbEncrypt :: EncryptionScheme -> ByteString -> ProtectionPassword
          -> Either StoreError EncryptedContent
pbEncrypt :: EncryptionScheme
-> ByteString -> ProtectionPassword -> Either StoreError ByteString
pbEncrypt (PBES2 PBES2Parameter
p)                 = (Key
 -> ContentEncryptionParams
 -> ByteString
 -> Either StoreError ByteString)
-> PBES2Parameter
-> ByteString
-> ProtectionPassword
-> Either StoreError ByteString
forall result.
(Key -> ContentEncryptionParams -> ByteString -> result)
-> PBES2Parameter -> ByteString -> ProtectionPassword -> result
pbes2  Key
-> ContentEncryptionParams
-> ByteString
-> Either StoreError ByteString
forall cek ba.
(ByteArray cek, ByteArray ba) =>
cek -> ContentEncryptionParams -> ba -> Either StoreError ba
contentEncrypt PBES2Parameter
p
pbEncrypt (PBE_MD5_DES_CBC PBEParameter
p)       = (StoreError -> Either StoreError ByteString)
-> (Key
    -> ContentEncryptionParams
    -> ByteString
    -> Either StoreError ByteString)
-> DigestProxy MD5
-> ContentEncryptionCipher DES
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> Either StoreError ByteString
forall hash cipher result.
(HashAlgorithm hash, BlockCipher cipher) =>
(StoreError -> result)
-> (Key -> ContentEncryptionParams -> ByteString -> result)
-> DigestProxy hash
-> ContentEncryptionCipher cipher
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> result
pkcs5  StoreError -> Either StoreError ByteString
forall a b. a -> Either a b
Left Key
-> ContentEncryptionParams
-> ByteString
-> Either StoreError ByteString
forall cek ba.
(ByteArray cek, ByteArray ba) =>
cek -> ContentEncryptionParams -> ba -> Either StoreError ba
contentEncrypt DigestProxy MD5
MD5  ContentEncryptionCipher DES
DES PBEParameter
p
pbEncrypt (PBE_SHA1_DES_CBC PBEParameter
p)      = (StoreError -> Either StoreError ByteString)
-> (Key
    -> ContentEncryptionParams
    -> ByteString
    -> Either StoreError ByteString)
-> DigestProxy SHA1
-> ContentEncryptionCipher DES
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> Either StoreError ByteString
forall hash cipher result.
(HashAlgorithm hash, BlockCipher cipher) =>
(StoreError -> result)
-> (Key -> ContentEncryptionParams -> ByteString -> result)
-> DigestProxy hash
-> ContentEncryptionCipher cipher
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> result
pkcs5  StoreError -> Either StoreError ByteString
forall a b. a -> Either a b
Left Key
-> ContentEncryptionParams
-> ByteString
-> Either StoreError ByteString
forall cek ba.
(ByteArray cek, ByteArray ba) =>
cek -> ContentEncryptionParams -> ba -> Either StoreError ba
contentEncrypt DigestProxy SHA1
SHA1 ContentEncryptionCipher DES
DES PBEParameter
p
pbEncrypt (PBE_SHA1_RC4_128 PBEParameter
p)      = (StoreError -> Either StoreError ByteString)
-> (Key -> ByteString -> Either StoreError ByteString)
-> DigestProxy SHA1
-> Int
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> Either StoreError ByteString
forall hash result.
HashAlgorithm hash =>
(StoreError -> result)
-> (Key -> ByteString -> result)
-> DigestProxy hash
-> Int
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> result
pkcs12stream StoreError -> Either StoreError ByteString
forall a b. a -> Either a b
Left Key -> ByteString -> Either StoreError ByteString
forall key ba.
(ByteArrayAccess key, ByteArray ba) =>
key -> ba -> Either StoreError ba
rc4Combine DigestProxy SHA1
SHA1 Int
16 PBEParameter
p
pbEncrypt (PBE_SHA1_RC4_40 PBEParameter
p)       = (StoreError -> Either StoreError ByteString)
-> (Key -> ByteString -> Either StoreError ByteString)
-> DigestProxy SHA1
-> Int
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> Either StoreError ByteString
forall hash result.
HashAlgorithm hash =>
(StoreError -> result)
-> (Key -> ByteString -> result)
-> DigestProxy hash
-> Int
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> result
pkcs12stream StoreError -> Either StoreError ByteString
forall a b. a -> Either a b
Left Key -> ByteString -> Either StoreError ByteString
forall key ba.
(ByteArrayAccess key, ByteArray ba) =>
key -> ba -> Either StoreError ba
rc4Combine DigestProxy SHA1
SHA1 Int
5 PBEParameter
p
pbEncrypt (PBE_SHA1_DES_EDE3_CBC PBEParameter
p) = (StoreError -> Either StoreError ByteString)
-> (Key
    -> ContentEncryptionParams
    -> ByteString
    -> Either StoreError ByteString)
-> DigestProxy SHA1
-> ContentEncryptionCipher DES_EDE3
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> Either StoreError ByteString
forall hash cipher result.
(HashAlgorithm hash, BlockCipher cipher) =>
(StoreError -> result)
-> (Key -> ContentEncryptionParams -> ByteString -> result)
-> DigestProxy hash
-> ContentEncryptionCipher cipher
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> result
pkcs12 StoreError -> Either StoreError ByteString
forall a b. a -> Either a b
Left Key
-> ContentEncryptionParams
-> ByteString
-> Either StoreError ByteString
forall cek ba.
(ByteArray cek, ByteArray ba) =>
cek -> ContentEncryptionParams -> ba -> Either StoreError ba
contentEncrypt DigestProxy SHA1
SHA1 ContentEncryptionCipher DES_EDE3
DES_EDE3 PBEParameter
p
pbEncrypt (PBE_SHA1_DES_EDE2_CBC PBEParameter
p) = (StoreError -> Either StoreError ByteString)
-> (Key
    -> ContentEncryptionParams
    -> ByteString
    -> Either StoreError ByteString)
-> DigestProxy SHA1
-> ContentEncryptionCipher DES_EDE2
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> Either StoreError ByteString
forall hash cipher result.
(HashAlgorithm hash, BlockCipher cipher) =>
(StoreError -> result)
-> (Key -> ContentEncryptionParams -> ByteString -> result)
-> DigestProxy hash
-> ContentEncryptionCipher cipher
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> result
pkcs12 StoreError -> Either StoreError ByteString
forall a b. a -> Either a b
Left Key
-> ContentEncryptionParams
-> ByteString
-> Either StoreError ByteString
forall cek ba.
(ByteArray cek, ByteArray ba) =>
cek -> ContentEncryptionParams -> ba -> Either StoreError ba
contentEncrypt DigestProxy SHA1
SHA1 ContentEncryptionCipher DES_EDE2
DES_EDE2 PBEParameter
p
pbEncrypt (PBE_SHA1_RC2_128 PBEParameter
p)      = (StoreError -> Either StoreError ByteString)
-> (Key
    -> ContentEncryptionParams
    -> ByteString
    -> Either StoreError ByteString)
-> DigestProxy SHA1
-> Int
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> Either StoreError ByteString
forall hash result.
HashAlgorithm hash =>
(StoreError -> result)
-> (Key -> ContentEncryptionParams -> ByteString -> result)
-> DigestProxy hash
-> Int
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> result
pkcs12rc2 StoreError -> Either StoreError ByteString
forall a b. a -> Either a b
Left Key
-> ContentEncryptionParams
-> ByteString
-> Either StoreError ByteString
forall cek ba.
(ByteArray cek, ByteArray ba) =>
cek -> ContentEncryptionParams -> ba -> Either StoreError ba
contentEncrypt DigestProxy SHA1
SHA1 Int
128 PBEParameter
p
pbEncrypt (PBE_SHA1_RC2_40 PBEParameter
p)       = (StoreError -> Either StoreError ByteString)
-> (Key
    -> ContentEncryptionParams
    -> ByteString
    -> Either StoreError ByteString)
-> DigestProxy SHA1
-> Int
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> Either StoreError ByteString
forall hash result.
HashAlgorithm hash =>
(StoreError -> result)
-> (Key -> ContentEncryptionParams -> ByteString -> result)
-> DigestProxy hash
-> Int
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> result
pkcs12rc2 StoreError -> Either StoreError ByteString
forall a b. a -> Either a b
Left Key
-> ContentEncryptionParams
-> ByteString
-> Either StoreError ByteString
forall cek ba.
(ByteArray cek, ByteArray ba) =>
cek -> ContentEncryptionParams -> ba -> Either StoreError ba
contentEncrypt DigestProxy SHA1
SHA1 Int
40 PBEParameter
p

-- | Decrypt an encrypted bytestring with the specified encryption scheme and
-- password.
pbDecrypt :: EncryptionScheme -> EncryptedContent -> ProtectionPassword -> Either StoreError ByteString
pbDecrypt :: EncryptionScheme
-> ByteString -> ProtectionPassword -> Either StoreError ByteString
pbDecrypt (PBES2 PBES2Parameter
p)                 = (Key
 -> ContentEncryptionParams
 -> ByteString
 -> Either StoreError ByteString)
-> PBES2Parameter
-> ByteString
-> ProtectionPassword
-> Either StoreError ByteString
forall result.
(Key -> ContentEncryptionParams -> ByteString -> result)
-> PBES2Parameter -> ByteString -> ProtectionPassword -> result
pbes2  Key
-> ContentEncryptionParams
-> ByteString
-> Either StoreError ByteString
forall cek ba.
(ByteArray cek, ByteArray ba) =>
cek -> ContentEncryptionParams -> ba -> Either StoreError ba
contentDecrypt PBES2Parameter
p
pbDecrypt (PBE_MD5_DES_CBC PBEParameter
p)       = (StoreError -> Either StoreError ByteString)
-> (Key
    -> ContentEncryptionParams
    -> ByteString
    -> Either StoreError ByteString)
-> DigestProxy MD5
-> ContentEncryptionCipher DES
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> Either StoreError ByteString
forall hash cipher result.
(HashAlgorithm hash, BlockCipher cipher) =>
(StoreError -> result)
-> (Key -> ContentEncryptionParams -> ByteString -> result)
-> DigestProxy hash
-> ContentEncryptionCipher cipher
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> result
pkcs5  StoreError -> Either StoreError ByteString
forall a b. a -> Either a b
Left Key
-> ContentEncryptionParams
-> ByteString
-> Either StoreError ByteString
forall cek ba.
(ByteArray cek, ByteArray ba) =>
cek -> ContentEncryptionParams -> ba -> Either StoreError ba
contentDecrypt DigestProxy MD5
MD5  ContentEncryptionCipher DES
DES PBEParameter
p
pbDecrypt (PBE_SHA1_DES_CBC PBEParameter
p)      = (StoreError -> Either StoreError ByteString)
-> (Key
    -> ContentEncryptionParams
    -> ByteString
    -> Either StoreError ByteString)
-> DigestProxy SHA1
-> ContentEncryptionCipher DES
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> Either StoreError ByteString
forall hash cipher result.
(HashAlgorithm hash, BlockCipher cipher) =>
(StoreError -> result)
-> (Key -> ContentEncryptionParams -> ByteString -> result)
-> DigestProxy hash
-> ContentEncryptionCipher cipher
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> result
pkcs5  StoreError -> Either StoreError ByteString
forall a b. a -> Either a b
Left Key
-> ContentEncryptionParams
-> ByteString
-> Either StoreError ByteString
forall cek ba.
(ByteArray cek, ByteArray ba) =>
cek -> ContentEncryptionParams -> ba -> Either StoreError ba
contentDecrypt DigestProxy SHA1
SHA1 ContentEncryptionCipher DES
DES PBEParameter
p
pbDecrypt (PBE_SHA1_RC4_128 PBEParameter
p)      = (StoreError -> Either StoreError ByteString)
-> (Key -> ByteString -> Either StoreError ByteString)
-> DigestProxy SHA1
-> Int
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> Either StoreError ByteString
forall hash result.
HashAlgorithm hash =>
(StoreError -> result)
-> (Key -> ByteString -> result)
-> DigestProxy hash
-> Int
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> result
pkcs12stream StoreError -> Either StoreError ByteString
forall a b. a -> Either a b
Left Key -> ByteString -> Either StoreError ByteString
forall key ba.
(ByteArrayAccess key, ByteArray ba) =>
key -> ba -> Either StoreError ba
rc4Combine DigestProxy SHA1
SHA1 Int
16 PBEParameter
p
pbDecrypt (PBE_SHA1_RC4_40 PBEParameter
p)       = (StoreError -> Either StoreError ByteString)
-> (Key -> ByteString -> Either StoreError ByteString)
-> DigestProxy SHA1
-> Int
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> Either StoreError ByteString
forall hash result.
HashAlgorithm hash =>
(StoreError -> result)
-> (Key -> ByteString -> result)
-> DigestProxy hash
-> Int
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> result
pkcs12stream StoreError -> Either StoreError ByteString
forall a b. a -> Either a b
Left Key -> ByteString -> Either StoreError ByteString
forall key ba.
(ByteArrayAccess key, ByteArray ba) =>
key -> ba -> Either StoreError ba
rc4Combine DigestProxy SHA1
SHA1 Int
5 PBEParameter
p
pbDecrypt (PBE_SHA1_DES_EDE3_CBC PBEParameter
p) = (StoreError -> Either StoreError ByteString)
-> (Key
    -> ContentEncryptionParams
    -> ByteString
    -> Either StoreError ByteString)
-> DigestProxy SHA1
-> ContentEncryptionCipher DES_EDE3
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> Either StoreError ByteString
forall hash cipher result.
(HashAlgorithm hash, BlockCipher cipher) =>
(StoreError -> result)
-> (Key -> ContentEncryptionParams -> ByteString -> result)
-> DigestProxy hash
-> ContentEncryptionCipher cipher
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> result
pkcs12 StoreError -> Either StoreError ByteString
forall a b. a -> Either a b
Left Key
-> ContentEncryptionParams
-> ByteString
-> Either StoreError ByteString
forall cek ba.
(ByteArray cek, ByteArray ba) =>
cek -> ContentEncryptionParams -> ba -> Either StoreError ba
contentDecrypt DigestProxy SHA1
SHA1 ContentEncryptionCipher DES_EDE3
DES_EDE3 PBEParameter
p
pbDecrypt (PBE_SHA1_DES_EDE2_CBC PBEParameter
p) = (StoreError -> Either StoreError ByteString)
-> (Key
    -> ContentEncryptionParams
    -> ByteString
    -> Either StoreError ByteString)
-> DigestProxy SHA1
-> ContentEncryptionCipher DES_EDE2
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> Either StoreError ByteString
forall hash cipher result.
(HashAlgorithm hash, BlockCipher cipher) =>
(StoreError -> result)
-> (Key -> ContentEncryptionParams -> ByteString -> result)
-> DigestProxy hash
-> ContentEncryptionCipher cipher
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> result
pkcs12 StoreError -> Either StoreError ByteString
forall a b. a -> Either a b
Left Key
-> ContentEncryptionParams
-> ByteString
-> Either StoreError ByteString
forall cek ba.
(ByteArray cek, ByteArray ba) =>
cek -> ContentEncryptionParams -> ba -> Either StoreError ba
contentDecrypt DigestProxy SHA1
SHA1 ContentEncryptionCipher DES_EDE2
DES_EDE2 PBEParameter
p
pbDecrypt (PBE_SHA1_RC2_128 PBEParameter
p)      = (StoreError -> Either StoreError ByteString)
-> (Key
    -> ContentEncryptionParams
    -> ByteString
    -> Either StoreError ByteString)
-> DigestProxy SHA1
-> Int
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> Either StoreError ByteString
forall hash result.
HashAlgorithm hash =>
(StoreError -> result)
-> (Key -> ContentEncryptionParams -> ByteString -> result)
-> DigestProxy hash
-> Int
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> result
pkcs12rc2 StoreError -> Either StoreError ByteString
forall a b. a -> Either a b
Left Key
-> ContentEncryptionParams
-> ByteString
-> Either StoreError ByteString
forall cek ba.
(ByteArray cek, ByteArray ba) =>
cek -> ContentEncryptionParams -> ba -> Either StoreError ba
contentDecrypt DigestProxy SHA1
SHA1 Int
128 PBEParameter
p
pbDecrypt (PBE_SHA1_RC2_40 PBEParameter
p)       = (StoreError -> Either StoreError ByteString)
-> (Key
    -> ContentEncryptionParams
    -> ByteString
    -> Either StoreError ByteString)
-> DigestProxy SHA1
-> Int
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> Either StoreError ByteString
forall hash result.
HashAlgorithm hash =>
(StoreError -> result)
-> (Key -> ContentEncryptionParams -> ByteString -> result)
-> DigestProxy hash
-> Int
-> PBEParameter
-> ByteString
-> ProtectionPassword
-> result
pkcs12rc2 StoreError -> Either StoreError ByteString
forall a b. a -> Either a b
Left Key
-> ContentEncryptionParams
-> ByteString
-> Either StoreError ByteString
forall cek ba.
(ByteArray cek, ByteArray ba) =>
cek -> ContentEncryptionParams -> ba -> Either StoreError ba
contentDecrypt DigestProxy SHA1
SHA1 Int
40 PBEParameter
p

pbes2 :: (Key -> ContentEncryptionParams -> ByteString -> result)
      -> PBES2Parameter -> ByteString -> ProtectionPassword -> result
pbes2 :: forall result.
(Key -> ContentEncryptionParams -> ByteString -> result)
-> PBES2Parameter -> ByteString -> ProtectionPassword -> result
pbes2 Key -> ContentEncryptionParams -> ByteString -> result
encdec PBES2Parameter{KeyDerivationFunc
ContentEncryptionParams
pbes2KDF :: PBES2Parameter -> KeyDerivationFunc
pbes2EScheme :: PBES2Parameter -> ContentEncryptionParams
pbes2KDF :: KeyDerivationFunc
pbes2EScheme :: ContentEncryptionParams
..} ByteString
bs ProtectionPassword
pwd = Key -> ContentEncryptionParams -> ByteString -> result
encdec Key
key ContentEncryptionParams
pbes2EScheme ByteString
bs
  where key :: Key
key = KeyDerivationFunc -> Int -> ByteString -> Key
forall password out.
(ByteArrayAccess password, ByteArray out) =>
KeyDerivationFunc -> Int -> password -> out
kdfDerive KeyDerivationFunc
pbes2KDF Int
len (ProtectionPassword -> ByteString
fromProtectionPassword ProtectionPassword
pwd) :: Key
        len :: Int
len = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe (ContentEncryptionParams -> Int
forall params. HasKeySize params => params -> Int
getMaximumKeySize ContentEncryptionParams
pbes2EScheme) (KeyDerivationFunc -> Maybe Int
kdfKeyLength KeyDerivationFunc
pbes2KDF)