-- |
-- Module      : Crypto.Store.PKCS8
-- License     : BSD-style
-- Maintainer  : Olivier Chéron <olivier.cheron@gmail.com>
-- Stability   : experimental
-- Portability : unknown
--
-- Private-Key Information Syntax, aka PKCS #8.
--
-- Presents an API similar to "Data.X509.Memory" and "Data.X509.File" but
-- allows to write private keys and provides support for password-based
-- encryption.
--
-- Functions to read a private key return an object wrapped in the
-- 'OptProtected' data type.
--
-- Functions related to public keys, certificates and CRLs are available from
-- "Crypto.Store.X509".
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE UndecidableInstances #-}
module Crypto.Store.PKCS8
    ( readKeyFile
    , readKeyFileFromMemory
    , pemToKey
    , writeKeyFile
    , writeKeyFileToMemory
    , keyToPEM
    , writeEncryptedKeyFile
    , writeEncryptedKeyFileToMemory
    , encryptKeyToPEM
    -- * Serialization formats
    , PrivateKeyFormat(..)
    , FormattedKey(..)
    -- * Password-based protection
    , ProtectionPassword
    , emptyNotTerminated
    , fromProtectionPassword
    , toProtectionPassword
    , OptProtected(..)
    , recover
    , recoverA
    -- * Reading and writing PEM files
    , readPEMs
    , writePEMs
    ) where

import Control.Applicative
import Control.Monad (void, when)

import Data.ASN1.Types
import Data.ASN1.BinaryEncoding
import Data.ASN1.BitArray
import Data.ASN1.Encoding
import Data.ByteArray (ByteArrayAccess, convert)
import Data.Maybe
import qualified Data.X509 as X509
import qualified Data.ByteString as B
import           Crypto.Error
import           Crypto.Number.Serialize (i2osp, i2ospOf_, os2ip)
import qualified Crypto.PubKey.Curve25519 as X25519
import qualified Crypto.PubKey.Curve448 as X448
import qualified Crypto.PubKey.DSA as DSA
import qualified Crypto.PubKey.ECC.ECDSA as ECDSA
import qualified Crypto.PubKey.Ed25519 as Ed25519
import qualified Crypto.PubKey.Ed448 as Ed448
import qualified Crypto.PubKey.RSA as RSA

import Crypto.Store.ASN1.Generate
import Crypto.Store.ASN1.Parse
import Crypto.Store.CMS.Attribute
import Crypto.Store.CMS.Util
import Crypto.Store.Error
import Crypto.Store.PEM
import Crypto.Store.PKCS5
import Crypto.Store.PKCS8.EC
import Crypto.Store.Util

-- | Data type for objects that are possibly protected with a password.
data OptProtected a = Unprotected a
                      -- ^ Value is unprotected
                    | Protected (ProtectionPassword -> Either StoreError a)
                      -- ^ Value is protected with a password

instance Functor OptProtected where
    fmap :: forall a b. (a -> b) -> OptProtected a -> OptProtected b
fmap a -> b
f (Unprotected a
x) = forall a. a -> OptProtected a
Unprotected (a -> b
f a
x)
    fmap a -> b
f (Protected ProtectionPassword -> Either StoreError a
g)   = forall a.
(ProtectionPassword -> Either StoreError a) -> OptProtected a
Protected (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProtectionPassword -> Either StoreError a
g)

-- | Try to recover an 'OptProtected' content using the specified password.
recover :: ProtectionPassword -> OptProtected a -> Either StoreError a
recover :: forall a.
ProtectionPassword -> OptProtected a -> Either StoreError a
recover ProtectionPassword
_   (Unprotected a
x) = forall a b. b -> Either a b
Right a
x
recover ProtectionPassword
pwd (Protected ProtectionPassword -> Either StoreError a
f)   = ProtectionPassword -> Either StoreError a
f ProtectionPassword
pwd

-- | Try to recover an 'OptProtected' content in an applicative context.  The
-- applicative password is used if necessary.
--
-- > import qualified Data.ByteString as B
-- > import           Crypto.Store.PKCS8
-- >
-- > [encryptedKey] <- readKeyFile "privkey.pem"
-- > let askForPassword = putStr "Please enter password: " >> B.getLine
-- > result <- recoverA (toProtectionPassword <$> askForPassword) encryptedKey
-- > case result of
-- >     Left err  -> putStrLn $ "Unable to recover key: " ++ show err
-- >     Right key -> print key
recoverA :: Applicative f
         => f ProtectionPassword
         -> OptProtected a
         -> f (Either StoreError a)
recoverA :: forall (f :: * -> *) a.
Applicative f =>
f ProtectionPassword -> OptProtected a -> f (Either StoreError a)
recoverA f ProtectionPassword
_   (Unprotected a
x) = forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a b. b -> Either a b
Right a
x)
recoverA f ProtectionPassword
get (Protected ProtectionPassword -> Either StoreError a
f)   = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ProtectionPassword -> Either StoreError a
f f ProtectionPassword
get


-- Reading from PEM format

-- | Read private keys from a PEM file.
readKeyFile :: FilePath -> IO [OptProtected X509.PrivKey]
readKeyFile :: FilePath -> IO [OptProtected PrivKey]
readKeyFile FilePath
path = [PEM] -> [OptProtected PrivKey]
accumulate forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FilePath -> IO [PEM]
readPEMs FilePath
path

-- | Read private keys from a bytearray in PEM format.
readKeyFileFromMemory :: B.ByteString -> [OptProtected X509.PrivKey]
readKeyFileFromMemory :: ByteString -> [OptProtected PrivKey]
readKeyFileFromMemory = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a b. a -> b -> a
const []) [PEM] -> [OptProtected PrivKey]
accumulate forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either FilePath [PEM]
pemParseBS

accumulate :: [PEM] -> [OptProtected X509.PrivKey]
accumulate :: [PEM] -> [OptProtected PrivKey]
accumulate = forall a. [Maybe a] -> [a]
catMaybes forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (forall a b c. (a -> b -> c) -> b -> a -> c
flip [Maybe (OptProtected PrivKey)]
-> PEM -> [Maybe (OptProtected PrivKey)]
pemToKey) []

-- | Read a private key from a 'PEM' element and add it to the accumulator list.
pemToKey :: [Maybe (OptProtected X509.PrivKey)] -> PEM -> [Maybe (OptProtected X509.PrivKey)]
pemToKey :: [Maybe (OptProtected PrivKey)]
-> PEM -> [Maybe (OptProtected PrivKey)]
pemToKey [Maybe (OptProtected PrivKey)]
acc PEM
pem =
    case forall a.
ASN1Decoding a =>
a -> ByteString -> Either ASN1Error [ASN1]
decodeASN1' BER
BER (PEM -> ByteString
pemContent PEM
pem) of
        Left ASN1Error
_     -> [Maybe (OptProtected PrivKey)]
acc
        Right [ASN1]
asn1 -> forall {a}. ParseASN1 () a -> [ASN1] -> Maybe a
run (FilePath -> ParseASN1 () (OptProtected PrivKey)
getParser forall a b. (a -> b) -> a -> b
$ PEM -> FilePath
pemName PEM
pem) [ASN1]
asn1 forall a. a -> [a] -> [a]
: [Maybe (OptProtected PrivKey)]
acc

  where
    run :: ParseASN1 () a -> [ASN1] -> Maybe a
run ParseASN1 () a
p = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a b. a -> b -> a
const forall a. Maybe a
Nothing) forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. ParseASN1 () a -> [ASN1] -> Either FilePath a
runParseASN1 ParseASN1 () a
p

    allTypes :: ParseASN1 () PrivKey
allTypes  = forall a. FormattedKey a -> a
unFormat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse
    rsa :: ParseASN1 () PrivKey
rsa       = PrivateKey -> PrivKey
X509.PrivKeyRSA forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. FormattedKey a -> a
unFormat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse
    dsa :: ParseASN1 () PrivKey
dsa       = PrivateKey -> PrivKey
X509.PrivKeyDSA forall b c a. (b -> c) -> (a -> b) -> a -> c
. KeyPair -> PrivateKey
DSA.toPrivateKey forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. FormattedKey a -> a
unFormat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse
    ecdsa :: ParseASN1 () PrivKey
ecdsa     = PrivKeyEC -> PrivKey
X509.PrivKeyEC forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. FormattedKey a -> a
unFormat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse
    x25519 :: ParseASN1 () PrivKey
x25519    = SecretKey -> PrivKey
X509.PrivKeyX25519 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e a. ParseASN1Object e (Modern a) => ParseASN1 e a
parseModern
    x448 :: ParseASN1 () PrivKey
x448      = SecretKey -> PrivKey
X509.PrivKeyX448 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e a. ParseASN1Object e (Modern a) => ParseASN1 e a
parseModern
    ed25519 :: ParseASN1 () PrivKey
ed25519   = SecretKey -> PrivKey
X509.PrivKeyEd25519 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e a. ParseASN1Object e (Modern a) => ParseASN1 e a
parseModern
    ed448 :: ParseASN1 () PrivKey
ed448     = SecretKey -> PrivKey
X509.PrivKeyEd448 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e a. ParseASN1Object e (Modern a) => ParseASN1 e a
parseModern
    encrypted :: ParseASN1 () (ProtectionPassword -> Either StoreError PrivKey)
encrypted = forall {t}.
(t -> Either StoreError ByteString)
-> t -> Either StoreError PrivKey
inner forall b c a. (b -> c) -> (a -> b) -> a -> c
. PKCS5 -> ProtectionPassword -> Either StoreError ByteString
decrypt forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse

    getParser :: FilePath -> ParseASN1 () (OptProtected PrivKey)
getParser FilePath
"PRIVATE KEY"           = forall a. a -> OptProtected a
Unprotected forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParseASN1 () PrivKey
allTypes
    getParser FilePath
"RSA PRIVATE KEY"       = forall a. a -> OptProtected a
Unprotected forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParseASN1 () PrivKey
rsa
    getParser FilePath
"DSA PRIVATE KEY"       = forall a. a -> OptProtected a
Unprotected forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParseASN1 () PrivKey
dsa
    getParser FilePath
"EC PRIVATE KEY"        = forall a. a -> OptProtected a
Unprotected forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParseASN1 () PrivKey
ecdsa
    getParser FilePath
"X25519 PRIVATE KEY"    = forall a. a -> OptProtected a
Unprotected forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParseASN1 () PrivKey
x25519
    getParser FilePath
"X448 PRIVATE KEY"      = forall a. a -> OptProtected a
Unprotected forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParseASN1 () PrivKey
x448
    getParser FilePath
"ED25519 PRIVATE KEY"   = forall a. a -> OptProtected a
Unprotected forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParseASN1 () PrivKey
ed25519
    getParser FilePath
"ED448 PRIVATE KEY"     = forall a. a -> OptProtected a
Unprotected forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParseASN1 () PrivKey
ed448
    getParser FilePath
"ENCRYPTED PRIVATE KEY" = forall a.
(ProtectionPassword -> Either StoreError a) -> OptProtected a
Protected   forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParseASN1 () (ProtectionPassword -> Either StoreError PrivKey)
encrypted
    getParser FilePath
_                       = forall (f :: * -> *) a. Alternative f => f a
empty

    inner :: (t -> Either StoreError ByteString)
-> t -> Either StoreError PrivKey
inner t -> Either StoreError ByteString
decfn t
pwd = do
        ByteString
decrypted <- t -> Either StoreError ByteString
decfn t
pwd
        [ASN1]
asn1 <- forall a b c. (a -> b) -> Either a c -> Either b c
mapLeft ASN1Error -> StoreError
DecodingError forall a b. (a -> b) -> a -> b
$ forall a.
ASN1Decoding a =>
a -> ByteString -> Either ASN1Error [ASN1]
decodeASN1' BER
BER ByteString
decrypted
        case forall {a}. ParseASN1 () a -> [ASN1] -> Maybe a
run ParseASN1 () PrivKey
allTypes [ASN1]
asn1 of
            Maybe PrivKey
Nothing -> forall a b. a -> Either a b
Left (FilePath -> StoreError
ParseFailure FilePath
"No key parsed after decryption")
            Just PrivKey
k  -> forall (m :: * -> *) a. Monad m => a -> m a
return PrivKey
k


-- Writing to PEM format

-- | Write unencrypted private keys to a PEM file.
writeKeyFile :: PrivateKeyFormat -> FilePath -> [X509.PrivKey] -> IO ()
writeKeyFile :: PrivateKeyFormat -> FilePath -> [PrivKey] -> IO ()
writeKeyFile PrivateKeyFormat
fmt FilePath
path = FilePath -> [PEM] -> IO ()
writePEMs FilePath
path forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (PrivateKeyFormat -> PrivKey -> PEM
keyToPEM PrivateKeyFormat
fmt)

-- | Write unencrypted private keys to a bytearray in PEM format.
writeKeyFileToMemory :: PrivateKeyFormat -> [X509.PrivKey] -> B.ByteString
writeKeyFileToMemory :: PrivateKeyFormat -> [PrivKey] -> ByteString
writeKeyFileToMemory PrivateKeyFormat
fmt = [PEM] -> ByteString
pemsWriteBS forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (PrivateKeyFormat -> PrivKey -> PEM
keyToPEM PrivateKeyFormat
fmt)

-- | Write a PKCS #8 encrypted private key to a PEM file.
--
-- If multiple keys need to be stored in the same file, use functions
-- 'encryptKeyToPEM' and 'writePEMs'.
--
-- Fresh 'EncryptionScheme' parameters should be generated for each key to
-- encrypt.
writeEncryptedKeyFile :: FilePath
                      -> EncryptionScheme -> ProtectionPassword -> X509.PrivKey
                      -> IO (Either StoreError ())
writeEncryptedKeyFile :: FilePath
-> EncryptionScheme
-> ProtectionPassword
-> PrivKey
-> IO (Either StoreError ())
writeEncryptedKeyFile FilePath
path EncryptionScheme
alg ProtectionPassword
pwd PrivKey
privKey =
    let pem :: Either StoreError PEM
pem = EncryptionScheme
-> ProtectionPassword -> PrivKey -> Either StoreError PEM
encryptKeyToPEM EncryptionScheme
alg ProtectionPassword
pwd PrivKey
privKey
     in forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> Either a b
Left) (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. b -> Either a b
Right forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> [PEM] -> IO ()
writePEMs FilePath
path forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. a -> [a] -> [a]
:[])) Either StoreError PEM
pem

-- | Write a PKCS #8 encrypted private key to a bytearray in PEM format.
--
-- If multiple keys need to be stored in the same bytearray, use functions
-- 'encryptKeyToPEM' and 'pemWriteBS' or 'pemWriteLBS'.
--
-- Fresh 'EncryptionScheme' parameters should be generated for each key to
-- encrypt.
writeEncryptedKeyFileToMemory :: EncryptionScheme -> ProtectionPassword
                              -> X509.PrivKey -> Either StoreError B.ByteString
writeEncryptedKeyFileToMemory :: EncryptionScheme
-> ProtectionPassword -> PrivKey -> Either StoreError ByteString
writeEncryptedKeyFileToMemory EncryptionScheme
alg ProtectionPassword
pwd PrivKey
privKey =
    PEM -> ByteString
pemWriteBS forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> EncryptionScheme
-> ProtectionPassword -> PrivKey -> Either StoreError PEM
encryptKeyToPEM EncryptionScheme
alg ProtectionPassword
pwd PrivKey
privKey

-- | Generate an unencrypted PEM for a private key.
keyToPEM :: PrivateKeyFormat -> X509.PrivKey -> PEM
keyToPEM :: PrivateKeyFormat -> PrivKey -> PEM
keyToPEM PrivateKeyFormat
TraditionalFormat = PrivKey -> PEM
keyToTraditionalPEM
keyToPEM PrivateKeyFormat
PKCS8Format       = PrivKey -> PEM
keyToModernPEM

keyToTraditionalPEM :: X509.PrivKey -> PEM
keyToTraditionalPEM :: PrivKey -> PEM
keyToTraditionalPEM PrivKey
privKey =
    FilePath -> ByteString -> PEM
mkPEM (FilePath
typeTag forall a. [a] -> [a] -> [a]
++ FilePath
" PRIVATE KEY") (ASN1PS -> ByteString
encodeASN1S ASN1PS
asn1)
  where (FilePath
typeTag, ASN1PS
asn1) = forall e. ASN1Elem e => PrivKey -> (FilePath, ASN1Stream e)
traditionalPrivKeyASN1S PrivKey
privKey

traditionalPrivKeyASN1S :: ASN1Elem e => X509.PrivKey -> (String, ASN1Stream e)
traditionalPrivKeyASN1S :: forall e. ASN1Elem e => PrivKey -> (FilePath, ASN1Stream e)
traditionalPrivKeyASN1S PrivKey
privKey =
    case PrivKey
privKey of
        X509.PrivKeyRSA PrivateKey
k -> (FilePath
"RSA", forall {e} {a}.
ProduceASN1Object e (Traditional a) =>
a -> ASN1Stream e
traditional PrivateKey
k)
        X509.PrivKeyDSA PrivateKey
k -> (FilePath
"DSA", forall {e} {a}.
ProduceASN1Object e (Traditional a) =>
a -> ASN1Stream e
traditional (PrivateKey -> KeyPair
dsaPrivToPair PrivateKey
k))
        X509.PrivKeyEC  PrivKeyEC
k -> (FilePath
"EC",  forall {e} {a}.
ProduceASN1Object e (Traditional a) =>
a -> ASN1Stream e
traditional PrivKeyEC
k)
        X509.PrivKeyX25519  SecretKey
k -> (FilePath
"X25519",  forall {e} {a}. ProduceASN1Object e (Modern a) => a -> ASN1Stream e
tradModern SecretKey
k)
        X509.PrivKeyX448    SecretKey
k -> (FilePath
"X448",    forall {e} {a}. ProduceASN1Object e (Modern a) => a -> ASN1Stream e
tradModern SecretKey
k)
        X509.PrivKeyEd25519 SecretKey
k -> (FilePath
"ED25519", forall {e} {a}. ProduceASN1Object e (Modern a) => a -> ASN1Stream e
tradModern SecretKey
k)
        X509.PrivKeyEd448   SecretKey
k -> (FilePath
"ED448",   forall {e} {a}. ProduceASN1Object e (Modern a) => a -> ASN1Stream e
tradModern SecretKey
k)
  where
    traditional :: a -> ASN1Stream e
traditional a
a = forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
asn1s (forall a. a -> Traditional a
Traditional a
a)
    tradModern :: a -> ASN1Stream e
tradModern a
a  = forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
asn1s (forall a. [Attribute] -> a -> Modern a
Modern [] a
a)

keyToModernPEM :: X509.PrivKey -> PEM
keyToModernPEM :: PrivKey -> PEM
keyToModernPEM PrivKey
privKey = FilePath -> ByteString -> PEM
mkPEM FilePath
"PRIVATE KEY" (ASN1PS -> ByteString
encodeASN1S ASN1PS
asn1)
  where asn1 :: ASN1PS
asn1 = forall e. ASN1Elem e => [Attribute] -> PrivKey -> ASN1Stream e
modernPrivKeyASN1S [] PrivKey
privKey

modernPrivKeyASN1S :: ASN1Elem e => [Attribute] -> X509.PrivKey -> ASN1Stream e
modernPrivKeyASN1S :: forall e. ASN1Elem e => [Attribute] -> PrivKey -> ASN1Stream e
modernPrivKeyASN1S [Attribute]
attrs PrivKey
privKey =
    case PrivKey
privKey of
        X509.PrivKeyRSA PrivateKey
k -> forall {e} {a}. ProduceASN1Object e (Modern a) => a -> ASN1Stream e
modern PrivateKey
k
        X509.PrivKeyDSA PrivateKey
k -> forall {e} {a}. ProduceASN1Object e (Modern a) => a -> ASN1Stream e
modern (PrivateKey -> KeyPair
dsaPrivToPair PrivateKey
k)
        X509.PrivKeyEC  PrivKeyEC
k -> forall {e} {a}. ProduceASN1Object e (Modern a) => a -> ASN1Stream e
modern PrivKeyEC
k
        X509.PrivKeyX25519  SecretKey
