TLS ALPN Proposal v3

Jason Greene jason.greene at
Fri Jul 24 19:38:36 UTC 2015

> On Jul 9, 2015, at 12:02 PM, Bradford Wetmore <bradford.wetmore at> wrote:
> Ok, I'll check with the HTTP/2 group tomorrow.  It appears the proper 
> list is:

Hi Brad, 

Your post to the H2 group got my attention, so I thought as a user of JSSE for an H2 implementation I should reply additionally here. My responses are inline:

> On 7/9/2015 8:29 AM, Simone Bordet wrote:
>> Hi,
>> On Thu, Jul 9, 2015 at 1:42 AM, Bradford Wetmore
>> <bradford.wetmore at> wrote:
>>> Xuelei/Simone wrote:
>>>>> Per my understanding, application protocol should be negotiated before
>>>>> cipher suite and protocol version negotiated.
>>>> This is not possible for HTTP/2.
>>>> Application protocol negotiation MUST happen *after* the TLS protocol
>>>> and the TLS cipher are negotiated.
>>> Yes, that's my understanding as well.
>> Well, to be precise, either the application protocol is negotiated
>> after the cipher (and you need cipher sorting to influence the cipher
>> selection towards the application protocol you would like to choose),
>> or it must happen at the same time - that is, cipher and application
>> protocol must be chosen at the same time - but this implies that the
>> action of choosing that tuple may be invoked multiple times with the
>> current OpenJDK implementation.
>> Note that I don't know if the fact that cipher selection is an
>> iterative process is an OpenJDK implementation detail.
>> If other implementations are not iterative, then perhaps they have a
>> single moment where the tuple is chosen.
>> I support Xuelei in that you should ask confirmation to the HTTP/2 editor.
>> Also, remember that Firefox, Chrome, OpenSSL, nghttp2, etc. are all
>> open source and their code is available to verify the behavior.

The truth is that there is a gap between the current capabilities of TLS stacks and what the specs are trying to achieve. Ultimately the desired semantic the specs are trying to achieve is that every ALPN protocol can have its own TLS requirements. In this case H2 wanted TLS 1.3 behavior before it was released. This is basically social engineering, the newer protocol is the carrot for updating your TLS stack. However there are other potential scenarios, such as protocols which desire to be encrypted but unauthenticated.

To truly resolve this gap in a future proof manner, TLS stacks need to support cipher suite selection based on the combination of ALPN protocol and TLS version. Until then h2 implementations have to rely on both peers sorting, with many clients taking the additional step of post-validating the selected cipher. With NSS this is accomplished using an API that that categorizes cipher aspects (e.g. not a block cipher etc). This approach, which is arguably a hack can lead to interop errors if the administrator has tried to influence cipher suite selection for other reasons. As an example, its quite common to use an abstract indicator (e.g GNU TLS priority strings & openssl cipher strings), and these may inadvertently disable ciphers now required for h2 interop. 
>>> IIUC, the HTTP/2 blacklist is just strongly recommended ("...SHOULD NOT use
>>> any of the cipher list"), but not required.  Such potential
>>> peers must also support such a configuration, but in general, it will not.
>>> See section 9.2.2.  I think it's still considered compliant to the spec tho.
>> From experience, if a server breaks this SHOULD NOT, it won't work
>> with any browser.
>> We had our share of pain trying to figure out interoperability with
>> browsers for Jetty :)
>> Sure, it's a SHOULD NOT, but it's like a MUST NOT if you want a
>> browser to talk to a Java server (or a Java client to talk to a
>> current HTTP/2 server).

Yes exactly. Firefox and Chrome enforce the SHOULDs, and if negotiation results in a cipher that violates the SHOULDs you not only fail to establish an h2 connection, you fail to establish any connection at all.

>>> Simone wrote two different ways to do selection:
>>>> 1) ... so that TLS protocol, cipher (possibly the alias too) and
>>>> application protocol are chosen together, or
>>>> 2) we separate the TLS protocol and
>>>> cipher negotiation (and alias) in one step, and we perform application
>>>> protocol selection afterwards.
>>> Rather than completely redo the JSSE selection mechanism with the
>>> (version/ciphersuite/ALPN)-tuple idea (which would be a much more involved
>>> API and behavior change), I think the more straightforward solution (2) is
>>> better.
>> That's what we do in Jetty's ALPN implementation too.
>> Be aware that it rules out some possibility such as those mentioned by
>> Michael from RFC 7301.

I’d highly recommend exploring 1) because its quite possible you will end up needing to go that route anyway based on the above reasoning.


>>> See the configuration in createSSLEngines() around line 265 and 280.
>>> Note the HTTP/2 blacklist and reordering code.
>>> The code is not actually "working" yet (haven't merged API/impl repos yet),
>>> but shows how to configure/use this API.
>> Just a reminder that the cipher blacklist is only valid for TLS 1.2.
>> For example, if the negotiated TLS protocol is 1.3, there is no need
>> to look at the ciphers (nor to sort them).

Yes, just to restate differently. The h2 requirements are simulating TLS 1.3 over TLS 1.2. The key difference being that TLS stacks are already architected for version directed suite negotiation. 

Jason T. Greene
WildFly Lead / JBoss EAP Platform Architect
JBoss, a division of Red Hat

More information about the security-dev mailing list