与 OpenSSL 的多个连接的上下文

Context for multiple connections with OpenSSL

我想通过 OpenSSL 建立多个连接。

  1. 我应该为每个新连接创建新的 SSL_CTX context 还是接受一个 context 的所有连接?

  2. 除了

    之外,我是否应该使用内存或具有 start/stop 连接的其他操作来执行其他操作
    close(_socket); //socket which accept the connection
    SSL_shutdown(_ssl); //_ssl — SSL connection
    SSL_free (_ssl);
    

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

这取决于服务器名称和不同证书的数量。

如果您有一个服务器名称和一个证书,则使用一个默认上下文。

如果您有多个服务器名称和一个证书,则使用一个默认上下文。

如果您有多个服务器名称和多个证书,请参阅下面的 SNI 或服务器名称回调和上下文交换。


如果您的服务器使用不同的证书侦听 foo.combar.com,那么您将需要三个上下文。一种默认上下文用于非 SNI 客户端,一种上下文用于 foo.com,一种上下文用于 bar.com.

实际上,两个站点之间唯一可能发生变化的是所提供的证书。因此,您使用默认上下文进行收听。 如果 客户端通过 SNI 提供了服务器名称,那么您可以在服务器名称回调和 SSL_set_SSL_CTX 中换入其他两个上下文之一。它的外观如下:

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] == '[=10=]')
        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 只是为 foo.combar.com 提供上下文。它创建一次,然后重复使用相同的。

对于默认上下文,您使用 SSL_CTX_set_tlsext_servername_callback 设置服务器名称回调。无需为非默认上下文设置它。

SSL_CTX_set_tlsext_servername_callback(ctx, ServerNameCallback);

上下文被引用计数,因此您可以重复使用它们。


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);

在这里,你应该寻求对这个问题的治疗。例如,您不应在 SSL_shutdown 之前调用 close。第一次调用 SSL_shutdown 可能会失败,因此您需要知道下一步该怎么做。

有关主题的处理,请参阅 Eric Rescorla 的教程: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