-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | X.509 Certificate and CRL validation
--   
--   X.509 Certificate and CRL validation
@package x509-validation
@version 1.6.8


-- | X.509 Certificate checks and validations routines
--   
--   Follows RFC5280 / RFC6818
module Data.X509.Validation

-- | 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 ServiceID = (HostName, ByteString)
type HostName = String

-- | Fingerprint of a certificate
newtype Fingerprint
Fingerprint :: ByteString -> Fingerprint

-- | Possible reason of certificate and chain failure.
--   
--   The values <a>InvalidName</a> and <a>InvalidWildcard</a> are
--   internal-only and are never returned by the validation functions.
--   <a>NameMismatch</a> is returned instead.
data FailedReason

-- | certificate contains an unknown critical extension
UnknownCriticalExtension :: FailedReason

-- | validity ends before checking time
Expired :: FailedReason

-- | validity starts after checking time
InFuture :: FailedReason

-- | certificate is self signed
SelfSigned :: FailedReason

-- | unknown Certificate Authority (CA)
UnknownCA :: FailedReason

-- | certificate is not allowed to sign
NotAllowedToSign :: FailedReason

-- | not a CA
NotAnAuthority :: FailedReason

-- | Violation of the optional Basic constraint's path length
AuthorityTooDeep :: FailedReason

-- | Certificate doesn't have any common name (CN)
NoCommonName :: FailedReason

-- | Invalid name in certificate
InvalidName :: String -> FailedReason

-- | connection name and certificate do not match
NameMismatch :: String -> FailedReason

-- | invalid wildcard in certificate
InvalidWildcard :: FailedReason

-- | the requested key usage is not compatible with the leaf certificate's
--   key usage
LeafKeyUsageNotAllowed :: FailedReason

-- | the requested key purpose is not compatible with the leaf
--   certificate's extended key usage
LeafKeyPurposeNotAllowed :: FailedReason

-- | Only authorized an X509.V3 certificate as leaf certificate.
LeafNotV3 :: FailedReason

-- | empty chain of certificate
EmptyChain :: FailedReason

-- | the cache explicitely denied this certificate
CacheSaysNo :: String -> FailedReason

-- | signature failed
InvalidSignature :: SignatureFailure -> FailedReason

-- | Various failure possible during signature checking
data SignatureFailure

-- | signature doesn't verify
SignatureInvalid :: SignatureFailure

-- | algorithm and public key mismatch, cannot proceed
SignaturePubkeyMismatch :: SignatureFailure

-- | unimplemented signature algorithm
SignatureUnimplemented :: SignatureFailure

-- | A set of checks to activate or parametrize to perform on certificates.
--   
--   It's recommended to use <a>defaultChecks</a> to create the structure,
--   to better cope with future changes or expansion of the structure.
data ValidationChecks
ValidationChecks :: Bool -> Maybe DateTime -> Bool -> Bool -> Bool -> Bool -> [ExtKeyUsageFlag] -> [ExtKeyUsagePurpose] -> Bool -> ValidationChecks

-- | check time validity of every certificate in the chain. the make sure
--   that current time is between each validity bounds in the certificate
[checkTimeValidity] :: ValidationChecks -> Bool

-- | The time when the validity check happens. When set to Nothing, the
--   current time will be used
[checkAtTime] :: ValidationChecks -> Maybe DateTime

-- | 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.
[checkStrictOrdering] :: ValidationChecks -> Bool

-- | Check that signing certificate got the CA basic constraint. this is
--   absolutely not recommended to turn it off.
[checkCAConstraints] :: ValidationChecks -> 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.
[checkExhaustive] :: ValidationChecks -> 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.
[checkLeafV3] :: ValidationChecks -> Bool

-- | 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.
[checkLeafKeyUsage] :: ValidationChecks -> [ExtKeyUsageFlag]

-- | 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.
[checkLeafKeyPurpose] :: ValidationChecks -> [ExtKeyUsagePurpose]

-- | 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.
[checkFQHN] :: ValidationChecks -> Bool

-- | A set of hooks to manipulate the way the verification works.
--   
--   BEWARE, it's easy to change behavior leading to compromised security.
data ValidationHooks
ValidationHooks :: (DistinguishedName -> Certificate -> Bool) -> (DateTime -> Certificate -> [FailedReason]) -> (HostName -> Certificate -> [FailedReason]) -> ([FailedReason] -> [FailedReason]) -> ValidationHooks

-- | check whether a given issuer <a>DistinguishedName</a> matches the
--   subject <a>DistinguishedName</a> of a candidate issuer certificate.
[hookMatchSubjectIssuer] :: ValidationHooks -> DistinguishedName -> Certificate -> Bool

-- | check whether the certificate in the second argument is valid at the
--   time provided in the first argument. Return an empty list for success
--   or else one or more failure reasons.
[hookValidateTime] :: ValidationHooks -> DateTime -> Certificate -> [FailedReason]

-- | validate the certificate leaf name with the DNS named used to connect
[hookValidateName] :: ValidationHooks -> HostName -> Certificate -> [FailedReason]

-- | user filter to modify the list of failure reasons
[hookFilterReason] :: ValidationHooks -> [FailedReason] -> [FailedReason]

-- | 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
defaultChecks :: ValidationChecks

-- | Default hooks in the validation process
defaultHooks :: ValidationHooks

-- | 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.
validate :: HashALG -> ValidationHooks -> ValidationChecks -> CertificateStore -> ValidationCache -> ServiceID -> CertificateChain -> IO [FailedReason]

-- | Validate using the default hooks and checks and the SHA256 mechanism
--   as hashing mechanism
validateDefault :: CertificateStore -> ValidationCache -> ServiceID -> CertificateChain -> IO [FailedReason]

-- | Get the fingerprint of the whole signed object using the hashing
--   algorithm specified
getFingerprint :: (Show a, Eq a, ASN1Object a) => SignedExact a -> HashALG -> Fingerprint

-- | The result of a cache query
data ValidationCacheResult

-- | cache allow this fingerprint to go through
ValidationCachePass :: ValidationCacheResult

-- | cache denied this fingerprint for further validation
ValidationCacheDenied :: String -> ValidationCacheResult

-- | unknown fingerprint in cache
ValidationCacheUnknown :: ValidationCacheResult

-- | Validation cache query callback type
type ValidationCacheQueryCallback = 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 callback type
type ValidationCacheAddCallback = ServiceID  connection's identification -> Fingerprint  fingerprint of the leaf certificate -> Certificate  leaf certificate -> IO ()

-- | All the callbacks needed for querying and adding to the cache.
data ValidationCache
ValidationCache :: ValidationCacheQueryCallback -> ValidationCacheAddCallback -> ValidationCache

-- | cache querying callback
[cacheQuery] :: ValidationCache -> ValidationCacheQueryCallback

-- | cache adding callback
[cacheAdd] :: ValidationCache -> ValidationCacheAddCallback

-- | 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.
exceptionValidationCache :: [(ServiceID, Fingerprint)] -> 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
tofuValidationCache :: [(ServiceID, Fingerprint)] -> IO ValidationCache
instance GHC.Classes.Eq Data.X509.Validation.ValidationChecks
instance GHC.Show.Show Data.X509.Validation.ValidationChecks
instance GHC.Classes.Eq Data.X509.Validation.FailedReason
instance GHC.Show.Show Data.X509.Validation.FailedReason
instance Data.Default.Class.Default Data.X509.Validation.ValidationChecks
instance Data.Default.Class.Default Data.X509.Validation.ValidationHooks
