ADR-008: server-path possession verification — the verifying verifier is the default (OQ-TLS-09 resolved)
Close review 001 §S-1: the default client-cert verifier never checked the client's CertificateVerify, so anyone holding a peer's *public* cert/SPKI bytes (public by design — peers publish them to be dialable) could complete a handshake as that peer, and the auth layer could not detect it. The consumer designs are known (X.509 and raw-key TCP/QUIC endpoints with identity-bearing clients), so implementing now — the zero-consumer moment — avoids the guaranteed breaking republish of flipping the default later. - VerifyPresentedCertVerifier (new): request, don't require, verify possession — permissive verify_client_cert (self-signed chains and bare SPKIs stay valid presentation) + CertificateVerify routing by presented cert kind (Ed25519 SPKI -> verify_tls13_signature_with_ raw_key both TLS versions; X.509 -> standard route), the same routing FingerprintPinVerifier implements. Nine-scheme list verbatim (shared fn, exact-list pin covers both). - Default on every TlsServerConfig path — X509 / RawKey / SelfSigned / ACME (the verifier install is crate-side rustls in new_acme, not rustls-acme's). - AcceptAnyCertVerifier stays public as the explicit no-pop escape hatch, no longer installed by any crate path. - tests/impersonation_posture.rs: four pins — default rejects the attacker (X.509: UnsupportedSignatureAlgorithmForPublicKeyContext; raw-key: BadSignature), escape hatch still accepts + extracts the victim's fingerprint (both cert types). - tests/handshake_behavior.rs: suites 4/4b — possession-checked legit clients (raw-key pin vs raw-key server; X.509 client vs X.509 server) complete and the server extracts the fingerprint; suite 3b doc updated. - Docs: ADR-008 written; OQ-TLS-09 -> resolved (option (b)); ADR-007 §Limits deferral retired to not-planned; server.md/client.md invariants/README/overview synced. Verification: cargo test 81 / --features tcp 95 / --all-features 104 green; clippy -D warnings clean (default + all-features); fmt clean; cargo doc warning-free.
This commit is contained in:
+11
-10
@@ -88,15 +88,14 @@ offer from the pin format — an `ed25519:<hex>` pin offers
|
||||
`server_certificate_types = [RawPublicKey]` and completes against a
|
||||
crate-built raw-key server (`raw_key_server_path_completes_with_crate_pin_client`);
|
||||
a `SHA256:<hex>` pin keeps the X.509 offer. A raw-key *client*
|
||||
identity presents its SPKI under the X.509 offer and
|
||||
`AcceptAnyCertVerifier` accepts it end-to-end
|
||||
(`raw_key_client_presents_spki_and_server_extracts_fingerprint`). A
|
||||
pin-format/cert-kind mismatch fails closed at negotiation, never a
|
||||
identity presents its SPKI under the X.509 offer and the server's
|
||||
default verifier possession-verifies it end-to-end
|
||||
(`raw_key_client_presents_spki_and_server_extracts_fingerprint`,
|
||||
`raw_key_client_vs_raw_key_server_default_verifier_checks_possession`).
|
||||
A pin-format/cert-kind mismatch fails closed at negotiation, never a
|
||||
downgrade (`ed25519_pin_against_x509_server_fails_closed_at_negotiation`).
|
||||
Raw-key peers that ride iroh/noq use those transports' own TLS and are
|
||||
unaffected. The strict-server limit (a foreign server demanding
|
||||
raw-only client certs still rejects an X.509-offer presentation) is
|
||||
recorded in ADR-007 §Limits.
|
||||
unaffected.
|
||||
|
||||
## `FingerprintPinVerifier`
|
||||
|
||||
@@ -111,9 +110,11 @@ algorithms; Ed25519 SPKI certs route through
|
||||
`verify_tls13_signature_with_raw_key`): the presenter must prove
|
||||
possession of the corresponding private key, so a stolen or observed
|
||||
certificate cannot be used by a party that does not hold the matching
|
||||
key. This verifier checks proof-of-possession; the server-side
|
||||
`AcceptAnyCertVerifier` does not (see
|
||||
[server.md](server.md), OQ-TLS-09).
|
||||
key. The same possession rule now holds server-side:
|
||||
`VerifyPresentedCertVerifier` is the default client-cert verifier on
|
||||
every server path (ADR-008, OQ-TLS-09); `AcceptAnyCertVerifier`
|
||||
remains the explicit no-pop escape hatch (see
|
||||
[server.md](server.md)).
|
||||
|
||||
The cert-type offer follows the pin format (ADR-007):
|
||||
`requires_raw_public_keys()` returns `true` for `ed25519:` pins
|
||||
|
||||
Reference in New Issue
Block a user