    -- |
    -- Module      : Data.X509.Ext
    -- License     : BSD-style
    -- Maintainer  : Vincent Hanquez <vincent@snarc.org>
    -- Stability   : experimental
    -- Portability : unknown
    --
    -- extension processing module.
    --
    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    module Data.X509.Ext
        ( Extension(..)
        -- * Common extension usually found in x509v3
        , ExtBasicConstraints(..)
        , ExtKeyUsage(..)
        , ExtKeyUsageFlag(..)
        , ExtExtendedKeyUsage(..)
        , ExtKeyUsagePurpose(..)
        , ExtSubjectKeyId(..)
        , ExtSubjectAltName(..)
        , ExtAuthorityKeyId(..)
        , ExtCrlDistributionPoints(..)
        , ExtNetscapeComment(..)
        , AltName(..)
        , DistributionPoint(..)
        , ReasonFlag(..)
        -- * Accessor turning extension into a specific one
        , extensionGet
        , extensionGetE
        , extensionDecode
        , extensionEncode
        ) where

    import qualified Data.ByteString as B
    import qualified Data.ByteString.Char8 as BC
    import Data.ASN1.Types
    import Data.ASN1.Parse
    import Data.ASN1.Encoding
    import Data.ASN1.BinaryEncoding
    import Data.ASN1.BitArray
    import Data.Proxy
    import Data.List (find)
    import Data.X509.ExtensionRaw
    import Data.X509.DistinguishedName
    import Control.Applicative
    import Control.Monad

    -- | key usage flag that is found in the key usage extension field.
    data ExtKeyUsageFlag =
          KeyUsage_digitalSignature -- (0)
        | KeyUsage_nonRepudiation   -- (1) recent X.509 ver have renamed this bit to contentCommitment
        | KeyUsage_keyEncipherment  -- (2)
        | KeyUsage_dataEncipherment -- (3)
        | KeyUsage_keyAgreement     -- (4)
        | KeyUsage_keyCertSign      -- (5)
        | KeyUsage_cRLSign          -- (6)
        | KeyUsage_encipherOnly     -- (7)
        | KeyUsage_decipherOnly     -- (8)
        deriving (Int -> ExtKeyUsageFlag -> ShowS
    [ExtKeyUsageFlag] -> ShowS
    ExtKeyUsageFlag -> String
    (Int -> ExtKeyUsageFlag -> ShowS)
    -> (ExtKeyUsageFlag -> String)
    -> ([ExtKeyUsageFlag] -> ShowS)
    -> Show ExtKeyUsageFlag
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ExtKeyUsageFlag -> ShowS
    showsPrec :: Int -> ExtKeyUsageFlag -> ShowS
    $cshow :: ExtKeyUsageFlag -> String
    show :: ExtKeyUsageFlag -> String
    $cshowList :: [ExtKeyUsageFlag] -> ShowS
    showList :: [ExtKeyUsageFlag] -> ShowS
    Show,ExtKeyUsageFlag -> ExtKeyUsageFlag -> Bool
    (ExtKeyUsageFlag -> ExtKeyUsageFlag -> Bool)
    -> (ExtKeyUsageFlag -> ExtKeyUsageFlag -> Bool)
    -> Eq ExtKeyUsageFlag
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> Bool
    == :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> Bool
    $c/= :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> Bool
    /= :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> Bool
    Eq,Eq ExtKeyUsageFlag
    Eq ExtKeyUsageFlag
    -> (ExtKeyUsageFlag -> ExtKeyUsageFlag -> Ordering)
    -> (ExtKeyUsageFlag -> ExtKeyUsageFlag -> Bool)
    -> (ExtKeyUsageFlag -> ExtKeyUsageFlag -> Bool)
    -> (ExtKeyUsageFlag -> ExtKeyUsageFlag -> Bool)
    -> (ExtKeyUsageFlag -> ExtKeyUsageFlag -> Bool)
    -> (ExtKeyUsageFlag -> ExtKeyUsageFlag -> ExtKeyUsageFlag)
    -> (ExtKeyUsageFlag -> ExtKeyUsageFlag -> ExtKeyUsageFlag)
    -> Ord ExtKeyUsageFlag
    ExtKeyUsageFlag -> ExtKeyUsageFlag -> Bool
    ExtKeyUsageFlag -> ExtKeyUsageFlag -> Ordering
    ExtKeyUsageFlag -> ExtKeyUsageFlag -> ExtKeyUsageFlag
    forall a.
    Eq a
    -> (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> Ordering
    compare :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> Ordering
    $c< :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> Bool
    < :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> Bool
    $c<= :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> Bool
    <= :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> Bool
    $c> :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> Bool
    > :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> Bool
    $c>= :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> Bool
    >= :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> Bool
    $cmax :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> ExtKeyUsageFlag
    max :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> ExtKeyUsageFlag
    $cmin :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> ExtKeyUsageFlag
    min :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> ExtKeyUsageFlag
    Ord,Int -> ExtKeyUsageFlag
    ExtKeyUsageFlag -> Int
    ExtKeyUsageFlag -> [ExtKeyUsageFlag]
    ExtKeyUsageFlag -> ExtKeyUsageFlag
    ExtKeyUsageFlag -> ExtKeyUsageFlag -> [ExtKeyUsageFlag]
    ExtKeyUsageFlag
    -> ExtKeyUsageFlag -> ExtKeyUsageFlag -> [ExtKeyUsageFlag]
    (ExtKeyUsageFlag -> ExtKeyUsageFlag)
    -> (ExtKeyUsageFlag -> ExtKeyUsageFlag)
    -> (Int -> ExtKeyUsageFlag)
    -> (ExtKeyUsageFlag -> Int)
    -> (ExtKeyUsageFlag -> [ExtKeyUsageFlag])
    -> (ExtKeyUsageFlag -> ExtKeyUsageFlag -> [ExtKeyUsageFlag])
    -> (ExtKeyUsageFlag -> ExtKeyUsageFlag -> [ExtKeyUsageFlag])
    -> (ExtKeyUsageFlag
        -> ExtKeyUsageFlag -> ExtKeyUsageFlag -> [ExtKeyUsageFlag])
    -> Enum ExtKeyUsageFlag
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    $csucc :: ExtKeyUsageFlag -> ExtKeyUsageFlag
    succ :: ExtKeyUsageFlag -> ExtKeyUsageFlag
    $cpred :: ExtKeyUsageFlag -> ExtKeyUsageFlag
    pred :: ExtKeyUsageFlag -> ExtKeyUsageFlag
    $ctoEnum :: Int -> ExtKeyUsageFlag
    toEnum :: Int -> ExtKeyUsageFlag
    $cfromEnum :: ExtKeyUsageFlag -> Int
    fromEnum :: ExtKeyUsageFlag -> Int
    $cenumFrom :: ExtKeyUsageFlag -> [ExtKeyUsageFlag]
    enumFrom :: ExtKeyUsageFlag -> [ExtKeyUsageFlag]
    $cenumFromThen :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> [ExtKeyUsageFlag]
    enumFromThen :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> [ExtKeyUsageFlag]
    $cenumFromTo :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> [ExtKeyUsageFlag]
    enumFromTo :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> [ExtKeyUsageFlag]
    $cenumFromThenTo :: ExtKeyUsageFlag
    -> ExtKeyUsageFlag -> ExtKeyUsageFlag -> [ExtKeyUsageFlag]
    enumFromThenTo :: ExtKeyUsageFlag
    -> ExtKeyUsageFlag -> ExtKeyUsageFlag -> [ExtKeyUsageFlag]
    Enum)

    {-
    -- RFC 5280
    oidDistributionPoints, oidPolicies, oidPoliciesMapping :: OID
    oidPolicies           = [2,5,29,32]
    oidPoliciesMapping    = [2,5,29,33]
    -}

    -- | Extension class.
    --
    -- each extension have a unique OID associated, and a way
    -- to encode and decode an ASN1 stream.
    --
    -- Errata: turns out, the content is not necessarily ASN1,
    -- it could be data that is only parsable by the extension
    -- e.g. raw ascii string. Add method to parse and encode with
    -- ByteString
    class Extension a where
        extOID           :: a -> OID
        extHasNestedASN1 :: Proxy a -> Bool
        extEncode        :: a -> [ASN1]
        extDecode        :: [ASN1] -> Either String a

        extDecodeBs :: B.ByteString -> Either String a
        extDecodeBs = ((ASN1Error -> Either String [ASN1])
    -> ([ASN1] -> Either String [ASN1])
    -> Either ASN1Error [ASN1]
    -> Either String [ASN1]
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either (String -> Either String [ASN1]
    forall a b. a -> Either a b
    Left (String -> Either String [ASN1])
    -> (ASN1Error -> String) -> ASN1Error -> Either String [ASN1]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ASN1Error -> String
    forall a. Show a => a -> String
    show) [ASN1] -> Either String [ASN1]
    forall a b. b -> Either a b
    Right (Either ASN1Error [ASN1] -> Either String [ASN1])
    -> (ByteString -> Either ASN1Error [ASN1])
    -> ByteString
    -> Either String [ASN1]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . BER -> ByteString -> Either ASN1Error [ASN1]
    forall a.
    ASN1Decoding a =>
    a -> ByteString -> Either ASN1Error [ASN1]
    decodeASN1' BER
    BER) (ByteString -> Either String [ASN1])
    -> ([ASN1] -> Either String a) -> ByteString -> Either String a
    forall (m :: * -> *) a b c.
    Monad m =>
    (a -> m b) -> (b -> m c) -> a -> m c
    >=> [ASN1] -> Either String a
    forall a. Extension a => [ASN1] -> Either String a
    extDecode

        extEncodeBs :: a -> B.ByteString
        extEncodeBs = DER -> [ASN1] -> ByteString
    forall a. ASN1Encoding a => a -> [ASN1] -> ByteString
    encodeASN1' DER
    DER ([ASN1] -> ByteString) -> (a -> [ASN1]) -> a -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> [ASN1]
    forall a. Extension a => a -> [ASN1]
    extEncode

    -- | Get a specific extension from a lists of raw extensions
    extensionGet :: Extension a => Extensions -> Maybe a
    extensionGet :: forall a. Extension a => Extensions -> Maybe a
    extensionGet (Extensions Maybe [ExtensionRaw]
    Nothing)  = Maybe a
    forall a. Maybe a
    Nothing
    extensionGet (Extensions (Just [ExtensionRaw]
    l)) = [ExtensionRaw] -> Maybe a
    forall {a}. Extension a => [ExtensionRaw] -> Maybe a
    findExt [ExtensionRaw]
    l
      where findExt :: [ExtensionRaw] -> Maybe a
    findExt []     = Maybe a
    forall a. Maybe a
    Nothing
            findExt (ExtensionRaw
    x:[ExtensionRaw]
    xs) = case ExtensionRaw -> Maybe (Either String a)
    forall a. Extension a => ExtensionRaw -> Maybe (Either String a)
    extensionDecode ExtensionRaw
    x of
                                Just (Right a
    e) -> a -> Maybe a
    forall a. a -> Maybe a
    Just a
    e
                                Maybe (Either String a)
    _              -> [ExtensionRaw] -> Maybe a
    findExt [ExtensionRaw]
    xs

    -- | Get a specific extension from a lists of raw extensions
    extensionGetE :: Extension a => Extensions -> Maybe (Either String a)
    extensionGetE :: forall a. Extension a => Extensions -> Maybe (Either String a)
    extensionGetE (Extensions Maybe [ExtensionRaw]
    Nothing)  = Maybe (Either String a)
    forall a. Maybe a
    Nothing
    extensionGetE (Extensions (Just [ExtensionRaw]
    l)) = [ExtensionRaw] -> Maybe (Either String a)
    forall {a}.
    Extension a =>
    [ExtensionRaw] -> Maybe (Either String a)
    findExt [ExtensionRaw]
    l
      where findExt :: [ExtensionRaw] -> Maybe (Either String a)
    findExt []     = Maybe (Either String a)
    forall a. Maybe a
    Nothing
            findExt (ExtensionRaw
    x:[ExtensionRaw]
    xs) = case ExtensionRaw -> Maybe (Either String a)
    forall a. Extension a => ExtensionRaw -> Maybe (Either String a)
    extensionDecode ExtensionRaw
    x of
                                Just Either String a
    r         -> Either String a -> Maybe (Either String a)
    forall a. a -> Maybe a
    Just Either String a
    r
                                Maybe (Either String a)
    _              -> [ExtensionRaw] -> Maybe (Either String a)
    findExt [ExtensionRaw]
    xs

    -- | Try to decode an ExtensionRaw.
    --
    -- If this function return:
    -- * Nothing, the OID doesn't match
    -- * Just Left, the OID matched, but the extension couldn't be decoded
    -- * Just Right, the OID matched, and the extension has been succesfully decoded
    extensionDecode :: forall a . Extension a => ExtensionRaw -> Maybe (Either String a)
    extensionDecode :: forall a. Extension a => ExtensionRaw -> Maybe (Either String a)
    extensionDecode er :: ExtensionRaw
    er@(ExtensionRaw OID
    oid Bool
    _ ByteString
    content)
        | a -> OID
    forall a. Extension a => a -> OID
    extOID (a
    forall a. HasCallStack => a
    undefined :: a) OID -> OID -> Bool
    forall a. Eq a => a -> a -> Bool
    /= OID
    oid      = Maybe (Either String a)
    forall a. Maybe a
    Nothing
        | Proxy a -> Bool
    forall a. Extension a => Proxy a -> Bool
    extHasNestedASN1 (Proxy a
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy a) = Either String a -> Maybe (Either String a)
    forall a. a -> Maybe a
    Just (ExtensionRaw -> Either String [ASN1]
    tryExtRawASN1 ExtensionRaw
    er Either String [ASN1]
    -> ([ASN1] -> Either String a) -> Either String a
    forall a b.
    Either String a -> (a -> Either String b) -> Either String b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= [ASN1] -> Either String a
    forall a. Extension a => [ASN1] -> Either String a
    extDecode)
        | Bool
    otherwise                           = Either String a -> Maybe (Either String a)
    forall a. a -> Maybe a
    Just (ByteString -> Either String a
    forall a. Extension a => ByteString -> Either String a
    extDecodeBs ByteString
    content)

    -- | Encode an Extension to extensionRaw
    extensionEncode :: forall a . Extension a => Bool -> a -> ExtensionRaw
    extensionEncode :: forall a. Extension a => Bool -> a -> ExtensionRaw
    extensionEncode Bool
    critical a
    ext
        | Proxy a -> Bool
    forall a. Extension a => Proxy a -> Bool
    extHasNestedASN1 (Proxy a
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy a) = OID -> Bool -> ByteString -> ExtensionRaw
    ExtensionRaw (a -> OID
    forall a. Extension a => a -> OID
    extOID a
    ext) Bool
    critical (DER -> [ASN1] -> ByteString
    forall a. ASN1Encoding a => a -> [ASN1] -> ByteString
    encodeASN1' DER
    DER ([ASN1] -> ByteString) -> [ASN1] -> ByteString
    forall a b. (a -> b) -> a -> b
    $ a -> [ASN1]
    forall a. Extension a => a -> [ASN1]
    extEncode a
    ext)
        | Bool
    otherwise                           = OID -> Bool -> ByteString -> ExtensionRaw
    ExtensionRaw (a -> OID
    forall a. Extension a => a -> OID
    extOID a
    ext) Bool
    critical (a -> ByteString
    forall a. Extension a => a -> ByteString
    extEncodeBs a
    ext)

    -- | Basic Constraints
    data ExtBasicConstraints = ExtBasicConstraints Bool (Maybe Integer)
        deriving (Int -> ExtBasicConstraints -> ShowS
    [ExtBasicConstraints] -> ShowS
    ExtBasicConstraints -> String
    (Int -> ExtBasicConstraints -> ShowS)
    -> (ExtBasicConstraints -> String)
    -> ([ExtBasicConstraints] -> ShowS)
    -> Show ExtBasicConstraints
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ExtBasicConstraints -> ShowS
    showsPrec :: Int -> ExtBasicConstraints -> ShowS
    $cshow :: ExtBasicConstraints -> String
    show :: ExtBasicConstraints -> String
    $cshowList :: [ExtBasicConstraints] -> ShowS
    showList :: [ExtBasicConstraints] -> ShowS
    Show,ExtBasicConstraints -> ExtBasicConstraints -> Bool
    (ExtBasicConstraints -> ExtBasicConstraints -> Bool)
    -> (ExtBasicConstraints -> ExtBasicConstraints -> Bool)
    -> Eq ExtBasicConstraints
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ExtBasicConstraints -> ExtBasicConstraints -> Bool
    == :: ExtBasicConstraints -> ExtBasicConstraints -> Bool
    $c/= :: ExtBasicConstraints -> ExtBasicConstraints -> Bool
    /= :: ExtBasicConstraints -> ExtBasicConstraints -> Bool
    Eq)

    instance Extension ExtBasicConstraints where
        extOID :: ExtBasicConstraints -> OID
    extOID = OID -> ExtBasicConstraints -> OID
    forall a b. a -> b -> a
    const [Integer
    2,Integer
    5,Integer
    29,Integer
    19]
        extHasNestedASN1 :: Proxy ExtBasicConstraints -> Bool
    extHasNestedASN1 = Bool -> Proxy ExtBasicConstraints -> Bool
    forall a b. a -> b -> a
    const Bool
    True
        extEncode :: ExtBasicConstraints -> [ASN1]
    extEncode (ExtBasicConstraints Bool
    b Maybe Integer
    Nothing)  = [ASN1ConstructionType -> ASN1
    Start ASN1ConstructionType
    Sequence,Bool -> ASN1
    Boolean Bool
    b,ASN1ConstructionType -> ASN1
    End ASN1ConstructionType
    Sequence]
        extEncode (ExtBasicConstraints Bool
    b (Just Integer
    i)) = [ASN1ConstructionType -> ASN1
    Start ASN1ConstructionType
    Sequence,Bool -> ASN1
    Boolean Bool
    b,Integer -> ASN1
    IntVal Integer
    i,ASN1ConstructionType -> ASN1
    End ASN1ConstructionType
    Sequence]

        extDecode :: [ASN1] -> Either String ExtBasicConstraints
    extDecode [Start ASN1ConstructionType
    Sequence,Boolean Bool
    b,IntVal Integer
    v,End ASN1ConstructionType
    Sequence]
            | Integer
    v Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Integer
    0    = ExtBasicConstraints -> Either String ExtBasicConstraints
    forall a b. b -> Either a b
    Right (Bool -> Maybe Integer -> ExtBasicConstraints
    ExtBasicConstraints Bool
    b (Integer -> Maybe Integer
    forall a. a -> Maybe a
    Just Integer
    v))
            | Bool
    otherwise = String -> Either String ExtBasicConstraints
    forall a b. a -> Either a b
    Left String
    "invalid pathlen"
        extDecode [Start ASN1ConstructionType
    Sequence,Boolean Bool
    b,End ASN1ConstructionType
    Sequence] = ExtBasicConstraints -> Either String ExtBasicConstraints
    forall a b. b -> Either a b
    Right (Bool -> Maybe Integer -> ExtBasicConstraints
    ExtBasicConstraints Bool
    b Maybe Integer
    forall a. Maybe a
    Nothing)
        extDecode [Start ASN1ConstructionType
    Sequence,End ASN1ConstructionType
    Sequence] = ExtBasicConstraints -> Either String ExtBasicConstraints
    forall a b. b -> Either a b
    Right (Bool -> Maybe Integer -> ExtBasicConstraints
    ExtBasicConstraints Bool
    False Maybe Integer
    forall a. Maybe a
    Nothing)
        extDecode [ASN1]
    _ = String -> Either String ExtBasicConstraints
    forall a b. a -> Either a b
    Left String
    "unknown sequence"

    -- | Describe key usage
    data ExtKeyUsage = ExtKeyUsage [ExtKeyUsageFlag]
        deriving (Int -> ExtKeyUsage -> ShowS
    [ExtKeyUsage] -> ShowS
    ExtKeyUsage -> String
    (Int -> ExtKeyUsage -> ShowS)
    -> (ExtKeyUsage -> String)
    -> ([ExtKeyUsage] -> ShowS)
    -> Show ExtKeyUsage
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ExtKeyUsage -> ShowS
    showsPrec :: Int -> ExtKeyUsage -> ShowS
    $cshow :: ExtKeyUsage -> String
    show :: ExtKeyUsage -> String
    $cshowList :: [ExtKeyUsage] -> ShowS
    showList :: [ExtKeyUsage] -> ShowS
    Show,ExtKeyUsage -> ExtKeyUsage -> Bool
    (ExtKeyUsage -> ExtKeyUsage -> Bool)
    -> (ExtKeyUsage -> ExtKeyUsage -> Bool) -> Eq ExtKeyUsage
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ExtKeyUsage -> ExtKeyUsage -> Bool
    == :: ExtKeyUsage -> ExtKeyUsage -> Bool
    $c/= :: ExtKeyUsage -> ExtKeyUsage -> Bool
    /= :: ExtKeyUsage -> ExtKeyUsage -> Bool
    Eq)

    instance Extension ExtKeyUsage where
        extOID :: ExtKeyUsage -> OID
    extOID = OID -> ExtKeyUsage -> OID
    forall a b. a -> b -> a
    const [Integer
    2,Integer
    5,Integer
    29,Integer
    15]
        extHasNestedASN1 :: Proxy ExtKeyUsage -> Bool
    extHasNestedASN1 = Bool -> Proxy ExtKeyUsage -> Bool
    forall a b. a -> b -> a
    const Bool
    True
        extEncode :: ExtKeyUsage -> [ASN1]
    extEncode (ExtKeyUsage [ExtKeyUsageFlag]
    flags) = [BitArray -> ASN1
    BitString (BitArray -> ASN1) -> BitArray -> ASN1
    forall a b. (a -> b) -> a -> b
    $ [ExtKeyUsageFlag] -> BitArray
    forall a. Enum a => [a] -> BitArray
    flagsToBits [ExtKeyUsageFlag]
    flags]
        extDecode :: [ASN1] -> Either String ExtKeyUsage
    extDecode [BitString BitArray
    bits] = ExtKeyUsage -> Either String ExtKeyUsage
    forall a b. b -> Either a b
    Right (ExtKeyUsage -> Either String ExtKeyUsage)
    -> ExtKeyUsage -> Either String ExtKeyUsage
    forall a b. (a -> b) -> a -> b
    $ [ExtKeyUsageFlag] -> ExtKeyUsage
    ExtKeyUsage ([ExtKeyUsageFlag] -> ExtKeyUsage)
    -> [ExtKeyUsageFlag] -> ExtKeyUsage
    forall a b. (a -> b) -> a -> b
    $ BitArray -> [ExtKeyUsageFlag]
    forall a. Enum a => BitArray -> [a]
    bitsToFlags BitArray
    bits
        extDecode [ASN1]
    _ = String -> Either String ExtKeyUsage
    forall a b. a -> Either a b
    Left String
    "unknown sequence"

    -- | Key usage purposes for the ExtendedKeyUsage extension
    data ExtKeyUsagePurpose =
          KeyUsagePurpose_ServerAuth
        | KeyUsagePurpose_ClientAuth
        | KeyUsagePurpose_CodeSigning
        | KeyUsagePurpose_EmailProtection
        | KeyUsagePurpose_TimeStamping
        | KeyUsagePurpose_OCSPSigning
        | KeyUsagePurpose_Unknown OID
        deriving (Int -> ExtKeyUsagePurpose -> ShowS
    [ExtKeyUsagePurpose] -> ShowS
    ExtKeyUsagePurpose -> String
    (Int -> ExtKeyUsagePurpose -> ShowS)
    -> (ExtKeyUsagePurpose -> String)
    -> ([ExtKeyUsagePurpose] -> ShowS)
    -> Show ExtKeyUsagePurpose
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ExtKeyUsagePurpose -> ShowS
    showsPrec :: Int -> ExtKeyUsagePurpose -> ShowS
    $cshow :: ExtKeyUsagePurpose -> String
    show :: ExtKeyUsagePurpose -> String
    $cshowList :: [ExtKeyUsagePurpose] -> ShowS
    showList :: [ExtKeyUsagePurpose] -> ShowS
    Show,ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool
    (ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool)
    -> (ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool)
    -> Eq ExtKeyUsagePurpose
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool
    == :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool
    $c/= :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool
    /= :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool
    Eq,Eq ExtKeyUsagePurpose
    Eq ExtKeyUsagePurpose
    -> (ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Ordering)
    -> (ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool)
    -> (ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool)
    -> (ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool)
    -> (ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool)
    -> (ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> ExtKeyUsagePurpose)
    -> (ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> ExtKeyUsagePurpose)
    -> Ord ExtKeyUsagePurpose
    ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool
    ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Ordering
    ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> ExtKeyUsagePurpose
    forall a.
    Eq a
    -> (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Ordering
    compare :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Ordering
    $c< :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool
    < :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool
    $c<= :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool
    <= :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool
    $c> :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool
    > :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool
    $c>= :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool
    >= :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool
    $cmax :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> ExtKeyUsagePurpose
    max :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> ExtKeyUsagePurpose
    $cmin :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> ExtKeyUsagePurpose
    min :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> ExtKeyUsagePurpose
    Ord)

    extKeyUsagePurposedOID :: [(OID, ExtKeyUsagePurpose)]
    extKeyUsagePurposedOID :: [(OID, ExtKeyUsagePurpose)]
    extKeyUsagePurposedOID =
        [(Integer -> OID
    forall {a}. Num a => a -> [a]
    keyUsagePurposePrefix Integer
    1, ExtKeyUsagePurpose
    KeyUsagePurpose_ServerAuth)
        ,(Integer -> OID
    forall {a}. Num a => a -> [a]
    keyUsagePurposePrefix Integer
    2, ExtKeyUsagePurpose
    KeyUsagePurpose_ClientAuth)
        ,(Integer -> OID
    forall {a}. Num a => a -> [a]
    keyUsagePurposePrefix Integer
    3, ExtKeyUsagePurpose
    KeyUsagePurpose_CodeSigning)
        ,(Integer -> OID
    forall {a}. Num a => a -> [a]
    keyUsagePurposePrefix Integer
    4, ExtKeyUsagePurpose
    KeyUsagePurpose_EmailProtection)
        ,(Integer -> OID
    forall {a}. Num a => a -> [a]
    keyUsagePurposePrefix Integer
    8, ExtKeyUsagePurpose
    KeyUsagePurpose_TimeStamping)
        ,(Integer -> OID
    forall {a}. Num a => a -> [a]
    keyUsagePurposePrefix Integer
    9, ExtKeyUsagePurpose
    KeyUsagePurpose_OCSPSigning)]
      where keyUsagePurposePrefix :: a -> [a]
    keyUsagePurposePrefix a
    r = [a
    1,a
    3,a
    6,a
    1,a
    5,a
    5,a
    7,a
    3,a
    r]

    -- | Extended key usage extension
    data ExtExtendedKeyUsage = ExtExtendedKeyUsage [ExtKeyUsagePurpose]
        deriving (Int -> ExtExtendedKeyUsage -> ShowS
    [ExtExtendedKeyUsage] -> ShowS
    ExtExtendedKeyUsage -> String
    (Int -> ExtExtendedKeyUsage -> ShowS)
    -> (ExtExtendedKeyUsage -> String)
    -> ([ExtExtendedKeyUsage] -> ShowS)
    -> Show ExtExtendedKeyUsage
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ExtExtendedKeyUsage -> ShowS
    showsPrec :: Int -> ExtExtendedKeyUsage -> ShowS
    $cshow :: ExtExtendedKeyUsage -> String
    show :: ExtExtendedKeyUsage -> String
    $cshowList :: [ExtExtendedKeyUsage] -> ShowS
    showList :: [ExtExtendedKeyUsage] -> ShowS
    Show,ExtExtendedKeyUsage -> ExtExtendedKeyUsage -> Bool
    (ExtExtendedKeyUsage -> ExtExtendedKeyUsage -> Bool)
    -> (ExtExtendedKeyUsage -> ExtExtendedKeyUsage -> Bool)
    -> Eq ExtExtendedKeyUsage
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ExtExtendedKeyUsage -> ExtExtendedKeyUsage -> Bool
    == :: ExtExtendedKeyUsage -> ExtExtendedKeyUsage -> Bool
    $c/= :: ExtExtendedKeyUsage -> ExtExtendedKeyUsage -> Bool
    /= :: ExtExtendedKeyUsage -> ExtExtendedKeyUsage -> Bool
    Eq)

    instance Extension ExtExtendedKeyUsage where
        extOID :: ExtExtendedKeyUsage -> OID
    extOID = OID -> ExtExtendedKeyUsage -> OID
    forall a b. a -> b -> a
    const [Integer
    2,Integer
    5,Integer
    29,Integer
    37]
        extHasNestedASN1 :: Proxy ExtExtendedKeyUsage -> Bool
    extHasNestedASN1 = Bool -> Proxy ExtExtendedKeyUsage -> Bool
    forall a b. a -> b -> a
    const Bool
    True
        extEncode :: ExtExtendedKeyUsage -> [ASN1]
    extEncode (ExtExtendedKeyUsage [ExtKeyUsagePurpose]
    purposes) =
            [ASN1ConstructionType -> ASN1
    Start ASN1ConstructionType
    Sequence] [ASN1] -> [ASN1] -> [ASN1]
    forall a. [a] -> [a] -> [a]
    ++ (ExtKeyUsagePurpose -> ASN1) -> [ExtKeyUsagePurpose] -> [ASN1]
    forall a b. (a -> b) -> [a] -> [b]
    map (OID -> ASN1
    OID (OID -> ASN1)
    -> (ExtKeyUsagePurpose -> OID) -> ExtKeyUsagePurpose -> ASN1
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ExtKeyUsagePurpose -> OID
    lookupRev) [ExtKeyUsagePurpose]
    purposes [ASN1] -> [ASN1] -> [ASN1]
    forall a. [a] -> [a] -> [a]
    ++ [ASN1ConstructionType -> ASN1
    End ASN1ConstructionType
    Sequence]
          where lookupRev :: ExtKeyUsagePurpose -> OID
    lookupRev (KeyUsagePurpose_Unknown OID
    oid) = OID
    oid
                lookupRev ExtKeyUsagePurpose
    kup = OID
    -> ((OID, ExtKeyUsagePurpose) -> OID)
    -> Maybe (OID, ExtKeyUsagePurpose)
    -> OID
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe (String -> OID
    forall a. HasCallStack => String -> a
    error String
    "unknown key usage purpose") (OID, ExtKeyUsagePurpose) -> OID
    forall a b. (a, b) -> a
    fst (Maybe (OID, ExtKeyUsagePurpose) -> OID)
    -> Maybe (OID, ExtKeyUsagePurpose) -> OID
    forall a b. (a -> b) -> a -> b
    $ ((OID, ExtKeyUsagePurpose) -> Bool)
    -> [(OID, ExtKeyUsagePurpose)] -> Maybe (OID, ExtKeyUsagePurpose)
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
    find (ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool
    forall a. Eq a => a -> a -> Bool
    (==) ExtKeyUsagePurpose
    kup (ExtKeyUsagePurpose -> Bool)
    -> ((OID, ExtKeyUsagePurpose) -> ExtKeyUsagePurpose)
    -> (OID, ExtKeyUsagePurpose)
    -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (OID, ExtKeyUsagePurpose) -> ExtKeyUsagePurpose
    forall a b. (a, b) -> b
    snd) [(OID, ExtKeyUsagePurpose)]
    extKeyUsagePurposedOID
        extDecode :: [ASN1] -> Either String ExtExtendedKeyUsage
    extDecode [ASN1]
    l = [ExtKeyUsagePurpose] -> ExtExtendedKeyUsage
    ExtExtendedKeyUsage ([ExtKeyUsagePurpose] -> ExtExtendedKeyUsage)
    -> Either String [ExtKeyUsagePurpose]
    -> Either String ExtExtendedKeyUsage
    forall a b. (a -> b) -> Either String a -> Either String b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` ((ParseASN1 [ExtKeyUsagePurpose]
     -> [ASN1] -> Either String [ExtKeyUsagePurpose])
    -> [ASN1]
    -> ParseASN1 [ExtKeyUsagePurpose]
    -> Either String [ExtKeyUsagePurpose]
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip ParseASN1 [ExtKeyUsagePurpose]
    -> [ASN1] -> Either String [ExtKeyUsagePurpose]
    forall a. ParseASN1 a -> [ASN1] -> Either String a
    runParseASN1 [ASN1]
    l (ParseASN1 [ExtKeyUsagePurpose]
     -> Either String [ExtKeyUsagePurpose])
    -> ParseASN1 [ExtKeyUsagePurpose]
    -> Either String [ExtKeyUsagePurpose]
    forall a b. (a -> b) -> a -> b
    $ ASN1ConstructionType
    -> ParseASN1 [ExtKeyUsagePurpose] -> ParseASN1 [ExtKeyUsagePurpose]
    forall a. ASN1ConstructionType -> ParseASN1 a -> ParseASN1 a
    onNextContainer ASN1ConstructionType
    Sequence (ParseASN1 [ExtKeyUsagePurpose] -> ParseASN1 [ExtKeyUsagePurpose])
    -> ParseASN1 [ExtKeyUsagePurpose] -> ParseASN1 [ExtKeyUsagePurpose]
    forall a b. (a -> b) -> a -> b
    $ ParseASN1 ExtKeyUsagePurpose -> ParseASN1 [ExtKeyUsagePurpose]
    forall a. ParseASN1 a -> ParseASN1 [a]
    getMany (ParseASN1 ExtKeyUsagePurpose -> ParseASN1 [ExtKeyUsagePurpose])
    -> ParseASN1 ExtKeyUsagePurpose -> ParseASN1 [ExtKeyUsagePurpose]
    forall a b. (a -> b) -> a -> b
    $ do
            ASN1
    n <- ParseASN1 ASN1
    getNext
            case ASN1
    n of
                OID OID
    o -> ExtKeyUsagePurpose -> ParseASN1 ExtKeyUsagePurpose
    forall a. a -> ParseASN1 a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (ExtKeyUsagePurpose -> ParseASN1 ExtKeyUsagePurpose)
    -> ExtKeyUsagePurpose -> ParseASN1 ExtKeyUsagePurpose
    forall a b. (a -> b) -> a -> b
    $ ExtKeyUsagePurpose
    -> (ExtKeyUsagePurpose -> ExtKeyUsagePurpose)
    -> Maybe ExtKeyUsagePurpose
    -> ExtKeyUsagePurpose
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe (OID -> ExtKeyUsagePurpose
    KeyUsagePurpose_Unknown OID
    o) ExtKeyUsagePurpose -> ExtKeyUsagePurpose
    forall a. a -> a
    id (Maybe ExtKeyUsagePurpose -> ExtKeyUsagePurpose)
    -> Maybe ExtKeyUsagePurpose -> ExtKeyUsagePurpose
    forall a b. (a -> b) -> a -> b
    $ OID -> [(OID, ExtKeyUsagePurpose)] -> Maybe ExtKeyUsagePurpose
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup OID
    o [(OID, ExtKeyUsagePurpose)]
    extKeyUsagePurposedOID
                ASN1
    _     -> String -> ParseASN1 ExtKeyUsagePurpose
    forall a. HasCallStack => String -> a
    error String
    "invalid content in extended key usage")

    -- | Provide a way to identify a public key by a short hash.
    data ExtSubjectKeyId = ExtSubjectKeyId B.ByteString
        deriving (Int -> ExtSubjectKeyId -> ShowS
    [ExtSubjectKeyId] -> ShowS
    ExtSubjectKeyId -> String
    (Int -> ExtSubjectKeyId -> ShowS)
    -> (ExtSubjectKeyId -> String)
    -> ([ExtSubjectKeyId] -> ShowS)
    -> Show ExtSubjectKeyId
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ExtSubjectKeyId -> ShowS
    showsPrec :: Int -> ExtSubjectKeyId -> ShowS
    $cshow :: ExtSubjectKeyId -> String
    show :: ExtSubjectKeyId -> String
    $cshowList :: [ExtSubjectKeyId] -> ShowS
    showList :: [ExtSubjectKeyId] -> ShowS
    Show,ExtSubjectKeyId -> ExtSubjectKeyId -> Bool
    (ExtSubjectKeyId -> ExtSubjectKeyId -> Bool)
    -> (ExtSubjectKeyId -> ExtSubjectKeyId -> Bool)
    -> Eq ExtSubjectKeyId
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ExtSubjectKeyId -> ExtSubjectKeyId -> Bool
    == :: ExtSubjectKeyId -> ExtSubjectKeyId -> Bool
    $c/= :: ExtSubjectKeyId -> ExtSubjectKeyId -> Bool
    /= :: ExtSubjectKeyId -> ExtSubjectKeyId -> Bool
    Eq)

    instance Extension ExtSubjectKeyId where
        extOID :: ExtSubjectKeyId -> OID
    extOID = OID -> ExtSubjectKeyId -> OID
    forall a b. a -> b -> a
    const [Integer
    2,Integer
    5,Integer
    29,Integer
    14]
        extHasNestedASN1 :: Proxy ExtSubjectKeyId -> Bool
    extHasNestedASN1 = Bool -> Proxy ExtSubjectKeyId -> Bool
    forall a b. a -> b -> a
    const Bool
    True
        extEncode :: ExtSubjectKeyId -> [ASN1]
    extEncode (ExtSubjectKeyId ByteString
    o) = [ByteString -> ASN1
    OctetString ByteString
    o]
        extDecode :: [ASN1] -> Either String ExtSubjectKeyId
    extDecode [OctetString ByteString
    o] = ExtSubjectKeyId -> Either String ExtSubjectKeyId
    forall a b. b -> Either a b
    Right (ExtSubjectKeyId -> Either String ExtSubjectKeyId)
    -> ExtSubjectKeyId -> Either String ExtSubjectKeyId
    forall a b. (a -> b) -> a -> b
    $ ByteString -> ExtSubjectKeyId
    ExtSubjectKeyId ByteString
    o
        extDecode [ASN1]
    _ = String -> Either String ExtSubjectKeyId
    forall a b. a -> Either a b
    Left String
    "unknown sequence"

    -- | Different naming scheme use by the extension.
    --
    -- Not all name types are available, missing:
    -- otherName
    -- x400Address
    -- directoryName
    -- ediPartyName
    -- registeredID
    --
    data AltName =
          AltNameRFC822 String
        | AltNameDNS String
        | AltNameURI String
        | AltNameIP  B.ByteString
        | AltNameXMPP String
        | AltNameDNSSRV String
        deriving (Int -> AltName -> ShowS
    [AltName] -> ShowS
    AltName -> String
    (Int -> AltName -> ShowS)
    -> (AltName -> String) -> ([AltName] -> ShowS) -> Show AltName
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> AltName -> ShowS
    showsPrec :: Int -> AltName -> ShowS
    $cshow :: AltName -> String
    show :: AltName -> String
    $cshowList :: [AltName] -> ShowS
    showList :: [AltName] -> ShowS
    Show,AltName -> AltName -> Bool
    (AltName -> AltName -> Bool)
    -> (AltName -> AltName -> Bool) -> Eq AltName
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: AltName -> AltName -> Bool
    == :: AltName -> AltName -> Bool
    $c/= :: AltName -> AltName -> Bool
    /= :: AltName -> AltName -> Bool
    Eq,Eq AltName
    Eq AltName
    -> (AltName -> AltName -> Ordering)
    -> (AltName -> AltName -> Bool)
    -> (AltName -> AltName -> Bool)
    -> (AltName -> AltName -> Bool)
    -> (AltName -> AltName -> Bool)
    -> (AltName -> AltName -> AltName)
    -> (AltName -> AltName -> AltName)
    -> Ord AltName
    AltName -> AltName -> Bool
    AltName -> AltName -> Ordering
    AltName -> AltName -> AltName
    forall a.
    Eq a
    -> (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: AltName -> AltName -> Ordering
    compare :: AltName -> AltName -> Ordering
    $c< :: AltName -> AltName -> Bool
    < :: AltName -> AltName -> Bool
    $c<= :: AltName -> AltName -> Bool
    <= :: AltName -> AltName -> Bool
    $c> :: AltName -> AltName -> Bool
    > :: AltName -> AltName -> Bool
    $c>= :: AltName -> AltName -> Bool
    >= :: AltName -> AltName -> Bool
    $cmax :: AltName -> AltName -> AltName
    max :: AltName -> AltName -> AltName
    $cmin :: AltName -> AltName -> AltName
    min :: AltName -> AltName -> AltName
    Ord)

    -- | Provide a way to supply alternate name that can be
    -- used for matching host name.
    data ExtSubjectAltName = ExtSubjectAltName [AltName]
        deriving (Int -> ExtSubjectAltName -> ShowS
    [ExtSubjectAltName] -> ShowS
    ExtSubjectAltName -> String
    (Int -> ExtSubjectAltName -> ShowS)
    -> (ExtSubjectAltName -> String)
    -> ([ExtSubjectAltName] -> ShowS)
    -> Show ExtSubjectAltName
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ExtSubjectAltName -> ShowS
    showsPrec :: Int -> ExtSubjectAltName -> ShowS
    $cshow :: ExtSubjectAltName -> String
    show :: ExtSubjectAltName -> String
    $cshowList :: [ExtSubjectAltName] -> ShowS
    showList :: [ExtSubjectAltName] -> ShowS
    Show,ExtSubjectAltName -> ExtSubjectAltName -> Bool
    (ExtSubjectAltName -> ExtSubjectAltName -> Bool)
    -> (ExtSubjectAltName -> ExtSubjectAltName -> Bool)
    -> Eq ExtSubjectAltName
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ExtSubjectAltName -> ExtSubjectAltName -> Bool
    == :: ExtSubjectAltName -> ExtSubjectAltName -> Bool
    $c/= :: ExtSubjectAltName -> ExtSubjectAltName -> Bool
    /= :: ExtSubjectAltName -> ExtSubjectAltName -> Bool
    Eq,Eq ExtSubjectAltName
    Eq ExtSubjectAltName
    -> (ExtSubjectAltName -> ExtSubjectAltName -> Ordering)
    -> (ExtSubjectAltName -> ExtSubjectAltName -> Bool)
    -> (ExtSubjectAltName -> ExtSubjectAltName -> Bool)
    -> (ExtSubjectAltName -> ExtSubjectAltName -> Bool)
    -> (ExtSubjectAltName -> ExtSubjectAltName -> Bool)
    -> (ExtSubjectAltName -> ExtSubjectAltName -> ExtSubjectAltName)
    -> (ExtSubjectAltName -> ExtSubjectAltName -> ExtSubjectAltName)
    -> Ord ExtSubjectAltName
    ExtSubjectAltName -> ExtSubjectAltName -> Bool
    ExtSubjectAltName -> ExtSubjectAltName -> Ordering
    ExtSubjectAltName -> ExtSubjectAltName -> ExtSubjectAltName
    forall a.
    Eq a
    -> (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: ExtSubjectAltName -> ExtSubjectAltName -> Ordering
    compare :: ExtSubjectAltName -> ExtSubjectAltName -> Ordering
    $c< :: ExtSubjectAltName -> ExtSubjectAltName -> Bool
    < :: ExtSubjectAltName -> ExtSubjectAltName -> Bool
    $c<= :: ExtSubjectAltName -> ExtSubjectAltName -> Bool
    <= :: ExtSubjectAltName -> ExtSubjectAltName -> Bool
    $c> :: ExtSubjectAltName -> ExtSubjectAltName -> Bool
    > :: ExtSubjectAltName -> ExtSubjectAltName -> Bool
    $c>= :: ExtSubjectAltName -> ExtSubjectAltName -> Bool
    >= :: ExtSubjectAltName -> ExtSubjectAltName -> Bool
    $cmax :: ExtSubjectAltName -> ExtSubjectAltName -> ExtSubjectAltName
    max :: ExtSubjectAltName -> ExtSubjectAltName -> ExtSubjectAltName
    $cmin :: ExtSubjectAltName -> ExtSubjectAltName -> ExtSubjectAltName
    min :: ExtSubjectAltName -> ExtSubjectAltName -> ExtSubjectAltName
    Ord)

    instance Extension ExtSubjectAltName where
        extOID :: ExtSubjectAltName -> OID
    extOID = OID -> ExtSubjectAltName -> OID
    forall a b. a -> b -> a
    const [Integer
    2,Integer
    5,Integer
    29,Integer
    17]
        extHasNestedASN1 :: Proxy ExtSubjectAltName -> Bool
    extHasNestedASN1 = Bool -> Proxy ExtSubjectAltName -> Bool
    forall a b. a -> b -> a
    const Bool
    True
        extEncode :: ExtSubjectAltName -> [ASN1]
    extEncode (ExtSubjectAltName [AltName]
    names) = [AltName] -> [ASN1]
    encodeGeneralNames [AltName]
    names
        extDecode :: [ASN1] -> Either String ExtSubjectAltName
    extDecode [ASN1]
    l = ParseASN1 ExtSubjectAltName
    -> [ASN1] -> Either String ExtSubjectAltName
    forall a. ParseASN1 a -> [ASN1] -> Either String a
    runParseASN1 ([AltName] -> ExtSubjectAltName
    ExtSubjectAltName ([AltName] -> ExtSubjectAltName)
    -> ParseASN1 [AltName] -> ParseASN1 ExtSubjectAltName
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ParseASN1 [AltName]
    parseGeneralNames) [ASN1]
    l

    -- | Provide a mean to identify the public key corresponding to the private key
    -- used to signed a certificate.
    data ExtAuthorityKeyId = ExtAuthorityKeyId B.ByteString
        deriving (Int -> ExtAuthorityKeyId -> ShowS
    [ExtAuthorityKeyId] -> ShowS
    ExtAuthorityKeyId -> String
    (Int -> ExtAuthorityKeyId -> ShowS)
    -> (ExtAuthorityKeyId -> String)
    -> ([ExtAuthorityKeyId] -> ShowS)
    -> Show ExtAuthorityKeyId
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ExtAuthorityKeyId -> ShowS
    showsPrec :: Int -> ExtAuthorityKeyId -> ShowS
    $cshow :: ExtAuthorityKeyId -> String
    show :: ExtAuthorityKeyId -> String
    $cshowList :: [ExtAuthorityKeyId] -> ShowS
    showList :: [ExtAuthorityKeyId] -> ShowS
    Show,ExtAuthorityKeyId -> ExtAuthorityKeyId -> Bool
    (ExtAuthorityKeyId -> ExtAuthorityKeyId -> Bool)
    -> (ExtAuthorityKeyId -> ExtAuthorityKeyId -> Bool)
    -> Eq ExtAuthorityKeyId
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ExtAuthorityKeyId -> ExtAuthorityKeyId -> Bool
    == :: ExtAuthorityKeyId -> ExtAuthorityKeyId -> Bool
    $c/= :: ExtAuthorityKeyId -> ExtAuthorityKeyId -> Bool
    /= :: ExtAuthorityKeyId -> ExtAuthorityKeyId -> Bool
    Eq)

    instance Extension ExtAuthorityKeyId where
        extOID :: ExtAuthorityKeyId -> OID
    extOID ExtAuthorityKeyId
    _ = [Integer
    2,Integer
    5,Integer
    29,Integer
    35]
        extHasNestedASN1 :: Proxy ExtAuthorityKeyId -> Bool
    extHasNestedASN1 = Bool -> Proxy ExtAuthorityKeyId -> Bool
    forall a b. a -> b -> a
    const Bool
    True
        extEncode :: ExtAuthorityKeyId -> [ASN1]
    extEncode (ExtAuthorityKeyId ByteString
    keyid) =
            [ASN1ConstructionType -> ASN1
    Start ASN1ConstructionType
    Sequence,ASN1Class -> Int -> ByteString -> ASN1
    Other ASN1Class
    Context Int
    0 ByteString
    keyid,ASN1ConstructionType -> ASN1
    End ASN1ConstructionType
    Sequence]
        extDecode :: [ASN1] -> Either String ExtAuthorityKeyId
    extDecode [Start ASN1ConstructionType
    Sequence,Other ASN1Class
    Context Int
    0 ByteString
    keyid,End ASN1ConstructionType
    Sequence] =
            ExtAuthorityKeyId -> Either String ExtAuthorityKeyId
    forall a b. b -> Either a b
    Right (ExtAuthorityKeyId -> Either String ExtAuthorityKeyId)
    -> ExtAuthorityKeyId -> Either String ExtAuthorityKeyId
    forall a b. (a -> b) -> a -> b
    $ ByteString -> ExtAuthorityKeyId
    ExtAuthorityKeyId ByteString
    keyid
        extDecode [ASN1]
    _ = String -> Either String ExtAuthorityKeyId
    forall a b. a -> Either a b
    Left String
    "unknown sequence"

    -- | Identify how CRL information is obtained
    data ExtCrlDistributionPoints = ExtCrlDistributionPoints [DistributionPoint]
        deriving (Int -> ExtCrlDistributionPoints -> ShowS
    [ExtCrlDistributionPoints] -> ShowS
    ExtCrlDistributionPoints -> String
    (Int -> ExtCrlDistributionPoints -> ShowS)
    -> (ExtCrlDistributionPoints -> String)
    -> ([ExtCrlDistributionPoints] -> ShowS)
    -> Show ExtCrlDistributionPoints
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ExtCrlDistributionPoints -> ShowS
    showsPrec :: Int -> ExtCrlDistributionPoints -> ShowS
    $cshow :: ExtCrlDistributionPoints -> String
    show :: ExtCrlDistributionPoints -> String
    $cshowList :: [ExtCrlDistributionPoints] -> ShowS
    showList :: [ExtCrlDistributionPoints] -> ShowS
    Show,ExtCrlDistributionPoints -> ExtCrlDistributionPoints -> Bool
    (ExtCrlDistributionPoints -> ExtCrlDistributionPoints -> Bool)
    -> (ExtCrlDistributionPoints -> ExtCrlDistributionPoints -> Bool)
    -> Eq ExtCrlDistributionPoints
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ExtCrlDistributionPoints -> ExtCrlDistributionPoints -> Bool
    == :: ExtCrlDistributionPoints -> ExtCrlDistributionPoints -> Bool
    $c/= :: ExtCrlDistributionPoints -> ExtCrlDistributionPoints -> Bool
    /= :: ExtCrlDistributionPoints -> ExtCrlDistributionPoints -> Bool
    Eq)

    -- | Reason flag for the CRL
    data ReasonFlag =
          Reason_Unused
        | Reason_KeyCompromise
        | Reason_CACompromise
        | Reason_AffiliationChanged
        | Reason_Superseded
        | Reason_CessationOfOperation
        | Reason_CertificateHold
        | Reason_PrivilegeWithdrawn
        | Reason_AACompromise
        deriving (Int -> ReasonFlag -> ShowS
    [ReasonFlag] -> ShowS
    ReasonFlag -> String
    (Int -> ReasonFlag -> ShowS)
    -> (ReasonFlag -> String)
    -> ([ReasonFlag] -> ShowS)
    -> Show ReasonFlag
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ReasonFlag -> ShowS
    showsPrec :: Int -> ReasonFlag -> ShowS
    $cshow :: ReasonFlag -> String
    show :: ReasonFlag -> String
    $cshowList :: [ReasonFlag] -> ShowS
    showList :: [ReasonFlag] -> ShowS
    Show,ReasonFlag -> ReasonFlag -> Bool
    (ReasonFlag -> ReasonFlag -> Bool)
    -> (ReasonFlag -> ReasonFlag -> Bool) -> Eq ReasonFlag
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ReasonFlag -> ReasonFlag -> Bool
    == :: ReasonFlag -> ReasonFlag -> Bool
    $c/= :: ReasonFlag -> ReasonFlag -> Bool
    /= :: ReasonFlag -> ReasonFlag -> Bool
    Eq,Eq ReasonFlag
    Eq ReasonFlag
    -> (ReasonFlag -> ReasonFlag -> Ordering)
    -> (ReasonFlag -> ReasonFlag -> Bool)
    -> (ReasonFlag -> ReasonFlag -> Bool)
    -> (ReasonFlag -> ReasonFlag -> Bool)
    -> (ReasonFlag -> ReasonFlag -> Bool)
    -> (ReasonFlag -> ReasonFlag -> ReasonFlag)
    -> (ReasonFlag -> ReasonFlag -> ReasonFlag)
    -> Ord ReasonFlag
    ReasonFlag -> ReasonFlag -> Bool
    ReasonFlag -> ReasonFlag -> Ordering
    ReasonFlag -> ReasonFlag -> ReasonFlag
    forall a.
    Eq a
    -> (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: ReasonFlag -> ReasonFlag -> Ordering
    compare :: ReasonFlag -> ReasonFlag -> Ordering
    $c< :: ReasonFlag -> ReasonFlag -> Bool
    < :: ReasonFlag -> ReasonFlag -> Bool
    $c<= :: ReasonFlag -> ReasonFlag -> Bool
    <= :: ReasonFlag -> ReasonFlag -> Bool
    $c> :: ReasonFlag -> ReasonFlag -> Bool
    > :: ReasonFlag -> ReasonFlag -> Bool
    $c>= :: ReasonFlag -> ReasonFlag -> Bool
    >= :: ReasonFlag -> ReasonFlag -> Bool
    $cmax :: ReasonFlag -> ReasonFlag -> ReasonFlag
    max :: ReasonFlag -> ReasonFlag -> ReasonFlag
    $cmin :: ReasonFlag -> ReasonFlag -> ReasonFlag
    min :: ReasonFlag -> ReasonFlag -> ReasonFlag
    Ord,Int -> ReasonFlag
    ReasonFlag -> Int
    ReasonFlag -> [ReasonFlag]
    ReasonFlag -> ReasonFlag
    ReasonFlag -> ReasonFlag -> [ReasonFlag]
    ReasonFlag -> ReasonFlag -> ReasonFlag -> [ReasonFlag]
    (ReasonFlag -> ReasonFlag)
    -> (ReasonFlag -> ReasonFlag)
    -> (Int -> ReasonFlag)
    -> (ReasonFlag -> Int)
    -> (ReasonFlag -> [ReasonFlag])
    -> (ReasonFlag -> ReasonFlag -> [ReasonFlag])
    -> (ReasonFlag -> ReasonFlag -> [ReasonFlag])
    -> (ReasonFlag -> ReasonFlag -> ReasonFlag -> [ReasonFlag])
    -> Enum ReasonFlag
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    $csucc :: ReasonFlag -> ReasonFlag
    succ :: ReasonFlag -> ReasonFlag
    $cpred :: ReasonFlag -> ReasonFlag
    pred :: ReasonFlag -> ReasonFlag
    $ctoEnum :: Int -> ReasonFlag
    toEnum :: Int -> ReasonFlag
    $cfromEnum :: ReasonFlag -> Int
    fromEnum :: ReasonFlag -> Int
    $cenumFrom :: ReasonFlag -> [ReasonFlag]
    enumFrom :: ReasonFlag -> [ReasonFlag]
    $cenumFromThen :: ReasonFlag -> ReasonFlag -> [ReasonFlag]
    enumFromThen :: ReasonFlag -> ReasonFlag -> [ReasonFlag]
    $cenumFromTo :: ReasonFlag -> ReasonFlag -> [ReasonFlag]
    enumFromTo :: ReasonFlag -> ReasonFlag -> [ReasonFlag]
    $cenumFromThenTo :: ReasonFlag -> ReasonFlag -> ReasonFlag -> [ReasonFlag]
    enumFromThenTo :: ReasonFlag -> ReasonFlag -> ReasonFlag -> [ReasonFlag]
    Enum)

    -- | Distribution point as either some GeneralNames or a DN
    data DistributionPoint =
          DistributionPointFullName [AltName]
        | DistributionNameRelative DistinguishedName
        deriving (Int -> DistributionPoint -> ShowS
    [DistributionPoint] -> ShowS
    DistributionPoint -> String
    (Int -> DistributionPoint -> ShowS)
    -> (DistributionPoint -> String)
    -> ([DistributionPoint] -> ShowS)
    -> Show DistributionPoint
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> DistributionPoint -> ShowS
    showsPrec :: Int -> DistributionPoint -> ShowS
    $cshow :: DistributionPoint -> String
    show :: DistributionPoint -> String
    $cshowList :: [DistributionPoint] -> ShowS
    showList :: [DistributionPoint] -> ShowS
    Show,DistributionPoint -> DistributionPoint -> Bool
    (DistributionPoint -> DistributionPoint -> Bool)
    -> (DistributionPoint -> DistributionPoint -> Bool)
    -> Eq DistributionPoint
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: DistributionPoint -> DistributionPoint -> Bool
    == :: DistributionPoint -> DistributionPoint -> Bool
    $c/= :: DistributionPoint -> DistributionPoint -> Bool
    /= :: DistributionPoint -> DistributionPoint -> Bool
    Eq)

    instance Extension ExtCrlDistributionPoints where
        extOID :: ExtCrlDistributionPoints -> OID
    extOID ExtCrlDistributionPoints
    _ = [Integer
    2,Integer
    5,Integer
    29,Integer
    31]
        extHasNestedASN1 :: Proxy ExtCrlDistributionPoints -> Bool
    extHasNestedASN1 = Bool -> Proxy ExtCrlDistributionPoints -> Bool
    forall a b. a -> b -> a
    const Bool
    True
        extEncode :: ExtCrlDistributionPoints -> [ASN1]
    extEncode = String -> ExtCrlDistributionPoints -> [ASN1]
    forall a. HasCallStack => String -> a
    error String
    "extEncode ExtCrlDistributionPoints unimplemented"
        extDecode :: [ASN1] -> Either String ExtCrlDistributionPoints
    extDecode = String -> [ASN1] -> Either String ExtCrlDistributionPoints
    forall a. HasCallStack => String -> a
    error String
    "extDecode ExtCrlDistributionPoints unimplemented"
        --extEncode (ExtCrlDistributionPoints )

    parseGeneralNames :: ParseASN1 [AltName]
    parseGeneralNames :: ParseASN1 [AltName]
    parseGeneralNames = ASN1ConstructionType -> ParseASN1 [AltName] -> ParseASN1 [AltName]
    forall a. ASN1ConstructionType -> ParseASN1 a -> ParseASN1 a
    onNextContainer ASN1ConstructionType
    Sequence (ParseASN1 [AltName] -> ParseASN1 [AltName])
    -> ParseASN1 [AltName] -> ParseASN1 [AltName]
    forall a b. (a -> b) -> a -> b
    $ ParseASN1 AltName -> ParseASN1 [AltName]
    forall a. ParseASN1 a -> ParseASN1 [a]
    getMany ParseASN1 AltName
    getAddr
      where
            getAddr :: ParseASN1 AltName
    getAddr = do
                Maybe AltName
    m <- ASN1ConstructionType
    -> ParseASN1 AltName -> ParseASN1 (Maybe AltName)
    forall a.
    ASN1ConstructionType -> ParseASN1 a -> ParseASN1 (Maybe a)
    onNextContainerMaybe (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    0) ParseASN1 AltName
    getComposedAddr
                case Maybe AltName
    m of
                    Maybe AltName
    Nothing -> ParseASN1 AltName
    getSimpleAddr
                    Just AltName
    r  -> AltName -> ParseASN1 AltName
    forall a. a -> ParseASN1 a
    forall (m :: * -> *) a. Monad m => a -> m a
    return AltName
    r
            getComposedAddr :: ParseASN1 AltName
    getComposedAddr = do
                ASN1
    n <- ParseASN1 ASN1
    getNext
                case ASN1
    n of
                    OID [Integer
    1,Integer
    3,Integer
    6,Integer
    1,Integer
    5,Integer
    5,Integer
    7,Integer
    8,Integer
    5] -> do -- xmpp addr
                        Maybe [ASN1]
    c <- ASN1ConstructionType -> ParseASN1 (Maybe [ASN1])
    getNextContainerMaybe (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    0)
                        case Maybe [ASN1]
    c of
                            Just [ASN1String ASN1CharacterString
    cs] ->
                                case ASN1CharacterString -> Maybe String
    asn1CharacterToString ASN1CharacterString
    cs of
                                    Maybe String
    Nothing -> String -> ParseASN1 AltName
    forall a. String -> ParseASN1 a
    throwParseError (String
    "GeneralNames: invalid string for XMPP Addr")
                                    Just String
    s  -> AltName -> ParseASN1 AltName
    forall a. a -> ParseASN1 a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (AltName -> ParseASN1 AltName) -> AltName -> ParseASN1 AltName
    forall a b. (a -> b) -> a -> b
    $ String -> AltName
    AltNameXMPP String
    s
                            Maybe [ASN1]
    _ -> String -> ParseASN1 AltName
    forall a. String -> ParseASN1 a
    throwParseError (String
    "GeneralNames: expecting string for XMPP Addr got: " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Maybe [ASN1] -> String
    forall a. Show a => a -> String
    show Maybe [ASN1]
    c)
                    OID [Integer
    1,Integer
    3,Integer
    6,Integer
    1,Integer
    5,Integer
    5,Integer
    7,Integer
    8,Integer
    7] -> do -- DNSSRV addr
                        Maybe [ASN1]
    c <- ASN1ConstructionType -> ParseASN1 (Maybe [ASN1])
    getNextContainerMaybe (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    0)
                        case Maybe [ASN1]
    c of
                            Just [ASN1String ASN1CharacterString
    cs] ->
                                case ASN1CharacterString -> Maybe String
    asn1CharacterToString ASN1CharacterString
    cs of
                                    Maybe String
    Nothing -> String -> ParseASN1 AltName
    forall a. String -> ParseASN1 a
    throwParseError (String
    "GeneralNames: invalid string for DNSSrv Addr")
                                    Just String
    s  -> AltName -> ParseASN1 AltName
    forall a. a -> ParseASN1 a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (AltName -> ParseASN1 AltName) -> AltName -> ParseASN1 AltName
    forall a b. (a -> b) -> a -> b
    $ String -> AltName
    AltNameDNSSRV String
    s
                            Maybe [ASN1]
    _ -> String -> ParseASN1 AltName
    forall a. String -> ParseASN1 a
    throwParseError (String
    "GeneralNames: expecting string for DNSSRV Addr got: " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Maybe [ASN1] -> String
    forall a. Show a => a -> String
    show Maybe [ASN1]
    c)
                    OID OID
    unknown -> String -> ParseASN1 AltName
    forall a. String -> ParseASN1 a
    throwParseError (String
    "GeneralNames: unknown OID " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ OID -> String
    forall a. Show a => a -> String
    show OID
    unknown)
                    ASN1
    _           -> String -> ParseASN1 AltName
    forall a. String -> ParseASN1 a
    throwParseError (String
    "GeneralNames: expecting OID but got " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ ASN1 -> String
    forall a. Show a => a -> String
    show ASN1
    n)

            getSimpleAddr :: ParseASN1 AltName
    getSimpleAddr = do
                ASN1
    n <- ParseASN1 ASN1
    getNext
                case ASN1
    n of
                    (Other ASN1Class
    Context Int
    1 ByteString
    b) -> AltName -> ParseASN1 AltName
    forall a. a -> ParseASN1 a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (AltName -> ParseASN1 AltName) -> AltName -> ParseASN1 AltName
    forall a b. (a -> b) -> a -> b
    $ String -> AltName
    AltNameRFC822 (String -> AltName) -> String -> AltName
    forall a b. (a -> b) -> a -> b
    $ ByteString -> String
    BC.unpack ByteString
    b
                    (Other ASN1Class
    Context Int
    2 ByteString
    b) -> AltName -> ParseASN1 AltName
    forall a. a -> ParseASN1 a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (AltName -> ParseASN1 AltName) -> AltName -> ParseASN1 AltName
    forall a b. (a -> b) -> a -> b
    $ String -> AltName
    AltNameDNS (String -> AltName) -> String -> AltName
    forall a b. (a -> b) -> a -> b
    $ ByteString -> String
    BC.unpack ByteString
    b
                    (Other ASN1Class
    Context Int
    6 ByteString
    b) -> AltName -> ParseASN1 AltName
    forall a. a -> ParseASN1 a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (AltName -> ParseASN1 AltName) -> AltName -> ParseASN1 AltName
    forall a b. (a -> b) -> a -> b
    $ String -> AltName
    AltNameURI (String -> AltName) -> String -> AltName
    forall a b. (a -> b) -> a -> b
    $ ByteString -> String
    BC.unpack ByteString
    b
                    (Other ASN1Class
    Context Int
    7 ByteString
    b) -> AltName -> ParseASN1 AltName
    forall a. a -> ParseASN1 a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (AltName -> ParseASN1 AltName) -> AltName -> ParseASN1 AltName
    forall a b. (a -> b) -> a -> b
    $ ByteString -> AltName
    AltNameIP  ByteString
    b
                    ASN1
    _                   -> String -> ParseASN1 AltName
    forall a. String -> ParseASN1 a
    throwParseError (String
    "GeneralNames: not coping with unknown stream " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ ASN1 -> String
    forall a. Show a => a -> String
    show ASN1
    n)

    encodeGeneralNames :: [AltName] -> [ASN1]
    encodeGeneralNames :: [AltName] -> [ASN1]
    encodeGeneralNames [AltName]
    names =
        [ASN1ConstructionType -> ASN1
    Start ASN1ConstructionType
    Sequence]
        [ASN1] -> [ASN1] -> [ASN1]
    forall a. [a] -> [a] -> [a]
    ++ (AltName -> [ASN1]) -> [AltName] -> [ASN1]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap AltName -> [ASN1]
    encodeAltName [AltName]
    names
        [ASN1] -> [ASN1] -> [ASN1]
    forall a. [a] -> [a] -> [a]
    ++ [ASN1ConstructionType -> ASN1
    End ASN1ConstructionType
    Sequence]
      where encodeAltName :: AltName -> [ASN1]
    encodeAltName (AltNameRFC822 String
    n) = [ASN1Class -> Int -> ByteString -> ASN1
    Other ASN1Class
    Context Int
    1 (ByteString -> ASN1) -> ByteString -> ASN1
    forall a b. (a -> b) -> a -> b
    $ String -> ByteString
    BC.pack String
    n]
            encodeAltName (AltNameDNS String
    n)    = [ASN1Class -> Int -> ByteString -> ASN1
    Other ASN1Class
    Context Int
    2 (ByteString -> ASN1) -> ByteString -> ASN1
    forall a b. (a -> b) -> a -> b
    $ String -> ByteString
    BC.pack String
    n]
            encodeAltName (AltNameURI String
    n)    = [ASN1Class -> Int -> ByteString -> ASN1
    Other ASN1Class
    Context Int
    6 (ByteString -> ASN1) -> ByteString -> ASN1
    forall a b. (a -> b) -> a -> b
    $ String -> ByteString
    BC.pack String
    n]
            encodeAltName (AltNameIP ByteString
    n)     = [ASN1Class -> Int -> ByteString -> ASN1
    Other ASN1Class
    Context Int
    7 (ByteString -> ASN1) -> ByteString -> ASN1
    forall a b. (a -> b) -> a -> b
    $ ByteString
    n]
            encodeAltName (AltNameXMPP String
    n)   = [ASN1ConstructionType -> ASN1
    Start (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    0),OID -> ASN1
    OID[Integer
    1,Integer
    3,Integer
    6,Integer
    1,Integer
    5,Integer
    5,Integer
    7,Integer
    8,Integer
    5]
                                              ,ASN1ConstructionType -> ASN1
    Start (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    0), ASN1CharacterString -> ASN1
    ASN1String (ASN1CharacterString -> ASN1) -> ASN1CharacterString -> ASN1
    forall a b. (a -> b) -> a -> b
    $ ASN1StringEncoding -> String -> ASN1CharacterString
    asn1CharacterString ASN1StringEncoding
    UTF8 String
    n, ASN1ConstructionType -> ASN1
    End (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    0)
                                              ,ASN1ConstructionType -> ASN1
    End (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    0)]
            encodeAltName (AltNameDNSSRV String
    n) = [ASN1ConstructionType -> ASN1
    Start (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    0),OID -> ASN1
    OID[Integer
    1,Integer
    3,Integer
    6,Integer
    1,Integer
    5,Integer
    5,Integer
    7,Integer
    8,Integer
    5]
                                              ,ASN1ConstructionType -> ASN1
    Start (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    0), ASN1CharacterString -> ASN1
    ASN1String (ASN1CharacterString -> ASN1) -> ASN1CharacterString -> ASN1
    forall a b. (a -> b) -> a -> b
    $ ASN1StringEncoding -> String -> ASN1CharacterString
    asn1CharacterString ASN1StringEncoding
    UTF8 String
    n, ASN1ConstructionType -> ASN1
    End (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    0)
                                              ,ASN1ConstructionType -> ASN1
    End (ASN1Class -> Int -> ASN1ConstructionType
    Container ASN1Class
    Context Int
    0)]

    bitsToFlags :: Enum a => BitArray -> [a]
    bitsToFlags :: forall a. Enum a => BitArray -> [a]
    bitsToFlags BitArray
    bits = [[a]] -> [a]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat ([[a]] -> [a]) -> [[a]] -> [a]
    forall a b. (a -> b) -> a -> b
    $ ((Word64 -> [a]) -> [Word64] -> [[a]])
    -> [Word64] -> (Word64 -> [a]) -> [[a]]
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip (Word64 -> [a]) -> [Word64] -> [[a]]
    forall a b. (a -> b) -> [a] -> [b]
    map [Word64
    0..(BitArray -> Word64
    bitArrayLength BitArray
    bitsWord64 -> Word64 -> Word64
    forall a. Num a => a -> a -> a
    -Word64
    1)] ((Word64 -> [a]) -> [[a]]) -> (Word64 -> [a]) -> [[a]]
    forall a b. (a -> b) -> a -> b
    $ \Word64
    i -> do
            let isSet :: Bool
    isSet = BitArray -> Word64 -> Bool
    bitArrayGetBit BitArray
    bits Word64
    i
            if Bool
    isSet then [Int -> a
    forall a. Enum a => Int -> a
    toEnum (Int -> a) -> Int -> a
    forall a b. (a -> b) -> a -> b
    $ Word64 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word64
    i] else []

    flagsToBits :: Enum a => [a] -> BitArray
    flagsToBits :: forall a. Enum a => [a] -> BitArray
    flagsToBits [a]
    flags = (BitArray -> Word64 -> BitArray)
    -> BitArray -> [Word64] -> BitArray
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl BitArray -> Word64 -> BitArray
    bitArraySetBit BitArray
    bitArrayEmpty ([Word64] -> BitArray) -> [Word64] -> BitArray
    forall a b. (a -> b) -> a -> b
    $ (a -> Word64) -> [a] -> [Word64]
    forall a b. (a -> b) -> [a] -> [b]
    map (Int -> Word64
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Int -> Word64) -> (a -> Int) -> a -> Word64
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> Int
    forall a. Enum a => a -> Int
    fromEnum) [a]
    flags
      where bitArrayEmpty :: BitArray
    bitArrayEmpty = ByteString -> Int -> BitArray
    toBitArray ([Word8] -> ByteString
    B.pack [Word8
    0,Word8
    0]) Int
    7

    data ExtNetscapeComment = ExtNetscapeComment B.ByteString
        deriving (Int -> ExtNetscapeComment -> ShowS
    [ExtNetscapeComment] -> ShowS
    ExtNetscapeComment -> String
    (Int -> ExtNetscapeComment -> ShowS)
    -> (ExtNetscapeComment -> String)
    -> ([ExtNetscapeComment] -> ShowS)
    -> Show ExtNetscapeComment
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ExtNetscapeComment -> ShowS
    showsPrec :: Int -> ExtNetscapeComment -> ShowS
    $cshow :: ExtNetscapeComment -> String
    show :: ExtNetscapeComment -> String
    $cshowList :: [ExtNetscapeComment] -> ShowS
    showList :: [ExtNetscapeComment] -> ShowS
    Show,ExtNetscapeComment -> ExtNetscapeComment -> Bool
    (ExtNetscapeComment -> ExtNetscapeComment -> Bool)
    -> (ExtNetscapeComment -> ExtNetscapeComment -> Bool)
    -> Eq ExtNetscapeComment
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ExtNetscapeComment -> ExtNetscapeComment -> Bool
    == :: ExtNetscapeComment -> ExtNetscapeComment -> Bool
    $c/= :: ExtNetscapeComment -> ExtNetscapeComment -> Bool
    /= :: ExtNetscapeComment -> ExtNetscapeComment -> Bool
    Eq)

    instance Extension ExtNetscapeComment where
        extOID :: ExtNetscapeComment -> OID
    extOID ExtNetscapeComment
    _ = [Integer
    2,Integer
    16,Integer
    840,Integer
    1,Integer
    113730,Integer
    1,Integer
    13]
        extHasNestedASN1 :: Proxy ExtNetscapeComment -> Bool
    extHasNestedASN1 = Bool -> Proxy ExtNetscapeComment -> Bool
    forall a b. a -> b -> a
    const Bool
    False
        extEncode :: ExtNetscapeComment -> [ASN1]
    extEncode = String -> ExtNetscapeComment -> [ASN1]
    forall a. HasCallStack => String -> a
    error String
    "Extension: Netscape Comment do not contain nested ASN1"
        extDecode :: [ASN1] -> Either String ExtNetscapeComment
    extDecode = String -> [ASN1] -> Either String ExtNetscapeComment
    forall a. HasCallStack => String -> a
    error String
    "Extension: Netscape Comment do not contain nested ASN1"
        extEncodeBs :: ExtNetscapeComment -> ByteString
    extEncodeBs (ExtNetscapeComment ByteString
    b) = ByteString
    b
        extDecodeBs :: ByteString -> Either String ExtNetscapeComment
    extDecodeBs = ExtNetscapeComment -> Either String ExtNetscapeComment
    forall a b. b -> Either a b
    Right (ExtNetscapeComment -> Either String ExtNetscapeComment)
    -> (ByteString -> ExtNetscapeComment)
    -> ByteString
    -> Either String ExtNetscapeComment
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> ExtNetscapeComment
    ExtNetscapeComment