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.10 6.9 6.8 6.5 Fixes: QTBUG-137041 Change-Id: I268f3bad669df77351fc458f56e318db75ecac7b Reviewed-by: Mate Barany <mate.barany@qt.io>
This commit is contained in:
parent
33dc247b6a
commit
9ed754e754
@ -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