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

source code of qtbase/src/network/ssl/qtlsbackend.cpp