Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qtlsbackend_openssl.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
10
11#if QT_CONFIG(dtls)
12#include "qdtls_openssl_p.h"
13#endif // QT_CONFIG(dtls)
14
15#include <QtNetwork/private/qsslcipher_p.h>
16
17#include <QtNetwork/qsslcipher.h>
18#include <QtNetwork/qssl.h>
19
20#include <QtCore/qdir.h>
21#include <QtCore/qdirlisting.h>
22#include <QtCore/qlist.h>
23#include <QtCore/qmutex.h>
24#include <QtCore/qscopeguard.h>
25#include <QtCore/qset.h>
26
27#include "qopenssl_p.h"
28
29#include <algorithm>
30
31QT_BEGIN_NAMESPACE
32
33using namespace Qt::StringLiterals;
34
35#if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
36constexpr auto DefaultWarningLevel = QtCriticalMsg;
37#else
38constexpr auto DefaultWarningLevel = QtDebugMsg;
39#endif
40
41Q_LOGGING_CATEGORY(lcTlsBackend, "qt.tlsbackend.ossl", DefaultWarningLevel);
42
43static void q_loadCiphersForConnection(SSL *connection, QList<QSslCipher> &ciphers,
44 QList<QSslCipher> &defaultCiphers)
45{
46 Q_ASSERT(connection);
47
48 STACK_OF(SSL_CIPHER) *supportedCiphers = q_SSL_get_ciphers(connection);
49 for (int i = 0; i < q_sk_SSL_CIPHER_num(supportedCiphers); ++i) {
50 if (SSL_CIPHER *cipher = q_sk_SSL_CIPHER_value(supportedCiphers, i)) {
51 const auto ciph = QTlsBackendOpenSSL::qt_OpenSSL_cipher_to_QSslCipher(cipher);
52 if (!ciph.isNull()) {
53 // Unconditionally exclude ADH and AECDH ciphers since they offer no MITM protection
54 if (!ciph.name().toLower().startsWith("adh"_L1) &&
55 !ciph.name().toLower().startsWith("exp-adh"_L1) &&
56 !ciph.name().toLower().startsWith("aecdh"_L1)) {
57 ciphers << ciph;
58
59 if (ciph.usedBits() >= 128)
60 defaultCiphers << ciph;
61 }
62 }
63 }
64 }
65}
66
67int QTlsBackendOpenSSL::s_indexForSSLExtraData = -1;
68
69QString QTlsBackendOpenSSL::getErrorsFromOpenSsl()
70{
71 QString errorString;
72 char buf[256] = {}; // OpenSSL docs claim both 120 and 256; use the larger.
73 unsigned long errNum;
74 while ((errNum = q_ERR_get_error())) {
75 if (!errorString.isEmpty())
76 errorString.append(", "_L1);
77 q_ERR_error_string_n(errNum, buf, sizeof buf);
78 errorString.append(QLatin1StringView(buf)); // error is ascii according to man ERR_error_string
79 }
80 return errorString;
81}
82
83void QTlsBackendOpenSSL::logAndClearErrorQueue()
84{
85 const auto errors = getErrorsFromOpenSsl();
86 if (errors.size())
87 qCWarning(lcTlsBackend) << "Discarding errors:" << errors;
88}
89
90void QTlsBackendOpenSSL::clearErrorQueue()
91{
92 while (q_ERR_get_error())
93 ;
94}
95
96bool QTlsBackendOpenSSL::ensureLibraryLoaded()
97{
98 static bool libraryLoaded = []() {
100 return false;
101
102 // Initialize OpenSSL.
103 if (q_OPENSSL_init_ssl(0, nullptr) != 1)
104 return false;
105
106 if (q_OpenSSL_version_num() < 0x10101000L) {
107 qCWarning(lcTlsBackend, "QSslSocket: OpenSSL >= 1.1.1 is required; %s was found instead", q_OpenSSL_version(OPENSSL_VERSION));
108 return false;
109 }
110
113
114 s_indexForSSLExtraData = q_CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, 0L, nullptr, nullptr,
115 nullptr, nullptr);
116
117 // If QCryptographicHash (openssl_hash feature) was used before this
118 // point, it may have loaded and then unloaded the default OpenSSL
119 // provider, draining its activation count to zero. With no providers
120 // active, RAND_status() returns 0 even though seeding would succeed
121 // with a loaded provider. Hold a permanent activation reference to
122 // prevent that. Skip in FIPS mode: the FIPS provider supplies its own
123 // RAND, and loading the non-FIPS default would violate the user's
124 // security policy.
125#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
126 if (!q_EVP_default_properties_is_fips_enabled(nullptr)) {
127 static OSSL_PROVIDER *s_defaultProvider = q_OSSL_PROVIDER_load(nullptr, "default");
128 (void)s_defaultProvider;
129 }
130#endif
131
132 // Initialize OpenSSL's random seed.
133 if (!q_RAND_status()) {
134 qWarning("Random number generator not seeded, disabling SSL support");
135 return false;
136 }
137
138 return true;
139 }();
140
141 return libraryLoaded;
142}
143
144QString QTlsBackendOpenSSL::backendName() const
145{
146 return builtinBackendNames[nameIndexOpenSSL];
147}
148
149bool QTlsBackendOpenSSL::isValid() const
150{
151 return ensureLibraryLoaded();
152}
153
154long QTlsBackendOpenSSL::tlsLibraryVersionNumber() const
155{
157}
158
159QString QTlsBackendOpenSSL::tlsLibraryVersionString() const
160{
161 const char *versionString = q_OpenSSL_version(OPENSSL_VERSION);
162 if (!versionString)
163 return QString();
164
165 return QString::fromLatin1(versionString);
166}
167
168long QTlsBackendOpenSSL::tlsLibraryBuildVersionNumber() const
169{
170 return OPENSSL_VERSION_NUMBER;
171}
172
173QString QTlsBackendOpenSSL::tlsLibraryBuildVersionString() const
174{
175 // Using QStringLiteral to store the version string as unicode and
176 // avoid false positives from Google searching the playstore for old
177 // SSL versions. See QTBUG-46265
178 return QStringLiteral(OPENSSL_VERSION_TEXT);
179}
180
181void QTlsBackendOpenSSL::ensureInitialized() const
182{
183 // Old qsslsocket_openssl calls supportsSsl() (which means
184 // library found and symbols resolved, this already assured
185 // by the fact we end up in this function (isValid() returned
186 // true for the backend, see its code). The qsslsocket_openssl
187 // proceedes with loading certificate, ciphers and elliptic
188 // curves.
189 ensureCiphersAndCertsLoaded();
190}
191
192void QTlsBackendOpenSSL::ensureCiphersAndCertsLoaded() const
193{
194 Q_CONSTINIT static bool initializationStarted = false;
195 Q_CONSTINIT static QAtomicInt initialized = Q_BASIC_ATOMIC_INITIALIZER(0);
196 Q_CONSTINIT static QRecursiveMutex initMutex;
197
198 if (initialized.loadAcquire())
199 return;
200
201 const QMutexLocker locker(&initMutex);
202
203 if (initializationStarted || initialized.loadAcquire())
204 return;
205
206 // Indicate that the initialization has already started in the current
207 // thread in case of recursive calls. The atomic variable cannot be used
208 // for this because it is checked without holding the init mutex.
209 initializationStarted = true;
210
211 auto guard = qScopeGuard([] { initialized.storeRelease(1); });
212
213 resetDefaultCiphers();
214 resetDefaultEllipticCurves();
215
216#if QT_CONFIG(library)
217 //load symbols needed to receive certificates from system store
218#if defined(Q_OS_QNX)
219 QSslSocketPrivate::setRootCertOnDemandLoadingSupported(true);
220#elif defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
221 // check whether we can enable on-demand root-cert loading (i.e. check whether the sym links are there)
222 const QList<QByteArray> dirs = QSslSocketPrivate::unixRootCertDirectories();
223 const QStringList symLinkFilter{
224 u"[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].[0-9]"_s};
225 for (const auto &dir : dirs) {
226 QDirListing dirList(QString::fromLatin1(dir), symLinkFilter,
227 QDirListing::IteratorFlag::FilesOnly);
228 if (dirList.cbegin() != dirList.cend()) { // Not empty
229 QSslSocketPrivate::setRootCertOnDemandLoadingSupported(true);
230 break;
231 }
232 }
233#endif
234#endif // QT_CONFIG(library)
235 // if on-demand loading was not enabled, load the certs now
236 if (!QSslSocketPrivate::rootCertOnDemandLoadingSupported())
237 setDefaultCaCertificates(systemCaCertificates());
238#ifdef Q_OS_WIN
239 //Enabled for fetching additional root certs from windows update on windows.
240 //This flag is set false by setDefaultCaCertificates() indicating the app uses
241 //its own cert bundle rather than the system one.
242 //Same logic that disables the unix on demand cert loading.
243 //Unlike unix, we do preload the certificates from the cert store.
244 QSslSocketPrivate::setRootCertOnDemandLoadingSupported(true);
245#endif
246}
247
248void QTlsBackendOpenSSL::resetDefaultCiphers()
249{
251 // Note, we assert, not just silently return/bail out early:
252 // this should never happen and problems with OpenSSL's initialization
253 // must be caught before this (see supportsSsl()).
254 Q_ASSERT(myCtx);
255 SSL *mySsl = q_SSL_new(myCtx);
256 Q_ASSERT(mySsl);
257
258 QList<QSslCipher> ciphers;
259 QList<QSslCipher> defaultCiphers;
260
261 q_loadCiphersForConnection(mySsl, ciphers, defaultCiphers);
262
263 q_SSL_CTX_free(myCtx);
264 q_SSL_free(mySsl);
265
266 setDefaultSupportedCiphers(ciphers);
267 setDefaultCiphers(defaultCiphers);
268
269#if QT_CONFIG(dtls)
270 ciphers.clear();
271 defaultCiphers.clear();
272 myCtx = q_SSL_CTX_new(q_DTLS_client_method());
273 if (myCtx) {
274 mySsl = q_SSL_new(myCtx);
275 if (mySsl) {
276 q_loadCiphersForConnection(mySsl, ciphers, defaultCiphers);
277 setDefaultDtlsCiphers(defaultCiphers);
278 q_SSL_free(mySsl);
279 }
280 q_SSL_CTX_free(myCtx);
281 }
282#endif // dtls
283}
284
285QList<QSsl::SslProtocol> QTlsBackendOpenSSL::supportedProtocols() const
286{
287 QList<QSsl::SslProtocol> protocols;
288
289 protocols << QSsl::AnyProtocol;
290 protocols << QSsl::SecureProtocols;
291QT_WARNING_PUSH
292QT_WARNING_DISABLE_DEPRECATED
293 protocols << QSsl::TlsV1_0;
294 protocols << QSsl::TlsV1_0OrLater;
295 protocols << QSsl::TlsV1_1;
296 protocols << QSsl::TlsV1_1OrLater;
297QT_WARNING_POP
298 protocols << QSsl::TlsV1_2;
299 protocols << QSsl::TlsV1_2OrLater;
300
301#ifdef TLS1_3_VERSION
302 protocols << QSsl::TlsV1_3;
303 protocols << QSsl::TlsV1_3OrLater;
304#endif // TLS1_3_VERSION
305
306#if QT_CONFIG(dtls)
307QT_WARNING_PUSH
308QT_WARNING_DISABLE_DEPRECATED
309 protocols << QSsl::DtlsV1_0;
310 protocols << QSsl::DtlsV1_0OrLater;
311QT_WARNING_POP
312 protocols << QSsl::DtlsV1_2;
313 protocols << QSsl::DtlsV1_2OrLater;
314#endif // dtls
315
316 return protocols;
317}
318
319QList<QSsl::SupportedFeature> QTlsBackendOpenSSL::supportedFeatures() const
320{
321 QList<QSsl::SupportedFeature> features;
322
323 features << QSsl::SupportedFeature::CertificateVerification;
324
325#if !defined(OPENSSL_NO_TLSEXT)
326 features << QSsl::SupportedFeature::ClientSideAlpn;
327 features << QSsl::SupportedFeature::ServerSideAlpn;
328#endif // !OPENSSL_NO_TLSEXT
329
330 features << QSsl::SupportedFeature::Ocsp;
331 features << QSsl::SupportedFeature::Psk;
332 features << QSsl::SupportedFeature::SessionTicket;
333 features << QSsl::SupportedFeature::Alerts;
334
335 return features;
336}
337
338QList<QSsl::ImplementedClass> QTlsBackendOpenSSL::implementedClasses() const
339{
340 QList<QSsl::ImplementedClass> classes;
341
342 classes << QSsl::ImplementedClass::Key;
343 classes << QSsl::ImplementedClass::Certificate;
344 classes << QSsl::ImplementedClass::Socket;
345#if QT_CONFIG(dtls)
346 classes << QSsl::ImplementedClass::Dtls;
347 classes << QSsl::ImplementedClass::DtlsCookie;
348#endif
349 classes << QSsl::ImplementedClass::EllipticCurve;
350 classes << QSsl::ImplementedClass::DiffieHellman;
351
352 return classes;
353}
354
355QTlsPrivate::TlsKey *QTlsBackendOpenSSL::createKey() const
356{
357 return new QTlsPrivate::TlsKeyOpenSSL;
358}
359
360QTlsPrivate::X509Certificate *QTlsBackendOpenSSL::createCertificate() const
361{
362 return new QTlsPrivate::X509CertificateOpenSSL;
363}
364
365namespace QTlsPrivate {
366
367#ifdef Q_OS_ANDROID
369#endif
370
372
373#ifndef Q_OS_DARWIN
375{
376#ifdef QSSLSOCKET_DEBUG
377 QElapsedTimer timer;
378 timer.start();
379#endif
380 QList<QSslCertificate> systemCerts;
381#if defined(Q_OS_WIN)
382 HCERTSTORE hSystemStore;
383 hSystemStore =
384 CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
385 CERT_STORE_READONLY_FLAG | CERT_SYSTEM_STORE_CURRENT_USER, L"ROOT");
386 if (hSystemStore) {
387 PCCERT_CONTEXT pc = nullptr;
388 while (1) {
389 pc = CertFindCertificateInStore(hSystemStore, X509_ASN_ENCODING, 0, CERT_FIND_ANY, nullptr, pc);
390 if (!pc)
391 break;
392 QByteArray der(reinterpret_cast<const char *>(pc->pbCertEncoded),
393 static_cast<int>(pc->cbCertEncoded));
394 QSslCertificate cert(der, QSsl::Der);
395 systemCerts.append(cert);
396 }
397 CertCloseStore(hSystemStore, 0);
398 }
399#elif defined(Q_OS_ANDROID)
400 const QList<QByteArray> certData = fetchSslCertificateData();
401 for (auto certDatum : certData)
402 systemCerts.append(QSslCertificate::fromData(certDatum, QSsl::Der));
403#elif defined(Q_OS_UNIX)
404 {
405 const QList<QByteArray> directories = QSslSocketPrivate::unixRootCertDirectories();
406 QSet<QString> certFiles = {
407 QStringLiteral("/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem"), // Red Hat 2013+
408 QStringLiteral("/etc/pki/tls/certs/ca-bundle.crt"), // Red Hat older, Mandriva
409 QStringLiteral("/usr/local/share/certs/ca-root-nss.crt") // FreeBSD's ca_root_nss
410 };
411
412 static const size_t extLen = strlen(".pem"); // or strlen(".crt")
413 auto hasMatchingExtension = [](const QString &fileName) {
414 if (size_t(fileName.size()) < extLen + 1)
415 return false;
416 auto ext = QStringView{fileName}.last(extLen);
417 return ext == ".pem"_L1 || ext == ".crt"_L1;
418 };
419
420 using F = QDirListing::IteratorFlag;
421 constexpr auto flags = F::FilesOnly | F::ResolveSymlinks; // Files and symlinks to files
422 for (const QByteArray &directory : directories) {
423 for (const auto &dirEntry : QDirListing(QFile::decodeName(directory), flags)) {
424 // use canonical path here to not load the same certificate twice if symlinked
425 if (hasMatchingExtension(dirEntry.fileName())) {
426 QString canonicalPath = dirEntry.canonicalFilePath();
427 // skip broken symlinks to not end up adding "" to the list which will then
428 // just be rejected by `QSslCertificate::fromFile`
429 if (!canonicalPath.isEmpty())
430 certFiles.insert(canonicalPath);
431 }
432 }
433 }
434 for (const QString& file : std::as_const(certFiles))
435 systemCerts.append(QSslCertificate::fromFile(file, QSsl::Pem));
436 }
437#endif // platform
438#ifdef QSSLSOCKET_DEBUG
439 qCDebug(lcTlsBackend) << "systemCaCertificates retrieval time " << timer.elapsed() << "ms";
440 qCDebug(lcTlsBackend) << "imported " << systemCerts.count() << " certificates";
441#endif
442
443 return systemCerts;
444}
445#endif // !Q_OS_DARWIN
446} // namespace QTlsPrivate
447
448QList<QSslCertificate> QTlsBackendOpenSSL::systemCaCertificates() const
449{
450 return QTlsPrivate::systemCaCertificates();
451}
452
454{
455#if QT_CONFIG(dtls)
456 return new QDtlsClientVerifierOpenSSL;
457#else
458 qCWarning(lcTlsBackend, "Feature 'dtls' is disabled, cannot verify DTLS cookies");
459 return nullptr;
460#endif // QT_CONFIG(dtls)
461}
462
464{
466}
467
468QTlsPrivate::DtlsCryptograph *QTlsBackendOpenSSL::createDtlsCryptograph(QDtls *q, int mode) const
469{
470#if QT_CONFIG(dtls)
471 return new QDtlsPrivateOpenSSL(q, QSslSocket::SslMode(mode));
472#else
473 Q_UNUSED(q);
474 Q_UNUSED(mode);
475 qCWarning(lcTlsBackend, "Feature 'dtls' is disabled, cannot encrypt UDP datagrams");
476 return nullptr;
477#endif // QT_CONFIG(dtls)
478}
479
480QTlsPrivate::X509ChainVerifyPtr QTlsBackendOpenSSL::X509Verifier() const
481{
482 return QTlsPrivate::X509CertificateOpenSSL::verify;
483}
484
485QTlsPrivate::X509PemReaderPtr QTlsBackendOpenSSL::X509PemReader() const
486{
487 return QTlsPrivate::X509CertificateOpenSSL::certificatesFromPem;
488}
489
490QTlsPrivate::X509DerReaderPtr QTlsBackendOpenSSL::X509DerReader() const
491{
492 return QTlsPrivate::X509CertificateOpenSSL::certificatesFromDer;
493}
494
496{
497 return QTlsPrivate::X509CertificateOpenSSL::importPkcs12;
498}
499
500QList<int> QTlsBackendOpenSSL::ellipticCurvesIds() const
501{
502 QList<int> ids;
503
504#ifndef OPENSSL_NO_EC
505 const size_t curveCount = q_EC_get_builtin_curves(nullptr, 0);
506 QVarLengthArray<EC_builtin_curve> builtinCurves(static_cast<int>(curveCount));
507
508 if (q_EC_get_builtin_curves(builtinCurves.data(), curveCount) == curveCount) {
509 ids.reserve(curveCount);
510 for (const auto &ec : builtinCurves)
511 ids.push_back(ec.nid);
512 }
513#endif // OPENSSL_NO_EC
514
515 return ids;
516}
517
518 int QTlsBackendOpenSSL::curveIdFromShortName(const QString &name) const
519 {
520 int nid = 0;
521 if (name.isEmpty())
522 return nid;
523
524 ensureInitialized(); // TLSTODO: check if it's needed!
525#ifndef OPENSSL_NO_EC
526 const QByteArray curveNameLatin1 = name.toLatin1();
527 nid = q_OBJ_sn2nid(curveNameLatin1.data());
528
529 if (nid == 0)
530 nid = q_EC_curve_nist2nid(curveNameLatin1.data());
531#endif // !OPENSSL_NO_EC
532
533 return nid;
534 }
535
536 int QTlsBackendOpenSSL::curveIdFromLongName(const QString &name) const
537 {
538 int nid = 0;
539 if (name.isEmpty())
540 return nid;
541
543
544#ifndef OPENSSL_NO_EC
545 const QByteArray curveNameLatin1 = name.toLatin1();
546 nid = q_OBJ_ln2nid(curveNameLatin1.data());
547#endif
548
549 return nid;
550 }
551
552 QString QTlsBackendOpenSSL::shortNameForId(int id) const
553 {
554 QString result;
555
556#ifndef OPENSSL_NO_EC
557 if (id != 0)
558 result = QString::fromLatin1(q_OBJ_nid2sn(id));
559#endif
560
561 return result;
562 }
563
564QString QTlsBackendOpenSSL::longNameForId(int id) const
565{
566 QString result;
567
568#ifndef OPENSSL_NO_EC
569 if (id != 0)
570 result = QString::fromLatin1(q_OBJ_nid2ln(id));
571#endif
572
573 return result;
574}
575
576// NIDs of named curves allowed in TLS as per RFCs 4492 and 7027,
577// see also https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8
578static const int tlsNamedCurveNIDs[] = {
579 // RFC 4492
580 NID_sect163k1,
581 NID_sect163r1,
582 NID_sect163r2,
583 NID_sect193r1,
584 NID_sect193r2,
585 NID_sect233k1,
586 NID_sect233r1,
587 NID_sect239k1,
588 NID_sect283k1,
589 NID_sect283r1,
590 NID_sect409k1,
591 NID_sect409r1,
592 NID_sect571k1,
593 NID_sect571r1,
594
595 NID_secp160k1,
596 NID_secp160r1,
597 NID_secp160r2,
598 NID_secp192k1,
599 NID_X9_62_prime192v1, // secp192r1
600 NID_secp224k1,
601 NID_secp224r1,
602 NID_secp256k1,
603 NID_X9_62_prime256v1, // secp256r1
604 NID_secp384r1,
605 NID_secp521r1,
606
607 // RFC 7027
608 NID_brainpoolP256r1,
609 NID_brainpoolP384r1,
610 NID_brainpoolP512r1
611};
612
614
615bool QTlsBackendOpenSSL::isTlsNamedCurve(int id) const
616{
617 const int *const tlsNamedCurveNIDsEnd = tlsNamedCurveNIDs + tlsNamedCurveNIDCount;
618 return std::find(tlsNamedCurveNIDs, tlsNamedCurveNIDsEnd, id) != tlsNamedCurveNIDsEnd;
619}
620
621QString QTlsBackendOpenSSL::msgErrorsDuringHandshake()
622{
623 return QSslSocket::tr("Error during SSL handshake: %1").arg(getErrorsFromOpenSsl());
624}
625
626QSslCipher QTlsBackendOpenSSL::qt_OpenSSL_cipher_to_QSslCipher(const SSL_CIPHER *cipher)
627{
628 Q_ASSERT(cipher);
629 char buf [256] = {};
630 const QString desc = QString::fromLatin1(q_SSL_CIPHER_description(cipher, buf, sizeof(buf)));
631 int supportedBits = 0;
632 const int bits = q_SSL_CIPHER_get_bits(cipher, &supportedBits);
633 return createCiphersuite(desc, bits, supportedBits);
634}
635
640
641QT_END_NAMESPACE
642
643#include "moc_qtlsbackend_openssl_p.cpp"
static void forceAutoTestSecurityLevel()
QTlsPrivate::X509DerReaderPtr X509DerReader() const override
QString tlsLibraryBuildVersionString() const override
QList< QSsl::SslProtocol > supportedProtocols() const override
QTlsPrivate::X509ChainVerifyPtr X509Verifier() const override
bool isTlsNamedCurve(int cid) const override
long tlsLibraryVersionNumber() const override
long tlsLibraryBuildVersionNumber() const override
QTlsPrivate::DtlsCryptograph * createDtlsCryptograph(QDtls *q, int mode) const override
static void logAndClearErrorQueue()
int curveIdFromShortName(const QString &name) const override
QTlsPrivate::X509PemReaderPtr X509PemReader() const override
int curveIdFromLongName(const QString &name) const override
bool isValid() const override
QList< int > ellipticCurvesIds() const override
QString shortNameForId(int cid) const override
QTlsPrivate::X509Certificate * createCertificate() const override
void forceAutotestSecurityLevel() override
QTlsPrivate::X509Pkcs12ReaderPtr X509Pkcs12Reader() const override
QString longNameForId(int cid) const override
QList< QSslCertificate > systemCaCertificates() const override
QList< QSsl::SupportedFeature > supportedFeatures() const override
QList< QSsl::ImplementedClass > implementedClasses() const override
QTlsPrivate::DtlsCookieVerifier * createDtlsCookieVerifier() const override
void ensureInitialized() const override
QTlsPrivate::TlsKey * createKey() const override
QTlsPrivate::TlsCryptograph * createTlsCryptograph() const override
QString backendName() const override
QString tlsLibraryVersionString() const override
Namespace containing onternal types that TLS backends implement.
QList< QSslCertificate > systemCaCertificates()
Q_LOGGING_CATEGORY(lcEventDispatcher, "qt.eventdispatcher")
void q_SSL_free(SSL *a)
void q_SSL_CTX_free(SSL_CTX *a)
const char * q_OpenSSL_version(int type)
bool q_resolveOpenSslSymbols()
#define q_SSL_load_error_strings()
unsigned long q_ERR_get_error()
void q_ERR_error_string_n(unsigned long e, char *buf, size_t len)
#define q_OpenSSL_add_all_algorithms()
int q_RAND_status()
SSL_CTX * q_SSL_CTX_new(const SSL_METHOD *a)
#define q_sk_SSL_CIPHER_num(st)
const SSL_METHOD * q_TLS_client_method()
SSL * q_SSL_new(SSL_CTX *a)
int q_SSL_CIPHER_get_bits(const SSL_CIPHER *a, int *b)
long q_OpenSSL_version_num()
int q_CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
#define q_sk_SSL_CIPHER_value(st, i)
int q_OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
constexpr auto DefaultWarningLevel
const size_t tlsNamedCurveNIDCount
static const int tlsNamedCurveNIDs[]
static void q_loadCiphersForConnection(SSL *connection, QList< QSslCipher > &ciphers, QList< QSslCipher > &defaultCiphers)