Schannel: fix verifying intermediate certificates with netscape ext
We were always checking 'client' or 'server' usage depending on our own type, which breaks for any intermediate certificate with the 'ca' usage set. We assume that any non-leaf certificate should be a CA (if anything), and leaf certificates must be for client or server usage. Pick-to: 6.9 6.8 6.5 Fixes: QTBUG-137041 Change-Id: I268f3bad669df77351fc458f56e318db75ecac7b Reviewed-by: Mate Barany <mate.barany@qt.io> (cherry picked from commit 9ed754e754a8769c6d3a7291dbfe45f38a7dd20a) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
e9a941053f
commit
1256098113
@ -806,7 +806,7 @@ QT_WARNING_POP
|
||||
\internal
|
||||
Used by verifyCertContext to check if a client cert is used by a server or vice versa.
|
||||
*/
|
||||
bool netscapeWrongCertType(const QList<QSslCertificateExtension> &extensions, bool isClient)
|
||||
bool netscapeWrongCertType(const QList<QSslCertificateExtension> &extensions, bool isClient, bool isLeaf)
|
||||
{
|
||||
const auto netscapeIt = std::find_if(
|
||||
extensions.cbegin(), extensions.cend(),
|
||||
@ -820,8 +820,13 @@ bool netscapeWrongCertType(const QList<QSslCertificateExtension> &extensions, bo
|
||||
dataStream >> netscapeCertType;
|
||||
if (dataStream.status() != QDataStream::Status::Ok)
|
||||
return true;
|
||||
const int expectedPeerCertType = isClient ? NETSCAPE_SSL_SERVER_AUTH_CERT_TYPE
|
||||
: NETSCAPE_SSL_CLIENT_AUTH_CERT_TYPE;
|
||||
const int expectedPeerCertType = [&]() {
|
||||
if (isLeaf) {
|
||||
return isClient ? NETSCAPE_SSL_SERVER_AUTH_CERT_TYPE
|
||||
: NETSCAPE_SSL_CLIENT_AUTH_CERT_TYPE;
|
||||
}
|
||||
return NETSCAPE_SSL_CA_CERT_TYPE;
|
||||
}();
|
||||
if ((netscapeCertType & expectedPeerCertType) == 0)
|
||||
return true;
|
||||
}
|
||||
@ -2549,7 +2554,7 @@ bool TlsCryptographSchannel::verifyCertContext(CERT_CONTEXT *certContext)
|
||||
// While netscape shouldn't be relevant now it defined an extension which is
|
||||
// still in use. Schannel does not check this automatically, so we do it here.
|
||||
// It is used to differentiate between client and server certificates.
|
||||
if (netscapeWrongCertType(extensions, isClient))
|
||||
if (netscapeWrongCertType(extensions, isClient, i == 0))
|
||||
element->TrustStatus.dwErrorStatus |= CERT_TRUST_IS_NOT_VALID_FOR_USAGE;
|
||||
|
||||
if (element->TrustStatus.dwErrorStatus & CERT_TRUST_IS_NOT_VALID_FOR_USAGE) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user