Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qtlsbackend.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
6
7#if QT_CONFIG(ssl)
8#include "qsslpresharedkeyauthenticator_p.h"
9#include "qsslpresharedkeyauthenticator.h"
10#include "qsslsocket_p.h"
11#include "qsslcipher_p.h"
12#include "qsslkey_p.h"
13#include "qsslkey.h"
14#endif
15
16#include "qssl_p.h"
17
18#include <QtCore/private/qfactoryloader_p.h>
19
20#include "QtCore/qapplicationstatic.h"
21#include <QtCore/qbytearray.h>
22#include <QtCore/qmutex.h>
23
24#include <algorithm>
25#include <vector>
26
27QT_BEGIN_NAMESPACE
28
29using namespace Qt::StringLiterals;
30
31Q_APPLICATION_STATIC(QFactoryLoader, qtlsbLoader, QTlsBackend_iid,
32 QStringLiteral("/tls"))
33
34namespace {
35
36class BackendCollection
37{
38public:
39 void addBackend(QTlsBackend *backend)
40 {
41 Q_ASSERT(backend);
42 Q_ASSERT(std::find(backends.begin(), backends.end(), backend) == backends.end());
43 const QMutexLocker locker(&collectionMutex);
44 backends.push_back(backend);
45 }
46
47 void removeBackend(QTlsBackend *backend)
48 {
49 Q_ASSERT(backend);
50 const QMutexLocker locker(&collectionMutex);
51 const auto it = std::find(backends.begin(), backends.end(), backend);
52 Q_ASSERT(it != backends.end());
53 backends.erase(it);
54 }
55
56 bool tryPopulateCollection()
57 {
58 if (!qtlsbLoader())
59 return false;
60
61 Q_CONSTINIT static QBasicMutex mutex;
62 const QMutexLocker locker(&mutex);
63 if (backends.size())
64 return true;
65
66#if QT_CONFIG(library)
67 qtlsbLoader->update();
68#endif
69 int index = 0;
70 while (qtlsbLoader->instance(index))
71 ++index;
72
73 return true;
74 }
75
76 QList<QString> backendNames()
77 {
78 QList<QString> names;
79 if (!tryPopulateCollection())
80 return names;
81
82 const QMutexLocker locker(&collectionMutex);
83 if (!backends.size())
84 return names;
85
86 names.reserve(backends.size());
87 for (const auto *backend : backends) {
88 if (backend->isValid())
89 names.append(backend->backendName());
90 }
91
92 return names;
93 }
94
95 QTlsBackend *backend(const QString &name)
96 {
97 if (!tryPopulateCollection())
98 return nullptr;
99
100 const QMutexLocker locker(&collectionMutex);
101 const auto it = std::find_if(backends.begin(), backends.end(),
102 [&name](const auto *fct) {return fct->backendName() == name;});
103
104 return it == backends.end() ? nullptr : *it;
105 }
106
107private:
108 std::vector<QTlsBackend *> backends;
109 QMutex collectionMutex;
110};
111
112} // Unnamed namespace
113
114Q_GLOBAL_STATIC(BackendCollection, backends);
115
116/*!
117 \class QTlsBackend
118 \internal (Network-private)
119 \brief QTlsBackend is a factory class, providing implementations
120 for the QSsl classes.
121
122 The purpose of QTlsBackend is to enable and simplify the addition
123 of new TLS backends to be used by QSslSocket and related classes.
124 Starting from Qt 6.1, these backends have plugin-based design (and
125 thus can co-exist simultaneously, unlike pre 6.1 times), although
126 any given run of a program can only use one of them.
127
128 Inheriting from QTlsBackend and creating an object of such
129 a class adds a new backend into the list of available TLS backends.
130
131 A new backend must provide a list of classes, features and protocols
132 it supports, and override the corresponding virtual functions that
133 create backend-specific implementations for these QSsl-classes.
134
135 The base abstract class - QTlsBackend - provides, where possible,
136 default implementations of its virtual member functions. These
137 default implementations can be overridden by a derived backend
138 class, if needed.
139
140 QTlsBackend also provides some auxiliary functions that a derived
141 backend class can use to interact with the internals of network-private classes.
142
143 \sa QSslSocket::availableBackends(), supportedFeatures(), supportedProtocols(), implementedClasses()
144*/
145
146/*!
147 \fn QString QTlsBackend::backendName() const
148 \internal
149 Returns the name of this backend. The name will be reported by QSslSocket::availableBackends().
150 Example of backend names: "openssl", "schannel", "securetransport".
151
152 \sa QSslSocket::availableBackends(), isValid()
153*/
154
155const QString QTlsBackend::builtinBackendNames[] = {
156 QStringLiteral("schannel"),
157 QStringLiteral("securetransport"),
158 QStringLiteral("openssl"),
159 QStringLiteral("cert-only")
160};
161
162/*!
163 \internal
164 The default constructor, adds a new backend to the list of available backends.
165
166 \sa ~QTlsBackend(), availableBackendNames(), QSslSocket::availableBackends()
167*/
168QTlsBackend::QTlsBackend()
169{
170 if (backends())
171 backends->addBackend(this);
172
173 if (QCoreApplication::instance()) {
174 connect(QCoreApplication::instance(), &QCoreApplication::destroyed, this, [this] {
175 delete this;
176 });
177 }
178}
179
180/*!
181 \internal
182 Removes this backend from the list of available backends.
183
184 \sa QTlsBackend(), availableBackendNames(), QSslSocket::availableBackends()
185*/
186QTlsBackend::~QTlsBackend()
187{
188 if (backends())
189 backends->removeBackend(this);
190}
191
192/*!
193 \internal
194 Returns \c true if this backend was initialised successfully. The default implementation
195 always returns \c true.
196
197 \note This function must be overridden if a particular backend has a non-trivial initialization
198 that can fail. If reimplemented, returning \c false will exclude this backend from the list of
199 backends, reported as available by QSslSocket.
200
201 \sa QSslSocket::availableBackends()
202*/
203
204bool QTlsBackend::isValid() const
205{
206 return true;
207}
208
209/*!
210 \internal
211 Returns an implementations-specific integer value, representing the TLS library's
212 version, that is currently used by this backend (i.e. runtime library version).
213 The default implementation returns 0.
214
215 \sa tlsLibraryBuildVersionNumber()
216*/
217long QTlsBackend::tlsLibraryVersionNumber() const
218{
219 return 0;
220}
221
222/*!
223 \internal
224 Returns an implementation-specific string, representing the TLS library's version,
225 that is currently used by this backend (i.e. runtime library version). The default
226 implementation returns an empty string.
227
228 \sa tlsLibraryBuildVersionString()
229*/
230
231QString QTlsBackend::tlsLibraryVersionString() const
232{
233 return {};
234}
235
236/*!
237 \internal
238 Returns an implementation-specific integer value, representing the TLS library's
239 version that this backend was built against (i.e. compile-time library version).
240 The default implementation returns 0.
241
242 \sa tlsLibraryVersionNumber()
243*/
244
245long QTlsBackend::tlsLibraryBuildVersionNumber() const
246{
247 return 0;
248}
249
250/*!
251 \internal
252 Returns an implementation-specific string, representing the TLS library's version
253 that this backend was built against (i.e. compile-time version). The default
254 implementation returns an empty string.
255
256 \sa tlsLibraryVersionString()
257*/
258QString QTlsBackend::tlsLibraryBuildVersionString() const
259{
260 return {};
261}
262
263/*!
264 \internal
265 QSslSocket and related classes call this function to ensure that backend's internal
266 resources - e.g. CA certificates, or ciphersuites - were properly initialized.
267*/
268void QTlsBackend::ensureInitialized() const
269{
270}
271
272#define REPORT_MISSING_SUPPORT(message)
273 qCWarning(lcSsl) << "The backend" << backendName() << message
274
275/*!
276 \internal
277 If QSsl::ImplementedClass::Key is present in this backend's implementedClasses(),
278 the backend must reimplement this method to return a dynamically-allocated instance
279 of an implementation-specific type, inheriting from the class QTlsPrivate::TlsKey.
280 The default implementation of this function returns \nullptr.
281
282 \sa QSslKey, implementedClasses(), QTlsPrivate::TlsKey
283*/
284QTlsPrivate::TlsKey *QTlsBackend::createKey() const
285{
286 REPORT_MISSING_SUPPORT("does not support QSslKey");
287 return nullptr;
288}
289
290/*!
291 \internal
292 If QSsl::ImplementedClass::Certificate is present in this backend's implementedClasses(),
293 the backend must reimplement this method to return a dynamically-allocated instance of an
294 implementation-specific type, inheriting from the class QTlsPrivate::X509Certificate.
295 The default implementation of this function returns \nullptr.
296
297 \sa QSslCertificate, QTlsPrivate::X509Certificate, implementedClasses()
298*/
299QTlsPrivate::X509Certificate *QTlsBackend::createCertificate() const
300{
301 REPORT_MISSING_SUPPORT("does not support QSslCertificate");
302 return nullptr;
303}
304
305/*!
306 \internal
307 This function returns a list of system CA certificates - e.g. certificates, loaded
308 from a system store, if available. This function allows implementation of the class
309 QSslConfiguration. The default implementation of this function returns an empty list.
310
311 \sa QSslCertificate, QSslConfiguration
312*/
313QList<QSslCertificate> QTlsBackend::systemCaCertificates() const
314{
315 REPORT_MISSING_SUPPORT("does not provide system CA certificates");
316 return {};
317}
318
319/*!
320 \internal
321 If QSsl::ImplementedClass::Socket is present in this backend's implementedClasses(),
322 the backend must reimplement this method to return a dynamically-allocated instance of an
323 implementation-specific type, inheriting from the class QTlsPrivate::TlsCryptograph.
324 The default implementation of this function returns \nullptr.
325
326 \sa QSslSocket, QTlsPrivate::TlsCryptograph, implementedClasses()
327*/
328QTlsPrivate::TlsCryptograph *QTlsBackend::createTlsCryptograph() const
329{
330 REPORT_MISSING_SUPPORT("does not support QSslSocket");
331 return nullptr;
332}
333
334/*!
335 \internal
336 If QSsl::ImplementedClass::Dtls is present in this backend's implementedClasses(),
337 the backend must reimplement this method to return a dynamically-allocated instance of an
338 implementation-specific type, inheriting from the class QTlsPrivate::DtlsCryptograph.
339 The default implementation of this function returns \nullptr.
340
341 \sa QDtls, QTlsPrivate::DtlsCryptograph, implementedClasses()
342*/
343QTlsPrivate::DtlsCryptograph *QTlsBackend::createDtlsCryptograph(QDtls *qObject, int mode) const
344{
345 Q_UNUSED(qObject);
346 Q_UNUSED(mode);
347 REPORT_MISSING_SUPPORT("does not support QDtls");
348 return nullptr;
349}
350
351/*!
352 \internal
353 If QSsl::ImplementedClass::DtlsCookie is present in this backend's implementedClasses(),
354 the backend must reimplement this method to return a dynamically-allocated instance of an
355 implementation-specific type, inheriting from the class QTlsPrivate::DtlsCookieVerifier. The
356 default implementation returns \nullptr.
357
358 \sa QDtlsClientVerifier, QTlsPrivate::DtlsCookieVerifier, implementedClasses()
359*/
360QTlsPrivate::DtlsCookieVerifier *QTlsBackend::createDtlsCookieVerifier() const
361{
362 REPORT_MISSING_SUPPORT("does not support DTLS cookies");
363 return nullptr;
364}
365
366/*!
367 \internal
368 If QSsl::SupportedFeature::CertificateVerification is present in this backend's
369 supportedFeatures(), the backend must reimplement this method to return a pointer
370 to a function, that checks a certificate (or a chain of certificates) against available
371 CA certificates. The default implementation returns \nullptr.
372
373 \sa supportedFeatures(), QSslCertificate
374*/
375
376QTlsPrivate::X509ChainVerifyPtr QTlsBackend::X509Verifier() const
377{
378 REPORT_MISSING_SUPPORT("does not support (manual) certificate verification");
379 return nullptr;
380}
381
382/*!
383 \internal
384 Returns a pointer to function, that reads certificates in PEM format. The
385 default implementation returns \nullptr.
386
387 \sa QSslCertificate
388*/
389QTlsPrivate::X509PemReaderPtr QTlsBackend::X509PemReader() const
390{
391 REPORT_MISSING_SUPPORT("cannot read PEM format");
392 return nullptr;
393}
394
395/*!
396 \internal
397 Returns a pointer to function, that can read certificates in DER format.
398 The default implementation returns \nullptr.
399
400 \sa QSslCertificate
401*/
402QTlsPrivate::X509DerReaderPtr QTlsBackend::X509DerReader() const
403{
404 REPORT_MISSING_SUPPORT("cannot read DER format");
405 return nullptr;
406}
407
408/*!
409 \internal
410 Returns a pointer to function, that can read certificates in PKCS 12 format.
411 The default implementation returns \nullptr.
412
413 \sa QSslCertificate
414*/
415QTlsPrivate::X509Pkcs12ReaderPtr QTlsBackend::X509Pkcs12Reader() const
416{
417 REPORT_MISSING_SUPPORT("cannot read PKCS12 format");
418 return nullptr;
419}
420
421/*!
422 \internal
423 If QSsl::ImplementedClass::EllipticCurve is present in this backend's implementedClasses(),
424 and the backend provides information about supported curves, it must reimplement this
425 method to return a list of unique identifiers of the supported elliptic curves. The default
426 implementation returns an empty list.
427
428 \note The meaning of a curve identifier is implementation-specific.
429
430 \sa implemenedClasses(), QSslEllipticCurve
431*/
432QList<int> QTlsBackend::ellipticCurvesIds() const
433{
434 REPORT_MISSING_SUPPORT("does not support QSslEllipticCurve");
435 return {};
436}
437
438/*!
439 \internal
440 If this backend provides information about available elliptic curves, this
441 function should return a unique integer identifier for a curve named \a name,
442 which is a conventional short name for the curve. The default implementation
443 returns 0.
444
445 \note The meaning of a curve identifier is implementation-specific.
446
447 \sa QSslEllipticCurve::shortName()
448*/
449int QTlsBackend::curveIdFromShortName(const QString &name) const
450{
451 Q_UNUSED(name);
452 REPORT_MISSING_SUPPORT("does not support QSslEllipticCurve");
453 return 0;
454}
455
456/*!
457 \internal
458 If this backend provides information about available elliptic curves, this
459 function should return a unique integer identifier for a curve named \a name,
460 which is a conventional long name for the curve. The default implementation
461 returns 0.
462
463 \note The meaning of a curve identifier is implementation-specific.
464
465 \sa QSslElliptiCurve::longName()
466*/
467int QTlsBackend::curveIdFromLongName(const QString &name) const
468{
469 Q_UNUSED(name);
470 REPORT_MISSING_SUPPORT("does not support QSslEllipticCurve");
471 return 0;
472}
473
474/*!
475 \internal
476 If this backend provides information about available elliptic curves,
477 this function should return a conventional short name for a curve identified
478 by \a cid. The default implementation returns an empty string.
479
480 \note The meaning of a curve identifier is implementation-specific.
481
482 \sa ellipticCurvesIds(), QSslEllipticCurve::shortName()
483*/
484QString QTlsBackend::shortNameForId(int cid) const
485{
486 Q_UNUSED(cid);
487 REPORT_MISSING_SUPPORT("does not support QSslEllipticCurve");
488 return {};
489}
490
491/*!
492 \internal
493 If this backend provides information about available elliptic curves,
494 this function should return a conventional long name for a curve identified
495 by \a cid. The default implementation returns an empty string.
496
497 \note The meaning of a curve identifier is implementation-specific.
498
499 \sa ellipticCurvesIds(), QSslEllipticCurve::shortName()
500*/
501QString QTlsBackend::longNameForId(int cid) const
502{
503 Q_UNUSED(cid);
504 REPORT_MISSING_SUPPORT("does not support QSslEllipticCurve");
505 return {};
506}
507
508/*!
509 \internal
510 Returns true if the elliptic curve identified by \a cid is one of the named
511 curves, that can be used in the key exchange when using an elliptic curve
512 cipher with TLS; false otherwise. The default implementation returns false.
513
514 \note The meaning of curve identifier is implementation-specific.
515*/
516bool QTlsBackend::isTlsNamedCurve(int cid) const
517{
518 Q_UNUSED(cid);
519 REPORT_MISSING_SUPPORT("does not support QSslEllipticCurve");
520 return false;
521}
522
523/*!
524 \internal
525 If this backend supports the class QSslDiffieHellmanParameters, this function is
526 needed for construction of a QSslDiffieHellmanParameters from DER encoded data.
527 This function is expected to return a value that matches an enumerator in
528 QSslDiffieHellmanParameters::Error enumeration. The default implementation of this
529 function returns 0 (equals to QSslDiffieHellmanParameters::NoError).
530
531 \sa QSslDiffieHellmanParameters, implementedClasses()
532*/
533int QTlsBackend::dhParametersFromDer(const QByteArray &derData, QByteArray *data) const
534{
535 Q_UNUSED(derData);
536 Q_UNUSED(data);
537 REPORT_MISSING_SUPPORT("does not support QSslDiffieHellmanParameters in DER format");
538 return {};
539}
540
541/*!
542 \internal
543 If this backend supports the class QSslDiffieHellmanParameters, this function is
544 is needed for construction of a QSslDiffieHellmanParameters from PEM encoded data.
545 This function is expected to return a value that matches an enumerator in
546 QSslDiffieHellmanParameters::Error enumeration. The default implementation of this
547 function returns 0 (equals to QSslDiffieHellmanParameters::NoError).
548
549 \sa QSslDiffieHellmanParameters, implementedClasses()
550*/
551int QTlsBackend::dhParametersFromPem(const QByteArray &pemData, QByteArray *data) const
552{
553 Q_UNUSED(pemData);
554 Q_UNUSED(data);
555 REPORT_MISSING_SUPPORT("does not support QSslDiffieHellmanParameters in PEM format");
556 return {};
557}
558
559/*!
560 \internal
561 Returns a list of names of available backends.
562
563 \note This list contains only properly initialized backends.
564
565 \sa QTlsBackend(), isValid()
566*/
567QList<QString> QTlsBackend::availableBackendNames()
568{
569 if (!backends())
570 return {};
571
572 return backends->backendNames();
573}
574
575/*!
576 \internal
577 Returns the name of the backend that QSslSocket() would use by default. If no
578 backend was found, the function returns an empty string.
579*/
580QString QTlsBackend::defaultBackendName()
581{
582 // We prefer OpenSSL as default:
583 const auto names = availableBackendNames();
584 auto name = builtinBackendNames[nameIndexOpenSSL];
585 if (names.contains(name))
586 return name;
587 name = builtinBackendNames[nameIndexSchannel];
588 if (names.contains(name))
589 return name;
590 name = builtinBackendNames[nameIndexSecureTransport];
591 if (names.contains(name))
592 return name;
593
594 const auto pos = std::find_if(names.begin(), names.end(), [](const auto &name) {
595 return name != builtinBackendNames[nameIndexCertOnly];
596 });
597
598 if (pos != names.end())
599 return *pos;
600
601 if (names.size())
602 return names[0];
603
604 return {};
605}
606
607/*!
608 \internal
609 Returns a backend named \a backendName, if it exists.
610 Otherwise, it returns \nullptr.
611
612 \sa backendName(), QSslSocket::availableBackends()
613*/
614QTlsBackend *QTlsBackend::findBackend(const QString &backendName)
615{
616 if (!backends())
617 return {};
618
619 if (auto *fct = backends->backend(backendName))
620 return fct;
621
622 qCWarning(lcSsl) << "Cannot create unknown backend named" << backendName;
623 return nullptr;
624}
625
626/*!
627 \internal
628 Returns the backend that QSslSocket is using. If Qt was built without TLS support,
629 this function returns a minimal backend that only supports QSslCertificate.
630
631 \sa defaultBackend()
632*/
633QTlsBackend *QTlsBackend::activeOrAnyBackend()
634{
635#if QT_CONFIG(ssl)
636 return QSslSocketPrivate::tlsBackendInUse();
637#else
638 return findBackend(defaultBackendName());
639#endif // QT_CONFIG(ssl)
640}
641
642/*!
643 \internal
644 Returns a list of TLS and DTLS protocol versions, that a backend named
645 \a backendName supports.
646
647 \note This list is supposed to also include range-based versions, which
648 allows negotiation of protocols during the handshake, so that these versions
649 can be used when configuring QSslSocket (e.g. QSsl::TlsV1_2OrLater).
650
651 \sa QSsl::SslProtocol
652*/
653QList<QSsl::SslProtocol> QTlsBackend::supportedProtocols(const QString &backendName)
654{
655 if (!backends())
656 return {};
657
658 if (const auto *fct = backends->backend(backendName))
659 return fct->supportedProtocols();
660
661 return {};
662}
663
664/*!
665 \internal
666 Returns a list of features that a backend named \a backendName supports. E.g.
667 a backend may support PSK (pre-shared keys, defined as QSsl::SupportedFeature::Psk)
668 or ALPN (application layer protocol negotiation, identified by
669 QSsl::SupportedFeature::ClientSideAlpn or QSsl::SupportedFeature::ServerSideAlpn).
670
671 \sa QSsl::SupportedFeature
672*/
673QList<QSsl::SupportedFeature> QTlsBackend::supportedFeatures(const QString &backendName)
674{
675 if (!backends())
676 return {};
677
678 if (const auto *fct = backends->backend(backendName))
679 return fct->supportedFeatures();
680
681 return {};
682}
683
684/*!
685 \internal
686 Returns a list of classes that a backend named \a backendName supports. E.g. a backend
687 may implement QSslSocket (QSsl::ImplementedClass::Socket), and QDtls
688 (QSsl::ImplementedClass::Dtls).
689
690 \sa QSsl::ImplementedClass
691*/
692QList<QSsl::ImplementedClass> QTlsBackend::implementedClasses(const QString &backendName)
693{
694 if (!backends())
695 return {};
696
697 if (const auto *fct = backends->backend(backendName))
698 return fct->implementedClasses();
699
700 return {};
701}
702
703/*!
704 \internal
705 Auxiliary function. Initializes \a key to use \a keyBackend.
706*/
707void QTlsBackend::resetBackend(QSslKey &key, QTlsPrivate::TlsKey *keyBackend)
708{
709#if QT_CONFIG(ssl)
710 key.d->backend.reset(keyBackend);
711#else
712 Q_UNUSED(key);
713 Q_UNUSED(keyBackend);
714#endif // QT_CONFIG(ssl)
715}
716
717/*!
718 \internal
719 Auxiliary function. Initializes client-side \a auth using the \a hint, \a hintLength,
720 \a maxIdentityLength and \a maxPskLen.
721*/
722void QTlsBackend::setupClientPskAuth(QSslPreSharedKeyAuthenticator *auth, const char *hint,
723 int hintLength, unsigned maxIdentityLen, unsigned maxPskLen)
724{
725 Q_ASSERT(auth);
726#if QT_CONFIG(ssl)
727 if (hint)
728 auth->d->identityHint = QByteArray::fromRawData(hint, hintLength); // it's NUL terminated, but do not include the NUL
729
730 auth->d->maximumIdentityLength = int(maxIdentityLen) - 1; // needs to be NUL terminated
731 auth->d->maximumPreSharedKeyLength = int(maxPskLen);
732#else
733 Q_UNUSED(auth);
734 Q_UNUSED(hint);
735 Q_UNUSED(hintLength);
736 Q_UNUSED(maxIdentityLen);
737 Q_UNUSED(maxPskLen);
738#endif
739}
740
741/*!
742 \internal
743 Auxiliary function. Initializes server-side \a auth using the \a identity, \a identityHint and
744 \a maxPskLen.
745*/
746void QTlsBackend::setupServerPskAuth(QSslPreSharedKeyAuthenticator *auth, const char *identity,
747 const QByteArray &identityHint, unsigned int maxPskLen)
748{
749#if QT_CONFIG(ssl)
750 Q_ASSERT(auth);
751 auth->d->identityHint = identityHint;
752 auth->d->identity = identity;
753 auth->d->maximumIdentityLength = 0; // user cannot set an identity
754 auth->d->maximumPreSharedKeyLength = int(maxPskLen);
755#else
756 Q_UNUSED(auth);
757 Q_UNUSED(identity);
758 Q_UNUSED(identityHint);
759 Q_UNUSED(maxPskLen);
760#endif
761}
762
763#if QT_CONFIG(ssl)
764/*!
765 \internal
766 Auxiliary function. Creates a new QSslCipher from \a descriptionOneLine, \a bits
767 and \a supportedBits. \a descriptionOneLine consists of several fields, separated by
768 whitespace. These include: cipher name, protocol version, key exchange method,
769 authentication method, encryption method, message digest (Mac). Example:
770 "ECDHE-RSA-AES256-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD"
771*/
772QSslCipher QTlsBackend::createCiphersuite(const QString &descriptionOneLine, int bits, int supportedBits)
773{
774 QSslCipher ciph;
775
776 const auto descriptionList = QStringView{descriptionOneLine}.split(u' ', Qt::SkipEmptyParts);
777 if (descriptionList.size() > 5) {
778 ciph.d->isNull = false;
779 ciph.d->name = descriptionList.at(0).toString();
780
781 QStringView protoString = descriptionList.at(1);
782 ciph.d->protocolString = protoString.toString();
783 ciph.d->protocol = QSsl::UnknownProtocol;
784QT_WARNING_PUSH
785QT_WARNING_DISABLE_DEPRECATED
786 if (protoString.startsWith(u"TLSv1")) {
787 QStringView tail = protoString.sliced(5);
788 if (tail.startsWith(u'.')) {
789 tail = tail.sliced(1);
790 if (tail == u"3")
791 ciph.d->protocol = QSsl::TlsV1_3;
792 else if (tail == u"2")
793 ciph.d->protocol = QSsl::TlsV1_2;
794 else if (tail == u"1")
795 ciph.d->protocol = QSsl::TlsV1_1;
796 } else if (tail.isEmpty()) {
797 ciph.d->protocol = QSsl::TlsV1_0;
798 }
799 }
800QT_WARNING_POP
801
802 if (descriptionList.at(2).startsWith("Kx="_L1))
803 ciph.d->keyExchangeMethod = descriptionList.at(2).mid(3).toString();
804 if (descriptionList.at(3).startsWith("Au="_L1))
805 ciph.d->authenticationMethod = descriptionList.at(3).mid(3).toString();
806 if (descriptionList.at(4).startsWith("Enc="_L1))
807 ciph.d->encryptionMethod = descriptionList.at(4).mid(4).toString();
808 ciph.d->exportable = (descriptionList.size() > 6 && descriptionList.at(6) == "export"_L1);
809
810 ciph.d->bits = bits;
811 ciph.d->supportedBits = supportedBits;
812 }
813
814 return ciph;
815}
816
817/*!
818 \internal
819 Auxiliary function. Creates a new QSslCipher from \a suiteName, \a protocol version and
820 \a protocolString. For example:
821 \code
822 createCiphersuite("ECDHE-RSA-AES256-GCM-SHA256"_L1, QSsl::TlsV1_2, "TLSv1.2"_L1);
823 \endcode
824*/
825QSslCipher QTlsBackend::createCiphersuite(const QString &suiteName, QSsl::SslProtocol protocol,
826 const QString &protocolString)
827{
828 QSslCipher ciph;
829
830 if (!suiteName.size())
831 return ciph;
832
833 ciph.d->isNull = false;
834 ciph.d->name = suiteName;
835 ciph.d->protocol = protocol;
836 ciph.d->protocolString = protocolString;
837
838 const auto bits = QStringView{ciph.d->name}.split(u'-');
839 if (bits.size() >= 2) {
840 if (bits.size() == 2 || bits.size() == 3)
841 ciph.d->keyExchangeMethod = "RSA"_L1;
842 else if (bits.front() == "DH"_L1 || bits.front() == "DHE"_L1)
843 ciph.d->keyExchangeMethod = "DH"_L1;
844 else if (bits.front() == "ECDH"_L1 || bits.front() == "ECDHE"_L1)
845 ciph.d->keyExchangeMethod = "ECDH"_L1;
846 else
847 qCWarning(lcSsl) << "Unknown Kx" << ciph.d->name;
848
849 if (bits.size() == 2 || bits.size() == 3)
850 ciph.d->authenticationMethod = "RSA"_L1;
851 else if (ciph.d->name.contains("-ECDSA-"_L1))
852 ciph.d->authenticationMethod = "ECDSA"_L1;
853 else if (ciph.d->name.contains("-RSA-"_L1))
854 ciph.d->authenticationMethod = "RSA"_L1;
855 else
856 qCWarning(lcSsl) << "Unknown Au" << ciph.d->name;
857
858 if (ciph.d->name.contains("RC4-"_L1)) {
859 ciph.d->encryptionMethod = "RC4(128)"_L1;
860 ciph.d->bits = 128;
861 ciph.d->supportedBits = 128;
862 } else if (ciph.d->name.contains("DES-CBC3-"_L1)) {
863 ciph.d->encryptionMethod = "3DES(168)"_L1;
864 ciph.d->bits = 168;
865 ciph.d->supportedBits = 168;
866 } else if (ciph.d->name.contains("AES128-"_L1)) {
867 ciph.d->encryptionMethod = "AES(128)"_L1;
868 ciph.d->bits = 128;
869 ciph.d->supportedBits = 128;
870 } else if (ciph.d->name.contains("AES256-GCM"_L1)) {
871 ciph.d->encryptionMethod = "AESGCM(256)"_L1;
872 ciph.d->bits = 256;
873 ciph.d->supportedBits = 256;
874 } else if (ciph.d->name.contains("AES256-"_L1)) {
875 ciph.d->encryptionMethod = "AES(256)"_L1;
876 ciph.d->bits = 256;
877 ciph.d->supportedBits = 256;
878 } else if (ciph.d->name.contains("CHACHA20-"_L1)) {
879 ciph.d->encryptionMethod = "CHACHA20"_L1;
880 ciph.d->bits = 256;
881 ciph.d->supportedBits = 256;
882 } else if (ciph.d->name.contains("NULL-"_L1)) {
883 ciph.d->encryptionMethod = "NULL"_L1;
884 } else {
885 qCWarning(lcSsl) << "Unknown Enc" << ciph.d->name;
886 }
887 }
888 return ciph;
889}
890
891/*!
892 \internal
893 Auxiliary function. Creates a new QSslCipher from \a name, \a keyExchangeMethod, \a encryptionMethod,
894 \a authenticationMethod, \a bits, \a protocol version and \a protocolString.
895 For example:
896 \code
897 createCiphersuite("ECDHE-RSA-AES256-GCM-SHA256"_L1, "ECDH"_L1, "AES"_L1, "RSA"_L1, 256,
898 QSsl::TlsV1_2, "TLSv1.2"_L1);
899 \endcode
900*/
901QSslCipher QTlsBackend::createCiphersuite(const QString &name, const QString &keyExchangeMethod,
902 const QString &encryptionMethod,
903 const QString &authenticationMethod,
904 int bits, QSsl::SslProtocol protocol,
905 const QString &protocolString)
906{
907 QSslCipher cipher;
908 cipher.d->isNull = false;
909 cipher.d->name = name;
910 cipher.d->bits = bits;
911 cipher.d->supportedBits = bits;
912 cipher.d->keyExchangeMethod = keyExchangeMethod;
913 cipher.d->encryptionMethod = encryptionMethod;
914 cipher.d->authenticationMethod = authenticationMethod;
915 cipher.d->protocol = protocol;
916 cipher.d->protocolString = protocolString;
917 return cipher;
918}
919
920/*!
921 \internal
922 Returns an implementation-specific list of ciphersuites that can be used by QSslSocket.
923
924 \sa QSslConfiguration::defaultCiphers()
925*/
926QList<QSslCipher> QTlsBackend::defaultCiphers()
927{
928 return QSslSocketPrivate::defaultCiphers();
929}
930
931/*!
932 \internal
933 Returns an implementation-specific list of ciphersuites that can be used by QDtls.
934*/
935QList<QSslCipher> QTlsBackend::defaultDtlsCiphers()
936{
937 return QSslSocketPrivate::defaultDtlsCiphers();
938}
939
940/*!
941 \internal
942 Sets \a ciphers as defaults ciphers that QSslSocket can use.
943
944 \sa defaultCiphers()
945*/
946void QTlsBackend::setDefaultCiphers(const QList<QSslCipher> &ciphers)
947{
948 QSslSocketPrivate::setDefaultCiphers(ciphers);
949}
950
951/*!
952 \internal
953 Sets \a ciphers as defaults ciphers that QDtls can use.
954
955 \sa defaultDtlsCiphers()
956*/
957void QTlsBackend::setDefaultDtlsCiphers(const QList<QSslCipher> &ciphers)
958{
959 QSslSocketPrivate::setDefaultDtlsCiphers(ciphers);
960}
961
962/*!
963 \internal
964 Sets \a ciphers as a list of supported ciphers.
965
966 \sa QSslConfiguration::supportedCiphers()
967*/
968void QTlsBackend::setDefaultSupportedCiphers(const QList<QSslCipher> &ciphers)
969{
970 QSslSocketPrivate::setDefaultSupportedCiphers(ciphers);
971}
972
973/*!
974 \internal
975 Sets the list of QSslEllipticCurve objects, that QSslConfiguration::supportedEllipticCurves()
976 returns, to ones that are supported by this backend.
977*/
978void QTlsBackend::resetDefaultEllipticCurves()
979{
980 QSslSocketPrivate::resetDefaultEllipticCurves();
981}
982
983/*!
984 Sets \a certs as a list of certificates, that QSslConfiguration::caCertificates()
985 reports.
986
987 \sa QSslConfiguration::defaultConfiguration(), QSslConfiguration::caCertificates()
988*/
989void QTlsBackend::setDefaultCaCertificates(const QList<QSslCertificate> &certs)
990{
991 QSslSocketPrivate::setDefaultCaCertificates(certs);
992}
993
994/*!
995 \internal
996 Returns true if \a configuration allows loading root certificates on demand.
997*/
998bool QTlsBackend::rootLoadingOnDemandAllowed(const QSslConfiguration &configuration)
999{
1000 return configuration.d->allowRootCertOnDemandLoading;
1001}
1002
1003/*!
1004 \internal
1005 Stores \a peerCert in the \a configuration.
1006*/
1007void QTlsBackend::storePeerCertificate(QSslConfiguration &configuration,
1008 const QSslCertificate &peerCert)
1009{
1010 configuration.d->peerCertificate = peerCert;
1011}
1012
1013/*!
1014 \internal
1015 Stores \a peerChain in the \a configuration.
1016*/
1017void QTlsBackend::storePeerCertificateChain(QSslConfiguration &configuration,
1018 const QList<QSslCertificate> &peerChain)
1019{
1020 configuration.d->peerCertificateChain = peerChain;
1021}
1022
1023/*!
1024 \internal
1025 Clears the peer certificate chain in \a configuration.
1026*/
1027void QTlsBackend::clearPeerCertificates(QSslConfiguration &configuration)
1028{
1029 configuration.d->peerCertificate.clear();
1030 configuration.d->peerCertificateChain.clear();
1031}
1032
1033/*!
1034 \internal
1035 Clears the peer certificate chain in \a d.
1036*/
1037void QTlsBackend::clearPeerCertificates(QSslSocketPrivate *d)
1038{
1039 Q_ASSERT(d);
1040 d->configuration.peerCertificate.clear();
1041 d->configuration.peerCertificateChain.clear();
1042}
1043
1044/*!
1045 \internal
1046 Updates the configuration in \a d with \a shared value.
1047*/
1048void QTlsBackend::setPeerSessionShared(QSslSocketPrivate *d, bool shared)
1049{
1050 Q_ASSERT(d);
1051 d->configuration.peerSessionShared = shared;
1052}
1053
1054/*!
1055 \internal
1056 Sets TLS session in \a d to \a asn1.
1057*/
1058void QTlsBackend::setSessionAsn1(QSslSocketPrivate *d, const QByteArray &asn1)
1059{
1060 Q_ASSERT(d);
1061 d->configuration.sslSession = asn1;
1062}
1063
1064/*!
1065 \internal
1066 Sets TLS session lifetime hint in \a d to \a hint.
1067*/
1068void QTlsBackend::setSessionLifetimeHint(QSslSocketPrivate *d, int hint)
1069{
1070 Q_ASSERT(d);
1071 d->configuration.sslSessionTicketLifeTimeHint = hint;
1072}
1073
1074/*!
1075 \internal
1076 Sets application layer protocol negotiation status in \a d to \a st.
1077*/
1078void QTlsBackend::setAlpnStatus(QSslSocketPrivate *d, AlpnNegotiationStatus st)
1079{
1080 Q_ASSERT(d);
1081 d->configuration.nextProtocolNegotiationStatus = st;
1082}
1083
1084/*!
1085 \internal
1086 Sets \a protocol in \a d as a negotiated application layer protocol.
1087*/
1088void QTlsBackend::setNegotiatedProtocol(QSslSocketPrivate *d, const QByteArray &protocol)
1089{
1090 Q_ASSERT(d);
1091 d->configuration.nextNegotiatedProtocol = protocol;
1092}
1093
1094/*!
1095 \internal
1096 Stores \a peerCert in the TLS configuration of \a d.
1097*/
1098void QTlsBackend::storePeerCertificate(QSslSocketPrivate *d, const QSslCertificate &peerCert)
1099{
1100 Q_ASSERT(d);
1101 d->configuration.peerCertificate = peerCert;
1102}
1103
1104/*!
1105 \internal
1106
1107 Stores \a peerChain in the TLS configuration of \a d.
1108
1109 \note This is a helper function that TlsCryptograph and DtlsCryptograph
1110 call during a handshake.
1111*/
1112void QTlsBackend::storePeerCertificateChain(QSslSocketPrivate *d,
1113 const QList<QSslCertificate> &peerChain)
1114{
1115 Q_ASSERT(d);
1116 d->configuration.peerCertificateChain = peerChain;
1117}
1118
1119/*!
1120 \internal
1121
1122 Adds \a rootCert to the list of trusted root certificates in \a d.
1123
1124 \note In Qt 6.1 it's only used on Windows, during so called 'CA fetch'.
1125*/
1126void QTlsBackend::addTustedRoot(QSslSocketPrivate *d, const QSslCertificate &rootCert)
1127{
1128 Q_ASSERT(d);
1129 if (!d->configuration.caCertificates.contains(rootCert))
1130 d->configuration.caCertificates += rootCert;
1131}
1132
1133/*!
1134 \internal
1135
1136 Saves ephemeral \a key in \a d.
1137
1138 \sa QSslConfiguration::ephemeralKey()
1139*/
1140void QTlsBackend::setEphemeralKey(QSslSocketPrivate *d, const QSslKey &key)
1141{
1142 Q_ASSERT(d);
1143 d->configuration.ephemeralServerKey = key;
1144}
1145
1146/*!
1147 \internal
1148
1149 Implementation-specific. Sets the security level suitable for Qt's
1150 auto-tests.
1151*/
1152void QTlsBackend::forceAutotestSecurityLevel()
1153{
1154}
1155
1156#endif // QT_CONFIG(ssl)
1157
1158namespace QTlsPrivate {
1159
1160/*!
1161 \internal (Network-private)
1162 \namespace QTlsPrivate
1163 \brief Namespace containing onternal types that TLS backends implement.
1164
1165 This namespace is private to Qt and the backends that implement its TLS support.
1166*/
1167
1168/*!
1169 \class TlsKey
1170 \internal (Network-private)
1171 \brief TlsKey is an abstract class, that allows a TLS plugin to provide
1172 an underlying implementation for the class QSslKey.
1173
1174 Most functions in the class TlsKey are pure virtual and thus have to be
1175 reimplemented by a TLS backend that supports QSslKey. In many cases an
1176 empty implementation as an overrider is sufficient, albeit with some
1177 of QSslKey's functionality missing.
1178
1179 \sa QTlsBackend::createKey(), QTlsBackend::implementedClasses(), QSslKey
1180*/
1181
1182/*!
1183 \fn void TlsKey::decodeDer(KeyType type, KeyAlgorithm algorithm, const QByteArray &der, const QByteArray &passPhrase, bool deepClear)
1184 \internal
1185
1186 If a support of public and private keys in DER format is required, this function
1187 must be overridden and should initialize this key using the \a type, \a algorithm, \a der
1188 and \a passPhrase. If this key was initialized previously, \a deepClear
1189 has an implementation-specific meaning (e.g., if an implementation is using
1190 reference-counting and can share internally some data structures, a value \c true may
1191 trigger decrementing a reference counter on some implementation-specific object).
1192
1193 \note An empty overrider is sufficient, but then reading keys in QSsl::Der format
1194 will not be supported.
1195
1196 \sa isNull(), QSsl::KeyType, QSsl::EncodingFormat, QSsl::KeyAlgorithm
1197*/
1198
1199/*!
1200 \fn void TlsKey::decodePem(KeyType type, KeyAlgorithm algorithm, const QByteArray &pem, const QByteArray &passPhrase, bool deepClear)
1201 \internal
1202
1203 If a support of public and private keys in PEM format is required, this function must
1204 be overridden and should initialize this key using the \a type, \a algorithm, \a pem and
1205 \a passPhrase. If this key was initialized previously, \a deepClear has an
1206 implementation-specific meaning (e.g., in an implementation using reference-counting,
1207 a value \c true may trigger decrementing a reference counter on some implementation-specific
1208 object).
1209
1210 \note An empty overrider is sufficient, but then reading keys in QSsl::Pem format
1211 will not be supported.
1212
1213 \sa isNull(), QSsl::KeyType, QSsl::EncodingFormat, QSsl::KeyAlgorithm
1214*/
1215
1216/*!
1217 \fn QByteArray TlsKey::toPem(const QByteArray &passPhrase) const
1218 \internal
1219
1220 This function must be overridden, if converting a key to PEM format, potentially with
1221 encryption, is needed (e.g. to save a QSslKey into a file). If this key is
1222 private and \a passPhrase is not empty, the key's data is expected to be encrypted using
1223 some conventional encryption algorithm (e.g. DES or AES - the one that different tools
1224 or even the class QSslKey can understand later).
1225
1226 \note If this particular functionality is not needed, an overrider returning an
1227 empty QByteArray is sufficient.
1228
1229 \sa QSslKey::toPem()
1230*/
1231
1232/*!
1233 \fn QByteArray TlsKey::derFromPem(const QByteArray &pem, QMap<QByteArray, QByteArray> *headers) const
1234 \internal
1235
1236 Converts \a pem to DER format, using this key's type and algorithm. The parameter \a headers
1237 must be a valid, non-null pointer. When parsing \a pem, the headers found there will be saved
1238 into \a headers.
1239
1240 \note An overrider returning an empty QByteArray is sufficient, if QSslKey::toDer() is not
1241 needed.
1242
1243 \note This function is very implementation-specific. A backend, that already has this key's
1244 non-empty DER data, may simply return this data.
1245
1246 \sa QSslKey::toDer()
1247*/
1248
1249/*!
1250 \fn QByteArray TlsKey::pemFromDer(const QByteArray &der, const QMap<QByteArray, QByteArray> &headers) const
1251 \internal
1252
1253 If overridden, this function is expected to convert \a der, using \a headers, to PEM format.
1254
1255 \note This function is very implementation-specific. As of now (Qt 6.1), it is only required by
1256 Qt's own non-OpenSSL backends, that internally use DER and implement QSslKey::toPem()
1257 via pemFromDer().
1258*/
1259
1260/*!
1261 \fn void TlsKey::fromHandle(Qt::HANDLE handle, KeyType type)
1262 \internal
1263
1264 Initializes this key using the \a handle and \a type, taking the ownership
1265 of the \a handle.
1266
1267 \note The meaning of the \a handle is implementation-specific.
1268
1269 \note If a TLS backend does not support such keys, it must provide an
1270 empty implementation.
1271
1272 \sa handle(), QSslKey::QSslKey(), QSslKet::handle()
1273*/
1274
1275/*!
1276 \fn TlsKey::handle() const
1277 \internal
1278
1279 If a TLS backend supports opaque keys, returns a native handle that
1280 this key was initialized with.
1281
1282 \sa fromHandle(), QSslKey::handle()
1283*/
1284
1285/*!
1286 \fn bool TlsKey::isNull() const
1287 \internal
1288
1289 Returns \c true if this is a null key, \c false otherwise.
1290
1291 \note A null key corresponds to the default-constructed
1292 QSslKey or the one, that was cleared via QSslKey::clear().
1293
1294 \sa QSslKey::isNull()
1295*/
1296
1297/*!
1298 \fn QSsl::KeyType TlsKey::type() const
1299 \internal
1300
1301 Returns the type of this key (public or private).
1302*/
1303
1304/*!
1305 \fn QSsl::KeyAlgorithm TlsKey::algorithm() const
1306 \internal
1307
1308 Return this key's algorithm.
1309*/
1310
1311/*!
1312 \fn int TlsKey::length() const
1313 \internal
1314
1315 Returns the length of the key in bits, or -1 if the key is null.
1316*/
1317
1318/*!
1319 \fn void TlsKey::clear(bool deep)
1320 \internal
1321
1322 Clears the contents of this key, making it a null key. The meaning
1323 of \a deep is implementation-specific (e.g. if some internal objects
1324 representing a key can be shared using reference counting, \a deep equal
1325 to \c true would imply decrementing a reference count).
1326
1327 \sa isNull()
1328*/
1329
1330/*!
1331 \fn bool TlsKey::isPkcs8() const
1332 \internal
1333
1334 This function is internally used only by Qt's own TLS plugins and affects
1335 the way PEM file is generated by TlsKey. It's sufficient to override it
1336 and return \c false in case a new TLS backend is not using Qt's plugin
1337 as a base.
1338*/
1339
1340/*!
1341 \fn QByteArray TlsKey::decrypt(Cipher cipher, const QByteArray &data, const QByteArray &passPhrase, const QByteArray &iv) const
1342 \internal
1343
1344 This function allows to decrypt \a data (for example, a private key read from a file), using
1345 \a passPhrase, initialization vector \a iv. \a cipher is describing a block cipher and its
1346 mode (for example, AES256 + CBC). decrypt() is needed to implement QSslKey's constructor.
1347
1348 \note A TLS backend may provide an empty implementation, but as a result QSslKey will not be able
1349 to work with private encrypted keys.
1350
1351 \sa QSslKey
1352*/
1353
1354/*!
1355 \fn QByteArray TlsKey::encrypt(Cipher cipher, const QByteArray &data, const QByteArray &passPhrase, const QByteArray &iv) const
1356 \internal
1357
1358 This function is needed to implement QSslKey::toPem() with encryption (for a private
1359 key). \a cipher names a block cipher to use to encrypt \a data, using
1360 \a passPhrase and initialization vector \a iv.
1361
1362 \note An empty implementation is sufficient, but QSslKey::toPem() will fail for
1363 a private key and non-empty passphrase.
1364
1365 \sa QSslKey
1366*/
1367
1368/*!
1369 \internal
1370
1371 Destroys this key.
1372*/
1373TlsKey::~TlsKey() = default;
1374
1375/*!
1376 \internal
1377
1378 A convenience function that returns a string, corresponding to the
1379 key type or algorithm, which can be used as a header in a PEM file.
1380*/
1382{
1383 if (type() == QSsl::PublicKey)
1384 return QByteArrayLiteral("-----BEGIN PUBLIC KEY-----");
1385 else if (algorithm() == QSsl::Rsa)
1386 return QByteArrayLiteral("-----BEGIN RSA PRIVATE KEY-----");
1387 else if (algorithm() == QSsl::Dsa)
1388 return QByteArrayLiteral("-----BEGIN DSA PRIVATE KEY-----");
1389 else if (algorithm() == QSsl::Ec)
1390 return QByteArrayLiteral("-----BEGIN EC PRIVATE KEY-----");
1391 else if (algorithm() == QSsl::Dh || algorithm() == QSsl::MlDsa)
1392 return QByteArrayLiteral("-----BEGIN PRIVATE KEY-----");
1393
1395}
1396
1397/*!
1398 \internal
1399 A convenience function that returns a string, corresponding to the
1400 key type or algorithm, which can be used as a footer in a PEM file.
1401*/
1403{
1404 if (type() == QSsl::PublicKey)
1405 return QByteArrayLiteral("-----END PUBLIC KEY-----");
1406 else if (algorithm() == QSsl::Rsa)
1407 return QByteArrayLiteral("-----END RSA PRIVATE KEY-----");
1408 else if (algorithm() == QSsl::Dsa)
1409 return QByteArrayLiteral("-----END DSA PRIVATE KEY-----");
1410 else if (algorithm() == QSsl::Ec)
1411 return QByteArrayLiteral("-----END EC PRIVATE KEY-----");
1412 else if (algorithm() == QSsl::Dh || algorithm() == QSsl::MlDsa)
1413 return QByteArrayLiteral("-----END PRIVATE KEY-----");
1414
1416}
1417
1418/*!
1419 \class X509Certificate
1420 \internal (Network-private)
1421 \brief X509Certificate is an abstract class that allows a TLS backend to
1422 provide an implementation of the QSslCertificate class.
1423
1424 This class provides an interface that must be reimplemented by a TLS plugin,
1425 that supports QSslCertificate. Most functions are pure virtual, and thus
1426 have to be overridden. For some of them, an empty overrider is acceptable,
1427 though a part of functionality in QSslCertificate will be missing.
1428
1429 \sa QTlsBackend::createCertificate(), QTlsBackend::X509PemReader(), QTlsBackend::X509DerReader()
1430*/
1431
1432/*!
1433 \fn bool X509Certificate::isEqual(const X509Certificate &other) const
1434 \internal
1435
1436 This function is expected to return \c true if this certificate is the same as
1437 the \a other, \c false otherwise. Used by QSslCertificate's comparison operators.
1438*/
1439
1440/*!
1441 \fn bool X509Certificate::isNull() const
1442 \internal
1443
1444 Returns true if this certificate was default-constructed and not initialized yet.
1445 This function is called by QSslCertificate::isNull().
1446
1447 \sa QSslCertificate::isNull()
1448*/
1449
1450/*!
1451 \fn bool X509Certificate::isSelfSigned() const
1452 \internal
1453
1454 This function is needed to implement QSslCertificate::isSelfSigned()
1455
1456 \sa QSslCertificate::isSelfSigned()
1457*/
1458
1459/*!
1460 \fn QByteArray X509Certificate::version() const
1461 \internal
1462
1463 Implements QSslCertificate::version().
1464
1465 \sa QSslCertificate::version()
1466*/
1467
1468/*!
1469 \fn QByteArray X509Certificate::serialNumber() const
1470 \internal
1471
1472 This function is expected to return the certificate's serial number string in
1473 hexadecimal format.
1474
1475 \sa QSslCertificate::serialNumber()
1476*/
1477
1478/*!
1479 \fn QStringList X509Certificate::issuerInfo(QSslCertificate::SubjectInfo subject) const
1480 \internal
1481
1482 This function is expected to return the issuer information for the \a subject
1483 from the certificate, or an empty list if there is no information for subject
1484 in the certificate. There can be more than one entry of each type.
1485
1486 \sa QSslCertificate::issuerInfo().
1487*/
1488
1489/*!
1490 \fn QStringList X509Certificate::issuerInfo(const QByteArray &attribute) const
1491 \internal
1492
1493 This function is expected to return the issuer information for attribute from
1494 the certificate, or an empty list if there is no information for \a attribute
1495 in the certificate. There can be more than one entry for an attribute.
1496
1497 \sa QSslCertificate::issuerInfo().
1498*/
1499
1500/*!
1501 \fn QStringList X509Certificate::subjectInfo(QSslCertificate::SubjectInfo subject) const
1502 \internal
1503
1504 This function is expected to return the information for the \a subject, or an empty list
1505 if there is no information for subject in the certificate. There can be more than one
1506 entry of each type.
1507
1508 \sa QSslCertificate::subjectInfo().
1509*/
1510
1511/*!
1512 \fn QStringList X509Certificate::subjectInfo(const QByteArray &attribute) const
1513 \internal
1514
1515 This function is expected to return the subject information for \a attribute, or
1516 an empty list if there is no information for attribute in the certificate.
1517 There can be more than one entry for an attribute.
1518
1519 \sa QSslCertificate::subjectInfo().
1520*/
1521
1522/*!
1523 \fn QList<QByteArray> X509Certificate::subjectInfoAttributes() const
1524 \internal
1525
1526 This function is expected to return a list of the attributes that have values
1527 in the subject information of this certificate. The information associated
1528 with a given attribute can be accessed using the subjectInfo() method. Note
1529 that this list may include the OIDs for any elements that are not known by
1530 the TLS backend.
1531
1532 \note This function is needed for QSslCertificate:::subjectInfoAttributes().
1533
1534 \sa subjectInfo()
1535*/
1536
1537/*!
1538 \fn QList<QByteArray> X509Certificate::issuerInfoAttributes() const
1539 \internal
1540
1541 This function is expected to return a list of the attributes that have
1542 values in the issuer information of this certificate. The information
1543 associated with a given attribute can be accessed using the issuerInfo()
1544 method. Note that this list may include the OIDs for any
1545 elements that are not known by the TLS backend.
1546
1547 \note This function implements QSslCertificate::issuerInfoAttributes().
1548
1549 \sa issuerInfo()
1550*/
1551
1552/*!
1553 \fn QMultiMap<QSsl::AlternativeNameEntryType, QString> X509Certificate::subjectAlternativeNames() const
1554 \internal
1555
1556 This function is expected to return the list of alternative subject names for
1557 this certificate. The alternative names typically contain host names, optionally
1558 with wildcards, that are valid for this certificate.
1559
1560 \sa subjectInfo()
1561*/
1562
1563/*!
1564 \fn QDateTime X509Certificate::effectiveDate() const
1565 \internal
1566
1567 This function is expected to return the date-time that the certificate
1568 becomes valid, or an empty QDateTime if this is a null certificate.
1569
1570 \sa expiryDate()
1571*/
1572
1573/*!
1574 \fn QDateTime X509Certificate::expiryDate() const
1575 \internal
1576
1577 This function is expected to return the date-time that the certificate expires,
1578 or an empty QDateTime if this is a null certificate.
1579
1580 \sa effectiveDate()
1581*/
1582
1583/*!
1584 \fn qsizetype X509Certificate::numberOfExtensions() const
1585 \internal
1586
1587 This function is expected to return the number of X509 extensions of
1588 this certificate.
1589*/
1590
1591/*!
1592 \fn QString X509Certificate::oidForExtension(qsizetype i) const
1593 \internal
1594
1595 This function is expected to return the ASN.1 OID for the extension
1596 with index \a i.
1597
1598 \sa numberOfExtensions()
1599*/
1600
1601/*!
1602 \fn QString X509Certificate::nameForExtension(qsizetype i) const
1603 \internal
1604
1605 This function is expected to return the name for the extension
1606 with index \a i. If no name is known for the extension then the
1607 OID will be returned.
1608
1609 \sa numberOfExtensions(), oidForExtension()
1610*/
1611
1612/*!
1613 \fn QVariant X509Certificate::valueForExtension(qsizetype i) const
1614 \internal
1615
1616 This function is expected to return the value of the extension
1617 with index \a i. The structure of the value returned depends on
1618 the extension type
1619
1620 \sa numberOfExtensions()
1621*/
1622
1623/*!
1624 \fn bool X509Certificate::isExtensionCritical(qsizetype i) const
1625 \internal
1626
1627 This function is expected to return the criticality of the extension
1628 with index \a i.
1629
1630 \sa numberOfExtensions()
1631*/
1632
1633/*!
1634 \fn bool X509Certificate::isExtensionSupported(qsizetype i) const
1635 \internal
1636
1637 This function is expected to return \c true if this extension is supported.
1638 In this case, supported simply means that the structure of the QVariant returned
1639 by the valueForExtension() accessor will remain unchanged between versions.
1640
1641 \sa numberOfExtensions()
1642*/
1643
1644/*!
1645 \fn QByteArray X509Certificate::toPem() const
1646 \internal
1647
1648 This function is expected to return this certificate converted to a PEM (Base64)
1649 encoded representation.
1650*/
1651
1652/*!
1653 \fn QByteArray X509Certificate::toDer() const
1654 \internal
1655
1656 This function is expected to return this certificate converted to a DER (binary)
1657 encoded representation.
1658*/
1659
1660/*!
1661 \fn QString X509Certificate::toText() const
1662 \internal
1663
1664 This function is expected to return this certificate converted to a human-readable
1665 text representation.
1666*/
1667
1668/*!
1669 \fn Qt::HANDLE X509Certificate::handle() const
1670 \internal
1671
1672 This function is expected to return a pointer to the native certificate handle,
1673 if there is one, else nullptr.
1674*/
1675
1676/*!
1677 \fn size_t X509Certificate::hash(size_t seed) const
1678 \internal
1679
1680 This function is expected to return the hash value for this certificate,
1681 using \a seed to seed the calculation.
1682*/
1683
1684/*!
1685 \internal
1686
1687 Destroys this certificate.
1688*/
1689X509Certificate::~X509Certificate() = default;
1690
1691/*!
1692 \internal
1693
1694 Returns the certificate subject's public key.
1695*/
1697{
1698 return nullptr;
1699}
1700
1701#if QT_CONFIG(ssl)
1702
1703/*!
1704 \class TlsCryptograph
1705 \internal (Network-private)
1706 \brief TlsCryptograph is an abstract class, that allows a TLS plugin to implement QSslSocket.
1707
1708 This abstract base class provides an interface that must be reimplemented by a TLS plugin,
1709 that supports QSslSocket. A class, implementing TlsCryptograph's interface, is responsible
1710 for TLS handshake, reading and writing encryped application data; it is expected
1711 to work with QSslSocket and it's private implementation - QSslSocketPrivate.
1712 QSslSocketPrivate provides access to its read/write buffers, QTcpSocket it
1713 internally uses for connecting, reading and writing. QSslSocketPrivate
1714 can also be used for reporting errors and storing the certificates received
1715 during the handshake phase.
1716
1717 \note Most of the functions in this class are pure virtual and have no actual implementation
1718 in the QtNetwork module. This documentation is mostly conceptual and only describes what those
1719 functions are expected to do, but not how they must be implemented.
1720
1721 \sa QTlsBackend::createTlsCryptograph()
1722*/
1723
1724/*!
1725 \fn void TlsCryptograph::init(QSslSocket *q, QSslSocketPrivate *d)
1726 \internal
1727
1728 When initializing this TlsCryptograph, QSslSocket will pass a pointer to self and
1729 its d-object using this function.
1730*/
1731
1732/*!
1733 \fn QList<QSslError> TlsCryptograph::tlsErrors() const
1734 \internal
1735
1736 Returns a list of QSslError, describing errors encountered during
1737 the TLS handshake.
1738
1739 \sa QSslSocket::sslHandshakeErrors()
1740*/
1741
1742/*!
1743 \fn void TlsCryptograph::startClientEncryption()
1744 \internal
1745
1746 A client-side QSslSocket calls this function after its internal TCP socket
1747 establishes a connection with a remote host, or from QSslSocket::startClientEncryption().
1748 This TlsCryptograph is expected to initialize some implementation-specific TLS context,
1749 if needed, and then start the client side of the TLS handshake (for example, by calling
1750 transmit()), using TCP socket from QSslSocketPrivate.
1751
1752 \sa init(), transmit(), QSslSocket::startClientEncryption(), QSslSocket::connectToHostEncrypted()
1753*/
1754
1755/*!
1756 \fn void TlsCryptograph::startServerEncryption()
1757 \internal
1758
1759 This function is called by QSslSocket::startServerEncryption(). The TlsCryptograph
1760 is expected to initialize some implementation-specific TLS context, if needed,
1761 and then try to read the ClientHello message and continue the TLS handshake
1762 (for example, by calling transmit()).
1763
1764 \sa transmit(), QSslSocket::startServerEncryption()
1765*/
1766
1767/*!
1768 \fn void TlsCryptograph::continueHandshake()
1769 \internal
1770
1771 QSslSocket::resume() calls this function if its pause mode is QAbstractSocket::PauseOnSslErrors,
1772 and errors, found during the handshake, were ignored. If implemented, this function is expected
1773 to emit QSslSocket::encrypted().
1774
1775 \sa QAbstractSocket::pauseMode(), QSslSocket::sslHandshakeErrors(), QSslSocket::ignoreSslErrors(), QSslSocket::resume()
1776*/
1777
1778/*!
1779 \fn void TlsCryptograph::disconnectFromHost()
1780 \internal
1781
1782 This function is expected to call disconnectFromHost() on the TCP socket
1783 that can be obtained from QSslSocketPrivate. Any additional actions
1784 are implementation-specific (e.g., sending shutdown alert message).
1785
1786*/
1787
1788/*!
1789 \fn void TlsCryptograph::disconnected()
1790 \internal
1791
1792 This function is called when the remote has disconnected. If there
1793 is data left to be read you may ignore the maxReadBufferSize restriction
1794 and read it all now.
1795*/
1796
1797/*!
1798 \fn QSslCipher TlsCryptograph::sessionCipher() const
1799 \internal
1800
1801 This function returns a QSslCipher object describing the ciphersuite negotiated
1802 during the handshake.
1803*/
1804
1805/*!
1806 \fn QSsl::SslProtocol TlsCryptograph::sessionProtocol() const
1807 \internal
1808
1809 This function returns the version of TLS (or DTLS) protocol negotiated during the handshake.
1810*/
1811
1812/*!
1813 \fn void TlsCryptograph::transmit()
1814 \internal
1815
1816 This function is responsible for reading and writing data. The meaning of these I/O
1817 operations depends on an implementation-specific TLS state machine. These read and write
1818 operations can be reading and writing parts of a TLS handshake (e.g. by calling handshake-specific
1819 functions), or reading and writing application data (if encrypted connection was already
1820 established). transmit() is expected to use the QSslSocket's TCP socket (accessible via
1821 QSslSocketPrivate) to read the incoming data and write the outgoing data. When in encrypted
1822 state, transmit() is also using QSslSocket's internal read and write buffers: the read buffer
1823 to fill with decrypted incoming data; the write buffer - for the data to encrypt and send.
1824 This TlsCryptograph can also use QSslSocketPrivate to check which TLS errors were ignored during
1825 the handshake.
1826
1827 \note This function is responsible for emitting QSslSocket's signals, that occur during the
1828 handshake (e.g. QSslSocket::sslErrors() or QSslSocket::encrypted()), and also read/write signals,
1829 e.g. QSslSocket::bytesWritten() and QSslSocket::readyRead().
1830
1831 \sa init()
1832*/
1833
1834/*!
1835 \internal
1836
1837 Destroys this object.
1838*/
1839TlsCryptograph::~TlsCryptograph() = default;
1840
1841/*!
1842 \internal
1843
1844 This function allows to share QSslContext between several QSslSocket objects.
1845 The default implementation does nothing.
1846
1847 \note The definition of the class QSslContext is implementation-specific.
1848
1849 \sa sslContext()
1850*/
1852{
1854}
1855
1856/*!
1857 \internal
1858
1859 Returns the context previously set by checkSettingSslContext() or \nullptr,
1860 if no context was set. The default implementation returns \nullptr.
1861
1862 \sa checkSettingSslContext()
1863*/
1865{
1866 return {};
1867}
1868
1869/*!
1870 \internal
1871
1872 If this TLS backend supports reporting errors before handshake is finished,
1873 e.g. from a verification callback function, enableHandshakeContinuation()
1874 allows this object to continue handshake. The default implementation does
1875 nothing.
1876
1877 \sa QSslSocket::handshakeInterruptedOnError(), QSslConfiguration::setHandshakeMustInterruptOnError()
1878*/
1880{
1881}
1882
1883/*!
1884 \internal
1885
1886 Windows and OpenSSL-specific, only used internally by Qt's OpenSSL TLS backend.
1887
1888 \note The default empty implementation is sufficient.
1889*/
1891{
1892}
1893
1894/*!
1895 \internal
1896
1897 Windows and Schannel-specific, only used by Qt's Schannel TLS backend, in
1898 general, if a backend has its own buffer where it stores undecrypted data
1899 then it must report true if it contains any data through this function.
1900
1901 \note The default empty implementation, returning \c false is sufficient.
1902*/
1904{
1905 return false;
1906}
1907
1908/*!
1909 \internal
1910
1911 Returns the list of OCSP (Online Certificate Status Protocol) responses,
1912 received during the handshake. The default implementation returns an empty
1913 list.
1914*/
1916{
1917 return {};
1918}
1919
1920/*!
1921 \internal
1922
1923 A helper function that can be used during a handshake. Returns \c true if the \a peerName
1924 matches one of subject alternative names or common names found in the \a certificate.
1925*/
1927{
1929}
1930
1931/*!
1932 \internal
1933 Calls QAbstractSocketPrivate::setErrorAndEmit() for \a d, passing \a errorCode and
1934 \a errorDescription as parameters.
1935*/
1937 const QString &errorDescription) const
1938{
1939 Q_ASSERT(d);
1941}
1942
1943#if QT_CONFIG(dtls)
1944/*!
1945 \class DtlsBase
1946 \internal (Network-private)
1947 \brief DtlsBase is a base class for the classes DtlsCryptograph and DtlsCookieVerifier.
1948
1949 DtlsBase is the base class for the classes DtlsCryptograph and DtlsCookieVerifier. It's
1950 an abstract class, an interface that these before-mentioned classes share. It allows to
1951 set, get and clear the last error that occurred, set and get cookie generation parameters,
1952 set and get QSslConfiguration.
1953
1954 \note This class is not supposed to be inherited directly, it's only needed by DtlsCryptograph
1955 and DtlsCookieVerifier.
1956
1957 \sa QDtls, QDtlsClientVerifier, DtlsCryptograph, DtlsCookieVerifier
1958*/
1959
1960/*!
1961 \fn void DtlsBase::setDtlsError(QDtlsError code, const QString &description)
1962 \internal
1963
1964 Sets the last error to \a code and its textual description to \a description.
1965
1966 \sa QDtlsError, error(), errorString()
1967*/
1968
1969/*!
1970 \fn QDtlsError DtlsBase::error() const
1971 \internal
1972
1973 This function, when overridden, is expected to return the code for the last error that occurred.
1974 If no error occurred it should return QDtlsError::NoError.
1975
1976 \sa QDtlsError, errorString(), setDtlsError()
1977*/
1978
1979/*!
1980 \fn QDtlsError DtlsBase::errorString() const
1981 \internal
1982
1983 This function, when overridden, is expected to return the textual description for the last error
1984 that occurred or an empty string if no error occurred.
1985
1986 \sa QDtlsError, error(), setDtlsError()
1987*/
1988
1989/*!
1990 \fn void DtlsBase::clearDtlsError()
1991 \internal
1992
1993 This function is expected to set the error code for the last error to QDtlsError::NoError and
1994 its textual description to an empty string.
1995
1996 \sa QDtlsError, setDtlsError(), error(), errorString()
1997*/
1998
1999/*!
2000 \fn void DtlsBase::setConfiguration(const QSslConfiguration &configuration)
2001 \internal
2002
2003 Sets a TLS configuration that an object of a class inheriting from DtlsCookieVerifier or
2004 DtlsCryptograph will use, to \a configuration.
2005
2006 \sa configuration()
2007*/
2008
2009/*!
2010 \fn QSslConfiguration DtlsBase::configuration() const
2011 \internal
2012
2013 Returns TLS configuration this object is using (either set by setConfiguration()
2014 previously, or the default DTLS configuration).
2015
2016 \sa setConfiguration(), QSslConfiguration::defaultDtlsConfiguration()
2017*/
2018
2019/*!
2020 \fn bool DtlsBase::setCookieGeneratorParameters(const QDtlsClientVerifier::GeneratorParameters &params)
2021 \internal
2022
2023 Sets the DTLS cookie generation parameters that DtlsCookieVerifier or DtlsCryptograph will use to
2024 \a params.
2025
2026 \note This function returns \c false if parameters were invalid - if the secret was empty. Otherwise,
2027 this function must return true.
2028
2029 \sa QDtlsClientVerifier::GeneratorParameters, cookieGeneratorParameters()
2030*/
2031
2032/*!
2033 \fn QDtlsClientVerifier::GeneratorParameters DtlsBase::cookieGeneratorParameters() const
2034 \internal
2035
2036 Returns DTLS cookie generation parameters that were either previously set by setCookieGeneratorParameters(),
2037 or default parameters.
2038
2039 \sa setCookieGeneratorParameters()
2040*/
2041
2042/*!
2043 \internal
2044
2045 Destroys this object.
2046*/
2047DtlsBase::~DtlsBase() = default;
2048
2049/*!
2050 \class DtlsCookieVerifier
2051 \internal (Network-private)
2052 \brief DtlsCookieVerifier is an interface that allows a TLS plugin to support the class QDtlsClientVerifier.
2053
2054 DtlsCookieVerifier is an interface, an abstract class, that has to be implemented by
2055 a TLS plugin that supports DTLS cookie verification.
2056
2057 \sa QDtlsClientVerifier
2058*/
2059
2060/*!
2061 \fn bool DtlsCookieVerifier::verifyClient(QUdpSocket *socket, const QByteArray &dgram, const QHostAddress &address, quint16 port)
2062 \internal
2063
2064 This function is expected to verify a ClientHello message, found in \a dgram, using \a address,
2065 \a port, and cookie generator parameters. The function returns \c true if such cookie was found
2066 and \c false otherwise. If no valid cookie was found in the \a dgram, this verifier should use
2067 \a socket to send a HelloVerifyRequest message, using \a address and \a port as the destination
2068 and a source material for cookie generation, see also
2069 \l {RFC 6347, section 4.2.1}
2070
2071 \sa QDtlsClientVerifier
2072*/
2073
2074/*!
2075 \fn QByteArray DtlsCookieVerifier::verifiedHello() const
2076 \internal
2077
2078 Returns the last ClientHello message containing the DTLS cookie that this verifier was
2079 able to verify as correct, or an empty byte array.
2080
2081 \sa verifyClient()
2082*/
2083
2084/*!
2085 \class DtlsCryptograph
2086 \internal (Network-private)
2087 \brief DtlsCryptograph is an interface that allows a TLS plugin to implement the class QDtls.
2088
2089 DtlsCryptograph is an abstract class; a TLS plugin can provide a class, inheriting from
2090 DtlsCryptograph and implementing its pure virtual functions, thus implementing the class
2091 QDtls and enabling DTLS over UDP.
2092
2093 To write DTLS datagrams, a class, inheriting DtlsCryptograph, is expected to use
2094 QUdpSocket. In general, all reading is done externally, so DtlsCryptograph is
2095 expected to only write into QUdpSocket, check possible socket errors, change socket
2096 options if needed.
2097
2098 \note All functions in this class are pure virtual and have no actual implementation
2099 in the QtNetwork module. This documentation is mostly conceptual and only describes
2100 what those functions are expected to do, but not how they must be implemented.
2101
2102 \sa QDtls, QUdpSocket
2103*/
2104
2105/*!
2106 \fn QSslSocket::SslMode DtlsCryptograph::cryptographMode() const
2107 \internal
2108
2109 Returns the mode (client or server) this object operates in.
2110
2111 \note This mode is set once when a new DtlsCryptograph is created
2112 by QTlsBackend and cannot change.
2113
2114 \sa QTlsBackend::createDtlsCryptograph()
2115*/
2116
2117/*!
2118 \fn void DtlsCryptograph::setPeer(const QHostAddress &addr, quint16 port, const QString &name)
2119 \internal
2120
2121 Sets the remote peer's address to \a addr and remote port to \a port. \a name,
2122 if not empty, is to be used when validating the peer's certificate.
2123
2124 \sa peerAddress(), peerPort(), peerVerificationName()
2125*/
2126
2127/*!
2128 \fn QHostAddress DtlsCryptograph::peerAddress() const
2129 \internal
2130
2131 Returns the remote peer's address previously set by setPeer() or,
2132 if no address was set, an empty address.
2133
2134 \sa setPeer()
2135*/
2136
2137/*!
2138 \fn quint16 DtlsCryptograph::peerPort() const
2139 \internal
2140
2141 Returns the remote peer's port previously set by setPeer() or
2142 0 if no port was set.
2143
2144 \sa setPeer(), peerAddress()
2145*/
2146
2147/*!
2148 \fn void DtlsCryptograph::setPeerVerificationName(const QString &name)
2149 \internal
2150
2151 Sets the host name to use during certificate validation to \a name.
2152
2153 \sa peerVerificationName(), setPeer()
2154*/
2155
2156/*!
2157 \fn QString DtlsCryptograph::peerVerificationName() const
2158 \internal
2159
2160 Returns the name that this object is using during the certificate validation,
2161 previously set by setPeer() or setPeerVerificationName(). Returns an empty string
2162 if no peer verification name was set.
2163
2164 \sa setPeer(), setPeerVerificationName()
2165*/
2166
2167/*!
2168 \fn void DtlsCryptograph::setDtlsMtuHint(quint16 mtu)
2169 \internal
2170
2171 Sets the maximum transmission unit (MTU), if it is supported by a TLS implementation, to \a mtu.
2172
2173 \sa dtlsMtuHint()
2174*/
2175
2176/*!
2177 \fn quint16 DtlsCryptograph::dtlsMtuHint() const
2178 \internal
2179
2180 Returns the value of the maximum transmission unit either previously set by setDtlsMtuHint(),
2181 or some implementation-specific value (guessed or somehow known to this DtlsCryptograph).
2182
2183 \sa setDtlsMtuHint()
2184*/
2185
2186/*!
2187 \fn QDtls::HandshakeState DtlsCryptograph::state() const
2188 \internal
2189
2190 Returns the current handshake state for this DtlsCryptograph (not started, in progress,
2191 peer verification error found, complete).
2192
2193 \sa isConnectionEncrypted(), startHandshake()
2194*/
2195
2196/*!
2197 \fn bool DtlsCryptograph::isConnectionEncrypted() const
2198 \internal
2199
2200 Returns \c true if this DtlsCryptograph has completed a handshake without validation
2201 errors (or these errors were ignored). Returns \c false otherwise.
2202*/
2203
2204/*!
2205 \fn bool DtlsCryptograph::startHandshake(QUdpSocket *socket, const QByteArray &dgram)
2206 \internal
2207
2208 This function is expected to initialize some implementation-specific context and to start a DTLS
2209 handshake, using \a socket to write datagrams (but not to read them). If this object is operating
2210 as a server, \a dgram is non-empty and contains the ClientHello message. This function returns
2211 \c true if no error occurred (and this DtlsCryptograph's state switching to
2212 QDtls::HandshakeState::HandshakeInProgress), \c false otherwise.
2213
2214 \sa continueHandshake(), handleTimeout(), resumeHandshake(), abortHandshake(), state()
2215*/
2216
2217/*!
2218 \fn bool DtlsCryptograph::handleTimeout(QUdpSocket *socket)
2219 \internal
2220
2221 In case a timeout occurred during the handshake, allows to re-transmit the last message,
2222 using \a socket to write the datagram. Returns \c true if no error occurred, \c false otherwise.
2223
2224 \sa QDtls::handshakeTimeout(), QDtls::handleTimeout()
2225*/
2226
2227/*!
2228 \fn bool DtlsCryptograph::continueHandshake(QUdpSocket *socket, const QByteArray &dgram)
2229 \internal
2230
2231 Continues the handshake, using \a socket to write datagrams (a handshake-specific message).
2232 \a dgram contains the peer's handshake-specific message. Returns \c false in case some error
2233 was encountered (this can include socket-related errors and errors found during the certificate
2234 validation). Returns \c true if the handshake was complete successfully, or is still in progress.
2235
2236 This function, depending on the implementation-specific state machine, may leave the handshake
2237 state in QDtls::HandshakeState::HandshakeInProgress, or switch to QDtls::HandshakeState::HandshakeComplete
2238 or QDtls::HandshakeState::PeerVerificationFailed.
2239
2240 This function may store the peer's certificate (or chain of certificates), extract and store
2241 the information about the negotiated session protocol and ciphersuite.
2242
2243 \sa startHandshake()
2244*/
2245
2246/*!
2247 \fn bool DtlsCryptograph::resumeHandshake(QUdpSocket *socket)
2248 \internal
2249
2250 If peer validation errors were found duing the handshake, this function tries to
2251 continue and complete the handshake. If errors were ignored, the function switches
2252 this object's state to QDtls::HandshakeState::HandshakeComplete and returns \c true.
2253
2254 \sa abortHandshake()
2255*/
2256
2257/*!
2258 \fn void DtlsCryptograph::abortHandshake(QUdpSocket *socket)
2259 \internal
2260
2261 Aborts the handshake if it's in progress or in the state QDtls::HandshakeState::PeerVerificationFailed.
2262 The use of \a socket is implementation-specific (for example, this DtlsCryptograph may send
2263 ShutdownAlert message).
2264
2265 \sa resumeHandshake()
2266*/
2267
2268/*!
2269 \fn void DtlsCryptograph::sendShutdownAlert(QUdpSocket *socket)
2270 \internal
2271
2272 If the underlying TLS library provides the required functionality, this function
2273 may sent ShutdownAlert message using \a socket.
2274*/
2275
2276/*!
2277 \fn QList<QSslError> DtlsCryptograph::peerVerificationErrors() const
2278 \internal
2279
2280 Returns the list of errors that this object encountered during DTLS handshake
2281 and certificate validation.
2282
2283 \sa ignoreVerificationErrors()
2284*/
2285
2286/*!
2287 \fn void DtlsCryptograph::ignoreVerificationErrors(const QList<QSslError> &errorsToIgnore)
2288 \internal
2289
2290 Tells this object to ignore errors from \a errorsToIgnore when they are found during
2291 DTLS handshake.
2292
2293 \sa peerVerificationErrors()
2294*/
2295
2296/*!
2297 \fn QSslCipher DtlsCryptograph::dtlsSessionCipher() const
2298 \internal
2299
2300 If such information is available, returns the ciphersuite, negotiated during
2301 the handshake.
2302
2303 \sa continueHandshake(), dtlsSessionProtocol()
2304*/
2305
2306/*!
2307 \fn QSsl::SslProtocol DtlsCryptograph::dtlsSessionProtocol() const
2308 \internal
2309
2310 Returns the version of the session protocol that was negotiated during the handshake or
2311 QSsl::UnknownProtocol if the handshake is incomplete or no information about the session
2312 protocol is available.
2313
2314 \sa continueHandshake(), dtlsSessionCipher()
2315*/
2316
2317/*!
2318 \fn qint64 DtlsCryptograph::writeDatagramEncrypted(QUdpSocket *socket, const QByteArray &dgram)
2319 \internal
2320
2321 If this DtlsCryptograph is in the QDtls::HandshakeState::HandshakeComplete state, this function
2322 encrypts \a dgram and writes this encrypted data into \a socket.
2323
2324 Returns the number of bytes (of \a dgram) written, or -1 in case of error. This function should
2325 set the error code and description if some error was encountered.
2326
2327 \sa decryptDatagram()
2328*/
2329
2330/*!
2331 \fn QByteArray DtlsCryptograph::decryptDatagram(QUdpSocket *socket, const QByteArray &dgram)
2332 \internal
2333
2334 If this DtlsCryptograph is in the QDtls::HandshakeState::HandshakeComplete state, decrypts \a dgram.
2335 The use of \a socket is implementation-specific. This function should return an empty byte array
2336 and set the error code and description if some error was encountered.
2337*/
2338
2339#endif // QT_CONFIG(dtls)
2340#endif // QT_CONFIG(ssl)
2341
2342} // namespace QTlsPrivate
2343
2344#if QT_CONFIG(ssl)
2345/*!
2346 \internal
2347*/
2348Q_NETWORK_EXPORT void qt_ForceTlsSecurityLevel()
2349{
2350 if (auto *backend = QSslSocketPrivate::tlsBackendInUse())
2351 backend->forceAutotestSecurityLevel();
2352}
2353
2354#endif // QT_CONFIG(ssl)
2355
2356QT_END_NAMESPACE
2357
2358#include "moc_qtlsbackend_p.cpp"
Namespace containing onternal types that TLS backends implement.
Q_APPLICATION_STATIC(QFactoryLoader, qtlsbLoader, QTlsBackend_iid, QStringLiteral("/tls")) namespace
#define REPORT_MISSING_SUPPORT(message)
Q_GLOBAL_STATIC(BackendCollection, backends)
#define QTlsBackend_iid