Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8173960

SSL handshake with elliptic_curves extension does not work in 8u121 without sunec.jar

    XMLWordPrintable

Details

    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.

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: