Category: Revocation
Complexity: ⭐⭐⭐⭐ (High)
Prerequisites: Base CRL available
Estimated Time: 20-30 Minutes
This scenario describes the creation of Delta CRLs (RFC 5280 section 5.2.4). Delta CRLs contain only changes since the last base CRL, enabling more efficient updates.
Advantages:
Disadvantages:
using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ; using System.Numerics; using var ctx = PqCryptoContext.Initialize(); // Load CA var caCert = ctx.LoadCertificate("intermediate-ca.crt.pem"); var caKey = ctx.LoadPrivateKey("intermediate-ca.key.pem", "CaPassword!"); // Load base CRL var baseCrl = ctx.ParseCrl(File.ReadAllBytes("intermediate-ca-base.crl")); var baseCrlNumber = baseCrl.CrlNumber; // Delta CRL builder var deltaCrlBuilder = new CertificateRevocationListBuilder(); // Add only NEW revocations since base CRL var newRevocations = GetRevocationsSince(baseCrl.ThisUpdate); foreach (var rev in newRevocations) { deltaCrlBuilder.AddEntry( rev.SerialNumber, rev.RevocationTime, rev.Reason ); } // Optional: Remove certificates from "Hold" var removedFromHold = GetRemovedFromHold(baseCrl.ThisUpdate); foreach (var serial in removedFromHold) { deltaCrlBuilder.AddEntry( serial, DateTimeOffset.UtcNow, X509RevocationReason.RemoveFromCrl // Code 8 ); } // Delta CRL extensions deltaCrlBuilder.AddExtension( oid: "2.5.29.27", // Delta CRL Indicator critical: true, value: EncodeDeltaCrlIndicator(baseCrlNumber) ); // Generate Delta CRL byte[] deltaCrlBytes = deltaCrlBuilder.Build( issuerCertificate: caCert, crlNumber: baseCrlNumber + 10, // Delta numbers between base numbers nextUpdate: DateTimeOffset.UtcNow.AddHours(4), // More frequent than base hashAlgorithm: HashAlgorithmName.SHA256, mode: CryptoMode.Hybrid ); File.WriteAllBytes("intermediate-ca-delta.crl", deltaCrlBytes); Console.WriteLine($"Delta CRL created:"); Console.WriteLine($" Base CRL Number: {baseCrlNumber}"); Console.WriteLine($" Delta CRL Number: {baseCrlNumber + 10}"); Console.WriteLine($" New Entries: {newRevocations.Count}"); Console.WriteLine($" Removed from Hold: {removedFromHold.Count}");
private byte[] EncodeDeltaCrlIndicator(BigInteger baseCrlNumber) { // Delta CRL Indicator is simply the base CRL number as INTEGER var writer = new AsnWriter(AsnEncodingRules.DER); writer.WriteInteger(baseCrlNumber); return writer.Encode(); }
// Base CRL must reference Delta CRLs var baseCrlBuilder = new CertificateRevocationListBuilder(); // Add all revoked certificates foreach (var rev in allRevocations) { baseCrlBuilder.AddEntry(rev.SerialNumber, rev.RevocationTime, rev.Reason); } // Freshest CRL Extension (points to Delta CRL) baseCrlBuilder.AddExtension( oid: "2.5.29.46", // Freshest CRL (Delta CRL Distribution Point) critical: false, value: EncodeFreshestCrl("http://crl.example.com/intermediate-delta.crl") ); byte[] baseCrlBytes = baseCrlBuilder.Build( issuerCertificate: caCert, crlNumber: BigInteger.Parse("1000"), nextUpdate: DateTimeOffset.UtcNow.AddDays(7), // Longer validity hashAlgorithm: HashAlgorithmName.SHA256, mode: CryptoMode.Hybrid ); File.WriteAllBytes("intermediate-ca-base.crl", baseCrlBytes);
public class DeltaCrlProcessor { public CombinedRevocationList CombineCrls( byte[] baseCrlBytes, byte[] deltaCrlBytes, PqCryptoContext ctx) { var baseCrl = ctx.ParseCrl(baseCrlBytes); var deltaCrl = ctx.ParseCrl(deltaCrlBytes); // Check if delta matches base var deltaIndicator = GetDeltaCrlIndicator(deltaCrl); if (deltaIndicator != baseCrl.CrlNumber) { throw new InvalidOperationException( $"Delta CRL (Indicator: {deltaIndicator}) does not match base CRL ({baseCrl.CrlNumber})" ); } // Create combined list var combined = new CombinedRevocationList { BaseCrlNumber = baseCrl.CrlNumber, DeltaCrlNumber = deltaCrl.CrlNumber, ThisUpdate = deltaCrl.ThisUpdate, // Delta is more current NextUpdate = deltaCrl.NextUpdate, Entries = new Dictionary<string, RevocationEntry>() }; // Copy base entries foreach (var entry in baseCrl.Entries) { combined.Entries[entry.SerialNumber] = entry; } // Apply delta entries foreach (var entry in deltaCrl.Entries) { if (entry.Reason == X509RevocationReason.RemoveFromCrl) { // Remove from CRL (hold released) combined.Entries.Remove(entry.SerialNumber); } else { // Add or update combined.Entries[entry.SerialNumber] = entry; } } return combined; } public bool IsRevoked(string serialNumber, CombinedRevocationList crl) { return crl.Entries.ContainsKey(serialNumber); } }
public class DeltaCrlScheduler { private readonly TimeSpan _baseCrlInterval = TimeSpan.FromDays(7); private readonly TimeSpan _deltaCrlInterval = TimeSpan.FromHours(4); private BigInteger _currentBaseCrlNumber = 1000; private BigInteger _currentDeltaNumber = 0; public async Task RunScheduler(CancellationToken cancellationToken) { var lastBaseCrl = DateTimeOffset.UtcNow; while (!cancellationToken.IsCancellationRequested) { if (DateTimeOffset.UtcNow - lastBaseCrl >= _baseCrlInterval) { // Time for new base CRL await CreateBaseCrl(); lastBaseCrl = DateTimeOffset.UtcNow; _currentBaseCrlNumber += 100; _currentDeltaNumber = 0; } else { // Create Delta CRL await CreateDeltaCrl(); _currentDeltaNumber++; } await Task.Delay(_deltaCrlInterval, cancellationToken); } } private async Task CreateBaseCrl() { Console.WriteLine($"Creating base CRL #{_currentBaseCrlNumber}"); // ... Base CRL logic } private async Task CreateDeltaCrl() { var deltaCrlNumber = _currentBaseCrlNumber + _currentDeltaNumber; Console.WriteLine($"Creating Delta CRL #{deltaCrlNumber} (Base: {_currentBaseCrlNumber})"); // ... Delta CRL logic } }
| Industry | Base CRL | Delta CRL | Recommendation |
|---|---|---|---|
| WebPKI | 7 days | 4 hours | Optional, OCSP preferred |
| Enterprise | 24 hours | 1 hour | Recommended |
| Financial Sector | 12 hours | 15 minutes | Mandatory |
| Energy/SCADA | 7 days | 24 hours | Depending on connectivity |
| Relationship | Scenario | Description |
|---|---|---|
| Prerequisite | 6.1 Create CRL | Base CRL |
| Alternative | 6.2 OCSP Responder | Real-time status |
| Related | 5.3 Revocation Check | Client verification |
« ← 6.2 OCSP Responder | ↑ Revocation Overview | 6.4 Revoke Certificate → »
Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional