JDK-8208642 : Server initiated TLSv1.2 renegotiation fails if Java client allows TLSv1.3
  • Type: Bug
  • Component: security-libs
  • Sub-Component: javax.net.ssl
  • Affected Version: 11
  • Priority: P2
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86_64
  • Submitted: 2018-08-01
  • Updated: 2019-07-18
  • Resolved: 2018-08-01
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 11
11Resolved
Related Reports
Duplicate :  
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



Comments
This issue will be fixed within JDK-8207009.
01-08-2018