ALPN API Proposal
Simone Bordet
simone.bordet at gmail.com
Fri Nov 7 13:10:44 UTC 2014
Hi,
The ALPN (RFC 7301) [0] API that the Jetty project has implemented,
and used for a while, to support SPDY and HTTP2 (h2), is here [1].
It consists of 2 provider interfaces, one for the client and one for
the server, with methods that are called by the JDK implementation at
the right times to let the application decide what protocol should be
negotiated. However, I believe they can be greatly simplified (to a
lambda) for JDK 9.
The providers needs these moments of interaction.
For the client:
C1) providing the list of protocols (before the ClientHello is sent)
C2) knowing whether the server support ALPN, and if so, what was the
protocol chosen (upon receiving the ServerHello)
For the server:
S1) knowing if the client supports ALPN, and if so what is the list of
protocols, and returning the chosen protocol (upon receiving the
ClientHello).
While C1 is a value that may be provided easily, C2 and S1 require
application code to be called by the TLS implementation.
The API that I would like to propose is something along these lines.
For the client:
SSLEngine engine = ...;
TLSExtension alpn = new ALPNClientExtension(protocol -> { ... }, "h2",
"spdy/3", "http/1.1");
engine.getLocalExtensions().add(alpn);
engine.beginHandshake();
For the server:
SSLEngine engine = ...;
TLSExtension alpn = new ALPNServerExtension(protocols -> { ... });
engine.getLocalExtensions().add(alpn);
The two lambdas will be called "as soon as possible", that is for the
client just after having received the ServerHello, and for the server
just after having received the ClientHello.
I say "as soon as possible" this because the h2 specification is still
in flux for what regards the constraints that needs to be put in place
to accept the negotiation of the h2 protocol (but see the other email
about).
It may well be that the connection must be closed before the end of
the TLS handshake.
Alternatively, lacking a full fledged TLS Extensions API, something
similar may be put into SSLParameters, although it would require two
"container" classes akin to ALPNClientExtension and
ALPNServerExtension (in particular for the client, to "link" the
lambda with the list of protocols offered).
The lambdas would be, for the client:
void selected(String protocol)
with the semantic that:
* a null parameter would mean the server does not support ALPN. If the
server cannot negotiate the protocol, it shall (per RFC 7301) close
the connection. This leaves open a case where an uncompliant server
sends down an empty/null protocol, but I guess this can be treated by
the client as if the server does not support ALPN (in fact, it does
not support it correctly).
* an exception thrown would mean the client is not happy with the
protocol chosen (for any reason), and the TLS implementation must
close the connection with alert code 120 (per 7301).
The lambda for the server would be:
String select(List<String> protocols)
with the semantic that:
* a null list would mean the client does not support (correctly) ALPN.
* a null return value or an exception thrown would mean the server
could not negotiate the protocol and the connection must be closed
with alert code 120 (per 7301).
I'd be happy to contribute code and experience about this, but I need
guidance on where to start and how to proceed.
In particular, if a larger effort for a TLS Extension API is
considered useful, then the ALPN implementation is trivial; the bulk
of the work would be to design this new TLS Extension API.
For a more complete picture about why I think a TLS Extension API
would be beneficial, see also the other emails.
Thanks !
[0] http://tools.ietf.org/html/rfc7301
[1] https://github.com/eclipse/jetty.alpn/blob/master/src/main/java/org/eclipse/jetty/alpn/ALPN.java
--
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless. Victoria Livschitz
More information about the security-dev
mailing list