HOWTO: Validation of X.509 certificates with SHA-2 signatures on .NET Compact Framework
As of today, all Rebex libraries still support .NET Compact Framework (as a legacy platform). Unfortunately, legacy versions of Windows CE / Windows Mobile operating systems, which are still used to run .NET CF applications, cannot handle X.509 certificates with SHA-2 signatures. This is a big issue because SHA-1 has been depreceated and trusted certification authorities no longer issue new SHA-1 certificates.
To address this major limitaton of legacy versions of Windows CE, we introduced a built-in replacement certificate validator in release 2016 R3 of Rebex libraries. It is enabled by default in all TLS/SSL and S/MIME enabled libraries such as Rebex FTP, Rebex IMAP, Rebex HTTPS, Rebex Telnet, and more.
Overview
When the signature of a certificate being validated utilizes SHA-256, SHA-384 or SHA-512 hashing algorithm and cannot be validated using Windows CryptoAPI, Rebex built-in validator is used instead. It's also used when the ValidationOptions.SkipRevocationCheck
has been specified because the OS doesn't support this option at all.
The validator performs all the necessary checks:
- Root trust
- Time integrity
- Chain integrity
- Signature validation
- Key usage validation
- Constraints validation
If all these checks (except time integrity) are passed, the revocation status of whole chain is determined. For each certificate:
- If the certificate supports Online Certificate Status Protocol (OCSP), the current OCSP response of the certificate is retrieved (from local cache or from the Internet).
- OCSP response integrity is validated with respect to issuing CA and current time
- Revocation status of the certificate is determined
- If the revocation status was not determined using OCSP, the current Certificate Revocation List (CRL) of the certificate is retrieved (from local cache or from the Internet).
- CRL integrity is validated with respect to issuing CA and current time.
- Revocation status of the certificate is determined.
CRL cache
When a CRL is downloaded, it is stored in the local CRL cache. The CRL cache uses system registry to store cached URLs and the local file system to store CRL data.
The CRL cache registry key is HKEY_CURRENT_USER\SOFTWARE\Rebex\CrlCache
. This key contains subkeys for each CRL.
Name of the sub-key represents URL from which the CRL was downloaded and value of each subkey is a GUID which represents
name of a file where the CRL was stored.
The CRL cache directory is \Program Files\Rebex\CrlCache
.
To clear the cache, just delete the contents of the registry key and the directory.
OCSP cache
When an OCSP response is retrieved, it is stored in the local OCSP cache. The OCSP cache uses system registry to store cached URLs and the local file system to store OCSP response data.
The OCSP cache registry key is HKEY_CURRENT_USER\SOFTWARE\Rebex\OcspCache
. This key contains subkeys for each OCSP response.
Name of the sub-key is URL#CERT_SERIAL_NO#ISSUER_NAME_HASH
,
where URL
represents URL from which the OCSP response was retrieved,
CERT_SERIAL_NO
represents serial number of the certificate being checked,
ISSUER_NAME_HASH
represents SHA-1 hash of the certificate's issuer distinguised name.
Value of each subkey is a GUID which represents name of a file where the OCSP response was stored.
The OCSP cache directory is \Program Files\Rebex\OcspCache
.
To clear the cache, just delete the contents of the registry key and the directory.
Unsupported features
The following ValidationOptions
are not currently supported by Rebex certificate validator:
AllowTestRoot
AllowUnknownCa
IgnoreCtlSignerRevUnknown
IgnoreCtlTimeNotValid
IgnoreInvalidBasicConstraints
IgnoreInvalidPolicy
TrustTestRoot
The following certificate extensions are not supported and a validation error is reported when a certificate chain with utilizing them (as critical extensions) is encountered:
- Name Constraints
- Policy Constraints
- Certificate Policies
- Policy Mappings
Using custom validator explicitly
Rebex enhanced built-in validator can be used for SHA-1 certificates as well - it is accessible through Rebex.Security.Certificates.CertificateEngine.Internal
object.
To make it the default validator, use it as the current certificate engine:
CertificateEngine.SetCurrentEngine(CertificateEngine.Internal);