OpenSSL mit KTLS funktioniert auf TX, aber warum wird es auf RX nicht aktiviert?

Ich habe einen Client und einen Server, die SSL_set_fd() verwenden, um einen Handshake für eine bestehende Verbindung zu starten. Grundsätzlich macht der Server:

auto ctx = SSL_CTX_new(TLS_server_method());
SSL_CTX_set_options(ctx, SSL_OP_ENABLE_KTLS);
SSL_CTX_use_certificate_chain_file(ctx, "cert.pem");
SSL_CTX_use_PrivateKey_file(ctx, "priv.pem", SSL_FILETYPE_PEM);
auto ssl = SSL_new(ctx);
SSL_set_fd(ssl, sock);
SSL_accept(ssl);   // client does SSL_connect()
std::cerr << BIO_get_ktls_send(SSL_get_wbio(ssl)) << "\n";
std::cerr << BIO_get_ktls_recv(SSL_get_rbio(ssl)) << "\n";

Ich habe die Fehlerbehandlung und die zusätzliche Zertifikatsprüfung ausgeschlossen, aber meine Frage ist, warum es nur ktls auf TX aktiviert, nicht auf RX. Mit anderen Worten, dies gibt eine 1 und dann eine 0 aus.

Wenn ich strace, sehe ich, dass OpenSSL tatsächlich TLS auf dem Socket aktiviert und es für TX aktiviert:

setsockopt(4, SOL_TCP, TCP_ULP, [7564404], 4) = 0
setsockopt(4, SOL_TLS, TLS_TX, "…algorithm and key material…") = 0

Das ist „tls“ in ganzzahliger Form, wodurch die Möglichkeit besteht, mit der Verwendung von KTLS zu beginnen. Die Nutzung des Kernelmoduls tls wird erhöht, während der Socket geöffnet ist (siehe lsmod | grep tls).

Für TX sieht es so aus, als würde es beide Schritte der Kernel-Dokumentation ausführen, aber warum nicht TLS_RX?

Ich verstehe BIO in OpenSSL nicht wirklich, also vermute ich, dass ich ein BIO anhängen muss, das es aktiviert? Zumindest schließe ich, dass mir ein KTLS-kompatibles BIO beim Lesen dieses Kommentars fehlt. Aber für TX geht es dann auch ohne.

Meine Frage ist: Was füge ich dem oben Gesagten hinzu, damit KTLS für RX "einsetzt"?

Natürlich nehme ich auch alle anderen Änderungsvorschläge an, wie z. B. "Oh, Sie verwenden die alte Oberfläche, das ist besser". Aber obwohl es möglicherweise APIs auf höherer Ebene gibt, ist dies sicherlich auch machbar, indem ich das ändere, was ich bisher habe?

Vielleicht kann ich die Krypto-Parameter aus OpenSSL extrahieren und setsockopt(…… TLX_RX, …) selbst aufrufen? Obwohl es so aussieht, als ob OpenSSL in der Lage sein sollte, es auf tragbarere Weise einzuschalten.

Die OpenSSL-Version ist diejenige, die mit Ubuntu 22.04.1 LTS geliefert wird: 3.0.2-ubuntu1.7. openssl version sagt OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022).

Bei der Überprüfung der apt-get source libssl-dev-Quelle sieht es so aus, als ob sie RX genauso gut unterstützen sollte wie TX.

Sowohl der Client als auch der Server erhalten KTLS auf TX, aber nicht auf RX, daher sollte es nicht sein, dass sie unterschiedliche Algorithmen ausgehandelt haben, von denen nur einer KTLS-kompatibel ist.

uname -a ist Linux myhost 5.15.0-46-generiC#49-Ubuntu SMP Thu Aug 4 18:03:25 UTC 2022 x86_64 x86_64 GNU/Linux


131
1

Antwort:

Gelöst

KTLS auf dem Empfangspfad wurde bis diesem Commit nicht für TLS 1.3 aktiviert, das zum Zeitpunkt dieses Schreibens in keine OpenSSL-Version integriert zu sein scheint (zuletzt 1.1.1 und 3.0.7).

Das Erzwingen der TLS-Version 1.2 aktiviert KTLS sowohl für RX als auch für TX:

SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION);

Nach diesem Fix kehrt das Testprogramm 1 und 1 für TX und RX KTLS zurück.