JDK-8173960 : SSL handshake with elliptic_curves extension does not work in 8u121 without sunec.jar
  • Type: Bug
  • Component: security-libs
  • Sub-Component: javax.net.ssl
  • Affected Version: 8u121
  • Priority: P3
  • Status: Resolved
  • Resolution: Duplicate
  • OS: generic
  • CPU: generic
  • Submitted: 2017-02-04
  • Updated: 2017-02-06
  • Resolved: 2017-02-06
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
(additionally the lib/ext/sunec.jar file has been removed)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

EXTRA RELEVANT SYSTEM CONFIGURATION :
$ openssl version
OpenSSL 1.0.2e 3 Dec 2015

A DESCRIPTION OF THE PROBLEM :
In 8u121, the SSL handshake of a server socket fails if sunec.jar is removed from jre1.8.0_121/lib/ext and the client hello contains an elliptic_curves extension (which seems to be a common case both with openssl and web browsers).

According to the JRE 8 Readme, removing sunec.jar should be safe as it does not contain any required algorithms listed on http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html

This is a regression from 8u112, seemingly caused by the fix for JDK-8148516 which throws if there are no supported elliptic curves. I would expect the extension to be simply ignored in this case.

REGRESSION.  Last worked in version 8u112

ADDITIONAL REGRESSION INFORMATION: 
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b15, mixed mode)
(additionally the lib/ext/sunec.jar file has been removed)

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Remove the lib/ext/sunec.jar file from the JRE under test.
2. Compile the test case into SSLTest.class.
3. Run keytool -genkeypair -keyalg RSA -dname cn=localhost -keystore keystore.jks -storepass changeit -keypass changeit
4. Run java SSLTest, which will wait for a connection
5. Run openssl s_client -connect localhost:8000

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
SSL handshake should succeed and the client should receive "Hello World!":
$ openssl s_client -connect localhost:8000 -brief
depth=0 CN = localhost
verify error:num=18:self signed certificate
CONNECTION ESTABLISHED
Protocol version: TLSv1.2
Ciphersuite: DHE-RSA-AES128-GCM-SHA256
Peer certificate: CN = localhost
Hash used: SHA512
Server Temp Key: DH, 1024 bits
Hello World!
ACTUAL -
The handshake fails:
$ openssl s_client -connect localhost:8000 -brief
2283136:error:140790E5:SSL routines:ssl23_write:ssl handshake failure:s23_lib.c:177:

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.ExceptionInInitializerError
        at sun.security.ssl.HelloExtensions.<init>(HelloExtensions.java:82)
        at sun.security.ssl.HandshakeMessage$ClientHello.<init>(HandshakeMessage.java:245)
        at sun.security.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:220)
        at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026)
        at sun.security.ssl.Handshaker.process_record(Handshaker.java:961)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
        at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:747)
        at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:123)
        at java.io.PrintStream.write(PrintStream.java:480)
        at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
        at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
        at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104)
        at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)
        at java.io.PrintStream.write(PrintStream.java:527)
        at java.io.PrintStream.print(PrintStream.java:669)
        at java.io.PrintStream.println(PrintStream.java:806)
        at SSLTest.main(SSLTest.java:12)
Caused by: java.lang.IllegalArgumentException: System property jdk.tls.namedGroups(null) contains no supported elliptic curves
        at sun.security.ssl.SupportedEllipticCurvesExtension.<clinit>(SupportedEllipticCurvesExtension.java:187)
        ... 18 more

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.io.*;
import java.net.*;
import javax.net.ssl.*;

public class SSLTest {
	public static void main(String[] args) throws IOException {
		System.setProperty("javax.net.ssl.keyStore", "keystore.jks");
		System.setProperty("javax.net.ssl.keyStorePassword", "changeit");
		ServerSocket ss = SSLServerSocketFactory.getDefault().createServerSocket(8000);
		try (Socket s = ss.accept()) {
			try(PrintStream out = new PrintStream(s.getOutputStream())) {
				out.println("Hello World!");
			}
		}
	}
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
The regression does not appear if lib/ext/sunec.jar is not removed. For license reasons this might not be a viable method, in which case downgrading to 8u112 is a possible workaround.


Comments
Moving to dup instead of incomplete.
2017-02-06

Yes - a duplicate of JDK-8173783
2017-02-06

To reproduce the issue , follow the steps outlined in the "Steps to reproduce" section of the bug report (test case is attached) JDK 8u112- Pass JDK 8u121 - Fail Following is the output : Exception in thread "main" java.lang.ExceptionInInitializerError at sun.security.ssl.HelloExtensions.<init>(HelloExtensions.java:82) at sun.security.ssl.HandshakeMessage$ClientHello.<init>(HandshakeMessage.java:245) at sun.security.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:220) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026) at sun.security.ssl.Handshaker.process_record(Handshaker.java:961) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375) at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:747) at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:123) at java.io.PrintStream.write(PrintStream.java:480) at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221) at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291) at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104) at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185) at java.io.PrintStream.write(PrintStream.java:527) at java.io.PrintStream.print(PrintStream.java:669) at java.io.PrintStream.println(PrintStream.java:806) at JI9047485.main(JI9047485.java:16) Caused by: java.lang.IllegalArgumentException: System property jdk.tls.namedGroups(null) contains no supported elliptic curves at sun.security.ssl.SupportedEllipticCurvesExtension.<clinit>(SupportedEllipticCurvesExtension.java:187) ... 18 more
2017-02-06