TLS ALPN Proposal v5

Bradford Wetmore bradford.wetmore at oracle.com
Tue Sep 29 01:40:06 UTC 2015


Several comments about David's proposal:


1. Only the initial ClientHellos are parsable.
===============================================
The biggest problem I have with an Explorer-based design is that only 
the initial ClientHello on a connection is passed in the clear. 
Subsequent negotiations on this connection will be completely missed, as 
the ClientHellos are now encrypted.

This seems like a deal breaker for me.

Also, and this is moot if the ClientHellos are encrypted, unless you 
wrap the underlying raw socket in your own "observer" socket wrapper, 
you won't be able to view the raw data once the SSLSocket starts 
processing.  SSLEngine doesn't have this problem since it's just 
ByteBuffers.

One other comments while on the topic of renegotiations/resumptions as 
there were some incorrect statements in previous emails.  H2 (RFC 
7540-Sec 9.2.1) allows for renegotiations/resumptions to occur before 
the initial connection preface to protect *CLIENT CREDENTIALS* only, but 
prohibits it once data has started passing. But there is no such 
restriction on HTTP/1.1, nor on ALPN in general. So in such a case, 
there's no way you can change it with this proposal, and the ALPN RFC 
specifically allows for it.


2.  "SSLExplorer" or something similar is needed.
=================================================
This approach depends on "examining SSLClientHello"s, but there isn't a 
class for this other than some sample code from a previous attempt.  I 
am assuming that this approach would make such an external API a 
necessity?  Being able to parse possible ClientHello formats is not a 
straightforward/easy job.  This will add a fair amount of complexity, 
and likely not an easy job in the remaining few weeks.  It could be 
added later for JDK 10 but that means apps would likely need to roll 
their own for 9.


3.  "no_application_protocol"
=============================
If the server doesn't support the protocols that the client advertises, 
the "no_application_protocol" must be thrown.   We could add a 
"no_application_protocol" protocol String that would flag such a 
condition internally.


4.  Much of this is already possible.
=====================================
If we were to go with the current API/internal and apps provided their 
own ClientHello scanner, many of the benefits of what was proposed are 
already available.  Apps can ask for the desired SSLContext, get the 
SSLSocket/SSLengine, check the SNI/ALPN values, order/set the enabled 
protocols/ciphers/etc + single ALPN value, then wrap the raw socket 
using SSLSocketFactory.createSocket(Socket s, InputStream consumed, 
boolean autoClose), and start the handshake.  The internal code would 
still call matches() but only once.  If you want to be sure the 
internals select the ApplicationProtocol, just put in a permissive 
ApplicationProtocol.

The API is still more complicated unfortunately as ApplicationProtocol 
is still present, but the overall behavior is quite similar.


5.  Other failure mode/fallback.
================================
In the new proposal, suppose you do set a single ALPN value in the 
application level, and the ServerHandshaker finds some other aspect of 
the handshake wasn't appropriate (creds were mentioned several times, 
but maybe a ciphersuite went dark due to new AlgorithmConstraints). 
This would cause the ServerHandshaker to fail and there's no way to go 
back to a different version unless you add a "for ALPN" loop into 
application.


6.  "Only one new method on SSLSocket/SSLEngine to set the protocol list 
(client) or selected single protocol (server)"
==============================================================
I think you would need two, "use this value on the next handshake" and 
"this was last negotiated/currently in effect."


One other comment:

Simone wrote:

 > I don't know if all the blacklisted ciphers are actually lower
 > strength of all the remaining ciphers,

Mainly it's about removing support for various algorithms.  e.g. static 
RSA/DH Key Exchange, DSA (draft-09), non-AEAD ciphers, customer DHE groups.

     https://tlswg.github.io/tls13-spec/#rfc.section.1.2


Unfortunately, this is a big change in direction and is coming very 
late. I'm getting very significant pushback and schedule pressure from 
management now, so without an "Aha" moment, we may not be able to go 
this route.

Thanks,

Brad



On 9/28/2015 11:06 AM, Jason Greene wrote:
>
>> On Sep 25, 2015, at 3:22 PM, David M. Lloyd <david.lloyd at redhat.com> wrote:
>>
>> On 09/25/2015 02:11 PM, Simone Bordet wrote:
>>> Hi,
>>>
>>> On Fri, Sep 25, 2015 at 7:23 PM, David M. Lloyd <david.lloyd at redhat.com> wrote:
>>>> The application protocol implementation chooses only valid cipher suites for
>>>> the protocol.  Why would it choose one that is not valid, considering that
>>>> the protocol implementation itself is the only thing that "knows" what is
>>>> valid or not?
>>>
>>> The cipher could fail for the number of reasons it fails in
>>> trySetCipherSuite(), even if the application has chosen the right
>>> combination of (application protocol, cipher, whatever else).
>>> At that point you have to try another application protocol.
>>
>>  From my reading of that code, it can only fail if you specifically set up invalid combinations of cipher suite, protocol, and credentials.  The application code should have all the information it needs to set up a correct configuration though.
>
> One example approach for a server-side H1 fallback scenario can be achieved using this approach, is to take the desired enabled portion of the supported cipher suite list for TLS 1.2+ (e.g. getSupportedCipherSuites, getSupportedSSLParameters, etc), which in simple scenarios is just the default suites (e.g. getDefaultSSLParameters, etc). Remove the H2 black-list from that and you have the h2 possible cipher-suite list. This list can then be further paired down based on key material (e.g disable ECDSA ciphers if only an RSA cert is present in the keystore). Finally the cipher list in client hello can be compared to find a possible intersection. If there is no intersection then use h1, otherwise configure h2.
>
> One additional topic that I see came up on this list is the notion that cipher suite selection using ALPN is a temporary use-case, since H2 loses this problem with TLS 1.3. I think this viewpoint is too limiting. Fundamentally, the key use case that ALPN is achieving, is multiplexing two TLS ports over one. Any TLS policy that was required for a single protocol over a single port is likely to still be needed in a mixed protocol setup. Once you have non-overlapping policies then you need the ability to have logic which is distinguished by ALPN. We shouldn’t just look at H2 here, but think of it more generically.
>
> Absent a non-limited TLS stack that does all the heavy lifting, deferring to the application is the next best thing. In some ways it can actually be better, since the portion of the logic on top of the JVM can evolve independently and more expediently than SE schedule allows. I also like David’s point that a simple solution is easier to backport to SE8, which is very important since EE8 is planned to require http2 and SE8 support.
>
> --
> Jason T. Greene
> WildFly Lead / JBoss EAP Platform Architect
> JBoss, a division of Red Hat
>



More information about the security-dev mailing list