-- |
-- 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
showList :: [ExtKeyUsageFlag] -> ShowS
$cshowList :: [ExtKeyUsageFlag] -> ShowS
show :: ExtKeyUsageFlag -> String
$cshow :: ExtKeyUsageFlag -> String
showsPrec :: Int -> ExtKeyUsageFlag -> ShowS
$cshowsPrec :: Int -> ExtKeyUsageFlag -> ShowS
Show,ExtKeyUsageFlag -> ExtKeyUsageFlag -> Bool
(ExtKeyUsageFlag -> ExtKeyUsageFlag -> Bool)
-> (ExtKeyUsageFlag -> ExtKeyUsageFlag -> Bool)
-> Eq ExtKeyUsageFlag
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> Bool
$c/= :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> Bool
== :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> Bool
$c== :: 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
min :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> ExtKeyUsageFlag
$cmin :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> ExtKeyUsageFlag
max :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> ExtKeyUsageFlag
$cmax :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> ExtKeyUsageFlag
>= :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> Bool
$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
compare :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> Ordering
$ccompare :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> Ordering
$cp1Ord :: Eq 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
enumFromThenTo :: ExtKeyUsageFlag
-> ExtKeyUsageFlag -> ExtKeyUsageFlag -> [ExtKeyUsageFlag]
$cenumFromThenTo :: ExtKeyUsageFlag
-> ExtKeyUsageFlag -> ExtKeyUsageFlag -> [ExtKeyUsageFlag]
enumFromTo :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> [ExtKeyUsageFlag]
$cenumFromTo :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> [ExtKeyUsageFlag]
enumFromThen :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> [ExtKeyUsageFlag]
$cenumFromThen :: ExtKeyUsageFlag -> ExtKeyUsageFlag -> [ExtKeyUsageFlag]
enumFrom :: ExtKeyUsageFlag -> [ExtKeyUsageFlag]
$cenumFrom :: ExtKeyUsageFlag -> [ExtKeyUsageFlag]
fromEnum :: ExtKeyUsageFlag -> Int
$cfromEnum :: ExtKeyUsageFlag -> Int
toEnum :: Int -> ExtKeyUsageFlag
$ctoEnum :: Int -> ExtKeyUsageFlag
pred :: ExtKeyUsageFlag -> ExtKeyUsageFlag
$cpred :: ExtKeyUsageFlag -> ExtKeyUsageFlag
succ :: ExtKeyUsageFlag -> ExtKeyUsageFlag
$csucc :: 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 :: 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 :: 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 :: 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 (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 :: 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
showList :: [ExtBasicConstraints] -> ShowS
$cshowList :: [ExtBasicConstraints] -> ShowS
show :: ExtBasicConstraints -> String
$cshow :: ExtBasicConstraints -> String
showsPrec :: Int -> ExtBasicConstraints -> ShowS
$cshowsPrec :: Int -> ExtBasicConstraints -> ShowS
Show,ExtBasicConstraints -> ExtBasicConstraints -> Bool
(ExtBasicConstraints -> ExtBasicConstraints -> Bool)
-> (ExtBasicConstraints -> ExtBasicConstraints -> Bool)
-> Eq ExtBasicConstraints
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ExtBasicConstraints -> ExtBasicConstraints -> Bool
$c/= :: ExtBasicConstraints -> ExtBasicConstraints -> Bool
== :: ExtBasicConstraints -> ExtBasicConstraints -> Bool
$c== :: 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
showList :: [ExtKeyUsage] -> ShowS
$cshowList :: [ExtKeyUsage] -> ShowS
show :: ExtKeyUsage -> String
$cshow :: ExtKeyUsage -> String
showsPrec :: Int -> ExtKeyUsage -> ShowS
$cshowsPrec :: Int -> ExtKeyUsage -> ShowS
Show,ExtKeyUsage -> ExtKeyUsage -> Bool
(ExtKeyUsage -> ExtKeyUsage -> Bool)
-> (ExtKeyUsage -> ExtKeyUsage -> Bool) -> Eq ExtKeyUsage
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ExtKeyUsage -> ExtKeyUsage -> Bool
$c/= :: ExtKeyUsage -> ExtKeyUsage -> Bool
== :: ExtKeyUsage -> ExtKeyUsage -> Bool
$c== :: 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
showList :: [ExtKeyUsagePurpose] -> ShowS
$cshowList :: [ExtKeyUsagePurpose] -> ShowS
show :: ExtKeyUsagePurpose -> String
$cshow :: ExtKeyUsagePurpose -> String
showsPrec :: Int -> ExtKeyUsagePurpose -> ShowS
$cshowsPrec :: Int -> ExtKeyUsagePurpose -> ShowS
Show,ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool
(ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool)
-> (ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool)
-> Eq ExtKeyUsagePurpose
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool
$c/= :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool
== :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool
$c== :: 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
min :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> ExtKeyUsagePurpose
$cmin :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> ExtKeyUsagePurpose
max :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> ExtKeyUsagePurpose
$cmax :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> ExtKeyUsagePurpose
>= :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Bool
$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
compare :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Ordering
$ccompare :: ExtKeyUsagePurpose -> ExtKeyUsagePurpose -> Ordering
$cp1Ord :: Eq 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
showList :: [ExtExtendedKeyUsage] -> ShowS
$cshowList :: [ExtExtendedKeyUsage] -> ShowS
show :: ExtExtendedKeyUsage -> String
$cshow :: ExtExtendedKeyUsage -> String
showsPrec :: Int -> ExtExtendedKeyUsage -> ShowS
$cshowsPrec :: Int -> ExtExtendedKeyUsage -> ShowS
Show,ExtExtendedKeyUsage -> ExtExtendedKeyUsage -> Bool
(ExtExtendedKeyUsage -> ExtExtendedKeyUsage -> Bool)
-> (ExtExtendedKeyUsage -> ExtExtendedKeyUsage -> Bool)
-> Eq ExtExtendedKeyUsage
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ExtExtendedKeyUsage -> ExtExtendedKeyUsage -> Bool
$c/= :: ExtExtendedKeyUsage -> ExtExtendedKeyUsage -> Bool
== :: ExtExtendedKeyUsage -> ExtExtendedKeyUsage -> Bool
$c== :: 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 (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 (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
showList :: [ExtSubjectKeyId] -> ShowS
$cshowList :: [ExtSubjectKeyId] -> ShowS
show :: ExtSubjectKeyId -> String
$cshow :: ExtSubjectKeyId -> String
showsPrec :: Int -> ExtSubjectKeyId -> ShowS
$cshowsPrec :: Int -> ExtSubjectKeyId -> ShowS
Show,ExtSubjectKeyId -> ExtSubjectKeyId -> Bool
(ExtSubjectKeyId -> ExtSubjectKeyId -> Bool)
-> (ExtSubjectKeyId -> ExtSubjectKeyId -> Bool)
-> Eq ExtSubjectKeyId
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ExtSubjectKeyId -> ExtSubjectKeyId -> Bool
$c/= :: ExtSubjectKeyId -> ExtSubjectKeyId -> Bool
== :: ExtSubjectKeyId -> ExtSubjectKeyId -> Bool
$c== :: 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
showList :: [AltName] -> ShowS
$cshowList :: [AltName] -> ShowS
show :: AltName -> String
$cshow :: AltName -> String
showsPrec :: Int -> AltName -> ShowS
$cshowsPrec :: Int -> AltName -> ShowS
Show,AltName -> AltName -> Bool
(AltName -> AltName -> Bool)
-> (AltName -> AltName -> Bool) -> Eq AltName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AltName -> AltName -> Bool
$c/= :: AltName -> AltName -> Bool
== :: AltName -> AltName -> Bool
$c== :: 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
min :: AltName -> AltName -> AltName
$cmin :: AltName -> AltName -> AltName
max :: AltName -> AltName -> AltName
$cmax :: AltName -> AltName -> AltName
>= :: AltName -> AltName -> Bool
$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
compare :: AltName -> AltName -> Ordering
$ccompare :: AltName -> AltName -> Ordering
$cp1Ord :: Eq 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
showList :: [ExtSubjectAltName] -> ShowS
$cshowList :: [ExtSubjectAltName] -> ShowS
show :: ExtSubjectAltName -> String
$cshow :: ExtSubjectAltName -> String
showsPrec :: Int -> ExtSubjectAltName -> ShowS
$cshowsPrec :: Int -> ExtSubjectAltName -> ShowS
Show,ExtSubjectAltName -> ExtSubjectAltName -> Bool
(ExtSubjectAltName -> ExtSubjectAltName -> Bool)
-> (ExtSubjectAltName -> ExtSubjectAltName -> Bool)
-> Eq ExtSubjectAltName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ExtSubjectAltName -> ExtSubjectAltName -> Bool
$c/= :: ExtSubjectAltName -> ExtSubjectAltName -> Bool
== :: ExtSubjectAltName -> ExtSubjectAltName -> Bool
$c== :: 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
min :: ExtSubjectAltName -> ExtSubjectAltName -> ExtSubjectAltName
$cmin :: ExtSubjectAltName -> ExtSubjectAltName -> ExtSubjectAltName
max :: ExtSubjectAltName -> ExtSubjectAltName -> ExtSubjectAltName
$cmax :: ExtSubjectAltName -> ExtSubjectAltName -> ExtSubjectAltName
>= :: ExtSubjectAltName -> ExtSubjectAltName -> Bool
$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
compare :: ExtSubjectAltName -> ExtSubjectAltName -> Ordering
$ccompare :: ExtSubjectAltName -> ExtSubjectAltName -> Ordering
$cp1Ord :: Eq 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
showList :: [ExtAuthorityKeyId] -> ShowS
$cshowList :: [ExtAuthorityKeyId] -> ShowS
show :: ExtAuthorityKeyId -> String
$cshow :: ExtAuthorityKeyId -> String
showsPrec :: Int -> ExtAuthorityKeyId -> ShowS
$cshowsPrec :: Int -> ExtAuthorityKeyId -> ShowS
Show,ExtAuthorityKeyId -> ExtAuthorityKeyId -> Bool
(ExtAuthorityKeyId -> ExtAuthorityKeyId -> Bool)
-> (ExtAuthorityKeyId -> ExtAuthorityKeyId -> Bool)
-> Eq ExtAuthorityKeyId
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ExtAuthorityKeyId -> ExtAuthorityKeyId -> Bool
$c/= :: ExtAuthorityKeyId -> ExtAuthorityKeyId -> Bool
== :: ExtAuthorityKeyId -> ExtAuthorityKeyId -> Bool
$c== :: 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
showList :: [ExtCrlDistributionPoints] -> ShowS
$cshowList :: [ExtCrlDistributionPoints] -> ShowS
show :: ExtCrlDistributionPoints -> String
$cshow :: ExtCrlDistributionPoints -> String
showsPrec :: Int -> ExtCrlDistributionPoints -> ShowS
$cshowsPrec :: Int -> ExtCrlDistributionPoints -> ShowS
Show,ExtCrlDistributionPoints -> ExtCrlDistributionPoints -> Bool
(ExtCrlDistributionPoints -> ExtCrlDistributionPoints -> Bool)
-> (ExtCrlDistributionPoints -> ExtCrlDistributionPoints -> Bool)
-> Eq ExtCrlDistributionPoints
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ExtCrlDistributionPoints -> ExtCrlDistributionPoints -> Bool
$c/= :: ExtCrlDistributionPoints -> ExtCrlDistributionPoints -> Bool
== :: ExtCrlDistributionPoints -> ExtCrlDistributionPoints -> Bool
$c== :: 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
showList :: [ReasonFlag] -> ShowS
$cshowList :: [ReasonFlag] -> ShowS
show :: ReasonFlag -> String
$cshow :: ReasonFlag -> String
showsPrec :: Int -> ReasonFlag -> ShowS
$cshowsPrec :: Int -> ReasonFlag -> ShowS
Show,ReasonFlag -> ReasonFlag -> Bool
(ReasonFlag -> ReasonFlag -> Bool)
-> (ReasonFlag -> ReasonFlag -> Bool) -> Eq ReasonFlag
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ReasonFlag -> ReasonFlag -> Bool
$c/= :: ReasonFlag -> ReasonFlag -> Bool
== :: ReasonFlag -> ReasonFlag -> Bool
$c== :: 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
min :: ReasonFlag -> ReasonFlag -> ReasonFlag
$cmin :: ReasonFlag -> ReasonFlag -> ReasonFlag
max :: ReasonFlag -> ReasonFlag -> ReasonFlag
$cmax :: ReasonFlag -> ReasonFlag -> ReasonFlag
>= :: ReasonFlag -> ReasonFlag -> Bool
$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
compare :: ReasonFlag -> ReasonFlag -> Ordering
$ccompare :: ReasonFlag -> ReasonFlag -> Ordering
$cp1Ord :: Eq 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
enumFromThenTo :: ReasonFlag -> ReasonFlag -> ReasonFlag -> [ReasonFlag]
$cenumFromThenTo :: ReasonFlag -> ReasonFlag -> ReasonFlag -> [ReasonFlag]
enumFromTo :: ReasonFlag -> ReasonFlag -> [ReasonFlag]
$cenumFromTo :: ReasonFlag -> ReasonFlag -> [ReasonFlag]
enumFromThen :: ReasonFlag -> ReasonFlag -> [ReasonFlag]
$cenumFromThen :: ReasonFlag -> ReasonFlag -> [ReasonFlag]
enumFrom :: ReasonFlag -> [ReasonFlag]
$cenumFrom :: ReasonFlag -> [ReasonFlag]
fromEnum :: ReasonFlag -> Int
$cfromEnum :: ReasonFlag -> Int
toEnum :: Int -> ReasonFlag
$ctoEnum :: Int -> ReasonFlag
pred :: ReasonFlag -> ReasonFlag
$cpred :: ReasonFlag -> ReasonFlag
succ :: ReasonFlag -> ReasonFlag
$csucc :: 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
showList :: [DistributionPoint] -> ShowS
$cshowList :: [DistributionPoint] -> ShowS
show :: DistributionPoint -> String
$cshow :: DistributionPoint -> String
showsPrec :: Int -> DistributionPoint -> ShowS
$cshowsPrec :: Int -> DistributionPoint -> ShowS
Show,DistributionPoint -> DistributionPoint -> Bool
(DistributionPoint -> DistributionPoint -> Bool)
-> (DistributionPoint -> DistributionPoint -> Bool)
-> Eq DistributionPoint
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DistributionPoint -> DistributionPoint -> Bool
$c/= :: DistributionPoint -> DistributionPoint -> Bool
== :: DistributionPoint -> DistributionPoint -> Bool
$c== :: 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 (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 (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 (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 (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 (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 (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 (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 :: 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 :: [a] -> BitArray
flagsToBits [a]
flags = (BitArray -> Word64 -> BitArray)
-> BitArray -> [Word64] -> BitArray
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
showList :: [ExtNetscapeComment] -> ShowS
$cshowList :: [ExtNetscapeComment] -> ShowS
show :: ExtNetscapeComment -> String
$cshow :: ExtNetscapeComment -> String
showsPrec :: Int -> ExtNetscapeComment -> ShowS
$cshowsPrec :: Int -> ExtNetscapeComment -> ShowS
Show,ExtNetscapeComment -> ExtNetscapeComment -> Bool
(ExtNetscapeComment -> ExtNetscapeComment -> Bool)
-> (ExtNetscapeComment -> ExtNetscapeComment -> Bool)
-> Eq ExtNetscapeComment
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ExtNetscapeComment -> ExtNetscapeComment -> Bool
$c/= :: ExtNetscapeComment -> ExtNetscapeComment -> Bool
== :: ExtNetscapeComment -> ExtNetscapeComment -> Bool
$c== :: 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