ECC Key Usage ignored

Xue-Lei Fan XUELEI.FAN at ORACLE.COM
Sat Oct 31 16:23:42 UTC 2020


Hi Daniel,

Would you mind file a bug for the tracking?

Xuelei

> On Oct 31, 2020, at 5:45 AM, Daniel Jeliński <djelinski1 at gmail.com> wrote:
> 
> 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 <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 <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 <djelinski1 at gmail.com <mailto:djelinski1 at 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 <https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r2.pdf>
> [2] http://mail.openjdk.java.net/pipermail/security-dev/2017-May/015902.html <http://mail.openjdk.java.net/pipermail/security-dev/2017-May/015902.html>
> [3] https://gist.github.com/djelinski/b4543a3eb7ea66306044c08b41bba00f <https://gist.github.com/djelinski/b4543a3eb7ea66306044c08b41bba00f>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/security-dev/attachments/20201031/6744ab86/attachment.htm>


More information about the security-dev mailing list