Subject: http2 opportunistic security negotiation

From: Erik Nygren <[email-masked]>
Date: Thu, 5 Feb 2015 10:08:58 -0500

While digging further into server-side implementation details of the
current opportunistic security draft, we identified a user experience
problem.  In particular, for a site that has Virtual Hosts which are
HTTP-only (ie, there is no valid certificate for them), there is no way in
the current proposal to both support Opportunistic Security  (negotiate h2
for http scheme over TLS without a necessarily valid certificate) without
also giving users accidentally typing in https URIs a certificate mismatch
interstitial they'd be prompted to click through.

Based on a number of discussions, a preferable behavior when a client tries
to access an HTTP-only site over HTTPS is to error out the TLS negotiation
rather than present a certificate mismatch.  However, there is also a
desire for the TLS handshake for OppSec to look identical to a non-OppSec
handshake to external observers.  Because of this, the current proposal
(send alpn=h2 for OppSec http scheme and for https scheme) means the server
does not know whether to negotiate h2 for OppSec http or return a TLS
handshake error for "no certificate available for this hostname" which is
the desired https behavior).

One proposal that came out of some offline discussion would be for clients
capable of doing HTTP/2 OppSec to always send in the client_hello
alpn=h2,h2o  (where "h2o" here might be some alpn token for HTTP/2 OppSec
for HTTP scheme).
The server would then:

* Negotiate alpn=h2o with a possibly invalid cert for an HTTP-only
ServerName/Host
* Negotiate alpn=h2 with a valid cert for a ServerName/Host supporting HTTPS
* Return a TLS handshake error ("no cert for this hostname") if neither are
available  (eg, for HTTP/1.1)

The downside of this is that the "h2o" server_hello negotiation would be
in-the-clear in TLS 1.2 (not desirable), although it will be encrypted in
TLS 1.3.  In true "opportunistic" fashion this may be an acceptable
trade-off as clients and servers supporting TLS 1.3 will then get the
additional level of protection over passive eavesdroppers seeing whether
OppSec was negotiated.

Another positive of this approach is that it might be reasonable to also
use an "h1o" ALPN token to allow for OppSec negotiation of HTTP/1.1 over
TLS.  For example, extensions like "HTTPS Everywhere" could potentially use
this even without HTTP/2 support.  (The problem with an OppSec for HTTP/1.1
had been a lack of a way to negotiate the scheme securely, but a separate
ALPN token provides this.)

         Erik

---

From: Ilari Liusvaara <[email-masked]>
Date: Thu, 5 Feb 2015 18:28:45 +0200

> additional level of protection over passive eavesdroppers seeing whether

Even TLS 1.3 won't encrypt the ALPN (at least as TLS 1.3 currently is).

-Ilari

---

From: Erik Nygren <[email-masked]>
Date: Thu, 5 Feb 2015 17:21:26 -0500

> Even TLS 1.3 won't encrypt the ALPN (at least as TLS 1.3 currently is).

Why can't the server's ALPN response be in EncryptedExtensions for a TLS
1.3 ServerHello
even if the client's ALPN (a superset so less interesting) is in-the-clear
in the ClientHello?

     Erik

---

From: Eric Rescorla <[email-masked]>
Date: Fri, 6 Feb 2015 11:03:19 +1100

> even if the client's ALPN (a superset so less interesting) is in-the-clear

That is my expectation, since it falls into the category of extensions
"which are not needed to establish the cryptographic context"

-Ekr

---

From: Ilari Liusvaara <[email-masked]>
Date: Fri, 6 Feb 2015 10:10:33 +0200

> even if the client's ALPN (a superset so less interesting) is in-the-clear

Ah yeah, Server's ALPN. Client's ALPN would be always constant per client.

Also, it occurs to me that if one can tell from certificate if it is
supposed to be valid or not, the ALPN leak does not add much:

- On TLS 1.2, one can inspect certificate of connection before deciding
  to MITM or not (since nothing before it has any commitments).
- In TLS 1.3, where that isn't possible (there are commitments from
  both sides before), one can still connect to the server and probe
  the certificate.

Then there are some servers where getting good certificate is
much less of a problem than dealing with the https:// scheme
(due to legacy internal baggage).

-Ilari

---

From: Martin Thomson <[email-masked]>
Date: Sat, 7 Feb 2015 08:35:17 +1100

I wouldn't assume to know with 100% confidence what any given client will
accept.
On Feb 6, 2015 7:16 PM, "Ilari Liusvaara" <[email-masked]>

---

From: Patrick McManus <[email-masked]>
Date: Tue, 10 Feb 2015 17:47:09 -0500

I might be under-thinking this one.... but it occurs to me its possible to
not put the tls version of the site on 443 if there is no https:// version
of the site.. oe doesn't require a particular port number and 443 seems
like the wrong choice if https:// isn't available. too simplistic?

---

From: Erik Nygren <[email-masked]>
Date: Tue, 10 Feb 2015 18:14:12 -0500

The two motivations for OE are to 1) help HTTP/2 deployment for HTTP-scheme
sites by getting around meddlesome middle-boxes, while 2) also providing a
tiny bit of protection against pervasive monitoring.  In both cases, the
closer the traffic is to HTTPS traffic (port 443) the more likely it is to
make it through and work without interference.  Both argue for using port
443 with a handshake where at least the ClientHello is indistinguishable
between a true HTTPS request and an OE HTTP request.

The "cleanest" solution would just be to give OE for HTTP/2 its own ALPN
token such that it is explicitly negotiated where you only send that token
in your ClientHello.  This would help for #1 but is not ideal for #2.  On
the other hand, there are some many attack vectors for #2 that it seems
more worthwhile to make sure #1 works well while raising the bar a little
for #2 where possible.

       Erik

On Tue, Feb 10, 2015 at 5:47 PM, Patrick McManus <[email-masked]>
wrote:

> not put the tls version of the site on 443 if there is no https://
> version of the site.. oe doesn't require a particular port number and 443
> seems like the wrong choice if https:// isn't available. too simplistic?
>

---

From: Patrick McManus <[email-masked]>
Date: Tue, 10 Feb 2015 19:02:32 -0500

What about 421 for https scheme or any h1 on 443?
On Feb 10, 2015 6:14 PM, "Erik Nygren" <[email-masked]> wrote:

> The two motivations for OE are to 1) help HTTP/2 deployment for
> HTTP-scheme sites by getting around meddlesome middle-boxes, while 2) also
> providing a tiny bit of protection against pervasive monitoring.  In both
> cases, the closer the traffic is to HTTPS traffic (port 443) the more
> likely it is to make it through and work without interference.  Both argue
> for using port 443 with a handshake where at least the ClientHello is
> indistinguishable between a true HTTPS request and an OE HTTP request.
>
>> I might be under-thinking this one.... but it occurs to me its possible
>> to not put the tls version of the site on 443 if there is no https://

---

From: Patrick McManus <[email-masked]>
Date: Tue, 10 Feb 2015 20:21:42 -0500

I guess what I meant, but didn't say, was I don't understand your assertion
that this needs to be handled at the TLS layer.

This is afterall a typo in the uri - and that's always a problem for
routing :)

There are lots of existing pure h1 sites that have working
http://example.com and an https://example.com that gives a cert warning and
then a broken website if you proceed. We can certainly do better than a
broken website using http level response codes 3xx or 4xx, and if the
possibility of a typo leading to a cert dialog is so painful I would
suggest a valid cert might be the right option for such a org.. the usual
reasons around why-not-https (3rd party content, referrer) really don't
apply strongly to responding to this particular transaction.

crazy?