6

For example, I develope email client. I know that some servers, for example, imap.gmail.com, cache SSL sessions. So I want reuse SSL sessions (from cache on my side) to reduce server load.

I use boost::asio as network engine. Questions are:

  1. if boost::asio::ssl::stream doesn't use the ssl-session-cache, how can I enable it?
  2. if boost::asio::ssl::stream use the ssl-session-cache, how can I turn it off? :)
o2gy
  • 333
  • 1
  • 13
  • I think it's due to the ssl_context: http://stackoverflow.com/a/35136363/85371 – sehe Mar 28 '16 at 11:17
  • 1
    @sehe, thank you, it's very helpful. I have understood, that I need use `ssl::context::native_handle()` + `SSL_CTX_set_session_cache_mode()` + `SSL_set_session()` and so on. I will try ) – o2gy Mar 28 '16 at 20:19

1 Answers1

4

boost::asio does not support ssl-session caching mechanism directly. But, as boost::asio::ssl::stream keeps SSL_SESSION object (from the openssl library) inside, it is easy to do manually.

An implementation could be as follows:

boost::asio::io_service io;
boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23_client);
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> backend(io, ctx); 

// need some object that will store the cache
std::map<std::string, SSL_SESSION*> ssl_cache;

// add session to the cache after a successful connection
SSL_SESSION *session = SSL_get1_session(backend.native_handle());
ssl_cache[host] = session;

// before a new connection to the 'host', check the cache
auto cached_session = ssl_cache.find(host);
if (cached_session != ssl_cache.end())
{
    SSL_SESSION *session = cached_session->second;
    SSL_set_session(backend.native_handle(), session);
}

// after a connection can check if ssl-session was reused
if (SSL_session_reused(backend.native_handle()))
{
    // reused
}

It is important that this approach supports both caching mechanism:

  • ssl-tickets (RFC 5077)
  • session identifiers (RFC 5246)
o2gy
  • 333
  • 1
  • 13
  • I'm confused where to put this. I have an app pretty much modelled after [http_server_async_ssl.cpp](https://www.boost.org/doc/libs/1_72_0/libs/beast/example/http/server/async-ssl/http_server_async_ssl.cpp), do you know where I'd put this? I thought I could call `SSL_set_session` right before `Session::on_handshake` is called, but it's not working. I've tried a few other places too to no avail. – Matt Feb 28 '20 at 21:18
  • @Matt, hi, this question (and answer) was about clients, not about servers. Your example by the link - it's a server. Sorry, I don't know how exactly enable caching support on SSL-server, but I thik you should look on direct settings your ssl-library. – o2gy Mar 03 '20 at 11:35
  • 1
    Okay, thanks anyways. I did find my answer though (in case any one also falls on this page with a similar question), turns out I needed to call [SSL_CTX_set_session_id_context](https://www.openssl.org/docs/man1.0.2/man3/SSL_CTX_set_session_id_context.html), and I was only seeing the problem when `Keep-Alive` was false (which is why I didn't see it in testing, but did in production.) I implemented it into my [minimal example](https://github.com/kheaactua/boost_ssl_async_example/blob/93bdc8a28c1723e31572240cedb270ffacca215e/ex/CertificateHelper.cpp#L386) – Matt Mar 03 '20 at 15:19