Skip to content

test(cms): boundary tests for DER length-encoding helpers#15

Merged
jamestexas merged 1 commit into
mainfrom
feat/audit-r3-length-boundaries
Jun 17, 2026
Merged

test(cms): boundary tests for DER length-encoding helpers#15
jamestexas merged 1 commit into
mainfrom
feat/audit-r3-length-boundaries

Conversation

@jamestexas

Copy link
Copy Markdown
Collaborator

Summary

Round 3 of the audit-equivalent hardening — kills the cluster of length-encoding boundary mutants that survived rounds 1 and 2.

Why these survived previous rounds

Integration and roundtrip tests sign data of one specific shape and observe one specific length. Mutation testing's CONDITIONALS_BOUNDARY mutants (`if length < 128` ↔ `if length <= 128`) only differ in behavior at the exact boundary values — values no production-API test happens to hit. They report as LIVED even though the helpers run on every sign call.

The fix is direct table tests on the helpers with byte-exact expected output at both sides of every DER length-form boundary.

What's added

`pkg/cms/length_boundary_test.go` — three table-driven tests sharing the same case table:

Case range Expected encoding (per X.690 §8.1.3.4)
0 / 1 short form, one byte
126 / 127 / 128 / 129 short ↔ long-1 boundary
254 / 255 / 256 / 257 long-1 ↔ long-2 boundary
65534 / 65535 / 65536 / 65537 long-2 ↔ long-3 boundary
  • `TestMakeSequenceHeaderBoundaries` — asserts `makeSequenceHeader` emits exactly `0x30 ` for each.
  • `TestMakeSetHeaderBoundaries` — same for `makeSetHeader` with `0x31` tag.
  • `TestMakeHeader_Roundtrip` — cross-checks producer/consumer consistency: every header `makeSequenceHeader` emits must parse cleanly via `parseASN1Length` (the strict-DER consumer) and recover the original length. Locks in the invariant against future drift between signer and verifier.

Mutation testing impact

Metric Before round 3 After round 3 Δ
Killed 197 203 +6
Lived 50 44 -6
Test efficacy 79.76% 82.19% +2.4
Mutator coverage 85.76% 85.76%
Statement coverage 78.9% 79.2% +0.3

All 6 boundary mutants in `signer.go:879/881/883/895/897/899` (and their `CONDITIONALS_NEGATION` siblings) are now killed.

Test plan

  • CI green
  • `go test ./pkg/cms -run 'TestMake(Sequence|Set)Header|TestMakeHeader_Roundtrip' -v` passes
  • `make mutation-test` reports >=82% efficacy

🤖 Generated with Claude Code

Round 3 of the audit-equivalent hardening: kills the cluster of
length-encoding boundary mutants in the DER header helpers that
survived previous rounds.

Why these survived before:

  Integration tests sign data of one shape and observe one length, so
  every CONDITIONALS_BOUNDARY mutant (e.g. `if length < 128` ↔
  `if length <= 128`) flips behaviour only at the exact boundary
  values — values no production-API test ever happens to hit. Mutation
  testing therefore reported them as LIVED even though the helpers
  are exercised on every sign call.

What's added (pkg/cms/length_boundary_test.go):

  - lengthEncodingCases: a table of 14 lengths probing both sides of
    every DER length-form boundary (0/1, 126/127/128/129, 254/255/
    256/257, 65534/65535/65536/65537), with byte-exact expected
    length-encoding bytes per X.690 §8.1.3.4.

  - TestMakeSequenceHeaderBoundaries: asserts makeSequenceHeader
    produces the expected `0x30 <len-bytes>` for every case. Kills
    the boundary mutants at signer.go:879/881/883.

  - TestMakeSetHeaderBoundaries: same shape for makeSetHeader. Kills
    the mutants at signer.go:895/897/899.

  - TestMakeHeader_Roundtrip: cross-checks producer/consumer
    consistency — every header makeSequenceHeader emits must parse
    cleanly via parseASN1Length and recover the original length. Locks
    in the invariant against future drift between the strict DER
    enforcer (verifier) and the length-form selector (signer).

Mutation testing impact:

  - Killed:  197 → 203  (+6)
  - Lived:    50 → 44  (-6)
  - Efficacy: 79.76% → 82.19%  (+2.4 points; crossed 80%)
  - Mutator coverage: 85.76% (unchanged)

Statement coverage: 78.9% → 79.2% (+0.3).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 17, 2026 17:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds focused boundary-condition unit tests for CMS DER length-encoding helpers to eliminate mutation-testing survivors at exact </<= thresholds and to lock producer/consumer consistency between signer header emission and verifier DER length parsing.

Changes:

  • Introduces a shared table of DER length boundary cases (short form and long-form 1/2/3-octet transitions).
  • Adds byte-exact table-driven tests for makeSequenceHeader and makeSetHeader.
  • Adds a roundtrip invariant test ensuring makeSequenceHeader output is accepted by parseASN1Length and yields the original length.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jamestexas jamestexas merged commit b46f33e into main Jun 17, 2026
10 of 14 checks passed
@jamestexas jamestexas deleted the feat/audit-r3-length-boundaries branch June 17, 2026 18:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants