Subject: Re: TLS Renegotiation and HTTP/2 (#363)

From: Yoav Nir <[email-masked]>
Date: Tue, 1 Apr 2014 14:02:09 +0300

#1 is not a bad option. It’s not pretty, but just the fact that it’s written down puts it ahead (process-wise) of the others.

The TLS working group is considering getting rid of renegotiation for TLS 1.3, because few use it except for client authentication in HTTPS. Going with option #2 leaves us with all of the complexity. I’d rather we didn’t go there.

#3 is a sure-fire way of getting angry comments and DISCUSSes for HTTP/2. Arguably, those with client certificates are those with the highest security requirements, and to disenfranchise those in a new version is likely to get the document in trouble.

#4 is an interesting one. I’m too lazy to look back at older specifications to see whether it was possible for the server to request the client to send this frame, but it could be done.

#5: hard to comment on things *you* haven’t though of yet, but I can suggest one of my own. Make it an HTTP authentication method. Something along the lines of (apologies for the HTTP/1.1 syntax)

Server sends:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Certs
        realm = “example.com”
        challenge="EKgoC3wwy8KuJROo/gmG1we43c5av9OwOlWaYVPStsw=“

Client sends:
Authorization: Certs
        realm=“example.com”
        hash=“SHA-256”
        cert=“MIIGzTCC...gpECY="
                challenge="EKgoC3wwy8KuJROo/gmG1we43c5av9OwOlWaYVPStsw=“
        signature=“FIMe3WLvlgX3BgJKYN0DXj4UGuauq5fwXgZErnFgVR0=“

All you really need with client certificate authentication is to show the certificate and sign something of the server’s choosing. You can make it fancier by having the server list supported hashes and trusted CAs, but that’s not strictly necessary.

On Apr 1, 2014, at 3:11 AM, Martin Thomson <[email-masked]> wrote:

> In my other email today, I've listed the items that are outstanding,
> of which I identify 6 issues that could result in disruptive changes
> to the protocol if we decide to act on them [1].
> 
> Of those, I think that TLS renegotiation is only the issue that fixes
> something we've actually broken.  Broken, the sense that if we don't
> do something about this issue, we've broken a feature that some people
> rely on.  Importantly, this is broken in a way for which the only real
> recourse is to revert to HTTP/1.1.
> 
> (Transfer-Encoding #445 arguably introduces a feature regression too.
> But it's a regression that can be handled trivially by spending bytes.
> It might be reasonable to say that given the degree to which
> Transfer-Encoding is used today, the odds that we are creating
> incentive to stay on HTTP/1.1 is lower.)
> 
> Relying on renegotiation for re-keying (to avoid key exhaustion) seems
> like a non-problem.  We already require the creation of new
> connections when stream IDs run out.  It does mean that extremely
> large requests or responses (broadly, anything longer than 2^64-1 TLS
> records, though probably less if the cipher suite requires re-keying
> earlier) cannot be carried at all.
> 
> The main issue here is client authentication.  I see several ways out:
> 
> 1. Pursue http://tools.ietf.org/html/draft-thomson-httpbis-catch-00 or
> something like it to the bitter end.  I don't see a way that we can do
> this without creating a new normative reference, unfortunately, and
> that work is clearly half-baked.
> 
> 2. Allow for some very limited form of renegotiation for the client
> authentication use case.  This might mean requiring that
> MAX_CONCURRENT_STREAMS be wound back to 1 at the server before
> renegotiation is triggered.  This avoids the dependency issue, and
> might work for the use cases in question, but the cost in complexity
> and loss of concurrency is extreme to the point that option 3 starts
> looking good.
> 
> 3. Force those using client authentication to stay on HTTP/1.1.  We
> basically get this for free if we intend to pretend that this issue
> doesn't exist.  I tend to think that this would be a bad outcome
> though.
> 
> 4. Resurrect the CREDENTIAL frame from SPDY.  My understanding of this
> mechanism is that it would be non-trivial to add this to the protocol.
> It is quite a flexible mechanism, but one with significant costs.
> This relies on RFC 5705 (TLS extractor) support, which is not
> universally supported in the various TLS stacks that are commonly
> used.  It also requires a new setting and modifications to the HEADERS
> frame.
> 
> 5. Something else that I haven't thought of yet.
> 
> Does anyone have a way forward to recommend?  My primary motivation
> here is getting HTTP/2 done.
> 
> 
> [1] http://lists.w3.org/Archives/Public/ietf-http-wg/2014JanMar/1292.html
>

---

From: Ilari Liusvaara <[email-masked]>
Date: Tue, 1 Apr 2014 15:21:20 +0300

> All you really need with client certificate authentication is to show the certificate and sign something of the server’s choosing. You can make it fancier by having the server list supported hashes…
 
That looks to be vulernable to forwarding and MITM attacks...

-Ilari

---

From: Yoav Nir <[email-masked]>
Date: Tue, 1 Apr 2014 15:26:17 +0300

Sure, but not more so than regular server-authenticated HTTPS.

We can get all fancy and tie it to extractors or channel bindings. The question is whether we want just mutual authentication or whether we want to foil MitM attacks and proxies while we’re at it.

Foiling MitM has the downside (or upside) of making this not work from behind next generation firewalls.

Yoav

---

From: Ilari Liusvaara <[email-masked]>
Date: Tue, 1 Apr 2014 15:39:08 +0300

> Foiling MitM has the downside (or upside) of making this not work from behind next generation firewalls.
 
Suppose that user visits a maliscous site. What is to prevent
that site from contacting target site and forwarding
authentication exchange across (with who knows what other
headers and payload)?

-Ilari

---

From: Yoav Nir <[email-masked]>
Date: Tue, 1 Apr 2014 17:21:00 +0300

The same is true of basic authentication. The user should not send a certificate to the wrong site. If I had a certificate for the corporate SSL VPN, I would not pick that certificate for connecting to some random site.

But you’ve convinced me - we should add the channel bindings to the signed data.

---

From: Martin Thomson <[email-masked]>
Date: Tue, 1 Apr 2014 10:18:39 -0700

> But you’ve convinced me - we should add the channel bindings to the signed data.

This looks quite similar to the CREDENTIAL frame when you do it that way.

---

From: Yoav Nir <[email-masked]>
Date: Tue, 1 Apr 2014 20:41:37 +0300

> This looks quite similar to the CREDENTIAL frame when you do it that way.

Sure. In general, HTTP authentication schemes are not tied to a connection. So if a resource requires authorization, the client can send the Authorization header with the first request without waiting for the 401.

This scheme would depend on having the challenge and Authorization header in the same connection, and also depend on the TLS state. I wonder if people would consider that a problem.

With sufficient time for the working groups to discuss this, I think both CREDENTIAL and authentication method are better than starting a new, client-authenticated connection in that they don’t require a connection. But your catch draft can probably get published sooner than either of them.

Yoav

---

From: Martin Thomson <[email-masked]>
Date: Tue, 1 Apr 2014 10:56:04 -0700

On 1 April 2014 04:02, Yoav Nir <[email-masked]> wrote:
> #1 is not a bad option. It’s not pretty, but just the fact that it’s written
> down puts it ahead (process-wise) of the others.
>
> The TLS working group is considering getting rid of renegotiation for TLS
> 1.3, because few use it except for client authentication in HTTPS. Going
> with option #2 leaves us with all of the complexity. I’d rather we didn’t go
> there.

This is why #1 perhaps has the edge on #2.  If we consider the
possibility that renegotiation could be impossible in TLS 1.3, then a
new connection is the only real option.  Either that or something RFC
5705-based, like #4.

As Patrick infers, I'm not that keen on #1.  But I do want a solution.

---

From: "Nicolas Mailhot" <[email-masked]>
Date: Wed, 2 Apr 2014 11:46:55 +0200

Le Mar 1 avril 2014 19:41, Yoav Nir a écrit :
> Sure. In general, HTTP authentication schemes are not tied to a
> connection.

Except when they are authenticating a connexion via a particuliar
intermediary…

-- 
Nicolas Mailhot

---

From: Yoav Nir <[email-masked]>
Date: Thu, 3 Apr 2014 11:59:29 +0300

> As Patrick infers, I'm not that keen on #1.  But I do want a solution.

I agree that #1 is the best way forward, because:
 - It can easily work with HTTP/1 which is not dead yet
 - It reduces complexity, especially eliminating the transition from non-authenticated to authenticated state mid-connection.

I’m not too worried about the latency. For browsers, choosing a certificate as part of the log-in process is one of those things that users expect to take noticeable time, especially if it requires user interaction with a certificate picker. So starting a new TCP connection? Not that bad.

I’m wondering if it’s possible to write some sensible text on what to do with the two connections. Suppose a resource is fetched from a server, and the server sends the 401 response. The client opens a new connection, this time with client authentication. So now there are two connections, one authenticated, while the other is not. The triggering resource obviously has to be fetched in the authenticated connection. I suppose we let all in-transit streams conclude normally, but what does the client do with any other resources that it needs. Do they go in the old or new connections? What about pushed resources from the server?  Does the server even know that the two connections are associated?  Probably not (unless there’s some outside mechanism at work such as cookies). Does the client close the original (non-authenticated) connection once the streams are closed?

I guess we’ll have to answer all of those if we choose #1  (not that the questions for the other solutions would be any less difficult)

Yoav

---

From: Martin Thomson <[email-masked]>
Date: Thu, 3 Apr 2014 09:59:04 -0700

> I’m wondering if it’s possible to write some sensible text on what to do with the two connections. Suppose a resource is fetched from a server, and the server sends the 401 response. The client ope…

It's worse than that even.  What happens when you have multiple realms
on the server, each requiring a different client certificate?

But I don't think that it's completely intractable.  As far as I'm
aware, most current HTTP authentication implementations send
subsequent requests with the new credentials.  That means switching
over to the new connection for that origin.

I imagine that if there were multiple realms and certificates, then it
would get properly ugly.  But I can imagine a few solutions that -
while totally suboptimal - wouldn't completely fail.

(Push is a non-issue, since pushes are always associated with an
existing stream.  And presumably a server wouldn't push things a
client isn't authorized to receive...)