Should I create new SSL_CTX context for every new connection or accept all connections with one context?
It depends on the number of server names and distinct certificates.
If you have one server name and one certificate, then use one default context.
If you have multiple server names and one certificate, then use one default context.
If you have multiple server names and multiple certificate, then see below on the SNI or servername callback and swapping in a context.
If your server listens for foo.com
and bar.com
with distinct certifcates, then you will need three contexts. One default context is for non-SNI clients, one context is for foo.com
, and one context is for bar.com
.
Effectively, the only thing that will likely change between the two sites is the certificate that's served. So you listen with the default context. If the client provided a servername via SNI, then you swap-in one of the other two contexts in the servername callback and SSL_set_SSL_CTX
. Here's how it would look:
static int ServerNameCallback(SSL *ssl, int *ad, void *arg)
{
UNUSED(ad);
UNUSED(arg);
ASSERT(ssl);
if (ssl == NULL)
return SSL_TLSEXT_ERR_NOACK;
const char* servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
ASSERT(servername && servername[0]);
if (!servername || servername[0] == '\0')
return SSL_TLSEXT_ERR_NOACK;
/* Need a certificate and context for this domain */
SSL_CTX* ctx = GetServerContext(servername);
ASSERT(ctx != NULL);
if (ctx == NULL)
return SSL_TLSEXT_ERR_NOACK;
/* We should not be peeking into the object like this... */
ASSERT(ctx != ssl->ctx);
/* Useless return value */
SSL_CTX* v = SSL_set_SSL_CTX(ssl, ctx);
return SSL_TLSEXT_ERR_OK;
}
GetServerContext
just provides the context for foo.com
or bar.com
. It creates them once, and then reuses the same ones.
For the default context, you set the servername callback with SSL_CTX_set_tlsext_servername_callback
. There's no need to set it for non-default contexts.
SSL_CTX_set_tlsext_servername_callback(ctx, ServerNameCallback);
Contexts are referenced counted, so you can reuse them.
Should I do additional actions with memory or something with
start/stop connection, except
close(_socket); //socket which accept the connection
SSL_shutdown(_ssl); //_ssl — SSL connection
SSL_free (_ssl);
Here, you should seek a treatment of the subject. For example, you should not call close
before SSL_shutdown
. And the first call to SSL_shutdown
may fail, so you need to know what to do next.
For a treatment of the subject, see Eric Rescorla's tutorials: An Introduction to OpenSSL Programming, Part I of II and An Introduction to OpenSSL Programming, Part II of II. Or get the book: Network Security with OpenSSL.