c++ - SSL_CTX_set_tlsext_servername_callback 回调函数未被调用

标签 c++ c ssl openssl

我正在编写一个 https 服务器,我需要在使用 SNI 的 ssl_accept() 之前从客户端获取主机名。我正在使用 SSL_CTX_set_tlsext_servername_callback() 来接收主机名,但根本没有调用回调。这是我的部分代码

// Server Name Indication callback from OpenSSL
static int serverNameCallback(SSL *ssl, int *ad, void *arg) 
{
    if (ssl == NULL)
        return SSL_TLSEXT_ERR_NOACK;

    const char* servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
    printf("ServerName: %s\n", servername);
}

int main()
{
    //some code 
    const SSL_METHOD *method;
    SSL_CTX *ctx;

    method = SSLv3_server_method();  
    ctx = SSL_CTX_new(method);   
    if ( ctx == NULL )
    { 
        printf("SSL_ctx_new() error\n");
    }

    int ret = SSL_CTX_set_tlsext_servername_callback(ctx, serverNameCallback);
}

最佳答案

I am writing a https server and i need to get host name from client before ssl_accept() using SNI.

您不调用 SSL_CTX_set_tlsext_servername_callback。 OpenSSL 库将在握手期间为您调用它。

您的 SNI 回调不会为 SSLv2 和 SSLv3 客户端调用。那是因为 SNI 是 TLS 扩展。

如果客户端是 Windows XP(或不使用 TLS 扩展的类似系统),那么将调用您的 SNI 回调,但 servername 将为 NULL .在这种情况下,您应该使用默认的服务器上下文。

如果客户端使用 TLS 并发送服务器名称,那么将调用您的 SNI 回调。在回调中,您应该 (1) 确定默认证书和上下文是否正常。如果成功,则返回 SSL_TLSEXT_ERR_OK。 (2) 如果您能提供更合适的证书,则使用SSL_set_SSL_CTX 交换新的上下文并返回SSL_TLSEXT_ERR_OK

如果遇到错误(如 NULL servername),则应返回 SSL_TLSEXT_ERR_NOACK。您可以返回另外两个错误代码。两者对连接都是致命的,IIRC。

回调的实现细节在 Serving multiple domains in one box with SNI 中给出。 .

关于c++ - SSL_CTX_set_tlsext_servername_callback 回调函数未被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22607121/

相关文章:

ASP.net WebRequest 内部 SSL 协议(protocol)?

c - 使用指针代替数组

c++ - 使用自动 : where can it be useful? 公开私有(private)类型

c++ - 用 C++ 编写 Haskell 解释器(使用 ghc 或 hugs 作为库)

c++ - 如何找出 C++ 中的当前字符集?

c - 在 C 中的非堆对象上使用 free()

在c中找不到这个合并排序程序的错误..总是显示段错误

apache - 从 HTTP 到 HTTPS 的代理传递失败,网关错误 "502"

winapi - 在 CertAddEncodedCertificateToSystemStore 对面从 Windows 证书存储中获取 ASN1 证书?

c++ - 使用 -std=gnu++11 时发现了哪些已知的性能差异