module Data.X509.Validation.Signature
( verifySignedSignature
, verifySignature
, SignatureVerification(..)
) where
import qualified Crypto.PubKey.RSA.PKCS15 as RSA
import qualified Crypto.PubKey.DSA as DSA
import qualified Crypto.Hash.SHA1 as SHA1
import Crypto.PubKey.HashDescr
import Data.ByteString (ByteString)
import Data.X509
import Data.ASN1.Types
data SignatureVerification =
SignaturePass
| SignatureFailed
| SignaturePubkeyMismatch
| SignatureUnimplemented
deriving (Show,Eq)
verifySignedSignature :: (Eq a, ASN1Object a) => SignedExact a -> PubKey -> SignatureVerification
verifySignedSignature signedObj pubKey =
verifySignature (signedAlg signed)
pubKey
(getSignedData signedObj)
(signedSignature signed)
where signed = getSigned signedObj
verifySignature :: SignatureALG
-> PubKey
-> ByteString
-> ByteString
-> SignatureVerification
verifySignature (SignatureALG_Unknown _) _ _ _ = SignatureUnimplemented
verifySignature (SignatureALG hashALG pubkeyALG) pubkey cdata signature
| pubkeyToAlg pubkey == pubkeyALG = case verifyF pubkey of
Nothing -> SignatureUnimplemented
Just f -> if f cdata signature
then SignaturePass
else SignatureFailed
| otherwise = SignaturePubkeyMismatch
where
toDescr HashMD2 = hashDescrMD2
toDescr HashMD5 = hashDescrMD5
toDescr HashSHA1 = hashDescrSHA1
toDescr HashSHA224 = hashDescrSHA224
toDescr HashSHA256 = hashDescrSHA256
toDescr HashSHA384 = hashDescrSHA384
toDescr HashSHA512 = hashDescrSHA512
verifyF (PubKeyRSA key) = Just $ RSA.verify (toDescr hashALG) key
verifyF (PubKeyDSA key)
| hashALG == HashSHA1 && False = Just $ \a -> DSA.verify SHA1.hash key (dsaToSignature a)
| otherwise = Nothing
verifyF _ = Nothing
dsaToSignature _ = DSA.Signature 0 0