Subject: Re: [TLS] ALPN concerns

From: Brian Smith <[email-masked]>
Date: Mon, 9 Dec 2013 05:32:53 -0800

Hi Andrei,

Sorry for the delay. Please see replies inline.

On Tue, Nov 19, 2013 at 11:42 AM, Andrei Popov
<[email-masked]> wrote:
> I totally agree that we need to encrypt more information in the TLS handshake,
> including the client cert and the contents of various extensions, such as SNI and ALPN.
> Unfortunately, the only way to make this information confidential in the existing versions
> of TLS is to incur additional round-trips (by using renegotiation, or otherwise exchanging
> messages after the TLS handshake is complete). This is one of the reasons why the TLS
> WG is pushing hard to make progress on TLS1.3.

Unfortunately, like I said in my previous message, I think it will be
extremely difficult, and probably impossible, for us to encrypt the
ALPN (and SNI) part of the handshake in TLS 1.3 if we standardize and
deploy the current ALPN design. As soon as we start using it, web
browsers will have a compatibility burden to continue sending the
unencrypted ALPN header in their ClientHello, because we won't be able
to assume that the server supports TLS 1.3's encrypted ALPN.

Note that this is not a problem for NPN because NPN does not disclose
any information in the ClientHello. We can completely change how
protocol negotiation works in TLS 1.3, and clients that support NPN
could seemlessly transition to the new mechanism without risking any
negative compatibility or performance impact.

>> As far as I've been led to believe, ALPN exists primarily to allow MitM to more easily
>> inspect what protocol the application is speaking and possibly block the application,
>> with as low of a cost to the MitM as possible--i.e. exactly the opposite goal of
>> everything we discussed at IETF88 in perpass and in other discussions.
>
> No, ALPN exists primarily to negotiate an application protocol without incurring extra
> round-trips, to allow the server to pick the application protocol and present the
> corresponding identity, and to align with the existing TLS extensions.

I have discussed the ALPN vs NPN issue with Eric Rescorla (co-chair of
this working group, alongside Joseph Salowey from Cisco) multiple
times, and each time Eric said that allowing passive MitM devices to
know which protocol is being used is important, and that this is an
advantage for ALPN over NPN. I will let him explain why, if it hasn't
already been explained on the list. FWIW, I strongly disagree that it
should be a goal to allow passive MitM to know which protocol is being
used. In fact, I think that we should have a goal of protecting the
protocol information so that passive MitM has a much more difficult
time of determining with certainty the protocol being used.

>>I think that in many cases, traffic analysis that relies on timing information will be
>>able to tell with a high degree of accuracy which protocol has been selected for use
>>on the connection. However, traffic analysis cannot tell us what protocols were
>> offered but *not* selected.
>
> Correct, and NPN offers the list of the application protocols in clear-text, so it does
> not solve this problem.

NPN does solve this problem *for the client*. NPN does not solve the
problem for the server. However, in the context of web browsers doing
normal web browsing stuff (as opposed to DTLS in WebRTC), the client's
privacy is fundamentally more important than the server's privacy in
this respect. Additionally, if you have a publicly-accessible server
on the internet, people could always probe it (with either ALPN or
NPN) to determine which protocols, which versions of protocols, and
likely which implementations of those protocols are available, so
protecting the server's privacy in this regard is futile. Conversely,
protecting the client's privacy is much more practical and useful. We
have seen, for example, how the Tor protocol attempts to make its TLS
handshake look like a browser's handshakes in order to thwart blocking
filtering of the Tor protocol.

> If we can avoid application protocol negotiation at the TLS layer without incurring additional round-trips, I am in full support. Looking forward to the write-up.

I am sorry that I've yet to create an internet draft describing the
idea. However, hopefully the following description, which is
copy-pasted from a private email sent to others previously, describes
the idea clearly enough. Note that some things need to be refined;
e.g. what happens when the client guesses the server's ECDH parameter
requirements wrongly.

First, let's assume that we can restrict things to ephemeral key
exchange mechanisms: TLS_ECDHE_* and TLS_DHE_*. For simplicity, let's
restrict things further and talk about TLS_ECDHE_*. Also, let's assume
for now that we don't care about the case where there are client
certificates.

