TLS ALPN Proposal
Bradford Wetmore
bradford.wetmore at oracle.com
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
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
More information about the security-dev
mailing list