Subject: http/2 and TLS security

From: Francisco Moraes <[email-masked]>
Date: Tue, 3 Nov 2015 09:59:20 -0500

Hi,

I have a few questions from a server perspective when implementing http/2:

1. if http/2 is selected to be supported, TLS 1.2 is required, but that 
doesn't mean that the server cannot negotiate TLS 1.x with clients that 
are not talking h2. It would be a client error to negotiate TLS 1.1 for 
example if it wants to talk h2. Should the server close the connection 
is for some reason TLS 1.1 or 1.0 was negotiated for http/2?

2. Appendix A of RFC 7540 lists a lot of ciphers that are black listed 
but the wording says the server MAY treat the negotiation of the ciphers 
with TLS 1.2 as a connection error. This doesn't imply that I should 
disallow those ciphers in my server configuration, but I have seen some 
of those ciphers cause an error on the client side (browser). What's the 
best practice here? Print a warning if those ciphers are used? Fail? 
Failing every single one of those ciphers leaves a very limited list of 
ciphers to be used.

Francisco

---

From: Cory Benfield <[email-masked]>
Date: Tue, 3 Nov 2015 15:34:11 +0000

> On 3 Nov 2015, at 14:59, Francisco Moraes <[email-masked]> wrote:
> 
> Hi,

Hi!

> 1. if http/2 is selected to be supported, TLS 1.2 is required, but that doesn't mean that the server cannot negotiate TLS 1.x with clients that are not talking h2. It would be a client error to negotiate TLS 1.1 for example if it wants to talk h2. Should the server close the connection is for some reason TLS 1.1 or 1.0 was negotiated for http/2?

RFC 7540, section 9.2 says that "implementations MUST use TLS version 1.2 or higher for HTTP/2 over TLS". Thus, if you negotiate HTTP/2 over TLS but negotiate a TLS version lower than 1.2, you should tear the connection down. The graceful thing to do is to send a GOAWAY frame with the error code INADEQUATE_SECURITY.

> 2. Appendix A of RFC 7540 lists a lot of ciphers that are black listed but the wording says the server MAY treat the negotiation of the ciphers with TLS 1.2 as a connection error. This doesn't imply that I should disallow those ciphers in my server configuration, but I have seen some of those ciphers cause an error on the client side (browser). What's the best practice here? Print a warning if those ciphers are used? Fail? Failing every single one of those ciphers leaves a very limited list of ciphers to be used.

Again, it should be conditional on what is negotiated. For HTTP/1.1 those ciphers are allowed. For HTTP/2, they are technically forbidden. If you find that you’ve negotiated one of those ciphers, you should probably tear the connection down (again, using GOAWAY with INADEQUATE_SECURITY). You are free to continue to use them if you so choose, but it’s a bad idea: section 9.2.2 says that you MAY choose to generate that error, and again, many implementations do.

As to the limited list of ciphers: yes, that’s the goal. Generally speaking, AEAD ciphers are the strongest security available today. In TLS 1.2 there is only one standard cipher suite that offers AEAD: AES in GCM mode. It is also potentially possible to negotiate CHACHA20-POLY1305, which is also an AEAD cipher, but if you’re dependent on OpenSSL it’s not available to you yet.

Anything else is potentially at risk. All modern web browsers support AES_GCM, so if you can you should restrict yourself to AES_GCM. If you still need to support legacy browsers (and I urge you to strongly consider whether you actually do!), then you should respect your own cipher preference first and put AES_GCM at the top of your cipher list. That way, if you negotiate HTTP/2 you’ll *probably* negotiate AES_GCM, and you know that if you failed to it was because the client outright does not support that cipher suite (and so is not RFC 7540 compliant).

For my part, my example web servers for Hyper-H2 use the following OpenSSL cipher string: “ECDHE+AESGCM”. Simple, and effective.

Cory

---

From: Mike Bishop <[email-masked]>
Date: Tue, 3 Nov 2015 15:40:23 +0000

Think of TLS negotiation as a menu -- the client offers a whole set of things it supports.  The server then chooses the combination of things that it wants, and informs the client of its decision.  That applies to both your questions -- from the list the client sends, the server selects TLS version (greatest version both it and the client support), cipher suite, and application protocol.

It would be a client error to offer TLS 1.1 and h2, but not a fatal one.  The server selects both the TLS version and the protocol from what the client offers.  So it would be a *server* error to select an invalid combination; a compliant server would just ignore the offer of h2 in a TLS 1.1 ClientHello.

The same applies to the second one -- the client offers lots of cipher suites, including ones that are only supposed to be used with HTTP/1.1.  When the server selects, it should select a cipher suite and protocol combination that's valid.  The SHOULD/MAY are there because some TLS stacks aren't actually able to do that -- negotiation happens in the TLS layer, which doesn't know these rules, and then the HTTP layer doesn't have any control until it sees the result of the negotiation.  At that point, the server can't do anything and it's back to the client's decision whether or not to proceed with the connection having seen the results of the handshake.