Let's imagine that a client can guess the 1-3 most likely curves that
the server is likely to choose for the ECDHE key exchange. That is
actually pretty easy now, even without any prior contact to the
server, because the server is almost always going to choose P-256,
P-384, P-521, in that order. So, the client could presumptuously
generate its own private/public keypair for those 1-3 curves before it
even connects to the server, right? Well, then it could just include
the public keys in an extension in its client hello, right? Then, when
the server has finished its ServerHello...ServerHelloDone, it has
enough information to send ChangeCipherSuite and Finished just like a
resumption handshake. That is, we've transformed the TLS full
handshake from a 2-RTT, client-sends-application-data-first handshake
into a 1-RTT server-sends-application-data-first handshake that is
equivalent to the 2-RTT version, in terms of security properties.
(Compare this to False Start or Snap Start, which both have weaker
security properties.) In other words, it is better performance
effectively for free.

Now, In order for the client and server to agree to do this, they have
to agree on it via some TLS extension--namely, the TLS extension that
contains the client's public keys. Now, imagine that this same
extension also contained a number N which means "the first four bytes
of application data contain a number N; following that are N bytes of
application data are actually connection-specific metadata that is
prefixed to the actual application data."

The peer TLS implementation would process these N bytes of metadata by
reading them and exposing them to the application through some API,
and then passing the actual application data to the application.

What kind of metadata would be in this header? At a minimum, I would
expect that the server would include information such as what
protocols it supports (replacing NPN), whether the server is HSTS
(i.e. bringing HSTS to IMAP, SMTP, POP, IRC, etc.), the server's key
pinning information (replacing HPKP), and whether the server wants to
force OCSP stapling (replacing the Must-Staple header that I will
propose soon). For the client, it would include information such as
what protocol it has chosen to speak (replacing NPN) and its channel
ID key/proof of possession (replacing channel ID).

Above, I just described a TLS handshake that looks like this:

H ClientHello
  (Client Key)  ---------------->
                <---------------- H ServerHello
                                  H Certificate
                                  H CertificateStatus
                                  H ServerKeyExchange
                                  H ServerHelloDone
                                  H NewSessionTicket
                                  C ChangeCipherSpec
                                  H Finished
                                  A Trust Metadata
C ChangeCipherSpec ------------->
H Finished
A Trust Metadata
A Application data <------------> A Application data

Now, we might worry that some intermediaries will choke on this
strange-looking handshake? Can we turn it into something that they
won't choke on? Yes, we can:

H ClientHello
H (Client Key)  ---------------->
                <---------------- H ServerHello
                                    (Server Key)
                                  C ChangeCipherSpec
                                  H Finished
                                  A Certificate
                                  A CertificateStatus
                                  A ServerKeyExchange
                                  A ServerHelloDone
                                  A NewSessionTicket
                                  A Trust Metadata
C ChangeCipherSpec ------------->
H Finished
A Trust Metadata
A Application data <------------> A Application data

Note that all the application data records are encrypted so the
intermediary can't read them--that is, it can't tell the difference
between metadata and actual application data, so it looks like this to
them:

H ClientHello
H (Client Key)  ---------------->
                <---------------- H ServerHello
                                    (Server Key)
                                  C ChangeCipherSpec
                                  H Finished
                                  A Application data
C ChangeCipherSpec ------------->
H Finished
A Application data <------------> A Application data

I.e. it looks exactly like the server false start handshake to an
outside observer. This should minimize the compatibility impact of
supporting the mechanism.

Besides creating a framework similar to "encrypted extensions" that
you could use for channel ID, this also gives us encrypted session
tickets, which means that there is a certain amount of unlinkability
between connections that wasn't there originally. Further, making the
Certificate and CertificateStatus messages opaque to outsiders allows
us to apply compression to those parts of the handshake without
worrying about intermediates choking on the compressed data. And/or we
can define new, non-X.509 certificate formats without fear of breakage
by intermediaries. We could also add back client certificates by
adding Certificate and CertificateVerify messages before the client's
Metadata. This would give us encrypted client certificates. Also, by
mandating TLS 1.2 for this mechanism, we can overload it as a TLS
downgrade prevention mechanism (if we can solve the
downgrade-to-SSL3.0-without-extensions issue). If we were to establish
some standards for padding session tickets to a certain size, then the
client could always send a session ticket in every client hello
(either a real one, or a randomly-generated one of the right size).
This would, I hope, eliminate the possibility to determine whether or
a handshake is a resumption handshake or a full handshake--i.e. mask
whether or not the user has visited the site before/recently.
(Measuring the timing of the server's side of the handshake would give
things away, but that is a harder attack to pull off.)

