jiebi/ids-paragraph-commentary-corpus huggingface dataset:
Draft: draft-ietf-tls-esni

Commentary: Now that we have separate client  and server  sections , move some server text to the server section . Also clarify that the second ClientHelloOuterAAD is computed from the second ClientHelloOuter , not reusing the first value . ( Some cleanup in advance of writing up the HPKE context reuse version . ) 
 Can we merge this ? The number of PRs is getting confusing .
Paragraph (version A):
The "info" parameter to SetupPSKS is the concatenation of "tls ech",
a zero byte, and the serialized ECHConfig.  Clients then encrypt the
second ClientHelloInner using this new HPKE context.  In doing so,
the encrypted value is also authenticated by ech_hrr_key.  The
rationale for this is described in flow-hrr-hijack.
Paragraph (version A):
ClientHelloOuterAAD is computed from the second ClientHelloOuter as
described in authenticating-outer.  The "info" parameter to SetupPSKR
is computed as above.
Paragraph (version B):
The "info" parameter to SetupPSKS is the concatenation of "tls ech",
a zero byte, and the serialized ECHConfig.  ClientHelloOuterAAD is
computed from the second ClientHelloOuter as described in
authenticating-outer.  Note the encrypted value is also authenticated
by ech_hrr_key.  The rationale for this is described in flow-hrr-
hijack.
Paragraph (version B):
ClientHelloOuterAAD is computed from the second ClientHelloOuter as
described in authenticating-outer.  The "info" parameter to SetupPSKR
is the concatenation of "tls ech", a zero byte, and the serialized
ECHConfig.
Draft: draft-ietf-tls-esni

Commentary: As written , the backend server performs this modification unconditionally when it sees an empty ECH extension . Although the client is required to only offer TLS 1.3 , the backend server does n't check this . However , as noted elsewhere in the document , these same 8 bytes are used for the TLS 1.3 downgrade protection mechanism . That mechanism only works if the server never produces a TLS 1.2 ServerKeyExchange signature without the signal , so it 's important that the server not signal ECH acceptance . Write this down . 
 Oops . Good catch!Yup , this is a good idea .
Paragraph (version B):
The backend server MUST NOT perform this operation if it negotiated
TLS 1.2 or below.  Note that doing so would overwrite the downgrade
signal for TLS 1.3 (see RFC8446, Section 4.1.3).
Paragraph (version B):
Note that the same bytes of the ServerHello.random are used to
implement downgrade protection for TLS 1.3 (see RFC8446,
Section 4.1.3).  These mechanisms do not interfere because the
backend server only signals ECH acceptance in TLS 1.3 or higher.
Draft: draft-ietf-tls-esni

Commentary: This does n't bind anything , so no sense wasting bytes . ( Note : this is orthogonal to , but it makes more sense with that PR . ) 
 I guess this makes the text in a little odd because " Compare ClientECH.config_id against identifiers of known ECHConfigs and select the one that matches , if any , as a candidate . " , is a little less clear . If we want to do this , it maybe should say " and select any that match " , even though there 'll really just be one match . 
 ( Rebased and made the text talk about multiple potential matches . ) 
 This matches the acceptance signal length , and we 've already accepted that probability of collision . 
 I agree this is fine .
