JDK-8233619 : SSLEngine handshake status immediately after the handshake can be NOT_HANDSHAKING rather than FINISHED with TLSv1.3
  • Type: Bug
  • Component: security-libs
  • Sub-Component: javax.net.ssl
  • Affected Version: 11.0.2,11.0.5-oracle,13.0.1,14
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: x86_64
  • Submitted: 2019-11-05
  • Updated: 2020-05-18
  • Resolved: 2020-03-10
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 15
15 b13Fixed
Related Reports
Cloners :  
Description
This was originally raised as an issue against Apache Tomcat:
https://bz.apache.org/bugzilla/show_bug.cgi?id=63892

Reproduction steps with Tomcat (including key stores and Tomcat configuration) are in that report. The summary is:
- Java 13.0.1+9
- Tomcat 9 latest release (or latest source)
- TLSv1.3
- client authentication required
- Firefox client in private browsing mode

Debugging of the TLS handshake in Tomcat (https://github.com/apache/tomcat/blob/master/java/org/apache/tomcat/util/net/SecureNioChannel.java#L169) shows that in private browsing mode the penultimate SSLEngine handshake status is NEED_TASK.
There is a single task containing 3 entries in the DelegatedAction map.
The final entry in that Map ends up in T13FinishedConsumer which in turn leads to...
TransportContext.finishHandshake(). While this method returns HandshakeStatus.FINISHED, the return value is ignored. As soon as that method sets handshakeContext=null, the SSLEngine handshake status is NOT_HANDSHAKING. This breaks Tomcat's TLS handshake code as Tomcat expects the SSLEngine handshake status to be FINISHED.

When Firefox is used in non-private browsing mode the penultimate SSLEngine handshake status is NEED_WRAP which becomes FINISHED after the write.
Comments
The original Apache Tomcat test case still fails with OpenJDK 15 ea13
11-03-2020

[~markt] [~xuelei] In my opinion, it is better to keep this bug as resolved in b13 for tracking purpose. Since the original fix was promoted to b13, may I suggest to close this bug with verification as "fix failed" and file a new bug to address.
05-03-2020

The original Apache Tomcat test case still fails with OpenJDK 15 ea13
05-03-2020

URL: https://hg.openjdk.java.net/jdk/jdk/rev/522f5bb0e92b User: xuelei Date: 2020-03-03 23:57:18 +0000
04-03-2020

Tried to reproduce the issue with following setup and JDK versions: Apache Tomcat version - 9.0.27 Test JDK - See below Firefox Browser - ver 70.0.1 in Private browser mode Url - https://localhost:8443/ Test JDK versions: 13.0.1 b9 11.0.6 b4 11.0.5 b10 11.0.4 b10 11.0.3 b12 11.0.2 b9 11.0.2 b2 (The issue is observed from this version onwards) I can see the same exception reported by submitter. 18-Nov-2019 12:44:36.093 FINE [https-jsse-nio-8443-exec-4] org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun Error during SSL handshake java.io.IOException: NOT_HANDSHAKING during handshake at org.apache.tomcat.util.net.SecureNioChannel.handshake(SecureNioChannel.java:193) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1556) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.base/java.lang.Thread.run(Thread.java:834) In the browser following message was displayed. Secure Connection Failed An error occurred during a connection to localhost:8443. The page you are trying to view cannot be shown because the authenticity of the received data could not be verified. Please contact the website owners to inform them of this problem. Note: The issue is not observed when browser is launched in normal(not private) mode. For older releases(tried 11.0.2 b01, 11.0.1 b13, 11 b28 & 11 b20) secure connection was failed with a different exception. javax.net.ssl|ERROR|21|https-jsse-nio-8443-exec-1|2019-11-18 12:10:04.049 IST|TransportContext.java:313|Fatal (HANDSHAKE_FAILURE): pre_shared_key key extension is offered without a psk_key_exchange_modes extension ( "throwable" : { javax.net.ssl.SSLHandshakeException: pre_shared_key key extension is offered without a psk_key_exchange_modes extension at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:128) at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117) at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:308) at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:264) at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:255) at java.base/sun.security.ssl.PskKeyExchangeModesExtension$PskKeyExchangeModesOnTradeAbsence.absent(PskKeyExchangeModesExtension.java:327) at java.base/sun.security.ssl.SSLExtension.absentOnTrade(SSLExtension.java:572) at java.base/sun.security.ssl.SSLExtensions.consumeOnTrade(SSLExtensions.java:180) at java.base/sun.security.ssl.ServerHello$T13ServerHelloProducer.produce(ServerHello.java:522) at java.base/sun.security.ssl.SSLHandshake.produce(SSLHandshake.java:436) at java.base/sun.security.ssl.ClientHello$T13ClientHelloConsumer.goServerHello(ClientHello.java:1224) at java.base/sun.security.ssl.ClientHello$T13ClientHelloConsumer.consume(ClientHello.java:1160) at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.onClientHello(ClientHello.java:849) at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.consume(ClientHello.java:810) at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392) at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:444) at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1065) at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1052) at java.base/java.security.AccessController.doPrivileged(Native Method) at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:999) at org.apache.tomcat.util.net.SecureNioChannel.tasks(SecureNioChannel.java:443) at org.apache.tomcat.util.net.SecureNioChannel.handshakeUnwrap(SecureNioChannel.java:507) at org.apache.tomcat.util.net.SecureNioChannel.handshake(SecureNioChannel.java:238) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1556) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.base/java.lang.Thread.run(Thread.java:834)} And in the browser following message was displayed. Secure Connection Failed An error occurred during a connection to localhost:8443. Cannot communicate securely with peer: no common encryption algorithm(s). Error code: SSL_ERROR_NO_CYPHER_OVERLAP Logs are attached for more details.
18-11-2019

I've attached two TLS debug logs - the result of using -Djavax.net.debug=ssl:handshake:verbose I note from taking a diff between the two that the failed log (from private browsing) doesn't include the session ticket extension. I'm wondering if it is the lack (or not) of that extension that is changing the behaviour at the end of the handshake since in the working example an additional write is required for the session ticket which means that penultimate SSLEngine handshake status is NEED_WRAP which then correctly transitions to FINISHED.
06-11-2019