k -> forall {e} {a}. ProduceASN1Object e (Modern a) => a -> ASN1Stream e
modern SecretKey
k
        X509.PrivKeyX448    SecretKey
k -> forall {e} {a}. ProduceASN1Object e (Modern a) => a -> ASN1Stream e
modern SecretKey
k
        X509.PrivKeyEd25519 SecretKey
k -> forall {e} {a}. ProduceASN1Object e (Modern a) => a -> ASN1Stream e
modern SecretKey
k
        X509.PrivKeyEd448   SecretKey
k -> forall {e} {a}. ProduceASN1Object e (Modern a) => a -> ASN1Stream e
modern SecretKey
k
  where
    modern :: a -> ASN1Stream e
modern a
a = forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
asn1s (forall a. [Attribute] -> a -> Modern a
Modern [Attribute]
attrs a
a)

-- | Generate a PKCS #8 encrypted PEM for a private key.
--
-- Fresh 'EncryptionScheme' parameters should be generated for each key to
-- encrypt.
encryptKeyToPEM :: EncryptionScheme -> ProtectionPassword -> X509.PrivKey
                -> Either StoreError PEM
encryptKeyToPEM :: EncryptionScheme
-> ProtectionPassword -> PrivKey -> Either StoreError PEM
encryptKeyToPEM EncryptionScheme
alg ProtectionPassword
pwd PrivKey
privKey = forall {obj}. ProduceASN1Object ASN1P obj => obj -> PEM
toPEM forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> EncryptionScheme
-> ProtectionPassword -> ByteString -> Either StoreError PKCS5
encrypt EncryptionScheme
alg ProtectionPassword
pwd ByteString
bs
  where bs :: ByteString
bs = PEM -> ByteString
pemContent (PrivKey -> PEM
keyToModernPEM PrivKey
privKey)
        toPEM :: obj -> PEM
toPEM obj
pkcs8 = FilePath -> ByteString -> PEM
mkPEM FilePath
"ENCRYPTED PRIVATE KEY" (forall obj. ProduceASN1Object ASN1P obj => obj -> ByteString
encodeASN1Object obj
pkcs8)

mkPEM :: String -> B.ByteString -> PEM
mkPEM :: FilePath -> ByteString -> PEM
mkPEM FilePath
name ByteString
bs = PEM { pemName :: FilePath
pemName = FilePath
name, pemHeader :: [(FilePath, ByteString)]
pemHeader = [], pemContent :: ByteString
pemContent = ByteString
bs}


-- Private key formats: traditional (SSLeay compatible) and modern (PKCS #8)

-- | Private-key serialization format.
--
-- Encryption in traditional format is not supported currently.
data PrivateKeyFormat = TraditionalFormat -- ^ SSLeay compatible
                      | PKCS8Format       -- ^ PKCS #8
                      deriving (Int -> PrivateKeyFormat -> ShowS
[PrivateKeyFormat] -> ShowS
PrivateKeyFormat -> FilePath
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
showList :: [PrivateKeyFormat] -> ShowS
$cshowList :: [PrivateKeyFormat] -> ShowS
show :: PrivateKeyFormat -> FilePath
$cshow :: PrivateKeyFormat -> FilePath
showsPrec :: Int -> PrivateKeyFormat -> ShowS
$cshowsPrec :: Int -> PrivateKeyFormat -> ShowS
Show,PrivateKeyFormat -> PrivateKeyFormat -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PrivateKeyFormat -> PrivateKeyFormat -> Bool
$c/= :: PrivateKeyFormat -> PrivateKeyFormat -> Bool
== :: PrivateKeyFormat -> PrivateKeyFormat -> Bool
$c== :: PrivateKeyFormat -> PrivateKeyFormat -> Bool
Eq)

newtype Traditional a = Traditional { forall a. Traditional a -> a
unTraditional :: a }

parseTraditional :: ParseASN1Object e (Traditional a) => ParseASN1 e a
parseTraditional :: forall e a. ParseASN1Object e (Traditional a) => ParseASN1 e a
parseTraditional = forall a. Traditional a -> a
unTraditional forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse

data Modern a = Modern [Attribute] a

instance Functor Modern where
    fmap :: forall a b. (a -> b) -> Modern a -> Modern b
fmap a -> b
f (Modern [Attribute]
attrs a
a) = forall a. [Attribute] -> a -> Modern a
Modern [Attribute]
attrs (a -> b
f a
a)

parseModern :: ParseASN1Object e (Modern a) => ParseASN1 e a
parseModern :: forall e a. ParseASN1Object e (Modern a) => ParseASN1 e a
parseModern = forall {a}. Modern a -> a
unModern forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse
  where unModern :: Modern a -> a
unModern (Modern [Attribute]
_ a
a) = a
a

-- | A key associated with format.  Allows to implement 'ASN1Object' instances.
data FormattedKey a = FormattedKey PrivateKeyFormat a
    deriving (Int -> FormattedKey a -> ShowS
forall a. Show a => Int -> FormattedKey a -> ShowS
forall a. Show a => [FormattedKey a] -> ShowS
forall a. Show a => FormattedKey a -> FilePath
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
showList :: [FormattedKey a] -> ShowS
$cshowList :: forall a. Show a => [FormattedKey a] -> ShowS
show :: FormattedKey a -> FilePath
$cshow :: forall a. Show a => FormattedKey a -> FilePath
showsPrec :: Int -> FormattedKey a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> FormattedKey a -> ShowS
Show,FormattedKey a -> FormattedKey a -> Bool
forall a. Eq a => FormattedKey a -> FormattedKey a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: FormattedKey a -> FormattedKey a -> Bool
$c/= :: forall a. Eq a => FormattedKey a -> FormattedKey a -> Bool
== :: FormattedKey a -> FormattedKey a -> Bool
$c== :: forall a. Eq a => FormattedKey a -> FormattedKey a -> Bool
Eq)

instance Functor FormattedKey where
    fmap :: forall a b. (a -> b) -> FormattedKey a -> FormattedKey b
fmap a -> b
f (FormattedKey PrivateKeyFormat
fmt a
a) = forall a. PrivateKeyFormat -> a -> FormattedKey a
FormattedKey PrivateKeyFormat
fmt (a -> b
f a
a)

instance (ProduceASN1Object e (Traditional a), ProduceASN1Object e (Modern a)) => ProduceASN1Object e (FormattedKey a) where
    asn1s :: FormattedKey a -> ASN1Stream e
asn1s (FormattedKey PrivateKeyFormat
TraditionalFormat a
k) = forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
asn1s (forall a. a -> Traditional a
Traditional a
k)
    asn1s (FormattedKey PrivateKeyFormat
PKCS8Format a
k)       = forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
asn1s (forall a. [Attribute] -> a -> Modern a
Modern [] a
k)

instance (Monoid e, ParseASN1Object e (Traditional a), ParseASN1Object e (Modern a)) => ParseASN1Object e (FormattedKey a) where
    parse :: ParseASN1 e (FormattedKey a)
parse = (forall {a}. a -> FormattedKey a
modern forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e a. ParseASN1Object e (Modern a) => ParseASN1 e a
parseModern) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (forall {a}. a -> FormattedKey a
traditional forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e a. ParseASN1Object e (Traditional a) => ParseASN1 e a
parseTraditional)
      where
        traditional :: a -> FormattedKey a
traditional = forall a. PrivateKeyFormat -> a -> FormattedKey a
FormattedKey PrivateKeyFormat
TraditionalFormat
        modern :: a -> FormattedKey a
modern      = forall a. PrivateKeyFormat -> a -> FormattedKey a
FormattedKey PrivateKeyFormat
PKCS8Format

unFormat :: FormattedKey a -> a
unFormat :: forall a. FormattedKey a -> a
unFormat (FormattedKey PrivateKeyFormat
_ a
a) = a
a


-- Private Keys

instance ASN1Object (FormattedKey X509.PrivKey) where
    toASN1 :: FormattedKey PrivKey -> ASN1S
toASN1   = forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
asn1s
    fromASN1 :: [ASN1] -> Either FilePath (FormattedKey PrivKey, [ASN1])
fromASN1 = forall a. ParseASN1 () a -> [ASN1] -> Either FilePath (a, [ASN1])
runParseASN1State forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse

instance ASN1Elem e => ProduceASN1Object e (Traditional X509.PrivKey) where
    asn1s :: Traditional PrivKey -> ASN1Stream e
asn1s (Traditional PrivKey
privKey) = forall a b. (a, b) -> b
snd forall a b. (a -> b) -> a -> b
$ forall e. ASN1Elem e => PrivKey -> (FilePath, ASN1Stream e)
traditionalPrivKeyASN1S PrivKey
privKey

instance Monoid e => ParseASN1Object e (Traditional X509.PrivKey) where
    parse :: ParseASN1 e (Traditional PrivKey)
parse = ParseASN1 e (Traditional PrivKey)
rsa forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParseASN1 e (Traditional PrivKey)
dsa forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParseASN1 e (Traditional PrivKey)
ecdsa
      where
        rsa :: ParseASN1 e (Traditional PrivKey)
rsa   = forall a. a -> Traditional a
Traditional forall b c a. (b -> c) -> (a -> b) -> a -> c
. PrivateKey -> PrivKey
X509.PrivKeyRSA forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Traditional a -> a
unTraditional forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse
        dsa :: ParseASN1 e (Traditional PrivKey)
dsa   = forall a. a -> Traditional a
Traditional forall b c a. (b -> c) -> (a -> b) -> a -> c
. PrivateKey -> PrivKey
X509.PrivKeyDSA forall b c a. (b -> c) -> (a -> b) -> a -> c
. KeyPair -> PrivateKey
DSA.toPrivateKey forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Traditional a -> a
unTraditional forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse
        ecdsa :: ParseASN1 e (Traditional PrivKey)
ecdsa = forall a. a -> Traditional a
Traditional forall b c a. (b -> c) -> (a -> b) -> a -> c
. PrivKeyEC -> PrivKey
X509.PrivKeyEC forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Traditional a -> a
unTraditional forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse

instance ASN1Elem e => ProduceASN1Object e (Modern X509.PrivKey) where
    asn1s :: Modern PrivKey -> ASN1Stream e
asn1s (Modern [Attribute]
attrs PrivKey
privKey) = forall e. ASN1Elem e => [Attribute] -> PrivKey -> ASN1Stream e
modernPrivKeyASN1S [Attribute]
attrs PrivKey
privKey

instance Monoid e => ParseASN1Object e (Modern X509.PrivKey) where
    parse :: ParseASN1 e (Modern PrivKey)
parse = ParseASN1 e (Modern PrivKey)
rsa forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParseASN1 e (Modern PrivKey)
dsa forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParseASN1 e (Modern PrivKey)
ecdsa forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParseASN1 e (Modern PrivKey)
x25519 forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParseASN1 e (Modern PrivKey)
x448 forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParseASN1 e (Modern PrivKey)
ed25519 forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParseASN1 e (Modern PrivKey)
ed448
      where
        rsa :: ParseASN1 e (Modern PrivKey)
rsa   = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap PrivateKey -> PrivKey
X509.PrivKeyRSA  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse
        dsa :: ParseASN1 e (Modern PrivKey)
dsa   = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (PrivateKey -> PrivKey
X509.PrivKeyDSA forall b c a. (b -> c) -> (a -> b) -> a -> c
. KeyPair -> PrivateKey
DSA.toPrivateKey) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse
        ecdsa :: ParseASN1 e (Modern PrivKey)
ecdsa = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap PrivKeyEC -> PrivKey
X509.PrivKeyEC forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse
        x25519 :: ParseASN1 e (Modern PrivKey)
x25519  = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SecretKey -> PrivKey
X509.PrivKeyX25519 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse
        x448 :: ParseASN1 e (Modern PrivKey)
x448    = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SecretKey -> PrivKey
X509.PrivKeyX448 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse
        ed25519 :: ParseASN1 e (Modern PrivKey)
ed25519 = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SecretKey -> PrivKey
X509.PrivKeyEd25519 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse
        ed448 :: ParseASN1 e (Modern PrivKey)
ed448   = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SecretKey -> PrivKey
X509.PrivKeyEd448 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse

skipVersion :: Monoid e => ParseASN1 e ()
skipVersion :: forall e. Monoid e => ParseASN1 e ()
skipVersion = do
    IntVal Integer
v <- forall e. Monoid e => ParseASN1 e ASN1
getNext
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Integer
v forall a. Eq a => a -> a -> Bool
/= Integer
0 Bool -> Bool -> Bool
&& Integer
v forall a. Eq a => a -> a -> Bool
/= Integer
1) forall a b. (a -> b) -> a -> b
$
        forall e a. FilePath -> ParseASN1 e a
