48

How to implement Server Name Indication(SNI) on OpenSSL in C or C++?

Are there any real world examples available?

jww
  • 97,681
  • 90
  • 411
  • 885
2.8a8a_G
  • 617
  • 1
  • 7
  • 16
  • 2
    Also see [Serving multiple domains in one box with SNI](http://stackoverflow.com/questions/22373332/serving-multiple-domains-in-one-box-with-sni) for some code examples and using `s_client` to test your server. – jww Mar 13 '14 at 15:48

1 Answers1

78

On the client side, you use SSL_set_tlsext_host_name(ssl, servername) before initiating the SSL connection.

On the server side, it's a little more complicated:

  • Set up an additional SSL_CTX() for each different certificate;
  • Add a servername callback to each SSL_CTX() using SSL_CTX_set_tlsext_servername_callback();
  • In the callback, retrieve the client-supplied servername with SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name). Figure out the right SSL_CTX to go with that host name, then switch the SSL object to that SSL_CTX with SSL_set_SSL_CTX().

The s_client.c and s_server.c files in the apps/ directory of the OpenSSL source distribution implement this functionality, so they're a good resource to see how it should be done.

caf
  • 233,326
  • 40
  • 323
  • 462
  • s_client.c and s_server.c are good examples. I am trying to implement SNI on a client who acts as a load generator(network) and hammers a server with http/https requests. And server already has server side SNI implemented. – 2.8a8a_G Feb 28 '11 at 07:09
  • Do the server calls hold up in a multithreaded context? It seems like the SSL_set_SSL_CTX is innately not threadsafe (i.e. if you have two different inbound connections with two different certs, youll have a problem). – chacham15 May 11 '14 at 18:57
  • @chacham15: One way to make it thread-safe is to allocate one `SSL_CTX()` per certificate, per thread (and always handle the same `SSL` and `SSL_CTX` objects from the same thread). The other way is to set thread callbacks with `CRYPTO_set_id_callback()` and `CRYPTO_set_locking_callback()`, in which case OpenSSL will make the right calls to the locking callback to make `SSL_set_SSL_CTX()` thread-safe. – caf May 17 '14 at 07:42
  • That's a very nice high-level write up, thank you! jww has illustrated exactly this approach with a code example in [another answer](http://stackoverflow.com/a/22375715/1613573). Could one or both of you please augment these answers with the issue raised in the comments regarding multiple threads? For example, how is `SSL_set_SSL_CTX` innately not thread safe? It seems to only affect the SSL connection specified in the first argument. – mat Jul 25 '16 at 14:43
  • Do you know how I can implement SNI support on a server using boost::asio as a socket ? I can't find any example.. I also don't see how I can add multiple ssl context, as the ssl socket takes the context in the constructor – Ben D Sep 27 '17 at 12:06