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 QByteArray output(entry.keyingValueSize, Qt::Uninitialized);
767 /*
768 * https://docs.openssl.org/1.1.1/man3/SSL_export_keying_material/
769 * Note that in TLSv1.2 and below a zero length context is treated
770 * differently from no context at all, and will result in different
771 * keying material being returned. In TLSv1.3 a zero length context
772 * is that same as no context at all and will result in the same
773 * keying material being returned.
774 */
775 auto *outputData = reinterpret_cast<unsigned char*>(output.data());
776 const auto *context = reinterpret_cast<const unsigned char*>(entry.context().constData());
777 if (q_SSL_export_keying_material(ssl,
778 outputData,
779 entry.keyingValueSize,
780 entry.label().constData(),
781 entry.label().size(),
782 context,
783 entry.context().size(),
784 entry.context().isNull() ? 0 : 1)) {
785 entry.keyingValue = output;
786#ifdef QSSLSOCKET_DEBUG
787 } else {
788 qCDebug(lcTlsBackend) << "cannot export keying material:" << entry;
789#endif
790 }
791 }
792
793 sslCfg.setKeyingMaterial(list);
794 q->setSslConfiguration(sslCfg);
795}
796
798{
799 Q_ASSERT(q);
800 Q_ASSERT(d);
801
802 auto *plainSocket = d->plainTcpSocket();
803 Q_ASSERT(plainSocket);
804
805 const auto mode = d->tlsMode();
806
807 // if we have a max read buffer size, reset the plain socket's to match
808 if (const auto maxSize = d->maxReadBufferSize())
809 plainSocket->setReadBufferSize(maxSize);
810
811 if (q_SSL_session_reused(ssl))
812 QTlsBackend::setPeerSessionShared(d, true);
813
814#ifdef QT_DECRYPT_SSL_TRAFFIC
815 if (q_SSL_get_session(ssl)) {
816 size_t master_key_len = q_SSL_SESSION_get_master_key(q_SSL_get_session(ssl), nullptr, 0);
817 size_t client_random_len = q_SSL_get_client_random(ssl, nullptr, 0);
818 QByteArray masterKey(int(master_key_len), Qt::Uninitialized); // Will not overflow
819 QByteArray clientRandom(int(client_random_len), Qt::Uninitialized); // Will not overflow
820
821 q_SSL_SESSION_get_master_key(q_SSL_get_session(ssl),
822 reinterpret_cast<unsigned char*>(masterKey.data()),
823 masterKey.size());
824 q_SSL_get_client_random(ssl, reinterpret_cast<unsigned char *>(clientRandom.data()),
825 clientRandom.size());
826
827 QByteArray debugLineClientRandom("CLIENT_RANDOM ");
828 debugLineClientRandom.append(clientRandom.toHex().toUpper());
829 debugLineClientRandom.append(" ");
830 debugLineClientRandom.append(masterKey.toHex().toUpper());
831 debugLineClientRandom.append("\n");
832
833 QString sslKeyFile = QDir::tempPath() + "/qt-ssl-keys"_L1;
834 QFile file(sslKeyFile);
835 if (!file.open(QIODevice::Append))
836 qCWarning(lcTlsBackend) << "could not open file" << sslKeyFile << "for appending";
837 if (!file.write(debugLineClientRandom))
838 qCWarning(lcTlsBackend) << "could not write to file" << sslKeyFile;
839 file.close();
840 } else {
841 qCWarning(lcTlsBackend, "could not decrypt SSL traffic");
842 }
843#endif // QT_DECRYPT_SSL_TRAFFIC
844
845 const auto &configuration = q->sslConfiguration();
846 // Cache this SSL session inside the QSslContext
847 if (!(configuration.testSslOption(QSsl::SslOptionDisableSessionSharing))) {
848 if (!sslContextPointer->cacheSession(ssl)) {
849 sslContextPointer.reset(); // we could not cache the session
850 } else {
851 // Cache the session for permanent usage as well
852 if (!(configuration.testSslOption(QSsl::SslOptionDisableSessionPersistence))) {
853 if (!sslContextPointer->sessionASN1().isEmpty())
854 QTlsBackend::setSessionAsn1(d, sslContextPointer->sessionASN1());
855 QTlsBackend::setSessionLifetimeHint(d, sslContextPointer->sessionTicketLifeTimeHint());
856 }
857 }
858 }
859
860#if !defined(OPENSSL_NO_NEXTPROTONEG)
861
862 QTlsBackend::setAlpnStatus(d, sslContextPointer->npnContext().status);
863 if (sslContextPointer->npnContext().status == QSslConfiguration::NextProtocolNegotiationUnsupported) {
864 // we could not agree -> be conservative and use HTTP/1.1
865 // T.P.: I have to admit, this is a really strange notion of 'conservative',
866 // given the protocol-neutral nature of ALPN/NPN.
867 QTlsBackend::setNegotiatedProtocol(d, QByteArrayLiteral("http/1.1"));
868 } else {
869 const unsigned char *proto = nullptr;
870 unsigned int proto_len = 0;
871
872 q_SSL_get0_alpn_selected(ssl, &proto, &proto_len);
873 if (proto_len && mode == QSslSocket::SslClientMode) {
874 // Client does not have a callback that sets it ...
875 QTlsBackend::setAlpnStatus(d, QSslConfiguration::NextProtocolNegotiationNegotiated);
876 }
877
878 if (!proto_len) { // Test if NPN was more lucky ...
879 q_SSL_get0_next_proto_negotiated(ssl, &proto, &proto_len);
880 }
881
882 if (proto_len)
883 QTlsBackend::setNegotiatedProtocol(d, QByteArray(reinterpret_cast<const char *>(proto), proto_len));
884 else
885 QTlsBackend::setNegotiatedProtocol(d,{});
886 }
887#endif // !defined(OPENSSL_NO_NEXTPROTONEG)
888
889 if (mode == QSslSocket::SslClientMode) {
890 EVP_PKEY *key;
891 if (q_SSL_get_server_tmp_key(ssl, &key))
892 QTlsBackend::setEphemeralKey(d, QSslKey(key, QSsl::PublicKey));
893 }
894
896
897 d->setEncrypted(true);
898 emit q->encrypted();
899 if (d->isAutoStartingHandshake() && d->isPendingClose()) {
900 d->setPendingClose(false);
901 q->disconnectFromHost();
902 }
903}
904
906{
907 Q_ASSERT(q);
908 Q_ASSERT(d);
909
910 using ScopedBool = QScopedValueRollback<bool>;
911
912 if (inSetAndEmitError)
913 return;
914
915 // If we don't have any SSL context, don't bother transmitting.
916 if (!ssl)
917 return;
918
919 auto &writeBuffer = d->tlsWriteBuffer();
920 auto &buffer = d->tlsBuffer();
921 auto *plainSocket = d->plainTcpSocket();
922 Q_ASSERT(plainSocket);
923 bool &emittedBytesWritten = d->tlsEmittedBytesWritten();
924
925 bool transmitting;
926 do {
927 transmitting = false;
928
929 // If the connection is secure, we can transfer data from the write
930 // buffer (in plain text) to the write BIO through SSL_write.
931 if (q->isEncrypted() && !writeBuffer.isEmpty()) {
932 qint64 totalBytesWritten = 0;
933 int nextDataBlockSize;
934 while ((nextDataBlockSize = writeBuffer.nextDataBlockSize()) > 0) {
935 int writtenBytes = q_SSL_write(ssl, writeBuffer.readPointer(), nextDataBlockSize);
936 if (writtenBytes <= 0) {
937 int error = q_SSL_get_error(ssl, writtenBytes);
938 //write can result in a want_write_error - not an error - continue transmitting
939 if (error == SSL_ERROR_WANT_WRITE) {
940 transmitting = true;
941 break;
942 } else if (error == SSL_ERROR_WANT_READ) {
943 //write can result in a want_read error, possibly due to renegotiation - not an error - stop transmitting
944 transmitting = false;
945 break;
946 } else {
947 // ### Better error handling.
948 const ScopedBool bg(inSetAndEmitError, true);
949 setErrorAndEmit(d, QAbstractSocket::SslInternalError,
950 QSslSocket::tr("Unable to write data: %1").arg(
951 QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
952 return;
953 }
954 }
955#ifdef QSSLSOCKET_DEBUG
956 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::transmit: encrypted" << writtenBytes << "bytes";
957#endif
958 writeBuffer.free(writtenBytes);
959 totalBytesWritten += writtenBytes;
960
961 if (writtenBytes < nextDataBlockSize) {
962 // break out of the writing loop and try again after we had read
963 transmitting = true;
964 break;
965 }
966 }
967
968 if (totalBytesWritten > 0) {
969 // Don't emit bytesWritten() recursively.
970 if (!emittedBytesWritten) {
971 emittedBytesWritten = true;
972 emit q->bytesWritten(totalBytesWritten);
973 emittedBytesWritten = false;
974 }
975 emit q->channelBytesWritten(0, totalBytesWritten);
976 }
977 }
978
979 // Check if we've got any data to be written to the socket.
980 QVarLengthArray<char, 4096> data;
981 int pendingBytes;
982 while (plainSocket->isValid() && (pendingBytes = q_BIO_pending(writeBio)) > 0
983 && plainSocket->openMode() != QIODevice::NotOpen) {
984 // Read encrypted data from the write BIO into a buffer.
985 data.resize(pendingBytes);
986 int encryptedBytesRead = q_BIO_read(writeBio, data.data(), pendingBytes);
987
988 // Write encrypted data from the buffer to the socket.
989 qint64 actualWritten = plainSocket->write(data.constData(), encryptedBytesRead);
990#ifdef QSSLSOCKET_DEBUG
991 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::transmit: wrote" << encryptedBytesRead
992 << "encrypted bytes to the socket" << actualWritten << "actual.";
993#endif
994 if (actualWritten < 0) {
995 //plain socket write fails if it was in the pending close state.
996 const ScopedBool bg(inSetAndEmitError, true);
997 setErrorAndEmit(d, plainSocket->error(), plainSocket->errorString());
998 return;
999 }
1000 transmitting = true;
1001 }
1002
1003 // Check if we've got any data to be read from the socket.
1004 if (!q->isEncrypted() || !d->maxReadBufferSize() || buffer.size() < d->maxReadBufferSize())
1005 while ((pendingBytes = plainSocket->bytesAvailable()) > 0) {
1006 // Read encrypted data from the socket into a buffer.
1007 data.resize(pendingBytes);
1008 // just peek() here because q_BIO_write could write less data than expected
1009 int encryptedBytesRead = plainSocket->peek(data.data(), pendingBytes);
1010
1011#ifdef QSSLSOCKET_DEBUG
1012 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::transmit: read" << encryptedBytesRead << "encrypted bytes from the socket";
1013#endif
1014 // Write encrypted data from the buffer into the read BIO.
1015 int writtenToBio = q_BIO_write(readBio, data.constData(), encryptedBytesRead);
1016
1017 // Throw away the results.
1018 if (writtenToBio > 0) {
1019 plainSocket->skip(writtenToBio);
1020 } else {
1021 // ### Better error handling.
1022 const ScopedBool bg(inSetAndEmitError, true);
1023 setErrorAndEmit(d, QAbstractSocket::SslInternalError,
1024 QSslSocket::tr("Unable to decrypt data: %1")
1025 .arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
1026 return;
1027 }
1028
1029 transmitting = true;
1030 }
1031
1032 // If the connection isn't secured yet, this is the time to retry the
1033 // connect / accept.
1034 if (!q->isEncrypted()) {
1035#ifdef QSSLSOCKET_DEBUG
1036 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::transmit: testing encryption";
1037#endif
1038 if (startHandshake()) {
1039#ifdef QSSLSOCKET_DEBUG
1040 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::transmit: encryption established";
1041#endif
1042 d->setEncrypted(true);
1043 transmitting = true;
1044 } else if (plainSocket->state() != QAbstractSocket::ConnectedState) {
1045#ifdef QSSLSOCKET_DEBUG
1046 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::transmit: connection lost";
1047#endif
1048 break;
1049 } else if (d->isPaused()) {
1050 // just wait until the user continues
1051 return;
1052 } else {
1053#ifdef QSSLSOCKET_DEBUG
1054 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::transmit: encryption not done yet";
1055#endif
1056 }
1057 }
1058
1059 // If the request is small and the remote host closes the transmission
1060 // after sending, there's a chance that startHandshake() will already
1061 // have triggered a shutdown.
1062 if (!ssl)
1063 continue;
1064
1065 // We always read everything from the SSL decryption buffers, even if
1066 // we have a readBufferMaxSize. There's no point in leaving data there
1067 // just so that readBuffer.size() == readBufferMaxSize.
1068 int readBytes = 0;
1069 const int bytesToRead = 4096;
1070 do {
1071 if (q->readChannelCount() == 0) {
1072 // The read buffer is deallocated, don't try resize or write to it.
1073 break;
1074 }
1075 // Don't use SSL_pending(). It's very unreliable.
1076 inSslRead = true;
1077 readBytes = q_SSL_read(ssl, buffer.reserve(bytesToRead), bytesToRead);
1078 inSslRead = false;
1079 if (renegotiated) {
1080 renegotiated = false;
1081 X509 *x509 = q_SSL_get_peer_certificate(ssl);
1082 const auto peerCertificate =
1083 QTlsPrivate::X509CertificateOpenSSL::certificateFromX509(x509);
1084 // Fail the renegotiate if the certificate has changed, else: continue.
1085 if (peerCertificate != q->peerCertificate()) {
1086 const ScopedBool bg(inSetAndEmitError, true);
1087 setErrorAndEmit(
1088 d, QAbstractSocket::RemoteHostClosedError,
1089 QSslSocket::tr(
1090 "TLS certificate unexpectedly changed during renegotiation!"));
1091 q->abort();
1092 return;
1093 }
1094 }
1095 if (readBytes > 0) {
1096#ifdef QSSLSOCKET_DEBUG
1097 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::transmit: decrypted" << readBytes << "bytes";
1098#endif
1099 buffer.chop(bytesToRead - readBytes);
1100
1101 if (bool *readyReadEmittedPointer = d->readyReadPointer())
1102 *readyReadEmittedPointer = true;
1103 emit q->readyRead();
1104 emit q->channelReadyRead(0);
1105 transmitting = true;
1106 continue;
1107 }
1108 buffer.chop(bytesToRead);
1109
1110 // Error.
1111 switch (q_SSL_get_error(ssl, readBytes)) {
1112 case SSL_ERROR_WANT_READ:
1113 case SSL_ERROR_WANT_WRITE:
1114 // Out of data.
1115 break;
1116 case SSL_ERROR_ZERO_RETURN:
1117 // The remote host closed the connection.
1118#ifdef QSSLSOCKET_DEBUG
1119 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::transmit: remote disconnect";
1120#endif
1121 shutdown = true; // the other side shut down, make sure we do not send shutdown ourselves
1122 {
1123 const ScopedBool bg(inSetAndEmitError, true);
1124 setErrorAndEmit(d, QAbstractSocket::RemoteHostClosedError,
1125 QSslSocket::tr("The TLS/SSL connection has been closed"));
1126 }
1127 return;
1128 case SSL_ERROR_SYSCALL: // some IO error
1129 case SSL_ERROR_SSL: // error in the SSL library
1130 // we do not know exactly what the error is, nor whether we can recover from it,
1131 // so just return to prevent an endless loop in the outer "while" statement
1132 systemOrSslErrorDetected = true;
1133 {
1134 const ScopedBool bg(inSetAndEmitError, true);
1135 setErrorAndEmit(d, QAbstractSocket::SslInternalError,
1136 QSslSocket::tr("Error while reading: %1")
1137 .arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
1138 }
1139 return;
1140 default:
1141 // SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: can only happen with a
1142 // BIO_s_connect() or BIO_s_accept(), which we do not call.
1143 // SSL_ERROR_WANT_X509_LOOKUP: can only happen with a
1144 // SSL_CTX_set_client_cert_cb(), which we do not call.
1145 // So this default case should never be triggered.
1146 {
1147 const ScopedBool bg(inSetAndEmitError, true);
1148 setErrorAndEmit(d, QAbstractSocket::SslInternalError,
1149 QSslSocket::tr("Error while reading: %1")
1150 .arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
1151 }
1152 break;
1153 }
1154 } while (ssl && readBytes > 0);
1155 } while (ssl && transmitting);
1156}
1157
1159{
1160 if (ssl) {
1161 if (!shutdown && !q_SSL_in_init(ssl) && !systemOrSslErrorDetected) {
1162 if (q_SSL_shutdown(ssl) != 1) {
1163 // Some error may be queued, clear it.
1164 QTlsBackendOpenSSL::clearErrorQueue();
1165 }
1166 shutdown = true;
1167 transmit();
1168 }
1169 }
1170 Q_ASSERT(d);
1171 auto *plainSocket = d->plainTcpSocket();
1172 Q_ASSERT(plainSocket);
1173 plainSocket->disconnectFromHost();
1174}
1175
1177{
1178 Q_ASSERT(d);
1179 auto *plainSocket = d->plainTcpSocket();
1180 Q_ASSERT(plainSocket);
1181 d->setEncrypted(false);
1182
1183 if (plainSocket->bytesAvailable() <= 0) {
1184 destroySslContext();
1185 } else {
1186 // Move all bytes into the plain buffer.
1187 const qint64 tmpReadBufferMaxSize = d->maxReadBufferSize();
1188 // Reset temporarily, so the plain socket buffer is completely drained:
1189 d->setMaxReadBufferSize(0);
1190 transmit();
1191 d->setMaxReadBufferSize(tmpReadBufferMaxSize);
1192 }
1193 //if there is still buffered data in the plain socket, don't destroy the ssl context yet.
1194 //it will be destroyed when the socket is deleted.
1195}
1196
1198{
1199 if (!ssl)
1200 return {};
1201
1202 const SSL_CIPHER *sessionCipher = q_SSL_get_current_cipher(ssl);
1203 return sessionCipher ? QTlsBackendOpenSSL::qt_OpenSSL_cipher_to_QSslCipher(sessionCipher) : QSslCipher{};
1204}
1205
1207{
1208 if (!ssl)
1209 return QSsl::UnknownProtocol;
1210
1211 const int ver = q_SSL_version(ssl);
1212 switch (ver) {
1213QT_WARNING_PUSH
1214QT_WARNING_DISABLE_DEPRECATED
1215 case 0x301:
1216 return QSsl::TlsV1_0;
1217 case 0x302:
1218 return QSsl::TlsV1_1;
1219QT_WARNING_POP
1220 case 0x303:
1221 return QSsl::TlsV1_2;
1222 case 0x304:
1223 return QSsl::TlsV1_3;
1224 }
1225
1226 return QSsl::UnknownProtocol;
1227}
1228
1230{
1231 return ocspResponses;
1232}
1233
1235{
1236 Q_ASSERT(q);
1237 Q_ASSERT(d);
1238
1239 if (sslErrors.isEmpty())
1240 return true;
1241
1242 emit q->sslErrors(sslErrors);
1243
1244 const auto vfyMode = q->peerVerifyMode();
1245 const auto mode = d->tlsMode();
1246
1247 bool doVerifyPeer = vfyMode == QSslSocket::VerifyPeer || (vfyMode == QSslSocket::AutoVerifyPeer
1248 && mode == QSslSocket::SslClientMode);
1249 bool doEmitSslError = !d->verifyErrorsHaveBeenIgnored();
1250 // check whether we need to emit an SSL handshake error
1251 if (doVerifyPeer && doEmitSslError) {
1252 if (q->pauseMode() & QAbstractSocket::PauseOnSslErrors) {
1253 QSslSocketPrivate::pauseSocketNotifiers(q);
1254 d->setPaused(true);
1255 } else {
1256 setErrorAndEmit(d, QAbstractSocket::SslHandshakeFailedError, sslErrors.constFirst().errorString());
1257 auto *plainSocket = d->plainTcpSocket();
1258 Q_ASSERT(plainSocket);
1259 plainSocket->disconnectFromHost();
1260 }
1261 return false;
1262 }
1263 return true;
1264}
1265
1267{
1268 // If we return 1, this means we own the session, but we don't.
1269 // 0 would tell OpenSSL to deref (but they still have it in the
1270 // internal cache).
1271 Q_ASSERT(connection);
1272
1273 Q_ASSERT(q);
1274 Q_ASSERT(d);
1275
1276 if (q->sslConfiguration().testSslOption(QSsl::SslOptionDisableSessionPersistence)) {
1277 // We silently ignore, do nothing, remove from cache.
1278 return 0;
1279 }
1280
1281 SSL_SESSION *currentSession = q_SSL_get_session(connection);
1282 if (!currentSession) {
1283 qCWarning(lcTlsBackend,
1284 "New session ticket callback, the session is invalid (nullptr)");
1285 return 0;
1286 }
1287
1288 if (q_SSL_version(connection) < 0x304) {
1289 // We only rely on this mechanics with TLS >= 1.3
1290 return 0;
1291 }
1292
1293#ifdef TLS1_3_VERSION
1294 if (!q_SSL_SESSION_is_resumable(currentSession)) {
1295 qCDebug(lcTlsBackend, "New session ticket, but the session is non-resumable");
1296 return 0;
1297 }
1298#endif // TLS1_3_VERSION
1299
1300 const int sessionSize = q_i2d_SSL_SESSION(currentSession, nullptr);
1301 if (sessionSize <= 0) {
1302 qCWarning(lcTlsBackend, "could not store persistent version of SSL session");
1303 return 0;
1304 }
1305
1306 // We have somewhat perverse naming, it's not a ticket, it's a session.
1307 QByteArray sessionTicket(sessionSize, 0);
1308 auto data = reinterpret_cast<unsigned char *>(sessionTicket.data());
1309 if (!q_i2d_SSL_SESSION(currentSession, &data)) {
1310 qCWarning(lcTlsBackend, "could not store persistent version of SSL session");
1311 return 0;
1312 }
1313
1314 QTlsBackend::setSessionAsn1(d, sessionTicket);
1315 QTlsBackend::setSessionLifetimeHint(d, q_SSL_SESSION_get_ticket_lifetime_hint(currentSession));
1316
1317 emit q->newSessionTicketReceived();
1318 return 0;
1319}
1320
1322{
1323 Q_ASSERT(q);
1324 Q_ASSERT(d);
1325
1326 const auto level = tlsAlertLevel(value);
1327 if (level == QSsl::AlertLevel::Fatal && !q->isEncrypted()) {
1328 // Note, this logic is handshake-time only:
1329 pendingFatalAlert = true;
1330 }
1331
1332 emit q->alertSent(level, tlsAlertType(value), tlsAlertDescription(value));
1333
1334}
1335
1337{
1338 Q_ASSERT(q);
1339
1340 emit q->alertReceived(tlsAlertLevel(value), tlsAlertType(value), tlsAlertDescription(value));
1341}
1342
1344{
1345 // Returns 0 to abort verification, 1 to continue despite error (as
1346 // OpenSSL expects from the verification callback).
1347 Q_ASSERT(q);
1348 Q_ASSERT(ctx);
1349
1350 using ScopedBool = QScopedValueRollback<bool>;
1351 // While we are not setting, we are emitting and in general -
1352 // we want to prevent accidental recursive startHandshake()
1353 // calls:
1354 const ScopedBool bg(inSetAndEmitError, true);
1355
1357 if (!x509) {
1358 qCWarning(lcTlsBackend, "Could not obtain the certificate (that failed to verify)");
1359 return 0;
1360 }
1361
1362 const QSslCertificate certificate = QTlsPrivate::X509CertificateOpenSSL::certificateFromX509(x509);
1363 const auto errorAndDepth = QTlsPrivate::X509CertificateOpenSSL::errorEntryFromStoreContext(ctx);
1364 const QSslError tlsError = QTlsPrivate::X509CertificateOpenSSL::openSSLErrorToQSslError(errorAndDepth.code, certificate);
1365
1366 errorsReportedFromCallback = true;
1367 handshakeInterrupted = true;
1368 emit q->handshakeInterruptedOnError(tlsError);
1369
1370 // Conveniently so, we also can access 'lastErrors' external data set
1371 // in startHandshake, we store it for the case an application later
1372 // wants to check errors (ignored or not):
1373 const auto offset = QTlsBackendOpenSSL::s_indexForSSLExtraData
1375 if (auto errorList = static_cast<QList<QSslErrorEntry> *>(q_SSL_get_ex_data(ssl, offset)))
1376 errorList->append(errorAndDepth);
1377
1378 // An application is expected to ignore this error (by calling ignoreSslErrors)
1379 // in its directly connected slot:
1380 return !handshakeInterrupted;
1381}
1382
1384{
1385 Q_ASSERT(pendingFatalAlert);
1386 Q_ASSERT(d);
1387
1388 auto *plainSocket = d->plainTcpSocket();
1389
1390 pendingFatalAlert = false;
1391 QVarLengthArray<char, 4096> data;
1392 int pendingBytes = 0;
1393 while (plainSocket->isValid() && (pendingBytes = q_BIO_pending(writeBio)) > 0
1394 && plainSocket->openMode() != QIODevice::NotOpen) {
1395 // Read encrypted data from the write BIO into a buffer.
1396 data.resize(pendingBytes);
1397 const int bioReadBytes = q_BIO_read(writeBio, data.data(), pendingBytes);
1398
1399 // Write encrypted data from the buffer to the socket.
1400 qint64 actualWritten = plainSocket->write(data.constData(), bioReadBytes);
1401 if (actualWritten < 0)
1402 return;
1403 plainSocket->flush();
1404 }
1405}
1406
1407bool TlsCryptographOpenSSL::initSslContext()
1408{
1409 Q_ASSERT(q);
1410 Q_ASSERT(d);
1411
1412 // If no external context was set (e.g. by QHttpNetworkConnection) we will
1413 // create a new one.
1414 const auto mode = d->tlsMode();
1415 const auto configuration = q->sslConfiguration();
1416 if (!sslContextPointer)
1417 sslContextPointer = QSslContext::sharedFromConfiguration(mode, configuration, d->isRootsOnDemandAllowed());
1418
1419 if (sslContextPointer->error() != QSslError::NoError) {
1420 setErrorAndEmit(d, QAbstractSocket::SslInvalidUserDataError, sslContextPointer->errorString());
1421 sslContextPointer.reset();
1422 return false;
1423 }
1424
1425 // Create and initialize SSL session
1426 if (!(ssl = sslContextPointer->createSsl())) {
1427 setErrorAndEmit(d, QAbstractSocket::SslInternalError,
1428 QSslSocket::tr("Error creating SSL session, %1").arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
1429 return false;
1430 }
1431
1432 if (configuration.protocol() != QSsl::UnknownProtocol && mode == QSslSocket::SslClientMode) {
1433 const auto verificationPeerName = d->verificationName();
1434 // Set server hostname on TLS extension. RFC4366 section 3.1 requires it in ACE format.
1435 QString tlsHostName = verificationPeerName.isEmpty() ? q->peerName() : verificationPeerName;
1436 if (tlsHostName.isEmpty())
1437 tlsHostName = d->tlsHostName();
1438 QByteArray ace = QUrl::toAce(tlsHostName);
1439 // only send the SNI header if the URL is valid and not an IP
1440 if (!ace.isEmpty()
1441 && !QHostAddress().setAddress(tlsHostName)
1442 && !(configuration.testSslOption(QSsl::SslOptionDisableServerNameIndication))) {
1443 // We don't send the trailing dot from the host header if present see
1444 // https://tools.ietf.org/html/rfc6066#section-3
1445 if (ace.endsWith('.'))
1446 ace.chop(1);
1447 if (!q_SSL_ctrl(ssl, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, ace.data()))
1448 qCWarning(lcTlsBackend, "could not set SSL_CTRL_SET_TLSEXT_HOSTNAME, Server Name Indication disabled");
1449 }
1450 }
1451
1452 // Clear the session.
1453 errorList.clear();
1454
1455 // Initialize memory BIOs for encryption and decryption.
1456 readBio = q_BIO_new(q_BIO_s_mem());
1457 writeBio = q_BIO_new(q_BIO_s_mem());
1458 if (!readBio || !writeBio) {
1459 setErrorAndEmit(d, QAbstractSocket::SslInternalError,
1460 QSslSocket::tr("Error creating SSL session: %1").arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
1461 if (readBio)
1462 q_BIO_free(readBio);
1463 if (writeBio)
1464 q_BIO_free(writeBio);
1465 return false;
1466 }
1467
1468 // Assign the bios.
1469 q_SSL_set_bio(ssl, readBio, writeBio);
1470
1471 if (mode == QSslSocket::SslClientMode)
1473 else
1475
1476 q_SSL_set_ex_data(ssl, QTlsBackendOpenSSL::s_indexForSSLExtraData, this);
1477
1478#ifndef OPENSSL_NO_PSK
1479 // Set the client callback for PSK
1480 if (mode == QSslSocket::SslClientMode)
1482 else if (mode == QSslSocket::SslServerMode)
1484
1485#if OPENSSL_VERSION_NUMBER >= 0x10101006L
1486 // Set the client callback for TLSv1.3 PSK
1487 if (mode == QSslSocket::SslClientMode
1488 && QSslSocket::sslLibraryBuildVersionNumber() >= 0x10101006L) {
1489 q_SSL_set_psk_use_session_callback(ssl, &q_ssl_psk_use_session_callback);
1490 }
1491#endif // openssl version >= 0x10101006L
1492
1493#endif // OPENSSL_NO_PSK
1494
1495#if QT_CONFIG(ocsp)
1496 if (configuration.ocspStaplingEnabled()) {
1497 if (mode == QSslSocket::SslServerMode) {
1498 setErrorAndEmit(d, QAbstractSocket::SslInvalidUserDataError,
1499 QSslSocket::tr("Server-side QSslSocket does not support OCSP stapling"));
1500 return false;
1501 }
1502 if (q_SSL_set_tlsext_status_type(ssl, TLSEXT_STATUSTYPE_ocsp) != 1) {
1503 setErrorAndEmit(d, QAbstractSocket::SslInternalError,
1504 QSslSocket::tr("Failed to enable OCSP stapling"));
1505 return false;
1506 }
1507 }
1508
1509 ocspResponseDer.clear();
1510 const auto backendConfig = configuration.backendConfiguration();
1511 auto responsePos = backendConfig.find("Qt-OCSP-response");
1512 if (responsePos != backendConfig.end()) {
1513 // This is our private, undocumented 'API' we use for the auto-testing of
1514 // OCSP-stapling. It must be a der-encoded OCSP response, presumably set
1515 // by tst_QOcsp.
1516 const QVariant data(responsePos.value());
1517 if (data.canConvert<QByteArray>())
1518 ocspResponseDer = data.toByteArray();
1519 }
1520
1521 if (ocspResponseDer.size()) {
1522 if (mode != QSslSocket::SslServerMode) {
1523 setErrorAndEmit(d, QAbstractSocket::SslInvalidUserDataError,
1524 QSslSocket::tr("Client-side sockets do not send OCSP responses"));
1525 return false;
1526 }
1527 }
1528#endif // ocsp
1529
1530 return true;
1531}
1532
1533void TlsCryptographOpenSSL::destroySslContext()
1534{
1535 if (ssl) {
1536 if (!q_SSL_in_init(ssl) && !systemOrSslErrorDetected) {
1537 // We do not send a shutdown alert here. Just mark the session as
1538 // resumable for qhttpnetworkconnection's "optimization", otherwise
1539 // OpenSSL won't start a session resumption.
1540 if (q_SSL_shutdown(ssl) != 1) {
1541 // Some error may be queued, clear it.
1542 const auto errors = QTlsBackendOpenSSL::getErrorsFromOpenSsl();
1543 Q_UNUSED(errors);
1544 }
1545 }
1546 q_SSL_free(ssl);
1547 ssl = nullptr;
1548 }
1549 sslContextPointer.reset();
1550}
1551
1553{
1554 Q_ASSERT(d);
1555
1556 // Store the peer certificate and chain. For clients, the peer certificate
1557 // chain includes the peer certificate; for servers, it doesn't. Both the
1558 // peer certificate and the chain may be empty if the peer didn't present
1559 // any certificate.
1560 X509 *x509 = q_SSL_get_peer_certificate(ssl);
1561
1562 const auto peerCertificate = QTlsPrivate::X509CertificateOpenSSL::certificateFromX509(x509);
1563 QTlsBackend::storePeerCertificate(d, peerCertificate);
1564 q_X509_free(x509);
1565 auto peerCertificateChain = q->peerCertificateChain();
1566 if (peerCertificateChain.isEmpty()) {
1567 peerCertificateChain = QTlsPrivate::X509CertificateOpenSSL::stackOfX509ToQSslCertificates(q_SSL_get_peer_cert_chain(ssl));
1568 if (!peerCertificate.isNull() && d->tlsMode() == QSslSocket::SslServerMode)
1569 peerCertificateChain.prepend(peerCertificate);
1570 QTlsBackend::storePeerCertificateChain(d, peerCertificateChain);
1571 }
1572}
1573
1574#if QT_CONFIG(ocsp)
1575
1577{
1578 Q_ASSERT(ssl);
1579 Q_ASSERT(d);
1580
1581 const auto &configuration = q->sslConfiguration();
1582 Q_ASSERT(d->tlsMode() == QSslSocket::SslClientMode); // See initSslContext() for SslServerMode
1584
1585 const auto clearErrorQueue = qScopeGuard([] {
1587 });
1588
1591 ocspErrors.clear();
1592
1593 const unsigned char *responseData = nullptr;
1595 if (responseLength <= 0 || !responseData) {
1597 return false;
1598 }
1599
1601 if (!response) {
1602 // Treat this as a fatal SslHandshakeError.
1603 ocspErrorDescription = QSslSocket::tr("Failed to decode OCSP response");
1604 return false;
1605 }
1607
1610 // It's not a definitive response, it's an error message (not signed by the responder).
1612 return false;
1613 }
1614
1616 if (!basicResponse) {
1617 // SslHandshakeError.
1618 ocspErrorDescription = QSslSocket::tr("Failed to extract basic OCSP response");
1619 return false;
1620 }
1622
1623 SSL_CTX *ctx = q_SSL_get_SSL_CTX(ssl); // Does not increment refcount.
1624 Q_ASSERT(ctx);
1625 X509_STORE *store = q_SSL_CTX_get_cert_store(ctx); // Does not increment refcount.
1626 if (!store) {
1627 // SslHandshakeError.
1628 ocspErrorDescription = QSslSocket::tr("No certificate verification store, cannot verify OCSP response");
1629 return false;
1630 }
1631
1632 STACK_OF(X509) *peerChain = q_SSL_get_peer_cert_chain(ssl); // Does not increment refcount.
1636 // OCSP_basic_verify with 0 as verificationFlags:
1637 //
1638 // 0) Tries to find the OCSP responder's certificate in either peerChain
1639 // or basicResponse->certs. If not found, verification fails.
1640 // 1) It checks the signature using the responder's public key.
1641 // 2) Then it tries to validate the responder's cert (building a chain
1642 // etc.)
1643 // 3) It checks CertID in response.
1644 // 4) Ensures the responder is authorized to sign the status respond.
1645 //
1646 // Note, OpenSSL prior to 1.0.2b would only use bs->certs to
1647 // verify the responder's chain (see their commit 4ba9a4265bd).
1648 // Working this around - is too much fuss for ancient versions we
1649 // are dropping quite soon anyway.
1650 const unsigned long verificationFlags = 0;
1652 if (success <= 0)
1654
1655 if (q_OCSP_resp_count(basicResponse) != 1) {
1657 return false;
1658 }
1659
1661 if (!singleResponse) {
1662 ocspErrors.clear();
1663 // A fatal problem -> SslHandshakeError.
1664 ocspErrorDescription = QSslSocket::tr("Failed to decode a SingleResponse from OCSP status response");
1665 return false;
1666 }
1667
1668 // Let's make sure the response is for the correct certificate - we
1669 // can re-create this CertID using our peer's certificate and its
1670 // issuer's public key.
1674 bool matchFound = false;
1678 } else {
1680 if (!certs) // Oh, what a cataclysm! Last try:
1682 if (certs) {
1683 // It could be the first certificate in 'certs' is our peer's
1684 // certificate. Since it was not captured by the 'self-signed' branch
1685 // above, the CertID will not match and we'll just iterate on to the
1686 // next certificate. So we start from 0, not 1.
1687 for (int i = 0, e = q_sk_X509_num(certs); i < e; ++i) {
1690 if (matchFound) {
1693 break;
1694 }
1695 matchFound = false;
1696 }
1697 }
1698 }
1699 }
1700
1701 if (!matchFound) {
1704 }
1705
1706 // Check if the response is valid time-wise:
1707 ASN1_GENERALIZEDTIME *revTime = nullptr;
1710 int reason;
1712 if (!thisUpdate) {
1713 // This is unexpected, treat as SslHandshakeError, OCSP_check_validity assumes this pointer
1714 // to be != nullptr.
1715 ocspErrors.clear();
1717 ocspErrorDescription = QSslSocket::tr("Failed to extract 'this update time' from the SingleResponse");
1718 return false;
1719 }
1720
1721 // OCSP_check_validity(this, next, nsec, maxsec) does this check:
1722 // this <= now <= next. They allow some freedom to account
1723 // for delays/time inaccuracy.
1724 // this > now + nsec ? -> NOT_YET_VALID
1725 // if maxsec >= 0:
1726 // now - maxsec > this ? -> TOO_OLD
1727 // now - nsec > next ? -> EXPIRED
1728 // next < this ? -> NEXT_BEFORE_THIS
1729 // OK.
1732
1733 // And finally, the status:
1734 switch (certStatus) {
1736 // This certificate was not found among the revoked ones.
1738 break;
1743 break;
1747 }
1748
1749 return !ocspErrors.size();
1750}
1751
1752#endif // QT_CONFIG(ocsp)
1753
1754
1755unsigned TlsCryptographOpenSSL::pskClientTlsCallback(const char *hint, char *identity,
1756 unsigned max_identity_len,
1757 unsigned char *psk, unsigned max_psk_len)
1758{
1759 Q_ASSERT(q);
1760
1761 QSslPreSharedKeyAuthenticator authenticator;
1762 // Fill in some read-only fields (for the user)
1763 const int hintLength = hint ? int(std::strlen(hint)) : 0;
1764 QTlsBackend::setupClientPskAuth(&authenticator, hint, hintLength, max_identity_len, max_psk_len);
1765 // Let the client provide the remaining bits...
1766 emit q->preSharedKeyAuthenticationRequired(&authenticator);
1767
1768 // No PSK set? Return now to make the handshake fail
1769 if (authenticator.preSharedKey().isEmpty())
1770 return 0;
1771
1772 // Copy data back into OpenSSL
1773 const int identityLength = qMin(authenticator.identity().size(), authenticator.maximumIdentityLength());
1774 std::memcpy(identity, authenticator.identity().constData(), identityLength);
1775 identity[identityLength] = 0;
1776
1777 const int pskLength = qMin(authenticator.preSharedKey().size(), authenticator.maximumPreSharedKeyLength());
1778 std::memcpy(psk, authenticator.preSharedKey().constData(), pskLength);
1779 return pskLength;
1780}
1781
1782unsigned TlsCryptographOpenSSL::pskServerTlsCallback(const char *identity, unsigned char *psk,
1783 unsigned max_psk_len)
1784{
1785 Q_ASSERT(q);
1786
1787 QSslPreSharedKeyAuthenticator authenticator;
1788
1789 // Fill in some read-only fields (for the user)
1790 QTlsBackend::setupServerPskAuth(&authenticator, identity, q->sslConfiguration().preSharedKeyIdentityHint(),
1791 max_psk_len);
1792 emit q->preSharedKeyAuthenticationRequired(&authenticator);
1793
1794 // No PSK set? Return now to make the handshake fail
1795 if (authenticator.preSharedKey().isEmpty())
1796 return 0;
1797
1798 // Copy data back into OpenSSL
1799 const int pskLength = qMin(authenticator.preSharedKey().size(), authenticator.maximumPreSharedKeyLength());
1800 std::memcpy(psk, authenticator.preSharedKey().constData(), pskLength);
1801 return pskLength;
1802}
1803
1805{
1806 return inSslRead;
1807}
1808
1810{
1811 this->renegotiated = renegotiated;
1812}
1813
1814#ifdef Q_OS_WIN
1815
1817{
1818 Q_ASSERT(d);
1819 Q_ASSERT(q);
1820
1821 //The root certificate is downloaded from windows update, which blocks for 15 seconds in the worst case
1822 //so the request is done in a worker thread.
1826
1827 //Remember we are fetching and what we are fetching:
1828 caToFetch = cert;
1829
1831 q->peerVerifyName());
1836 d->setPaused(true);
1837}
1838
1840{
1841 if (caToFetch != cert) {
1842 //Ooops, something from the previous connection attempt, ignore!
1843 return;
1844 }
1845
1846 Q_ASSERT(d);
1847 Q_ASSERT(q);
1848
1849 //Done, fetched already:
1850 caToFetch.reset();
1851
1856 }
1857
1860 //Add the new root cert to default cert list for use by future sockets
1864 }
1865 //Add the new root cert to this socket for future connections
1867 //Remove the broken chain ssl errors (as chain is verified by windows)
1868 for (int i=sslErrors.count() - 1; i >= 0; --i) {
1869 if (sslErrors.at(i).certificate() == cert) {
1870 switch (sslErrors.at(i).error()) {
1875 // error can be ignored if OS says the chain is trusted
1877 break;
1878 default:
1879 // error cannot be ignored
1880 break;
1881 }
1882 }
1883 }
1884 }
1885
1886 auto *plainSocket = d->plainTcpSocket();
1888 // Continue with remaining errors
1889 if (plainSocket)
1891 d->setPaused(false);
1892 if (checkSslErrors() && ssl) {
1895 if (!willClose)
1896 transmit();
1897 }
1898}
1899
1900#endif // Q_OS_WIN
1901
1902} // namespace QTlsPrivate
1903
1904QT_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)