Draft: draft-ietf-tls-esni

Commentary: Resolves a second issue detailed in Replaces the empty encryptedclienthello extension with a new extension , isclienthello_inner , to indicate that the ClientHello is a ClientHelloInner . Let me know if I 've completely misunderstood what the issue was or what the fix was supposed to be . 
 would you remind rebasing ? 
 can you please resolve conflicts ? 
 ESNI seems to rely on TLS 1.3 KeyShareEntry which makes it incompatible with TLS 1.2 . That 's unfortunate with that " The protocol designed in this document is quite straightforward . " The gist of ESNI comes down to " encryptedservername extension , which contains the true extension encrypted under the provider ’s public key . " That seems pretty generic and backwards compatible . 
 To prevent cut - and - paste attacks , you need to bind ESNI to the CH . That means we ’d need 1.2 clients to send a key share in the CH to use when deriving encryption keying material , and that ’s not currently done . 
 Since TLS 1.2 sends the server certificate in plaintext it seems like ESNI would n't be particularly useful there anyway , no ? 
 Indeed . I guess someone could argue about wildcard certificates or when multiple names are present but the names are usually related so I agree there ’s no significant benefit from encrypting the SNI .
Paragraph (version A):
When a client wants to establish a TLS session with the backend
server, it constructs its ClientHello as usual (we will refer to this
as the ClientHelloInner message) and then encrypts this message using
the public key of the ECH configuration.  It then constructs a new
ClientHello (ClientHelloOuter) with innocuous values for sensitive
extensions, e.g., SNI, ALPN, etc., and with an
"encrypted_client_hello" extension, which this document defines
(encrypted-client-hello).  The extension's payload carries the
encrypted ClientHelloInner and specifies the ECH configuration used
for encryption.  Finally, it sends ClientHelloOuter to the server.
Paragraph (version B):
When a client wants to establish a TLS session with the backend
server, it constructs its ClientHello as indicated in real-ech.  (We
will refer to this as the ClientHelloInner message.)  The client
encrypts this message using the public key of the ECH configuration.
It then constructs a new ClientHello (ClientHelloOuter) with
innocuous values for sensitive extensions, e.g., SNI, ALPN, etc., and
with an "encrypted_client_hello" extension, which this document
defines (encrypted-client-hello).  The extension's payload carries
the encrypted ClientHelloInner and specifies the ECH configuration
used for encryption.  Finally, it sends ClientHelloOuter to the
server.
Paragraph (version A):
Some TLS 1.3 extensions can be quite large and having them both in
ClientHelloInner and ClientHelloOuter will lead to a very large
overall size.  One particularly pathological example is "key_share"
with post-quantum algorithms.  In order to reduce the impact of
duplicated extensions, the client may use the "outer_extensions"
extension.
Paragraph (version B):
Some TLS 1.3 extensions can be quite large and having them both in
ClientHelloInner and ClientHelloOuter will lead to a very large
overall size.  One particularly pathological example is "key_share"
with post-quantum algorithms.  In order to reduce the impact of
duplicated extensions, the client may use the "ech_outer_extensions"
extension.
Paragraph (version A):
The client then MAY substitute extensions which it knows will be
duplicated in ClientHelloOuter.  To do so, the client removes and
replaces extensions from EncodedClientHelloInner with a single
"outer_extensions" extension.  Removed extensions MUST be ordered
consecutively in ClientHelloInner.  The list of outer extensions,
OuterExtensions, includes those which were removed from
EncodedClientHelloInner, in the order in which they were removed.
Paragraph (version A):
The client-facing server computes ClientHelloInner by reversing this
process.  First it makes a copy of EncodedClientHelloInner and copies
the legacy_session_id field from ClientHelloOuter.  It then looks for
an "outer_extensions" extension.  If found, it replaces the extension
with the corresponding sequence of extensions in the
ClientHelloOuter.  If any referenced extensions are missing or if
"encrypted_client_hello" appears in the list, the server MUST abort
the connection with an "illegal_parameter" alert.
Paragraph (version A):
The "outer_extensions" extension is only used for compressing the
ClientHelloInner.  It MUST NOT be sent in either ClientHelloOuter or
ClientHelloInner.
Paragraph (version B):
The "ech_outer_extensions" extension is only used for compressing the
ClientHelloInner.  It MUST NOT be sent in either ClientHelloOuter or
ClientHelloInner.
Paragraph (version B):
ClientHelloOuterAAD is computed as described in authenticating-outer,
but again using the second ClientHelloOuter.  Note an HPKE context
maintains a sequence number, so this operation internally uses a
fresh nonce for the AEAD operation.  Reusing the HPKE context avoids
an attack described in flow-hrr-hijack.
Paragraph (version A):
Servers that that implement the ECH extension play one of two roles,
depending on the form of the ECH extension in the ClientHello.  If
the extension value is non-empty, the server acts as a client-facing
server and proceeds as described in client-facing-server to extract a
ClientHelloInner if available.  If the extension value is empty, the
server acts as a backend server and proceeds as described in backend-
server.
Paragraph (version B):
Servers that support ECH play one of two roles, depending on the
extension in the ClientHello.  If the "encrypted_client_hello"
extension is present, the server acts as a client-facing server and
proceeds as described in client-facing-server to extract a
ClientHelloInner, if available.  If the "ech_is_inner" extension is
present and the "encrypted_client_hello" extension is not present,
the server acts as a backend server and proceeds as described in
backend-server.
Paragraph (version B):
Upon receiving an "encrypted_client_hello" extension in an initial
ClientHello, 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.
Paragraph (version B):
ClientHelloOuterAAD is computed as described in authenticating-outer,
but using the second ClientHelloOuter.  If decryption fails, the
client-facing server MUST abort the handshake with a "decrypt_error"
alert.  Otherwise, it reconstructs the second ClientHelloInner from
the new EncodedClientHelloInner as described in encoding-inner, using
the second ClientHelloOuter for any referenced extensions.
Paragraph (version B):
The client-facing server then forwards the resulting ClientHelloInner
to the backend server.  It forwards all subsequent TLS messages
between the client and backend server unmodified.
Paragraph (version B):
Upon receipt of an "ech_is_inner" extension in a ClientHello, if the
backend server negotiates TLS 1.3 or higher, then it MUST confirm ECH
acceptance to the client by computing its ServerHello as described
here.  If both the "ech_is_inner" and "encrypted_client_hello"
extensions are present in the ClientHello, the backend server MUST
abort with an "illegal_parameter" alert.
Paragraph (version B):
where Derive-Secret and Handshake Secret are as specified in RFC8446,
Section 7.1 and ClientHelloInner..ServerHelloECHConf refers to the
sequence of handshake messages beginning with the first ClientHello
and ending with ServerHelloECHConf.  Finally, the backend server
constructs its ServerHello message so that it is equal to
ServerHelloECHConf but with the last 8 bytes of ServerHello.random
set to the first 8 bytes of accept_confirmation.
Paragraph (version B):
This attack is mitigated by using the same HPKE context for both
ClientHello messages.  The attacker does not possess the context's
keys, so it cannot generate a valid encryption of the second inner
ClientHello.
Paragraph (version B):
If the attacker could manipulate the second ClientHello, it might be
possible for the server to act as an oracle if it required parameters
from the first ClientHello to match that of the second ClientHello.
For example, imagine the client's original SNI value in the inner
ClientHello is "example.com", and the attacker's hijacked SNI value
in its inner ClientHello is "test.com".  A server which checks these
for equality and changes behavior based on the result can be used as
an oracle to learn the client's SNI.
Paragraph (version A):
encrypted_client_hello(0xfe08), with "TLS 1.3" column values being
set to "CH, EE", and "Recommended" column being set to "Yes".
Paragraph (version A):
outer_extensions(0xfd00), with the "TLS 1.3" column values being
set to "", and "Recommended" column being set to "Yes".
Paragraph (version A):
IANA is requested to create an entry, ech_required(121) in the
existing registry for Alerts (defined in RFC8446), with the "DTLS-OK"
column being set to "Y".
Paragraph (version B):
encrypted_client_hello(0xfe09), with "TLS 1.3" column values set
to "CH, EE", and "Recommended" column set to "Yes".
Paragraph (version B):
ech_outer_extensions(0xfd00), with the "TLS 1.3" column values set
to "", and "Recommended" column set to "Yes".
Paragraph (version B):
IANA is requested to create an entry, ech_required(121) in the
existing registry for Alerts (defined in RFC8446), with the "DTLS-OK"
column set to "Y".