x509-validation-1.5.2: X.509 Certificate and CRL validation

LicenseBSD-style
MaintainerVincent Hanquez <vincent@snarc.org>
Stabilityexperimental
Portabilityunknown
Safe HaskellNone
LanguageHaskell98

Data.X509.Validation

Contents

Description

X.509 Certificate checks and validations routines

Follows RFC5280 / RFC6818

Synopsis

Documentation

type ServiceID = (HostName, ByteString) Source

identification of the connection consisting of the fully qualified host name (e.g. www.example.com) and an optional suffix.

The suffix is not used by the validation process, but is used by the optional cache to identity certificate per service on a specific host. For example, one might have a different certificate on 2 differents ports (443 and 995) for the same host.

for TCP connection, it's recommended to use: :port, or :service for the suffix.

type HostName = String

Either a host name e.g., "haskell.org" or a numeric host address string consisting of a dotted decimal IPv4 address or an IPv6 address e.g., "192.168.0.1".

newtype Fingerprint Source

Fingerprint of a certificate

Constructors

Fingerprint ByteString 

Failed validation types

data FailedReason Source

Possible reason of certificate and chain failure

Constructors

UnknownCriticalExtension

certificate contains an unknown critical extension

Expired

validity ends before checking time

InFuture

validity starts after checking time

SelfSigned

certificate is self signed

UnknownCA

unknown Certificate Authority (CA)

NotAllowedToSign

certificate is not allowed to sign

NotAnAuthority

not a CA

AuthorityTooDeep

Violation of the optional Basic constraint's path length

NoCommonName

Certificate doesn't have any common name (CN)

InvalidName String

Invalid name in certificate

NameMismatch String

connection name and certificate do not match

InvalidWildcard

invalid wildcard in certificate

LeafKeyUsageNotAllowed

the requested key usage is not compatible with the leaf certificate's key usage

LeafKeyPurposeNotAllowed

the requested key purpose is not compatible with the leaf certificate's extended key usage

LeafNotV3

Only authorized an X509.V3 certificate as leaf certificate.

EmptyChain

empty chain of certificate

CacheSaysNo String

the cache explicitely denied this certificate

InvalidSignature SignatureFailure

signature failed

data SignatureFailure Source

Various failure possible during signature checking

Constructors

SignatureInvalid

signature doesn't verify

SignaturePubkeyMismatch

algorithm and public key mismatch, cannot proceed

SignatureUnimplemented

unimplemented signature algorithm

Validation configuration types

data ValidationChecks Source

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.

Constructors

ValidationChecks 

Fields

checkTimeValidity :: Bool

check time validity of every certificate in the chain. the make sure that current time is between each validity bounds in the certificate

checkAtTime :: Maybe DateTime

The time when the validity check happens. When set to Nothing, the current time will be used

checkStrictOrdering :: Bool

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.

checkCAConstraints :: Bool

Check that signing certificate got the CA basic constraint. this is absolutely not recommended to turn it off.

checkExhaustive :: Bool

Check the whole certificate chain without stopping at the first failure. Allow gathering a exhaustive list of failure reasons. if this is turn off, it's absolutely not safe to ignore a failed reason even it doesn't look serious (e.g. Expired) as other more serious checks would not have been performed.

checkLeafV3 :: Bool

Check that the leaf certificate is version 3. If disable, version 2 certificate is authorized in leaf position and key usage cannot be checked.

checkLeafKeyUsage :: [ExtKeyUsageFlag]

Check that the leaf certificate is authorized to be used for certain usage. If set to empty list no check are performed, otherwise all the flags is the list need to exists in the key usage extension. If the extension is not present, the check will pass and behave as if the certificate key is not restricted to any specific usage.

checkLeafKeyPurpose :: [ExtKeyUsagePurpose]

Check that the leaf certificate is authorized to be used for certain purpose. If set to empty list no check are performed, otherwise all the flags is the list need to exists in the extended key usage extension if present. If the extension is not present, then the check will pass and behave as if the certificate is not restricted to any specific purpose.

checkFQHN :: Bool

Check the top certificate names matching the fully qualified hostname (FQHN). it's not recommended to turn this check off, if no other name checks are performed.

data ValidationHooks Source