throwParseError (FilePath
"PKCS8: parsed invalid version: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> FilePath
show Integer
v)

skipPublicKey :: Monoid e => ParseASN1 e ()
skipPublicKey :: forall e. Monoid e => ParseASN1 e ()
skipPublicKey = forall (f :: * -> *) a. Functor f => f a -> f ()
void (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. a -> Maybe a
Just ParseASN1 e ByteString
parseTaggedPrimitive forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing)
  where parseTaggedPrimitive :: ParseASN1 e ByteString
parseTaggedPrimitive = do { Other ASN1Class
_ Int
1 ByteString
bs <- forall e. Monoid e => ParseASN1 e ASN1
getNext; forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
bs }

parseAttrKeys :: Monoid e => ParseASN1 e ([Attribute], B.ByteString)
parseAttrKeys :: forall e. Monoid e => ParseASN1 e ([Attribute], ByteString)
parseAttrKeys = do
    OctetString ByteString
bs <- forall e. Monoid e => ParseASN1 e ASN1
getNext
    [Attribute]
attrs <- forall e.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e [Attribute]
parseAttributes (ASN1Class -> Int -> ASN1ConstructionType
Container ASN1Class
Context Int
0)
    forall e. Monoid e => ParseASN1 e ()
skipPublicKey
    forall (m :: * -> *) a. Monad m => a -> m a
return ([Attribute]
attrs, ByteString
bs)


-- RSA

instance ASN1Object (FormattedKey RSA.PrivateKey) where
    toASN1 :: FormattedKey PrivateKey -> ASN1S
toASN1   = forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
asn1s
    fromASN1 :: [ASN1] -> Either FilePath (FormattedKey PrivateKey, [ASN1])
fromASN1 = forall a. ParseASN1 () a -> [ASN1] -> Either FilePath (a, [ASN1])
runParseASN1State forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse

instance ASN1Elem e => ProduceASN1Object e (Traditional RSA.PrivateKey) where
    asn1s :: Traditional PrivateKey -> ASN1Stream e
asn1s (Traditional PrivateKey
privKey) =
        forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container ASN1ConstructionType
Sequence (ASN1Stream e
v forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
n forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
e forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
d forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
p1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
p2 forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
pexp1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
pexp2 forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
pcoef)
      where
        pubKey :: PublicKey
pubKey = PrivateKey -> PublicKey
RSA.private_pub PrivateKey
privKey

        v :: ASN1Stream e
v     = forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal Integer
0
        n :: ASN1Stream e
n     = forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal (PublicKey -> Integer
RSA.public_n PublicKey
pubKey)
        e :: ASN1Stream e
e     = forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal (PublicKey -> Integer
RSA.public_e PublicKey
pubKey)
        d :: ASN1Stream e
d     = forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal (PrivateKey -> Integer
RSA.private_d PrivateKey
privKey)
        p1 :: ASN1Stream e
p1    = forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal (PrivateKey -> Integer
RSA.private_p PrivateKey
privKey)
        p2 :: ASN1Stream e
p2    = forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal (PrivateKey -> Integer
RSA.private_q PrivateKey
privKey)
        pexp1 :: ASN1Stream e
pexp1 = forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal (PrivateKey -> Integer
RSA.private_dP PrivateKey
privKey)
        pexp2 :: ASN1Stream e
pexp2 = forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal (PrivateKey -> Integer
RSA.private_dQ PrivateKey
privKey)
        pcoef :: ASN1Stream e
pcoef = forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal (PrivateKey -> Integer
RSA.private_qinv PrivateKey
privKey)

instance Monoid e => ParseASN1Object e (Traditional RSA.PrivateKey) where
    parse :: ParseASN1 e (Traditional PrivateKey)
parse = forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
onNextContainer ASN1ConstructionType
Sequence forall a b. (a -> b) -> a -> b
$ do
        IntVal Integer
0 <- forall e. Monoid e => ParseASN1 e ASN1
getNext
        IntVal Integer
n <- forall e. Monoid e => ParseASN1 e ASN1
getNext
        IntVal Integer
e <- forall e. Monoid e => ParseASN1 e ASN1
getNext
        IntVal Integer
d <- forall e. Monoid e => ParseASN1 e ASN1
getNext
        IntVal Integer
p1 <- forall e. Monoid e => ParseASN1 e ASN1
getNext
        IntVal Integer
p2 <- forall e. Monoid e => ParseASN1 e ASN1
getNext
        IntVal Integer
pexp1 <- forall e. Monoid e => ParseASN1 e ASN1
getNext
        IntVal Integer
pexp2 <- forall e. Monoid e => ParseASN1 e ASN1
getNext
        IntVal Integer
pcoef <- forall e. Monoid e => ParseASN1 e ASN1
getNext
        let pubKey :: PublicKey
pubKey  = RSA.PublicKey { public_size :: Int
RSA.public_size = Integer -> Int
numBytes Integer
n
                                    , public_n :: Integer
RSA.public_n    = Integer
n
                                    , public_e :: Integer
RSA.public_e    = Integer
e
                                    }
            privKey :: PrivateKey
privKey = RSA.PrivateKey { private_pub :: PublicKey
RSA.private_pub  = PublicKey
pubKey
                                    , private_d :: Integer
RSA.private_d    = Integer
d
                                    , private_p :: Integer
RSA.private_p    = Integer
p1
                                    , private_q :: Integer
RSA.private_q    = Integer
p2
                                    , private_dP :: Integer
RSA.private_dP   = Integer
pexp1
                                    , private_dQ :: Integer
RSA.private_dQ   = Integer
pexp2
                                    , private_qinv :: Integer
RSA.private_qinv = Integer
pcoef
                                    }
        forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Traditional a
Traditional PrivateKey
privKey)

instance ASN1Elem e => ProduceASN1Object e (Modern RSA.PrivateKey) where
    asn1s :: Modern PrivateKey -> ASN1Stream e
asn1s (Modern [Attribute]
attrs PrivateKey
privKey) =
        forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container ASN1ConstructionType
Sequence (ASN1Stream e
v forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
alg forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
bs forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
att)
      where
        v :: ASN1Stream e
v     = forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal Integer
0
        alg :: ASN1Stream e
alg   = forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container ASN1ConstructionType
Sequence (ASN1Stream e
oid forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e. ASN1Elem e => ASN1Stream e
gNull)
        oid :: ASN1Stream e
oid   = forall e. ASN1Elem e => OID -> ASN1Stream e
gOID [Integer
1,Integer
2,Integer
840,Integer
113549,Integer
1,Integer
1,Integer
1]
        bs :: ASN1Stream e
bs    = forall e. ASN1Elem e => ByteString -> ASN1Stream e
gOctetString (forall obj. ProduceASN1Object ASN1P obj => obj -> ByteString
encodeASN1Object forall a b. (a -> b) -> a -> b
$ forall a. a -> Traditional a
Traditional PrivateKey
privKey)
        att :: ASN1Stream e
att   = forall e.
ASN1Elem e =>
ASN1ConstructionType -> [Attribute] -> ASN1Stream e
attributesASN1S (ASN1Class -> Int -> ASN1ConstructionType
Container ASN1Class
Context Int
0) [Attribute]
attrs

instance Monoid e => ParseASN1Object e (Modern RSA.PrivateKey) where
    parse :: ParseASN1 e (Modern PrivateKey)
parse = forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
onNextContainer ASN1ConstructionType
Sequence forall a b. (a -> b) -> a -> b
$ do
        forall e. Monoid e => ParseASN1 e ()
skipVersion
        ASN1
