I often hear that PKI operators would like to see a new certificate revocation list issued immediately for revoked certificates.
Below, I would like to share some thoughts on why this approach is not ideal and propose a more elegant solution.
What problem are we actually trying to solve?
The real reason behind the immediate publication of the block list is the desire for a „live revocation“—that is, for the revocation to take effect immediately, or at least as quickly as possible.
In this context, "effective" means that Relying Parties immediately detect the certificate revocation and, accordingly, no longer accept the revoked certificates.
The Limits of Meaningfulness
Before we talk about solutions, we should realize that our approach is doomed to fail from the start.
Certificate revocation information is not „live“: (Windows) clients store CRLs between and therefore do not retrieve new revocation lists every time a certificate is verified. In the worst-case scenario, clients do not retrieve a new certificate revocation list until the cached revocation list has expired. The use of the The Online Responder (OCSP) role will not change this.
And even if we have a highly robust revocation status infrastructure, we still face the problem that not all relying parties will actually check the revocation status of certificates at all.
We can therefore conclude that we cannot guarantee that clients will actually make use of newly issued certificate revocation lists, which in turn means that we will not derive any significant benefit from issuing them more frequently (except in exceptional cases).
The most obvious approach would be to trigger the generation of a certificate revocation list immediately whenever a certificate is revoked.
For example, some people create a scheduled task on the certification authority for this purpose, which Event ID 25 from the Microsoft-Windows-CertificationAuthority source or the Event ID 4870 from the Microsoft Windows Security Auditing source intercepts it and then triggers the publication of a block list.
There have also reportedly been feature requests for Certificate Lifecycle Management (CLM) products I'm familiar with, asking that corresponding commands be sent to the certification authority.
However, this approach has several serious drawbacks:
Creating a certificate revocation list is resource-intensive—especially if many certificates have been revoked or are to be revoked. Generating a certificate revocation list can take several minutes and consume a corresponding amount of storage space and system resources. As a rule of thumb, you can assume 1 MB per 20,000 revoked certificates.
Every certificate revocation list that has been issued and is still valid is stored in the certification authority database. If we generate certificate revocation lists too often (and, in the worst-case scenario, they are also quite large), our certification authority database grows enormously. As an extreme real-world example, I once encountered a certification authority whose database contained over 65 GB (!) of valid certificate revocation lists. This was caused by the mass revocation of certificates via script. Each individual revocation triggered the generation of a new CRL, which led to a chain reaction.
In addition, the principle of Separation of roles is violated if a CLM system has the authority to instruct the certification authority to issue certificate revocation lists.
What We Actually Want and What Is Realistically Feasible
Now that we have come to realize that publishing a certificate revocation list every time a certificate is revoked is not a particularly good idea, we might conclude that regular publication by the certification authority could be a sensible solution instead. And that, after all, is exactly what the certification authority already does in its default configuration.
However, this interval might be too long for us, and we'd like to trigger a release sooner.
For example, we could issue a new revocation list at regular intervals—without any interaction from a certificate authority administrator, and only if certificates have been revoked since the last publication—without placing an unnecessary burden on the certificate authority.
Our approach could look something like this:
- First, we determine when the most recent certificate revocation list was issued (by evaluating the NotBefore date of the current certificate revocation list).
- We then determine whether any certificates have been revoked since then (by querying the Windows event log for the period between „now“ and the publication date of the most recent CRL)
- If that is the case, we will issue a new certificate revocation list. If not, then we won't.
To do this, we use the Event with ID 25 from the Microsoft-Windows-CertificationAuthority source.
Alternatively, this would also work Event ID 4870 from the Microsoft Windows Security Auditing source, the but it must first be activated), since we can design an efficient query here.
We could also obtain this information from the certification authority database, but that is significantly less efficient and will become increasingly slow as the number of certificates grows.
Here is an example PowerShell script:
#requires -RunAsAdministrator
[cmdletbinding()]
param()
$RegistryRoot = "HKLM:\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration"
If (-not (Test-Path -Path $RegistryRoot)) {
Write-Error -Message "No CA found!" -ErrorAction Stop
}
# Query the CA registry for the relevant information
$CaName = (Get-ItemPropertyValue -Path $RegistryRoot -Name "Active")
$CaServerName = (Get-ItemPropertyValue -Path "$RegistryRoot\$CaName" -Name 'CAServerName')
$ClockSkewMinutes = (Get-ItemPropertyValue -Path "$RegistryRoot\$CaName" -Name 'ClockSkewMinutes')
# Parse the current CRL for it's creation time
$CRLFile = "$env:SystemRoot\System32\CertSrv\CertEnroll\$CaName.crl"
$CRL = New-Object -ComObject X509Enrollment.CX509CertificateRevocationList
$CRL.InitializeDecode([System.Convert]::ToBase64String((Get-Content -Path $CRLFile -Encoding Byte)), 1)
$ThisUpdateUtc = [DateTime]::SpecifyKind($CRL.ThisUpdate, [DateTimeKind]::Utc)
# Query the audit log for any revocations that happened since the last $Events = Get-WinEvent -FilterHashtable @{
Logname='Application'
ProviderName='Microsoft-Windows-CertificationAuthority'
Id='25'
StartTime=($ThisUpdateUtc.AddMinutes($ClockSkewMinutes).ToLocalTime())
} -ErrorAction SilentlyContinue
# Only publish a new CRL if there were any revocations since the last CRL publication
If ($Events) {
Write-Host "Publishing CRL"
$CertAdmin = New-Object -ComObject CertificateAuthority.Admin
$CertAdmin.PublishCRL("$CaServerName\$CaName", 0)
}
We run this script at regular intervals as a scheduled task on the certification authority, for example, once an hour.
If a certificate is revoked in the meantime, our script detects this and publishes a new certificate revocation list the next time it runs.

Pitfalls
On high-volume certification authorities, the event log fills up more quickly and reaches its maximum size sooner, which will result in the oldest events being deleted. To ensure that the script works reliably, a sufficiently large maximum size must be set for the certification authority's event log.
Closing words
In my opinion, the certificate revocation mechanism is overrated.
- As a PKI operator, we have no control over whether relying parties actually check the revocation status.
- As a PKI operator, we have no control over whether relying parties request a new certificate revocation list or OCSP response as long as a previous certificate revocation list is still valid.
- As a PKI operator, we have no control over whether we even receive the information that certificates need to be revoked.
I'm taking the same approach here as Peter Gutmann: CRLs don't work.
In my opinion, the most robust approach is not to rely on the revocation status infrastructure and instead to use certificates with the shortest possible validity periods—which results in frequent recertification.
Related links:
- Overview of the audit events generated by the certification authority - Uwe Gradenegger
- Overview of Windows events generated by the certification authority
- View and clear the revocation list address cache (CRL URL Cache).
- Configuration of security event monitoring (auditing settings) for certification authorities - Uwe Gradenegger
- Roles in a public key infrastructure
- Google Chrome and Microsoft Edge do not check certificate revocation state
- Basics: Checking the revocation status of certificates - Uwe Gradenegger
- Basics: Delta blocking lists - Uwe Gradenegger