{-# LANGUAGE LambdaCase, RecordWildCards, TypeApplications #-}
module Network.AWS.CloudFront.SignedCookies.Crypto.Internal
( rsaPrivateKeyFromASN1
) where
import Data.Bifunctor (first)
import Data.Semigroup ((<>))
import Data.ASN1.Types
import Data.ASN1.Encoding
import Data.ASN1.BinaryEncoding
import Data.ASN1.BitArray
import qualified Crypto.PubKey.RSA as RSA
rsaPrivateKeyFromASN1 :: [ASN1] -> Either String RSA.PrivateKey
rsaPrivateKeyFromASN1 =
\case
( Start Sequence
: IntVal version
: IntVal n
: IntVal e
: IntVal d
: IntVal p
: IntVal q
: IntVal dP
: IntVal dQ
: IntVal qinv
: End Sequence
: [] ) ->
case version of
0 -> Right (buildKey Params{..})
v -> Left $ "rsaPrivateKeyFromASN1: unexpected version " <>
show @Integer version
_ -> Left "rsaPrivateKeyFromASN1: unexpected format"
data Params =
Params
{ n :: Integer
, e :: Integer
, d :: Integer
, p :: Integer
, q :: Integer
, dP :: Integer
, dQ :: Integer
, qinv :: Integer
}
buildKey :: Params -> RSA.PrivateKey
buildKey Params{..} =
let
size = head [i | i <- [1..], 2 ^ (i * 8) > n]
pub = RSA.PublicKey
{ public_size = size
, public_n = n
, public_e = e
}
in
RSA.PrivateKey
{ RSA.private_pub = pub
, RSA.private_d = d
, RSA.private_p = p
, RSA.private_q = q
, RSA.private_dP = dP
, RSA.private_dQ = dQ
, RSA.private_qinv = qinv
}