Skip to content

feat(application): parse TLS handshake extensions - #2595

Merged
JarryShaw merged 1 commit into
mainfrom
feat/2514-tls-extensions
Nov 2, 2026
Merged

JarryShaw merged 1 commit into
mainfrom
feat/2514-tls-extensions

Conversation

@JarryShaw

Copy link
Copy Markdown
Owner

What is the purpose of your pull request?

  • feat — adds a feature

Description of your pull request and other information

TLS handshake extensions are now parsed. ClientHello, ServerHello and EncryptedExtensions decode their extension lists, with decoders for server_name, supported_versions, supported_groups, signature_algorithms, key_share and ALPN. The extension types come from the IANA ExtensionType registry, with a crawler plus a generated const module. SSL.__extension__ holds the decoders, and SSL.register_extension and register_tls_extension register more.

An extension with no decoder, or whose decoder rejects its body, keeps its octets raw. That rejection is built inside CaughtByCaller(ProtocolError), so it logs nothing and leaves sys.excepthook alone (#2588). A broken extension list or EncryptedExtensions vector still refuses the message. Round trips are byte-exact.

Settled on the worker's recommendations, open to the owner:

  • a malformed body is kept raw rather than raised;
  • HelloRetryRequest is signalled through msg_type;
  • the wrapper is named register_tls_extension, after IANA's TLS registry;
  • server_name and ALPN names are bytes.

An odd-length ClientHello supported_versions body now yields no version list.

Closes #2514

@JarryShaw JarryShaw added feat Pull requests that add a new capability (feat: subject prefix) review: good-to-go Cross-review at the current head says ready; CI state is separate labels Nov 1, 2026
@JarryShaw

Copy link
Copy Markdown
Owner Author

GOOD TO GO at 11cf6bae2. Two Sonnet reviews passed: the parser, then its fix round. The docs match the code: pep.rst, dtls_handshake and DTLSHandshake now include EncryptedExtensions. A malformed extension body logs nothing and leaves sys.excepthook alone, which a sentinel-hook test checks. Round trips over built hellos are byte-exact. The SSL.register_extension row in the registrar identity table is mutation-checked. The rebase onto f4aa57742 is patch-identical outside the resolved files.

@JarryShaw JarryShaw moved this to In review in PyPCAPKit Nov 1, 2026
@github-actions

github-actions Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

Coverage: 93.95% (unit tier, Python 3.15, 11cf6bae2, Unit Tests run success)

Package Statements Missed Branches Partial Cover
pcapkit (top level) 104 4 20 2 95.16%
pcapkit/const 20232 162 2756 143 98.63%
pcapkit/corekit 2605 74 818 37 96.52%
pcapkit/dumpkit 281 3 100 3 98.43%
pcapkit/foundation 3368 27 1188 32 98.71%
pcapkit/interface 138 4 52 3 96.32%
pcapkit/protocols 20574 220 5448 204 98.36%
pcapkit/toolkit 961 28 342 10 96.32%
pcapkit/utilities 506 7 144 5 98.15%
pcapkit/vendor 5063 2258 1160 183 52.06%

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

@JarryShaw

Copy link
Copy Markdown
Owner Author

Prefer to have those value unpack/pack helper methods (uint, vector, etc.) added as part of the base Protocol's utility helper methods so they can be shared across other protocols.

@JarryShaw

Copy link
Copy Markdown
Owner Author

Owner request, paraphrased: the value pack and unpack helpers this PR adds as module-level functions in ssl.py should move into the base Protocol's utility methods, so that other protocols can share them. These are _vector, _whole_vector, _uint16s, _prefixed and _make_uint16s. They become width-generic _read_*/_make_* methods beside _read_unpack and _make_pack, and TLS calls them from there. TLS behaviour must stay byte-identical.
Moving to review: needs-changes, with CI on this head cancelled. A worker is making the change, and I'll push it with a lease and post the verdict.

@JarryShaw JarryShaw added review: needs-changes Cross-review at the current head says changes are required; see the verdict comment and removed review: good-to-go Cross-review at the current head says ready; CI state is separate labels Nov 2, 2026
@github-actions github-actions Bot added this to the PyPCAPKit v1.6 milestone Nov 2, 2026
- Add the IANA TLS ExtensionType registry: pcapkit.vendor.tls.extension_type
  and the pcapkit.const.tls.extension_type module it generates.
- Add SSL.__extension__ with register_extension and the
  register_tls_extension wrapper; decode server_name, supported_groups,
  signature_algorithms, ALPN, supported_versions and key_share in
  ClientHello, ServerHello, HelloRetryRequest and EncryptedExtensions.
- Keep unknown extensions, and bodies their decoder rejects, as raw octets,
  the rejection quiet under CaughtByCaller; decode EncryptedExtensions.
- Build extensions from data models, raw octets or (type, kwargs) pairs,
  byte-exact both ways; add the tls-extension options-generator family.
- Add the shared value helpers to Protocol: _read_vector,
  _read_whole_vector, _read_uints, _make_uint, _make_vector and
  _make_uints, which the SSL extension readers and makers call.
- Document the models, registry and wrapper, and the decoded bodies in the
  DTLS models, the roadmap and the TLS/DTLS pages; bump the const pins.
@JarryShaw
JarryShaw force-pushed the feat/2514-tls-extensions branch from 11cf6ba to 0ef7139 Compare November 2, 2026 03:00
@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 Nov 2, 2026
@JarryShaw

Copy link
Copy Markdown
Owner Author

The fix round for the helper request is pushed: 11cf6bae2 → 0ef7139a6, rebased onto main e78967773.

@JarryShaw

Copy link
Copy Markdown
Owner Author

GOOD TO GO at 0ef7139a6: Sonnet's review of the helper fix round.

  • The old names are gone. The six methods sit on ProtocolBase in member order, and the guard passes with no exceptions.
  • TLS behaviour is unchanged: across about 13,800 reader calls and parse/rebuild trials against the old tree, bytes, fields and error messages are identical.
  • The new helper tests fail without the change, and _make_uint's check and message match feat(link): dissect the IEEE 802.11 MAC header behind radiotap #2607's.
  • One consistency fix is being folded in: three two-octet sites (the key-share group, selected_version, selected_group) still raise a bare OverflowError where the helpers raise StructError. They are being routed through _make_pack, with a TLS-level test.

@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 Nov 2, 2026
@JarryShaw
JarryShaw merged commit e78fb2a into main Nov 2, 2026
60 of 61 checks passed
@JarryShaw
JarryShaw deleted the feat/2514-tls-extensions branch November 2, 2026 03:17
@github-project-automation github-project-automation Bot moved this from In review to Done in PyPCAPKit Nov 2, 2026
@JarryShaw JarryShaw removed the review: good-to-go Cross-review at the current head says ready; CI state is separate label Nov 2, 2026
@JarryShaw

Copy link
Copy Markdown
Owner Author

Merged at 0ef7139a6, before the reviewed StructError fold (de4482b29) was pushed. Five two-octet and one-octet sites in ssl.py therefore still raise a bare OverflowError or ValueError. Those sites are the key-share group, selected_version, selected_group, the extension type and name_type. The fold and its TLS-level test carry over into #2614's next commit, which also moves TLS's _take and its bytes-buffer reads onto the base class.

JarryShaw added a commit that referenced this pull request Nov 2, 2026
…6.0 (#2449)

- Folded into the TLS/DTLS entry: the hello and EncryptedExtensions
  extension lists, their registered body decoders, register_tls_extension
  and the pcapkit.const.tls extension types (#2595), and each whole DTLS
  record in a datagram as a further layer (#2603).
- The conventions entry records #2611's per-test purge rule; the
  member-order entry cites #2491.
- No entry for #2595's private ProtocolBase value helpers, as for the
  other private API.
- CHANGELOG.md regenerated; util/changelog_md.py --check passes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat Pull requests that add a new capability (feat: subject prefix)

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

feat(application): parse TLS handshake extensions

1 participant