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

Server initiated TLSv1.2 renegotiation fails if Java client allows TLSv1.3

    XMLWordPrintable

Details

    • b20
    • 11
    • x86_64
    • linux

    Description

      ADDITIONAL SYSTEM INFORMATION :
      Observed on 64-bit Linux with both Oracle and OpenJDk builds

      openjdk version "11-ea" 2018-09-25
      OpenJDK Runtime Environment 18.9 (build 11-ea+24)
      OpenJDK 64-Bit Server VM 18.9 (build 11-ea+24, mixed mode)

      java version "11-ea" 2018-09-25
      Java(TM) SE Runtime Environment 18.9 (build 11-ea+24)
      Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11-ea+24, mixed mode)

      Linux study04 4.15.0-29-generic #31-Ubuntu SMP Tue Jul 17 15:39:52 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

      A DESCRIPTION OF THE PROBLEM :
      Failure observed while running Apache Tomcat trunk test suite with Java 11 EA 24. Failure not observed with Java 10.0.2

      Relevant configuration details:
      - Server
        - TLSv1, TLSv1.2, SSLv2Hello, TLSv1.1
        - Want client authentication
      - Client
        - Default protocols (includes TLSv1.3)
        - Will send client cert if requested

      The test proceeds as follows:
      - TLS connection established to server. No client cert auth since client does not send cert.
      - Client makes HTTP request to endpoint that does not require authentication
      - Server responds
      - Client makes HTTP request to endpoint that DOES require authentication
      - Server starts renegotiation
      - Client fails to process the "request hello" message

      The failure occurs in sun.security.ssl.SSLHandshake.getHandshakeConsumer()

      The message is correctly identified as a 'hello request' and the consumer is set to SSLHandshake.HELLO_REQUEST at line 432 of HandshakeContext.
      Execution proceeds to line 445 of HandshakeContext
      Execution proceeds to line 388 of SSLHandshake

      At line 405 of SSLHandshake hc.negotiatedProtocol is null so protocol version is updated to hc.maximumActiveProtocol which is now TLS13.

      The for loops at lines 412-419 fail to find a matching consumer because SSLHandshake.HELLO_REQUEST only supports TLS12 and below.

      A null SSLConsumer is returned and the connection fails due to the unrecognised message.

      The full stack trace at the client is:
      javax.net.ssl.SSLProtocolException: Unsupported handshake message: hello_request
      at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:126)
      at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:325)
      at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:268)
      at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:447)
      at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:422)
      at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:178)
      at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:164)
      at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:880)
      at java.base/sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:852)
      at java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:602)
      at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:252)
      at java.base/java.io.BufferedInputStream.read1(BufferedInputStream.java:292)
      at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:351)
      at java.base/sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:746)
      at java.base/sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:689)
      at java.base/sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:717)
      at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1604)
      at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1509)
      at java.base/java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:527)
      at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:329)
      at org.apache.catalina.startup.TomcatBaseTest.methodUrl(TomcatBaseTest.java:690)
      at org.apache.catalina.startup.TomcatBaseTest.methodUrl(TomcatBaseTest.java:663)
      at org.apache.catalina.startup.TomcatBaseTest.getUrl(TomcatBaseTest.java:657)
      at org.apache.catalina.startup.TomcatBaseTest.getUrl(TomcatBaseTest.java:651)
      at org.apache.catalina.startup.TomcatBaseTest.getUrl(TomcatBaseTest.java:636)
      at org.apache.catalina.startup.TomcatBaseTest.getUrl(TomcatBaseTest.java:630)
      at org.apache.tomcat.util.net.TestClientCert.doTestClientCertGet(TestClientCert.java:84)
      at org.apache.tomcat.util.net.TestClientCert.testClientCertGetWithoutPreemptive(TestClientCert.java:39)
      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.base/java.lang.reflect.Method.invoke(Method.java:566)
      at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
      at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
      at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
      at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
      at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
      at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
      at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
      at org.junit.rules.RunRules.evaluate(RunRules.java:20)
      at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
      at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
      at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
      at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
      at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
      at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
      at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
      at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
      at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
      at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
      at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
      at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
      at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
      Caused by: java.lang.UnsupportedOperationException: Unsupported handshake consumer: hello_request
      at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
      at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:445)
      ... 53 more



      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Tomcat source code:
      http://svn.apache.org/repos/asf/tomcat/trunk/
      or
      https://github.com/apache/tomcat

      Run this test:
      org.apache.tomcat.util.net.TestClientCert.testClientCertGetWithoutPreemptive

      Adding the following properties to build.properties will limit the test suite to this single test:
      test.entry=org.apache.tomcat.util.net.TestClientCert
      test.entry.methods=testClientCertGetWithoutPreemptive


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The renegotiation succeeds and the test passes.
      ACTUAL -
      The renegotiation fails and the test fails.

      ---------- BEGIN SOURCE ----------
      See steps to reproduce
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Disable TLSv1.3 support in the client. e.g. with:
      System.setProperty("https.protocols", "TLSv1.1,TLSv1.2")

      FREQUENCY : always


      Attachments

        Issue Links

          Activity

            People

              xuelei Xuelei Fan
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: