THRIFT-6174: Fix TSSLSocket build with OpenSSL 4.0 - #3752
Conversation
03d0ac3 to
af482d1
Compare
af482d1 to
29e962e
Compare
|
This branch has conflicts that must be resolved |
|
Is it expected that SecurityTest and SecurityFromBufferTest both hang/timeout with OpenSSL 4.0.2 and the test expectations will be changed in a future pull request?
|
OpenSSL 4.0 removes SSLv3_method(), per-version TLS method functions, ERR_remove_state(), ASN1_STRING_data(), and returns const pointers from X509 accessor functions. Fix both C++ and C GLib bindings. Upstream-Status: Submitted [apache/thrift#3752] Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
29e962e to
e949922
Compare
Done. rebased and please check |
Thanks for the feedback! Updated the PR:
I haven't been able to run the SecurityTest/SecurityFromBufferTest locally — if there are still test timeouts, happy to iterate. |
|
Thank you for working on this. There are still timeouts which I was able to fix with: --- a/lib/cpp/test/SecurityFromBufferTest.cpp
+++ b/lib/cpp/test/SecurityFromBufferTest.cpp
@@ -229,7 +229,7 @@ BOOST_AUTO_TEST_CASE(ssl_security_matrix) {
continue;
}
-#ifdef OPENSSL_NO_SSL3
+#if defined(OPENSSL_NO_SSL3) || OPENSSL_VERSION_NUMBER >= 0x40000000L
if (si == 2 || ci == 2) {
// Skip all SSLv3 cases - protocol not supported
continue;
diff --git a/lib/cpp/test/SecurityTest.cpp b/lib/cpp/test/SecurityTest.cpp
index 86640bd68..b133ef0f8 100644
--- a/lib/cpp/test/SecurityTest.cpp
+++ b/lib/cpp/test/SecurityTest.cpp
@@ -357,7 +357,7 @@ BOOST_AUTO_TEST_CASE(ssl_security_matrix)
continue;
}
-#ifdef OPENSSL_NO_SSL3
+#if defined(OPENSSL_NO_SSL3) || OPENSSL_VERSION_NUMBER >= 0x40000000L
if (si == 2 || ci == 2)
{
// Skip all SSLv3 cases - protocol not supportedAll tests then pass for C and C++ however I believe that is due to lack of coverage in testtransportsslsocket.c compared to SecurityTest.cpp for SSLv3/TLSv1_0/TLSv1_1. I think the C code needs SSL_CTX_set_min_proto_version() / SSL_CTX_set_max_proto_version() to match the C++ code. |
OpenSSL 4.0 removes SSLv3_method(), per-version TLS method functions, ERR_remove_state(), ASN1_STRING_data(), and returns const pointers from X509 accessor functions. C++ (TSSLSocket.cpp): - Remove ERR_remove_state() calls (no-op since OpenSSL 1.1) - Guard SSLv3_method with version check - Use TLS_method() + SSL_CTX_set_min/max_proto_version() for TLSv1.0/1.1/1.2 on OpenSSL 4.0 (per-version methods removed) - Replace ASN1_STRING_data with ASN1_STRING_get0_data - Add const qualifiers for X509_NAME, X509_NAME_ENTRY, ASN1_STRING C (thrift_ssl_socket.c): - Remove ERR_remove_state() calls - Guard SSLv3 and TLS version methods with version check Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech>
e949922 to
53ba61e
Compare
|
This additional patch adds SSL_CTX_set_min_proto_version and SSL_CTX_set_max_proto_version use to the C bindings matching the C++ bindings and adds unit tests for the C bings for SSL3, TLSv1, TLSv1.1, TLSv1.2 it does not check the result of SSL_CTX_set_min_proto_version or SSL_CTX_set_max_proto_version as @FinnRG's patch does to match the current PR. diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.c b/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.c
index b734ec914..4987018b2 100644
--- a/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.c
+++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.c
@@ -833,12 +833,25 @@ thrift_ssl_socket_context_initialize(ThriftSSLSocketProtocol ssl_protocol, GErro
case SSLTLS:
context = SSL_CTX_new(SSLv23_method());
break;
-#if OPENSSL_VERSION_NUMBER < 0x40000000L
-#ifndef OPENSSL_NO_SSL3
+#if !defined(OPENSSL_NO_SSL3) && OPENSSL_VERSION_NUMBER < 0x40000000L
case SSLv3:
context = SSL_CTX_new(SSLv3_method());
break;
#endif
+#if OPENSSL_VERSION_NUMBER >= 0x40000000L
+ case TLSv1_0:
+ case TLSv1_1:
+ case TLSv1_2:
+ context = SSL_CTX_new(TLS_method());
+ if (context != NULL) {
+ int ver = (ssl_protocol == TLSv1_0) ? TLS1_VERSION
+ : (ssl_protocol == TLSv1_1) ? TLS1_1_VERSION
+ : TLS1_2_VERSION;
+ SSL_CTX_set_min_proto_version(context, ver);
+ SSL_CTX_set_max_proto_version(context, ver);
+ }
+ break;
+#else
case TLSv1_0:
context = SSL_CTX_new(TLSv1_method());
break;
@@ -848,7 +861,7 @@ thrift_ssl_socket_context_initialize(ThriftSSLSocketProtocol ssl_protocol, GErro
case TLSv1_2:
context = SSL_CTX_new(TLSv1_2_method());
break;
-#endif /* OPENSSL_VERSION_NUMBER < 0x40000000L */
+#endif
default:
g_set_error (error, THRIFT_TRANSPORT_ERROR,
THRIFT_SSL_SOCKET_ERROR_CIPHER_NOT_AVAILABLE,
diff --git a/lib/c_glib/test/CMakeLists.txt b/lib/c_glib/test/CMakeLists.txt
index 4f60473b2..205390389 100644
--- a/lib/c_glib/test/CMakeLists.txt
+++ b/lib/c_glib/test/CMakeLists.txt
@@ -68,6 +68,12 @@ add_executable(testtransportsocket testtransportsocket.c)
target_link_libraries(testtransportsocket thrift_c_glib)
add_test(NAME testtransportsocket COMMAND testtransportsocket)
+if(OPENSSL_FOUND AND WITH_OPENSSL)
+ add_executable(testtransportsslsocket testtransportsslsocket.c)
+ target_link_libraries(testtransportsslsocket thrift_c_glib)
+ add_test(NAME testtransportsslsocket COMMAND testtransportsslsocket)
+endif()
+
add_executable(testbinaryprotocol testbinaryprotocol.c)
target_link_libraries(testbinaryprotocol thrift_c_glib)
add_test(NAME testbinaryprotocol COMMAND testbinaryprotocol)
diff --git a/lib/c_glib/test/testtransportsslsocket.c b/lib/c_glib/test/testtransportsslsocket.c
index ba9ffdcae..ec0b86e2a 100644
--- a/lib/c_glib/test/testtransportsslsocket.c
+++ b/lib/c_glib/test/testtransportsslsocket.c
@@ -514,6 +514,65 @@ thrift_socket_server (const int port)
g_object_unref (client);
}
+static void
+test_ssl_context_for_ssl_tls(void)
+{
+ GError *error = NULL;
+ SSL_CTX *ctx = thrift_ssl_socket_context_initialize(SSLTLS, &error);
+ g_assert (ctx != NULL);
+ g_assert_no_error (error);
+ SSL_CTX_free(ctx);
+}
+
+static void
+test_ssl_context_for_sslv3(void)
+{
+ GError *error = NULL;
+ SSL_CTX *ctx = thrift_ssl_socket_context_initialize(SSLv3, &error);
+#if defined(OPENSSL_NO_SSL3) || OPENSSL_VERSION_NUMBER >= 0x40000000L
+ if (ctx == NULL) {
+ g_assert (error != NULL);
+ g_clear_error (&error);
+ } else {
+ SSL_CTX_free(ctx);
+ }
+#else
+ g_assert (ctx != NULL);
+ g_assert_no_error (error);
+ SSL_CTX_free(ctx);
+#endif
+}
+
+static void
+test_ssl_context_for_tlsv1_0(void)
+{
+ GError *error = NULL;
+ SSL_CTX *ctx = thrift_ssl_socket_context_initialize(TLSv1_0, &error);
+ g_assert (ctx != NULL);
+ g_assert_no_error (error);
+ SSL_CTX_free(ctx);
+}
+
+static void
+test_ssl_context_for_tlsv1_1(void)
+{
+ GError *error = NULL;
+ SSL_CTX *ctx = thrift_ssl_socket_context_initialize(TLSv1_1, &error);
+ g_assert (ctx != NULL);
+ g_assert_no_error (error);
+ SSL_CTX_free(ctx);
+}
+
+static void
+test_ssl_context_for_tlsv1_2(void)
+{
+ GError *error = NULL;
+ SSL_CTX *ctx = thrift_ssl_socket_context_initialize(TLSv1_2, &error);
+ g_assert (ctx != NULL);
+ g_assert_no_error (error);
+ SSL_CTX_free(ctx);
+}
+
int
main(int argc, char *argv[])
{
@@ -530,6 +591,11 @@ main(int argc, char *argv[])
g_test_add_func ("/testtransportsslsocket/CreateAndSetProperties", test_ssl_create_and_set_properties);
g_test_add_func ("/testtransportsslsocket/OpenAndCloseNonSSLServer", test_ssl_open_and_close_non_ssl_server);
g_test_add_func ("/testtransportsslsocket/OpenAndWriteInvalidSocket", test_ssl_write_invalid_socket);
+ g_test_add_func ("/testtransportsslsocket/ContextForSSLTLS", test_ssl_context_for_ssl_tls);
+ g_test_add_func ("/testtransportsslsocket/ContextForSSLv3", test_ssl_context_for_sslv3);
+ g_test_add_func ("/testtransportsslsocket/ContextForTLSv1_0", test_ssl_context_for_tlsv1_0);
+ g_test_add_func ("/testtransportsslsocket/ContextForTLSv1_1", test_ssl_context_for_tlsv1_1);
+ g_test_add_func ("/testtransportsslsocket/ContextForTLSv1_2", test_ssl_context_for_tlsv1_2);
diff --git a/lib/cpp/test/SecurityFromBufferTest.cpp b/lib/cpp/test/SecurityFromBufferTest.cpp
index 08f76b3f2..3df15106e 100644
--- a/lib/cpp/test/SecurityFromBufferTest.cpp
+++ b/lib/cpp/test/SecurityFromBufferTest.cpp
@@ -229,7 +229,7 @@ BOOST_AUTO_TEST_CASE(ssl_security_matrix) {
continue;
}
-#ifdef OPENSSL_NO_SSL3
+#if defined(OPENSSL_NO_SSL3) || OPENSSL_VERSION_NUMBER >= 0x40000000L
if (si == 2 || ci == 2) {
// Skip all SSLv3 cases - protocol not supported
continue;
diff --git a/lib/cpp/test/SecurityTest.cpp b/lib/cpp/test/SecurityTest.cpp
index 86640bd68..b133ef0f8 100644
--- a/lib/cpp/test/SecurityTest.cpp
+++ b/lib/cpp/test/SecurityTest.cpp
@@ -357,7 +357,7 @@ BOOST_AUTO_TEST_CASE(ssl_security_matrix)
continue;
}
-#ifdef OPENSSL_NO_SSL3
+#if defined(OPENSSL_NO_SSL3) || OPENSSL_VERSION_NUMBER >= 0x40000000L
if (si == 2 || ci == 2)
{
// Skip all SSLv3 cases - protocol not supported |
| if (ctx_) { | ||
| int ver = (protocol == TLSv1_0) ? TLS1_VERSION : (protocol == TLSv1_1) ? TLS1_1_VERSION : TLS1_2_VERSION; | ||
| SSL_CTX_set_min_proto_version(ctx_, ver); | ||
| SSL_CTX_set_max_proto_version(ctx_, ver); |
There was a problem hiding this comment.
The result is not checked. On failure the context should be released and ctx_ set to null then either a new error thrown or it could then be managed by the existing check for ctx_ being a nullptr.


OpenSSL 4.0 removes SSLv3_method() and per-version TLS method functions (TLSv1_method, TLSv1_1_method, TLSv1_2_method), the deprecated ASN1_STRING_data() function, and returns const pointers from X509_get_subject_name(), X509_NAME_get_entry(), and X509_NAME_ENTRY_get_data().
This is backward-compatible with OpenSSL >= 1.1.0 since all replacement APIs exist since that version.
[skip ci]anywhere in the commit message to free up build resources.