How Certificate Revocation Works
Applies To: Windows 7, Windows Server 2008, Windows Server 2008 R2, Windows Vista
The following sections provide summaries of how certificate revocation checking works. The summaries include:
Basic Certificate Chain Validation
Validating Revocation Information
Network Retrieval and Caching
Basic Certificate Chain Validation
When CryptoAPI builds and validates a certificate chain, three distinct phases take place:
All possible certificate chains are built using locally cached certificates. If none of the certificate chains ends in a self-signed certificate, CryptoAPI then selects the best possible chain and attempt to retrieve issuer certificates specified in the authority information access extension to complete the chain. This process is repeated until a chain to a self-signed certificate is built.
For each chain that ends in a self-signed certificate in the trusted root store, revocation checking is performed.
Revocation checking is performed from the root CA certificate down to the evaluated certificate.
CryptoAPI attempts to build all possible certificate chains. Certificate will be collected from the following locations:
Certificates provided by the application. Some applications will include the ability to preload all certificates in their certificate chain and distribute the certificates to clients.
The set of certificates already cached in memory by the certificate validation engine (Crypt32.dll). Each process that uses Crypt32.dll may have one or more certificate validations executing, each with its own separate state and memory cache.
Local certificate stores including Group Policy. Certificates that are manually installed into the Trusted Root and Intermediate certificate stores (including those downloaded by Group Policy) can be used to build a certificate chain.
Certificates stored in the local disk cache by CryptoAPI.
Network Retrieval from locations specified in the authority information access extension. The URLs are only used if CryptoAPI cannot build a single chain that chains to a self-signed certificate from the previously mentioned certificate locations.
At the end of the process, CryptoAPI will compute and report error or information status based on the error and status codes.
After CryptoAPI starts validating the individual certificates in the presented certificate chain(s), the following checks are performed:
CryptoAPI determines whether the certificate is included in the Untrusted certificate store. All certificates in the Untrusted certificate store are explicitly designated as disallowed certificates.
If the certificate included a stapled OCSP response and the stapled response is time valid, use the stapled OCSP response to valid the revocation status of the certificate.
If a CRL with the matching issuer name and optionally the same IDP is already in the CA store, use that version of the CRL.
If a stapled response or previously downloaded CRL is not available, then CryptoAPI must attempt URL retrieval to determine the revocation status of the certificate.
The URLs for OCSP and CDP are built in the following order:
OCSP URLs from Group Policy
OCSP URLs from the authority information access extension
CRL URLs from the CDP extension
If delta CRLs are implemented, then base and delta CRL processing will continue using the same processes as described in Certificate Status and Revocation Checking (https://social.technet.microsoft.com/wiki/contents/articles/certificate-status-and-revocation-checking.aspx).
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.
Details on how CryptoAPI decides between using OCSP or CRLs for revocation status checking are discussed in the Determining Preference between OCSP and CRLs section later in this document.
Only Evaluate Chains that Terminate in a Trusted Root Certificate
After CryptoAPI builds a certificate chain up to a trusted root authority certificate, it will check for certificate revocation. The validation will continue from the root CA certificate to the entity certificate presented to the application. If there are multiple certificate chains that terminate in a trusted root authority certificate, then CryptoAPI will validate each chain until it finds a chain that is not revoked.
Validating Revocation Information
When CryptoAPI determines the revocation status of a certificate, it is done by either examining the CRL or the OCSP response. In both cases, if the certificate is revoked, the revocation date is determined by comparing the current date with the RevocationDate field in the CRL or the OCSP response.
Determining Preference between OCSP and CRLs
Although the default behavior in Windows Vista is to prefer OCSP URLs in the authority information access extension to CRL distribution point URLs, it is not realistic to assume that OCSP will always be preferred over CRLs.
It is possible that a single server has issued several certificates that must be validated in the same revocation period. In this scenario, it may be less bandwidth intensive to download the CRL at the beginning of the revocation period than to request an OCSP response every time a certificate issued by the CA is validated.
For example, a typical OCSP response is 2 kilobytes (KBs). If smart card logon is enabled, a domain controller will cache approximately 100 megabytes (MBs) of OCSP responses after validating 50,000 user certificates during the logon process. In comparison, a CRL with 50,000 entries would be approximately 4 MBs (based on an assumption of 80 bytes per entry).
When CryptoAPI must validate a certificate for revocation status, the following algorithm is used:
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.
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.
If both OCSP URLs and CDP URLs are present, the following routine is followed:
The initial assumption is that OCSP is preferred over CRLs.
When an OCSP response is cached, the URL is hashed and used as the prefix for the file name in the URL cache entry.
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_MACHINE\Software\Policies\Microsoft\SystemCertificates\ChainEngine\Config registry key.
CRL Specific Information
If the CRL contains an IDP extension, then IDP matching is used to determine whether the IDP name matches the CRL name.
If validated by a client that supports partitioned and indirect CRLs, the IDP extension enables the client to determine the necessary scope of a CRL when a CA certificate is renewed or re-keyed. For Windows Server CAs, the IDP extension can limit revocation information in a CRL to only end-entity certificates or to CA certificates. CryptoAPI does not support attribute certificates or partitioning CRLs by reason codes.
When the CRL is validated, the signature is checked to ensure that the signer used the same name and key as the certificate issuer.
OCSP Specific Information
The signature on OCSP responses must follow the following rules to be considered valid by a Windows Vista or Windows Server 2008 client:
For Windows Vista, either the OCSP signing certificate must be issued by the same CA as the certificate being verified or the OCSP response must be signed by the issuing CA.
For Windows Vista with Service Pack 1 and Windows Server 2008, the OCSP signing certificate may chain up to any trusted root CA as long as the certificate chain includes the OCSP Signing EKU extension.
CryptoAPI will not support independent OCSP signer during revocation checking on this OCSP signing certificate chain to avoid circular dependency. CryptoAPI will support CRL and delegated OCSP signer only.
We recommend that you enable the id-pkix-ocsp-nocheck (22.214.171.124.126.96.36.199.1.5) extension in the OCSP signing certificate so that no revocation checking is performed on the OCSP signing certificate. This ensures that a CRL is not downloaded to validate the OCSP signing certificate.
Network Retrieval and Caching
When CryptoAPI performs network retrieval of revocation information, CryptoAPI first determines whether the required revocation information is already cached. The following sections provide details on how network retrieval is performed and how the results are cached.
CryptoAPI first determines whether a time valid version of the revocation object exists in the CryptoAPI disk cache.
If a time-valid object is not found in the disk cache, the network retrieval process starts. For each URL that is available for retrieval, CryptoAPI starts a background thread to perform the network retrieval of that designated object. By default, the calling thread will wait up to 15 seconds for the retrieval to complete (as defined in Group Policy).
If the object takes longer than 15 seconds to download, then CryptoAPI will report the server as offline, even as the retrieval continues in the background. If the CRL distribution point specifies multiple working URLs, then CryptoAPI will start the download of the second URL 15 seconds after the URL retrieval began.
If the application performs a second certificate validation while the first background retrieval continues, then the retrieval for the second validation will fail immediately.
Most applications do not specify to CryptoAPI to use a cumulative time-out. If the cumulative time-out option is not enabled, CryptoAPI uses the CryptoAPI default setting which is a time-out of 15 seconds per URL. If the cumulative time-out option specified by the application, then CryptoAPI will use a default setting of 20 seconds as the cumulative timeout. The first URL receives a maximum timeout of 10 seconds. Each subsequent URL timeout is half of the remaining balance in the cumulative timeout value.
CryptoAPI can prevent repeated fetching of objects that are located at unreachable URLs. For example, if the client is behind a firewall that blocks outgoing LDAP connections, no connections to an LDAP URL will succeed. To prevent continued attempts to unreachable URLs:
The unreachable URL is added to a list of unreachable URLs. The list of unreachable URLs is maintained on a per process basis.
CryptoAPI determines the earliest time that it will allow another attempt to retrieve the object at the unreachable URL. Until that time is reached, any attempt to retrieve the object will fail immediately with an offline error.
After the designated time is reached, CryptoAPI will attempt to connect to the URL again. If the connection fails, CryptoAPI will extend the time it will wait until another attempt is processed. The maximum time that it will wait is 30 minutes.
If the attempted connection is successful, then the interval is reset to 15 seconds.
When CryptoAPI attempts to download a PKI object from an HTTP 1.1 server or from a proxy server, CryptoAPI uses the ETag and Max-age headers to improve operation performance:
ETag. The ETag header is a value used for comparing two or more entities from the same requested HTTP URI. The client can then use a conditional GET to download the object only if the original object has changed by specifying the ETag from a previous download.
Max-age. The Max-age header contains the time in seconds that a HTTP proxy can field requests without revalidating with the origin server.
If you are publishing CRLs to a Network Load Balanced (NLB) clustered Web service, the method that you implement must be carefully designed to ensure that all nodes in the cluster maintain the same ETag value for a specific CRL. To ensure that the same ETag value is maintained, each node’s version of the CRL must have the same date/time stamp. This is done by copying the CRLs from a single source to all nodes in the cluster. If the CRLs are generated or created on each node of the Web cluster, then the CRLs would have different ETag values.
Using ETags and Max-age in a Request
The use of ETag and Max-age minimize bandwidth usage by helping to identify whether the client must download an updated object from the server.
Figure 1 CRL download with caching at the proxy
For example, take the case of an organization that publishes an updated CRL for its root CA every six months. Without using ETag and Max-age, it is possible that a subordinate CA is revoked one month later, but is not recognized by clients until the previous CRL expires in five months time.
However, although the CA is configured with a six month CRL, you can get clients to poll weekly for updates. You can do this by setting the Max-age to 604800 seconds (1 week) and an ETag value.
When the client (Client A in Figure 1) downloads the CRL from the CRL distribution point, the proxy server used by the client will cache both the CRL object and the header information (including the ETag and Max-age). If another client computer (Client C) connects to the proxy server to download the CRL, the proxy will respond with the cached CRL because the Max-Age is still in the period after the current date and time. This is indicated by set of arrows labeled as 2 in the figure.
A week later, the first client will poll for a new CRL by using a conditional GET. The proxy server or origin server will return the CRL object only if it is different from the version cached on the client. The client also sets the Max-age header to 1 week. This forces the proxy server to revalidate the object headers with the origin server. During the week that follows, successive conditional GET requests will be fielded by the proxy server (unless the object is removed from the proxy cache). This process repeats for another 25 weeks until the CA finally replaces its CRL.
The following sections provide detailed information on how HTTP 1.1 Proxy support reduces the bandwidth used in revocation checking.
The Initial Request and Response
When a request is made to a HTTP 1.1 server, the following HTTP header is sent from the client to the HTTP 1.1 server:
GET http://crl.verisign.com/pca3.crl HTTP/1.1
The first line contains the HTTP method (GET), the URI (http://crl.verisign.com/pca3.crl) and the HTTP version (HTTP/1.1).
When the origin server responds, the following data is sent back to the client:
HTTP/1.1 200 OK
The following details are included in the response:
The first line indicates that the highest HTTP version supported by the server is version 1.1, that the Status code for the operation is 200 signifying the operation was successful, and the reason is OK.
The Content-Length header indicates the size of the CRL.
The Via header indicates the names of the proxy servers.
The Date header contains the date and time the message was generated at the origin server.
The Content-Type header indicates that the object is a CRL.
The ETag header is set to a value of "570084-33c-64a62480".
The Last-Modified header contains the date and time at which the origin server asserts the object was last modified.
The Cache-Control: Max-age is set to a value of 86,400 which indicates that the proxy can use the cached object for 1 day before it must determine whether a more recent object is available at the origin server.
If another client were to submit a request for the http://crl.verisign.com/pca3.crl object through the PRXY-23 proxy, the proxy server can respond with the cached copy without revalidating with the origin server (as long as the request is within one day of the original request).
Fetching New Objects
When a client fetches a new object for the first time, CryptoAPI performs a simple HTTP GET without any additional headers. In this case, the server may respond with the following headers along with the requested object:
HTTP/1.1 200 OK
When CryptoAPI receives the object, the object will be added to the local cache. In addition, CryptoAPI will cache the ETag, Max-age, Last-Modified, and Via headers.
Although a simple GET is useful, conditional GETs enable the client to be more efficient by avoiding repeated downloads of information that has not changed on the server
Conditional headers to the GET method are used by Windows to determine whether the CRL or OCSP has changed since the last download. The two conditional headers used by CryptoAPI are:
If-Modified-Since. A client can determine whether the requested object has not been modified since the time specified in the If-Modified-Since header. The server will respond with either Not Modified or the updated object.
If-None-Match. A client can verify whether a previously requested entity is current by including a list of associated ETags in the If-None-Match header field. The server will respond not modified response that includes the ETag header and updated Max-age header.
If a server receives both the If-None-Match and If-Modified-Since headers, the If-None-Match header takes precedence. CryptoAPI sends only one of these conditional headers in the request. If the server returned the ETag header in its previous response, CryptoAPI will use the If-None-Match header that indicates the provided ETag value.
If the server did not return the ETag, CryptoAPI will use the Last-Modified header’s date and time included in the previous response and use that date and time in the If-Modified-Since header.
If the server returned both the ETag header and the Last-Modified header, a non-CryptoAPI client can include both the If-None-Match and If-Modified-Since headers. If both headers are submitted in a request, an HTTP 1.1 compliant server is supposed to prefer the If-None-Match header to the If-Modified-Since header if both are submitted in a request.
For example, if a client wished to update the cached version of the codesigning.crl file here, the following conditional GET request would be submitted to the origin server:
GET https://crl.microsoft.com/codesigning.crl HTTP/1.1
The conditional GET also includes a Max-age directive. The directive is included to trigger any intermediate proxies to revalidate with the origin server if the age of its cached object exceeds the max-age indicated in the conditional GET.
More details about the disk and memory cache are available in the Disk and Memory Caches section later in this document.
If the Server / Proxy Returned an Expired Object
During the execution of a simple GET or a conditional GET, the server may return an expired object to the client. If the origin server or the proxy server returns an expired object, CryptoAPI will assume that one of the proxies in the path is returning the expired object.
The client determines whether the object is expired by inspecting the NextUpdate field in the certificate, CRL, or OCSP response object. The object is considered expired if the date in the NextUpdate field is earlier than the current date or time.
The object is also considered expired if the response from the origin server or proxy server contains a Date header that is more recent than the Date header from the previously cached response.
To update the expired object, the client will send a new conditional GET request. For an HTTP 1.1 origin server or proxy server, the following request is sent:
GET https://crl.microsoft.com/codesigning.crl HTTP/1.1
CryptoAPI can also support the use of LDAP for PKI object retrieval. The following section provides details on LDAP object retrieval.
LDAP Server Retrieval
If CryptoAPI is attempting to download a CRL from an LDAP server, the following behavior is used:
If the host name is not included in the LDAP URL, CryptoAPI assumes that the CRL is referencing Active Directory and the LDAP query is submitted to the nearest domain controller.
The LDAP scope is limited to the base referenced in the LDAP URL.
CryptoAPI will make a maximum of three attempts to connect to the LDAP server:
CryptoAPI will first attempt to bind to the LDAP server using mutual authentication. It will make the connection attempt with LDAP_OPT_VERSION set to V3 and will use Kerberos for signing and encryption. This is a change in Windows Vista SP1 and Windows Server 2008. Previously, CryptoAPI would fall back to NTLM if Kerberos authentication failed.
If the server responds with LDAP_AUTH_METHOD_NOT_SUPPORTED or LDAP_INVALID_CREDENTIALS, then CryptoAPI will fall back use anonymous authentication with LDAP_OPT_VERSION set to V3.
If the anonymous authentication attempt fails, CryptoAPI will retry the connection using LDAP_OPT_VERSION set to V2.
Whether HTTP or LDAP is used, the downloaded objects are stored in the either the disk cache, the memory cache, or both the disk cache and memory cache of the client. The following section provides details on each cache and its use.
Disk and Memory Caches
CryptoAPI uses the following two caches for CRLs and OCSP responses:
A disk cache, which maintains copies of all CRLs and OCSP responses retrieved during the revocation checking process on the local file system. All items in the disk cache are maintained until their validity period expires.
A memory cache, which contains revocation information used by a specific process. The memory cache is maintained within the memory used by the calling process. When the process terminates, the memory is released and the memory cache is flushed. If an object exists in the disk cache, the object is read into the memory cache for the calling process.
Table 1 provides details on the disk cache locations for computers running Windows Vista and Windows Server 2008, or Windows XP and Windows Server 2003 operating systems.
|Location||Windows XP and Windows Server 2003||Windows Vista and Windows Server 2008|
C:\Documents and Settings\username\Application Data\Microsoft\CryptnetUrlCache
C:\Windows\System32\config\ systemprofile\Application Data\ Microsoft\CryptnetUrlCache
C:\Windows\System32\config\ systemprofile\AppData\LocalLow\ Microsoft\CryptnetUrlCache
Table 1 Disk cache locations
Flushing the Disk Cache
For Windows XP or Windows Server 2003, it is now supported to delete items from the disk cache. There are different commands available for flushing the cache:
To delete the CRL cache:
certutil -urlcache crl delete
To delete the OCSP cache:
certutil -urlcache ocsp delete
To delete all cache entries:
certutil -urlcache * delete
It may be necessary to restart the application or even the computer in order to flush the CRL cache in Windows XP or Windows Server 2003.
To use Certutil.exe on a Windows XP client, you must install the Windows Server 2003 Administration Tools Pack.
Certutil.exe works in the user context in which it is called. The commands here would delete the cache for the currently logged in user. To delete the cache for other users, the command would need to be run in corresponding user context.
Windows Vista and Windows Server 2008 also support flushing of items from the disk cache by running the three commands above. When the command is executed, all files are removed from the disk cache location on the file system. We do not recommend deleting the disk cache on Windows Vista. Deleting the disk cache does not delete files that are locked by another application. In addition, deleting the disk cache does not affect applications that have already cached items in memory.
You can also use Certutil.exe to view the current contents of the CRL and OCSP disk cache. The following examples provide details on viewing the CRL and OCSP disk cache:
If you want to view what is currently in the CRL disk cache:
certutil -urlcache crl
If you want to view what is currently in the OCSP disk cache:
certutil -urlcache ocsp
Flushing the Memory Cache
For Windows Vista and Windows 2008, it is preferable to invalidate the memory cache instead of deleting the disk cache. You can do so by invalidating the cached CRLs and OCSP responses before the time specified in the object.
To invalidate the cache, you must run the following commands from an Administrative command prompt:
To immediately invalidate all items from the cache:
certutil -setreg chain\ChainCacheResyncFiletime @now
To invalidate the currently cached items in 1 day, 2 hours:
certutil -setreg chain\ChainCacheResyncFiletime @now+1:2
To identify the last time that the cache was invalidated:
certutil -getreg chain\ChainCacheResyncFiletime
If the ChainCacheResyncFiletime was never manually set, the registry key will not exist and the getreg command will fail. This is expected behavior. This registry key is applied for the whole computer, so the commands here will invalidate the cache for all processes running on the computer. To reset the ChainCacheResyncFileTime, set it to a time sufficiently in the past using the setreg command.