<aside> 🧭

Module 09 · Revocation: CRL, OCSP & Why It's Broken

Every module so far has had a note saying "revocation is covered in Module 09". This is it — and the honest headline is that revocation on the public internet does not work, and the industry has stopped pretending otherwise. Understanding why explains the single biggest change happening in TLS right now: certificate lifetimes collapsing from years to weeks.

🧠 concept → 🧪 exercise → ✅ expected result (hidden) → 🎯 interview questions (answers hidden)

Prerequisite: Modules 01–08. You need the CRL and AIA extensions from Module 03 (C5), openssl ca and index.txt from Module 05 (B2), and OCSP stapling from Module 08 (D2).

</aside>


<aside> 💳

The picture to hold in your head for this whole module — a cancelled credit card.

Your card is stolen. You ring the bank and cancel it. The card itself is unchanged — same numbers, same hologram, same expiry date printed on the front. Nothing about the card tells a shopkeeper it is dead.

So how does the shop find out? Two ways, historically:

  1. A printed book of cancelled numbers under the counter, delivered weekly. That is a CRL.
  2. Phoning the bank to ask about this one card. That is OCSP.

Both work in principle. Both have a problem that turns out to be fatal in practice — and this module is about what that problem is and what replaced them.

</aside>

<aside> 🖥️

Build the revocation lab. Everything here runs offline — no network, no CA, nothing outside ~/tls-lab/.

mkdir -p ~/tls-lab/m09 && cd ~/tls-lab/m09
umask 077
mkdir -p certs db && touch db/index.txt
openssl rand -hex 8 > db/serial
echo 1000 > db/crlnumber          # NEW: CRLs need their own counter

cat > ca.cnf <<'EOF'
[ca]
default_ca=CA
[CA]
dir=.
database=$dir/db/index.txt
serial=$dir/db/serial
crlnumber=$dir/db/crlnumber
new_certs_dir=$dir/certs
certificate=$dir/ca.crt
private_key=$dir/ca.key
default_md=sha256
default_days=90
default_crl_days=7
policy=pol
rand_serial=yes
unique_subject=no
copy_extensions=none
email_in_dn=no
[pol]
commonName=supplied
[srv]
basicConstraints=critical,CA:FALSE
keyUsage=critical,digitalSignature
extendedKeyUsage=serverAuth
subjectAltName=DNS:a.test,DNS:b.test,DNS:c.test
crlDistributionPoints=URI:<http://crl.example.test/ca.crl>
EOF

openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out ca.key
openssl req -x509 -key ca.key -out ca.crt -days 3650 -subj "/CN=Revocation Lab CA" \
  -addext "basicConstraints=critical,CA:TRUE" -addext "keyUsage=critical,keyCertSign,cRLSign"

openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out srv.key
for n in a b c; do
  openssl req -new -key srv.key -out $n.csr -subj "/CN=$n.test"
  openssl ca -config ca.cnf -extensions srv -batch -notext -in $n.csr -out $n.crt
done

cat db/index.txt

Two new things in this config, both required before openssl ca will generate a CRL: a crlnumber file (a counter, like serial, but for CRLs) and default_crl_days (how long each CRL is valid).

All output in this module was produced on OpenSSL 3.0.13.

</aside>

Part A · What revocation actually is

A1 · Revoking a certificate — two fields in a text file

<aside> 📖

Official docs: RFC 5280 §5 — CRL and CRL Extensions Profile · openssl ca-revoke and -crl_reason · RFC 5280 §5.3.1 — Reason Code

</aside>

<aside> 📒

The analogy — crossing a name off the ledger.

In Module 05 the CA's index.txt was described as the office ledger: every document issued, with its number and its status.

Revocation is nothing more than changing one letter in that ledgerV for valid becomes R for revoked — and writing today's date beside it.

That is genuinely all it is. Everything else in this module is about the much harder problem of telling the world what the ledger now says.

</aside>

🧪 Exercise A1.1 — Revoke a certificate and watch the ledger change

cd ~/tls-lab/m09

echo "=== the ledger before ==="
cat db/index.txt

echo
echo "=== revoke b.test, and say why ==="
openssl ca -config ca.cnf -revoke b.crt -crl_reason keyCompromise

echo
echo "=== the ledger after ==="
cat db/index.txt

🎯 Interview questions — What revocation is


A2 · CRL — the printed book under the counter

<aside> 📖

Official docs: RFC 5280 §5 — CRL Profile · openssl ca -gencrl · openssl crl manual

</aside>

<aside> 📕

The analogy — the book of stolen card numbers.

Before card machines were online, shops kept a printed booklet of cancelled card numbers under the counter. The bank posted a new one every week. For a large purchase the assistant would look the number up.

It works, and you can see the problems immediately:

A CRL is that booklet: a signed list of revoked serial numbers, published at a URL, with a "next update" date.

</aside>

🧪 Exercise A2.1 — Generate a real CRL and read it