Pre-Fetching

Applies To: Windows 7, Windows Server 2008, Windows Server 2008 R2, Windows Vista

Pre-fetching enables a CryptoAPI client to download updates to revocation information used previously to validate certificates before they are needed. Generally, CryptoAPI will attempt to pre-fetch any object in the disk cache. The only exception is CRLs that were retrieved because all of the OCSP URLs specified in a certificate’s authority information access extension failed.

Motivation for Pre-Fetching

Pre-fetching was implemented to improve the performance of revocation checking. The reasons for implementing pre-fetch include:

  • Pre-fetch works for both OCSP responses and CRLs (Both base CRLs and delta CRLs).

  • Pre-fetch eliminates the delays associated with retrieving frequently used revocation information. Instead of waiting for the download of a CRL or OCSP response during the validation of the certificate, the CRL or OCSP response is downloaded before use and is available in the cache.

  • Pre-fetch works with both HTTP and LDAP URLs.

  • Pre-fetch can reduce the peak load and bandwidth costs of revocation servers by spreading the downloads across the overlap period.

The Pre-Fetch Algorithm

Pre-fetching uses the cached ETag and Cache-Control:max-age headers to determine when the CryptoAPI client should attempt to pre-fetch a CRL or OCSP response. In addition, CryptoAPI will use the following attributes from CRLs and OCSP responses when determining the pre-fetch time for an object:

  • NextPublish. A noncritical extension that contains the date and time when the CA will publish an updated CRL or OCSP response.

  • NextUpdate. A field that denotes the expiry date for the CRL or OCSP response. When the date and time in this field is reached, the client will consider the CRL or OCSP response to be expired.

  • ThisUpdate. A field that denotes that the date and time that the CRL or OCSP response was created.

Figure 2   Example of the pre-fetching timeline

CryptoAPI also associates LastSyncTime attribute with every object in the cache and uses this in determining the pre-fetch time. LastSyncTime is the last time at which an object was checked for freshness with the origin server. LastSyncTime is initially set as the time at which an object is added to the cache, and is updated every time CryptoAPI verifies freshness of the object with the server.

The following algorithm is used to determine when to pre-fetch an object:

  1. Max-age associated with a cached object indicates the time interval for which the object can be used without checking for freshness. CryptoAPI will attempt to verify the freshness of the object if this time interval has elapsed since the value in the LastSyncTime attribute. If the object has changed then CryptoAPI will retrieve and cache the updated object.

Note

This step is skipped if the object’s NextPublish time is earlier than the current time or the object does not have a Max-age value associated with it. In this case, pre-fetch is attempted at a time within the NextPublishPeriod window.

  1. The NextPublishPeriod window is approximately defined as the time between next expected publish time (NextPublish) and expiration (NextUpdate) (as shown in figure 2). CryptoAPI determines a time within this window as follows:

    • CryptoAPI calculates a random time in the first half of this window by hashing parts of the HTTP header information.

    • CryptoAPI then adds a random number for an additional delay to get the time when the background service should retrieve the object.

    If the computed time is earlier than the current time, then CryptoAPI skips pre-fetch and waits until the object expires.

  2. If pre-fetch did not run or the object did not have a NextPublish extension, CryptoAPI computes a new window beyond the NextUpdate time.

    • This new window starts at the NextUpdate time and has a length of the lesser of four hours or the length of the validity period (difference between NextUpdate and ThisUpdate).

    • CryptoAPI then uses the same randomization algorithm as in step 2 to determine a retry time.