Visitar URL original
createSocket with consumed InputStream and com.sun.net.ssl.requireCloseNotify throws SocketException · Issue #2142 · bcgit/bc-java · GitHub
Skip to content

createSocket with consumed InputStream and com.sun.net.ssl.requireCloseNotify throws SocketException #2142

Description

@ulrokx

When the createSocket factory method is used with a non-null InputStream consumed argument, a SequenceInputStream is created. One consideration with using SequenceInputStream is the following

After each input stream from the enumeration is exhausted, it is closed by calling its close method.

https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/SequenceInputStream.html

If a client opens a connection, handshakes successfully, writes some data, then closes the connection without sending close_notify, this will typically result in a TlsNoCloseNotifyException being thrown. If the com.sun.net.ssl.requireCloseNotify is set to false, then instead we send our own close_notify. If this property is used in combination with the InputStream consumed argument, BC will try to write to a closed socket and throw a SocketException

java.net.SocketException: Socket closed
sun.nio.ch.NioSocketImpl.ensureOpenAndConnected (NioSocketImpl.java:165)
sun.nio.ch.NioSocketImpl.beginWrite (NioSocketImpl.java:371)
sun.nio.ch.NioSocketImpl.implWrite (NioSocketImpl.java:416)
sun.nio.ch.NioSocketImpl.write (NioSocketImpl.java:445)
sun.nio.ch.NioSocketImpl$2.write (NioSocketImpl.java:831)
java.net.Socket$SocketOutputStream.write (Socket.java:1035)
org.bouncycastle.tls.RecordStream.writeRecord (RecordStream.java:309)
org.bouncycastle.tls.TlsProtocol.safeWriteRecord (TlsProtocol.java:950)
org.bouncycastle.tls.TlsProtocol.raiseAlertWarning (TlsProtocol.java:1721)
org.bouncycastle.tls.TlsProtocol.handleClose (TlsProtocol.java:300)
org.bouncycastle.tls.TlsProtocol.safeReadRecord (TlsProtocol.java:891)
org.bouncycastle.tls.TlsProtocol.readApplicationData (TlsProtocol.java:842)
org.bouncycastle.jsse.provider.ProvSSLSocketWrap$AppDataInput.read (ProvSSLSocketWrap.java:801)
java.io.SequenceInputStream.read (SequenceInputStream.java:198)
java.io.BufferedInputStream.fill (BufferedInputStream.java:244)
java.io.BufferedInputStream.read1 (BufferedInputStream.java:284)
java.io.BufferedInputStream.read (BufferedInputStream.java:343)

Activity

  1. peterdettman commented on Aug 7, 2025

    @peterdettman
    Collaborator

    I don't think the SequenceInputStream is relevant here.

    I see: client connects, handshakes, and then at some point fails to read next application data record -> server has closed the connection, in this case without sending close_notify alert. Since client has configured to not requireCloseNotify it ignores this and continues to handleClose.

    Usual close handling includes trying to send a close_notify alert ourselves, which often fails if the socket is fully closed.

    So the issue seems to be that a SocketException when trying to send our close_notify should probably be caught and ignored (at least in the reactive case, perhaps always).

    Possibly we should not even try to send the close_notify if we are reacting to a peer closure that didn't send one, but it seems better to try, so long as the exception is ignored.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions