Subject: Client certificates in HTTP/2

From: Yoav Nir <[email-masked]>
Date: Tue, 9 Jun 2015 10:58:00 +0300

Hi

Long time ago there was a long discussion about using client certificates on the web with HTTP/2. Feel free to skip the next paragraph if you remember the issue.

Most of the web does not use client certificates. Websites that do don’t like users to get a certificate picker when they first land on the page. So what they do is protect the site with regular, server-authenticated TLS and have a landing page. On the landing page there’s going to be something clickable that says “login with certificates”. When the user clicks that, it sends a request for some resource (maybe “/loginWithCerts.html”). When the server gets that request, it triggers the TLS layer to re-negotiate, this time with the certificate request message that causes the certificate picker to pop up. This is the way it’s usually done in HTTP/1, but for HTTP/2, section 9.2.1 prohibits this use or renegotiation and hints at future specification that might provide this.

So a year ago Martin Thomson wrote a pair of draft for solving this: one an HTTP authentication scheme that just says, “go away and come back with a certificate”, while the other is a TLS extension that tells the server that the client would like to authenticate:
https://tools.ietf.org/html/draft-thomson-httpbis-catch-00
https://tools.ietf.org/html/draft-thomson-tls-care-00

Neither was adopted, here or at TLS, so currently HTTP/2 is not usable with mutual authentication. Why has this (useful IMO) extension withered on the vine rather than progressed?  If anyone needs help in pushing this along, I’ll be glad to help.

Yoav

---

From: Mike Bishop <[email-masked]>
Date: Tue, 9 Jun 2015 17:51:39 +0000

There have been a number of suggestions for this scenario, and none of them are entirely satisfying.

The TLS WG, last I heard, was discussing a way to present client certificates without full-blown renegotiation.  I'm not sure how the mechanics of that have progressed, if at all, but depending on the form, that might solve this discussion for TLS 1.3.  It doesn't help TLS 1.2, however, where HTTP/2 imposes a restriction on renegotiation.

Our implementation supports two different approaches:  A client which has a client cert ready to offer will send an extension setting TLS_RENEG_PERMITTED advertising that it's willing to accept a server-initiated renegotiation.  If the server also supports that extension, they can renegotiate as they have always done and exchange certs.  (Our client will only advertise that if it has the cert ready, to minimize the stall introduced to other streams by the reneg exchange.  Cert selection can involve showing UI, and we don't want to stall the network on the user.)  If the client doesn't offer that extension, we'll send HTTP_1_1_REQUIRED and drop the client back to HTTP/1.1, where we'll renegotiate to get the client cert.  Definitely not ideal, but it's the only fully-standardized approach that exists right now.

Martin's approach, along with the early-renegotiation dance in the HTTP/2 spec, still forces the creation of a new TLS connection, something we'd prefer to avoid.  It's better than HTTP_1_1_REQUIRED in that it lets the client keep using HTTP/2, but worse in that it mixes the TLS and HTTP layers, something we'd also prefer to minimize.

-----Original Message-----
From: Yoav Nir [mailto:[email-masked]] 
Sent: Tuesday, June 9, 2015 12:58 AM
To: HTTP Working Group
Subject: Client certificates in HTTP/2

Hi

Yoav

---

From: Ilari Liusvaara <[email-masked]>
Date: Tue, 9 Jun 2015 21:48:54 +0300

On Tue, Jun 09, 2015 at 05:51:39PM +0000, Mike Bishop wrote:
> 
> Martin's approach, along with the early-renegotiation dance in the
> HTTP/2 spec, still forces the creation of a new TLS connection,
> something we'd prefer to avoid.  It's better than HTTP_1_1_REQUIRED
> in that it lets the client keep using HTTP/2, but worse in that it
> mixes the TLS and HTTP layers, something we'd also prefer to minimize.

If one really wants to avoid new TLS connection creation in something
that could be actually secure, one would have to support SPDY-style
client certificate slots, presumably signaling which slot to use per
request in Authorization: header.

This is because changing connection authentication mid-connection is
asking for security problems (especially if client side is a browser),
even if no proxies are involved.

Of course, doing SPDY-style auth safely requires EMS or TLS 1.3+.

-Ilari

---

From: Yoav Nir <[email-masked]>
Date: Tue, 9 Jun 2015 22:43:21 +0300

> On Jun 9, 2015, at 8:51 PM, Mike Bishop <[email-masked]> wrote:
> 

To me the “No soup for you!” approach is considerably less satisfying than any of them.

> The TLS WG, last I heard, was discussing a way to present client certificates without full-blown renegotiation.  I'm not sure how the mechanics of that have progressed, if at all, but depending on…

TLS 1.3 may allow the client to present a certificate without being prompted by the server. That still requires the client to foresee the need for sending a particular certificate. The user interaction would still be weird if you only want to browse the public parts of a website or if you haven’t plugged in your dongle or if you have your key store configured to require a passphrase to use the certificate. What TLS 1.3 will offer is equivalent to Martin’s draft-thomson-tls-care. It’s not enough by itself.

> Our implementation supports two different approaches:  A client which has a client cert ready to offer will send an extension setting TLS_RENEG_PERMITTED advertising that it's willing to accept a s…

That’s the “No soup for you” approach. I also question whether you can standardize the TLS_RENEG_PERMITTED extension, because this WG went out of its way to prohibit this behavior, and the reason was IIRC that it led to a race condition between the authentication and the multiple parallel streams. That’s not helped by the client announcing that it has a certificate.

> Martin's approach, along with the early-renegotiation dance in the HTTP/2 spec, still forces the creation of a new TLS connection, something we'd prefer to avoid.  It's better than HTTP_1_1_REQUIRE…

While I agree that creation of new TLS streams is something you would want to minimize, the use cases for client certificate are such that this happens seldom. Certificate are used in SSL VPNs, a few high-value websites like some banks (most of them use other methods), corporate portals. These are things the average user would need either a few times a month or a few times a day. As for mixing layers, it’s no worse than an HTTP resource request triggering a TLS renegotiation with different parameters.

Yoav

---

From: "Adrien de Croy" <[email-masked]>
Date: Tue, 09 Jun 2015 21:34:48 +0000

------ Original Message ------
From: "Mike Bishop" <[email-masked]>
To: "Yoav Nir" <[email-masked]>; "HTTP Working Group" 
<[email-masked]>
Sent: 10/06/2015 5:51:39 a.m.
Subject: RE: Client certificates in HTTP/2

<snip>

>
>A client which has a client cert ready to offer will send an extension 
>setting TLS_RENEG_PERMITTED advertising that it's willing to accept a 
>server-initiated renegotiation.
>
I don't really like this approach.  When would the client send this 
option?

a) always -> let's tell every site we have a client cert
b) only on sites where the client previously received a request for a 
cert -> yay another database to maintain
c) after some strange UI (open this link with client cert)
d) by magic

What's wrong with being challenged for a client cert, it's just like 
being challenged for auth, we're not proposing deprecating 403 are we?

Some sites may wish to make it conditional whether a client cert is 
required based on other things.  This requirement to pre-advertise 
support just seems like bad engineering when TLS already has a mechanism 
to deal with client certs

Adrien

---

From: "Adrien de Croy" <[email-masked]>
Date: Tue, 09 Jun 2015 22:13:46 +0000

-
>being challenged for auth, we're not proposing deprecating 403 are we?
sorry should have been 401/407

---

From: Martin Thomson <[email-masked]>
Date: Tue, 9 Jun 2015 15:15:42 -0700

> a) always -> let's tell every site we have a client cert

I think that this is the only sensible option.  But it wouldn't tell
sites that you have a cert, because you would send it unconditionally,
even if you didn't have a cert.

---

From: "Adrien de Croy" <[email-masked]>
Date: Tue, 09 Jun 2015 22:18:45 +0000

>From an information theory POV it only carries any information if it may 
sometime not be sent.  If it is always sent it is completely redundant 
and just protocol bloat and should be removed just to reduce bandwidth, 
if the server can't assume it means there is a cert, then we are back at 
the challenge.

