JDK-8273553 : sun.security.ssl.SSLEngineImpl.closeInbound also has similar error of JDK-8253368
  • Type: Bug
  • Component: security-libs
  • Sub-Component: javax.net.ssl
  • Affected Version: 15,16,17,18
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2021-09-09
  • Updated: 2022-10-19
  • Resolved: 2022-04-02
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 15 JDK 17 JDK 19 JDK 8
11.0.18-oracleFixed 15.0.10Fixed 17.0.6-oracleFixed 19 b17Fixed 8u361Fixed
Related Reports
Relates :  
Description
ADDITIONAL SYSTEM INFORMATION :
Initially observed in OpenJDK 15, also observed in OpenJDK 16.

A DESCRIPTION OF THE PROBLEM :
I am seeing the same behaviour as in the original bug report, only the exception is thrown at java.base/sun.security.ssl.SSLEngineImpl.closeInbound(SSLEngineImpl.java:796) rather than at sun.security.ssl.SSLSocketImpl.shutdownInput(SSLSocketImpl.java:656). The two methods are very similar, so I was wondering if the exception thrown in the former should also be a non-fatal one, i.e. the fix implemented for the original bug. This is the stacktrace:

00:00:18,708 ERROR [stderr] (default task-1) javax.net.ssl|ERROR|A4|default task-1|2021-09-03 24:00:18.708 BST|TransportContext.java:361|Fatal (INTERNAL_ERROR): closing inbound before receiving peer's close_notify (
00:00:18,708 ERROR [stderr] (default task-1) "throwable" : {
00:00:18,708 ERROR [stderr] (default task-1)   javax.net.ssl.SSLException: closing inbound before receiving peer's close_notify
00:00:18,708 ERROR [stderr] (default task-1)    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:133)
00:00:18,708 ERROR [stderr] (default task-1)    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
00:00:18,708 ERROR [stderr] (default task-1)    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:356)
00:00:18,708 ERROR [stderr] (default task-1)    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:312)
00:00:18,708 ERROR [stderr] (default task-1)    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:303)
00:00:18,708 ERROR [stderr] (default task-1)    at java.base/sun.security.ssl.SSLEngineImpl.closeInbound(SSLEngineImpl.java:796)
00:00:18,708 ERROR [stderr] (default task-1)    at io.undertow.core@2.2.8.Final//io.undertow.server.protocol.http.ALPNLimitingSSLEngine.closeInbound(ALPNLimitingSSLEngine.java:169)
00:00:18,708 ERROR [stderr] (default task-1)    at io.undertow.core@2.2.8.Final//io.undertow.protocols.ssl.SslConduit.notifyReadClosed(SslConduit.java:636)
00:00:18,708 ERROR [stderr] (default task-1)    at io.undertow.core@2.2.8.Final//io.undertow.protocols.ssl.SslConduit.closed(SslConduit.java:1064)
00:00:18,708 ERROR [stderr] (default task-1)    at io.undertow.core@2.2.8.Final//io.undertow.protocols.ssl.SslConduit.close(SslConduit.java:1196)
00:00:18,708 ERROR [stderr] (default task-1)    at io.undertow.core@2.2.8.Final//io.undertow.protocols.ssl.UndertowSslConnection.closeAction(UndertowSslConnection.java:155)
00:00:18,708 ERROR [stderr] (default task-1)    at org.jboss.xnio@3.8.4.Final//org.xnio.Connection.close(Connection.java:132)
00:00:18,708 ERROR [stderr] (default task-1)    at io.undertow.core@2.2.8.Final//io.undertow.server.AbstractServerConnection.close(AbstractServerConnection.java:159)
00:00:18,708 ERROR [stderr] (default task-1)    at org.jboss.xnio@3.8.4.Final//org.xnio.IoUtils.safeClose(IoUtils.java:152)

REGRESSION : Last worked in version 8


FREQUENCY : often



Comments
A pull request was submitted for review. URL: https://git.openjdk.org/jdk15u-dev/pull/289 Date: 2022-10-19 07:03:12 +0000
19-10-2022

Fix request (15u) I'd like to backport it for parity with major releases. Clean backport. Security tests run fine.
19-10-2022

