Certificate revocation: CRL and OCSP
An EAP-TLS client certificate can be checked for revocation two ways: against a
CRL (the CA’s signed list of revoked certificates, held on disk) and with an
OCSP responder (asked about one certificate at the moment it authenticates).
Both are decided per CA: a CA is checked because something is configured on it,
and a CA with nothing configured is not checked at all. The check itself is made by
FreeRADIUS in the nac container, during the TLS handshake, before any policy rule
runs.
This page covers what is checked and why. Where each CRL comes from, how it is downloaded and which alerts watch it is on PKI & trust → CRL.
Key concepts
Section titled “Key concepts”| Term | What it means here |
|---|---|
| Enable CRL Check | The one switch for CRL checking, on NAC → Settings, section CRL Control. Off: no client certificate is checked against any CRL. On: the chains below are checked. New installations start with it on. |
| CA with a CRL configured | An Internal CA, always (Taranac signs its CRL). A Trusted CA or an LDAP EAP-TLS CA once it has a CRL URL or an uploaded CRL. |
| Issuing CA | The CA that signed the client certificate, the one directly above it. Its CRL is the one that lists the client. |
| Check revocation with OCSP | A switch on a Trusted CA and on an LDAP configuration’s EAP-TLS tab. Independent of Enable CRL Check. Internal CAs have no OCSP. |
| OCSP responder URL | The responder to ask, set beside the switch. Empty means the OCSP address in the client certificate (its AIA). |
CRL checking
Section titled “CRL checking”Which certificates are checked
Section titled “Which certificates are checked”With Enable CRL Check on, a client certificate is checked against a CRL when some CA of its chain, up to the root, has a CRL configured. A chain with no such CA is accepted without a CRL check, and FreeRADIUS logs a warning naming the issuer (CRL not checked for ’…’: no CA in its chain has a CRL configured), once per issuer.
What makes a CA “configured” is the data, not a per-CA switch:
| Source | Configured when |
|---|---|
| Internal CA | Always, while it is enabled and active. |
| Trusted CA / LDAP EAP-TLS CA with a stored CRL | The certificate of the record whose key signed that CRL. In a record that holds a chain, the other certificates are not configured by it. |
| Trusted CA / LDAP EAP-TLS CA with a CRL URL but no CRL yet, or a CRL whose signer is not in the record | Every certificate of the record, until a CRL narrows it to its signer. |
| Trusted CA / LDAP EAP-TLS CA with neither | Nothing: its clients are not checked. |
A CA is recognised by its key, so the same CA in two places (a Trusted CA and an LDAP configuration, or a renewal with the same key) is configured in both as soon as it is configured in one. Adding a CRL can only make checking stricter; nothing turns checking off for the clients of a configured CA.
The CRL that counts is the issuing CA’s
Section titled “The CRL that counts is the issuing CA’s”Once a chain is checked, the client certificate is looked up in the CRL of its issuing CA, and only there. That CRL must be present and current:
- no CRL for the issuing CA: the client is refused,
tls_crl_missing; - the CRL has passed its next update: the client is refused,
tls_crl_expired; - the certificate is on it: refused,
tls_client_cert_revoked.
A root’s CRL lists the sub-CAs the root revoked, not their clients. So a root’s CRL does not cover the clients of its sub-CA: configure a CRL on the root only and every client of the sub-CA is refused as CRL missing until the sub-CA’s own CRL is added, in the same record or in a record of its own. With a two-tier AD CS, that means the CRL of the issuing CA (the distribution point the client certificates name), not the root’s.
| Hierarchy | What to configure | Result |
|---|---|---|
| Root issues the client certificates | The root, with its CRL | Clients checked against the root’s CRL |
| Root → issuing CA, record holds both, CRL of the issuing CA | The issuing CA’s CRL URL on the record | Clients checked against the issuing CA’s CRL |
| Root → issuing CA, CRL of the root only | — | Every client refused, tls_crl_missing |
| Root → two issuing CAs, one record each, only one with a CRL | One issuing CA’s CRL | Its clients checked; the other CA’s clients accepted unchecked |
| Any CA, no CRL URL and no uploaded CRL | — | Not checked |
A revoked certificate found on a CRL is refused whatever the configuration, as long as Enable CRL Check is on. The issuing chain above an Internal CA signed by your corporate PKI is not part of EAP-TLS trust, so its CRLs are not used here (see Upper-chain CRLs).
Setting a CRL on a Trusted CA or an LDAP configuration
Section titled “Setting a CRL on a Trusted CA or an LDAP configuration”The Revocation checking section of a Trusted CA, and the Certificate Revocation List (CRL) section of an LDAP configuration’s EAP-TLS tab, are always shown. The rules are the same on both:
- Saving a CRL URL downloads the CRL. A new or changed CRL distribution URL is fetched in the same save and stored with the URL. If it cannot be downloaded or its signature does not verify against the CA, nothing is saved and the error is shown at the URL field. Fetch tests a URL without saving.
- A distribution point that only another cluster node can reach: upload the CRL file (PEM or DER) in the same save. A CRL sent with the save replaces the download.
- Clearing the URL removes its CRL too, unless you upload a CRL in the same save. A URL owns the CRL it downloads; a CRL left behind without one would one day expire and refuse every client of the CA.
- Delete CRL removes the URL and the CRL together; the CA is then no longer checked against a CRL. The form says what will be removed before you save, and Keep CRL takes it back.
A CRL URL that has not delivered a CRL yet raises its download alert on the first failure, critical while CRL checking is on, because its clients are already being refused. The alerts are listed under CRL alerts.
When a revocation takes effect
Section titled “When a revocation takes effect”The first CRL of a CA applies at once. A replaced CRL applies within 5 minutes: FreeRADIUS rebuilds its CA store from the CRL files at most every 5 minutes, on the first new TLS session after that interval. Adding or removing a CRL source on a CA changes the revocation policy itself, which is applied as a new NAC configuration (see Applying a configuration): EAP conversations in flight at that moment start again.
End to end, a revocation by an external CA reaches clients after: its publication in
the CA’s next base CRL (delta CRLs are not used), plus up to the External CRL
Fetch interval (15 minutes by default), plus up to 5 minutes, plus the port’s next
authentication. A port that is already open stays open until it re-authenticates: a
revocation sends no CoA. To shorten that, publish the CRL at once on the CA
(certutil -CRL on AD CS) and give switch ports a re-authentication timer. A
revocation in an Internal CA re-signs its CRL immediately.
OCSP checking
Section titled “OCSP checking”Which certificates OCSP checks
Section titled “Which certificates OCSP checks”Check revocation with OCSP on a Trusted CA or an LDAP EAP-TLS configuration makes FreeRADIUS ask an OCSP responder about the client certificates of that CA and its sub-CAs, and of no other CA. It is independent of Enable CRL Check: a CA can be checked by CRL, by OCSP, or by both (a certificate revoked on the CRL is then refused without asking the responder).
In a record that holds a chain, OCSP marks the lowest certificates, those that issued nothing else in the record. A record holding a root and its issuing CA checks the clients of the issuing CA; another issuing CA under the same root, in a record without OCSP, is not touched. Only the client certificate is asked about, once per authentication, after its chain, dates and CRL have been checked. Internal CAs are never checked with OCSP: Taranac re-signs their CRL the moment a certificate is revoked and runs no responder.
Which responder is asked
Section titled “Which responder is asked”- The record’s OCSP responder URL, when it is set, whatever the certificate says. It is taken from the nearest checked CA of the chain, starting at the issuing CA.
- Otherwise the first
http://OCSP address in the client certificate’s Authority Information Access (AIA).httpsandldapentries are skipped. - Neither: the check cannot be made and the client is refused.
Requests carry no nonce (Microsoft’s Online Responder answers a nonce with
unauthorized). A response signed by the CA itself is accepted without its
certificate attached, and so is one from a delegated signer with the OCSP Signing
purpose. A response is accepted within its thisUpdate/nextUpdate window (5 minutes’
tolerance); one without a nextUpdate only while it is at most 5 minutes old. There is
no response cache: every full handshake asks.
A client is refused whenever the check cannot be made
Section titled “A client is refused whenever the check cannot be made”There is no soft-fail. The client is refused when the responder says the certificate
is revoked, when it does not know the certificate, and when there is no answer to
use: no responder address, no reply in time, an HTTP error, a response that is not
successful (for example unauthorized), a signature or a date that does not check
out. Switch on OCSP only for a CA whose responder every node can reach.
The responder URL field
Section titled “The responder URL field”- Only
http://. OCSP responses are signed, so TLS adds nothing;https://is refused with its own message. A host is required (IPv6 in brackets), a port must be 1–65535, no user name or password (the URL is written into the daemon’s configuration and every OCSP refusal in the log), only printable ASCII with no spaces,",\or$, at most 512 characters. - Saving asks the responder first. When OCSP is on and a URL is set, and OCSP was
just turned on, the URL changed, or (on an LDAP configuration) the CA certificate
changed, Taranac asks that responder about this CA before anything is saved. If it
does not answer as FreeRADIUS needs, the save is refused with the reason at the URL
field: unreachable within 3 seconds, a redirect (FreeRADIUS does not follow one),
an HTTP error, not an OCSP response,
unauthorized, or revocation data out of date. The question comes from theapicontainer of the node you save on; FreeRADIUS asks from thenaccontainer of every node. - Leave it empty to use the address in the client certificates, when that address
is right. No question is asked on save then. That is also the way around responders
that answer
unauthorizedfor serial numbers they never issued (cfssl, Boulder), which the save check would otherwise refuse.
A change of the switch or the URL is applied as a new NAC configuration: EAP conversations in flight at that moment start again.
Threads, timeouts and DNS
Section titled “Threads, timeouts and DNS”One OCSP check gets about 3 seconds in total, waiting for a slot included. At
most 8 checks are in flight and 8 more wait for a slot; beyond that a check is
refused at once (tls_ocsp_failed, class busy). The NAC container runs 32
FreeRADIUS worker threads, so a dead or slow responder holds at most 16 of them and
MAB, PEAP and MFA pushes keep the rest. The slots are shared by all CAs: while one
CA’s responder is down, clients of another CA checked by OCSP may be refused as busy.
The nac container’s resolver gives up after 2 seconds with one retry, so a dead
DNS server cannot push a check past the switch’s RADIUS timeout. Give the responder a
name that resolves quickly from every node, or use its IP address.
TLS session resumption is off while any CA is checked by CRL or by OCSP: a resumed session skips the revocation check. Every EAP-TLS, PEAP and EAP-TTLS authentication then makes a full handshake.
What a refusal looks like
Section titled “What a refusal looks like”The NAC Auth Log (Logging & Reports → NAC Logs → Auth Log) names the cause of a refused client certificate, with OpenSSL’s error and the certificate’s issuer in the message:
| Reject reason | Shown as | Meaning |
|---|---|---|
tls_client_cert_revoked | EAP-TLS: the client certificate is revoked | Listed on its issuing CA’s CRL. |
tls_crl_missing | EAP-TLS: CRL checking is on, but no CRL is loaded for the client certificate’s CA | The chain is checked, and the issuing CA has no CRL: often a CRL configured on the root only. |
tls_crl_expired | EAP-TLS: the CRL of the client certificate’s CA has expired — publish a fresh CRL | The issuing CA’s CRL is past its next update. |
tls_client_cert_expired | EAP-TLS: the client certificate has expired | |
tls_client_cert_not_yet_valid | EAP-TLS: the client certificate is not yet valid (its start date is in the future) | Often a clock. |
tls_client_cert_untrusted | EAP-TLS: the client certificate’s issuer is not in the NAC Trusted CAs | No trusted CA issued it. |
tls_ocsp_revoked | OCSP check failed: the client certificate is revoked | The responder says revoked; the message gives its reason and time. |
tls_ocsp_unknown | OCSP check failed: the responder does not know the client certificate | Often a responder that serves another CA. |
tls_ocsp_failed | OCSP check failed: the check could not be completed | The class follows: transport (no usable answer in time), response (unauthorized, tryLater…), verify (signature, signer or dates), busy (no free slot), config (no responder address). |
Each OCSP row names the responder asked and the issuer. The raw data of the entry keeps every failure message FreeRADIUS reported.
Alerts
Section titled “Alerts”| Alert | Raised when | Severity |
|---|---|---|
OCSP responder not usable: <url> (nac_ocsp:responder_unreachable:<url>, per node) | A client was refused because the responder gave no usable answer (transport, response or verify). | error |
OCSP check impossible for clients of <issuer> (nac_ocsp:config:<hash>, per node) | The check could not be made at all, usually because there is no URL on the record and no OCSP address in the certificate. | error |
NAC CA bundle not updated: a trusted CA cannot be used (nac_ca_bundle:unreadable, per node) | A trusted CA’s certificate does not decrypt on this node or cannot be parsed, or a stored OCSP responder URL cannot be used. The CA bundle and the EAP configuration are kept as they were until it is fixed. | error |
NAC daemon does not understand the per-CA revocation policy (nac_daemon:ca_policy_unsupported, per node) | The node’s nac image is older than its api. It keeps requiring a CRL from every trusted CA, and is not given a configuration with OCSP: the previous one keeps running. Update the node’s images. | error |
The two OCSP alerts close after an hour without another such refusal, with no resolution notice: FreeRADIUS logs no success, and silence does not prove the responder answers again. CRL download and expiry alerts are on PKI & trust.
Microsoft Online Responder (AD CS)
Section titled “Microsoft Online Responder (AD CS)”- A Revocation Configuration for every issuing CA whose clients you check.
Without one the responder answers
unauthorized: a saved URL is refused, and with the URL empty every client is refused. - The signing certificate from the OCSP Response Signing template. The responder attaches it to its answers.
- Nonce support can stay as it is. Taranac sends no nonce.
- Set the Web Proxy cache to 0 entries. By default the responder answers from its
cache until the response’s nextUpdate, and a revocation is not seen until then.
Restarting the OCSP service does not clear that cache; recycling the
OCSPISAPIAppPoolapplication pool does. - The responder learns of a revocation from its CA’s CRL. A revocation reaches it once the CA publishes a CRL and the responder’s CRL refresh interval has passed.
- The OCSP address reaches the AIA only of certificates issued after it was configured on the CA. For older certificates, set the OCSP responder URL on the Trusted CA or LDAP configuration.
In a cluster
Section titled “In a cluster”Each node downloads CRLs and asks OCSP responders on its own, so a distribution point or a responder must be reachable from every node. Refusals in the log and the OCSP alerts carry the node. A responder that only one node can reach is saved on that node, or left empty if the certificates’ AIA is right.
Diagnosing
Section titled “Diagnosing”./taranac diagnose --protocol nac collects what the daemon sees: which CAs are
checked against a CRL and why, which clients would be refused for a CRL of the wrong
level, the CRLs on disk against those in the database, which CAs are checked with OCSP
and with which responder, the last day’s OCSP refusals, and a live question to each
responder URL.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Cause | Fix |
|---|---|---|
Every client of one sub-CA refused, tls_crl_missing | A CRL is configured on the root (or on a record holding the chain), not on the issuing CA | Add the issuing CA’s CRL, on the same record or a record of its own |
Every client of one CA refused, tls_crl_expired | Its CRL stopped being refreshed | Check the Last fetch error and the CRL alerts; publish a fresh base CRL |
| A revoked certificate still gets in | Enable CRL Check is off, no CA of the chain has a CRL, the CA has not published a new base CRL yet, or the port has not re-authenticated | Check the switch and the CA’s CRL; give the port a re-authentication timer |
Every client of an OCSP-checked CA refused, tls_ocsp_failed transport | The responder is not reachable from the nac container of this node | Open HTTP from every node, or fix the URL |
tls_ocsp_failed response with unauthorized | The responder does not serve this CA (on AD CS: no Revocation Configuration) | Configure the responder for the issuing CA |
tls_ocsp_unknown | The responder serves another CA, or does not know this certificate yet | Point the URL at the responder of the issuing CA |
tls_ocsp_failed config | No URL on the record and no OCSP address in the certificate | Set the OCSP responder URL |
| A revocation takes a day or more to show over OCSP | The Online Responder answers from its Web Proxy cache | Set the cache to 0 entries |
Related
Section titled “Related”- PKI & trust — where each CRL comes from, downloads, CRL alerts, publishing a CRL
- Taranac under your corporate root — upper-chain CRLs, which EAP-TLS does not use
- 802.1X authentication — EAP-TLS trust and identity
- EAP-TLS for domain users — the AD CS walkthrough
- LDAP / Active Directory — the EAP-TLS tab
- Alerts