与 OpenSSL 的多个连接的上下文

Vla*_*lav 4 c connection ssl openssl

我想与 OpenSSL 建立多个连接。

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

  2. 我是否应该对内存或启动/停止连接执行其他操作,除了

    close(_socket); //socket which accept the connection
    SSL_shutdown(_ssl); //_ssl — SSL connection
    SSL_free (_ssl);
    
    Run Code Online (Sandbox Code Playgroud)

jww*_*jww 5

我应该为每个新连接创建新的 SSL_CTX 上下文还是接受具有一个上下文的所有连接?

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

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

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

如果您有多个服务器名称和多个证书,请参阅下面的 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] == '\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;
}
Run Code Online (Sandbox Code Playgroud)

GetServerContext只提供foo.comor的上下文bar.com。它创建一次,然后重用相同的。

对于默认上下文,您使用SSL_CTX_set_tlsext_servername_callback. 无需为非默认上下文设置它。

SSL_CTX_set_tlsext_servername_callback(ctx, ServerNameCallback);
Run Code Online (Sandbox Code Playgroud)

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


我是否应该对内存或启动/停止连接执行其他操作,除了

close(_socket); //socket which accept the connection
SSL_shutdown(_ssl); //_ssl — SSL connection
SSL_free (_ssl);
Run Code Online (Sandbox Code Playgroud)

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

有关该主题的处理,请参阅 Eric Rescorla 的教程:OpenSSL 编程简介,II 的第一部分OpenSSL 编程简介,II 的第二部分。或者获取这本书:使用 OpenSSL 的网络安全