One of these two revocation checks returns a signed answer about a single certificate, and the other returns a signed list that you download whole. Both are meant to tell a verifier whether a credential is still trusted, and both fail in ways that look nothing alike. The order below follows what an operator actually hits in production, starting with the bytes on the wire and ending with a gateway refusing a connection. Skipping a step is how a deployment ends up with a revocation policy that exists only on paper.

Step 1: What each check hands back and how long it stays usable

A CRL is published as one signed object covering every certificate an issuer has revoked, so a verifier fetches it once and reuses it until the list's nextUpdate passes. An OCSP response is narrower: it answers for exactly one certificate and carries thisUpdate, producedAt and usually nextUpdate as well. That difference drives everything else. A cached CRL goes stale silently, because the file still parses and its signature still verifies, while an expired OCSP answer is obviously worthless the moment you read its timestamps.

Caching is therefore the first thing to pin down: which component holds the copy, and what ceiling that copy obeys. On a gateway the ceiling should be nextUpdate minus a safety margin, never whatever an HTTP cache header happens to suggest. openssl crl -in issuer.crl -noout -lastupdate -nextupdate prints both dates, and a list whose nextUpdate is already in the past has to be treated as missing rather than merely old.

Step 2: Where the certificate points the client

The leaf certificate usually carries two hints: a CRL distribution point extension and an authority information access entry for OCSP. openssl x509 -in client.pem -noout -ext crlDistributionPoints prints the first, and the second sits under the AIA section of openssl x509 -in client.pem -noout -text. Either extension is a pointer, not an obligation. A client that never implements revocation checking will connect perfectly well against a certificate whose extensions name a responder that has been dead for a year.

Distribution points often name an internal host that resolves only inside one network segment, and some older clients refuse ldap URLs outright. Test reachability from the host that terminates the tunnel, not from your own laptop, because that is the only vantage point whose failure actually matters.

Step 3: Pick fail-closed or fail-open before the outage

An unreachable responder or an expired list forces a decision: refuse the connection, or accept it and record the gap. OpenSSL's verify subcommand makes the strict choice explicit, because adding -crl_check turns an unavailable CRL into unable to get certificate CRL and a failed verification. Soft-fail in most stacks is not a flag at all, it is the absence of the check, which is exactly why it ships by accident.

To see which behaviour a client really has, take the responder away and reconnect. If the tunnel still comes up, find the log line that recorded the skipped check, then ask whether anyone would read that line during an incident. The same vendor can differ per protocol, with an IKEv2 client and an OpenVPN client on one machine reading unrelated configuration knobs.

Step 4: Prove the check runs where traffic is admitted

Find the process that terminates or authorises the connection, then ask it for the configuration line that enables revocation checking. A gateway that validates the chain but never asks about revocation is enforcing a different policy from the one in your documentation, and no screenshot of a certificate chain proves otherwise. OpenVPN spells the option crl-verify; strongSwan keeps CRL and OCSP lookups under the CA configuration, where crl_uris or ocsp_uris are set. If you cannot point at either, assume the check is absent.

An OCSP answer counts only when the issuing CA signed it, or when a responder holding the OCSPSigning extended key usage delegated by that CA signed it, so an answer from an unrelated service proves nothing. If you run the responder yourself, monitor it as a hard dependency, since one dead service becomes an outage for every fail-closed client at once.

Step 5: Revoke one certificate on purpose

Take a test certificate, revoke it through the same channel production uses, and ask the responder directly. openssl ocsp -issuer ca.pem -cert old.pem -url http://ocsp.example.net -resp_text should report Cert Status: revoked together with a revocation time, and a good answer means your revocation did not reach the responder your clients query. Then run openssl verify -crl_check -CRLfile issuer.crl -CAfile ca.pem old.pem to see the same decision through the list path. Read the reason string rather than the exit code, because a revocation rejection and a chain error both end in failure.

The step that actually matters is the last one: reconnect with the old profile against the real enforcement point and confirm the refusal comes from revocation. Then reconnect with a fresh, valid certificate to prove you did not merely break the listener. Deleting the profile on the client proves nothing about the server's decision, and neither does a passing openssl verify run on a machine that never terminates a tunnel. RFC 6960 defines what a conforming OCSP response contains, including the status values this test reads.

Nsɛm a ɛfa ho