jiebi/TextFlow huggingface dataset:
Original text:
Note: This is a different construction from that in TLS 1.2, which specified a partially explicit nonce. <del> The plaintext is the concatenation of TLSPlaintext.fragment and TLSPlaintext.type. </del>  The AEAD output consists of the ciphertext output by the AEAD encryption operation.  The length of the plaintext is greater than

Reviewer comments:
This sentence in general seems redundant, but if it's going to be included it should be correct.

Revised text:
Note: This is a different construction from that in TLS 1.2, which specified a partially explicit nonce.  <ins> The plaintext is the concatenation of TLSPlaintext.fragment, TLSPlaintext.type, and any padding bytes (zeros). </ins> The AEAD output consists of the ciphertext output by the AEAD encryption operation.  The length of the plaintext is greater than
Original text:
Note: Alerts and any other record types are not handshake messages and are not included in the hash computations.  4.4. TLS also allows other messages to be sent after the main handshake.

Reviewer comments:
(My impression from the list is that we're not doing post-handshake key separation. If I'm wrong and we are, this will need to be slightly tweaked. Anyway, the current state of the world is we don't do it, so I've worded it accordingly.) As the Finished message is an implicit ChangeCipherSpec, it's worth clarifying that this is the point at which the cipher state changes. Should an implementation not send half-RTT data, it may defer switching traffic keys until both Finished messages have been exchanged. This will not work well, as alerts sent in response to a bad client certificate will be unreadable. The outgoing traffic keys must be switched early.

Revised text:
Note: Alerts and any other record types are not handshake messages and are not included in the hash computations. <ins> Any records following a 1-RTT Finished message MUST be encrypted under the application traffic key.  In particular, this includes any alerts sent by the server in response to client Certificate and CertificateVerify messages. </ins> 4.4. TLS also allows other messages to be sent after the main handshake.
Original text:
which will be echoed in the client's Certificate message.  The certificate_request_context MUST be unique within the scope of this connection (thus preventing replay of client <del> CertificateVerify messages). </del>  A list of the signature algorithms that the server is able to verify, listed in descending order of preference.  Any

Reviewer comments:
It's only useful during the handshake, so avoid forcing the client save that field for the in-handshake version.
I went back and forth on this, but on balance I think you're right.

Revised text:
which will be echoed in the client's Certificate message.  The certificate_request_context MUST be unique within the scope of this connection (thus preventing replay of client  <ins> CertificateVerify messages).  Within the handshake, this field MUST be empty. </ins> A list of the signature algorithms that the server is able to verify, listed in descending order of preference.  Any
Original text:
The actual content type of the record is found in fragment.type after decryption. <del> The record_version field is identical to TLSPlaintext.record_version and is always { 3, 1 }.  Note that the handshake protocol including the ClientHello and ServerHello messages authenticates the protocol version, so this value is redundant. </del>  The length (in bytes) of the following TLSCiphertext.fragment, which is the sum of the lengths of the content and the padding,

Reviewer comments:
From the past three times we've bumped the version, reality has unequivocally told us that the TLS version negotiation, as described in previous specifications, has been a collossal failure. The working group decided not to replace the mechanism with a more sustainable one, so do the next best thing in trying to save TLS from itself. If the fields are renamed to what they actually are ('serverversion' is the true version and 'clientversion' is a maximum), then perhaps we'll have some hope of future implementors getting it right, if we ever clear through the prior iterations of the bug. While I'm here, remove the mention of 'The protocol version the current record is compatible with' for recordversion. recordversion is purely vestigial.
+1
This sounds like a good idea, however for the server version I'd go with "negotiatedversion" to be more precise. For "recordversion", we could also extend the "legacy" prefix convention we've started using and change it to "legacyrecordversion" to remind that it's a deprecated field.
Hrm. We don't name other fields like ServerHello.negotiatedciphersuite and such. Though if we wanted to be consistent with those fields, it should be ClientHello.maxversion rather than ClientHello.maxsupportedversion. Dunno, maybe that would be better... maxsupported_version is a bit wordy. (Though I do think breaking pattern on the ClientHello version is justified because that field is already inconsistent with everything else in TLS. The version is the only place where the client doesn't offer a list, so everything else already self-describes as a "pick one of these" type of field.) Done.

