[PATCH] crypt32: Correctly return how the issuer of a self signed certificate was matched.
Nikolay Sivov
nsivov at codeweavers.com
Mon Jun 25 06:12:12 CDT 2018
Original patch by Michael Müller.
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/crypt32/chain.c | 53 +++++++++++++++-------------------
dlls/crypt32/crypt32_private.h | 2 +-
2 files changed, 24 insertions(+), 31 deletions(-)
diff --git a/dlls/crypt32/chain.c b/dlls/crypt32/chain.c
index 6e8076c66c..d7015d797d 100644
--- a/dlls/crypt32/chain.c
+++ b/dlls/crypt32/chain.c
@@ -265,10 +265,10 @@ typedef struct _CertificateChain
LONG ref;
} CertificateChain;
-BOOL CRYPT_IsCertificateSelfSigned(PCCERT_CONTEXT cert)
+DWORD CRYPT_IsCertificateSelfSigned(const CERT_CONTEXT *cert)
{
+ DWORD size, status = 0;
PCERT_EXTENSION ext;
- DWORD size;
BOOL ret;
if ((ext = CertFindExtension(szOID_AUTHORITY_KEY_IDENTIFIER2,
@@ -296,10 +296,9 @@ BOOL CRYPT_IsCertificateSelfSigned(PCCERT_CONTEXT cert)
&info->AuthorityCertIssuer.rgAltEntry[i];
if (directoryName)
{
- ret = CertCompareCertificateName(cert->dwCertEncodingType,
- &directoryName->u.DirectoryName, &cert->pCertInfo->Issuer)
- && CertCompareIntegerBlob(&info->AuthorityCertSerialNumber,
- &cert->pCertInfo->SerialNumber);
+ if (CertCompareCertificateName(cert->dwCertEncodingType, &directoryName->u.DirectoryName, &cert->pCertInfo->Issuer)
+ && CertCompareIntegerBlob(&info->AuthorityCertSerialNumber, &cert->pCertInfo->SerialNumber))
+ status = CERT_TRUST_HAS_NAME_MATCH_ISSUER;
}
else
{
@@ -317,16 +316,12 @@ BOOL CRYPT_IsCertificateSelfSigned(PCCERT_CONTEXT cert)
if (buf)
{
- CertGetCertificateContextProperty(cert,
- CERT_KEY_IDENTIFIER_PROP_ID, buf, &size);
- ret = !memcmp(buf, info->KeyId.pbData, size);
+ CertGetCertificateContextProperty(cert, CERT_KEY_IDENTIFIER_PROP_ID, buf, &size);
+ if (!memcmp(buf, info->KeyId.pbData, size))
+ status = CERT_TRUST_HAS_KEY_MATCH_ISSUER;
CryptMemFree(buf);
}
- else
- ret = FALSE;
}
- else
- ret = FALSE;
}
LocalFree(info);
}
@@ -344,10 +339,9 @@ BOOL CRYPT_IsCertificateSelfSigned(PCCERT_CONTEXT cert)
{
if (info->CertIssuer.cbData && info->CertSerialNumber.cbData)
{
- ret = CertCompareCertificateName(cert->dwCertEncodingType,
- &info->CertIssuer, &cert->pCertInfo->Issuer) &&
- CertCompareIntegerBlob(&info->CertSerialNumber,
- &cert->pCertInfo->SerialNumber);
+ if (CertCompareCertificateName(cert->dwCertEncodingType, &info->CertIssuer, &cert->pCertInfo->Issuer)
+ && CertCompareIntegerBlob(&info->CertSerialNumber, &cert->pCertInfo->SerialNumber))
+ status = CERT_TRUST_HAS_NAME_MATCH_ISSUER;
}
else if (info->KeyId.cbData)
{
@@ -361,24 +355,23 @@ BOOL CRYPT_IsCertificateSelfSigned(PCCERT_CONTEXT cert)
{
CertGetCertificateContextProperty(cert,
CERT_KEY_IDENTIFIER_PROP_ID, buf, &size);
- ret = !memcmp(buf, info->KeyId.pbData, size);
+ if (!memcmp(buf, info->KeyId.pbData, size))
+ status = CERT_TRUST_HAS_KEY_MATCH_ISSUER;
CryptMemFree(buf);
}
- else
- ret = FALSE;
}
- else
- ret = FALSE;
}
- else
- ret = FALSE;
LocalFree(info);
}
}
else
- ret = CertCompareCertificateName(cert->dwCertEncodingType,
- &cert->pCertInfo->Subject, &cert->pCertInfo->Issuer);
- return ret;
+ if (CertCompareCertificateName(cert->dwCertEncodingType, &cert->pCertInfo->Subject, &cert->pCertInfo->Issuer))
+ status = CERT_TRUST_HAS_NAME_MATCH_ISSUER;
+
+ if (status)
+ status |= CERT_TRUST_IS_SELF_SIGNED;
+
+ return status;
}
static void CRYPT_FreeChainElement(PCERT_CHAIN_ELEMENT element)
@@ -1890,6 +1883,7 @@ static void CRYPT_CheckSimpleChain(CertificateChainEngine *engine,
int i;
BOOL pathLengthConstraintViolated = FALSE;
CERT_BASIC_CONSTRAINTS2_INFO constraints = { FALSE, FALSE, 0 };
+ DWORD status;
TRACE_(chain)("checking chain with %d elements for time %s\n",
chain->cElement, filetime_to_str(time));
@@ -1977,10 +1971,9 @@ static void CRYPT_CheckSimpleChain(CertificateChainEngine *engine,
}
CRYPT_CheckChainNameConstraints(chain);
CRYPT_CheckChainPolicies(chain);
- if (CRYPT_IsCertificateSelfSigned(rootElement->pCertContext))
+ if ((status = CRYPT_IsCertificateSelfSigned(rootElement->pCertContext)))
{
- rootElement->TrustStatus.dwInfoStatus |=
- CERT_TRUST_IS_SELF_SIGNED | CERT_TRUST_HAS_NAME_MATCH_ISSUER;
+ rootElement->TrustStatus.dwInfoStatus |= status;
CRYPT_CheckRootCert(engine->hRoot, rootElement);
}
CRYPT_CombineTrustStatus(&chain->TrustStatus, &rootElement->TrustStatus);
diff --git a/dlls/crypt32/crypt32_private.h b/dlls/crypt32/crypt32_private.h
index dbf6dca411..95ee67c6cb 100644
--- a/dlls/crypt32/crypt32_private.h
+++ b/dlls/crypt32/crypt32_private.h
@@ -343,7 +343,7 @@ void CRYPT_ImportSystemRootCertsToReg(void) DECLSPEC_HIDDEN;
BOOL CRYPT_SerializeContextsToReg(HKEY key, DWORD flags, const WINE_CONTEXT_INTERFACE *contextInterface,
HCERTSTORE memStore) DECLSPEC_HIDDEN;
-BOOL CRYPT_IsCertificateSelfSigned(PCCERT_CONTEXT cert) DECLSPEC_HIDDEN;
+DWORD CRYPT_IsCertificateSelfSigned(const CERT_CONTEXT *cert) DECLSPEC_HIDDEN;
/* Allocates and initializes a certificate chain engine, but without creating
* the root store. Instead, it uses root, and assumes the caller has done any
--
2.18.0
More information about the wine-devel
mailing list