re-baseline the four pending remediation tasks against the ADR-007/008 tree
The tasks were decomposed (d7db6b1) before 49d4432/ac440f3 landed;
both commits touched exactly the areas the tasks reference. Fixes
grounded in verified sources (vendored rustls-acme 0.12.1, rustls-pemfile
2.2.0, rustls-native-certs 0.8.4) and a fresh cargo llvm-cov run:
- acme-event-loop-test: the termination assertion was impossible —
rustls-acme's Stream for AcmeState never yields None
(state.rs:407-412, poll_next_infinite + 2^16s backoff); the review's
U-1 exit-condition premise is withdrawn and corrected in place.
Replaced with timeout-bounded event collection, a reachable-arm
inventory (Order warn, AccountCacheStore, Load/Parse error arms,
DeployedCachedCert/CertCacheStore via deterministic DirCache file
pre-seeding), and an explicit mark for the full-fake-CA arms.
server.rs:135 flagged as unreachable dead code (delete or accept).
- coverage-cheap-closes: re-baselined per-line ground truth — original
groups 1 and 5 are already closed by the handshake suites; group 2's
TLS 1.3 half is covered, leaving the TLS 1.2 else-arm (client.rs:316);
new group added for VerifyPresentedCertVerifier::verify_tls12_signature
(server.rs:349-366, opened by ADR-008; required for the >=98% bar);
AcceptAnyCertVerifier refs moved to server.rs:468-475 with the stale
OQ-TLS-09 coordination caveat retired.
- docs-pin-c1-c4-n3-n4: N-4 re-scoped (the mechanism analysis already
lives in ADR-007 + the resolver doc block; what remains is a short
server-verifier note covering both verifiers); C-4 updated for
ADR-007's negotiation-earlier failure point; added the
FingerprintPinVerifier pop cross-ref update (post-ADR-008 the default
verifier does verify possession).
- config-validation-and-trivia: added the feature-gate mechanics note
for the C-3 test (a non-gated test passes vacuously under default
features); refreshed drifted line refs with a re-grep advisory.
- review 001: Status block records OQ-TLS-09/-10 resolutions; U-1
carries the termination correction; U-2 carries the supersession
note. ADR-008 gains the suite-number-to-test-name mapping.
Verification: taskgraph validate 14 tasks; cargo doc --no-deps
warning-free; all edits docs-only (no code paths touched).
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: coverage-cheap-closes
|
||||
name: Cheap coverage closes — resolver resolve() calls, non-Ed25519 pin arm, PEM parse-error arm, fallback seam (U-2)
|
||||
name: Cheap coverage closes — non-Ed25519 pin arms, PEM parse-error arm, fallback seam, escape-hatch methods (U-2, re-baselined)
|
||||
status: pending
|
||||
depends_on: []
|
||||
scope: narrow
|
||||
@@ -12,56 +12,84 @@ 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:
|
||||
The coverage inventory (review 001 Part C) — **re-baselined
|
||||
2026-09-12 by a fresh `cargo llvm-cov --all-features` run** after
|
||||
ADR-007/ADR-008 landed (commits `49d4432`/`ac440f3`): the new
|
||||
handshake and impersonation suites already closed two of the original
|
||||
groups, and ADR-008's new verifier opened one new gap. Current
|
||||
per-line ground truth (all line numbers re-verified against the
|
||||
current tree):
|
||||
|
||||
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
|
||||
1. **client.rs:316** — `FingerprintPinVerifier::
|
||||
verify_tls12_signature`'s non-Ed25519 else-arm
|
||||
(`rustls::crypto::verify_tls12_signature`) is never executed. (The
|
||||
original group-2 text pointed at the TLS 1.3 twin at 297/316-322 —
|
||||
that TLS 1.3 arm is now covered by the handshake suite's pin
|
||||
suites; only the TLS 1.2 else-arm remains.) Pinned test: an
|
||||
ECDSA-P256 rcgen cert + `dss_with_scheme` (P256/SHA256) against
|
||||
`verify_tls12_signature`, assert ok, then a forged sig → err.
|
||||
Mirrors the existing Ed25519 TLS 1.3 routing pin
|
||||
(`fingerprint_pin_verifier_routes_ed25519_spki_tls13_signature_
|
||||
through_raw_key_path`, client.rs:472).
|
||||
2. **server.rs:349-366** — `VerifyPresentedCertVerifier::
|
||||
verify_tls12_signature`'s body (ADR-008's default verifier; did
|
||||
not exist at decomposition time) is entirely uncovered: no TLS 1.2
|
||||
handshake exists in the suite. Same pop-routing shape as the pin
|
||||
verifier (Ed25519-SPKI → `verify_tls13_signature_with_raw_key`,
|
||||
else `verify_tls12_signature`). A direct unit-call test (Ed25519
|
||||
SPKI + valid sig → ok; wrong-key or mismatched-message dss → err)
|
||||
closes it. **This group must be included or the ≥98% acceptance
|
||||
bar is unreachable while the ACME loop stays open** (owned by
|
||||
`acme-event-loop-test`).
|
||||
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
|
||||
exercises it. Verified against rustls-pemfile 2.2.0: malformed
|
||||
base64 in a keyed section is a real `Error::Base64Decoding`-class
|
||||
`Err` from `private_key` — the prescribed input works.
|
||||
4. **client.rs:145-148** — 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
|
||||
test. (`rustls_native_certs::CertificateResult` has public `certs`
|
||||
/ `errors` fields, so the seam shape is a plain refactor — see
|
||||
Work item 2.) The `tracing::warn!` for native-cert errors at
|
||||
client.rs:139 sits in the same uncovered pocket.
|
||||
5. **server.rs:468-475** — `AcceptAnyCertVerifier` (now the
|
||||
*escape-hatch* verifier post-ADR-008, moved to server.rs:429) is
|
||||
only partially covered by the impersonation suite's escape-hatch
|
||||
tests: `verify_tls12_signature`'s body and
|
||||
`supported_verify_schemes()` (468-475) are never called. Two-line
|
||||
test each (call, assert `Ok` / assert the nine-scheme list),
|
||||
making the no-pop posture explicit in the suite. (The original
|
||||
group-6 range 287-303 is now `VerifyPresentedCertVerifier`'s code
|
||||
— the file shifted under the ADR-008 commit.) Note: the original
|
||||
"coordinate with OQ-TLS-09's resolution" caveat is stale —
|
||||
OQ-TLS-09 is resolved (ADR-008), the escape-hatch posture is
|
||||
permanent and pinned by `tests/impersonation_posture.rs`.
|
||||
6. **fingerprint.rs:67** — the second disjunct
|
||||
(`len() != 33 || [0] != 0x00`) matrix case (34-byte bit-string +
|
||||
unused-bits ≠ 0 vs len ≠ 33). Cosmetic.
|
||||
|
||||
**Already closed by the ADR-007/ADR-008 suites (do not redo):** the
|
||||
client resolvers' `resolve` calls (original group 1 —
|
||||
`RawKeyClientCertResolver::resolve` and `NoClientCertResolver::resolve`
|
||||
are exercised by the handshake suites) and `RawKeyCertResolver::resolve`
|
||||
(original group 5 — exercised end-to-end by
|
||||
`tests/handshake_behavior.rs`, e.g.
|
||||
`raw_key_client_presents_spki_and_server_extracts_fingerprint`).
|
||||
`FingerprintPinVerifier::verify_tls13_signature`'s non-Ed25519 arm
|
||||
(original group 2's TLS 1.3 half) is also covered.
|
||||
|
||||
## 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
|
||||
2. Item 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.
|
||||
@@ -69,24 +97,28 @@ tests closes them all. Per group:
|
||||
|
||||
## 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)
|
||||
- [ ] `cargo llvm-cov --all-features` shows the six groups covered
|
||||
(client.rs 316/145-148, pem.rs 30, server.rs 349-366/468-475,
|
||||
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
|
||||
- [ ] Line coverage ≥ 98% (from 95.81% currently; 95.32% at
|
||||
decomposition) with every load-bearing uncovered group closed
|
||||
- [ ] No public-API growth
|
||||
|
||||
## References
|
||||
|
||||
- docs/reviews/001-implementation-review.md §U-2, Part C (the inventory)
|
||||
- docs/reviews/001-implementation-review.md §U-2, Part C (the
|
||||
inventory rows for the closed groups are stale — this task's
|
||||
Description is the current baseline)
|
||||
- src/client.rs, src/pem.rs, src/server.rs, src/fingerprint.rs
|
||||
- tasks/handshake-tests.md (the overlap note for group 5)
|
||||
- tests/handshake_behavior.rs (the suites that closed original groups
|
||||
1 and 5), tests/impersonation_posture.rs (the escape-hatch pins —
|
||||
group 5's `verify_tls13_signature` coverage comes from here)
|
||||
|
||||
## Notes
|
||||
|
||||
|
||||
Reference in New Issue
Block a user