-- |
-- 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
    -- * Key Encapsulation recipients
    , KEMRecipientInfo(..)
    , forKeyEncapRecipient
    , withRecipientKeyEncap
    ) 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
import Crypto.Store.Keys

-- | 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)  = [ASN1] -> ASN1Stream e
forall e. ASN1Elem e => [ASN1] -> ASN1Stream e
gMany [ASN1Class -> Int -> ByteString -> ASN1
Other ASN1Class
Context Int
0 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
<$>
                do { Other Context 0 bs <- ParseASN1 e ASN1
forall e. Monoid e => ParseASN1 e ASN1
getNext; return bs }

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
        i <- ParseASN1 e DistinguishedName
forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse
        IntVal s <- getNext
        return IssuerAndSerialNumber { iasnIssuer = i
                                     , iasnSerial = 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 <- 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 <- ParseASN1 e ASN1
forall e. Monoid e => ParseASN1 e ASN1
getNext
                    guard (oid == idEcPublicKey)
                    getMany getNext
        BitString ba <- getNext
        return (OriginatorPublicKeyEC asn1 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)    = [ASN1] -> ASN1Stream e
forall e. ASN1Elem e => [ASN1] -> ASN1Stream e
gMany [ASN1Class -> Int -> ByteString -> ASN1
Other ASN1Class
Context Int
0 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
<$>
                do { Other Context 0 bs <- ParseASN1 e ASN1
forall e. Monoid e => ParseASN1 e ASN1
getNext; return bs }
            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 -> KeyIdentifier -> ASN1Stream e
forall e.
ASN1Elem e =>
ASN1ConstructionType -> KeyIdentifier -> ASN1Stream e
keyIdentifierASN1S (ASN1Class -> Int -> ASN1ConstructionType
Container ASN1Class
Context Int
0) 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
forall e.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e KeyIdentifier
parseKeyIdentifier (ASN1Class -> Int -> ASN1ConstructionType
Container ASN1Class
Context Int
0)

-- | 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
        rid <- ParseASN1 e KeyAgreeRecipientIdentifier
forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse
        OctetString ek <- getNext
        return RecipientEncryptedKey { rekRid = rid, rekEncryptedKey = 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
    fn :: RecipientEncryptedKey -> Bool
fn RecipientEncryptedKey
rek = SignedCertificate -> RecipientIdentifier -> Bool
matchRecipient SignedCertificate
cert (RecipientIdentifier -> Bool) -> RecipientIdentifier -> Bool
forall a b. (a -> b) -> a -> b
$ case RecipientEncryptedKey -> KeyAgreeRecipientIdentifier
rekRid RecipientEncryptedKey
rek of
        KeyAgreeRecipientIASN IssuerAndSerialNumber
iasn -> IssuerAndSerialNumber -> RecipientIdentifier
RecipientIASN IssuerAndSerialNumber
iasn
        KeyAgreeRecipientKI   KeyIdentifier
ki   -> ByteString -> RecipientIdentifier
RecipientSKI (KeyIdentifier -> ByteString
keyIdentifier KeyIdentifier
ki)

matchRecipient :: SignedCertificate -> RecipientIdentifier -> Bool
matchRecipient :: SignedCertificate -> RecipientIdentifier -> Bool
matchRecipient SignedCertificate
cert RecipientIdentifier
rid =
    case RecipientIdentifier
rid of
        RecipientIASN IssuerAndSerialNumber
iasn -> IssuerAndSerialNumber -> Bool
matchIASN IssuerAndSerialNumber
iasn
        RecipientSKI  ByteString
ski  -> ByteString -> Bool
matchSKI ByteString
ski
  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

-- | Additional information in a t'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 attrId <- ParseASN1 e ASN1
forall e. Monoid e => ParseASN1 e ASN1
getNext
        attr <- getMany getNext
        return OtherKeyAttribute { keyAttrId = attrId, keyAttr = 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)

keyIdentifierASN1S :: ASN1Elem e
                   => ASN1ConstructionType -> KeyIdentifier -> ASN1Stream e
keyIdentifierASN1S :: forall e.
ASN1Elem e =>
ASN1ConstructionType -> KeyIdentifier -> ASN1Stream e
keyIdentifierASN1S ASN1ConstructionType
ty 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
ty (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

parseKeyIdentifier :: Monoid e
                   => ASN1ConstructionType -> ParseASN1 e KeyIdentifier
parseKeyIdentifier :: forall e.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e KeyIdentifier
parseKeyIdentifier ASN1ConstructionType
ty = ASN1ConstructionType
-> ParseASN1 e KeyIdentifier -> ParseASN1 e KeyIdentifier
forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
onNextContainer ASN1ConstructionType
ty (ParseASN1 e KeyIdentifier -> ParseASN1 e KeyIdentifier)
-> ParseASN1 e KeyIdentifier -> ParseASN1 e KeyIdentifier
forall a b. (a -> b) -> a -> b
$ do
    OctetString keyId <- ParseASN1 e ASN1
forall e. Monoid e => ParseASN1 e ASN1
getNext
    date <- getNextMaybe dateTimeOrNothing
    b <- hasNext
    other <- if b then Just <$> parse else return Nothing
    return KeyIdentifier { keyIdentifier = keyId
                         , keyDate = date
                         , keyOther = 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)

-- | Recipient using key encapsulation.
data KEMRecipientInfo = KEMRecipientInfo
    { KEMRecipientInfo -> RecipientIdentifier
kemRid :: RecipientIdentifier                       -- ^ identifier of recipient
    , KEMRecipientInfo -> KeyEncapsulationMechanism
kemEncapsulationParams :: KeyEncapsulationMechanism -- ^ key encapsulation mechanism
    , KEMRecipientInfo -> ByteString
kemCipherText :: ByteString                         -- ^ ciphertext for this recipient
    , KEMRecipientInfo -> KeyDerivationFn
kemDerivationFn :: KeyDerivationFn                  -- ^ key derivation used
    , KEMRecipientInfo -> Int
kemKekLength :: Int                                 -- ^ size of key encryption key
    , KEMRecipientInfo -> Maybe ByteString
kemUkm :: Maybe UserKeyingMaterial                  -- ^ user keying material
    , KEMRecipientInfo -> KeyEncryptionParams
kemEncryptionParams :: KeyEncryptionParams          -- ^ key encryption algorithm
    , KEMRecipientInfo -> ByteString
kemEncryptedKey :: EncryptedKey                     -- ^ encrypted content-encryption key
    }
    deriving (Int -> KEMRecipientInfo -> ShowS
[KEMRecipientInfo] -> ShowS
KEMRecipientInfo -> String
(Int -> KEMRecipientInfo -> ShowS)
-> (KEMRecipientInfo -> String)
-> ([KEMRecipientInfo] -> ShowS)
-> Show KEMRecipientInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> KEMRecipientInfo -> ShowS
showsPrec :: Int -> KEMRecipientInfo -> ShowS
$cshow :: KEMRecipientInfo -> String
show :: KEMRecipientInfo -> String
$cshowList :: [KEMRecipientInfo] -> ShowS
showList :: [KEMRecipientInfo] -> ShowS
Show,KEMRecipientInfo -> KEMRecipientInfo -> Bool
(KEMRecipientInfo -> KEMRecipientInfo -> Bool)
-> (KEMRecipientInfo -> KEMRecipientInfo -> Bool)
-> Eq KEMRecipientInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: KEMRecipientInfo -> KEMRecipientInfo -> Bool
== :: KEMRecipientInfo -> KEMRecipientInfo -> Bool
$c/= :: KEMRecipientInfo -> KEMRecipientInfo -> Bool
/= :: KEMRecipientInfo -> KEMRecipientInfo -> Bool
Eq)

instance ASN1Elem e => ProduceASN1Object e KEMRecipientInfo where
    asn1s :: KEMRecipientInfo -> ASN1Stream e
asn1s KEMRecipientInfo{Int
Maybe ByteString
ByteString
KeyEncapsulationMechanism
KeyEncryptionParams
KeyDerivationFn
RecipientIdentifier
kemRid :: KEMRecipientInfo -> RecipientIdentifier
kemEncapsulationParams :: KEMRecipientInfo -> KeyEncapsulationMechanism
kemCipherText :: KEMRecipientInfo -> ByteString
kemDerivationFn :: KEMRecipientInfo -> KeyDerivationFn
kemKekLength :: KEMRecipientInfo -> Int
kemUkm :: KEMRecipientInfo -> Maybe ByteString
kemEncryptionParams :: KEMRecipientInfo -> KeyEncryptionParams
kemEncryptedKey :: KEMRecipientInfo -> ByteString
kemRid :: RecipientIdentifier
kemEncapsulationParams :: KeyEncapsulationMechanism
kemCipherText :: ByteString
kemDerivationFn :: KeyDerivationFn
kemKekLength :: Int
kemUkm :: Maybe ByteString
kemEncryptionParams :: KeyEncryptionParams
kemEncryptedKey :: 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
kem ASN1Stream e -> ASN1Stream e -> ASN1Stream e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
ct 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
len 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
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
        rid :: ASN1Stream e
rid = RecipientIdentifier -> ASN1Stream e
forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
asn1s RecipientIdentifier
kemRid
        kem :: ASN1Stream e
kem = ASN1ConstructionType -> KeyEncapsulationMechanism -> ASN1Stream e
forall e param.
(ASN1Elem e, AlgorithmId param, OIDable (AlgorithmType param)) =>
ASN1ConstructionType -> param -> ASN1Stream e
algorithmASN1S ASN1ConstructionType
Sequence KeyEncapsulationMechanism
kemEncapsulationParams
        ct :: ASN1Stream e
ct  = ByteString -> ASN1Stream e
forall e. ASN1Elem e => ByteString -> ASN1Stream e
gOctetString ByteString
kemCipherText
        kdf :: ASN1Stream e
kdf = ASN1ConstructionType -> KeyDerivationFn -> ASN1Stream e
forall e param.
(ASN1Elem e, AlgorithmId param, OIDable (AlgorithmType param)) =>
ASN1ConstructionType -> param -> ASN1Stream e
algorithmASN1S ASN1ConstructionType
Sequence KeyDerivationFn
kemDerivationFn
        len :: ASN1Stream e
len = Integer -> ASN1Stream e
forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal (Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
kemKekLength)
        ukm :: ASN1Stream e
ukm = Maybe ByteString -> (ByteString -> ASN1Stream e) -> ASN1Stream e
forall a e. Maybe a -> (a -> ASN1Stream e) -> ASN1Stream e
optASN1S Maybe ByteString
kemUkm ((ByteString -> ASN1Stream e) -> ASN1Stream e)
-> (ByteString -> ASN1Stream e) -> ASN1Stream e
forall a b. (a -> b) -> a -> b
$ ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container (ASN1Class -> Int -> ASN1ConstructionType
Container ASN1Class
Context Int
0) (ASN1Stream e -> ASN1Stream e)
-> (ByteString -> ASN1Stream e) -> ByteString -> ASN1Stream e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ASN1Stream e
forall e. ASN1Elem e => ByteString -> ASN1Stream e
gOctetString
        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
kemEncryptionParams
        ek :: ASN1Stream e
ek  = ByteString -> ASN1Stream e
forall e. ASN1Elem e => ByteString -> ASN1Stream e
gOctetString ByteString
kemEncryptedKey

instance Monoid e => ParseASN1Object e KEMRecipientInfo where
    parse :: ParseASN1 e KEMRecipientInfo
parse = ASN1ConstructionType
-> ParseASN1 e KEMRecipientInfo -> ParseASN1 e KEMRecipientInfo
forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
onNextContainer ASN1ConstructionType
Sequence (ParseASN1 e KEMRecipientInfo -> ParseASN1 e KEMRecipientInfo)
-> ParseASN1 e KEMRecipientInfo -> ParseASN1 e KEMRecipientInfo
forall a b. (a -> b) -> a -> b
$ do
        IntVal 0 <- ParseASN1 e ASN1
forall e. Monoid e => ParseASN1 e ASN1
getNext
        rid <- parse
        kem <- parseAlgorithm Sequence
        OctetString ct <- getNext
        kdf <- parseAlgorithm Sequence
        IntVal len <- getNext
        when (len < 1 || len > 65535) $
            throwParseError ("KEMRecipientInfo: parsed invalid kekLength: " ++ show len)
        ukm <- onNextContainerMaybe (Container Context 0) $
                   do { OctetString bs <- getNext; return bs }
        kep <- parseAlgorithm Sequence
        OctetString ek <- getNext
        return KEMRecipientInfo { kemRid = rid
                                , kemEncapsulationParams = kem
                                , kemCipherText = ct
                                , kemDerivationFn = kdf
                                , kemKekLength = fromInteger len
                                , kemUkm = ukm
                                , kemEncryptionParams = kep
                                , kemEncryptedKey = ek
                                }

data CMSORIforKEMOtherInfo = CMSORIforKEMOtherInfo
    { CMSORIforKEMOtherInfo -> KeyEncryptionParams
kemoiWrap :: KeyEncryptionParams
    , CMSORIforKEMOtherInfo -> Int
kemoiKekLength :: Int
    , CMSORIforKEMOtherInfo -> Maybe ByteString
kemoiUkm :: Maybe UserKeyingMaterial
    }
    deriving (Int -> CMSORIforKEMOtherInfo -> ShowS
[CMSORIforKEMOtherInfo] -> ShowS
CMSORIforKEMOtherInfo -> String
(Int -> CMSORIforKEMOtherInfo -> ShowS)
-> (CMSORIforKEMOtherInfo -> String)
-> ([CMSORIforKEMOtherInfo] -> ShowS)
-> Show CMSORIforKEMOtherInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CMSORIforKEMOtherInfo -> ShowS
showsPrec :: Int -> CMSORIforKEMOtherInfo -> ShowS
$cshow :: CMSORIforKEMOtherInfo -> String
show :: CMSORIforKEMOtherInfo -> String
$cshowList :: [CMSORIforKEMOtherInfo] -> ShowS
showList :: [CMSORIforKEMOtherInfo] -> ShowS
Show,CMSORIforKEMOtherInfo -> CMSORIforKEMOtherInfo -> Bool
(CMSORIforKEMOtherInfo -> CMSORIforKEMOtherInfo -> Bool)
-> (CMSORIforKEMOtherInfo -> CMSORIforKEMOtherInfo -> Bool)
-> Eq CMSORIforKEMOtherInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CMSORIforKEMOtherInfo -> CMSORIforKEMOtherInfo -> Bool
== :: CMSORIforKEMOtherInfo -> CMSORIforKEMOtherInfo -> Bool
$c/= :: CMSORIforKEMOtherInfo -> CMSORIforKEMOtherInfo -> Bool
/= :: CMSORIforKEMOtherInfo -> CMSORIforKEMOtherInfo -> Bool
Eq)

instance ASN1Elem e => ProduceASN1Object e CMSORIforKEMOtherInfo where
    asn1s :: CMSORIforKEMOtherInfo -> ASN1Stream e
asn1s CMSORIforKEMOtherInfo{Int
Maybe ByteString
KeyEncryptionParams
kemoiWrap :: CMSORIforKEMOtherInfo -> KeyEncryptionParams
kemoiKekLength :: CMSORIforKEMOtherInfo -> Int
kemoiUkm :: CMSORIforKEMOtherInfo -> Maybe ByteString
kemoiWrap :: KeyEncryptionParams
kemoiKekLength :: Int
kemoiUkm :: Maybe ByteString
..} =
        ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container ASN1ConstructionType
Sequence (ASN1Stream e
wrap ASN1Stream e -> ASN1Stream e -> ASN1Stream e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
len ASN1Stream e -> ASN1Stream e -> ASN1Stream e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
ukm)
      where
        wrap :: ASN1Stream e
wrap = ASN1ConstructionType -> KeyEncryptionParams -> ASN1Stream e
forall e param.
(ASN1Elem e, AlgorithmId param, OIDable (AlgorithmType param)) =>
ASN1ConstructionType -> param -> ASN1Stream e
algorithmASN1S ASN1ConstructionType
Sequence KeyEncryptionParams
kemoiWrap
        len :: ASN1Stream e
len = Integer -> ASN1Stream e
forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal (Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
kemoiKekLength)
        ukm :: ASN1Stream e
ukm = Maybe ByteString -> (ByteString -> ASN1Stream e) -> ASN1Stream e
forall a e. Maybe a -> (a -> ASN1Stream e) -> ASN1Stream e
optASN1S Maybe ByteString
kemoiUkm ((ByteString -> ASN1Stream e) -> ASN1Stream e)
-> (ByteString -> ASN1Stream e) -> ASN1Stream e
forall a b. (a -> b) -> a -> b
$ ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container (ASN1Class -> Int -> ASN1ConstructionType
Container ASN1Class
Context Int
0) (ASN1Stream e -> ASN1Stream e)
-> (ByteString -> ASN1Stream e) -> ByteString -> ASN1Stream e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ASN1Stream e
forall e. ASN1Elem e => ByteString -> ASN1Stream e
gOctetString

-- | Information for a recipient of an t'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
                   | KEMRI KEMRecipientInfo
                     -- ^ Recipient using key encapsulation
    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 = ASN1ConstructionType -> KeyIdentifier -> ASN1Stream e
forall e.
ASN1Elem e =>
ASN1ConstructionType -> KeyIdentifier -> ASN1Stream e
keyIdentifierASN1S ASN1ConstructionType
Sequence 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

    asn1s (KEMRI KEMRecipientInfo
ri) =
        ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container (ASN1Class -> Int -> ASN1ConstructionType
Container ASN1Class
Context Int
4) (ASN1Stream e
typ ASN1Stream e -> ASN1Stream e -> ASN1Stream e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
val)
      where
        typ :: ASN1Stream e
typ = OID -> ASN1Stream e
forall e. ASN1Elem e => OID -> ASN1Stream e
gOID [Integer
1,Integer
2,Integer
840,Integer
113549,Integer
1,Integer
9,Integer
16,Integer
13,Integer
3]
        val :: ASN1Stream e
val = KEMRecipientInfo -> ASN1Stream e
forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
asn1s KEMRecipientInfo
ri

instance Monoid e => ParseASN1Object e RecipientInfo where
    parse :: ParseASN1 e RecipientInfo
parse = do
        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
             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
4) ParseASN1 e RecipientInfo
parseOther
        case 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 v <- ParseASN1 e ASN1
forall e. Monoid e => ParseASN1 e ASN1
getNext
            unless (v `elem` [0, 2]) $
                throwParseError ("RecipientInfo: parsed invalid KT version: " ++ show v)
            rid <- parse
            ktp <- parseAlgorithm Sequence
            OctetString ek <- getNext
            return KTRecipientInfo { ktRid = rid
                                   , ktKeyTransportParams = ktp
                                   , ktEncryptedKey = 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 3 <- ParseASN1 e ASN1
forall e. Monoid e => ParseASN1 e ASN1
getNext
            ori <- onNextContainer (Container Context 0) parse
            ukm <- onNextContainerMaybe (Container Context 1) $
                       do { OctetString bs <- getNext; return bs }
            kap <- parseAlgorithm Sequence
            reks <- onNextContainer Sequence parse
            return KARecipientInfo { kaOriginator = ori
                                   , kaUkm = ukm
                                   , kaKeyAgreementParams = kap
                                   , kaRecipientEncryptedKeys = 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 4 <- ParseASN1 e ASN1
forall e. Monoid e => ParseASN1 e ASN1
getNext
            kid <- parseKeyIdentifier Sequence
            kep <- parseAlgorithm Sequence
            OctetString ek <- getNext
            return KEKRecipientInfo { kekId = kid
                                    , kekKeyEncryptionParams = kep
                                    , kekEncryptedKey = 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 0 <- ParseASN1 e ASN1
forall e. Monoid e => ParseASN1 e ASN1
getNext
            kdf <- parseAlgorithm (Container Context 0)
            kep <- parseAlgorithm Sequence
            OctetString ek <- getNext
            return PasswordRecipientInfo { priKeyDerivationFunc = kdf
                                         , priKeyEncryptionParams = kep
                                         , priEncryptedKey = ek
                                         }

        parseOther :: ParseASN1 e RecipientInfo
parseOther = KEMRecipientInfo -> RecipientInfo
KEMRI (KEMRecipientInfo -> RecipientInfo)
-> ParseASN1 e KEMRecipientInfo -> ParseASN1 e RecipientInfo
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> do
            OID [1,2,840,113549,1,9,16,13,3] <- ParseASN1 e ASN1
forall e. Monoid e => ParseASN1 e ASN1
getNext
            parse

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
isVersion0 (KEMRI KEMRecipientInfo
_)      = 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
isPwriOri (KEMRI KEMRecipientInfo
_)      = 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 v <- ParseASN1 [ASN1Event] ASN1
forall e. Monoid e => ParseASN1 e ASN1
getNext
            when (v > 4) $
                throwParseError ("EnvelopedData: parsed invalid version: " ++ show v)
            oi <- parseOriginatorInfo (Container Context 0) <|> return mempty
            ris <- onNextContainer Set parse
            (ct, params, ec) <- parseEncryptedContentInfo
            attrs <- parseAttributes (Container Context 1)
            return EnvelopedData { evOriginatorInfo = oi
                                 , evRecipientInfos = ris
                                 , evContentType = ct
                                 , evContentEncryptionParams = params
                                 , evEncryptedContent = ec
                                 , evUnprotectedAttrs = 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
    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
    return (KTRI . build <$> 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 => KeyPair -> ConsumerOfRI m
withRecipientKeyTrans :: forall (m :: * -> *). MonadRandom m => KeyPair -> ConsumerOfRI m
withRecipientKeyTrans KeyPair
keyPair (KTRI KTRecipientInfo{ByteString
KeyTransportParams
RecipientIdentifier
ktRid :: KTRecipientInfo -> RecipientIdentifier
ktKeyTransportParams :: KTRecipientInfo -> KeyTransportParams
ktEncryptedKey :: KTRecipientInfo -> ByteString
ktRid :: RecipientIdentifier
ktKeyTransportParams :: KeyTransportParams
ktEncryptedKey :: ByteString
..}) =
    KeyTransportParams
-> KeyPair -> ByteString -> m (Either StoreError ByteString)
forall (m :: * -> *).
MonadRandom m =>
KeyTransportParams
-> KeyPair -> ByteString -> m (Either StoreError ByteString)
transportDecrypt KeyTransportParams
ktKeyTransportParams KeyPair
keyPair ByteString
ktEncryptedKey
withRecipientKeyTrans KeyPair
_ 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
    ephemeral <- PubKey -> m (Either StoreError ECDHPair)
forall (m :: * -> *).
MonadRandom m =>
PubKey -> m (Either StoreError ECDHPair)
ecdhGenerate (Certificate -> PubKey
certPubKey Certificate
obj)
    case 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)
            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
            return (KARI . build aPub <$> 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 => KeyPair -> SignedCertificate -> ConsumerOfRI m
withRecipientKeyAgree :: forall (m :: * -> *).
MonadRandom m =>
KeyPair -> SignedCertificate -> ConsumerOfRI m
withRecipientKeyAgree KeyPair
pair 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]
..})
    | KeyPair -> SignedCertificate -> Bool
keyPairMatchesCert KeyPair
pair SignedCertificate
cert =
        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
-> KeyPair
-> ByteString
-> ByteString
-> Either StoreError ByteString
forall ba.
ByteArray ba =>
KeyAgreementParams
-> Maybe ByteString
-> KeyPair
-> ByteString
-> ba
-> Either StoreError ba
ecdhDecrypt KeyAgreementParams
kaKeyAgreementParams Maybe ByteString
kaUkm KeyPair
pair 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)
    | Bool
otherwise = Either StoreError ByteString -> m (Either StoreError ByteString)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either StoreError ByteString -> m (Either StoreError ByteString))
-> Either StoreError ByteString -> m (Either StoreError ByteString)
forall a b. (a -> b) -> a -> b
$ StoreError -> Either StoreError ByteString
forall a b. a -> Either a b
Left StoreError
PublicPrivateKeyMismatch
withRecipientKeyAgree KeyPair
_ 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
    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
    return (KEKRI . build <$> 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
    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
    return (PasswordRI . build <$> 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)

-- | Generate a Key Encapsulation recipient from a certificate and
-- desired algorithms.  The recipient info will contain the KEM ciphertext.
--
-- This function can be used as parameter to 'Crypto.Store.CMS.envelopData'.
--
-- To avoid decreasing the security strength, selected algorithms should all be
-- equal or stronger than the content encryption key.
forKeyEncapRecipient :: MonadRandom m
                     => SignedCertificate
                     -> KeyDerivationFn
                     -> KeyEncryptionParams
                     -> KeyEncapsulationMechanism
                     -> ProducerOfRI m
forKeyEncapRecipient :: forall (m :: * -> *).
MonadRandom m =>
SignedCertificate
-> KeyDerivationFn
-> KeyEncryptionParams
-> KeyEncapsulationMechanism
-> ProducerOfRI m
forKeyEncapRecipient SignedCertificate
cert KeyDerivationFn
kdf KeyEncryptionParams
kep KeyEncapsulationMechanism
params ByteString
inkey = do
    ephemeral <- KeyEncapsulationMechanism
-> PubKey -> m (Either StoreError (ByteString, ByteString))
forall (m :: * -> *) ct ss.
(MonadRandom m, ByteArray ct, ByteArray ss) =>
KeyEncapsulationMechanism
-> PubKey -> m (Either StoreError (ct, ss))
kemEncap KeyEncapsulationMechanism
params (Certificate -> PubKey
certPubKey Certificate
obj)
    case ephemeral of
        Right (ByteString
ct, ByteString
ss) ->
            case KeyDerivationFn
-> ByteString
-> Int
-> ByteString
-> ByteString
-> Either StoreError ByteString
forall salt ikm out.
(ByteArrayAccess salt, ByteArrayAccess ikm, ByteArray out) =>
KeyDerivationFn
-> salt -> Int -> ByteString -> ikm -> Either StoreError out
kdfApply KeyDerivationFn
kdf ByteString
noSalt Int
len ByteString
prm (ByteString
ss :: EncryptedKey) of
                Left StoreError
err -> Either StoreError RecipientInfo
-> m (Either StoreError RecipientInfo)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (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
                Right ByteString
kek -> do
                    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
kek :: EncryptedKey) KeyEncryptionParams
kep ByteString
inkey
                    pure (KEMRI . build ct <$> ek)
        Left StoreError
err -> Either StoreError RecipientInfo
-> m (Either StoreError RecipientInfo)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (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)
    prm :: ByteString
prm = ASN1Stream ASN1P -> ByteString
encodeASN1S (CMSORIforKEMOtherInfo -> ASN1Stream ASN1P
forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
asn1s CMSORIforKEMOtherInfo
info)

    len :: Int
len  = KeyEncryptionParams -> Int
forall params. HasKeySize params => params -> Int
getMaximumKeySize KeyEncryptionParams
kep
    info :: CMSORIforKEMOtherInfo
info = CMSORIforKEMOtherInfo
        { kemoiWrap :: KeyEncryptionParams
kemoiWrap = KeyEncryptionParams
kep
        , kemoiKekLength :: Int
kemoiKekLength = Int
len
        , kemoiUkm :: Maybe ByteString
kemoiUkm = Maybe ByteString
forall a. Maybe a
Nothing
        }

    build :: ByteString -> ByteString -> KEMRecipientInfo
build ByteString
ct ByteString
ek =
        KEMRecipientInfo
            { kemRid :: RecipientIdentifier
kemRid = IssuerAndSerialNumber -> RecipientIdentifier
RecipientIASN IssuerAndSerialNumber
isn
            , kemEncapsulationParams :: KeyEncapsulationMechanism
kemEncapsulationParams = KeyEncapsulationMechanism
params
            , kemCipherText :: ByteString
kemCipherText = ByteString
ct
            , kemDerivationFn :: KeyDerivationFn
kemDerivationFn = KeyDerivationFn
kdf
            , kemKekLength :: Int
kemKekLength = Int
len
            , kemUkm :: Maybe ByteString
kemUkm = Maybe ByteString
forall a. Maybe a
Nothing
            , kemEncryptionParams :: KeyEncryptionParams
kemEncryptionParams = KeyEncryptionParams
kep
            , kemEncryptedKey :: ByteString
kemEncryptedKey = ByteString
ek
            }

-- | Use a Key Encapsulation recipient, knowing the recipient private key.
-- The recipient certificate is also used to determine if a recipient info
-- is applicable.
--
-- This function can be used as parameter to
-- 'Crypto.Store.CMS.openEnvelopedData'.
withRecipientKeyEncap :: MonadRandom m => KeyPair -> SignedCertificate -> ConsumerOfRI m
withRecipientKeyEncap :: forall (m :: * -> *).
MonadRandom m =>
KeyPair -> SignedCertificate -> ConsumerOfRI m
withRecipientKeyEncap KeyPair
pair SignedCertificate
cert (KEMRI KEMRecipientInfo{Int
Maybe ByteString
ByteString
KeyEncapsulationMechanism
KeyEncryptionParams
KeyDerivationFn
RecipientIdentifier
kemRid :: KEMRecipientInfo -> RecipientIdentifier
kemEncapsulationParams :: KEMRecipientInfo -> KeyEncapsulationMechanism
kemCipherText :: KEMRecipientInfo -> ByteString
kemDerivationFn :: KEMRecipientInfo -> KeyDerivationFn
kemKekLength :: KEMRecipientInfo -> Int
kemUkm :: KEMRecipientInfo -> Maybe ByteString
kemEncryptionParams :: KEMRecipientInfo -> KeyEncryptionParams
kemEncryptedKey :: KEMRecipientInfo -> ByteString
kemRid :: RecipientIdentifier
kemEncapsulationParams :: KeyEncapsulationMechanism
kemCipherText :: ByteString
kemDerivationFn :: KeyDerivationFn
kemKekLength :: Int
kemUkm :: Maybe ByteString
kemEncryptionParams :: KeyEncryptionParams
kemEncryptedKey :: ByteString
..})
    | Bool -> Bool
not (KeyPair -> SignedCertificate -> Bool
keyPairMatchesCert KeyPair
pair SignedCertificate
cert) =
        Either StoreError ByteString -> m (Either StoreError ByteString)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either StoreError ByteString -> m (Either StoreError ByteString))
-> Either StoreError ByteString -> m (Either StoreError ByteString)
forall a b. (a -> b) -> a -> b
$ StoreError -> Either StoreError ByteString
forall a b. a -> Either a b
Left StoreError
PublicPrivateKeyMismatch
    | Bool -> Bool
not (SignedCertificate -> RecipientIdentifier -> Bool
matchRecipient SignedCertificate
cert RecipientIdentifier
kemRid) =
        Either StoreError ByteString -> m (Either StoreError ByteString)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either StoreError ByteString -> m (Either StoreError ByteString))
-> Either StoreError ByteString -> m (Either StoreError ByteString)
forall a b. (a -> b) -> a -> b
$ StoreError -> Either StoreError ByteString
forall a b. a -> Either a b
Left StoreError
NoRecipientInfoMatched
    | Bool
otherwise =
        case KeyEncapsulationMechanism
-> KeyPair -> ByteString -> Either StoreError ByteString
forall ct ss.
(ByteArrayAccess ct, ByteArray ss) =>
KeyEncapsulationMechanism -> KeyPair -> ct -> Either StoreError ss
kemDecap KeyEncapsulationMechanism
kemEncapsulationParams KeyPair
pair ByteString
kemCipherText of
            Left StoreError
err -> Either StoreError ByteString -> m (Either StoreError ByteString)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either StoreError ByteString -> m (Either StoreError ByteString))
-> Either StoreError ByteString -> m (Either StoreError ByteString)
forall a b. (a -> b) -> a -> b
$ StoreError -> Either StoreError ByteString
forall a b. a -> Either a b
Left StoreError
err
            Right ByteString
ss | Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
kemKekLength -> Either StoreError ByteString -> m (Either StoreError ByteString)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either StoreError ByteString -> m (Either StoreError ByteString))
-> Either StoreError ByteString -> m (Either StoreError ByteString)
forall a b. (a -> b) -> a -> b
$
                case KeyDerivationFn
-> ByteString
-> Int
-> ByteString
-> ByteString
-> Either StoreError ByteString
forall salt ikm out.
(ByteArrayAccess salt, ByteArrayAccess ikm, ByteArray out) =>
KeyDerivationFn
-> salt -> Int -> ByteString -> ikm -> Either StoreError out
kdfApply KeyDerivationFn
kemDerivationFn ByteString
noSalt Int
kemKekLength ByteString
prm (ByteString
ss :: EncryptedKey) of
                    Left StoreError
err -> StoreError -> Either StoreError ByteString
forall a b. a -> Either a b
Left StoreError
err
                    Right ByteString
kek -> ByteString
-> KeyEncryptionParams
-> ByteString
-> Either StoreError ByteString
forall kek ba.
(ByteArray kek, ByteArray ba) =>
kek -> KeyEncryptionParams -> ba -> Either StoreError ba
keyDecrypt (ByteString
kek :: EncryptedKey)
                        KeyEncryptionParams
kemEncryptionParams ByteString
kemEncryptedKey
            Right ByteString
_ -> Either StoreError ByteString -> m (Either StoreError ByteString)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either StoreError ByteString -> m (Either StoreError ByteString))
-> Either StoreError ByteString -> m (Either StoreError ByteString)
forall a b. (a -> b) -> a -> b
$ StoreError -> Either StoreError ByteString
forall a b. a -> Either a b
Left (String -> StoreError
InvalidInput String
"Wrong kekLength in KEMRecipientInfo")
  where
    len :: Int
len  = KeyEncryptionParams -> Int
forall params. HasKeySize params => params -> Int
getMaximumKeySize KeyEncryptionParams
kemEncryptionParams
    prm :: ByteString
prm  = ASN1Stream ASN1P -> ByteString
encodeASN1S (CMSORIforKEMOtherInfo -> ASN1Stream ASN1P
forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
asn1s CMSORIforKEMOtherInfo
info)
    info :: CMSORIforKEMOtherInfo
info = CMSORIforKEMOtherInfo
        { kemoiWrap :: KeyEncryptionParams
kemoiWrap = KeyEncryptionParams
kemEncryptionParams
        , kemoiKekLength :: Int
kemoiKekLength = Int
kemKekLength
        , kemoiUkm :: Maybe ByteString
kemoiUkm = Maybe ByteString
kemUkm
        }
withRecipientKeyEncap KeyPair
_ 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)

noSalt :: ByteString
noSalt :: ByteString
noSalt = ByteString
forall a. Monoid a => a
mempty