module Data.Certificate.KeyRSA
( Private(..)
, decodePrivate
, encodePrivate
) where
import Data.ASN1.DER (encodeASN1Stream, ASN1(..), ASN1ConstructionType(..))
import Data.ASN1.BER (decodeASN1Stream)
import qualified Data.ByteString.Lazy as L
data Private = Private
{ version :: Int
, lenmodulus :: Int
, modulus :: Integer
, public_exponant :: Integer
, private_exponant :: Integer
, p1 :: Integer
, p2 :: Integer
, exp1 :: Integer
, exp2 :: Integer
, coef :: Integer
}
parsePrivate :: [ASN1] -> Either String Private
parsePrivate
[ Start Sequence
, IntVal ver, IntVal p_modulus, IntVal pub_exp
, IntVal priv_exp, IntVal p_p1, IntVal p_p2
, IntVal p_exp1, IntVal p_exp2, IntVal p_coef
, End Sequence ] =
Right $ Private
{ version = fromIntegral ver
, lenmodulus = calculate_modulus p_modulus 1
, modulus = p_modulus
, public_exponant = pub_exp
, private_exponant = priv_exp
, p1 = p_p1
, p2 = p_p2
, exp1 = p_exp1
, exp2 = p_exp2
, coef = p_coef
}
where
calculate_modulus n i = if (2 ^ (i * 8)) > n then i else calculate_modulus n (i+1)
parsePrivate _ = Left "unexpected format"
decodePrivate :: L.ByteString -> Either String Private
decodePrivate dat = either (Left . show) parsePrivate $ decodeASN1Stream dat
encodePrivate :: Private -> L.ByteString
encodePrivate pk =
case encodeASN1Stream pkseq of
Left err -> error $ show err
Right lbs -> lbs
where pkseq =
[ Start Sequence
, IntVal $ fromIntegral $ version pk
, IntVal $ modulus pk
, IntVal $ public_exponant pk
, IntVal $ private_exponant pk
, IntVal $ p1 pk
, IntVal $ p2 pk
, IntVal $ exp1 pk
, IntVal $ exp2 pk
, IntVal $ fromIntegral $ coef pk
, End Sequence
]