target = "https://tools.ietf.org/rfc/rfc8446#5.1" # 5.1. Record Layer # # The record layer fragments information blocks into TLSPlaintext # records carrying data in chunks of 2^14 bytes or less. Message # boundaries are handled differently depending on the underlying # ContentType. Any future content types MUST specify appropriate # rules. Note that these rules are stricter than what was enforced in # TLS 1.2. # # Handshake messages MAY be coalesced into a single TLSPlaintext record # or fragmented across several records, provided that: # # - Handshake messages MUST NOT be interleaved with other record # types. That is, if a handshake message is split over two or more # records, there MUST NOT be any other records between them. # # - 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. # # Implementations MUST NOT send zero-length fragments of Handshake # types, even if those fragments contain padding. # # Alert messages (Section 6) MUST NOT be fragmented across records, and # multiple alert messages MUST NOT be coalesced into a single # TLSPlaintext record. In other words, a record with an Alert type # MUST contain exactly one message. # # Application Data messages contain data that is opaque to TLS. # Application Data messages are always protected. Zero-length # fragments of Application Data MAY be sent, as they are potentially # useful as a traffic analysis countermeasure. Application Data # fragments MAY be split across multiple records or coalesced into a # single record. # # enum { # invalid(0), # change_cipher_spec(20), # alert(21), # handshake(22), # application_data(23), # (255) # } ContentType; # # struct { # ContentType type; # ProtocolVersion legacy_record_version; # uint16 length; # opaque fragment[TLSPlaintext.length]; # } TLSPlaintext; # # type: The higher-level protocol used to process the enclosed # fragment. # # legacy_record_version: MUST be set to 0x0303 for all records # generated by a TLS 1.3 implementation other than an initial # ClientHello (i.e., one not generated after a HelloRetryRequest), # where it MAY also be 0x0301 for compatibility purposes. This # field is deprecated and MUST be ignored for all purposes. # Previous versions of TLS would use other values in this field # under some circumstances. # # length: The length (in bytes) of the following # TLSPlaintext.fragment. The length MUST NOT exceed 2^14 bytes. An # endpoint that receives a record that exceeds this length MUST # terminate the connection with a "record_overflow" alert. # # fragment: The data being transmitted. This value is transparent and # is treated as an independent block to be dealt with by the higher- # level protocol specified by the type field. # # This document describes TLS 1.3, which uses the version 0x0304. This # version value is historical, deriving from the use of 0x0301 for # TLS 1.0 and 0x0300 for SSL 3.0. In order to maximize backward # compatibility, a record containing an initial ClientHello SHOULD have # version 0x0301 (reflecting TLS 1.0) and a record containing a second # ClientHello or a ServerHello MUST have version 0x0303 (reflecting # TLS 1.2). When negotiating prior versions of TLS, endpoints follow # the procedure and requirements provided in Appendix D. # # When record protection has not yet been engaged, TLSPlaintext # structures are written directly onto the wire. Once record # protection has started, TLSPlaintext records are protected and sent # as described in the following section. Note that Application Data # records MUST NOT be written to the wire unprotected (see Section 2 # for details). [[spec]] level = "MUST" quote = ''' Any future content types MUST specify appropriate rules. ''' [[spec]] level = "MAY" quote = ''' Handshake messages MAY be coalesced into a single TLSPlaintext record or fragmented across several records, provided that: ''' [[spec]] level = "MUST" quote = ''' - Handshake messages MUST NOT be interleaved with other record types. ''' [[spec]] level = "MUST" quote = ''' That is, if a handshake message is split over two or more records, there MUST NOT be any other records between them. ''' [[spec]] level = "MUST" quote = ''' - Handshake messages MUST NOT span key changes. ''' [[spec]] level = "MUST" quote = ''' 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. ''' [[spec]] level = "MUST" quote = ''' 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. ''' [[spec]] level = "MUST" quote = ''' 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. ''' [[spec]] level = "MUST" quote = ''' Implementations MUST NOT send zero-length fragments of Handshake types, even if those fragments contain padding. ''' [[spec]] level = "MUST" quote = ''' Alert messages (Section 6) MUST NOT be fragmented across records, and multiple alert messages MUST NOT be coalesced into a single TLSPlaintext record. ''' [[spec]] level = "MUST" quote = ''' Alert messages (Section 6) MUST NOT be fragmented across records, and multiple alert messages MUST NOT be coalesced into a single TLSPlaintext record. ''' [[spec]] level = "MUST" quote = ''' In other words, a record with an Alert type MUST contain exactly one message. ''' [[spec]] level = "MAY" quote = ''' Zero-length fragments of Application Data MAY be sent, as they are potentially useful as a traffic analysis countermeasure. ''' [[spec]] level = "MAY" quote = ''' Application Data fragments MAY be split across multiple records or coalesced into a single record. ''' [[spec]] level = "MUST" quote = ''' legacy_record_version: MUST be set to 0x0303 for all records generated by a TLS 1.3 implementation other than an initial ClientHello (i.e., one not generated after a HelloRetryRequest), where it MAY also be 0x0301 for compatibility purposes. ''' [[spec]] level = "MUST" quote = ''' This field is deprecated and MUST be ignored for all purposes. ''' [[spec]] level = "MUST" quote = ''' The length MUST NOT exceed 2^14 bytes. ''' [[spec]] level = "MUST" quote = ''' An endpoint that receives a record that exceeds this length MUST terminate the connection with a "record_overflow" alert. ''' [[spec]] level = "MUST" quote = ''' In order to maximize backward compatibility, a record containing an initial ClientHello SHOULD have version 0x0301 (reflecting TLS 1.0) and a record containing a second ClientHello or a ServerHello MUST have version 0x0303 (reflecting TLS 1.2). ''' [[spec]] level = "MUST" quote = ''' Note that Application Data records MUST NOT be written to the wire unprotected (see Section 2 for details). '''