javasslsslengine

SSLEngine Shutdown


The SSLEngine documentation gives indication on how to properly close an SSL connection. More specifically, it gives instructions on how to handle a severed connection:

In addition to orderly shutdowns, there can also be unorderly shutdowns in which the transport link is severed before close messages are exchanged. In the previous examples, the application might get -1 when trying to read or write to the non-blocking SocketChannel. When you get to the end of your input data, you should call engine.closeInbound(), which will verify with the SSLEngine that the remote peer has closed cleanly from the SSL/TLS perspective, and then the application should still try to shutdown cleanly by using the procedure above.

Basically, if the link is severed, engine.closeInbound() should be called. However, the documentation of this closeInbound() method indicates that it will throw an exception if it is called before receiving the proper closing message from peer. It seems to me that if the connection is severed, this close_notify message will never be received, so this method will always throw that exception.

I made the test, made a simple shutdown procedure where is socketChannel.read() returns -1, I call engine.closeInbound() and I indeed get the following exception:

javax.net.ssl.SSLException: Inbound closed before receiving peer's close_notify: possible truncation attack?

What am I missing? Aren't those 2 parts of the documentation in contradiction?


Solution

  • I don't think these two parts of the documentation contradict each other.

    When you get to the end of your input data, you should call engine.closeInbound()

    This applies to both cleanly closed and severed connections. It's when the connection has been severed that the exception will be thrown (i.e. if you call it before having received close_notify). If close_notify was received (or if the connection hasn't even started at all), this exception won't be thrown.

    I'm not quite sure how you've made your simple shutdown test, but you should have sent close_notify from the other end first (with closeOutbound(), for example). In this case, you shouldn't have received -1 from socketChannel.read() before getting close_notify (and you wouldn't get an exception then).

    (Just in case that's of interest, there was a similar question on SSLSocket a while ago.)