TLS backend: merge with its factory

QTlsBackend is a factory itself - it creates TLS/X509 objects. Having
an intermediary between Factory->Backend->TLS primitive does not look
very natural thus let's squash the first two parts. Backend is a factory
creating TLS primitives, but its static functions also provide information
about backends availablei and give access to those backends.

Fixes: QTBUG-90606
Task-number: QTBUG-65922
Change-Id: I8409d81fd11fb46e6ab4465b4937a7680a8c2447
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
bb10
Timur Pocheptsov 2021-01-25 11:28:48 +01:00
parent 795ea19ca0
commit 1a2dd92767
7 changed files with 218 additions and 294 deletions

View File

@ -1557,7 +1557,7 @@ QString QSslSocket::sslLibraryBuildVersionString()
*/
QList<QString> QSslSocket::availableBackends()
{
return QTlsBackendFactory::availableBackendNames();
return QTlsBackend::availableBackendNames();
}
/*!
@ -1577,7 +1577,7 @@ QString QSslSocket::activeBackend()
const QMutexLocker locker(&QSslSocketPrivate::backendMutex);
if (!QSslSocketPrivate::activeBackendName.size())
QSslSocketPrivate::activeBackendName = QTlsBackendFactory::defaultBackendName();
QSslSocketPrivate::activeBackendName = QTlsBackend::defaultBackendName();
return QSslSocketPrivate::activeBackendName;
}
@ -1610,7 +1610,7 @@ bool QSslSocket::setActiveBackend(const QString &backendName)
return activeBackend() == backendName;
}
if (!QTlsBackendFactory::availableBackendNames().contains(backendName)) {
if (!QTlsBackend::availableBackendNames().contains(backendName)) {
qCWarning(lcSsl) << "Cannot set unavailable backend named" << backendName
<< "as active";
return false;
@ -1632,7 +1632,7 @@ bool QSslSocket::setActiveBackend(const QString &backendName)
*/
QList<QSsl::SslProtocol> QSslSocket::supportedProtocols(const QString &backendName)
{
return QTlsBackendFactory::supportedProtocols(backendName.size() ? backendName : activeBackend());
return QTlsBackend::supportedProtocols(backendName.size() ? backendName : activeBackend());
}
/*!
@ -1658,7 +1658,7 @@ bool QSslSocket::isProtocolSupported(QSsl::SslProtocol protocol, const QString &
*/
QList<QSsl::ImplementedClass> QSslSocket::implementedClasses(const QString &backendName)
{
return QTlsBackendFactory::implementedClasses(backendName.size() ? backendName : activeBackend());
return QTlsBackend::implementedClasses(backendName.size() ? backendName : activeBackend());
}
/*!
@ -1683,7 +1683,7 @@ bool QSslSocket::isClassImplemented(QSsl::ImplementedClass cl, const QString &ba
*/
QList<QSsl::SupportedFeature> QSslSocket::supportedFeatures(const QString &backendName)
{
return QTlsBackendFactory::supportedFeatures(backendName.size() ? backendName : activeBackend());
return QTlsBackend::supportedFeatures(backendName.size() ? backendName : activeBackend());
}
/*!

View File

@ -84,20 +84,7 @@ class SecureTransportBackend : public QTlsBackend
private:
QString backendName() const override
{
return QTlsBackendFactory::builtinBackendNames[QTlsBackendFactory::nameIndexSecureTransport];
}
};
class SecureTransportBackendFactory : public QTlsBackendFactory
{
private:
QString backendName() const override
{
return QTlsBackendFactory::builtinBackendNames[QTlsBackendFactory::nameIndexSecureTransport];
}
QTlsBackend *create() const override
{
return new SecureTransportBackend;
return builtinBackendNames[nameIndexSecureTransport];
}
QList<QSsl::SslProtocol> supportedProtocols() const override
@ -135,7 +122,7 @@ private:
}
};
Q_GLOBAL_STATIC(SecureTransportBackendFactory, factory)
Q_GLOBAL_STATIC(SecureTransportBackend, backend)
#ifdef Q_OS_MACOS
/*
@ -1618,7 +1605,7 @@ void QSslSocketPrivate::registerAdHocFactory()
{
// TLSTODO: this is a temporary solution, waiting for
// backends to move to ... plugins.
if (!factory())
if (!backend())
qCWarning(lcSsl, "Failed to create backend factory");
}

View File

@ -108,22 +108,8 @@ class OpenSSLBackend : public QTlsBackend
private:
QString backendName() const override
{
return QTlsBackendFactory::builtinBackendNames[QTlsBackendFactory::nameIndexOpenSSL];
return builtinBackendNames[nameIndexOpenSSL];
}
};
class OpenSSLBackendFactory : public QTlsBackendFactory
{
private:
QString backendName() const override
{
return QTlsBackendFactory::builtinBackendNames[QTlsBackendFactory::nameIndexOpenSSL];
}
QTlsBackend *create() const override
{
return new OpenSSLBackend;
}
QList<QSsl::SslProtocol> supportedProtocols() const override
{
QList<QSsl::SslProtocol> protocols;
@ -182,7 +168,7 @@ private:
}
};
Q_GLOBAL_STATIC(OpenSSLBackendFactory, factory)
Q_GLOBAL_STATIC(OpenSSLBackend, backend)
QSsl::AlertLevel tlsAlertLevel(int value)
{
@ -2597,7 +2583,7 @@ void QSslSocketPrivate::registerAdHocFactory()
{
// TLSTODO: this is a temporary solution, waiting for
// backends to move to ... plugins.
if (!factory())
if (!backend())
qCWarning(lcSsl, "Failed to create backend factory");
}

View File

@ -46,6 +46,7 @@
#include "qsslcertificateextension.h"
#include "qsslcertificate_p.h"
#include "qsslcipher_p.h"
#include "qtlsbackend_p.h"
#include <QtCore/qscopeguard.h>
#include <QtCore/qoperatingsystemversion.h>
@ -163,21 +164,7 @@ class SchannelBackend : public QTlsBackend
private:
QString backendName() const override
{
return QTlsBackendFactory::builtinBackendNames[QTlsBackendFactory::nameIndexSchannel];
}
};
bool supportsTls13();
class SchannelBackendFactory : public QTlsBackendFactory
{
private:
QString backendName() const override
{
return QTlsBackendFactory::builtinBackendNames[QTlsBackendFactory::nameIndexSchannel];
}
QTlsBackend *create() const override
{
return new SchannelBackend;
return builtinBackendNames[nameIndexSchannel];
}
QList<QSsl::SslProtocol> supportedProtocols() const override
@ -223,8 +210,7 @@ private:
}
};
Q_GLOBAL_STATIC(SchannelBackendFactory, factory);
Q_GLOBAL_STATIC(SchannelBackend, backend)
SecBuffer createSecBuffer(void *ptr, unsigned long length, unsigned long bufferType)
{
@ -2217,7 +2203,7 @@ void QSslSocketPrivate::registerAdHocFactory()
{
// TLSTODO: this is a temporary solution, waiting for
// backends to move to ... plugins.
if (!factory())
if (!backend())
qCWarning(lcSsl, "Failed to create backend factory");
}

View File

@ -51,23 +51,113 @@
QT_BEGIN_NAMESPACE
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QTlsBackendFactory_iid, QStringLiteral("/tlsbackends")))
(QTlsBackend_iid, QStringLiteral("/tlsbackends")))
const QString QTlsBackendFactory::builtinBackendNames[] = {
namespace {
class BackendCollection
{
public:
void addBackend(QTlsBackend *backend)
{
Q_ASSERT(backend);
Q_ASSERT(std::find(backends.begin(), backends.end(), backend) == backends.end());
const QMutexLocker locker(&collectionMutex);
backends.push_back(backend);
}
void removeBackend(QTlsBackend *backend)
{
Q_ASSERT(backend);
const QMutexLocker locker(&collectionMutex);
const auto it = std::find(backends.begin(), backends.end(), backend);
Q_ASSERT(it != backends.end());
backends.erase(it);
}
bool tryPopulateCollection()
{
if (!loader())
return false;
static QBasicMutex mutex;
const QMutexLocker locker(&mutex);
if (loaded)
return true;
#if QT_CONFIG(library)
loader->update();
#endif
int index = 0;
while (loader->instance(index))
++index;
// TLSTODO: obviously, this one should go away:
QSslSocketPrivate::registerAdHocFactory();
return loaded = true;
}
QList<QString> backendNames()
{
QList<QString> names;
if (!tryPopulateCollection())
return names;
const QMutexLocker locker(&collectionMutex);
if (!backends.size())
return names;
names.reserve(backends.size());
for (const auto *factory : backends)
names.append(factory->backendName());
return names;
}
QTlsBackend *backend(const QString &name)
{
if (!tryPopulateCollection())
return nullptr;
const QMutexLocker locker(&collectionMutex);
const auto it = std::find_if(backends.begin(), backends.end(),
[&name](const auto *fct) {return fct->backendName() == name;});
return it == backends.end() ? nullptr : *it;
}
private:
std::vector<QTlsBackend *> backends;
QMutex collectionMutex;
bool loaded = false;
};
} // Unnamed namespace
Q_GLOBAL_STATIC(BackendCollection, backends);
const QString QTlsBackend::builtinBackendNames[] = {
QStringLiteral("schannel"),
QStringLiteral("securetransport"),
QStringLiteral("openssl")
};
QTlsBackend::QTlsBackend()
{
if (backends())
backends->addBackend(this);
}
QTlsBackend::QTlsBackend() = default;
QTlsBackend::~QTlsBackend() = default;
const QString dummyName = QStringLiteral("dummyTLS");
QTlsBackend::~QTlsBackend()
{
if (backends())
backends->removeBackend(this);
}
QString QTlsBackend::backendName() const
{
return dummyName;
return QStringLiteral("dummyTLS");
}
QSsl::TlsKey *QTlsBackend::createKey() const
@ -124,116 +214,15 @@ QSsl::X509Pkcs12ReaderPtr QTlsBackend::X509Pkcs12Reader() const
return nullptr;
}
namespace {
class BackEndFactoryCollection
QList<QString> QTlsBackend::availableBackendNames()
{
public:
void addFactory(QTlsBackendFactory *newFactory)
{
Q_ASSERT(newFactory);
Q_ASSERT(std::find(backendFactories.begin(), backendFactories.end(), newFactory) == backendFactories.end());
const QMutexLocker locker(&collectionMutex);
backendFactories.push_back(newFactory);
}
void removeFactory(QTlsBackendFactory *factory)
{
Q_ASSERT(factory);
const QMutexLocker locker(&collectionMutex);
const auto it = std::find(backendFactories.begin(), backendFactories.end(), factory);
Q_ASSERT(it != backendFactories.end());
backendFactories.erase(it);
}
bool tryPopulateCollection()
{
if (!loader())
return false;
static QBasicMutex mutex;
const QMutexLocker locker(&mutex);
if (loaded)
return true;
#if QT_CONFIG(library)
loader->update();
#endif
int index = 0;
while (loader->instance(index))
++index;
// TLSTODO: obviously, this one should go away:
QSslSocketPrivate::registerAdHocFactory();
return loaded = true;
}
QList<QString> backendNames()
{
QList<QString> names;
if (!tryPopulateCollection())
return names;
const QMutexLocker locker(&collectionMutex);
if (!backendFactories.size())
return names;
names.reserve(backendFactories.size());
for (const auto *factory : backendFactories)
names.append(factory->backendName());
return names;
}
QTlsBackendFactory *factory(const QString &name)
{
if (!tryPopulateCollection())
return nullptr;
const QMutexLocker locker(&collectionMutex);
const auto it = std::find_if(backendFactories.begin(), backendFactories.end(),
[&name](const auto *fct) {return fct->backendName() == name;});
return it == backendFactories.end() ? nullptr : *it;
}
private:
std::vector<QTlsBackendFactory *> backendFactories;
QMutex collectionMutex;
bool loaded = false;
};
Q_GLOBAL_STATIC(BackEndFactoryCollection, factories);
} // unnamed namespace
QTlsBackendFactory::QTlsBackendFactory()
{
if (factories())
factories->addFactory(this);
}
QTlsBackendFactory::~QTlsBackendFactory()
{
if (factories())
factories->removeFactory(this);
}
QString QTlsBackendFactory::backendName() const
{
return dummyName;
}
QList<QString> QTlsBackendFactory::availableBackendNames()
{
if (!factories())
if (!backends())
return {};
return factories->backendNames();
return backends->backendNames();
}
QString QTlsBackendFactory::defaultBackendName()
QString QTlsBackend::defaultBackendName()
{
// We prefer native as default:
const auto names = availableBackendNames();
@ -250,46 +239,46 @@ QString QTlsBackendFactory::defaultBackendName()
return {};
}
QTlsBackend *QTlsBackendFactory::create(const QString &backendName)
QTlsBackend *QTlsBackend::findBackend(const QString &backendName)
{
if (!factories())
if (!backends())
return {};
if (const auto *fct = factories->factory(backendName))
return fct->create();
if (auto *fct = backends->backend(backendName))
return fct;
qCWarning(lcSsl) << "Cannot create unknown backend named" << backendName;
return nullptr;
}
QList<QSsl::SslProtocol> QTlsBackendFactory::supportedProtocols(const QString &backendName)
QList<QSsl::SslProtocol> QTlsBackend::supportedProtocols(const QString &backendName)
{
if (!factories())
if (!backends())
return {};
if (const auto *fct = factories->factory(backendName))
if (const auto *fct = backends->backend(backendName))
return fct->supportedProtocols();
return {};
}
QList<QSsl::SupportedFeature> QTlsBackendFactory::supportedFeatures(const QString &backendName)
QList<QSsl::SupportedFeature> QTlsBackend::supportedFeatures(const QString &backendName)
{
if (!factories())
if (!backends())
return {};
if (const auto *fct = factories->factory(backendName))
if (const auto *fct = backends->backend(backendName))
return fct->supportedFeatures();
return {};
}
QList<QSsl::ImplementedClass> QTlsBackendFactory::implementedClasses(const QString &backendName)
QList<QSsl::ImplementedClass> QTlsBackend::implementedClasses(const QString &backendName)
{
if (!factories())
if (!backends())
return {};
if (const auto *fct = factories->factory(backendName))
if (const auto *fct = backends->backend(backendName))
return fct->implementedClasses();
return {};

View File

@ -107,8 +107,6 @@ class DtlsCookieVerifier;
// Factory, creating back-end specific implementations of
// different entities QSslSocket is using.
// TLSTODO: consider merging with ... it's own factory
// below, no real benefit in having this split.
class Q_NETWORK_EXPORT QTlsBackend : public QObject
{
Q_OBJECT
@ -116,7 +114,10 @@ public:
QTlsBackend();
~QTlsBackend() override;
virtual QString backendName() const;
virtual QString backendName() const = 0;
virtual QList<QSsl::SslProtocol> supportedProtocols() const = 0;
virtual QList<QSsl::SupportedFeature> supportedFeatures() const = 0;
virtual QList<QSsl::ImplementedClass> implementedClasses() const = 0;
// X509 and keys:
virtual QSsl::TlsKey *createKey() const;
@ -133,26 +134,9 @@ public:
virtual QSsl::X509DerReaderPtr X509DerReader() const;
virtual QSsl::X509Pkcs12ReaderPtr X509Pkcs12Reader() const;
Q_DISABLE_COPY_MOVE(QTlsBackend)
};
// Factory for a backend.
class Q_NETWORK_EXPORT QTlsBackendFactory : public QObject
{
Q_OBJECT
public:
QTlsBackendFactory();
~QTlsBackendFactory() override;
virtual QString backendName() const = 0;
virtual QTlsBackend *create() const = 0;
virtual QList<QSsl::SslProtocol> supportedProtocols() const = 0;
virtual QList<QSsl::SupportedFeature> supportedFeatures() const = 0;
virtual QList<QSsl::ImplementedClass> implementedClasses() const = 0;
static QList<QString> availableBackendNames();
static QString defaultBackendName();
static QTlsBackend *create(const QString &backendName);
static QTlsBackend *findBackend(const QString &backendName);
static QList<QSsl::SslProtocol> supportedProtocols(const QString &backendName);
static QList<QSsl::SupportedFeature> supportedFeatures(const QString &backendName);
@ -165,11 +149,11 @@ public:
static const QString builtinBackendNames[];
Q_DISABLE_COPY_MOVE(QTlsBackendFactory)
Q_DISABLE_COPY_MOVE(QTlsBackend)
};
#define QTlsBackendFactory_iid "org.qt-project.Qt.QTlsBackendFactory"
Q_DECLARE_INTERFACE(QTlsBackendFactory, QTlsBackendFactory_iid);
#define QTlsBackend_iid "org.qt-project.Qt.QTlsBackend"
Q_DECLARE_INTERFACE(QTlsBackend, QTlsBackend_iid);
QT_END_NAMESPACE

View File

@ -165,6 +165,7 @@ public slots:
#ifndef QT_NO_SSL
private slots:
void activeBackend();
void backends();
void constructing();
void configNoOnDemandLoad();
@ -438,54 +439,6 @@ void tst_QSslSocket::initTestCase()
QSKIP("No network test server available");
#endif // QT_TEST_SERVER
#endif // QT_NO_SSL
// Since a backend can be loaded only once by an application (this test in our case),
// we do backend testing here.
// Before we tried to load anything, the active is the same thing as the default one:
QCOMPARE(QSslSocket::activeBackend(), QTlsBackendFactory::defaultBackendName());
const QString nonExistingBackend = QStringLiteral("TheQtTLS");
QCOMPARE(QSslSocket::setActiveBackend(nonExistingBackend), false);
QCOMPARE(QSslSocket::supportedProtocols(nonExistingBackend).size(), 0);
QCOMPARE(QSslSocket::supportedFeatures(nonExistingBackend), QList<QSsl::SupportedFeature>());
QCOMPARE(QSslSocket::implementedClasses(nonExistingBackend), QList<QSsl::ImplementedClass>());
const QString backendName = QSslSocket::activeBackend();
// Implemented by all our existing backends:
const auto implemented = QSsl::ImplementedClass::Socket;
const auto supportedFt = QSsl::SupportedFeature::ClientSideAlpn;
QVERIFY(QSslSocket::availableBackends().contains(backendName));
QCOMPARE(QSslSocket::setActiveBackend(backendName), true);
QCOMPARE(QSslSocket::activeBackend(), backendName);
QCOMPARE(QSslSocket::setActiveBackend(backendName), true); // We can do it again.
QCOMPARE(QSslSocket::activeBackend(), backendName);
const auto protocols = QSslSocket::supportedProtocols();
QVERIFY(protocols.size() > 0);
// 'Any' and 'Secure', since they are always present:
QVERIFY(protocols.contains(QSsl::AnyProtocol));
QVERIFY(protocols.contains(QSsl::SecureProtocols));
const auto protocolsForNamed = QSslSocket::supportedProtocols(backendName);
QCOMPARE(protocols, protocolsForNamed);
// Any and secure, new versions are coming, old
// go away, nothing more specific.
QVERIFY(protocolsForNamed.contains(QSsl::AnyProtocol));
QVERIFY(protocolsForNamed.contains(QSsl::SecureProtocols));
QCOMPARE(QSslSocket::isProtocolSupported(QSsl::SecureProtocols), true);
QCOMPARE(QSslSocket::isProtocolSupported(QSsl::SecureProtocols, backendName), true);
const auto classes = QSslSocket::implementedClasses();
QVERIFY(classes.contains(implemented));
QVERIFY(QSslSocket::isClassImplemented(implemented));
QVERIFY(QSslSocket::isClassImplemented(implemented, backendName));
const auto features = QSslSocket::supportedFeatures();
QVERIFY(features.contains(QSsl::SupportedFeature(supportedFt)));
QVERIFY(QSslSocket::isFeatureSupported(QSsl::SupportedFeature(supportedFt)));
QVERIFY(QSslSocket::isFeatureSupported(QSsl::SupportedFeature(supportedFt), backendName));
}
void tst_QSslSocket::init()
@ -564,19 +517,62 @@ void tst_QSslSocket::proxyAuthenticationRequired(const QNetworkProxy &, QAuthent
#ifndef QT_NO_SSL
void tst_QSslSocket::activeBackend()
{
QFETCH_GLOBAL(const bool, setProxy);
if (setProxy) // Not interesting for backend test.
return;
QCOMPARE(QSslSocket::activeBackend(), QTlsBackend::defaultBackendName());
// We cannot set non-existing as active:
const QString nonExistingBackend = QStringLiteral("TheQtTLS");
QCOMPARE(QSslSocket::setActiveBackend(nonExistingBackend), false);
QCOMPARE(QSslSocket::supportedProtocols(nonExistingBackend).size(), 0);
QCOMPARE(QSslSocket::supportedFeatures(nonExistingBackend), QList<QSsl::SupportedFeature>());
QCOMPARE(QSslSocket::implementedClasses(nonExistingBackend), QList<QSsl::ImplementedClass>());
const QString backendName = QSslSocket::activeBackend();
// Implemented by all our existing backends:
const auto implemented = QSsl::ImplementedClass::Socket;
const auto supportedFt = QSsl::SupportedFeature::ClientSideAlpn;
QVERIFY(QSslSocket::availableBackends().contains(backendName));
QCOMPARE(QSslSocket::setActiveBackend(backendName), true);
QCOMPARE(QSslSocket::activeBackend(), backendName);
QCOMPARE(QSslSocket::setActiveBackend(backendName), true); // We can do it again.
QCOMPARE(QSslSocket::activeBackend(), backendName);
const auto protocols = QSslSocket::supportedProtocols();
QVERIFY(protocols.size() > 0);
// 'Any' and 'Secure', since they are always present:
QVERIFY(protocols.contains(QSsl::AnyProtocol));
QVERIFY(protocols.contains(QSsl::SecureProtocols));
const auto protocolsForNamed = QSslSocket::supportedProtocols(backendName);
QCOMPARE(protocols, protocolsForNamed);
// Any and secure, new versions are coming, old
// go away, nothing more specific.
QVERIFY(protocolsForNamed.contains(QSsl::AnyProtocol));
QVERIFY(protocolsForNamed.contains(QSsl::SecureProtocols));
QCOMPARE(QSslSocket::isProtocolSupported(QSsl::SecureProtocols), true);
QCOMPARE(QSslSocket::isProtocolSupported(QSsl::SecureProtocols, backendName), true);
const auto classes = QSslSocket::implementedClasses();
QVERIFY(classes.contains(implemented));
QVERIFY(QSslSocket::isClassImplemented(implemented));
QVERIFY(QSslSocket::isClassImplemented(implemented, backendName));
const auto features = QSslSocket::supportedFeatures();
QVERIFY(features.contains(QSsl::SupportedFeature(supportedFt)));
QVERIFY(QSslSocket::isFeatureSupported(QSsl::SupportedFeature(supportedFt)));
QVERIFY(QSslSocket::isFeatureSupported(QSsl::SupportedFeature(supportedFt), backendName));
}
namespace {
struct MockTlsBackend : QTlsBackend
{
MockTlsBackend(const QString &n) : name(n) {}
QString backendName() const override
{
return name;
}
QString name;
};
struct MockTlsFactory : QTlsBackendFactory
{
MockTlsFactory(const QString &mockName) : name(mockName)
MockTlsBackend(const QString &mockName) : name(mockName)
{
}
QString backendName() const override
@ -596,26 +592,24 @@ struct MockTlsFactory : QTlsBackendFactory
{
return classes;
}
QTlsBackend *create() const override
{
auto tls = new MockTlsBackend(name);
return tls;
}
QString name;
QList<QSsl::ImplementedClass> classes;
QList<QSsl::SupportedFeature> features;
QList<QSsl::SslProtocol> protocols;
};
} // Unnamed backend.
void tst_QSslSocket::backends()
{
QFETCH_GLOBAL(const bool, setProxy);
if (setProxy)
QSKIP("Proxy is not interesting for backend test");
if (setProxy) // Not interesting for backend test.
return;
// We are here, protected by !QT_NO_SSL. Some backend must be pre-existing.
// Let's test the 'real' backend:
auto backendNames = QTlsBackendFactory::availableBackendNames();
auto backendNames = QTlsBackend::availableBackendNames();
const auto sizeBefore = backendNames.size();
QVERIFY(sizeBefore > 0);
@ -628,11 +622,9 @@ void tst_QSslSocket::backends()
const auto builtinFeatures = QSslSocket::supportedFeatures(builtinBackend);
QVERIFY(builtinFeatures.contains(QSsl::SupportedFeature::ClientSideAlpn));
{
// Verify that non-dummy backend can be created (and delete it):
const std::unique_ptr<QTlsBackend> systemBackend(QTlsBackendFactory::create(backendNames.first()));
QVERIFY(systemBackend.get());
}
// Verify that non-dummy backend can be created (and delete it):
auto *systemBackend = QTlsBackend::findBackend(builtinBackend);
QVERIFY(systemBackend);
const auto protocols = QList<QSsl::SslProtocol>{QSsl::SecureProtocols};
const auto classes = QList<QSsl::ImplementedClass>{QSsl::ImplementedClass::Socket};
@ -646,12 +638,16 @@ void tst_QSslSocket::backends()
QVERIFY(!backendNames.contains(nameB));
QVERIFY(!backendNames.contains(nonExisting));
{
MockTlsFactory factoryA(nameA);
backendNames = QTlsBackendFactory::availableBackendNames();
MockTlsBackend factoryA(nameA);
backendNames = QTlsBackend::availableBackendNames();
QVERIFY(backendNames.contains(nameA));
QVERIFY(!backendNames.contains(nameB));
QVERIFY(!backendNames.contains(nonExisting));
const auto *backendA = QTlsBackend::findBackend(nameA);
QVERIFY(backendA);
QCOMPARE(backendA->backendName(), nameA);
QCOMPARE(factoryA.supportedFeatures().size(), 0);
QCOMPARE(factoryA.supportedProtocols().size(), 0);
QCOMPARE(factoryA.implementedClasses().size(), 0);
@ -666,23 +662,19 @@ void tst_QSslSocket::backends()
QCOMPARE(factoryA.implementedClasses(), classes);
// That's a helper function (static member function):
QCOMPARE(QTlsBackendFactory::supportedProtocols(nameA), protocols);
QCOMPARE(QTlsBackendFactory::supportedFeatures(nameA), features);
QCOMPARE(QTlsBackendFactory::implementedClasses(nameA), classes);
QCOMPARE(QTlsBackend::supportedProtocols(nameA), protocols);
QCOMPARE(QTlsBackend::supportedFeatures(nameA), features);
QCOMPARE(QTlsBackend::implementedClasses(nameA), classes);
MockTlsFactory factoryB(nameB);
QVERIFY(QTlsBackendFactory::availableBackendNames().contains(nameA));
QVERIFY(QTlsBackendFactory::availableBackendNames().contains(nameB));
QVERIFY(!QTlsBackendFactory::availableBackendNames().contains(nonExisting));
MockTlsBackend factoryB(nameB);
QVERIFY(QTlsBackend::availableBackendNames().contains(nameA));
QVERIFY(QTlsBackend::availableBackendNames().contains(nameB));
QVERIFY(!QTlsBackend::availableBackendNames().contains(nonExisting));
const std::unique_ptr<QTlsBackend> backendA(QTlsBackendFactory::create(nameA));
QVERIFY(backendA.get());
QCOMPARE(backendA->backendName(), nameA);
const std::unique_ptr<QTlsBackend> nullBackend(QTlsBackendFactory::create(nonExisting));
QCOMPARE(nullBackend.get(), nullptr);
const auto *nullBackend = QTlsBackend::findBackend(nonExisting);
QCOMPARE(nullBackend, nullptr);
}
backendNames = QTlsBackendFactory::availableBackendNames();
backendNames = QTlsBackend::availableBackendNames();
QCOMPARE(backendNames.size(), sizeBefore);
// Check we cleaned up our factories:
QVERIFY(!backendNames.contains(nameA));