mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-05 18:01:34 +00:00
crypt32: Check CA certificates for the enhanced key usage extension.
This commit is contained in:
parent
60770fb011
commit
07b735682b
1 changed files with 59 additions and 0 deletions
|
@ -1173,6 +1173,58 @@ static BOOL CRYPT_KeyUsageValid(PCertificateChainEngine engine,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_ExtendedKeyUsageValidForCA(PCCERT_CONTEXT cert)
|
||||
{
|
||||
PCERT_EXTENSION ext;
|
||||
BOOL ret;
|
||||
|
||||
/* RFC 5280, section 4.2.1.12: "In general, this extension will only
|
||||
* appear in end entity certificates." And, "If a certificate contains
|
||||
* both a key usage extension and an extended key usage extension, then
|
||||
* both extensions MUST be processed independently and the certificate MUST
|
||||
* only be used for a purpose consistent with both extensions." This seems
|
||||
* to imply that it should be checked if present, and ignored if not.
|
||||
* Unfortunately some CAs, e.g. the Thawte SGC CA, don't include the code
|
||||
* signing extended key usage, whereas they do include the keyCertSign
|
||||
* key usage. Thus, when checking for a CA, we only require the
|
||||
* code signing extended key usage if the extended key usage is critical.
|
||||
*/
|
||||
ext = CertFindExtension(szOID_ENHANCED_KEY_USAGE,
|
||||
cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension);
|
||||
if (ext && ext->fCritical)
|
||||
{
|
||||
CERT_ENHKEY_USAGE *usage;
|
||||
DWORD size;
|
||||
|
||||
ret = CryptDecodeObjectEx(cert->dwCertEncodingType,
|
||||
X509_ENHANCED_KEY_USAGE, ext->Value.pbData, ext->Value.cbData,
|
||||
CRYPT_DECODE_ALLOC_FLAG, NULL, &usage, &size);
|
||||
if (ret)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
/* Explicitly require the code signing extended key usage for a CA
|
||||
* with an extended key usage extension. That is, don't assume
|
||||
* a cert is allowed to be a CA if it specifies the
|
||||
* anyExtendedKeyUsage usage oid. See again RFC 5280, section
|
||||
* 4.2.1.12: "Applications that require the presence of a
|
||||
* particular purpose MAY reject certificates that include the
|
||||
* anyExtendedKeyUsage OID but not the particular OID expected for
|
||||
* the application."
|
||||
*/
|
||||
ret = FALSE;
|
||||
for (i = 0; !ret && i < usage->cUsageIdentifier; i++)
|
||||
if (!strcmp(usage->rgpszUsageIdentifier[i],
|
||||
szOID_PKIX_KP_CODE_SIGNING))
|
||||
ret = TRUE;
|
||||
LocalFree(usage);
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_CriticalExtensionsSupported(PCCERT_CONTEXT cert)
|
||||
{
|
||||
BOOL ret = TRUE;
|
||||
|
@ -1196,6 +1248,8 @@ static BOOL CRYPT_CriticalExtensionsSupported(PCCERT_CONTEXT cert)
|
|||
ret = TRUE;
|
||||
else if (!strcmp(oid, szOID_SUBJECT_ALT_NAME2))
|
||||
ret = TRUE;
|
||||
else if (!strcmp(oid, szOID_ENHANCED_KEY_USAGE))
|
||||
ret = TRUE;
|
||||
else
|
||||
{
|
||||
FIXME("unsupported critical extension %s\n",
|
||||
|
@ -1265,6 +1319,11 @@ static void CRYPT_CheckSimpleChain(PCertificateChainEngine engine,
|
|||
constraints.fCA, i))
|
||||
chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
|
||||
CERT_TRUST_IS_NOT_VALID_FOR_USAGE;
|
||||
if (i != 0)
|
||||
if (!CRYPT_ExtendedKeyUsageValidForCA(
|
||||
chain->rgpElement[i]->pCertContext))
|
||||
chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
|
||||
CERT_TRUST_IS_NOT_VALID_FOR_USAGE;
|
||||
if (CRYPT_IsSimpleChainCyclic(chain))
|
||||
{
|
||||
/* If the chain is cyclic, then the path length constraints
|
||||
|
|
Loading…
Reference in a new issue