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.