Summary

  • TLS 1.3 certificate_authorities carries an ordered vector of DER-encoded Distinguished Names. It tells the receiver which CA names may guide certificate-chain selection; a name is not a certificate, trusted key, completed path or permission grant.
  • The extension can travel in either direction: a client can guide the server's certificate choice in ClientHello, and a server can guide client-certificate choice in CertificateRequest. The same wire shape does not make the two operating decisions interchangeable.
  • Defensible mutual TLS preserves four separate results: who generated the advertised list, why a credential was selected, which path and trust anchor were verified, and how the authenticated identity was mapped to an application action.

A certificate was selected, but no principal was admitted

Consider a service with two client certificates. One chains toward a CA name included in the server's CertificateRequest; the other does not. The TLS library selects the first, sends its chain and proves possession of its private key. The server verifies a path to an anchor in its current verification store.

None of that creates an application principal. The certificate may name the wrong tenant, carry an unrecognized URI SAN, omit a required role attribute or be valid for a purpose that the service does not authorize. The service can correctly return an access denial after a successful certificate verification.

The CA list was neither false nor useless. It narrowed selection. The mistake was turning a hint about possible certification paths into a statement about who may act. A control plane that stores only ca_match=true cannot reconstruct whether the client merely saw a name, selected a credential, passed path validation or received permission.

A Distinguished Name is not the thing it names

IANA assigns extension value 47 to certificate_authorities. RFC 9846 defines its payload as one or more DER-encoded X.501 Distinguished Names. A name may identify a desired trust anchor or a subordinate CA and should guide the certificate the peer chooses.

That compact representation is deliberate. The extension does not transmit the corresponding CA certificate, public key, constraints, policies or trust-store record. Two operationally different CA certificates can present the same subject name. A file can yield a subject name even when the contained certificate is not a CA. A matching string or DER name therefore cannot establish which key the sender trusts.

Trust anchors are normally configured independently and may be omitted from the certificate chain on the wire. Path validation needs the actual trust anchor and policy inputs, signatures, validity periods, basic and name constraints, key usage and other state defined by the PKI profile. Name membership cannot replace that work.

The only safe positive claim is narrow: at this message boundary, the sender advertised this encoded name in this ordered list. Presence does not prove every certificate beneath that name will be accepted. Omission does not prove universal distrust; a list may be bounded, privacy-reduced, unavailable, stale relative to another store or deliberately incomplete.

One extension, two directions

A client may include the extension in ClientHello. The client is then giving the server information that can influence which server certificate and alternate chain it presents. A server may instead include it in CertificateRequest to influence which client credential is returned.

The messages have different owners and different consequences. A client-side list can disclose organizational or trust naming information to the server; OpenSSL warns that those CA names are sent in plaintext. A server-side list can reduce client-certificate ambiguity but can also become large, expose PKI structure or exclude an otherwise usable credential through local selection behavior.

The legacy trusted_ca_keys extension is not the TLS 1.3 mechanism. A multi-version ClientHello may contain legacy signaling for older negotiation, but telemetry must identify the negotiated version, message context and extension type instead of labeling every CA-related field as the same policy.

Selection is an intersection, not a lookup

A CA-name match is only one input to credential selection. The peer also advertises signature algorithms and may separately constrain certificate-signature algorithms. The implementation considers key type, private-key availability, certificate validity, key usage, extended key usage, server name, OID filters and the alternate chains it can actually construct.

This produces useful negative evidence. A credential can be rejected because its issuer name is absent, because its signing algorithm is unacceptable, because its leaf lacks the right EKU, because the private key is missing, or because no offered chain reaches a named authority. Logging only the selected leaf discards the candidates and reason codes that explain the choice.

If a requested client has no suitable certificate, TLS 1.3 provides an honest result: an empty Certificate message. The server may then continue under its application profile or reject with certificate_required. Inventing a chain, falling back to an unrelated credential or treating absence as an anonymous success destroys the protocol's explicit boundary.

The advertised list and the verification store are separate controls

OpenSSL makes the separation unusually clear. Its CA-name list APIs configure names sent to a peer. They do not add the named certificates to the verification store. Trust must be loaded through verification-location or trust-store APIs.