Fix request [11u] I backport this for parity with 11.0.18-oracle. The test fails without the fix, and passes with it. At least medium risk, it changes an exception. But as I understand a needed fix. I had to resolve a chunk and adapt the coding slightly. SAP nighlty testing passed.
11-10-2022

A pull request was submitted for review. URL: https://git.openjdk.org/jdk11u-dev/pull/1422 Date: 2022-10-09 18:58:00 +0000
09-10-2022

Fix request [17u] I backport this for parity with 17.0.6-oracle. No risk, only a test change. -- After pushing this: I must correct myself. It touches Security code, medium risk. Clean backport. SAP nightly testing passed.
09-10-2022

A pull request was submitted for review. URL: https://git.openjdk.org/jdk17u-dev/pull/695 Date: 2022-09-19 20:45:56 +0000
19-09-2022

Changeset: 0b09f70a Author: Bradford Wetmore <wetmore@openjdk.org> Date: 2022-04-02 00:30:48 +0000 URL: https://git.openjdk.java.net/jdk/commit/0b09f70a730404ceb827673f1d3c82fbf495bb41
02-04-2022

During the test development, I chose to use SSLSocketSSLEngineTemplate as the test base so that we could check that both SSLSocket and SSLEngine behavior was similar. One code review comment was to use the flat text keystore (non-binary) that has been developed for SSLSocketTemplate/SSLEngineTemplate. The SSLSocketTemplate, SSLEngineTemplate and SSLSocketSSLEngineTemplate testbeds have diverged broadly (as noted in JDK-8284047), so this is not an easy fix. There are customer requests for quick relief, so in the interest of time, I'll use the existing template, and hope someone can address JDK-8284047 for future issues. As many existing tests still use the binary keystores, so this will just be one more.
01-04-2022

A pull request was submitted for review. URL: https://git.openjdk.java.net/jdk/pull/7796 Date: 2022-03-12 00:55:07 +0000
18-03-2022

A draft pull request has been created. https://github.com/openjdk/jdk/pull/7796 More details to follow.
12-03-2022