Null <- forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
onNextContainer ASN1ConstructionType
Sequence forall a b. (a -> b) -> a -> b
$ do
                    OID [Integer
1,Integer
2,Integer
840,Integer
113549,Integer
1,Integer
1,Integer
1] <- forall e. Monoid e => ParseASN1 e ASN1
getNext
                    forall e. Monoid e => ParseASN1 e ASN1
getNext
        ([Attribute]
attrs, ByteString
bs) <- forall e. Monoid e => ParseASN1 e ([Attribute], ByteString)
parseAttrKeys
        let inner :: Either ASN1Error [ASN1]
inner = forall a.
ASN1Decoding a =>
a -> ByteString -> Either ASN1Error [ASN1]
decodeASN1' BER
BER ByteString
bs
            strError :: ASN1Error -> Either FilePath b
strError = forall a b. a -> Either a b
Left forall b c a. (b -> c) -> (a -> b) -> a -> c
.  (FilePath
"PKCS8: error decoding inner RSA: " forall a. [a] -> [a] -> [a]
++) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> FilePath
show
        case forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall {b}. ASN1Error -> Either FilePath b
strError (forall a. ParseASN1 () a -> [ASN1] -> Either FilePath a
runParseASN1 forall e a. ParseASN1Object e (Traditional a) => ParseASN1 e a
parseTraditional) Either ASN1Error [ASN1]
inner of
             Left FilePath
err -> forall e a. FilePath -> ParseASN1 e a
throwParseError (FilePath
"PKCS8: error parsing inner RSA: " forall a. [a] -> [a] -> [a]
++ FilePath
err)
             Right PrivateKey
privKey -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. [Attribute] -> a -> Modern a
Modern [Attribute]
attrs PrivateKey
privKey)


-- DSA

instance ASN1Object (FormattedKey DSA.KeyPair) where
    toASN1 :: FormattedKey KeyPair -> ASN1S
toASN1   = forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
asn1s
    fromASN1 :: [ASN1] -> Either FilePath (FormattedKey KeyPair, [ASN1])
fromASN1 = forall a. ParseASN1 () a -> [ASN1] -> Either FilePath (a, [ASN1])
runParseASN1State forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse

instance ASN1Elem e => ProduceASN1Object e (Traditional DSA.KeyPair) where
    asn1s :: Traditional KeyPair -> ASN1Stream e
asn1s (Traditional (DSA.KeyPair Params
params Integer
pub Integer
priv)) =
        forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container ASN1ConstructionType
Sequence (ASN1Stream e
v forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e. ASN1Elem e => Params -> ASN1Stream e
pqgASN1S Params
params forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
pub' forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
priv')
      where
        v :: ASN1Stream e
v     = forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal Integer
0
        pub' :: ASN1Stream e
pub'  = forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal Integer
pub
        priv' :: ASN1Stream e
priv' = forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal Integer
priv

instance Monoid e => ParseASN1Object e (Traditional DSA.KeyPair) where
    parse :: ParseASN1 e (Traditional KeyPair)
parse = forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
onNextContainer ASN1ConstructionType
Sequence forall a b. (a -> b) -> a -> b
$ do
        IntVal Integer
0 <- forall e. Monoid e => ParseASN1 e ASN1
getNext
        Params
params <- forall e. Monoid e => ParseASN1 e Params
parsePQG
        IntVal Integer
pub <- forall e. Monoid e => ParseASN1 e ASN1
getNext
        IntVal Integer
priv <- forall e. Monoid e => ParseASN1 e ASN1
getNext
        forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Traditional a
Traditional forall a b. (a -> b) -> a -> b
$ Params -> Integer -> Integer -> KeyPair
DSA.KeyPair Params
params Integer
pub Integer
priv)

instance ASN1Elem e => ProduceASN1Object e (Modern DSA.KeyPair) where
    asn1s :: Modern KeyPair -> ASN1Stream e
asn1s (Modern [Attribute]
attrs (DSA.KeyPair Params
params Integer
_ Integer
priv)) =
        forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container ASN1ConstructionType
Sequence (ASN1Stream e
v forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
alg forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
bs forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
att)
      where
        v :: ASN1Stream e
v     = forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal Integer
0
        alg :: ASN1Stream e
alg   = forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container ASN1ConstructionType
Sequence (ASN1Stream e
oid forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
pr)
        oid :: ASN1Stream e
oid   = forall e. ASN1Elem e => OID -> ASN1Stream e
gOID [Integer
1,Integer
2,Integer
840,Integer
10040,Integer
4,Integer
1]
        pr :: ASN1Stream e
pr    = forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container ASN1ConstructionType
Sequence (forall e. ASN1Elem e => Params -> ASN1Stream e
pqgASN1S Params
params)
        bs :: ASN1Stream e
bs    = forall e. ASN1Elem e => ByteString -> ASN1Stream e
gOctetString (ASN1PS -> ByteString
encodeASN1S forall a b. (a -> b) -> a -> b
$ forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal Integer
priv)
        att :: ASN1Stream e
att   = forall e.
ASN1Elem e =>
ASN1ConstructionType -> [Attribute] -> ASN1Stream e
attributesASN1S (ASN1Class -> Int -> ASN1ConstructionType
Container ASN1Class
Context Int
0) [Attribute]
attrs

instance Monoid e => ParseASN1Object e (Modern DSA.KeyPair) where
    parse :: ParseASN1 e (Modern KeyPair)
parse = forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
onNextContainer ASN1ConstructionType
Sequence forall a b. (a -> b) -> a -> b
$ do
        forall e. Monoid e => ParseASN1 e ()
skipVersion
        Params
params <- forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
onNextContainer ASN1ConstructionType
Sequence forall a b. (a -> b) -> a -> b
$ do
                      OID [Integer
1,Integer
2,Integer
840,Integer
10040,Integer
4,Integer
1] <- forall e. Monoid e => ParseASN1 e ASN1
getNext
                      forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
onNextContainer ASN1ConstructionType
Sequence forall e. Monoid e => ParseASN1 e Params
parsePQG
        ([Attribute]
attrs, ByteString
bs) <- forall e. Monoid e => ParseASN1 e ([Attribute], ByteString)
parseAttrKeys
        case forall a.
ASN1Decoding a =>
a -> ByteString -> Either ASN1Error [ASN1]
decodeASN1' BER
BER ByteString
bs of
            Right [IntVal Integer
priv] ->
                let pub :: Integer
pub = Params -> Integer -> Integer
DSA.calculatePublic Params
params Integer
priv
                 in forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. [Attribute] -> a -> Modern a
Modern [Attribute]
attrs forall a b. (a -> b) -> a -> b
$ Params -> Integer -> Integer -> KeyPair
DSA.KeyPair Params
params Integer
pub Integer
priv)
            Right [ASN1]
_ -> forall e a. FilePath -> ParseASN1 e a
throwParseError FilePath
"PKCS8: invalid format when parsing inner DSA"
            Left  ASN1Error
e -> forall e a. FilePath -> ParseASN1 e a
throwParseError (FilePath
"PKCS8: error parsing inner DSA: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> FilePath
show ASN1Error
e)

pqgASN1S :: ASN1Elem e => DSA.Params -> ASN1Stream e
pqgASN1S :: forall e. ASN1Elem e => Params -> ASN1Stream e
pqgASN1S Params
params = [e] -> [e]
p forall b c a. (b -> c) -> (a -> b) -> a -> c
. [e] -> [e]
q forall b c a. (b -> c) -> (a -> b) -> a -> c
. [e] -> [e]
g
  where p :: [e] -> [e]
p = forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal (Params -> Integer
DSA.params_p Params
params)
        q :: [e] -> [e]
q = forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal (Params -> Integer
DSA.params_q Params
params)
        g :: [e] -> [e]
g = forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal (Params -> Integer
DSA.params_g Params
params)

parsePQG :: Monoid e => ParseASN1 e DSA.Params
parsePQG :: forall e. Monoid e => ParseASN1 e Params
parsePQG = do
    IntVal Integer
p <- forall e. Monoid e => ParseASN1 e ASN1
getNext
    IntVal Integer
q <- forall e. Monoid e => ParseASN1 e ASN1
getNext
    IntVal Integer
g <- forall e. Monoid e => ParseASN1 e ASN1
getNext
    forall (m :: * -> *) a. Monad m => a -> m a
return DSA.Params { params_p :: Integer
DSA.params_p = Integer
p
                      , params_q :: Integer
DSA.params_q = Integer
q
                      , params_g :: Integer
DSA.params_g = Integer
g
                      }

dsaPrivToPair :: DSA.PrivateKey -> DSA.KeyPair
dsaPrivToPair :: PrivateKey -> KeyPair
dsaPrivToPair PrivateKey
k = Params -> Integer -> Integer -> KeyPair
DSA.KeyPair Params
params Integer
pub Integer
x
  where pub :: Integer
pub     = Params -> Integer -> Integer
DSA.calculatePublic Params
params Integer
x
        params :: Params
params  = PrivateKey -> Params
DSA.private_params PrivateKey
k
        x :: Integer
x       = PrivateKey -> Integer
DSA.private_x PrivateKey
k


-- ECDSA

instance ASN1Object (FormattedKey X509.PrivKeyEC) where
    toASN1 :: FormattedKey PrivKeyEC -> ASN1S
toASN1   = forall e obj. ProduceASN1Object e obj => obj -> ASN1Stream e
asn1s
    fromASN1 :: [ASN1] -> Either FilePath (FormattedKey PrivKeyEC, [ASN1])
fromASN1 = forall a. ParseASN1 () a -> [ASN1] -> Either FilePath (a, [ASN1])
runParseASN1State forall e obj. ParseASN1Object e obj => ParseASN1 e obj
parse

instance ASN1Elem e => ProduceASN1Object e (Traditional X509.PrivKeyEC) where
    asn1s :: Traditional PrivKeyEC -> ASN1Stream e
asn1s = forall e. ASN1Elem e => Bool -> PrivKeyEC -> ASN1Stream e
innerEcdsaASN1S Bool
True forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Traditional a -> a
unTraditional

instance Monoid e => ParseASN1Object e (Traditional X509.PrivKeyEC) where
    parse :: ParseASN1 e (Traditional PrivKeyEC)
