TLS renegotiation #363

Closed
briansmith opened this Issue Jan 25, 2014 · 12 comments

Comments

Projects
None yet
7 participants

In Firefox, we refuse servers' requests for client certificates if we've done connection coalescing on a connection. This has potential interop issues. For example, Apache can be configured to require a client certificate (via a TLS renegotiation) only upon the first request to some particular paths. This can easily put us in a state where we cannot access such paths:

  1. Browser connects to https://foo.example.org
  2. Browser coalesces https://bar.example.org onto that same connection.
  3. Browser requests https://foo.example.org/requires-cert.
  4. Server requests (demands) client cert
  5. Browser refuses to send one.
  6. Server returns 401/403/whatever error.

Note that in theory coalescing could happen before any requests are sent on the connection. Thus, this has the potential to make some client-certificate-required resources completely inaccessible to the client, unless the client retries the request. The client probably won't retry the request, and may not be allowed to if it isn't idempotent.

Besides the problems with connection coalescing, TLS renegotiation doesn't fit well with browser UI. In particular, it is possible for the server to send a different server cert in a renegotiation than it sent in the initial handshake. It could do this renegotiation even in the middle of a request or response, even in HTTP/1. This problem is even more likely to occur in HTTP/2 because transactions are multiplexed instead of being serialized. The browser thus cannot map requests/responses to certificates in a well-defined way. Yet, usually browsers present server identity in such a way that would make any server certificate change potentially misleading to the user.

I am sure we can think of many reasons why TLS renegotiation is a bad idea for HTTP servers (of any version). It's probably too late to do anything meaningful about it for HTTP/1 since clients have to deal with existing servers that do it. it would be great to improve things for HTTP/2.

However, because TLS <= 1.2 sends the client certificate in the clear, many implementations (including, IIRC, IIS in its default configuration) do a handshake without a client certificate and then immediately renegotiate to get the client certificate, to protect the client's identity. Thus, we probably cannot prohibit renegotiations that occur at the start of the handshake. A further complication is that TLS False Start interacts poorly with such schemes because the client may send a request on the connection before the server can even request the renegotiation that it intended to occur before any requests were made.

BukhariH commented Feb 2, 2014

TLS renegotiation is a problem that's been discussed an awful lot since 2010 when the renegotiation handshake exploit came out. Later on it was fixed by RFC 5746 however the discussion was at the time that TLS renegotiation had to be changed (probably in a way that wasn't backwards incompatible).

Hence, I agree with Brian that this behaviour isn't the fault of connection coalescing but rather a fundamental problem with TLS renegotiation hence we should probably limit it's use if not completely forbidding it.

Owner

mnot commented Mar 5, 2014

Discussed in London; sense in the room that renegotiation shouldn't be allowed; more discussion about how to accommodate use cases to ensue (e.g., at design team meeting).

Contributor

willchan commented Mar 5, 2014

Just documenting my concern for posterity...I too would like to forbid TLS renegotiation if possible. I just worry that we will create pressure for servers not to adopt HTTP/2 or for users to switch browsers if TLS renegotiation isn't supported in HTTP/2. Other than this concern, I'm all for forbidding TLS renegotiation. I hope we can get away with it :)

Member

martinthomson commented Mar 13, 2014

As far as I can tell the high running reasons for using renegotiation are:

  1. client authentication (either mid-session, or to provide confidentiality for user credentials)
  2. key update for long-running sessions

Since we already have an expiration date on HTTP/2 connections, perhaps we can punt on the second one.

I've put together a pair of proposals for addressing the first. If these are palatable, then we should consider forcing implementations to only renegotiate immediately after connecting. That would address these concerns, especially allowing TLS 1.2 and earlier implementations to get confidentiality protection for client credentials.

I think the aim of HTTP/2 is to be backwards compatible so as to rush adoption of it as a protocol hence I think @martinthomson is on the right track. We can still be mostly backwards compatible by forcing renegotiations to happen immediately after the initial handshake.

But, these are still all short term solutions I feel because TLS renegotiation is an utter mess and the only real way to fix it would be to forbid TLS renegotiation and force the use of TLS > 1.2 but that would be backwards incompatible hence it's off the table I would assume.

Member

martinthomson commented Mar 14, 2014

@BukhariH, yeah, mandating use of something that doesn't yet exist (TLS 1.3) would be a non-starter.

@martinthomson TLS 1.2 in practical terms is reliant on renegotiations as Brian described hence we can't exactly forbid renegotiation without making TLS connections are workable.

Also see Rob's posting - http://lists.w3.org/Archives/Public/ietf-http-wg/2014AprJun/0186.html -

We have been doing some internal investigations and it looks like we have scenarios that require TLS client auth. Based on this, we took another look at the current editor's draft, and it appears that the spec creates a conflict between the [TLS-EXT] spec and coalescing. Essentially, coalescing to multiple server names violates section 3, RFC 6066 [TLS-EXT] where it states:

"If the server_name is established in the TLS session handshake, the client SHOULD NOT attempt to request a different server name at the application layer."

Because of this, we have two SHOULD NOT statements that clearly contradict each other and now cause complication for existing HTTP deployments. The original text of section 9.1 was that we were encouraging clients to follow the same origin policy which would avoid these problems. The new text in section 9.1 actually discourages implementations from following the same origin policy.

My proposal is the following:

  1.   Discourage coalescing. This is especially true for TLS connections in order to reuse TLS and SNI as defined and implemented.  This also follows the principle from the charter of maintaining existing HTTP semantics.
    
  2.   If an implementation is doing #1 then we can leave client auth as is and we do not need to disallow HTTP/2 for scenarios that require it today.
    
  3.   Refer the discussion of coalescing, removing renegotiation and client auth to the TLS working group.  Maybe it is something that can be addressed in TLS 1.3.
    
Contributor

MikeBishop commented Jun 2, 2014

Commit 565572d introduces the conflict with SNI. The simplest resolution to that aspect would be to expand the definition of a destination from IP:port to IP:port:SNI when TLS is used. Then the SHOULD NOTs would align.

Member

martinthomson commented Jun 2, 2014

Let's not try to disguise this issue as a bug-fix. This is a feature that some parties find important. Let's discuss this a) on the list, and b) as openly as we can manage. I've opened issue #490 to cover this.

The alternatives I see are:

  1. Permit coalescing, as the current text allows and deal with the RFC 6066 violation.
  2. Forbid coalescing.

I think that we can easily collect pros and cons on both options and then have it out.

mnot changed the title from Recommend, forbid, or limit use of TLS renegotiation for HTTP/2 to TLS renegotiation Jun 4, 2014

mnot added the editor-ready label Jun 6, 2014

Owner

mnot commented Jun 6, 2014

Discussed in NYC; #496 resolution gives a transitional strategy; better things may be done in the future.

Spec text needs to disallow (MUST NOT) renegotiation (client to PROTOCOL_ERROR) and illustrate what to do (i.e., fall back to 1.1) for client auth using #496 (non-normative).

Member

martinthomson commented Jun 16, 2014

Closed in #514.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment