TLS ALPN Proposal v5
Bradford Wetmore
bradford.wetmore at oracle.com
Thu Sep 24 23:45:23 UTC 2015
On 9/23/2015 2:33 AM, Simone Bordet wrote:
> Hi,
>
> On Wed, Sep 23, 2015 at 7:04 AM, Bradford Wetmore
> <bradford.wetmore at oracle.com> wrote:
>>
>>> This new proposal still requires that ciphers are sorted in a way that
>>> matches the ApplicationProtocol order.
>>> Would be nice if, along with the HTTP/2 blacklist, there is a HTTP/2
>>> comparator that sorts ciphers putting the blacklisted ones at the end.
>>
>> Hm...is the sample code at the end of the initial class description
>> insufficient? Adding a comparator seems a little heavyweight in that it
>> could require access to the ciphersuite internals and would add a lot of
>> complexity for this one known use case. When TLSv1.3 is done, the blacklist
>> stuff in HTTP/2 goes away.
>
> Sure, but until TLS 1.3 widely deployed, applications will have to
> sort the ciphers to put HTTP/2 ones before the blacklisted ones.
> Providing this comparator is as trivial as providing
> ApplicationProtocol.HTTP2BLACKLIST, so I thought to mention it.
I learned something today: Collections/Arrays.sort()/others are stable.
(i.e. equal elements will not be reordered as a result of the sort)
My expectation of "equals" was .equals(), not return value == 0.
I was concerned that such a Comparator might reorder valid H2 suites
from what was passed in. Thankfully, that's not the case, so I've added
this Comparator. There is a warning now about "consistency with
equals()", as the Strings obvioulsy won't be equals() and thus sorted
sets/maps just won't work. (See the Comparator pages for further
discussion.)
>>> I also don't understand why there are 2 methods for the protocol name
>>> ? What value does it bring to have 2 methods for the same thing ?
>>
>> Please see the IANA registry:
>>
>> http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids
>>
>> for RFC 7301:
>>
>> http://www.rfc-editor.org/info/rfc7301
>>
>> getProtocolName() is the IANA/IETF textual representation of the protocol
>> name (i.e. "Protocol" column), for example "HTTP/1.1", "SPDY/3", and "HTTP/2
>> over TLS". I suppose toString() could be used instead, but thought it might
>> eventually output additional ALPN value state. I don't have any concrete
>> plans at this point.
>>
>> getNetworkSequence() is the identification sequence for the protocol (i.e.
>> "Identification Sequence" column), and represents the actual byte
>> identifiers that will travel the network in an ALPN extension.
>>
>> 0x68 0x74 0x74 0x70 0x2f 0x31 0x2e 0x31 ("http/1.1")
>> 0x73 0x70 0x64 0x79 0x2f 0x33 ("spdy/3")
>> 0x68 0x32 ("h2")
>>
>> When client wants to send the extension over the network, it grabs the
>> ApplicationProtocols values from the SSLParameters, then calls
>> getNetworkSequence() on each ApplicationProtocol to obtain the actual opaque
>> ProtocolName(1..2^8-1) to send. Likewise on the server side, we match the
>> incoming active ALPN opaque values with the list of mutually agreeable ALPN
>> values. And of course, send back the final selected value.
>
> Sure, but application will have to implement two methods instead of
> one, and AFAIU the JDK implementation is never calling
> getProtocolName() since it's just a description for humans.
I think that a textual name will be better than:
// Output: javax.net.ssl.ApplicationProtocol$1 at 1b9e1916
System.out.println(ApplicationProtocol.H2);
and there's no UTF-8 ambiguity.
>> I've updated the webrev to include an SSLSocket test variant, and added a
>> few more comments.
>>
>> http://cr.openjdk.java.net/~wetmore/8051498/webrev.14/
>>
>> Hopefully things are more clear now. Thanks for your review/comments.
>
> I see now, thanks for the pointers !
>
> Indulge me a bit more below on the Map passed as parameter to
> ApplicationProtocol :)
>
> IIUC, by the time we are executing the code that calls
> ApplicationProtocol.match(), the TLS protocol is already chosen and
> it's available in SSLSession.
Not necessarily. This could also be called before the connection has
even been attempted, say if the client wants to determine if the
proposed protocols or protocol/ciphersuites it wants to use are even
allowed by an ApplicationProtocol.
> When remains is the transient value of cipher that is being chosen.
> Because we already have modified the API to support the application
> protocol transient value (by adding
> SSLEngine.getHandshakeApplicationProtocol()) to be used by
> KeyManagers, I was wondering if we cannot either:
CipherSuite is more of a Session value, so it should probably be part of
the handshakeSSLSession. We could set
handshakeSSLSession.getCipherSuite() before calling the ALPN selector,
or pass it in as part of the Map.
> A) add: String SSLEngine.getHandshakeCipherSuite(), to be used by
> ApplicationProtocol
That's kind of what we are doing already, but just in the
ApplicationProtocol matcher instead so that it doesn't add extra methods
to SSLSocket/SSLEngine.
And this doesn't really help the pre-connection situation where you want
to query/filter out unacceptable values.
http://cr.openjdk.java.net/~wetmore/8051498/webrev.15/
1. New H2BLACKLISTCOMPARATOR
2. Renamed the HTTP2BLACKLIST to H2BLACKLIST
Brad
More information about the security-dev
mailing list