ADCS and dedicated CRL-signing certificates

 We're seeing what appears to be random revocation checking failures on clients for certificates issued by our CA. The infrastructure is a 2-tier PKI with an OCSP defined on the issuing CA certificate and the CRL from the Root CA signed by a dedicated CRL-signing certificate (i.e. not the issuing cert).  

We´ve observed that in cases where the OCSP is reachable the revocation checking succeeds but even this seems to sometimes fail for the same CRL.


CAPI2 does not support using a dedicated CRL signing certificate, it only supports CRL's signed by the issuer of the certificate being validated.  CAPI2 *does* however support OCSP responses signed by a dedicated OCSP-signing certificate.

In your case the CRL check will always fail because the CRL isn't signed by the issuer, when using OCSP it will succeed as the OCSP response is signed by the dedicated OCSP-signing certificate.  As long as the OCSP check succeeds then the certificate validates and everything is fine and dandy.

However, if a revocation check request is made more than the magic number of 50 times (the default) for a specific issuer then the default behaviour is to switch to CRL instead and this will fail as the CRL isn't signed by the issuer of the CRL (which explains the seeming randomness of the failure).

So, in your case once the client has made more than 50 revocation checks for certificates issued by your CA (which will succeed) then it switches to CRL's (which will fail).  This will be locally on each client so you may see two clients side-by-side where one works and the other one fails because it has done more than 50 checks.  Rebooting the failing client will reset the magic number count and things will magically work again (until 50 checks have been made).

Simple, eh? :-)



In some cases, CryptoAPI may retrieve CRLs before OCSP URLs. This only occurs when one of the following two circumstances exist:

  • The number of cached OCSP responses for a specific certificate issuer exceeds the magic number defined in Group Policy. This number is 50 by default.
  • Group Policy is configured to prefer CRLs over OCSP for revocation checking.


When CryptoAPI must validate a certificate for revocation status, the following algorithm is used:

  1. If a stapled OCSP response that was returned by the TLS server or the DC is time valid, the stapled response is used to validate the certificate.
  2. If the certificate being validated only includes either OCSP or CRL information, then the URLs are processed in the order in which they are presented in the certificate.
  3. If both OCSP URLs and CDP URLs are present, the following routine is followed:
    1. The initial assumption is that OCSP is preferred over CRLs.
    2. When an OCSP response is cached, the URL is hashed and used as the prefix for the file name in the URL cache entry.
  4. The total number of cached OCSP responses from a single OCSP responder URL is calculated, and then compared to a predefined value known as the magic count. The default magic count value is 50.
    • If the number is less than or equal to the magic count, then the OCSP URLs are processed in the order dictated by the authority information access extension.
    • If the number of is greater than the magic count, then the CRL URLs are processed in the order dictated by the CRL distribution point extension.
    • If none of the OCSP URLs in the authority information access extension succeeds, then fall back to using CRLs.


The magic count value can be specified in the “CryptnetCachedOcspSwitchToCrlCount” DWORD value in the HKEY_LOCAL_MACHINESoftwarePoliciesMicrosoftSystemCertificatesChainEngineConfig registry key.  

Note: setting this to 0 uses the default of 50, if you want to turn off OCSP fetching then you need to use the Options DWORD and the CERT_CHAIN_OPTION_DISABLE_AIA_URL_RETRIEVAL flag (0x2).  See WinCrypt.h in the Platforms SDK for details.


Further details:

How Certificate Revocation Works

Optimizing the Revocation Experience

Installing the Platform SDK and Configuring Visual C++