-- |
-- Module      : Data.X509.Memory
-- License     : BSD-style
-- Maintainer  : Vincent Hanquez <vincent@snarc.org>
-- Stability   : experimental
-- Portability : unknown
--
--
module Data.X509.Memory
    ( readKeyFileFromMemory
    , readSignedObjectFromMemory
    , pemToKey
    ) where

import Data.ASN1.Types
import Data.ASN1.BinaryEncoding
import Data.ASN1.BitArray
import Data.ASN1.Encoding
import Data.ASN1.Stream
import Data.Maybe
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.Serialize (os2ip)
import qualified Crypto.PubKey.DSA as DSA
import qualified Crypto.PubKey.ECC.ECDSA as ECDSA
import qualified Crypto.PubKey.RSA as RSA

readKeyFileFromMemory :: B.ByteString -> [X509.PrivKey]
readKeyFileFromMemory :: ByteString -> [PrivKey]
readKeyFileFromMemory = (String -> [PrivKey])
-> ([PEM] -> [PrivKey]) -> Either String [PEM] -> [PrivKey]
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ([PrivKey] -> String -> [PrivKey]
forall a b. a -> b -> a
const []) ([Maybe PrivKey] -> [PrivKey]
forall a. [Maybe a] -> [a]
catMaybes ([Maybe PrivKey] -> [PrivKey])
-> ([PEM] -> [Maybe PrivKey]) -> [PEM] -> [PrivKey]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Maybe PrivKey] -> PEM -> [Maybe PrivKey])
-> [Maybe PrivKey] -> [PEM] -> [Maybe PrivKey]
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl [Maybe PrivKey] -> PEM -> [Maybe PrivKey]
pemToKey []) (Either String [PEM] -> [PrivKey])
-> (ByteString -> Either String [PEM]) -> ByteString -> [PrivKey]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either String [PEM]
pemParseBS

readSignedObjectFromMemory :: (ASN1Object a, Eq a, Show a)
                           => B.ByteString
                           -> [X509.SignedExact a]