------ Original Message ------
From: "Martin Thomson" <[email-masked]>
To: "Adrien de Croy" <[email-masked]>
Cc: "Mike Bishop" <[email-masked]>; "Yoav Nir" 
<[email-masked]>; "HTTP Working Group" <[email-masked]>
Sent: 10/06/2015 10:15:42 a.m.
Subject: Re: Client certificates in HTTP/2

---

From: Martin Thomson <[email-masked]>
Date: Tue, 9 Jun 2015 15:26:32 -0700

On 9 June 2015 at 15:18, Adrien de Croy <[email-masked]> wrote:
> sometime not be sent.

Sure, IE will send it, Firefox won't.

---

From: "Adrien de Croy" <[email-masked]>
Date: Tue, 09 Jun 2015 22:26:31 +0000

so the proposal is to include some flag in all requests (but maybe not 
by some browsers) which can't be used by the server.

That doesn't seem like a good use of resource.

Or is tongue firmly planted in cheek on this one?

Did you forget Chromium as well?

------ Original Message ------
From: "Martin Thomson" <[email-masked]>
To: "Adrien de Croy" <[email-masked]>
Cc: "Mike Bishop" <[email-masked]>; "Yoav Nir" 
<[email-masked]>; "HTTP Working Group" <[email-masked]>
Sent: 10/06/2015 10:26:32 a.m.
Subject: Re: Client certificates in HTTP/2

---

From: Martin Thomson <[email-masked]>
Date: Tue, 9 Jun 2015 15:40:58 -0700

On 9 June 2015 at 15:26, Adrien de Croy <[email-masked]> wrote:
>
> so the proposal is to include some flag in all requests (but maybe not by
> some browsers) which can't be used by the server.

Sure it can be used.

> That doesn't seem like a good use of resource.

It's a few bytes.  We've wasted a lot more elsewhere for less worthy
reasons.  Not that I think this is a great idea, but I can appreciate
that Microsoft have to do *something*.  It's an existing use that
isn't well served.  I'd rather the option I proposed, but we're not
seeing a lot of movement on the client authentication piece.

Maybe when Microsoft produce a proposal for TLS 1.3, we'll be a better
position.  Maybe that will be possible when the TLS 1.3 key schedule
and handshake becomes stable (which should be very soon).

> Or is tongue firmly planted in cheek on this one?

Not this time.  I refer you to:
http://download.microsoft.com/download/C/6/C/C6C3C6F1-E84A-44EF-82A9-49BD3AAD8F58/Windows/%5BMS-HTTP2E-Preview%5D.pdf

> Did you forget Chromium as well?

I never forget Chromium, or Safari, or Opera, or Yandex, or UC
browser...  I just don't know what they plan to do yet.  I think that
Chromium have disabled renegotiation, but I wasn't sure.

---

From: "Adrien de Croy" <[email-masked]>
Date: Tue, 09 Jun 2015 22:46:21 +0000

------ Original Message ------
From: "Martin Thomson" <[email-masked]>
To: "Adrien de Croy" <[email-masked]>
Cc: "Mike Bishop" <[email-masked]>; "Yoav Nir" 
<[email-masked]>; "HTTP Working Group" <[email-masked]>
Sent: 10/06/2015 10:40:58 a.m.
Subject: Re: Client certificates in HTTP/2

>>  some browsers) which can't be used by the server.

so the server is entitled to send a request if it sees the flag, is that 
the intention?

In which case, why not just let the server send the request if it wants 
a client cert, and the client can bounce the request if it doesn't want 
to support that.  That has several benefits.

1. reduced cost.  Only incur cost when the server wants a client cert, 
rather than on all connections.
2. clients can measure how often they are asked for a cert so that devs 
can make decisions about whether to support it or not.

>seeing a lot of movement on the client authentication piece.
OK, I agree something needs to be done to carry over client cert auth.

>http://download.microsoft.com/download/C/6/C/C6C3C6F1-E84A-44EF-82A9-49BD3AAD8F58/Windows/%5BMS-HTTP2E-Preview%5D.pdf
thanks for the link

