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 6.6
Task-number: QTBUG-118569
Change-Id: I76ce07fc38bf82ef5c93097d839724ddee1edeef
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
bb10
Tim Jenssen 2023-10-30 20:31:52 +01:00 committed by Mårten Nordheim
parent ed7912dbe0
commit 91fe6fb2e1
2 changed files with 14 additions and 4 deletions

View File

@ -2422,6 +2422,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<QSslCertificateExtension> extensions = certificate.extensions();
#ifdef QSSLSOCKET_DEBUG

View File

@ -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<X509CertificateSchannel>(certificate);
Q_ASSERT(certBackend);
certBackend->certificateContext = CertDuplicateCertificateContext(certificateContext);
if (!certificate.isNull()) {
auto *certBackend = QTlsBackend::backend<X509CertificateSchannel>(certificate);
Q_ASSERT(certBackend);
certBackend->certificateContext = CertDuplicateCertificateContext(certificateContext);
}
return certificate;
}