parse = forall a. a -> Traditional a
Traditional forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e.
Monoid e =>
Maybe (Integer -> PrivKeyEC) -> ParseASN1 e PrivKeyEC
parseInnerEcdsa forall a. Maybe a
Nothing

instance ASN1Elem e => ProduceASN1Object e (Modern X509.PrivKeyEC) where
    asn1s :: Modern PrivKeyEC -> ASN1Stream e
asn1s (Modern [Attribute]
attrs PrivKeyEC
privKey) = forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container ASN1ConstructionType
Sequence (ASN1Stream e
v forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
bs forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
att)
      where
        v :: ASN1Stream e
v     = forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal Integer
0
        f :: ASN1Stream e
f     = forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container ASN1ConstructionType
Sequence (ASN1Stream e
oid forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e. ASN1Elem e => PrivKeyEC -> ASN1Stream e
curveFnASN1S PrivKeyEC
privKey)
        oid :: ASN1Stream e
oid   = forall e. ASN1Elem e => OID -> ASN1Stream e
gOID [Integer
1,Integer
2,Integer
840,Integer
10045,Integer
2,Integer
1]
        bs :: ASN1Stream e
bs    = forall e. ASN1Elem e => ByteString -> ASN1Stream e
gOctetString (ASN1PS -> ByteString
encodeASN1S ASN1PS
inner)
        inner :: ASN1PS
inner = forall e. ASN1Elem e => Bool -> PrivKeyEC -> ASN1Stream e
innerEcdsaASN1S Bool
False PrivKeyEC
privKey
        att :: ASN1Stream e
att   = forall e.
ASN1Elem e =>
ASN1ConstructionType -> [Attribute] -> ASN1Stream e
attributesASN1S (ASN1Class -> Int -> ASN1ConstructionType
Container ASN1Class
Context Int
0) [Attribute]
attrs

instance Monoid e => ParseASN1Object e (Modern X509.PrivKeyEC) where
    parse :: ParseASN1 e (Modern PrivKeyEC)
parse = forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
onNextContainer ASN1ConstructionType
Sequence forall a b. (a -> b) -> a -> b
$ do
        forall e. Monoid e => ParseASN1 e ()
skipVersion
        Integer -> PrivKeyEC
f <- forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
onNextContainer ASN1ConstructionType
Sequence forall a b. (a -> b) -> a -> b
$ do
            OID [Integer
1,Integer
2,Integer
840,Integer
10045,Integer
2,Integer
1] <- forall e. Monoid e => ParseASN1 e ASN1
getNext
            forall e. Monoid e => ParseASN1 e (Integer -> PrivKeyEC)
parseCurveFn
        ([Attribute]
attrs, ByteString
bs) <- forall e. Monoid e => ParseASN1 e ([Attribute], ByteString)
parseAttrKeys
        let inner :: Either ASN1Error [ASN1]
inner = forall a.
ASN1Decoding a =>
a -> ByteString -> Either ASN1Error [ASN1]
decodeASN1' BER
BER ByteString
bs
            strError :: ASN1Error -> Either FilePath b
strError = forall a b. a -> Either a b
Left forall b c a. (b -> c) -> (a -> b) -> a -> c
.  (FilePath
"PKCS8: error decoding inner EC: " forall a. [a] -> [a] -> [a]
++) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> FilePath
show
        case forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall {b}. ASN1Error -> Either FilePath b
strError (forall a. ParseASN1 () a -> [ASN1] -> Either FilePath a
runParseASN1 forall a b. (a -> b) -> a -> b
$ forall e.
Monoid e =>
Maybe (Integer -> PrivKeyEC) -> ParseASN1 e PrivKeyEC
parseInnerEcdsa forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just Integer -> PrivKeyEC
f) Either ASN1Error [ASN1]
inner of
            Left FilePath
err -> forall e a. FilePath -> ParseASN1 e a
throwParseError (FilePath
"PKCS8: error parsing inner EC: " forall a. [a] -> [a] -> [a]
++ FilePath
err)
            Right PrivKeyEC
privKey -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. [Attribute] -> a -> Modern a
Modern [Attribute]
attrs PrivKeyEC
privKey)

innerEcdsaASN1S :: ASN1Elem e => Bool -> X509.PrivKeyEC -> ASN1Stream e
innerEcdsaASN1S :: forall e. ASN1Elem e => Bool -> PrivKeyEC -> ASN1Stream e
innerEcdsaASN1S Bool
addC PrivKeyEC
k
    | Bool
addC      = forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container ASN1ConstructionType
Sequence ([e] -> [e]
v forall b c a. (b -> c) -> (a -> b) -> a -> c
. [e] -> [e]
ds forall b c a. (b -> c) -> (a -> b) -> a -> c
. [e] -> [e]
c0 forall b c a. (b -> c) -> (a -> b) -> a -> c
. [e] -> [e]
c1)
    | Bool
otherwise = forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container ASN1ConstructionType
Sequence ([e] -> [e]
v forall b c a. (b -> c) -> (a -> b) -> a -> c
. [e] -> [e]
ds forall b c a. (b -> c) -> (a -> b) -> a -> c
. [e] -> [e]
c1)
  where
    curve :: Curve
curve = forall a. a -> Maybe a -> a
fromMaybe (forall a. HasCallStack => FilePath -> a
error FilePath
"PKCS8: invalid EC parameters") (PrivKeyEC -> Maybe Curve
ecPrivKeyCurve PrivKeyEC
k)
    bytes :: Int
bytes = Curve -> Int
curveOrderBytes Curve
curve

    v :: [e] -> [e]
v  = forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal Integer
1
    ds :: [e] -> [e]
ds = forall e. ASN1Elem e => ByteString -> ASN1Stream e
gOctetString (forall ba. ByteArray ba => Int -> Integer -> ba
i2ospOf_ Int
bytes (PrivKeyEC -> Integer
X509.privkeyEC_priv PrivKeyEC
k))
    c0 :: [e] -> [e]
c0 = forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container (ASN1Class -> Int -> ASN1ConstructionType
Container ASN1Class
Context Int
0) (forall e. ASN1Elem e => PrivKeyEC -> ASN1Stream e
curveFnASN1S PrivKeyEC
k)
    c1 :: [e] -> [e]
c1 = forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container (ASN1Class -> Int -> ASN1ConstructionType
Container ASN1Class
Context Int
1) [e] -> [e]
pub

    pub :: [e] -> [e]
pub = forall e. ASN1Elem e => BitArray -> ASN1Stream e
gBitString (ByteString -> Int -> BitArray
toBitArray ByteString
sp Int
0)
    X509.SerializedPoint ByteString
sp = Curve -> Integer -> SerializedPoint
getSerializedPoint Curve
curve (PrivKeyEC -> Integer
X509.privkeyEC_priv PrivKeyEC
k)

parseInnerEcdsa :: Monoid e
                => Maybe (ECDSA.PrivateNumber -> X509.PrivKeyEC)
                -> ParseASN1 e X509.PrivKeyEC
parseInnerEcdsa :: forall e.
Monoid e =>
Maybe (Integer -> PrivKeyEC) -> ParseASN1 e PrivKeyEC
parseInnerEcdsa Maybe (Integer -> PrivKeyEC)
fn = forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
onNextContainer ASN1ConstructionType
Sequence forall a b. (a -> b) -> a -> b
$ do
    IntVal Integer
1 <- forall e. Monoid e => ParseASN1 e ASN1
getNext
    OctetString ByteString
ds <- forall e. Monoid e => ParseASN1 e ASN1
getNext
    let d :: Integer
d = forall ba. ByteArrayAccess ba => ba -> Integer
os2ip ByteString
ds
    Maybe (Integer -> PrivKeyEC)
m <- forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e (Maybe a)
onNextContainerMaybe (ASN1Class -> Int -> ASN1ConstructionType
Container ASN1Class
Context Int
0) forall e. Monoid e => ParseASN1 e (Integer -> PrivKeyEC)
parseCurveFn
    Maybe BitArray
_ <- forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e (Maybe a)
onNextContainerMaybe (ASN1Class -> Int -> ASN1ConstructionType
Container ASN1Class
Context Int
1) ParseASN1 e BitArray
parsePK
    case Maybe (Integer -> PrivKeyEC)
fn forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe (Integer -> PrivKeyEC)
m of
        Maybe (Integer -> PrivKeyEC)
Nothing     -> forall e a. FilePath -> ParseASN1 e a
throwParseError FilePath
"PKCS8: no curve found in EC private key"
        Just Integer -> PrivKeyEC
getKey -> forall (m :: * -> *) a. Monad m => a -> m a
return (Integer -> PrivKeyEC
getKey Integer
d)
  where
    parsePK :: ParseASN1 e BitArray
parsePK = do { BitString BitArray
bs <- forall e. Monoid e => ParseASN1 e ASN1
getNext; forall (m :: * -> *) a. Monad m => a -> m a
return BitArray
bs }

curveFnASN1S :: ASN1Elem e => X509.PrivKeyEC -> ASN1Stream e
curveFnASN1S :: forall e. ASN1Elem e => PrivKeyEC -> ASN1Stream e
curveFnASN1S X509.PrivKeyEC_Named{Integer
CurveName
privkeyEC_name :: PrivKeyEC -> CurveName
privkeyEC_priv :: Integer
privkeyEC_name :: CurveName
privkeyEC_priv :: PrivKeyEC -> Integer
..} = forall e. ASN1Elem e => OID -> ASN1Stream e
gOID (CurveName -> OID
curveNameOID CurveName
privkeyEC_name)
curveFnASN1S X509.PrivKeyEC_Prime{Integer
SerializedPoint
privkeyEC_a :: PrivKeyEC -> Integer
privkeyEC_b :: PrivKeyEC -> Integer
privkeyEC_prime :: PrivKeyEC -> Integer
privkeyEC_generator :: PrivKeyEC -> SerializedPoint
privkeyEC_order :: PrivKeyEC -> Integer
privkeyEC_cofactor :: PrivKeyEC -> Integer
privkeyEC_seed :: PrivKeyEC -> Integer
privkeyEC_seed :: Integer
privkeyEC_cofactor :: Integer
privkeyEC_order :: Integer
privkeyEC_generator :: SerializedPoint
privkeyEC_prime :: Integer
privkeyEC_b :: Integer
privkeyEC_a :: Integer
privkeyEC_priv :: Integer
privkeyEC_priv :: PrivKeyEC -> Integer
..} =
    forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container ASN1ConstructionType