Adrien

---

From: Mike Bishop <[email-masked]>
Date: Tue, 9 Jun 2015 22:55:51 +0000

We don't have a client cert much of the time.  Two flows exist:

a)  The app above us (above WinInet) knows it needs to supply a client cert.  It sets one on the request, but obviously we can't send it until the server requests it.  We turn on the setting at that point, in anticipation of the server wanting it.

b)  The HTTP/2 server sent us back to HTTP/1.1, and we renegotiated there without stalling anything.  We now have a client cert in memory for that origin, so we'll send the setting on the still-open HTTP/2 connection and try to keep using that connection for future requests.  (Guessing that the client cert is why we got the fallback command for the first request.)  If we get the fallback for more requests, we'll drop the HTTP/2 connection.

As to your last comment, I wholeheartedly agree.  This should have been left in the realm of TLS, where the server can challenge for client auth at any time -- which would mean not prohibiting reneg in an HTTP spec.  But that ship has sailed, and now we all get to find our ways around or through that.

-----Original Message-----
From: Adrien de Croy [mailto:[email-masked]] 
Sent: Tuesday, June 9, 2015 2:35 PM
To: Mike Bishop; Yoav Nir; HTTP Working Group
Subject: Re: Client certificates in HTTP/2

------ Original Message ------
From: "Mike Bishop" <[email-masked]>
To: "Yoav Nir" <[email-masked]>; "HTTP Working Group" 
<[email-masked]>

<snip>

>server-initiated renegotiation.
I don't really like this approach.  When would the client send this option?

a) always -> let's tell every site we have a client cert
b) only on sites where the client previously received a request for a cert -> yay another database to maintain
c) after some strange UI (open this link with client cert)
d) by magic

What's wrong with being challenged for a client cert, it's just like being challenged for auth, we're not proposing deprecating 403 are we?

Some sites may wish to make it conditional whether a client cert is required based on other things.  This requirement to pre-advertise support just seems like bad engineering when TLS already has a mechanism to deal with client certs

Adrien

---

From: Mike Bishop <[email-masked]>
Date: Tue, 9 Jun 2015 23:03:55 +0000

The doc conflates a few things -- the extension and the quirks of our implementation that we're required to document.  I would really rather have had the extension in a separate doc for easy reading, and the original text of it does still live at http://tools.ietf.org/html/draft-bishop-support-reneg-00 as a stand-alone doc.  (Far fewer pages, and less boilerplate.)  However, I was advised that an independent document would be easier to manage, so it got folded into our quirks/profile doc that we had to publish anyway.

The short form is that mutually-consenting HTTP/2 implementations can agree to change the rules, and we didn't see a good alternative to being able to change the reneg rule in some scenarios.

-----Original Message-----
From: Adrien de Croy [mailto:[email-masked]] 
Sent: Tuesday, June 9, 2015 3:46 PM
To: Martin Thomson
Cc: Mike Bishop; Yoav Nir; HTTP Working Group
Subject: Re: Client certificates in HTTP/2

------ Original Message ------
From: "Martin Thomson" <[email-masked]>
To: "Adrien de Croy" <[email-masked]>
Cc: "Mike Bishop" <[email-masked]>; "Yoav Nir" 

>>  some browsers) which can't be used by the server.

so the server is entitled to send a request if it sees the flag, is that the intention?

In which case, why not just let the server send the request if it wants a client cert, and the client can bounce the request if it doesn't want to support that.  That has several benefits.

1. reduced cost.  Only incur cost when the server wants a client cert, rather than on all connections.
2. clients can measure how often they are asked for a cert so that devs can make decisions about whether to support it or not.

>that Microsoft have to do *something*.  It's an existing use that isn't 
>well served.  I'd rather the option I proposed, but we're not seeing a 
>lot of movement on the client authentication piece.

>http://download.microsoft.com/download/C/6/C/C6C3C6F1-E84A-44EF-82A9-49
>BD3AAD8F58/Windows/%5BMS-HTTP2E-Preview%5D.pdf
thanks for the link

Adrien