On my running server (using OpenSSL 1.1.1d) I tried extracting the Server Name (SNI) extension from ClientHello messages using the following callback API by:
SSL_client_hello_get0_ext
with the TLSEXT_TYPE_server_name
type as done in the repo.SSL_get_servername
with TLSEXT_NAMETYPE_host_name
as documented.Yet nothing seems to work, the SNI is either NULL or garbage.
One thing that I noticed was that only after finishing the ClientHello callback I was able to extract it, but at that point it's too late. Has someone encountered a similar issue?
Attaching below a minimal code sample demonstrating how I retrieve the SNI:
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);
}
Special thanks to Steffen for clearing stuff out.
The SSL_get_servername
must be called directly from the server name callback, therfore not solving the original issue.
Instead, the server name extension can be parsed manually (as done here) using SSL_client_hello_get0_ext
directly from the client hello callback.