{-# 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 :: [ASN1] -> Either String PrivateKey
rsaPrivateKeyFromASN1 =
\case
( Start ASN1ConstructionType
Sequence
: IntVal Integer
version
: IntVal Integer
n
: IntVal Integer
e
: IntVal Integer
d
: IntVal Integer
p
: IntVal Integer
q
: IntVal Integer
dP
: IntVal Integer
dQ
: IntVal Integer
qinv
: End ASN1ConstructionType
Sequence
: [] ) ->
case Integer
version of
Integer
0 -> PrivateKey -> Either String PrivateKey
forall a b. b -> Either a b
Right (Params -> PrivateKey
buildKey Params :: Integer
-> Integer
-> Integer
-> Integer
-> Integer
-> Integer
-> Integer
-> Integer
-> Params
Params{Integer
qinv :: Integer
dQ :: Integer
dP :: Integer
q :: Integer
p :: Integer
d :: Integer
e :: Integer
n :: Integer
qinv :: Integer
dQ :: Integer
dP :: Integer
q :: Integer
p :: Integer
d :: Integer
e :: Integer
n :: Integer
..})
Integer
v -> String -> Either String PrivateKey
forall a b. a -> Either a b
Left (String -> Either String PrivateKey)
-> String -> Either String PrivateKey
forall a b. (a -> b) -> a -> b
$ String
"rsaPrivateKeyFromASN1: unexpected version " String -> String -> String
forall a. Semigroup a => a -> a -> a
<>
Integer -> String
forall a. Show a => a -> String
show @Integer Integer
version
[ASN1]
_ -> String -> Either String PrivateKey
forall a b. a -> Either a b
Left String
"rsaPrivateKeyFromASN1: unexpected format"
data Params =
Params
{ Params -> Integer
n :: Integer
, Params -> Integer
e :: Integer
, Params -> Integer
d :: Integer
, Params -> Integer
p :: Integer
, Params -> Integer
q :: Integer
, Params -> Integer
dP :: Integer
, Params -> Integer
dQ :: Integer
, Params -> Integer
qinv :: Integer
}
buildKey :: Params -> RSA.PrivateKey
buildKey :: Params -> PrivateKey
buildKey Params{Integer
qinv :: Integer
dQ :: Integer
dP :: Integer
q :: Integer
p :: Integer
d :: Integer
e :: Integer
n :: Integer
qinv :: Params -> Integer
dQ :: Params -> Integer
dP :: Params -> Integer
q :: Params -> Integer
p :: Params -> Integer
d :: Params -> Integer
e :: Params -> Integer
n :: Params -> Integer
..} =
let
size :: Int
size = [Int] -> Int
forall a. [a] -> a
head [Int
i | Int
i <- [Int
1..], Integer
2 Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
8) Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
n]
pub :: PublicKey
pub = PublicKey :: Int -> Integer -> Integer -> PublicKey
RSA.PublicKey
{ public_size :: Int
public_size = Int
size
, public_n :: Integer
public_n = Integer
n
, public_e :: Integer
public_e = Integer
e
}
in
PrivateKey :: PublicKey
-> Integer
-> Integer
-> Integer
-> Integer
-> Integer
-> Integer
-> PrivateKey
RSA.PrivateKey
{ private_pub :: PublicKey
RSA.private_pub = PublicKey
pub
, private_d :: Integer
RSA.private_d = Integer
d
, private_p :: Integer
RSA.private_p = Integer
p
, private_q :: Integer
RSA.private_q = Integer
q
, private_dP :: Integer
RSA.private_dP = Integer
dP
, private_dQ :: Integer
RSA.private_dQ = Integer
dQ
, private_qinv :: Integer
RSA.private_qinv = Integer
qinv
}