4

I want to get multiple connections with OpenSSL.

  1. Should I create new SSL_CTX context for every new connection or accept all connections with one context?

  2. 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);
    
jww
  • 97,681
  • 90
  • 411
  • 885
Vlad
  • 1,541
  • 1
  • 21
  • 27
  • Related, see [Does OpenSSL allow multiple SSL_CTX per process, one SSL_CTX used for server sessions and the other SSL_CTX for client sessions?](http://stackoverflow.com/q/27649641). – jww Jun 01 '15 at 02:00

1 Answers1

6

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.

jww
  • 97,681
  • 90
  • 411
  • 885