C++ 无法使用OpenSSL 1.1.1从ClientHello检索服务器名称(SNI)
在我正在运行的服务器上(使用OpenSSL 1.1.1d),我尝试通过以下回调从ClientHello消息中提取服务器名称(SNI)扩展名:C++ 无法使用OpenSSL 1.1.1从ClientHello检索服务器名称(SNI),c++,ssl,openssl,tls1.2,sni,C++,Ssl,Openssl,Tls1.2,Sni,在我正在运行的服务器上(使用OpenSSL 1.1.1d),我尝试通过以下回调从ClientHello消息中提取服务器名称(SNI)扩展名: 调用SSL\u client\u hello\u get0\u ext,使用中的TLSEXT\u TYPE\u server\u name类型 使用TLSEXT\u NAMETYPE\u host\u name调用SSL\u get\u servername 然而,似乎什么都不起作用,SNI要么是空的,要么是垃圾 我注意到的一件事是,只有在完成Clie
- 调用
,使用中的SSL\u client\u hello\u get0\u ext
类型TLSEXT\u TYPE\u server\u name
- 使用
调用TLSEXT\u NAMETYPE\u host\u name
SSL\u get\u servername
int
my_server::client_hello_cb(SSL *ssl, int *al, void *arg)
{
my_server* server = static_cast<my_server*>(SSL_get_app_data(ssl));
const char *sni = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
server->set_client_sni(sni);
return 0;
}
void
my_server::create()
{
SSL* ssl = SSL_new(ctx_);
SSL_set_app_data(ssl, this);
BIO* rbio = BIO_new(BIO_s_mem());
BIO* wbio = BIO_new(BIO_s_mem());
SSL_set_bio(ssl, rbio, wbio);
SSL_CTX* ctx = SSL_CTX_new(TLS_server_method());
SSL_CTX_set_ecdh_auto(ctx, 1);
SSL_CTX_set_client_hello_cb(ctx, client_hello_cb, nullptr);
}
int
my_server::client_hello_cb(SSL*SSL,int*al,void*arg)
{
my_server*server=static_cast(SSL_get_app_data(SSL));
const char*sni=SSL\u get\u servername(SSL,TLSEXT\u NAMETYPE\u host\u name);
服务器->设置客户端sni(sni);
返回0;
}
无效的
我的服务器::创建()
{
SSL*SSL=SSL_新(ctx_u);
SSL\u set\u app\u数据(SSL,this);
BIO*rbio=BIO_new(BIO_s_mem());
BIO*wbio=BIO_new(BIO_s_mem());
SSL_set_bio(SSL、rbio、wbio);
SSL_CTX*CTX=SSL_CTX_new(TLS_server_method());
SSL\u CTX\u set\u ecdh\u auto(CTX,1);
SSL_CTX_set_client_hello_cb(CTX,client_hello_cb,nullptr);
}
特别感谢您清理了这些东西
必须直接从服务器名称回调调用SSL\u get\u servername
,否则无法解决原始问题
相反,可以使用
SSL\u client\u hello\u get0\u ext直接从客户端hello回调手动解析服务器名称扩展名。请为您的问题提供解决方案。由于它的行为与OpenSSL测试代码不同,这表明您的代码中存在一些本质的不同之处。@SteffenUllrich很遗憾,我无法共享源代码。但是,主流程是在我的服务器上注册到“SSL\u CTX\u set\u client\u hello\u cb”,并在调用回调时调用“SSL\u get\u servername”(返回null)。EDI没有要求您共享原始源代码。事实上,这可能是太多的代码无法查看。相反,我要求您创建一些最小的代码示例,其他人可以使用这些示例来重现问题。一种常见的方法是将原始代码剥离到再现问题所需的最低限度。另一种方法是根据您在问题中的描述创建一些最小的代码-如果这还不足以重新创建问题,则您的问题缺少基本的细节。@SteffenUllrich添加了一些演示基本流程的代码示例,希望它可能会有所帮助可能是因为SSL\u get\u servername
在clienthello回调中不起作用,因为它更适合稍后出现的(过时的)tlsext\u servername\u回调。但是您特别提到的是SSL\u client\u hello\u get0\u ext
即使在OpenSSL测试代码中使用了它,也无法工作。请在示例代码中使用它,并提供关于它返回的声明“垃圾”的更多详细信息。