The distinction creates a productive failure test. Configure a server to advertise a CA subject name while omitting the corresponding trusted key from its verification store. A client can select a matching chain, yet the server can reject it with unknown_ca. Reverse the mismatch and a locally trusted chain may exist even though its CA name was not advertised.

These are not library inconsistencies. They reveal independent generations of state: list generation and verification policy. Hot reload can change one without changing the other. Operations must record the hash and activation time of both, then bind each handshake to the generations it actually used.

OpenSSL's helper for loading client-CA names further shows why provenance matters: it extracts subject names, and the input is not limited to CA certificates. “The file loaded” is evidence of parsing, not proof that each entry represents a capable, trusted certification authority.

Verification authenticates a credential, not an application role

Once a peer sends a chain, RFC 5280 path processing and the applicable TLS profile determine whether it leads to an acceptable trust anchor under the required constraints. Endpoint identity rules then interpret names for the protocol in use. Those decisions are stronger than list membership, but they still stop short of business authorization.

A service must decide which authenticated identity maps to which tenant, account, workload, role and action. That mapping can depend on an exact SAN form, a namespace, issuer-plus-subject pair, certificate policy OID, enrollment state or an external entitlement. A valid certificate can remain unauthorized by design.

The client also cannot infer from a completed TLS exchange that the server considers it mutually authenticated for an application operation. Protocol and deployment provisioning may need to return an explicit application result. Treating “handshake complete” as “role granted” is an authority leak across layers.

Runtime callbacks prove paths only when they run

OpenSSL, GnuTLS and BoringSSL expose callbacks and getters for selection, CA names and certificate verification. Those surfaces are instrumentation opportunities, not evidence by mere configuration. A registered callback proves capability. A timestamped invocation tied to a connection proves execution.

BoringSSL constrains some CA-list views to a certificate-selection callback or a paused handshake lifetime. Retaining a pointer beyond that lifetime is not durable provenance; copy or hash the encoded values inside the valid scope. GnuTLS similarly separates certificate-selection callbacks from trust-list and TLS-session verification functions. Selected and verified are different events in the API as well as in the protocol.

Resumption changes the evidence boundary. In a PSK-resumed TLS 1.3 handshake, a server authenticating with the PSK does not conduct a fresh main-handshake CertificateRequest exchange. A metric must not claim that a new CA list was processed or a client certificate was re-evaluated when the relevant callback never ran.

Privacy, size and drift belong in the threat model

Distinguished Names can expose internal organization labels, jurisdiction strings and PKI hierarchy. Because a client-originated list is visible to the server, copying an enterprise trust inventory into every ClientHello can turn configuration into disclosure. Minimize the list for the actual selection need, document why it is sent and test what passive and active endpoints can observe.

Long lists also consume handshake bytes, parsing work and memory. The standard representation is bounded by its vector encoding, but an implementation still needs limits and failure behavior. Test numerous and oversized names without letting truncation silently change which authorities appear acceptable.

Drift is the more common risk. A list generator, credential selector, verifier and application authorization service may refresh on different schedules. Their disagreement is not captured by one boolean. Evidence should retain component version, policy generation, ordered name hashes, candidate outcomes, chosen chain, verified anchor and final application decision.

Negative tests that keep the hint in its lane

Advertise a DN while trusting no key with that identity. Trust one of two same-name CA certificates and offer a chain to the other. Select a name-matching certificate with an expired leaf, wrong EKU, forbidden policy or unavailable private key. Confirm that selection rejects the candidate before it becomes a generic authentication failure.

Allow the chain to validate, then deny the subject at the tenant or role boundary. Remove all suitable client credentials and observe an empty Certificate followed by the server's named decision. Change the verification store without changing the advertised list, and then change the list without the store. The resulting alerts should name which generation diverged.

Capture a ClientHello list to measure organizational disclosure. Exercise large name vectors. Resume a session and confirm no fresh-certificate counter increments. Install a callback and prove that telemetry distinguishes installed, invoked, selected, verified and authorized.

The resulting evidence ladder is precise: advertised name, candidate set, selected credential, proof of private-key possession, verified certification path, interpreted identity and authorized operation. Each rung has a different owner. No lower rung inherits the authority of the one above it.

Sources