Verified that this behavior is still observed with JDK 16 EA 22.

Client side code responsible for server certificate validation is located
in EndEntityChecker.checkTLSServer [1]. That code is not executed when the
certificate is trusted [2]. I believe this is a bug - I wouldn't choose to
accept a server certificate when that certificate was only meant for
signing other certificates, for example.

Server side code responsible for cipher selection may need some
refactoring; currently the server selects the first cipher that passes
validation checks and for which keyManager.chooseServerAlias(keyType,...)
returns a key. The key manager does not have information about the intended
key usage (keyType is "EC" for both ECDH and ECDSA, and we don't know which
cipher is being checked), so it returns the same certificate when querying
for ECDH and ECDSA.

Fortunately ECDH is not popular, and most clients won't even try to
negotiate it. Still, I believe this is a bug that should be addressed.

As far as I could tell, there were no bugs reported for this in the bug
system. Should I report them there?

If someone is interested in the server code, here's the interesting portion
of stack trace:

chooseServerAlias:260, SunX509KeyManagerImpl (sun.security.ssl)
createServerPossession:288, X509Authentication$X509PossessionGenerator
(sun.security.ssl)
createPossession:214, X509Authentication$X509PossessionGenerator
(sun.security.ssl)
createPossession:90, X509Authentication (sun.security.ssl)
createPossessions:51, SSLKeyExchange (sun.security.ssl)
chooseCipherSuite:443, ServerHello$T12ServerHelloProducer (sun.security.ssl)


[1]
http://hg.openjdk.java.net/jdk/jdk/file/ee1d592a9f53/src/java.base/share/classes/sun/security/validator/EndEntityChecker.java#l276
[2]
http://hg.openjdk.java.net/jdk/jdk/file/ee1d592a9f53/src/java.base/share/classes/sun/security/validator/Validator.java#l267

wt., 27 paź 2020 o 18:44 Daniel Jeliński <djelins...@gmail.com> napisał(a):

> Hi all,
>
> TL;DR: both SSL server and client ignore KeyUsage certificate extension
> when determining the list of available cipher suites. They shouldn't;
> KeyUsage is the only differentiator between ECDH and ECDSA certificates.
>
> Long version:
> I'm experimenting with ECC certificates on my Jetty server; when I created
> an ECC certificate and tested the server with nmap, I found that both ECDSA
> and ECDH cipher suites are enabled. I don't want ECDH ciphers, but I don't
> want to add explicit excludes either.
>
> Reading into NIST recommendations [1] I found that ECDSA certificates
> should define KeyUsage extension with value digitalSignature, vs ECDH which
> should use keyAgreement value.
> I experimented with both combinations of KeyValue, both resulted in the
> same set of ciphers being offered by the server. The client doesn't seem to
> care about KeyUsage either - it accepts connections even when the selected
> cipher doesn't match KeyUsage.
>
> Chrome browser doesn't support ECDH ciphers, but it does support ECDSA.
> When connecting to a Java server using ECDH certificate, it displays the
> error "ERR_SSL_KEY_USAGE_INCOMPATIBLE"; the server offers an ECDSA cipher
> suite, which is rejected by the browser.
>
> The issue was already reported by Bernd Eckenfels here [2], but as far as
> I can tell, it is not addressed yet; I was able to reproduce it using
> slightly modified code of this gist [3]. Certificates were generated using
> keytool commands:
>
> ECDSA:
> keytool -genkeypair -alias ec -keyalg EC -keysize 256 -sigalg
> SHA256withECDSA -validity 365 -dname
> "CN=localhost,OU=Unknown,O=Unknown,L=Unknown,S=Unknown,C=Unknown"
> -storetype JKS -keystore ectest.jks -storepass 123456 -ext
> KeyUsage:c=digitalSignature,keyCertSign
>
> ECDH:
> keytool -genkeypair -alias ec -keyalg EC -keysize 256 -sigalg
> SHA256withECDSA -validity 365 -dname
> "CN=localhost,OU=Unknown,O=Unknown,L=Unknown,S=Unknown,C=Unknown"
> -storetype JKS -keystore ectest.jks -storepass 123456 -ext
> KeyUsage:c=keyAgreement,keyCertSign
>
> I'm not sure if keyCertSign is required on self-signed certificates, added
> it just in case.
>
> Tested on OpenJDK 11.0.6.
>
> Regards,
> Daniel Jeliński
>
>
> [1]
> https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r2.pdf
> [2]
> http://mail.openjdk.java.net/pipermail/security-dev/2017-May/015902.html
> [3] https://gist.github.com/djelinski/b4543a3eb7ea66306044c08b41bba00f
>

Reply via email to