docs-pin batch: self-signed validity, pin format-exactness, non-Clone decision, negotiation note (C-1, C-4, N-3, N-4)

- C-1: SelfSignedCert + generate_self_signed_cert document the
  rcgen-default validity (1975→4096, never expires in practice), no
  SANs (CA verification fails as designed — pairs with SHA256: pinning),
  and the additive not_before/not_after route if tighter validity is
  ever wanted
- C-4: RemoteIdentity::fingerprint + FingerprintPinVerifier document
  case-/format-exactness (pins produced by fingerprint_from_cert_der,
  lowercase hex, exact ed25519:/SHA256: prefixes); written from the
  ADR-007-corrected chain — same-format-but-wrong pins fail closed at
  the pin compare, cross-format mismatches fail earlier at cert-type
  negotiation (the review's original pin-compare mechanism superseded)
- N-3: TlsServerConfig doc records the keep-non-Clone-for-v1 decision
  (API identical across feature configurations; conditional Clone is
  its own trap); N-3 closed in review 001
- N-4: "Client-cert-type negotiation" section on
  VerifyPresentedCertVerifier (cross-referenced from
  AcceptAnyCertVerifier): requires_raw_public_keys() stays trait-default
  false on both server verifiers — do not fix to true (rejects X.509
  clients); the raw-only-offer rejection can only arise from a foreign
  resolver with only_raw_public_keys() == true — interop boundary of
  the request-not-require shape, fail-closed, not a downgrade; pinned
  by server_verifiers_keep_requires_raw_public_keys_default_false
- Work item 5: FingerprintPinVerifier's pop cross-ref now names both
  server verifiers (default VerifyPresentedCertVerifier verifies per
  ADR-008; AcceptAnyCertVerifier escape hatch does not)

Verification: cargo test (default, 69 lib tests) and --all-features
(78 lib tests, 1 new), clippy --all-targets --all-features -D warnings,
fmt --check, doc --no-deps warning-free — all green
This commit is contained in:
2026-09-12 04:28:58 +00:00
parent 9bdc32d848
commit 7713a6e210
5 changed files with 229 additions and 9 deletions
+19
View File
@@ -31,6 +31,19 @@ SPKI under the X.509 offer). The pending remediation tasks
against that tree — see the correction notes in each task file and in
§U-1/§U-2 below.
**Status update (2026-09-12, docs-pin batch): C-1, C-4, N-3, N-4 are
closed** by `tasks/docs-pin-c1-c4-n3-n4.md` (completed) as rustdoc
pins: the self-signed cert's never-expires/no-SAN facts (§C-1), the
pin's case-/format-exactness with the ADR-007 negotiation-earlier
failure point (§C-4), the non-Clone decision recorded on
`TlsServerConfig` (§N-3, closed as decided), and the
request-not-require negotiation boundary on the server verifiers
(§N-4, with the pinned
`server_verifiers_keep_requires_raw_public_keys_default_false` unit
test). The review's original §C-4 mechanism ("rejected at pin
comparison") is superseded by ADR-007 for the cross-format case — the
docs are written from the corrected chain.
**One correction to this review, found during the S-1 remediation:** the
N-4 parenthetical "alknet's own client resolver offers both types" is
**inaccurate** — rustls 0.23.41 and 0.23.44 both send
@@ -567,6 +580,12 @@ feature is its own trap (a consumer compiling both configurations
would see an API difference). Recorded as an observation, not a
change request; the all-features posture is the one the freeze pins.
**Remediation status (2026-09-12): closed by decision**
`tasks/docs-pin-c1-c4-n3-n4.md` (completed): `TlsServerConfig` stays
non-`Clone` for v1, the reasoning is recorded in the type's rustdoc
(src/server.rs), and this finding is closed. Revisit only if a
concrete consumer demands it.
## N-4 [minor, docs] — `AcceptAnyCertVerifier::root_hint_subjects() == &[]` means clients see no CA hints; combined with `client_auth_mandatory() == false` this is the correct request-not-require shape, but `requires_raw_public_keys()` (the trait's third relevant knob, rustls `src/verify.rs:143`, default `false`) is never overridden — correct here (the verifier accepts both X.509 and RFC 7250 client certs), worth one doc sentence so the next reader doesn't "fix" it to `true` for the raw-key peers
The raw-key client path works because rustls negotiates the