packages feed

crypton-x509-store 1.6.9 → 1.6.10

raw patch · 6 files changed

+550/−476 lines, 6 filessetup-changedPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

Data/X509/CertificateStore.hs view
@@ -1,13 +1,15 @@ {-# LANGUAGE CPP #-}-module Data.X509.CertificateStore-    ( CertificateStore-    , makeCertificateStore-    , readCertificateStore-    , readCertificates++module Data.X509.CertificateStore (+    CertificateStore,+    makeCertificateStore,+    readCertificateStore,+    readCertificates,+     -- * Queries-    , findCertificate-    , listCertificates-    ) where+    findCertificate,+    listCertificates,+) where  import Data.Char (isDigit, isHexDigit) import Data.Either (rights)@@ -17,20 +19,24 @@ #else import           Data.Monoid #endif-import Data.PEM (pemParseBS, pemContent)-import Data.X509-import qualified Data.Map as M import Control.Applicative ((<$>))-import Control.Monad (mplus, filterM)-import System.Directory (getDirectoryContents, doesFileExist, doesDirectoryExist)-import System.FilePath ((</>)) import qualified Control.Exception as E+import Control.Monad (filterM, mplus) import qualified Data.ByteString as B-+import qualified Data.Map as M+import Data.PEM (pemContent, pemParseBS)+import Data.X509+import System.Directory (+    doesDirectoryExist,+    doesFileExist,+    getDirectoryContents,+ )+import System.FilePath ((</>))  -- | A Collection of certificate or store of certificates.-data CertificateStore = CertificateStore (M.Map DistinguishedName SignedCertificate)-                      | CertificateStores [CertificateStore]+data CertificateStore+    = CertificateStore (M.Map DistinguishedName SignedCertificate)+    | CertificateStores [CertificateStore]  #if MIN_VERSION_base(4,9,0) instance Semigroup CertificateStore where@@ -38,32 +44,35 @@ #endif  instance Monoid CertificateStore where-    mempty  = CertificateStore M.empty+    mempty = CertificateStore M.empty #if !(MIN_VERSION_base(4,11,0))     mappend = append #endif  append :: CertificateStore -> CertificateStore -> CertificateStore-append s1@(CertificateStore _)   s2@(CertificateStore _) = CertificateStores [s1,s2]-append    (CertificateStores l)  s2@(CertificateStore _) = CertificateStores (l ++ [s2])-append s1@(CertificateStore _)   (CertificateStores l)   = CertificateStores ([s1] ++ l)-append    (CertificateStores l1) (CertificateStores l2)  = CertificateStores (l1 ++ l2)+append s1@(CertificateStore _) s2@(CertificateStore _) = CertificateStores [s1, s2]+append (CertificateStores l) s2@(CertificateStore _) = CertificateStores (l ++ [s2])+append s1@(CertificateStore _) (CertificateStores l) = CertificateStores ([s1] ++ l)+append (CertificateStores l1) (CertificateStores l2) = CertificateStores (l1 ++ l2)  -- | Create a certificate store out of a list of X509 certificate makeCertificateStore :: [SignedCertificate] -> CertificateStore makeCertificateStore = CertificateStore . foldl' accumulate M.empty-    where accumulate m x509 = M.insert (certSubjectDN $ getCertificate x509) x509 m+  where+    accumulate m x509 = M.insert (certSubjectDN $ getCertificate x509) x509 m  -- | Find a certificate using the subject distinguished name-findCertificate :: DistinguishedName -> CertificateStore -> Maybe SignedCertificate+findCertificate+    :: DistinguishedName -> CertificateStore -> Maybe SignedCertificate findCertificate dn store = lookupIn store-    where lookupIn (CertificateStore m)  = M.lookup dn m-          lookupIn (CertificateStores l) = foldl mplus Nothing $ map lookupIn l+  where+    lookupIn (CertificateStore m) = M.lookup dn m+    lookupIn (CertificateStores l) = foldl mplus Nothing $ map lookupIn l  -- | List all certificates in a store listCertificates :: CertificateStore -> [SignedCertificate] listCertificates (CertificateStore store) = map snd $ M.toList store-listCertificates (CertificateStores l)    = concatMap listCertificates l+listCertificates (CertificateStores l) = concatMap listCertificates l  -- | Create certificate store by reading certificates from file or directory --@@ -73,16 +82,17 @@ -- certificate). readCertificateStore :: FilePath -> IO (Maybe CertificateStore) readCertificateStore path = do-    isDir  <- doesDirectoryExist path+    isDir <- doesDirectoryExist path     isFile <- doesFileExist path-    wrapStore <$> (if isDir then makeDirStore else if isFile then makeFileStore else return [])+    wrapStore+        <$> (if isDir then makeDirStore else if isFile then makeFileStore else return [])   where     wrapStore :: [SignedCertificate] -> Maybe CertificateStore     wrapStore [] = Nothing-    wrapStore l  = Just $ makeCertificateStore l+    wrapStore l = Just $ makeCertificateStore l      makeFileStore = readCertificates path-    makeDirStore  = do+    makeDirStore = do         certFiles <- listDirectoryCerts path         concat <$> mapM readCertificates certFiles @@ -90,11 +100,14 @@ -- -- The file may contains multiple certificates readCertificates :: FilePath -> IO [SignedCertificate]-readCertificates file = E.catch (either (const []) (rights . map getCert) . pemParseBS <$> B.readFile file) skipIOError-    where-        getCert = decodeSignedCertificate . pemContent-        skipIOError :: E.IOException -> IO [SignedCertificate]-        skipIOError _ = return []+readCertificates file =+    E.catch+        (either (const []) (rights . map getCert) . pemParseBS <$> B.readFile file)+        skipIOError+  where+    getCert = decodeSignedCertificate . pemContent+    skipIOError :: E.IOException -> IO [SignedCertificate]+    skipIOError _ = return []  -- List all the path susceptible to contains a certificate in a directory --@@ -103,12 +116,17 @@ listDirectoryCerts path =     getDirContents >>= filterM doesFileExist   where-    isHashedFile s = length s == 10-                  && isDigit (s !! 9)-                  && (s !! 8) == '.'-                  && all isHexDigit (take 8 s)+    isHashedFile s =+        length s == 10+            && isDigit (s !! 9)+            && (s !! 8) == '.'+            && all isHexDigit (take 8 s)     isCert x = (not $ isPrefixOf "." x) && (not $ isHashedFile x) -    getDirContents = E.catch (map (path </>) . filter isCert <$> getDirectoryContents path) emptyPaths-            where emptyPaths :: E.IOException -> IO [FilePath]-                  emptyPaths _ = return []+    getDirContents =+        E.catch+            (map (path </>) . filter isCert <$> getDirectoryContents path)+            emptyPaths+      where+        emptyPaths :: E.IOException -> IO [FilePath]+        emptyPaths _ = return []
Data/X509/File.hs view
@@ -1,25 +1,25 @@-module Data.X509.File-    ( readSignedObject-    , readKeyFile-    , PEMError (..)-    ) where+module Data.X509.File (+    readSignedObject,+    readKeyFile,+    PEMError (..),+) where  import Control.Applicative import Control.Exception (Exception (..), throw)-import Data.ASN1.Types import Data.ASN1.BinaryEncoding import Data.ASN1.Encoding+import Data.ASN1.Types+import qualified Data.ByteString.Lazy as L import Data.Maybe+import Data.PEM (PEM, pemContent, pemName, pemParseLBS) import qualified Data.X509 as X509-import           Data.X509.Memory (pemToKey)-import Data.PEM (pemParseLBS, pemContent, pemName, PEM)-import qualified Data.ByteString.Lazy as L+import Data.X509.Memory (pemToKey)  newtype PEMError = PEMError {displayPEMError :: String}-  deriving Show+    deriving (Show)  instance Exception PEMError where-  displayException = displayPEMError+    displayException = displayPEMError  readPEMs :: FilePath -> IO [PEM] readPEMs filepath = do@@ -29,12 +29,14 @@ -- | return all the signed objects in a file. -- -- (only one type at a time).-readSignedObject :: (ASN1Object a, Eq a, Show a)-                 => FilePath-                 -> IO [X509.SignedExact a]+readSignedObject+    :: (ASN1Object a, Eq a, Show a)+    => FilePath+    -> IO [X509.SignedExact a] readSignedObject filepath = decodePEMs <$> readPEMs filepath-  where decodePEMs pems =-          [ obj | pem <- pems, Right obj <- [X509.decodeSignedObject $ pemContent pem] ]+  where+    decodePEMs pems =+        [obj | pem <- pems, Right obj <- [X509.decodeSignedObject $ pemContent pem]]  -- | return all the private keys that were successfully read from a file. readKeyFile :: FilePath -> IO [X509.PrivKey]
Data/X509/Memory.hs view
@@ -4,46 +4,43 @@ -- Maintainer  : Vincent Hanquez <vincent@snarc.org> -- Stability   : experimental -- Portability : unknown-------module Data.X509.Memory-    ( readKeyFileFromMemory-    , readSignedObjectFromMemory-    , pemToKey-    ) where+module Data.X509.Memory (+    readKeyFileFromMemory,+    readSignedObjectFromMemory,+    pemToKey,+) where -import Data.ASN1.Types+import Crypto.Number.Basic (numBytes)+import Crypto.Number.Serialize (os2ip)+import qualified Crypto.PubKey.DSA as DSA+import qualified Crypto.PubKey.ECC.ECDSA as ECDSA+import qualified Crypto.PubKey.RSA as RSA import Data.ASN1.BinaryEncoding import Data.ASN1.BitArray import Data.ASN1.Encoding import Data.ASN1.Stream+import Data.ASN1.Types+import qualified Data.ByteString as B import Data.Maybe+import Data.PEM (PEM, pemContent, pemName, pemParseBS) import qualified Data.X509 as X509-import           Data.X509.EC as X509-import Data.PEM (pemParseBS, pemContent, pemName, PEM)-import qualified Data.ByteString as B-import           Crypto.Number.Basic (numBytes)-import           Crypto.Number.Serialize (os2ip)-import qualified Crypto.PubKey.DSA as DSA-import qualified Crypto.PubKey.ECC.ECDSA as ECDSA-import qualified Crypto.PubKey.RSA as RSA+import Data.X509.EC as X509  readKeyFileFromMemory :: B.ByteString -> [X509.PrivKey] readKeyFileFromMemory = either (const []) (catMaybes . foldl pemToKey []) . pemParseBS -readSignedObjectFromMemory :: (ASN1Object a, Eq a, Show a)-                           => B.ByteString-                           -> [X509.SignedExact a]-readSignedObjectFromMemory = either (const []) (foldl pemToSigned []) . pemParseBS-  where pemToSigned acc pem =-            case X509.decodeSignedObject $ pemContent pem of-                Left _    -> acc-                Right obj -> obj : acc+readSignedObjectFromMemory+    :: (ASN1Object a, Eq a, Show a)+    => B.ByteString+    -> [X509.SignedExact a]+readSignedObjectFromMemory = either (const []) decodePems . pemParseBS+  where+    decodePems pems = [ obj | pem <- pems, Right obj <- [X509.decodeSignedObject $ pemContent pem] ]  pemToKey :: [Maybe X509.PrivKey] -> PEM -> [Maybe X509.PrivKey] pemToKey acc pem =     case decodeASN1' BER (pemContent pem) of-        Left _     -> acc+        Left _ -> acc         Right asn1 ->             case pemName pem of                 "PRIVATE KEY" ->@@ -52,7 +49,7 @@                     tryRSA asn1 : acc                 "DSA PRIVATE KEY" ->                     tryDSA asn1 : acc-                "EC PRIVATE KEY"  ->+                "EC PRIVATE KEY" ->                     tryECDSA asn1 : acc                 "X25519 PRIVATE KEY" ->                     tryNewcurve asn1 : acc@@ -62,160 +59,182 @@                     tryNewcurve asn1 : acc                 "ED448 PRIVATE KEY" ->                     tryNewcurve asn1 : acc-                _                 -> acc+                _ -> acc   where-        tryRSA asn1 = case rsaFromASN1 asn1 of-                    Left _      -> Nothing-                    Right (k,_) -> Just $ X509.PrivKeyRSA k-        tryDSA asn1 = case dsaFromASN1 asn1 of-                    Left _      -> Nothing-                    Right (k,_) -> Just $ X509.PrivKeyDSA $ DSA.toPrivateKey k-        tryECDSA asn1 = case ecdsaFromASN1 [] asn1 of-                    Left _      -> Nothing-                    Right (k,_) -> Just $ X509.PrivKeyEC k-        tryNewcurve asn1 = case fromASN1 asn1 of-                    Right (k@(X509.PrivKeyX25519  _),_) -> Just k-                    Right (k@(X509.PrivKeyX448    _),_) -> Just k-                    Right (k@(X509.PrivKeyEd25519 _),_) -> Just k-                    Right (k@(X509.PrivKeyEd448   _),_) -> Just k-                    _ -> Nothing+    tryRSA asn1 = case rsaFromASN1 asn1 of+        Left _ -> Nothing+        Right (k, _) -> Just $ X509.PrivKeyRSA k+    tryDSA asn1 = case dsaFromASN1 asn1 of+        Left _ -> Nothing+        Right (k, _) -> Just $ X509.PrivKeyDSA $ DSA.toPrivateKey k+    tryECDSA asn1 = case ecdsaFromASN1 [] asn1 of+        Left _ -> Nothing+        Right (k, _) -> Just $ X509.PrivKeyEC k+    tryNewcurve asn1 = case fromASN1 asn1 of+        Right (k@(X509.PrivKeyX25519 _), _) -> Just k+        Right (k@(X509.PrivKeyX448 _), _) -> Just k+        Right (k@(X509.PrivKeyEd25519 _), _) -> Just k+        Right (k@(X509.PrivKeyEd448 _), _) -> Just k+        _ -> Nothing  dsaFromASN1 :: [ASN1] -> Either String (DSA.KeyPair, [ASN1]) dsaFromASN1 (Start Sequence : IntVal n : xs)-    | n /= 0    = Left "fromASN1: DSA.KeyPair: unknown format"+    | n /= 0 = Left "fromASN1: DSA.KeyPair: unknown format"     | otherwise =         case xs of             IntVal p : IntVal q : IntVal g : IntVal pub : IntVal priv : End Sequence : xs2 ->-                let params = DSA.Params { DSA.params_p = p, DSA.params_g = g, DSA.params_q = q }+                let params = DSA.Params{DSA.params_p = p, DSA.params_g = g, DSA.params_q = q}                  in Right (DSA.KeyPair params pub priv, xs2)-            (Start Sequence-             : OID [1, 2, 840, 10040, 4, 1]-             : Start Sequence-             : IntVal p-             : IntVal q-             : IntVal g-             : End Sequence-             : End Sequence-             : OctetString bs-             : End Sequence-             : xs2) ->-                let params = DSA.Params { DSA.params_p = p, DSA.params_g = g, DSA.params_q = q }-                 in case decodeASN1' BER bs of-                        Right [IntVal priv] ->-                            let pub = DSA.calculatePublic params priv-                             in Right (DSA.KeyPair params pub priv, xs2)-                        Right _ -> Left "dsaFromASN1: DSA.PrivateKey: unexpected format"-                        Left  e -> Left $ "dsaFromASN1: DSA.PrivateKey: " ++ show e+            ( Start Sequence+                    : OID [1, 2, 840, 10040, 4, 1]+                    : Start Sequence+                    : IntVal p+                    : IntVal q+                    : IntVal g+                    : End Sequence+                    : End Sequence+                    : OctetString bs+                    : End Sequence+                    : xs2+                ) ->+                    let params = DSA.Params{DSA.params_p = p, DSA.params_g = g, DSA.params_q = q}+                     in case decodeASN1' BER bs of+                            Right [IntVal priv] ->+                                let pub = DSA.calculatePublic params priv+                                 in Right (DSA.KeyPair params pub priv, xs2)+                            Right _ -> Left "dsaFromASN1: DSA.PrivateKey: unexpected format"+                            Left e -> Left $ "dsaFromASN1: DSA.PrivateKey: " ++ show e             _ ->                 Left "dsaFromASN1: DSA.KeyPair: invalid format (version=0)" dsaFromASN1 _ = Left "dsaFromASN1: DSA.KeyPair: unexpected format"  ecdsaFromASN1 :: [ASN1] -> [ASN1] -> Either String (X509.PrivKeyEC, [ASN1])-ecdsaFromASN1 curveOid1 (Start Sequence-                         : IntVal 1-                         : OctetString ds-                         : xs) = do-    let (curveOid2, ys) = containerWithTag 0 xs-    privKey <- getPrivKeyEC (os2ip ds) (curveOid2 ++ curveOid1)-    case containerWithTag 1 ys of-        (_, End Sequence : zs) -> return (privKey, zs)-        _                      -> Left "ecdsaFromASN1: unexpected EC format"-ecdsaFromASN1 curveOid1 (Start Sequence-                         : IntVal 0-                         : Start Sequence-                         : OID [1, 2, 840, 10045, 2, 1]-                         : xs) =-    let strError = Left .  ("ecdsaFromASN1: ECDSA.PrivateKey: " ++) . show-        (curveOid2, ys) = getConstructedEnd 0 xs-     in case ys of-            (OctetString bs-             : zs) -> do-                let curveOids = curveOid2 ++ curveOid1-                    inner = either strError (ecdsaFromASN1 curveOids) (decodeASN1' BER bs)-                either Left (\(k, _) -> Right (k, zs)) inner-            _      -> Left "ecdsaFromASN1: unexpected format"+ecdsaFromASN1+    curveOid1+    ( Start Sequence+            : IntVal 1+            : OctetString ds+            : xs+        ) = do+        let (curveOid2, ys) = containerWithTag 0 xs+        privKey <- getPrivKeyEC (os2ip ds) (curveOid2 ++ curveOid1)+        case containerWithTag 1 ys of+            (_, End Sequence : zs) -> return (privKey, zs)+            _ -> Left "ecdsaFromASN1: unexpected EC format"+ecdsaFromASN1+    curveOid1+    ( Start Sequence+            : IntVal 0+            : Start Sequence+            : OID [1, 2, 840, 10045, 2, 1]+            : xs+        ) =+        let strError = Left . ("ecdsaFromASN1: ECDSA.PrivateKey: " ++) . show+            (curveOid2, ys) = getConstructedEnd 0 xs+         in case ys of+                ( OctetString bs+                        : zs+                    ) -> do+                        let curveOids = curveOid2 ++ curveOid1+                            inner = either strError (ecdsaFromASN1 curveOids) (decodeASN1' BER bs)+                        either Left (\(k, _) -> Right (k, zs)) inner+                _ -> Left "ecdsaFromASN1: unexpected format" ecdsaFromASN1 _ _ =     Left "ecdsaFromASN1: unexpected format"  getPrivKeyEC :: ECDSA.PrivateNumber -> [ASN1] -> Either String X509.PrivKeyEC-getPrivKeyEC _ []                 = Left "ecdsaFromASN1: curve is missing"+getPrivKeyEC _ [] = Left "ecdsaFromASN1: curve is missing" getPrivKeyEC d (OID curveOid : _) =     case X509.lookupCurveNameByOID curveOid of-        Just name -> Right X509.PrivKeyEC_Named { X509.privkeyEC_name = name-                                                , X509.privkeyEC_priv = d-                                                }-        Nothing   -> Left ("ecdsaFromASN1: unknown curve " ++ show curveOid)-getPrivKeyEC d (Null : xs)        = getPrivKeyEC d xs-getPrivKeyEC d (Start Sequence-                : IntVal 1-                : Start Sequence-                : OID [1, 2, 840, 10045, 1, 1]-                : IntVal prime-                : End Sequence-                : Start Sequence-                : OctetString a-                : OctetString b-                : BitString seed-                : End Sequence-                : OctetString generator-                : IntVal order-                : IntVal cofactor-                : End Sequence-                : _)              =-    Right X509.PrivKeyEC_Prime-              { X509.privkeyEC_priv      = d-              , X509.privkeyEC_a         = os2ip a-              , X509.privkeyEC_b         = os2ip b-              , X509.privkeyEC_prime     = prime-              , X509.privkeyEC_generator = X509.SerializedPoint generator-              , X509.privkeyEC_order     = order-              , X509.privkeyEC_cofactor  = cofactor-              , X509.privkeyEC_seed      = os2ip $ bitArrayGetData seed-              }-getPrivKeyEC _ _                  = Left "ecdsaFromASN1: unexpected curve format"+        Just name ->+            Right+                X509.PrivKeyEC_Named+                    { X509.privkeyEC_name = name+                    , X509.privkeyEC_priv = d+                    }+        Nothing -> Left ("ecdsaFromASN1: unknown curve " ++ show curveOid)+getPrivKeyEC d (Null : xs) = getPrivKeyEC d xs+getPrivKeyEC+    d+    ( Start Sequence+            : IntVal 1+            : Start Sequence+            : OID [1, 2, 840, 10045, 1, 1]+            : IntVal prime+            : End Sequence+            : Start Sequence+            : OctetString a+            : OctetString b+            : BitString seed+            : End Sequence+            : OctetString generator+            : IntVal order+            : IntVal cofactor+            : End Sequence+            : _+        ) =+        Right+            X509.PrivKeyEC_Prime+                { X509.privkeyEC_priv = d+                , X509.privkeyEC_a = os2ip a+                , X509.privkeyEC_b = os2ip b+                , X509.privkeyEC_prime = prime+                , X509.privkeyEC_generator = X509.SerializedPoint generator+                , X509.privkeyEC_order = order+                , X509.privkeyEC_cofactor = cofactor+                , X509.privkeyEC_seed = os2ip $ bitArrayGetData seed+                }+getPrivKeyEC _ _ = Left "ecdsaFromASN1: unexpected curve format"  containerWithTag :: ASN1Tag -> [ASN1] -> ([ASN1], [ASN1]) containerWithTag etag (Start (Container _ atag) : xs)     | etag == atag = getConstructedEnd 0 xs-containerWithTag _    xs = ([], xs)+containerWithTag _ xs = ([], xs)  rsaFromASN1 :: [ASN1] -> Either String (RSA.PrivateKey, [ASN1])-rsaFromASN1 (Start Sequence-             : IntVal 0-             : IntVal n-             : IntVal e-             : IntVal d-             : IntVal p1-             : IntVal p2-             : IntVal pexp1-             : IntVal pexp2-             : IntVal pcoef-             : End Sequence-             : xs) = Right (privKey, xs)-  where-    pubKey  = RSA.PublicKey { RSA.public_size = numBytes n-                            , RSA.public_n    = n-                            , RSA.public_e    = e-                            }-    privKey = RSA.PrivateKey { RSA.private_pub  = pubKey-                             , RSA.private_d    = d-                             , RSA.private_p    = p1-                             , RSA.private_q    = p2-                             , RSA.private_dP   = pexp1-                             , RSA.private_dQ   = pexp2-                             , RSA.private_qinv = pcoef-                             }--rsaFromASN1 ( Start Sequence-             : IntVal 0-             : Start Sequence-             : OID [1, 2, 840, 113549, 1, 1, 1]-             : Null-             : End Sequence-             : OctetString bs-             : xs) =-    let inner = either strError rsaFromASN1 $ decodeASN1' BER bs-        strError = Left .  ("rsaFromASN1: RSA.PrivateKey: " ++) . show-     in either Left (\(k, _) -> Right (k, xs)) inner+rsaFromASN1+    ( Start Sequence+            : IntVal 0+            : IntVal n+            : IntVal e+            : IntVal d+            : IntVal p1+            : IntVal p2+            : IntVal pexp1+            : IntVal pexp2+            : IntVal pcoef+            : End Sequence+            : xs+        ) = Right (privKey, xs)+      where+        pubKey =+            RSA.PublicKey+                { RSA.public_size = numBytes n+                , RSA.public_n = n+                , RSA.public_e = e+                }+        privKey =+            RSA.PrivateKey+                { RSA.private_pub = pubKey+                , RSA.private_d = d+                , RSA.private_p = p1+                , RSA.private_q = p2+                , RSA.private_dP = pexp1+                , RSA.private_dQ = pexp2+                , RSA.private_qinv = pcoef+                }+rsaFromASN1+    ( Start Sequence+            : IntVal 0+            : Start Sequence+            : OID [1, 2, 840, 113549, 1, 1, 1]+            : Null+            : End Sequence+            : OctetString bs+            : xs+        ) =+        let inner = either strError rsaFromASN1 $ decodeASN1' BER bs+            strError = Left . ("rsaFromASN1: RSA.PrivateKey: " ++) . show+         in either Left (\(k, _) -> Right (k, xs)) inner rsaFromASN1 _ =     Left "rsaFromASN1: unexpected format"
Setup.hs view
@@ -1,2 +1,3 @@ import Distribution.Simple+ main = defaultMain
Tests/Tests.hs view
@@ -2,9 +2,9 @@ module Main (main) where  import qualified Data.ByteString as B-import           Data.String (fromString)-import           Data.X509-import           Data.X509.Memory+import Data.String (fromString)+import Data.X509+import Data.X509.Memory  import Test.Tasty import Test.Tasty.HUnit@@ -16,53 +16,56 @@   openssl rsa -in privkey.pem | sed -e 's/^\(.*\)$/    "\1\\n"/' -e '$!s/$/ ++/' -} rsaCertificate, rsaKey1, rsaKey2 :: B.ByteString-rsaCertificate = fromString $-    "-----BEGIN CERTIFICATE-----\n" ++-    "MIIB7DCCAVWgAwIBAgIJAPmzhcKJcLZtMA0GCSqGSIb3DQEBCwUAMA8xDTALBgNV\n" ++-    "BAMMBFRlc3QwHhcNMTcwMzAyMTgwODU3WhcNMTcwNDAxMTgwODU3WjAPMQ0wCwYD\n" ++-    "VQQDDARUZXN0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzkysIZyZ1UYFl\n" ++-    "OFKOhZ+T7Usgove7Z9z9zBSXM7ufXl5NF5QV+u76bDo5ITD81NYiqCLoNGRVC1FY\n" ++-    "srVmx97AyqQ6Hj2IGfar2JyymTO2Y4E7kYO21hxJSrIJOVnAbGdxHYwiKVFZkP5g\n" ++-    "PS5FzYqwfMet4gpbPJcvBjfZVo2MIQIDAQABo1AwTjAdBgNVHQ4EFgQUhJgtg9dO\n" ++-    "jcpA08w0BuXptQw+JVkwHwYDVR0jBBgwFoAUhJgtg9dOjcpA08w0BuXptQw+JVkw\n" ++-    "DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQA2OIHfXV9Ro7208mNaz6Bi\n" ++-    "QYhW4gGbQA6/5N/BYby5kHLC+veJ9qAXjILn5qW5hsuf4X4Nq7VO3HKQ89Jo2COc\n" ++-    "6fAvjhCWKqlZFAIBKbcEcg3QZqAdXJ4Q8RLMvG3y/vDzixp1Xuxk0Zbr88D7SX7i\n" ++-    "Lx+S385X8OT7Wiu6qhM6ig==\n" ++-    "-----END CERTIFICATE-----\n"-rsaKey1 = fromString $-    "-----BEGIN PRIVATE KEY-----\n" ++-    "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALOTKwhnJnVRgWU4\n" ++-    "Uo6Fn5PtSyCi97tn3P3MFJczu59eXk0XlBX67vpsOjkhMPzU1iKoIug0ZFULUViy\n" ++-    "tWbH3sDKpDoePYgZ9qvYnLKZM7ZjgTuRg7bWHElKsgk5WcBsZ3EdjCIpUVmQ/mA9\n" ++-    "LkXNirB8x63iCls8ly8GN9lWjYwhAgMBAAECgYAxGVkXyBRU2X82rMqt201Bhg0X\n" ++-    "lFeF7yUWY7lxihyPu56vF3ZO+DhlUjgtLK0XRB50hWJd+Q1Bz4FjbiF5Q8bcm/rz\n" ++-    "4BzyojpoCHoMnrcPyP+7+LE50MFsySvjQWCJkz0WSoFBsoEVQOvkAkhCEiR4vqoJ\n" ++-    "UNjZczb2PAvWjlUsvQJBAOyLOm+P4RnrRaV/dMXx3pfNTolJp7KQ0zXghKc4clF5\n" ++-    "ESMsWHwHRGU++/tW90m/j8ApDvlIrXTmYOyQ4jKCCk8CQQDCWGAzeVa4xL+p2SaO\n" ++-    "TP5aqRjfEIVf0O3HjB9GklrdwtnDF4JrUUILdUKJ3qxqEetNpSZjzc3H6dDtxvy1\n" ++-    "yRaPAkEAp+fMexRufK98qJVolnmxv5+Ed/9IgoA67KuKfgibXSnK+GSqCqA99IBY\n" ++-    "7Xg14KuRpp1+e4UTWz+M3V+asK+OEQJBAKvQW8RGCqAw+M0c+FQnx1q5Ug6q2W77\n" ++-    "E6wtudy3OPQC9mfemeNspDnjAd9HaCAiFWfAkK79XGbX1GjSWcoQrAsCQQDRoscG\n" ++-    "Udtf0rxGk4y79YNXPeTReF+0wCdWdDNpAdnhpYCnFE+74LyiY8YRbfe2jP7X2uyn\n" ++-    "/h1HwfRSKCZ7Epcv\n" ++-    "-----END PRIVATE KEY-----\n"-rsaKey2 = fromString $-    "-----BEGIN RSA PRIVATE KEY-----\n" ++-    "MIICXgIBAAKBgQCzkysIZyZ1UYFlOFKOhZ+T7Usgove7Z9z9zBSXM7ufXl5NF5QV\n" ++-    "+u76bDo5ITD81NYiqCLoNGRVC1FYsrVmx97AyqQ6Hj2IGfar2JyymTO2Y4E7kYO2\n" ++-    "1hxJSrIJOVnAbGdxHYwiKVFZkP5gPS5FzYqwfMet4gpbPJcvBjfZVo2MIQIDAQAB\n" ++-    "AoGAMRlZF8gUVNl/NqzKrdtNQYYNF5RXhe8lFmO5cYocj7uerxd2Tvg4ZVI4LSyt\n" ++-    "F0QedIViXfkNQc+BY24heUPG3Jv68+Ac8qI6aAh6DJ63D8j/u/ixOdDBbMkr40Fg\n" ++-    "iZM9FkqBQbKBFUDr5AJIQhIkeL6qCVDY2XM29jwL1o5VLL0CQQDsizpvj+EZ60Wl\n" ++-    "f3TF8d6XzU6JSaeykNM14ISnOHJReREjLFh8B0RlPvv7VvdJv4/AKQ75SK105mDs\n" ++-    "kOIyggpPAkEAwlhgM3lWuMS/qdkmjkz+WqkY3xCFX9Dtx4wfRpJa3cLZwxeCa1FC\n" ++-    "C3VCid6sahHrTaUmY83Nx+nQ7cb8tckWjwJBAKfnzHsUbnyvfKiVaJZ5sb+fhHf/\n" ++-    "SIKAOuyrin4Im10pyvhkqgqgPfSAWO14NeCrkaadfnuFE1s/jN1fmrCvjhECQQCr\n" ++-    "0FvERgqgMPjNHPhUJ8dauVIOqtlu+xOsLbnctzj0AvZn3pnjbKQ54wHfR2ggIhVn\n" ++-    "wJCu/Vxm19Ro0lnKEKwLAkEA0aLHBlHbX9K8RpOMu/WDVz3k0XhftMAnVnQzaQHZ\n" ++-    "4aWApxRPu+C8omPGEW33toz+19rsp/4dR8H0UigmexKXLw==\n" ++-    "-----END RSA PRIVATE KEY-----\n"+rsaCertificate =+    fromString $+        "-----BEGIN CERTIFICATE-----\n"+            ++ "MIIB7DCCAVWgAwIBAgIJAPmzhcKJcLZtMA0GCSqGSIb3DQEBCwUAMA8xDTALBgNV\n"+            ++ "BAMMBFRlc3QwHhcNMTcwMzAyMTgwODU3WhcNMTcwNDAxMTgwODU3WjAPMQ0wCwYD\n"+            ++ "VQQDDARUZXN0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzkysIZyZ1UYFl\n"+            ++ "OFKOhZ+T7Usgove7Z9z9zBSXM7ufXl5NF5QV+u76bDo5ITD81NYiqCLoNGRVC1FY\n"+            ++ "srVmx97AyqQ6Hj2IGfar2JyymTO2Y4E7kYO21hxJSrIJOVnAbGdxHYwiKVFZkP5g\n"+            ++ "PS5FzYqwfMet4gpbPJcvBjfZVo2MIQIDAQABo1AwTjAdBgNVHQ4EFgQUhJgtg9dO\n"+            ++ "jcpA08w0BuXptQw+JVkwHwYDVR0jBBgwFoAUhJgtg9dOjcpA08w0BuXptQw+JVkw\n"+            ++ "DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQA2OIHfXV9Ro7208mNaz6Bi\n"+            ++ "QYhW4gGbQA6/5N/BYby5kHLC+veJ9qAXjILn5qW5hsuf4X4Nq7VO3HKQ89Jo2COc\n"+            ++ "6fAvjhCWKqlZFAIBKbcEcg3QZqAdXJ4Q8RLMvG3y/vDzixp1Xuxk0Zbr88D7SX7i\n"+            ++ "Lx+S385X8OT7Wiu6qhM6ig==\n"+            ++ "-----END CERTIFICATE-----\n"+rsaKey1 =+    fromString $+        "-----BEGIN PRIVATE KEY-----\n"+            ++ "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALOTKwhnJnVRgWU4\n"+            ++ "Uo6Fn5PtSyCi97tn3P3MFJczu59eXk0XlBX67vpsOjkhMPzU1iKoIug0ZFULUViy\n"+            ++ "tWbH3sDKpDoePYgZ9qvYnLKZM7ZjgTuRg7bWHElKsgk5WcBsZ3EdjCIpUVmQ/mA9\n"+            ++ "LkXNirB8x63iCls8ly8GN9lWjYwhAgMBAAECgYAxGVkXyBRU2X82rMqt201Bhg0X\n"+            ++ "lFeF7yUWY7lxihyPu56vF3ZO+DhlUjgtLK0XRB50hWJd+Q1Bz4FjbiF5Q8bcm/rz\n"+            ++ "4BzyojpoCHoMnrcPyP+7+LE50MFsySvjQWCJkz0WSoFBsoEVQOvkAkhCEiR4vqoJ\n"+            ++ "UNjZczb2PAvWjlUsvQJBAOyLOm+P4RnrRaV/dMXx3pfNTolJp7KQ0zXghKc4clF5\n"+            ++ "ESMsWHwHRGU++/tW90m/j8ApDvlIrXTmYOyQ4jKCCk8CQQDCWGAzeVa4xL+p2SaO\n"+            ++ "TP5aqRjfEIVf0O3HjB9GklrdwtnDF4JrUUILdUKJ3qxqEetNpSZjzc3H6dDtxvy1\n"+            ++ "yRaPAkEAp+fMexRufK98qJVolnmxv5+Ed/9IgoA67KuKfgibXSnK+GSqCqA99IBY\n"+            ++ "7Xg14KuRpp1+e4UTWz+M3V+asK+OEQJBAKvQW8RGCqAw+M0c+FQnx1q5Ug6q2W77\n"+            ++ "E6wtudy3OPQC9mfemeNspDnjAd9HaCAiFWfAkK79XGbX1GjSWcoQrAsCQQDRoscG\n"+            ++ "Udtf0rxGk4y79YNXPeTReF+0wCdWdDNpAdnhpYCnFE+74LyiY8YRbfe2jP7X2uyn\n"+            ++ "/h1HwfRSKCZ7Epcv\n"+            ++ "-----END PRIVATE KEY-----\n"+rsaKey2 =+    fromString $+        "-----BEGIN RSA PRIVATE KEY-----\n"+            ++ "MIICXgIBAAKBgQCzkysIZyZ1UYFlOFKOhZ+T7Usgove7Z9z9zBSXM7ufXl5NF5QV\n"+            ++ "+u76bDo5ITD81NYiqCLoNGRVC1FYsrVmx97AyqQ6Hj2IGfar2JyymTO2Y4E7kYO2\n"+            ++ "1hxJSrIJOVnAbGdxHYwiKVFZkP5gPS5FzYqwfMet4gpbPJcvBjfZVo2MIQIDAQAB\n"+            ++ "AoGAMRlZF8gUVNl/NqzKrdtNQYYNF5RXhe8lFmO5cYocj7uerxd2Tvg4ZVI4LSyt\n"+            ++ "F0QedIViXfkNQc+BY24heUPG3Jv68+Ac8qI6aAh6DJ63D8j/u/ixOdDBbMkr40Fg\n"+            ++ "iZM9FkqBQbKBFUDr5AJIQhIkeL6qCVDY2XM29jwL1o5VLL0CQQDsizpvj+EZ60Wl\n"+            ++ "f3TF8d6XzU6JSaeykNM14ISnOHJReREjLFh8B0RlPvv7VvdJv4/AKQ75SK105mDs\n"+            ++ "kOIyggpPAkEAwlhgM3lWuMS/qdkmjkz+WqkY3xCFX9Dtx4wfRpJa3cLZwxeCa1FC\n"+            ++ "C3VCid6sahHrTaUmY83Nx+nQ7cb8tckWjwJBAKfnzHsUbnyvfKiVaJZ5sb+fhHf/\n"+            ++ "SIKAOuyrin4Im10pyvhkqgqgPfSAWO14NeCrkaadfnuFE1s/jN1fmrCvjhECQQCr\n"+            ++ "0FvERgqgMPjNHPhUJ8dauVIOqtlu+xOsLbnctzj0AvZn3pnjbKQ54wHfR2ggIhVn\n"+            ++ "wJCu/Vxm19Ro0lnKEKwLAkEA0aLHBlHbX9K8RpOMu/WDVz3k0XhftMAnVnQzaQHZ\n"+            ++ "4aWApxRPu+C8omPGEW33toz+19rsp/4dR8H0UigmexKXLw==\n"+            ++ "-----END RSA PRIVATE KEY-----\n"  {-   openssl dsaparam 1024 -out dsaparams@@ -72,47 +75,50 @@   openssl dsa -in privkey.pem | sed -e 's/^\(.*\)$/    "\1\\n"/' -e '$!s/$/ ++/' -} dsaCertificate, dsaKey1, dsaKey2 :: B.ByteString-dsaCertificate = fromString $-    "-----BEGIN CERTIFICATE-----\n" ++-    "MIICrzCCAmugAwIBAgIJALFEpgowHmcXMAsGCWCGSAFlAwQDAjAPMQ0wCwYDVQQD\n" ++-    "DARUZXN0MB4XDTE3MDMwMjE4MTA0OFoXDTE3MDQwMTE4MTA0OFowDzENMAsGA1UE\n" ++-    "AwwEVGVzdDCCAbYwggErBgcqhkjOOAQBMIIBHgKBgQCsH77mdMUYCgpdNnqljOoG\n" ++-    "OLOkPb+9pIrV/LWoX9TvhyfoVOJli5dEWqcui9eTZZ4LW+2F1//0HpTjW5d+aZk7\n" ++-    "znkSRg9yihhzYzqGL7GEinFGHIPBL5uKoCW7a2HlJ+OdLBNQ/yeCDpTvt+/agLlA\n" ++-    "K1CgpBd1NeG7jFmfgmJ+gwIVAOs+Q1CAhIZzqH7Ymgp4X2buU1plAoGALiXg/kXS\n" ++-    "DSWVzbP6kEKMjkpc0KMmUQCErJgcTZmqe2IddoghCHq44ofbdMyJivk0V3lAfprP\n" ++-    "l2LMKKnwc0NgWEcPPmR+ZyYXODxOeXlZd1qznDKWdvpciOkMdWOsxF+cbtmGBrxs\n" ++-    "+Rm86f+95+EsptH/8FeLFMw7L8u/0FNgAyoDgYQAAoGAIBhO3gbkWHsZSic+5rdh\n" ++-    "HS0z0h/kBqbqY2BHFXchaMAgzMrzD/rTpeZ+mND8tIRzOw73tKckeHrfauBNPstc\n" ++-    "c2SCFy9lc7eITD/HmoCJFuMLbYxpWlOYL5JU5EQT/1VlH58RprfMp5+HA1tSMZov\n" ++-    "zf7ck2W7Rt6zH77Io5lt0aujUDBOMB0GA1UdDgQWBBQOlmp9KHZbomx3TbKxBiGL\n" ++-    "oVUB1zAfBgNVHSMEGDAWgBQOlmp9KHZbomx3TbKxBiGLoVUB1zAMBgNVHRMEBTAD\n" ++-    "AQH/MAsGCWCGSAFlAwQDAgMxADAuAhUAp/XUpSnDENVgqr2MS1XCXHjI9kACFQDq\n" ++-    "jV1C0EYgKTRYKjrztFjBEHv3Ig==\n" ++-    "-----END CERTIFICATE-----\n"-dsaKey1 = fromString $-    "-----BEGIN PRIVATE KEY-----\n" ++-    "MIIBSgIBADCCASsGByqGSM44BAEwggEeAoGBAKwfvuZ0xRgKCl02eqWM6gY4s6Q9\n" ++-    "v72kitX8tahf1O+HJ+hU4mWLl0Rapy6L15Nlngtb7YXX//QelONbl35pmTvOeRJG\n" ++-    "D3KKGHNjOoYvsYSKcUYcg8Evm4qgJbtrYeUn450sE1D/J4IOlO+379qAuUArUKCk\n" ++-    "F3U14buMWZ+CYn6DAhUA6z5DUICEhnOoftiaCnhfZu5TWmUCgYAuJeD+RdINJZXN\n" ++-    "s/qQQoyOSlzQoyZRAISsmBxNmap7Yh12iCEIerjih9t0zImK+TRXeUB+ms+XYswo\n" ++-    "qfBzQ2BYRw8+ZH5nJhc4PE55eVl3WrOcMpZ2+lyI6Qx1Y6zEX5xu2YYGvGz5Gbzp\n" ++-    "/73n4Sym0f/wV4sUzDsvy7/QU2ADKgQWAhQ/q2pbQjljQ7CD3Uc6FA63FS7fYg==\n" ++-    "-----END PRIVATE KEY-----\n"-dsaKey2 = fromString $-    "-----BEGIN DSA PRIVATE KEY-----\n" ++-    "MIIBugIBAAKBgQCsH77mdMUYCgpdNnqljOoGOLOkPb+9pIrV/LWoX9TvhyfoVOJl\n" ++-    "i5dEWqcui9eTZZ4LW+2F1//0HpTjW5d+aZk7znkSRg9yihhzYzqGL7GEinFGHIPB\n" ++-    "L5uKoCW7a2HlJ+OdLBNQ/yeCDpTvt+/agLlAK1CgpBd1NeG7jFmfgmJ+gwIVAOs+\n" ++-    "Q1CAhIZzqH7Ymgp4X2buU1plAoGALiXg/kXSDSWVzbP6kEKMjkpc0KMmUQCErJgc\n" ++-    "TZmqe2IddoghCHq44ofbdMyJivk0V3lAfprPl2LMKKnwc0NgWEcPPmR+ZyYXODxO\n" ++-    "eXlZd1qznDKWdvpciOkMdWOsxF+cbtmGBrxs+Rm86f+95+EsptH/8FeLFMw7L8u/\n" ++-    "0FNgAyoCgYAgGE7eBuRYexlKJz7mt2EdLTPSH+QGpupjYEcVdyFowCDMyvMP+tOl\n" ++-    "5n6Y0Py0hHM7Dve0pyR4et9q4E0+y1xzZIIXL2Vzt4hMP8eagIkW4wttjGlaU5gv\n" ++-    "klTkRBP/VWUfnxGmt8ynn4cDW1Ixmi/N/tyTZbtG3rMfvsijmW3RqwIUP6tqW0I5\n" ++-    "Y0Owg91HOhQOtxUu32I=\n" ++-    "-----END DSA PRIVATE KEY-----\n"+dsaCertificate =+    fromString $+        "-----BEGIN CERTIFICATE-----\n"+            ++ "MIICrzCCAmugAwIBAgIJALFEpgowHmcXMAsGCWCGSAFlAwQDAjAPMQ0wCwYDVQQD\n"+            ++ "DARUZXN0MB4XDTE3MDMwMjE4MTA0OFoXDTE3MDQwMTE4MTA0OFowDzENMAsGA1UE\n"+            ++ "AwwEVGVzdDCCAbYwggErBgcqhkjOOAQBMIIBHgKBgQCsH77mdMUYCgpdNnqljOoG\n"+            ++ "OLOkPb+9pIrV/LWoX9TvhyfoVOJli5dEWqcui9eTZZ4LW+2F1//0HpTjW5d+aZk7\n"+            ++ "znkSRg9yihhzYzqGL7GEinFGHIPBL5uKoCW7a2HlJ+OdLBNQ/yeCDpTvt+/agLlA\n"+            ++ "K1CgpBd1NeG7jFmfgmJ+gwIVAOs+Q1CAhIZzqH7Ymgp4X2buU1plAoGALiXg/kXS\n"+            ++ "DSWVzbP6kEKMjkpc0KMmUQCErJgcTZmqe2IddoghCHq44ofbdMyJivk0V3lAfprP\n"+            ++ "l2LMKKnwc0NgWEcPPmR+ZyYXODxOeXlZd1qznDKWdvpciOkMdWOsxF+cbtmGBrxs\n"+            ++ "+Rm86f+95+EsptH/8FeLFMw7L8u/0FNgAyoDgYQAAoGAIBhO3gbkWHsZSic+5rdh\n"+            ++ "HS0z0h/kBqbqY2BHFXchaMAgzMrzD/rTpeZ+mND8tIRzOw73tKckeHrfauBNPstc\n"+            ++ "c2SCFy9lc7eITD/HmoCJFuMLbYxpWlOYL5JU5EQT/1VlH58RprfMp5+HA1tSMZov\n"+            ++ "zf7ck2W7Rt6zH77Io5lt0aujUDBOMB0GA1UdDgQWBBQOlmp9KHZbomx3TbKxBiGL\n"+            ++ "oVUB1zAfBgNVHSMEGDAWgBQOlmp9KHZbomx3TbKxBiGLoVUB1zAMBgNVHRMEBTAD\n"+            ++ "AQH/MAsGCWCGSAFlAwQDAgMxADAuAhUAp/XUpSnDENVgqr2MS1XCXHjI9kACFQDq\n"+            ++ "jV1C0EYgKTRYKjrztFjBEHv3Ig==\n"+            ++ "-----END CERTIFICATE-----\n"+dsaKey1 =+    fromString $+        "-----BEGIN PRIVATE KEY-----\n"+            ++ "MIIBSgIBADCCASsGByqGSM44BAEwggEeAoGBAKwfvuZ0xRgKCl02eqWM6gY4s6Q9\n"+            ++ "v72kitX8tahf1O+HJ+hU4mWLl0Rapy6L15Nlngtb7YXX//QelONbl35pmTvOeRJG\n"+            ++ "D3KKGHNjOoYvsYSKcUYcg8Evm4qgJbtrYeUn450sE1D/J4IOlO+379qAuUArUKCk\n"+            ++ "F3U14buMWZ+CYn6DAhUA6z5DUICEhnOoftiaCnhfZu5TWmUCgYAuJeD+RdINJZXN\n"+            ++ "s/qQQoyOSlzQoyZRAISsmBxNmap7Yh12iCEIerjih9t0zImK+TRXeUB+ms+XYswo\n"+            ++ "qfBzQ2BYRw8+ZH5nJhc4PE55eVl3WrOcMpZ2+lyI6Qx1Y6zEX5xu2YYGvGz5Gbzp\n"+            ++ "/73n4Sym0f/wV4sUzDsvy7/QU2ADKgQWAhQ/q2pbQjljQ7CD3Uc6FA63FS7fYg==\n"+            ++ "-----END PRIVATE KEY-----\n"+dsaKey2 =+    fromString $+        "-----BEGIN DSA PRIVATE KEY-----\n"+            ++ "MIIBugIBAAKBgQCsH77mdMUYCgpdNnqljOoGOLOkPb+9pIrV/LWoX9TvhyfoVOJl\n"+            ++ "i5dEWqcui9eTZZ4LW+2F1//0HpTjW5d+aZk7znkSRg9yihhzYzqGL7GEinFGHIPB\n"+            ++ "L5uKoCW7a2HlJ+OdLBNQ/yeCDpTvt+/agLlAK1CgpBd1NeG7jFmfgmJ+gwIVAOs+\n"+            ++ "Q1CAhIZzqH7Ymgp4X2buU1plAoGALiXg/kXSDSWVzbP6kEKMjkpc0KMmUQCErJgc\n"+            ++ "TZmqe2IddoghCHq44ofbdMyJivk0V3lAfprPl2LMKKnwc0NgWEcPPmR+ZyYXODxO\n"+            ++ "eXlZd1qznDKWdvpciOkMdWOsxF+cbtmGBrxs+Rm86f+95+EsptH/8FeLFMw7L8u/\n"+            ++ "0FNgAyoCgYAgGE7eBuRYexlKJz7mt2EdLTPSH+QGpupjYEcVdyFowCDMyvMP+tOl\n"+            ++ "5n6Y0Py0hHM7Dve0pyR4et9q4E0+y1xzZIIXL2Vzt4hMP8eagIkW4wttjGlaU5gv\n"+            ++ "klTkRBP/VWUfnxGmt8ynn4cDW1Ixmi/N/tyTZbtG3rMfvsijmW3RqwIUP6tqW0I5\n"+            ++ "Y0Owg91HOhQOtxUu32I=\n"+            ++ "-----END DSA PRIVATE KEY-----\n"  {-   openssl ecparam -name prime256v1 -out ecparams -param_enc named_curve@@ -122,29 +128,32 @@   openssl ec -in privkey.pem | sed -e 's/^\(.*\)$/    "\1\\n"/' -e '$!s/$/ ++/' -} ecCertificateNc, ecKey1Nc, ecKey2Nc :: B.ByteString-ecCertificateNc = fromString $-    "-----BEGIN CERTIFICATE-----\n" ++-    "MIIBZTCCAQugAwIBAgIJAPF7NB8WKn6XMAoGCCqGSM49BAMCMA8xDTALBgNVBAMM\n" ++-    "BFRlc3QwHhcNMTcwMzAyMTgxMTI1WhcNMTcwNDAxMTgxMTI1WjAPMQ0wCwYDVQQD\n" ++-    "DARUZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAETCmVJNQ5HWoFKMpyZFly\n" ++-    "kILKFuE0ZTu2t8G5jXpQp0g4g8OqyRo/6iSZSs/WAP3e2vcJuyhnDSd8MocSnEfi\n" ++-    "pqNQME4wHQYDVR0OBBYEFKCemJ7KZ+JfExQxOh/0qhKO3cJwMB8GA1UdIwQYMBaA\n" ++-    "FKCemJ7KZ+JfExQxOh/0qhKO3cJwMAwGA1UdEwQFMAMBAf8wCgYIKoZIzj0EAwID\n" ++-    "SAAwRQIhALhWJShVXsrupU8ISSBJVGmzRhPcueHsjuydyyfOsxElAiADbsp0SM/9\n" ++-    "6CQCvqX+V8DAwxT1WiRDzN8ilV6ZIfUI3Q==\n" ++-    "-----END CERTIFICATE-----\n"-ecKey1Nc = fromString $-    "-----BEGIN PRIVATE KEY-----\n" ++-    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg1hT2Mdt5IS0Qs9Bb\n" ++-    "LJ8ZAW3VTDIq1zn8qSYGiLcMVkShRANCAARMKZUk1DkdagUoynJkWXKQgsoW4TRl\n" ++-    "O7a3wbmNelCnSDiDw6rJGj/qJJlKz9YA/d7a9wm7KGcNJ3wyhxKcR+Km\n" ++-    "-----END PRIVATE KEY-----\n"-ecKey2Nc = fromString $-    "-----BEGIN EC PRIVATE KEY-----\n" ++-    "MHcCAQEEINYU9jHbeSEtELPQWyyfGQFt1UwyKtc5/KkmBoi3DFZEoAoGCCqGSM49\n" ++-    "AwEHoUQDQgAETCmVJNQ5HWoFKMpyZFlykILKFuE0ZTu2t8G5jXpQp0g4g8OqyRo/\n" ++-    "6iSZSs/WAP3e2vcJuyhnDSd8MocSnEfipg==\n" ++-    "-----END EC PRIVATE KEY-----\n"+ecCertificateNc =+    fromString $+        "-----BEGIN CERTIFICATE-----\n"+            ++ "MIIBZTCCAQugAwIBAgIJAPF7NB8WKn6XMAoGCCqGSM49BAMCMA8xDTALBgNVBAMM\n"+            ++ "BFRlc3QwHhcNMTcwMzAyMTgxMTI1WhcNMTcwNDAxMTgxMTI1WjAPMQ0wCwYDVQQD\n"+            ++ "DARUZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAETCmVJNQ5HWoFKMpyZFly\n"+            ++ "kILKFuE0ZTu2t8G5jXpQp0g4g8OqyRo/6iSZSs/WAP3e2vcJuyhnDSd8MocSnEfi\n"+            ++ "pqNQME4wHQYDVR0OBBYEFKCemJ7KZ+JfExQxOh/0qhKO3cJwMB8GA1UdIwQYMBaA\n"+            ++ "FKCemJ7KZ+JfExQxOh/0qhKO3cJwMAwGA1UdEwQFMAMBAf8wCgYIKoZIzj0EAwID\n"+            ++ "SAAwRQIhALhWJShVXsrupU8ISSBJVGmzRhPcueHsjuydyyfOsxElAiADbsp0SM/9\n"+            ++ "6CQCvqX+V8DAwxT1WiRDzN8ilV6ZIfUI3Q==\n"+            ++ "-----END CERTIFICATE-----\n"+ecKey1Nc =+    fromString $+        "-----BEGIN PRIVATE KEY-----\n"+            ++ "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg1hT2Mdt5IS0Qs9Bb\n"+            ++ "LJ8ZAW3VTDIq1zn8qSYGiLcMVkShRANCAARMKZUk1DkdagUoynJkWXKQgsoW4TRl\n"+            ++ "O7a3wbmNelCnSDiDw6rJGj/qJJlKz9YA/d7a9wm7KGcNJ3wyhxKcR+Km\n"+            ++ "-----END PRIVATE KEY-----\n"+ecKey2Nc =+    fromString $+        "-----BEGIN EC PRIVATE KEY-----\n"+            ++ "MHcCAQEEINYU9jHbeSEtELPQWyyfGQFt1UwyKtc5/KkmBoi3DFZEoAoGCCqGSM49\n"+            ++ "AwEHoUQDQgAETCmVJNQ5HWoFKMpyZFlykILKFuE0ZTu2t8G5jXpQp0g4g8OqyRo/\n"+            ++ "6iSZSs/WAP3e2vcJuyhnDSd8MocSnEfipg==\n"+            ++ "-----END EC PRIVATE KEY-----\n"  {-   openssl ecparam -name prime256v1 -out ecparams -param_enc explicit@@ -154,44 +163,47 @@   openssl ec -in privkey.pem | sed -e 's/^\(.*\)$/    "\1\\n"/' -e '$!s/$/ ++/' -} ecCertificateEpc, ecKey1Epc, ecKey2Epc :: B.ByteString-ecCertificateEpc = fromString $-    "-----BEGIN CERTIFICATE-----\n" ++-    "MIICWTCCAf+gAwIBAgIJAPF9pxfJTwfaMAoGCCqGSM49BAMCMA8xDTALBgNVBAMM\n" ++-    "BFRlc3QwHhcNMTcwMzAyMTgxMTUxWhcNMTcwNDAxMTgxMTUxWjAPMQ0wCwYDVQQD\n" ++-    "DARUZXN0MIIBSzCCAQMGByqGSM49AgEwgfcCAQEwLAYHKoZIzj0BAQIhAP////8A\n" ++-    "AAABAAAAAAAAAAAAAAAA////////////////MFsEIP////8AAAABAAAAAAAAAAAA\n" ++-    "AAAA///////////////8BCBaxjXYqjqT57PrvVV2mIa8ZR0GsMxTsPY7zjw+J9Jg\n" ++-    "SwMVAMSdNgiG5wSTamZ44ROdJreBn36QBEEEaxfR8uEsQkf4vOblY6RA8ncDfYEt\n" ++-    "6zOg9KE5RdiYwpZP40Li/hp/m47n60p8D54WK84zV2sxXs7LtkBoN79R9QIhAP//\n" ++-    "//8AAAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABHXlHgRztuAF/Vs5\n" ++-    "GMB5GEfGpFsSsua+GDB8/zvjT4UBgpnb71HJPFOC0yrYliunXds00VlOs3v+FCVL\n" ++-    "mU5yW+2jUDBOMB0GA1UdDgQWBBSFV0KwoW1mPah12w3rngU7t1kjETAfBgNVHSME\n" ++-    "GDAWgBSFV0KwoW1mPah12w3rngU7t1kjETAMBgNVHRMEBTADAQH/MAoGCCqGSM49\n" ++-    "BAMCA0gAMEUCIDqqWyJEIRo2YSvvrQKJZ3wKQSGeWoPnJvWfXMjgODd5AiEAsXCt\n" ++-    "LYmBKulTMXATynvrqa/xDi3z2lkwcWQC1AZBZ8M=\n" ++-    "-----END CERTIFICATE-----\n"-ecKey1Epc = fromString $-    "-----BEGIN PRIVATE KEY-----\n" ++-    "MIIBeQIBADCCAQMGByqGSM49AgEwgfcCAQEwLAYHKoZIzj0BAQIhAP////8AAAAB\n" ++-    "AAAAAAAAAAAAAAAA////////////////MFsEIP////8AAAABAAAAAAAAAAAAAAAA\n" ++-    "///////////////8BCBaxjXYqjqT57PrvVV2mIa8ZR0GsMxTsPY7zjw+J9JgSwMV\n" ++-    "AMSdNgiG5wSTamZ44ROdJreBn36QBEEEaxfR8uEsQkf4vOblY6RA8ncDfYEt6zOg\n" ++-    "9KE5RdiYwpZP40Li/hp/m47n60p8D54WK84zV2sxXs7LtkBoN79R9QIhAP////8A\n" ++-    "AAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBBG0wawIBAQQgBnbFaCHgp5Cn\n" ++-    "stu9ntk7QiEP6j/7FzK6GC4dzsID7/ihRANCAAR15R4Ec7bgBf1bORjAeRhHxqRb\n" ++-    "ErLmvhgwfP8740+FAYKZ2+9RyTxTgtMq2JYrp13bNNFZTrN7/hQlS5lOclvt\n" ++-    "-----END PRIVATE KEY-----\n"-ecKey2Epc = fromString $-    "-----BEGIN EC PRIVATE KEY-----\n" ++-    "MIIBaAIBAQQgBnbFaCHgp5Cnstu9ntk7QiEP6j/7FzK6GC4dzsID7/iggfowgfcC\n" ++-    "AQEwLAYHKoZIzj0BAQIhAP////8AAAABAAAAAAAAAAAAAAAA////////////////\n" ++-    "MFsEIP////8AAAABAAAAAAAAAAAAAAAA///////////////8BCBaxjXYqjqT57Pr\n" ++-    "vVV2mIa8ZR0GsMxTsPY7zjw+J9JgSwMVAMSdNgiG5wSTamZ44ROdJreBn36QBEEE\n" ++-    "axfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5RdiYwpZP40Li/hp/m47n60p8D54W\n" ++-    "K84zV2sxXs7LtkBoN79R9QIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8\n" ++-    "YyVRAgEBoUQDQgAEdeUeBHO24AX9WzkYwHkYR8akWxKy5r4YMHz/O+NPhQGCmdvv\n" ++-    "Uck8U4LTKtiWK6dd2zTRWU6ze/4UJUuZTnJb7Q==\n" ++-    "-----END EC PRIVATE KEY-----\n"+ecCertificateEpc =+    fromString $+        "-----BEGIN CERTIFICATE-----\n"+            ++ "MIICWTCCAf+gAwIBAgIJAPF9pxfJTwfaMAoGCCqGSM49BAMCMA8xDTALBgNVBAMM\n"+            ++ "BFRlc3QwHhcNMTcwMzAyMTgxMTUxWhcNMTcwNDAxMTgxMTUxWjAPMQ0wCwYDVQQD\n"+            ++ "DARUZXN0MIIBSzCCAQMGByqGSM49AgEwgfcCAQEwLAYHKoZIzj0BAQIhAP////8A\n"+            ++ "AAABAAAAAAAAAAAAAAAA////////////////MFsEIP////8AAAABAAAAAAAAAAAA\n"+            ++ "AAAA///////////////8BCBaxjXYqjqT57PrvVV2mIa8ZR0GsMxTsPY7zjw+J9Jg\n"+            ++ "SwMVAMSdNgiG5wSTamZ44ROdJreBn36QBEEEaxfR8uEsQkf4vOblY6RA8ncDfYEt\n"+            ++ "6zOg9KE5RdiYwpZP40Li/hp/m47n60p8D54WK84zV2sxXs7LtkBoN79R9QIhAP//\n"+            ++ "//8AAAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABHXlHgRztuAF/Vs5\n"+            ++ "GMB5GEfGpFsSsua+GDB8/zvjT4UBgpnb71HJPFOC0yrYliunXds00VlOs3v+FCVL\n"+            ++ "mU5yW+2jUDBOMB0GA1UdDgQWBBSFV0KwoW1mPah12w3rngU7t1kjETAfBgNVHSME\n"+            ++ "GDAWgBSFV0KwoW1mPah12w3rngU7t1kjETAMBgNVHRMEBTADAQH/MAoGCCqGSM49\n"+            ++ "BAMCA0gAMEUCIDqqWyJEIRo2YSvvrQKJZ3wKQSGeWoPnJvWfXMjgODd5AiEAsXCt\n"+            ++ "LYmBKulTMXATynvrqa/xDi3z2lkwcWQC1AZBZ8M=\n"+            ++ "-----END CERTIFICATE-----\n"+ecKey1Epc =+    fromString $+        "-----BEGIN PRIVATE KEY-----\n"+            ++ "MIIBeQIBADCCAQMGByqGSM49AgEwgfcCAQEwLAYHKoZIzj0BAQIhAP////8AAAAB\n"+            ++ "AAAAAAAAAAAAAAAA////////////////MFsEIP////8AAAABAAAAAAAAAAAAAAAA\n"+            ++ "///////////////8BCBaxjXYqjqT57PrvVV2mIa8ZR0GsMxTsPY7zjw+J9JgSwMV\n"+            ++ "AMSdNgiG5wSTamZ44ROdJreBn36QBEEEaxfR8uEsQkf4vOblY6RA8ncDfYEt6zOg\n"+            ++ "9KE5RdiYwpZP40Li/hp/m47n60p8D54WK84zV2sxXs7LtkBoN79R9QIhAP////8A\n"+            ++ "AAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBBG0wawIBAQQgBnbFaCHgp5Cn\n"+            ++ "stu9ntk7QiEP6j/7FzK6GC4dzsID7/ihRANCAAR15R4Ec7bgBf1bORjAeRhHxqRb\n"+            ++ "ErLmvhgwfP8740+FAYKZ2+9RyTxTgtMq2JYrp13bNNFZTrN7/hQlS5lOclvt\n"+            ++ "-----END PRIVATE KEY-----\n"+ecKey2Epc =+    fromString $+        "-----BEGIN EC PRIVATE KEY-----\n"+            ++ "MIIBaAIBAQQgBnbFaCHgp5Cnstu9ntk7QiEP6j/7FzK6GC4dzsID7/iggfowgfcC\n"+            ++ "AQEwLAYHKoZIzj0BAQIhAP////8AAAABAAAAAAAAAAAAAAAA////////////////\n"+            ++ "MFsEIP////8AAAABAAAAAAAAAAAAAAAA///////////////8BCBaxjXYqjqT57Pr\n"+            ++ "vVV2mIa8ZR0GsMxTsPY7zjw+J9JgSwMVAMSdNgiG5wSTamZ44ROdJreBn36QBEEE\n"+            ++ "axfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5RdiYwpZP40Li/hp/m47n60p8D54W\n"+            ++ "K84zV2sxXs7LtkBoN79R9QIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8\n"+            ++ "YyVRAgEBoUQDQgAEdeUeBHO24AX9WzkYwHkYR8akWxKy5r4YMHz/O+NPhQGCmdvv\n"+            ++ "Uck8U4LTKtiWK6dd2zTRWU6ze/4UJUuZTnJb7Q==\n"+            ++ "-----END EC PRIVATE KEY-----\n"  {-   openssl req -new -x509 -subj /CN=CA -newkey rsa:1024 -nodes -reqexts v3_ca \@@ -208,23 +220,26 @@       | sed -e 's/^\(.*\)$/    "\1\\n"/' -e '$!s/$/ ++/' -} x25519Certificate, x25519Key1, x25519Key2 :: B.ByteString-x25519Certificate = fromString $-    "-----BEGIN CERTIFICATE-----\n" ++-    "MIIBEzB+AgECMA0GCSqGSIb3DQEBCwUAMA0xCzAJBgNVBAMMAkNBMB4XDTE4MDgy\n" ++-    "NjE0MTIzOFoXDTE4MDkyNTE0MTIzOFowDzENMAsGA1UEAwwEVGVzdDAqMAUGAytl\n" ++-    "bgMhAMzDmaCSEjQR6yWKSdWBxw4YNOb6YMETiWt7AVOUaxw9MA0GCSqGSIb3DQEB\n" ++-    "CwUAA4GBAEJrXXtt9XaL3oARVv8hm/abqhUds9ytT4CQtaQgSV7HQIp96LN87pc9\n" ++-    "pwrISZrWuIlVpyQpGOK1i+uI3LgdKn1zO5CJdjRtW6lCCXg9R/wEcEKAiVKIzg2G\n" ++-    "FanQ4TG8YzfBToUbsSMfptxhbKPk/lVa8ffmXLZBILjPbI63iu4d\n" ++-    "-----END CERTIFICATE-----\n"-x25519Key1 = fromString $-    "-----BEGIN PRIVATE KEY-----\n" ++-    "MC4CAQAwBQYDK2VuBCIEIEhpc79EOwSU0JgHC6/32OUYul2yRiha3aftJiHybq1F\n" ++-    "-----END PRIVATE KEY-----\n"-x25519Key2 = fromString $-    "-----BEGIN X25519 PRIVATE KEY-----\n" ++-    "MC4CAQAwBQYDK2VuBCIEIEhpc79EOwSU0JgHC6/32OUYul2yRiha3aftJiHybq1F\n" ++-    "-----END X25519 PRIVATE KEY-----\n"+x25519Certificate =+    fromString $+        "-----BEGIN CERTIFICATE-----\n"+            ++ "MIIBEzB+AgECMA0GCSqGSIb3DQEBCwUAMA0xCzAJBgNVBAMMAkNBMB4XDTE4MDgy\n"+            ++ "NjE0MTIzOFoXDTE4MDkyNTE0MTIzOFowDzENMAsGA1UEAwwEVGVzdDAqMAUGAytl\n"+            ++ "bgMhAMzDmaCSEjQR6yWKSdWBxw4YNOb6YMETiWt7AVOUaxw9MA0GCSqGSIb3DQEB\n"+            ++ "CwUAA4GBAEJrXXtt9XaL3oARVv8hm/abqhUds9ytT4CQtaQgSV7HQIp96LN87pc9\n"+            ++ "pwrISZrWuIlVpyQpGOK1i+uI3LgdKn1zO5CJdjRtW6lCCXg9R/wEcEKAiVKIzg2G\n"+            ++ "FanQ4TG8YzfBToUbsSMfptxhbKPk/lVa8ffmXLZBILjPbI63iu4d\n"+            ++ "-----END CERTIFICATE-----\n"+x25519Key1 =+    fromString $+        "-----BEGIN PRIVATE KEY-----\n"+            ++ "MC4CAQAwBQYDK2VuBCIEIEhpc79EOwSU0JgHC6/32OUYul2yRiha3aftJiHybq1F\n"+            ++ "-----END PRIVATE KEY-----\n"+x25519Key2 =+    fromString $+        "-----BEGIN X25519 PRIVATE KEY-----\n"+            ++ "MC4CAQAwBQYDK2VuBCIEIEhpc79EOwSU0JgHC6/32OUYul2yRiha3aftJiHybq1F\n"+            ++ "-----END X25519 PRIVATE KEY-----\n"  {-   openssl req -new -x509 -subj /CN=CA -newkey rsa:1024 -nodes -reqexts v3_ca \@@ -241,26 +256,29 @@       | sed -e 's/^\(.*\)$/    "\1\\n"/' -e '$!s/$/ ++/' -} x448Certificate, x448Key1, x448Key2 :: B.ByteString-x448Certificate = fromString $-    "-----BEGIN CERTIFICATE-----\n" ++-    "MIIBLDCBlgIBAjANBgkqhkiG9w0BAQsFADANMQswCQYDVQQDDAJDQTAeFw0xODA4\n" ++-    "MjYxNDEzMTlaFw0xODA5MjUxNDEzMTlaMA8xDTALBgNVBAMMBFRlc3QwQjAFBgMr\n" ++-    "ZW8DOQCh0ta92rVURtIK29lN9F1QbBpSV0jAr7jAXLdz4SHPPO1OO+2gXvjuDpt3\n" ++-    "lTzR6oZQkAc5nK43PjANBgkqhkiG9w0BAQsFAAOBgQCk2dVKQpLS4/EEe2fuRMvs\n" ++-    "2qvERTT41P9cjkz3obrizjg68Aaj1m/0SeQFWYh4QeGf7lVSA6evPQG8XdscHHMd\n" ++-    "/7/U/gfY+aTiaKTf/E7pXMdtiMEOkcrA1J5fnI5M96R6UMRIRbqxhpGC/Jb7EdVM\n" ++-    "LAlOqcCwRBVCEJnexQK1TA==\n" ++-    "-----END CERTIFICATE-----\n"-x448Key1 = fromString $-    "-----BEGIN PRIVATE KEY-----\n" ++-    "MEYCAQAwBQYDK2VvBDoEOKxpGvu6rhYy78qgxgtT+uZt4Ctxd3AB/S59i1Cx03hR\n" ++-    "kVB9q7Mz02YjHbwAaM/hAHajYdwHa7aV\n" ++-    "-----END PRIVATE KEY-----\n"-x448Key2 = fromString $-    "-----BEGIN X448 PRIVATE KEY-----\n" ++-    "MEYCAQAwBQYDK2VvBDoEOKxpGvu6rhYy78qgxgtT+uZt4Ctxd3AB/S59i1Cx03hR\n" ++-    "kVB9q7Mz02YjHbwAaM/hAHajYdwHa7aV\n" ++-    "-----END X448 PRIVATE KEY-----\n"+x448Certificate =+    fromString $+        "-----BEGIN CERTIFICATE-----\n"+            ++ "MIIBLDCBlgIBAjANBgkqhkiG9w0BAQsFADANMQswCQYDVQQDDAJDQTAeFw0xODA4\n"+            ++ "MjYxNDEzMTlaFw0xODA5MjUxNDEzMTlaMA8xDTALBgNVBAMMBFRlc3QwQjAFBgMr\n"+            ++ "ZW8DOQCh0ta92rVURtIK29lN9F1QbBpSV0jAr7jAXLdz4SHPPO1OO+2gXvjuDpt3\n"+            ++ "lTzR6oZQkAc5nK43PjANBgkqhkiG9w0BAQsFAAOBgQCk2dVKQpLS4/EEe2fuRMvs\n"+            ++ "2qvERTT41P9cjkz3obrizjg68Aaj1m/0SeQFWYh4QeGf7lVSA6evPQG8XdscHHMd\n"+            ++ "/7/U/gfY+aTiaKTf/E7pXMdtiMEOkcrA1J5fnI5M96R6UMRIRbqxhpGC/Jb7EdVM\n"+            ++ "LAlOqcCwRBVCEJnexQK1TA==\n"+            ++ "-----END CERTIFICATE-----\n"+x448Key1 =+    fromString $+        "-----BEGIN PRIVATE KEY-----\n"+            ++ "MEYCAQAwBQYDK2VvBDoEOKxpGvu6rhYy78qgxgtT+uZt4Ctxd3AB/S59i1Cx03hR\n"+            ++ "kVB9q7Mz02YjHbwAaM/hAHajYdwHa7aV\n"+            ++ "-----END PRIVATE KEY-----\n"+x448Key2 =+    fromString $+        "-----BEGIN X448 PRIVATE KEY-----\n"+            ++ "MEYCAQAwBQYDK2VvBDoEOKxpGvu6rhYy78qgxgtT+uZt4Ctxd3AB/S59i1Cx03hR\n"+            ++ "kVB9q7Mz02YjHbwAaM/hAHajYdwHa7aV\n"+            ++ "-----END X448 PRIVATE KEY-----\n"  {-   openssl req -new -x509 -subj /CN=Test -newkey ed25519 -nodes -reqexts v3_req \@@ -270,24 +288,27 @@       | sed -e 's/^\(.*\)$/    "\1\\n"/' -e '$!s/$/ ++/' -} ed25519Certificate, ed25519Key1, ed25519Key2 :: B.ByteString-ed25519Certificate = fromString $-    "-----BEGIN CERTIFICATE-----\n" ++-    "MIIBMjCB5aADAgECAhR6ecRAmI54Nv+XftTZ/GSiPICx0TAFBgMrZXAwDzENMAsG\n" ++-    "A1UEAwwEVGVzdDAeFw0xODA4MTUxMTQ3MDNaFw0xODA5MTQxMTQ3MDNaMA8xDTAL\n" ++-    "BgNVBAMMBFRlc3QwKjAFBgMrZXADIQAI0GFxXxlCuJD082Grn0p0AZ/staBylKsS\n" ++-    "OwPu6iPHb6NTMFEwHQYDVR0OBBYEFGTOlalKBchEtrbeG5jRF5fbzhDJMB8GA1Ud\n" ++-    "IwQYMBaAFGTOlalKBchEtrbeG5jRF5fbzhDJMA8GA1UdEwEB/wQFMAMBAf8wBQYD\n" ++-    "K2VwA0EARON+KCuJoY1u8Yrn/MrCBpeu49AIMbqoyB8YN6msQpLPjWzLYaC70Cc2\n" ++-    "DY6BFI5hKr+mLCN/+VlzRzqW8dqSDg==\n" ++-    "-----END CERTIFICATE-----\n"-ed25519Key1 = fromString $-    "-----BEGIN PRIVATE KEY-----\n" ++-    "MC4CAQAwBQYDK2VwBCIEILEtRbG7T++/S58HPwVUJSR12Iu8FVputSfQBkotgeZ0\n" ++-    "-----END PRIVATE KEY-----\n"-ed25519Key2 = fromString $-    "-----BEGIN ED25519 PRIVATE KEY-----\n" ++-    "MC4CAQAwBQYDK2VwBCIEILEtRbG7T++/S58HPwVUJSR12Iu8FVputSfQBkotgeZ0\n" ++-    "-----END ED25519 PRIVATE KEY-----\n"+ed25519Certificate =+    fromString $+        "-----BEGIN CERTIFICATE-----\n"+            ++ "MIIBMjCB5aADAgECAhR6ecRAmI54Nv+XftTZ/GSiPICx0TAFBgMrZXAwDzENMAsG\n"+            ++ "A1UEAwwEVGVzdDAeFw0xODA4MTUxMTQ3MDNaFw0xODA5MTQxMTQ3MDNaMA8xDTAL\n"+            ++ "BgNVBAMMBFRlc3QwKjAFBgMrZXADIQAI0GFxXxlCuJD082Grn0p0AZ/staBylKsS\n"+            ++ "OwPu6iPHb6NTMFEwHQYDVR0OBBYEFGTOlalKBchEtrbeG5jRF5fbzhDJMB8GA1Ud\n"+            ++ "IwQYMBaAFGTOlalKBchEtrbeG5jRF5fbzhDJMA8GA1UdEwEB/wQFMAMBAf8wBQYD\n"+            ++ "K2VwA0EARON+KCuJoY1u8Yrn/MrCBpeu49AIMbqoyB8YN6msQpLPjWzLYaC70Cc2\n"+            ++ "DY6BFI5hKr+mLCN/+VlzRzqW8dqSDg==\n"+            ++ "-----END CERTIFICATE-----\n"+ed25519Key1 =+    fromString $+        "-----BEGIN PRIVATE KEY-----\n"+            ++ "MC4CAQAwBQYDK2VwBCIEILEtRbG7T++/S58HPwVUJSR12Iu8FVputSfQBkotgeZ0\n"+            ++ "-----END PRIVATE KEY-----\n"+ed25519Key2 =+    fromString $+        "-----BEGIN ED25519 PRIVATE KEY-----\n"+            ++ "MC4CAQAwBQYDK2VwBCIEILEtRbG7T++/S58HPwVUJSR12Iu8FVputSfQBkotgeZ0\n"+            ++ "-----END ED25519 PRIVATE KEY-----\n"  {-   openssl req -new -x509 -subj /CN=Test -newkey ed448 -nodes -reqexts v3_req \@@ -297,74 +318,87 @@       | sed -e 's/^\(.*\)$/    "\1\\n"/' -e '$!s/$/ ++/' -} ed448Certificate, ed448Key1, ed448Key2 :: B.ByteString-ed448Certificate = fromString $-    "-----BEGIN CERTIFICATE-----\n" ++-    "MIIBfTCB/qADAgECAhQ4hHMRAtg46drqmq6GQxeDN1WScDAFBgMrZXEwDzENMAsG\n" ++-    "A1UEAwwEVGVzdDAeFw0xODA4MTUxMTQ1MzRaFw0xODA5MTQxMTQ1MzRaMA8xDTAL\n" ++-    "BgNVBAMMBFRlc3QwQzAFBgMrZXEDOgBMbAytTVwKE9JHijqIy1q+wgs/G235N2w9\n" ++-    "Hfai1DjPd5nyVDeSD+BHiuJZDWfxRe6y34seoIsszQCjUzBRMB0GA1UdDgQWBBQo\n" ++-    "Nz/cV3FL07M93xsySVPHD0nOojAfBgNVHSMEGDAWgBQoNz/cV3FL07M93xsySVPH\n" ++-    "D0nOojAPBgNVHRMBAf8EBTADAQH/MAUGAytlcQNzABqXoKLJjmHK+smSGeh5M0vU\n" ++-    "PbHM3oSuiS25Q5UqHnrrxgyVBvq83/jCpEHc03BOSrMU5fRhbc84AK1kAPeEdGns\n" ++-    "dsG2uVxz0be795jKStt0a0o/w9cN5bd761Oeqoqs8CxWtjALhLu27IiY5uRkG5Uq\n" ++-    "AA==\n" ++-    "-----END CERTIFICATE-----\n"-ed448Key1 = fromString $-    "-----BEGIN PRIVATE KEY-----\n" ++-    "MEcCAQAwBQYDK2VxBDsEOcYO2tQ1U1vNoCUT0bNXVeausDEkUMmN0RI4ZUWU+9jA\n" ++-    "ZxaQP40ONQ5yQM/V6Nuw3NlDnp8OU9R18Q==\n" ++-    "-----END PRIVATE KEY-----\n"-ed448Key2 = fromString $-    "-----BEGIN ED448 PRIVATE KEY-----\n" ++-    "MEcCAQAwBQYDK2VxBDsEOcYO2tQ1U1vNoCUT0bNXVeausDEkUMmN0RI4ZUWU+9jA\n" ++-    "ZxaQP40ONQ5yQM/V6Nuw3NlDnp8OU9R18Q==\n" ++-    "-----END ED448 PRIVATE KEY-----\n"+ed448Certificate =+    fromString $+        "-----BEGIN CERTIFICATE-----\n"+            ++ "MIIBfTCB/qADAgECAhQ4hHMRAtg46drqmq6GQxeDN1WScDAFBgMrZXEwDzENMAsG\n"+            ++ "A1UEAwwEVGVzdDAeFw0xODA4MTUxMTQ1MzRaFw0xODA5MTQxMTQ1MzRaMA8xDTAL\n"+            ++ "BgNVBAMMBFRlc3QwQzAFBgMrZXEDOgBMbAytTVwKE9JHijqIy1q+wgs/G235N2w9\n"+            ++ "Hfai1DjPd5nyVDeSD+BHiuJZDWfxRe6y34seoIsszQCjUzBRMB0GA1UdDgQWBBQo\n"+            ++ "Nz/cV3FL07M93xsySVPHD0nOojAfBgNVHSMEGDAWgBQoNz/cV3FL07M93xsySVPH\n"+            ++ "D0nOojAPBgNVHRMBAf8EBTADAQH/MAUGAytlcQNzABqXoKLJjmHK+smSGeh5M0vU\n"+            ++ "PbHM3oSuiS25Q5UqHnrrxgyVBvq83/jCpEHc03BOSrMU5fRhbc84AK1kAPeEdGns\n"+            ++ "dsG2uVxz0be795jKStt0a0o/w9cN5bd761Oeqoqs8CxWtjALhLu27IiY5uRkG5Uq\n"+            ++ "AA==\n"+            ++ "-----END CERTIFICATE-----\n"+ed448Key1 =+    fromString $+        "-----BEGIN PRIVATE KEY-----\n"+            ++ "MEcCAQAwBQYDK2VxBDsEOcYO2tQ1U1vNoCUT0bNXVeausDEkUMmN0RI4ZUWU+9jA\n"+            ++ "ZxaQP40ONQ5yQM/V6Nuw3NlDnp8OU9R18Q==\n"+            ++ "-----END PRIVATE KEY-----\n"+ed448Key2 =+    fromString $+        "-----BEGIN ED448 PRIVATE KEY-----\n"+            ++ "MEcCAQAwBQYDK2VxBDsEOcYO2tQ1U1vNoCUT0bNXVeausDEkUMmN0RI4ZUWU+9jA\n"+            ++ "ZxaQP40ONQ5yQM/V6Nuw3NlDnp8OU9R18Q==\n"+            ++ "-----END ED448 PRIVATE KEY-----\n"  memoryKeyTests :: TestTree-memoryKeyTests = testGroup "Key"-    [ keyTest "RSA"                        rsaKey1      rsaKey2-    , keyTest "DSA"                        dsaKey1      dsaKey2-    , keyTest "EC (named curve)"           ecKey1Nc     ecKey2Nc-    , keyTest "EC (explicit prime curve)"  ecKey1Epc    ecKey2Epc-    , keyTest "X25519"                     x25519Key1   x25519Key2-    , keyTest "X448"                       x448Key1     x448Key2-    , keyTest "Ed25519"                    ed25519Key1  ed25519Key2-    , keyTest "Ed448"                      ed448Key1    ed448Key2-    ]+memoryKeyTests =+    testGroup+        "Key"+        [ keyTest "RSA" rsaKey1 rsaKey2+        , keyTest "DSA" dsaKey1 dsaKey2+        , keyTest "EC (named curve)" ecKey1Nc ecKey2Nc+        , keyTest "EC (explicit prime curve)" ecKey1Epc ecKey2Epc+        , keyTest "X25519" x25519Key1 x25519Key2+        , keyTest "X448" x448Key1 x448Key2+        , keyTest "Ed25519" ed25519Key1 ed25519Key2+        , keyTest "Ed448" ed448Key1 ed448Key2+        ]   where     keyTest name outer inner =         let kInner = readKeyFileFromMemory inner             kOuter = readKeyFileFromMemory outer-         in testGroup name+         in testGroup+                name                 [ testCase "read outer" $ length kOuter @?= 1                 , testCase "read inner" $ length kInner @?= 1-                , testCase "same key"   $-                      assertBool "keys differ" (kInner == kOuter)+                , testCase "same key" $+                    assertBool "keys differ" (kInner == kOuter)                 ]  memoryCertificateTests :: TestTree-memoryCertificateTests = testGroup "Certificate"-    [ certTest "RSA"                        rsaCertificate-    , certTest "DSA"                        dsaCertificate-    , certTest "EC (named curve)"           ecCertificateNc-    , certTest "EC (explicit prime curve)"  ecCertificateEpc-    , certTest "X25519"                     x25519Certificate-    , certTest "X448"                       x448Certificate-    , certTest "Ed25519"                    ed25519Certificate-    , certTest "Ed448"                      ed448Certificate-    ]+memoryCertificateTests =+    testGroup+        "Certificate"+        [ certTest "RSA" rsaCertificate+        , certTest "DSA" dsaCertificate+        , certTest "EC (named curve)" ecCertificateNc+        , certTest "EC (explicit prime curve)" ecCertificateEpc+        , certTest "X25519" x25519Certificate+        , certTest "X448" x448Certificate+        , certTest "Ed25519" ed25519Certificate+        , certTest "Ed448" ed448Certificate+        ]   where-    certTest name bytes = testCase name $-        length (readSignedCertificateFromMemory bytes) @?= 1+    certTest name bytes =+        testCase name $+            length (readSignedCertificateFromMemory bytes) @?= 1      readSignedCertificateFromMemory :: B.ByteString -> [SignedCertificate]     readSignedCertificateFromMemory = readSignedObjectFromMemory  -- | Runs the test suite. main :: IO ()-main = defaultMain $ testGroup "x509-store"-    [ testGroup "Memory"-          [ memoryKeyTests-          , memoryCertificateTests-          ]-    ]+main =+    defaultMain $+        testGroup+            "x509-store"+            [ testGroup+                "Memory"+                [ memoryKeyTests+                , memoryCertificateTests+                ]+            ]
crypton-x509-store.cabal view
@@ -1,5 +1,5 @@ Name:                crypton-x509-store-version:             1.6.9+version:             1.6.10 Description:         X.509 collection accessing and storing methods for certificate, crl, exception list License:             BSD3 License-file:        LICENSE