Skip to content

TLS: defer root resolution so http:// fingerprint bootstrap works without configured roots #1907

Description

@kixelated

Follow-up from #1902 (CodeRabbit, thread).

Problem

client.rs::new() calls config.tls.build() (→ tls::Client::verification()) eagerly for every backend, and QuicheClient::new() resolves verification() too. Both run before any connect() sees the URL scheme. So in a roots-less configuration — --tls-system-roots=false with no --tls-root and no --tls-fingerprintverification() returns NoRoots and client construction fails, even though an http:// URL would fetch /certificate.sha256 and pin it (bypassing CA roots) for that connection.

Net effect: the http:// insecure-bootstrap path is unusable in environments with no system/custom roots. It's fail-closed (errors rather than connecting insecurely) and niche, but it's a real functional limitation and it's consistent across quinn/noq/quiche.

Fix sketch

Defer trust-root resolution to per-connection, after the URL scheme is known, so a fetched http:// pin can satisfy the connection without resolved CA roots. Touches client.rs (which currently builds the rustls config once and shares it), all three backends, and the websocket fallback path — hence deferred out of #1902.

Not a security issue (it only over-restricts).

(Written by Claude)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions