====== Runbook: Revoke Certificate ======
**Duration:** ~5 minutes \\
**Role:** PKI Operator / Security \\
**Priority:** HIGH on compromise
----
===== Workflow =====
flowchart TD
A[Revocation request] --> B{Reason?}
B -->|Compromise| C[Revoke IMMEDIATELY]
B -->|Replacement| D[Revoke planned]
B -->|Error| E[Check + revoke]
C --> F[Update CRL]
D --> F
E --> F
F --> G[Distribute CRL]
G --> H[Update OCSP]
H --> I[Notification]
I --> J[Documentation]
style C fill:#ffebee
style F fill:#fff3e0
style G fill:#e3f2fd
----
===== Revocation Reasons (RFC 5280) =====
| Code | Reason | When to use |
|------|--------|-------------|
| 0 | unspecified | Default (not recommended) |
| 1 | keyCompromise | **Private key compromised** |
| 2 | cACompromise | CA compromised |
| 3 | affiliationChanged | Organization changed |
| 4 | superseded | Replaced by new certificate |
| 5 | cessationOfOperation | Service discontinued |
| 9 | privilegeWithdrawn | Permission revoked |
----
===== Step 1: Identify Certificate =====
# Search by serial number
openssl x509 -in certificate.pem -serial -subject -noout
# Search in CA database
grep -r "CN=server.example.com" /etc/pki/CA/index.txt
# PowerShell: Find certificate
Get-ChildItem Cert:\LocalMachine\My | Where-Object {
$_.Subject -like "*server.example.com*"
} | Select-Object SerialNumber, Subject, Thumbprint
----
===== Step 2: Perform Revocation =====
==== OpenSSL (CLI) ====
# Revoke certificate
openssl ca -config openssl.cnf \
-revoke /path/to/certificate.pem \
-crl_reason keyCompromise
# Alternative: By serial number
openssl ca -config openssl.cnf \
-revoke_by_serial 01234567890ABCDEF \
-crl_reason keyCompromise
==== C# (WvdS.System.Security.Cryptography) ====
// Revoke certificate and create CRL
var crlBuilder = new CertificateRevocationListBuilder();
// Add revocation
crlBuilder.AddEntry(
revokedCert.SerialNumber,
DateTimeOffset.UtcNow,
X509RevocationReason.KeyCompromise);
// Sign CRL (Hybrid mode)
using var issuerCert = new X509Certificate2("ca.pfx", "password");
var crlNumber = BigInteger.Parse("42");
var nextUpdate = DateTimeOffset.UtcNow.AddDays(7);
byte[] crl = crlBuilder.Build(
issuerCert,
crlNumber,
nextUpdate,
HashAlgorithmName.SHA384,
CryptoMode.Hybrid);
File.WriteAllBytes("crl.der", crl);
----
===== Step 3: Generate and Distribute CRL =====
# Generate new CRL
openssl ca -config openssl.cnf -gencrl -out crl.pem
# Convert CRL to DER format (for distribution)
openssl crl -in crl.pem -outform DER -out crl.der
# Verify CRL
openssl crl -in crl.pem -text -noout
**Distribution Points:**
| Method | Target | Command |
|--------|--------|---------|
| HTTP | Web server | ''cp crl.der /var/www/pki/crl.der'' |
| LDAP | Active Directory | ''ldapmodify -f update-crl.ldif'' |
| CDP | In certificate | Automatic via URL |
# Copy CRL to web server
scp crl.der webserver:/var/www/html/pki/crl.der
# Nginx/Apache reload (if cached)
ssh webserver "systemctl reload nginx"
----
===== Step 4: Update OCSP (if used) =====
# OCSP responder index updates automatically (OpenSSL CA)
# Responder reads /etc/pki/CA/index.txt
# Test OCSP response
openssl ocsp \
-issuer intermediate.pem \
-cert certificate.pem \
-url http://ocsp.example.com \
-resp_text
**Expected response after revocation:**
Cert Status: revoked
Revocation Time: Dec 15 10:30:00 2024 GMT
Revocation Reason: keyCompromise
----
===== Step 5: Notification =====
**Required notifications:**
| Recipient | Method | Content |
|-----------|--------|---------|
| Certificate holder | E-mail | Serial number, reason, next steps |
| Security Team | Ticket | Incident details |
| Affected systems | Alert | Automatic via monitoring |
# Send e-mail template
cat << 'EOF' | mail -s "Certificate Revoked - Action Required" admin@example.com
Certificate has been revoked:
Serial number: 01:23:45:67:89:AB:CD:EF
Subject: CN=server.example.com
Reason: Key Compromise
Date: $(date -Iseconds)
Action required:
1. Configure service with new certificate
2. Remove old certificate from all systems
Questions: pki-team@example.com
EOF
----
===== Step 6: Documentation =====
| Field | Value |
|-------|-------|
| Serial number | ''01:23:45:67:89:AB:CD:EF'' |
| Subject | ''CN=server.example.com'' |
| Revocation reason | ''keyCompromise'' |
| Revocation date | ''2024-12-15 10:30:00 UTC'' |
| CRL number | ''42'' |
| Operator | ''Operator-Name'' |
| Ticket | ''SEC-2024-0815'' |
----
===== Emergency: Mass Revocation =====
**On CA compromise:** -> [[..:disaster-recovery:notfall-revocation|Emergency Revocation Runbook]]
# Revoke all certificates of a CA
for cert in /etc/pki/CA/newcerts/*.pem; do
openssl ca -config openssl.cnf -revoke "$cert" -crl_reason cACompromise
done
# New CRL with short validity
openssl ca -config openssl.cnf -gencrl -crldays 1 -out emergency-crl.pem
----
===== Checklist =====
| # | Checkpoint | Done |
|---|------------|------|
| 1 | Certificate entered in CRL | |
| 2 | CRL signed and valid | |
| 3 | CRL available on all CDPs | |
| 4 | OCSP responds ''revoked'' | |
| 5 | Certificate holder notified | |
| 6 | Security ticket documented | |
----
===== Troubleshooting =====
| Problem | Cause | Solution |
|---------|-------|----------|
| ''already revoked'' | Duplicate revocation | Ignore |
| ''unknown serial'' | Not from this CA | Check CA |
| CRL invalid | Signature error | Check CA key |
| OCSP responds ''good'' | Cache/sync | Restart OCSP responder |
----
===== Related Runbooks =====
* [[.:zertifikat-ausstellen|Issue Certificate]] - Replacement certificate
* [[..:disaster-recovery:notfall-revocation|Emergency Revocation]] - Mass revocation
* [[en:int:pqcrypt:szenarien:kurzreferenz:validierung|Validation Quick Reference]] - CRL/OCSP verification
----
<< [[.:zertifikat-erneuern|<- Renew Certificate]] | [[.:health-check|-> Health Check]] >>
----
//Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional//
{{tag>runbook certificate revocation crl ocsp operator}}