    -- |
    -- Module      : Crypto.Store.CMS.Enveloped
    -- License     : BSD-style
    -- Maintainer  : Olivier Chéron <olivier.cheron@gmail.com>
    -- Stability   : experimental
    -- Portability : unknown
    --
    --
    {-# LANGUAGE FlexibleInstances #-}
    {-# LANGUAGE MultiParamTypeClasses #-}
    {-# LANGUAGE RecordWildCards #-}
    module Crypto.Store.CMS.Enveloped
        ( EncryptedKey
        , UserKeyingMaterial
        , RecipientInfo(..)
        , EnvelopedData(..)
        , ProducerOfRI
        , ConsumerOfRI
        -- * Key Transport recipients
        , KTRecipientInfo(..)
        , RecipientIdentifier(..)
        , IssuerAndSerialNumber(..)
        , forKeyTransRecipient
        , withRecipientKeyTrans
        -- * Key Agreement recipients
        , KARecipientInfo(..)
        , OriginatorIdentifierOrKey(..)
        , OriginatorPublicKey
        , RecipientEncryptedKey(..)
        , KeyAgreeRecipientIdentifier(..)
        , forKeyAgreeRecipient
        , withRecipientKeyAgree
        -- * Key Encryption Key recipients
        , KeyEncryptionKey
        , KEKRecipientInfo(..)
        , KeyIdentifier(..)
        , OtherKeyAttribute(..)
        , forKeyRecipient
        , withRecipientKey
        -- * Password recipients
        , Password
        , PasswordRecipientInfo(..)
        , forPasswordRecipient
        , withRecipientPassword
        ) where

    import Control.Applicative
    import Control.Monad

    import Data.ASN1.BitArray
    import Data.ASN1.Types
    import Data.ByteString (ByteString)
    import Data.List (find)
    import Data.Maybe (fromMaybe)
    import Data.X509

    import Time.Types

    import Crypto.Random (MonadRandom)

    import Crypto.Store.ASN1.Generate
    import Crypto.Store.ASN1.Parse
    import Crypto.Store.CMS.Algorithms
    import Crypto.Store.CMS.Attribute
    import Crypto.Store.CMS.Encrypted
    import Crypto.Store.CMS.OriginatorInfo
    import Crypto.Store.CMS.Type
    import Crypto.Store.CMS.Util
    import Crypto.Store.Error

    -- | Encrypted key.
    type EncryptedKey = ByteString

    -- | User keying material.
    type UserKeyingMaterial = ByteString

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

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

    -- | Union type related to identification of the recipient.
    data RecipientIdentifier
        = RecipientIASN IssuerAndSerialNumber  -- ^ Issuer and Serial Number
        | RecipientSKI  ByteString             -- ^ Subject Key Identifier
        deriving (Int -> RecipientIdentifier -> ShowS
    [RecipientIdentifier] -> ShowS
    RecipientIdentifier -> String
    (Int -> RecipientIdentifier -> ShowS)
    -> (RecipientIdentifier -> String)
    -> ([RecipientIdentifier] -> ShowS)
    -> Show RecipientIdentifier
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> RecipientIdentifier -> ShowS
    showsPrec :: Int -> RecipientIdentifier -> ShowS
    $cshow :: RecipientIdentifier -> String
    show :: RecipientIdentifier -> String
    $cshowList :: [RecipientIdentifier] -> ShowS
    showList :: [RecipientIdentifier] -> ShowS
    Show,RecipientIdentifier -> RecipientIdentifier -> Bool
    (RecipientIdentifier -> RecipientIdentifier -> Bool)
    -> (RecipientIdentifier -> RecipientIdentifier -> Bool)
    -> Eq RecipientIdentifier
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: RecipientIdentifier -> RecipientIdentifier -> Bool
    == :: RecipientIdentifier -> RecipientIdentifier -> Bool
    $c/= :: RecipientIdentifier -> RecipientIdentifier -> Bool
    /= :: RecipientIdentifier -> RecipientIdentifier -> Bool
    Eq)

    instance ASN1Elem e => ProduceASN1Object e RecipientIdentifier where
        asn1s :: RecipientIdentifier -> ASN1Stream e
    asn1s (RecipientIASN IssuerAndSerialNumber
    iasn) = IssuerAndSerialNumber -> ASN1Stream e
    forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
    asn1s IssuerAndSerialNumber
    iasn
        asn1s (RecipientSKI  ByteString
    ski)  = ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    asn1Container (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    0)
                                        (ByteString -> ASN1Stream e
    forall e. ASN1Elem e => ByteString -> ASN1Stream e
    gOctetString ByteString
    ski)

    instance Monoid e => ParseASN1Object e RecipientIdentifier where
        parse :: ParseASN1 e RecipientIdentifier
    parse = ParseASN1 e RecipientIdentifier
    parseIASN ParseASN1 e RecipientIdentifier
    -> ParseASN1 e RecipientIdentifier
    -> ParseASN1 e RecipientIdentifier
    forall a. ParseASN1 e a -> ParseASN1 e a -> ParseASN1 e a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> ParseASN1 e RecipientIdentifier
    parseSKI
          where parseIASN :: ParseASN1 e RecipientIdentifier
    parseIASN = IssuerAndSerialNumber -> RecipientIdentifier
    RecipientIASN (IssuerAndSerialNumber -> RecipientIdentifier)
    -> ParseASN1 e IssuerAndSerialNumber
    -> ParseASN1 e RecipientIdentifier
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ParseASN1 e IssuerAndSerialNumber
    forall e obj. ParseASN1Object e obj => ParseASN1 e obj
    parse
                parseSKI :: ParseASN1 e RecipientIdentifier
    parseSKI  = ByteString -> RecipientIdentifier
    RecipientSKI  (ByteString -> RecipientIdentifier)
    -> ParseASN1 e ByteString -> ParseASN1 e RecipientIdentifier
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>
                    ASN1ConstructionType
    -> ParseASN1 e ByteString -> ParseASN1 e ByteString
    forall e a.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
    onNextContainer (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    0) ParseASN1 e ByteString
    forall e. Monoid e => ParseASN1 e ByteString
    parseOctetStringPrim

    getKTVersion :: RecipientIdentifier -> Integer
    getKTVersion :: RecipientIdentifier -> Integer
    getKTVersion (RecipientIASN IssuerAndSerialNumber
    _) = Integer
    0
    getKTVersion (RecipientSKI ByteString
    _)  = Integer
    2

    -- | Identification of a certificate using the issuer DN and serial number.
    data IssuerAndSerialNumber = IssuerAndSerialNumber
        { IssuerAndSerialNumber -> DistinguishedName
    iasnIssuer :: DistinguishedName
          -- ^ Distinguished name of the certificate issuer
        , IssuerAndSerialNumber -> Integer
    iasnSerial :: Integer
          -- ^ Issuer-specific certificate serial number
        }
        deriving (Int -> IssuerAndSerialNumber -> ShowS
    [IssuerAndSerialNumber] -> ShowS
    IssuerAndSerialNumber -> String
    (Int -> IssuerAndSerialNumber -> ShowS)
    -> (IssuerAndSerialNumber -> String)
    -> ([IssuerAndSerialNumber] -> ShowS)
    -> Show IssuerAndSerialNumber
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> IssuerAndSerialNumber -> ShowS
    showsPrec :: Int -> IssuerAndSerialNumber -> ShowS
    $cshow :: IssuerAndSerialNumber -> String
    show :: IssuerAndSerialNumber -> String
    $cshowList :: [IssuerAndSerialNumber] -> ShowS
    showList :: [IssuerAndSerialNumber] -> ShowS
    Show,IssuerAndSerialNumber -> IssuerAndSerialNumber -> Bool
    (IssuerAndSerialNumber -> IssuerAndSerialNumber -> Bool)
    -> (IssuerAndSerialNumber -> IssuerAndSerialNumber -> Bool)
    -> Eq IssuerAndSerialNumber
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: IssuerAndSerialNumber -> IssuerAndSerialNumber -> Bool
    == :: IssuerAndSerialNumber -> IssuerAndSerialNumber -> Bool
    $c/= :: IssuerAndSerialNumber -> IssuerAndSerialNumber -> Bool
    /= :: IssuerAndSerialNumber -> IssuerAndSerialNumber -> Bool
    Eq)

    instance ASN1Elem e => ProduceASN1Object e IssuerAndSerialNumber where
        asn1s :: IssuerAndSerialNumber -> ASN1Stream e
    asn1s IssuerAndSerialNumber{Integer
    DistinguishedName
    iasnIssuer :: IssuerAndSerialNumber -> DistinguishedName
    iasnSerial :: IssuerAndSerialNumber -> Integer
    iasnIssuer :: DistinguishedName
    iasnSerial :: Integer
    ..} =
            ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    asn1Container ASN1ConstructionType
    Sequence (DistinguishedName -> ASN1Stream e
    forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
    asn1s DistinguishedName
    iasnIssuer ASN1Stream e -> ASN1Stream e -> ASN1Stream e
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Integer -> ASN1Stream e
    forall e. ASN1Elem e => Integer -> ASN1Stream e
    gIntVal Integer
    iasnSerial)

    instance Monoid e => ParseASN1Object e IssuerAndSerialNumber where
        parse :: ParseASN1 e IssuerAndSerialNumber
    parse = ASN1ConstructionType
    -> ParseASN1 e IssuerAndSerialNumber
    -> ParseASN1 e IssuerAndSerialNumber
    forall e a.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
    onNextContainer ASN1ConstructionType
    Sequence (ParseASN1 e IssuerAndSerialNumber
     -> ParseASN1 e IssuerAndSerialNumber)
    -> ParseASN1 e IssuerAndSerialNumber
    -> ParseASN1 e IssuerAndSerialNumber
    forall a b. (a -> b) -> a -> b
    $ do
            DistinguishedName
    i <- ParseASN1 e DistinguishedName
    forall e obj. ParseASN1Object e obj => ParseASN1 e obj
    parse
            IntVal Integer
    s <- ParseASN1 e ASN1
    forall e. Monoid e => ParseASN1 e ASN1
    getNext
            IssuerAndSerialNumber -> ParseASN1 e IssuerAndSerialNumber
    forall a. a -> ParseASN1 e a
    forall (m :: * -> *) a. Monad m => a -> m a
    return IssuerAndSerialNumber { iasnIssuer :: DistinguishedName
    iasnIssuer = DistinguishedName
    i
                                         , iasnSerial :: Integer
    iasnSerial = Integer
    s
                                         }

    idEcPublicKey :: OID
    idEcPublicKey :: OID
    idEcPublicKey = [Integer
    1,Integer
    2,Integer
    840,Integer
    10045,Integer
    2,Integer
    1]

    -- | Originator public key used for key-agreement.  Contrary to 'PubKey' the
    -- domain parameters are not used and may be left empty.
    data OriginatorPublicKey = OriginatorPublicKeyEC [ASN1] BitArray
        deriving (Int -> OriginatorPublicKey -> ShowS
    [OriginatorPublicKey] -> ShowS
    OriginatorPublicKey -> String
    (Int -> OriginatorPublicKey -> ShowS)
    -> (OriginatorPublicKey -> String)
    -> ([OriginatorPublicKey] -> ShowS)
    -> Show OriginatorPublicKey
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> OriginatorPublicKey -> ShowS
    showsPrec :: Int -> OriginatorPublicKey -> ShowS
    $cshow :: OriginatorPublicKey -> String
    show :: OriginatorPublicKey -> String
    $cshowList :: [OriginatorPublicKey] -> ShowS
    showList :: [OriginatorPublicKey] -> ShowS
    Show,OriginatorPublicKey -> OriginatorPublicKey -> Bool
    (OriginatorPublicKey -> OriginatorPublicKey -> Bool)
    -> (OriginatorPublicKey -> OriginatorPublicKey -> Bool)
    -> Eq OriginatorPublicKey
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: OriginatorPublicKey -> OriginatorPublicKey -> Bool
    == :: OriginatorPublicKey -> OriginatorPublicKey -> Bool
    $c/= :: OriginatorPublicKey -> OriginatorPublicKey -> Bool
    /= :: OriginatorPublicKey -> OriginatorPublicKey -> Bool
    Eq)

    originatorPublicKeyASN1S :: ASN1Elem e
                             => ASN1ConstructionType
                             -> OriginatorPublicKey
                             -> ASN1Stream e
    originatorPublicKeyASN1S :: forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> OriginatorPublicKey -> ASN1Stream e
    originatorPublicKeyASN1S ASN1ConstructionType
    ty (OriginatorPublicKeyEC [ASN1]
    asn1 BitArray
    ba) =
        ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    asn1Container ASN1ConstructionType
    ty (ASN1Stream e
    alg ASN1Stream e -> ASN1Stream e -> ASN1Stream e
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . BitArray -> ASN1Stream e
    forall e. ASN1Elem e => BitArray -> ASN1Stream e
    gBitString BitArray
    ba)
      where
        alg :: ASN1Stream e
    alg = ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    asn1Container ASN1ConstructionType
    Sequence (OID -> ASN1Stream e
    forall e. ASN1Elem e => OID -> ASN1Stream e
    gOID OID
    idEcPublicKey ASN1Stream e -> ASN1Stream e -> ASN1Stream e
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [ASN1] -> ASN1Stream e
    forall e. ASN1Elem e => [ASN1] -> ASN1Stream e
    gMany [ASN1]
    asn1)

    parseOriginatorPublicKey :: Monoid e
                             => ASN1ConstructionType
                             -> ParseASN1 e OriginatorPublicKey
    parseOriginatorPublicKey :: forall e.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e OriginatorPublicKey
    parseOriginatorPublicKey ASN1ConstructionType
    ty =
        ASN1ConstructionType
    -> ParseASN1 e OriginatorPublicKey
    -> ParseASN1 e OriginatorPublicKey
    forall e a.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
    onNextContainer ASN1ConstructionType
    ty (ParseASN1 e OriginatorPublicKey
     -> ParseASN1 e OriginatorPublicKey)
    -> ParseASN1 e OriginatorPublicKey
    -> ParseASN1 e OriginatorPublicKey
    forall a b. (a -> b) -> a -> b
    $ do
            [ASN1]
    asn1 <- ASN1ConstructionType -> ParseASN1 e [ASN1] -> ParseASN1 e [ASN1]
    forall e a.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
    onNextContainer ASN1ConstructionType
    Sequence (ParseASN1 e [ASN1] -> ParseASN1 e [ASN1])
    -> ParseASN1 e [ASN1] -> ParseASN1 e [ASN1]
    forall a b. (a -> b) -> a -> b
    $ do
                        OID OID
    oid <- ParseASN1 e ASN1
    forall e. Monoid e => ParseASN1 e ASN1
    getNext
                        Bool -> ParseASN1 e ()
    forall (f :: * -> *). Alternative f => Bool -> f ()
    guard (OID
    oid OID -> OID -> Bool
    forall a. Eq a => a -> a -> Bool
    == OID
    idEcPublicKey)
                        ParseASN1 e ASN1 -> ParseASN1 e [ASN1]
    forall e a. ParseASN1 e a -> ParseASN1 e [a]
    getMany ParseASN1 e ASN1
    forall e. Monoid e => ParseASN1 e ASN1
    getNext
            BitString BitArray
    ba <- ParseASN1 e ASN1
    forall e. Monoid e => ParseASN1 e ASN1
    getNext
            OriginatorPublicKey -> ParseASN1 e OriginatorPublicKey
    forall a. a -> ParseASN1 e a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([ASN1] -> BitArray -> OriginatorPublicKey
    OriginatorPublicKeyEC [ASN1]
    asn1 BitArray
    ba)

    -- | Union type related to identification of the originator.
    data OriginatorIdentifierOrKey
        = OriginatorIASN IssuerAndSerialNumber  -- ^ Issuer and Serial Number
        | OriginatorSKI  ByteString             -- ^ Subject Key Identifier
        | OriginatorPublic OriginatorPublicKey  -- ^ Anonymous public key
        deriving (Int -> OriginatorIdentifierOrKey -> ShowS
    [OriginatorIdentifierOrKey] -> ShowS
    OriginatorIdentifierOrKey -> String
    (Int -> OriginatorIdentifierOrKey -> ShowS)
    -> (OriginatorIdentifierOrKey -> String)
    -> ([OriginatorIdentifierOrKey] -> ShowS)
    -> Show OriginatorIdentifierOrKey
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> OriginatorIdentifierOrKey -> ShowS
    showsPrec :: Int -> OriginatorIdentifierOrKey -> ShowS
    $cshow :: OriginatorIdentifierOrKey -> String
    show :: OriginatorIdentifierOrKey -> String
    $cshowList :: [OriginatorIdentifierOrKey] -> ShowS
    showList :: [OriginatorIdentifierOrKey] -> ShowS
    Show,OriginatorIdentifierOrKey -> OriginatorIdentifierOrKey -> Bool
    (OriginatorIdentifierOrKey -> OriginatorIdentifierOrKey -> Bool)
    -> (OriginatorIdentifierOrKey -> OriginatorIdentifierOrKey -> Bool)
    -> Eq OriginatorIdentifierOrKey
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: OriginatorIdentifierOrKey -> OriginatorIdentifierOrKey -> Bool
    == :: OriginatorIdentifierOrKey -> OriginatorIdentifierOrKey -> Bool
    $c/= :: OriginatorIdentifierOrKey -> OriginatorIdentifierOrKey -> Bool
    /= :: OriginatorIdentifierOrKey -> OriginatorIdentifierOrKey -> Bool
    Eq)

    instance ASN1Elem e => ProduceASN1Object e OriginatorIdentifierOrKey where
        asn1s :: OriginatorIdentifierOrKey -> ASN1Stream e
    asn1s (OriginatorIASN IssuerAndSerialNumber
    iasn)   = IssuerAndSerialNumber -> ASN1Stream e
    forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
    asn1s IssuerAndSerialNumber
    iasn
        asn1s (OriginatorSKI  ByteString
    ski)    = ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    asn1Container (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    0)
                                           (ByteString -> ASN1Stream e
    forall e. ASN1Elem e => ByteString -> ASN1Stream e
    gOctetString ByteString
    ski)
        asn1s (OriginatorPublic OriginatorPublicKey
    pub)  =
            ASN1ConstructionType -> OriginatorPublicKey -> ASN1Stream e
    forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> OriginatorPublicKey -> ASN1Stream e
    originatorPublicKeyASN1S (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    1) OriginatorPublicKey
    pub

    instance Monoid e => ParseASN1Object e OriginatorIdentifierOrKey where
        parse :: ParseASN1 e OriginatorIdentifierOrKey
    parse = ParseASN1 e OriginatorIdentifierOrKey
    parseIASN ParseASN1 e OriginatorIdentifierOrKey
    -> ParseASN1 e OriginatorIdentifierOrKey
    -> ParseASN1 e OriginatorIdentifierOrKey
    forall a. ParseASN1 e a -> ParseASN1 e a -> ParseASN1 e a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> ParseASN1 e OriginatorIdentifierOrKey
    parseSKI ParseASN1 e OriginatorIdentifierOrKey
    -> ParseASN1 e OriginatorIdentifierOrKey
    -> ParseASN1 e OriginatorIdentifierOrKey
    forall a. ParseASN1 e a -> ParseASN1 e a -> ParseASN1 e a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> ParseASN1 e OriginatorIdentifierOrKey
    parsePublic
          where parseIASN :: ParseASN1 e OriginatorIdentifierOrKey
    parseIASN = IssuerAndSerialNumber -> OriginatorIdentifierOrKey
    OriginatorIASN (IssuerAndSerialNumber -> OriginatorIdentifierOrKey)
    -> ParseASN1 e IssuerAndSerialNumber
    -> ParseASN1 e OriginatorIdentifierOrKey
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ParseASN1 e IssuerAndSerialNumber
    forall e obj. ParseASN1Object e obj => ParseASN1 e obj
    parse
                parseSKI :: ParseASN1 e OriginatorIdentifierOrKey
    parseSKI  = ByteString -> OriginatorIdentifierOrKey
    OriginatorSKI  (ByteString -> OriginatorIdentifierOrKey)
    -> ParseASN1 e ByteString -> ParseASN1 e OriginatorIdentifierOrKey
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>
                    ASN1ConstructionType
    -> ParseASN1 e ByteString -> ParseASN1 e ByteString
    forall e a.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
    onNextContainer (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    0) ParseASN1 e ByteString
    forall e. Monoid e => ParseASN1 e ByteString
    parseOctetStringPrim
                parsePublic :: ParseASN1 e OriginatorIdentifierOrKey
    parsePublic  = OriginatorPublicKey -> OriginatorIdentifierOrKey
    OriginatorPublic (OriginatorPublicKey -> OriginatorIdentifierOrKey)
    -> ParseASN1 e OriginatorPublicKey
    -> ParseASN1 e OriginatorIdentifierOrKey
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>
                    ASN1ConstructionType -> ParseASN1 e OriginatorPublicKey
    forall e.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e OriginatorPublicKey
    parseOriginatorPublicKey (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    1)

    -- | Union type related to identification of a key-agreement recipient.
    data KeyAgreeRecipientIdentifier
        = KeyAgreeRecipientIASN IssuerAndSerialNumber  -- ^ Issuer and Serial Number
        | KeyAgreeRecipientKI   KeyIdentifier          -- ^ Key identifier
        deriving (Int -> KeyAgreeRecipientIdentifier -> ShowS
    [KeyAgreeRecipientIdentifier] -> ShowS
    KeyAgreeRecipientIdentifier -> String
    (Int -> KeyAgreeRecipientIdentifier -> ShowS)
    -> (KeyAgreeRecipientIdentifier -> String)
    -> ([KeyAgreeRecipientIdentifier] -> ShowS)
    -> Show KeyAgreeRecipientIdentifier
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> KeyAgreeRecipientIdentifier -> ShowS
    showsPrec :: Int -> KeyAgreeRecipientIdentifier -> ShowS
    $cshow :: KeyAgreeRecipientIdentifier -> String
    show :: KeyAgreeRecipientIdentifier -> String
    $cshowList :: [KeyAgreeRecipientIdentifier] -> ShowS
    showList :: [KeyAgreeRecipientIdentifier] -> ShowS
    Show,KeyAgreeRecipientIdentifier -> KeyAgreeRecipientIdentifier -> Bool
    (KeyAgreeRecipientIdentifier
     -> KeyAgreeRecipientIdentifier -> Bool)
    -> (KeyAgreeRecipientIdentifier
        -> KeyAgreeRecipientIdentifier -> Bool)
    -> Eq KeyAgreeRecipientIdentifier
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: KeyAgreeRecipientIdentifier -> KeyAgreeRecipientIdentifier -> Bool
    == :: KeyAgreeRecipientIdentifier -> KeyAgreeRecipientIdentifier -> Bool
    $c/= :: KeyAgreeRecipientIdentifier -> KeyAgreeRecipientIdentifier -> Bool
    /= :: KeyAgreeRecipientIdentifier -> KeyAgreeRecipientIdentifier -> Bool
    Eq)

    instance ASN1Elem e => ProduceASN1Object e KeyAgreeRecipientIdentifier where
        asn1s :: KeyAgreeRecipientIdentifier -> ASN1Stream e
    asn1s (KeyAgreeRecipientIASN IssuerAndSerialNumber
    iasn) = IssuerAndSerialNumber -> ASN1Stream e
    forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
    asn1s IssuerAndSerialNumber
    iasn
        asn1s (KeyAgreeRecipientKI   KeyIdentifier
    ki)   = ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    asn1Container (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    0)
                                                (KeyIdentifier -> ASN1Stream e
    forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
    asn1s KeyIdentifier
    ki)

    instance Monoid e => ParseASN1Object e KeyAgreeRecipientIdentifier where
        parse :: ParseASN1 e KeyAgreeRecipientIdentifier
    parse = ParseASN1 e KeyAgreeRecipientIdentifier
    parseIASN ParseASN1 e KeyAgreeRecipientIdentifier
    -> ParseASN1 e KeyAgreeRecipientIdentifier
    -> ParseASN1 e KeyAgreeRecipientIdentifier
    forall a. ParseASN1 e a -> ParseASN1 e a -> ParseASN1 e a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> ParseASN1 e KeyAgreeRecipientIdentifier
    parseKI
          where parseIASN :: ParseASN1 e KeyAgreeRecipientIdentifier
    parseIASN = IssuerAndSerialNumber -> KeyAgreeRecipientIdentifier
    KeyAgreeRecipientIASN (IssuerAndSerialNumber -> KeyAgreeRecipientIdentifier)
    -> ParseASN1 e IssuerAndSerialNumber
    -> ParseASN1 e KeyAgreeRecipientIdentifier
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ParseASN1 e IssuerAndSerialNumber
    forall e obj. ParseASN1Object e obj => ParseASN1 e obj
    parse
                parseKI :: ParseASN1 e KeyAgreeRecipientIdentifier
    parseKI   = KeyIdentifier -> KeyAgreeRecipientIdentifier
    KeyAgreeRecipientKI   (KeyIdentifier -> KeyAgreeRecipientIdentifier)
    -> ParseASN1 e KeyIdentifier
    -> ParseASN1 e KeyAgreeRecipientIdentifier
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>
                    ASN1ConstructionType
    -> ParseASN1 e KeyIdentifier -> ParseASN1 e KeyIdentifier
    forall e a.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
    onNextContainer (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    0) ParseASN1 e KeyIdentifier
    forall e obj. ParseASN1Object e obj => ParseASN1 e obj
    parse

    -- | Encrypted key for a recipient in a key-agreement RI.
    data RecipientEncryptedKey = RecipientEncryptedKey
        { RecipientEncryptedKey -> KeyAgreeRecipientIdentifier
    rekRid :: KeyAgreeRecipientIdentifier -- ^ identifier of recipient
        , RecipientEncryptedKey -> ByteString
    rekEncryptedKey :: EncryptedKey       -- ^ encrypted content-encryption key
        }
        deriving (Int -> RecipientEncryptedKey -> ShowS
    [RecipientEncryptedKey] -> ShowS
    RecipientEncryptedKey -> String
    (Int -> RecipientEncryptedKey -> ShowS)
    -> (RecipientEncryptedKey -> String)
    -> ([RecipientEncryptedKey] -> ShowS)
    -> Show RecipientEncryptedKey
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> RecipientEncryptedKey -> ShowS
    showsPrec :: Int -> RecipientEncryptedKey -> ShowS
    $cshow :: RecipientEncryptedKey -> String
    show :: RecipientEncryptedKey -> String
    $cshowList :: [RecipientEncryptedKey] -> ShowS
    showList :: [RecipientEncryptedKey] -> ShowS
    Show,RecipientEncryptedKey -> RecipientEncryptedKey -> Bool
    (RecipientEncryptedKey -> RecipientEncryptedKey -> Bool)
    -> (RecipientEncryptedKey -> RecipientEncryptedKey -> Bool)
    -> Eq RecipientEncryptedKey
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: RecipientEncryptedKey -> RecipientEncryptedKey -> Bool
    == :: RecipientEncryptedKey -> RecipientEncryptedKey -> Bool
    $c/= :: RecipientEncryptedKey -> RecipientEncryptedKey -> Bool
    /= :: RecipientEncryptedKey -> RecipientEncryptedKey -> Bool
    Eq)

    instance ASN1Elem e => ProduceASN1Object e RecipientEncryptedKey where
        asn1s :: RecipientEncryptedKey -> ASN1Stream e
    asn1s RecipientEncryptedKey{ByteString
    KeyAgreeRecipientIdentifier
    rekRid :: RecipientEncryptedKey -> KeyAgreeRecipientIdentifier
    rekEncryptedKey :: RecipientEncryptedKey -> ByteString
    rekRid :: KeyAgreeRecipientIdentifier
    rekEncryptedKey :: ByteString
    ..} = ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    asn1Container ASN1ConstructionType
    Sequence (ASN1Stream e
    rid ASN1Stream e -> ASN1Stream e -> ASN1Stream e
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ASN1Stream e
    ek)
          where rid :: ASN1Stream e
    rid = KeyAgreeRecipientIdentifier -> ASN1Stream e
    forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
    asn1s KeyAgreeRecipientIdentifier
    rekRid
                ek :: ASN1Stream e
    ek  = ByteString -> ASN1Stream e
    forall e. ASN1Elem e => ByteString -> ASN1Stream e
    gOctetString ByteString
    rekEncryptedKey

    instance Monoid e => ParseASN1Object e RecipientEncryptedKey where
        parse :: ParseASN1 e RecipientEncryptedKey
    parse = ASN1ConstructionType
    -> ParseASN1 e RecipientEncryptedKey
    -> ParseASN1 e RecipientEncryptedKey
    forall e a.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
    onNextContainer ASN1ConstructionType
    Sequence (ParseASN1 e RecipientEncryptedKey
     -> ParseASN1 e RecipientEncryptedKey)
    -> ParseASN1 e RecipientEncryptedKey
    -> ParseASN1 e RecipientEncryptedKey
    forall a b. (a -> b) -> a -> b
    $ do
            KeyAgreeRecipientIdentifier
    rid <- ParseASN1 e KeyAgreeRecipientIdentifier
    forall e obj. ParseASN1Object e obj => ParseASN1 e obj
    parse
            OctetString ByteString
    ek <- ParseASN1 e ASN1
    forall e. Monoid e => ParseASN1 e ASN1
    getNext
            RecipientEncryptedKey -> ParseASN1 e RecipientEncryptedKey
    forall a. a -> ParseASN1 e a
    forall (m :: * -> *) a. Monad m => a -> m a
    return RecipientEncryptedKey { rekRid :: KeyAgreeRecipientIdentifier
    rekRid = KeyAgreeRecipientIdentifier
    rid, rekEncryptedKey :: ByteString
    rekEncryptedKey = ByteString
    ek }

    findRecipientEncryptedKey :: SignedCertificate
                              -> [RecipientEncryptedKey]
                              -> Maybe EncryptedKey
    findRecipientEncryptedKey :: SignedCertificate -> [RecipientEncryptedKey] -> Maybe ByteString
    findRecipientEncryptedKey SignedCertificate
    cert [RecipientEncryptedKey]
    list = RecipientEncryptedKey -> ByteString
    rekEncryptedKey (RecipientEncryptedKey -> ByteString)
    -> Maybe RecipientEncryptedKey -> Maybe ByteString
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (RecipientEncryptedKey -> Bool)
    -> [RecipientEncryptedKey] -> Maybe RecipientEncryptedKey
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
    find RecipientEncryptedKey -> Bool
    fn [RecipientEncryptedKey]
    list
      where
        c :: Certificate
    c = Signed Certificate -> Certificate
    forall a. (Show a, Eq a, ASN1Object a) => Signed a -> a
    signedObject (SignedCertificate -> Signed Certificate
    forall a. (Show a, Eq a, ASN1Object a) => SignedExact a -> Signed a
    getSigned SignedCertificate
    cert)
        matchIASN :: IssuerAndSerialNumber -> Bool
    matchIASN IssuerAndSerialNumber
    iasn =
            (IssuerAndSerialNumber -> DistinguishedName
    iasnIssuer IssuerAndSerialNumber
    iasn, IssuerAndSerialNumber -> Integer
    iasnSerial IssuerAndSerialNumber
    iasn) (DistinguishedName, Integer)
    -> (DistinguishedName, Integer) -> Bool
    forall a. Eq a => a -> a -> Bool
    == (Certificate -> DistinguishedName
    certIssuerDN Certificate
    c, Certificate -> Integer
    certSerial Certificate
    c)
        matchSKI :: ByteString -> Bool
    matchSKI ByteString
    ski   =
            case Extensions -> Maybe ExtSubjectKeyId
    forall a. Extension a => Extensions -> Maybe a
    extensionGet (Certificate -> Extensions
    certExtensions Certificate
    c) of
                Just (ExtSubjectKeyId ByteString
    idBs) -> ByteString
    idBs ByteString -> ByteString -> Bool
    forall a. Eq a => a -> a -> Bool
    == ByteString
    ski
                Maybe ExtSubjectKeyId
    Nothing                     -> Bool
    False
        fn :: RecipientEncryptedKey -> Bool
    fn RecipientEncryptedKey
    rek = case RecipientEncryptedKey -> KeyAgreeRecipientIdentifier
    rekRid RecipientEncryptedKey
    rek of
                     KeyAgreeRecipientIASN IssuerAndSerialNumber
    iasn -> IssuerAndSerialNumber -> Bool
    matchIASN IssuerAndSerialNumber
    iasn
                     KeyAgreeRecipientKI   KeyIdentifier
    ki   -> ByteString -> Bool
    matchSKI (KeyIdentifier -> ByteString
    keyIdentifier KeyIdentifier
    ki)

    -- | Additional information in a 'KeyIdentifier'.
    data OtherKeyAttribute = OtherKeyAttribute
        { OtherKeyAttribute -> OID
    keyAttrId :: OID    -- ^ attribute identifier
        , OtherKeyAttribute -> [ASN1]
    keyAttr   :: [ASN1] -- ^ attribute value
        }
        deriving (Int -> OtherKeyAttribute -> ShowS
    [OtherKeyAttribute] -> ShowS
    OtherKeyAttribute -> String
    (Int -> OtherKeyAttribute -> ShowS)
    -> (OtherKeyAttribute -> String)
    -> ([OtherKeyAttribute] -> ShowS)
    -> Show OtherKeyAttribute
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> OtherKeyAttribute -> ShowS
    showsPrec :: Int -> OtherKeyAttribute -> ShowS
    $cshow :: OtherKeyAttribute -> String
    show :: OtherKeyAttribute -> String
    $cshowList :: [OtherKeyAttribute] -> ShowS
    showList :: [OtherKeyAttribute] -> ShowS
    Show,OtherKeyAttribute -> OtherKeyAttribute -> Bool
    (OtherKeyAttribute -> OtherKeyAttribute -> Bool)
    -> (OtherKeyAttribute -> OtherKeyAttribute -> Bool)
    -> Eq OtherKeyAttribute
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: OtherKeyAttribute -> OtherKeyAttribute -> Bool
    == :: OtherKeyAttribute -> OtherKeyAttribute -> Bool
    $c/= :: OtherKeyAttribute -> OtherKeyAttribute -> Bool
    /= :: OtherKeyAttribute -> OtherKeyAttribute -> Bool
    Eq)

    instance ASN1Elem e => ProduceASN1Object e OtherKeyAttribute where
        asn1s :: OtherKeyAttribute -> ASN1Stream e
    asn1s OtherKeyAttribute{OID
    [ASN1]
    keyAttrId :: OtherKeyAttribute -> OID
    keyAttr :: OtherKeyAttribute -> [ASN1]
    keyAttrId :: OID
    keyAttr :: [ASN1]
    ..} = ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    asn1Container ASN1ConstructionType
    Sequence (ASN1Stream e
    attrId ASN1Stream e -> ASN1Stream e -> ASN1Stream e
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ASN1Stream e
    attr)
          where attrId :: ASN1Stream e
    attrId = OID -> ASN1Stream e
    forall e. ASN1Elem e => OID -> ASN1Stream e
    gOID OID
    keyAttrId
                attr :: ASN1Stream e
    attr   = [ASN1] -> ASN1Stream e
    forall e. ASN1Elem e => [ASN1] -> ASN1Stream e
    gMany [ASN1]
    keyAttr

    instance Monoid e => ParseASN1Object e OtherKeyAttribute where
        parse :: ParseASN1 e OtherKeyAttribute
    parse = ASN1ConstructionType
    -> ParseASN1 e OtherKeyAttribute -> ParseASN1 e OtherKeyAttribute
    forall e a.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
    onNextContainer ASN1ConstructionType
    Sequence (ParseASN1 e OtherKeyAttribute -> ParseASN1 e OtherKeyAttribute)
    -> ParseASN1 e OtherKeyAttribute -> ParseASN1 e OtherKeyAttribute
    forall a b. (a -> b) -> a -> b
    $ do
            OID OID
    attrId <- ParseASN1 e ASN1
    forall e. Monoid e => ParseASN1 e ASN1
    getNext
            [ASN1]
    attr <- ParseASN1 e ASN1 -> ParseASN1 e [ASN1]
    forall e a. ParseASN1 e a -> ParseASN1 e [a]
    getMany ParseASN1 e ASN1
    forall e. Monoid e => ParseASN1 e ASN1
    getNext
            OtherKeyAttribute -> ParseASN1 e OtherKeyAttribute
    forall a. a -> ParseASN1 e a
    forall (m :: * -> *) a. Monad m => a -> m a
    return OtherKeyAttribute { keyAttrId :: OID
    keyAttrId = OID
    attrId, keyAttr :: [ASN1]
    keyAttr = [ASN1]
    attr }

    -- | Key identifier and optional attributes.
    data KeyIdentifier = KeyIdentifier
        { KeyIdentifier -> ByteString
    keyIdentifier :: ByteString         -- ^ identifier of the key
        , KeyIdentifier -> Maybe DateTime
    keyDate :: Maybe DateTime           -- ^ optional timestamp
        , KeyIdentifier -> Maybe OtherKeyAttribute
    keyOther :: Maybe OtherKeyAttribute -- ^ optional information
        }
        deriving (Int -> KeyIdentifier -> ShowS
    [KeyIdentifier] -> ShowS
    KeyIdentifier -> String
    (Int -> KeyIdentifier -> ShowS)
    -> (KeyIdentifier -> String)
    -> ([KeyIdentifier] -> ShowS)
    -> Show KeyIdentifier
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> KeyIdentifier -> ShowS
    showsPrec :: Int -> KeyIdentifier -> ShowS
    $cshow :: KeyIdentifier -> String
    show :: KeyIdentifier -> String
    $cshowList :: [KeyIdentifier] -> ShowS
    showList :: [KeyIdentifier] -> ShowS
    Show,KeyIdentifier -> KeyIdentifier -> Bool
    (KeyIdentifier -> KeyIdentifier -> Bool)
    -> (KeyIdentifier -> KeyIdentifier -> Bool) -> Eq KeyIdentifier
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: KeyIdentifier -> KeyIdentifier -> Bool
    == :: KeyIdentifier -> KeyIdentifier -> Bool
    $c/= :: KeyIdentifier -> KeyIdentifier -> Bool
    /= :: KeyIdentifier -> KeyIdentifier -> Bool
    Eq)

    instance ASN1Elem e => ProduceASN1Object e KeyIdentifier where
        asn1s :: KeyIdentifier -> ASN1Stream e
    asn1s KeyIdentifier{Maybe DateTime
    Maybe OtherKeyAttribute
    ByteString
    keyIdentifier :: KeyIdentifier -> ByteString
    keyDate :: KeyIdentifier -> Maybe DateTime
    keyOther :: KeyIdentifier -> Maybe OtherKeyAttribute
    keyIdentifier :: ByteString
    keyDate :: Maybe DateTime
    keyOther :: Maybe OtherKeyAttribute
    ..} = ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    asn1Container ASN1ConstructionType
    Sequence (ASN1Stream e
    keyId ASN1Stream e -> ASN1Stream e -> ASN1Stream e
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ASN1Stream e
    date ASN1Stream e -> ASN1Stream e -> ASN1Stream e
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ASN1Stream e
    other)
          where
            keyId :: ASN1Stream e
    keyId = ByteString -> ASN1Stream e
    forall e. ASN1Elem e => ByteString -> ASN1Stream e
    gOctetString ByteString
    keyIdentifier
            date :: ASN1Stream e
    date  = Maybe DateTime -> (DateTime -> ASN1Stream e) -> ASN1Stream e
    forall a e. Maybe a -> (a -> ASN1Stream e) -> ASN1Stream e
    optASN1S Maybe DateTime
    keyDate ((DateTime -> ASN1Stream e) -> ASN1Stream e)
    -> (DateTime -> ASN1Stream e) -> ASN1Stream e
    forall a b. (a -> b) -> a -> b
    $ \DateTime
    v -> ASN1TimeType -> DateTime -> Maybe TimezoneOffset -> ASN1Stream e
    forall e.
    ASN1Elem e =>
    ASN1TimeType -> DateTime -> Maybe TimezoneOffset -> ASN1Stream e
    gASN1Time ASN1TimeType
    TimeGeneralized DateTime
    v Maybe TimezoneOffset
    forall a. Maybe a
    Nothing
            other :: ASN1Stream e
    other = Maybe OtherKeyAttribute
    -> (OtherKeyAttribute -> ASN1Stream e) -> ASN1Stream e
    forall a e. Maybe a -> (a -> ASN1Stream e) -> ASN1Stream e
    optASN1S Maybe OtherKeyAttribute
    keyOther OtherKeyAttribute -> ASN1Stream e
    forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
    asn1s

    instance Monoid e => ParseASN1Object e KeyIdentifier where
        parse :: ParseASN1 e KeyIdentifier
    parse = ASN1ConstructionType
    -> ParseASN1 e KeyIdentifier -> ParseASN1 e KeyIdentifier
    forall e a.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
    onNextContainer ASN1ConstructionType
    Sequence (ParseASN1 e KeyIdentifier -> ParseASN1 e KeyIdentifier)
    -> ParseASN1 e KeyIdentifier -> ParseASN1 e KeyIdentifier
    forall a b. (a -> b) -> a -> b
    $ do
            OctetString ByteString
    keyId <- ParseASN1 e ASN1
    forall e. Monoid e => ParseASN1 e ASN1
    getNext
            Maybe DateTime
    date <- (ASN1 -> Maybe DateTime) -> ParseASN1 e (Maybe DateTime)
    forall e a. Monoid e => (ASN1 -> Maybe a) -> ParseASN1 e (Maybe a)
    getNextMaybe ASN1 -> Maybe DateTime
    dateTimeOrNothing
            Bool
    b <- ParseASN1 e Bool
    forall e. ParseASN1 e Bool
    hasNext
            Maybe OtherKeyAttribute
    other <- if Bool
    b then OtherKeyAttribute -> Maybe OtherKeyAttribute
    forall a. a -> Maybe a
    Just (OtherKeyAttribute -> Maybe OtherKeyAttribute)
    -> ParseASN1 e OtherKeyAttribute
    -> ParseASN1 e (Maybe OtherKeyAttribute)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ParseASN1 e OtherKeyAttribute
    forall e obj. ParseASN1Object e obj => ParseASN1 e obj
    parse else Maybe OtherKeyAttribute -> ParseASN1 e (Maybe OtherKeyAttribute)
    forall a. a -> ParseASN1 e a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe OtherKeyAttribute
    forall a. Maybe a
    Nothing
            KeyIdentifier -> ParseASN1 e KeyIdentifier
    forall a. a -> ParseASN1 e a
    forall (m :: * -> *) a. Monad m => a -> m a
    return KeyIdentifier { keyIdentifier :: ByteString
    keyIdentifier = ByteString
    keyId
                                 , keyDate :: Maybe DateTime
    keyDate = Maybe DateTime
    date
                                 , keyOther :: Maybe OtherKeyAttribute
    keyOther = Maybe OtherKeyAttribute
    other
                                 }

    -- | Recipient using key transport.
    data KTRecipientInfo = KTRecipientInfo
        { KTRecipientInfo -> RecipientIdentifier
    ktRid :: RecipientIdentifier                 -- ^ identifier of recipient
        , KTRecipientInfo -> KeyTransportParams
    ktKeyTransportParams :: KeyTransportParams   -- ^ key transport algorithm
        , KTRecipientInfo -> ByteString
    ktEncryptedKey :: EncryptedKey               -- ^ encrypted content-encryption key
        }
        deriving (Int -> KTRecipientInfo -> ShowS
    [KTRecipientInfo] -> ShowS
    KTRecipientInfo -> String
    (Int -> KTRecipientInfo -> ShowS)
    -> (KTRecipientInfo -> String)
    -> ([KTRecipientInfo] -> ShowS)
    -> Show KTRecipientInfo
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> KTRecipientInfo -> ShowS
    showsPrec :: Int -> KTRecipientInfo -> ShowS
    $cshow :: KTRecipientInfo -> String
    show :: KTRecipientInfo -> String
    $cshowList :: [KTRecipientInfo] -> ShowS
    showList :: [KTRecipientInfo] -> ShowS
    Show,KTRecipientInfo -> KTRecipientInfo -> Bool
    (KTRecipientInfo -> KTRecipientInfo -> Bool)
    -> (KTRecipientInfo -> KTRecipientInfo -> Bool)
    -> Eq KTRecipientInfo
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: KTRecipientInfo -> KTRecipientInfo -> Bool
    == :: KTRecipientInfo -> KTRecipientInfo -> Bool
    $c/= :: KTRecipientInfo -> KTRecipientInfo -> Bool
    /= :: KTRecipientInfo -> KTRecipientInfo -> Bool
    Eq)

    -- | Recipient using key agreement.
    data KARecipientInfo = KARecipientInfo
        { KARecipientInfo -> OriginatorIdentifierOrKey
    kaOriginator :: OriginatorIdentifierOrKey           -- ^ identifier of orginator or anonymous key
        , KARecipientInfo -> Maybe ByteString
    kaUkm        :: Maybe UserKeyingMaterial            -- ^ user keying material
        , KARecipientInfo -> KeyAgreementParams
    kaKeyAgreementParams :: KeyAgreementParams          -- ^ key agreement algorithm
        , KARecipientInfo -> [RecipientEncryptedKey]
    kaRecipientEncryptedKeys :: [RecipientEncryptedKey] -- ^ encrypted content-encryption key for one or multiple recipients
        }
        deriving (Int -> KARecipientInfo -> ShowS
    [KARecipientInfo] -> ShowS
    KARecipientInfo -> String
    (Int -> KARecipientInfo -> ShowS)
    -> (KARecipientInfo -> String)
    -> ([KARecipientInfo] -> ShowS)
    -> Show KARecipientInfo
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> KARecipientInfo -> ShowS
    showsPrec :: Int -> KARecipientInfo -> ShowS
    $cshow :: KARecipientInfo -> String
    show :: KARecipientInfo -> String
    $cshowList :: [KARecipientInfo] -> ShowS
    showList :: [KARecipientInfo] -> ShowS
    Show,KARecipientInfo -> KARecipientInfo -> Bool
    (KARecipientInfo -> KARecipientInfo -> Bool)
    -> (KARecipientInfo -> KARecipientInfo -> Bool)
    -> Eq KARecipientInfo
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: KARecipientInfo -> KARecipientInfo -> Bool
    == :: KARecipientInfo -> KARecipientInfo -> Bool
    $c/= :: KARecipientInfo -> KARecipientInfo -> Bool
    /= :: KARecipientInfo -> KARecipientInfo -> Bool
    Eq)

    -- | Recipient using key encryption.
    data KEKRecipientInfo = KEKRecipientInfo
        { KEKRecipientInfo -> KeyIdentifier
    kekId :: KeyIdentifier                        -- ^ identifier of key encryption key
        , KEKRecipientInfo -> KeyEncryptionParams
    kekKeyEncryptionParams :: KeyEncryptionParams -- ^ key encryption algorithm
        , KEKRecipientInfo -> ByteString
    kekEncryptedKey :: EncryptedKey               -- ^ encrypted content-encryption key
        }
        deriving (Int -> KEKRecipientInfo -> ShowS
    [KEKRecipientInfo] -> ShowS
    KEKRecipientInfo -> String
    (Int -> KEKRecipientInfo -> ShowS)
    -> (KEKRecipientInfo -> String)
    -> ([KEKRecipientInfo] -> ShowS)
    -> Show KEKRecipientInfo
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> KEKRecipientInfo -> ShowS
    showsPrec :: Int -> KEKRecipientInfo -> ShowS
    $cshow :: KEKRecipientInfo -> String
    show :: KEKRecipientInfo -> String
    $cshowList :: [KEKRecipientInfo] -> ShowS
    showList :: [KEKRecipientInfo] -> ShowS
    Show,KEKRecipientInfo -> KEKRecipientInfo -> Bool
    (KEKRecipientInfo -> KEKRecipientInfo -> Bool)
    -> (KEKRecipientInfo -> KEKRecipientInfo -> Bool)
    -> Eq KEKRecipientInfo
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: KEKRecipientInfo -> KEKRecipientInfo -> Bool
    == :: KEKRecipientInfo -> KEKRecipientInfo -> Bool
    $c/= :: KEKRecipientInfo -> KEKRecipientInfo -> Bool
    /= :: KEKRecipientInfo -> KEKRecipientInfo -> Bool
    Eq)

    -- | Recipient using password-based protection.
    data PasswordRecipientInfo = PasswordRecipientInfo
        { PasswordRecipientInfo -> KeyDerivationFunc
    priKeyDerivationFunc :: KeyDerivationFunc     -- ^ function to derive key
        , PasswordRecipientInfo -> KeyEncryptionParams
    priKeyEncryptionParams :: KeyEncryptionParams -- ^ key encryption algorithm
        , PasswordRecipientInfo -> ByteString
    priEncryptedKey :: EncryptedKey               -- ^ encrypted content-encryption key
        }
        deriving (Int -> PasswordRecipientInfo -> ShowS
    [PasswordRecipientInfo] -> ShowS
    PasswordRecipientInfo -> String
    (Int -> PasswordRecipientInfo -> ShowS)
    -> (PasswordRecipientInfo -> String)
    -> ([PasswordRecipientInfo] -> ShowS)
    -> Show PasswordRecipientInfo
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> PasswordRecipientInfo -> ShowS
    showsPrec :: Int -> PasswordRecipientInfo -> ShowS
    $cshow :: PasswordRecipientInfo -> String
    show :: PasswordRecipientInfo -> String
    $cshowList :: [PasswordRecipientInfo] -> ShowS
    showList :: [PasswordRecipientInfo] -> ShowS
    Show,PasswordRecipientInfo -> PasswordRecipientInfo -> Bool
    (PasswordRecipientInfo -> PasswordRecipientInfo -> Bool)
    -> (PasswordRecipientInfo -> PasswordRecipientInfo -> Bool)
    -> Eq PasswordRecipientInfo
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: PasswordRecipientInfo -> PasswordRecipientInfo -> Bool
    == :: PasswordRecipientInfo -> PasswordRecipientInfo -> Bool
    $c/= :: PasswordRecipientInfo -> PasswordRecipientInfo -> Bool
    /= :: PasswordRecipientInfo -> PasswordRecipientInfo -> Bool
    Eq)

    -- | Information for a recipient of an 'EnvelopedData'.  An element contains
    -- the content-encryption key in encrypted form.
    data RecipientInfo = KTRI KTRecipientInfo
                         -- ^ Recipient using key transport
                       | KARI KARecipientInfo
                         -- ^ Recipient using key agreement
                       | KEKRI KEKRecipientInfo
                         -- ^ Recipient using key encryption
                       | PasswordRI PasswordRecipientInfo
                         -- ^ Recipient using password-based protection
        deriving (Int -> RecipientInfo -> ShowS
    [RecipientInfo] -> ShowS
    RecipientInfo -> String
    (Int -> RecipientInfo -> ShowS)
    -> (RecipientInfo -> String)
    -> ([RecipientInfo] -> ShowS)
    -> Show RecipientInfo
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> RecipientInfo -> ShowS
    showsPrec :: Int -> RecipientInfo -> ShowS
    $cshow :: RecipientInfo -> String
    show :: RecipientInfo -> String
    $cshowList :: [RecipientInfo] -> ShowS
    showList :: [RecipientInfo] -> ShowS
    Show,RecipientInfo -> RecipientInfo -> Bool
    (RecipientInfo -> RecipientInfo -> Bool)
    -> (RecipientInfo -> RecipientInfo -> Bool) -> Eq RecipientInfo
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: RecipientInfo -> RecipientInfo -> Bool
    == :: RecipientInfo -> RecipientInfo -> Bool
    $c/= :: RecipientInfo -> RecipientInfo -> Bool
    /= :: RecipientInfo -> RecipientInfo -> Bool
    Eq)

    instance ASN1Elem e => ProduceASN1Object e RecipientInfo where
        asn1s :: RecipientInfo -> ASN1Stream e
    asn1s (KTRI KTRecipientInfo{ByteString
    KeyTransportParams
    RecipientIdentifier
    ktRid :: KTRecipientInfo -> RecipientIdentifier
    ktKeyTransportParams :: KTRecipientInfo -> KeyTransportParams
    ktEncryptedKey :: KTRecipientInfo -> ByteString
    ktRid :: RecipientIdentifier
    ktKeyTransportParams :: KeyTransportParams
    ktEncryptedKey :: ByteString
    ..}) =
            ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    asn1Container ASN1ConstructionType
    Sequence (ASN1Stream e
    ver ASN1Stream e -> ASN1Stream e -> ASN1Stream e
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ASN1Stream e
    rid ASN1Stream e -> ASN1Stream e -> ASN1Stream e
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ASN1Stream e
    ktp ASN1Stream e -> ASN1Stream e -> ASN1Stream e
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ASN1Stream e
    ek)
          where
            ver :: ASN1Stream e
    ver = Integer -> ASN1Stream e
    forall e. ASN1Elem e => Integer -> ASN1Stream e
    gIntVal (RecipientIdentifier -> Integer
    getKTVersion RecipientIdentifier
    ktRid)
            rid :: ASN1Stream e
    rid = RecipientIdentifier -> ASN1Stream e
    forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
    asn1s RecipientIdentifier
    ktRid
            ktp :: ASN1Stream e
    ktp = ASN1ConstructionType -> KeyTransportParams -> ASN1Stream e
    forall e param.
    (ASN1Elem e, AlgorithmId param, OIDable (AlgorithmType param)) =>
    ASN1ConstructionType -> param -> ASN1Stream e
    algorithmASN1S ASN1ConstructionType
    Sequence KeyTransportParams
    ktKeyTransportParams
            ek :: ASN1Stream e
    ek  = ByteString -> ASN1Stream e
    forall e. ASN1Elem e => ByteString -> ASN1Stream e
    gOctetString ByteString
    ktEncryptedKey

        asn1s (KARI KARecipientInfo{[RecipientEncryptedKey]
    Maybe ByteString
    KeyAgreementParams
    OriginatorIdentifierOrKey
    kaOriginator :: KARecipientInfo -> OriginatorIdentifierOrKey
    kaUkm :: KARecipientInfo -> Maybe ByteString
    kaKeyAgreementParams :: KARecipientInfo -> KeyAgreementParams
    kaRecipientEncryptedKeys :: KARecipientInfo -> [RecipientEncryptedKey]
    kaOriginator :: OriginatorIdentifierOrKey
    kaUkm :: Maybe ByteString
    kaKeyAgreementParams :: KeyAgreementParams
    kaRecipientEncryptedKeys :: [RecipientEncryptedKey]
    ..}) =
            ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    asn1Container (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    1) (ASN1Stream e
    ver ASN1Stream e -> ASN1Stream e -> ASN1Stream e
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ASN1Stream e
    ori ASN1Stream e -> ASN1Stream e -> ASN1Stream e
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ASN1Stream e
    ukm ASN1Stream e -> ASN1Stream e -> ASN1Stream e
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ASN1Stream e
    kap ASN1Stream e -> ASN1Stream e -> ASN1Stream e
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ASN1Stream e
    reks)
          where
            ver :: ASN1Stream e
    ver  = Integer -> ASN1Stream e
    forall e. ASN1Elem e => Integer -> ASN1Stream e
    gIntVal Integer
    3
            ori :: ASN1Stream e
    ori  = ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    asn1Container (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    0) (OriginatorIdentifierOrKey -> ASN1Stream e
    forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
    asn1s OriginatorIdentifierOrKey
    kaOriginator)
            kap :: ASN1Stream e
    kap  = ASN1ConstructionType -> KeyAgreementParams -> ASN1Stream e
    forall e param.
    (ASN1Elem e, AlgorithmId param, OIDable (AlgorithmType param)) =>
    ASN1ConstructionType -> param -> ASN1Stream e
    algorithmASN1S ASN1ConstructionType
    Sequence KeyAgreementParams
    kaKeyAgreementParams
            reks :: ASN1Stream e
    reks = ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    asn1Container ASN1ConstructionType
    Sequence ([RecipientEncryptedKey] -> ASN1Stream e
    forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
    asn1s [RecipientEncryptedKey]
    kaRecipientEncryptedKeys)

            ukm :: ASN1Stream e
    ukm = case Maybe ByteString
    kaUkm of
                      Maybe ByteString
    Nothing -> ASN1Stream e
    forall a. a -> a
    id
                      Just ByteString
    bs -> ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    asn1Container (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    1) (ByteString -> ASN1Stream e
    forall e. ASN1Elem e => ByteString -> ASN1Stream e
    gOctetString ByteString
    bs)

        asn1s (KEKRI KEKRecipientInfo{ByteString
    KeyEncryptionParams
    KeyIdentifier
    kekId :: KEKRecipientInfo -> KeyIdentifier
    kekKeyEncryptionParams :: KEKRecipientInfo -> KeyEncryptionParams
    kekEncryptedKey :: KEKRecipientInfo -> ByteString
    kekId :: KeyIdentifier
    kekKeyEncryptionParams :: KeyEncryptionParams
    kekEncryptedKey :: ByteString
    ..}) =
            ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    asn1Container (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    2) (ASN1Stream e
    ver ASN1Stream e -> ASN1Stream e -> ASN1Stream e
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ASN1Stream e
    kid ASN1Stream e -> ASN1Stream e -> ASN1Stream e
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ASN1Stream e
    kep ASN1Stream e -> ASN1Stream e -> ASN1Stream e
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ASN1Stream e
    ek)
          where
            ver :: ASN1Stream e
    ver = Integer -> ASN1Stream e
    forall e. ASN1Elem e => Integer -> ASN1Stream e
    gIntVal Integer
    4
            kid :: ASN1Stream e
    kid = KeyIdentifier -> ASN1Stream e
    forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
    asn1s KeyIdentifier
    kekId
            kep :: ASN1Stream e
    kep = ASN1ConstructionType -> KeyEncryptionParams -> ASN1Stream e
    forall e param.
    (ASN1Elem e, AlgorithmId param, OIDable (AlgorithmType param)) =>
    ASN1ConstructionType -> param -> ASN1Stream e
    algorithmASN1S ASN1ConstructionType
    Sequence KeyEncryptionParams
    kekKeyEncryptionParams
            ek :: ASN1Stream e
    ek  = ByteString -> ASN1Stream e
    forall e. ASN1Elem e => ByteString -> ASN1Stream e
    gOctetString ByteString
    kekEncryptedKey

        asn1s (PasswordRI PasswordRecipientInfo{ByteString
    KeyEncryptionParams
    KeyDerivationFunc
    priKeyDerivationFunc :: PasswordRecipientInfo -> KeyDerivationFunc
    priKeyEncryptionParams :: PasswordRecipientInfo -> KeyEncryptionParams
    priEncryptedKey :: PasswordRecipientInfo -> ByteString
    priKeyDerivationFunc :: KeyDerivationFunc
    priKeyEncryptionParams :: KeyEncryptionParams
    priEncryptedKey :: ByteString
    ..}) =
            ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    asn1Container (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    3) (ASN1Stream e
    ver ASN1Stream e -> ASN1Stream e -> ASN1Stream e
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ASN1Stream e
    kdf ASN1Stream e -> ASN1Stream e -> ASN1Stream e
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ASN1Stream e
    kep ASN1Stream e -> ASN1Stream e -> ASN1Stream e
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ASN1Stream e
    ek)
          where
            ver :: ASN1Stream e
    ver = Integer -> ASN1Stream e
    forall e. ASN1Elem e => Integer -> ASN1Stream e
    gIntVal Integer
    0
            kdf :: ASN1Stream e
    kdf = ASN1ConstructionType -> KeyDerivationFunc -> ASN1Stream e
    forall e param.
    (ASN1Elem e, AlgorithmId param, OIDable (AlgorithmType param)) =>
    ASN1ConstructionType -> param -> ASN1Stream e
    algorithmASN1S (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    0) KeyDerivationFunc
    priKeyDerivationFunc
            kep :: ASN1Stream e
    kep = ASN1ConstructionType -> KeyEncryptionParams -> ASN1Stream e
    forall e param.
    (ASN1Elem e, AlgorithmId param, OIDable (AlgorithmType param)) =>
    ASN1ConstructionType -> param -> ASN1Stream e
    algorithmASN1S ASN1ConstructionType
    Sequence KeyEncryptionParams
    priKeyEncryptionParams
            ek :: ASN1Stream e
    ek  = ByteString -> ASN1Stream e
    forall e. ASN1Elem e => ByteString -> ASN1Stream e
    gOctetString ByteString
    priEncryptedKey

    instance Monoid e => ParseASN1Object e RecipientInfo where
        parse :: ParseASN1 e RecipientInfo
    parse = do
            Maybe RecipientInfo
    c <- ASN1ConstructionType
    -> ParseASN1 e RecipientInfo -> ParseASN1 e (Maybe RecipientInfo)
    forall e a.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e (Maybe a)
    onNextContainerMaybe ASN1ConstructionType
    Sequence ParseASN1 e RecipientInfo
    parseKT
                 ParseASN1 e (Maybe RecipientInfo)
    -> ParseASN1 e (Maybe RecipientInfo)
    -> ParseASN1 e (Maybe RecipientInfo)
    forall (m :: * -> *) a.
    Monad m =>
    m (Maybe a) -> m (Maybe a) -> m (Maybe a)
    `orElse` ASN1ConstructionType
    -> ParseASN1 e RecipientInfo -> ParseASN1 e (Maybe RecipientInfo)
    forall e a.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e (Maybe a)
    onNextContainerMaybe (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    1) ParseASN1 e RecipientInfo
    parseKA
                 ParseASN1 e (Maybe RecipientInfo)
    -> ParseASN1 e (Maybe RecipientInfo)
    -> ParseASN1 e (Maybe RecipientInfo)
    forall (m :: * -> *) a.
    Monad m =>
    m (Maybe a) -> m (Maybe a) -> m (Maybe a)
    `orElse` ASN1ConstructionType
    -> ParseASN1 e RecipientInfo -> ParseASN1 e (Maybe RecipientInfo)
    forall e a.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e (Maybe a)
    onNextContainerMaybe (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    2) ParseASN1 e RecipientInfo
    parseKEK
                 ParseASN1 e (Maybe RecipientInfo)
    -> ParseASN1 e (Maybe RecipientInfo)
    -> ParseASN1 e (Maybe RecipientInfo)
    forall (m :: * -> *) a.
    Monad m =>
    m (Maybe a) -> m (Maybe a) -> m (Maybe a)
    `orElse` ASN1ConstructionType
    -> ParseASN1 e RecipientInfo -> ParseASN1 e (Maybe RecipientInfo)
    forall e a.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e (Maybe a)
    onNextContainerMaybe (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    3) ParseASN1 e RecipientInfo
    parsePassword
            case Maybe RecipientInfo
    c of
                Just RecipientInfo
    val -> RecipientInfo -> ParseASN1 e RecipientInfo
    forall a. a -> ParseASN1 e a
    forall (m :: * -> *) a. Monad m => a -> m a
    return RecipientInfo
    val
                Maybe RecipientInfo
    Nothing  -> String -> ParseASN1 e RecipientInfo
    forall e a. String -> ParseASN1 e a
    throwParseError String
    "RecipientInfo: unable to parse"
          where
            parseKT :: ParseASN1 e RecipientInfo
    parseKT = KTRecipientInfo -> RecipientInfo
    KTRI (KTRecipientInfo -> RecipientInfo)
    -> ParseASN1 e KTRecipientInfo -> ParseASN1 e RecipientInfo
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> do
                IntVal Integer
    v <- ParseASN1 e ASN1
    forall e. Monoid e => ParseASN1 e ASN1
    getNext
                Bool -> ParseASN1 e () -> ParseASN1 e ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Integer
    v Integer -> OID -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `notElem` [Integer
    0, Integer
    2]) (ParseASN1 e () -> ParseASN1 e ())
    -> ParseASN1 e () -> ParseASN1 e ()
    forall a b. (a -> b) -> a -> b
    $
                    String -> ParseASN1 e ()
    forall e a. String -> ParseASN1 e a
    throwParseError (String
    "RecipientInfo: parsed invalid KT version: " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Integer -> String
    forall a. Show a => a -> String
    show Integer
    v)
                RecipientIdentifier
    rid <- ParseASN1 e RecipientIdentifier
    forall e obj. ParseASN1Object e obj => ParseASN1 e obj
    parse
                KeyTransportParams
    ktp <- ASN1ConstructionType -> ParseASN1 e KeyTransportParams
    forall e param.
    (Monoid e, AlgorithmId param, OIDNameable (AlgorithmType param)) =>
    ASN1ConstructionType -> ParseASN1 e param
    parseAlgorithm ASN1ConstructionType
    Sequence
                OctetString ByteString
    ek <- ParseASN1 e ASN1
    forall e. Monoid e => ParseASN1 e ASN1
    getNext
                KTRecipientInfo -> ParseASN1 e KTRecipientInfo
    forall a. a -> ParseASN1 e a
    forall (m :: * -> *) a. Monad m => a -> m a
    return KTRecipientInfo { ktRid :: RecipientIdentifier
    ktRid = RecipientIdentifier
    rid
                                       , ktKeyTransportParams :: KeyTransportParams
    ktKeyTransportParams = KeyTransportParams
    ktp
                                       , ktEncryptedKey :: ByteString
    ktEncryptedKey = ByteString
    ek
                                       }

            parseKA :: ParseASN1 e RecipientInfo
    parseKA = KARecipientInfo -> RecipientInfo
    KARI (KARecipientInfo -> RecipientInfo)
    -> ParseASN1 e KARecipientInfo -> ParseASN1 e RecipientInfo
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> do
                IntVal Integer
    3 <- ParseASN1 e ASN1
    forall e. Monoid e => ParseASN1 e ASN1
    getNext
                OriginatorIdentifierOrKey
    ori <- ASN1ConstructionType
    -> ParseASN1 e OriginatorIdentifierOrKey
    -> ParseASN1 e OriginatorIdentifierOrKey
    forall e a.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
    onNextContainer (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    0) ParseASN1 e OriginatorIdentifierOrKey
    forall e obj. ParseASN1Object e obj => ParseASN1 e obj
    parse
                Maybe ByteString
    ukm <- ASN1ConstructionType
    -> ParseASN1 e ByteString -> ParseASN1 e (Maybe ByteString)
    forall e a.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e (Maybe a)
    onNextContainerMaybe (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    1) (ParseASN1 e ByteString -> ParseASN1 e (Maybe ByteString))
    -> ParseASN1 e ByteString -> ParseASN1 e (Maybe ByteString)
    forall a b. (a -> b) -> a -> b
    $
                           do { OctetString ByteString
    bs <- ParseASN1 e ASN1
    forall e. Monoid e => ParseASN1 e ASN1
    getNext; ByteString -> ParseASN1 e ByteString
    forall a. a -> ParseASN1 e a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ByteString
    bs }
                KeyAgreementParams
    kap <- ASN1ConstructionType -> ParseASN1 e KeyAgreementParams
    forall e param.
    (Monoid e, AlgorithmId param, OIDNameable (AlgorithmType param)) =>
    ASN1ConstructionType -> ParseASN1 e param
    parseAlgorithm ASN1ConstructionType
    Sequence
                [RecipientEncryptedKey]
    reks <- ASN1ConstructionType
    -> ParseASN1 e [RecipientEncryptedKey]
    -> ParseASN1 e [RecipientEncryptedKey]
    forall e a.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
    onNextContainer ASN1ConstructionType
    Sequence ParseASN1 e [RecipientEncryptedKey]
    forall e obj. ParseASN1Object e obj => ParseASN1 e obj
    parse
                KARecipientInfo -> ParseASN1 e KARecipientInfo
    forall a. a -> ParseASN1 e a
    forall (m :: * -> *) a. Monad m => a -> m a
    return KARecipientInfo { kaOriginator :: OriginatorIdentifierOrKey
    kaOriginator = OriginatorIdentifierOrKey
    ori
                                       , kaUkm :: Maybe ByteString
    kaUkm = Maybe ByteString
    ukm
                                       , kaKeyAgreementParams :: KeyAgreementParams
    kaKeyAgreementParams = KeyAgreementParams
    kap
                                       , kaRecipientEncryptedKeys :: [RecipientEncryptedKey]
    kaRecipientEncryptedKeys = [RecipientEncryptedKey]
    reks
                                       }

            parseKEK :: ParseASN1 e RecipientInfo
    parseKEK = KEKRecipientInfo -> RecipientInfo
    KEKRI (KEKRecipientInfo -> RecipientInfo)
    -> ParseASN1 e KEKRecipientInfo -> ParseASN1 e RecipientInfo
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> do
                IntVal Integer
    4 <- ParseASN1 e ASN1
    forall e. Monoid e => ParseASN1 e ASN1
    getNext
                KeyIdentifier
    kid <- ParseASN1 e KeyIdentifier
    forall e obj. ParseASN1Object e obj => ParseASN1 e obj
    parse
                KeyEncryptionParams
    kep <- ASN1ConstructionType -> ParseASN1 e KeyEncryptionParams
    forall e param.
    (Monoid e, AlgorithmId param, OIDNameable (AlgorithmType param)) =>
    ASN1ConstructionType -> ParseASN1 e param
    parseAlgorithm ASN1ConstructionType
    Sequence
                OctetString ByteString
    ek <- ParseASN1 e ASN1
    forall e. Monoid e => ParseASN1 e ASN1
    getNext
                KEKRecipientInfo -> ParseASN1 e KEKRecipientInfo
    forall a. a -> ParseASN1 e a
    forall (m :: * -> *) a. Monad m => a -> m a
    return KEKRecipientInfo { kekId :: KeyIdentifier
    kekId = KeyIdentifier
    kid
                                        , kekKeyEncryptionParams :: KeyEncryptionParams
    kekKeyEncryptionParams = KeyEncryptionParams
    kep
                                        , kekEncryptedKey :: ByteString
    kekEncryptedKey = ByteString
    ek
                                        }

            parsePassword :: ParseASN1 e RecipientInfo
    parsePassword = PasswordRecipientInfo -> RecipientInfo
    PasswordRI (PasswordRecipientInfo -> RecipientInfo)
    -> ParseASN1 e PasswordRecipientInfo -> ParseASN1 e RecipientInfo
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> do
                IntVal Integer
    0 <- ParseASN1 e ASN1
    forall e. Monoid e => ParseASN1 e ASN1
    getNext
                KeyDerivationFunc
    kdf <- ASN1ConstructionType -> ParseASN1 e KeyDerivationFunc
    forall e param.
    (Monoid e, AlgorithmId param, OIDNameable (AlgorithmType param)) =>
    ASN1ConstructionType -> ParseASN1 e param
    parseAlgorithm (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    0)
                KeyEncryptionParams
    kep <- ASN1ConstructionType -> ParseASN1 e KeyEncryptionParams
    forall e param.
    (Monoid e, AlgorithmId param, OIDNameable (AlgorithmType param)) =>
    ASN1ConstructionType -> ParseASN1 e param
    parseAlgorithm ASN1ConstructionType
    Sequence
                OctetString ByteString
    ek <- ParseASN1 e ASN1
    forall e. Monoid e => ParseASN1 e ASN1
    getNext
                PasswordRecipientInfo -> ParseASN1 e PasswordRecipientInfo
    forall a. a -> ParseASN1 e a
    forall (m :: * -> *) a. Monad m => a -> m a
    return PasswordRecipientInfo { priKeyDerivationFunc :: KeyDerivationFunc
    priKeyDerivationFunc = KeyDerivationFunc
    kdf
                                             , priKeyEncryptionParams :: KeyEncryptionParams
    priKeyEncryptionParams = KeyEncryptionParams
    kep
                                             , priEncryptedKey :: ByteString
    priEncryptedKey = ByteString
    ek
                                             }

    isVersion0 :: RecipientInfo -> Bool
    isVersion0 :: RecipientInfo -> Bool
    isVersion0 (KTRI KTRecipientInfo
    x)       = RecipientIdentifier -> Integer
    getKTVersion (KTRecipientInfo -> RecipientIdentifier
    ktRid KTRecipientInfo
    x) Integer -> Integer -> Bool
    forall a. Eq a => a -> a -> Bool
    == Integer
    0
    isVersion0 (KARI KARecipientInfo
    _)       = Bool
    False      -- because version is always 3
    isVersion0 (KEKRI KEKRecipientInfo
    _)      = Bool
    False      -- because version is always 4
    isVersion0 (PasswordRI PasswordRecipientInfo
    _) = Bool
    True       -- because version is always 0

    isPwriOri :: RecipientInfo -> Bool
    isPwriOri :: RecipientInfo -> Bool
    isPwriOri (KTRI KTRecipientInfo
    _)       = Bool
    False
    isPwriOri (KARI KARecipientInfo
    _)       = Bool
    False
    isPwriOri (KEKRI KEKRecipientInfo
    _)      = Bool
    False
    isPwriOri (PasswordRI PasswordRecipientInfo
    _) = Bool
    True

    -- | Enveloped content information.
    data EnvelopedData content = EnvelopedData
        { forall content. EnvelopedData content -> OriginatorInfo
    evOriginatorInfo :: OriginatorInfo
          -- ^ Optional information about the originator
        , forall content. EnvelopedData content -> [RecipientInfo]
    evRecipientInfos :: [RecipientInfo]
          -- ^ Information for recipients, allowing to decrypt the content
        , forall content. EnvelopedData content -> ContentType
    evContentType :: ContentType
          -- ^ Inner content type
        , forall content. EnvelopedData content -> ContentEncryptionParams
    evContentEncryptionParams :: ContentEncryptionParams
          -- ^ Encryption algorithm
        , forall content. EnvelopedData content -> content
    evEncryptedContent :: content
          -- ^ Encrypted content info
        , forall content. EnvelopedData content -> [Attribute]
    evUnprotectedAttrs :: [Attribute]
          -- ^ Optional unprotected attributes
        }
        deriving (Int -> EnvelopedData content -> ShowS
    [EnvelopedData content] -> ShowS
    EnvelopedData content -> String
    (Int -> EnvelopedData content -> ShowS)
    -> (EnvelopedData content -> String)
    -> ([EnvelopedData content] -> ShowS)
    -> Show (EnvelopedData content)
    forall content.
    Show content =>
    Int -> EnvelopedData content -> ShowS
    forall content. Show content => [EnvelopedData content] -> ShowS
    forall content. Show content => EnvelopedData content -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: forall content.
    Show content =>
    Int -> EnvelopedData content -> ShowS
    showsPrec :: Int -> EnvelopedData content -> ShowS
    $cshow :: forall content. Show content => EnvelopedData content -> String
    show :: EnvelopedData content -> String
    $cshowList :: forall content. Show content => [EnvelopedData content] -> ShowS
    showList :: [EnvelopedData content] -> ShowS
    Show,EnvelopedData content -> EnvelopedData content -> Bool
    (EnvelopedData content -> EnvelopedData content -> Bool)
    -> (EnvelopedData content -> EnvelopedData content -> Bool)
    -> Eq (EnvelopedData content)
    forall content.
    Eq content =>
    EnvelopedData content -> EnvelopedData content -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: forall content.
    Eq content =>
    EnvelopedData content -> EnvelopedData content -> Bool
    == :: EnvelopedData content -> EnvelopedData content -> Bool
    $c/= :: forall content.
    Eq content =>
    EnvelopedData content -> EnvelopedData content -> Bool
    /= :: EnvelopedData content -> EnvelopedData content -> Bool
    Eq)

    instance ProduceASN1Object ASN1P (EnvelopedData (Encap EncryptedContent)) where
        asn1s :: EnvelopedData (Encap ByteString) -> ASN1Stream ASN1P
    asn1s EnvelopedData{[Attribute]
    [RecipientInfo]
    Encap ByteString
    ContentType
    OriginatorInfo
    ContentEncryptionParams
    evOriginatorInfo :: forall content. EnvelopedData content -> OriginatorInfo
    evRecipientInfos :: forall content. EnvelopedData content -> [RecipientInfo]
    evContentType :: forall content. EnvelopedData content -> ContentType
    evContentEncryptionParams :: forall content. EnvelopedData content -> ContentEncryptionParams
    evEncryptedContent :: forall content. EnvelopedData content -> content
    evUnprotectedAttrs :: forall content. EnvelopedData content -> [Attribute]
    evOriginatorInfo :: OriginatorInfo
    evRecipientInfos :: [RecipientInfo]
    evContentType :: ContentType
    evContentEncryptionParams :: ContentEncryptionParams
    evEncryptedContent :: Encap ByteString
    evUnprotectedAttrs :: [Attribute]
    ..} =
            ASN1ConstructionType -> ASN1Stream ASN1P -> ASN1Stream ASN1P
    forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    asn1Container ASN1ConstructionType
    Sequence (ASN1Stream ASN1P
    ver ASN1Stream ASN1P -> ASN1Stream ASN1P -> ASN1Stream ASN1P
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ASN1Stream ASN1P
    oi ASN1Stream ASN1P -> ASN1Stream ASN1P -> ASN1Stream ASN1P
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ASN1Stream ASN1P
    ris ASN1Stream ASN1P -> ASN1Stream ASN1P -> ASN1Stream ASN1P
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ASN1Stream ASN1P
    eci ASN1Stream ASN1P -> ASN1Stream ASN1P -> ASN1Stream ASN1P
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ASN1Stream ASN1P
    ua)
          where
            ver :: ASN1Stream ASN1P
    ver = Integer -> ASN1Stream ASN1P
    forall e. ASN1Elem e => Integer -> ASN1Stream e
    gIntVal Integer
    v
            ris :: ASN1Stream ASN1P
    ris = ASN1ConstructionType -> ASN1Stream ASN1P -> ASN1Stream ASN1P
    forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    asn1Container ASN1ConstructionType
    Set ([RecipientInfo] -> ASN1Stream ASN1P
    forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
    asn1s [RecipientInfo]
    evRecipientInfos)
            eci :: ASN1Stream ASN1P
    eci = (ContentType, ContentEncryptionParams, Encap ByteString)
    -> ASN1Stream ASN1P
    forall e alg.
    (ASN1Elem e, ProduceASN1Object e alg) =>
    (ContentType, alg, Encap ByteString) -> ASN1Stream e
    encryptedContentInfoASN1S
                      (ContentType
    evContentType, ContentEncryptionParams
    evContentEncryptionParams, Encap ByteString
    evEncryptedContent)
            ua :: ASN1Stream ASN1P
    ua  = ASN1ConstructionType -> [Attribute] -> ASN1Stream ASN1P
    forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> [Attribute] -> ASN1Stream e
    attributesASN1S (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    1) [Attribute]
    evUnprotectedAttrs

            oi :: ASN1Stream ASN1P
    oi | OriginatorInfo
    evOriginatorInfo OriginatorInfo -> OriginatorInfo -> Bool
    forall a. Eq a => a -> a -> Bool
    == OriginatorInfo
    forall a. Monoid a => a
    mempty = ASN1Stream ASN1P
    forall a. a -> a
    id
               | Bool
    otherwise = ASN1ConstructionType -> OriginatorInfo -> ASN1Stream ASN1P
    originatorInfoASN1S (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    0) OriginatorInfo
    evOriginatorInfo

            v :: Integer
    v | OriginatorInfo -> Bool
    forall a. HasChoiceOther a => a -> Bool
    hasChoiceOther OriginatorInfo
    evOriginatorInfo = Integer
    4
              | (RecipientInfo -> Bool) -> [RecipientInfo] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    any RecipientInfo -> Bool
    isPwriOri [RecipientInfo]
    evRecipientInfos  = Integer
    3
              | OriginatorInfo
    evOriginatorInfo OriginatorInfo -> OriginatorInfo -> Bool
    forall a. Eq a => a -> a -> Bool
    /= OriginatorInfo
    forall a. Monoid a => a
    mempty      = Integer
    2
              | Bool -> Bool
    not ([Attribute] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Attribute]
    evUnprotectedAttrs)   = Integer
    2
              | (RecipientInfo -> Bool) -> [RecipientInfo] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all RecipientInfo -> Bool
    isVersion0 [RecipientInfo]
    evRecipientInfos = Integer
    0
              | Bool
    otherwise                       = Integer
    2

    instance ParseASN1Object [ASN1Event] (EnvelopedData (Encap EncryptedContent)) where
        parse :: ParseASN1 [ASN1Event] (EnvelopedData (Encap ByteString))
    parse =
            ASN1ConstructionType
    -> ParseASN1 [ASN1Event] (EnvelopedData (Encap ByteString))
    -> ParseASN1 [ASN1Event] (EnvelopedData (Encap ByteString))
    forall e a.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
    onNextContainer ASN1ConstructionType
    Sequence (ParseASN1 [ASN1Event] (EnvelopedData (Encap ByteString))
     -> ParseASN1 [ASN1Event] (EnvelopedData (Encap ByteString)))
    -> ParseASN1 [ASN1Event] (EnvelopedData (Encap ByteString))
    -> ParseASN1 [ASN1Event] (EnvelopedData (Encap ByteString))
    forall a b. (a -> b) -> a -> b
    $ do
                IntVal Integer
    v <- ParseASN1 [ASN1Event] ASN1
    forall e. Monoid e => ParseASN1 e ASN1
    getNext
                Bool -> ParseASN1 [ASN1Event] () -> ParseASN1 [ASN1Event] ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Integer
    v Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    > Integer
    4) (ParseASN1 [ASN1Event] () -> ParseASN1 [ASN1Event] ())
    -> ParseASN1 [ASN1Event] () -> ParseASN1 [ASN1Event] ()
    forall a b. (a -> b) -> a -> b
    $
                    String -> ParseASN1 [ASN1Event] ()
    forall e a. String -> ParseASN1 e a
    throwParseError (String
    "EnvelopedData: parsed invalid version: " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Integer -> String
    forall a. Show a => a -> String
    show Integer
    v)
                OriginatorInfo
    oi <- ASN1ConstructionType -> ParseASN1 [ASN1Event] OriginatorInfo
    parseOriginatorInfo (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    0) ParseASN1 [ASN1Event] OriginatorInfo
    -> ParseASN1 [ASN1Event] OriginatorInfo
    -> ParseASN1 [ASN1Event] OriginatorInfo
    forall a.
    ParseASN1 [ASN1Event] a
    -> ParseASN1 [ASN1Event] a -> ParseASN1 [ASN1Event] a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> OriginatorInfo -> ParseASN1 [ASN1Event] OriginatorInfo
    forall a. a -> ParseASN1 [ASN1Event] a
    forall (m :: * -> *) a. Monad m => a -> m a
    return OriginatorInfo
    forall a. Monoid a => a
    mempty
                [RecipientInfo]
    ris <- ASN1ConstructionType
    -> ParseASN1 [ASN1Event] [RecipientInfo]
    -> ParseASN1 [ASN1Event] [RecipientInfo]
    forall e a.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
    onNextContainer ASN1ConstructionType
    Set ParseASN1 [ASN1Event] [RecipientInfo]
    forall e obj. ParseASN1Object e obj => ParseASN1 e obj
    parse
                (ContentType
    ct, ContentEncryptionParams
    params, Encap ByteString
    ec) <- ParseASN1
      [ASN1Event]
      (ContentType, ContentEncryptionParams, Encap ByteString)
    forall e alg.
    ParseASN1Object e alg =>
    ParseASN1 e (ContentType, alg, Encap ByteString)
    parseEncryptedContentInfo
                [Attribute]
    attrs <- ASN1ConstructionType -> ParseASN1 [ASN1Event] [Attribute]
    forall e.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e [Attribute]
    parseAttributes (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    1)
                EnvelopedData (Encap ByteString)
    -> ParseASN1 [ASN1Event] (EnvelopedData (Encap ByteString))
    forall a. a -> ParseASN1 [ASN1Event] a
    forall (m :: * -> *) a. Monad m => a -> m a
    return EnvelopedData { evOriginatorInfo :: OriginatorInfo
    evOriginatorInfo = OriginatorInfo
    oi
                                     , evRecipientInfos :: [RecipientInfo]
    evRecipientInfos = [RecipientInfo]
    ris
                                     , evContentType :: ContentType
    evContentType = ContentType
    ct
                                     , evContentEncryptionParams :: ContentEncryptionParams
    evContentEncryptionParams = ContentEncryptionParams
    params
                                     , evEncryptedContent :: Encap ByteString
    evEncryptedContent = Encap ByteString
    ec
                                     , evUnprotectedAttrs :: [Attribute]
    evUnprotectedAttrs = [Attribute]
    attrs
                                     }

    -- | 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)

    -- | 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 'Crypto.Store.CMS.envelopData'.
    forKeyTransRecipient :: MonadRandom m
                         => SignedCertificate -> KeyTransportParams -> ProducerOfRI m
    forKeyTransRecipient :: forall (m :: * -> *).
    MonadRandom m =>
    SignedCertificate -> KeyTransportParams -> ProducerOfRI m
    forKeyTransRecipient SignedCertificate
    cert KeyTransportParams
    params ByteString
    inkey = do
        Either StoreError ByteString
    ek <- KeyTransportParams
    -> PubKey -> ByteString -> m (Either StoreError ByteString)
    forall (m :: * -> *).
    MonadRandom m =>
    KeyTransportParams
    -> PubKey -> ByteString -> m (Either StoreError ByteString)
    transportEncrypt KeyTransportParams
    params (Certificate -> PubKey
    certPubKey Certificate
    obj) ByteString
    inkey
        Either StoreError RecipientInfo
    -> m (Either StoreError RecipientInfo)
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (KTRecipientInfo -> RecipientInfo
    KTRI (KTRecipientInfo -> RecipientInfo)
    -> (ByteString -> KTRecipientInfo) -> ByteString -> RecipientInfo
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> KTRecipientInfo
    build (ByteString -> RecipientInfo)
    -> Either StoreError ByteString -> Either StoreError RecipientInfo
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Either StoreError ByteString
    ek)
      where
        obj :: Certificate
    obj = Signed Certificate -> Certificate
    forall a. (Show a, Eq a, ASN1Object a) => Signed a -> a
    signedObject (SignedCertificate -> Signed Certificate
    forall a. (Show a, Eq a, ASN1Object a) => SignedExact a -> Signed a
    getSigned SignedCertificate
    cert)
        isn :: IssuerAndSerialNumber
    isn = DistinguishedName -> Integer -> IssuerAndSerialNumber
    IssuerAndSerialNumber (Certificate -> DistinguishedName
    certIssuerDN Certificate
    obj) (Certificate -> Integer
    certSerial Certificate
    obj)

        build :: ByteString -> KTRecipientInfo
    build ByteString
    ek = KTRecipientInfo
                      { ktRid :: RecipientIdentifier
    ktRid = IssuerAndSerialNumber -> RecipientIdentifier
    RecipientIASN IssuerAndSerialNumber
    isn
                      , ktKeyTransportParams :: KeyTransportParams
    ktKeyTransportParams = KeyTransportParams
    params
                      , ktEncryptedKey :: ByteString
    ktEncryptedKey = ByteString
    ek
                      }

    -- | Use a Key Transport recipient, knowing the private key.
    --
    -- This function can be used as parameter to
    -- 'Crypto.Store.CMS.openEnvelopedData'.
    withRecipientKeyTrans :: MonadRandom m => PrivKey -> ConsumerOfRI m
    withRecipientKeyTrans :: forall (m :: * -> *). MonadRandom m => PrivKey -> ConsumerOfRI m
    withRecipientKeyTrans PrivKey
    privKey (KTRI KTRecipientInfo{ByteString
    KeyTransportParams
    RecipientIdentifier
    ktRid :: KTRecipientInfo -> RecipientIdentifier
    ktKeyTransportParams :: KTRecipientInfo -> KeyTransportParams
    ktEncryptedKey :: KTRecipientInfo -> ByteString
    ktRid :: RecipientIdentifier
    ktKeyTransportParams :: KeyTransportParams
    ktEncryptedKey :: ByteString
    ..}) =
        KeyTransportParams
    -> PrivKey -> ByteString -> m (Either StoreError ByteString)
    forall (m :: * -> *).
    MonadRandom m =>
    KeyTransportParams
    -> PrivKey -> ByteString -> m (Either StoreError ByteString)
    transportDecrypt KeyTransportParams
    ktKeyTransportParams PrivKey
    privKey ByteString
    ktEncryptedKey
    withRecipientKeyTrans PrivKey
    _ RecipientInfo
    _ = Either StoreError ByteString -> m (Either StoreError ByteString)
    forall a. a -> m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (StoreError -> Either StoreError ByteString
    forall a b. a -> Either a b
    Left StoreError
    RecipientTypeMismatch)

    -- | 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 'Crypto.Store.CMS.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
    forKeyAgreeRecipient :: forall (m :: * -> *).
    MonadRandom m =>
    SignedCertificate -> KeyAgreementParams -> ProducerOfRI m
    forKeyAgreeRecipient SignedCertificate
    cert KeyAgreementParams
    params ByteString
    inkey = do
        Either StoreError ECDHPair
    ephemeral <- PubKey -> m (Either StoreError ECDHPair)
    forall (m :: * -> *).
    MonadRandom m =>
    PubKey -> m (Either StoreError ECDHPair)
    ecdhGenerate (Certificate -> PubKey
    certPubKey Certificate
    obj)
        case Either StoreError ECDHPair
    ephemeral of
            Right ECDHPair
    pair -> do
                let pt :: ByteString
    pt = ECDHPair -> ByteString
    ecdhPublic ECDHPair
    pair
                    aPub :: OriginatorPublicKey
    aPub = [ASN1] -> BitArray -> OriginatorPublicKey
    OriginatorPublicKeyEC [] (ByteString -> Int -> BitArray
    toBitArray ByteString
    pt Int
    0)
                Either StoreError ByteString
    ek <- KeyAgreementParams
    -> Maybe ByteString
    -> ECDHPair
    -> ByteString
    -> m (Either StoreError ByteString)
    forall (m :: * -> *) ba.
    (MonadRandom m, ByteArray ba) =>
    KeyAgreementParams
    -> Maybe ByteString -> ECDHPair -> ba -> m (Either StoreError ba)
    ecdhEncrypt KeyAgreementParams
    params Maybe ByteString
    forall a. Maybe a
    Nothing ECDHPair
    pair ByteString
    inkey
                Either StoreError RecipientInfo
    -> m (Either StoreError RecipientInfo)
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (KARecipientInfo -> RecipientInfo
    KARI (KARecipientInfo -> RecipientInfo)
    -> (ByteString -> KARecipientInfo) -> ByteString -> RecipientInfo
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . OriginatorPublicKey -> ByteString -> KARecipientInfo
    build OriginatorPublicKey
    aPub (ByteString -> RecipientInfo)
    -> Either StoreError ByteString -> Either StoreError RecipientInfo
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Either StoreError ByteString
    ek)
            Left StoreError
    err -> Either StoreError RecipientInfo
    -> m (Either StoreError RecipientInfo)
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Either StoreError RecipientInfo
     -> m (Either StoreError RecipientInfo))
    -> Either StoreError RecipientInfo
    -> m (Either StoreError RecipientInfo)
    forall a b. (a -> b) -> a -> b
    $ StoreError -> Either StoreError RecipientInfo
    forall a b. a -> Either a b
    Left StoreError
    err
      where
        obj :: Certificate
    obj = Signed Certificate -> Certificate
    forall a. (Show a, Eq a, ASN1Object a) => Signed a -> a
    signedObject (SignedCertificate -> Signed Certificate
    forall a. (Show a, Eq a, ASN1Object a) => SignedExact a -> Signed a
    getSigned SignedCertificate
    cert)
        isn :: IssuerAndSerialNumber
    isn = DistinguishedName -> Integer -> IssuerAndSerialNumber
    IssuerAndSerialNumber (Certificate -> DistinguishedName
    certIssuerDN Certificate
    obj) (Certificate -> Integer
    certSerial Certificate
    obj)

        makeREK :: ByteString -> RecipientEncryptedKey
    makeREK ByteString
    ek = RecipientEncryptedKey
                         { rekRid :: KeyAgreeRecipientIdentifier
    rekRid = IssuerAndSerialNumber -> KeyAgreeRecipientIdentifier
    KeyAgreeRecipientIASN IssuerAndSerialNumber
    isn
                         , rekEncryptedKey :: ByteString
    rekEncryptedKey = ByteString
    ek
                         }

        build :: OriginatorPublicKey -> ByteString -> KARecipientInfo
    build OriginatorPublicKey
    aPub ByteString
    ek =
            KARecipientInfo
                { kaOriginator :: OriginatorIdentifierOrKey
    kaOriginator = OriginatorPublicKey -> OriginatorIdentifierOrKey
    OriginatorPublic OriginatorPublicKey
    aPub
                , kaUkm :: Maybe ByteString
    kaUkm = Maybe ByteString
    forall a. Maybe a
    Nothing
                , kaKeyAgreementParams :: KeyAgreementParams
    kaKeyAgreementParams = KeyAgreementParams
    params
                , kaRecipientEncryptedKeys :: [RecipientEncryptedKey]
    kaRecipientEncryptedKeys = [ ByteString -> RecipientEncryptedKey
    makeREK ByteString
    ek ]
                }

    -- | 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
    -- 'Crypto.Store.CMS.openEnvelopedData'.
    withRecipientKeyAgree :: MonadRandom m => PrivKey -> SignedCertificate -> ConsumerOfRI m
    withRecipientKeyAgree :: forall (m :: * -> *).
    MonadRandom m =>
    PrivKey -> SignedCertificate -> ConsumerOfRI m
    withRecipientKeyAgree PrivKey
    priv SignedCertificate
    cert (KARI KARecipientInfo{[RecipientEncryptedKey]
    Maybe ByteString
    KeyAgreementParams
    OriginatorIdentifierOrKey
    kaOriginator :: KARecipientInfo -> OriginatorIdentifierOrKey
    kaUkm :: KARecipientInfo -> Maybe ByteString
    kaKeyAgreementParams :: KARecipientInfo -> KeyAgreementParams
    kaRecipientEncryptedKeys :: KARecipientInfo -> [RecipientEncryptedKey]
    kaOriginator :: OriginatorIdentifierOrKey
    kaUkm :: Maybe ByteString
    kaKeyAgreementParams :: KeyAgreementParams
    kaRecipientEncryptedKeys :: [RecipientEncryptedKey]
    ..}) =
        case OriginatorIdentifierOrKey
    kaOriginator of
            OriginatorPublic (OriginatorPublicKeyEC [ASN1]
    _ BitArray
    ba) ->
                case SignedCertificate -> [RecipientEncryptedKey] -> Maybe ByteString
    findRecipientEncryptedKey SignedCertificate
    cert [RecipientEncryptedKey]
    kaRecipientEncryptedKeys of
                    Maybe ByteString
    Nothing -> Either StoreError ByteString -> m (Either StoreError ByteString)
    forall a. a -> m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (StoreError -> Either StoreError ByteString
    forall a b. a -> Either a b
    Left StoreError
    RecipientKeyNotFound)
                    Just ByteString
    ek ->
                        let pub :: ByteString
    pub = BitArray -> ByteString
    bitArrayGetData BitArray
    ba
                         in Either StoreError ByteString -> m (Either StoreError ByteString)
    forall a. a -> m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (KeyAgreementParams
    -> Maybe ByteString
    -> PrivKey
    -> ByteString
    -> ByteString
    -> Either StoreError ByteString
    forall ba.
    ByteArray ba =>
    KeyAgreementParams
    -> Maybe ByteString
    -> PrivKey
    -> ByteString
    -> ba
    -> Either StoreError ba
    ecdhDecrypt KeyAgreementParams
    kaKeyAgreementParams Maybe ByteString
    kaUkm PrivKey
    priv ByteString
    pub ByteString
    ek)
            OriginatorIdentifierOrKey
    _ -> Either StoreError ByteString -> m (Either StoreError ByteString)
    forall a. a -> m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (StoreError -> Either StoreError ByteString
    forall a b. a -> Either a b
    Left StoreError
    UnsupportedOriginatorFormat)
    withRecipientKeyAgree PrivKey
    _ SignedCertificate
    _ RecipientInfo
    _        = Either StoreError ByteString -> m (Either StoreError ByteString)
    forall a. a -> m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (StoreError -> Either StoreError ByteString
    forall a b. a -> Either a b
    Left StoreError
    RecipientTypeMismatch)

    -- | 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 'Crypto.Store.CMS.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
    forKeyRecipient :: forall (m :: * -> *).
    MonadRandom m =>
    ByteString
    -> KeyIdentifier -> KeyEncryptionParams -> ProducerOfRI m
    forKeyRecipient ByteString
    key KeyIdentifier
    kid KeyEncryptionParams
    params ByteString
    inkey = do
        Either StoreError ByteString
    ek <- ByteString
    -> KeyEncryptionParams
    -> ByteString
    -> m (Either StoreError ByteString)
    forall (m :: * -> *) kek ba.
    (MonadRandom m, ByteArray kek, ByteArray ba) =>
    kek -> KeyEncryptionParams -> ba -> m (Either StoreError ba)
    keyEncrypt ByteString
    key KeyEncryptionParams
    params ByteString
    inkey
        Either StoreError RecipientInfo
    -> m (Either StoreError RecipientInfo)
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (KEKRecipientInfo -> RecipientInfo
    KEKRI (KEKRecipientInfo -> RecipientInfo)
    -> (ByteString -> KEKRecipientInfo) -> ByteString -> RecipientInfo
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> KEKRecipientInfo
    build (ByteString -> RecipientInfo)
    -> Either StoreError ByteString -> Either StoreError RecipientInfo
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Either StoreError ByteString
    ek)
      where
        build :: ByteString -> KEKRecipientInfo
    build ByteString
    ek = KEKRecipientInfo
                       { kekId :: KeyIdentifier
    kekId = KeyIdentifier
    kid
                       , kekKeyEncryptionParams :: KeyEncryptionParams
    kekKeyEncryptionParams = KeyEncryptionParams
    params
                       , kekEncryptedKey :: ByteString
    kekEncryptedKey = ByteString
    ek
                       }

    -- | Use a Key Encryption Key recipient, knowing the key encryption key.
    --
    -- This function can be used as parameter to
    -- 'Crypto.Store.CMS.openEnvelopedData'.
    withRecipientKey :: Applicative f => KeyEncryptionKey -> ConsumerOfRI f
    withRecipientKey :: forall (f :: * -> *). Applicative f => ByteString -> ConsumerOfRI f
    withRecipientKey ByteString
    key (KEKRI KEKRecipientInfo{ByteString
    KeyEncryptionParams
    KeyIdentifier
    kekId :: KEKRecipientInfo -> KeyIdentifier
    kekKeyEncryptionParams :: KEKRecipientInfo -> KeyEncryptionParams
    kekEncryptedKey :: KEKRecipientInfo -> ByteString
    kekId :: KeyIdentifier
    kekKeyEncryptionParams :: KeyEncryptionParams
    kekEncryptedKey :: ByteString
    ..}) =
        Either StoreError ByteString -> f (Either StoreError ByteString)
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (ByteString
    -> KeyEncryptionParams
    -> ByteString
    -> Either StoreError ByteString
    forall kek ba.
    (ByteArray kek, ByteArray ba) =>
    kek -> KeyEncryptionParams -> ba -> Either StoreError ba
    keyDecrypt ByteString
    key KeyEncryptionParams
    kekKeyEncryptionParams ByteString
    kekEncryptedKey)
    withRecipientKey ByteString
    _ RecipientInfo
    _ = Either StoreError ByteString -> f (Either StoreError ByteString)
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (StoreError -> Either StoreError ByteString
    forall a b. a -> Either a b
    Left StoreError
    RecipientTypeMismatch)

    -- | Generate a password recipient from a password.
    --
    -- This function can be used as parameter to 'Crypto.Store.CMS.envelopData'.
    forPasswordRecipient :: MonadRandom m
                         => Password
                         -> KeyDerivationFunc
                         -> KeyEncryptionParams
                         -> ProducerOfRI m
    forPasswordRecipient :: forall (m :: * -> *).
    MonadRandom m =>
    ByteString
    -> KeyDerivationFunc -> KeyEncryptionParams -> ProducerOfRI m
    forPasswordRecipient ByteString
    pwd KeyDerivationFunc
    kdf KeyEncryptionParams
    params ByteString
    inkey = do
        Either StoreError ByteString
    ek <- ByteString
    -> KeyEncryptionParams
    -> ByteString
    -> m (Either StoreError ByteString)
    forall (m :: * -> *) kek ba.
    (MonadRandom m, ByteArray kek, ByteArray ba) =>
    kek -> KeyEncryptionParams -> ba -> m (Either StoreError ba)
    keyEncrypt ByteString
    derived KeyEncryptionParams
    params ByteString
    inkey
        Either StoreError RecipientInfo
    -> m (Either StoreError RecipientInfo)
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (PasswordRecipientInfo -> RecipientInfo
    PasswordRI (PasswordRecipientInfo -> RecipientInfo)
    -> (ByteString -> PasswordRecipientInfo)
    -> ByteString
    -> RecipientInfo
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> PasswordRecipientInfo
    build (ByteString -> RecipientInfo)
    -> Either StoreError ByteString -> Either StoreError RecipientInfo
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Either StoreError ByteString
    ek)
      where
        derived :: ByteString
    derived = KeyDerivationFunc -> Int -> ByteString -> ByteString
    forall password out.
    (ByteArrayAccess password, ByteArray out) =>
    KeyDerivationFunc -> Int -> password -> out
    kdfDerive KeyDerivationFunc
    kdf Int
    len ByteString
    pwd :: EncryptedKey
        len :: Int
    len = Int -> Maybe Int -> Int
    forall a. a -> Maybe a -> a
    fromMaybe (KeyEncryptionParams -> Int
    forall params. HasKeySize params => params -> Int
    getMaximumKeySize KeyEncryptionParams
    params) (KeyDerivationFunc -> Maybe Int
    kdfKeyLength KeyDerivationFunc
    kdf)
        build :: ByteString -> PasswordRecipientInfo
    build ByteString
    ek = PasswordRecipientInfo
                       { priKeyDerivationFunc :: KeyDerivationFunc
    priKeyDerivationFunc = KeyDerivationFunc
    kdf
                       , priKeyEncryptionParams :: KeyEncryptionParams
    priKeyEncryptionParams = KeyEncryptionParams
    params
                       , priEncryptedKey :: ByteString
    priEncryptedKey = ByteString
    ek
                       }

    -- | Use a password recipient, knowing the password.
    --
    -- This function can be used as parameter to
    -- 'Crypto.Store.CMS.openEnvelopedData'.
    withRecipientPassword :: Applicative f => Password -> ConsumerOfRI f
    withRecipientPassword :: forall (f :: * -> *). Applicative f => ByteString -> ConsumerOfRI f
    withRecipientPassword ByteString
    pwd (PasswordRI PasswordRecipientInfo{ByteString
    KeyEncryptionParams
    KeyDerivationFunc
    priKeyDerivationFunc :: PasswordRecipientInfo -> KeyDerivationFunc
    priKeyEncryptionParams :: PasswordRecipientInfo -> KeyEncryptionParams
    priEncryptedKey :: PasswordRecipientInfo -> ByteString
    priKeyDerivationFunc :: KeyDerivationFunc
    priKeyEncryptionParams :: KeyEncryptionParams
    priEncryptedKey :: ByteString
    ..}) =
        Either StoreError ByteString -> f (Either StoreError ByteString)
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (ByteString
    -> KeyEncryptionParams
    -> ByteString
    -> Either StoreError ByteString
    forall kek ba.
    (ByteArray kek, ByteArray ba) =>
    kek -> KeyEncryptionParams -> ba -> Either StoreError ba
    keyDecrypt ByteString
    derived KeyEncryptionParams
    priKeyEncryptionParams ByteString
    priEncryptedKey)
      where
        derived :: ByteString
    derived = KeyDerivationFunc -> Int -> ByteString -> ByteString
    forall password out.
    (ByteArrayAccess password, ByteArray out) =>
    KeyDerivationFunc -> Int -> password -> out
    kdfDerive KeyDerivationFunc
    priKeyDerivationFunc Int
    len ByteString
    pwd :: EncryptedKey
        len :: Int
    len = Int -> Maybe Int -> Int
    forall a. a -> Maybe a -> a
    fromMaybe (KeyEncryptionParams -> Int
    forall params. HasKeySize params => params -> Int
    getMaximumKeySize KeyEncryptionParams
    priKeyEncryptionParams)
                        (KeyDerivationFunc -> Maybe Int
    kdfKeyLength KeyDerivationFunc
    priKeyDerivationFunc)
    withRecipientPassword ByteString
    _ RecipientInfo
    _ = Either StoreError ByteString -> f (Either StoreError ByteString)
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (StoreError -> Either StoreError ByteString
    forall a b. a -> Either a b
    Left StoreError
    RecipientTypeMismatch)