RFC Errata
RFC 9147, "The Datagram Transport Layer Security (DTLS) Protocol Version 1.3", April 2022
Source of RFC: tls (sec)
Errata ID: 8067
Status: Reported
Type: Technical
Publication Format(s) : TEXT, PDF, HTML
Reported By: David Benjamin
Date Reported: 2024-08-08
Section 5.3 says:
legacy_session_id: Versions of TLS and DTLS before version 1.3 supported a "session resumption" feature, which has been merged with pre-shared keys (PSK) in version 1.3. A client which has a cached session ID set by a pre-DTLS 1.3 server SHOULD set this field to that value. Otherwise, it MUST be set as a zero-length vector (i.e., a zero-valued single byte length field).
It should say:
legacy_session_id: Versions of TLS and DTLS before version 1.3 supported a "session resumption" feature, which has been merged with pre-shared keys (PSK) in version 1.3. A client which has a cached session set by a pre-DTLS 1.3 server SHOULD set this field according to that session. Otherwise, it MUST be set as a zero-length vector (i.e., a zero-valued single byte length field).
Notes:
The old text is written as if only ID-based DTLS 1.2 sessions (as opposed to ticket-based DTLS 1.2 sessions) require filling in legacy_session_id. This is not quite true. (D)TLS 1.2 ticket sessions (usually!) also fill in legacy_session_id, but to a random value. See the second paragraph of Section 3.4 of RFC 5077. This is needed because a (D)TLS 1.2 server still indicates resumption by echoing the session ID.
I say usually because RFC 5077 unhelpfully makes this behavior optional for the client. The client may instead leave session ID empty, in which case the ServerHello is ambiguous on whether resumption happened! Instead, the client must detect resumption based on whether ServerHello is followed by ChangeCipherSpec (resumption) or more cleartext handshake messages (full handshake). This is a mess for the state machine and, as far as I know, no one does this. (Except for RFC 4851. That was a mistake.) Moreover, this alternative does not work for DTLS, where ChangeCipherSpec is not sequenced relative to handshake messages. Although I cannot find any text that says this. It seems DTLS 1.2 implementors needed to figure that out for themselves.
Given this mess, I've opted to just be vague and say "set this field according to that session". We can't really say "that value" because, in the ticket case, you synthesize one. I'd also rather not wade into the mess that is this behavior being de jure optional, but de facto required, for DTLS 1.2.
This errata also applies to https://www.rfc-editor.org/errata/eid8066. In the replacement text, "cached session ID" should say "cached session".