At a higher level, this breaks TLS into three distinct phases: (1) TLS
is the layer that establishes the keys and authenticates the
connection with those keys, mutually anonymously, (2) the Trust
Metadata phase is where the TLS stack and the application work
together to establish trust of the peer and of the peer's data, and
(3) the application data phase is well, the application data. Given
this, we could say that the TLS working group is responsible for
defining the first phase (TLS) while perhaps some other groups could
define the second phase (Trust Metadata). My hope is that the trust
metadata layer might be useful even in non-TLS protocols.

Cheers,
Brian

---

From: Nikos Mavrogiannopoulos <[email-masked]>
Date: Mon, 09 Dec 2013 15:07:50 +0100

> time of determining with certainty the protocol being used.

I think we need to clarify not only the reason we need the protocol
negotiation in TLS but most importantly, how we expect implementations
to support it.

If we expect a lightweight super-server or a firewall to do the mapping
of the incoming protocol requests in the client hello to the appropriate
servers, then having NPN means that the firewall or super-server has to
terminate TLS in order to discover the intended protocol. That's pretty
unacceptable in many scenarios, not only because of the unnecessary load
on the firewall/super-server, but also because it makes TLS client
authentication very hard to impossible.

If we expect that the incoming protocol requests will be handled by a
single server application (that is no super-servers or a firewall will
be involved to distribute the protocols)... then NPN suits that
scenario, and provides more than ALPN. However one server handling all
possible protocols feels like a very restricted use-case.

regards,
Nikos

---

From: Andrei Popov <[email-masked]>
Date: Mon, 9 Dec 2013 20:25:32 +0000

Hi Brian,

Thanks for describing your ideas for early encryption in the TLS handshake. At a high level, this looks very similar to some of the flows in Eric Rescorla's TLS 1.3 draft. Perhaps what we need is to converge on the next level of detail, and I believe Eric will welcome your suggestions\feedback as he is working on an updated draft.

I agree that TLS 1.3 deployment will be a challenge, but I don't believe ALPN vs. NPN will make it any harder or easier. Either the server will support the TLS 1.3 protocol, with its encrypted extensions and application protocol negotiation mechanism, or a fallback to TLS 1.2/1.1/1.0 will need to take place, at which point the current clear-text extensions will need to be sent.

Cheers,

Andrei

-----Original Message-----
From: Brian Smith [mailto:[email-masked]] 
Sent: Monday, December 9, 2013 5:33 AM
To: Andrei Popov
Cc: <[email-masked]>; Peter Gutmann
Subject: Re: [TLS] ALPN concerns

Hi Andrei,

On Tue, Nov 19, 2013 at 11:42 AM, Andrei Popov <[email-masked]> wrote:
> I totally agree that we need to encrypt more information in the TLS 
> handshake, including the client cert and the contents of various extensions, such as SNI and ALPN.
> Unfortunately, the only way to make this information confidential in 
> the existing versions of TLS is to incur additional round-trips (by 
> using renegotiation, or otherwise exchanging messages after the TLS 
> handshake is complete). This is one of the reasons why the TLS WG is pushing hard to make progress on TLS1.3.

Unfortunately, like I said in my previous message, I think it will be extremely difficult, and probably impossible, for us to encrypt the ALPN (and SNI) part of the handshake in TLS 1.3 if we standardize and deploy the current ALPN design. As soon as we start using it, web browsers will have a compatibility burden to continue sending the unencrypted ALPN header in their ClientHello, because we won't be able to assume that the server supports TLS 1.3's encrypted ALPN.

Note that this is not a problem for NPN because NPN does not disclose any information in the ClientHello. We can completely change how protocol negotiation works in TLS 1.3, and clients that support NPN could seemlessly transition to the new mechanism without risking any negative compatibility or performance impact.

