TLS ALPN Proposal

Bradford Wetmore bradford.wetmore at oracle.com
Fri May 22 00:55:52 UTC 2015


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


More information about the security-dev mailing list