summaryrefslogtreecommitdiffstats
path: root/src/network/ssl/qtlsbackend.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/ssl/qtlsbackend.cpp')
-rw-r--r--src/network/ssl/qtlsbackend.cpp160
1 files changed, 72 insertions, 88 deletions
diff --git a/src/network/ssl/qtlsbackend.cpp b/src/network/ssl/qtlsbackend.cpp
index 144bd620c9..761ab33fbe 100644
--- a/src/network/ssl/qtlsbackend.cpp
+++ b/src/network/ssl/qtlsbackend.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtNetwork module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qtlsbackend_p.h"
@@ -52,6 +16,7 @@
#include <QtCore/private/qfactoryloader_p.h>
+#include "QtCore/qapplicationstatic.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmutex.h>
@@ -60,8 +25,10 @@
QT_BEGIN_NAMESPACE
-Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
- (QTlsBackend_iid, QStringLiteral("/tls")))
+using namespace Qt::StringLiterals;
+
+Q_APPLICATION_STATIC(QFactoryLoader, qtlsbLoader, QTlsBackend_iid,
+ QStringLiteral("/tls"))
namespace {
@@ -87,22 +54,22 @@ public:
bool tryPopulateCollection()
{
- if (!loader())
+ if (!qtlsbLoader())
return false;
- static QBasicMutex mutex;
+ Q_CONSTINIT static QBasicMutex mutex;
const QMutexLocker locker(&mutex);
- if (loaded)
+ if (backends.size())
return true;
#if QT_CONFIG(library)
- loader->update();
+ qtlsbLoader->update();
#endif
int index = 0;
- while (loader->instance(index))
+ while (qtlsbLoader->instance(index))
++index;
- return loaded = true;
+ return true;
}
QList<QString> backendNames()
@@ -139,7 +106,6 @@ public:
private:
std::vector<QTlsBackend *> backends;
QMutex collectionMutex;
- bool loaded = false;
};
} // Unnamed namespace
@@ -202,6 +168,12 @@ QTlsBackend::QTlsBackend()
{
if (backends())
backends->addBackend(this);
+
+ if (QCoreApplication::instance()) {
+ connect(QCoreApplication::instance(), &QCoreApplication::destroyed, this, [this] {
+ delete this;
+ });
+ }
}
/*!
@@ -800,7 +772,7 @@ QSslCipher QTlsBackend::createCiphersuite(const QString &descriptionOneLine, int
{
QSslCipher ciph;
- const auto descriptionList = QStringView{descriptionOneLine}.split(QLatin1Char(' '), Qt::SkipEmptyParts);
+ const auto descriptionList = QStringView{descriptionOneLine}.split(u' ', Qt::SkipEmptyParts);
if (descriptionList.size() > 5) {
ciph.d->isNull = false;
ciph.d->name = descriptionList.at(0).toString();
@@ -826,13 +798,13 @@ QT_WARNING_DISABLE_DEPRECATED
}
QT_WARNING_POP
- if (descriptionList.at(2).startsWith(QLatin1String("Kx=")))
+ if (descriptionList.at(2).startsWith("Kx="_L1))
ciph.d->keyExchangeMethod = descriptionList.at(2).mid(3).toString();
- if (descriptionList.at(3).startsWith(QLatin1String("Au=")))
+ if (descriptionList.at(3).startsWith("Au="_L1))
ciph.d->authenticationMethod = descriptionList.at(3).mid(3).toString();
- if (descriptionList.at(4).startsWith(QLatin1String("Enc=")))
+ if (descriptionList.at(4).startsWith("Enc="_L1))
ciph.d->encryptionMethod = descriptionList.at(4).mid(4).toString();
- ciph.d->exportable = (descriptionList.size() > 6 && descriptionList.at(6) == QLatin1String("export"));
+ ciph.d->exportable = (descriptionList.size() > 6 && descriptionList.at(6) == "export"_L1);
ciph.d->bits = bits;
ciph.d->supportedBits = supportedBits;
@@ -846,7 +818,7 @@ QT_WARNING_POP
Auxiliary function. Creates a new QSslCipher from \a suiteName, \a protocol version and
\a protocolString. For example:
\code
- createCiphersuite(QLatin1String("ECDHE-RSA-AES256-GCM-SHA256"), QSsl::TlsV1_2, QLatin1String("TLSv1.2"));
+ createCiphersuite("ECDHE-RSA-AES256-GCM-SHA256"_L1, QSsl::TlsV1_2, "TLSv1.2"_L1);
\endcode
*/
QSslCipher QTlsBackend::createCiphersuite(const QString &suiteName, QSsl::SslProtocol protocol,
@@ -862,48 +834,52 @@ QSslCipher QTlsBackend::createCiphersuite(const QString &suiteName, QSsl::SslPro
ciph.d->protocol = protocol;
ciph.d->protocolString = protocolString;
- const auto bits = QStringView{ciph.d->name}.split(QLatin1Char('-'));
+ const auto bits = QStringView{ciph.d->name}.split(u'-');
if (bits.size() >= 2) {
if (bits.size() == 2 || bits.size() == 3)
- ciph.d->keyExchangeMethod = QLatin1String("RSA");
- else if (bits.front() == QLatin1String("DH") || bits.front() == QLatin1String("DHE"))
- ciph.d->keyExchangeMethod = QLatin1String("DH");
- else if (bits.front() == QLatin1String("ECDH") || bits.front() == QLatin1String("ECDHE"))
- ciph.d->keyExchangeMethod = QLatin1String("ECDH");
+ ciph.d->keyExchangeMethod = "RSA"_L1;
+ else if (bits.front() == "DH"_L1 || bits.front() == "DHE"_L1)
+ ciph.d->keyExchangeMethod = "DH"_L1;
+ else if (bits.front() == "ECDH"_L1 || bits.front() == "ECDHE"_L1)
+ ciph.d->keyExchangeMethod = "ECDH"_L1;
else
qCWarning(lcSsl) << "Unknown Kx" << ciph.d->name;
if (bits.size() == 2 || bits.size() == 3)
- ciph.d->authenticationMethod = QLatin1String("RSA");
- else if (ciph.d->name.contains(QLatin1String("-ECDSA-")))
- ciph.d->authenticationMethod = QLatin1String("ECDSA");
- else if (ciph.d->name.contains(QLatin1String("-RSA-")))
- ciph.d->authenticationMethod = QLatin1String("RSA");
+ ciph.d->authenticationMethod = "RSA"_L1;
+ else if (ciph.d->name.contains("-ECDSA-"_L1))
+ ciph.d->authenticationMethod = "ECDSA"_L1;
+ else if (ciph.d->name.contains("-RSA-"_L1))
+ ciph.d->authenticationMethod = "RSA"_L1;
else
qCWarning(lcSsl) << "Unknown Au" << ciph.d->name;
- if (ciph.d->name.contains(QLatin1String("RC4-"))) {
- ciph.d->encryptionMethod = QLatin1String("RC4(128)");
+ if (ciph.d->name.contains("RC4-"_L1)) {
+ ciph.d->encryptionMethod = "RC4(128)"_L1;
ciph.d->bits = 128;
ciph.d->supportedBits = 128;
- } else if (ciph.d->name.contains(QLatin1String("DES-CBC3-"))) {
- ciph.d->encryptionMethod = QLatin1String("3DES(168)");
+ } else if (ciph.d->name.contains("DES-CBC3-"_L1)) {
+ ciph.d->encryptionMethod = "3DES(168)"_L1;
ciph.d->bits = 168;
ciph.d->supportedBits = 168;
- } else if (ciph.d->name.contains(QLatin1String("AES128-"))) {
- ciph.d->encryptionMethod = QLatin1String("AES(128)");
+ } else if (ciph.d->name.contains("AES128-"_L1)) {
+ ciph.d->encryptionMethod = "AES(128)"_L1;
ciph.d->bits = 128;
ciph.d->supportedBits = 128;
- } else if (ciph.d->name.contains(QLatin1String("AES256-GCM"))) {
- ciph.d->encryptionMethod = QLatin1String("AESGCM(256)");
+ } else if (ciph.d->name.contains("AES256-GCM"_L1)) {
+ ciph.d->encryptionMethod = "AESGCM(256)"_L1;
+ ciph.d->bits = 256;
+ ciph.d->supportedBits = 256;
+ } else if (ciph.d->name.contains("AES256-"_L1)) {
+ ciph.d->encryptionMethod = "AES(256)"_L1;
ciph.d->bits = 256;
ciph.d->supportedBits = 256;
- } else if (ciph.d->name.contains(QLatin1String("AES256-"))) {
- ciph.d->encryptionMethod = QLatin1String("AES(256)");
+ } else if (ciph.d->name.contains("CHACHA20-"_L1)) {
+ ciph.d->encryptionMethod = "CHACHA20"_L1;
ciph.d->bits = 256;
ciph.d->supportedBits = 256;
- } else if (ciph.d->name.contains(QLatin1String("NULL-"))) {
- ciph.d->encryptionMethod = QLatin1String("NULL");
+ } else if (ciph.d->name.contains("NULL-"_L1)) {
+ ciph.d->encryptionMethod = "NULL"_L1;
} else {
qCWarning(lcSsl) << "Unknown Enc" << ciph.d->name;
}
@@ -913,20 +889,28 @@ QSslCipher QTlsBackend::createCiphersuite(const QString &suiteName, QSsl::SslPro
/*!
\internal
- Auxiliary function. Creates a new QSslCipher from \a name (which is an implementation-specific
- string), \a protocol and \a protocolString, e.g.:
+ Auxiliary function. Creates a new QSslCipher from \a name, \a keyExchangeMethod, \a encryptionMethod,
+ \a authenticationMethod, \a bits, \a protocol version and \a protocolString.
+ For example:
\code
- createCipher(QStringLiteral("schannel"), QSsl::TlsV1_2, QLatin1String("TLSv1.2"));
+ createCiphersuite("ECDHE-RSA-AES256-GCM-SHA256"_L1, "ECDH"_L1, "AES"_L1, "RSA"_L1, 256,
+ QSsl::TlsV1_2, "TLSv1.2"_L1);
\endcode
*/
-QSslCipher QTlsBackend::createCipher(const QString &name, QSsl::SslProtocol protocol,
- const QString &protocolString)
+QSslCipher QTlsBackend::createCiphersuite(const QString &name, const QString &keyExchangeMethod,
+ const QString &encryptionMethod,
+ const QString &authenticationMethod,
+ int bits, QSsl::SslProtocol protocol,
+ const QString &protocolString)
{
- // Note the name 'createCipher' (not 'ciphersuite'): we don't provide
- // information about Kx, Au, bits/supported etc.
QSslCipher cipher;
cipher.d->isNull = false;
cipher.d->name = name;
+ cipher.d->bits = bits;
+ cipher.d->supportedBits = bits;
+ cipher.d->keyExchangeMethod = keyExchangeMethod;
+ cipher.d->encryptionMethod = encryptionMethod;
+ cipher.d->authenticationMethod = authenticationMethod;
cipher.d->protocol = protocol;
cipher.d->protocolString = protocolString;
return cipher;
@@ -1406,8 +1390,7 @@ QByteArray TlsKey::pemHeader() const
else if (algorithm() == QSsl::Dh)
return QByteArrayLiteral("-----BEGIN PRIVATE KEY-----");
- Q_UNREACHABLE();
- return {};
+ Q_UNREACHABLE_RETURN({});
}
/*!
@@ -1428,8 +1411,7 @@ QByteArray TlsKey::pemFooter() const
else if (algorithm() == QSsl::Dh)
return QByteArrayLiteral("-----END PRIVATE KEY-----");
- Q_UNREACHABLE();
- return {};
+ Q_UNREACHABLE_RETURN({});
}
/*!
@@ -1720,7 +1702,7 @@ TlsKey *X509Certificate::publicKey() const
/*!
\class TlsCryptograph
\internal (Network-private)
- \brief TlsCryptograph is an abstract class, that allows a TLS pluging to implement QSslSocket.
+ \brief TlsCryptograph is an abstract class, that allows a TLS plugin to implement QSslSocket.
This abstract base class provides an interface that must be reimplemented by a TLS plugin,
that supports QSslSocket. A class, implementing TlsCryptograph's interface, is responsible
@@ -2371,3 +2353,5 @@ Q_NETWORK_EXPORT void qt_ForceTlsSecurityLevel()
#endif // QT_CONFIG(ssl)
QT_END_NAMESPACE
+
+#include "moc_qtlsbackend_p.cpp"