contacting submitter shouldn't be necessary. Here's a simple edit to an existing test case to mimic the issue diff --git a/test/jdk/javax/net/ssl/SSLEngine/LargePacket.java b/test/jdk/javax/net/ssl/SSLEngine/LargePacket.java index 33f2c4f49ba..894d23541aa 100644 --- a/test/jdk/javax/net/ssl/SSLEngine/LargePacket.java +++ b/test/jdk/javax/net/ssl/SSLEngine/LargePacket.java @@ -101,6 +101,8 @@ public class LargePacket extends SSLEngineService { // send out application data deliver(ssle, sc); + ssle.closeInbound(); + // close the socket channel. sc.close(); ssc.close();
11-03-2022

Requested a simple reproducer from the submitter.
11-03-2022

The TLS specification in this area seems to have altered over the years in the newer TLS protocol versions that were released. I've captured some of the main differences in this area in the notes below. I think we should re-examine if the above example should indeed lead to a fatal alert of not. Note that unlike SSLSocket, SSLEngine exposes more API control in this area for closing inbound/outbound traffic. ===== Closure Alert RFC changes since TLSv1.0 TLS v1: This message notifies the recipient that the sender will not send any more messages on this connection. The session becomes unresumable if any connection is terminated without proper close_notify messages with level equal to warning. TLS v1.1: Note that as of TLS 1.1, failure to properly close a connection no longer requires that a session not be resumed. This is a change from TLS 1.0 to conform with widespread implementation practice. TLS v1 to TLS v1.2: Unless some other fatal alert has been transmitted, each party is required to send a close_notify alert before closing the write side of the connection. The other party MUST respond with a close_notify alert of its own and close down the connection immediately, discarding any pending writes. It is not required for the initiator of the close to wait for the responding close_notify alert before closing the read side of the connection. If the application protocol using TLS provides that any data may be carried over the underlying transport after the TLS connection is closed, the TLS implementation must receive the responding close_notify alert before indicating to the application layer that the TLS connection has ended. If the application protocol will not transfer any additional data, but will only close the underlying transport connection, then the implementation MAY choose to close the transport without waiting for the responding close_notify. TLS v1.2 (text) versus TLS v1.3: close_notify This message notifies the recipient that the sender will not send any more messages on this connection. Note that as of TLS 1.1, failure to properly close a connection no longer requires that a session not be resumed. This is a change from TLS 1.0 to conform with widespread implementation practice. close_notify This alert notifies the recipient that the sender will not send any more messages on this connection. Any data received after a closure alert has been received MUST be ignored. Further clarification in TLS v1.3: Either party MAY initiate a close of its write side of the connection by sending a "close_notify" alert. Any data received after a closure alert has been received MUST be ignored. If a transport-level close is received prior to a "close_notify", the receiver cannot know that all the data that was sent has been received. Each party MUST send a "close_notify" alert before closing its write side of the connection, unless it has already sent some error alert. This does not have any effect on its read side of the connection. Note that this is a change from versions of TLS prior to TLS 1.3 in which implementations were required to react to a "close_notify" by discarding pending writes and sending an immediate "close_notify" alert of their own. That previous requirement could cause truncation in the read side. Both parties need not wait to receive a "close_notify" alert before closing their read side of the connection, though doing so would introduce the possibility of truncation.
11-10-2021

The additional information from the submitter: I am aware that JDK-8253368 has been fixed, but I'm seeing the same error being thrown in a different class. The original bug was reported for sun.security.ssl.SSLSocketImpl.shutdownInput(SSLSocketImpl.java:656) whereas in my case the error is thrown in sun.security.ssl.SSLEngineImpl.closeInbound(SSLEngineImpl.java:796). The two methods are very similar, so I was wondering if the fix applied to the first can also be applied to the second. Here's the stacktrace: 00:00:18,708 ERROR [stderr] (default task-1) javax.net.ssl|ERROR|A4|default task-1|2021-09-03 24:00:18.708 BST|TransportContext.java:361|Fatal (INTERNAL_ERROR): closing inbound before receiving peer's close_notify ( 00:00:18,708 ERROR [stderr] (default task-1) "throwable" : { 00:00:18,708 ERROR [stderr] (default task-1) javax.net.ssl.SSLException: closing inbound before receiving peer's close_notify 00:00:18,708 ERROR [stderr] (default task-1) at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:133) 00:00:18,708 ERROR [stderr] (default task-1) at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117) 00:00:18,708 ERROR [stderr] (default task-1) at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:356) 00:00:18,708 ERROR [stderr] (default task-1) at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:312) 00:00:18,708 ERROR [stderr] (default task-1) at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:303) 00:00:18,708 ERROR [stderr] (default task-1) at java.base/sun.security.ssl.SSLEngineImpl.closeInbound(SSLEngineImpl.java:796) 00:00:18,708 ERROR [stderr] (default task-1) at io.undertow.core@2.2.8.Final//io.undertow.server.protocol.http.ALPNLimitingSSLEngine.closeInbound(ALPNLimitingSSLEngine.java:169) 00:00:18,708 ERROR [stderr] (default task-1) at io.undertow.core@2.2.8.Final//io.undertow.protocols.ssl.SslConduit.notifyReadClosed(SslConduit.java:636) 00:00:18,708 ERROR [stderr] (default task-1) at io.undertow.core@2.2.8.Final//io.undertow.protocols.ssl.SslConduit.closed(SslConduit.java:1064) 00:00:18,708 ERROR [stderr] (default task-1) at io.undertow.core@2.2.8.Final//io.undertow.protocols.ssl.SslConduit.close(SslConduit.java:1196) 00:00:18,708 ERROR [stderr] (default task-1) at io.undertow.core@2.2.8.Final//io.undertow.protocols.ssl.UndertowSslConnection.closeAction(UndertowSslConnection.java:155) 00:00:18,708 ERROR [stderr] (default task-1) at org.jboss.xnio@3.8.4.Final//org.xnio.Connection.close(Connection.java:132) 00:00:18,708 ERROR [stderr] (default task-1) at io.undertow.core@2.2.8.Final//io.undertow.server.AbstractServerConnection.close(AbstractServerConnection.java:159) 00:00:18,708 ERROR [stderr] (default task-1) at org.jboss.xnio@3.8.4.Final//org.xnio.IoUtils.safeClose(IoUtils.java:152) [...]
09-09-2021

Requested the submitter download the latest version of JDK 17 from https://jdk.java.net/17/ and test again.
09-09-2021