Inhaltsverzeichnis

RevocationExtensions Class

Extension methods for checking certificate revocation.


Definition

namespace WvdS.System.Security.Cryptography.X509Certificates;
 
public static class RevocationExtensions

Methods

Method Description
IsRevoked Checks if a certificate is revoked
FetchCrlAsync Downloads CRL from URL (from certificate extension)
CheckRevocationAsync Combined: Load CRL and check revocation
GetCrlDistributionPoints Extracts CRL URLs from certificate
GetOcspUrls Extracts OCSP URLs from certificate

Checking Revocation

With existing CRL:

using System.Security.Cryptography.X509Certificates;
using WvdS.System.Security.Cryptography.X509Certificates;
 
var certificate = new X509Certificate2("user.cer");
byte[] crlData = File.ReadAllBytes("ca.crl");
var caCert = new X509Certificate2("ca.cer");
 
// Check with signature verification
RevocationResult result = certificate.IsRevoked(crlData, caCert, CryptoMode.Hybrid);
 
if (result.Success)
{
    if (result.IsRevoked)
    {
        Console.WriteLine($"Certificate revoked on: {result.RevocationDate}");
        Console.WriteLine($"Reason: {result.Reason}");
    }
    else
    {
        Console.WriteLine("Certificate is valid");
    }
}
else
{
    Console.WriteLine($"Error: {result.ErrorMessage}");
}

Automatically load CRL:

// Loads CRL from URL in the certificate's CDP extension
RevocationResult result = await certificate.CheckRevocationAsync(
    caCert,
    mode: CryptoMode.Hybrid);

Loading CRL

// Only load CRL, without checking
byte[]? crlData = await certificate.FetchCrlAsync();
 
if (crlData != null)
{
    File.WriteAllBytes("downloaded.crl", crlData);
}

With custom HttpClient:

using var httpClient = new HttpClient();
httpClient.Timeout = TimeSpan.FromSeconds(10);
 
byte[]? crlData = await certificate.FetchCrlAsync(httpClient);

Reading CRL Distribution Points

IReadOnlyList<string> crlUrls = certificate.GetCrlDistributionPoints();
 
foreach (var url in crlUrls)
{
    Console.WriteLine($"CRL URL: {url}");
}
 
// Quick check
bool hasCdp = certificate.HasCrlDistributionPoints();

Reading OCSP URLs

IReadOnlyList<string> ocspUrls = certificate.GetOcspUrls();
 
foreach (var url in ocspUrls)
{
    Console.WriteLine($"OCSP Responder: {url}");
}
 
// Quick check
bool hasOcsp = certificate.HasOcspUrls();

RevocationResult Class

Property Type Description
IsRevoked bool Certificate is revoked
RevocationDate DateTimeOffset? Time of revocation
Reason CrlReason? Revocation reason
CrlVerified bool CRL signature was verified
ErrorMessage string? Error message (if check failed)
Success bool Check was successful

CRL Cache

For frequent checks with automatic caching:

using var cache = new CrlCache(defaultCacheDuration: TimeSpan.FromHours(1));
 
// Check with automatic CRL caching
RevocationResult result1 = await cache.CheckRevocationAsync(cert1, caCert);
RevocationResult result2 = await cache.CheckRevocationAsync(cert2, caCert); // CRL from cache
 
// Clear cache
cache.Clear();

With custom HttpClient:

using var httpClient = new HttpClient();
using var cache = new CrlCache(httpClient, TimeSpan.FromMinutes(30));
 
// Check multiple certificates
foreach (var cert in certificates)
{
    var result = await cache.CheckRevocationAsync(cert, caCert, CryptoMode.Hybrid);
    // ...
}

Integration with X509Chain

For complete chain validation with CRL checking:

using var chain = new X509Chain();
chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
 
bool valid = chain.Build(certificate, CryptoMode.Hybrid);
 
if (!valid)
{
    foreach (var status in chain.ChainStatus)
    {
        if (status.Status == X509ChainStatusFlags.Revoked)
        {
            Console.WriteLine("Certificate in chain revoked");
        }
    }
}

Offline Checking

For air-gapped systems without network access:

// Download CRLs in advance and store
var crlFiles = new Dictionary<string, byte[]>
{
    ["CN=Root CA"] = File.ReadAllBytes("root.crl"),
    ["CN=Issuing CA"] = File.ReadAllBytes("issuing.crl")
};
 
// Offline check
RevocationResult result = certificate.IsRevoked(crlFiles["CN=Issuing CA"], caCert);

Best Practices


See Also


Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional