Skip to main content

client_config

Function client_config 

Source
pub(crate) fn client_config(
    options: &QuicDialOptions,
    alpn: Vec<Vec<u8>>,
) -> Result<ClientConfig, DialError>
Expand description

The one place either transport decides what a server certificate is checked against.

Shared, and that is the whole point of it. Two transports answering this question apart from each other answer it differently: a RootCertStore seeded from the webpki-roots bundle with ca_certs added to it on one side, wtransport’s with_native_certs() — the OS trust store, which never sees ca_certs — on the other. Two consequences, both of which a conformance run publishes as facts about the relay:

  • The bundled Mozilla set and a machine’s own set are not the same set. They diverge on newly-added roots, on roots a distribution has retired early, and on whatever a corporate MITM appliance installed. A relay would therefore pass over QUIC and fail over WebTransport with nothing about the relay differing between the two dials.
  • A caller supplying a private CA would have it honoured on one transport and silently dropped on the other. Not an error, not a warning — a handshake failure that looks exactly like a relay presenting a bad chain.

Bundled roots for both, rather than native for both, because a published measurement has to be reproducible: webpki-roots is a fixed set compiled into the binary, so two runs on two machines validate against the same anchors and any difference in the outcome is a difference in the relay. The cost is that a peer whose chain the operator trusts only via the OS store is not trusted here — that operator passes the CA in ca_certs, which is what the field is for and why it reaches both transports.

alpn is a parameter and not read off options because it is the one part of the handshake the two transports do not share: a QUIC dial offers the draft ALPNs it wants the server to choose between, a WebTransport session offers h3 and nothing else. Everything a certificate is judged by comes from options.

Returns DialError::TlsConfig for a ca_certs entry that is not a parseable certificate, and for a crypto provider without the AES-128-GCM suite QUIC’s initial packets are obliged to use.

§The initial suite is separate from the offered suites

QUIC encrypts its Initial packets with AES-128-GCM and has no say in the matter (RFC 9001 §5.2), which normally makes that suite impossible to leave out of an offer — and therefore makes “does this peer accept only ChaCha20” unaskable. QuicClientConfig::with_initial exists for exactly this: it takes the initial keys from one suite and lets the TLS config offer another. So when QuicDialOptions::cipher_suites excludes AES-128-GCM, the initial suite is taken from the process default provider and only the traffic suites are restricted.