-
Bug
-
Resolution: Unresolved
-
P3
-
None
-
openjdk8u272, 11, 15
During a handshake process, The client or server occasionally enter a loop of producers like in T12ClientHelloConsumer::consume
https://github.com/openjdk/jdk/blob/7ddc2b5606cd5353a3c25dde476ff0e6ccc2ed23/src/java.base/share/classes/sun/security/ssl/ClientHello.java#L1102-L1121
The producers in the loop create and write to the socket. The client receives and starts processing the message immediately. In certain cases, where the network is faster than the computation, the peer can receive the message and respond before the loop of producers are completed. If the peer encounters a fatal condition, it would sends a fatal and closes the socket on its end. The currently running producer is unaware of this case and attempts to write to the socket nonetheless. This will cause the write to fail with a SocketException (Broken Pipe).
Since the host has not attempted to read from the socket, it's unaware that the peer has sent a fatal and closed the socket. It ends up throwing SocketException instead of a SSLHandshakeException.
Example of the Case
```
SERVER CLIENT
* <------------ CLIENT_HELLO
CLIENT_HELLO_CONSUMER
SERVER_HELLO_PRODUCER -------------> SERVER_HELLO_CONSUMER
CERTIFICATE_PRODUCER -------------> CERTIFICATE_CONSUMER
CERTIFICATE_STATUS -------------> Still in CERTIFICATE_CONSUMER
START SERVER_KEY_EXCHANGE_PRODUCER
* <------------- CERTIFICATE_CONSUMER sends bad_certificate alert
* <------------- CLIENT_CLOSES_SOCKET
SERVER_KEY_EXCHANGE_PRODUCER
attempts to write to socket --------||||
(broken_pipe exception)
Server throws a SocketException(broken_pipe) exception instead of SSLHandshakeException(bad_certificate)
```
Up untilJDK-8237578, the issue was masked because SocketExceptions were being wrapped into SSLExceptions.
https://github.com/openjdk/jdk/blob/7ddc2b5606cd5353a3c25dde476ff0e6ccc2ed23/src/java.base/share/classes/sun/security/ssl/ClientHello.java#L1102-L1121
The producers in the loop create and write to the socket. The client receives and starts processing the message immediately. In certain cases, where the network is faster than the computation, the peer can receive the message and respond before the loop of producers are completed. If the peer encounters a fatal condition, it would sends a fatal and closes the socket on its end. The currently running producer is unaware of this case and attempts to write to the socket nonetheless. This will cause the write to fail with a SocketException (Broken Pipe).
Since the host has not attempted to read from the socket, it's unaware that the peer has sent a fatal and closed the socket. It ends up throwing SocketException instead of a SSLHandshakeException.
Example of the Case
```
SERVER CLIENT
* <------------ CLIENT_HELLO
CLIENT_HELLO_CONSUMER
SERVER_HELLO_PRODUCER -------------> SERVER_HELLO_CONSUMER
CERTIFICATE_PRODUCER -------------> CERTIFICATE_CONSUMER
CERTIFICATE_STATUS -------------> Still in CERTIFICATE_CONSUMER
START SERVER_KEY_EXCHANGE_PRODUCER
* <------------- CERTIFICATE_CONSUMER sends bad_certificate alert
* <------------- CLIENT_CLOSES_SOCKET
SERVER_KEY_EXCHANGE_PRODUCER
attempts to write to socket --------||||
(broken_pipe exception)
Server throws a SocketException(broken_pipe) exception instead of SSLHandshakeException(bad_certificate)
```
Up until
- blocks
-
JDK-8259662 Don't wrap SocketExceptions into SSLExceptions in SSLSocketImpl
- Resolved
- relates to
-
JDK-8237578 JDK-8214339 (SSLSocketImpl wraps SocketException) appears to not be fully fixed
- Closed