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
qtls_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:critical reason:cryptography
4
8
9#ifdef Q_OS_WIN
10#include "qwindowscarootfetcher_p.h"
11#endif
12
13#include <QtNetwork/private/qsslpresharedkeyauthenticator_p.h>
14#include <QtNetwork/private/qsslcertificate_p.h>
15#include <QtNetwork/private/qocspresponse_p.h>
16#include <QtNetwork/private/qsslsocket_p.h>
17
18#include <QtNetwork/qsslpresharedkeyauthenticator.h>
19#include <QtNetwork/qsslkeyingmaterial.h>
20
21#include <QtCore/qscopedvaluerollback.h>
22#include <QtCore/qscopeguard.h>
23
24#include <algorithm>
25#include <cstring>
26
27QT_BEGIN_NAMESPACE
28
29using namespace Qt::StringLiterals;
30
31namespace {
32
33QSsl::AlertLevel tlsAlertLevel(int value)
34{
35 using QSsl::AlertLevel;
36
37 if (const char *typeString = q_SSL_alert_type_string(value)) {
38 // Documented to return 'W' for warning, 'F' for fatal,
39 // 'U' for unknown.
40 switch (typeString[0]) {
41 case 'W':
42 return AlertLevel::Warning;
43 case 'F':
44 return AlertLevel::Fatal;
45 default:;
46 }
47 }
48
49 return AlertLevel::Unknown;
50}
51
52QString tlsAlertDescription(int value)
53{
54 QString description = QLatin1StringView(q_SSL_alert_desc_string_long(value));
55 if (!description.size())
56 description = "no description provided"_L1;
57 return description;
58}
59
60QSsl::AlertType tlsAlertType(int value)
61{
62 // In case for some reason openssl gives us a value,
63 // which is not in our enum actually, we leave it to
64 // an application to handle (supposedly they have
65 // if or switch-statements).
66 return QSsl::AlertType(value & 0xff);
67}
68
69#ifdef Q_OS_WIN
70
71QSslCertificate findCertificateToFetch(const QList<QSslError> &tlsErrors, bool checkAIA)
72{
73 QSslCertificate certToFetch;
74
75 for (const auto &tlsError : tlsErrors) {
76 switch (tlsError.error()) {
77 case QSslError::UnableToGetLocalIssuerCertificate: // site presented intermediate cert, but root is unknown
78 case QSslError::SelfSignedCertificateInChain: // site presented a complete chain, but root is unknown
79 certToFetch = tlsError.certificate();
80 break;
81 case QSslError::SelfSignedCertificate:
82 case QSslError::CertificateBlacklisted:
83 //With these errors, we know it will be untrusted so save time by not asking windows
84 return QSslCertificate{};
85 default:
86#ifdef QSSLSOCKET_DEBUG
87 qCDebug(lcTlsBackend) << tlsError.errorString();
88#endif
89 //TODO - this part is strange.
90 break;
91 }
92 }
93
94 if (checkAIA) {
95 const auto extensions = certToFetch.extensions();
96 for (const auto &ext : extensions) {
97 if (ext.oid() == u"1.3.6.1.5.5.7.1.1") // See RFC 4325
98 return certToFetch;
99 }
100 //The only reason we check this extensions is because an application set trusted
101 //CA certificates explicitly, thus technically disabling CA fetch. So, if it's
102 //the case and an intermediate certificate is missing, and no extensions is
103 //present on the leaf certificate - we fail the handshake immediately.
104 return QSslCertificate{};
105 }
106
107 return certToFetch;
108}
109
110#endif // Q_OS_WIN
111
112} // unnamed namespace
113
114namespace QTlsPrivate {
115
116int q_X509Callback(int ok, X509_STORE_CTX *ctx)
117{
118 if (!ok) {
119 // Store the error and at which depth the error was detected.
120
121 using ErrorListPtr = QList<QSslErrorEntry> *;
122 ErrorListPtr errors = nullptr;
123
124 // Error list is attached to either 'SSL' or 'X509_STORE'.
125 if (X509_STORE *store = q_X509_STORE_CTX_get0_store(ctx)) // We try store first:
126 errors = ErrorListPtr(q_X509_STORE_get_ex_data(store, 0));
127
128 if (!errors) {
129 // Not found on store? Try SSL and its external data then. According to the OpenSSL's
130 // documentation:
131 //
132 // "Whenever a X509_STORE_CTX object is created for the verification of the
133 // peer's certificate during a handshake, a pointer to the SSL object is
134 // stored into the X509_STORE_CTX object to identify the connection affected.
135 // To retrieve this pointer the X509_STORE_CTX_get_ex_data() function can be
136 // used with the correct index."
137 const auto offset = QTlsBackendOpenSSL::s_indexForSSLExtraData
139 if (SSL *ssl = static_cast<SSL *>(q_X509_STORE_CTX_get_ex_data(
141
142 // We may be in a renegotiation, check if we are inside a call to SSL_read:
143 const auto tlsOffset = QTlsBackendOpenSSL::s_indexForSSLExtraData
145 auto tls = static_cast<TlsCryptographOpenSSL *>(q_SSL_get_ex_data(ssl, tlsOffset));
146 Q_ASSERT(tls);
147 if (tls->isInSslRead()) {
148 // We are in a renegotiation, make a note of this for later.
149 // We'll check that the certificate is the same as the one we got during
150 // the initial handshake
151 tls->setRenegotiated(true);
152 return 1;
153 }
154
155 errors = ErrorListPtr(q_SSL_get_ex_data(ssl, offset));
156 }
157 }
158
159 if (!errors) {
160 qCWarning(lcTlsBackend, "Neither X509_STORE, nor SSL contains error list, handshake failure");
161 return 0;
162 }
163
164 errors->append(X509CertificateOpenSSL::errorEntryFromStoreContext(ctx));
165 }
166 // Always return OK to allow verification to continue. We handle the
167 // errors gracefully after collecting all errors, after verification has
168 // completed.
169 return 1;
170}
171
172int q_X509CallbackDirect(int ok, X509_STORE_CTX *ctx)
173{
174 // Passed to SSL_CTX_set_verify()
175 // https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_verify.html
176 // Returns 0 to abort verification, 1 to continue.
177
178 // This is a new, experimental verification callback, reporting
179 // errors immediately and returning 0 or 1 depending on an application
180 // either ignoring or not ignoring verification errors as they come.
181 if (!ctx) {
182 qCWarning(lcTlsBackend, "Invalid store context (nullptr)");
183 return 0;
184 }
185
186 if (!ok) {
187 // "Whenever a X509_STORE_CTX object is created for the verification of the
188 // peer's certificate during a handshake, a pointer to the SSL object is
189 // stored into the X509_STORE_CTX object to identify the connection affected.
190 // To retrieve this pointer the X509_STORE_CTX_get_ex_data() function can be
191 // used with the correct index."
193 if (!ssl) {
194 qCWarning(lcTlsBackend, "No external data (SSL) found in X509 store object");
195 return 0;
196 }
197
198 const auto offset = QTlsBackendOpenSSL::s_indexForSSLExtraData
200 auto crypto = static_cast<TlsCryptographOpenSSL *>(q_SSL_get_ex_data(ssl, offset));
201 if (!crypto) {
202 qCWarning(lcTlsBackend, "No external data (TlsCryptographOpenSSL) found in SSL object");
203 return 0;
204 }
205
206 return crypto->emitErrorFromCallback(ctx);
207 }
208 return 1;
209}
210
211#ifndef OPENSSL_NO_PSK
212static unsigned q_ssl_psk_client_callback(SSL *ssl, const char *hint, char *identity, unsigned max_identity_len,
213 unsigned char *psk, unsigned max_psk_len)
214{
215 auto *tls = static_cast<TlsCryptographOpenSSL *>(q_SSL_get_ex_data(ssl, QTlsBackendOpenSSL::s_indexForSSLExtraData));
216 return tls->pskClientTlsCallback(hint, identity, max_identity_len, psk, max_psk_len);
217}
218
219static unsigned int q_ssl_psk_server_callback(SSL *ssl, const char *identity, unsigned char *psk,
220 unsigned int max_psk_len)
221{
222 auto *tls = static_cast<TlsCryptographOpenSSL *>(q_SSL_get_ex_data(ssl, QTlsBackendOpenSSL::s_indexForSSLExtraData));
223 Q_ASSERT(tls);
224 return tls->pskServerTlsCallback(identity, psk, max_psk_len);
225}
226
227#ifdef TLS1_3_VERSION
228static unsigned q_ssl_psk_restore_client(SSL *ssl, const char *hint, char *identity, unsigned max_identity_len,
229 unsigned char *psk, unsigned max_psk_len)
230{
231 Q_UNUSED(hint);
232 Q_UNUSED(identity);
233 Q_UNUSED(max_identity_len);
234 Q_UNUSED(psk);
235 Q_UNUSED(max_psk_len);
236
237#ifdef QT_DEBUG
238 auto tls = static_cast<TlsCryptographOpenSSL *>(q_SSL_get_ex_data(ssl, QTlsBackendOpenSSL::s_indexForSSLExtraData));
239 Q_ASSERT(tls);
240 Q_ASSERT(tls->d);
241 Q_ASSERT(tls->d->tlsMode() == QSslSocket::SslClientMode);
242#endif
243 unsigned retVal = 0;
244
245 // Let developers opt-in to having the normal PSK callback get called for TLS 1.3
246 // PSK (which works differently in a few ways, and is called at the start of every connection).
247 // When they do opt-in we just call the old callback from here.
248 if (qEnvironmentVariableIsSet("QT_USE_TLS_1_3_PSK"))
249 retVal = q_ssl_psk_client_callback(ssl, hint, identity, max_identity_len, psk, max_psk_len);
250
252
253 return retVal;
254}
255
256static int q_ssl_psk_use_session_callback(SSL *ssl, const EVP_MD *md, const unsigned char **id,
257 size_t *idlen, SSL_SESSION **sess)
258{
259 Q_UNUSED(md);
260 Q_UNUSED(id);
261 Q_UNUSED(idlen);
262 Q_UNUSED(sess);
263
264#ifdef QT_DEBUG
265 auto *tls = static_cast<TlsCryptographOpenSSL *>(q_SSL_get_ex_data(ssl, QTlsBackendOpenSSL::s_indexForSSLExtraData));
266 Q_ASSERT(tls);
267 Q_ASSERT(tls->d);
268 Q_ASSERT(tls->d->tlsMode() == QSslSocket::SslClientMode);
269#endif
270
271 // Temporarily rebind the psk because it will be called next. The function will restore it.
272 q_SSL_set_psk_client_callback(ssl, &q_ssl_psk_restore_client);
273
274 return 1; // need to return 1 or else "the connection setup fails."
275}
276
277int q_ssl_sess_set_new_cb(SSL *ssl, SSL_SESSION *session)
278{
279 if (!ssl) {
280 qCWarning(lcTlsBackend, "Invalid SSL (nullptr)");
281 return 0;
282 }
283 if (!session) {
284 qCWarning(lcTlsBackend, "Invalid SSL_SESSION (nullptr)");
285 return 0;
286 }
287
288 auto *tls = static_cast<TlsCryptographOpenSSL *>(q_SSL_get_ex_data(ssl, QTlsBackendOpenSSL::s_indexForSSLExtraData));
289 Q_ASSERT(tls);
290 return tls->handleNewSessionTicket(ssl);
291}
292#endif // TLS1_3_VERSION
293
294#endif // !OPENSSL_NO_PSK
295
296#if QT_CONFIG(ocsp)
297
299{
301 if (!ssl)
303
305 if (!crypto)
307
308 Q_ASSERT(crypto->d);
312
313 unsigned char *derCopy = static_cast<unsigned char *>(q_OPENSSL_malloc(size_t(response.size())));
314 if (!derCopy)
316
318 // We don't check the return value: internally OpenSSL simply assigns the
319 // pointer (it assumes it now owns this memory btw!) and the length.
321
322 return SSL_TLSEXT_ERR_OK;
323}
324
325#endif // ocsp
326
327void qt_AlertInfoCallback(const SSL *connection, int from, int value)
328{
329 // Passed to SSL_set_info_callback()
330 // https://www.openssl.org/docs/man1.1.1/man3/SSL_set_info_callback.html
331
332 if (!connection) {
333#ifdef QSSLSOCKET_DEBUG
334 qCWarning(lcTlsBackend, "Invalid 'connection' parameter (nullptr)");
335#endif // QSSLSOCKET_DEBUG
336 return;
337 }
338
339 const auto offset = QTlsBackendOpenSSL::s_indexForSSLExtraData
341 auto crypto = static_cast<TlsCryptographOpenSSL *>(q_SSL_get_ex_data(connection, offset));
342 if (!crypto) {
343 // SSL_set_ex_data can fail:
344#ifdef QSSLSOCKET_DEBUG
345 qCWarning(lcTlsBackend, "No external data (socket backend) found for parameter 'connection'");
346#endif // QSSLSOCKET_DEBUG
347 return;
348 }
349
350 if (!(from & SSL_CB_ALERT)) {
351 // We only want to know about alerts (at least for now).
352 return;
353 }
354
355 if (from & SSL_CB_WRITE)
356 crypto->alertMessageSent(value);
357 else
358 crypto->alertMessageReceived(value);
359}
360
361#if QT_CONFIG(ocsp)
362namespace {
363
365{
366 switch (code) {
372 return QSslError::OcspTryLater;
378 default:
379 return {};
380 }
382}
383
385{
386 switch (reason) {
405 default:
407 }
408
410}
411
413{
414 // OCSP_basic_verify does verify that the responder is legit, the response is
415 // correctly signed, CertID is correct. But it does not know which certificate
416 // we were presented with by our peer, so it does not check if it's a response
417 // for our peer's certificate.
419
420 const OCSP_CERTID *certId = q_OCSP_SINGLERESP_get0_id(singleResponse); // Does not increment refcount.
421 if (!certId) {
422 qCWarning(lcTlsBackend, "A SingleResponse without CertID");
423 return false;
424 }
425
426 ASN1_OBJECT *md = nullptr;
428 const int result = q_OCSP_id_get0_info(nullptr, &md, nullptr, &reportedSerialNumber, const_cast<OCSP_CERTID *>(certId));
429 if (result != 1 || !md || !reportedSerialNumber) {
430 qCWarning(lcTlsBackend, "Failed to extract a hash and serial number from CertID structure");
431 return false;
432 }
433
435 // Is this possible at all? But we have to check this,
436 // ASN1_INTEGER_cmp (called from OCSP_id_cmp) dereferences
437 // without any checks at all.
438 qCWarning(lcTlsBackend, "No serial number in peer's ceritificate");
439 return false;
440 }
441
442 const int nid = q_OBJ_obj2nid(md);
443 if (nid == NID_undef) {
444 qCWarning(lcTlsBackend, "Unknown hash algorithm in CertID");
445 return false;
446 }
447
448 const EVP_MD *digest = q_EVP_get_digestbynid(nid); // Does not increment refcount.
449 if (!digest) {
450 qCWarning(lcTlsBackend) << "No digest for nid" << nid;
451 return false;
452 }
453
455 if (!recreatedId) {
456 qCWarning(lcTlsBackend, "Failed to re-create CertID");
457 return false;
458 }
460
461 if (q_OCSP_id_cmp(const_cast<OCSP_CERTID *>(certId), recreatedId)) {
462 qCDebug(lcTlsBackend, "Certificate ID mismatch");
463 return false;
464 }
465 // Bingo!
466 return true;
467}
468
469} // unnamed namespace
470#endif // ocsp
471
473{
474 destroySslContext();
475}
476
477void TlsCryptographOpenSSL::init(QSslSocket *qObj, QSslSocketPrivate *dObj)
478{
479 Q_ASSERT(qObj);
480 Q_ASSERT(dObj);
481 q = qObj;
482 d = dObj;
483
484 ocspResponses.clear();
485 ocspResponseDer.clear();
486
487 systemOrSslErrorDetected = false;
488 handshakeInterrupted = false;
489
490 fetchAuthorityInformation = false;
491 caToFetch.reset();
492}
493
499
501{
502 return sslContextPointer;
503}
504
506{
507 return sslErrors;
508}
509
511{
512 if (!initSslContext()) {
513 Q_ASSERT(d);
514 setErrorAndEmit(d, QAbstractSocket::SslInternalError,
515 QSslSocket::tr("Unable to init SSL Context: %1").arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
516 return;
517 }
518
519 // Start connecting. This will place outgoing data in the BIO, so we
520 // follow up with calling transmit().
523}
524
526{
527 if (!initSslContext()) {
528 Q_ASSERT(d);
529 setErrorAndEmit(d, QAbstractSocket::SslInternalError,
530 QSslSocket::tr("Unable to init SSL Context: %1").arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
531 return;
532 }
533
534 // Start connecting. This will place outgoing data in the BIO, so we
535 // follow up with calling transmit().
538}
539
541{
542 // Check if the connection has been established. Get all errors from the
543 // verification stage.
544 Q_ASSERT(q);
545 Q_ASSERT(d);
546
547 using ScopedBool = QScopedValueRollback<bool>;
548
549 if (inSetAndEmitError)
550 return false;
551
552 const auto mode = d->tlsMode();
553
554 pendingFatalAlert = false;
555 errorsReportedFromCallback = false;
556 QList<QSslErrorEntry> lastErrors;
557 q_SSL_set_ex_data(ssl, QTlsBackendOpenSSL::s_indexForSSLExtraData + errorOffsetInExData, &lastErrors);
558
559 // SSL_set_ex_data can fail, but see the callback's code - we handle this there.
562
563 int result = (mode == QSslSocket::SslClientMode) ? q_SSL_connect(ssl) : q_SSL_accept(ssl);
565 // Note, unlike errors as external data on SSL object, we do not unset
566 // a callback/ex-data if alert notifications are enabled: an alert can
567 // arrive after the handshake, for example, this happens when the server
568 // does not find a ClientCert or does not like it.
569
570 if (!lastErrors.isEmpty() || errorsReportedFromCallback)
572
573 // storePeerCertificate() if called above - would update the
574 // configuration with peer's certificates.
575 auto configuration = q->sslConfiguration();
576 if (!errorsReportedFromCallback) {
577 const auto &peerCertificateChain = configuration.peerCertificateChain();
578 for (const auto &currentError : std::as_const(lastErrors)) {
579 emit q->peerVerifyError(QTlsPrivate::X509CertificateOpenSSL::openSSLErrorToQSslError(currentError.code,
580 peerCertificateChain.value(currentError.depth)));
581 if (q->state() != QAbstractSocket::ConnectedState)
582 break;
583 }
584 }
585
586 errorList << lastErrors;
587
588 // Connection aborted during handshake phase.
589 if (q->state() != QAbstractSocket::ConnectedState)
590 return false;
591
592 // Check if we're encrypted or not.
593 if (result <= 0) {
594 switch (q_SSL_get_error(ssl, result)) {
595 case SSL_ERROR_WANT_READ:
596 case SSL_ERROR_WANT_WRITE:
597 // The handshake is not yet complete.
598 break;
599 default:
600 QString errorString = QTlsBackendOpenSSL::msgErrorsDuringHandshake();
601#ifdef QSSLSOCKET_DEBUG
602 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::startHandshake: error!" << errorString;
603#endif
604 {
605 const ScopedBool bg(inSetAndEmitError, true);
606 setErrorAndEmit(d, QAbstractSocket::SslHandshakeFailedError, errorString);
607 if (pendingFatalAlert) {
609 pendingFatalAlert = false;
610 }
611 }
612 q->abort();
613 }
614 return false;
615 }
616
617 // store peer certificate chain
619
620 // Start translating errors.
621 QList<QSslError> errors;
622
623 // Note, the storePeerCerificates() probably updated the configuration at this point.
624 configuration = q->sslConfiguration();
625 // Check the whole chain for blacklisting (including root, as we check for subjectInfo and issuer)
626 const auto &peerCertificateChain = configuration.peerCertificateChain();
627 for (const QSslCertificate &cert : peerCertificateChain) {
628 if (QSslCertificatePrivate::isBlacklisted(cert)) {
629 QSslError error(QSslError::CertificateBlacklisted, cert);
630 errors << error;
631 emit q->peerVerifyError(error);
632 if (q->state() != QAbstractSocket::ConnectedState)
633 return false;
634 }
635 }
636
637 const bool doVerifyPeer = configuration.peerVerifyMode() == QSslSocket::VerifyPeer
638 || (configuration.peerVerifyMode() == QSslSocket::AutoVerifyPeer
639 && mode == QSslSocket::SslClientMode);
640
641#if QT_CONFIG(ocsp)
642 // For now it's always QSslSocket::SslClientMode - initSslContext() will bail out early,
643 // if it's enabled in QSslSocket::SslServerMode. This can change.
644 if (!configuration.peerCertificate().isNull() && configuration.ocspStaplingEnabled() && doVerifyPeer) {
645 if (!checkOcspStatus()) {
646 if (ocspErrors.isEmpty()) {
647 {
648 const ScopedBool bg(inSetAndEmitError, true);
649 setErrorAndEmit(d, QAbstractSocket::SslHandshakeFailedError, ocspErrorDescription);
650 }
651 q->abort();
652 return false;
653 }
654
655 for (const QSslError &error : ocspErrors) {
656 errors << error;
657 emit q->peerVerifyError(error);
658 if (q->state() != QAbstractSocket::ConnectedState)
659 return false;
660 }
661 }
662 }
663#endif // ocsp
664
665 // Check the peer certificate itself. First try the subject's common name
666 // (CN) as a wildcard, then try all alternate subject name DNS entries the
667 // same way.
668 if (!configuration.peerCertificate().isNull()) {
669 // but only if we're a client connecting to a server
670 // if we're the server, don't check CN
671 const auto verificationPeerName = d->verificationName();
672 if (mode == QSslSocket::SslClientMode) {
673 QString peerName = (verificationPeerName.isEmpty () ? q->peerName() : verificationPeerName);
674
675 if (!isMatchingHostname(configuration.peerCertificate(), peerName)) {
676 // No matches in common names or alternate names.
677 QSslError error(QSslError::HostNameMismatch, configuration.peerCertificate());
678 errors << error;
679 emit q->peerVerifyError(error);
680 if (q->state() != QAbstractSocket::ConnectedState)
681 return false;
682 }
683 }
684 } else {
685 // No peer certificate presented. Report as error if the socket
686 // expected one.
687 if (doVerifyPeer) {
688 QSslError error(QSslError::NoPeerCertificate);
689 errors << error;
690 emit q->peerVerifyError(error);
691 if (q->state() != QAbstractSocket::ConnectedState)
692 return false;
693 }
694 }
695
696 // Translate errors from the error list into QSslErrors.
697 errors.reserve(errors.size() + errorList.size());
698 for (const auto &error : std::as_const(errorList))
699 errors << X509CertificateOpenSSL::openSSLErrorToQSslError(error.code, peerCertificateChain.value(error.depth));
700
701 if (!errors.isEmpty()) {
702 sslErrors = errors;
703#ifdef Q_OS_WIN
704 const bool fetchEnabled = QSslSocketPrivate::rootCertOnDemandLoadingSupported()
705 && d->isRootsOnDemandAllowed();
706 // !fetchEnabled is a special case scenario, when we potentially have a missing
707 // intermediate certificate and a recoverable chain, but on demand cert loading
708 // was disabled by setCaCertificates call. For this scenario we check if "Authority
709 // Information Access" is present - wincrypt can deal with such certificates.
710 QSslCertificate certToFetch;
711 if (doVerifyPeer && !d->verifyErrorsHaveBeenIgnored())
712 certToFetch = findCertificateToFetch(sslErrors, !fetchEnabled);
713
714 //Skip this if not using system CAs, or if the SSL errors are configured in advance to be ignorable
715 if (!certToFetch.isNull()) {
716 fetchAuthorityInformation = !fetchEnabled;
717 //Windows desktop versions starting from vista ship with minimal set of roots and download on demand
718 //from the windows update server CA roots that are trusted by MS. It also can fetch a missing intermediate
719 //in case "Authority Information Access" extension is present.
720 //
721 //However, this is only transparent if using WinINET - we have to trigger it
722 //ourselves.
723 fetchCaRootForCert(certToFetch);
724 return false;
725 }
726#endif // Q_OS_WIN
727 if (!checkSslErrors())
728 return false;
729 // A slot, attached to sslErrors signal can call
730 // abort/close/disconnetFromHost/etc; no need to
731 // continue handshake then.
732 if (q->state() != QAbstractSocket::ConnectedState)
733 return false;
734 } else {
735 sslErrors.clear();
736 }
737
739 return true;
740}
741
743{
744 handshakeInterrupted = false;
745}
746
748{
749 fetchAuthorityInformation = false;
750 caToFetch.reset();
751}
752
754{
755 auto sslCfg = q->sslConfiguration();
756 auto list = sslCfg.keyingMaterial();
757
758 for (auto &entry : list) {
759 if (!entry.isValid()) {
760#ifdef QSSLSOCKET_DEBUG
761 qCDebug(lcTlsBackend) << "keying material request is invalid:" << entry;
762#endif
763 continue;
764 }
765
766 /*
767 * https://docs.openssl.org/1.1.1/man3/SSL_export_keying_material/
768 * Note that in TLSv1.2 and below a zero length context is treated
769 * differently from no context at all, and will result in different
770 * keying material being returned. In TLSv1.3 a zero length context
771 * is that same as no context at all and will result in the same
772 * keying material being returned.
773 */
774 const auto context = entry.context();
775 const auto label = entry.label();
776 if (QByteArray output(entry.keyingValueSize, Qt::Uninitialized);
777 q_SSL_export_keying_material(ssl,
778 reinterpret_cast<unsigned char*>(output.data_ptr().data()),
779 entry.keyingValueSize,
780 label.data(),
781 label.size(),
782 reinterpret_cast<const unsigned char*>(context.data()),
783 context.size(),
784 context.isNull() ? 0 : 1))
785 {
786 entry.keyingValue = std::move(output);
787#ifdef QSSLSOCKET_DEBUG
788 } else {
789 qCDebug(lcTlsBackend) << "cannot export keying material:" << entry;
790#endif
791 }
792 }
793
794 sslCfg.setKeyingMaterial(list);
795 q->setSslConfiguration(sslCfg);
796}
797
799{
800 Q_ASSERT(q);
801 Q_ASSERT(d);
802
803 auto *plainSocket = d->plainTcpSocket();
804 Q_ASSERT(plainSocket);
805
806 const auto mode = d->tlsMode();
807
808 // if we have a max read buffer size, reset the plain socket's to match
809 if (const auto maxSize = d->maxReadBufferSize())
810 plainSocket->setReadBufferSize(maxSize);
811
812 if (q_SSL_session_reused(ssl))
813 QTlsBackend::setPeerSessionShared(d, true);
814
815#ifdef QT_DECRYPT_SSL_TRAFFIC
816 if (q_SSL_get_session(ssl)) {
817 size_t master_key_len = q_SSL_SESSION_get_master_key(q_SSL_get_session(ssl), nullptr, 0);
818 size_t client_random_len = q_SSL_get_client_random(ssl, nullptr, 0);
819 QByteArray masterKey(int(master_key_len), Qt::Uninitialized); // Will not overflow
820 QByteArray clientRandom(int(client_random_len), Qt::Uninitialized); // Will not overflow
821
822 q_SSL_SESSION_get_master_key(q_SSL_get_session(ssl),
823 reinterpret_cast<unsigned char*>(masterKey.data()),
824 masterKey.size());
825 q_SSL_get_client_random(ssl, reinterpret_cast<unsigned char *>(clientRandom.data()),
826 clientRandom.size());
827
828 QByteArray debugLineClientRandom("CLIENT_RANDOM ");
829 debugLineClientRandom.append(clientRandom.toHex().toUpper());
830 debugLineClientRandom.append(" ");
831 debugLineClientRandom.append(masterKey.toHex().toUpper());
832 debugLineClientRandom.append("\n");
833
834 QString sslKeyFile = QDir::tempPath() + "/qt-ssl-keys"_L1;
835 QFile file(sslKeyFile);
836 if (!file.open(QIODevice::Append))
837 qCWarning(lcTlsBackend) << "could not open file" << sslKeyFile << "for appending";
838 if (!file.write(debugLineClientRandom))
839 qCWarning(lcTlsBackend) << "could not write to file" << sslKeyFile;
840 file.close();
841 } else {
842 qCWarning(lcTlsBackend, "could not decrypt SSL traffic");
843 }
844#endif // QT_DECRYPT_SSL_TRAFFIC
845
846 const auto &configuration = q->sslConfiguration();
847 // Cache this SSL session inside the QSslContext
848 if (!(configuration.testSslOption(QSsl::SslOptionDisableSessionSharing))) {
849 if (!sslContextPointer->cacheSession(ssl)) {
850 sslContextPointer.reset(); // we could not cache the session
851 } else {
852 // Cache the session for permanent usage as well
853 if (!(configuration.testSslOption(QSsl::SslOptionDisableSessionPersistence))) {
854 if (!sslContextPointer->sessionASN1().isEmpty())
855 QTlsBackend::setSessionAsn1(d, sslContextPointer->sessionASN1());
856 QTlsBackend::setSessionLifetimeHint(d, sslContextPointer->sessionTicketLifeTimeHint());
857 }
858 }
859 }
860
861#if !defined(OPENSSL_NO_NEXTPROTONEG)
862
863 QTlsBackend::setAlpnStatus(d, sslContextPointer->npnContext().status);
864 if (sslContextPointer->npnContext().status == QSslConfiguration::NextProtocolNegotiationUnsupported) {
865 // we could not agree -> be conservative and use HTTP/1.1
866 // T.P.: I have to admit, this is a really strange notion of 'conservative',
867 // given the protocol-neutral nature of ALPN/NPN.
868 QTlsBackend::setNegotiatedProtocol(d, QByteArrayLiteral("http/1.1"));
869 } else {
870 const unsigned char *proto = nullptr;
871 unsigned int proto_len = 0;
872
873 q_SSL_get0_alpn_selected(ssl, &proto, &proto_len);
874 if (proto_len && mode == QSslSocket::SslClientMode) {
875 // Client does not have a callback that sets it ...
876 QTlsBackend::setAlpnStatus(d, QSslConfiguration::NextProtocolNegotiationNegotiated);
877 }
878
879 if (!proto_len) { // Test if NPN was more lucky ...
880 q_SSL_get0_next_proto_negotiated(ssl, &proto, &proto_len);
881 }
882
883 if (proto_len)
884 QTlsBackend::setNegotiatedProtocol(d, QByteArray(reinterpret_cast<const char *>(proto), proto_len));
885 else
886 QTlsBackend::setNegotiatedProtocol(d,{});
887 }
888#endif // !defined(OPENSSL_NO_NEXTPROTONEG)
889
890 if (mode == QSslSocket::SslClientMode) {
891 EVP_PKEY *key;
892 if (q_SSL_get_server_tmp_key(ssl, &key))
893 QTlsBackend::setEphemeralKey(d, QSslKey(key, QSsl::PublicKey));
894 }
895
897
898 d->setEncrypted(true);
899 emit q->encrypted();
900 if (d->isAutoStartingHandshake() && d->isPendingClose()) {
901 d->setPendingClose(false);
902 q->disconnectFromHost();
903 }
904}
905
907{
908 Q_ASSERT(q);
909 Q_ASSERT(d);
910
911 using ScopedBool = QScopedValueRollback<bool>;
912
913 if (inSetAndEmitError)
914 return;
915
916 // If we don't have any SSL context, don't bother transmitting.
917 if (!ssl)
918 return;
919
920 auto &writeBuffer = d->tlsWriteBuffer();
921 auto &buffer = d->tlsBuffer();
922 auto *plainSocket = d->plainTcpSocket();
923 Q_ASSERT(plainSocket);
924 bool &emittedBytesWritten = d->tlsEmittedBytesWritten();
925
926 bool transmitting;
927 do {
928 transmitting = false;
929
930 // If the connection is secure, we can transfer data from the write
931 // buffer (in plain text) to the write BIO through SSL_write.
932 if (q->isEncrypted() && !writeBuffer.isEmpty()) {
933 qint64 totalBytesWritten = 0;
934 int nextDataBlockSize;
935 while ((nextDataBlockSize = writeBuffer.nextDataBlockSize()) > 0) {
936 int writtenBytes = q_SSL_write(ssl, writeBuffer.readPointer(), nextDataBlockSize);
937 if (writtenBytes <= 0) {
938 int error = q_SSL_get_error(ssl, writtenBytes);
939 //write can result in a want_write_error - not an error - continue transmitting
940 if (error == SSL_ERROR_WANT_WRITE) {
941 transmitting = true;
942 break;
943 } else if (error == SSL_ERROR_WANT_READ) {
944 //write can result in a want_read error, possibly due to renegotiation - not an error - stop transmitting
945 transmitting = false;
946 break;
947 } else {
948 // ### Better error handling.
949 const ScopedBool bg(inSetAndEmitError, true);
950 setErrorAndEmit(d, QAbstractSocket::SslInternalError,
951 QSslSocket::tr("Unable to write data: %1").arg(
952 QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
953 return;
954 }
955 }
956#ifdef QSSLSOCKET_DEBUG
957 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::transmit: encrypted" << writtenBytes << "bytes";
958#endif
959 writeBuffer.free(writtenBytes);
960 totalBytesWritten += writtenBytes;
961
962 if (writtenBytes < nextDataBlockSize) {
963 // break out of the writing loop and try again after we had read
964 transmitting = true;
965 break;
966 }
967 }
968
969 if (totalBytesWritten > 0) {
970 // Don't emit bytesWritten() recursively.
971 if (!emittedBytesWritten) {
972 emittedBytesWritten = true;
973 emit q->bytesWritten(totalBytesWritten);
974 emittedBytesWritten = false;
975 }
976 emit q->channelBytesWritten(0, totalBytesWritten);
977 }
978 }
979
980 // Check if we've got any data to be written to the socket.
981 QVarLengthArray<char, 4096> data;
982 int pendingBytes;
983 while (plainSocket->isValid() && (pendingBytes = q_BIO_pending(writeBio)) > 0
984 && plainSocket->openMode() != QIODevice::NotOpen) {
985 // Read encrypted data from the write BIO into a buffer.
986 data.resize(pendingBytes);
987 int encryptedBytesRead = q_BIO_read(writeBio, data.data(), pendingBytes);
988
989 // Write encrypted data from the buffer to the socket.
990 qint64 actualWritten = plainSocket->write(data.constData(), encryptedBytesRead);
991#ifdef QSSLSOCKET_DEBUG
992 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::transmit: wrote" << encryptedBytesRead
993 << "encrypted bytes to the socket" << actualWritten << "actual.";
994#endif
995 if (actualWritten < 0) {
996 //plain socket write fails if it was in the pending close state.
997 const ScopedBool bg(inSetAndEmitError, true);
998 setErrorAndEmit(d, plainSocket->error(), plainSocket->errorString());
999 return;
1000 }
1001 transmitting = true;
1002 }
1003
1004 // Check if we've got any data to be read from the socket.
1005 if (!q->isEncrypted() || !d->maxReadBufferSize() || buffer.size() < d->maxReadBufferSize())
1006 while ((pendingBytes = plainSocket->bytesAvailable()) > 0) {
1007 // Read encrypted data from the socket into a buffer.
1008 data.resize(pendingBytes);
1009 // just peek() here because q_BIO_write could write less data than expected
1010 int encryptedBytesRead = plainSocket->peek(data.data(), pendingBytes);
1011
1012#ifdef QSSLSOCKET_DEBUG
1013 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::transmit: read" << encryptedBytesRead << "encrypted bytes from the socket";
1014#endif
1015 // Write encrypted data from the buffer into the read BIO.
1016 int writtenToBio = q_BIO_write(readBio, data.constData(), encryptedBytesRead);
1017
1018 // Throw away the results.
1019 if (writtenToBio > 0) {
1020 plainSocket->skip(writtenToBio);
1021 } else {
1022 // ### Better error handling.
1023 const ScopedBool bg(inSetAndEmitError, true);
1024 setErrorAndEmit(d, QAbstractSocket::SslInternalError,
1025 QSslSocket::tr("Unable to decrypt data: %1")
1026 .arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
1027 return;
1028 }
1029
1030 transmitting = true;
1031 }
1032
1033 // If the connection isn't secured yet, this is the time to retry the
1034 // connect / accept.
1035 if (!q->isEncrypted()) {
1036#ifdef QSSLSOCKET_DEBUG
1037 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::transmit: testing encryption";
1038#endif
1039 if (startHandshake()) {
1040#ifdef QSSLSOCKET_DEBUG
1041 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::transmit: encryption established";
1042#endif
1043 d->setEncrypted(true);
1044 transmitting = true;
1045 } else if (plainSocket->state() != QAbstractSocket::ConnectedState) {
1046#ifdef QSSLSOCKET_DEBUG
1047 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::transmit: connection lost";
1048#endif
1049 break;
1050 } else if (d->isPaused()) {
1051 // just wait until the user continues
1052 return;
1053 } else {
1054#ifdef QSSLSOCKET_DEBUG
1055 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::transmit: encryption not done yet";
1056#endif
1057 }
1058 }
1059
1060 // If the request is small and the remote host closes the transmission
1061 // after sending, there's a chance that startHandshake() will already
1062 // have triggered a shutdown.
1063 if (!ssl)
1064 continue;
1065
1066 // We always read everything from the SSL decryption buffers, even if
1067 // we have a readBufferMaxSize. There's no point in leaving data there
1068 // just so that readBuffer.size() == readBufferMaxSize.
1069 int readBytes = 0;
1070 const int bytesToRead = 4096;
1071 do {
1072 if (q->readChannelCount() == 0) {
1073 // The read buffer is deallocated, don't try resize or write to it.
1074 break;
1075 }
1076 // Don't use SSL_pending(). It's very unreliable.
1077 inSslRead = true;
1078 readBytes = q_SSL_read(ssl, buffer.reserve(bytesToRead), bytesToRead);
1079 inSslRead = false;
1080 if (renegotiated) {
1081 renegotiated = false;
1082 X509 *x509 = q_SSL_get_peer_certificate(ssl);
1083 const auto peerCertificate =
1084 QTlsPrivate::X509CertificateOpenSSL::certificateFromX509(x509);
1085 // Fail the renegotiate if the certificate has changed, else: continue.
1086 if (peerCertificate != q->peerCertificate()) {
1087 const ScopedBool bg(inSetAndEmitError, true);
1088 setErrorAndEmit(
1089 d, QAbstractSocket::RemoteHostClosedError,
1090 QSslSocket::tr(
1091 "TLS certificate unexpectedly changed during renegotiation!"));
1092 q->abort();
1093 return;
1094 }
1095 }
1096 if (readBytes > 0) {
1097#ifdef QSSLSOCKET_DEBUG
1098 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::transmit: decrypted" << readBytes << "bytes";
1099#endif
1100 buffer.chop(bytesToRead - readBytes);
1101
1102 if (bool *readyReadEmittedPointer = d->readyReadPointer())
1103 *readyReadEmittedPointer = true;
1104 emit q->readyRead();
1105 emit q->channelReadyRead(0);
1106 transmitting = true;
1107 continue;
1108 }
1109 buffer.chop(bytesToRead);
1110
1111 // Error.
1112 switch (q_SSL_get_error(ssl, readBytes)) {
1113 case SSL_ERROR_WANT_READ:
1114 case SSL_ERROR_WANT_WRITE:
1115 // Out of data.
1116 break;
1117 case SSL_ERROR_ZERO_RETURN:
1118 // The remote host closed the connection.
1119#ifdef QSSLSOCKET_DEBUG
1120 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::transmit: remote disconnect";
1121#endif
1122 shutdown = true; // the other side shut down, make sure we do not send shutdown ourselves
1123 {
1124 const ScopedBool bg(inSetAndEmitError, true);
1125 setErrorAndEmit(d, QAbstractSocket::RemoteHostClosedError,
1126 QSslSocket::tr("The TLS/SSL connection has been closed"));
1127 }
1128 return;
1129 case SSL_ERROR_SYSCALL: // some IO error
1130 case SSL_ERROR_SSL: // error in the SSL library
1131 // we do not know exactly what the error is, nor whether we can recover from it,
1132 // so just return to prevent an endless loop in the outer "while" statement
1133 systemOrSslErrorDetected = true;
1134 {
1135 const ScopedBool bg(inSetAndEmitError, true);
1136 setErrorAndEmit(d, QAbstractSocket::SslInternalError,
1137 QSslSocket::tr("Error while reading: %1")
1138 .arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
1139 }
1140 return;
1141 default:
1142 // SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: can only happen with a
1143 // BIO_s_connect() or BIO_s_accept(), which we do not call.
1144 // SSL_ERROR_WANT_X509_LOOKUP: can only happen with a
1145 // SSL_CTX_set_client_cert_cb(), which we do not call.
1146 // So this default case should never be triggered.
1147 {
1148 const ScopedBool bg(inSetAndEmitError, true);
1149 setErrorAndEmit(d, QAbstractSocket::SslInternalError,
1150 QSslSocket::tr("Error while reading: %1")
1151 .arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
1152 }
1153 break;
1154 }
1155 } while (ssl && readBytes > 0);
1156 } while (ssl && transmitting);
1157}
1158
1160{
1161 if (ssl) {
1162 if (!shutdown && !q_SSL_in_init(ssl) && !systemOrSslErrorDetected) {
1163 if (q_SSL_shutdown(ssl) != 1) {
1164 // Some error may be queued, clear it.
1165 QTlsBackendOpenSSL::clearErrorQueue();
1166 }
1167 shutdown = true;
1168 transmit();
1169 }
1170 }
1171 Q_ASSERT(d);
1172 auto *plainSocket = d->plainTcpSocket();
1173 Q_ASSERT(plainSocket);
1174 plainSocket->disconnectFromHost();
1175}
1176
1178{
1179 Q_ASSERT(d);
1180 auto *plainSocket = d->plainTcpSocket();
1181 Q_ASSERT(plainSocket);
1182 d->setEncrypted(false);
1183
1184 if (plainSocket->bytesAvailable() <= 0) {
1185 destroySslContext();
1186 } else {
1187 // Move all bytes into the plain buffer.
1188 const qint64 tmpReadBufferMaxSize = d->maxReadBufferSize();
1189 // Reset temporarily, so the plain socket buffer is completely drained:
1190 d->setMaxReadBufferSize(0);
1191 transmit();
1192 d->setMaxReadBufferSize(tmpReadBufferMaxSize);
1193 }
1194 //if there is still buffered data in the plain socket, don't destroy the ssl context yet.
1195 //it will be destroyed when the socket is deleted.
1196}
1197
1199{
1200 if (!ssl)
1201 return {};
1202
1203 const SSL_CIPHER *sessionCipher = q_SSL_get_current_cipher(ssl);
1204 return sessionCipher ? QTlsBackendOpenSSL::qt_OpenSSL_cipher_to_QSslCipher(sessionCipher) : QSslCipher{};
1205}
1206
1208{
1209 if (!ssl)
1210 return QSsl::UnknownProtocol;
1211
1212 const int ver = q_SSL_version(ssl);
1213 switch (ver) {
1214QT_WARNING_PUSH
1215QT_WARNING_DISABLE_DEPRECATED
1216 case 0x301:
1217 return QSsl::TlsV1_0;
1218 case 0x302:
1219 return QSsl::TlsV1_1;
1220QT_WARNING_POP
1221 case 0x303:
1222 return QSsl::TlsV1_2;
1223 case 0x304:
1224 return QSsl::TlsV1_3;
1225 }
1226
1227 return QSsl::UnknownProtocol;
1228}
1229
1231{
1232 return ocspResponses;
1233}
1234
1236{
1237 Q_ASSERT(q);
1238 Q_ASSERT(d);
1239
1240 if (sslErrors.isEmpty())
1241 return true;
1242
1243 emit q->sslErrors(sslErrors);
1244
1245 const auto vfyMode = q->peerVerifyMode();
1246 const auto mode = d->tlsMode();
1247
1248 bool doVerifyPeer = vfyMode == QSslSocket::VerifyPeer || (vfyMode == QSslSocket::AutoVerifyPeer
1249 && mode == QSslSocket::SslClientMode);
1250 bool doEmitSslError = !d->verifyErrorsHaveBeenIgnored();
1251 // check whether we need to emit an SSL handshake error
1252 if (doVerifyPeer && doEmitSslError) {
1253 if (q->pauseMode() & QAbstractSocket::PauseOnSslErrors) {
1254 QSslSocketPrivate::pauseSocketNotifiers(q);
1255 d->setPaused(true);
1256 } else {
1257 setErrorAndEmit(d, QAbstractSocket::SslHandshakeFailedError, sslErrors.constFirst().errorString());
1258 auto *plainSocket = d->plainTcpSocket();
1259 Q_ASSERT(plainSocket);
1260 plainSocket->disconnectFromHost();
1261 }
1262 return false;
1263 }
1264 return true;
1265}
1266
1268{
1269 // If we return 1, this means we own the session, but we don't.
1270 // 0 would tell OpenSSL to deref (but they still have it in the
1271 // internal cache).
1272 Q_ASSERT(connection);
1273
1274 Q_ASSERT(q);
1275 Q_ASSERT(d);
1276
1277 if (q->sslConfiguration().testSslOption(QSsl::SslOptionDisableSessionPersistence)) {
1278 // We silently ignore, do nothing, remove from cache.
1279 return 0;
1280 }
1281
1282 SSL_SESSION *currentSession = q_SSL_get_session(connection);
1283 if (!currentSession) {
1284 qCWarning(lcTlsBackend,
1285 "New session ticket callback, the session is invalid (nullptr)");
1286 return 0;
1287 }
1288
1289 if (q_SSL_version(connection) < 0x304) {
1290 // We only rely on this mechanics with TLS >= 1.3
1291 return 0;
1292 }
1293
1294#ifdef TLS1_3_VERSION
1295 if (!q_SSL_SESSION_is_resumable(currentSession)) {
1296 qCDebug(lcTlsBackend, "New session ticket, but the session is non-resumable");
1297 return 0;
1298 }
1299#endif // TLS1_3_VERSION
1300
1301 const int sessionSize = q_i2d_SSL_SESSION(currentSession, nullptr);
1302 if (sessionSize <= 0) {
1303 qCWarning(lcTlsBackend, "could not store persistent version of SSL session");
1304 return 0;
1305 }
1306
1307 // We have somewhat perverse naming, it's not a ticket, it's a session.
1308 QByteArray sessionTicket(sessionSize, 0);
1309 auto data = reinterpret_cast<unsigned char *>(sessionTicket.data());
1310 if (!q_i2d_SSL_SESSION(currentSession, &data)) {
1311 qCWarning(lcTlsBackend, "could not store persistent version of SSL session");
1312 return 0;
1313 }
1314
1315 QTlsBackend::setSessionAsn1(d, sessionTicket);
1316 QTlsBackend::setSessionLifetimeHint(d, q_SSL_SESSION_get_ticket_lifetime_hint(currentSession));
1317
1318 emit q->newSessionTicketReceived();
1319 return 0;
1320}
1321
1323{
1324 Q_ASSERT(q);
1325 Q_ASSERT(d);
1326
1327 const auto level = tlsAlertLevel(value);
1328 if (level == QSsl::AlertLevel::Fatal && !q->isEncrypted()) {
1329 // Note, this logic is handshake-time only:
1330 pendingFatalAlert = true;
1331 }
1332
1333 emit q->alertSent(level, tlsAlertType(value), tlsAlertDescription(value));
1334
1335}
1336
1338{
1339 Q_ASSERT(q);
1340
1341 emit q->alertReceived(tlsAlertLevel(value), tlsAlertType(value), tlsAlertDescription(value));
1342}
1343
1345{
1346 // Returns 0 to abort verification, 1 to continue despite error (as
1347 // OpenSSL expects from the verification callback).
1348 Q_ASSERT(q);
1349 Q_ASSERT(ctx);
1350
1351 using ScopedBool = QScopedValueRollback<bool>;
1352 // While we are not setting, we are emitting and in general -
1353 // we want to prevent accidental recursive startHandshake()
1354 // calls:
1355 const ScopedBool bg(inSetAndEmitError, true);
1356
1358 if (!x509) {
1359 qCWarning(lcTlsBackend, "Could not obtain the certificate (that failed to verify)");
1360 return 0;
1361 }
1362
1363 const QSslCertificate certificate = QTlsPrivate::X509CertificateOpenSSL::certificateFromX509(x509);
1364 const auto errorAndDepth = QTlsPrivate::X509CertificateOpenSSL::errorEntryFromStoreContext(ctx);
1365 const QSslError tlsError = QTlsPrivate::X509CertificateOpenSSL::openSSLErrorToQSslError(errorAndDepth.code, certificate);
1366
1367 errorsReportedFromCallback = true;
1368 handshakeInterrupted = true;
1369 emit q->handshakeInterruptedOnError(tlsError);
1370
1371 // Conveniently so, we also can access 'lastErrors' external data set
1372 // in startHandshake, we store it for the case an application later
1373 // wants to check errors (ignored or not):
1374 const auto offset = QTlsBackendOpenSSL::s_indexForSSLExtraData
1376 if (auto errorList = static_cast<QList<QSslErrorEntry> *>(q_SSL_get_ex_data(ssl, offset)))
1377 errorList->append(errorAndDepth);
1378
1379 // An application is expected to ignore this error (by calling ignoreSslErrors)
1380 // in its directly connected slot:
1381 return !handshakeInterrupted;
1382}
1383
1385{
1386 Q_ASSERT(pendingFatalAlert);
1387 Q_ASSERT(d);
1388
1389 auto *plainSocket = d->plainTcpSocket();
1390
1391 pendingFatalAlert = false;
1392 QVarLengthArray<char, 4096> data;
1393 int pendingBytes = 0;
1394 while (plainSocket->isValid() && (pendingBytes = q_BIO_pending(writeBio)) > 0
1395 && plainSocket->openMode() != QIODevice::NotOpen) {
1396 // Read encrypted data from the write BIO into a buffer.
1397 data.resize(pendingBytes);
1398 const int bioReadBytes = q_BIO_read(writeBio, data.data(), pendingBytes);
1399
1400 // Write encrypted data from the buffer to the socket.
1401 qint64 actualWritten = plainSocket->write(data.constData(), bioReadBytes);
1402 if (actualWritten < 0)
1403 return;
1404 plainSocket->flush();
1405 }
1406}
1407
1408bool TlsCryptographOpenSSL::initSslContext()
1409{
1410 Q_ASSERT(q);
1411 Q_ASSERT(d);
1412
1413 // If no external context was set (e.g. by QHttpNetworkConnection) we will
1414 // create a new one.
1415 const auto mode = d->tlsMode();
1416 const auto configuration = q->sslConfiguration();
1417 if (!sslContextPointer)
1418 sslContextPointer = QSslContext::sharedFromConfiguration(mode, configuration, d->isRootsOnDemandAllowed());
1419
1420 if (sslContextPointer->error() != QSslError::NoError) {
1421 setErrorAndEmit(d, QAbstractSocket::SslInvalidUserDataError, sslContextPointer->errorString());
1422 sslContextPointer.reset();
1423 return false;
1424 }
1425
1426 // Create and initialize SSL session
1427 if (!(ssl = sslContextPointer->createSsl())) {
1428 setErrorAndEmit(d, QAbstractSocket::SslInternalError,
1429 QSslSocket::tr("Error creating SSL session, %1").arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
1430 return false;
1431 }
1432
1433 if (configuration.protocol() != QSsl::UnknownProtocol && mode == QSslSocket::SslClientMode) {
1434 const auto verificationPeerName = d->verificationName();
1435 // Set server hostname on TLS extension. RFC4366 section 3.1 requires it in ACE format.
1436 QString tlsHostName = verificationPeerName.isEmpty() ? q->peerName() : verificationPeerName;
1437 if (tlsHostName.isEmpty())
1438 tlsHostName = d->tlsHostName();
1439 QByteArray ace = QUrl::toAce(tlsHostName);
1440 // only send the SNI header if the URL is valid and not an IP
1441 if (!ace.isEmpty()
1442 && !QHostAddress().setAddress(tlsHostName)
1443 && !(configuration.testSslOption(QSsl::SslOptionDisableServerNameIndication))) {
1444 // We don't send the trailing dot from the host header if present see
1445 // https://tools.ietf.org/html/rfc6066#section-3
1446 if (ace.endsWith('.'))
1447 ace.chop(1);
1448 if (!q_SSL_ctrl(ssl, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, ace.data()))
1449 qCWarning(lcTlsBackend, "could not set SSL_CTRL_SET_TLSEXT_HOSTNAME, Server Name Indication disabled");
1450 }
1451 }
1452
1453 // Clear the session.
1454 errorList.clear();
1455
1456 // Initialize memory BIOs for encryption and decryption.
1457 readBio = q_BIO_new(q_BIO_s_mem());
1458 writeBio = q_BIO_new(q_BIO_s_mem());
1459 if (!readBio || !writeBio) {
1460 setErrorAndEmit(d, QAbstractSocket::SslInternalError,
1461 QSslSocket::tr("Error creating SSL session: %1").arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
1462 if (readBio)
1463 q_BIO_free(readBio);
1464 if (writeBio)
1465 q_BIO_free(writeBio);
1466 return false;
1467 }
1468
1469 // Assign the bios.
1470 q_SSL_set_bio(ssl, readBio, writeBio);
1471
1472 if (mode == QSslSocket::SslClientMode)
1474 else
1476
1477 q_SSL_set_ex_data(ssl, QTlsBackendOpenSSL::s_indexForSSLExtraData, this);
1478
1479#ifndef OPENSSL_NO_PSK
1480 // Set the client callback for PSK
1481 if (mode == QSslSocket::SslClientMode)
1483 else if (mode == QSslSocket::SslServerMode)
1485
1486#if OPENSSL_VERSION_NUMBER >= 0x10101006L
1487 // Set the client callback for TLSv1.3 PSK
1488 if (mode == QSslSocket::SslClientMode
1489 && QSslSocket::sslLibraryBuildVersionNumber() >= 0x10101006L) {
1490 q_SSL_set_psk_use_session_callback(ssl, &q_ssl_psk_use_session_callback);
1491 }
1492#endif // openssl version >= 0x10101006L
1493
1494#endif // OPENSSL_NO_PSK
1495
1496#if QT_CONFIG(ocsp)
1497 if (configuration.ocspStaplingEnabled()) {
1498 if (mode == QSslSocket::SslServerMode) {
1499 setErrorAndEmit(d, QAbstractSocket::SslInvalidUserDataError,
1500 QSslSocket::tr("Server-side QSslSocket does not support OCSP stapling"));
1501 return false;
1502 }
1503 if (q_SSL_set_tlsext_status_type(ssl, TLSEXT_STATUSTYPE_ocsp) != 1) {
1504 setErrorAndEmit(d, QAbstractSocket::SslInternalError,
1505 QSslSocket::tr("Failed to enable OCSP stapling"));
1506 return false;
1507 }
1508 }
1509
1510 ocspResponseDer.clear();
1511 const auto backendConfig = configuration.backendConfiguration();
1512 auto responsePos = backendConfig.find("Qt-OCSP-response");
1513 if (responsePos != backendConfig.end()) {
1514 // This is our private, undocumented 'API' we use for the auto-testing of
1515 // OCSP-stapling. It must be a der-encoded OCSP response, presumably set
1516 // by tst_QOcsp.
1517 const QVariant data(responsePos.value());
1518 if (data.canConvert<QByteArray>())
1519 ocspResponseDer = data.toByteArray();
1520 }
1521
1522 if (ocspResponseDer.size()) {
1523 if (mode != QSslSocket::SslServerMode) {
1524 setErrorAndEmit(d, QAbstractSocket::SslInvalidUserDataError,
1525 QSslSocket::tr("Client-side sockets do not send OCSP responses"));
1526 return false;
1527 }
1528 }
1529#endif // ocsp
1530
1531 return true;
1532}
1533
1534void TlsCryptographOpenSSL::destroySslContext()
1535{
1536 if (ssl) {
1537 if (!q_SSL_in_init(ssl) && !systemOrSslErrorDetected) {
1538 // We do not send a shutdown alert here. Just mark the session as
1539 // resumable for qhttpnetworkconnection's "optimization", otherwise
1540 // OpenSSL won't start a session resumption.
1541 if (q_SSL_shutdown(ssl) != 1) {
1542 // Some error may be queued, clear it.
1543 const auto errors = QTlsBackendOpenSSL::getErrorsFromOpenSsl();
1544 Q_UNUSED(errors);
1545 }
1546 }
1547 q_SSL_free(ssl);
1548 ssl = nullptr;
1549 }
1550 sslContextPointer.reset();
1551}
1552
1554{
1555 Q_ASSERT(d);
1556
1557 // Store the peer certificate and chain. For clients, the peer certificate
1558 // chain includes the peer certificate; for servers, it doesn't. Both the
1559 // peer certificate and the chain may be empty if the peer didn't present
1560 // any certificate.
1561 X509 *x509 = q_SSL_get_peer_certificate(ssl);
1562
1563 const auto peerCertificate = QTlsPrivate::X509CertificateOpenSSL::certificateFromX509(x509);
1564 QTlsBackend::storePeerCertificate(d, peerCertificate);
1565 q_X509_free(x509);
1566 auto peerCertificateChain = q->peerCertificateChain();
1567 if (peerCertificateChain.isEmpty()) {
1568 peerCertificateChain = QTlsPrivate::X509CertificateOpenSSL::stackOfX509ToQSslCertificates(q_SSL_get_peer_cert_chain(ssl));
1569 if (!peerCertificate.isNull() && d->tlsMode() == QSslSocket::SslServerMode)
1570 peerCertificateChain.prepend(peerCertificate);
1571 QTlsBackend::storePeerCertificateChain(d, peerCertificateChain);
1572 }
1573}
1574
1575#if QT_CONFIG(ocsp)
1576
1578{
1579 Q_ASSERT(ssl);
1580 Q_ASSERT(d);
1581
1582 const auto &configuration = q->sslConfiguration();
1583 Q_ASSERT(d->tlsMode() == QSslSocket::SslClientMode); // See initSslContext() for SslServerMode
1585
1586 const auto clearErrorQueue = qScopeGuard([] {
1588 });
1589
1592 ocspErrors.clear();
1593
1594 const unsigned char *responseData = nullptr;
1596 if (responseLength <= 0 || !responseData) {
1598 return false;
1599 }
1600
1602 if (!response) {
1603 // Treat this as a fatal SslHandshakeError.
1604 ocspErrorDescription = QSslSocket::tr("Failed to decode OCSP response");
1605 return false;
1606 }
1608
1611 // It's not a definitive response, it's an error message (not signed by the responder).
1613 return false;
1614 }
1615
1617 if (!basicResponse) {
1618 // SslHandshakeError.
1619 ocspErrorDescription = QSslSocket::tr("Failed to extract basic OCSP response");
1620 return false;
1621 }
1623
1624 SSL_CTX *ctx = q_SSL_get_SSL_CTX(ssl); // Does not increment refcount.
1625 Q_ASSERT(ctx);
1626 X509_STORE *store = q_SSL_CTX_get_cert_store(ctx); // Does not increment refcount.
1627 if (!store) {
1628 // SslHandshakeError.
1629 ocspErrorDescription = QSslSocket::tr("No certificate verification store, cannot verify OCSP response");
1630 return false;
1631 }
1632
1633 STACK_OF(X509) *peerChain = q_SSL_get_peer_cert_chain(ssl); // Does not increment refcount.
1637 // OCSP_basic_verify with 0 as verificationFlags:
1638 //
1639 // 0) Tries to find the OCSP responder's certificate in either peerChain
1640 // or basicResponse->certs. If not found, verification fails.
1641 // 1) It checks the signature using the responder's public key.
1642 // 2) Then it tries to validate the responder's cert (building a chain
1643 // etc.)
1644 // 3) It checks CertID in response.
1645 // 4) Ensures the responder is authorized to sign the status respond.
1646 //
1647 // Note, OpenSSL prior to 1.0.2b would only use bs->certs to
1648 // verify the responder's chain (see their commit 4ba9a4265bd).
1649 // Working this around - is too much fuss for ancient versions we
1650 // are dropping quite soon anyway.
1651 const unsigned long verificationFlags = 0;
1653 if (success <= 0)
1655
1656 if (q_OCSP_resp_count(basicResponse) != 1) {
1658 return false;
1659 }
1660
1662 if (!singleResponse) {
1663 ocspErrors.clear();
1664 // A fatal problem -> SslHandshakeError.
1665 ocspErrorDescription = QSslSocket::tr("Failed to decode a SingleResponse from OCSP status response");
1666 return false;
1667 }
1668
1669 // Let's make sure the response is for the correct certificate - we
1670 // can re-create this CertID using our peer's certificate and its
1671 // issuer's public key.
1675 bool matchFound = false;
1679 } else {
1681 if (!certs) // Oh, what a cataclysm! Last try:
1683 if (certs) {
1684 // It could be the first certificate in 'certs' is our peer's
1685 // certificate. Since it was not captured by the 'self-signed' branch
1686 // above, the CertID will not match and we'll just iterate on to the
1687 // next certificate. So we start from 0, not 1.
1688 for (int i = 0, e = q_sk_X509_num(certs); i < e; ++i) {
1691 if (matchFound) {
1694 break;
1695 }
1696 matchFound = false;
1697 }
1698 }
1699 }
1700 }
1701
1702 if (!matchFound) {
1705 }
1706
1707 // Check if the response is valid time-wise:
1708 ASN1_GENERALIZEDTIME *revTime = nullptr;
1711 int reason;
1713 if (!thisUpdate) {
1714 // This is unexpected, treat as SslHandshakeError, OCSP_check_validity assumes this pointer
1715 // to be != nullptr.
1716 ocspErrors.clear();
1718 ocspErrorDescription = QSslSocket::tr("Failed to extract 'this update time' from the SingleResponse");
1719 return false;
1720 }
1721
1722 // OCSP_check_validity(this, next, nsec, maxsec) does this check:
1723 // this <= now <= next. They allow some freedom to account
1724 // for delays/time inaccuracy.
1725 // this > now + nsec ? -> NOT_YET_VALID
1726 // if maxsec >= 0:
1727 // now - maxsec > this ? -> TOO_OLD
1728 // now - nsec > next ? -> EXPIRED
1729 // next < this ? -> NEXT_BEFORE_THIS
1730 // OK.
1733
1734 // And finally, the status:
1735 switch (certStatus) {
1737 // This certificate was not found among the revoked ones.
1739 break;
1744 break;
1748 }
1749
1750 return !ocspErrors.size();
1751}
1752
1753#endif // QT_CONFIG(ocsp)
1754
1755
1756unsigned TlsCryptographOpenSSL::pskClientTlsCallback(const char *hint, char *identity,
1757 unsigned max_identity_len,
1758 unsigned char *psk, unsigned max_psk_len)
1759{
1760 Q_ASSERT(q);
1761
1762 QSslPreSharedKeyAuthenticator authenticator;
1763 // Fill in some read-only fields (for the user)
1764 const int hintLength = hint ? int(std::strlen(hint)) : 0;
1765 QTlsBackend::setupClientPskAuth(&authenticator, hint, hintLength, max_identity_len, max_psk_len);
1766 // Let the client provide the remaining bits...
1767 emit q->preSharedKeyAuthenticationRequired(&authenticator);
1768
1769 // No PSK set? Return now to make the handshake fail
1770 if (authenticator.preSharedKey().isEmpty())
1771 return 0;
1772
1773 // Copy data back into OpenSSL
1774 const int identityLength = qMin(authenticator.identity().size(), authenticator.maximumIdentityLength());
1775 std::memcpy(identity, authenticator.identity().constData(), identityLength);
1776 identity[identityLength] = 0;
1777
1778 const int pskLength = qMin(authenticator.preSharedKey().size(), authenticator.maximumPreSharedKeyLength());
1779 std::memcpy(psk, authenticator.preSharedKey().constData(), pskLength);
1780 return pskLength;
1781}
1782
1783unsigned TlsCryptographOpenSSL::pskServerTlsCallback(const char *identity, unsigned char *psk,
1784 unsigned max_psk_len)
1785{
1786 Q_ASSERT(q);
1787
1788 QSslPreSharedKeyAuthenticator authenticator;
1789
1790 // Fill in some read-only fields (for the user)
1791 QTlsBackend::setupServerPskAuth(&authenticator, identity, q->sslConfiguration().preSharedKeyIdentityHint(),
1792 max_psk_len);
1793 emit q->preSharedKeyAuthenticationRequired(&authenticator);
1794
1795 // No PSK set? Return now to make the handshake fail
1796 if (authenticator.preSharedKey().isEmpty())
1797 return 0;
1798
1799 // Copy data back into OpenSSL
1800 const int pskLength = qMin(authenticator.preSharedKey().size(), authenticator.maximumPreSharedKeyLength());
1801 std::memcpy(psk, authenticator.preSharedKey().constData(), pskLength);
1802 return pskLength;
1803}
1804
1806{
1807 return inSslRead;
1808}
1809
1811{
1812 this->renegotiated = renegotiated;
1813}
1814
1815#ifdef Q_OS_WIN
1816
1818{
1819 Q_ASSERT(d);
1820 Q_ASSERT(q);
1821
1822 //The root certificate is downloaded from windows update, which blocks for 15 seconds in the worst case
1823 //so the request is done in a worker thread.
1827
1828 //Remember we are fetching and what we are fetching:
1829 caToFetch = cert;
1830
1832 q->peerVerifyName());
1837 d->setPaused(true);
1838}
1839
1841{
1842 if (caToFetch != cert) {
1843 //Ooops, something from the previous connection attempt, ignore!
1844 return;
1845 }
1846
1847 Q_ASSERT(d);
1848 Q_ASSERT(q);
1849
1850 //Done, fetched already:
1851 caToFetch.reset();
1852
1857 }
1858
1861 //Add the new root cert to default cert list for use by future sockets
1865 }
1866 //Add the new root cert to this socket for future connections
1868 //Remove the broken chain ssl errors (as chain is verified by windows)
1869 for (int i=sslErrors.count() - 1; i >= 0; --i) {
1870 if (sslErrors.at(i).certificate() == cert) {
1871 switch (sslErrors.at(i).error()) {
1876 // error can be ignored if OS says the chain is trusted
1878 break;
1879 default:
1880 // error cannot be ignored
1881 break;
1882 }
1883 }
1884 }
1885 }
1886
1887 auto *plainSocket = d->plainTcpSocket();
1889 // Continue with remaining errors
1890 if (plainSocket)
1892 d->setPaused(false);
1893 if (checkSslErrors() && ssl) {
1896 if (!willClose)
1897 transmit();
1898 }
1899}
1900
1901#endif // Q_OS_WIN
1902
1903} // namespace QTlsPrivate
1904
1905QT_END_NAMESPACE
unsigned pskClientTlsCallback(const char *hint, char *identity, unsigned max_identity_len, unsigned char *psk, unsigned max_psk_len)
std::shared_ptr< QSslContext > sslContext() const override
int handleNewSessionTicket(SSL *connection)
QList< QOcspResponse > ocsps() const override
int emitErrorFromCallback(X509_STORE_CTX *ctx)
unsigned pskServerTlsCallback(const char *identity, unsigned char *psk, unsigned max_psk_len)
QSsl::SslProtocol sessionProtocol() const override
void init(QSslSocket *qObj, QSslSocketPrivate *dObj) override
QList< QSslError > tlsErrors() const override
void setRenegotiated(bool renegotiated)
QSslCipher sessionCipher() const override
static QSslErrorEntry errorEntryFromStoreContext(X509_STORE_CTX *ctx)
Namespace containing onternal types that TLS backends implement.
int q_X509Callback(int ok, X509_STORE_CTX *ctx)
static unsigned q_ssl_psk_client_callback(SSL *ssl, const char *hint, char *identity, unsigned max_identity_len, unsigned char *psk, unsigned max_psk_len)
void qt_AlertInfoCallback(const SSL *connection, int from, int value)
static unsigned int q_ssl_psk_server_callback(SSL *ssl, const char *identity, unsigned char *psk, unsigned int max_psk_len)
int q_X509CallbackDirect(int ok, X509_STORE_CTX *ctx)
void q_SSL_free(SSL *a)
void q_SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, unsigned *len)
int q_SSL_in_init(const SSL *s)
const SSL_CIPHER * q_SSL_get_current_cipher(SSL *a)
void * q_X509_STORE_get_ex_data(X509_STORE *r, int idx)
int q_SSL_get_ex_data_X509_STORE_CTX_idx()
X509 * q_X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx)
void q_SSL_set_connect_state(SSL *a)
#define q_SSL_get_server_tmp_key(ssl, key)
int q_SSL_get_error(SSL *a, int b)
void * q_X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx)
void q_SSL_set_accept_state(SSL *a)
int q_SSL_shutdown(SSL *a)
BIO * q_BIO_new(const BIO_METHOD *a)
int q_i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
const char * q_SSL_alert_desc_string_long(int value)
void * q_SSL_get_ex_data(const SSL *ssl, int idx)
SSL_SESSION * q_SSL_get_session(const SSL *ssl)
#define q_BIO_pending(b)
int q_SSL_version(const SSL *a)
const BIO_METHOD * q_BIO_s_mem()
const char * q_SSL_alert_type_string(int value)
void q_SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, unsigned *len)
void q_SSL_set_bio(SSL *a, BIO *b, BIO *c)
void q_X509_free(X509 *a)
void q_SSL_set_psk_server_callback(SSL *ssl, q_psk_server_callback_t callback)
void q_SSL_set_info_callback(SSL *ssl, void(*cb)(const SSL *ssl, int type, int val))
X509_STORE * q_X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx)
void q_SSL_set_psk_client_callback(SSL *ssl, q_psk_client_callback_t callback)
int q_BIO_free(BIO *a)
int q_SSL_set_ex_data(SSL *ssl, int idx, void *arg)