| 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 | |
| 26 | QT_BEGIN_NAMESPACE |
| 27 | |
| 28 | using namespace Qt::StringLiterals; |
| 29 | |
| 30 | Q_APPLICATION_STATIC(QFactoryLoader, qtlsbLoader, QTlsBackend_iid, |
| 31 | QStringLiteral("/tls" )) |
| 32 | |
| 33 | namespace { |
| 34 | |
| 35 | class BackendCollection |
| 36 | { |
| 37 | public: |
| 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 | |
| 106 | private: |
| 107 | std::vector<QTlsBackend *> backends; |
| 108 | QMutex collectionMutex; |
| 109 | }; |
| 110 | |
| 111 | } // Unnamed namespace |
| 112 | |
| 113 | Q_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 | |
| 154 | const 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 | */ |
| 167 | QTlsBackend::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 | */ |
| 185 | QTlsBackend::~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 | |
| 203 | bool 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 | */ |
| 216 | long 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 | |
| 230 | QString 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 | |
| 244 | long 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 | */ |
| 257 | QString 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 | */ |
| 267 | void 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 | */ |
| 283 | QTlsPrivate::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 | */ |
| 298 | QTlsPrivate::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 | */ |
| 312 | QList<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 | */ |
| 327 | QTlsPrivate::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 | */ |
| 342 | QTlsPrivate::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 | */ |
| 359 | QTlsPrivate::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 | |
| 375 | QTlsPrivate::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 | */ |
| 388 | QTlsPrivate::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 | */ |
| 401 | QTlsPrivate::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 | */ |
| 414 | QTlsPrivate::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 | */ |
| 431 | QList<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 | */ |
| 448 | int 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 | */ |
| 466 | int 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 | */ |
| 483 | QString 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 | */ |
| 500 | QString 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 | */ |
| 515 | bool 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 | */ |
| 532 | int 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 | */ |
| 550 | int 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 | */ |
| 566 | QList<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 | */ |
| 579 | QString 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 | */ |
| 613 | QTlsBackend *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 | */ |
| 632 | QTlsBackend *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 | */ |
| 652 | QList<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 | */ |
| 672 | QList<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 | */ |
| 691 | QList<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 | */ |
| 706 | void 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 | */ |
| 721 | void 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 | */ |
| 745 | void 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 | */ |
| 771 | QSslCipher 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; |
| 783 | QT_WARNING_PUSH |
| 784 | QT_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 | } |
| 799 | QT_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 | */ |
| 824 | QSslCipher 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 | */ |
| 900 | QSslCipher 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 | */ |
| 925 | QList<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 | */ |
| 934 | QList<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 | */ |
| 945 | void 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 | */ |
| 956 | void 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 | */ |
| 967 | void 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 | */ |
| 977 | void 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 | */ |
| 988 | void 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 | */ |
| 997 | bool 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 | */ |
| 1006 | void 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 | */ |
| 1016 | void 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 | */ |
| 1026 | void 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 | */ |
| 1036 | void 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 | */ |
| 1047 | void 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 | */ |
| 1057 | void 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 | */ |
| 1067 | void 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 | */ |
| 1077 | void 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 | */ |
| 1087 | void 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 | */ |
| 1097 | void 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 | */ |
| 1111 | void 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 | */ |
| 1125 | void 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 | */ |
| 1139 | void 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 | */ |
| 1151 | void QTlsBackend::forceAutotestSecurityLevel() |
| 1152 | { |
| 1153 | } |
| 1154 | |
| 1155 | #endif // QT_CONFIG(ssl) |
| 1156 | |
| 1157 | namespace 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 | */ |
| 1372 | TlsKey::~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 | */ |
| 1380 | QByteArray TlsKey::() 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 | */ |
| 1401 | QByteArray TlsKey::() 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 | */ |
| 1688 | X509Certificate::~X509Certificate() = default; |
| 1689 | |
| 1690 | /*! |
| 1691 | \internal |
| 1692 | |
| 1693 | Returns the certificate subject's public key. |
| 1694 | */ |
| 1695 | TlsKey *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 | */ |
| 1838 | TlsCryptograph::~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 | */ |
| 1850 | void 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 | */ |
| 1863 | std::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 | */ |
| 1878 | void 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 | */ |
| 1889 | void 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 | */ |
| 1902 | bool 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 | */ |
| 1914 | QList<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 | */ |
| 1925 | bool 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 | */ |
| 1935 | void 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 ¶ms) |
| 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 | */ |
| 2046 | DtlsBase::~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 | */ |
| 2347 | Q_NETWORK_EXPORT void qt_ForceTlsSecurityLevel() |
| 2348 | { |
| 2349 | if (auto *backend = QSslSocketPrivate::tlsBackendInUse()) |
| 2350 | backend->forceAutotestSecurityLevel(); |
| 2351 | } |
| 2352 | |
| 2353 | #endif // QT_CONFIG(ssl) |
| 2354 | |
| 2355 | QT_END_NAMESPACE |
| 2356 | |
| 2357 | #include "moc_qtlsbackend_p.cpp" |
| 2358 | |