diff options
author | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2021-01-25 11:28:48 +0100 |
---|---|---|
committer | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2021-01-28 16:21:07 +0100 |
commit | 1a2dd9276759742a7eda704341ee618d296ad8bf (patch) | |
tree | d6d0b7f8cf473c2d682aeae12bc2bad0680ace0b /src/network/ssl | |
parent | 795ea19ca0a7e484793655b35f19de8dbc88e987 (diff) |
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>
Diffstat (limited to 'src/network/ssl')
-rw-r--r-- | src/network/ssl/qsslsocket.cpp | 12 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket_mac.cpp | 19 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket_openssl.cpp | 20 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket_schannel.cpp | 22 | ||||
-rw-r--r-- | src/network/ssl/qtlsbackend.cpp | 221 | ||||
-rw-r--r-- | src/network/ssl/qtlsbackend_p.h | 32 |
6 files changed, 129 insertions, 197 deletions
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 0c231c1600..d2b386d024 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -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()); } /*! diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp index abbcf8a6ac..6370a83dd3 100644 --- a/src/network/ssl/qsslsocket_mac.cpp +++ b/src/network/ssl/qsslsocket_mac.cpp @@ -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"); } diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 2f39b68002..e6efaca2d0 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -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"); } diff --git a/src/network/ssl/qsslsocket_schannel.cpp b/src/network/ssl/qsslsocket_schannel.cpp index ca9bad96b6..d36b1790e1 100644 --- a/src/network/ssl/qsslsocket_schannel.cpp +++ b/src/network/ssl/qsslsocket_schannel.cpp @@ -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"); } diff --git a/src/network/ssl/qtlsbackend.cpp b/src/network/ssl/qtlsbackend.cpp index 4183c1e2f1..4c726a5b5d 100644 --- a/src/network/ssl/qtlsbackend.cpp +++ b/src/network/ssl/qtlsbackend.cpp @@ -51,99 +51,28 @@ QT_BEGIN_NAMESPACE Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, - (QTlsBackendFactory_iid, QStringLiteral("/tlsbackends"))) - -const QString QTlsBackendFactory::builtinBackendNames[] = { - QStringLiteral("schannel"), - QStringLiteral("securetransport"), - QStringLiteral("openssl") -}; - - -QTlsBackend::QTlsBackend() = default; -QTlsBackend::~QTlsBackend() = default; - -const QString dummyName = QStringLiteral("dummyTLS"); - -QString QTlsBackend::backendName() const -{ - return dummyName; -} - -QSsl::TlsKey *QTlsBackend::createKey() const -{ - qCWarning(lcSsl, "Dummy TLS backend, cannot generate a key"); - return nullptr; -} - -QSsl::X509Certificate *QTlsBackend::createCertificate() const -{ - qCWarning(lcSsl, "Dummy TLS backend, cannot create a certificate"); - return nullptr; -} - -QSsl::TlsCryptograph *QTlsBackend::createTlsCryptograph() const -{ - qCWarning(lcSsl, "Dummy TLS backend, cannot create TLS session"); - return nullptr; -} - -QSsl::DtlsCryptograph *QTlsBackend::createDtlsCryptograph() const -{ - qCWarning(lcSsl, "Dummy TLS backend, cannot create DTLS session"); - return nullptr; -} - -QSsl::DtlsCookieVerifier *QTlsBackend::createDtlsCookieVerifier() const -{ - qCWarning(lcSsl, "Dummy TLS backend, cannot create DTLS cookie generator/verifier"); - return nullptr; -} - -QSsl::X509ChainVerifyPtr QTlsBackend::X509Verifier() const -{ - qCWarning(lcSsl, "Dummy TLS backend, cannot verify X509 chain"); - return nullptr; -} - -QSsl::X509PemReaderPtr QTlsBackend::X509PemReader() const -{ - qCWarning(lcSsl, "Dummy TLS backend, cannot read PEM format"); - return nullptr; -} - -QSsl::X509DerReaderPtr QTlsBackend::X509DerReader() const -{ - qCWarning(lcSsl, "Dummy TLS backend, don't know how to read DER"); - return nullptr; -} - -QSsl::X509Pkcs12ReaderPtr QTlsBackend::X509Pkcs12Reader() const -{ - qCWarning(lcSsl, "Dummy TLS backend, cannot read PKCS12"); - return nullptr; -} + (QTlsBackend_iid, QStringLiteral("/tlsbackends"))) namespace { -class BackEndFactoryCollection +class BackendCollection { public: - void addFactory(QTlsBackendFactory *newFactory) + void addBackend(QTlsBackend *backend) { - Q_ASSERT(newFactory); - Q_ASSERT(std::find(backendFactories.begin(), backendFactories.end(), newFactory) == backendFactories.end()); + Q_ASSERT(backend); + Q_ASSERT(std::find(backends.begin(), backends.end(), backend) == backends.end()); const QMutexLocker locker(&collectionMutex); - backendFactories.push_back(newFactory); + backends.push_back(backend); } - void removeFactory(QTlsBackendFactory *factory) + void removeBackend(QTlsBackend *backend) { - Q_ASSERT(factory); + Q_ASSERT(backend); const QMutexLocker locker(&collectionMutex); - const auto it = std::find(backendFactories.begin(), backendFactories.end(), factory); - Q_ASSERT(it != backendFactories.end()); - backendFactories.erase(it); + const auto it = std::find(backends.begin(), backends.end(), backend); + Q_ASSERT(it != backends.end()); + backends.erase(it); } bool tryPopulateCollection() @@ -176,64 +105,124 @@ public: return names; const QMutexLocker locker(&collectionMutex); - if (!backendFactories.size()) + if (!backends.size()) return names; - names.reserve(backendFactories.size()); - for (const auto *factory : backendFactories) + names.reserve(backends.size()); + for (const auto *factory : backends) names.append(factory->backendName()); return names; } - QTlsBackendFactory *factory(const QString &name) + QTlsBackend *backend(const QString &name) { if (!tryPopulateCollection()) return nullptr; const QMutexLocker locker(&collectionMutex); - const auto it = std::find_if(backendFactories.begin(), backendFactories.end(), + const auto it = std::find_if(backends.begin(), backends.end(), [&name](const auto *fct) {return fct->backendName() == name;}); - return it == backendFactories.end() ? nullptr : *it; + return it == backends.end() ? nullptr : *it; } private: - std::vector<QTlsBackendFactory *> backendFactories; + std::vector<QTlsBackend *> backends; QMutex collectionMutex; bool loaded = false; }; -Q_GLOBAL_STATIC(BackEndFactoryCollection, factories); +} // 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() +{ + if (backends()) + backends->removeBackend(this); +} + +QString QTlsBackend::backendName() const +{ + return QStringLiteral("dummyTLS"); +} -} // unnamed namespace +QSsl::TlsKey *QTlsBackend::createKey() const +{ + qCWarning(lcSsl, "Dummy TLS backend, cannot generate a key"); + return nullptr; +} -QTlsBackendFactory::QTlsBackendFactory() +QSsl::X509Certificate *QTlsBackend::createCertificate() const { - if (factories()) - factories->addFactory(this); + qCWarning(lcSsl, "Dummy TLS backend, cannot create a certificate"); + return nullptr; } -QTlsBackendFactory::~QTlsBackendFactory() +QSsl::TlsCryptograph *QTlsBackend::createTlsCryptograph() const { - if (factories()) - factories->removeFactory(this); + qCWarning(lcSsl, "Dummy TLS backend, cannot create TLS session"); + return nullptr; } -QString QTlsBackendFactory::backendName() const +QSsl::DtlsCryptograph *QTlsBackend::createDtlsCryptograph() const { - return dummyName; + qCWarning(lcSsl, "Dummy TLS backend, cannot create DTLS session"); + return nullptr; +} + +QSsl::DtlsCookieVerifier *QTlsBackend::createDtlsCookieVerifier() const +{ + qCWarning(lcSsl, "Dummy TLS backend, cannot create DTLS cookie generator/verifier"); + return nullptr; +} + +QSsl::X509ChainVerifyPtr QTlsBackend::X509Verifier() const +{ + qCWarning(lcSsl, "Dummy TLS backend, cannot verify X509 chain"); + return nullptr; +} + +QSsl::X509PemReaderPtr QTlsBackend::X509PemReader() const +{ + qCWarning(lcSsl, "Dummy TLS backend, cannot read PEM format"); + return nullptr; +} + +QSsl::X509DerReaderPtr QTlsBackend::X509DerReader() const +{ + qCWarning(lcSsl, "Dummy TLS backend, don't know how to read DER"); + return nullptr; +} + +QSsl::X509Pkcs12ReaderPtr QTlsBackend::X509Pkcs12Reader() const +{ + qCWarning(lcSsl, "Dummy TLS backend, cannot read PKCS12"); + return nullptr; } -QList<QString> QTlsBackendFactory::availableBackendNames() +QList<QString> QTlsBackend::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 {}; diff --git a/src/network/ssl/qtlsbackend_p.h b/src/network/ssl/qtlsbackend_p.h index 9c4f2d3eb8..4650848a53 100644 --- a/src/network/ssl/qtlsbackend_p.h +++ b/src/network/ssl/qtlsbackend_p.h @@ -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 |