Paragraph (version A):
The configuration identifier, equal to "Expand(Extract("",
config), "tls ech config id", Nh)", where "config" is the
"ECHConfig" structure and "Extract", "Expand", and "Nh" are as
specified by the cipher suite KDF.  (Passing the literal """" as
the salt is interpreted by "Extract" as no salt being provided.)
The length of this value SHOULD NOT be less than 16 bytes unless
it is optional for an application; see optional-configs.
Paragraph (version B):
Set the "config_id" field to a randomly-generated 8-byte string.
Paragraph (version A):
Compare ClientECH.config_id against identifiers of known
ECHConfigs and select the one that matches, if any, as a
candidate.
Paragraph (version B):
Compare ClientECH.config_id against identifiers of known
ECHConfigs and select the ones that match, if any, as candidates.
Draft: draft-ietf-tls-esni

Commentary: cc 
 Yeah , that 's what I figured . I doubt we 'll need more than 8 , but we can pick a different range if that works ? 
 Yeah , this works for me . I do n't see any reason why we should keep the code points dense . 
 Note to self . Let 's pick a set and range that works .
Paragraph (version A):
encrypted_client_hello(0xff08), with "TLS 1.3" column values being
set to "CH, EE", and "Recommended" column being set to "Yes".
Paragraph (version A):
outer_extensions(0xff04), with the "TLS 1.3" column values being
set to "", and "Recommended" column being set to "Yes".
Paragraph (version B):
encrypted_client_hello(0xfe08), with "TLS 1.3" column values being
set to "CH, EE", and "Recommended" column being set to "Yes".
Paragraph (version B):
outer_extensions(0xfd00), with the "TLS 1.3" column values being
set to "", and "Recommended" column being set to "Yes".
Draft: draft-ietf-tls-esni

Commentary: This fixes a few issues with the " Upon determining the true SNI " paragraph : It talkes about determining the " true SNI " , but we should probably talk about the ClientHelloInner more generally . It refers to behavior in " the following section " which no longer matches . This is a remnant of before   was described as a special case of   , so remove it . It says the server forwards messages unmodified , which is n't true . It needs to forward the decrypted ClientHello . It also needs to process  . I 've cited the HRR section for the modified decryption procedure , which does n't really exist right now , but is handling that . 
 Yup , this aligns with my understanding !
Paragraph (version A):
Upon determining the true SNI, the client-facing server then either
serves the connection directly (if in Shared Mode), in which case it
executes the steps in the following section, or forwards the TLS
connection to the backend server (if in Split Mode).  In the latter
case, it does not make any changes to the TLS messages, but just
blindly forwards them.
Paragraph (version B):
Upon determining the ClientHelloInner, the client-facing server then
forwards the ClientHelloInner to the appropriate backend server,
which proceeds as in backend-server-behavior.  If the backend server
responds with a HelloRetryRequest, the client-facing server forwards
it, decrypts the client's second ClientHelloOuter using the modified
procedure in server-hrr, and forwards the resulting second
ClientHelloInner.  The client-facing server forwards all other TLS
messages between the client and backend server unmodified.
Draft: draft-ietf-tls-esni

Commentary: This clause is a remnant of when we tried to partition the resumption space across ECH negotiation , which was simplified in .
Paragraph (version A):
If the server sends a NewSessionTicket message, the corresponding PSK
MUST be ignored by all other servers in the deployment when not
negotiating ECH, including servers which do not implement this
specification.
Draft: draft-ietf-tls-esni

Commentary: We use a mix of sentence case and title case in the document . The RFC style guide says to use title case . This PR aligns with that . Additionally , the ESNI criteria document has changed slightly since the comparison against criteria section was written . I 've aligned the titles with the final wording in RFC8744 . RFC8744 has also merged " Proper security context " and " Split server spoofing " , so I 've done the same here . " Support Multiple Protocols " also now talks about transport protocols and ALPN , so I 've a few words about that .
Paragraph (version A):
This design permits servers operating in Split Mode to forward
connections directly to backend origin servers, thereby avoiding
unnecessary MiTM attacks.
Paragraph (version A):
Assuming ECH records retrieved from DNS are authenticated, e.g., via
DNSSEC or fetched from a trusted Recursive Resolver, spoofing a
server operating in Split Mode is not possible.  See plaintext-dns
for more details regarding plaintext DNS.
Paragraph (version A):
Authenticating the ECHConfigs structure naturally authenticates the
included public name.  This also authenticates any retry signals from
the server because the client validates the server certificate
against the public name before retrying.
Paragraph (version A):
This design has no impact on application layer protocol negotiation.
It may affect connection routing, server certificate selection, and
client certificate verification.  Thus, it is compatible with
multiple protocols.
Paragraph (version B):
This design permits servers operating in Split Mode to forward
connections directly to backend origin servers.  The client
authenticates the identity of the backend origin server, thereby
avoiding unnecessary MiTM attacks.
Paragraph (version B):
Conversely, assuming ECH records retrieved from DNS are
authenticated, e.g., via DNSSEC or fetched from a trusted Recursive
Resolver, spoofing a client-facing server operating in Split Mode is
not possible.  See plaintext-dns for more details regarding plaintext
DNS.
Paragraph (version B):
Authenticating the ECHConfigs structure naturally authenticates the
included public name.  This also authenticates any retry signals from
the client-facing server because the client validates the server
certificate against the public name before retrying.
Paragraph (version B):
This design has no impact on application layer protocol negotiation.
It may affect connection routing, server certificate selection, and
client certificate verification.  Thus, it is compatible with
multiple application and transport protocols.  By encrypting the
entire ClientHello, this design additionally supports encrypting the
ALPN extension.
Draft: draft-ietf-tls-esni

Commentary: I noticed there 's an OPEN ISSUE to add ClientHelloOuter guidance , but there 's already a section for it . Link to it and flesh it out a little more . Sadly , in doing so , I 've traded one OPEN ISSUE for another OPEN ISSUE , but hopefully that 'll be closed shortly .
Paragraph (version B):
The client might duplicate non-sensitive extensions in both messages.
However, implementations need to take care to ensure that sensitive
extensions are not offered in the ClientHelloOuter.  See outer-
clienthello for additional guidance.
Paragraph (version A):
Values which are independent of the true server name, or other
information the client wishes to protect, MAY be included in
ClientHelloOuter and compressed as described in outer-extensions.
Paragraph (version B):
A client may also use different preferences in different contexts.
For example, it may send a different ALPN lists to different servers
or in different application contexts.  A client that treats this
context as sensitive SHOULD NOT send context-specific values in
ClientHelloOuter.
Paragraph (version B):
Values which are independent of the true server name, or other
information the client wishes to protect, MAY be included in
ClientHelloOuter.  If they match the corresponding ClientHelloInner,
they MAY be compressed as described in outer-extensions.  However,
note the payload length reveals information about which extensions
are compressed, so inner extensions which only sometimes match the
corresponding outer extension SHOULD NOT be compressed.
Paragraph (version B):
Clients MAY include additional extensions in ClientHelloOuter to
avoid signaling unusual behavior to passive observers, provided the
choice of value and value itself are not sensitive.  See do-not-
stick-out.
Draft: draft-ietf-tls-esni

Commentary: There are two ClientHelloInners , the actual one used in the handshake , and the encoded one with outerextensions substituted in . Both are described as ClientHelloInner , but this makes it slightly ambiguous which goes into , say , the handshake transcript . ( It 's late now , so I 'll leave this as an issue without a PR . If we do n't end up resolving this separately , I 'll probably fix this as part of . If we decide to implicitly copy over legacysession_id , the encryption payload becomes less and less defensibly an actual ClientHelloInner . ) 
 In my own implementation , I 've been referring to the plaintext payload as CompressedClientHelloInner . Which is terrible , but unambiguous . 
 Works for me . I was thinking EncodedClientHelloInner because it 's shorter and still works even if you choose not to compress anything . ( A no - op encoding is still an encoding . ) 
 +1 to EncodedClientHelloInner , given that compression is optional . if you have time , could you whip up a PR ? 
 I noticed this while drafting a PR for . We 're a little inconsistent about whether the ClientHelloInner or ClientHelloOuter is constructed first . Section 4 says inner before outer : Section 5.1 implies inner before outer : But section 6.1 says outer before inner : I think inner before outer makes more sense . You certainly ca n't finish the outer one before you 've computed the inner one . ( Of course , an implementation can pick whatever order is most convenient , but I think the spec should be consistent with itself . )
Paragraph (version A):
It MAY offer any other extension in the ClientHelloOuter except
those that have been incorporated into the ClientHelloInner as
described in outer-extensions.
Paragraph (version A):
If implementing TLS 1.3's compatibility mode (see Appendix D.4 of
RFC8446), it MUST copy the legacy_session_id field from
ClientHelloOuter.  This allows the server to echo the correct
session ID when ECH is negotiated.
Paragraph (version B):
If implementing TLS 1.3's compatibility mode (see Appendix D.4 of
RFC8446), it MUST copy the legacy_session_id field from
ClientHelloInner.  This allows the server to echo the correct
session ID when ECH is negotiated.
Draft: draft-ietf-tls-esni

Commentary: Looks like this was missing .
Paragraph (version A):
This process is reversed by client-facing server.  Specifically, the
server replaces the "outer_extension" with the corresponding sequence
of extensions in the ClientHelloOuter.  The server then computes the
digest of the reconstructed ClientHelloInner.  If the digest does not
equal OuterExtensions.inner_digest, then the server MUST abort the
connection with a "decrypt_error" alert.
Paragraph (version B):
This process is reversed by client-facing server.  Specifically, the
server replaces the "outer_extension" with the corresponding sequence
of extensions in the ClientHelloOuter.  If any referenced extensions
are missing, the server MUST abort the connection with an
"illegal_parameter" alert.  The server then computes the digest of
the reconstructed ClientHelloInner.  If the digest does not equal
OuterExtensions.inner_digest, then the server MUST abort the
connection with a "decrypt_error" alert.
Draft: draft-ietf-tls-esni

Commentary: I think this is a more general attack and deserves a more general description of the mitigation . See and .
Paragraph (version A):
This attack uses resumption PSKs as an oracle for dictionary attacks
against a given ClientHello's true SNI.  To begin, the attacker first
interacts with a server to obtain a resumption ticket for a given
test domain, such as "test.com".  Later, upon receipt of a legitimate
ClientHello without a PSK binder, it computes a PSK binder using its
own ticket and forwards the resulting ClientHello.  Assume the server
then validates the PSK binder on the outer ClientHello and chooses
connection parameters based on the inner ClientHello.  A server which
then validates information in ClientHelloOuter ticket against
information in ClientHelloInner, such as the SNI, introduces an
oracle that can be used to test the encrypted SNI value of specific
ClientHello messages.
Paragraph (version A):
ECH mitigates against this attack by (1) prohibiting the
"pre_shared_key" extension in ClientHelloOuter and (2) requiring
servers ignore this extension when processing ClientHelloOuter.
Thus, if the server accepts the inner ClientHello, it only validates
binders in the inner ClientHello.  This means that PSKs are used
within the HPKE encryption envelope.
Paragraph (version B):
This attack aims to leak information about secret parts of the
encrypted ClientHello by adding attacker-controlled parameters and
observing the server's response.  In particular, the compression
mechanism described in outer-extensions references parts of a
potentially attacker-controlled ClientHelloOuter to construct
ClientHelloInner, or a buggy server may incorrectly apply parameters
from ClientHelloOuter to the handshake.
Paragraph (version B):
To begin, the attacker first interacts with a server to obtain a
resumption ticket for a given test domain, such as "example.com".
Later, upon receipt of a ClientHelloOuter, it modifies it such that
the server will process the resumption ticket with ClientHelloInner.
If the server only accepts resumption PSKs that match the server
name, it will fail the PSK binder check with an alert when
ClientHelloInner is for "example.com" but silently ignore the PSK and
continue when ClientHelloInner is for any other name.  This
introduces an oracle for testing encrypted SNI values.
Paragraph (version B):
This attack may be generalized to any parameter which the server
varies by server name, such as ALPN preferences.
Paragraph (version B):
ECH mitigates this attack by only using ClientHelloOuter to compute
ClientHelloInner and authenticating all of ClientHelloInner with the
HPKE AEAD.  If any extensions are compressed as in outer-extensions,
the OuterExtensions.inner_digest field authenticates the decompressed
result.  If none are compressed, the entire ClientHello is encrypted
and authenticated directly.  An earlier iteration of this
specification only encrypted and authenticated the "server_name"
extension, which left the overall ClientHello vulnerable to an
analogue of this attack.
Draft: draft-ietf-tls-esni

Commentary: The version check on the outer ClientHello does n't make much sense since , when ECH is accepted , the version is based on the inner ClientHello anyway . See I 've left a TODO since it seems weird to have a client requirement like that be so load - bearing without a corresponding server check . Not sure where we should go there . 
 I like this change , but it might be worth resolving the TODO . 
 Removed the TODO in favor of some clarifying text on the client side .
Paragraph (version A):
It MUST NOT offer to negotiate TLS 1.2 or below.
Paragraph (version B):
It MUST NOT offer to negotiate TLS 1.2 or below.  Note this is
necessary to ensure the backend server does not negotiate a TLS
version that is incompatible with ECH.
Paragraph (version A):
Upon receiving an "encrypted_client_hello" extension, the client-
facing server MUST check that it is able to negotiate TLS 1.3 or
greater.  If not, it MUST abort the connection with a
"handshake_failure" alert.
Paragraph (version B):
Upon receiving an "encrypted_client_hello" extension, the client-
facing server determines if it will accept ECH, prior to negotiating
any other TLS parameters.  Note that successfully decrypting the
extension will result in a new ClientHello to process, so even the
client's TLS version preferences may have changed.
Draft: draft-ietf-tls-esni

Commentary: cc 
 See
Paragraph (version A):
On the other hand, the probability that two 8-byte strings are the
same is non-negligible.  This poses a modest operational risk.
Suppose the client-facing server terminates the connection (i.e., ECH
is rejected or bypassed): if the last 8 bytes of its
ServerHello.random coincide with the confirmation signal, then the
client will incorrectly presume acceptance and proceed as if the
backend server terminated the connection.  However, the probability
of a false positive occurring for a given connection is only 1 in
2^64.
Paragraph (version B):
On the other hand, the probability that two 8-byte strings are the
same is non-negligible.  This poses a modest operational risk.
Suppose the client-facing server terminates the connection (i.e., ECH
is rejected or bypassed): if the last 8 bytes of its
ServerHello.random coincide with the confirmation signal, then the
client will incorrectly presume acceptance and proceed as if the
backend server terminated the connection.  However, the probability
of a false positive occurring for a given connection is only 1 in
2^64.  This value is smaller than the probability of network
connection failures in practice.
Draft: draft-ietf-tls-esni

Commentary: Section 6 : implementations to track , alongside each PSK established by a previous connection , whether the connection negotiated this extension with the " echaccept " response type . If so , this is referred to as an " ECH PSK " . Otherwise , it is a " non - ECH PSK " . This may be implemented by adding a new field to client and server session states . " echaccept " is not defined anywhere . 
 I suspect " the connection negotiated this extension with the ' ech_accept ' response type " is an incorrect way of saying that ECH was accepted .
Paragraph (version A):
Per client-behavior and server-behavior, implementations are required
to track, alongside each PSK established by a previous connection,
whether the connection negotiated this extension with the
"ech_accept" response type.  If so, this is referred to as an "ECH
PSK".  Otherwise, it is a "non-ECH PSK".  This may be implemented by
adding a new field to client and server session states.
Paragraph (version B):
Per client-behavior and server-behavior, implementations are required
to track, alongside each PSK established by a previous connection,
whether ECH was accepted for this connection.  If so, this is
referred to as an "ECH PSK".  Otherwise, it is a "non-ECH PSK".  This
may be implemented by adding a new field to client and server session
states.
Draft: draft-ietf-tls-esni

Commentary: While reading the draft , I 'm confused with ClientEncryptedCH structure . Section : The " encryptedclienthello " extension says ... ~ enc : The HPKE encapsulated key , used by servers to decrypt the corresponding field . encryptedch : The serialized and encrypted ClientHelloInner structure , encrypted using HPKE as described in { { send - ech } } . and Section : Sending an encrypted ClientHello says ... The encrypted ClientHello value is then computed as : ~ Cause output of the context . Seal ( ) function is ciphertext output of AEAD encryption ( According to draft - irtf - cfrg - hpke-05 ) , I think encryptedch has only ciphertext value of the ClientHelloInner , not the enc value . But the same section also says ... encryptedch contains the HPKE encapsulated key ( enc ) and the ClientHelloInner ciphertext ( encryptedchinner ) . Q. Does encryptedch have enc and encryptedchinner ? Or it just has the ciphertext of ClientHelloInner and encryptedch_inner is just mistype ? 
 Nice catch ! should just be the AEAD ciphertext . The following text is wrong : ciphertext ( encryptedchinner ) . It should be : cc/ 
 OK , there 's no .. thanks !
Paragraph (version A):
encrypted_ch contains the HPKE encapsulated key (enc) and the
ClientHelloInner ciphertext (encrypted_ch_inner).
Paragraph (version B):
encrypted_ch contains the AEAD-encrypted ClientHelloInner.