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

import Control.Applicative
import Control.Monad

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

import Time.Types

import Crypto.Random (MonadRandom)

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

-- | Encrypted key.
type EncryptedKey = ByteString

-- | User keying material.
type UserKeyingMaterial = ByteString

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

-- | Generate a Key Transport recipient from a certificate and
-- desired algorithm.  The recipient will contain certificate identifier.
--
-- This function can be used as parameter to 'Crypto.Store.CMS.envelopData'.
forKeyTransRecipient :: MonadRandom m
                     => SignedCertificate -> KeyTransportParams -> ProducerOfRI m
forKeyTransRecipient :: forall (m :: * -> *).
MonadRandom m =>
SignedCertificate -> KeyTransportParams -> ProducerOfRI m
forKeyTransRecipient SignedCertificate
cert KeyTransportParams
params ByteString
inkey = do
    Either StoreError ByteString
ek <- KeyTransportParams
-> PubKey -> ByteString -> m (Either StoreError ByteString)
forall (m :: * -> *).
MonadRandom m =>
KeyTransportParams
-> PubKey -> ByteString -> m (Either StoreError ByteString)
transportEncrypt KeyTransportParams
params (Certificate -> PubKey
certPubKey Certificate
obj) ByteString
inkey
    Either StoreError RecipientInfo
-> m (Either StoreError RecipientInfo)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (KTRecipientInfo -> RecipientInfo
KTRI (KTRecipientInfo -> RecipientInfo)
-> (ByteString -> KTRecipientInfo) -> ByteString -> RecipientInfo
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> KTRecipientInfo
build (ByteString -> RecipientInfo)
-> Either StoreError ByteString -> Either StoreError RecipientInfo
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Either StoreError ByteString
ek)
  where
    obj :: Certificate
obj = Signed Certificate -> Certificate
forall a. (Show a, Eq a, ASN1Object a) => Signed a -> a
signedObject (SignedCertificate -> Signed Certificate
forall a. (Show a, Eq a, ASN1Object a) => SignedExact a -> Signed a
getSigned SignedCertificate
cert)
    isn :: IssuerAndSerialNumber
isn = DistinguishedName -> Integer -> IssuerAndSerialNumber
IssuerAndSerialNumber (Certificate -> DistinguishedName
certIssuerDN Certificate
obj) (Certificate -> Integer
certSerial Certificate
obj)

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

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

-- | Generate a Key Agreement recipient from a certificate and
-- desired algorithm.  The recipient info will contain an ephemeral public key.
--
-- This function can be used as parameter to 'Crypto.Store.CMS.envelopData'.
--
-- To avoid decreasing the security strength, Key Encryption parameters should
-- use a key size equal or greater than the content encryption key.
forKeyAgreeRecipient :: MonadRandom m
                     => SignedCertificate -> KeyAgreementParams -> ProducerOfRI m
forKeyAgreeRecipient :: forall (m :: * -> *).
MonadRandom m =>
SignedCertificate -> KeyAgreementParams -> ProducerOfRI m
forKeyAgreeRecipient SignedCertificate
cert KeyAgreementParams
params ByteString
inkey = do
    Either StoreError ECDHPair
ephemeral <- PubKey -> m (Either StoreError ECDHPair)
forall (m :: * -> *).
MonadRandom m =>
PubKey -> m (Either StoreError ECDHPair)
ecdhGenerate (Certificate -> PubKey
certPubKey Certificate
obj)
    case Either StoreError ECDHPair
ephemeral of
        Right ECDHPair
pair -> do
            let pt :: ByteString
pt = ECDHPair -> ByteString
ecdhPublic ECDHPair
pair
                aPub :: OriginatorPublicKey
aPub = [ASN1] -> BitArray -> OriginatorPublicKey
OriginatorPublicKeyEC [] (ByteString -> Int -> BitArray
toBitArray ByteString
pt Int
0)
            Either StoreError ByteString
ek <- KeyAgreementParams
-> Maybe ByteString
-> ECDHPair
-> ByteString
-> m (Either StoreError ByteString)
forall (m :: * -> *) ba.
(MonadRandom m, ByteArray ba) =>
KeyAgreementParams
-> Maybe ByteString -> ECDHPair -> ba -> m (Either StoreError ba)
ecdhEncrypt KeyAgreementParams
params Maybe ByteString
forall a. Maybe a
Nothing ECDHPair
pair ByteString
inkey
            Either StoreError RecipientInfo
-> m (Either StoreError RecipientInfo)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (KARecipientInfo -> RecipientInfo
KARI (KARecipientInfo -> RecipientInfo)
-> (ByteString -> KARecipientInfo) -> ByteString -> RecipientInfo
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OriginatorPublicKey -> ByteString -> KARecipientInfo
build OriginatorPublicKey
aPub (ByteString -> RecipientInfo)
-> Either StoreError ByteString -> Either StoreError RecipientInfo
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Either StoreError ByteString
ek)
        Left StoreError
err -> Either StoreError RecipientInfo
-> m (Either StoreError RecipientInfo)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either StoreError RecipientInfo
 -> m (Either StoreError RecipientInfo))
-> Either StoreError RecipientInfo
-> m (Either StoreError RecipientInfo)
forall a b. (a -> b) -> a -> b
$ StoreError -> Either StoreError RecipientInfo
forall a b. a -> Either a b
Left StoreError
err
  where
    obj :: Certificate
obj = Signed Certificate -> Certificate
forall a. (Show a, Eq a, ASN1Object a) => Signed a -> a
signedObject (SignedCertificate -> Signed Certificate
forall a. (Show a, Eq a, ASN1Object a) => SignedExact a -> Signed a
getSigned SignedCertificate
cert)
    isn :: IssuerAndSerialNumber
