7

For debugging reasons I want sometimes to capture traffic and analyze it. One option to do that was to configure OpenSSL or boost::asio::ssl to keep the transport untouched. I couldn't find anything in the API.

shoren
  • 931
  • 8
  • 20
  • Note that `boost::asio::ssl::stream` has the same i/o-related interface as `asio:ip::tcp::socket`, so they would be interchangeable in most parts of your code, and you could select `asio:ip::tcp::socket` in run-time or compile-time - either for debug purposes or if needed to switch the encryption off. – Igor R. May 08 '13 at 06:55
  • possible duplicate of [Using SSL sockets and non-SSL sockets simultaneously in Boost.Asio?](http://stackoverflow.com/questions/4720120/using-ssl-sockets-and-non-ssl-sockets-simultaneously-in-boost-asio) – Sam Miller May 08 '13 at 15:58
  • Thank you all for the good answers. I didn't notice the similarity between SSL and non-SSL sockets, and I didn't know Wireshark supports SSL decryption. However, for debugging it is easier for me to disable encryption than to abstract sockets, and the Wireshark solution might not work in case of partially corrupted data. – shoren May 16 '13 at 17:38

2 Answers2

8

If you can configure both ends of your connection you can use a null cipher. When you create your boost::asio::ssl::stream configure it with only ciphers that do not encrypt. This can be done with the OpenSSL API by passing the encapsulated OpenSSL pointer:

boost::asio::ssl::stream<boost::asio::ip::tcp::socket> sslSocket(io, ssl);
SSL_set_cipher_list(sslSocket.native_handle(), "eNULL");
SSL_set_options(sslSocket.native_handle(), SSL_OP_NO_COMPRESSION);

The SSL_set_cipher_list() call sets the allowed ciphers, and "eNULL" matches the ciphers with no encryption (see OpenSSL ciphers). The SSL_set_options() call turns off compression which has nothing to do with encryption but it's easier to view traffic on the wire without compression. SSL_OP_NO_COMPRESSION may only be available with OpenSSL 0.9.9 or later. If you are using an earlier OpenSSL version, this page has a workaround to disable compression. It is sufficient to disable compression on one side of the connection.

eNULL ciphers are never enabled by default so you will need to explicitly configure both ends. If you configure only one end then handshaking will fail. You can set up a simple test server with the OpenSSL s_server command like this:

openssl s_server -accept 8443 -cert server.pem -key server.pem -cipher eNULL

Adding the -debug flag will also dump the protocol and you should be able to see plaintext if your client has compression disabled.

Here's a proof of concept client that will talk to the above s_server command (verify_none mode used for simplicity, upgrade mode to prevent MITM attacks):

#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>

int main() {
   boost::asio::io_service io;

   boost::asio::ssl::context ssl(io,boost::asio::ssl::context::sslv23);
   ssl.set_verify_mode(boost::asio::ssl::context::verify_none);

   boost::asio::ssl::stream<boost::asio::ip::tcp::socket> sslSocket(io, ssl);
   SSL_set_cipher_list(sslSocket.native_handle(), "eNULL");
   SSL_set_options(sslSocket.native_handle(), SSL_OP_NO_COMPRESSION);

   boost::asio::ip::tcp::resolver resolver(io);
   boost::asio::ip::tcp::resolver::query query("localhost", "8443");
   boost::asio::ip::tcp::resolver::iterator endpoint = resolver.resolve(query);
   boost::system::error_code error = boost::asio::error::host_not_found;
   while (error && endpoint != boost::asio::ip::tcp::resolver::iterator())
   {
      sslSocket.lowest_layer().close();
      sslSocket.lowest_layer().connect(*endpoint++, error);
   }

   sslSocket.handshake(boost::asio::ssl::stream_base::client);
   boost::asio::write(sslSocket, boost::asio::buffer("how now brown cow\n"));
   sslSocket.shutdown(error);

   return 0;
}
rhashimoto
  • 15,650
  • 2
  • 52
  • 80
4

I don't know how to tell asio to turn off encryption when using boost::asio::ssl::stream as the socket object. However, I have used Wireshark before to look at the SSL data coming in and going out over the wire. Wireshark provides the capability to add an RSA key file that it uses to decrypt the data and thus ends up displaying the original data in a window.

To specify the key file, bring up Wireshark and select Edit / Preferences to bring up the preferences dialog box. At the bottom of the left hand side of the window, there should be Protocols. Click on that to show all the protocols. Next, select SSL. On the right hand side of the window you should now see an RSA keys list Edit... button. Click on that button to bring up the window to specify the key file. You will need to have the key file, I/P address, and port number for each server or client that you are talking to.

Wireshark can be downloaded from this link.

Bob Bryan
  • 3,687
  • 1
  • 32
  • 45