JDK-8207009 : TLS 1.3 half-close and synchronization issues
  • Type: Bug
  • Component: security-libs
  • Sub-Component: javax.net.ssl
  • Affected Version: 11
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2018-07-10
  • Updated: 2023-12-12
  • Resolved: 2018-08-15
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 JDK 12 JDK 8 Other
11 b27Fixed 12Fixed 8u261Fixed openjdk8u272Fixed
Related Reports
CSR :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Relates :  
Description
TLS 1.3 issues:
1. Existing specification of SSLEngine#closeInbound states the following

Throws:
    SSLException - if this engine has not received the proper SSL/TLS/DTLS close notification message from the peer.

However, starting from JDKb20 this exception is not thrown because of half-close policy implementation requirement for TLSv1.3

Also TLS 1.2 and prior versions in JDK are updated to use the half-close policy as well.

2. Does not support half-close in the current TLS 1.3 implementation.

3. Deadlock issues in the current TLS 1.3 implementation if read, write and handshake use different threads.
Comments
URL: http://hg.openjdk.java.net/jdk/jdk11/rev/d0e2e34eec65 User: xuelei Date: 2018-08-14 23:56:12 +0000
15-08-2018

Fix request approved. Pending CSR approval which is expected soon.
13-08-2018

Bug submitter of JDK-8208642 confirmed webrev.01 fix their issue, Comment from him: "Good news. I can confirm that the 01 patch does fix this issue."
03-08-2018

Comment from bug submitter of JDK-8208642: I have testing this locally and the proposed patch for JDK-8207009 *does not* address the issue described in JDK-8208642. I was concerned that I wasn't building the JDK correctly and/or picking up the wrong JDK but I've added a bunch of System.out.println() statements that confirm I am running the correct (current source plus JDK-8207009 patch) and that the failure described in JDK-8208642 is still happening in the same way.
02-08-2018

Fix Request --------------- For TLS 1.3, the close of inbound and outbound are independent (half-close). While for TLS 1.2 and prior versions, closing inbound will close the outbound as well, and the same for closing outbound (duplex-close). And the SSLSocket.close() specification also requires duplex-close. To be compatible with the SSLSocket.close() specification, in the current TLS 1.3 implementation, we choose to use a duplex-close policy, which is not strictly follow the TLS 1.3 specification. However, Jetty is running into serious problems with this policy. In this update, we are trying to provide both half-close and duplex-close policies per the TLS specification. And there are also application deadlock reported for JDK b20. In this update, we also try to simplify the synchronization, and mitigate the potential deadlock risks. The Mach5 testing is green, and interop testing passed. We are asking for external testing from Netty, Jetty. The risk should be low. webrev: http://cr.openjdk.java.net/~xuelei/8207009/webrev.00/
30-07-2018

Issue reported, http://mail.openjdk.java.net/pipermail/security-dev/2018-July/017633.html: ------------------------------- My understanding is that when you are interested in closing the underlying socket when using the SSLEngine, you must call closeOutbound() and WRAP and UNWRAP until both isInboundDone() and isOutboundDone() return true. One edge case of this is if you are interested in closing the socket prior to the completion of a handshake. In JDK 10.0.1 (and I believe prior JDKs) this was the behavior for one way in which this arises: 1. Initiate handshake 2. UNWRAP data from client 3. WRAP data to send to client. Handshake status is "NEED_UNWRAP" 4. Call closeOutbound() (perhaps the server is shutting down and you want to close the connection). 5. Handshake status now returns "NEED_WRAP" JDK10: isInboundDone() - returns false isOutboundDone() - returns false A call to wrap() produces 7 bytes and status = CLOSED. Handshake status is now NEED_UNWRAP. isInboundDone() - returns false isOutboundDone() - returns true JDK11: isInboundDone() - returns true isOutboundDone() - returns false A call to wrap() throws the following exception: javax.net.ssl.SSLException: Cannot kickstart, the connection is broken or closed at java.base/sun.security.ssl.TransportContext.kickstart(TransportContext.java:205) at java.base/sun.security.ssl.SSLEngineImpl.writeRecord(SSLEngineImpl.java:167) at java.base/sun.security.ssl.SSLEngineImpl.wrap(SSLEngineImpl.java:138) at java.base/sun.security.ssl.SSLEngineImpl.wrap(SSLEngineImpl.java:116) at java.base/javax.net.ssl.SSLEngine.wrap(SSLEngine.java:471) I’m not sure what the procedure for closing a connection prior to handshake completion is for TLS. But obviously this is a scenario that can arise. It seems wrong to me that the state transitions for the SSLEngine do not handle this. The fact that “isOutboundDone()” returns false, but I cannot WRAP seems to be an issue.
18-07-2018