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