Skip to content

DTLS 1.3's unified-header (RFC 9147) encrypted-record format is unimplemented #2467

Closed

Description

@JarryShaw

Summary

Follow-up from the family-wide restructure on PR #2441. The current DTLS implementation (#2441/#2451) parses only the legacy fixed-format record header shared by DTLS 1.0/1.2 (content type, legacy version, 2-byte epoch, 48-bit sequence number, 2-byte length). DTLS 1.3 (RFC 9147) keeps that format for plaintext records (alert/handshake/ack content types) but introduces a genuinely different unified header for encrypted records:

  • First byte is a bit field: top 3 bits fixed 001, then C (Connection ID present), S (sequence number width: 8 or 16 bits), L (length field present), and the 2 low bits of a shortened epoch.
  • No content-type or version byte at all — the real content type is inside the encrypted payload.
  • Sequence number is encrypted (masked from the ciphertext) and shortened.
  • Length is optional — a record with L=0 runs to the end of the datagram.
  • Receivers distinguish an encrypted DTLS 1.3 record from a legacy-format one by checking whether the first byte's top 3 bits are 001 (ciphertext) vs. a recognized legacy content-type value (plaintext).

Scope

New parsing capability, not a refactor: a schema/dissector for the unified header, record-format auto-detection (legacy vs. unified) ahead of the existing content-type dispatch, and Connection ID support if that's in scope for this project. This should land as its own PR once the version-split restructure from #2441 is in place, since the new DTLSv1_3 concrete class is the natural place for it.

Activity

  1. added
    featPull requests that add a new capability (feat: subject prefix)
    blockedDeferred pending another issue or decision; see the last comment for what unblocks it
    on Oct 30, 2026
  2. JarryShaw commented on Oct 30, 2026

    @JarryShaw
    OwnerAuthor

    Blocked on the TLS/DTLS version-split restructure (PR #2441) landing first — the new DTLSv1_3 class is the natural home for this. Unblocks when #2441 merges.

  3. added this to the PyPCAPKit v1.5 milestone on Oct 30, 2026
  4. moved this to Blocked in PyPCAPKiton Oct 30, 2026
  5. added
    pendingAccepted and unstarted - nobody is on it and nothing blocks it
    and removed
    blockedDeferred pending another issue or decision; see the last comment for what unblocks it
    on Oct 31, 2026
  6. moved this from Blocked to Pending in PyPCAPKiton Oct 31, 2026
  7. removed
    pendingAccepted and unstarted - nobody is on it and nothing blocks it
    on Oct 31, 2026
  8. 1 remaining item

  9. moved this from Pending to WIP in PyPCAPKiton Oct 31, 2026
  10. added
    needs: decisionWaiting on the maintainer to decide — not blocked by other work
    on Oct 31, 2026
  11. JarryShaw commented on Oct 31, 2026

    @JarryShaw
    OwnerAuthor

    Open questions for the owner, paraphrased: (1) decode connection-ID records? That needs the negotiated CID length, which this layer does not track; the commit refuses them. (2) add a plausibility rule on UDP 5684? Any datagram whose first octet is 0x20 to 0x3F and whose header fits parses as DTLS 1.3 today. (3) keep DTLSCiphertext as its own data model, or fold the optional fields into DTLS? Commit 504ca20c4 is local and not pushed.

  12. JarryShaw commented on Oct 31, 2026

    @JarryShaw
    OwnerAuthor

    Decisions needed, DTLS 1.3 records (504ca20c4, local, unpushed): (1) Decode connection-ID records? Options: refuse them (current, degrades to Raw) or decode using a negotiated CID length this layer does not track. Recommendation: refuse until CID length is tracked. (2) Plausibility rule on UDP 5684? Options: keep as-is (any datagram with first octet 0x20–0x3F that fits the header parses) or add a version-field check. Recommendation: add the version check to avoid false DTLS 1.3 matches. (3) DTLSCiphertext separate model or folded into DTLS? Recommendation: separate, since the optional fields differ.

  13. JarryShaw commented on Oct 31, 2026

    @JarryShaw
    OwnerAuthor

    take your recommendations. but RFC is the source of truth on the correct behaviour.

  14. moved this from WIP to Needs decision in PyPCAPKiton Oct 31, 2026
  15. removed
    needs: decisionWaiting on the maintainer to decide — not blocked by other work
    on Oct 31, 2026
  16. JarryShaw commented on Oct 31, 2026

    @JarryShaw
    OwnerAuthor

    Hold, not pushed. The DTLS 1.3 work is local commit e8011a8b9 on top of main eaddd9061, and it adds the 16-octet minimum ciphertext check from RFC 9147 section 4.2.3. Push and PR wait until the Actions queue drops below 20 (currently 26 queued). The commit is ready for review as soon as it is pushed.

  17. moved this from Needs decision to WIP in PyPCAPKiton Oct 31, 2026
  18. JarryShaw commented on Oct 31, 2026

    @JarryShaw
    OwnerAuthor

    PR opened as #2494 from the held commit e8011a8b9.

  19. removed
    wipWork in flight - a covering PR is open or an agent is actively on it
    on Oct 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

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

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions