    -- |
    -- Module      : Crypto.Store.CMS.OriginatorInfo
    -- 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.OriginatorInfo
        ( OriginatorInfo(..)
        , CertificateChoice(..)
        , OtherCertificateFormat(..)
        , RevocationInfoChoice(..)
        , OtherRevocationInfoFormat(..)
        , originatorInfoASN1S
        , parseOriginatorInfo
        , hasChoiceOther
        ) where

    import Control.Applicative

    import Data.ASN1.Types
    import Data.Maybe (fromMaybe)
    import Data.Semigroup
    import Data.X509

    import Crypto.Store.ASN1.Generate
    import Crypto.Store.ASN1.Parse
    import Crypto.Store.CMS.Util

    -- | Data types where choice "other" is available.
    class HasChoiceOther a where
        -- | Return true when choice "other" is selected.
        hasChoiceOther :: a -> Bool

    instance (HasChoiceOther a, Foldable f) => HasChoiceOther (f a) where
        hasChoiceOther :: f a -> Bool
    hasChoiceOther = (a -> Bool) -> f a -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    any a -> Bool
    forall a. HasChoiceOther a => a -> Bool
    hasChoiceOther

    -- | Information about the originator of the content info, to be used when
    -- a key management algorithm requires this information.
    data OriginatorInfo = OriginatorInfo
        { OriginatorInfo -> [CertificateChoice]
    originatorCerts :: [CertificateChoice]
          -- ^ The collection of certificates
        , OriginatorInfo -> [RevocationInfoChoice]
    originatorCRLs  :: [RevocationInfoChoice]
          -- ^ The collection of CRLs
        }
        deriving (Int -> OriginatorInfo -> ShowS
    [OriginatorInfo] -> ShowS
    OriginatorInfo -> String
    (Int -> OriginatorInfo -> ShowS)
    -> (OriginatorInfo -> String)
    -> ([OriginatorInfo] -> ShowS)
    -> Show OriginatorInfo
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> OriginatorInfo -> ShowS
    showsPrec :: Int -> OriginatorInfo -> ShowS
    $cshow :: OriginatorInfo -> String
    show :: OriginatorInfo -> String
    $cshowList :: [OriginatorInfo] -> ShowS
    showList :: [OriginatorInfo] -> ShowS
    Show,OriginatorInfo -> OriginatorInfo -> Bool
    (OriginatorInfo -> OriginatorInfo -> Bool)
    -> (OriginatorInfo -> OriginatorInfo -> Bool) -> Eq OriginatorInfo
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: OriginatorInfo -> OriginatorInfo -> Bool
    == :: OriginatorInfo -> OriginatorInfo -> Bool
    $c/= :: OriginatorInfo -> OriginatorInfo -> Bool
    /= :: OriginatorInfo -> OriginatorInfo -> Bool
    Eq)

    instance Semigroup OriginatorInfo where
        OriginatorInfo [CertificateChoice]
    a [RevocationInfoChoice]
    b <> :: OriginatorInfo -> OriginatorInfo -> OriginatorInfo
    <> OriginatorInfo [CertificateChoice]
    c [RevocationInfoChoice]
    d = [CertificateChoice] -> [RevocationInfoChoice] -> OriginatorInfo
    OriginatorInfo ([CertificateChoice]
    a [CertificateChoice] -> [CertificateChoice] -> [CertificateChoice]
    forall a. Semigroup a => a -> a -> a
    <> [CertificateChoice]
    c) ([RevocationInfoChoice]
    b [RevocationInfoChoice]
    -> [RevocationInfoChoice] -> [RevocationInfoChoice]
    forall a. Semigroup a => a -> a -> a
    <> [RevocationInfoChoice]
    d)

    instance Monoid OriginatorInfo where
        mempty :: OriginatorInfo
    mempty = [CertificateChoice] -> [RevocationInfoChoice] -> OriginatorInfo
    OriginatorInfo [] []
        mappend :: OriginatorInfo -> OriginatorInfo -> OriginatorInfo
    mappend = OriginatorInfo -> OriginatorInfo -> OriginatorInfo
    forall a. Semigroup a => a -> a -> a
    (<>)

    instance HasChoiceOther OriginatorInfo where
        hasChoiceOther :: OriginatorInfo -> Bool
    hasChoiceOther OriginatorInfo{[RevocationInfoChoice]
    [CertificateChoice]
    originatorCerts :: OriginatorInfo -> [CertificateChoice]
    originatorCRLs :: OriginatorInfo -> [RevocationInfoChoice]
    originatorCerts :: [CertificateChoice]
    originatorCRLs :: [RevocationInfoChoice]
    ..} =
            [CertificateChoice] -> Bool
    forall a. HasChoiceOther a => a -> Bool
    hasChoiceOther [CertificateChoice]
    originatorCerts Bool -> Bool -> Bool
    || [RevocationInfoChoice] -> Bool
    forall a. HasChoiceOther a => a -> Bool
    hasChoiceOther [RevocationInfoChoice]
    originatorCRLs

    instance ProduceASN1Object ASN1P OriginatorInfo where
        asn1s :: OriginatorInfo -> ASN1Stream ASN1P
    asn1s = ASN1ConstructionType -> OriginatorInfo -> ASN1Stream ASN1P
    originatorInfoASN1S ASN1ConstructionType
    Sequence

    instance ParseASN1Object [ASN1Event] OriginatorInfo where
        parse :: ParseASN1 [ASN1Event] OriginatorInfo
    parse = ASN1ConstructionType -> ParseASN1 [ASN1Event] OriginatorInfo
    parseOriginatorInfo ASN1ConstructionType
    Sequence

    -- | Generate ASN.1 with the specified constructed type for the originator
    -- information.
    originatorInfoASN1S :: ASN1ConstructionType -> OriginatorInfo -> ASN1PS
    originatorInfoASN1S :: ASN1ConstructionType -> OriginatorInfo -> ASN1Stream ASN1P
    originatorInfoASN1S ASN1ConstructionType
    ty OriginatorInfo{[RevocationInfoChoice]
    [CertificateChoice]
    originatorCerts :: OriginatorInfo -> [CertificateChoice]
    originatorCRLs :: OriginatorInfo -> [RevocationInfoChoice]
    originatorCerts :: [CertificateChoice]
    originatorCRLs :: [RevocationInfoChoice]
    ..} =
        ASN1ConstructionType -> ASN1Stream ASN1P -> ASN1Stream ASN1P
    forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    asn1Container ASN1ConstructionType
    ty (ASN1Stream ASN1P -> ASN1Stream ASN1P)
    -> ASN1Stream ASN1P -> ASN1Stream ASN1P
    forall a b. (a -> b) -> a -> b
    $ Int -> [CertificateChoice] -> ASN1Stream ASN1P
    forall {t :: * -> *} {e} {a}.
    (Foldable t, ASN1Elem e, ProduceASN1Object e (t a)) =>
    Int -> t a -> [e] -> [e]
    gen Int
    0 [CertificateChoice]
    originatorCerts ASN1Stream ASN1P -> ASN1Stream ASN1P -> ASN1Stream ASN1P
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> [RevocationInfoChoice] -> ASN1Stream ASN1P
    forall {t :: * -> *} {e} {a}.
    (Foldable t, ASN1Elem e, ProduceASN1Object e (t a)) =>
    Int -> t a -> [e] -> [e]
    gen Int
    1 [RevocationInfoChoice]
    originatorCRLs
      where
        gen :: Int -> t a -> [e] -> [e]
    gen Int
    tag t a
    list
            | t a -> Bool
    forall a. t a -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null t a
    list = [e] -> [e]
    forall a. a -> a
    id
            | Bool
    otherwise = ASN1ConstructionType -> ([e] -> [e]) -> [e] -> [e]
    forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    asn1Container (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    tag) (t a -> [e] -> [e]
    forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
    asn1s t a
    list)

    -- | Parse originator information with the specified constructed type.
    parseOriginatorInfo :: ASN1ConstructionType
                        -> ParseASN1 [ASN1Event] OriginatorInfo
    parseOriginatorInfo :: ASN1ConstructionType -> ParseASN1 [ASN1Event] OriginatorInfo
    parseOriginatorInfo ASN1ConstructionType
    ty = ASN1ConstructionType
    -> ParseASN1 [ASN1Event] OriginatorInfo
    -> ParseASN1 [ASN1Event] OriginatorInfo
    forall e a.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
    onNextContainer ASN1ConstructionType
    ty (ParseASN1 [ASN1Event] OriginatorInfo
     -> ParseASN1 [ASN1Event] OriginatorInfo)
    -> ParseASN1 [ASN1Event] OriginatorInfo
    -> ParseASN1 [ASN1Event] OriginatorInfo
    forall a b. (a -> b) -> a -> b
    $ do
        [CertificateChoice]
    certs <- Int -> ParseASN1 [ASN1Event] [CertificateChoice]
    forall {e} {a}. ParseASN1Object e a => Int -> ParseASN1 e [a]
    parseOptList Int
    0
        [RevocationInfoChoice]
    crls  <- Int -> ParseASN1 [ASN1Event] [RevocationInfoChoice]
    forall {e} {a}. ParseASN1Object e a => Int -> ParseASN1 e [a]
    parseOptList Int
    1
        OriginatorInfo -> ParseASN1 [ASN1Event] OriginatorInfo
    forall a. a -> ParseASN1 [ASN1Event] a
    forall (m :: * -> *) a. Monad m => a -> m a
    return OriginatorInfo { originatorCerts :: [CertificateChoice]
    originatorCerts = [CertificateChoice]
    certs
                              , originatorCRLs :: [RevocationInfoChoice]
    originatorCRLs  = [RevocationInfoChoice]
    crls
                              }
      where
        parseOptList :: Int -> ParseASN1 e [a]
    parseOptList Int
    tag =
            [a] -> Maybe [a] -> [a]
    forall a. a -> Maybe a -> a
    fromMaybe [] (Maybe [a] -> [a]) -> ParseASN1 e (Maybe [a]) -> ParseASN1 e [a]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ASN1ConstructionType -> ParseASN1 e [a] -> ParseASN1 e (Maybe [a])
    forall e a.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e (Maybe a)
    onNextContainerMaybe (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    tag) ParseASN1 e [a]
    forall e obj. ParseASN1Object e obj => ParseASN1 e obj
    parse

    -- | Union type related to certificate formats.
    data CertificateChoice
        = CertificateCertificate SignedCertificate -- ^ X.509 certificate
        | CertificateOther OtherCertificateFormat  -- ^ Other format
        deriving (Int -> CertificateChoice -> ShowS
    [CertificateChoice] -> ShowS
    CertificateChoice -> String
    (Int -> CertificateChoice -> ShowS)
    -> (CertificateChoice -> String)
    -> ([CertificateChoice] -> ShowS)
    -> Show CertificateChoice
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> CertificateChoice -> ShowS
    showsPrec :: Int -> CertificateChoice -> ShowS
    $cshow :: CertificateChoice -> String
    show :: CertificateChoice -> String
    $cshowList :: [CertificateChoice] -> ShowS
    showList :: [CertificateChoice] -> ShowS
    Show,CertificateChoice -> CertificateChoice -> Bool
    (CertificateChoice -> CertificateChoice -> Bool)
    -> (CertificateChoice -> CertificateChoice -> Bool)
    -> Eq CertificateChoice
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: CertificateChoice -> CertificateChoice -> Bool
    == :: CertificateChoice -> CertificateChoice -> Bool
    $c/= :: CertificateChoice -> CertificateChoice -> Bool
    /= :: CertificateChoice -> CertificateChoice -> Bool
    Eq)

    instance HasChoiceOther CertificateChoice where
        hasChoiceOther :: CertificateChoice -> Bool
    hasChoiceOther (CertificateOther OtherCertificateFormat
    _) = Bool
    True
        hasChoiceOther CertificateChoice
    _                    = Bool
    False

    instance ProduceASN1Object ASN1P CertificateChoice where
        asn1s :: CertificateChoice -> ASN1Stream ASN1P
    asn1s (CertificateCertificate SignedCertificate
    cert) = SignedCertificate -> ASN1Stream ASN1P
    forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
    asn1s SignedCertificate
    cert
        asn1s (CertificateOther OtherCertificateFormat
    other) =
            ASN1ConstructionType -> OtherCertificateFormat -> ASN1Stream ASN1P
    forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> OtherCertificateFormat -> ASN1Stream e
    otherCertificateFormatASN1PS (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    3) OtherCertificateFormat
    other

    instance ParseASN1Object [ASN1Event] CertificateChoice where
        parse :: ParseASN1 [ASN1Event] CertificateChoice
    parse = ParseASN1 [ASN1Event] CertificateChoice
    parseMain ParseASN1 [ASN1Event] CertificateChoice
    -> ParseASN1 [ASN1Event] CertificateChoice
    -> ParseASN1 [ASN1Event] CertificateChoice
    forall a.
    ParseASN1 [ASN1Event] a
    -> ParseASN1 [ASN1Event] a -> ParseASN1 [ASN1Event] a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> ParseASN1 [ASN1Event] CertificateChoice
    parseOther
          where parseMain :: ParseASN1 [ASN1Event] CertificateChoice
    parseMain  = SignedCertificate -> CertificateChoice
    CertificateCertificate (SignedCertificate -> CertificateChoice)
    -> ParseASN1 [ASN1Event] SignedCertificate
    -> ParseASN1 [ASN1Event] CertificateChoice
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ParseASN1 [ASN1Event] SignedCertificate
    forall e obj. ParseASN1Object e obj => ParseASN1 e obj
    parse
                parseOther :: ParseASN1 [ASN1Event] CertificateChoice
    parseOther = OtherCertificateFormat -> CertificateChoice
    CertificateOther (OtherCertificateFormat -> CertificateChoice)
    -> ParseASN1 [ASN1Event] OtherCertificateFormat
    -> ParseASN1 [ASN1Event] CertificateChoice
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>
                    ASN1ConstructionType
    -> ParseASN1 [ASN1Event] OtherCertificateFormat
    forall e.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e OtherCertificateFormat
    parseOtherCertificateFormat (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    3)

    -- | Union type related to revocation info formats.
    data RevocationInfoChoice
        = RevocationInfoCRL SignedCRL
          -- ^ A CRL, ARL, Delta CRL, or an ACRL
        | RevocationInfoOther OtherRevocationInfoFormat
          -- ^ Other format
        deriving (Int -> RevocationInfoChoice -> ShowS
    [RevocationInfoChoice] -> ShowS
    RevocationInfoChoice -> String
    (Int -> RevocationInfoChoice -> ShowS)
    -> (RevocationInfoChoice -> String)
    -> ([RevocationInfoChoice] -> ShowS)
    -> Show RevocationInfoChoice
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> RevocationInfoChoice -> ShowS
    showsPrec :: Int -> RevocationInfoChoice -> ShowS
    $cshow :: RevocationInfoChoice -> String
    show :: RevocationInfoChoice -> String
    $cshowList :: [RevocationInfoChoice] -> ShowS
    showList :: [RevocationInfoChoice] -> ShowS
    Show,RevocationInfoChoice -> RevocationInfoChoice -> Bool
    (RevocationInfoChoice -> RevocationInfoChoice -> Bool)
    -> (RevocationInfoChoice -> RevocationInfoChoice -> Bool)
    -> Eq RevocationInfoChoice
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: RevocationInfoChoice -> RevocationInfoChoice -> Bool
    == :: RevocationInfoChoice -> RevocationInfoChoice -> Bool
    $c/= :: RevocationInfoChoice -> RevocationInfoChoice -> Bool
    /= :: RevocationInfoChoice -> RevocationInfoChoice -> Bool
    Eq)

    instance HasChoiceOther RevocationInfoChoice where
        hasChoiceOther :: RevocationInfoChoice -> Bool
    hasChoiceOther (RevocationInfoOther OtherRevocationInfoFormat
    _) = Bool
    True
        hasChoiceOther RevocationInfoChoice
    _                       = Bool
    False

    instance ProduceASN1Object ASN1P RevocationInfoChoice where
        asn1s :: RevocationInfoChoice -> ASN1Stream ASN1P
    asn1s (RevocationInfoCRL SignedCRL
    crl) = SignedCRL -> ASN1Stream ASN1P
    forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
    asn1s SignedCRL
    crl
        asn1s (RevocationInfoOther OtherRevocationInfoFormat
    other) =
            ASN1ConstructionType
    -> OtherRevocationInfoFormat -> ASN1Stream ASN1P
    forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> OtherRevocationInfoFormat -> ASN1Stream e
    otherRevocationInfoFormatASN1PS (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    1) OtherRevocationInfoFormat
    other

    instance ParseASN1Object [ASN1Event] RevocationInfoChoice where
        parse :: ParseASN1 [ASN1Event] RevocationInfoChoice
    parse = ParseASN1 [ASN1Event] RevocationInfoChoice
    parseMain ParseASN1 [ASN1Event] RevocationInfoChoice
    -> ParseASN1 [ASN1Event] RevocationInfoChoice
    -> ParseASN1 [ASN1Event] RevocationInfoChoice
    forall a.
    ParseASN1 [ASN1Event] a
    -> ParseASN1 [ASN1Event] a -> ParseASN1 [ASN1Event] a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> ParseASN1 [ASN1Event] RevocationInfoChoice
    parseOther
          where parseMain :: ParseASN1 [ASN1Event] RevocationInfoChoice
    parseMain  = SignedCRL -> RevocationInfoChoice
    RevocationInfoCRL (SignedCRL -> RevocationInfoChoice)
    -> ParseASN1 [ASN1Event] SignedCRL
    -> ParseASN1 [ASN1Event] RevocationInfoChoice
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ParseASN1 [ASN1Event] SignedCRL
    forall e obj. ParseASN1Object e obj => ParseASN1 e obj
    parse
                parseOther :: ParseASN1 [ASN1Event] RevocationInfoChoice
    parseOther = OtherRevocationInfoFormat -> RevocationInfoChoice
    RevocationInfoOther (OtherRevocationInfoFormat -> RevocationInfoChoice)
    -> ParseASN1 [ASN1Event] OtherRevocationInfoFormat
    -> ParseASN1 [ASN1Event] RevocationInfoChoice
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>
                    ASN1ConstructionType
    -> ParseASN1 [ASN1Event] OtherRevocationInfoFormat
    forall e.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e OtherRevocationInfoFormat
    parseOtherRevocationInfoFormat (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    1)

    -- | Certificate information in a format not supported natively.
    data OtherCertificateFormat = OtherCertificateFormat
        { OtherCertificateFormat -> OID
    otherCertFormat :: OID    -- ^ Format identifier
        , OtherCertificateFormat -> [ASN1]
    otherCertValues :: [ASN1] -- ^ ASN.1 values using this format
        }
        deriving (Int -> OtherCertificateFormat -> ShowS
    [OtherCertificateFormat] -> ShowS
    OtherCertificateFormat -> String
    (Int -> OtherCertificateFormat -> ShowS)
    -> (OtherCertificateFormat -> String)
    -> ([OtherCertificateFormat] -> ShowS)
    -> Show OtherCertificateFormat
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> OtherCertificateFormat -> ShowS
    showsPrec :: Int -> OtherCertificateFormat -> ShowS
    $cshow :: OtherCertificateFormat -> String
    show :: OtherCertificateFormat -> String
    $cshowList :: [OtherCertificateFormat] -> ShowS
    showList :: [OtherCertificateFormat] -> ShowS
    Show,OtherCertificateFormat -> OtherCertificateFormat -> Bool
    (OtherCertificateFormat -> OtherCertificateFormat -> Bool)
    -> (OtherCertificateFormat -> OtherCertificateFormat -> Bool)
    -> Eq OtherCertificateFormat
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: OtherCertificateFormat -> OtherCertificateFormat -> Bool
    == :: OtherCertificateFormat -> OtherCertificateFormat -> Bool
    $c/= :: OtherCertificateFormat -> OtherCertificateFormat -> Bool
    /= :: OtherCertificateFormat -> OtherCertificateFormat -> Bool
    Eq)

    otherCertificateFormatASN1PS :: ASN1Elem e
                                 => ASN1ConstructionType
                                 -> OtherCertificateFormat
                                 -> ASN1Stream e
    otherCertificateFormatASN1PS :: forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> OtherCertificateFormat -> ASN1Stream e
    otherCertificateFormatASN1PS ASN1ConstructionType
    ty OtherCertificateFormat{OID
    [ASN1]
    otherCertFormat :: OtherCertificateFormat -> OID
    otherCertValues :: OtherCertificateFormat -> [ASN1]
    otherCertFormat :: OID
    otherCertValues :: [ASN1]
    ..} =
        ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    asn1Container ASN1ConstructionType
    ty (ASN1Stream e
    f ASN1Stream e -> ASN1Stream e -> ASN1Stream e
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ASN1Stream e
    v)
      where f :: ASN1Stream e
    f = OID -> ASN1Stream e
    forall e. ASN1Elem e => OID -> ASN1Stream e
    gOID OID
    otherCertFormat
            v :: ASN1Stream e
    v = [ASN1] -> ASN1Stream e
    forall e. ASN1Elem e => [ASN1] -> ASN1Stream e
    gMany [ASN1]
    otherCertValues

    parseOtherCertificateFormat :: Monoid e
                                => ASN1ConstructionType
                                -> ParseASN1 e OtherCertificateFormat
    parseOtherCertificateFormat :: forall e.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e OtherCertificateFormat
    parseOtherCertificateFormat ASN1ConstructionType
    ty = ASN1ConstructionType
    -> ParseASN1 e OtherCertificateFormat
    -> ParseASN1 e OtherCertificateFormat
    forall e a.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
    onNextContainer ASN1ConstructionType
    ty (ParseASN1 e OtherCertificateFormat
     -> ParseASN1 e OtherCertificateFormat)
    -> ParseASN1 e OtherCertificateFormat
    -> ParseASN1 e OtherCertificateFormat
    forall a b. (a -> b) -> a -> b
    $ do
        OID OID
    f <- ParseASN1 e ASN1
    forall e. Monoid e => ParseASN1 e ASN1
    getNext
        [ASN1]
    v <- 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
        OtherCertificateFormat -> ParseASN1 e OtherCertificateFormat
    forall a. a -> ParseASN1 e a
    forall (m :: * -> *) a. Monad m => a -> m a
    return OtherCertificateFormat { otherCertFormat :: OID
    otherCertFormat = OID
    f
                                      , otherCertValues :: [ASN1]
    otherCertValues = [ASN1]
    v }

    -- | Revocation information in a format not supported natively.
    data OtherRevocationInfoFormat = OtherRevocationInfoFormat
        { OtherRevocationInfoFormat -> OID
    otherRevInfoFormat :: OID    -- ^ Format identifier
        , OtherRevocationInfoFormat -> [ASN1]
    otherRevInfoValues :: [ASN1] -- ^ ASN.1 values using this format
        }
        deriving (Int -> OtherRevocationInfoFormat -> ShowS
    [OtherRevocationInfoFormat] -> ShowS
    OtherRevocationInfoFormat -> String
    (Int -> OtherRevocationInfoFormat -> ShowS)
    -> (OtherRevocationInfoFormat -> String)
    -> ([OtherRevocationInfoFormat] -> ShowS)
    -> Show OtherRevocationInfoFormat
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> OtherRevocationInfoFormat -> ShowS
    showsPrec :: Int -> OtherRevocationInfoFormat -> ShowS
    $cshow :: OtherRevocationInfoFormat -> String
    show :: OtherRevocationInfoFormat -> String
    $cshowList :: [OtherRevocationInfoFormat] -> ShowS
    showList :: [OtherRevocationInfoFormat] -> ShowS
    Show,OtherRevocationInfoFormat -> OtherRevocationInfoFormat -> Bool
    (OtherRevocationInfoFormat -> OtherRevocationInfoFormat -> Bool)
    -> (OtherRevocationInfoFormat -> OtherRevocationInfoFormat -> Bool)
    -> Eq OtherRevocationInfoFormat
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: OtherRevocationInfoFormat -> OtherRevocationInfoFormat -> Bool
    == :: OtherRevocationInfoFormat -> OtherRevocationInfoFormat -> Bool
    $c/= :: OtherRevocationInfoFormat -> OtherRevocationInfoFormat -> Bool
    /= :: OtherRevocationInfoFormat -> OtherRevocationInfoFormat -> Bool
    Eq)

    otherRevocationInfoFormatASN1PS :: ASN1Elem e
                                    => ASN1ConstructionType
                                    -> OtherRevocationInfoFormat
                                    -> ASN1Stream e
    otherRevocationInfoFormatASN1PS :: forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> OtherRevocationInfoFormat -> ASN1Stream e
    otherRevocationInfoFormatASN1PS ASN1ConstructionType
    ty OtherRevocationInfoFormat{OID
    [ASN1]
    otherRevInfoFormat :: OtherRevocationInfoFormat -> OID
    otherRevInfoValues :: OtherRevocationInfoFormat -> [ASN1]
    otherRevInfoFormat :: OID
    otherRevInfoValues :: [ASN1]
    ..} =
        ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    forall e.
    ASN1Elem e =>
    ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
    asn1Container ASN1ConstructionType
    ty (ASN1Stream e
    f ASN1Stream e -> ASN1Stream e -> ASN1Stream e
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ASN1Stream e
    v)
      where f :: ASN1Stream e
    f = OID -> ASN1Stream e
    forall e. ASN1Elem e => OID -> ASN1Stream e
    gOID OID
    otherRevInfoFormat
            v :: ASN1Stream e
    v = [ASN1] -> ASN1Stream e
    forall e. ASN1Elem e => [ASN1] -> ASN1Stream e
    gMany [ASN1]
    otherRevInfoValues

    parseOtherRevocationInfoFormat :: Monoid e
                                   => ASN1ConstructionType
                                   -> ParseASN1 e OtherRevocationInfoFormat
    parseOtherRevocationInfoFormat :: forall e.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e OtherRevocationInfoFormat
    parseOtherRevocationInfoFormat ASN1ConstructionType
    ty = ASN1ConstructionType
    -> ParseASN1 e OtherRevocationInfoFormat
    -> ParseASN1 e OtherRevocationInfoFormat
    forall e a.
    Monoid e =>
    ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
    onNextContainer ASN1ConstructionType
    ty (ParseASN1 e OtherRevocationInfoFormat
     -> ParseASN1 e OtherRevocationInfoFormat)
    -> ParseASN1 e OtherRevocationInfoFormat
    -> ParseASN1 e OtherRevocationInfoFormat
    forall a b. (a -> b) -> a -> b
    $ do
        OID OID
    f <- ParseASN1 e ASN1
    forall e. Monoid e => ParseASN1 e ASN1
    getNext
        [ASN1]
    v <- 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
        OtherRevocationInfoFormat -> ParseASN1 e OtherRevocationInfoFormat
    forall a. a -> ParseASN1 e a
    forall (m :: * -> *) a. Monad m => a -> m a
    return OtherRevocationInfoFormat { otherRevInfoFormat :: OID
    otherRevInfoFormat = OID
    f
                                         , otherRevInfoValues :: [ASN1]
    otherRevInfoValues = [ASN1]
    v }