>> As far as I've been led to believe, ALPN exists primarily to allow 
>> MitM to more easily inspect what protocol the application is speaking 
>> and possibly block the application, with as low of a cost to the MitM 
>> as possible--i.e. exactly the opposite goal of everything we discussed at IETF88 in perpass and in other discussions.
>
> No, ALPN exists primarily to negotiate an application protocol without 
> incurring extra round-trips, to allow the server to pick the 
> application protocol and present the corresponding identity, and to align with the existing TLS extensions.

I have discussed the ALPN vs NPN issue with Eric Rescorla (co-chair of this working group, alongside Joseph Salowey from Cisco) multiple times, and each time Eric said that allowing passive MitM devices to know which protocol is being used is important, and that this is an advantage for ALPN over NPN. I will let him explain why, if it hasn't already been explained on the list. FWIW, I strongly disagree that it should be a goal to allow passive MitM to know which protocol is being used. In fact, I think that we should have a goal of protecting the protocol information so that passive MitM has a much more difficult time of determining with certainty the protocol being used.

>>I think that in many cases, traffic analysis that relies on timing 
>>information will be able to tell with a high degree of accuracy which 
>>protocol has been selected for use on the connection. However, traffic 
>>analysis cannot tell us what protocols were  offered but *not* selected.
>
> Correct, and NPN offers the list of the application protocols in 
> clear-text, so it does not solve this problem.

NPN does solve this problem *for the client*. NPN does not solve the problem for the server. However, in the context of web browsers doing normal web browsing stuff (as opposed to DTLS in WebRTC), the client's privacy is fundamentally more important than the server's privacy in this respect. Additionally, if you have a publicly-accessible server on the internet, people could always probe it (with either ALPN or
NPN) to determine which protocols, which versions of protocols, and likely which implementations of those protocols are available, so protecting the server's privacy in this regard is futile. Conversely, protecting the client's privacy is much more practical and useful. We have seen, for example, how the Tor protocol attempts to make its TLS handshake look like a browser's handshakes in order to thwart blocking filtering of the Tor protocol.

> If we can avoid application protocol negotiation at the TLS layer without incurring additional round-trips, I am in full support. Looking forward to the write-up.

I am sorry that I've yet to create an internet draft describing the idea. However, hopefully the following description, which is copy-pasted from a private email sent to others previously, describes the idea clearly enough. Note that some things need to be refined; e.g. what happens when the client guesses the server's ECDH parameter requirements wrongly.

First, let's assume that we can restrict things to ephemeral key exchange mechanisms: TLS_ECDHE_* and TLS_DHE_*. For simplicity, let's restrict things further and talk about TLS_ECDHE_*. Also, let's assume for now that we don't care about the case where there are client certificates.

Let's imagine that a client can guess the 1-3 most likely curves that the server is likely to choose for the ECDHE key exchange. That is actually pretty easy now, even without any prior contact to the server, because the server is almost always going to choose P-256, P-384, P-521, in that order. So, the client could presumptuously generate its own private/public keypair for those 1-3 curves before it even connects to the server, right? Well, then it could just include the public keys in an extension in its client hello, right? Then, when the server has finished its ServerHello...ServerHelloDone, it has enough information to send ChangeCipherSuite and Finished just like a resumption handshake. That is, we've transformed the TLS full handshake from a 2-RTT, client-sends-application-data-first handshake into a 1-RTT server-sends-application-data-first handshake that is equivalent to the 2-RTT version, in terms of security properties.
(Compare this to False Start or Snap Start, which both have weaker security properties.) In other words, it is better performance effectively for free.

Now, In order for the client and server to agree to do this, they have to agree on it via some TLS extension--namely, the TLS extension that contains the client's public keys. Now, imagine that this same extension also contained a number N which means "the first four bytes of application data contain a number N; following that are N bytes of application data are actually connection-specific metadata that is prefixed to the actual application data."

The peer TLS implementation would process these N bytes of metadata by reading them and exposing them to the application through some API, and then passing the actual application data to the application.

What kind of metadata would be in this header? At a minimum, I would expect that the server would include information such as what protocols it supports (replacing NPN), whether the server is HSTS (i.e. bringing HSTS to IMAP, SMTP, POP, IRC, etc.), the server's key pinning information (replacing HPKP), and whether the server wants to force OCSP stapling (replacing the Must-Staple header that I will propose soon). For the client, it would include information such as what protocol it has chosen to speak (replacing NPN) and its channel ID key/proof of possession (replacing channel ID).

H ClientHello
  (Client Key)  ---------------->
                <---------------- H ServerHello
                                  H Certificate
                                  H CertificateStatus
                                  H ServerKeyExchange
                                  H ServerHelloDone
                                  H NewSessionTicket
                                  C ChangeCipherSpec
                                  H Finished
                                  A Trust Metadata C ChangeCipherSpec -------------> H Finished A Trust Metadata A Application data <------------> A Application data

Now, we might worry that some intermediaries will choke on this strange-looking handshake? Can we turn it into something that they won't choke on? Yes, we can:

H ClientHello
H (Client Key)  ---------------->
                <---------------- H ServerHello
                                    (Server Key)
                                  C ChangeCipherSpec
                                  H Finished
                                  A Certificate
                                  A CertificateStatus
                                  A ServerKeyExchange
                                  A ServerHelloDone
                                  A NewSessionTicket
                                  A Trust Metadata C ChangeCipherSpec -------------> H Finished A Trust Metadata A Application data <------------> A Application data

Note that all the application data records are encrypted so the intermediary can't read them--that is, it can't tell the difference between metadata and actual application data, so it looks like this to
them:

H ClientHello
H (Client Key)  ---------------->
                <---------------- H ServerHello
                                    (Server Key)
                                  C ChangeCipherSpec
                                  H Finished
                                  A Application data C ChangeCipherSpec -------------> H Finished A Application data <------------> A Application data

I.e. it looks exactly like the server false start handshake to an outside observer. This should minimize the compatibility impact of supporting the mechanism.

Besides creating a framework similar to "encrypted extensions" that you could use for channel ID, this also gives us encrypted session tickets, which means that there is a certain amount of unlinkability between connections that wasn't there originally. Further, making the Certificate and CertificateStatus messages opaque to outsiders allows us to apply compression to those parts of the handshake without worrying about intermediates choking on the compressed data. And/or we can define new, non-X.509 certificate formats without fear of breakage by intermediaries. We could also add back client certificates by adding Certificate and CertificateVerify messages before the client's Metadata. This would give us encrypted client certificates. Also, by mandating TLS 1.2 for this mechanism, we can overload it as a TLS downgrade prevention mechanism (if we can solve the downgrade-to-SSL3.0-without-extensions issue). If we were to establish some standards for padding session tickets to a certain size, then the client could always send a session ticket in every client hello (either a real one, or a randomly-generated one of the right size).
This would, I hope, eliminate the possibility to determine whether or a handshake is a resumption handshake or a full handshake--i.e. mask whether or not the user has visited the site before/recently.
(Measuring the timing of the server's side of the handshake would give things away, but that is a harder attack to pull off.)

At a higher level, this breaks TLS into three distinct phases: (1) TLS is the layer that establishes the keys and authenticates the connection with those keys, mutually anonymously, (2) the Trust Metadata phase is where the TLS stack and the application work together to establish trust of the peer and of the peer's data, and
(3) the application data phase is well, the application data. Given this, we could say that the TLS working group is responsible for defining the first phase (TLS) while perhaps some other groups could define the second phase (Trust Metadata). My hope is that the trust metadata layer might be useful even in non-TLS protocols.

Cheers,
Brian

---

From: Pascal Urien <[email-masked]>
Date: Mon, 9 Dec 2013 21:39:05 +0100

Hi all

2013/11/19 Andrei Popov <[email-masked]>

> handshake, including the client cert and the contents of various
> extensions, such as SNI and ALPN. Unfortunately, the only way to make this
> information confidential in the existing versions of TLS is to incur
> additional round-trips (by using renegotiation, or otherwise exchanging
> messages after the TLS handshake is complete). This is one of the reasons
> why the TLS WG is pushing hard to make progress on TLS1.3.
>

Encryption of the client's certificate is possible without renegociation

See
http://tools.ietf.org/id/draft-urien-badra-eap-tls-identity-protection-01.txt

The idea is very simple, just add a key for the client's certificate
encryption such as

  enc-key = PRF(SecurityParameters.master_secret,
                 "client_certificate",
                  SecurityParameters.client-random +
                  SecurityParameters.server-random);

Some slides from the IETF 66th

http://www.ietf.org/proceedings/66/slides/emu-2/sld1.htm

This feature has been implemented and tested with TLS1.0

Regards

Pascal Urien