Revised text:
The actual content type of the record is found in fragment.type after decryption.  <ins> The legacy_record_version field is identical to TLSPlaintext.legacy_record_version and is always { 3, 1 }.  Note that the handshake protocol including the ClientHello and ServerHello messages authenticates the protocol version, so this value is redundant. </ins> The length (in bytes) of the following TLSCiphertext.fragment, which is the sum of the lengths of the content and the padding,
Original text:
These messages use a handshake content type and are encrypted under the application traffic key.  4.4.1. At any time after the server has received the client Finished

Reviewer comments:
No sender could possibly need to send half of a message interleaved with application data in TLS, so forbid this. This cuts down on the state-space a receiver needs to worry about. This also means one cannot force the peer to buffer all but one byte of a giant post-handshake message, and then never complete it for the lifetime of the connection. (Although it does not remove all steady state buffering DoS-type concerns.)

Revised text:
These messages use a handshake content type and are encrypted under the application traffic key. <ins> Handshake messages sent after the handshake MUST NOT be interleaved with other record types.  That is, if a message is split over two or more handshake records, there MUST NOT be any other records between them. </ins> 4.4.1. At any time after the server has received the client Finished
Original text:
not correspond to a group which was provided in the "key_share" extension in the original ClientHello.  If either of these checks fails, then the client MUST abort the handshake with a fatal <del> "handshake_failure" alert.  Clients SHOULD also abort with "handshake_failure" in response to any second HelloRetryRequest which was sent in the same connection (i.e., where the ClientHello was itself in response to a HelloRetryRequest). </del>  Otherwise, the client MUST send a ClientHello with an updated KeyShare extension to the server.  The client MUST append a new ServerHello/KeyShare, the client MUST verify that the selected CipherSuite and NamedGroup match that supplied in the HelloRetryRequest.  If either of these values differ, the client MUST <del> abort the connection with a fatal "handshake_failure" alert. </del>  4.2. Separate specifications may define matching rules for other certificate extensions. <del> Note: It is a fatal "handshake_failure" alert for an anonymous server to request client authentication. </del>  4.3.

Reviewer comments:
Noticed these while reviewing the negotiation PR: handshakefailure means "the sender was unable to negotiate an acceptable set of security parameters given the options available", but these are all protocol errors that should only occur with a buggy server. Switch them to more appropriate ones: If the HelloRetryRequest makes no sense, it is an illegalparameter. If we get a second HelloRetryRequest, it's an unexpectedmessage (the client is in a state where it expects a ServerHello and will likely just fall through to the generic message-mismatch codepath). If HelloRetryRequest and ServerHello are inconsistent, it is an illegalparameter. If an anonymous server sends a CertificateRequest, it's an unexpected_message (this too will likely use the generic message-mismatch codepath).

Revised text:
not correspond to a group which was provided in the "key_share" extension in the original ClientHello.  If either of these checks fails, then the client MUST abort the handshake with a fatal  <ins> "illegal_parameter" alert.  Clients SHOULD also abort with "unexpected_message" in response to any second HelloRetryRequest which was sent in the same connection (i.e., where the ClientHello was itself in response to a HelloRetryRequest). </ins> Otherwise, the client MUST send a ClientHello with an updated KeyShare extension to the server.  The client MUST append a new ServerHello/KeyShare, the client MUST verify that the selected CipherSuite and NamedGroup match that supplied in the HelloRetryRequest.  If either of these values differ, the client MUST  <ins> abort the connection with a fatal "illegal_parameter" alert. </ins> 4.2. Separate specifications may define matching rules for other certificate extensions.  <ins> Note: It is a fatal "unexpected_message" alert for an anonymous server to request client authentication. </ins> 4.3.
Original text:
Note: In versions of TLS prior to TLS 1.3, this extension was named "elliptic_curves" and only contained elliptic curve groups.  See <del> RFC4492 and I-D.ietf-tls-negotiated-ff-dhe.  This extension was also used to negotiate ECDSA curves.  Signature algorithms are now negotiated independently (see signature-algorithms). </del>  The "extension_data" field of this extension contains a "NamedGroupList" value: 0xFEFF are reserved for private use. Indicates support of the corresponding finite field group, defined <del> in I-D.ietf-tls-negotiated-ff-dhe.  Values 0x01FC through 0x01FF are reserved for private use. </del>  Items in named_group_list are ordered according to the client's preferences (most preferred choice first).

Reviewer comments:
draft-ietf-tls-negotiated-ff-dhe is now RFC 7919. draft-mattsson-tls-ecdhe-psk-aead is now draft-ietf-tls-ecdhe-psk-aead.
Do we even need a reference to draft-ietf-tls-ecdhe-psk-aead with the new negotiation syntax?
NAME I removed it from the reference section. It was used in previous versions. But it is no longer referenced to by any text in the spec since version 15.

Revised text:
Note: In versions of TLS prior to TLS 1.3, this extension was named "elliptic_curves" and only contained elliptic curve groups.  See  <ins> RFC4492 and RFC7919.  This extension was also used to negotiate ECDSA curves.  Signature algorithms are now negotiated independently (see signature-algorithms). </ins> The "extension_data" field of this extension contains a "NamedGroupList" value: 0xFEFF are reserved for private use. Indicates support of the corresponding finite field group, defined  <ins> in RFC7919.  Values 0x01FC through 0x01FF are reserved for private use. </ins> Items in named_group_list are ordered according to the client's preferences (most preferred choice first).
Original text:
Including a new KeyShareEntry as the lowest priority share (i.e., appended to the list of shares in the "key_share" extension). <del> Removing the EarlyDataIndication early-data-indication extension if one was present.  Early data is not permitted after HelloRetryRequest. </del>  If a server receives a ClientHello at any other time, it MUST send a fatal "unexpected_message" alert and close the connection. the early data.  It is not possible for the server to accept only a subset of the early data messages.  In order to accept early data, the server server MUST have accepted a PSK cipher suite and selected the the first key offered in the client's "pre_shared_key" extension.  In addition, it MUST verify

Reviewer comments:
ClientHello mentions that earlydata should be removed, but earlydata doesn't mention it. Editorial.

Revised text:
Including a new KeyShareEntry as the lowest priority share (i.e., appended to the list of shares in the "key_share" extension).  <ins> Removing the "early_data" extension (early-data-indication) if one was present.  Early data is not permitted after HelloRetryRequest. </ins> If a server receives a ClientHello at any other time, it MUST send a fatal "unexpected_message" alert and close the connection. the early data.  It is not possible for the server to accept only a subset of the early data messages. <ins> Request that the client send another ClientHello by responding with a HelloRetryRequest.  A client MUST NOT include the "early_data" extension in its followup ClientHello. </ins> In order to accept early data, the server server MUST have accepted a PSK cipher suite and selected the the first key offered in the client's "pre_shared_key" extension.  In addition, it MUST verify
Original text:
The primary goal of TLS is to provide a secure channel between two communicating peers.  Specifically, the channel should provide the <del> following properties. </del>  Authentication: The server side of the channel is always authenticated; the client side is optionally authenticated. TLS consists of two primary components: <del> A handshake protocol (handshake-protocol) which authenticates the </del>  communicating parties, negotiates cryptographic modes and parameters, and establishes shared keying material.  The handshake protocol is designed to resist tampering; an active attacker parameters than they would if the connection were not under attack. <del> A record protocol (record-protocol) which uses the parameters </del>  established by the handshake protocol to protect traffic between the communicating peers.  The record protocol divides traffic up into a series of records, each of which is independently protected TLS is application protocol independent; higher-level protocols can layer on top of TLS transparently.  The TLS standard, however, does <del> not specify how protocols add security with TLS; the decisions on how to initiate TLS handshaking and how to interpret the authentication certificates exchanged are left to the judgment of the designers and implementors of protocols that run on top of TLS. </del>  This document defines TLS version 1.3.  While TLS 1.3 is not directly compatible with previous versions, all versions of TLS incorporate a

Reviewer comments:
Some suggested nits for s1: adding a semi-colon and swapping two whichs for thats.

