{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RecordWildCards #-}
module Crypto.Store.CMS.AuthEnveloped
( AuthEnvelopedData(..)
, encodeAuthAttrs
) where
import Control.Applicative
import Control.Monad
import Data.ASN1.Types
import Data.ByteArray (convert)
import Data.ByteString (ByteString)
import Crypto.Cipher.Types
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.Enveloped
import Crypto.Store.CMS.OriginatorInfo
import Crypto.Store.CMS.Type
import Crypto.Store.CMS.Util
data AuthEnvelopedData content = AuthEnvelopedData
{ forall content. AuthEnvelopedData content -> OriginatorInfo
aeOriginatorInfo :: OriginatorInfo
, forall content. AuthEnvelopedData content -> [RecipientInfo]
aeRecipientInfos :: [RecipientInfo]
, forall content. AuthEnvelopedData content -> ContentType
aeContentType :: ContentType
, forall content.
AuthEnvelopedData content
-> ASN1ObjectExact AuthContentEncryptionParams
aeContentEncryptionParams :: ASN1ObjectExact AuthContentEncryptionParams
, forall content. AuthEnvelopedData content -> content
aeEncryptedContent :: content
, forall content. AuthEnvelopedData content -> [Attribute]
aeAuthAttrs :: [Attribute]
, forall content.
AuthEnvelopedData content -> MessageAuthenticationCode
aeMAC :: MessageAuthenticationCode
, forall content. AuthEnvelopedData content -> [Attribute]
aeUnauthAttrs :: [Attribute]
}
deriving (Int -> AuthEnvelopedData content -> ShowS
[AuthEnvelopedData content] -> ShowS
AuthEnvelopedData content -> String
(Int -> AuthEnvelopedData content -> ShowS)
-> (AuthEnvelopedData content -> String)
-> ([AuthEnvelopedData content] -> ShowS)
-> Show (AuthEnvelopedData content)
forall content.
Show content =>
Int -> AuthEnvelopedData content -> ShowS
forall content.
Show content =>
[AuthEnvelopedData content] -> ShowS
forall content. Show content => AuthEnvelopedData content -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall content.
Show content =>
Int -> AuthEnvelopedData content -> ShowS
showsPrec :: Int -> AuthEnvelopedData content -> ShowS
$cshow :: forall content. Show content => AuthEnvelopedData content -> String
show :: AuthEnvelopedData content -> String
$cshowList :: forall content.
Show content =>
[AuthEnvelopedData content] -> ShowS
showList :: [AuthEnvelopedData content] -> ShowS
Show,AuthEnvelopedData content -> AuthEnvelopedData content -> Bool
(AuthEnvelopedData content -> AuthEnvelopedData content -> Bool)
-> (AuthEnvelopedData content -> AuthEnvelopedData content -> Bool)
-> Eq (AuthEnvelopedData content)
forall content.
Eq content =>
AuthEnvelopedData content -> AuthEnvelopedData content -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall content.
Eq content =>
AuthEnvelopedData content -> AuthEnvelopedData content -> Bool
== :: AuthEnvelopedData content -> AuthEnvelopedData content -> Bool
$c/= :: forall content.
Eq content =>
AuthEnvelopedData content -> AuthEnvelopedData content -> Bool
/= :: AuthEnvelopedData content -> AuthEnvelopedData content -> Bool
Eq)
instance ProduceASN1Object ASN1P (AuthEnvelopedData (Encap EncryptedContent)) where
asn1s :: AuthEnvelopedData (Encap ByteString) -> ASN1Stream ASN1P
asn1s AuthEnvelopedData{[Attribute]
[RecipientInfo]
MessageAuthenticationCode
ASN1ObjectExact AuthContentEncryptionParams
Encap ByteString
ContentType
OriginatorInfo
aeOriginatorInfo :: forall content. AuthEnvelopedData content -> OriginatorInfo
aeRecipientInfos :: forall content. AuthEnvelopedData content -> [RecipientInfo]
aeContentType :: forall content. AuthEnvelopedData content -> ContentType
aeContentEncryptionParams :: forall content.
AuthEnvelopedData content
-> ASN1ObjectExact AuthContentEncryptionParams
aeEncryptedContent :: forall content. AuthEnvelopedData content -> content
aeAuthAttrs :: forall content. AuthEnvelopedData content -> [Attribute]
aeMAC :: forall content.
AuthEnvelopedData content -> MessageAuthenticationCode
aeUnauthAttrs :: forall content. AuthEnvelopedData content -> [Attribute]
aeOriginatorInfo :: OriginatorInfo
aeRecipientInfos :: [RecipientInfo]
aeContentType :: ContentType
aeContentEncryptionParams :: ASN1ObjectExact AuthContentEncryptionParams
aeEncryptedContent :: Encap ByteString
aeAuthAttrs :: [Attribute]
aeMAC :: MessageAuthenticationCode
aeUnauthAttrs :: [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
aa ASN1Stream ASN1P -> ASN1Stream ASN1P -> ASN1Stream ASN1P
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream ASN1P
tag 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
0
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]
aeRecipientInfos)
eci :: ASN1Stream ASN1P
eci = (ContentType, ASN1ObjectExact AuthContentEncryptionParams,
Encap ByteString)
-> ASN1Stream ASN1P
forall e alg.
(ASN1Elem e, ProduceASN1Object e alg) =>
(ContentType, alg, Encap ByteString) -> ASN1Stream e
encryptedContentInfoASN1S
(ContentType
aeContentType, ASN1ObjectExact AuthContentEncryptionParams
aeContentEncryptionParams, Encap ByteString
aeEncryptedContent)
aa :: ASN1Stream ASN1P
aa = ASN1ConstructionType -> [Attribute] -> ASN1Stream ASN1P
forall e.
ASN1Elem e =>
ASN1ConstructionType -> [Attribute] -> ASN1Stream e
attributesASN1S (ASN1Class -> Int -> ASN1ConstructionType
Container ASN1Class
Context Int
1) [Attribute]
aeAuthAttrs
tag :: ASN1Stream ASN1P
tag = ByteString -> ASN1Stream ASN1P
forall e. ASN1Elem e => ByteString -> ASN1Stream e
gOctetString (MessageAuthenticationCode -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
convert MessageAuthenticationCode
aeMAC)
ua :: ASN1Stream ASN1P
ua = ASN1ConstructionType -> [Attribute] -> ASN1Stream ASN1P
forall e.
ASN1Elem e =>
ASN1ConstructionType -> [Attribute] -> ASN1Stream e
attributesASN1S (ASN1Class -> Int -> ASN1ConstructionType
Container ASN1Class
Context Int
2) [Attribute]
aeUnauthAttrs
oi :: ASN1Stream ASN1P
oi | OriginatorInfo
aeOriginatorInfo 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
aeOriginatorInfo
instance ParseASN1Object [ASN1Event] (AuthEnvelopedData (Encap EncryptedContent)) where
parse :: ParseASN1 [ASN1Event] (AuthEnvelopedData (Encap ByteString))
parse =
ASN1ConstructionType
-> ParseASN1 [ASN1Event] (AuthEnvelopedData (Encap ByteString))
-> ParseASN1 [ASN1Event] (AuthEnvelopedData (Encap ByteString))
forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
onNextContainer ASN1ConstructionType
Sequence (ParseASN1 [ASN1Event] (AuthEnvelopedData (Encap ByteString))
-> ParseASN1 [ASN1Event] (AuthEnvelopedData (Encap ByteString)))
-> ParseASN1 [ASN1Event] (AuthEnvelopedData (Encap ByteString))
-> ParseASN1 [ASN1Event] (AuthEnvelopedData (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. Eq a => a -> a -> Bool
/= Integer
0) (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
"AuthEnvelopedData: 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, ASN1ObjectExact AuthContentEncryptionParams
params, Encap ByteString
ec) <- ParseASN1
[ASN1Event]
(ContentType, ASN1ObjectExact AuthContentEncryptionParams,
Encap ByteString)
forall e alg.
ParseASN1Object e alg =>
ParseASN1 e (ContentType, alg, Encap ByteString)
parseEncryptedContentInfo
[Attribute]
aAttrs <- ASN1ConstructionType -> ParseASN1 [ASN1Event] [Attribute]
forall e.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e [Attribute]
parseAttributes (ASN1Class -> Int -> ASN1ConstructionType
Container ASN1Class
Context Int
1)
OctetString ByteString
tag <- ParseASN1 [ASN1Event] ASN1
forall e. Monoid e => ParseASN1 e ASN1
getNext
[Attribute]
uAttrs <- ASN1ConstructionType -> ParseASN1 [ASN1Event] [Attribute]
forall e.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e [Attribute]
parseAttributes (ASN1Class -> Int -> ASN1ConstructionType
Container ASN1Class
Context Int
2)
AuthEnvelopedData (Encap ByteString)
-> ParseASN1 [ASN1Event] (AuthEnvelopedData (Encap ByteString))
forall a. a -> ParseASN1 [ASN1Event] a
forall (m :: * -> *) a. Monad m => a -> m a
return AuthEnvelopedData { aeOriginatorInfo :: OriginatorInfo
aeOriginatorInfo = OriginatorInfo
oi
, aeContentType :: ContentType
aeContentType = ContentType
ct
, aeRecipientInfos :: [RecipientInfo]
aeRecipientInfos = [RecipientInfo]
ris
, aeContentEncryptionParams :: ASN1ObjectExact AuthContentEncryptionParams
aeContentEncryptionParams = ASN1ObjectExact AuthContentEncryptionParams
params
, aeEncryptedContent :: Encap ByteString
aeEncryptedContent = Encap ByteString
ec
, aeAuthAttrs :: [Attribute]
aeAuthAttrs = [Attribute]
aAttrs
, aeMAC :: MessageAuthenticationCode
aeMAC = Bytes -> MessageAuthenticationCode
AuthTag (Bytes -> MessageAuthenticationCode)
-> Bytes -> MessageAuthenticationCode
forall a b. (a -> b) -> a -> b
$ ByteString -> Bytes
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
convert ByteString
tag
, aeUnauthAttrs :: [Attribute]
aeUnauthAttrs = [Attribute]
uAttrs
}
encodeAuthAttrs :: [Attribute] -> ByteString
encodeAuthAttrs :: [Attribute] -> ByteString
encodeAuthAttrs [] = ByteString
forall a. Monoid a => a
mempty
encodeAuthAttrs [Attribute]
l = ASN1Stream ASN1P -> ByteString
encodeASN1S (ASN1Stream ASN1P -> ByteString) -> ASN1Stream ASN1P -> ByteString
forall a b. (a -> b) -> a -> b
$ ASN1ConstructionType -> ASN1Stream ASN1P -> ASN1Stream ASN1P
forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container ASN1ConstructionType
Set ([Attribute] -> ASN1Stream ASN1P
forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
asn1s [Attribute]
l)