mardi 21 juin 2016

What is the proper way to securely disconnect an asio SSL socket?


A boost-asio SSL/TLS TCP socket is implemented as an ssl::stream over a tcp::socket:

boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_socket;

In the TLS protocol, a cryptographically secure shutdown involves parties exchanging close_notify messages. Simply closing the lowest layer may make the session vulnerable to a truncation attack.

In boost asio ssl async_shutdown always finishes with an error? @Tanner Sansbury describes the SSL shutdown process in detail with a number of scenarios and proposes using an async_shutdown followed by an async_write to disconnect an SSL stream prior to closing the socket:

ssl_socket.async_shutdown(...);
const char buffer[] = "";
async_write(ssl_socket, buffer, [](...) { ssl_socket.close(); }) 

Performing an async_shutdown on an ssl::stream sends an SSL close_notify message and waits for a response from the other end. The purpose of writing to the stream after the async_shutdown is to be notified when async_shutdown has sent the close_notify so that the socket can be closed without waiting for the response. However, in the current (1.59) version of boost the call to async_write fails...

In How to gracefully shutdown a boost asio ssl client? @maxschlepzig proposes shutting down receiver of the underlying TCP socket:

ssl_socket.lowest_layer()::shutdown(tcp::socket::shutdown_receive);

This produces a short read error, and async_shutdown is called when it's detected in the error handler:

// const boost::system::error_code &ec
if (ec.category() == asio::error::get_ssl_category() &&
  ec.value()    == ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ))
{
  // -> not a real error:
  do_ssl_async_shutdown();
}

Or cancelling the read/write operations on the socket and then calling SSL async shutdown, i.e.:

boost::system::error_code ec;
ssl_socket.cancel(ec);
ssl_socket.async_shutdown([](...) { ssl_socket.close(); };

I'm currently using this last method since it works with the current version of boost.

What is the correct/best way to securely disconnect a boost-asio SSL socket?


Aucun commentaire:

Enregistrer un commentaire