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.ll...@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.ll...@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

Reply via email to