A set of hooks to manipulate the way the verification works.

BEWARE, it's easy to change behavior leading to compromised security.

Constructors

ValidationHooks 

Fields

hookMatchSubjectIssuer :: DistinguishedName -> Certificate -> Bool

check the the issuer DistinguishedName match the subject DistinguishedName of a certificate.

hookValidateTime :: DateTime -> Certificate -> [FailedReason]

validate that the parametrized time valide with the certificate in argument

hookValidateName :: HostName -> Certificate -> [FailedReason]

validate the certificate leaf name with the DNS named used to connect

hookFilterReason :: [FailedReason] -> [FailedReason]

user filter to modify the list of failure reasons

defaultChecks :: ValidationChecks Source

Default checks to perform

The default checks are: * Each certificate time is valid * CA constraints is enforced for signing certificate * Leaf certificate is X.509 v3 * Check that the FQHN match

defaultHooks :: ValidationHooks Source

Default hooks in the validation process

Validation

validate Source

Arguments

:: HashALG

the hash algorithm we want to use for hashing the leaf certificate

-> ValidationHooks

Hooks to use

-> ValidationChecks

Checks to do

-> CertificateStore

The trusted certificate store for CA

-> ValidationCache

the validation cache callbacks

-> ServiceID

identification of the connection

-> CertificateChain

the certificate chain we want to validate

-> IO [FailedReason]

the return failed reasons (empty list is no failure)

X509 validation

the function first interrogate the cache and if the validation fail, proper verification is done. If the verification pass, the add to cache callback is called.

validateDefault Source

Arguments

:: CertificateStore

The trusted certificate store for CA

-> ValidationCache

the validation cache callbacks

-> ServiceID

identification of the connection

-> CertificateChain

the certificate chain we want to validate

-> IO [FailedReason]

the return failed reasons (empty list is no failure)

Validate using the default hooks and checks and the SHA256 mechanism as hashing mechanism

getFingerprint Source

Arguments

:: (Show a, Eq a, ASN1Object a) 
=> SignedExact a

object to fingerprint

-> HashALG

algorithm to compute the fingerprint

-> Fingerprint

fingerprint in binary form

Get the fingerprint of the whole signed object using the hashing algorithm specified

Cache

Cache for validation

data ValidationCacheResult Source

The result of a cache query

Constructors

ValidationCachePass

cache allow this fingerprint to go through

ValidationCacheDenied String

cache denied this fingerprint for further validation

ValidationCacheUnknown

unknown fingerprint in cache

type ValidationCacheQueryCallback Source

Arguments

 = ServiceID

connection's identification

-> Fingerprint

fingerprint of the leaf certificate

-> Certificate

leaf certificate

-> IO ValidationCacheResult

return if the operation is succesful or not

Validation cache query callback type

type ValidationCacheAddCallback Source

Arguments

 = ServiceID

connection's identification

-> Fingerprint

fingerprint of the leaf certificate

-> Certificate

leaf certificate

-> IO () 

Validation cache callback type

data ValidationCache Source

All the callbacks needed for querying and adding to the cache.

Constructors

ValidationCache 

Fields

cacheQuery :: ValidationCacheQueryCallback

cache querying callback

cacheAdd :: ValidationCacheAddCallback

cache adding callback

Simple instances of cache mechanism

exceptionValidationCache :: [(ServiceID, Fingerprint)] -> ValidationCache Source

create a simple constant cache that list exceptions to the certification validation. Typically this is use to allow self-signed certificates for specific use, with out-of-bounds user checks.

No fingerprints will be added after the instance is created.

The underlying structure for the check is kept as a list, as usually the exception list will be short, but when the list go above a dozen exceptions it's recommended to use another cache mechanism with a faster lookup mechanism (hashtable, map, etc).

Note that only one fingerprint is allowed per ServiceID, for other use, another cache mechanism need to be use.

tofuValidationCache Source

Arguments

:: [(ServiceID, Fingerprint)]

a list of exceptions

-> IO ValidationCache 

Trust on first use (TOFU) cache with an optional list of exceptions

this is similar to the exceptionCache, except that after each succesfull validation it does add the fingerprint to the database. This prevent any further modification of the fingerprint for the remaining