-- | -- Module : Data.Certificate.Key -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- Read/Write Private Key -- module Data.Certificate.KeyDSA ( decodePrivate , encodePrivate ) where import Data.ASN1.Stream import Data.ASN1.Encoding import Data.ASN1.BinaryEncoding import qualified Data.ByteString.Lazy as L import qualified Crypto.Types.PubKey.DSA as DSA parsePrivate :: [ASN1] -> Either String (DSA.PublicKey, DSA.PrivateKey) parsePrivate [ Start Sequence , IntVal 0, IntVal p, IntVal q, IntVal g, IntVal pub, IntVal priv , End Sequence ] = Right (pubkey, privkey) where privkey = DSA.PrivateKey { DSA.private_params = params, DSA.private_x = priv } pubkey = DSA.PublicKey { DSA.public_params = params, DSA.public_y = pub } params = DSA.Params { DSA.params_p = p, DSA.params_g = g, DSA.params_q = q } parsePrivate (Start Sequence : IntVal n : _) | n == 0 = Left "DSA key format: not recognized" | otherwise = Left ("DSA key format: unknown version " ++ show n) parsePrivate _ = Left "unexpected format" decodePrivate :: L.ByteString -> Either String (DSA.PublicKey, DSA.PrivateKey) decodePrivate dat = either (Left . show) parsePrivate $ decodeASN1 BER dat encodePrivate :: (DSA.PublicKey, DSA.PrivateKey) -> L.ByteString encodePrivate (pubkey, privkey) = encodeASN1 DER pkseq where pkseq = [ Start Sequence , IntVal 0 , IntVal $ DSA.params_p params , IntVal $ DSA.params_q params , IntVal $ DSA.params_g params , IntVal $ DSA.public_y pubkey , IntVal $ DSA.private_x privkey , End Sequence ] params = DSA.private_params privkey