This is a fork of the previous thread:
Subject: TLS Handshake Message Proposal
(Was: Re: JEP 244: TLS Application-Layer Protocol
Negotiation Extension)
I broke this thread off to keep this proposal discussion together, but
if you're interested in the history, please see the previous thread.
This approach combines different suggestions from security-dev in a new
way, and simplifies the ALPN selection process quite a bit. I think it
addresses most of the concerns about selection that were raised.
This approach can be completely separated from the Handshake mechanism I
discussed in the previous message, so I'm thinking of this approach for
JDK 9 and targeting the more general handshake approach for JDK 10.
Here's the summary of API additions:
SSLParameters:
--------------
Client-side: gets/sets the list of protocol names to send.
Server-side: gets/sets a ApplicationProtocolSelector which is a
user-defined callback mechanism.
ApplicationProtocolSelector:
----------------------------
Server-side: callback methods for SSLSocket/SSLEngine which
are provided with handshake information for making
the selection
ExtendedSSLSession:
-------------------
gets the negotiated protocol String
Specifics below. The javadoc obviously needs work.
class SSLParameters {
...deleted...
/**
* Gets the list of application protocols that will sent by
* the client.
*
* The list could be empty, in which case no protocols will be
* sent.
*
* @returns a list of application protocol names.
*/
public List<String> getApplicationProtocols() { };
/**
* Sets the list of application protocols that will sent by
* the client.
*
* protocols could be empty, in which case no protocols will be
* sent.
*
* @param protocols a list of application protocol names
* @throws IllegalArgumentException if protocols is null.
*/
public void setApplicationProtocols(List<String> protocols);
/**
* Gets the current server-side application layer protocol selector.
*
* @param the selector mechanism.
* @return the current application protocol selector, or null if
* there is not one.
*/
public ApplicationProtocolSelector
getApplicationProtocolSelector() {};
/**
* Sets the server-side application layer protocol selector.
*
* @param the selector mechanism, or null if protocol selection
* should not be done.
*/
public void setApplicationProtocolSelector(
ApplicationProtocolSelector selector) {};
}
/*
* A callback class on the server side that is responsible for
* choosing which Application Protocol should be used in a SSL/TLS
* connection.
*/
public abstract class ApplicationProtocolSelector {
/*
* SSLSocket callback to choose which Application Protocol value
* to return to a SSL/TLS client
*
* @param sslSocket the SSLSocket for this connection
* @param protocols the list of protocols advertised by the client
* @param protocolVersion the negotiated protocol version
* @param ciphersuite the negotiated ciphersuite
* @return a non-empty protocol String to send to the client,
* or null if no protocol value (i.e. extension) should be sent.
* @throws SSLProtocolException if the connection should be aborted
* because the the server supports none of the protocols that
* the client advertised.
*/
public String select(SSLSocket sslSocket, String[] protocols,
String protocolVersion, String ciphersuite)
throws SSLProtocolException;
/*
* SSLEngine callback to choose which Application Protocol to return
* to a SSL/TLS client.
*
* @param sslEngine the SSLEngine for this connection
* @param protocols the list of protocols advertised by the client
* @param protocolVersion the negotiated protocol version
* @param ciphersuite the negotiated ciphersuite
* @return a non-empty protocol String to send to the client,
* or null if no protocol value should be sent.
* @throws SSLProtocolException if the connection should be aborted
* because the the server supports none of the protocols that
* the client advertised.
*/
public String select(SSLEngine sslEngine, String[] protocols,
String protocolVersion, String ciphersuite)
throws SSLProtocolException;
}
If need be, we could include the received extensions or in a future
version of this class.
public class ExtendedSSLSession implements SSLSession {
...deleted...
/**
* Gets the application protocol negotiated for this connection.
*
* @returns the application protocol name or null if none was
* negotiated.
*/
public String getApplicationProtocol() { };
}
There was also some internal discussion about whether the values should
be Strings or byte arrays. The ALPN RFC only discusses bytes, and a
String.toBytes("US-ASCII") would limit the API to ASCII strings.
Lastly, we could also add some convenience values for well-known values.
e.g.:
public static final AP_HTTP_1.1 = "http/1.1";
or in byte form:
public static final AP_H2 = "h2".getBytes(""US-ASCII");
I refrained from including SPDY/*, since they are on their way out now,
and NAT/STUN since there hasn't been any call for it so far.
Thanks,
Brad