Draft: draft-ietf-tls-sni-encryption

Commentary: Rewrite the draft to only include the informational part . Move specification part to a companion draft .
This draft describes the general problem of encryption of the Server
Name Identification (SNI) parameter.  The proposed solutions hide a
Hidden Service behind a Fronting Service, only disclosing the SNI of
the Fronting Service to external observers.  The draft starts by
listing known attacks against SNI encryption, discusses the current
"co-tenancy fronting" solution, and then presents two potential TLS
layer solutions that might mitigate these attacks.
The first solution is based on TLS in TLS "quasi tunneling", and the
second solution is based on "combined tickets".  These solutions only
require minimal extensions to the TLS protocol.
This draft describes the general problem of encryption of the Server
Name Identification (SNI) parameter.  The proposed solutions hide a
Hidden Service behind a Fronting Service, only disclosing the SNI of
the Fronting Service to external observers.  The draft lists known
attacks against SNI encryption, discusses the current "co-tenancy
fronting" solution, and presents requirements for future TLS layer
solutions.
The current draft proposes two designs for SNI Encryption in TLS.
Both designs hide a "Hidden Service" behind a "Fronting Service".  To
an external observer, the TLS connections will appear to be directed
towards the Fronting Service.  The cleartext SNI parameter will
document the Fronting Service.  A second SNI parameter will be
transmitted in an encrypted form to the Fronting Service, and will
allow that service to redirect the connection towards the Hidden
Service.
The first design relies on tunneling TLS in TLS, as explained in
snitunnel.  It does not require TLS extensions, but relies on
conventions in the implementation of TLS 1.3 I-D.ietf-tls-tls13 by
the Client and the Fronting Server.
The second design, presented in comboticket removes the requirement
for tunneling, on simply relies on Combined Tickets.  It uses the
extension process for session tickets already defined in I-D.ietf-
tls-tls13.
This draft is presented as is to trigger discussions.  It is expected
that as the draft progresses, only one of the two proposed solutions
will be retained.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in RFC2119.
The SNI extension was standardized in 2003 in RFC3546 to facilitate
management of "colocation servers", in which a multiple services
shared the same IP address.  A typical example would be mutiple web
sites served by the same web server.  The SNI extension carries the
name of a specific server, enabling the TLS connection to be
established with the desired server context.  The current SNI
extension specification can be found in RFC6066.
The SNI specification allowed for different types of server names,
but only the "hostname" variant was standardized and deployed.  In
that variant, the SNI extension carries the domain name of the target
server.  The SNI extension is carried in clear text in the TLS
"Client Hello" message.
The SNI is probably also included in the general collection of
metadata by pervasive surveillance actors.
The clear-text transmission of the SNI was not flagged as a problem
in the security consideration sections of RFC3546, RFC4366, or
RFC6066.  These specifications did not anticipate the abuses
described in snileak.  One reason may be that, when these RFCs were
written, the SNI information was available through a variety of other
means.
Many deployments still allocate different IP addresses to different
services, so that different services can be identified by their IP
addresses.  However, content distribution networks (CDN) commonly
serve a large number of services through a small number of addresses.
The SNI carries the domain name of the server, which is also sent as
part of the DNS queries.  Most of the SNI usage described in snileak
could also be implemented by monitoring DNS traffic or controlling
DNS usage.  But this is changing with the advent of DNS resolvers
providing services like DNS over TLS RFC7858 or DNS over HTTPS I-
D.ietf-doh-dns-over-https.
The common name component of the server certificate generally exposes
the same name as the SNI.  In TLS versions 1.0 RFC2246, 1.1 RFC4346,
and 1.2 RFC5246, the server send their certificate in clear text,
ensuring that there would be limited benefits in hiding the SNI.  But
the transmission of the server certificate is protected in TLS 1.3 I-
D.ietf-tls-tls13.
The decoupling of IP addresses and server names, the deployment of
DNS privacy, and the protection of server certificates transmissions
all contribute to user privacy.  Encrypting the SNI now will complete
this push for privacy and make it much harder to censor specific
internet services.
Deploying SNI encryption will help thwarting most the "unanticipated"
SNI usages described in snileak, including censorship and pervasive
surveillance.  It will also thwart functions that are sometimes
described as legitimate.  Most of these functions can however be
realized by other means.  For example, some DNS service providers
offer customers the provision to "opt in" filtering services for
parental control and phishing protection.  Per stream QoS can be
provided by a combination of packet marking and end to end
agreements.  Enterprises can deploy monitoring software to control
usage of the enterprises computers.  As SNI encryption becomes
common, we can expect more deployment of such "end to end" solutions.
When designing SNI encryption schemes, we have to take into account
attacks that strip parameters from the Client Hello, or replay
attacks.  In both cases, the desired behavior is to fall back to a
connection with the fronting server, so there is no visble difference
between a regular connection to that server and an atempt to reach
the hidden server.
When designing SNI encryption schemes, we have to take into account
attacks that strip parameters from the Client Hello, or replay
attacks.  In both cases, the desired behavior is to fall back to a
connection with the fronting server, so there is no visble difference
between a regular connection to that server and an attempt to reach
the hidden server.
The discovery issue is common to pretty much every SNI encryption
solution, and is also discussed in tlsintlsclientreq and
newfirstsession.  The browser issue may be solved by developing a
browser extension that support HTTP Fronting, and manages the list of
fronting services associated with the hidden services that the client
uses.  The multi-protocol issue can be mitigated by using
implementation of other applications over HTTP, such as for example
DNS over HTTPS I-D.hoffman-dns-over-https.  The trust issue, however,
requires specific developments.
The discovery issue is common to pretty much every SNI encryption
solution.  The browser issue may be solved by developing a browser
extension that support HTTP Fronting, and manages the list of
fronting services associated with the hidden services that the client
uses.  The multi-protocol issue can be mitigated by using
implementation of other applications over HTTP, such as for example
DNS over HTTPS I-D.hoffman-dns-over-https.  The trust issue, however,
requires specific developments.
Clients would see their privacy compromised if they contacted the
wrong fronting server to access the hidden service, since this wrong
server could disclose their access to adversaries.  This can possibly
be mitigated by recording the relation between fronting server and
hidden server in a Delegation Token.
If N multiple domains on a CDN are acceptable fronts, then we may
want some way to indicate this without publishing and maintaining N
separate tokens.
Delegation tokens could be published by the fronting server, in
response for example to a specific query by a client.  The client
would then examine whether one of the Delegation Tokens matches the
hidden service that it wants to access.
QUESTION: Do we need a revocation mechanism?  What if a fronting
service obtains a delegation token, and then becomes untrustable for
some other reason?  Or is it sufficient to just use short TTL?
We propose to provide SNI Privacy by using a form of TLS
encapsulation.  The big advantage of this design compared to previous
attempts is that it requires effectively no changes to TLS 1.3.  It
only requires a way to signal to the Fronting Server server that the
encrypted application data is actually a ClientHello which is
intended for the hidden service.  Once the tunneled session is
established, encrypted packets will be forwarded to the Hidden
Service without requiring encryption or decryption by the Fronting
Service.
The proposed design is to encapsulate a second Client Hello in the
early data of a TLS connection to the Fronting Service.  To the
outside, it just appears that the client is resuming a session with
the fronting service.
in the client's first flight, which is actually ClientHello#2 from
the client, containing the true SNI and then passes it on to the
Hidden server.  However, the Hidden Server responds with its own
ServerHello which the Fronting Server just passes unchanged, because
it's actually the response to ClientHello#2 rather than to
ClientHello#1.  As long as ClientHello#1 and ClientHello#2 are
similar (e.g., differing only in the client's actual share (though of
course it must be in the same group)), SNI, and maybe
EarlyDataIndication), then an attacker should not be able to
distinguish these cases -- although there may be possible attacks
through timing analysis, or by observing traffic between the Fronting
Server and Hidden Server if they are not colocated.
The big advantage of this design is that it requires effectively no
changes to TLS.  It only requires a way to signal to the Fronting
Server that the encrypted application data is actually a ClientHello
which is intended for the hidden service.
The major disadvantage of this overall design strategy (however it's
signaled) is that it's somewhat harder to implement in the co-
tenanted cases than the simple schemes that carry the "real SNI" in
an encrypted parameter of the Client Hello.  That means that it's
somewhat less likely that servers will implement it "by default" and
more likely that they will have to take explicit effort to allow
Encrypted SNI.  Conversely, however, these schemes (aside from a
server with a single wildcard or multi-SAN cert) involve more changes
to TLS to deal with issues like "what is the server cert that is
digested into the keys", and that requires more analysis, so there is
an advantage to deferring that.  If we have EncryptedExtensions in
the client's first flight it would be possible to define a "Real SNI"
extension later if/when we had clearer analysis for that case.
The client part of that logic, including the handling of question #3
above, is discussed in tlsintlsclientreq.
EncryptedExtensions would be the most natural, but they were removed
from the ClientHello during the TLS standardization.  In tlsintls we
assume that the second ClientHello is just transmitted as 0-RTT data,
and that the servers use some form of pattern matching to
differentiate between this second ClientHello and other application
messages.
Each of these ways has its issues.  The double encryption scenario
would require two end of early data messages, one double encrypted
and relayed by the Fronting Server to the Hidden Server, and another
sent from Client to Fronting Server, to delimit the end of the double
encrypted stream, and also to ensure that the stream of messages is
not distinguishable from simply sending 0-RTT data to the Fronting
server.  The blind relaying is simpler, and is the scenario described
in the diagram of tlsintls.  In that scenario, the Fronting server
switches to relaying mode immediately after unwrapping and forwarding
the second ClientHello.  However, the blind relaying requires the
ClientHello to be isolated to a single record.
In order to use the tunneling service, the client needs to identify
the Fronting Service willing to tunnel to the Hidden Service.  We can
assume that the client will learn the identity of suitable Fronting
Services from the Hidden Service itself.
In order to tunnel the second ClientHello as 0-RTT data, the client
needs to have a shared secret with the Fronting Service.  To avoid
the trap of "well known shared secrets" described in sharedsecrets,
this should be a pair wise secret.  The most practical solution is to
use a session resumption ticket.  This requires that prior to the
tunneling attempt, the client establishes regular connections with
the fronting service and obtains one or several session resumption
tickets.
EDITOR'S NOTE: This section is an alternative design to snitunnel.
As the draft progresses, only one of the alternatives will be
selected, and the text corresponding to the other alternative will be
deleted.
We propose to provide SNI Privacy by relying solely on "combined
tickets".  The big advantage of this design compared to previous
attempts is that it requires only minimal changes to implementations
of TLS 1.3.  These changes are confined to the handling of the
combined ticket by Fronting and Hidden service, and to the signaling
of the Fronting SNI to the client by the Hidden service.
The Fronting server that receives the Client Hello will find the
combined ticket in the pre_shared_key extensions, just as it would in
a regular session resumption attempt.  When parsing the ticket, the
Fronting server will discover that the session really is meant to be
resumed with the Hidden server.  It will arrange for all the
connection data to be forwarded to the Hidden server, including
forwarding a copy of the initial Client Hello.
The Hidden server will receive the Client Hello.  It will obtain the
identity of the Fronting service from the SNI parameter.  It will
then parse the session resumption ticket, and proceed with the
resumption of the session.
In this design, the Client Hello message is relayed unchanged from
Fronting server to hidden server.  This ensures that code changes are
confined to the interpretation of the message parameters.  The
construction of handshake contexts is left unchanged.
The hidden server can just refresh the ticket any time it pleases, as
usual.
This design allows the Hidden Service to hide behind many Fronting
Services, each using a different key.  The Client Hello received by
the Hidden Server carries the SNI of the Fronting Service, which the
Hidden Server can use to select the appropriate K_sni.
In the public key design, the Hidden Server encrypts the tickets with
a public key of the Fronting Server.  The ticket itself would be
similar to what is used in the shared key design.  The compute cost
for a single decryption may be higher, but the Fronting Server would
not need to blindly try multiple decryption keys associated with
multiple Hidden Servers.  The Hidden Server would not be able to
decrypt the ession Tickets, which means that it would have to rely on
some kind of stateful storage.
The previous sections present how sessions can be resumed with the
combined ticket.  Clients have that have never contacted the Hidden
Server will need to obtain a first ticket during a first session.
The most plausible option is to have the client directly connect to
the Hidden Service, and then ask for a combined ticket.  The obvious
issue is that the SNI will not be encrypted for this first
connection, which exposes the client to surveillance and censorship.
The client may also learn about the relation between Fronting Service
and Hidden Service through an out of band channel, such as DNS
service, or word of mouth.  However, it is difficult to establish a
combined ticket completely out of band, since the ticket must be
associated to two shared secrets, one understood by the Fronting
service and the other shared with the Hidden service to ensure
protection against replay attacks.
An alternative may be to use the TLS-in-TLS service described in
tlsintls for the first contact.  There will be some overhead due to
tunnelling, but as we discussed in tlsintlsclientreq the tunneling
solution allows for safe first contact.  Yet another way would be to
use the HTTPS in HTTPS tunneling described in httpfrontingtunnels.
The encapsulation protocol proposed in this draft mitigates the known
attacks listed in snisecreq.  For example, the encapsulation design
uses pairwise security contexts, and is not dependent on the widely
shared secrets described in sharedsecrets.  The design also does not
rely on additional public key operations by the multiplexed server or
by the fronting server, and thus does not open the attack surface for
denial of service discussed in serveroverload.  The session keys are
negotiated end to end between the client and the protected service,
as required in nocontextsharing.
The combined ticket solution also mitigates the known attacks.  The
design also uses pairwise security contexts, and is not dependent on
the widely shared secrets described in sharedsecrets.  The design
also does not rely on additional public key operations by the
multiplexed server or by the fronting server, and thus does not open
the attack surface for denial of service discussed in serveroverload.
The session keys are negotiated end to end between the client and the
protected service, as required in nocontextsharing.
However, in some cases, proper mitigation depends on careful
implementation.
Both solutions mitigate the replay attacks described in replayattack
because adversaries cannot decrypt the replies intended for the
client.  However, the connection from the fronting service to the
hidden service can be observed through side channels.
To give an obvious example, suppose that the fronting service merely
relays the data by establishing a TCP connection to the hidden
service.  An adversary capable of observing all network traffic at
the fronting server can associate the arrival of an encrypted message
to the fronting service and the TCP handshake between the fronting
server and the hidden service, and deduce which hidden service the
user accessed.
The mitigation of this attack relies on proper implementation of the
fronting service.  This may require cooperation from the multiplexed
server.
The TLS encapsulation protocol mostly fulfills the requirements to
"not stick out" expressed in snireqdontstickout.  The initial
messages will be sent as 0-RTT data, and will be encrypted using the
0-RTT key negotiated with the fronting service.  Adversaries cannot
tell whether the client is using TLS encapsulation or some other
0-RTT service.  However, this is only true if the fronting service
regularly uses 0-RTT data.
The combined token solution almost perfectly fulfills the
requirements to "not stick out" expressed in snireqdontstickout, as
the observable flow of message is almost exactly the same as a
regular TLS connection.  However, adversaries could observe the
values of the PSK Identifier that contains the combined ticket.  The
proposed ticket structure is designed to thwart analysis of the
ticket, but if implementations are not careful the size of the
combined ticket can be used as a side channel allowing adversaries to
distinguish between different Hidden Services located behind the same
Fronting Service.
In the TLS encapsulation protocol, the encapsulated Client Hello is
encrypted using the session resumption key.  If this key is revealed,
the Client Hello data will also be revealed.  The mitigation there is
to not use the same session resumption key multiple time.
The most common implementations of TLS tickets have the server using
Session Ticket Encryption Keys (STEKs) to create an encrypted copy of
the session parameters which is then stored by the client.  When the
client resumes, it supplies this encrypted copy, the server decrypts
it, and has the parameters it needs to resume.  The server need only
remember the STEK.  If a STEK is disclosed to an adversary, then all
of the data encrypted by sessions protected by the STEK may be
decrypted by an adversary.
To mitigate this attack, server implementations of the combined
ticket protocol SHOULD use stateful tickets instead of STEK protected
TLS tickets.  If they do rely on STEK protected tickets, they MUST
ensure that the K_sni keys used to encrypt these tickets are rotated
frequently.
Do we need to register an extension point?  Or is it just OK to use
early data?
During the discussion of SNI Encryption in Yokohama, Deb Cooley
argued that rather than messing with TLS to allow SNI encryption, we
should just tunnel TLS in TLS.  A number of people objected to this
on the grounds of the performance cost for the Fronting Server
because it has to encrypt and decrypt everything.
After the meeting, Martin Thomson suggested a modification to the
tunnelling proposal that removes this cost.  The key observation is
that if we think of the 0-RTT flight as a separate message attached
to the handshake, then we can tunnel a second first flight in it.
The combined ticket approach was first proposed by Cedric Fournet and
Antoine Delignaut-Lavaud.
The delegation token design comes from many people, including Ben
Schwartz, Brian Sniffen and Rich Salz.
Clients would see their privacy compromised if they contacted the
wrong fronting server to access the hidden service, since this wrong
server could disclose their access to adversaries.  This requires a
controlled way to indicate which fronting ferver is acceptable by the
hidden service.
This problem is both similar and different from the "fronting server
spoofing" attack described in frontingspoofing.  Here, the spoofing
would be performed by distributing fake advice, such as "to reach
example hidden.example.com, use fake.example.com as a fronting
server", when "fake.example.com" is under the control of an
adversary.
In practice, this attack is well mitigated when the hidden service is
accessed through a specialized application.  The name of the fronting
server can then be programmed in the code of the application.  But
the attack is much harder to mitigate when the hidden service has to
be accessed through general purpose web browsers.  The browsers will
need a mechanism to obtain the fronting server indication in a secure
way.
There are several proposed solutions to this problem, such as
creating a special form of certificate to codify the relation between
fronting and hidden server, or obtaining the relation between hidden
and fronting service through the DNS, possibly using DNSSEC to avoid
spoofing.
We can observe that content distribution network have a similar
requirement.  They need to convince the client that "www.example.com"
can be accessed through the seemingly unrelated "cdn-node-
xyz.example.net".  Most CDN have deployed DNS-based solutions to this
problem.
Replacing clear text SNI transmission by an encrypted variant will
improve the privacy and reliability of TLS connections, but the
design of proper SNI encryption solutions is difficult.  This
document does not present the design of a solution, but provide
guidelines for evaluating proposed solutions.
This document lists a number of attacks against SNI encryption in
snisecreq, and also in delegationtokens, and presents a list of
requirements to mitigate these attacks.  The current HTTP based
solutions described in httpfronting only meet some of these
requirements.  In practice, it may well be that no solution can meet
every requirement, and that practical solutions will have to make
some compromises.
In particular, the requirement to not stick out presented in
snireqdontstickout may have to be lifted, especially if for proposed
solutions that could quickly reach large scale deployments.
This draft does not require any IANA action.