RFR: 8366453: TLS 1.3 KeyUpdate record is not rejected if not on a record boundary

Alice Pellegrini duke at openjdk.org
Mon Sep 29 15:32:37 UTC 2025


According to RFC 8446 section 5.1
> Handshake messages MUST NOT span key changes. Implementations
>       MUST verify that all messages immediately preceding a key change
>       align with a record boundary; if not, then they MUST terminate the
>       connection with an "unexpected_message" alert. Because the
>       ClientHello, EndOfEarlyData, ServerHello, Finished, and KeyUpdate
>       messages can immediately precede a key change, implementations
>       MUST send these messages in alignment with a record boundary.

The TLS implementation does not fail with alert(fatal, unexpected_message) when a KeyUpdate record is not on a record boundary, but this is required by the specification (as a key change happens immediately after a key update record)


Since the data on whether a message aligns with a record boundary is only known in the implementations of `InputRecord` (as even incomplete parts of other handshake messages, if coming after one of the mentioned handshakes records, would require a failure, making checking that said message is the last complete one of that record insufficient), and the fact that, **if the negotiated protocol is TLS13** _(or even DTLS13 in the future)_, knowing that any of the mentioned messages did not align with the record boundary is enough to fail the connection, I am proposing to add this as a method of `InputRecord`; 

In addition, even if the handshake context was accessible from within `InputRecord`, for both ServerHello and ClientHello the negotiated protocol version is not known when the input record is decoded.

The change mentions the name of the message currently being consumed in the exception because (since the messages are consumed in the order in which they appear in the record's body, and the groups of messages contained in each record are consumed in the order in which said records were delivered) it can be shown that if that flag is set, the first consumer that calls `tls13keyChangeHsExceedsRecordBoundary` will correspond to the first message to violate the boundary requirement, among the messages in the record it was found in.

<br/><br/>

I would appreciate suggestions on how to make the code better, especially in terms of where and how to store the fact that the violation might (if the negotiated protocol is or will be TLS13) have happened, and where to put the comments mentioning the specification RFC8446, for example in the `InputRecord` base class or the TLS13 Consumers that were modified.

-------------

Commit messages:
 - fix typo in comments
 - modifiers fixes
 - added explanation for additional wrap in test
 - implement test
 - Stylistic and naming changes
 - Fail with fatal without logging the `Consuming` message
 - Inheritance and comments cleanup
 - First draft of more correct check of tls version
 - add check that spec is tls13plus
 - 8366453: TLS 1.3 KeyUpdate record is not rejected if not on a record boundary

Changes: https://git.openjdk.org/jdk/pull/27437/files
  Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=27437&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8366453
  Stats: 241 lines in 9 files changed: 238 ins; 0 del; 3 mod
  Patch: https://git.openjdk.org/jdk/pull/27437.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/27437/head:pull/27437

PR: https://git.openjdk.org/jdk/pull/27437


More information about the security-dev mailing list