Sequence ([e] -> [e]
v forall b c a. (b -> c) -> (a -> b) -> a -> c
. [e] -> [e]
prime forall b c a. (b -> c) -> (a -> b) -> a -> c
. [e] -> [e]
abSeed forall b c a. (b -> c) -> (a -> b) -> a -> c
. [e] -> [e]
gen forall b c a. (b -> c) -> (a -> b) -> a -> c
. [e] -> [e]
o forall b c a. (b -> c) -> (a -> b) -> a -> c
. [e] -> [e]
c)
  where
    X509.SerializedPoint ByteString
generator = SerializedPoint
privkeyEC_generator
    bytes :: Int
bytes  = Integer -> Int
numBytes Integer
privkeyEC_prime

    v :: [e] -> [e]
v      = forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal Integer
1

    prime :: [e] -> [e]
prime  = forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container ASN1ConstructionType
Sequence ([e] -> [e]
oid forall b c a. (b -> c) -> (a -> b) -> a -> c
. [e] -> [e]
p)
    oid :: [e] -> [e]
oid    = forall e. ASN1Elem e => OID -> ASN1Stream e
gOID [Integer
1,Integer
2,Integer
840,Integer
10045,Integer
1,Integer
1]
    p :: [e] -> [e]
p      = forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal Integer
privkeyEC_prime

    abSeed :: [e] -> [e]
abSeed = forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container ASN1ConstructionType
Sequence ([e] -> [e]
a forall b c a. (b -> c) -> (a -> b) -> a -> c
. [e] -> [e]
b forall b c a. (b -> c) -> (a -> b) -> a -> c
. [e] -> [e]
seed)
    a :: [e] -> [e]
a      = forall e. ASN1Elem e => ByteString -> ASN1Stream e
gOctetString (forall ba. ByteArray ba => Int -> Integer -> ba
i2ospOf_ Int
bytes Integer
privkeyEC_a)
    b :: [e] -> [e]
b      = forall e. ASN1Elem e => ByteString -> ASN1Stream e
gOctetString (forall ba. ByteArray ba => Int -> Integer -> ba
i2ospOf_ Int
bytes Integer
privkeyEC_b)
    seed :: [e] -> [e]
seed   = if Integer
privkeyEC_seed forall a. Ord a => a -> a -> Bool
> Integer
0
                 then forall e. ASN1Elem e => BitArray -> ASN1Stream e
gBitString (ByteString -> Int -> BitArray
toBitArray (forall ba. ByteArray ba => Integer -> ba
i2osp Integer
privkeyEC_seed) Int
0)
                 else forall a. a -> a
id

    gen :: [e] -> [e]
gen    = forall e. ASN1Elem e => ByteString -> ASN1Stream e
gOctetString ByteString
generator
    o :: [e] -> [e]
o      = forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal Integer
privkeyEC_order
    c :: [e] -> [e]
c      = forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal Integer
privkeyEC_cofactor

parseCurveFn :: Monoid e => ParseASN1 e (ECDSA.PrivateNumber -> X509.PrivKeyEC)
parseCurveFn :: forall e. Monoid e => ParseASN1 e (Integer -> PrivKeyEC)
parseCurveFn = ParseASN1 e (Integer -> PrivKeyEC)
parseNamedCurve forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParseASN1 e (Integer -> PrivKeyEC)
parsePrimeCurve
  where
    parseNamedCurve :: ParseASN1 e (Integer -> PrivKeyEC)
parseNamedCurve = do
        OID OID
oid <- forall e. Monoid e => ParseASN1 e ASN1
getNext
        case OID -> Maybe CurveName
lookupCurveNameByOID OID
oid of
            Just CurveName
name -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ \Integer
d ->
                            X509.PrivKeyEC_Named
                                { privkeyEC_name :: CurveName
X509.privkeyEC_name = CurveName
name
                                , privkeyEC_priv :: Integer
X509.privkeyEC_priv = Integer
d
                                }
            Maybe CurveName
Nothing -> forall e a. FilePath -> ParseASN1 e a
throwParseError (FilePath
"PKCS8: unknown EC curve with OID " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> FilePath
show OID
oid)

    parsePrimeCurve :: ParseASN1 e (Integer -> PrivKeyEC)
parsePrimeCurve =
        forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
onNextContainer ASN1ConstructionType
Sequence forall a b. (a -> b) -> a -> b
$ do
            IntVal Integer
1 <- forall e. Monoid e => ParseASN1 e ASN1
getNext
            Integer
prime <- forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
onNextContainer ASN1ConstructionType
Sequence forall a b. (a -> b) -> a -> b
$ do
                OID [Integer
1,Integer
2,Integer
840,Integer
10045,Integer
1,Integer
1] <- forall e. Monoid e => ParseASN1 e ASN1
getNext
                IntVal Integer
prime <- forall e. Monoid e => ParseASN1 e ASN1
getNext
                forall (m :: * -> *) a. Monad m => a -> m a
return Integer
prime
            (ByteString
a, ByteString
b, Integer
seed) <- forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
onNextContainer ASN1ConstructionType
Sequence forall a b. (a -> b) -> a -> b
$ do
                OctetString ByteString
a <- forall e. Monoid e => ParseASN1 e ASN1
getNext
                OctetString ByteString
b <- forall e. Monoid e => ParseASN1 e ASN1
getNext
                Integer
seed <- ParseASN1 e Integer
parseOptionalSeed
                forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString
a, ByteString
b, Integer
seed)
            OctetString ByteString
generator <- forall e. Monoid e => ParseASN1 e ASN1
getNext
            IntVal Integer
order <- forall e. Monoid e => ParseASN1 e ASN1
getNext
            IntVal Integer
cofactor <- forall e. Monoid e => ParseASN1 e ASN1
getNext
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ \Integer
d ->
                X509.PrivKeyEC_Prime
                    { privkeyEC_priv :: Integer
X509.privkeyEC_priv      = Integer
d
                    , privkeyEC_a :: Integer
X509.privkeyEC_a         = forall ba. ByteArrayAccess ba => ba -> Integer
os2ip ByteString
a
                    , privkeyEC_b :: Integer
X509.privkeyEC_b         = forall ba. ByteArrayAccess ba => ba -> Integer
os2ip ByteString
b
                    , privkeyEC_prime :: Integer
X509.privkeyEC_prime     = Integer
prime
                    , privkeyEC_generator :: SerializedPoint
X509.privkeyEC_generator = ByteString -> SerializedPoint
X509.SerializedPoint ByteString
generator
                    , privkeyEC_order :: Integer
X509.privkeyEC_order     = Integer
order
                    , privkeyEC_cofactor :: Integer
X509.privkeyEC_cofactor  = Integer
cofactor
                    , privkeyEC_seed :: Integer
X509.privkeyEC_seed      = Integer
seed
                    }

    parseOptionalSeed :: ParseASN1 e Integer
parseOptionalSeed = do
        Bool
seedAvail <- forall e. ParseASN1 e Bool
hasNext
        if Bool
seedAvail
            then do BitString BitArray
seed <- forall e. Monoid e => ParseASN1 e ASN1
getNext
                    forall (m :: * -> *) a. Monad m => a -> m a
return (forall ba. ByteArrayAccess ba => ba -> Integer
os2ip forall a b. (a -> b) -> a -> b
$ BitArray -> ByteString
bitArrayGetData BitArray
seed)
            else forall (m :: * -> *) a. Monad m => a -> m a
return Integer
0


-- X25519, X448, Ed25519, Ed448

instance ASN1Elem e => ProduceASN1Object e (Modern X25519.SecretKey) where
    asn1s :: Modern SecretKey -> ASN1Stream e
asn1s (Modern [Attribute]
attrs SecretKey
privKey) = forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container ASN1ConstructionType
Sequence (ASN1Stream e
v forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
alg forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
bs forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
att)
      where
        v :: ASN1Stream e
v     = forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal Integer
0
        alg :: ASN1Stream e
alg   = forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container ASN1ConstructionType
Sequence (forall e. ASN1Elem e => OID -> ASN1Stream e
gOID [Integer
1,Integer
3,Integer
101,Integer
110])
        bs :: ASN1Stream e
bs    = forall e key.
(ASN1Elem e, ByteArrayAccess key) =>
key -> ASN1Stream e
innerEddsaASN1S SecretKey
privKey
        att :: ASN1Stream e
att   = forall e.
ASN1Elem e =>
ASN1ConstructionType -> [Attribute] -> ASN1Stream e
attributesASN1S (ASN1Class -> Int -> ASN1ConstructionType
Container ASN1Class
Context Int
0) [Attribute]
attrs

instance Monoid e => ParseASN1Object e (Modern X25519.SecretKey) where
    parse :: ParseASN1 e (Modern SecretKey)
parse = forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
onNextContainer ASN1ConstructionType
Sequence forall a b. (a -> b) -> a -> b
$ do
        forall e. Monoid e => ParseASN1 e ()
skipVersion
        forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
onNextContainer ASN1ConstructionType
Sequence forall a b. (a -> b) -> a -> b
$ do { OID [Integer
1,Integer
3,Integer
101,Integer
110] <- forall e. Monoid e => ParseASN1 e ASN1
getNext; forall (m :: * -> *) a. Monad m => a -> m a
return () }
        ([Attribute]
attrs, ByteString
bs) <- forall e. Monoid e => ParseASN1 e ([Attribute], ByteString)
parseAttrKeys
        forall a. [Attribute] -> a -> Modern a
Modern [Attribute]
attrs forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e key.
Monoid e =>
FilePath
-> (ByteString -> CryptoFailable key)
-> ByteString
-> ParseASN1 e key
parseInnerEddsa FilePath
"X25519" forall bs. ByteArrayAccess bs => bs -> CryptoFailable SecretKey
X25519.secretKey ByteString
bs

instance ASN1Elem e => ProduceASN1Object e (Modern X448.SecretKey) where
    asn1s :: Modern SecretKey -> ASN1Stream e
asn1s (Modern [Attribute]
attrs SecretKey
privKey) = forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container ASN1ConstructionType
Sequence (ASN1Stream e
v forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
alg forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
bs forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
att)
      where
        v :: ASN1Stream e
v     = forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal Integer
0
        alg :: ASN1Stream e
alg   = forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container ASN1ConstructionType
Sequence (forall e. ASN1Elem e => OID -> ASN1Stream e
gOID [Integer
1,Integer
3,Integer
101,Integer
111])
        bs :: ASN1Stream e
bs    = forall e key.
(ASN1Elem e, ByteArrayAccess key) =>
key -> ASN1Stream e
innerEddsaASN1S SecretKey
privKey
        att :: ASN1Stream e
att   = forall e.
ASN1Elem e =>
ASN1ConstructionType -> [Attribute] -> ASN1Stream e
attributesASN1S (ASN1Class -> Int -> ASN1ConstructionType
Container ASN1Class
Context Int
0) [Attribute]
attrs

instance Monoid e => ParseASN1Object e (Modern X448.SecretKey) where
    parse :: ParseASN1 e (Modern SecretKey)
parse = forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
onNextContainer ASN1ConstructionType
Sequence forall a b. (a -> b) -> a -> b
$ do
        forall e. Monoid e => ParseASN1 e ()
skipVersion
        forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
onNextContainer ASN1ConstructionType
Sequence forall a b. (a -> b) -> a -> b
$ do { OID [Integer
1,Integer
3,Integer
101,Integer
111] <- forall e. Monoid e => ParseASN1 e ASN1
getNext; forall (m :: * -> *) a. Monad m => a -> m a
return () }
        ([Attribute]
attrs, ByteString
bs) <- forall e. Monoid e => ParseASN1 e ([Attribute], ByteString)
parseAttrKeys
        forall a. [Attribute] -> a -> Modern a
Modern [Attribute]
attrs forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e key.
Monoid e =>
FilePath
-> (ByteString -> CryptoFailable key)
-> ByteString
-> ParseASN1 e key
parseInnerEddsa FilePath
"X448" forall bs. ByteArrayAccess bs => bs -> CryptoFailable SecretKey
X448.secretKey ByteString
bs

instance ASN1Elem e => ProduceASN1Object e (Modern Ed25519.SecretKey) where
    asn1s :: Modern SecretKey -> ASN1Stream e
asn1s (Modern [Attribute]
attrs SecretKey
privKey) = forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container ASN1ConstructionType
Sequence (ASN1Stream e
v forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
alg forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
bs forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
att)
      where
        v :: ASN1Stream e
v     = forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal Integer
0
        alg :: ASN1Stream e
alg   = forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container ASN1ConstructionType
Sequence (forall e. ASN1Elem e => OID -> ASN1Stream e
gOID [Integer
1,Integer
3,Integer
101,Integer
112])
        bs :: ASN1Stream e
bs    = forall e key.
(ASN1Elem e, ByteArrayAccess key) =>
key -> ASN1Stream e
innerEddsaASN1S SecretKey
privKey
        att :: ASN1Stream e
att   = forall e.
ASN1Elem e =>
ASN1ConstructionType -> [Attribute] -> ASN1Stream e
attributesASN1S (ASN1Class -> Int -> ASN1ConstructionType
Container ASN1Class
Context Int
0) [Attribute]
attrs

instance Monoid e => ParseASN1Object e (Modern Ed25519.SecretKey) where
    parse :: ParseASN1 e (Modern SecretKey)
parse = forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
onNextContainer ASN1ConstructionType
Sequence forall a b. (a -> b) -> a -> b
$ do
        forall e. Monoid e => ParseASN1 e ()
skipVersion
        forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
onNextContainer ASN1ConstructionType
Sequence forall a b. (a -> b) -> a -> b
$ do { OID [Integer
1,Integer
3,Integer
101,Integer
112] <- forall e. Monoid e => ParseASN1 e ASN1
getNext; forall (m :: * -> *) a. Monad m => a -> m a
return () }
        ([Attribute]
attrs, ByteString
bs) <- forall e. Monoid e => ParseASN1 e ([Attribute], ByteString)
parseAttrKeys
        forall a. [Attribute] -> a -> Modern a
Modern [Attribute]
attrs forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e key.
Monoid e =>
FilePath
-> (ByteString -> CryptoFailable key)
-> ByteString
-> ParseASN1 e key
parseInnerEddsa FilePath
"Ed25519" forall ba. ByteArrayAccess ba => ba -> CryptoFailable SecretKey
Ed25519.secretKey ByteString
bs

instance ASN1Elem e => ProduceASN1Object e (Modern Ed448.SecretKey) where
    asn1s :: Modern SecretKey -> ASN1Stream e
asn1s (Modern [Attribute]
attrs SecretKey
privKey) = forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container ASN1ConstructionType
Sequence (ASN1Stream e
v forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
alg forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
bs forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Stream e
att)
      where
        v :: ASN1Stream e
v     = forall e. ASN1Elem e => Integer -> ASN1Stream e
gIntVal Integer
0
        alg :: ASN1Stream e
alg   = forall e.
ASN1Elem e =>
ASN1ConstructionType -> ASN1Stream e -> ASN1Stream e
asn1Container ASN1ConstructionType
Sequence (forall e. ASN1Elem e => OID -> ASN1Stream e
gOID [Integer
1,Integer
3,Integer
101,Integer
113])
        bs :: ASN1Stream e
bs    = forall e key.
(ASN1Elem e, ByteArrayAccess key) =>
key -> ASN1Stream e
innerEddsaASN1S SecretKey
privKey
        att :: ASN1Stream e
att   = forall e.
ASN1Elem e =>
ASN1ConstructionType -> [Attribute] -> ASN1Stream e
attributesASN1S (ASN1Class -> Int -> ASN1ConstructionType
Container ASN1Class
Context Int
0) [Attribute]
attrs

instance Monoid e => ParseASN1Object e (Modern Ed448.SecretKey) where
    parse :: ParseASN1 e (Modern SecretKey)
parse = forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
onNextContainer ASN1ConstructionType
Sequence forall a b. (a -> b) -> a -> b
$ do
        forall e. Monoid e => ParseASN1 e ()
skipVersion
        forall e a.
Monoid e =>
ASN1ConstructionType -> ParseASN1 e a -> ParseASN1 e a
onNextContainer ASN1ConstructionType
Sequence forall a b. (a -> b) -> a -> b
$ do { OID [Integer
1,Integer
3,Integer
101,Integer
113] <- forall e. Monoid e => ParseASN1 e ASN1
getNext; forall (m :: * -> *) a. Monad m => a -> m a
return () }
        ([Attribute]
attrs, ByteString
bs) <- forall e. Monoid e => ParseASN1 e ([Attribute], ByteString)
parseAttrKeys
        forall a. [Attribute] -> a -> Modern a
Modern [Attribute]
attrs forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall e key.
Monoid e =>
FilePath
-> (ByteString -> CryptoFailable key)
-> ByteString
-> ParseASN1 e key
parseInnerEddsa FilePath
"Ed448" forall ba. ByteArrayAccess ba => ba -> CryptoFailable SecretKey
Ed448.secretKey ByteString
bs

innerEddsaASN1S :: (ASN1Elem e, ByteArrayAccess key) => key -> ASN1Stream e
innerEddsaASN1S :: forall e key.
(ASN1Elem e, ByteArrayAccess key) =>
key -> ASN1Stream e
innerEddsaASN1S key
key = forall e. ASN1Elem e => ByteString -> ASN1Stream e
gOctetString (ASN1PS -> ByteString
encodeASN1S ASN1PS
inner)
  where inner :: ASN1PS
inner = forall e. ASN1Elem e => ByteString -> ASN1Stream e
gOctetString (forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
convert key
key)

parseInnerEddsa :: Monoid e
                => String
                -> (B.ByteString -> CryptoFailable key)
                -> B.ByteString
                -> ParseASN1 e key
parseInnerEddsa :: forall e key.
Monoid e =>
FilePath
-> (ByteString -> CryptoFailable key)
-> ByteString
-> ParseASN1 e key
parseInnerEddsa FilePath
name ByteString -> CryptoFailable key
buildKey ByteString
input =
    case forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall {b}. ASN1Error -> Either FilePath b
strError (forall a. ParseASN1 () a -> [ASN1] -> Either FilePath a
runParseASN1 ParseASN1 () key
parser) (forall a.
ASN1Decoding a =>
a -> ByteString -> Either ASN1Error [ASN1]
decodeASN1' BER
BER ByteString
input) of
        Left FilePath
err -> forall e a. FilePath -> ParseASN1 e a
throwParseError (FilePath
"PKCS8: error parsing inner " forall a. [a] -> [a] -> [a]
++ FilePath
name forall a. [a] -> [a] -> [a]
++ FilePath
": " forall a. [a] -> [a] -> [a]
++ FilePath
err)
        Right key
privKey -> forall (m :: * -> *) a. Monad m => a -> m a
return key
privKey
  where
    innerMsg :: FilePath
innerMsg = FilePath
"PKCS8: error decoding inner " forall a. [a] -> [a] -> [a]
++ FilePath
name forall a. [a] -> [a] -> [a]
++ FilePath
": "
    strError :: ASN1Error -> Either FilePath b
strError = forall a b. a -> Either a b
Left forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FilePath
innerMsg forall a. [a] -> [a] -> [a]
++) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> FilePath
show
    parser :: ParseASN1 () key
parser   = do
        OctetString ByteString
bs <- forall e. Monoid e => ParseASN1 e ASN1
getNext
        case ByteString -> CryptoFailable key
buildKey ByteString
bs of
            CryptoPassed key
privKey -> forall (m :: * -> *) a. Monad m => a -> m a
return key
privKey
            CryptoFailed CryptoError
_       ->
                forall e a. FilePath -> ParseASN1 e a
throwParseError (FilePath
"PKCS8: parsed invalid " forall a. [a] -> [a] -> [a]
++ FilePath
name forall a. [a] -> [a] -> [a]
++ FilePath
" secret key")