Revised text:
The primary goal of TLS is to provide a secure channel between two communicating peers.  Specifically, the channel should provide the  <ins> following properties: </ins> Authentication: The server side of the channel is always authenticated; the client side is optionally authenticated. TLS consists of two primary components:  <ins> A handshake protocol (handshake-protocol) that authenticates the </ins> communicating parties, negotiates cryptographic modes and parameters, and establishes shared keying material.  The handshake protocol is designed to resist tampering; an active attacker parameters than they would if the connection were not under attack.  <ins> A record protocol (record-protocol) that uses the parameters </ins> established by the handshake protocol to protect traffic between the communicating peers.  The record protocol divides traffic up into a series of records, each of which is independently protected TLS is application protocol independent; higher-level protocols can layer on top of TLS transparently.  The TLS standard, however, does  <ins> not specify how protocols add security with TLS; how to initiate TLS handshaking and how to interpret the authentication certificates exchanged are left to the judgment of the designers and implementors of protocols that run on top of TLS. </ins> This document defines TLS version 1.3.  While TLS 1.3 is not directly compatible with previous versions, all versions of TLS incorporate a
Original text:
client) and provide key confirmation and handshake integrity. In the Key Exchange phase, the client sends the ClientHello (client- <del> hello) message, which contains a random nonce (ClientHello.random), its offered protocol version, a list of symmetric cipher/HKDF hash pairs, some set of Diffie-Hellman key shares (in the "key_share" </del>  extension key-share), one or more pre-shared key labels (in the <del> "pre_shared_key" extension pre-shared-key-extension), or both, and </del>  potentially some other extensions. The server processes the ClientHello and determines the appropriate

Reviewer comments:
At least to me, the KE phase description currently reads like the DH share and PSK are always sent. It's DH, PSK, or both.

Revised text:
client) and provide key confirmation and handshake integrity. In the Key Exchange phase, the client sends the ClientHello (client-  <ins> hello) message, which contains a random nonce (ClientHello.random); its offered protocol version; a list of symmetric cipher/HKDF hash pairs; some set of Diffie-Hellman key shares (in the "key_share" </ins> extension key-share), one or more pre-shared key labels (in the  <ins> "pre_shared_key" extension pre-shared-key-extension), or both; and </ins> potentially some other extensions. The server processes the ClientHello and determines the appropriate
Original text:
being in the order of the client's preference, with most preferred first. <del> PskKeyExchangeModes have the following meanings: </del>  PSK-only key establishment.  In this mode, the server MUST not supply a "key_share" value. mode, the client and servers MUST supply "key_share" values as described in key-share. <del> PskAuthenticationModes have the following meanings: </del>  PSK-only authentication.  In this mode, the server MUST NOT supply either a Certificate or CertificateVerify message.  [TODO: Add a

Reviewer comments:
The PskKeMode and PskAuthMode types were not defined, substitute them by the defined enums. Use non-plural enum names for consistency with other enumeration types. Remove the old opaque psk_identity type in favor of PskIdentity which was otherwise unused. Increase minimum length from 2 to 4 to account for the PskIdentity.identity field length.

Revised text:
being in the order of the client's preference, with most preferred first.  <ins> PskKeyExchangeMode values have the following meanings: </ins> PSK-only key establishment.  In this mode, the server MUST not supply a "key_share" value. mode, the client and servers MUST supply "key_share" values as described in key-share.  <ins> PskAuthenticationMode values have the following meanings: </ins> PSK-only authentication.  In this mode, the server MUST NOT supply either a Certificate or CertificateVerify message.  [TODO: Add a
Original text:
values SHALL be marked as "Recommended": ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384, rsa_pss_sha256, rsa_pss_sha384, rsa_pss_sha512, ed25519. 

