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