isn = DistinguishedName -> Integer -> IssuerAndSerialNumber
IssuerAndSerialNumber (Certificate -> DistinguishedName
certIssuerDN Certificate
obj) (Certificate -> Integer
certSerial Certificate
obj)

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

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

-- | Use a Key Agreement recipient, knowing the recipient private key.  The
-- recipient certificate is also required to locate which encrypted key to use.
--
-- This function can be used as parameter to
-- 'Crypto.Store.CMS.openEnvelopedData'.
withRecipientKeyAgree :: MonadRandom m => PrivKey -> SignedCertificate -> ConsumerOfRI m
withRecipientKeyAgree :: forall (m :: * -> *).
MonadRandom m =>
PrivKey -> SignedCertificate -> ConsumerOfRI m
withRecipientKeyAgree PrivKey
priv SignedCertificate
cert (KARI KARecipientInfo{[RecipientEncryptedKey]
Maybe ByteString
KeyAgreementParams
OriginatorIdentifierOrKey
kaOriginator :: KARecipientInfo -> OriginatorIdentifierOrKey
kaUkm :: KARecipientInfo -> Maybe ByteString
kaKeyAgreementParams :: KARecipientInfo -> KeyAgreementParams
kaRecipientEncryptedKeys :: KARecipientInfo -> [RecipientEncryptedKey]
kaOriginator :: OriginatorIdentifierOrKey
kaUkm :: Maybe ByteString
kaKeyAgreementParams :: KeyAgreementParams
kaRecipientEncryptedKeys :: [RecipientEncryptedKey]
..}) =
    case OriginatorIdentifierOrKey
kaOriginator of
        OriginatorPublic (OriginatorPublicKeyEC [ASN1]
_ BitArray
ba) ->
            case SignedCertificate -> [RecipientEncryptedKey] -> Maybe ByteString
findRecipientEncryptedKey SignedCertificate
cert [RecipientEncryptedKey]
kaRecipientEncryptedKeys of
                Maybe ByteString
Nothing -> Either StoreError ByteString -> m (Either StoreError ByteString)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (StoreError -> Either StoreError ByteString
forall a b. a -> Either a b
Left StoreError
RecipientKeyNotFound)
                Just ByteString
ek ->
                    let pub :: ByteString
pub = BitArray -> ByteString
bitArrayGetData BitArray
ba
                     in Either StoreError ByteString -> m (Either StoreError ByteString)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (KeyAgreementParams
-> Maybe ByteString
-> PrivKey
-> ByteString
-> ByteString
-> Either StoreError ByteString
forall ba.
ByteArray ba =>
KeyAgreementParams
-> Maybe ByteString
-> PrivKey
-> ByteString
-> ba
-> Either StoreError ba
ecdhDecrypt KeyAgreementParams
kaKeyAgreementParams Maybe ByteString
kaUkm PrivKey
priv ByteString
pub ByteString
ek)
        OriginatorIdentifierOrKey
_ -> Either StoreError ByteString -> m (Either StoreError ByteString)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (StoreError -> Either StoreError ByteString
forall a b. a -> Either a b
Left StoreError
UnsupportedOriginatorFormat)
withRecipientKeyAgree PrivKey
_ SignedCertificate
_ RecipientInfo
_        = Either StoreError ByteString -> m (Either StoreError ByteString)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (StoreError -> Either StoreError ByteString
forall a b. a -> Either a b
Left StoreError
RecipientTypeMismatch)

-- | Generate a Key Encryption Key recipient from a key encryption key and
-- desired algorithm.  The recipient may identify the KEK that was used with
-- the supplied identifier.
--
-- This function can be used as parameter to 'Crypto.Store.CMS.envelopData'.
--
-- To avoid decreasing the security strength, Key Encryption parameters should
-- use a key size equal or greater than the content encryption key.
forKeyRecipient :: MonadRandom m
                => KeyEncryptionKey
                -> KeyIdentifier
                -> KeyEncryptionParams
                -> ProducerOfRI m
forKeyRecipient :: forall (m :: * -> *).
MonadRandom m =>
ByteString
-> KeyIdentifier -> KeyEncryptionParams -> ProducerOfRI m
forKeyRecipient ByteString
key KeyIdentifier
kid KeyEncryptionParams
params ByteString
inkey = do
    Either StoreError ByteString
ek <- ByteString
-> KeyEncryptionParams
-> ByteString
-> m (Either StoreError ByteString)
forall (m :: * -> *) kek ba.
(MonadRandom m, ByteArray kek, ByteArray ba) =>
kek -> KeyEncryptionParams -> ba -> m (Either StoreError ba)
keyEncrypt ByteString
key KeyEncryptionParams
params ByteString
inkey
    Either StoreError RecipientInfo
-> m (Either StoreError RecipientInfo)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (KEKRecipientInfo -> RecipientInfo
KEKRI (KEKRecipientInfo -> RecipientInfo)
-> (ByteString -> KEKRecipientInfo) -> ByteString -> RecipientInfo
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> KEKRecipientInfo
build (ByteString -> RecipientInfo)
-> Either StoreError ByteString -> Either StoreError RecipientInfo
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Either StoreError ByteString
ek)
  where
    build :: ByteString -> KEKRecipientInfo
build ByteString
ek = KEKRecipientInfo
                   { kekId :: KeyIdentifier
kekId = KeyIdentifier
kid
                   , kekKeyEncryptionParams :: KeyEncryptionParams
kekKeyEncryptionParams = KeyEncryptionParams
params
                   , kekEncryptedKey :: ByteString
kekEncryptedKey = ByteString
ek
                   }

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

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

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