Reviewer comments:
It has been replaced by SignatureScheme which assumes that no more HashAlgorithms will ever be allocated. Future allocations will go in SignatureScheme. Closes issue .
(Well, I think, strictly speaking, we need only lock down HashAlgorithm.) The SignatureScheme change assumes that we will never again allocate new values in the TLS 1.2 HashAlgorithm and SignatureAlgorithm ranges. I'm not sure how to write that kind of IANA consideration or I'd put together a PR. The end result should probably be something like s/Unassigned/Reserved for TLS 1.3 compatibility/. From TLS 1.3 onwards, all new signature algorithms that apply to TLS 1.2 must go through a backported SignatureScheme. (If we're not happy with that strong of a restriction, we could perhaps only burn HashAlgorithms 0x80 and up. Then TLS 1.3 SignatureSchemes live in the 0x8000 to 0xfdff range. Though 's PSS text already implies we'll be backporting SignatureSchemes, so the division probably isn't necessary? I dunno. I don't really care either way.)
Let's just lock down HAshAlgorithm. Can you submit a PR?

Revised text:
values SHALL be marked as "Recommended": ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384, rsa_pss_sha256, rsa_pss_sha384, rsa_pss_sha512, ed25519. <ins> Finally, this document obsoletes a registry originally created in RFC5246.  IANA [shall/has] updated it to list values 7-223 as "Reserved". </ins>
Original text:
network byte (big-endian) order; the uint32 represented by the hex bytes 01 02 03 04 is equivalent to the decimal value 16909060. <del> Note that in some cases (e.g., DH parameters) it is necessary to represent integers as opaque vectors.  In such cases, they are represented as unsigned integers (i.e., additional leading zero octets are not used even if the most significant bit is set). </del> 3.5. An additional sparse data type is available called enum.  A field of

Reviewer comments:
It looks like this is carried over from TLS 1.2---seems I was wrong and TLS 1.2 did actually say whether there were leading zeros in front of DHE parameters---but I believe it is no longer used. Instead our crypto primitives all act on byte strings. Any conversion between byte strings and the primitive's internal structures is handled by the primitive itself. (RFC 7748 natively acts on byte strings, specifies how FFDHE is encoded, RSA-PSS comes with a byte string form, etc.)

Revised text:
network byte (big-endian) order; the uint32 represented by the hex bytes 01 02 03 04 is equivalent to the decimal value 16909060.  3.5. An additional sparse data type is available called enum.  A field of
Original text:
If a server receives a ClientHello at any other time, it MUST send a fatal "unexpected_message" alert and close the connection.  Structure of this message: %%% Key Exchange Messages

Reviewer comments:
the renegotiation mechanism from TLSv1.2 and earlier is deprecated, that deprecation extends to the ability to renegotiate existing TLSv1.2 (or earlier) session to TLSv1.3
Sorry, but I just realized you can't do this. You need to prohibit negotiating back up to 1.3, but the client has to be able to offer 1.3. Here's the Bugzilla thread on this URL
so the client MAY send a TLSv1.3 Client Hello in a TLSv1.2 session, but server MUST NOT negotiate TLSv1.3 then?
How about this?
OpenSSL derived implementations don't even allow you to switch versions on renego at all because that would be insane. We do send the higher ClientHello version for the reasons EKR pointed out, but the ServerHello version must match. I would actually argue that it is fair game to assume version-related things are implicitly forked and locked (a 1.1 session implicitly cannot be resumed at 1.2, etc.), but the spec should be much clearer on this, so saying it explicitly now is a good idea.
Yes. , Hubert Kario EMAIL wrote:
I agree, resuming sessions must be at the same version and text saying so is a good idea.
NAME This is actually about negotiating at TLS 1.2 and then renegotiating to TLS 1.3. It's not clear how you would even manage to resume a TLS 1.2 session at TLS 1.3 or vice versa, but explicit text to this effect would be good. It has certainly historically been a mess.
OK, that should fix all the comments.
Merged. NAME please send me a PR adding yourself to Contributors
NAME here it is:

Revised text:
If a server receives a ClientHello at any other time, it MUST send a fatal "unexpected_message" alert and close the connection. <ins> If a server established a TLS session at a previous version of the protocol and receives a TLS 1.3 ClientHello in a renegotiation, it MUST retain the previous protocol version.  In particular, it MUST NOT negotiate TLS 1.3.  A client that receives a TLS 1.3 ServerHello in an established session MUST send a fatal "protocol_version" alert and close the connection. </ins> Structure of this message: %%% Key Exchange Messages