The Qt v5.15 Community doesn't support OpenSSL 3 by default. You will face some issues at runtime if you attempt to build it with OpenSSL 3. This gist explains how to do it by yourself.
- Apply two attached patches
- Install OpenSSL 3
- Config the Qt with installed OpenSSL like this:
..\configure -prefix h:\mousavi\Qt\5.15.10\win32-msvc2019-x86 -debug-and-release -skip qtwebengine -openssl-runtime OPENSSL_PREFIX="H:\mousavi\OpenSSL-Win32"`
- Make sure that the configure tool is detected the ssl library
...
OpenSSL ................................ yes
Qt Directly linked to OpenSSL ........ no
...
- Build & install the Qt
The Qt v5.15 uses the OpenSSL v1.1 by default, while this version is deprecated and should be replaced with 3. So, I used OpenSSL 3 to build the Qt. The build was successful, but it didn't work at runtime:
qt.network.ssl: QSslSocket: cannot resolve EVP_PKEY_base_id
qt.network.ssl: QSslSocket: cannot resolve SSL_get_peer_certificate
Build version: "OpenSSL 3.1.1 30 May 2023"
Run version: "OpenSSL 3.1.1 30 May 2023"
Supports SSL: true
There is an issue in the Qt issue tracker that deals with this issue.
I found that the issue is already resolved in the commercial version of the Qt. So, I don't have it in the community version.
The assigned engineer gave me a clue about resolving the problem. I reviewed the related sources in Qt v6, and I edited the v5.15 as follow:
Change 1
diff --git a/H:/mosuavi/Qt/src/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h b/H:/mosuavi/Qt/src-modified/qsslsocket_openssl_symbols_p.h
index 95e8897..417d78f 100644
--- a/H:/mosuavi/Qt/src/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h
+++ b/H:/mosuavi/Qt/src-modified/qsslsocket_openssl_symbols_p.h
@@ -237,7 +237,6 @@ Q_AUTOTEST_EXPORT int q_EVP_PKEY_up_ref(EVP_PKEY *a);
EVP_PKEY_CTX *q_EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
void q_EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
int q_EVP_PKEY_param_check(EVP_PKEY_CTX *ctx);
-int q_EVP_PKEY_base_id(EVP_PKEY *a);
int q_RSA_bits(RSA *a);
Q_AUTOTEST_EXPORT int q_OPENSSL_sk_num(OPENSSL_STACK *a);
Q_AUTOTEST_EXPORT void q_OPENSSL_sk_pop_free(OPENSSL_STACK *a, void (*b)(void *));
@@ -383,6 +382,17 @@ const EC_GROUP* q_EC_KEY_get0_group(const EC_KEY* k);
int q_EC_GROUP_get_degree(const EC_GROUP* g);
#endif // OPENSSL_NO_EC
+// Here we have the ones that make difference between OpenSSL pre/post v3:
+#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
+X509 *q_SSL_get1_peer_certificate(SSL *a);
+#define q_SSL_get_peer_certificate q_SSL_get1_peer_certificate
+int q_EVP_PKEY_get_base_id(const EVP_PKEY *pkey);
+#define q_EVP_PKEY_base_id q_EVP_PKEY_get_base_id
+#else
+X509 *q_SSL_get_peer_certificate(SSL *a);
+int q_EVP_PKEY_base_id(EVP_PKEY *a);
+#endif // OPENSSL_VERSION_MAJOR >= 3
+
DSA *q_DSA_new();
void q_DSA_free(DSA *a);
X509 *q_d2i_X509(X509 **a, const unsigned char **b, long c);
@@ -510,7 +520,6 @@ const SSL_CIPHER *q_SSL_get_current_cipher(SSL *a);
int q_SSL_version(const SSL *a);
int q_SSL_get_error(SSL *a, int b);
STACK_OF(X509) *q_SSL_get_peer_cert_chain(SSL *a);
-X509 *q_SSL_get_peer_certificate(SSL *a);
long q_SSL_get_verify_result(const SSL *a);
SSL *q_SSL_new(SSL_CTX *a);
SSL_CTX *q_SSL_get_SSL_CTX(SSL *a);
Change 2
diff --git a/H:/mosuavi/Qt/src/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp b/H:/mosuavi/Qt/src-modified/qsslsocket_openssl_symbols.cpp
index e53fb27..57fd6f8 100644
--- a/H:/mosuavi/Qt/src/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/H:/mosuavi/Qt/src-modified/qsslsocket_openssl_symbols.cpp
@@ -148,7 +148,6 @@ DEFINEFUNC(int, EVP_PKEY_up_ref, EVP_PKEY *a, a, return 0, return)
DEFINEFUNC2(EVP_PKEY_CTX *, EVP_PKEY_CTX_new, EVP_PKEY *pkey, pkey, ENGINE *e, e, return nullptr, return)
DEFINEFUNC(int, EVP_PKEY_param_check, EVP_PKEY_CTX *ctx, ctx, return 0, return)
DEFINEFUNC(void, EVP_PKEY_CTX_free, EVP_PKEY_CTX *ctx, ctx, return, return)
-DEFINEFUNC(int, EVP_PKEY_base_id, EVP_PKEY *a, a, return NID_undef, return)
DEFINEFUNC(int, RSA_bits, RSA *a, a, return 0, return)
DEFINEFUNC(int, DSA_bits, DSA *a, a, return 0, return)
DEFINEFUNC(int, OPENSSL_sk_num, OPENSSL_STACK *a, a, return -1, return)
@@ -371,7 +370,15 @@ DEFINEFUNC(const SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return nullptr
DEFINEFUNC(int, SSL_version, const SSL *a, a, return 0, return)
DEFINEFUNC2(int, SSL_get_error, SSL *a, a, int b, b, return -1, return)
DEFINEFUNC(STACK_OF(X509) *, SSL_get_peer_cert_chain, SSL *a, a, return nullptr, return)
+
+#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
+DEFINEFUNC(X509 *, SSL_get1_peer_certificate, SSL *a, a, return nullptr, return)
+DEFINEFUNC(int, EVP_PKEY_get_base_id, const EVP_PKEY *pkey, pkey, return -1, return)
+#else
DEFINEFUNC(X509 *, SSL_get_peer_certificate, SSL *a, a, return nullptr, return)
+DEFINEFUNC(int, EVP_PKEY_base_id, EVP_PKEY *a, a, return NID_undef, return)
+#endif // OPENSSL_VERSION_MAJOR >= 3
+
DEFINEFUNC(long, SSL_get_verify_result, const SSL *a, a, return -1, return)
DEFINEFUNC(SSL *, SSL_new, SSL_CTX *a, a, return nullptr, return)
DEFINEFUNC(SSL_CTX *, SSL_get_SSL_CTX, SSL *a, a, return nullptr, return)
@@ -868,7 +875,15 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(EVP_PKEY_CTX_new)
RESOLVEFUNC(EVP_PKEY_param_check)
RESOLVEFUNC(EVP_PKEY_CTX_free)
+
+#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
+ RESOLVEFUNC(SSL_get1_peer_certificate)
+ RESOLVEFUNC(EVP_PKEY_get_base_id)
+#else
+ RESOLVEFUNC(SSL_get_peer_certificate)
RESOLVEFUNC(EVP_PKEY_base_id)
+#endif // OPENSSL_VERSION_MAJOR >= 3
+
RESOLVEFUNC(RSA_bits)
RESOLVEFUNC(OPENSSL_sk_new_null)
RESOLVEFUNC(OPENSSL_sk_push)
@@ -1107,7 +1122,6 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(SSL_version)
RESOLVEFUNC(SSL_get_error)
RESOLVEFUNC(SSL_get_peer_cert_chain)
- RESOLVEFUNC(SSL_get_peer_certificate)
RESOLVEFUNC(SSL_get_verify_result)
RESOLVEFUNC(SSL_new)
RESOLVEFUNC(SSL_get_SSL_CTX)
I tried to build Qt 5.15 with OpenSSL v3 again, and this time it works as expected:
Build version: "OpenSSL 3.1.1 30 May 2023"
Run version: "OpenSSL 3.1.1 30 May 2023"
Supports SSL: true