summaryrefslogtreecommitdiffstats
path: root/src/network/ssl
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/ssl')
-rw-r--r--src/network/ssl/qsslcertificate_openssl.cpp13
-rw-r--r--src/network/ssl/qsslsocket_mac.cpp2
-rw-r--r--src/network/ssl/qsslsocket_openssl11.cpp2
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp128
-rw-r--r--src/network/ssl/qsslsocket_schannel.cpp2
5 files changed, 77 insertions, 70 deletions
diff --git a/src/network/ssl/qsslcertificate_openssl.cpp b/src/network/ssl/qsslcertificate_openssl.cpp
index 806c6426e4..6f1fb26add 100644
--- a/src/network/ssl/qsslcertificate_openssl.cpp
+++ b/src/network/ssl/qsslcertificate_openssl.cpp
@@ -45,12 +45,19 @@
#include "qsslcertificateextension_p.h"
#include <QtCore/qendian.h>
+#include <QtCore/qmutex.h>
-#if QT_CONFIG(thread)
-#include <QtCore/private/qmutexpool_p.h>
-#endif
QT_BEGIN_NAMESPACE
+Q_CONSTEXPR int MutexPoolSize = 17;
+static QBasicMutex mutexPool[MutexPoolSize];
+namespace QMutexPool {
+ static QBasicMutex *globalInstanceGet(const void *addr)
+ {
+ return mutexPool + (quintptr(addr) % MutexPoolSize);
+ }
+}
+
// forward declaration
static QMultiMap<QByteArray, QString> _q_mapFromX509Name(X509_NAME *name);
diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp
index 487e975db6..1725937bc2 100644
--- a/src/network/ssl/qsslsocket_mac.cpp
+++ b/src/network/ssl/qsslsocket_mac.cpp
@@ -215,7 +215,7 @@ void QSecureTransportContext::reset(SSLContextRef newContext)
context = newContext;
}
-Q_GLOBAL_STATIC_WITH_ARGS(QMutex, qt_securetransport_mutex, (QMutex::Recursive))
+Q_GLOBAL_STATIC(QRecursiveMutex, qt_securetransport_mutex)
//#define QSSLSOCKET_DEBUG
diff --git a/src/network/ssl/qsslsocket_openssl11.cpp b/src/network/ssl/qsslsocket_openssl11.cpp
index cc2d6ea2d9..28be4f2e79 100644
--- a/src/network/ssl/qsslsocket_openssl11.cpp
+++ b/src/network/ssl/qsslsocket_openssl11.cpp
@@ -72,7 +72,7 @@
QT_BEGIN_NAMESPACE
-Q_GLOBAL_STATIC_WITH_ARGS(QMutex, qt_opensslInitMutex, (QMutex::Recursive))
+Q_GLOBAL_STATIC(QRecursiveMutex, qt_opensslInitMutex)
void QSslSocketPrivate::deinitialize()
{
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index 2eb9763e90..1fcfdf9f16 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -63,13 +63,11 @@
# include <QtCore/qlibrary.h>
#endif
#include <QtCore/qmutex.h>
-#if QT_CONFIG(thread)
-#include <private/qmutexpool_p.h>
-#endif
#include <QtCore/qdatetime.h>
#if defined(Q_OS_UNIX)
#include <QtCore/qdir.h>
#endif
+#include <QtCore/private/qmemory_p.h>
#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
#include <link.h>
#endif
@@ -599,8 +597,8 @@ DEFINEFUNC2(PKCS12 *, d2i_PKCS12_bio, BIO *bio, bio, PKCS12 **pkcs12, pkcs12, re
DEFINEFUNC(void, PKCS12_free, PKCS12 *pkcs12, pkcs12, return, DUMMYARG)
#define RESOLVEFUNC(func) \
- if (!(_q_##func = _q_PTR_##func(libs.first->resolve(#func))) \
- && !(_q_##func = _q_PTR_##func(libs.second->resolve(#func)))) \
+ if (!(_q_##func = _q_PTR_##func(libs.ssl->resolve(#func))) \
+ && !(_q_##func = _q_PTR_##func(libs.crypto->resolve(#func)))) \
qsslSocketCannotResolveSymbolWarning(#func);
#if !defined QT_LINKED_OPENSSL
@@ -736,34 +734,31 @@ static QStringList findAllLibCrypto()
# endif
#ifdef Q_OS_WIN
-static bool tryToLoadOpenSslWin32Library(QLatin1String ssleay32LibName, QLatin1String libeay32LibName, QPair<QSystemLibrary*, QSystemLibrary*> &pair)
-{
- pair.first = 0;
- pair.second = 0;
- QSystemLibrary *ssleay32 = new QSystemLibrary(ssleay32LibName);
+struct LoadedOpenSsl {
+ std::unique_ptr<QSystemLibrary> ssl, crypto;
+};
+
+static bool tryToLoadOpenSslWin32Library(QLatin1String ssleay32LibName, QLatin1String libeay32LibName, LoadedOpenSsl &result)
+{
+ auto ssleay32 = qt_make_unique<QSystemLibrary>(ssleay32LibName);
if (!ssleay32->load(false)) {
- delete ssleay32;
return FALSE;
}
- QSystemLibrary *libeay32 = new QSystemLibrary(libeay32LibName);
+ auto libeay32 = qt_make_unique<QSystemLibrary>(libeay32LibName);
if (!libeay32->load(false)) {
- delete ssleay32;
- delete libeay32;
return FALSE;
}
- pair.first = ssleay32;
- pair.second = libeay32;
+ result.ssl = std::move(ssleay32);
+ result.crypto = std::move(libeay32);
return TRUE;
}
-static QPair<QSystemLibrary*, QSystemLibrary*> loadOpenSslWin32()
+static LoadedOpenSsl loadOpenSsl()
{
- QPair<QSystemLibrary*,QSystemLibrary*> pair;
- pair.first = 0;
- pair.second = 0;
+ LoadedOpenSsl result;
#if QT_CONFIG(opensslv11)
// With OpenSSL 1.1 the names have changed to libssl-1_1(-x64) and libcrypto-1_1(-x64), for builds using
@@ -776,7 +771,7 @@ static QPair<QSystemLibrary*, QSystemLibrary*> loadOpenSslWin32()
#endif // !Q_PROCESSOR_x86_64
tryToLoadOpenSslWin32Library(QLatin1String("libssl-1_1" QT_SSL_SUFFIX),
- QLatin1String("libcrypto-1_1" QT_SSL_SUFFIX), pair);
+ QLatin1String("libcrypto-1_1" QT_SSL_SUFFIX), result);
#undef QT_SSL_SUFFIX
@@ -785,28 +780,30 @@ static QPair<QSystemLibrary*, QSystemLibrary*> loadOpenSslWin32()
// When OpenSSL is built using MSVC then the libraries are named 'ssleay32.dll' and 'libeay32'dll'.
// When OpenSSL is built using GCC then different library names are used (depending on the OpenSSL version)
// The oldest version of a GCC-based OpenSSL which can be detected by the code below is 0.9.8g (released in 2007)
- if (!tryToLoadOpenSslWin32Library(QLatin1String("ssleay32"), QLatin1String("libeay32"), pair)) {
- if (!tryToLoadOpenSslWin32Library(QLatin1String("libssl-10"), QLatin1String("libcrypto-10"), pair)) {
- if (!tryToLoadOpenSslWin32Library(QLatin1String("libssl-8"), QLatin1String("libcrypto-8"), pair)) {
- tryToLoadOpenSslWin32Library(QLatin1String("libssl-7"), QLatin1String("libcrypto-7"), pair);
+ if (!tryToLoadOpenSslWin32Library(QLatin1String("ssleay32"), QLatin1String("libeay32"), result)) {
+ if (!tryToLoadOpenSslWin32Library(QLatin1String("libssl-10"), QLatin1String("libcrypto-10"), result)) {
+ if (!tryToLoadOpenSslWin32Library(QLatin1String("libssl-8"), QLatin1String("libcrypto-8"), result)) {
+ tryToLoadOpenSslWin32Library(QLatin1String("libssl-7"), QLatin1String("libcrypto-7"), result);
}
}
}
#endif // !QT_CONFIG(opensslv11)
- return pair;
+ return result;
}
#else
-static QPair<QLibrary*, QLibrary*> loadOpenSsl()
+struct LoadedOpenSsl {
+ std::unique_ptr<QLibrary> ssl, crypto;
+};
+
+static LoadedOpenSsl loadOpenSsl()
{
- QPair<QLibrary*,QLibrary*> pair;
+ LoadedOpenSsl result = {qt_make_unique<QLibrary>(), qt_make_unique<QLibrary>()};
# if defined(Q_OS_UNIX)
- QLibrary *&libssl = pair.first;
- QLibrary *&libcrypto = pair.second;
- libssl = new QLibrary;
- libcrypto = new QLibrary;
+ QLibrary * const libssl = result.ssl.get();
+ QLibrary * const libcrypto = result.crypto.get();
// Try to find the libssl library on the system.
//
@@ -850,7 +847,7 @@ static QPair<QLibrary*, QLibrary*> loadOpenSsl()
libcrypto->setFileNameAndVersion(QLatin1String("crypto"), QLatin1String(SHLIB_VERSION_NUMBER));
if (libcrypto->load() && libssl->load()) {
// libssl.so.<SHLIB_VERSION_NUMBER> and libcrypto.so.<SHLIB_VERSION_NUMBER> found
- return pair;
+ return result;
} else {
libssl->unload();
libcrypto->unload();
@@ -869,7 +866,7 @@ static QPair<QLibrary*, QLibrary*> loadOpenSsl()
libssl->setFileNameAndVersion(QLatin1String("ssl"), fallbackSoname);
libcrypto->setFileNameAndVersion(QLatin1String("crypto"), fallbackSoname);
if (libcrypto->load() && libssl->load()) {
- return pair;
+ return result;
} else {
libssl->unload();
libcrypto->unload();
@@ -885,11 +882,28 @@ static QPair<QLibrary*, QLibrary*> loadOpenSsl()
// macOS's /usr/lib/libssl.dylib, /usr/lib/libcrypto.dylib will be picked up in the third
// attempt, _after_ <bundle>/Contents/Frameworks has been searched.
// iOS does not ship a system libssl.dylib, libcrypto.dylib in the first place.
+# if defined(Q_OS_ANDROID)
+ // OpenSSL 1.1.x must be suffixed otherwise it will use the system libcrypto.so libssl.so which on API-21 are OpenSSL 1.0 not 1.1
+ auto openSSLSuffix = [](const QByteArray &defaultSuffix = {}) {
+ auto suffix = qgetenv("ANDROID_OPENSSL_SUFFIX");
+ if (suffix.isEmpty())
+ return defaultSuffix;
+ return suffix;
+ };
+# if QT_CONFIG(opensslv11)
+ static QString suffix = QString::fromLatin1(openSSLSuffix("_1_1"));
+# else
+ static QString suffix = QString::fromLatin1(openSSLSuffix());
+# endif
+ libssl->setFileNameAndVersion(QLatin1String("ssl") + suffix, -1);
+ libcrypto->setFileNameAndVersion(QLatin1String("crypto") + suffix, -1);
+# else
libssl->setFileNameAndVersion(QLatin1String("ssl"), -1);
libcrypto->setFileNameAndVersion(QLatin1String("crypto"), -1);
+# endif
if (libcrypto->load() && libssl->load()) {
// libssl.so.0 and libcrypto.so.0 found
- return pair;
+ return result;
} else {
libssl->unload();
libcrypto->unload();
@@ -914,7 +928,7 @@ static QPair<QLibrary*, QLibrary*> loadOpenSsl()
if (libssl->load()) {
// libssl.so.x and libcrypto.so.x found
- return pair;
+ return result;
} else {
libssl->unload();
}
@@ -924,41 +938,33 @@ static QPair<QLibrary*, QLibrary*> loadOpenSsl()
}
// failed to load anything
- delete libssl;
- delete libcrypto;
- libssl = libcrypto = 0;
- return pair;
+ result = {};
+ return result;
# else
// not implemented for this platform yet
- return pair;
+ return result;
# endif
}
#endif
+static QBasicMutex symbolResolveMutex;
+static QBasicAtomicInt symbolsResolved = Q_BASIC_ATOMIC_INITIALIZER(false);
+static bool triedToResolveSymbols = false;
+
bool q_resolveOpenSslSymbols()
{
- static bool symbolsResolved = false;
- static bool triedToResolveSymbols = false;
-#if QT_CONFIG(thread)
-#if QT_CONFIG(opensslv11)
- QMutexLocker locker(QMutexPool::globalInstanceGet((void *)&q_OPENSSL_init_ssl));
-#else
- QMutexLocker locker(QMutexPool::globalInstanceGet((void *)&q_SSL_library_init));
-#endif
-#endif
- if (symbolsResolved)
+ if (symbolsResolved.loadAcquire())
+ return true;
+ QMutexLocker locker(&symbolResolveMutex);
+ if (symbolsResolved.loadRelaxed())
return true;
if (triedToResolveSymbols)
return false;
triedToResolveSymbols = true;
-#ifdef Q_OS_WIN
- QPair<QSystemLibrary *, QSystemLibrary *> libs = loadOpenSslWin32();
-#else
- QPair<QLibrary *, QLibrary *> libs = loadOpenSsl();
-#endif
- if (!libs.first || !libs.second)
+ LoadedOpenSsl libs = loadOpenSsl();
+ if (!libs.ssl || !libs.crypto)
// failed to load them
return false;
@@ -1007,8 +1013,6 @@ bool q_resolveOpenSslSymbols()
if (!_q_OpenSSL_version) {
// Apparently, we were built with OpenSSL 1.1 enabled but are now using
// a wrong library.
- delete libs.first;
- delete libs.second;
qCWarning(lcSsl, "Incompatible version of OpenSSL");
return false;
}
@@ -1130,8 +1134,6 @@ bool q_resolveOpenSslSymbols()
// OpenSSL 1.1 has deprecated and removed SSLeay. We consider a failure to
// resolve this symbol as a failure to resolve symbols.
// The right operand of '||' above is ... a bit of paranoia.
- delete libs.first;
- delete libs.second;
qCWarning(lcSsl, "Incompatible version of OpenSSL");
return false;
}
@@ -1402,9 +1404,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(d2i_PKCS12_bio)
RESOLVEFUNC(PKCS12_free)
- symbolsResolved = true;
- delete libs.first;
- delete libs.second;
+ symbolsResolved.storeRelease(true);
return true;
}
#endif // QT_CONFIG(library)
diff --git a/src/network/ssl/qsslsocket_schannel.cpp b/src/network/ssl/qsslsocket_schannel.cpp
index 1314b432a4..c254659a33 100644
--- a/src/network/ssl/qsslsocket_schannel.cpp
+++ b/src/network/ssl/qsslsocket_schannel.cpp
@@ -431,7 +431,7 @@ QByteArray createAlpnString(const QByteArrayList &nextAllowedProtocols)
bool QSslSocketPrivate::s_loadRootCertsOnDemand = true;
bool QSslSocketPrivate::s_loadedCiphersAndCerts = false;
-Q_GLOBAL_STATIC_WITH_ARGS(QMutex, qt_schannel_mutex, (QMutex::Recursive))
+Q_GLOBAL_STATIC(QRecursiveMutex, qt_schannel_mutex)
void QSslSocketPrivate::ensureInitialized()
{