Skip to main content

Certificate Trust and Revocation

A certificate principal authenticates to the key server (kS) with an X.509 certificate and the private key that goes with it. This page describes the checks the kS applies at every certificate login, in the order it applies them, and how it learns that a certificate has been revoked. The same checks apply wherever the kS resolves a certificate to a principal: the certificate login (AM08), the TLS client-certificate lookup on a mutually authenticated connection, and the target of a delegated login.

Every check is made at use, against the kS's clock and its database at that moment — not once at enrolment and remembered.

The login is bound to its TLS connection

The certificate login module, X509Authentication (AM08), sends a random challenge. The client proves possession of its key by signing a message that binds that challenge to the TLS connection it arrived on (ADR-0104, ADR-0107):

M = "TE-AM08-CHANNEL-BOUND-v1" || 0x00 || SHA-256("tls-exporter:" || exporter) || challenge

exporter is the connection's RFC 9266 channel binding — 32 bytes of TLS exporter output under the label EXPORTER-Channel-Binding — and M is 89 bytes. The client signs M under its key's own scheme:

KeySignature
RSARSASSA-PSS, SHA-256, MGF1-SHA-256, salt length exactly 32
ECECDSA over SHA-256, DER-encoded

Nothing else is accepted and nothing is negotiated. The kS verifies against its own copy of the exporter, which no client and no relay can learn, so a signature made for one connection cannot be replayed on another, and a relay that terminates TLS and re-originates it cannot forward the login. The exporter exists only on TLS 1.3, which every kS listener requires; a connection with no exporter is refused by name.

The SDK clients build M for you: see TEX509AuthenticationContext (C++) and X509Context (Java).

The checks, in order

1. Validity

The certificate is refused if the kS's clock is before its notBefore or after its notAfter (ADR-0108). Both bounds are inclusive and there is no clock-skew allowance. The refusal names the bound: certificate not yet valid: notBefore … or certificate expired: notAfter …. An already-expired certificate is also refused at enrolment; a certificate whose notBefore is in the future is admitted at enrolment as planned activation and refused at use until that time.

2. Fitness for authentication

Read from the certificate's own extensions (ADR-0109):

  • a keyUsage extension that does not include digitalSignature — refused;
  • an extendedKeyUsage extension that does not include clientAuth — refused;
  • extensions that do not parse — refused;
  • an absent extension — admitted.

The refusal begins certificate not permitted for authentication:. The same rule is applied at enrolment, so an unfit certificate cannot be enrolled in the first place.

3. Trust

The policy parameter Policy.X509.TrustMode selects what the kS trusts (ADR-0111):

ValueMeaning
pinned-leaf-and-ca (shipped)The presented certificate must be the exact enrolled leaf, and it must chain to an anchor the kS trusts at that moment — a certificate authority in its trusted list, or the kS's own issuing CA.
pinned-leafThe exact enrolled leaf; no chain is required.

Any other value refuses the kS's start. Anchors are read from the database at every check, so removing a CA from the trusted list takes effect at the next login, and an expired anchor anchors nothing. Fitness is required in both modes.

4. Revocation

The kS asks whether the certificate is still good, and refuses when it cannot tell (ADR-0115). Three outcomes refuse a login:

Refusal beginsWhen
certificate is revoked:The issuer's CRL lists the certificate. Always refused, whatever the policy.
certificate revocation status is unavailable:The kS holds no revocation evidence for the issuer, and the policy says refuse.
certificate revocation evidence is stale:The evidence is older than the policy allows, or past its nextUpdate, and the policy says refuse.

The policy is read from Policy.X509.Revocation.Issuer.<digest> for the issuer, else Policy.X509.Revocation.Default. The shipped default is

evidence=crl;max-age=24h;refresh=1h;fallback=refuse

— it fails closed. Certificates issued by the kS's own CA are exempt; a certificate issued by an external CA is refused until that CA's CRL has been imported or a per-issuer policy says otherwise. Plan for that step when you enrol users under an external CA.

A session that is already open is re-evaluated at its next operation when its certificate is revoked; revocation does not wait for the session to end.

How a CRL reaches the kS

Imported

A Security Officer imports a CRL with the administrative operation IMPORT_CRL; the C++ SDK surface is TEAdminCertificate::importCRL. The kS validates a CRL once, when it arrives (ADR-0114) — issuer authority, signature, scope and freshness, in that order — and refuses it with a message beginning CRL refused: if any check fails. Delta CRLs, indirect CRLs and CRLs carrying an issuingDistributionPoint are refused, as is a CRL that is already stale. A CRL is accepted only if it is newer than the one held for that issuer, and it then replaces that issuer's evidence in one transaction.

Accepted revocation entries are stored as indexed rows in the key database, so a login's revocation check is a lookup, not a parse. Two further operations read them back: GET_REVOCATION_EVIDENCE (the CRL held for an issuer — TERevocationEvidence) and LOOKUP_REVOCATION (one certificate's answer: revoked, not listed, or no evidence — TERevocationLookup).

Fetched

The kS can also fetch a CRL itself (ADR-0116). The URL comes only from the url= clause of the issuer's revocation policy — the kS never follows a certificate's cRLDistributionPoints extension — and must be http://. The fetch runs on the policy's refresh= cadence, and a fetched CRL is judged exactly as an imported one. A failed fetch changes nothing: the evidence already held stays in force until max-age makes it stale. A login never triggers a fetch.

Remote engines

A Remote Engine (rE) holds no revocation evidence of its own and offers no certificate login (ADR-0119). Online, it takes every key from the kS at the moment of use, so a revocation the kS has recorded is honored immediately. Offline, it serves the keys it checked out, with the authority it had when it checked them out. The kS checks the engine's own certificate at every handshake it makes upstream.