Hi Brad,

A couple of initial comments/questions.

1) Certificate selection is one feature envisaged by ALPN. ie a client or a server ought to be able to choose a different certificate depending on the application name
    that gets negotiated. Is that possible with this API?

2) The notion of client preference needs to be made explicit. This could just be a matter of javadoc given that List<String> is ordered. So, it could be enough to say the same
    order is used in the protocol.

3) It's a shame that the RFC didn't mandate UTF8 encoded byte sequences for the protocol name, because it's theoretically possible that non UTF8 byte sequences
    could get registered, but that's not a concern for HTTP/2 at least.

Thanks,
Michael

On 22/05/15 01:55, Bradford Wetmore wrote:
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

Reply via email to