summaryrefslogtreecommitdiffstats
path: root/src/plugins/tls/openssl/qtlsbackend_openssl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/tls/openssl/qtlsbackend_openssl.cpp')
-rw-r--r--src/plugins/tls/openssl/qtlsbackend_openssl.cpp64
1 files changed, 39 insertions, 25 deletions
diff --git a/src/plugins/tls/openssl/qtlsbackend_openssl.cpp b/src/plugins/tls/openssl/qtlsbackend_openssl.cpp
index ea31086fad..d73515724b 100644
--- a/src/plugins/tls/openssl/qtlsbackend_openssl.cpp
+++ b/src/plugins/tls/openssl/qtlsbackend_openssl.cpp
@@ -17,7 +17,7 @@
#include <QtNetwork/qssl.h>
#include <QtCore/qdir.h>
-#include <QtCore/qdiriterator.h>
+#include <QtCore/qdirlisting.h>
#include <QtCore/qlist.h>
#include <QtCore/qmutex.h>
#include <QtCore/qscopeguard.h>
@@ -31,9 +31,13 @@ QT_BEGIN_NAMESPACE
using namespace Qt::StringLiterals;
-Q_LOGGING_CATEGORY(lcTlsBackend, "qt.tlsbackend.ossl");
+#if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
+constexpr auto DefaultWarningLevel = QtCriticalMsg;
+#else
+constexpr auto DefaultWarningLevel = QtDebugMsg;
+#endif
-Q_GLOBAL_STATIC(QRecursiveMutex, qt_opensslInitMutex)
+Q_LOGGING_CATEGORY(lcTlsBackend, "qt.tlsbackend.ossl", DefaultWarningLevel);
static void q_loadCiphersForConnection(SSL *connection, QList<QSslCipher> &ciphers,
QList<QSslCipher> &defaultCiphers)
@@ -59,8 +63,6 @@ static void q_loadCiphersForConnection(SSL *connection, QList<QSslCipher> &ciphe
}
}
-bool QTlsBackendOpenSSL::s_libraryLoaded = false;
-bool QTlsBackendOpenSSL::s_loadedCiphersAndCerts = false;
int QTlsBackendOpenSSL::s_indexForSSLExtraData = -1;
QString QTlsBackendOpenSSL::getErrorsFromOpenSsl()
@@ -92,12 +94,10 @@ void QTlsBackendOpenSSL::clearErrorQueue()
bool QTlsBackendOpenSSL::ensureLibraryLoaded()
{
- if (!q_resolveOpenSslSymbols())
- return false;
-
- const QMutexLocker locker(qt_opensslInitMutex());
+ static bool libraryLoaded = []() {
+ if (!q_resolveOpenSslSymbols())
+ return false;
- if (!s_libraryLoaded) {
// Initialize OpenSSL.
if (q_OPENSSL_init_ssl(0, nullptr) != 1)
return false;
@@ -119,10 +119,10 @@ bool QTlsBackendOpenSSL::ensureLibraryLoaded()
return false;
}
- s_libraryLoaded = true;
- }
+ return true;
+ }();
- return true;
+ return libraryLoaded;
}
QString QTlsBackendOpenSSL::backendName() const
@@ -175,11 +175,24 @@ void QTlsBackendOpenSSL::ensureInitialized() const
void QTlsBackendOpenSSL::ensureCiphersAndCertsLoaded() const
{
- const QMutexLocker locker(qt_opensslInitMutex());
+ Q_CONSTINIT static bool initializationStarted = false;
+ Q_CONSTINIT static QAtomicInt initialized = Q_BASIC_ATOMIC_INITIALIZER(0);
+ Q_CONSTINIT static QRecursiveMutex initMutex;
- if (s_loadedCiphersAndCerts)
+ if (initialized.loadAcquire())
return;
- s_loadedCiphersAndCerts = true;
+
+ const QMutexLocker locker(&initMutex);
+
+ if (initializationStarted || initialized.loadAcquire())
+ return;
+
+ // Indicate that the initialization has already started in the current
+ // thread in case of recursive calls. The atomic variable cannot be used
+ // for this because it is checked without holding the init mutex.
+ initializationStarted = true;
+
+ auto guard = qScopeGuard([] { initialized.storeRelease(1); });
resetDefaultCiphers();
resetDefaultEllipticCurves();
@@ -191,11 +204,11 @@ void QTlsBackendOpenSSL::ensureCiphersAndCertsLoaded() const
#elif defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
// check whether we can enable on-demand root-cert loading (i.e. check whether the sym links are there)
const QList<QByteArray> dirs = QSslSocketPrivate::unixRootCertDirectories();
- QStringList symLinkFilter;
- symLinkFilter << "[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].[0-9]"_L1;
+ const QStringList symLinkFilter{
+ u"[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].[0-9]"_s};
for (const auto &dir : dirs) {
- QDirIterator iterator(QLatin1StringView(dir), symLinkFilter, QDir::Files);
- if (iterator.hasNext()) {
+ QDirListing dirList(QString::fromLatin1(dir), symLinkFilter, QDir::Files);
+ if (dirList.cbegin() != dirList.cend()) { // Not empty
QSslSocketPrivate::setRootCertOnDemandLoadingSupported(true);
break;
}
@@ -350,7 +363,9 @@ QList<QSslCertificate> systemCaCertificates()
QList<QSslCertificate> systemCerts;
#if defined(Q_OS_WIN)
HCERTSTORE hSystemStore;
- hSystemStore = CertOpenSystemStoreW(0, L"ROOT");
+ hSystemStore =
+ CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
+ CERT_STORE_READONLY_FLAG | CERT_SYSTEM_STORE_CURRENT_USER, L"ROOT");
if (hSystemStore) {
PCCERT_CONTEXT pc = nullptr;
while (1) {
@@ -379,13 +394,12 @@ QList<QSslCertificate> systemCaCertificates()
currentDir.setNameFilters(QStringList{QStringLiteral("*.pem"), QStringLiteral("*.crt")});
for (const auto &directory : directories) {
currentDir.setPath(QLatin1StringView(directory));
- QDirIterator it(currentDir);
- while (it.hasNext()) {
+ for (const auto &dirEntry : QDirListing(currentDir)) {
// use canonical path here to not load the same certificate twice if symlinked
- certFiles.insert(it.nextFileInfo().canonicalFilePath());
+ certFiles.insert(dirEntry.canonicalFilePath());
}
}
- for (const QString& file : qAsConst(certFiles))
+ for (const QString& file : std::as_const(certFiles))
systemCerts.append(QSslCertificate::fromPath(file, QSsl::Pem));
}
#endif // platform