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.cpp2357
1 files changed, 2357 insertions, 0 deletions
diff --git a/src/network/ssl/qtlsbackend.cpp b/src/network/ssl/qtlsbackend.cpp
new file mode 100644
index 0000000000..761ab33fbe
--- /dev/null
+++ b/src/network/ssl/qtlsbackend.cpp
@@ -0,0 +1,2357 @@
+// 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"
+
+#if QT_CONFIG(ssl)
+#include "qsslpresharedkeyauthenticator_p.h"
+#include "qsslpresharedkeyauthenticator.h"
+#include "qsslsocket_p.h"
+#include "qsslcipher_p.h"
+#include "qsslkey_p.h"
+#include "qsslkey.h"
+#endif
+
+#include "qssl_p.h"
+
+#include <QtCore/private/qfactoryloader_p.h>
+
+#include "QtCore/qapplicationstatic.h"
+#include <QtCore/qbytearray.h>
+#include <QtCore/qmutex.h>
+
+#include <algorithm>
+#include <vector>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Qt::StringLiterals;
+
+Q_APPLICATION_STATIC(QFactoryLoader, qtlsbLoader, QTlsBackend_iid,
+ QStringLiteral("/tls"))
+
+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 (!qtlsbLoader())
+ return false;
+
+ Q_CONSTINIT static QBasicMutex mutex;
+ const QMutexLocker locker(&mutex);
+ if (backends.size())
+ return true;
+
+#if QT_CONFIG(library)
+ qtlsbLoader->update();
+#endif
+ int index = 0;
+ while (qtlsbLoader->instance(index))
+ ++index;
+
+ return 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 *backend : backends) {
+ if (backend->isValid())
+ names.append(backend->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;
+};
+
+} // Unnamed namespace
+
+Q_GLOBAL_STATIC(BackendCollection, backends);
+
+/*!
+ \class QTlsBackend
+ \internal (Network-private)
+ \brief QTlsBackend is a factory class, providing implementations
+ for the QSsl classes.
+
+ The purpose of QTlsBackend is to enable and simplify the addition
+ of new TLS backends to be used by QSslSocket and related classes.
+ Starting from Qt 6.1, these backends have plugin-based design (and
+ thus can co-exist simultaneously, unlike pre 6.1 times), although
+ any given run of a program can only use one of them.
+
+ Inheriting from QTlsBackend and creating an object of such
+ a class adds a new backend into the list of available TLS backends.
+
+ A new backend must provide a list of classes, features and protocols
+ it supports, and override the corresponding virtual functions that
+ create backend-specific implementations for these QSsl-classes.
+
+ The base abstract class - QTlsBackend - provides, where possible,
+ default implementations of its virtual member functions. These
+ default implementations can be overridden by a derived backend
+ class, if needed.
+
+ QTlsBackend also provides some auxiliary functions that a derived
+ backend class can use to interact with the internals of network-private classes.
+
+ \sa QSslSocket::availableBackends(), supportedFeatures(), supportedProtocols(), implementedClasses()
+*/
+
+/*!
+ \fn QString QTlsBackend::backendName() const
+ \internal
+ Returns the name of this backend. The name will be reported by QSslSocket::availableBackends().
+ Example of backend names: "openssl", "schannel", "securetransport".
+
+ \sa QSslSocket::availableBackends(), isValid()
+*/
+
+const QString QTlsBackend::builtinBackendNames[] = {
+ QStringLiteral("schannel"),
+ QStringLiteral("securetransport"),
+ QStringLiteral("openssl"),
+ QStringLiteral("cert-only")
+};
+
+/*!
+ \internal
+ The default constructor, adds a new backend to the list of available backends.
+
+ \sa ~QTlsBackend(), availableBackendNames(), QSslSocket::availableBackends()
+*/
+QTlsBackend::QTlsBackend()
+{
+ if (backends())
+ backends->addBackend(this);
+
+ if (QCoreApplication::instance()) {
+ connect(QCoreApplication::instance(), &QCoreApplication::destroyed, this, [this] {
+ delete this;
+ });
+ }
+}
+
+/*!
+ \internal
+ Removes this backend from the list of available backends.
+
+ \sa QTlsBackend(), availableBackendNames(), QSslSocket::availableBackends()
+*/
+QTlsBackend::~QTlsBackend()
+{
+ if (backends())
+ backends->removeBackend(this);
+}
+
+/*!
+ \internal
+ Returns \c true if this backend was initialised successfully. The default implementation
+ always returns \c true.
+
+ \note This function must be overridden if a particular backend has a non-trivial initialization
+ that can fail. If reimplemented, returning \c false will exclude this backend from the list of
+ backends, reported as available by QSslSocket.
+
+ \sa QSslSocket::availableBackends()
+*/
+
+bool QTlsBackend::isValid() const
+{
+ return true;
+}
+
+/*!
+ \internal
+ Returns an implementations-specific integer value, representing the TLS library's
+ version, that is currently used by this backend (i.e. runtime library version).
+ The default implementation returns 0.
+
+ \sa tlsLibraryBuildVersionNumber()
+*/
+long QTlsBackend::tlsLibraryVersionNumber() const
+{
+ return 0;
+}
+
+/*!
+ \internal
+ Returns an implementation-specific string, representing the TLS library's version,
+ that is currently used by this backend (i.e. runtime library version). The default
+ implementation returns an empty string.
+
+ \sa tlsLibraryBuildVersionString()
+*/
+
+QString QTlsBackend::tlsLibraryVersionString() const
+{
+ return {};
+}
+
+/*!
+ \internal
+ Returns an implementation-specific integer value, representing the TLS library's
+ version that this backend was built against (i.e. compile-time library version).
+ The default implementation returns 0.
+
+ \sa tlsLibraryVersionNumber()
+*/
+
+long QTlsBackend::tlsLibraryBuildVersionNumber() const
+{
+ return 0;
+}
+
+/*!
+ \internal
+ Returns an implementation-specific string, representing the TLS library's version
+ that this backend was built against (i.e. compile-time version). The default
+ implementation returns an empty string.
+
+ \sa tlsLibraryVersionString()
+*/
+QString QTlsBackend::tlsLibraryBuildVersionString() const
+{
+ return {};
+}
+
+/*!
+ \internal
+ QSslSocket and related classes call this function to ensure that backend's internal
+ resources - e.g. CA certificates, or ciphersuites - were properly initialized.
+*/
+void QTlsBackend::ensureInitialized() const
+{
+}
+
+#define REPORT_MISSING_SUPPORT(message) \
+ qCWarning(lcSsl) << "The backend" << backendName() << message
+
+/*!
+ \internal
+ If QSsl::ImplementedClass::Key is present in this backend's implementedClasses(),
+ the backend must reimplement this method to return a dynamically-allocated instance
+ of an implementation-specific type, inheriting from the class QTlsPrivate::TlsKey.
+ The default implementation of this function returns \nullptr.
+
+ \sa QSslKey, implementedClasses(), QTlsPrivate::TlsKey
+*/
+QTlsPrivate::TlsKey *QTlsBackend::createKey() const
+{
+ REPORT_MISSING_SUPPORT("does not support QSslKey");
+ return nullptr;
+}
+
+/*!
+ \internal
+ If QSsl::ImplementedClass::Certificate is present in this backend's implementedClasses(),
+ the backend must reimplement this method to return a dynamically-allocated instance of an
+ implementation-specific type, inheriting from the class QTlsPrivate::X509Certificate.
+ The default implementation of this function returns \nullptr.
+
+ \sa QSslCertificate, QTlsPrivate::X509Certificate, implementedClasses()
+*/
+QTlsPrivate::X509Certificate *QTlsBackend::createCertificate() const
+{
+ REPORT_MISSING_SUPPORT("does not support QSslCertificate");
+ return nullptr;
+}
+
+/*!
+ \internal
+ This function returns a list of system CA certificates - e.g. certificates, loaded
+ from a system store, if available. This function allows implementation of the class
+ QSslConfiguration. The default implementation of this function returns an empty list.
+
+ \sa QSslCertificate, QSslConfiguration
+*/
+QList<QSslCertificate> QTlsBackend::systemCaCertificates() const
+{
+ REPORT_MISSING_SUPPORT("does not provide system CA certificates");
+ return {};
+}
+
+/*!
+ \internal
+ If QSsl::ImplementedClass::Socket is present in this backend's implementedClasses(),
+ the backend must reimplement this method to return a dynamically-allocated instance of an
+ implementation-specific type, inheriting from the class QTlsPrivate::TlsCryptograph.
+ The default implementation of this function returns \nullptr.
+
+ \sa QSslSocket, QTlsPrivate::TlsCryptograph, implementedClasses()
+*/
+QTlsPrivate::TlsCryptograph *QTlsBackend::createTlsCryptograph() const
+{
+ REPORT_MISSING_SUPPORT("does not support QSslSocket");
+ return nullptr;
+}
+
+/*!
+ \internal
+ If QSsl::ImplementedClass::Dtls is present in this backend's implementedClasses(),
+ the backend must reimplement this method to return a dynamically-allocated instance of an
+ implementation-specific type, inheriting from the class QTlsPrivate::DtlsCryptograph.
+ The default implementation of this function returns \nullptr.
+
+ \sa QDtls, QTlsPrivate::DtlsCryptograph, implementedClasses()
+*/
+QTlsPrivate::DtlsCryptograph *QTlsBackend::createDtlsCryptograph(QDtls *qObject, int mode) const
+{
+ Q_UNUSED(qObject);
+ Q_UNUSED(mode);
+ REPORT_MISSING_SUPPORT("does not support QDtls");
+ return nullptr;
+}
+
+/*!
+ \internal
+ If QSsl::ImplementedClass::DtlsCookie is present in this backend's implementedClasses(),
+ the backend must reimplement this method to return a dynamically-allocated instance of an
+ implementation-specific type, inheriting from the class QTlsPrivate::DtlsCookieVerifier. The
+ default implementation returns \nullptr.
+
+ \sa QDtlsClientVerifier, QTlsPrivate::DtlsCookieVerifier, implementedClasses()
+*/
+QTlsPrivate::DtlsCookieVerifier *QTlsBackend::createDtlsCookieVerifier() const
+{
+ REPORT_MISSING_SUPPORT("does not support DTLS cookies");
+ return nullptr;
+}
+
+/*!
+ \internal
+ If QSsl::SupportedFeature::CertificateVerification is present in this backend's
+ supportedFeatures(), the backend must reimplement this method to return a pointer
+ to a function, that checks a certificate (or a chain of certificates) against available
+ CA certificates. The default implementation returns \nullptr.
+
+ \sa supportedFeatures(), QSslCertificate
+*/
+
+QTlsPrivate::X509ChainVerifyPtr QTlsBackend::X509Verifier() const
+{
+ REPORT_MISSING_SUPPORT("does not support (manual) certificate verification");
+ return nullptr;
+}
+
+/*!
+ \internal
+ Returns a pointer to function, that reads certificates in PEM format. The
+ default implementation returns \nullptr.
+
+ \sa QSslCertificate
+*/
+QTlsPrivate::X509PemReaderPtr QTlsBackend::X509PemReader() const
+{
+ REPORT_MISSING_SUPPORT("cannot read PEM format");
+ return nullptr;
+}
+
+/*!
+ \internal
+ Returns a pointer to function, that can read certificates in DER format.
+ The default implementation returns \nullptr.
+
+ \sa QSslCertificate
+*/
+QTlsPrivate::X509DerReaderPtr QTlsBackend::X509DerReader() const
+{
+ REPORT_MISSING_SUPPORT("cannot read DER format");
+ return nullptr;
+}
+
+/*!
+ \internal
+ Returns a pointer to function, that can read certificates in PKCS 12 format.
+ The default implementation returns \nullptr.
+
+ \sa QSslCertificate
+*/
+QTlsPrivate::X509Pkcs12ReaderPtr QTlsBackend::X509Pkcs12Reader() const
+{
+ REPORT_MISSING_SUPPORT("cannot read PKCS12 format");
+ return nullptr;
+}
+
+/*!
+ \internal
+ If QSsl::ImplementedClass::EllipticCurve is present in this backend's implementedClasses(),
+ and the backend provides information about supported curves, it must reimplement this
+ method to return a list of unique identifiers of the supported elliptic curves. The default
+ implementation returns an empty list.
+
+ \note The meaning of a curve identifier is implementation-specific.
+
+ \sa implemenedClasses(), QSslEllipticCurve
+*/
+QList<int> QTlsBackend::ellipticCurvesIds() const
+{
+ REPORT_MISSING_SUPPORT("does not support QSslEllipticCurve");
+ return {};
+}
+
+/*!
+ \internal
+ If this backend provides information about available elliptic curves, this
+ function should return a unique integer identifier for a curve named \a name,
+ which is a conventional short name for the curve. The default implementation
+ returns 0.
+
+ \note The meaning of a curve identifier is implementation-specific.
+
+ \sa QSslEllipticCurve::shortName()
+*/
+int QTlsBackend::curveIdFromShortName(const QString &name) const
+{
+ Q_UNUSED(name);
+ REPORT_MISSING_SUPPORT("does not support QSslEllipticCurve");
+ return 0;
+}
+
+/*!
+ \internal
+ If this backend provides information about available elliptic curves, this
+ function should return a unique integer identifier for a curve named \a name,
+ which is a conventional long name for the curve. The default implementation
+ returns 0.
+
+ \note The meaning of a curve identifier is implementation-specific.
+
+ \sa QSslElliptiCurve::longName()
+*/
+int QTlsBackend::curveIdFromLongName(const QString &name) const
+{
+ Q_UNUSED(name);
+ REPORT_MISSING_SUPPORT("does not support QSslEllipticCurve");
+ return 0;
+}
+
+/*!
+ \internal
+ If this backend provides information about available elliptic curves,
+ this function should return a conventional short name for a curve identified
+ by \a cid. The default implementation returns an empty string.
+
+ \note The meaning of a curve identifier is implementation-specific.
+
+ \sa ellipticCurvesIds(), QSslEllipticCurve::shortName()
+*/
+QString QTlsBackend::shortNameForId(int cid) const
+{
+ Q_UNUSED(cid);
+ REPORT_MISSING_SUPPORT("does not support QSslEllipticCurve");
+ return {};
+}
+
+/*!
+ \internal
+ If this backend provides information about available elliptic curves,
+ this function should return a conventional long name for a curve identified
+ by \a cid. The default implementation returns an empty string.
+
+ \note The meaning of a curve identifier is implementation-specific.
+
+ \sa ellipticCurvesIds(), QSslEllipticCurve::shortName()
+*/
+QString QTlsBackend::longNameForId(int cid) const
+{
+ Q_UNUSED(cid);
+ REPORT_MISSING_SUPPORT("does not support QSslEllipticCurve");
+ return {};
+}
+
+/*!
+ \internal
+ Returns true if the elliptic curve identified by \a cid is one of the named
+ curves, that can be used in the key exchange when using an elliptic curve
+ cipher with TLS; false otherwise. The default implementation returns false.
+
+ \note The meaning of curve identifier is implementation-specific.
+*/
+bool QTlsBackend::isTlsNamedCurve(int cid) const
+{
+ Q_UNUSED(cid);
+ REPORT_MISSING_SUPPORT("does not support QSslEllipticCurve");
+ return false;
+}
+
+/*!
+ \internal
+ If this backend supports the class QSslDiffieHellmanParameters, this function is
+ needed for construction of a QSslDiffieHellmanParameters from DER encoded data.
+ This function is expected to return a value that matches an enumerator in
+ QSslDiffieHellmanParameters::Error enumeration. The default implementation of this
+ function returns 0 (equals to QSslDiffieHellmanParameters::NoError).
+
+ \sa QSslDiffieHellmanParameters, implementedClasses()
+*/
+int QTlsBackend::dhParametersFromDer(const QByteArray &derData, QByteArray *data) const
+{
+ Q_UNUSED(derData);
+ Q_UNUSED(data);
+ REPORT_MISSING_SUPPORT("does not support QSslDiffieHellmanParameters in DER format");
+ return {};
+}
+
+/*!
+ \internal
+ If this backend supports the class QSslDiffieHellmanParameters, this function is
+ is needed for construction of a QSslDiffieHellmanParameters from PEM encoded data.
+ This function is expected to return a value that matches an enumerator in
+ QSslDiffieHellmanParameters::Error enumeration. The default implementation of this
+ function returns 0 (equals to QSslDiffieHellmanParameters::NoError).
+
+ \sa QSslDiffieHellmanParameters, implementedClasses()
+*/
+int QTlsBackend::dhParametersFromPem(const QByteArray &pemData, QByteArray *data) const
+{
+ Q_UNUSED(pemData);
+ Q_UNUSED(data);
+ REPORT_MISSING_SUPPORT("does not support QSslDiffieHellmanParameters in PEM format");
+ return {};
+}
+
+/*!
+ \internal
+ Returns a list of names of available backends.
+
+ \note This list contains only properly initialized backends.
+
+ \sa QTlsBackend(), isValid()
+*/
+QList<QString> QTlsBackend::availableBackendNames()
+{
+ if (!backends())
+ return {};
+
+ return backends->backendNames();
+}
+
+/*!
+ \internal
+ Returns the name of the backend that QSslSocket() would use by default. If no
+ backend was found, the function returns an empty string.
+*/
+QString QTlsBackend::defaultBackendName()
+{
+ // We prefer OpenSSL as default:
+ const auto names = availableBackendNames();
+ auto name = builtinBackendNames[nameIndexOpenSSL];
+ if (names.contains(name))
+ return name;
+ name = builtinBackendNames[nameIndexSchannel];
+ if (names.contains(name))
+ return name;
+ name = builtinBackendNames[nameIndexSecureTransport];
+ if (names.contains(name))
+ return name;
+
+ const auto pos = std::find_if(names.begin(), names.end(), [](const auto &name) {
+ return name != builtinBackendNames[nameIndexCertOnly];
+ });
+
+ if (pos != names.end())
+ return *pos;
+
+ if (names.size())
+ return names[0];
+
+ return {};
+}
+
+/*!
+ \internal
+ Returns a backend named \a backendName, if it exists.
+ Otherwise, it returns \nullptr.
+
+ \sa backendName(), QSslSocket::availableBackends()
+*/
+QTlsBackend *QTlsBackend::findBackend(const QString &backendName)
+{
+ if (!backends())
+ return {};
+
+ if (auto *fct = backends->backend(backendName))
+ return fct;
+
+ qCWarning(lcSsl) << "Cannot create unknown backend named" << backendName;
+ return nullptr;
+}
+
+/*!
+ \internal
+ Returns the backend that QSslSocket is using. If Qt was built without TLS support,
+ this function returns a minimal backend that only supports QSslCertificate.
+
+ \sa defaultBackend()
+*/
+QTlsBackend *QTlsBackend::activeOrAnyBackend()
+{
+#if QT_CONFIG(ssl)
+ return QSslSocketPrivate::tlsBackendInUse();
+#else
+ return findBackend(defaultBackendName());
+#endif // QT_CONFIG(ssl)
+}
+
+/*!
+ \internal
+ Returns a list of TLS and DTLS protocol versions, that a backend named
+ \a backendName supports.
+
+ \note This list is supposed to also include range-based versions, which
+ allows negotiation of protocols during the handshake, so that these versions
+ can be used when configuring QSslSocket (e.g. QSsl::TlsV1_2OrLater).
+
+ \sa QSsl::SslProtocol
+*/
+QList<QSsl::SslProtocol> QTlsBackend::supportedProtocols(const QString &backendName)
+{
+ if (!backends())
+ return {};
+
+ if (const auto *fct = backends->backend(backendName))
+ return fct->supportedProtocols();
+
+ return {};
+}
+
+/*!
+ \internal
+ Returns a list of features that a backend named \a backendName supports. E.g.
+ a backend may support PSK (pre-shared keys, defined as QSsl::SupportedFeature::Psk)
+ or ALPN (application layer protocol negotiation, identified by
+ QSsl::SupportedFeature::ClientSideAlpn or QSsl::SupportedFeature::ServerSideAlpn).
+
+ \sa QSsl::SupportedFeature
+*/
+QList<QSsl::SupportedFeature> QTlsBackend::supportedFeatures(const QString &backendName)
+{
+ if (!backends())
+ return {};
+
+ if (const auto *fct = backends->backend(backendName))
+ return fct->supportedFeatures();
+
+ return {};
+}
+
+/*!
+ \internal
+ Returns a list of classes that a backend named \a backendName supports. E.g. a backend
+ may implement QSslSocket (QSsl::ImplementedClass::Socket), and QDtls
+ (QSsl::ImplementedClass::Dtls).
+
+ \sa QSsl::ImplementedClass
+*/
+QList<QSsl::ImplementedClass> QTlsBackend::implementedClasses(const QString &backendName)
+{
+ if (!backends())
+ return {};
+
+ if (const auto *fct = backends->backend(backendName))
+ return fct->implementedClasses();
+
+ return {};
+}
+
+/*!
+ \internal
+ Auxiliary function. Initializes \a key to use \a keyBackend.
+*/
+void QTlsBackend::resetBackend(QSslKey &key, QTlsPrivate::TlsKey *keyBackend)
+{
+#if QT_CONFIG(ssl)
+ key.d->backend.reset(keyBackend);
+#else
+ Q_UNUSED(key);
+ Q_UNUSED(keyBackend);
+#endif // QT_CONFIG(ssl)
+}
+
+/*!
+ \internal
+ Auxiliary function. Initializes client-side \a auth using the \a hint, \a hintLength,
+ \a maxIdentityLength and \a maxPskLen.
+*/
+void QTlsBackend::setupClientPskAuth(QSslPreSharedKeyAuthenticator *auth, const char *hint,
+ int hintLength, unsigned maxIdentityLen, unsigned maxPskLen)
+{
+ Q_ASSERT(auth);
+#if QT_CONFIG(ssl)
+ if (hint)
+ auth->d->identityHint = QByteArray::fromRawData(hint, hintLength); // it's NUL terminated, but do not include the NUL
+
+ auth->d->maximumIdentityLength = int(maxIdentityLen) - 1; // needs to be NUL terminated
+ auth->d->maximumPreSharedKeyLength = int(maxPskLen);
+#else
+ Q_UNUSED(auth);
+ Q_UNUSED(hint);
+ Q_UNUSED(hintLength);
+ Q_UNUSED(maxIdentityLen);
+ Q_UNUSED(maxPskLen);
+#endif
+}
+
+/*!
+ \internal
+ Auxiliary function. Initializes server-side \a auth using the \a identity, \a identityHint and
+ \a maxPskLen.
+*/
+void QTlsBackend::setupServerPskAuth(QSslPreSharedKeyAuthenticator *auth, const char *identity,
+ const QByteArray &identityHint, unsigned int maxPskLen)
+{
+#if QT_CONFIG(ssl)
+ Q_ASSERT(auth);
+ auth->d->identityHint = identityHint;
+ auth->d->identity = identity;
+ auth->d->maximumIdentityLength = 0; // user cannot set an identity
+ auth->d->maximumPreSharedKeyLength = int(maxPskLen);
+#else
+ Q_UNUSED(auth);
+ Q_UNUSED(identity);
+ Q_UNUSED(identityHint);
+ Q_UNUSED(maxPskLen);
+#endif
+}
+
+#if QT_CONFIG(ssl)
+/*!
+ \internal
+ Auxiliary function. Creates a new QSslCipher from \a descriptionOneLine, \a bits
+ and \a supportedBits. \a descriptionOneLine consists of several fields, separated by
+ whitespace. These include: cipher name, protocol version, key exchange method,
+ authentication method, encryption method, message digest (Mac). Example:
+ "ECDHE-RSA-AES256-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD"
+*/
+QSslCipher QTlsBackend::createCiphersuite(const QString &descriptionOneLine, int bits, int supportedBits)
+{
+ QSslCipher ciph;
+
+ const auto descriptionList = QStringView{descriptionOneLine}.split(u' ', Qt::SkipEmptyParts);
+ if (descriptionList.size() > 5) {
+ ciph.d->isNull = false;
+ ciph.d->name = descriptionList.at(0).toString();
+
+ QStringView protoString = descriptionList.at(1);
+ ciph.d->protocolString = protoString.toString();
+ ciph.d->protocol = QSsl::UnknownProtocol;
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+ if (protoString.startsWith(u"TLSv1")) {
+ QStringView tail = protoString.sliced(5);
+ if (tail.startsWith(u'.')) {
+ tail = tail.sliced(1);
+ if (tail == u"3")
+ ciph.d->protocol = QSsl::TlsV1_3;
+ else if (tail == u"2")
+ ciph.d->protocol = QSsl::TlsV1_2;
+ else if (tail == u"1")
+ ciph.d->protocol = QSsl::TlsV1_1;
+ } else if (tail.isEmpty()) {
+ ciph.d->protocol = QSsl::TlsV1_0;
+ }
+ }
+QT_WARNING_POP
+
+ if (descriptionList.at(2).startsWith("Kx="_L1))
+ ciph.d->keyExchangeMethod = descriptionList.at(2).mid(3).toString();
+ if (descriptionList.at(3).startsWith("Au="_L1))
+ ciph.d->authenticationMethod = descriptionList.at(3).mid(3).toString();
+ 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) == "export"_L1);
+
+ ciph.d->bits = bits;
+ ciph.d->supportedBits = supportedBits;
+ }
+
+ return ciph;
+}
+
+/*!
+ \internal
+ Auxiliary function. Creates a new QSslCipher from \a suiteName, \a protocol version and
+ \a protocolString. For example:
+ \code
+ createCiphersuite("ECDHE-RSA-AES256-GCM-SHA256"_L1, QSsl::TlsV1_2, "TLSv1.2"_L1);
+ \endcode
+*/
+QSslCipher QTlsBackend::createCiphersuite(const QString &suiteName, QSsl::SslProtocol protocol,
+ const QString &protocolString)
+{
+ QSslCipher ciph;
+
+ if (!suiteName.size())
+ return ciph;
+
+ ciph.d->isNull = false;
+ ciph.d->name = suiteName;
+ ciph.d->protocol = protocol;
+ ciph.d->protocolString = protocolString;
+
+ const auto bits = QStringView{ciph.d->name}.split(u'-');
+ if (bits.size() >= 2) {
+ if (bits.size() == 2 || bits.size() == 3)
+ 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 = "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("RC4-"_L1)) {
+ ciph.d->encryptionMethod = "RC4(128)"_L1;
+ ciph.d->bits = 128;
+ ciph.d->supportedBits = 128;
+ } 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("AES128-"_L1)) {
+ ciph.d->encryptionMethod = "AES(128)"_L1;
+ ciph.d->bits = 128;
+ ciph.d->supportedBits = 128;
+ } 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("CHACHA20-"_L1)) {
+ ciph.d->encryptionMethod = "CHACHA20"_L1;
+ ciph.d->bits = 256;
+ ciph.d->supportedBits = 256;
+ } else if (ciph.d->name.contains("NULL-"_L1)) {
+ ciph.d->encryptionMethod = "NULL"_L1;
+ } else {
+ qCWarning(lcSsl) << "Unknown Enc" << ciph.d->name;
+ }
+ }
+ return ciph;
+}
+
+/*!
+ \internal
+ 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
+ createCiphersuite("ECDHE-RSA-AES256-GCM-SHA256"_L1, "ECDH"_L1, "AES"_L1, "RSA"_L1, 256,
+ QSsl::TlsV1_2, "TLSv1.2"_L1);
+ \endcode
+*/
+QSslCipher QTlsBackend::createCiphersuite(const QString &name, const QString &keyExchangeMethod,
+ const QString &encryptionMethod,
+ const QString &authenticationMethod,
+ int bits, QSsl::SslProtocol protocol,
+ const QString &protocolString)
+{
+ 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;
+}
+
+/*!
+ \internal
+ Returns an implementation-specific list of ciphersuites that can be used by QSslSocket.
+
+ \sa QSslConfiguration::defaultCiphers()
+*/
+QList<QSslCipher> QTlsBackend::defaultCiphers()
+{
+ return QSslSocketPrivate::defaultCiphers();
+}
+
+/*!
+ \internal
+ Returns an implementation-specific list of ciphersuites that can be used by QDtls.
+*/
+QList<QSslCipher> QTlsBackend::defaultDtlsCiphers()
+{
+ return QSslSocketPrivate::defaultDtlsCiphers();
+}
+
+/*!
+ \internal
+ Sets \a ciphers as defaults ciphers that QSslSocket can use.
+
+ \sa defaultCiphers()
+*/
+void QTlsBackend::setDefaultCiphers(const QList<QSslCipher> &ciphers)
+{
+ QSslSocketPrivate::setDefaultCiphers(ciphers);
+}
+
+/*!
+ \internal
+ Sets \a ciphers as defaults ciphers that QDtls can use.
+
+ \sa defaultDtlsCiphers()
+*/
+void QTlsBackend::setDefaultDtlsCiphers(const QList<QSslCipher> &ciphers)
+{
+ QSslSocketPrivate::setDefaultDtlsCiphers(ciphers);
+}
+
+/*!
+ \internal
+ Sets \a ciphers as a list of supported ciphers.
+
+ \sa QSslConfiguration::supportedCiphers()
+*/
+void QTlsBackend::setDefaultSupportedCiphers(const QList<QSslCipher> &ciphers)
+{
+ QSslSocketPrivate::setDefaultSupportedCiphers(ciphers);
+}
+
+/*!
+ \internal
+ Sets the list of QSslEllipticCurve objects, that QSslConfiguration::supportedEllipticCurves()
+ returns, to ones that are supported by this backend.
+*/
+void QTlsBackend::resetDefaultEllipticCurves()
+{
+ QSslSocketPrivate::resetDefaultEllipticCurves();
+}
+
+/*!
+ Sets \a certs as a list of certificates, that QSslConfiguration::caCertificates()
+ reports.
+
+ \sa QSslConfiguration::defaultConfiguration(), QSslConfiguration::caCertificates()
+*/
+void QTlsBackend::setDefaultCaCertificates(const QList<QSslCertificate> &certs)
+{
+ QSslSocketPrivate::setDefaultCaCertificates(certs);
+}
+
+/*!
+ \internal
+ Returns true if \a configuration allows loading root certificates on demand.
+*/
+bool QTlsBackend::rootLoadingOnDemandAllowed(const QSslConfiguration &configuration)
+{
+ return configuration.d->allowRootCertOnDemandLoading;
+}
+
+/*!
+ \internal
+ Stores \a peerCert in the \a configuration.
+*/
+void QTlsBackend::storePeerCertificate(QSslConfiguration &configuration,
+ const QSslCertificate &peerCert)
+{
+ configuration.d->peerCertificate = peerCert;
+}
+
+/*!
+ \internal
+ Stores \a peerChain in the \a configuration.
+*/
+void QTlsBackend::storePeerCertificateChain(QSslConfiguration &configuration,
+ const QList<QSslCertificate> &peerChain)
+{
+ configuration.d->peerCertificateChain = peerChain;
+}
+
+/*!
+ \internal
+ Clears the peer certificate chain in \a configuration.
+*/
+void QTlsBackend::clearPeerCertificates(QSslConfiguration &configuration)
+{
+ configuration.d->peerCertificate.clear();
+ configuration.d->peerCertificateChain.clear();
+}
+
+/*!
+ \internal
+ Clears the peer certificate chain in \a d.
+*/
+void QTlsBackend::clearPeerCertificates(QSslSocketPrivate *d)
+{
+ Q_ASSERT(d);
+ d->configuration.peerCertificate.clear();
+ d->configuration.peerCertificateChain.clear();
+}
+
+/*!
+ \internal
+ Updates the configuration in \a d with \a shared value.
+*/
+void QTlsBackend::setPeerSessionShared(QSslSocketPrivate *d, bool shared)
+{
+ Q_ASSERT(d);
+ d->configuration.peerSessionShared = shared;
+}
+
+/*!
+ \internal
+ Sets TLS session in \a d to \a asn1.
+*/
+void QTlsBackend::setSessionAsn1(QSslSocketPrivate *d, const QByteArray &asn1)
+{
+ Q_ASSERT(d);
+ d->configuration.sslSession = asn1;
+}
+
+/*!
+ \internal
+ Sets TLS session lifetime hint in \a d to \a hint.
+*/
+void QTlsBackend::setSessionLifetimeHint(QSslSocketPrivate *d, int hint)
+{
+ Q_ASSERT(d);
+ d->configuration.sslSessionTicketLifeTimeHint = hint;
+}
+
+/*!
+ \internal
+ Sets application layer protocol negotiation status in \a d to \a st.
+*/
+void QTlsBackend::setAlpnStatus(QSslSocketPrivate *d, AlpnNegotiationStatus st)
+{
+ Q_ASSERT(d);
+ d->configuration.nextProtocolNegotiationStatus = st;
+}
+
+/*!
+ \internal
+ Sets \a protocol in \a d as a negotiated application layer protocol.
+*/
+void QTlsBackend::setNegotiatedProtocol(QSslSocketPrivate *d, const QByteArray &protocol)
+{
+ Q_ASSERT(d);
+ d->configuration.nextNegotiatedProtocol = protocol;
+}
+
+/*!
+ \internal
+ Stores \a peerCert in the TLS configuration of \a d.
+*/
+void QTlsBackend::storePeerCertificate(QSslSocketPrivate *d, const QSslCertificate &peerCert)
+{
+ Q_ASSERT(d);
+ d->configuration.peerCertificate = peerCert;
+}
+
+/*!
+ \internal
+
+ Stores \a peerChain in the TLS configuration of \a d.
+
+ \note This is a helper function that TlsCryptograph and DtlsCryptograph
+ call during a handshake.
+*/
+void QTlsBackend::storePeerCertificateChain(QSslSocketPrivate *d,
+ const QList<QSslCertificate> &peerChain)
+{
+ Q_ASSERT(d);
+ d->configuration.peerCertificateChain = peerChain;
+}
+
+/*!
+ \internal
+
+ Adds \a rootCert to the list of trusted root certificates in \a d.
+
+ \note In Qt 6.1 it's only used on Windows, during so called 'CA fetch'.
+*/
+void QTlsBackend::addTustedRoot(QSslSocketPrivate *d, const QSslCertificate &rootCert)
+{
+ Q_ASSERT(d);
+ if (!d->configuration.caCertificates.contains(rootCert))
+ d->configuration.caCertificates += rootCert;
+}
+
+/*!
+ \internal
+
+ Saves ephemeral \a key in \a d.
+
+ \sa QSslConfiguration::ephemeralKey()
+*/
+void QTlsBackend::setEphemeralKey(QSslSocketPrivate *d, const QSslKey &key)
+{
+ Q_ASSERT(d);
+ d->configuration.ephemeralServerKey = key;
+}
+
+/*!
+ \internal
+
+ Implementation-specific. Sets the security level suitable for Qt's
+ auto-tests.
+*/
+void QTlsBackend::forceAutotestSecurityLevel()
+{
+}
+
+#endif // QT_CONFIG(ssl)
+
+namespace QTlsPrivate {
+
+/*!
+ \internal (Network-private)
+ \namespace QTlsPrivate
+ \brief Namespace containing onternal types that TLS backends implement.
+
+ This namespace is private to Qt and the backends that implement its TLS support.
+*/
+
+/*!
+ \class TlsKey
+ \internal (Network-private)
+ \brief TlsKey is an abstract class, that allows a TLS plugin to provide
+ an underlying implementation for the class QSslKey.
+
+ Most functions in the class TlsKey are pure virtual and thus have to be
+ reimplemented by a TLS backend that supports QSslKey. In many cases an
+ empty implementation as an overrider is sufficient, albeit with some
+ of QSslKey's functionality missing.
+
+ \sa QTlsBackend::createKey(), QTlsBackend::implementedClasses(), QSslKey
+*/
+
+/*!
+ \fn void TlsKey::decodeDer(KeyType type, KeyAlgorithm algorithm, const QByteArray &der, const QByteArray &passPhrase, bool deepClear)
+ \internal
+
+ If a support of public and private keys in DER format is required, this function
+ must be overridden and should initialize this key using the \a type, \a algorithm, \a der
+ and \a passPhrase. If this key was initialized previously, \a deepClear
+ has an implementation-specific meaning (e.g., if an implementation is using
+ reference-counting and can share internally some data structures, a value \c true may
+ trigger decrementing a reference counter on some implementation-specific object).
+
+ \note An empty overrider is sufficient, but then reading keys in QSsl::Der format
+ will not be supported.
+
+ \sa isNull(), QSsl::KeyType, QSsl::EncodingFormat, QSsl::KeyAlgorithm
+*/
+
+/*!
+ \fn void TlsKey::decodePem(KeyType type, KeyAlgorithm algorithm, const QByteArray &pem, const QByteArray &passPhrase, bool deepClear)
+ \internal
+
+ If a support of public and private keys in PEM format is required, this function must
+ be overridden and should initialize this key using the \a type, \a algorithm, \a pem and
+ \a passPhrase. If this key was initialized previously, \a deepClear has an
+ implementation-specific meaning (e.g., in an implementation using reference-counting,
+ a value \c true may trigger decrementing a reference counter on some implementation-specific
+ object).
+
+ \note An empty overrider is sufficient, but then reading keys in QSsl::Pem format
+ will not be supported.
+
+ \sa isNull(), QSsl::KeyType, QSsl::EncodingFormat, QSsl::KeyAlgorithm
+*/
+
+/*!
+ \fn QByteArray TlsKey::toPem(const QByteArray &passPhrase) const
+ \internal
+
+ This function must be overridden, if converting a key to PEM format, potentially with
+ encryption, is needed (e.g. to save a QSslKey into a file). If this key is
+ private and \a passPhrase is not empty, the key's data is expected to be encrypted using
+ some conventional encryption algorithm (e.g. DES or AES - the one that different tools
+ or even the class QSslKey can understand later).
+
+ \note If this particular functionality is not needed, an overrider returning an
+ empty QByteArray is sufficient.
+
+ \sa QSslKey::toPem()
+*/
+
+/*!
+ \fn QByteArray TlsKey::derFromPem(const QByteArray &pem, QMap<QByteArray, QByteArray> *headers) const
+ \internal
+
+ Converts \a pem to DER format, using this key's type and algorithm. The parameter \a headers
+ must be a valid, non-null pointer. When parsing \a pem, the headers found there will be saved
+ into \a headers.
+
+ \note An overrider returning an empty QByteArray is sufficient, if QSslKey::toDer() is not
+ needed.
+
+ \note This function is very implementation-specific. A backend, that already has this key's
+ non-empty DER data, may simply return this data.
+
+ \sa QSslKey::toDer()
+*/
+
+/*!
+ \fn QByteArray TlsKey::pemFromDer(const QByteArray &der, const QMap<QByteArray, QByteArray> &headers) const
+ \internal
+
+ If overridden, this function is expected to convert \a der, using \a headers, to PEM format.
+
+ \note This function is very implementation-specific. As of now (Qt 6.1), it is only required by
+ Qt's own non-OpenSSL backends, that internally use DER and implement QSslKey::toPem()
+ via pemFromDer().
+*/
+
+/*!
+ \fn void TlsKey::fromHandle(Qt::HANDLE handle, KeyType type)
+ \internal
+
+ Initializes this key using the \a handle and \a type, taking the ownership
+ of the \a handle.
+
+ \note The meaning of the \a handle is implementation-specific.
+
+ \note If a TLS backend does not support such keys, it must provide an
+ empty implementation.
+
+ \sa handle(), QSslKey::QSslKey(), QSslKet::handle()
+*/
+
+/*!
+ \fn TlsKey::handle() const
+ \internal
+
+ If a TLS backend supports opaque keys, returns a native handle that
+ this key was initialized with.
+
+ \sa fromHandle(), QSslKey::handle()
+*/
+
+/*!
+ \fn bool TlsKey::isNull() const
+ \internal
+
+ Returns \c true if this is a null key, \c false otherwise.
+
+ \note A null key corresponds to the default-constructed
+ QSslKey or the one, that was cleared via QSslKey::clear().
+
+ \sa QSslKey::isNull()
+*/
+
+/*!
+ \fn QSsl::KeyType TlsKey::type() const
+ \internal
+
+ Returns the type of this key (public or private).
+*/
+
+/*!
+ \fn QSsl::KeyAlgorithm TlsKey::algorithm() const
+ \internal
+
+ Return this key's algorithm.
+*/
+
+/*!
+ \fn int TlsKey::length() const
+ \internal
+
+ Returns the length of the key in bits, or -1 if the key is null.
+*/
+
+/*!
+ \fn void TlsKey::clear(bool deep)
+ \internal
+
+ Clears the contents of this key, making it a null key. The meaning
+ of \a deep is implementation-specific (e.g. if some internal objects
+ representing a key can be shared using reference counting, \a deep equal
+ to \c true would imply decrementing a reference count).
+
+ \sa isNull()
+*/
+
+/*!
+ \fn bool TlsKey::isPkcs8() const
+ \internal
+
+ This function is internally used only by Qt's own TLS plugins and affects
+ the way PEM file is generated by TlsKey. It's sufficient to override it
+ and return \c false in case a new TLS backend is not using Qt's plugin
+ as a base.
+*/
+
+/*!
+ \fn QByteArray TlsKey::decrypt(Cipher cipher, const QByteArray &data, const QByteArray &passPhrase, const QByteArray &iv) const
+ \internal
+
+ This function allows to decrypt \a data (for example, a private key read from a file), using
+ \a passPhrase, initialization vector \a iv. \a cipher is describing a block cipher and its
+ mode (for example, AES256 + CBC). decrypt() is needed to implement QSslKey's constructor.
+
+ \note A TLS backend may provide an empty implementation, but as a result QSslKey will not be able
+ to work with private encrypted keys.
+
+ \sa QSslKey
+*/
+
+/*!
+ \fn QByteArray TlsKey::encrypt(Cipher cipher, const QByteArray &data, const QByteArray &passPhrase, const QByteArray &iv) const
+ \internal
+
+ This function is needed to implement QSslKey::toPem() with encryption (for a private
+ key). \a cipher names a block cipher to use to encrypt \a data, using
+ \a passPhrase and initialization vector \a iv.
+
+ \note An empty implementation is sufficient, but QSslKey::toPem() will fail for
+ a private key and non-empty passphrase.
+
+ \sa QSslKey
+*/
+
+/*!
+ \internal
+
+ Destroys this key.
+*/
+TlsKey::~TlsKey() = default;
+
+/*!
+ \internal
+
+ A convenience function that returns a string, corresponding to the
+ key type or algorithm, which can be used as a header in a PEM file.
+*/
+QByteArray TlsKey::pemHeader() const
+{
+ if (type() == QSsl::PublicKey)
+ return QByteArrayLiteral("-----BEGIN PUBLIC KEY-----");
+ else if (algorithm() == QSsl::Rsa)
+ return QByteArrayLiteral("-----BEGIN RSA PRIVATE KEY-----");
+ else if (algorithm() == QSsl::Dsa)
+ return QByteArrayLiteral("-----BEGIN DSA PRIVATE KEY-----");
+ else if (algorithm() == QSsl::Ec)
+ return QByteArrayLiteral("-----BEGIN EC PRIVATE KEY-----");
+ else if (algorithm() == QSsl::Dh)
+ return QByteArrayLiteral("-----BEGIN PRIVATE KEY-----");
+
+ Q_UNREACHABLE_RETURN({});
+}
+
+/*!
+ \internal
+ A convenience function that returns a string, corresponding to the
+ key type or algorithm, which can be used as a footer in a PEM file.
+*/
+QByteArray TlsKey::pemFooter() const
+{
+ if (type() == QSsl::PublicKey)
+ return QByteArrayLiteral("-----END PUBLIC KEY-----");
+ else if (algorithm() == QSsl::Rsa)
+ return QByteArrayLiteral("-----END RSA PRIVATE KEY-----");
+ else if (algorithm() == QSsl::Dsa)
+ return QByteArrayLiteral("-----END DSA PRIVATE KEY-----");
+ else if (algorithm() == QSsl::Ec)
+ return QByteArrayLiteral("-----END EC PRIVATE KEY-----");
+ else if (algorithm() == QSsl::Dh)
+ return QByteArrayLiteral("-----END PRIVATE KEY-----");
+
+ Q_UNREACHABLE_RETURN({});
+}
+
+/*!
+ \class X509Certificate
+ \internal (Network-private)
+ \brief X509Certificate is an abstract class that allows a TLS backend to
+ provide an implementation of the QSslCertificate class.
+
+ This class provides an interface that must be reimplemented by a TLS plugin,
+ that supports QSslCertificate. Most functions are pure virtual, and thus
+ have to be overridden. For some of them, an empty overrider is acceptable,
+ though a part of functionality in QSslCertificate will be missing.
+
+ \sa QTlsBackend::createCertificate(), QTlsBackend::X509PemReader(), QTlsBackend::X509DerReader()
+*/
+
+/*!
+ \fn bool X509Certificate::isEqual(const X509Certificate &other) const
+ \internal
+
+ This function is expected to return \c true if this certificate is the same as
+ the \a other, \c false otherwise. Used by QSslCertificate's comparison operators.
+*/
+
+/*!
+ \fn bool X509Certificate::isNull() const
+ \internal
+
+ Returns true if this certificate was default-constructed and not initialized yet.
+ This function is called by QSslCertificate::isNull().
+
+ \sa QSslCertificate::isNull()
+*/
+
+/*!
+ \fn bool X509Certificate::isSelfSigned() const
+ \internal
+
+ This function is needed to implement QSslCertificate::isSelfSigned()
+
+ \sa QSslCertificate::isSelfSigned()
+*/
+
+/*!
+ \fn QByteArray X509Certificate::version() const
+ \internal
+
+ Implements QSslCertificate::version().
+
+ \sa QSslCertificate::version()
+*/
+
+/*!
+ \fn QByteArray X509Certificate::serialNumber() const
+ \internal
+
+ This function is expected to return the certificate's serial number string in
+ hexadecimal format.
+
+ \sa QSslCertificate::serialNumber()
+*/
+
+/*!
+ \fn QStringList X509Certificate::issuerInfo(QSslCertificate::SubjectInfo subject) const
+ \internal
+
+ This function is expected to return the issuer information for the \a subject
+ from the certificate, or an empty list if there is no information for subject
+ in the certificate. There can be more than one entry of each type.
+
+ \sa QSslCertificate::issuerInfo().
+*/
+
+/*!
+ \fn QStringList X509Certificate::issuerInfo(const QByteArray &attribute) const
+ \internal
+
+ This function is expected to return the issuer information for attribute from
+ the certificate, or an empty list if there is no information for \a attribute
+ in the certificate. There can be more than one entry for an attribute.
+
+ \sa QSslCertificate::issuerInfo().
+*/
+
+/*!
+ \fn QStringList X509Certificate::subjectInfo(QSslCertificate::SubjectInfo subject) const
+ \internal
+
+ This function is expected to return the information for the \a subject, or an empty list
+ if there is no information for subject in the certificate. There can be more than one
+ entry of each type.
+
+ \sa QSslCertificate::subjectInfo().
+*/
+
+/*!
+ \fn QStringList X509Certificate::subjectInfo(const QByteArray &attribute) const
+ \internal
+
+ This function is expected to return the subject information for \a attribute, or
+ an empty list if there is no information for attribute in the certificate.
+ There can be more than one entry for an attribute.
+
+ \sa QSslCertificate::subjectInfo().
+*/
+
+/*!
+ \fn QList<QByteArray> X509Certificate::subjectInfoAttributes() const
+ \internal
+
+ This function is expected to return a list of the attributes that have values
+ in the subject information of this certificate. The information associated
+ with a given attribute can be accessed using the subjectInfo() method. Note
+ that this list may include the OIDs for any elements that are not known by
+ the TLS backend.
+
+ \note This function is needed for QSslCertificate:::subjectInfoAttributes().
+
+ \sa subjectInfo()
+*/
+
+/*!
+ \fn QList<QByteArray> X509Certificate::issuerInfoAttributes() const
+ \internal
+
+ This function is expected to return a list of the attributes that have
+ values in the issuer information of this certificate. The information
+ associated with a given attribute can be accessed using the issuerInfo()
+ method. Note that this list may include the OIDs for any
+ elements that are not known by the TLS backend.
+
+ \note This function implements QSslCertificate::issuerInfoAttributes().
+
+ \sa issuerInfo()
+*/
+
+/*!
+ \fn QMultiMap<QSsl::AlternativeNameEntryType, QString> X509Certificate::subjectAlternativeNames() const
+ \internal
+
+ This function is expected to return the list of alternative subject names for
+ this certificate. The alternative names typically contain host names, optionally
+ with wildcards, that are valid for this certificate.
+
+ \sa subjectInfo()
+*/
+
+/*!
+ \fn QDateTime X509Certificate::effectiveDate() const
+ \internal
+
+ This function is expected to return the date-time that the certificate
+ becomes valid, or an empty QDateTime if this is a null certificate.
+
+ \sa expiryDate()
+*/
+
+/*!
+ \fn QDateTime X509Certificate::expiryDate() const
+ \internal
+
+ This function is expected to return the date-time that the certificate expires,
+ or an empty QDateTime if this is a null certificate.
+
+ \sa effectiveDate()
+*/
+
+/*!
+ \fn qsizetype X509Certificate::numberOfExtensions() const
+ \internal
+
+ This function is expected to return the number of X509 extensions of
+ this certificate.
+*/
+
+/*!
+ \fn QString X509Certificate::oidForExtension(qsizetype i) const
+ \internal
+
+ This function is expected to return the ASN.1 OID for the extension
+ with index \a i.
+
+ \sa numberOfExtensions()
+*/
+
+/*!
+ \fn QString X509Certificate::nameForExtension(qsizetype i) const
+ \internal
+
+ This function is expected to return the name for the extension
+ with index \a i. If no name is known for the extension then the
+ OID will be returned.
+
+ \sa numberOfExtensions(), oidForExtension()
+*/
+
+/*!
+ \fn QVariant X509Certificate::valueForExtension(qsizetype i) const
+ \internal
+
+ This function is expected to return the value of the extension
+ with index \a i. The structure of the value returned depends on
+ the extension type
+
+ \sa numberOfExtensions()
+*/
+
+/*!
+ \fn bool X509Certificate::isExtensionCritical(qsizetype i) const
+ \internal
+
+ This function is expected to return the criticality of the extension
+ with index \a i.
+
+ \sa numberOfExtensions()
+*/
+
+/*!
+ \fn bool X509Certificate::isExtensionSupported(qsizetype i) const
+ \internal
+
+ This function is expected to return \c true if this extension is supported.
+ In this case, supported simply means that the structure of the QVariant returned
+ by the valueForExtension() accessor will remain unchanged between versions.
+
+ \sa numberOfExtensions()
+*/
+
+/*!
+ \fn QByteArray X509Certificate::toPem() const
+ \internal
+
+ This function is expected to return this certificate converted to a PEM (Base64)
+ encoded representation.
+*/
+
+/*!
+ \fn QByteArray X509Certificate::toDer() const
+ \internal
+
+ This function is expected to return this certificate converted to a DER (binary)
+ encoded representation.
+*/
+
+/*!
+ \fn QString X509Certificate::toText() const
+ \internal
+
+ This function is expected to return this certificate converted to a human-readable
+ text representation.
+*/
+
+/*!
+ \fn Qt::HANDLE X509Certificate::handle() const
+ \internal
+
+ This function is expected to return a pointer to the native certificate handle,
+ if there is one, else nullptr.
+*/
+
+/*!
+ \fn size_t X509Certificate::hash(size_t seed) const
+ \internal
+
+ This function is expected to return the hash value for this certificate,
+ using \a seed to seed the calculation.
+*/
+
+/*!
+ \internal
+
+ Destroys this certificate.
+*/
+X509Certificate::~X509Certificate() = default;
+
+/*!
+ \internal
+
+ Returns the certificate subject's public key.
+*/
+TlsKey *X509Certificate::publicKey() const
+{
+ return nullptr;
+}
+
+#if QT_CONFIG(ssl)
+
+/*!
+ \class TlsCryptograph
+ \internal (Network-private)
+ \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
+ for TLS handshake, reading and writing encryped application data; it is expected
+ to work with QSslSocket and it's private implementation - QSslSocketPrivate.
+ QSslSocketPrivate provides access to its read/write buffers, QTcpSocket it
+ internally uses for connecting, reading and writing. QSslSocketPrivate
+ can also be used for reporting errors and storing the certificates received
+ during the handshake phase.
+
+ \note Most of the functions in this class are pure virtual and have no actual implementation
+ in the QtNetwork module. This documentation is mostly conceptual and only describes what those
+ functions are expected to do, but not how they must be implemented.
+
+ \sa QTlsBackend::createTlsCryptograph()
+*/
+
+/*!
+ \fn void TlsCryptograph::init(QSslSocket *q, QSslSocketPrivate *d)
+ \internal
+
+ When initializing this TlsCryptograph, QSslSocket will pass a pointer to self and
+ its d-object using this function.
+*/
+
+/*!
+ \fn QList<QSslError> TlsCryptograph::tlsErrors() const
+ \internal
+
+ Returns a list of QSslError, describing errors encountered during
+ the TLS handshake.
+
+ \sa QSslSocket::sslHandshakeErrors()
+*/
+
+/*!
+ \fn void TlsCryptograph::startClientEncryption()
+ \internal
+
+ A client-side QSslSocket calls this function after its internal TCP socket
+ establishes a connection with a remote host, or from QSslSocket::startClientEncryption().
+ This TlsCryptograph is expected to initialize some implementation-specific TLS context,
+ if needed, and then start the client side of the TLS handshake (for example, by calling
+ transmit()), using TCP socket from QSslSocketPrivate.
+
+ \sa init(), transmit(), QSslSocket::startClientEncryption(), QSslSocket::connectToHostEncrypted()
+*/
+
+/*!
+ \fn void TlsCryptograph::startServerEncryption()
+ \internal
+
+ This function is called by QSslSocket::startServerEncryption(). The TlsCryptograph
+ is expected to initialize some implementation-specific TLS context, if needed,
+ and then try to read the ClientHello message and continue the TLS handshake
+ (for example, by calling transmit()).
+
+ \sa transmit(), QSslSocket::startServerEncryption()
+*/
+
+/*!
+ \fn void TlsCryptograph::continueHandshake()
+ \internal
+
+ QSslSocket::resume() calls this function if its pause mode is QAbstractSocket::PauseOnSslErrors,
+ and errors, found during the handshake, were ignored. If implemented, this function is expected
+ to emit QSslSocket::encrypted().
+
+ \sa QAbstractSocket::pauseMode(), QSslSocket::sslHandshakeErrors(), QSslSocket::ignoreSslErrors(), QSslSocket::resume()
+*/
+
+/*!
+ \fn void TlsCryptograph::disconnectFromHost()
+ \internal
+
+ This function is expected to call disconnectFromHost() on the TCP socket
+ that can be obtained from QSslSocketPrivate. Any additional actions
+ are implementation-specific (e.g., sending shutdown alert message).
+
+*/
+
+/*!
+ \fn void TlsCryptograph::disconnected()
+ \internal
+
+ This function is called when the remote has disconnected. If there
+ is data left to be read you may ignore the maxReadBufferSize restriction
+ and read it all now.
+*/
+
+/*!
+ \fn QSslCipher TlsCryptograph::sessionCipher() const
+ \internal
+
+ This function returns a QSslCipher object describing the ciphersuite negotiated
+ during the handshake.
+*/
+
+/*!
+ \fn QSsl::SslProtocol TlsCryptograph::sessionProtocol() const
+ \internal
+
+ This function returns the version of TLS (or DTLS) protocol negotiated during the handshake.
+*/
+
+/*!
+ \fn void TlsCryptograph::transmit()
+ \internal
+
+ This function is responsible for reading and writing data. The meaning of these I/O
+ operations depends on an implementation-specific TLS state machine. These read and write
+ operations can be reading and writing parts of a TLS handshake (e.g. by calling handshake-specific
+ functions), or reading and writing application data (if encrypted connection was already
+ established). transmit() is expected to use the QSslSocket's TCP socket (accessible via
+ QSslSocketPrivate) to read the incoming data and write the outgoing data. When in encrypted
+ state, transmit() is also using QSslSocket's internal read and write buffers: the read buffer
+ to fill with decrypted incoming data; the write buffer - for the data to encrypt and send.
+ This TlsCryptograph can also use QSslSocketPrivate to check which TLS errors were ignored during
+ the handshake.
+
+ \note This function is responsible for emitting QSslSocket's signals, that occur during the
+ handshake (e.g. QSslSocket::sslErrors() or QSslSocket::encrypted()), and also read/write signals,
+ e.g. QSslSocket::bytesWritten() and QSslSocket::readyRead().
+
+ \sa init()
+*/
+
+/*!
+ \internal
+
+ Destroys this object.
+*/
+TlsCryptograph::~TlsCryptograph() = default;
+
+/*!
+ \internal
+
+ This function allows to share QSslContext between several QSslSocket objects.
+ The default implementation does nothing.
+
+ \note The definition of the class QSslContext is implementation-specific.
+
+ \sa sslContext()
+*/
+void TlsCryptograph::checkSettingSslContext(std::shared_ptr<QSslContext> tlsContext)
+{
+ Q_UNUSED(tlsContext);
+}
+
+/*!
+ \internal
+
+ Returns the context previously set by checkSettingSslContext() or \nullptr,
+ if no context was set. The default implementation returns \nullptr.
+
+ \sa checkSettingSslContext()
+*/
+std::shared_ptr<QSslContext> TlsCryptograph::sslContext() const
+{
+ return {};
+}
+
+/*!
+ \internal
+
+ If this TLS backend supports reporting errors before handshake is finished,
+ e.g. from a verification callback function, enableHandshakeContinuation()
+ allows this object to continue handshake. The default implementation does
+ nothing.
+
+ \sa QSslSocket::handshakeInterruptedOnError(), QSslConfiguration::setHandshakeMustInterruptOnError()
+*/
+void TlsCryptograph::enableHandshakeContinuation()
+{
+}
+
+/*!
+ \internal
+
+ Windows and OpenSSL-specific, only used internally by Qt's OpenSSL TLS backend.
+
+ \note The default empty implementation is sufficient.
+*/
+void TlsCryptograph::cancelCAFetch()
+{
+}
+
+/*!
+ \internal
+
+ Windows and Schannel-specific, only used by Qt's Schannel TLS backend, in
+ general, if a backend has its own buffer where it stores undecrypted data
+ then it must report true if it contains any data through this function.
+
+ \note The default empty implementation, returning \c false is sufficient.
+*/
+bool TlsCryptograph::hasUndecryptedData() const
+{
+ return false;
+}
+
+/*!
+ \internal
+
+ Returns the list of OCSP (Online Certificate Status Protocol) responses,
+ received during the handshake. The default implementation returns an empty
+ list.
+*/
+QList<QOcspResponse> TlsCryptograph::ocsps() const
+{
+ return {};
+}
+
+/*!
+ \internal
+
+ A helper function that can be used during a handshake. Returns \c true if the \a peerName
+ matches one of subject alternative names or common names found in the \a certificate.
+*/
+bool TlsCryptograph::isMatchingHostname(const QSslCertificate &certificate, const QString &peerName)
+{
+ return QSslSocketPrivate::isMatchingHostname(certificate, peerName);
+}
+
+/*!
+ \internal
+ Calls QAbstractSocketPrivate::setErrorAndEmit() for \a d, passing \a errorCode and
+ \a errorDescription as parameters.
+*/
+void TlsCryptograph::setErrorAndEmit(QSslSocketPrivate *d, QAbstractSocket::SocketError errorCode,
+ const QString &errorDescription) const
+{
+ Q_ASSERT(d);
+ d->setErrorAndEmit(errorCode, errorDescription);
+}
+
+#if QT_CONFIG(dtls)
+/*!
+ \class DtlsBase
+ \internal (Network-private)
+ \brief DtlsBase is a base class for the classes DtlsCryptograph and DtlsCookieVerifier.
+
+ DtlsBase is the base class for the classes DtlsCryptograph and DtlsCookieVerifier. It's
+ an abstract class, an interface that these before-mentioned classes share. It allows to
+ set, get and clear the last error that occurred, set and get cookie generation parameters,
+ set and get QSslConfiguration.
+
+ \note This class is not supposed to be inherited directly, it's only needed by DtlsCryptograph
+ and DtlsCookieVerifier.
+
+ \sa QDtls, QDtlsClientVerifier, DtlsCryptograph, DtlsCookieVerifier
+*/
+
+/*!
+ \fn void DtlsBase::setDtlsError(QDtlsError code, const QString &description)
+ \internal
+
+ Sets the last error to \a code and its textual description to \a description.
+
+ \sa QDtlsError, error(), errorString()
+*/
+
+/*!
+ \fn QDtlsError DtlsBase::error() const
+ \internal
+
+ This function, when overridden, is expected to return the code for the last error that occurred.
+ If no error occurred it should return QDtlsError::NoError.
+
+ \sa QDtlsError, errorString(), setDtlsError()
+*/
+
+/*!
+ \fn QDtlsError DtlsBase::errorString() const
+ \internal
+
+ This function, when overridden, is expected to return the textual description for the last error
+ that occurred or an empty string if no error occurred.
+
+ \sa QDtlsError, error(), setDtlsError()
+*/
+
+/*!
+ \fn void DtlsBase::clearDtlsError()
+ \internal
+
+ This function is expected to set the error code for the last error to QDtlsError::NoError and
+ its textual description to an empty string.
+
+ \sa QDtlsError, setDtlsError(), error(), errorString()
+*/
+
+/*!
+ \fn void DtlsBase::setConfiguration(const QSslConfiguration &configuration)
+ \internal
+
+ Sets a TLS configuration that an object of a class inheriting from DtlsCookieVerifier or
+ DtlsCryptograph will use, to \a configuration.
+
+ \sa configuration()
+*/
+
+/*!
+ \fn QSslConfiguration DtlsBase::configuration() const
+ \internal
+
+ Returns TLS configuration this object is using (either set by setConfiguration()
+ previously, or the default DTLS configuration).
+
+ \sa setConfiguration(), QSslConfiguration::defaultDtlsConfiguration()
+*/
+
+/*!
+ \fn bool DtlsBase::setCookieGeneratorParameters(const QDtlsClientVerifier::GeneratorParameters &params)
+ \internal
+
+ Sets the DTLS cookie generation parameters that DtlsCookieVerifier or DtlsCryptograph will use to
+ \a params.
+
+ \note This function returns \c false if parameters were invalid - if the secret was empty. Otherwise,
+ this function must return true.
+
+ \sa QDtlsClientVerifier::GeneratorParameters, cookieGeneratorParameters()
+*/
+
+/*!
+ \fn QDtlsClientVerifier::GeneratorParameters DtlsBase::cookieGeneratorParameters() const
+ \internal
+
+ Returns DTLS cookie generation parameters that were either previously set by setCookieGeneratorParameters(),
+ or default parameters.
+
+ \sa setCookieGeneratorParameters()
+*/
+
+/*!
+ \internal
+
+ Destroys this object.
+*/
+DtlsBase::~DtlsBase() = default;
+
+/*!
+ \class DtlsCookieVerifier
+ \internal (Network-private)
+ \brief DtlsCookieVerifier is an interface that allows a TLS plugin to support the class QDtlsClientVerifier.
+
+ DtlsCookieVerifier is an interface, an abstract class, that has to be implemented by
+ a TLS plugin that supports DTLS cookie verification.
+
+ \sa QDtlsClientVerifier
+*/
+
+/*!
+ \fn bool DtlsCookieVerifier::verifyClient(QUdpSocket *socket, const QByteArray &dgram, const QHostAddress &address, quint16 port)
+ \internal
+
+ This function is expected to verify a ClientHello message, found in \a dgram, using \a address,
+ \a port, and cookie generator parameters. The function returns \c true if such cookie was found
+ and \c false otherwise. If no valid cookie was found in the \a dgram, this verifier should use
+ \a socket to send a HelloVerifyRequest message, using \a address and \a port as the destination
+ and a source material for cookie generation, see also
+ \l {RFC 6347, section 4.2.1}
+
+ \sa QDtlsClientVerifier
+*/
+
+/*!
+ \fn QByteArray DtlsCookieVerifier::verifiedHello() const
+ \internal
+
+ Returns the last ClientHello message containing the DTLS cookie that this verifier was
+ able to verify as correct, or an empty byte array.
+
+ \sa verifyClient()
+*/
+
+/*!
+ \class DtlsCryptograph
+ \internal (Network-private)
+ \brief DtlsCryptograph is an interface that allows a TLS plugin to implement the class QDtls.
+
+ DtlsCryptograph is an abstract class; a TLS plugin can provide a class, inheriting from
+ DtlsCryptograph and implementing its pure virtual functions, thus implementing the class
+ QDtls and enabling DTLS over UDP.
+
+ To write DTLS datagrams, a class, inheriting DtlsCryptograph, is expected to use
+ QUdpSocket. In general, all reading is done externally, so DtlsCryptograph is
+ expected to only write into QUdpSocket, check possible socket errors, change socket
+ options if needed.
+
+ \note All functions in this class are pure virtual and have no actual implementation
+ in the QtNetwork module. This documentation is mostly conceptual and only describes
+ what those functions are expected to do, but not how they must be implemented.
+
+ \sa QDtls, QUdpSocket
+*/
+
+/*!
+ \fn QSslSocket::SslMode DtlsCryptograph::cryptographMode() const
+ \internal
+
+ Returns the mode (client or server) this object operates in.
+
+ \note This mode is set once when a new DtlsCryptograph is created
+ by QTlsBackend and cannot change.
+
+ \sa QTlsBackend::createDtlsCryptograph()
+*/
+
+/*!
+ \fn void DtlsCryptograph::setPeer(const QHostAddress &addr, quint16 port, const QString &name)
+ \internal
+
+ Sets the remote peer's address to \a addr and remote port to \a port. \a name,
+ if not empty, is to be used when validating the peer's certificate.
+
+ \sa peerAddress(), peerPort(), peerVerificationName()
+*/
+
+/*!
+ \fn QHostAddress DtlsCryptograph::peerAddress() const
+ \internal
+
+ Returns the remote peer's address previously set by setPeer() or,
+ if no address was set, an empty address.
+
+ \sa setPeer()
+*/
+
+/*!
+ \fn quint16 DtlsCryptograph::peerPort() const
+ \internal
+
+ Returns the remote peer's port previously set by setPeer() or
+ 0 if no port was set.
+
+ \sa setPeer(), peerAddress()
+*/
+
+/*!
+ \fn void DtlsCryptograph::setPeerVerificationName(const QString &name)
+ \internal
+
+ Sets the host name to use during certificate validation to \a name.
+
+ \sa peerVerificationName(), setPeer()
+*/
+
+/*!
+ \fn QString DtlsCryptograph::peerVerificationName() const
+ \internal
+
+ Returns the name that this object is using during the certificate validation,
+ previously set by setPeer() or setPeerVerificationName(). Returns an empty string
+ if no peer verification name was set.
+
+ \sa setPeer(), setPeerVerificationName()
+*/
+
+/*!
+ \fn void DtlsCryptograph::setDtlsMtuHint(quint16 mtu)
+ \internal
+
+ Sets the maximum transmission unit (MTU), if it is supported by a TLS implementation, to \a mtu.
+
+ \sa dtlsMtuHint()
+*/
+
+/*!
+ \fn quint16 DtlsCryptograph::dtlsMtuHint() const
+ \internal
+
+ Returns the value of the maximum transmission unit either previously set by setDtlsMtuHint(),
+ or some implementation-specific value (guessed or somehow known to this DtlsCryptograph).
+
+ \sa setDtlsMtuHint()
+*/
+
+/*!
+ \fn QDtls::HandshakeState DtlsCryptograph::state() const
+ \internal
+
+ Returns the current handshake state for this DtlsCryptograph (not started, in progress,
+ peer verification error found, complete).
+
+ \sa isConnectionEncrypted(), startHandshake()
+*/
+
+/*!
+ \fn bool DtlsCryptograph::isConnectionEncrypted() const
+ \internal
+
+ Returns \c true if this DtlsCryptograph has completed a handshake without validation
+ errors (or these errors were ignored). Returns \c false otherwise.
+*/
+
+/*!
+ \fn bool DtlsCryptograph::startHandshake(QUdpSocket *socket, const QByteArray &dgram)
+ \internal
+
+ This function is expected to initialize some implementation-specific context and to start a DTLS
+ handshake, using \a socket to write datagrams (but not to read them). If this object is operating
+ as a server, \a dgram is non-empty and contains the ClientHello message. This function returns
+ \c true if no error occurred (and this DtlsCryptograph's state switching to
+ QDtls::HandshakeState::HandshakeInProgress), \c false otherwise.
+
+ \sa continueHandshake(), handleTimeout(), resumeHandshake(), abortHandshake(), state()
+*/
+
+/*!
+ \fn bool DtlsCryptograph::handleTimeout(QUdpSocket *socket)
+ \internal
+
+ In case a timeout occurred during the handshake, allows to re-transmit the last message,
+ using \a socket to write the datagram. Returns \c true if no error occurred, \c false otherwise.
+
+ \sa QDtls::handshakeTimeout(), QDtls::handleTimeout()
+*/
+
+/*!
+ \fn bool DtlsCryptograph::continueHandshake(QUdpSocket *socket, const QByteArray &dgram)
+ \internal
+
+ Continues the handshake, using \a socket to write datagrams (a handshake-specific message).
+ \a dgram contains the peer's handshake-specific message. Returns \c false in case some error
+ was encountered (this can include socket-related errors and errors found during the certificate
+ validation). Returns \c true if the handshake was complete successfully, or is still in progress.
+
+ This function, depending on the implementation-specific state machine, may leave the handshake
+ state in QDtls::HandshakeState::HandshakeInProgress, or switch to QDtls::HandshakeState::HandshakeComplete
+ or QDtls::HandshakeState::PeerVerificationFailed.
+
+ This function may store the peer's certificate (or chain of certificates), extract and store
+ the information about the negotiated session protocol and ciphersuite.
+
+ \sa startHandshake()
+*/
+
+/*!
+ \fn bool DtlsCryptograph::resumeHandshake(QUdpSocket *socket)
+ \internal
+
+ If peer validation errors were found duing the handshake, this function tries to
+ continue and complete the handshake. If errors were ignored, the function switches
+ this object's state to QDtls::HandshakeState::HandshakeComplete and returns \c true.
+
+ \sa abortHandshake()
+*/
+
+/*!
+ \fn void DtlsCryptograph::abortHandshake(QUdpSocket *socket)
+ \internal
+
+ Aborts the handshake if it's in progress or in the state QDtls::HandshakeState::PeerVerificationFailed.
+ The use of \a socket is implementation-specific (for example, this DtlsCryptograph may send
+ ShutdownAlert message).
+
+ \sa resumeHandshake()
+*/
+
+/*!
+ \fn void DtlsCryptograph::sendShutdownAlert(QUdpSocket *socket)
+ \internal
+
+ If the underlying TLS library provides the required functionality, this function
+ may sent ShutdownAlert message using \a socket.
+*/
+
+/*!
+ \fn QList<QSslError> DtlsCryptograph::peerVerificationErrors() const
+ \internal
+
+ Returns the list of errors that this object encountered during DTLS handshake
+ and certificate validation.
+
+ \sa ignoreVerificationErrors()
+*/
+
+/*!
+ \fn void DtlsCryptograph::ignoreVerificationErrors(const QList<QSslError> &errorsToIgnore)
+ \internal
+
+ Tells this object to ignore errors from \a errorsToIgnore when they are found during
+ DTLS handshake.
+
+ \sa peerVerificationErrors()
+*/
+
+/*!
+ \fn QSslCipher DtlsCryptograph::dtlsSessionCipher() const
+ \internal
+
+ If such information is available, returns the ciphersuite, negotiated during
+ the handshake.
+
+ \sa continueHandshake(), dtlsSessionProtocol()
+*/
+
+/*!
+ \fn QSsl::SslProtocol DtlsCryptograph::dtlsSessionProtocol() const
+ \internal
+
+ Returns the version of the session protocol that was negotiated during the handshake or
+ QSsl::UnknownProtocol if the handshake is incomplete or no information about the session
+ protocol is available.
+
+ \sa continueHandshake(), dtlsSessionCipher()
+*/
+
+/*!
+ \fn qint64 DtlsCryptograph::writeDatagramEncrypted(QUdpSocket *socket, const QByteArray &dgram)
+ \internal
+
+ If this DtlsCryptograph is in the QDtls::HandshakeState::HandshakeComplete state, this function
+ encrypts \a dgram and writes this encrypted data into \a socket.
+
+ Returns the number of bytes (of \a dgram) written, or -1 in case of error. This function should
+ set the error code and description if some error was encountered.
+
+ \sa decryptDatagram()
+*/
+
+/*!
+ \fn QByteArray DtlsCryptograph::decryptDatagram(QUdpSocket *socket, const QByteArray &dgram)
+ \internal
+
+ If this DtlsCryptograph is in the QDtls::HandshakeState::HandshakeComplete state, decrypts \a dgram.
+ The use of \a socket is implementation-specific. This function should return an empty byte array
+ and set the error code and description if some error was encountered.
+*/
+
+#endif // QT_CONFIG(dtls)
+#endif // QT_CONFIG(ssl)
+
+} // namespace QTlsPrivate
+
+#if QT_CONFIG(ssl)
+/*!
+ \internal
+*/
+Q_NETWORK_EXPORT void qt_ForceTlsSecurityLevel()
+{
+ if (auto *backend = QSslSocketPrivate::tlsBackendInUse())
+ backend->forceAutotestSecurityLevel();
+}
+
+#endif // QT_CONFIG(ssl)
+
+QT_END_NAMESPACE
+
+#include "moc_qtlsbackend_p.cpp"