summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2019-06-25 11:17:32 +0200
committerLiang Qi <liang.qi@qt.io>2019-06-25 13:04:27 +0200
commitef37ab9970ffb9347bc95a3e6006de956c0155c9 (patch)
tree4c6afb6d232c6ed8aab732763ef895e8bd85ec55 /src/network
parent79bdc7cf1daec75df59de9236599a9f24077511a (diff)
parent5b5e8f78fecbe2bd9279bfa9ef10015cef8b1bc7 (diff)
Merge remote-tracking branch 'origin/5.12' into dev
Conflicts: .qmake.conf src/gui/painting/qdrawhelper.cpp src/gui/text/qdistancefield.cpp src/gui/text/qdistancefield_p.h src/network/ssl/qsslsocket_openssl.cpp src/plugins/platforms/android/qandroidinputcontext.cpp src/widgets/styles/qstylesheetstyle.cpp Done-With: Timur Pocheptsov <timur.pocheptsov@qt.io> Change-Id: Ia7daad21f077ea889898f17734ec46303e71fe6b
Diffstat (limited to 'src/network')
-rw-r--r--src/network/bearer/qnetworkconfigmanager.cpp27
-rw-r--r--src/network/bearer/qnetworksession.cpp3
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp189
-rw-r--r--src/network/ssl/qsslsocket_openssl11_symbols_p.h8
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp12
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols_p.h1
-rw-r--r--src/network/ssl/qsslsocket_opensslpre11_symbols_p.h2
7 files changed, 155 insertions, 87 deletions
diff --git a/src/network/bearer/qnetworkconfigmanager.cpp b/src/network/bearer/qnetworkconfigmanager.cpp
index 81b5e01d6a..cd87c3669c 100644
--- a/src/network/bearer/qnetworkconfigmanager.cpp
+++ b/src/network/bearer/qnetworkconfigmanager.cpp
@@ -233,19 +233,20 @@ QNetworkConfigurationManager::QNetworkConfigurationManager(QObject *parent)
: QObject(parent)
{
QNetworkConfigurationManagerPrivate *priv = qNetworkConfigurationManagerPrivate();
-
- connect(priv, SIGNAL(configurationAdded(QNetworkConfiguration)),
- this, SIGNAL(configurationAdded(QNetworkConfiguration)));
- connect(priv, SIGNAL(configurationRemoved(QNetworkConfiguration)),
- this, SIGNAL(configurationRemoved(QNetworkConfiguration)));
- connect(priv, SIGNAL(configurationChanged(QNetworkConfiguration)),
- this, SIGNAL(configurationChanged(QNetworkConfiguration)));
- connect(priv, SIGNAL(onlineStateChanged(bool)),
- this, SIGNAL(onlineStateChanged(bool)));
- connect(priv, SIGNAL(configurationUpdateComplete()),
- this, SIGNAL(updateCompleted()));
-
- priv->enablePolling();
+ if (priv) {
+ connect(priv, SIGNAL(configurationAdded(QNetworkConfiguration)),
+ this, SIGNAL(configurationAdded(QNetworkConfiguration)));
+ connect(priv, SIGNAL(configurationRemoved(QNetworkConfiguration)),
+ this, SIGNAL(configurationRemoved(QNetworkConfiguration)));
+ connect(priv, SIGNAL(configurationChanged(QNetworkConfiguration)),
+ this, SIGNAL(configurationChanged(QNetworkConfiguration)));
+ connect(priv, SIGNAL(onlineStateChanged(bool)),
+ this, SIGNAL(onlineStateChanged(bool)));
+ connect(priv, SIGNAL(configurationUpdateComplete()),
+ this, SIGNAL(updateCompleted()));
+
+ priv->enablePolling();
+ }
}
/*!
diff --git a/src/network/bearer/qnetworksession.cpp b/src/network/bearer/qnetworksession.cpp
index 471d322998..1636bcee97 100644
--- a/src/network/bearer/qnetworksession.cpp
+++ b/src/network/bearer/qnetworksession.cpp
@@ -258,7 +258,8 @@ QNetworkSession::QNetworkSession(const QNetworkConfiguration &connectionConfig,
// invalid configuration
if (!connectionConfig.identifier().isEmpty()) {
- const auto engines = qNetworkConfigurationManagerPrivate()->engines();
+ auto priv = qNetworkConfigurationManagerPrivate();
+ const auto engines = priv ? priv->engines() : QList<QBearerEngine *>();
for (QBearerEngine *engine : engines) {
if (engine->hasIdentifier(connectionConfig.identifier())) {
d = engine->createSessionBackend();
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 3927a592cb..d4bad1b1a5 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -71,6 +71,10 @@
#include "qwindowscarootfetcher_p.h"
#endif
+#if !QT_CONFIG(opensslv11)
+#include <openssl/x509_vfy.h>
+#endif
+
#include <QtCore/qdatetime.h>
#include <QtCore/qdebug.h>
#include <QtCore/qdir.h>
@@ -137,6 +141,55 @@ static unsigned int q_ssl_psk_server_callback(SSL *ssl,
Q_ASSERT(d);
return d->tlsPskServerCallback(identity, psk, max_psk_len);
}
+
+#ifdef TLS1_3_VERSION
+#ifndef OPENSSL_NO_PSK
+static unsigned int q_ssl_psk_restore_client(SSL *ssl,
+ const char *hint,
+ char *identity, unsigned int max_identity_len,
+ unsigned char *psk, unsigned int max_psk_len)
+{
+ Q_UNUSED(hint);
+ Q_UNUSED(identity);
+ Q_UNUSED(max_identity_len);
+ Q_UNUSED(psk);
+ Q_UNUSED(max_psk_len);
+
+#ifdef QT_DEBUG
+ QSslSocketBackendPrivate *d = reinterpret_cast<QSslSocketBackendPrivate *>(q_SSL_get_ex_data(ssl, QSslSocketBackendPrivate::s_indexForSSLExtraData));
+ Q_ASSERT(d);
+ Q_ASSERT(d->mode == QSslSocket::SslClientMode);
+#endif
+ q_SSL_set_psk_client_callback(ssl, &q_ssl_psk_client_callback);
+
+ return 0;
+}
+#endif // !OPENSSL_NO_PSK
+
+static int q_ssl_psk_use_session_callback(SSL *ssl, const EVP_MD *md, const unsigned char **id,
+ size_t *idlen, SSL_SESSION **sess)
+{
+ Q_UNUSED(ssl);
+ Q_UNUSED(md);
+ Q_UNUSED(id);
+ Q_UNUSED(idlen);
+ Q_UNUSED(sess);
+
+#ifndef OPENSSL_NO_PSK
+#ifdef QT_DEBUG
+ QSslSocketBackendPrivate *d = reinterpret_cast<QSslSocketBackendPrivate *>(q_SSL_get_ex_data(ssl, QSslSocketBackendPrivate::s_indexForSSLExtraData));
+ Q_ASSERT(d);
+ Q_ASSERT(d->mode == QSslSocket::SslClientMode);
+#endif
+
+ // Temporarily rebind the psk because it will be called next. The function will restore it.
+ q_SSL_set_psk_client_callback(ssl, &q_ssl_psk_restore_client);
+#endif
+
+ return 1; // need to return 1 or else "the connection setup fails."
+}
+#endif // TLS1_3_VERSION
+
#endif
#if QT_CONFIG(ocsp)
@@ -345,47 +398,41 @@ bool qt_OCSP_certificate_match(OCSP_SINGLERESP *singleResponse, X509 *peerCert,
#endif // ocsp
-// ### This list is shared between all threads, and protected by a
-// mutex. Investigate using thread local storage instead. Or better properly
-// use OpenSSL's ability to attach application data to an SSL/SSL_CTX
-// and extract it in a callback. See how it's done, for example, in PSK
-// callback or in DTLS verification callback.
-struct QSslErrorList
-{
- QMutex mutex;
- QVector<QSslErrorEntry> errors;
-};
-
-Q_GLOBAL_STATIC(QSslErrorList, _q_sslErrorList)
-
int q_X509Callback(int ok, X509_STORE_CTX *ctx)
{
if (!ok) {
// Store the error and at which depth the error was detected.
- _q_sslErrorList()->errors << QSslErrorEntry::fromStoreContext(ctx);
-#if !QT_CONFIG(opensslv11)
-#ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << "verification error: dumping bad certificate";
- qCDebug(lcSsl) << QSslCertificatePrivate::QSslCertificate_from_X509(q_X509_STORE_CTX_get_current_cert(ctx)).toPem();
- qCDebug(lcSsl) << "dumping chain";
- const auto certs = QSslSocketBackendPrivate::STACKOFX509_to_QSslCertificates(q_X509_STORE_CTX_get_chain(ctx));
- for (const QSslCertificate &cert : certs) {
- qCDebug(lcSsl) << "Issuer:" << "O=" << cert.issuerInfo(QSslCertificate::Organization)
- << "CN=" << cert.issuerInfo(QSslCertificate::CommonName)
- << "L=" << cert.issuerInfo(QSslCertificate::LocalityName)
- << "OU=" << cert.issuerInfo(QSslCertificate::OrganizationalUnitName)
- << "C=" << cert.issuerInfo(QSslCertificate::CountryName)
- << "ST=" << cert.issuerInfo(QSslCertificate::StateOrProvinceName);
- qCDebug(lcSsl) << "Subject:" << "O=" << cert.subjectInfo(QSslCertificate::Organization)
- << "CN=" << cert.subjectInfo(QSslCertificate::CommonName)
- << "L=" << cert.subjectInfo(QSslCertificate::LocalityName)
- << "OU=" << cert.subjectInfo(QSslCertificate::OrganizationalUnitName)
- << "C=" << cert.subjectInfo(QSslCertificate::CountryName)
- << "ST=" << cert.subjectInfo(QSslCertificate::StateOrProvinceName);
- qCDebug(lcSsl) << "Valid:" << cert.effectiveDate() << '-' << cert.expiryDate();
+
+ using ErrorListPtr = QVector<QSslErrorEntry>*;
+ ErrorListPtr errors = nullptr;
+
+ // Error list is attached to either 'SSL' or 'X509_STORE'.
+ if (X509_STORE *store = q_X509_STORE_CTX_get0_store(ctx)) { // We try store first:
+#if QT_CONFIG(opensslv11)
+ errors = ErrorListPtr(q_X509_STORE_get_ex_data(store, 0));
+#else
+ errors = ErrorListPtr(q_CRYPTO_get_ex_data(&store->ex_data, 0));
+#endif // opensslv11
}
-#endif // QSSLSOCKET_DEBUG
-#endif // !QT_CONFIG(opensslv11)
+
+ if (!errors) {
+ // Not found on store? Try SSL and its external data then. According to the OpenSSL's
+ // documentation:
+ //
+ // "Whenever a X509_STORE_CTX object is created for the verification of the peers certificate
+ // during a handshake, a pointer to the SSL object is stored into the X509_STORE_CTX object
+ // to identify the connection affected. To retrieve this pointer the X509_STORE_CTX_get_ex_data()
+ // function can be used with the correct index."
+ if (SSL *ssl = static_cast<SSL *>(q_X509_STORE_CTX_get_ex_data(ctx, q_SSL_get_ex_data_X509_STORE_CTX_idx())))
+ errors = ErrorListPtr(q_SSL_get_ex_data(ssl, QSslSocketBackendPrivate::s_indexForSSLExtraData + 1));
+ }
+
+ if (!errors) {
+ qCWarning(lcSsl, "Neither X509_STORE, nor SSL contains error list, handshake failure");
+ return 0;
+ }
+
+ errors->append(QSslErrorEntry::fromStoreContext(ctx));
}
// Always return OK to allow verification to continue. We handle the
// errors gracefully after collecting all errors, after verification has
@@ -541,11 +588,7 @@ bool QSslSocketBackendPrivate::initSslContext()
else
q_SSL_set_accept_state(ssl);
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L
- // Save a pointer to this object into the SSL structure.
- if (QSslSocket::sslLibraryVersionNumber() >= 0x10001000L)
- q_SSL_set_ex_data(ssl, s_indexForSSLExtraData, this);
-#endif
+ q_SSL_set_ex_data(ssl, s_indexForSSLExtraData, this);
#if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK)
// Set the client callback for PSK
@@ -556,6 +599,13 @@ bool QSslSocketBackendPrivate::initSslContext()
q_SSL_set_psk_server_callback(ssl, &q_ssl_psk_server_callback);
}
#endif
+#if OPENSSL_VERSION_NUMBER >= 0x10101006L
+ // Set the client callback for TLSv1.3 PSK
+ if (mode == QSslSocket::SslClientMode
+ && QSslSocket::sslLibraryBuildVersionNumber() >= 0x10101006L) {
+ q_SSL_set_psk_use_session_callback(ssl, &q_ssl_psk_use_session_callback);
+ }
+#endif // openssl version >= 0x10101006L
#if QT_CONFIG(ocsp)
if (configuration.ocspStaplingEnabled) {
@@ -1123,14 +1173,14 @@ bool QSslSocketBackendPrivate::startHandshake()
if (inSetAndEmitError)
return false;
- QMutexLocker locker(&_q_sslErrorList()->mutex);
- _q_sslErrorList()->errors.clear();
+ QVector<QSslErrorEntry> lastErrors;
+ q_SSL_set_ex_data(ssl, s_indexForSSLExtraData + 1, &lastErrors);
int result = (mode == QSslSocket::SslClientMode) ? q_SSL_connect(ssl) : q_SSL_accept(ssl);
+ q_SSL_set_ex_data(ssl, s_indexForSSLExtraData + 1, nullptr);
- const auto &lastErrors = _q_sslErrorList()->errors;
if (!lastErrors.isEmpty())
storePeerCertificates();
- for (const auto &currentError : lastErrors) {
+ for (const auto &currentError : qAsConst(lastErrors)) {
emit q->peerVerifyError(_q_OpenSSL_to_QSslError(currentError.code,
configuration.peerCertificateChain.value(currentError.depth)));
if (q->state() != QAbstractSocket::ConnectedState)
@@ -1138,7 +1188,6 @@ bool QSslSocketBackendPrivate::startHandshake()
}
errorList << lastErrors;
- locker.unlock();
// Connection aborted during handshake phase.
if (q->state() != QAbstractSocket::ConnectedState)
@@ -1520,28 +1569,14 @@ bool QSslSocketBackendPrivate::checkOcspStatus()
// 3) It checks CertID in response.
// 4) Ensures the responder is authorized to sign the status respond.
//
- // Here it's important to notice that it calls X509_cert_verify and
- // as a result, possibly, our verification callback. Given this callback
- // at the moment uses a global variable, we have to lock. This will change
- // as soon as we fix our verification procedure.
- // Also note, OpenSSL prior to 1.0.2b would only use bs->certs to
+ // Note, OpenSSL prior to 1.0.2b would only use bs->certs to
// verify the responder's chain (see their commit 4ba9a4265bd).
// Working this around - is too much fuss for ancient versions we
// are dropping quite soon anyway.
- {
- const unsigned long verificationFlags = 0;
- const QMutexLocker locker(&_q_sslErrorList()->mutex);
- // Before unlocking the mutex, startHandshake() stores errors (found in SSL_connect()
- // or SSL_accept()) into the local variable, so it's safe to clear it here - as soon
- // as we managed to lock, whoever had the lock before, already stored their own copy
- // of errors.
- _q_sslErrorList()->errors.clear();
- const int success = q_OCSP_basic_verify(basicResponse, peerChain, store, verificationFlags);
- if (success <= 0 || _q_sslErrorList()->errors.size()) {
- _q_sslErrorList()->errors.clear();
- ocspErrors.push_back(QSslError::OcspResponseCannotBeTrusted);
- }
- }
+ const unsigned long verificationFlags = 0;
+ const int success = q_OCSP_basic_verify(basicResponse, peerChain, store, verificationFlags);
+ if (success <= 0)
+ ocspErrors.push_back(QSslError::OcspResponseCannotBeTrusted);
if (q_OCSP_resp_count(basicResponse) != 1) {
ocspErrors.push_back(QSslError::OcspMalformedResponse);
@@ -1752,7 +1787,20 @@ QList<QSslError> QSslSocketBackendPrivate::verify(const QList<QSslCertificate> &
}
}
- QMutexLocker sslErrorListMutexLocker(&_q_sslErrorList()->mutex);
+ QVector<QSslErrorEntry> lastErrors;
+#if QT_CONFIG(opensslv11)
+ if (!q_X509_STORE_set_ex_data(certStore, 0, &lastErrors)) {
+ qCWarning(lcSsl) << "Unable to attach external data (error list) to a store";
+ errors << QSslError(QSslError::UnspecifiedError);
+ return errors;
+ }
+#else
+ if (!q_CRYPTO_set_ex_data(&certStore->ex_data, 0, &lastErrors)) {
+ qCWarning(lcSsl) << "Unable to attach external data (error list) to a store";
+ errors << QSslError(QSslError::UnspecifiedError);
+ return errors;
+ }
+#endif // opensslv11
// Register a custom callback to get all verification errors.
q_X509_STORE_set_verify_cb(certStore, q_X509Callback);
@@ -1802,12 +1850,7 @@ QList<QSslError> QSslSocketBackendPrivate::verify(const QList<QSslCertificate> &
q_OPENSSL_sk_free((OPENSSL_STACK *)intermediates);
// Now process the errors
- const auto errorList = std::move(_q_sslErrorList()->errors);
- _q_sslErrorList()->errors.clear();
- sslErrorListMutexLocker.unlock();
-
- // Translate the errors
if (QSslCertificatePrivate::isBlacklisted(certificateChain[0])) {
QSslError error(QSslError::CertificateBlacklisted, certificateChain[0]);
errors << error;
@@ -1821,8 +1864,8 @@ QList<QSslError> QSslSocketBackendPrivate::verify(const QList<QSslCertificate> &
}
// Translate errors from the error list into QSslErrors.
- errors.reserve(errors.size() + errorList.size());
- for (const auto &error : qAsConst(errorList))
+ errors.reserve(errors.size() + lastErrors.size());
+ for (const auto &error : qAsConst(lastErrors))
errors << _q_OpenSSL_to_QSslError(error.code, certificateChain.value(error.depth));
q_X509_STORE_free(certStore);
diff --git a/src/network/ssl/qsslsocket_openssl11_symbols_p.h b/src/network/ssl/qsslsocket_openssl11_symbols_p.h
index 9d0a14360d..0fe0899d4f 100644
--- a/src/network/ssl/qsslsocket_openssl11_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl11_symbols_p.h
@@ -107,6 +107,8 @@ Q_AUTOTEST_EXPORT void q_X509_up_ref(X509 *a);
long q_X509_get_version(X509 *a);
EVP_PKEY *q_X509_get_pubkey(X509 *a);
void q_X509_STORE_set_verify_cb(X509_STORE *ctx, X509_STORE_CTX_verify_cb verify_cb);
+int q_X509_STORE_set_ex_data(X509_STORE *ctx, int idx, void *data);
+void *q_X509_STORE_get_ex_data(X509_STORE *r, int idx);
STACK_OF(X509) *q_X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx);
void q_DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g);
int q_DH_bits(DH *dh);
@@ -184,4 +186,10 @@ const OCSP_CERTID *q_OCSP_SINGLERESP_get0_id(const OCSP_SINGLERESP *x);
#define q_SSL_CTX_set_max_proto_version(ctx, version) \
q_SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION, version, nullptr)
+extern "C" {
+typedef int (*q_SSL_psk_use_session_cb_func_t)(SSL *, const EVP_MD *, const unsigned char **, size_t *,
+ SSL_SESSION **);
+}
+void q_SSL_set_psk_use_session_callback(SSL *s, q_SSL_psk_use_session_cb_func_t);
+
#endif
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index 6f935a02e4..2eb9763e90 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -164,6 +164,7 @@ DEFINEFUNC(int, SSL_session_reused, SSL *a, a, return 0, return)
DEFINEFUNC2(unsigned long, SSL_CTX_set_options, SSL_CTX *ctx, ctx, unsigned long op, op, return 0, return)
#ifdef TLS1_3_VERSION
DEFINEFUNC2(int, SSL_CTX_set_ciphersuites, SSL_CTX *ctx, ctx, const char *str, str, return 0, return)
+DEFINEFUNC2(void, SSL_set_psk_use_session_callback, SSL *ssl, ssl, q_SSL_psk_use_session_cb_func_t callback, callback, return, DUMMYARG)
#endif
DEFINEFUNC3(size_t, SSL_get_client_random, SSL *a, a, unsigned char *out, out, size_t outlen, outlen, return 0, return)
DEFINEFUNC3(size_t, SSL_SESSION_get_master_key, const SSL_SESSION *ses, ses, unsigned char *out, out, size_t outlen, outlen, return 0, return)
@@ -179,6 +180,8 @@ DEFINEFUNC(ASN1_TIME *, X509_getm_notAfter, X509 *a, a, return nullptr, return)
DEFINEFUNC(long, X509_get_version, X509 *a, a, return -1, return)
DEFINEFUNC(EVP_PKEY *, X509_get_pubkey, X509 *a, a, return nullptr, return)
DEFINEFUNC2(void, X509_STORE_set_verify_cb, X509_STORE *a, a, X509_STORE_CTX_verify_cb verify_cb, verify_cb, return, DUMMYARG)
+DEFINEFUNC3(int, X509_STORE_set_ex_data, X509_STORE *a, a, int idx, idx, void *data, data, return 0, return)
+DEFINEFUNC2(void *, X509_STORE_get_ex_data, X509_STORE *r, r, int idx, idx, return nullptr, return)
DEFINEFUNC(STACK_OF(X509) *, X509_STORE_CTX_get0_chain, X509_STORE_CTX *a, a, return nullptr, return)
DEFINEFUNC3(void, CRYPTO_free, void *str, str, const char *file, file, int line, line, return, DUMMYARG)
DEFINEFUNC(long, OpenSSL_version_num, void, DUMMYARG, return 0, return)
@@ -253,6 +256,8 @@ DEFINEFUNC(int, CRYPTO_num_locks, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(void, CRYPTO_set_locking_callback, void (*a)(int, int, const char *, int), a, return, DUMMYARG)
DEFINEFUNC(void, CRYPTO_set_id_callback, unsigned long (*a)(), a, return, DUMMYARG)
DEFINEFUNC(void, CRYPTO_free, void *a, a, return, DUMMYARG)
+DEFINEFUNC3(int, CRYPTO_set_ex_data, CRYPTO_EX_DATA *ad, ad, int idx, idx, void *val, val, return 0, return)
+DEFINEFUNC2(void *, CRYPTO_get_ex_data, const CRYPTO_EX_DATA *ad, ad, int idx, idx, return nullptr, return)
DEFINEFUNC(unsigned long, ERR_peek_last_error, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(void, ERR_free_strings, void, DUMMYARG, return, DUMMYARG)
DEFINEFUNC(void, EVP_CIPHER_CTX_cleanup, EVP_CIPHER_CTX *a, a, return, DUMMYARG)
@@ -525,6 +530,7 @@ DEFINEFUNC2(int, X509_STORE_CTX_set_purpose, X509_STORE_CTX *a, a, int b, b, ret
DEFINEFUNC(int, X509_STORE_CTX_get_error, X509_STORE_CTX *a, a, return -1, return)
DEFINEFUNC(int, X509_STORE_CTX_get_error_depth, X509_STORE_CTX *a, a, return -1, return)
DEFINEFUNC(X509 *, X509_STORE_CTX_get_current_cert, X509_STORE_CTX *a, a, return nullptr, return)
+DEFINEFUNC(X509_STORE *, X509_STORE_CTX_get0_store, X509_STORE_CTX *ctx, ctx, return nullptr, return)
DEFINEFUNC(X509_STORE_CTX *, X509_STORE_CTX_new, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC2(void *, X509_STORE_CTX_get_ex_data, X509_STORE_CTX *ctx, ctx, int idx, idx, return nullptr, return)
DEFINEFUNC(int, SSL_get_ex_data_X509_STORE_CTX_idx, DUMMYARG, DUMMYARG, return -1, return)
@@ -975,6 +981,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(SSL_CTX_set_options)
#ifdef TLS1_3_VERSION
RESOLVEFUNC(SSL_CTX_set_ciphersuites)
+ RESOLVEFUNC(SSL_set_psk_use_session_callback)
#endif // TLS 1.3 or OpenSSL > 1.1.1
RESOLVEFUNC(SSL_get_client_random)
RESOLVEFUNC(SSL_SESSION_get_master_key)
@@ -992,6 +999,8 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(X509_get_version)
RESOLVEFUNC(X509_get_pubkey)
RESOLVEFUNC(X509_STORE_set_verify_cb)
+ RESOLVEFUNC(X509_STORE_set_ex_data)
+ RESOLVEFUNC(X509_STORE_get_ex_data)
RESOLVEFUNC(CRYPTO_free)
RESOLVEFUNC(OpenSSL_version_num)
RESOLVEFUNC(OpenSSL_version)
@@ -1063,6 +1072,8 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(CRYPTO_num_locks)
RESOLVEFUNC(CRYPTO_set_id_callback)
RESOLVEFUNC(CRYPTO_set_locking_callback)
+ RESOLVEFUNC(CRYPTO_set_ex_data)
+ RESOLVEFUNC(CRYPTO_get_ex_data)
RESOLVEFUNC(ERR_peek_last_error)
RESOLVEFUNC(ERR_free_strings)
RESOLVEFUNC(EVP_CIPHER_CTX_cleanup)
@@ -1324,6 +1335,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(X509_STORE_CTX_get_error)
RESOLVEFUNC(X509_STORE_CTX_get_error_depth)
RESOLVEFUNC(X509_STORE_CTX_get_current_cert)
+ RESOLVEFUNC(X509_STORE_CTX_get0_store)
RESOLVEFUNC(X509_cmp)
RESOLVEFUNC(X509_STORE_CTX_get_ex_data)
diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h
index fcf96dbd47..69b2b90fbd 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h
@@ -464,6 +464,7 @@ int q_X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose);
int q_X509_STORE_CTX_get_error(X509_STORE_CTX *ctx);
int q_X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
X509 *q_X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
+X509_STORE *q_X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx);
// Diffie-Hellman support
DH *q_DH_new();
diff --git a/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h b/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h
index 46b6505346..f5626d5d16 100644
--- a/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h
+++ b/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h
@@ -84,6 +84,8 @@ int q_CRYPTO_num_locks();
void q_CRYPTO_set_locking_callback(void (*a)(int, int, const char *, int));
void q_CRYPTO_set_id_callback(unsigned long (*a)());
void q_CRYPTO_free(void *a);
+int q_CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val);
+void *q_CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx);
unsigned long q_ERR_peek_last_error();
void q_ERR_free_strings();
void q_EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a);