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