Skip to content

quic: trust anchors are fixed at construction, so a rotation cannot change who may connect #201

Description

@MDA2AV

A cross-stack difference in what ReplaceCertificates can do, which matters because the same operational runbook works on one stack and silently does nothing on the other.

On TCP, anchors given as TlsOptions.ClientCaPath are re-read from that path on every rotation. That is deliberate and documented, and it is how an issuer is revoked without a restart — RotationTests pins both directions ("trust anchors are re-read, so who may connect can be changed", "an anchor file emptied under a rotation stops admitting anyone").

On QUIC the verifier is built once, in iq_engine_new_mtls, and every certificate generation points at that same verifier. QuicEngine.ReplaceCertificates marshals only certificate and key paths — no CA — so anchors cannot be rotated at all. Both behaviours are now documented, but the gap is real: an operator who revokes an issuer by editing the bundle and rotating gets what they asked for on TCP and a no-op on QUIC, with nothing said.

Two ways out, and the choice is a design decision rather than a fix:

  • extend ReplaceCertificates (or add a sibling) to rebuild the verifier, which means the same build-then-publish care the certificate generations already get, since picotls keeps reading the verifier for the life of a connection;
  • or leave it and make the asymmetry loud — the docs now state it, but nothing refuses or warns.

Related: tests/Ioxide.Tests.Http/CrossStackParityTests.cs exists for exactly this class of divergence.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions