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, \a keyExchangeMethod, \a encryptionMethod,
893 \a authenticationMethod, \a bits, \a protocol version and \a protocolString.
894 For example:
895 \code
896 createCiphersuite("ECDHE-RSA-AES256-GCM-SHA256"_L1, "ECDH"_L1, "AES"_L1, "RSA"_L1, 256,
897 QSsl::TlsV1_2, "TLSv1.2"_L1);
898 \endcode
899*/
900QSslCipher QTlsBackend::createCiphersuite(const QString &name, const QString &keyExchangeMethod,
901 const QString &encryptionMethod,
902 const QString &authenticationMethod,
903 int bits, QSsl::SslProtocol protocol,
904 const QString &protocolString)
905{
906 QSslCipher cipher;
907 cipher.d->isNull = false;
908 cipher.d->name = name;
909 cipher.d->bits = bits;
910 cipher.d->supportedBits = bits;
911 cipher.d->keyExchangeMethod = keyExchangeMethod;
912 cipher.d->encryptionMethod = encryptionMethod;
913 cipher.d->authenticationMethod = authenticationMethod;
914 cipher.d->protocol = protocol;
915 cipher.d->protocolString = protocolString;
916 return cipher;
917}
918
919/*!
920 \internal
921 Returns an implementation-specific list of ciphersuites that can be used by QSslSocket.
922
923 \sa QSslConfiguration::defaultCiphers()
924*/
925QList<QSslCipher> QTlsBackend::defaultCiphers()
926{
927 return QSslSocketPrivate::defaultCiphers();
928}
929
930/*!
931 \internal
932 Returns an implementation-specific list of ciphersuites that can be used by QDtls.
933*/
934QList<QSslCipher> QTlsBackend::defaultDtlsCiphers()
935{
936 return QSslSocketPrivate::defaultDtlsCiphers();
937}
938
939/*!
940 \internal
941 Sets \a ciphers as defaults ciphers that QSslSocket can use.
942
943 \sa defaultCiphers()
944*/
945void QTlsBackend::setDefaultCiphers(const QList<QSslCipher> &ciphers)
946{
947 QSslSocketPrivate::setDefaultCiphers(ciphers);
948}
949
950/*!
951 \internal
952 Sets \a ciphers as defaults ciphers that QDtls can use.
953
954 \sa defaultDtlsCiphers()
955*/
956void QTlsBackend::setDefaultDtlsCiphers(const QList<QSslCipher> &ciphers)
957{
958 QSslSocketPrivate::setDefaultDtlsCiphers(ciphers);
959}
960
961/*!
962 \internal
963 Sets \a ciphers as a list of supported ciphers.
964
965 \sa QSslConfiguration::supportedCiphers()
966*/
967void QTlsBackend::setDefaultSupportedCiphers(const QList<QSslCipher> &ciphers)
968{
969 QSslSocketPrivate::setDefaultSupportedCiphers(ciphers);
970}
971
972/*!
973 \internal
974 Sets the list of QSslEllipticCurve objects, that QSslConfiguration::supportedEllipticCurves()
975 returns, to ones that are supported by this backend.
976*/
977void QTlsBackend::resetDefaultEllipticCurves()
978{
979 QSslSocketPrivate::resetDefaultEllipticCurves();
980}
981
982/*!
983 Sets \a certs as a list of certificates, that QSslConfiguration::caCertificates()
984 reports.
985
986 \sa QSslConfiguration::defaultConfiguration(), QSslConfiguration::caCertificates()
987*/
988void QTlsBackend::setDefaultCaCertificates(const QList<QSslCertificate> &certs)
989{
990 QSslSocketPrivate::setDefaultCaCertificates(certs);
991}
992
993/*!
994 \internal
995 Returns true if \a configuration allows loading root certificates on demand.
996*/
997bool QTlsBackend::rootLoadingOnDemandAllowed(const QSslConfiguration &configuration)
998{
999 return configuration.d->allowRootCertOnDemandLoading;
1000}
1001
1002/*!
1003 \internal
1004 Stores \a peerCert in the \a configuration.
1005*/
1006void QTlsBackend::storePeerCertificate(QSslConfiguration &configuration,
1007 const QSslCertificate &peerCert)
1008{
1009 configuration.d->peerCertificate = peerCert;
1010}
1011
1012/*!
1013 \internal
1014 Stores \a peerChain in the \a configuration.
1015*/
1016void QTlsBackend::storePeerCertificateChain(QSslConfiguration &configuration,
1017 const QList<QSslCertificate> &peerChain)
1018{
1019 configuration.d->peerCertificateChain = peerChain;
1020}
1021
1022/*!
1023 \internal
1024 Clears the peer certificate chain in \a configuration.
1025*/
1026void QTlsBackend::clearPeerCertificates(QSslConfiguration &configuration)
1027{
1028 configuration.d->peerCertificate.clear();
1029 configuration.d->peerCertificateChain.clear();
1030}
1031
1032/*!
1033 \internal
1034 Clears the peer certificate chain in \a d.
1035*/
1036void QTlsBackend::clearPeerCertificates(QSslSocketPrivate *d)
1037{
1038 Q_ASSERT(d);
1039 d->configuration.peerCertificate.clear();
1040 d->configuration.peerCertificateChain.clear();
1041}
1042
1043/*!
1044 \internal
1045 Updates the configuration in \a d with \a shared value.
1046*/
1047void QTlsBackend::setPeerSessionShared(QSslSocketPrivate *d, bool shared)
1048{
1049 Q_ASSERT(d);
1050 d->configuration.peerSessionShared = shared;
1051}
1052
1053/*!
1054 \internal
1055 Sets TLS session in \a d to \a asn1.
1056*/
1057void QTlsBackend::setSessionAsn1(QSslSocketPrivate *d, const QByteArray &asn1)
1058{
1059 Q_ASSERT(d);
1060 d->configuration.sslSession = asn1;
1061}
1062
1063/*!
1064 \internal
1065 Sets TLS session lifetime hint in \a d to \a hint.
1066*/
1067void QTlsBackend::setSessionLifetimeHint(QSslSocketPrivate *d, int hint)
1068{
1069 Q_ASSERT(d);
1070 d->configuration.sslSessionTicketLifeTimeHint = hint;
1071}
1072
1073/*!
1074 \internal
1075 Sets application layer protocol negotiation status in \a d to \a st.
1076*/
1077void QTlsBackend::setAlpnStatus(QSslSocketPrivate *d, AlpnNegotiationStatus st)
1078{
1079 Q_ASSERT(d);
1080 d->configuration.nextProtocolNegotiationStatus = st;
1081}
1082
1083/*!
1084 \internal
1085 Sets \a protocol in \a d as a negotiated application layer protocol.
1086*/
1087void QTlsBackend::setNegotiatedProtocol(QSslSocketPrivate *d, const QByteArray &protocol)
1088{
1089 Q_ASSERT(d);
1090 d->configuration.nextNegotiatedProtocol = protocol;
1091}
1092
1093/*!
1094 \internal
1095 Stores \a peerCert in the TLS configuration of \a d.
1096*/
1097void QTlsBackend::storePeerCertificate(QSslSocketPrivate *d, const QSslCertificate &peerCert)
1098{
1099 Q_ASSERT(d);
1100 d->configuration.peerCertificate = peerCert;
1101}
1102
1103/*!
1104 \internal
1105
1106 Stores \a peerChain in the TLS configuration of \a d.
1107
1108 \note This is a helper function that TlsCryptograph and DtlsCryptograph
1109 call during a handshake.
1110*/
1111void QTlsBackend::storePeerCertificateChain(QSslSocketPrivate *d,
1112 const QList<QSslCertificate> &peerChain)
1113{
1114 Q_ASSERT(d);
1115 d->configuration.peerCertificateChain = peerChain;
1116}
1117
1118/*!
1119 \internal
1120
1121 Adds \a rootCert to the list of trusted root certificates in \a d.
1122
1123 \note In Qt 6.1 it's only used on Windows, during so called 'CA fetch'.
1124*/
1125void QTlsBackend::addTustedRoot(QSslSocketPrivate *d, const QSslCertificate &rootCert)
1126{
1127 Q_ASSERT(d);
1128 if (!d->configuration.caCertificates.contains(t: rootCert))
1129 d->configuration.caCertificates += rootCert;
1130}
1131
1132/*!
1133 \internal
1134
1135 Saves ephemeral \a key in \a d.
1136
1137 \sa QSslConfiguration::ephemeralKey()
1138*/
1139void QTlsBackend::setEphemeralKey(QSslSocketPrivate *d, const QSslKey &key)
1140{
1141 Q_ASSERT(d);
1142 d->configuration.ephemeralServerKey = key;
1143}
1144
1145/*!
1146 \internal
1147
1148 Implementation-specific. Sets the security level suitable for Qt's
1149 auto-tests.
1150*/
1151void QTlsBackend::forceAutotestSecurityLevel()
1152{
1153}
1154
1155#endif // QT_CONFIG(ssl)
1156
1157namespace QTlsPrivate {
1158
1159/*!
1160 \internal (Network-private)
1161 \namespace QTlsPrivate
1162 \brief Namespace containing onternal types that TLS backends implement.
1163
1164 This namespace is private to Qt and the backends that implement its TLS support.
1165*/
1166
1167/*!
1168 \class TlsKey
1169 \internal (Network-private)
1170 \brief TlsKey is an abstract class, that allows a TLS plugin to provide
1171 an underlying implementation for the class QSslKey.
1172
1173 Most functions in the class TlsKey are pure virtual and thus have to be
1174 reimplemented by a TLS backend that supports QSslKey. In many cases an
1175 empty implementation as an overrider is sufficient, albeit with some
1176 of QSslKey's functionality missing.
1177
1178 \sa QTlsBackend::createKey(), QTlsBackend::implementedClasses(), QSslKey
1179*/
1180
1181/*!
1182 \fn void TlsKey::decodeDer(KeyType type, KeyAlgorithm algorithm, const QByteArray &der, const QByteArray &passPhrase, bool deepClear)
1183 \internal
1184
1185 If a support of public and private keys in DER format is required, this function
1186 must be overridden and should initialize this key using the \a type, \a algorithm, \a der
1187 and \a passPhrase. If this key was initialized previously, \a deepClear
1188 has an implementation-specific meaning (e.g., if an implementation is using
1189 reference-counting and can share internally some data structures, a value \c true may
1190 trigger decrementing a reference counter on some implementation-specific object).
1191
1192 \note An empty overrider is sufficient, but then reading keys in QSsl::Der format
1193 will not be supported.
1194
1195 \sa isNull(), QSsl::KeyType, QSsl::EncodingFormat, QSsl::KeyAlgorithm
1196*/
1197
1198/*!
1199 \fn void TlsKey::decodePem(KeyType type, KeyAlgorithm algorithm, const QByteArray &pem, const QByteArray &passPhrase, bool deepClear)
1200 \internal
1201
1202 If a support of public and private keys in PEM format is required, this function must
1203 be overridden and should initialize this key using the \a type, \a algorithm, \a pem and
1204 \a passPhrase. If this key was initialized previously, \a deepClear has an
1205 implementation-specific meaning (e.g., in an implementation using reference-counting,
1206 a value \c true may trigger decrementing a reference counter on some implementation-specific
1207 object).
1208
1209 \note An empty overrider is sufficient, but then reading keys in QSsl::Pem format
1210 will not be supported.
1211
1212 \sa isNull(), QSsl::KeyType, QSsl::EncodingFormat, QSsl::KeyAlgorithm
1213*/
1214
1215/*!
1216 \fn QByteArray TlsKey::toPem(const QByteArray &passPhrase) const
1217 \internal
1218
1219 This function must be overridden, if converting a key to PEM format, potentially with
1220 encryption, is needed (e.g. to save a QSslKey into a file). If this key is
1221 private and \a passPhrase is not empty, the key's data is expected to be encrypted using
1222 some conventional encryption algorithm (e.g. DES or AES - the one that different tools
1223 or even the class QSslKey can understand later).
1224
1225 \note If this particular functionality is not needed, an overrider returning an
1226 empty QByteArray is sufficient.
1227
1228 \sa QSslKey::toPem()
1229*/
1230
1231/*!
1232 \fn QByteArray TlsKey::derFromPem(const QByteArray &pem, QMap<QByteArray, QByteArray> *headers) const
1233 \internal
1234
1235 Converts \a pem to DER format, using this key's type and algorithm. The parameter \a headers
1236 must be a valid, non-null pointer. When parsing \a pem, the headers found there will be saved
1237 into \a headers.
1238
1239 \note An overrider returning an empty QByteArray is sufficient, if QSslKey::toDer() is not
1240 needed.
1241
1242 \note This function is very implementation-specific. A backend, that already has this key's
1243 non-empty DER data, may simply return this data.
1244
1245 \sa QSslKey::toDer()
1246*/
1247
1248/*!
1249 \fn QByteArray TlsKey::pemFromDer(const QByteArray &der, const QMap<QByteArray, QByteArray> &headers) const
1250 \internal
1251
1252 If overridden, this function is expected to convert \a der, using \a headers, to PEM format.
1253
1254 \note This function is very implementation-specific. As of now (Qt 6.1), it is only required by
1255 Qt's own non-OpenSSL backends, that internally use DER and implement QSslKey::toPem()
1256 via pemFromDer().
1257*/
1258
1259/*!
1260 \fn void TlsKey::fromHandle(Qt::HANDLE handle, KeyType type)
1261 \internal
1262
1263 Initializes this key using the \a handle and \a type, taking the ownership
1264 of the \a handle.
1265
1266 \note The meaning of the \a handle is implementation-specific.
1267
1268 \note If a TLS backend does not support such keys, it must provide an
1269 empty implementation.
1270
1271 \sa handle(), QSslKey::QSslKey(), QSslKet::handle()
1272*/
1273
1274/*!
1275 \fn TlsKey::handle() const
1276 \internal
1277
1278 If a TLS backend supports opaque keys, returns a native handle that
1279 this key was initialized with.
1280
1281 \sa fromHandle(), QSslKey::handle()
1282*/
1283
1284/*!
1285 \fn bool TlsKey::isNull() const
1286 \internal
1287
1288 Returns \c true if this is a null key, \c false otherwise.
1289
1290 \note A null key corresponds to the default-constructed
1291 QSslKey or the one, that was cleared via QSslKey::clear().
1292
1293 \sa QSslKey::isNull()
1294*/
1295
1296/*!
1297 \fn QSsl::KeyType TlsKey::type() const
1298 \internal
1299
1300 Returns the type of this key (public or private).
1301*/
1302
1303/*!
1304 \fn QSsl::KeyAlgorithm TlsKey::algorithm() const
1305 \internal
1306
1307 Return this key's algorithm.
1308*/
1309
1310/*!
1311 \fn int TlsKey::length() const
1312 \internal
1313
1314 Returns the length of the key in bits, or -1 if the key is null.
1315*/
1316
1317/*!
1318 \fn void TlsKey::clear(bool deep)
1319 \internal
1320
1321 Clears the contents of this key, making it a null key. The meaning
1322 of \a deep is implementation-specific (e.g. if some internal objects
1323 representing a key can be shared using reference counting, \a deep equal
1324 to \c true would imply decrementing a reference count).
1325
1326 \sa isNull()
1327*/
1328
1329/*!
1330 \fn bool TlsKey::isPkcs8() const
1331 \internal
1332
1333 This function is internally used only by Qt's own TLS plugins and affects
1334 the way PEM file is generated by TlsKey. It's sufficient to override it
1335 and return \c false in case a new TLS backend is not using Qt's plugin
1336 as a base.
1337*/
1338
1339/*!
1340 \fn QByteArray TlsKey::decrypt(Cipher cipher, const QByteArray &data, const QByteArray &passPhrase, const QByteArray &iv) const
1341 \internal
1342
1343 This function allows to decrypt \a data (for example, a private key read from a file), using
1344 \a passPhrase, initialization vector \a iv. \a cipher is describing a block cipher and its
1345 mode (for example, AES256 + CBC). decrypt() is needed to implement QSslKey's constructor.
1346
1347 \note A TLS backend may provide an empty implementation, but as a result QSslKey will not be able
1348 to work with private encrypted keys.
1349
1350 \sa QSslKey
1351*/
1352
1353/*!
1354 \fn QByteArray TlsKey::encrypt(Cipher cipher, const QByteArray &data, const QByteArray &passPhrase, const QByteArray &iv) const
1355 \internal
1356
1357 This function is needed to implement QSslKey::toPem() with encryption (for a private
1358 key). \a cipher names a block cipher to use to encrypt \a data, using
1359 \a passPhrase and initialization vector \a iv.
1360
1361 \note An empty implementation is sufficient, but QSslKey::toPem() will fail for
1362 a private key and non-empty passphrase.
1363
1364 \sa QSslKey
1365*/
1366
1367/*!
1368 \internal
1369
1370 Destroys this key.
1371*/
1372TlsKey::~TlsKey() = default;
1373
1374/*!
1375 \internal
1376
1377 A convenience function that returns a string, corresponding to the
1378 key type or algorithm, which can be used as a header in a PEM file.
1379*/
1380QByteArray TlsKey::pemHeader() const
1381{
1382 if (type() == QSsl::PublicKey)
1383 return QByteArrayLiteral("-----BEGIN PUBLIC KEY-----");
1384 else if (algorithm() == QSsl::Rsa)
1385 return QByteArrayLiteral("-----BEGIN RSA PRIVATE KEY-----");
1386 else if (algorithm() == QSsl::Dsa)
1387 return QByteArrayLiteral("-----BEGIN DSA PRIVATE KEY-----");
1388 else if (algorithm() == QSsl::Ec)
1389 return QByteArrayLiteral("-----BEGIN EC PRIVATE KEY-----");
1390 else if (algorithm() == QSsl::Dh)
1391 return QByteArrayLiteral("-----BEGIN PRIVATE KEY-----");
1392
1393 Q_UNREACHABLE_RETURN({});
1394}
1395
1396/*!
1397 \internal
1398 A convenience function that returns a string, corresponding to the
1399 key type or algorithm, which can be used as a footer in a PEM file.
1400*/
1401QByteArray TlsKey::pemFooter() const
1402{
1403 if (type() == QSsl::PublicKey)
1404 return QByteArrayLiteral("-----END PUBLIC KEY-----");
1405 else if (algorithm() == QSsl::Rsa)
1406 return QByteArrayLiteral("-----END RSA PRIVATE KEY-----");
1407 else if (algorithm() == QSsl::Dsa)
1408 return QByteArrayLiteral("-----END DSA PRIVATE KEY-----");
1409 else if (algorithm() == QSsl::Ec)
1410 return QByteArrayLiteral("-----END EC PRIVATE KEY-----");
1411 else if (algorithm() == QSsl::Dh)
1412 return QByteArrayLiteral("-----END PRIVATE KEY-----");
1413
1414 Q_UNREACHABLE_RETURN({});
1415}
1416
1417/*!
1418 \class X509Certificate
1419 \internal (Network-private)
1420 \brief X509Certificate is an abstract class that allows a TLS backend to
1421 provide an implementation of the QSslCertificate class.
1422
1423 This class provides an interface that must be reimplemented by a TLS plugin,
1424 that supports QSslCertificate. Most functions are pure virtual, and thus
1425 have to be overridden. For some of them, an empty overrider is acceptable,
1426 though a part of functionality in QSslCertificate will be missing.
1427
1428 \sa QTlsBackend::createCertificate(), QTlsBackend::X509PemReader(), QTlsBackend::X509DerReader()
1429*/
1430
1431/*!
1432 \fn bool X509Certificate::isEqual(const X509Certificate &other) const
1433 \internal
1434
1435 This function is expected to return \c true if this certificate is the same as
1436 the \a other, \c false otherwise. Used by QSslCertificate's comparison operators.
1437*/
1438
1439/*!
1440 \fn bool X509Certificate::isNull() const
1441 \internal
1442
1443 Returns true if this certificate was default-constructed and not initialized yet.
1444 This function is called by QSslCertificate::isNull().
1445
1446 \sa QSslCertificate::isNull()
1447*/
1448
1449/*!
1450 \fn bool X509Certificate::isSelfSigned() const
1451 \internal
1452
1453 This function is needed to implement QSslCertificate::isSelfSigned()
1454
1455 \sa QSslCertificate::isSelfSigned()
1456*/
1457
1458/*!
1459 \fn QByteArray X509Certificate::version() const
1460 \internal
1461
1462 Implements QSslCertificate::version().
1463
1464 \sa QSslCertificate::version()
1465*/
1466
1467/*!
1468 \fn QByteArray X509Certificate::serialNumber() const
1469 \internal
1470
1471 This function is expected to return the certificate's serial number string in
1472 hexadecimal format.
1473
1474 \sa QSslCertificate::serialNumber()
1475*/
1476
1477/*!
1478 \fn QStringList X509Certificate::issuerInfo(QSslCertificate::SubjectInfo subject) const
1479 \internal
1480
1481 This function is expected to return the issuer information for the \a subject
1482 from the certificate, or an empty list if there is no information for subject
1483 in the certificate. There can be more than one entry of each type.
1484
1485 \sa QSslCertificate::issuerInfo().
1486*/
1487
1488/*!
1489 \fn QStringList X509Certificate::issuerInfo(const QByteArray &attribute) const
1490 \internal
1491
1492 This function is expected to return the issuer information for attribute from
1493 the certificate, or an empty list if there is no information for \a attribute
1494 in the certificate. There can be more than one entry for an attribute.
1495
1496 \sa QSslCertificate::issuerInfo().
1497*/
1498
1499/*!
1500 \fn QStringList X509Certificate::subjectInfo(QSslCertificate::SubjectInfo subject) const
1501 \internal
1502
1503 This function is expected to return the information for the \a subject, or an empty list
1504 if there is no information for subject in the certificate. There can be more than one
1505 entry of each type.
1506
1507 \sa QSslCertificate::subjectInfo().
1508*/
1509
1510/*!
1511 \fn QStringList X509Certificate::subjectInfo(const QByteArray &attribute) const
1512 \internal
1513
1514 This function is expected to return the subject information for \a attribute, or
1515 an empty list if there is no information for attribute in the certificate.
1516 There can be more than one entry for an attribute.
1517
1518 \sa QSslCertificate::subjectInfo().
1519*/
1520
1521/*!
1522 \fn QList<QByteArray> X509Certificate::subjectInfoAttributes() const
1523 \internal
1524
1525 This function is expected to return a list of the attributes that have values
1526 in the subject information of this certificate. The information associated
1527 with a given attribute can be accessed using the subjectInfo() method. Note
1528 that this list may include the OIDs for any elements that are not known by
1529 the TLS backend.
1530
1531 \note This function is needed for QSslCertificate:::subjectInfoAttributes().
1532
1533 \sa subjectInfo()
1534*/
1535
1536/*!
1537 \fn QList<QByteArray> X509Certificate::issuerInfoAttributes() const
1538 \internal
1539
1540 This function is expected to return a list of the attributes that have
1541 values in the issuer information of this certificate. The information
1542 associated with a given attribute can be accessed using the issuerInfo()
1543 method. Note that this list may include the OIDs for any
1544 elements that are not known by the TLS backend.
1545
1546 \note This function implements QSslCertificate::issuerInfoAttributes().
1547
1548 \sa issuerInfo()
1549*/
1550
1551/*!
1552 \fn QMultiMap<QSsl::AlternativeNameEntryType, QString> X509Certificate::subjectAlternativeNames() const
1553 \internal
1554
1555 This function is expected to return the list of alternative subject names for
1556 this certificate. The alternative names typically contain host names, optionally
1557 with wildcards, that are valid for this certificate.
1558
1559 \sa subjectInfo()
1560*/
1561
1562/*!
1563 \fn QDateTime X509Certificate::effectiveDate() const
1564 \internal
1565
1566 This function is expected to return the date-time that the certificate
1567 becomes valid, or an empty QDateTime if this is a null certificate.
1568
1569 \sa expiryDate()
1570*/
1571
1572/*!
1573 \fn QDateTime X509Certificate::expiryDate() const
1574 \internal
1575
1576 This function is expected to return the date-time that the certificate expires,
1577 or an empty QDateTime if this is a null certificate.
1578
1579 \sa effectiveDate()
1580*/
1581
1582/*!
1583 \fn qsizetype X509Certificate::numberOfExtensions() const
1584 \internal
1585
1586 This function is expected to return the number of X509 extensions of
1587 this certificate.
1588*/
1589
1590/*!
1591 \fn QString X509Certificate::oidForExtension(qsizetype i) const
1592 \internal
1593
1594 This function is expected to return the ASN.1 OID for the extension
1595 with index \a i.
1596
1597 \sa numberOfExtensions()
1598*/
1599
1600/*!
1601 \fn QString X509Certificate::nameForExtension(qsizetype i) const
1602 \internal
1603
1604 This function is expected to return the name for the extension
1605 with index \a i. If no name is known for the extension then the
1606 OID will be returned.
1607
1608 \sa numberOfExtensions(), oidForExtension()
1609*/
1610
1611/*!
1612 \fn QVariant X509Certificate::valueForExtension(qsizetype i) const
1613 \internal
1614
1615 This function is expected to return the value of the extension
1616 with index \a i. The structure of the value returned depends on
1617 the extension type
1618
1619 \sa numberOfExtensions()
1620*/
1621
1622/*!
1623 \fn bool X509Certificate::isExtensionCritical(qsizetype i) const
1624 \internal
1625
1626 This function is expected to return the criticality of the extension
1627 with index \a i.
1628
1629 \sa numberOfExtensions()
1630*/
1631
1632/*!
1633 \fn bool X509Certificate::isExtensionSupported(qsizetype i) const
1634 \internal
1635
1636 This function is expected to return \c true if this extension is supported.
1637 In this case, supported simply means that the structure of the QVariant returned
1638 by the valueForExtension() accessor will remain unchanged between versions.
1639
1640 \sa numberOfExtensions()
1641*/
1642
1643/*!
1644 \fn QByteArray X509Certificate::toPem() const
1645 \internal
1646
1647 This function is expected to return this certificate converted to a PEM (Base64)
1648 encoded representation.
1649*/
1650
1651/*!
1652 \fn QByteArray X509Certificate::toDer() const
1653 \internal
1654
1655 This function is expected to return this certificate converted to a DER (binary)
1656 encoded representation.
1657*/
1658
1659/*!
1660 \fn QString X509Certificate::toText() const
1661 \internal
1662
1663 This function is expected to return this certificate converted to a human-readable
1664 text representation.
1665*/
1666
1667/*!
1668 \fn Qt::HANDLE X509Certificate::handle() const
1669 \internal
1670
1671 This function is expected to return a pointer to the native certificate handle,
1672 if there is one, else nullptr.
1673*/
1674
1675/*!
1676 \fn size_t X509Certificate::hash(size_t seed) const
1677 \internal
1678
1679 This function is expected to return the hash value for this certificate,
1680 using \a seed to seed the calculation.
1681*/
1682
1683/*!
1684 \internal
1685
1686 Destroys this certificate.
1687*/
1688X509Certificate::~X509Certificate() = default;
1689
1690/*!
1691 \internal
1692
1693 Returns the certificate subject's public key.
1694*/
1695TlsKey *X509Certificate::publicKey() const
1696{
1697 return nullptr;
1698}
1699
1700#if QT_CONFIG(ssl)
1701
1702/*!
1703 \class TlsCryptograph
1704 \internal (Network-private)
1705 \brief TlsCryptograph is an abstract class, that allows a TLS plugin to implement QSslSocket.
1706
1707 This abstract base class provides an interface that must be reimplemented by a TLS plugin,
1708 that supports QSslSocket. A class, implementing TlsCryptograph's interface, is responsible
1709 for TLS handshake, reading and writing encryped application data; it is expected
1710 to work with QSslSocket and it's private implementation - QSslSocketPrivate.
1711 QSslSocketPrivate provides access to its read/write buffers, QTcpSocket it
1712 internally uses for connecting, reading and writing. QSslSocketPrivate
1713 can also be used for reporting errors and storing the certificates received
1714 during the handshake phase.
1715
1716 \note Most of the functions in this class are pure virtual and have no actual implementation
1717 in the QtNetwork module. This documentation is mostly conceptual and only describes what those
1718 functions are expected to do, but not how they must be implemented.
1719
1720 \sa QTlsBackend::createTlsCryptograph()
1721*/
1722
1723/*!
1724 \fn void TlsCryptograph::init(QSslSocket *q, QSslSocketPrivate *d)
1725 \internal
1726
1727 When initializing this TlsCryptograph, QSslSocket will pass a pointer to self and
1728 its d-object using this function.
1729*/
1730
1731/*!
1732 \fn QList<QSslError> TlsCryptograph::tlsErrors() const
1733 \internal
1734
1735 Returns a list of QSslError, describing errors encountered during
1736 the TLS handshake.
1737
1738 \sa QSslSocket::sslHandshakeErrors()
1739*/
1740
1741/*!
1742 \fn void TlsCryptograph::startClientEncryption()
1743 \internal
1744
1745 A client-side QSslSocket calls this function after its internal TCP socket
1746 establishes a connection with a remote host, or from QSslSocket::startClientEncryption().
1747 This TlsCryptograph is expected to initialize some implementation-specific TLS context,
1748 if needed, and then start the client side of the TLS handshake (for example, by calling
1749 transmit()), using TCP socket from QSslSocketPrivate.
1750
1751 \sa init(), transmit(), QSslSocket::startClientEncryption(), QSslSocket::connectToHostEncrypted()
1752*/
1753
1754/*!
1755 \fn void TlsCryptograph::startServerEncryption()
1756 \internal
1757
1758 This function is called by QSslSocket::startServerEncryption(). The TlsCryptograph
1759 is expected to initialize some implementation-specific TLS context, if needed,
1760 and then try to read the ClientHello message and continue the TLS handshake
1761 (for example, by calling transmit()).
1762
1763 \sa transmit(), QSslSocket::startServerEncryption()
1764*/
1765
1766/*!
1767 \fn void TlsCryptograph::continueHandshake()
1768 \internal
1769
1770 QSslSocket::resume() calls this function if its pause mode is QAbstractSocket::PauseOnSslErrors,
1771 and errors, found during the handshake, were ignored. If implemented, this function is expected
1772 to emit QSslSocket::encrypted().
1773
1774 \sa QAbstractSocket::pauseMode(), QSslSocket::sslHandshakeErrors(), QSslSocket::ignoreSslErrors(), QSslSocket::resume()
1775*/
1776
1777/*!
1778 \fn void TlsCryptograph::disconnectFromHost()
1779 \internal
1780
1781 This function is expected to call disconnectFromHost() on the TCP socket
1782 that can be obtained from QSslSocketPrivate. Any additional actions
1783 are implementation-specific (e.g., sending shutdown alert message).
1784
1785*/
1786
1787/*!
1788 \fn void TlsCryptograph::disconnected()
1789 \internal
1790
1791 This function is called when the remote has disconnected. If there
1792 is data left to be read you may ignore the maxReadBufferSize restriction
1793 and read it all now.
1794*/
1795
1796/*!
1797 \fn QSslCipher TlsCryptograph::sessionCipher() const
1798 \internal
1799
1800 This function returns a QSslCipher object describing the ciphersuite negotiated
1801 during the handshake.
1802*/
1803
1804/*!
1805 \fn QSsl::SslProtocol TlsCryptograph::sessionProtocol() const
1806 \internal
1807
1808 This function returns the version of TLS (or DTLS) protocol negotiated during the handshake.
1809*/
1810
1811/*!
1812 \fn void TlsCryptograph::transmit()
1813 \internal
1814
1815 This function is responsible for reading and writing data. The meaning of these I/O
1816 operations depends on an implementation-specific TLS state machine. These read and write
1817 operations can be reading and writing parts of a TLS handshake (e.g. by calling handshake-specific
1818 functions), or reading and writing application data (if encrypted connection was already
1819 established). transmit() is expected to use the QSslSocket's TCP socket (accessible via
1820 QSslSocketPrivate) to read the incoming data and write the outgoing data. When in encrypted
1821 state, transmit() is also using QSslSocket's internal read and write buffers: the read buffer
1822 to fill with decrypted incoming data; the write buffer - for the data to encrypt and send.
1823 This TlsCryptograph can also use QSslSocketPrivate to check which TLS errors were ignored during
1824 the handshake.
1825
1826 \note This function is responsible for emitting QSslSocket's signals, that occur during the
1827 handshake (e.g. QSslSocket::sslErrors() or QSslSocket::encrypted()), and also read/write signals,
1828 e.g. QSslSocket::bytesWritten() and QSslSocket::readyRead().
1829
1830 \sa init()
1831*/
1832
1833/*!
1834 \internal
1835
1836 Destroys this object.
1837*/
1838TlsCryptograph::~TlsCryptograph() = default;
1839
1840/*!
1841 \internal
1842
1843 This function allows to share QSslContext between several QSslSocket objects.
1844 The default implementation does nothing.
1845
1846 \note The definition of the class QSslContext is implementation-specific.
1847
1848 \sa sslContext()
1849*/
1850void TlsCryptograph::checkSettingSslContext(std::shared_ptr<QSslContext> tlsContext)
1851{
1852 Q_UNUSED(tlsContext);
1853}
1854
1855/*!
1856 \internal
1857
1858 Returns the context previously set by checkSettingSslContext() or \nullptr,
1859 if no context was set. The default implementation returns \nullptr.
1860
1861 \sa checkSettingSslContext()
1862*/
1863std::shared_ptr<QSslContext> TlsCryptograph::sslContext() const
1864{
1865 return {};
1866}
1867
1868/*!
1869 \internal
1870
1871 If this TLS backend supports reporting errors before handshake is finished,
1872 e.g. from a verification callback function, enableHandshakeContinuation()
1873 allows this object to continue handshake. The default implementation does
1874 nothing.
1875
1876 \sa QSslSocket::handshakeInterruptedOnError(), QSslConfiguration::setHandshakeMustInterruptOnError()
1877*/
1878void TlsCryptograph::enableHandshakeContinuation()
1879{
1880}
1881
1882/*!
1883 \internal
1884
1885 Windows and OpenSSL-specific, only used internally by Qt's OpenSSL TLS backend.
1886
1887 \note The default empty implementation is sufficient.
1888*/
1889void TlsCryptograph::cancelCAFetch()
1890{
1891}
1892
1893/*!
1894 \internal
1895
1896 Windows and Schannel-specific, only used by Qt's Schannel TLS backend, in
1897 general, if a backend has its own buffer where it stores undecrypted data
1898 then it must report true if it contains any data through this function.
1899
1900 \note The default empty implementation, returning \c false is sufficient.
1901*/
1902bool TlsCryptograph::hasUndecryptedData() const
1903{
1904 return false;
1905}
1906
1907/*!
1908 \internal
1909
1910 Returns the list of OCSP (Online Certificate Status Protocol) responses,
1911 received during the handshake. The default implementation returns an empty
1912 list.
1913*/
1914QList<QOcspResponse> TlsCryptograph::ocsps() const
1915{
1916 return {};
1917}
1918
1919/*!
1920 \internal
1921
1922 A helper function that can be used during a handshake. Returns \c true if the \a peerName
1923 matches one of subject alternative names or common names found in the \a certificate.
1924*/
1925bool TlsCryptograph::isMatchingHostname(const QSslCertificate &certificate, const QString &peerName)
1926{
1927 return QSslSocketPrivate::isMatchingHostname(cert: certificate, peerName);
1928}
1929
1930/*!
1931 \internal
1932 Calls QAbstractSocketPrivate::setErrorAndEmit() for \a d, passing \a errorCode and
1933 \a errorDescription as parameters.
1934*/
1935void TlsCryptograph::setErrorAndEmit(QSslSocketPrivate *d, QAbstractSocket::SocketError errorCode,
1936 const QString &errorDescription) const
1937{
1938 Q_ASSERT(d);
1939 d->setErrorAndEmit(errorCode, errorString: errorDescription);
1940}
1941
1942#if QT_CONFIG(dtls)
1943/*!
1944 \class DtlsBase
1945 \internal (Network-private)
1946 \brief DtlsBase is a base class for the classes DtlsCryptograph and DtlsCookieVerifier.
1947
1948 DtlsBase is the base class for the classes DtlsCryptograph and DtlsCookieVerifier. It's
1949 an abstract class, an interface that these before-mentioned classes share. It allows to
1950 set, get and clear the last error that occurred, set and get cookie generation parameters,
1951 set and get QSslConfiguration.
1952
1953 \note This class is not supposed to be inherited directly, it's only needed by DtlsCryptograph
1954 and DtlsCookieVerifier.
1955
1956 \sa QDtls, QDtlsClientVerifier, DtlsCryptograph, DtlsCookieVerifier
1957*/
1958
1959/*!
1960 \fn void DtlsBase::setDtlsError(QDtlsError code, const QString &description)
1961 \internal
1962
1963 Sets the last error to \a code and its textual description to \a description.
1964
1965 \sa QDtlsError, error(), errorString()
1966*/
1967
1968/*!
1969 \fn QDtlsError DtlsBase::error() const
1970 \internal
1971
1972 This function, when overridden, is expected to return the code for the last error that occurred.
1973 If no error occurred it should return QDtlsError::NoError.
1974
1975 \sa QDtlsError, errorString(), setDtlsError()
1976*/
1977
1978/*!
1979 \fn QDtlsError DtlsBase::errorString() const
1980 \internal
1981
1982 This function, when overridden, is expected to return the textual description for the last error
1983 that occurred or an empty string if no error occurred.
1984
1985 \sa QDtlsError, error(), setDtlsError()
1986*/
1987
1988/*!
1989 \fn void DtlsBase::clearDtlsError()
1990 \internal
1991
1992 This function is expected to set the error code for the last error to QDtlsError::NoError and
1993 its textual description to an empty string.
1994
1995 \sa QDtlsError, setDtlsError(), error(), errorString()
1996*/
1997
1998/*!
1999 \fn void DtlsBase::setConfiguration(const QSslConfiguration &configuration)
2000 \internal
2001
2002 Sets a TLS configuration that an object of a class inheriting from DtlsCookieVerifier or
2003 DtlsCryptograph will use, to \a configuration.
2004
2005 \sa configuration()
2006*/
2007
2008/*!
2009 \fn QSslConfiguration DtlsBase::configuration() const
2010 \internal
2011
2012 Returns TLS configuration this object is using (either set by setConfiguration()
2013 previously, or the default DTLS configuration).
2014
2015 \sa setConfiguration(), QSslConfiguration::defaultDtlsConfiguration()
2016*/
2017
2018/*!
2019 \fn bool DtlsBase::setCookieGeneratorParameters(const QDtlsClientVerifier::GeneratorParameters &params)
2020 \internal
2021
2022 Sets the DTLS cookie generation parameters that DtlsCookieVerifier or DtlsCryptograph will use to
2023 \a params.
2024
2025 \note This function returns \c false if parameters were invalid - if the secret was empty. Otherwise,
2026 this function must return true.
2027
2028 \sa QDtlsClientVerifier::GeneratorParameters, cookieGeneratorParameters()
2029*/
2030
2031/*!
2032 \fn QDtlsClientVerifier::GeneratorParameters DtlsBase::cookieGeneratorParameters() const
2033 \internal
2034
2035 Returns DTLS cookie generation parameters that were either previously set by setCookieGeneratorParameters(),
2036 or default parameters.
2037
2038 \sa setCookieGeneratorParameters()
2039*/
2040
2041/*!
2042 \internal
2043
2044 Destroys this object.
2045*/
2046DtlsBase::~DtlsBase() = default;
2047
2048/*!
2049 \class DtlsCookieVerifier
2050 \internal (Network-private)
2051 \brief DtlsCookieVerifier is an interface that allows a TLS plugin to support the class QDtlsClientVerifier.
2052
2053 DtlsCookieVerifier is an interface, an abstract class, that has to be implemented by
2054 a TLS plugin that supports DTLS cookie verification.
2055
2056 \sa QDtlsClientVerifier
2057*/
2058
2059/*!
2060 \fn bool DtlsCookieVerifier::verifyClient(QUdpSocket *socket, const QByteArray &dgram, const QHostAddress &address, quint16 port)
2061 \internal
2062
2063 This function is expected to verify a ClientHello message, found in \a dgram, using \a address,
2064 \a port, and cookie generator parameters. The function returns \c true if such cookie was found
2065 and \c false otherwise. If no valid cookie was found in the \a dgram, this verifier should use
2066 \a socket to send a HelloVerifyRequest message, using \a address and \a port as the destination
2067 and a source material for cookie generation, see also
2068 \l {RFC 6347, section 4.2.1}
2069
2070 \sa QDtlsClientVerifier
2071*/
2072
2073/*!
2074 \fn QByteArray DtlsCookieVerifier::verifiedHello() const
2075 \internal
2076
2077 Returns the last ClientHello message containing the DTLS cookie that this verifier was
2078 able to verify as correct, or an empty byte array.
2079
2080 \sa verifyClient()
2081*/
2082
2083/*!
2084 \class DtlsCryptograph
2085 \internal (Network-private)
2086 \brief DtlsCryptograph is an interface that allows a TLS plugin to implement the class QDtls.
2087
2088 DtlsCryptograph is an abstract class; a TLS plugin can provide a class, inheriting from
2089 DtlsCryptograph and implementing its pure virtual functions, thus implementing the class
2090 QDtls and enabling DTLS over UDP.
2091
2092 To write DTLS datagrams, a class, inheriting DtlsCryptograph, is expected to use
2093 QUdpSocket. In general, all reading is done externally, so DtlsCryptograph is
2094 expected to only write into QUdpSocket, check possible socket errors, change socket
2095 options if needed.
2096
2097 \note All functions in this class are pure virtual and have no actual implementation
2098 in the QtNetwork module. This documentation is mostly conceptual and only describes
2099 what those functions are expected to do, but not how they must be implemented.
2100
2101 \sa QDtls, QUdpSocket
2102*/
2103
2104/*!
2105 \fn QSslSocket::SslMode DtlsCryptograph::cryptographMode() const
2106 \internal
2107
2108 Returns the mode (client or server) this object operates in.
2109
2110 \note This mode is set once when a new DtlsCryptograph is created
2111 by QTlsBackend and cannot change.
2112
2113 \sa QTlsBackend::createDtlsCryptograph()
2114*/
2115
2116/*!
2117 \fn void DtlsCryptograph::setPeer(const QHostAddress &addr, quint16 port, const QString &name)
2118 \internal
2119
2120 Sets the remote peer's address to \a addr and remote port to \a port. \a name,
2121 if not empty, is to be used when validating the peer's certificate.
2122
2123 \sa peerAddress(), peerPort(), peerVerificationName()
2124*/
2125
2126/*!
2127 \fn QHostAddress DtlsCryptograph::peerAddress() const
2128 \internal
2129
2130 Returns the remote peer's address previously set by setPeer() or,
2131 if no address was set, an empty address.
2132
2133 \sa setPeer()
2134*/
2135
2136/*!
2137 \fn quint16 DtlsCryptograph::peerPort() const
2138 \internal
2139
2140 Returns the remote peer's port previously set by setPeer() or
2141 0 if no port was set.
2142
2143 \sa setPeer(), peerAddress()
2144*/
2145
2146/*!
2147 \fn void DtlsCryptograph::setPeerVerificationName(const QString &name)
2148 \internal
2149
2150 Sets the host name to use during certificate validation to \a name.
2151
2152 \sa peerVerificationName(), setPeer()
2153*/
2154
2155/*!
2156 \fn QString DtlsCryptograph::peerVerificationName() const
2157 \internal
2158
2159 Returns the name that this object is using during the certificate validation,
2160 previously set by setPeer() or setPeerVerificationName(). Returns an empty string
2161 if no peer verification name was set.
2162
2163 \sa setPeer(), setPeerVerificationName()
2164*/
2165
2166/*!
2167 \fn void DtlsCryptograph::setDtlsMtuHint(quint16 mtu)
2168 \internal
2169
2170 Sets the maximum transmission unit (MTU), if it is supported by a TLS implementation, to \a mtu.
2171
2172 \sa dtlsMtuHint()
2173*/
2174
2175/*!
2176 \fn quint16 DtlsCryptograph::dtlsMtuHint() const
2177 \internal
2178
2179 Returns the value of the maximum transmission unit either previously set by setDtlsMtuHint(),
2180 or some implementation-specific value (guessed or somehow known to this DtlsCryptograph).
2181
2182 \sa setDtlsMtuHint()
2183*/
2184
2185/*!
2186 \fn QDtls::HandshakeState DtlsCryptograph::state() const
2187 \internal
2188
2189 Returns the current handshake state for this DtlsCryptograph (not started, in progress,
2190 peer verification error found, complete).
2191
2192 \sa isConnectionEncrypted(), startHandshake()
2193*/
2194
2195/*!
2196 \fn bool DtlsCryptograph::isConnectionEncrypted() const
2197 \internal
2198
2199 Returns \c true if this DtlsCryptograph has completed a handshake without validation
2200 errors (or these errors were ignored). Returns \c false otherwise.
2201*/
2202
2203/*!
2204 \fn bool DtlsCryptograph::startHandshake(QUdpSocket *socket, const QByteArray &dgram)
2205 \internal
2206
2207 This function is expected to initialize some implementation-specific context and to start a DTLS
2208 handshake, using \a socket to write datagrams (but not to read them). If this object is operating
2209 as a server, \a dgram is non-empty and contains the ClientHello message. This function returns
2210 \c true if no error occurred (and this DtlsCryptograph's state switching to
2211 QDtls::HandshakeState::HandshakeInProgress), \c false otherwise.
2212
2213 \sa continueHandshake(), handleTimeout(), resumeHandshake(), abortHandshake(), state()
2214*/
2215
2216/*!
2217 \fn bool DtlsCryptograph::handleTimeout(QUdpSocket *socket)
2218 \internal
2219
2220 In case a timeout occurred during the handshake, allows to re-transmit the last message,
2221 using \a socket to write the datagram. Returns \c true if no error occurred, \c false otherwise.
2222
2223 \sa QDtls::handshakeTimeout(), QDtls::handleTimeout()
2224*/
2225
2226/*!
2227 \fn bool DtlsCryptograph::continueHandshake(QUdpSocket *socket, const QByteArray &dgram)
2228 \internal
2229
2230 Continues the handshake, using \a socket to write datagrams (a handshake-specific message).
2231 \a dgram contains the peer's handshake-specific message. Returns \c false in case some error
2232 was encountered (this can include socket-related errors and errors found during the certificate
2233 validation). Returns \c true if the handshake was complete successfully, or is still in progress.
2234
2235 This function, depending on the implementation-specific state machine, may leave the handshake
2236 state in QDtls::HandshakeState::HandshakeInProgress, or switch to QDtls::HandshakeState::HandshakeComplete
2237 or QDtls::HandshakeState::PeerVerificationFailed.
2238
2239 This function may store the peer's certificate (or chain of certificates), extract and store
2240 the information about the negotiated session protocol and ciphersuite.
2241
2242 \sa startHandshake()
2243*/
2244
2245/*!
2246 \fn bool DtlsCryptograph::resumeHandshake(QUdpSocket *socket)
2247 \internal
2248
2249 If peer validation errors were found duing the handshake, this function tries to
2250 continue and complete the handshake. If errors were ignored, the function switches
2251 this object's state to QDtls::HandshakeState::HandshakeComplete and returns \c true.
2252
2253 \sa abortHandshake()
2254*/
2255
2256/*!
2257 \fn void DtlsCryptograph::abortHandshake(QUdpSocket *socket)
2258 \internal
2259
2260 Aborts the handshake if it's in progress or in the state QDtls::HandshakeState::PeerVerificationFailed.
2261 The use of \a socket is implementation-specific (for example, this DtlsCryptograph may send
2262 ShutdownAlert message).
2263
2264 \sa resumeHandshake()
2265*/
2266
2267/*!
2268 \fn void DtlsCryptograph::sendShutdownAlert(QUdpSocket *socket)
2269 \internal
2270
2271 If the underlying TLS library provides the required functionality, this function
2272 may sent ShutdownAlert message using \a socket.
2273*/
2274
2275/*!
2276 \fn QList<QSslError> DtlsCryptograph::peerVerificationErrors() const
2277 \internal
2278
2279 Returns the list of errors that this object encountered during DTLS handshake
2280 and certificate validation.
2281
2282 \sa ignoreVerificationErrors()
2283*/
2284
2285/*!
2286 \fn void DtlsCryptograph::ignoreVerificationErrors(const QList<QSslError> &errorsToIgnore)
2287 \internal
2288
2289 Tells this object to ignore errors from \a errorsToIgnore when they are found during
2290 DTLS handshake.
2291
2292 \sa peerVerificationErrors()
2293*/
2294
2295/*!
2296 \fn QSslCipher DtlsCryptograph::dtlsSessionCipher() const
2297 \internal
2298
2299 If such information is available, returns the ciphersuite, negotiated during
2300 the handshake.
2301
2302 \sa continueHandshake(), dtlsSessionProtocol()
2303*/
2304
2305/*!
2306 \fn QSsl::SslProtocol DtlsCryptograph::dtlsSessionProtocol() const
2307 \internal
2308
2309 Returns the version of the session protocol that was negotiated during the handshake or
2310 QSsl::UnknownProtocol if the handshake is incomplete or no information about the session
2311 protocol is available.
2312
2313 \sa continueHandshake(), dtlsSessionCipher()
2314*/
2315
2316/*!
2317 \fn qint64 DtlsCryptograph::writeDatagramEncrypted(QUdpSocket *socket, const QByteArray &dgram)
2318 \internal
2319
2320 If this DtlsCryptograph is in the QDtls::HandshakeState::HandshakeComplete state, this function
2321 encrypts \a dgram and writes this encrypted data into \a socket.
2322
2323 Returns the number of bytes (of \a dgram) written, or -1 in case of error. This function should
2324 set the error code and description if some error was encountered.
2325
2326 \sa decryptDatagram()
2327*/
2328
2329/*!
2330 \fn QByteArray DtlsCryptograph::decryptDatagram(QUdpSocket *socket, const QByteArray &dgram)
2331 \internal
2332
2333 If this DtlsCryptograph is in the QDtls::HandshakeState::HandshakeComplete state, decrypts \a dgram.
2334 The use of \a socket is implementation-specific. This function should return an empty byte array
2335 and set the error code and description if some error was encountered.
2336*/
2337
2338#endif // QT_CONFIG(dtls)
2339#endif // QT_CONFIG(ssl)
2340
2341} // namespace QTlsPrivate
2342
2343#if QT_CONFIG(ssl)
2344/*!
2345 \internal
2346*/
2347Q_NETWORK_EXPORT void qt_ForceTlsSecurityLevel()
2348{
2349 if (auto *backend = QSslSocketPrivate::tlsBackendInUse())
2350 backend->forceAutotestSecurityLevel();
2351}
2352
2353#endif // QT_CONFIG(ssl)
2354
2355QT_END_NAMESPACE
2356
2357#include "moc_qtlsbackend_p.cpp"
2358

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

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