review-001 decomposition: 6 remediation tasks from verified findings
Verify every review-001 finding before decomposition: - S-1 re-confirmed by fresh executable probe (X.509 + raw-key impersonation both complete the handshake with the victim's fingerprint extracted server-side) - U-2/U-3 uncovered-line inventory re-derived from cargo llvm-cov (--all-features); matches Part C exactly - rcgen 1975/4096 defaults, rustls cert-type negotiation arm, packaging list, doc texts: all verified against sources Tasks (all verified, none speculative): - fix-accept-any-cert-verifier-posture (S-1 + N-1 + OQ-TLS-09 + probe) - handshake-tests (U-3 suites 1-3; suite 4 lives in the S-1 task) - coverage-cheap-closes (U-2's seven groups) - acme-event-loop-test (U-1; depends on coverage-cheap-closes for the tracing-capture pattern) - config-validation-and-trivia (C-2 ALPN dedup, C-3 empty-domains, N-6 excludes, N-7 https doc line) - docs-pin-c1-c4-n3-n4 (C-1, C-4, N-3 decision note, N-4 negotiation note) Graph: acme-event-loop-test is generation 2; the rest run in generation 1. taskgraph validate: 14 tasks, no cycles. Verification: cargo test (default + --all-features) green before and after; probe file deleted after its run.
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
---
|
||||
id: coverage-cheap-closes
|
||||
name: Cheap coverage closes — resolver resolve() calls, non-Ed25519 pin arm, PEM parse-error arm, fallback seam (U-2)
|
||||
status: pending
|
||||
depends_on: []
|
||||
scope: narrow
|
||||
risk: low
|
||||
impact: component
|
||||
level: implementation
|
||||
tags: [tests, coverage, review-001, u2]
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
The coverage inventory (review 001 Part C, re-verified in the
|
||||
decomposition session — llvm-cov matches every listed range) shows
|
||||
several small, cheap-to-close gaps. One pass over unit + integration
|
||||
tests closes them all. Per group:
|
||||
|
||||
1. **client.rs 183-189, 212-218** — `RawKeyClientCertResolver::resolve`
|
||||
and `NoClientCertResolver::resolve` are never *called* by a test.
|
||||
One-line tests: `resolve` returns `Some(key)` for the raw-key
|
||||
resolver and `None` for `NoClientCertResolver`.
|
||||
2. **client.rs 297, 316-322** — `FingerprintPinVerifier`'s
|
||||
non-Ed25519 TLS 1.3 signature arm
|
||||
(`rustls::crypto::verify_tls13_signature`) is only covered by the
|
||||
deleted review probes. Pinned test: an ECDSA-P256 rcgen cert +
|
||||
`dss_with_scheme` (P256/SHA256), assert ok, then a forged sig →
|
||||
err. Mirrors the existing Ed25519 routing pin
|
||||
(`fingerprint_pin_verifier_routes_ed25519_spki_tls13_signature_through_raw_key_path`).
|
||||
3. **pem.rs 30** — the `Err(e) => Err(io::Error::other(e))` arm of
|
||||
`load_private_key` (a *parse* failure, distinct from "no key
|
||||
found") has no test: garbage-but-keyed file
|
||||
(`b"-----BEGIN PRIVATE KEY-----\n!!!\n-----END PRIVATE KEY-----\n"`)
|
||||
exercises it.
|
||||
4. **client.rs 144-147** — the webpki-roots fallback *push* loop is
|
||||
covered only nondeterministically (passes vacuously when the
|
||||
platform store is non-empty). Deterministic remediation: a
|
||||
`#[cfg(test)]`-visible helper taking the "native certs" as a
|
||||
parameter (or an injectable `load_native_certs` seam) so the
|
||||
empty-platform case is testable without root. This is a
|
||||
load-bearing invariant whose fallback branch has no deterministic
|
||||
test.
|
||||
5. **server.rs 341-346** — `RawKeyCertResolver::resolve` is never
|
||||
called (only `only_raw_public_keys()` is). A one-line assert
|
||||
(`resolve(hello).is_some()`) covers it — a `ClientHello` can be
|
||||
synthesized via `rustls::server::test_client_hello`-style helpers;
|
||||
the end-to-end raw-key handshake in `handshake-tests` also covers
|
||||
it, but the one-liner keeps this task independent of that one.
|
||||
6. **server.rs 287-303** — `AcceptAnyCertVerifier`'s two
|
||||
signature-assertion methods are never called by a test. Two-line
|
||||
test each (call, assert `Ok`), making the no-pop posture explicit
|
||||
in the suite. Note: this pins the *current* behavior; if
|
||||
OQ-TLS-09's resolution changes the verifier, these tests change
|
||||
with it (coordinate with `fix-accept-any-cert-verifier-posture`).
|
||||
7. **fingerprint.rs 67** — the second disjunct
|
||||
(`len() != 33 || [0] != 0x00`) matrix case (34-byte bit-string +
|
||||
unused-bits ≠ 0 vs len ≠ 33). Cosmetic.
|
||||
|
||||
## Work
|
||||
|
||||
1. Write the unit tests (in-module `#[cfg(test)]` where the items are
|
||||
private-visible, tests/ where public API suffices).
|
||||
2. Group (4) is the only one touching non-test code: extract a
|
||||
test-visible seam for the fallback loop. Keep the seam
|
||||
`#[cfg(test)]`-visible or behind a plain `pub(crate)` fn — do not
|
||||
grow the public API.
|
||||
3. Run llvm-cov and confirm the ranges close.
|
||||
|
||||
## Verification
|
||||
|
||||
- [ ] `cargo llvm-cov --all-features` shows the seven groups covered
|
||||
(client.rs 183-189/212-218/297/316-322, pem.rs 30, server.rs
|
||||
287-303/341-346, fingerprint.rs 67)
|
||||
- [ ] The fallback test deterministically exercises the push loop
|
||||
(platform-store-independent)
|
||||
- [ ] `cargo test`, `cargo test --all-features`, clippy, fmt green
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] Line coverage ≥ 98% (from 95.32%) with every load-bearing
|
||||
uncovered group closed
|
||||
- [ ] No public-API growth
|
||||
|
||||
## References
|
||||
|
||||
- docs/reviews/001-implementation-review.md §U-2, Part C (the inventory)
|
||||
- src/client.rs, src/pem.rs, src/server.rs, src/fingerprint.rs
|
||||
- tasks/handshake-tests.md (the overlap note for group 5)
|
||||
|
||||
## Notes
|
||||
|
||||
> Agent fills this during implementation.
|
||||
|
||||
## Summary
|
||||
|
||||
> Agent fills this on completion.
|
||||
Reference in New Issue
Block a user