Here are some solid reasons that this is the best possible approach:

* It will work for 100% of foreseeable use cases - i.e. there is 0% risk of permanently baking in flawed logic into the API * It is dead simple - only one new method on SSLSocket/SSLEngine to set the protocol list (client) or selected single protocol (server)
* Because it is dead simple, it should be very easy to backport to Java 8
*Example 1*: Add a static org.openjdk.jsse.ALPN#setApplicationProtocol(SSLEngine | SSLSocket s, String[] protocols) method, which calls (maybe even reflectively?) the setApplicationProtocol() method on the SSLEngine/SSLSocket implementation if it is present & public *Example 2*: Add an org.openjdk.jsse.ALPNAware interface with the setApplicationProtocol(String[]) method, which is implemented by JSSE providers * Now Java EE 8 can trivially achieve HTTP/2.0 support with very low risk to either the JDK/SE timeline or the EE timeline * Since most or all of the "hard" logic is on the server side, the majority of API consumers will have an easy time using the API
* We server developers can handle the rest!

On 09/25/2015 12:23 PM, David M. Lloyd wrote:
On 09/25/2015 12:13 PM, Simone Bordet wrote:
Hi,

On Fri, Sep 25, 2015 at 6:49 PM, David M. Lloyd
<david.ll...@redhat.com> wrote:
A: receive raw SSL packet on Socket or SocketChannel
A: examine SSL ClientHello, extract SNI, ALPN, cipher suite info

This requires the application to write a TLS parser. This is currently
not necessary, nor provided.

It is already necessary to make many non-trivial SNI decisions.  I don't
see ALPN as deserving higher treatment than SNI.

You think this could be provided via a JDK utility class ?
And if so, how can it be extended in the future when more TLS
Extensions are defined ?

I don't think it's necessary, no.


A: use whatever algorithm(s) you want to analyze SNI/ALPN/cipher
suite info

The application must intersect the ciphers, application protocols...
perhaps again this can be done by some JDK utility class.

The point of the approach is that it is unlikely that any JDK-driven
logic will be adequate for all use cases.  It's better to let the
application be a black box: ALPN+SNI+Ciphers -> app logic -> one ALPN
protocol, one SNI name, only valid ciphers.

A: either proxy the connection, or obtain or create the relevant
SSLContext
from the desired provider
A: construct server-side SSLSocket/SSLEngine from SSLContext
A: setApplicationProtocol(H2)
A: setEnabledCipherSuites(only allowed suites in desired order)
A: start handshake
J: receive ClientHello (buffered from A)
J: verify SNI is matched, fail otherwise (as today)
J: verify ALPN is matched, fail otherwise (new)

There is a missing step here which is to verify the cipher
(trySetCipherSuite() logic).

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?

If that fails then we must try another application protocol.
We cannot just fail the connection.
How do we go from here to the top again to choose another protocol ?

J: send ServerHello (with the single, user-selected protocol)
...

This is very simple from the JDK perspective, and also much more
flexible.

Well, I kinda like it, but I have strong reservations that it cannot
really "negotiate" the application protocol, meaning that if one
application protocol fails, try the next, and then the next and so
forth until one succeeds (or they all fail).

This validation should have happened before the JDK ever has a chance to
be involved.

--
- DML

Reply via email to