From ebb80cbb08d8d417dbe0df334460f4f81401094a Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Mon, 30 Oct 2023 20:31:52 +0100 Subject: [PATCH] Schannel: Avoid crashing for unparsed certificate Crash reports imply the `certBackend` we extract in QSslCertificate_from_CERT_CONTEXT is null, which means that something went wrong when parsing the certificate data we get from the certificate chain. We assume the rest is okay since it must be inside the bounds of the length of the chain. It's not clear why the certificate would be invalid, but it's better to avoid the crash for now. Pick-to: 6.5 Task-number: QTBUG-118569 Change-Id: I76ce07fc38bf82ef5c93097d839724ddee1edeef Reviewed-by: Tim Jenssen Reviewed-by: Edward Welbourne (cherry picked from commit 91fe6fb2e14f295c0020eb5e7f33444dfddbd7dd) Reviewed-by: Qt Cherry-pick Bot --- src/plugins/tls/schannel/qtls_schannel.cpp | 9 +++++++++ src/plugins/tls/schannel/qx509_schannel.cpp | 9 +++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/plugins/tls/schannel/qtls_schannel.cpp b/src/plugins/tls/schannel/qtls_schannel.cpp index 1c0ce128eed..aae770b2007 100644 --- a/src/plugins/tls/schannel/qtls_schannel.cpp +++ b/src/plugins/tls/schannel/qtls_schannel.cpp @@ -2098,6 +2098,15 @@ bool TlsCryptographSchannel::verifyCertContext(CERT_CONTEXT *certContext) for (DWORD i = 0; i < verifyDepth; i++) { CERT_CHAIN_ELEMENT *element = chain->rgpElement[i]; QSslCertificate certificate = getCertificateFromChainElement(element); + if (certificate.isNull()) { + const auto &previousCert = !peerCertificateChain.isEmpty() ? peerCertificateChain.last() + : QSslCertificate(); + auto error = QSslError(QSslError::SslError::UnableToGetIssuerCertificate, previousCert); + sslErrors += error; + emit q->peerVerifyError(error); + if (previousCert.isNull() || q->state() != QAbstractSocket::ConnectedState) + return false; + } const QList extensions = certificate.extensions(); #ifdef QSSLSOCKET_DEBUG diff --git a/src/plugins/tls/schannel/qx509_schannel.cpp b/src/plugins/tls/schannel/qx509_schannel.cpp index 46be873a7d4..d9d82dce29f 100644 --- a/src/plugins/tls/schannel/qx509_schannel.cpp +++ b/src/plugins/tls/schannel/qx509_schannel.cpp @@ -41,10 +41,11 @@ QSslCertificate X509CertificateSchannel::QSslCertificate_from_CERT_CONTEXT(const QByteArray derData = QByteArray((const char *)certificateContext->pbCertEncoded, certificateContext->cbCertEncoded); QSslCertificate certificate(derData, QSsl::Der); - - auto *certBackend = QTlsBackend::backend(certificate); - Q_ASSERT(certBackend); - certBackend->certificateContext = CertDuplicateCertificateContext(certificateContext); + if (!certificate.isNull()) { + auto *certBackend = QTlsBackend::backend(certificate); + Q_ASSERT(certBackend); + certBackend->certificateContext = CertDuplicateCertificateContext(certificateContext); + } return certificate; }