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
parent
795ea19ca0
commit
1a2dd92767
|
|
@ -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());
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
Loading…
Reference in New Issue