{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}

-- |
-- Module      : Data.X509.Ext
-- License     : BSD-style
-- Maintainer  : Vincent Hanquez <vincent@snarc.org>
-- Stability   : experimental
-- Portability : unknown
--
-- extension processing module.
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 Control.Applicative
import Control.Monad
import Data.ASN1.BinaryEncoding
import Data.ASN1.BitArray
import Data.ASN1.Encoding
import Data.ASN1.Parse
import Data.ASN1.Types
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as BC
import Data.List (find)
import Data.Proxy
import Data.X509.DistinguishedName
import Data.X509.ExtensionRaw

-- | 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
bits Word64 -> 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