Issues with ALPN implementation in JDK 9

Greg Wilkins gregw at webtide.com
Wed Jun 15 02:28:43 UTC 2016


On 15 June 2016 at 11:40, Jason T. Greene <jason.greene at redhat.com> wrote:
>
>
> > On Jun 14, 2016, at 7:04 PM, Greg Wilkins <gregw at webtide.com> wrote:
> >
> > If SslEngine is changed to allow the negotiated application protocol to
> be set up until the time the hello response was wrapped, that would fix the
> problem.  Would it create any others?
>
> Well the fundamental issue is that the application protocol isn't a direct
> function of a cipher, rather the application protocol has a policy of
> allowed ciphers and optimal selection is finding the most recent protocol
> with a matching allowed cipher.


So doesn't that make application protocol a function of the negotiated
cipher?     Isn't working out which of the acceptable protocols allows the
negotiated cipher a function?


Put another way,  it is not possible to implement:

Protocol selectProtocol(List<Cipher> mutualAcceptableCiphers,
                        List<Protocol> mutualAcceptableProtocols)

such that it always returns a correct result, as a acceptable cipher may
not allowable for a given acceptable protocol.   Furthermore it ls not
possible to implement:

String selectProtocol(List<Pair<Cipher,Protocol>> mutualAcceptable)

because within that function there is no indication of what ciphers might
be negotiated.


So further information is needed, which could either be:

String selectProtocol(List<Pair<Cipher,Protocol>> mutualAcceptable,
                      List<Certificate> availableCertificates,
                      IPAddress host)

Which requires the implementation to rework the certificate selection and
SNI logic that is already performed by SslEngine.  Either this logic needs
to be duplicated (fragile) or an extra instance of SslEngine would need to
be used to duplicate the logic.

Alternately the function could be implemented as:

String selectProtocol(List<Pair<Cipher,Protocol>> mutualAcceptable,

                      Cipher negotiatedCipher)

ie a function of the negotiated cipher, but as the negotiatedCipher is
known only after the Hello message is unwrapped, this would require that
SslEngine allows setApplicationProtocol to be called after the hello unwrap
but before the hello response wrap.

I guess the other alternative would be to replace the SSLParameters.
setApplicationProtocols(List<Protocol>) method with something like:

SSLParameters.setApplicationProtocols(Function<Cipher,Protocol>
selectProtocol)

or

SSLParameters.setApplicationProtocols(List<Pair<Cipher,Protocol>>
cipherProtocolPairs)

or

SSLParameters.setApplicationProtocols(Map<Cipher,Protocol>>
protocolsForCiphers)



In short, either the cipher/SNI logic of SslEngine has to be duplicated or
the selection of the protocol needs to be deferred until after the cipher
is negotiated - either by allowing the setter to be called after
negotiation or by giving the SslEngine the information to know what
protocols are acceptable for which ciphers.


I believe that duplication is unacceptable for a new feature like ALPN.
Does anybody really believe that it is acceptable?
Are there any other alternatives other than the ones I've outlined above?

cheers

PS. The Cipher and Protocol types would most likely just be String in all
of the above examples. Using strong typing in the examples for clarity.










-- 
Greg Wilkins <gregw at webtide.com> CTO http://webtide.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/security-dev/attachments/20160615/924821c8/attachment-0001.html>


More information about the security-dev mailing list