OpenSSL/C++: Die SNI-Erweiterung kann nicht in ClientHello angezeigt werden

Ich versuche, eine TLS-Verbindung zu initiieren, und sie muss eine SNI-Erweiterung enthalten. Das folgende Programm funktioniert, erzeugt aber trotz Aufruf von SSL_set_tlsext_host_name keinen SNI-Eintrag im Client-Hello-Paket:

#include <openssl/ssl.h>
#include <openssl/bio.h>

int main()
{
    SSL_CTX* ctx = SSL_CTX_new(TLS_client_method());
    SSL* ssl = SSL_new(ctx);
    BIO* bio = BIO_new_ssl_connect(ctx);
    BIO_set_conn_hostname(bio, "demo.piesocket.com:443");
    SSL_set_tlsext_host_name(ssl, "demo.piesocket.com");
    BIO_do_connect(bio);
    BIO_free_all(bio);
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    return 0;
}

Der folgende Befehl tut es jedoch:

openssl s_client demo.piesocket.com:443

Ich habe beide Austausche mit Wireshark überprüft und die Client-Hello-Pakete unterscheiden sich nur in Abwesenheit/Anwesenheit von SNI. Ja, ich habe mir s_client.c lange und gründlich angesehen, aber es macht zu viele Dinge und ich bin neu bei OpenSSL und TLS. Was vermisse ich?

(Der Kürze halber habe ich alle Überprüfungen aus diesem Beispielcode entfernt, aber es funktioniert, der Server, den ich hier verwende, scheint kein SNI zu erfordern, und die TLS-Verbindung wird tatsächlich in beiden Fällen hergestellt. Der TLS-Teil des Pakets von openssl .exe sieht so aus:

TLSv1.2 Record Layer: Handshake Protocol: Client Hello
    Content Type: Handshake (22)
    Version: TLS 1.0 (0x0301)
    Length: 319
    Handshake Protocol: Client Hello
        Handshake Type: Client Hello (1)
        Length: 315
        Version: TLS 1.2 (0x0303)
        Random: 8772af2a36342435d6b73a0593087c229b67342030d23ae5…
        Session ID Length: 32
        Session ID: 49a1e1b7eb761bd9b279efcb4cac15bae2f09bb92e641a75…
        Cipher Suites Length: 62
        Cipher Suites (31 suites)
        Compression Methods Length: 1
        Compression Methods (1 method)
        Extensions Length: 180
        Extension: server_name (len=23)
        Extension: ec_point_formats (len=4)
        Extension: supported_groups (len=22)
        Extension: session_ticket (len=0)
        Extension: encrypt_then_mac (len=0)
        Extension: extended_master_secret (len=0)
        Extension: signature_algorithms (len=42)
        Extension: supported_versions (len=9)
        Extension: psk_key_exchange_modes (len=2)
        Extension: key_share (len=38)

Das Paket aus dem Programm hat keine Extension: server_name (len=23)-Zeile. OpenSSL-Version 3.0.7, Windows 7, MinGW.)

🤔 А знаете ли вы, что...
C++ был разработан в начале 1980-х годов Бьярном Страуструпом в Bell Labs.


52
1

Antwort:

Gelöst

Sie erstellen eine SSL-BIO über BIO_new_ssl_connect. Dies erstellt im Wesentlichen ein BIO und darin ein neues SSL-Objekt für die Verbindung basierend auf dem SSL_CTX, das Sie übergeben. Völlig getrennt davon erstellen Sie ein anderes SSL-Objekt, legen den SNI-Hostnamen darauf fest und verwenden es dann für nichts - Sie geben es einfach frei.

Erstellen Sie kein separates SSL-Objekt. Holen Sie sich stattdessen das SSL-Objekt in der BIO mit BIO_get_ssl. Legen Sie darauf den SNI-Hostnamen fest.

https://www.openssl.org/docs/man3.0/man3/BIO_get_ssl.html