readSignedObjectFromMemory :: ByteString -> [SignedExact a]
readSignedObjectFromMemory = (String -> [SignedExact a])
-> ([PEM] -> [SignedExact a])
-> Either String [PEM]
-> [SignedExact a]
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ([SignedExact a] -> String -> [SignedExact a]
forall a b. a -> b -> a
const []) (([SignedExact a] -> PEM -> [SignedExact a])
-> [SignedExact a] -> [PEM] -> [SignedExact a]
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl [SignedExact a] -> PEM -> [SignedExact a]
forall a.
(Show a, Eq a, ASN1Object a) =>
[SignedExact a] -> PEM -> [SignedExact a]
pemToSigned []) (Either String [PEM] -> [SignedExact a])
-> (ByteString -> Either String [PEM])
-> ByteString
-> [SignedExact a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either String [PEM]
pemParseBS
  where pemToSigned :: [SignedExact a] -> PEM -> [SignedExact a]
pemToSigned acc :: [SignedExact a]
acc pem :: PEM
pem =
            case ByteString -> Either String (SignedExact a)
forall a.
(Show a, Eq a, ASN1Object a) =>
ByteString -> Either String (SignedExact a)
X509.decodeSignedObject (ByteString -> Either String (SignedExact a))
-> ByteString -> Either String (SignedExact a)
forall a b. (a -> b) -> a -> b
$ PEM -> ByteString
pemContent PEM
pem of
                Left _    -> [SignedExact a]
acc
                Right obj :: SignedExact a
obj -> SignedExact a
obj SignedExact a -> [SignedExact a] -> [SignedExact a]
forall a. a -> [a] -> [a]
: [SignedExact a]
acc

pemToKey :: [Maybe X509.PrivKey] -> PEM -> [Maybe X509.PrivKey]
pemToKey :: [Maybe PrivKey] -> PEM -> [Maybe PrivKey]
pemToKey acc :: [Maybe PrivKey]
acc pem :: PEM
pem =
    case BER -> ByteString -> Either ASN1Error [ASN1]
forall a.
ASN1Decoding a =>
a -> ByteString -> Either ASN1Error [ASN1]
decodeASN1' BER
BER (PEM -> ByteString
pemContent PEM
pem) of
        Left _     -> [Maybe PrivKey]
acc
        Right asn1 :: [ASN1]
asn1 ->
            case PEM -> String
pemName PEM
pem of
                "PRIVATE KEY" ->
                    [ASN1] -> Maybe PrivKey
tryRSA [ASN1]
asn1 Maybe PrivKey -> [Maybe PrivKey] -> [Maybe PrivKey]
forall a. a -> [a] -> [a]
: [ASN1] -> Maybe PrivKey
tryNewcurve [ASN1]
asn1 Maybe PrivKey -> [Maybe PrivKey] -> [Maybe PrivKey]
forall a. a -> [a] -> [a]
: [ASN1] -> Maybe PrivKey
tryECDSA [ASN1]
asn1 Maybe PrivKey -> [Maybe PrivKey] -> [Maybe PrivKey]
forall a. a -> [a] -> [a]
: [ASN1] -> Maybe PrivKey
tryDSA [ASN1]
asn1 Maybe PrivKey -> [Maybe PrivKey] -> [Maybe PrivKey]
forall a. a -> [a] -> [a]
: [Maybe PrivKey]
acc
                "RSA PRIVATE KEY" ->
                    [ASN1] -> Maybe PrivKey
tryRSA [ASN1]
asn1 Maybe PrivKey -> [Maybe PrivKey] -> [Maybe PrivKey]
forall a. a -> [a] -> [a]
: [Maybe PrivKey]
acc
                "DSA PRIVATE KEY" ->
                    [ASN1] -> Maybe PrivKey
tryDSA [ASN1]
asn1 Maybe PrivKey -> [Maybe PrivKey] -> [Maybe PrivKey]
forall a. a -> [a] -> [a]
: [Maybe PrivKey]
acc
                "EC PRIVATE KEY"  ->
                    [ASN1] -> Maybe PrivKey
tryECDSA [ASN1]
asn1 Maybe PrivKey -> [Maybe PrivKey] -> [Maybe PrivKey]
forall a. a -> [a] -> [a]
: [Maybe PrivKey]
acc
                "X25519 PRIVATE KEY" ->
                    [ASN1] -> Maybe PrivKey
tryNewcurve [ASN1]
asn1 Maybe PrivKey -> [Maybe PrivKey] -> [Maybe PrivKey]
forall a. a -> [a] -> [a]
: [Maybe PrivKey]
acc
                "X448 PRIVATE KEY" ->
                    [ASN1] -> Maybe PrivKey
tryNewcurve [ASN1]
asn1 Maybe PrivKey -> [Maybe PrivKey] -> [Maybe PrivKey]
forall a. a -> [a] -> [a]
: [Maybe PrivKey]
acc
                "ED25519 PRIVATE KEY" ->
                    [ASN1] -> Maybe PrivKey
tryNewcurve [ASN1]
asn1 Maybe PrivKey -> [Maybe PrivKey] -> [Maybe PrivKey]
forall a. a -> [a] -> [a]
: [Maybe PrivKey]
acc
                "ED448 PRIVATE KEY" ->
                    [ASN1] -> Maybe PrivKey
tryNewcurve [ASN1]
asn1 Maybe PrivKey -> [Maybe PrivKey] -> [Maybe PrivKey]
forall a. a -> [a] -> [a]
: [Maybe PrivKey]
acc
                _                 -> [Maybe PrivKey]
acc
  where
        tryRSA :: [ASN1] -> Maybe PrivKey
tryRSA asn1 :: [ASN1]
asn1 = case [ASN1] -> Either String (PrivateKey, [ASN1])
rsaFromASN1 [ASN1]
asn1 of
                    Left _      -> Maybe PrivKey
forall a. Maybe a
Nothing
                    Right (k :: PrivateKey
k,_) -> PrivKey -> Maybe PrivKey
forall a. a -> Maybe a
Just (PrivKey -> Maybe PrivKey) -> PrivKey -> Maybe PrivKey
forall a b. (a -> b) -> a -> b
$ PrivateKey -> PrivKey
X509.PrivKeyRSA PrivateKey
k
        tryDSA :: [ASN1] -> Maybe PrivKey
tryDSA asn1 :: [ASN1]
asn1 = case [ASN1] -> Either String (KeyPair, [ASN1])
dsaFromASN1 [ASN1]
asn1 of
                    Left _      -> Maybe PrivKey
forall a. Maybe a
Nothing
                    Right (k :: KeyPair
k,_) -> PrivKey -> Maybe PrivKey
forall a. a -> Maybe a
Just (PrivKey -> Maybe PrivKey) -> PrivKey -> Maybe PrivKey
forall a b. (a -> b) -> a -> b
$ PrivateKey -> PrivKey
X509.PrivKeyDSA (PrivateKey -> PrivKey) -> PrivateKey -> PrivKey
forall a b. (a -> b) -> a -> b
$ KeyPair -> PrivateKey
DSA.toPrivateKey KeyPair
k
        tryECDSA :: [ASN1] -> Maybe PrivKey
tryECDSA asn1 :: [ASN1]
asn1 = case [ASN1] -> [ASN1] -> Either String (PrivKeyEC, [ASN1])
ecdsaFromASN1 [] [ASN1]
asn1 of
                    Left _      -> Maybe PrivKey
forall a. Maybe a
Nothing
                    Right (k :: PrivKeyEC
k,_) -> PrivKey -> Maybe PrivKey
forall a. a -> Maybe a
Just (PrivKey -> Maybe PrivKey) -> PrivKey -> Maybe PrivKey
forall a b. (a -> b) -> a -> b
$ PrivKeyEC -> PrivKey
X509.PrivKeyEC PrivKeyEC
k
        tryNewcurve :: [ASN1] -> Maybe PrivKey
tryNewcurve asn1 :: [ASN1]
asn1 = case [ASN1] -> Either String (PrivKey, [ASN1])
forall a. ASN1Object a => [ASN1] -> Either String (a, [ASN1])
fromASN1 [ASN1]
asn1 of
                    Right (k :: PrivKey
k@(X509.PrivKeyX25519  _),_) -> PrivKey -> Maybe PrivKey
forall a. a -> Maybe a
Just PrivKey
k
                    Right (k :: PrivKey
k@(X509.PrivKeyX448    _),_) -> PrivKey -> Maybe PrivKey
forall a. a -> Maybe a
Just PrivKey
k
                    Right (k :: PrivKey
k@(X509.PrivKeyEd25519 _),_) -> PrivKey -> Maybe PrivKey
forall a. a -> Maybe a
Just PrivKey
k
                    Right (k :: PrivKey
k@(X509.PrivKeyEd448   _),_) -> PrivKey -> Maybe PrivKey
forall a. a -> Maybe a
Just PrivKey
k
                    _ -> Maybe PrivKey
forall a. Maybe a
Nothing

dsaFromASN1 :: [ASN1] -> Either String (DSA.KeyPair, [ASN1])
dsaFromASN1 :: [ASN1] -> Either String (KeyPair, [ASN1])
dsaFromASN1 (Start Sequence : IntVal n :: Integer
n : xs :: [ASN1]
xs)
    | Integer
n Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
/= 0    = String -> Either String (KeyPair, [ASN1])
forall a b. a -> Either a b
Left "fromASN1: DSA.KeyPair: unknown format"
    | Bool
otherwise =
        case [ASN1]
xs of
            IntVal p :: Integer
p : IntVal q :: Integer
q : IntVal g :: Integer
g : IntVal pub :: Integer
pub : IntVal priv :: Integer
priv : End Sequence : xs2 :: [ASN1]
xs2 ->
                let params :: Params
params = Params :: Integer -> Integer -> Integer -> Params
DSA.Params { params_p :: Integer
DSA.params_p = Integer
p, params_g :: Integer
DSA.params_g = Integer
g, params_q :: Integer
DSA.params_q = Integer
q }
                 in (KeyPair, [ASN1]) -> Either String (KeyPair, [ASN1])
forall a b. b -> Either a b
Right (Params -> Integer -> Integer -> KeyPair
DSA.KeyPair Params
params Integer
pub Integer
priv, [ASN1]
xs2)
            (Start Sequence
             : OID [1, 2, 840, 10040, 4, 1]
             : Start Sequence
             : IntVal p :: Integer
p
             : IntVal q :: Integer
q
             : IntVal g :: Integer
g
             : End Sequence
             : End Sequence
             : OctetString bs :: ByteString
bs
             : End Sequence
             : xs2 :: [ASN1]
xs2) ->
                let params :: Params
params = Params :: Integer -> Integer -> Integer -> Params
DSA.Params { params_p :: Integer
DSA.params_p = Integer
p, params_g :: Integer
DSA.params_g = Integer
g, params_q :: Integer
DSA.params_q = Integer
q }
                 in case BER -> ByteString -> Either ASN1Error [ASN1]
forall a.
ASN1Decoding a =>
a -> ByteString -> Either ASN1Error [ASN1]
decodeASN1' BER
BER ByteString
bs of
                        Right [IntVal priv :: Integer
priv] ->
                            let pub :: Integer
pub = Params -> Integer -> Integer
DSA.calculatePublic Params
params Integer
priv
                             in (KeyPair, [ASN1]) -> Either String (KeyPair, [ASN1])
forall a b. b -> Either a b
Right (Params -> Integer -> Integer -> KeyPair
DSA.KeyPair Params
params Integer
pub Integer
priv, [ASN1]
xs2)
                        Right _ -> String -> Either String (KeyPair, [ASN1])
forall a b. a -> Either a b
Left "dsaFromASN1: DSA.PrivateKey: unexpected format"
                        Left  e :: ASN1Error
e -> String -> Either String (KeyPair, [ASN1])
forall a b. a -> Either a b
Left (String -> Either String (KeyPair, [ASN1]))
-> String -> Either String (KeyPair, [ASN1])
forall a b. (a -> b) -> a -> b
$ "dsaFromASN1: DSA.PrivateKey: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ ASN1Error -> String
forall a. Show a => a -> String
show ASN1Error
e
            _ ->
                String -> Either String (KeyPair, [ASN1])
forall a b. a -> Either a b
Left "dsaFromASN1: DSA.KeyPair: invalid format (version=0)"
dsaFromASN1 _ = String -> Either String (KeyPair, [ASN1])
forall a b. a -> Either a b
Left "dsaFromASN1: DSA.KeyPair: unexpected format"

ecdsaFromASN1 :: [ASN1] -> [ASN1] -> Either String (X509.PrivKeyEC, [ASN1])
ecdsaFromASN1 :: [ASN1] -> [ASN1] -> Either String (PrivKeyEC, [ASN1])
ecdsaFromASN1 curveOid1 :: [ASN1]
curveOid1 (Start Sequence
                         : IntVal 1
                         : OctetString ds :: ByteString
ds
                         : xs :: [ASN1]
xs) = do
    let (curveOid2 :: [ASN1]
curveOid2, ys :: [ASN1]
ys) = ASN1Tag -> [ASN1] -> ([ASN1], [ASN1])
containerWithTag 0 [ASN1]
xs
    PrivKeyEC
privKey <- Integer -> [ASN1] -> Either String PrivKeyEC
getPrivKeyEC (ByteString -> Integer
forall ba. ByteArrayAccess ba => ba -> Integer
os2ip ByteString
ds) ([ASN1]
curveOid2 [ASN1] -> [ASN1] -> [ASN1]
forall a. [a] -> [a] -> [a]
++ [ASN1]
curveOid1)
    case ASN1Tag -> [ASN1] -> ([ASN1], [ASN1])
containerWithTag 1 [ASN1]
ys of
        (_, End Sequence : zs :: [ASN1]
zs) -> (PrivKeyEC, [ASN1]) -> Either String (PrivKeyEC, [ASN1])
forall (m :: * -> *) a. Monad m => a -> m a
return (PrivKeyEC
privKey, [ASN1]
zs)
        _                      -> String -> Either String (PrivKeyEC, [ASN1])
forall a b. a -> Either a b
Left "ecdsaFromASN1: unexpected EC format"
ecdsaFromASN1 curveOid1 :: [ASN1]
curveOid1 (Start Sequence
                         : IntVal 0
                         : Start Sequence
                         : OID [1, 2, 840, 10045, 2, 1]
                         : xs :: [ASN1]
xs) =
    let strError :: ASN1Error -> Either String b
strError = String -> Either String b
forall a b. a -> Either a b
Left (String -> Either String b)
-> (ASN1Error -> String) -> ASN1Error -> Either String b
forall b c a. (b -> c) -> (a -> b) -> a -> c
.  ("ecdsaFromASN1: ECDSA.PrivateKey: " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (ASN1Error -> String) -> ASN1Error -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Error -> String
forall a. Show a => a -> String
show
        (curveOid2 :: [ASN1]
curveOid2, ys :: [ASN1]
ys) = ASN1Tag -> [ASN1] -> ([ASN1], [ASN1])
getConstructedEnd 0 [ASN1]
xs
     in case [ASN1]
ys of
            (OctetString bs :: ByteString
bs
             : zs :: [ASN1]
zs) -> do
                let curveOids :: [ASN1]
curveOids = [ASN1]
curveOid2 [ASN1] -> [ASN1] -> [ASN1]
forall a. [a] -> [a] -> [a]
++ [ASN1]
curveOid1
                    inner :: Either String (PrivKeyEC, [ASN1])
inner = (ASN1Error -> Either String (PrivKeyEC, [ASN1]))
-> ([ASN1] -> Either String (PrivKeyEC, [ASN1]))
-> Either ASN1Error [ASN1]
-> Either String (PrivKeyEC, [ASN1])
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ASN1Error -> Either String (PrivKeyEC, [ASN1])
forall b. ASN1Error -> Either String b
strError ([ASN1] -> [ASN1] -> Either String (PrivKeyEC, [ASN1])
ecdsaFromASN1 [ASN1]
curveOids) (BER -> ByteString -> Either ASN1Error [ASN1]
forall a.
ASN1Decoding a =>
a -> ByteString -> Either ASN1Error [ASN1]
decodeASN1' BER
BER ByteString
bs)
                (String -> Either String (PrivKeyEC, [ASN1]))
-> ((PrivKeyEC, [ASN1]) -> Either String (PrivKeyEC, [ASN1]))
-> Either String (PrivKeyEC, [ASN1])
-> Either String (PrivKeyEC, [ASN1])
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> Either String (PrivKeyEC, [ASN1])
forall a b. a -> Either a b
Left (\(k :: PrivKeyEC
k, _) -> (PrivKeyEC, [ASN1]) -> Either String (PrivKeyEC, [ASN1])
forall a b. b -> Either a b
Right (PrivKeyEC
k, [ASN1]
zs)) Either String (PrivKeyEC, [ASN1])
inner
            _      -> String -> Either String (PrivKeyEC, [ASN1])
forall a b. a -> Either a b
Left "ecdsaFromASN1: unexpected format"
ecdsaFromASN1 _ _ =
    String -> Either String (PrivKeyEC, [ASN1])
forall a b. a -> Either a b
Left "ecdsaFromASN1: unexpected format"

getPrivKeyEC :: ECDSA.PrivateNumber -> [ASN1] -> Either String X509.PrivKeyEC
getPrivKeyEC :: Integer -> [ASN1] -> Either String PrivKeyEC
getPrivKeyEC _ []                 = String -> Either String PrivKeyEC
forall a b. a -> Either a b
Left "ecdsaFromASN1: curve is missing"
getPrivKeyEC d :: Integer
d (OID curveOid :: OID
curveOid : _) =
    case OID -> Maybe CurveName
X509.lookupCurveNameByOID OID
curveOid of
        Just name :: CurveName
name -> PrivKeyEC -> Either String PrivKeyEC
forall a b. b -> Either a b
Right PrivKeyEC_Named :: CurveName -> Integer -> PrivKeyEC
X509.PrivKeyEC_Named { privkeyEC_name :: CurveName
X509.privkeyEC_name = CurveName
name
                                                , privkeyEC_priv :: Integer
X509.privkeyEC_priv = Integer
d
                                                }
        Nothing   -> String -> Either String PrivKeyEC
forall a b. a -> Either a b
Left ("ecdsaFromASN1: unknown curve " String -> String -> String
forall a. [a] -> [a] -> [a]
++ OID -> String
forall a. Show a => a -> String
show OID
curveOid)
getPrivKeyEC d :: Integer
d (Null : xs :: [ASN1]
xs)        = Integer -> [ASN1] -> Either String PrivKeyEC
getPrivKeyEC Integer
d [ASN1]
xs
getPrivKeyEC d :: Integer
d (Start Sequence
                : IntVal 1
                : Start Sequence
                : OID [1, 2, 840, 10045, 1, 1]
                : IntVal prime :: Integer
prime
                : End Sequence
                : Start Sequence
                : OctetString a :: ByteString
a
                : OctetString b :: ByteString
b
                : BitString seed :: BitArray
seed
                : End Sequence
                : OctetString generator :: ByteString
generator
                : IntVal order :: Integer
order
                : IntVal cofactor :: Integer
cofactor
                : End Sequence
                : _)              =
    PrivKeyEC -> Either String PrivKeyEC
forall a b. b -> Either a b
Right PrivKeyEC_Prime :: Integer
-> Integer
-> Integer
-> Integer
-> SerializedPoint
-> Integer
-> Integer
-> Integer
-> PrivKeyEC
X509.PrivKeyEC_Prime
              { privkeyEC_priv :: Integer
X509.privkeyEC_priv      = Integer
d
              , privkeyEC_a :: Integer
X509.privkeyEC_a         = ByteString -> Integer
forall ba. ByteArrayAccess ba => ba -> Integer
os2ip ByteString
a
              , privkeyEC_b :: Integer
X509.privkeyEC_b         = ByteString -> Integer
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      = ByteString -> Integer
forall ba. ByteArrayAccess ba => ba -> Integer
os2ip (ByteString -> Integer) -> ByteString -> Integer
forall a b. (a -> b) -> a -> b
$ BitArray -> ByteString
bitArrayGetData BitArray
seed
              }
getPrivKeyEC _ _                  = String -> Either String PrivKeyEC
forall a b. a -> Either a b
Left "ecdsaFromASN1: unexpected curve format"

containerWithTag :: ASN1Tag -> [ASN1] -> ([ASN1], [ASN1])
containerWithTag :: ASN1Tag -> [ASN1] -> ([ASN1], [ASN1])
containerWithTag etag :: ASN1Tag
etag (Start (Container _ atag :: ASN1Tag
atag) : xs :: [ASN1]
xs)
    | ASN1Tag
etag ASN1Tag -> ASN1Tag -> Bool
forall a. Eq a => a -> a -> Bool
== ASN1Tag
atag = ASN1Tag -> [ASN1] -> ([ASN1], [ASN1])
getConstructedEnd 0 [ASN1]
xs
containerWithTag _    xs :: [ASN1]
xs = ([], [ASN1]
xs)

rsaFromASN1 :: [ASN1] -> Either String (RSA.PrivateKey, [ASN1])
rsaFromASN1 :: [ASN1] -> Either String (PrivateKey, [ASN1])
rsaFromASN1 (Start Sequence
             : IntVal 0
             : IntVal n :: Integer
n
             : IntVal e :: Integer
e
             : IntVal d :: Integer
d
             : IntVal p1 :: Integer
p1
             : IntVal p2 :: Integer
p2
             : IntVal pexp1 :: Integer
pexp1
             : IntVal pexp2 :: Integer
pexp2
             : IntVal pcoef :: Integer
pcoef
             : End Sequence
             : xs :: [ASN1]
xs) = (PrivateKey, [ASN1]) -> Either String (PrivateKey, [ASN1])
forall a b. b -> Either a b
Right (PrivateKey
privKey, [ASN1]
xs)
  where
    calculate_modulus :: t -> t -> t
calculate_modulus m :: t
m i :: t
i = if (2 t -> t -> t
forall a b. (Num a, Integral b) => a -> b -> a
^ (t
i t -> t -> t
forall a. Num a => a -> a -> a
* 8)) t -> t -> Bool
forall a. Ord a => a -> a -> Bool
> t
m then t
i else t -> t -> t
calculate_modulus t
m (t
it -> t -> t
forall a. Num a => a -> a -> a
+1)
    pubKey :: PublicKey
pubKey  = PublicKey :: ASN1Tag -> Integer -> Integer -> PublicKey
RSA.PublicKey { public_size :: ASN1Tag
RSA.public_size = Integer -> ASN1Tag -> ASN1Tag
forall t t. (Integral t, Num t, Ord t) => t -> t -> t
calculate_modulus Integer
n 1
                            , public_n :: Integer
RSA.public_n    = Integer
n
                            , public_e :: Integer
RSA.public_e    = Integer
e
                            }
    privKey :: PrivateKey
privKey = PrivateKey :: PublicKey
-> Integer
-> Integer
-> Integer
-> Integer
-> Integer
-> Integer
-> PrivateKey
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
                             }

rsaFromASN1 ( Start Sequence
             : IntVal 0
             : Start Sequence
             : OID [1, 2, 840, 113549, 1, 1, 1]
             : Null
             : End Sequence
             : OctetString bs :: ByteString
bs
             : xs :: [ASN1]
xs) =
    let inner :: Either String (PrivateKey, [ASN1])
inner = (ASN1Error -> Either String (PrivateKey, [ASN1]))
-> ([ASN1] -> Either String (PrivateKey, [ASN1]))
-> Either ASN1Error [ASN1]
-> Either String (PrivateKey, [ASN1])
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ASN1Error -> Either String (PrivateKey, [ASN1])
forall b. ASN1Error -> Either String b
strError [ASN1] -> Either String (PrivateKey, [ASN1])
rsaFromASN1 (Either ASN1Error [ASN1] -> Either String (PrivateKey, [ASN1]))
-> Either ASN1Error [ASN1] -> Either String (PrivateKey, [ASN1])
forall a b. (a -> b) -> a -> b
$ BER -> ByteString -> Either ASN1Error [ASN1]
forall a.
ASN1Decoding a =>
a -> ByteString -> Either ASN1Error [ASN1]
decodeASN1' BER
BER ByteString
bs
        strError :: ASN1Error -> Either String b
strError = String -> Either String b
forall a b. a -> Either a b
Left (String -> Either String b)
-> (ASN1Error -> String) -> ASN1Error -> Either String b
forall b c a. (b -> c) -> (a -> b) -> a -> c
.  ("rsaFromASN1: RSA.PrivateKey: " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (ASN1Error -> String) -> ASN1Error -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASN1Error -> String
forall a. Show a => a -> String
show
     in (String -> Either String (PrivateKey, [ASN1]))
-> ((PrivateKey, [ASN1]) -> Either String (PrivateKey, [ASN1]))
-> Either String (PrivateKey, [ASN1])
-> Either String (PrivateKey, [ASN1])
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> Either String (PrivateKey, [ASN1])
forall a b. a -> Either a b
Left (\(k :: PrivateKey
k, _) -> (PrivateKey, [ASN1]) -> Either String (PrivateKey, [ASN1])
forall a b. b -> Either a b
Right (PrivateKey
k, [ASN1]
xs)) Either String (PrivateKey, [ASN1])
inner
rsaFromASN1 _ =
    String -> Either String (PrivateKey, [ASN1])
forall a b. a -> Either a b
Left "rsaFromASN1: unexpected format"