Expand description
TLS machinery for listeners (DW-007, feature analysis 4.10 / 4.13).
Responsibilities:
- process-global crypto provider installation (aws-lc-rs; must happen before the first rustls object is created),
- building a hot-reloadable
rustls::ServerConfigfrom aListenerTlsterminate block, with SNI-based certificate selection (the singlecert_file/key_filepair is the fallback certificate,certificatesentries are matched by SNI), - outbound TRUST for https dials (#121): the default webpki public
root set, PEM-bundle root stores for the
trusted_ca_fileconfig field (private CAs), and the shared HTTP/1.1 client-config shape used by upstream connectors, active health probes, and the JWKS fetcher, - a minimal TLS ClientHello SNI parser used by passthrough routing, and the passthrough byte-splice itself.
Hot reload model: TlsTermination keeps the current
Arc<rustls::ServerConfig> behind an ArcSwap. Each accepted
connection clones the current Arc into a fresh TlsAcceptor, so a
swap only affects handshakes that start after it: in-flight TLS
sessions keep their negotiated configuration and existing connections
are never dropped by a reload.
Documented v1 limitation: TLS 1.3 and 1.2 are both enabled with rustls’s default (modern) cipher-suite policy; no cipher/version overrides are configurable yet.
Structs§
- SniCert
Resolver - SNI-aware certificate resolver: exact server-name match against the
certificatesentries; falls back to the single pair (or the first entry when no pair is configured). Names are compared lowercase per the SNI specification. - TlsTermination
- A hot-reloadable TLS termination configuration for one listener.
Enums§
- Passthrough
Action - Passthrough routing outcome.
- Spiffe
Mtls Config - A SPIFFE-aware mTLS rustls config: either a client config (for
outbound upstream connections) or a server config (for inbound
listener connections). Built from an X.509 SVID and a trust
bundle by
build_spiffe_mtls_config. - Spiffe
Mtls Role - The mTLS role the SPIFFE-aware TLS config plays for a connection. Inbound sidecar connections act as the mTLS server (terminate the peer’s SVID); outbound sidecar connections act as the mTLS client (present the local workload’s SVID).
- TlsError
- Error loading or building TLS material.
Functions§
- admin_
mtls_ server_ config - Build the mTLS-ONLY
rustls::ServerConfigfor the admin listener (DW-022, decision 6). Client certificates are REQUIRED and must chain to the CA inclient_ca_file(WebPkiClientVerifierover a root store loaded from that PEM); the server presents the single cert/key pair. The key is checked against the leaf exactly like dataplane termination, so a torn pair cannot boot. ALPN advertises HTTP/1.1 only — the admin API is a small request/response surface. - build_
spiffe_ mtls_ config - Build a SPIFFE-aware mTLS rustls config from an X.509 SVID and a trust bundle. This is the integration point between the mesh domain (which fetches SVIDs from the SPIRE Workload API) and the TLS machinery here.
- extract_
spiffe_ id_ from_ peer_ cert - Extract the SPIFFE ID (the URI SAN) from a verified peer certificate. This is the auth identity the mesh uses for policy decisions: the sidecar terminates mTLS, verifies the peer SVID against the trust bundle, then extracts the SPIFFE ID from the peer cert’s URI SAN and hands it to the auth layer as the principal/consumer.
- fingerprint_
colon_ hex - Format the SHA-256 fingerprint of a certificate DER as lowercase
colon-separated hex (DW-035): the format the
mtls_consumer_mapping.consumers[].fingerprintconfig field and theX-Client-Cert-Fingerprintforwarding header use. The raw hex (no colons) is the credential SELECTOR the authn registry indexes; this colon-separated form is the OPERATOR-facing display format (config and headers), so the two never collide. - handle_
passthrough - Peek the ClientHello off a passthrough connection, decide the route, and either splice both directions to the upstream or close.
- https_
h1_ client_ config - HTTP/1.1-ALPN rustls client config over the given trust roots: the
shared shape for every outbound https dial that speaks HTTP/1.1 —
https-protocol upstream connectors, active health probes, and the JWKS fetcher (#121). Keeping one constructor here means a config generation applies IDENTICAL trust and handshake policy across the pooled client, the probes, and the fetcher;http2upstreams build their own config (same roots,h2ALPN). - https_
h1_ client_ config_ pq - DW-105: HTTP/1.1-ALPN rustls client config with post-quantum hybrid
key exchange opt-in. When
pqistrue, the config is built with a provider that has the X25519+ML-KEM hybrid kx group prepended. The classical X25519 group remains as a fallback for non-PQ servers. Whenpqisfalse, this is identical tohttps_h1_client_config. - https_
h1_ client_ config_ with_ auth - SEC-03: HTTP/1.1-ALPN rustls client config WITH client auth (mTLS
to the upstream). Loads the client cert chain and private key from
PEM files and installs them via
with_client_auth_cert. Used when an upstream configuresmtls.client_cert_file+mtls.client_key_file. Fails withTlsError::Iowhen the files cannot be read or parsed. - https_
h2_ client_ config_ with_ auth - SEC-03: HTTP/2-ALPN rustls client config WITH client auth (mTLS to
the upstream). Same as
https_h1_client_config_with_authbut withh2ALPN and a client locked to HTTP/2. - https_
h3_ client_ config - HTTP/3-ALPN rustls client config over the given trust roots (DW-108):
the shared shape for every outbound H3/QUIC dial — the H3 upstream
connector and the QUIC active health probe. QUIC mandates TLS 1.3,
so this always negotiates
h3over the same root store the pooled https connector would use (#121: webpki by default, the upstream’strusted_ca_filebundle when configured). Keeping the constructor here means one trust/handshake policy across the pooled H3 client and its probes, mirroringhttps_h1_client_config. - install_
aws_ lc_ rs_ provider - Install the aws-lc-rs crypto provider as the process-global rustls default. Idempotent: installing twice (e.g. binary + tests in one process) returns Ok the first time and an ignorable error afterwards.
- issuer_
cn_ of_ leaf - Extract the issuer CommonName of a leaf certificate (DW-035): the
value of the FIRST CN attribute (OID 2.5.4.3) in the issuer RDN
sequence. Same strict UTF-8 decode as
subject_cn_of_leaf;Nonewhen the issuer carries no decodable CN. THE CERTIFICATE IS ALREADY VERIFIED at the TLS layer when this runs; extraction only reads the value for theX-Client-Cert-Issuer-CNforwarding header. - not_
after_ unix_ secs - Extract the
notAftertimestamp of a leaf certificate (DW-035) as Unix epoch seconds. The validity SEQUENCE holds two time values:notBeforethennotAfter, each a UTCTime (tag 0x17, YYMMDDHHMMSSZ) or GeneralizedTime (tag 0x18, YYYYMMDDHHMMSSZ). ReturnsNoneon any structural shortcoming or an unparseable time. THE CERTIFICATE IS ALREADY VERIFIED at the TLS layer when this runs; extraction only reads the value for theX-Client-Cert-Not-Afterforwarding header. - peek_
client_ hello_ sni - Peek the TLS ClientHello SNI off a TCP stream WITHOUT splicing.
- resolve_
passthrough - Resolve a passthrough SNI route against the gateway config.
- root_
store_ from_ pem_ file - Build a rustls
RootCertStorefrom a PEM file of CA certificates (#121). The file may carry SEVERAL certificates — a typical CA bundle lists an anchor plus intermediates — and every certificate in it becomes a trust anchor. Fails withTlsError::Iowhen the file cannot be read or parsed, and withTlsError::EmptyPemwhen it parses to zero certificates (an empty trust set is always a configuration mistake, never a valid “trust nothing” — that would silently fail every TLS handshake). - sni_
from_ client_ hello - Parse the SNI server name out of a TLS ClientHello, reassembling handshake fragments across records when the hello does not fit in one (#120).
- spki_
of_ leaf - Extract the DER-encoded SubjectPublicKeyInfo of a leaf certificate by
walking Certificate -> TBSCertificate -> (version?) serial, signature,
issuer, validity, subject, SPKI. Returns the SPKI DER including its own
SEQUENCE header (the same encoding
SigningKey::public_keyyields) or None on any structural shortcoming (treated as a mismatch by the caller, which rejects). - subject_
cn_ of_ leaf - Extract the subject CommonName of a leaf certificate (#124): the
value of the FIRST CN attribute (OID 2.5.4.3) in the subject RDN
sequence, decoded from UTF8String / PrintableString / IA5String (the
string types CNs carry in practice). The decode is STRICT UTF-8:
invalid CN bytes yield
Nonerather than being lossy-folded to U+FFFD, which could collide two distinct malformed names into one selector.Nonealso when the subject carries no CN at all — either way such a certificate can only match a by-fingerprint mTLS credential (the caller falls back to the fingerprint selector). Hand-rolled DER walk (no X.509 parser dependency), same substrate as the private SPKI extractor in this module. THE CERTIFICATE IS ALREADY VERIFIED at the TLS layer when this runs; extraction only reads the match value. - system_
root_ store - REL-08 (#219): the OS-native root CA store as a rustls
RootCertStore. Loaded viarustls-native-certs, which reads the platform trust store (macOS keychain, Linux CA bundle, Windows root store). Used by upstreams that opt intouse_system_rootsinstead of the bundled webpki set. Failures to load native certs fall back to the webpki set rather than failing every TLS handshake, because a missing OS trust store is a deployment mistake, not a security decision — and the operator’s intent (“trust the OS”) is best approximated by “trust what we have” rather than “trust nothing”. - webpki_
root_ store - The Mozilla (webpki) public root set as a rustls
RootCertStore: the DEFAULT trust for every outbound https dial — upstream connectors, active health probes, and the JWKS fetcher (#121 made the per-entity override configurable; this remains what an entity without atrusted_ca_fileverifies against). Lives here, next to the other root-store machinery, so all outbound callers share one definition instead of each rebuilding it inline.
Type Aliases§
- Endpoint
Picker - Endpoint resolver for passthrough routing: maps an upstream NAME to a
load-balanced
(address, port). The dataplane caller builds it from the CURRENT registry (see dwara-bin’s listener), so passthrough picks follow config reloads;Send + Syncbecause the passthrough path runs on spawned tasks.Nonemeans “no dataplane” — the first configured endpoint is used.