If you have an architecture like that, your best option on the server is simply to prioritize the permitted cipher suites.  If the client supports them, you'll pick one.  And since clients that support HTTP/2 are required to support at least one of these cipher suites, it becomes a non-issue with compliant clients.  Yes, the list of good cipher suites is a little short these days.

-----Original Message-----
From: Francisco Moraes [mailto:[email-masked]] 
Sent: Tuesday, November 3, 2015 11:59 PM
To: [email-masked]
Subject: http/2 and TLS security

Hi,

2. Appendix A of RFC 7540 lists a lot of ciphers that are black listed but the wording says the server MAY treat the negotiation of the ciphers with TLS 1.2 as a connection error. This doesn't imply that I should disallow those ciphers in my server configuration, but I have seen some of those ciphers cause an error on the client side (browser). What's the best practice here? Print a warning if those ciphers are used? Fail? 
Failing every single one of those ciphers leaves a very limited list of ciphers to be used.

Francisco

---

From: Patrick McManus <[email-masked]>
Date: Wed, 4 Nov 2015 09:29:19 +0900

Hi Francisco

On Tue, Nov 3, 2015 at 11:59 PM, Francisco Moraes <
[email-masked]> wrote:

> doesn't mean that the server cannot negotiate TLS 1.x with clients that are
> not talking h2. It would be a client error to negotiate TLS 1.1 for example
> if it wants to talk h2. Should the server close the connection is for some
> reason TLS 1.1 or 1.0 was negotiated for http/2?
>
>
The server makes the final choice of both application layer protocol and
tls version (subject to intersection with what the client offers). If it
cannot select >= 1.2 then it must not select h2. Doing so would be a 7540
violation and some clients are likely to generate INADEQUATE_SECURITY.
(Firefox will.) Falling back to h1 would be fine assuming some version of
tls is negotiated.

> 2. Appendix A of RFC 7540 lists a lot of ciphers that are black listed but
> the wording says the server MAY treat the negotiation of the ciphers with
> TLS 1.2 as a connection error. This doesn't imply that I should disallow
> those ciphers in my server configuration, but I have seen some of those
> ciphers cause an error on the client side (browser). What's the best
> practice here? Print a warning if those ciphers are used? Fail? Failing
> every single one of those ciphers leaves a very limited list of ciphers to
> be used.
>

Restricting the cipher list to the set of best practices is definitely the
point. If you have a h2 only server then you can just disable them - just
making them lowest priority generally does the trick in a server that needs
backwards compat with older h1 clients.

---

From: Francisco Moraes <[email-masked]>
Date: Wed, 4 Nov 2015 09:18:16 -0500

Hi Patrick,

On 11/3/2015 7:29 PM, Patrick McManus wrote:
> The server makes the final choice of both application layer protocol 
> and tls version (subject to intersection with what the client offers). 
> If it cannot select >= 1.2 then it must not select h2. Doing so would 
> be a 7540 violation and some clients are likely to generate 
> INADEQUATE_SECURITY. (Firefox will.) Falling back to h1 would be fine 
> assuming some version of tls is negotiated.

But during the ALPN callback, as far as I can tell, OpenSSL still has 
not selected a cipher nor protocol, so I cannot choose to ignore the 
upgrade request to h2, unless I missed something. I would have to accept 
the request and then after the initial handshake, tear it down with 
INADEQUATE_SECURITY if either a bad cipher was selected or a lower 
version of TLS was selected.
> Restricting the cipher list to the set of best practices is definitely 
> the point. If you have a h2 only server then you can just disable them 
> - just making them lowest priority generally does the trick in a 
> server that needs backwards compat with older h1 clients.
>
Yes, I will make a check to at least make sure some cipher that's 
acceptable to h2 is available, otherwise I will flag it is a 
configuration error. At runtime, I will have to actually check which 
cipher was selected.

Francisco

---

From: Patrick McManus <[email-masked]>
Date: Thu, 5 Nov 2015 10:16:15 +0900

On Wed, Nov 4, 2015 at 11:18 PM, Francisco Moraes <
[email-masked]> wrote:

> But during the ALPN callback, as far as I can tell, OpenSSL still has not
> selected a cipher nor protocol,

so nss required a little work to make the equivalent of SSL_get_version()
work during the alpn callback. Is this something that should be pursued in
the openssl bug tracker? (Have you double checked that?) Its more of an
open source implementation thing than a working group item..

in practice the client shouldn't be offering h2 if it isn't also offering
1.2 so this shouldn't come up as long as you're configured to
unconditionally prefer 1.2.. weird behavior should be limited to clients
that made non sensical offers.

---

From: Martin Thomson <[email-masked]>
Date: Thu, 5 Nov 2015 11:10:29 +0900

On 5 November 2015 at 10:16, Patrick McManus <[email-masked]> wrote:
> On Wed, Nov 4, 2015 at 11:18 PM, Francisco Moraes
> <[email-masked]> wrote:
>>
> the openssl bug tracker? (Have you double checked that?) Its more of an open
> source implementation thing than a working group item..

Actually, the OpenSSL situation could be easier.  You could scrub the
ClientHello for acceptable cipher suites in the ALPN callback. If that
results in no suites left, then you could disable h2 and reset the
cipher suite stuff.