Darn those Chicken/Eggs [1]!

Yes, you are correct.  The steps for the current server code:

1. The ClientHello is parsed, and the SNI matcher callback is called. It does not return which value was matched in the ServerHello, just whether a SNI name was matched or not:

    The "extension_data" field of this extension SHALL be
    empty.

2.  Begin generating the ServerHello, choose the Protocol Version.

3. Iterate through the list of client's ciphersuites and call the Server's KeyManager (KM) callback until the KM returns key material we can use. A return string selects the proposed ciphersuite.

So we currently don't know the selected ciphersuite until the KM has been called (possibly multiple times).

If we choose the ALPN before the ciphersuite, the ciphersuite selection may end up being inappropriate (HTTP/2 blacklist). If we choose the ciphersuite first, then the ALPN value wasn't used to drive the certificate selection.

Two suggestions in preferred order below.

In each of these cases, unfortunately there is currently no indication of the proposed Ciphersuite, so we need to modify the behavior of getHandshakeSession().getCipherSuite() to fill in the proposed CipherSuite before the call to the KM. This seems ok with the current wording, but we'd need to make that explicit. This value will change for each ciphersuite/KM choice attempt.

Each suggestion below is followed by our previously proposed ALPN callback to make the actual ALPN value selection:


1a.  Add a parallel method to ExtendedSSLSession:

    public List<String> getRequestedApplicationProtocolNames();

along with the previously proposed selected name:

    public String getApplicationProtocol()

(I'll be changing these names.  I'm open to suggestions).

When the KM is called, the TLS protocol (e.g. TLSv1.2) has already been selected.

Both of the major selection parameters (protocol/proposed ciphersuite) are now available, and applications have access to the ordered ALPN list to see what the client's requested values were.

-or-

1b. Keep API as is, and make two callbacks. This first is an advisory value, the TLS protocol version and proposed ciphersuite will be available in getHandshakeSession(). The second callback sets the final value that will be sent.


I think 1.a is my preference.

To answer some of the other questions.

On 5/25/2015 3:08 AM, Michael McMahon wrote:

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.

Yes, I'll add that.

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.

No. Not sure what we can do about that, short of going back to the byte[] option. Given that IANA operates mainly in English, I would expect the namespaces will probably be ASCII, but that is just conjecture.

> This would be possible, IIUC, using
> sslEngine.getHandshakeSession().getRequestedServerNames() in the
> ApplicationProtocolSelector implementation.

Yes.

> but I understand it's mentioned in RFC 7301.

Yes, see the last sentence section 1.

Brad


[1] https://www.youtube.com/watch?v=ixgf5SlvOB4&feature=youtu.be&t=27

Reply via email to