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