x509-validation 1.4.1 → 1.4.2
raw patch · 4 files changed
+65/−16 lines, 4 filesdep +asn1-encodingdep ~asn1-typesdep ~crypto-pubkeydep ~crypto-pubkey-types
Dependencies added: asn1-encoding
Dependency ranges changed: asn1-types, crypto-pubkey, crypto-pubkey-types, cryptohash, x509, x509-store
Files
- Data/X509/Validation.hs +8/−2
- Data/X509/Validation/Fingerprint.hs +36/−0
- Data/X509/Validation/Signature.hs +17/−12
- x509-validation.cabal +4/−2
Data/X509/Validation.hs view
@@ -16,6 +16,7 @@ , defaultChecks , validate , validateWith+ , getFingerprint ) where import Control.Applicative@@ -23,6 +24,7 @@ import Data.X509 import Data.X509.CertificateStore import Data.X509.Validation.Signature+import Data.X509.Validation.Fingerprint import Data.Time.Clock import Data.Maybe import Data.List@@ -44,13 +46,17 @@ | EmptyChain -- ^ empty chain of certificate deriving (Show,Eq) +-- | A set of checks to activate or parametrize to perform on certificates.+--+-- It's recommended to use 'defaultChecks' to create the structure,+-- to better cope with future changes or expansion of the structure. data Checks = Checks { -- | check time validity of every certificate in the chain. -- the make sure that current time is between each validity bounds -- in the certificate checkTimeValidity :: Bool- -- | Check that no certificate is included that doesn't+ -- | Check that no certificate is included that shouldn't be included. -- unfortunately despite the specification violation, a lots of -- real world server serves useless and usually old certificates -- that are not relevant to the certificate sent, in their chain.@@ -105,7 +111,7 @@ -- check if we have a trusted certificate in the store belonging to this issuer. return r |> (case findCertificate (certIssuerDN cert) store of Just trustedSignedCert -> return $ checkSignature current trustedSignedCert- Nothing | isSelfSigned cert -> return [SelfSigned]+ Nothing | isSelfSigned cert -> return [SelfSigned] |> return (checkSignature current current) | null chain -> return [UnknownCA] | otherwise -> case findIssuer (certIssuerDN cert) chain of
+ Data/X509/Validation/Fingerprint.hs view
@@ -0,0 +1,36 @@+-- |+-- Module : Data.X509.Validation.Fingerprint+-- License : BSD-style+-- Maintainer : Vincent Hanquez <vincent@snarc.org>+-- Stability : experimental+-- Portability : unknown+--+module Data.X509.Validation.Fingerprint+ ( getFingerprint+ , toDescr+ ) where++import Crypto.PubKey.HashDescr+import Data.X509+import Data.ASN1.Types+import Data.ByteString (ByteString)++-- | Get the fingerprint of the whole signed object+-- using the hashing algorithm specified+getFingerprint :: (Show a, Eq a, ASN1Object a)+ => SignedExact a -- ^ object to fingerprint+ -> HashALG -- ^ algorithm to compute the fingerprint+ -> ByteString -- ^ fingerprint in binary form+getFingerprint sobj halg = hashF $ encodeSignedObject sobj+ where hashDescr = toDescr halg+ hashF = hashFunction hashDescr++-- | Convert a hash algorithm into a Hash Description+toDescr :: HashALG -> HashDescr+toDescr HashMD2 = hashDescrMD2+toDescr HashMD5 = hashDescrMD5+toDescr HashSHA1 = hashDescrSHA1+toDescr HashSHA224 = hashDescrSHA224+toDescr HashSHA256 = hashDescrSHA256+toDescr HashSHA384 = hashDescrSHA384+toDescr HashSHA512 = hashDescrSHA512
Data/X509/Validation/Signature.hs view
@@ -16,11 +16,13 @@ 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.X509.Validation.Fingerprint import Data.ASN1.Types+import Data.ASN1.Encoding+import Data.ASN1.BinaryEncoding -- | A set of possible return from signature verification. --@@ -37,7 +39,10 @@ deriving (Show,Eq) -- | Verify a Signed object against a specified public key-verifySignedSignature :: (Eq a, ASN1Object a) => SignedExact a -> PubKey -> SignatureVerification+verifySignedSignature :: (Show a, Eq a, ASN1Object a)+ => SignedExact a+ -> PubKey+ -> SignatureVerification verifySignedSignature signedObj pubKey = verifySignature (signedAlg signed) pubKey@@ -60,19 +65,19 @@ 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)+ | hashALG == HashSHA1 = Just $ \a b -> case dsaToSignature a of+ Nothing -> False+ Just dsaSig -> DSA.verify SHA1.hash key dsaSig b | otherwise = Nothing verifyF _ = Nothing - -- TODO : need to work out how to get R/S from the bytestring- dsaToSignature _ = DSA.Signature 0 0+ dsaToSignature :: ByteString -> Maybe DSA.Signature+ dsaToSignature b =+ case decodeASN1' BER b of+ Left _ -> Nothing+ Right asn1 -> case fromASN1 asn1 of+ Left _ -> Nothing+ Right (dsaSig, _) -> Just dsaSig
x509-validation.cabal view
@@ -1,5 +1,5 @@ Name: x509-validation-Version: 1.4.1+Version: 1.4.2 Description: X.509 Certificate and CRL validation License: BSD3 License-file: LICENSE@@ -19,7 +19,8 @@ , mtl , pem >= 0.1 && < 0.2 , asn1-types- , x509+ , asn1-encoding+ , x509 >= 1.4.2 , x509-store , crypto-pubkey >= 0.1.4 , crypto-pubkey-types >= 0.4.0@@ -31,6 +32,7 @@ , time Exposed-modules: Data.X509.Validation Other-modules: Data.X509.Validation.Signature+ Data.X509.Validation.Fingerprint ghc-options: -Wall source-repository head