TLS ALPN Proposal

Bradford Wetmore bradford.wetmore at
Tue May 26 00:30:44 UTC 2015

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

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 

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.


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.


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

Yes, see the last sentence section 1.



More information about the security-dev mailing list