TLS ALPN Proposal v2

Xuelei Fan at
Fri Jun 5 04:11:38 UTC 2015


See inlines, please.

On 6/5/2015 5:30 AM, Simone Bordet wrote:
> Hi,
> On Thu, Jun 4, 2015 at 6:50 PM, Xuelei Fan < at> wrote:
>> Hm, I see your point now.  But I may not agree with your ALPN "MUST
>> happen after" protocol/cipher suite negotiation conclusion.
>> I parse this section as, a H2 server must be strong enough(comply to
>> RFC7540), and a H2 client must also be strong enough (comply to
>> RFC7540).  Otherwise, both side may terminated the connection, and
>> cannot declare as complying to H2.  It is not necessary for an
>> application protocol selector to detect whether a H2 server/client
>> comply to H2 or not.
>> If "H2" is requested, it means that the client supports H2. Otherwise,
>> it's a client application bug.
> Not that simple, see below.
>> If "H2" is selected by a selected, it
>> means that the selected server supports H2.  Otherwise, it is a selector
>> implementation bug.  If something wrong in either client or server, it
>> is expected to terminate the connection immediately, rather than
>> downgrade to a not-strong enough level.
>> From the points above, I think an application protocol selector may not
>> need to know the negotiated protocol version and cipher suite.
> No.
> The client may send ciphers that are valid for http/1.1 (but invalid
> for h2), along with ciphers that are good for h2 (as well as http/1.1
> of course), plus the list of protocols it supports.
> The client has no idea what the server supports.
I think it should be true that if a client requests h2, the client MUST
support H2 and the requested cipher suites MUST contains at least one H2
required cipher suite.  Otherwise, it's bug in client side.

> When the server sees that the client supports h2, it MUST pick a
> cipher that is valid for h2.
> Alternatively, the ciphers on the server are sorted so that those
> valid for h2 have higher priority (they are attempted before all the
> others), so that there is a high chance that a h2 valid cipher is
> chosen (but no guarantee) before choosing the application protocol.
> When the application protocol selector callback is invoked, it can
> only pick h2 IFF the cipher is h2 valid, otherwise it has to fallback
> to http/1.1.
I think it should be true that if a server can negotiate h2, the server
MUST support H2 and the enabled cipher suites MUST contains at least one
H2 required cipher suite.  Otherwise, it's bug in server side.

It's instinctive that if a server support h2, and then the application
protocol selector would select h2.  If the server declare to support h2,
but no suitable cipher suites, it may be a server bug.  The connection
should be terminated rather than downgrade to HTTP/1.1, I think.

Is it possible that client only request h2_valid_cipher_a, but server
only support h2_valid_cipher_b, and as would result in that there is no
common cipher suites between client and server for H2?  It is possible,
surely.  Should the connection be terminated, or fall-back to HTTP/1.1?
 I think connection should be terminated immediately, rather than
fall-back to HTTP/1.1.  Per page 68, section 9.2.2, RFC 7540, there is
an mandatory cipher suite (TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) MUST
be supported in both client and server.  If there is no common cipher
suites between client and server for H2, it is actually a bad
deployments, and the connection should be terminated rather than
fall-back to HTTP/1.1.  Version downgrading is not a safe behavior, I think.

> With your reasoning, the client can send [h2_invalid_cipher,
> h2_valid_cipher], the server may pick h2_invalid_cipher, then the
> application protocol selector is invoked, which will only look at the
> protocols, pick h2 since it's supported by client and server, and now
> you have an invalid connection: the h2 protocol with
> h2_invalid_cipher.
That's an interesting case.  The question actually is: between requested
application protocols and cipher suites, which preference should be
respected at first.  Because it is a application requirement that a
certain cipher suite is not suitable to H2, I think requested
application protocols should be respected at first.

My scenarios look like:
1. client sends [h2_invalid_cipher, h2_valid_cipher] and h2/http/1.1
application protocol.
2. server selects h2 (we need an API for the selection).
3. server selects h2_valid_cipher because of h2 is selected previously
(may need an API for the selection).

In #1, if there is no h2_valid_cipher requested, it is a bug in client side.
In #3, if there is no h2_valid_cipher that can be negotiated, it is a
bug in server side, or the client does not enabled the mandatory cipher
suite (a bug in client).

> We have been through these issues for months in the RFC 7540 expert
> group, and the outcome is that protocol selection, for h2, depends on
> the cipher.
> We have also been through a number of scenarios where both the client
> and the server send h2 valid ciphers, but their intersection is empty
> (this may happen when a very old client talks to a very new server,
> think TLS 1.2 vs TLS 1.4, or viceversa).
> Same outcome: to pick h2 you MUST have a h2 valid cipher in common
> between client and server, so application protocol selection, for h2,
> depends on the cipher.
I still cannot understand the outcome.  I think, if there is no h2 valid
cipher in common, the connection should be terminated as there is a bug
in client or server side (see above).

I'm not familiar with HTTP/2 protocol, can you share more scenarios that
application protocol selection depends on the cipher?

> A bit of warning here: we are designing an API for ALPN, not for HTTP/2.
> The ALPN API should be flexible enough to implement *at least* HTTP/2,
> possibly even more complex scenarios (for example alias selection),
> but IMHO it should not be tied to HTTP/2.
Yes.  That's what I intended to do now.  It's very bad if application
protocol selection depends on the negotiation of TLS protocols, cipher
suites, or other handshake attributes, or other Chicken/Eggs dependence.
As would make the JSSE provider hard to be implemented, and the API hard
to be used.  That's what I want to avoid in JSSE layer.

> Again, I see 2 cases: either the JDK implementation picks the TLS
> protocol, the cipher and the alias like it does now, and then invokes
> the "callback" to pick the application protocol (current Jetty ALPN
> behavior), or the implementation must be reviewed to perform TLS
> protocol, cipher, alias and application protocol selection at once,
> with a "callback" that will be invoked possibly multiple times until
> it can find the right tuple to return.
The former has a drawback that the cipher may not suitable for the
application protocol.  It's application protocol define with cipher
suite is suitable (RFC7540), not cipher suite define which application
protocol is suitable.  So application protocol should be selected at
first, and let the specific application protocol determines the
negotiable cipher suite.

The latter made the TLS implementation pretty complicated.  It is even
not doable actually in general. Too much attributes need to be
considered if more handshake properties are involved, such as
certificate, key parameters, etc.

See also my previous mail about the rerouting requirement.

I think application-layer protocol negotiation should happen before the
actually general-handshaking (TLS protocol, cipher suite, general
extension negotiation).  For any incoming ClientHello message, the
scenarios in server side is as simple as:
1. select the right application-layer protocols.
2. do the actual general handshaking.  If something failed, terminate
the connection.

I'm not familiar with HTTP/2, I'm open to hear more case why above
scenarios does not work.

> The latter would be the optimal solution, the former has certainly
> working implementations.
> Hope this clarified.
> Thanks !
Thank you very much for the discussion of the potential issue.  It's an
effective way for us to understand what's the best option and what's the
actual requirement in the industry.


More information about the security-dev mailing list