module Network.AWS.CloudFront.SignedCookies.Crypto.Internal
( rsaPrivateKeyFromASN1
) where
import Data.ASN1.Types (ASN1 (End, IntVal, Start), ASN1ConstructionType (Sequence))
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
n :: Integer
e :: Integer
d :: Integer
p :: Integer
q :: Integer
dP :: Integer
dQ :: Integer
qinv :: Integer
n :: Integer
e :: Integer
d :: Integer
p :: Integer
q :: Integer
dP :: Integer
dQ :: Integer
qinv :: Integer
..})
Integer
_ -> 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
<>
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
n :: Params -> Integer
e :: Params -> Integer
d :: Params -> Integer
p :: Params -> Integer
q :: Params -> Integer
dP :: Params -> Integer
dQ :: Params -> Integer
qinv :: Params -> Integer
n :: Integer
e :: Integer
d :: Integer
p :: Integer
q :: Integer
dP :: Integer
dQ :: Integer
qinv :: Integer
..} =
let
size :: Int
size = [Int] -> Int
forall a. HasCallStack => [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 = RSA.PublicKey
{ public_size :: Int
public_size = Int
size
, public_n :: Integer
public_n = Integer
n
, public_e :: Integer
public_e = Integer
e
}
in
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
}