Skip to content

fix(internet): the ESP read path and integrity-key warning name the protocol (#2411) - #2413

Merged
JarryShaw merged 1 commit into
mainfrom
fix/2411-esp-missing-prefix
Oct 28, 2026
Merged

JarryShaw merged 1 commit into
mainfrom
fix/2411-esp-missing-prefix

Conversation

@JarryShaw

Copy link
Copy Markdown
Owner

Please follow the guide below

What is the purpose of your pull request?

  • fix — corrects a defect

Description of your pull request and other information

Fixes #2411.

#2366 (fixing #2297) put the house ESP: <lowercase description> prefix on ESP.make's ProtocolError messages and on SecurityAssociation.unavailable, but eight sites were outside its checklist. The same condition therefore read two ways depending on which direction it was hit from — make said ESP: no security association for SPI 0x..., read said no security association for SPI 0x....

The eight, and the text each now carries:

Site Message
_read_trailer, plaintext too short ESP: decrypted payload too short: SPI 0x00004321 decrypts to 1 octets, too short to hold a pad length and next header
_read_trailer, pad length beyond the plaintext ESP: invalid pad length: the decrypted payload for SPI 0x00004321 declares 255 octets of padding but holds only 3; the encryption key is most likely wrong
_read_trailer, padding pattern (returned and warned with) ESP: invalid padding: the decrypted payload for SPI 0x00004321 does not follow the monotonically increasing sequence of RFC 4303 s2.4
ESP.read, NO_SA ESP: no security association for SPI 0x00004321
ESP.read, TRUNCATED ESP: payload too short: 4 octets, shorter than the 16-octet ICV the security association declares
ESP.read, AUTH_FAILED (separate integrity) ESP: integrity check value does not verify for SPI 0x00004321 sequence 7
ESP.read, AUTH_FAILED (AEAD tag) ESP: authentication tag does not verify for SPI 0x00004321 sequence 3; the encryption key is most likely wrong
SecurityAssociation.__init__, integrity-key warning ESP: invalid integrity key: AUTH_HMAC_SHA2_256_128 expects a 32-octet key, got 16 octets; the ICV will very likely fail to verify

_read_trailer is a staticmethod, so it spells the prefix literally, as every SecurityAssociation site does; ESP.read is an instance method and uses {self.alias}:, as ESP.make does.

The warning is the one that needed this most: warn reports the caller's frame rather than the protocol, so the message text is the only thing naming ESP at all.

Two messages were reworded rather than only prefixed, to avoid ESP: ESP payload ... and ESP: decrypted ESP payload ...; the three reading <thing> for SPI x does/declares y were turned into the description: detail house form. Every substring the existing tests match on is preserved.

Tests. tests/protocols/internet/test_esp_message_prefix_2411_unit.py, 13 tests, each message pinned whole rather than by substring — matching fragments is exactly why the omission survived #2366. Fail-without-fix confirmed: against unpatched esp.py, 10 failed and 3 passed, each failure a missing prefix; the 3 that passed are the controls asserting the guards did not widen (a correct ICV still verifies, a consistent trailer is still read, a right-sized key still does not warn). tests/protocols/ in full: 2033 passed / 51388 subtests / 0 failed.

All but one of the new tests runs without cryptography: an ENCR_NULL SA reaches the trailer and separate-integrity paths on hmac and hashlib alone. Only the AEAD-tag case is gated on HAS_CRYPTO.

@JarryShaw JarryShaw added the bug Issues reporting a defect (set by the bug report template; a default, not an assessment) label Oct 28, 2026
@JarryShaw JarryShaw moved this to In review in PyPCAPKit Oct 28, 2026
@github-actions github-actions Bot added this to the PyPCAPKit v1.5 milestone Oct 28, 2026
@JarryShaw JarryShaw added fix Pull requests that fix a defect (fix: subject prefix) review: running A cross-review is in flight against the current head - no verdict yet labels Oct 28, 2026
@JarryShaw

Copy link
Copy Markdown
Owner Author

Review: NEEDS CHANGES at 144d27aa (Sonnet, read-only cross-review).

Real blocker: tests/test_tier_guard.py::DependencyGateFalsifiabilityTests::test_removing_crypto_from_the_test_job_is_caught fails — the new test file adds a second skipUnless(HAS_CRYPTO) gate, but that test's expected set hardcodes {test_esp_unit.py}. Reproduced locally (199 passed/1 failed on PR head, 200 passed on main) and confirmed in real CI — Python 3.11-3.14 legs all show exactly this one failure. The "0 failed" in the PR's own report only ran tests/protocols/, which skips this top-level test file. Fix: add the new module to the expected set in test_tier_guard.py, or move the AEAD-gated test into test_esp_unit.py instead of a separate file.

Everything else checks out: all eight message prefixes correct (literal ESP: vs {self.alias}), every rendered value (SPI, octet counts, pad length, sequence, key size) verified correct, all 5 existing assertIn substrings in test_esp_unit.py survive, fail-without-fix confirmed (10 failed/3 passed on revert), no regression vs main (identical pre-existing FileNotFoundError failures in fresh worktrees, resolved by generating samples), no scope creep beyond esp.py + the new test file.

Non-blocking nits: "too short" appears twice in the trailer message; the ICV/tag messages are prefixed but not restructured into the description: detail form the three trailer messages use.

@JarryShaw JarryShaw added review: needs-changes Cross-review at the current head says changes are required; see the verdict comment and removed review: running A cross-review is in flight against the current head - no verdict yet labels Oct 28, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Coverage: 91.73% -- tests failure, so this is partial (unit tier, Python 3.15, 144d27aa4, Unit Tests run failure)

Package Statements Missed Branches Partial Cover
pcapkit (top level) 104 4 20 2 95.16%
pcapkit/const 19609 879 2620 866 92.13%
pcapkit/corekit 2596 74 818 37 96.51%
pcapkit/dumpkit 282 3 102 3 98.44%
pcapkit/foundation 3045 24 1062 26 98.78%
pcapkit/interface 138 4 52 3 96.32%
pcapkit/protocols 17576 193 4668 179 98.32%
pcapkit/toolkit 924 36 334 10 95.55%
pcapkit/utilities 502 7 144 5 98.14%
pcapkit/vendor 4449 1961 1020 167 52.64%

Per-file detail: the coverage-html artifact of this run.

…rotocol (#2411)

#2366 (fixing #2297) put the house `ESP: <lowercase description>` prefix on
`ESP.make`'s ProtocolError messages and on `SecurityAssociation.unavailable`,
but eight sites were outside its checklist. The same condition therefore read
two ways depending on the direction it was hit from -- `make` said
`ESP: no security association for SPI 0x...`, `read` said
`no security association for SPI 0x...`.

- esp.py `ESP._read_trailer` (a staticmethod, so the prefix is spelled
  literally, as every `SecurityAssociation` site does): the plaintext-too-short
  diagnostic, the pad-length-beyond-the-plaintext one, and the padding-pattern
  one, which is both returned and warned with.
- esp.py `ESP.read` (an instance method, so `{self.alias}:`, as `ESP.make`):
  the NO_SA, TRUNCATED, separate-integrity AUTH_FAILED and AEAD-tag
  AUTH_FAILED messages, surfaced as `esp.error`.
- esp.py `SecurityAssociation.__init__`: the short-integrity-key warning.
  `warn` reports the caller's frame rather than the protocol, so the message
  text is the only thing naming ESP -- it needs the prefix more than the
  exceptions do, not less.
- test_tier_guard.py `DependencyGateFalsifiabilityTests
  .test_removing_crypto_from_the_test_job_is_caught`: the new module is the
  second to carry a `HAS_CRYPTO` gate, so it joins that test's expected set of
  gated modules and its `describe_gap` location assertions. #2324 dropped this
  test's `len(gap.gates)` pin and kept the set equality as the structural
  claim, so the fix is to extend the set rather than to loosen it.

Two messages were reworded rather than only prefixed, to avoid `ESP: ESP
payload ...` and `ESP: decrypted ESP payload ...`, and the three that read as
`<thing> for SPI x does/declares y` were turned into the `description: detail`
house form. Every substring the existing tests match on is preserved.

Test: tests/protocols/internet/test_esp_message_prefix_2411_unit.py (new, 13
tests, every message pinned whole rather than by substring -- matching
fragments is why the omission survived #2366). Confirmed 10 failed / 3 passed
against unpatched esp.py, each failure a missing prefix; the 3 that passed are
the controls that assert the guards did not widen. All but one of the new tests
runs without `cryptography`: an ENCR_NULL SA reaches the trailer and
separate-integrity paths on hmac and hashlib alone.
tests/test_tier_guard.py in full: 135 passed / 2497 subtests / 0 failed.
tests/ in full, after `examples/generators/make_samples.py`: 6776 passed / 118
skipped / 101828 subtests / 0 failed.

Fixes #2411.
@JarryShaw
JarryShaw force-pushed the fix/2411-esp-missing-prefix branch from 144d27a to d77427d Compare October 28, 2026 15:29
@JarryShaw JarryShaw added review: running A cross-review is in flight against the current head - no verdict yet and removed review: needs-changes Cross-review at the current head says changes are required; see the verdict comment labels Oct 28, 2026
@JarryShaw

Copy link
Copy Markdown
Owner Author

Review: GOOD TO GO at d77427d5 (Sonnet, round 2 — narrow final check). Delta from round 1 is exactly tests/test_tier_guard.py (+8/-1); esp.py and the new test module are byte-identical. Blocker confirmed fixed — the file now passes 135/2497/0. Independently judged (not just trusted): extending the gate set is the right call per #2324's own design (a per-gate tuple set, several gated modules is expected), the new assertIn is non-vacuous, and none of the other 3 open PRs adds a conflicting crypto gate. Spot-checked both ESP test files (49 passed) and tests/protocols/ in full (2033 passed, 0 failed) — did not re-run the full 36-minute suite from round 1's own report, so that figure stands unverified but the narrower checks are sufficient here.

@JarryShaw JarryShaw added review: good-to-go Cross-review at the current head says ready; CI state is separate and removed review: running A cross-review is in flight against the current head - no verdict yet labels Oct 28, 2026
@JarryShaw
JarryShaw merged commit 0599a3b into main Oct 28, 2026
65 checks passed
@github-project-automation github-project-automation Bot moved this from In review to Done in PyPCAPKit Oct 28, 2026
@JarryShaw
JarryShaw deleted the fix/2411-esp-missing-prefix branch October 28, 2026 15:52
@JarryShaw JarryShaw removed the review: good-to-go Cross-review at the current head says ready; CI state is separate label Oct 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Issues reporting a defect (set by the bug report template; a default, not an assessment) fix Pull requests that fix a defect (fix: subject prefix)

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

fix(internet): ESP read/warn messages missing the ESP: prefix #2366 established

1 participant