Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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
6#include "qtlskey_openssl_p.h"
7#include "qx509_openssl_p.h"
8#include "qtls_openssl_p.h"
9
10#if QT_CONFIG(dtls)
11#include "qdtls_openssl_p.h"
12#endif // QT_CONFIG(dtls)
13
14#include <QtNetwork/private/qsslcipher_p.h>
15
16#include <QtNetwork/qsslcipher.h>
17#include <QtNetwork/qssl.h>
18
19#include <QtCore/qdir.h>
20#include <QtCore/qdirlisting.h>
21#include <QtCore/qlist.h>
22#include <QtCore/qmutex.h>
23#include <QtCore/qscopeguard.h>
24#include <QtCore/qset.h>
25
26#include "qopenssl_p.h"
27
28#include <algorithm>
29
31
32using namespace Qt::StringLiterals;
33
34#if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
35constexpr auto DefaultWarningLevel = QtCriticalMsg;
36#else
38#endif
39
40Q_LOGGING_CATEGORY(lcTlsBackend, "qt.tlsbackend.ossl", DefaultWarningLevel);
41
42static void q_loadCiphersForConnection(SSL *connection, QList<QSslCipher> &ciphers,
43 QList<QSslCipher> &defaultCiphers)
44{
46
47 STACK_OF(SSL_CIPHER) *supportedCiphers = q_SSL_get_ciphers(connection);
48 for (int i = 0; i < q_sk_SSL_CIPHER_num(supportedCiphers); ++i) {
49 if (SSL_CIPHER *cipher = q_sk_SSL_CIPHER_value(supportedCiphers, i)) {
51 if (!ciph.isNull()) {
52 // Unconditionally exclude ADH and AECDH ciphers since they offer no MITM protection
53 if (!ciph.name().toLower().startsWith("adh"_L1) &&
54 !ciph.name().toLower().startsWith("exp-adh"_L1) &&
55 !ciph.name().toLower().startsWith("aecdh"_L1)) {
56 ciphers << ciph;
57
58 if (ciph.usedBits() >= 128)
59 defaultCiphers << ciph;
60 }
61 }
62 }
63 }
64}
65
67
69{
70 QString errorString;
71 char buf[256] = {}; // OpenSSL docs claim both 120 and 256; use the larger.
72 unsigned long errNum;
73 while ((errNum = q_ERR_get_error())) {
74 if (!errorString.isEmpty())
75 errorString.append(", "_L1);
76 q_ERR_error_string_n(errNum, buf, sizeof buf);
77 errorString.append(QLatin1StringView(buf)); // error is ascii according to man ERR_error_string
78 }
79 return errorString;
80}
81
83{
84 const auto errors = getErrorsFromOpenSsl();
85 if (errors.size())
86 qCWarning(lcTlsBackend) << "Discarding errors:" << errors;
87}
88
94
95bool QTlsBackendOpenSSL::ensureLibraryLoaded()
96{
97 static bool libraryLoaded = []() {
99 return false;
100
101 // Initialize OpenSSL.
102 if (q_OPENSSL_init_ssl(0, nullptr) != 1)
103 return false;
104
105 if (q_OpenSSL_version_num() < 0x10101000L) {
106 qCWarning(lcTlsBackend, "QSslSocket: OpenSSL >= 1.1.1 is required; %s was found instead", q_OpenSSL_version(OPENSSL_VERSION));
107 return false;
108 }
109
112
113 s_indexForSSLExtraData = q_CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, 0L, nullptr, nullptr,
114 nullptr, nullptr);
115
116 // Initialize OpenSSL's random seed.
117 if (!q_RAND_status()) {
118 qWarning("Random number generator not seeded, disabling SSL support");
119 return false;
120 }
121
122 return true;
123 }();
124
125 return libraryLoaded;
126}
127
132
134{
135 return ensureLibraryLoaded();
136}
137
142
144{
145 const char *versionString = q_OpenSSL_version(OPENSSL_VERSION);
146 if (!versionString)
147 return QString();
148
149 return QString::fromLatin1(versionString);
150}
151
153{
154 return OPENSSL_VERSION_NUMBER;
155}
156
158{
159 // Using QStringLiteral to store the version string as unicode and
160 // avoid false positives from Google searching the playstore for old
161 // SSL versions. See QTBUG-46265
162 return QStringLiteral(OPENSSL_VERSION_TEXT);
163}
164
166{
167 // Old qsslsocket_openssl calls supportsSsl() (which means
168 // library found and symbols resolved, this already assured
169 // by the fact we end up in this function (isValid() returned
170 // true for the backend, see its code). The qsslsocket_openssl
171 // proceedes with loading certificate, ciphers and elliptic
172 // curves.
173 ensureCiphersAndCertsLoaded();
174}
175
176void QTlsBackendOpenSSL::ensureCiphersAndCertsLoaded() const
177{
178 Q_CONSTINIT static bool initializationStarted = false;
179 Q_CONSTINIT static QAtomicInt initialized = Q_BASIC_ATOMIC_INITIALIZER(0);
180 Q_CONSTINIT static QRecursiveMutex initMutex;
181
182 if (initialized.loadAcquire())
183 return;
184
185 const QMutexLocker locker(&initMutex);
186
187 if (initializationStarted || initialized.loadAcquire())
188 return;
189
190 // Indicate that the initialization has already started in the current
191 // thread in case of recursive calls. The atomic variable cannot be used
192 // for this because it is checked without holding the init mutex.
193 initializationStarted = true;
194
195 auto guard = qScopeGuard([] { initialized.storeRelease(1); });
196
197 resetDefaultCiphers();
198 resetDefaultEllipticCurves();
199
200#if QT_CONFIG(library)
201 //load symbols needed to receive certificates from system store
202#if defined(Q_OS_QNX)
204#elif defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
205 // check whether we can enable on-demand root-cert loading (i.e. check whether the sym links are there)
206 const QList<QByteArray> dirs = QSslSocketPrivate::unixRootCertDirectories();
207 const QStringList symLinkFilter{
208 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};
209 for (const auto &dir : dirs) {
210 QDirListing dirList(QString::fromLatin1(dir), symLinkFilter, QDir::Files);
211 if (dirList.cbegin() != dirList.cend()) { // Not empty
213 break;
214 }
215 }
216#endif
217#endif // QT_CONFIG(library)
218 // if on-demand loading was not enabled, load the certs now
220 setDefaultCaCertificates(systemCaCertificates());
221#ifdef Q_OS_WIN
222 //Enabled for fetching additional root certs from windows update on windows.
223 //This flag is set false by setDefaultCaCertificates() indicating the app uses
224 //its own cert bundle rather than the system one.
225 //Same logic that disables the unix on demand cert loading.
226 //Unlike unix, we do preload the certificates from the cert store.
228#endif
229}
230
231void QTlsBackendOpenSSL::resetDefaultCiphers()
232{
233 SSL_CTX *myCtx = q_SSL_CTX_new(q_TLS_client_method());
234 // Note, we assert, not just silently return/bail out early:
235 // this should never happen and problems with OpenSSL's initialization
236 // must be caught before this (see supportsSsl()).
237 Q_ASSERT(myCtx);
238 SSL *mySsl = q_SSL_new(myCtx);
239 Q_ASSERT(mySsl);
240
241 QList<QSslCipher> ciphers;
242 QList<QSslCipher> defaultCiphers;
243
244 q_loadCiphersForConnection(mySsl, ciphers, defaultCiphers);
245
246 q_SSL_CTX_free(myCtx);
247 q_SSL_free(mySsl);
248
249 setDefaultSupportedCiphers(ciphers);
250 setDefaultCiphers(defaultCiphers);
251
252#if QT_CONFIG(dtls)
253 ciphers.clear();
255 myCtx = q_SSL_CTX_new(q_DTLS_client_method());
256 if (myCtx) {
257 mySsl = q_SSL_new(myCtx);
258 if (mySsl) {
259 q_loadCiphersForConnection(mySsl, ciphers, defaultCiphers);
260 setDefaultDtlsCiphers(defaultCiphers);
261 q_SSL_free(mySsl);
262 }
263 q_SSL_CTX_free(myCtx);
264 }
265#endif // dtls
266}
267
268QList<QSsl::SslProtocol> QTlsBackendOpenSSL::supportedProtocols() const
269{
270 QList<QSsl::SslProtocol> protocols;
271
272 protocols << QSsl::AnyProtocol;
273 protocols << QSsl::SecureProtocols;
276 protocols << QSsl::TlsV1_0;
277 protocols << QSsl::TlsV1_0OrLater;
278 protocols << QSsl::TlsV1_1;
279 protocols << QSsl::TlsV1_1OrLater;
281 protocols << QSsl::TlsV1_2;
282 protocols << QSsl::TlsV1_2OrLater;
283
284#ifdef TLS1_3_VERSION
285 protocols << QSsl::TlsV1_3;
286 protocols << QSsl::TlsV1_3OrLater;
287#endif // TLS1_3_VERSION
288
289#if QT_CONFIG(dtls)
292 protocols << QSsl::DtlsV1_0;
293 protocols << QSsl::DtlsV1_0OrLater;
295 protocols << QSsl::DtlsV1_2;
296 protocols << QSsl::DtlsV1_2OrLater;
297#endif // dtls
298
299 return protocols;
300}
301
302QList<QSsl::SupportedFeature> QTlsBackendOpenSSL::supportedFeatures() const
303{
304 QList<QSsl::SupportedFeature> features;
305
307
308#if !defined(OPENSSL_NO_TLSEXT)
311#endif // !OPENSSL_NO_TLSEXT
312
314 features << QSsl::SupportedFeature::Psk;
317
318 return features;
319}
320
321QList<QSsl::ImplementedClass> QTlsBackendOpenSSL::implementedClasses() const
322{
323 QList<QSsl::ImplementedClass> classes;
324
328#if QT_CONFIG(dtls)
331#endif
334
335 return classes;
336}
337
342
347
348namespace QTlsPrivate {
349
350#ifdef Q_OS_ANDROID
351QList<QByteArray> fetchSslCertificateData();
352#endif
353
354QList<QSslCertificate> systemCaCertificates();
355
356#ifndef Q_OS_DARWIN
357QList<QSslCertificate> systemCaCertificates()
358{
359#ifdef QSSLSOCKET_DEBUG
361 timer.start();
362#endif
363 QList<QSslCertificate> systemCerts;
364#if defined(Q_OS_WIN)
365 HCERTSTORE hSystemStore;
366 hSystemStore =
367 CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
368 CERT_STORE_READONLY_FLAG | CERT_SYSTEM_STORE_CURRENT_USER, L"ROOT");
369 if (hSystemStore) {
370 PCCERT_CONTEXT pc = nullptr;
371 while (1) {
372 pc = CertFindCertificateInStore(hSystemStore, X509_ASN_ENCODING, 0, CERT_FIND_ANY, nullptr, pc);
373 if (!pc)
374 break;
375 QByteArray der(reinterpret_cast<const char *>(pc->pbCertEncoded),
376 static_cast<int>(pc->cbCertEncoded));
378 systemCerts.append(cert);
379 }
380 CertCloseStore(hSystemStore, 0);
381 }
382#elif defined(Q_OS_ANDROID)
383 const QList<QByteArray> certData = fetchSslCertificateData();
384 for (auto certDatum : certData)
385 systemCerts.append(QSslCertificate::fromData(certDatum, QSsl::Der));
386#elif defined(Q_OS_UNIX)
387 {
388 const QList<QByteArray> directories = QSslSocketPrivate::unixRootCertDirectories();
389 QSet<QString> certFiles = {
390 QStringLiteral("/etc/pki/tls/certs/ca-bundle.crt"), // Fedora, Mandriva
391 QStringLiteral("/usr/local/share/certs/ca-root-nss.crt") // FreeBSD's ca_root_nss
392 };
393 QDir currentDir;
394 currentDir.setNameFilters(QStringList{QStringLiteral("*.pem"), QStringLiteral("*.crt")});
395 for (const auto &directory : directories) {
397 for (const auto &dirEntry : QDirListing(currentDir)) {
398 // use canonical path here to not load the same certificate twice if symlinked
399 certFiles.insert(dirEntry.canonicalFilePath());
400 }
401 }
402 for (const QString& file : std::as_const(certFiles))
403 systemCerts.append(QSslCertificate::fromPath(file, QSsl::Pem));
404 }
405#endif // platform
406#ifdef QSSLSOCKET_DEBUG
407 qCDebug(lcTlsBackend) << "systemCaCertificates retrieval time " << timer.elapsed() << "ms";
408 qCDebug(lcTlsBackend) << "imported " << systemCerts.count() << " certificates";
409#endif
410
411 return systemCerts;
412}
413#endif // !Q_OS_DARWIN
414} // namespace QTlsPrivate
415
416QList<QSslCertificate> QTlsBackendOpenSSL::systemCaCertificates() const
417{
419}
420
421QTlsPrivate::DtlsCookieVerifier *QTlsBackendOpenSSL::createDtlsCookieVerifier() const
422{
423#if QT_CONFIG(dtls)
425#else
426 qCWarning(lcTlsBackend, "Feature 'dtls' is disabled, cannot verify DTLS cookies");
427 return nullptr;
428#endif // QT_CONFIG(dtls)
429}
430
431QTlsPrivate::TlsCryptograph *QTlsBackendOpenSSL::createTlsCryptograph() const
432{
434}
435
436QTlsPrivate::DtlsCryptograph *QTlsBackendOpenSSL::createDtlsCryptograph(QDtls *q, int mode) const
437{
438#if QT_CONFIG(dtls)
440#else
441 Q_UNUSED(q);
442 Q_UNUSED(mode);
443 qCWarning(lcTlsBackend, "Feature 'dtls' is disabled, cannot encrypt UDP datagrams");
444 return nullptr;
445#endif // QT_CONFIG(dtls)
446}
447
452
457
462
467
469{
470 QList<int> ids;
471
472#ifndef OPENSSL_NO_EC
473 const size_t curveCount = q_EC_get_builtin_curves(nullptr, 0);
474 QVarLengthArray<EC_builtin_curve> builtinCurves(static_cast<int>(curveCount));
475
476 if (q_EC_get_builtin_curves(builtinCurves.data(), curveCount) == curveCount) {
477 ids.reserve(curveCount);
478 for (const auto &ec : builtinCurves)
479 ids.push_back(ec.nid);
480 }
481#endif // OPENSSL_NO_EC
482
483 return ids;
484}
485
487 {
488 int nid = 0;
489 if (name.isEmpty())
490 return nid;
491
492 ensureInitialized(); // TLSTODO: check if it's needed!
493#ifndef OPENSSL_NO_EC
494 const QByteArray curveNameLatin1 = name.toLatin1();
495 nid = q_OBJ_sn2nid(curveNameLatin1.data());
496
497 if (nid == 0)
498 nid = q_EC_curve_nist2nid(curveNameLatin1.data());
499#endif // !OPENSSL_NO_EC
500
501 return nid;
502 }
503
505 {
506 int nid = 0;
507 if (name.isEmpty())
508 return nid;
509
511
512#ifndef OPENSSL_NO_EC
513 const QByteArray curveNameLatin1 = name.toLatin1();
514 nid = q_OBJ_ln2nid(curveNameLatin1.data());
515#endif
516
517 return nid;
518 }
519
521 {
523
524#ifndef OPENSSL_NO_EC
525 if (id != 0)
527#endif
528
529 return result;
530 }
531
533{
535
536#ifndef OPENSSL_NO_EC
537 if (id != 0)
539#endif
540
541 return result;
542}
543
544// NIDs of named curves allowed in TLS as per RFCs 4492 and 7027,
545// see also https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8
546static const int tlsNamedCurveNIDs[] = {
547 // RFC 4492
548 NID_sect163k1,
549 NID_sect163r1,
550 NID_sect163r2,
551 NID_sect193r1,
552 NID_sect193r2,
553 NID_sect233k1,
554 NID_sect233r1,
555 NID_sect239k1,
556 NID_sect283k1,
557 NID_sect283r1,
558 NID_sect409k1,
559 NID_sect409r1,
560 NID_sect571k1,
561 NID_sect571r1,
562
563 NID_secp160k1,
564 NID_secp160r1,
565 NID_secp160r2,
566 NID_secp192k1,
567 NID_X9_62_prime192v1, // secp192r1
568 NID_secp224k1,
569 NID_secp224r1,
570 NID_secp256k1,
571 NID_X9_62_prime256v1, // secp256r1
572 NID_secp384r1,
573 NID_secp521r1,
574
575 // RFC 7027
576 NID_brainpoolP256r1,
577 NID_brainpoolP384r1,
578 NID_brainpoolP512r1
579};
580
582
584{
585 const int *const tlsNamedCurveNIDsEnd = tlsNamedCurveNIDs + tlsNamedCurveNIDCount;
586 return std::find(tlsNamedCurveNIDs, tlsNamedCurveNIDsEnd, id) != tlsNamedCurveNIDsEnd;
587}
588
590{
591 return QSslSocket::tr("Error during SSL handshake: %1").arg(getErrorsFromOpenSsl());
592}
593
595{
596 Q_ASSERT(cipher);
597 char buf [256] = {};
598 const QString desc = QString::fromLatin1(q_SSL_CIPHER_description(cipher, buf, sizeof(buf)));
599 int supportedBits = 0;
600 const int bits = q_SSL_CIPHER_get_bits(cipher, &supportedBits);
601 return createCiphersuite(desc, bits, supportedBits);
602}
603
608
610
611#include "moc_qtlsbackend_openssl_p.cpp"
\inmodule QtCore
Definition qatomic.h:112
\inmodule QtCore
Definition qbytearray.h:57
The QDirListing class provides an STL-style iterator for directory entries.
Definition qdirlisting.h:18
\inmodule QtCore
Definition qdir.h:20
void setPath(const QString &path)
Sets the path of the directory to path.
Definition qdir.cpp:638
void setNameFilters(const QStringList &nameFilters)
Sets the name filters used by entryList() and entryInfoList() to the list of filters specified by nam...
Definition qdir.cpp:1071
@ Files
Definition qdir.h:23
This class provides encryption for UDP sockets.
Definition qdtls.h:83
\inmodule QtCore
void clear()
Definition qlist.h:434
\inmodule QtCore
Definition qmutex.h:313
\inmodule QtCore
Definition qmutex.h:309
The QSslCertificate class provides a convenient API for an X509 certificate.
static QList< QSslCertificate > fromData(const QByteArray &data, QSsl::EncodingFormat format=QSsl::Pem)
Searches for and parses all certificates in data that are encoded in the specified format and returns...
static QList< QSslCertificate > fromPath(const QString &path, QSsl::EncodingFormat format=QSsl::Pem, PatternSyntax syntax=PatternSyntax::FixedString)
The QSslCipher class represents an SSL cryptographic cipher.
Definition qsslcipher.h:22
static void forceAutoTestSecurityLevel()
static void setRootCertOnDemandLoadingSupported(bool supported)
static QList< QByteArray > unixRootCertDirectories()
static bool rootCertOnDemandLoadingSupported()
SslMode
Describes the connection modes available for QSslSocket.
Definition qsslsocket.h:33
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5871
void start(int msec)
Starts or restarts the timer with a timeout interval of msec milliseconds.
Definition qtimer.cpp:241
QTlsPrivate::X509DerReaderPtr X509DerReader() const override
static QSslCipher qt_OpenSSL_cipher_to_QSslCipher(const SSL_CIPHER *cipher)
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
static QString msgErrorsDuringHandshake()
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
static QString getErrorsFromOpenSsl()
static constexpr const int nameIndexOpenSSL
static const QString builtinBackendNames[]
TlsKey is an abstract class, that allows a TLS plugin to provide an underlying implementation for the...
static bool importPkcs12(QIODevice *device, QSslKey *key, QSslCertificate *cert, QList< QSslCertificate > *caCertificates, const QByteArray &passPhrase)
static QList< QSslCertificate > certificatesFromDer(const QByteArray &der, int count)
static QList< QSslCertificate > certificatesFromPem(const QByteArray &pem, int count)
static QList< QSslError > verify(const QList< QSslCertificate > &chain, const QString &hostName)
X509Certificate is an abstract class that allows a TLS backend to provide an implementation of the QS...
@ Pem
Definition qssl.h:29
@ Der
Definition qssl.h:30
@ DtlsV1_2
Definition qssl.h:63
@ TlsV1_2OrLater
Definition qssl.h:59
@ TlsV1_3
Definition qssl.h:66
@ DtlsV1_2OrLater
Definition qssl.h:64
@ TlsV1_3OrLater
Definition qssl.h:67
@ SecureProtocols
Definition qssl.h:55
@ TlsV1_2
Definition qssl.h:53
@ AnyProtocol
Definition qssl.h:54
Combined button and popup list for selecting options.
Namespace containing onternal types that TLS backends implement.
QList< QSslCipher > defaultCiphers()
QList< QByteArray > fetchSslCertificateData()
QList< QSslCertificate > systemCaCertificates()
QList< QSslCertificate >(*)(const QByteArray &pem, int count) X509PemReaderPtr
bool(*)(QIODevice *device, QSslKey *key, QSslCertificate *cert, QList< QSslCertificate > *caCertificates, const QByteArray &passPhrase) X509Pkcs12ReaderPtr
QList< QSslError >(*)(const QList< QSslCertificate > &chain, const QString &hostName) X509ChainVerifyPtr
X509PemReaderPtr X509DerReaderPtr
#define Q_BASIC_ATOMIC_INITIALIZER(a)
#define QT_WARNING_POP
#define QT_WARNING_DISABLE_DEPRECATED
#define QT_WARNING_PUSH
DBusConnection * connection
@ QtCriticalMsg
Definition qlogging.h:32
@ QtDebugMsg
Definition qlogging.h:30
#define qWarning
Definition qlogging.h:166
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
GLenum mode
GLenum GLenum GLsizei const GLuint * ids
GLenum GLuint GLenum GLsizei const GLchar * buf
GLuint name
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLuint64EXT * result
[6]
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QScopeGuard< typename std::decay< F >::type > qScopeGuard(F &&f)
[qScopeGuard]
Definition qscopeguard.h:60
bool q_resolveOpenSslSymbols()
void q_SSL_free(SSL *a)
void q_SSL_CTX_free(SSL_CTX *a)
const char * q_OpenSSL_version(int type)
char * q_SSL_CIPHER_description(const SSL_CIPHER *a, char *b, int c)
#define q_SSL_load_error_strings()
const char * q_OBJ_nid2sn(int a)
int q_OBJ_ln2nid(const char *s)
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)
int q_EC_curve_nist2nid(const char *name)
const char * q_OBJ_nid2ln(int a)
STACK_OF(X509) *q_X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx)
size_t q_EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems)
#define q_sk_SSL_CIPHER_num(st)
const SSL_METHOD * q_TLS_client_method()
SSL * q_SSL_new(SSL_CTX *a)
int q_OBJ_sn2nid(const char *s)
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)
#define QStringLiteral(str)
constexpr auto DefaultWarningLevel
const size_t tlsNamedCurveNIDCount
static void q_loadCiphersForConnection(SSL *connection, QList< QSslCipher > &ciphers, QList< QSslCipher > &defaultCiphers)
static const int tlsNamedCurveNIDs[]
#define Q_UNUSED(x)
QFile file
[0]
QTimer * timer
[3]
QString dir
[11]
QList< QSslCertificate > cert
[0]