Hello all! This blog posts opens an "AD CS Partitioned CRLs - A Comprehensive Guide" blog post series. The first is an introduction.

Starting with 2025 10B update (October 14, 2025), AD CS on Windows Server 2019 and newer will receive a new feature called Partitioned Certificate Revocation List (CRL), or Partitioned CRL. CRL partitioning is a process of splitting single CRL into a set of smaller CRLs. The following updates will enable this feature:

Let's recall the need of partitioned CRL and current state of the subject before we dig into new update.

Why we need partitioned CRLs?

As per definition, CRL is a list of certificates revoked by issuing CA during entire CA operational lifetime, which can span decades. Some CAs can operate for 20-30 years. And the number of revoked certificates can be huge. This can increase CRL size to quite large size. I've seen CAs with 50MB+ CRLs. And all clients that validate particular certificate have to regularly download and cache big CRLs. Certificate validation process isn't a business logic, it is a background process and should be completed as quickly as possible. Given that certificates are our daily routine, we deal with them hundreds times a day, large CRLs cause noticeable delays and reduce process performance.

We have Delta CRLs, why partitioning?

Very fair. RFC 3280 and 5280 define a concept of full (Base) and differential (Delta) CRLs. The strategy is to publish potentially large full CRL and larger intervals (periods) and publish smaller differential CRLs more often. This will help clients to do less frequent large CRL fetches and improve certificate revocation checking more effective. While this approach is working, a problem happens when large cached CRL is expiring and client needs to fetch another large CRL which would cause network and CPU/memory overhead. You still have to spend CPU resources to decode entire CRL in memory.

We have OCSP, why still CRLs?

Well, we already have a solution to address large CRLs, by using online certificate status protocol (OCSP) which queries revocation status of a particular certificate regardless of CRL size on CA side. For example, typical OCSP transaction size for a single certificate is around 1.5-2KB, even if CRL is 100MB. Sounds great? Indeed. However there are some fundamental limitations in OCSP:

  • Massive certificate validation volume

Imagine, Monday morning and AD environment. People start to log on to their workstations with smart cards or other certificate-based authentication. Domain controller has to make OCSP query for each such certificate. Eventually, OCSP transaction size can exceed actual CRL size, especially if CRL size is small or moderate, say tens KB. In this case, OCSP overhead is much larger than CRL. Microsoft implemented a behavior that if client face certificates from the same issuer more than defined threshold, client will stop OCSP query and will fetch CRL once. No matter of its size. It is worth to mention that it is Microsoft-only proprietary behavior.

  • Privacy concerns

Not something obvious, but became apparent after actively using it in internet PKI. Previously, OCSP was mandatory for extended validation (EV) certificates as primary revocation checking method. However OCSP leaked privacy information: OCSP is able to get server/subject name from queried serial number and information about the client: IP address, region, crypto library or application. This is enough to start building somewhat advanced usage analytics of a particular web site OCSP server don't own. It works against website visitors as well. OCSP can track user preferences by binding client IP address to OCSP queries and see what websites visit particular IP address, when and how often.

These privacy concerns were primary reasons to deprecate OCSP in internet PKI. Let's encrypt already shut down all their OCSP servers. Other large CAs such as DigiCert still maintain OCSP servers (as of this blog post publication time), but the time is counting against OCSP, at some points it will end its journey in internet PKI. In enterprises and private PKIs, OCSP is still a viable solution since such privacy isn't a big concern.

In the end, we are moving back to old revocation checking solution with all its limitations. And latest developments are oriented to address large CRLs in one or another way.

RFC 5280 already supports partitioned CRLs. Isn't it?

Some can argue that RFC 3280 and its successor RFC 5280 already define partitioned CRLs, so CA can break single large CRL into multiple smaller CRLs. CA can split CRL by a couple of factors:

  • Subject type (CA, end entity)
  • Revocation reason

This is supported via CRL Distribution Points (CDP) certificate extension as per §4.2.1.13 and Issuing Distribution Points (IDP) CRL extension as per §5.2.5. Sounds like a solution?

Somewhat. Of course RFC-based CRL partitioning somewhat addresses partitioned CRLs, the behavior is pretty sloppy and increases client code implementation complexity. For example, CA implements CRL partitioning by revocation reason. Separate CRL for each reason or a combination of a couple of reasons. If client is concerned about particular reason, it may work fine, client fetches only one CRLs for required reasons. What if client cares about all kind of reasons? Client is required to download all partitions, resulting in full CRL size. In addition, some partitions such as with keyCompromise can be very small (say, 2%) while superseded or affiliationChanged can be large (remaining 98%).

These RFC-based CRL partitioning complexities resulted in very small implementation adoption. For example, Microsoft CryptoAPI client never implemented this type of CRL partitioning. So, the problem with large CRLs is still on a table.

What Microsoft offers?

With new update, Microsoft delivers a very simple, flexible and very effective partitioned CRL which doesn't require client modifications. Last part is very important: we already saw that any feature (even a good one) that require client update face huge adoption latency, it takes years to update major clients and some clients may never get such updates. And it is worth to mention that new partitioned CRL is optional. If you don't have issues with large CRLs. This topic is to organizations with high revocation volume or heavy CRLs.

The idea is pretty simple:

  • Define a number of CRL partitions. Say, 2, 10, 1000, whatever you find reasonable
  • At the time a CSR arrives at the CA, it is assigned to a partition using either random allocation or a round-robin algorithm
  • When certificate is issued, include URL to selected partition in CDP extension
  • If certificate is revoked, it will be included only to CRL in bound partition

The following diagram illustrates the concept:

From client perspective, the behavior will be exactly the same as 20 years ago: there is an URL in CDP extension which points a full base CRL where certificate in subject would appear after revocation. In fact, it will be partial base CRL, but client is not interested in such details as long as CRL meets client expectations. Client is interested to know if certificate is revoked or not. And given that CA will include serial number in exact CRL referenced in CDP extension of particular certificate, the problem is solved.

This CRL partitioning using randomization will distribute revoked certificates in partitions more evenly or uniformly than RFC-provided partitioning method. In addition, this may help to move away from Delta CRLs in some cases. If you have relatively small CRLs in chunks, you can avoid Delta CRLs and publish Base CRL partitions more often.

In next post, I will provide details about how to configure partitioned CRL in Microsoft AD CS, various options and API changes associated with new feature.


Share this article:

Comments:


Post your comment:

Please, solve this little equation and enter result below. Captcha image