crypt32: Check whether each signing certificate can be a CA.

This commit is contained in:
Juan Lang 2007-08-30 17:59:13 -07:00 committed by Alexandre Julliard
parent 51948b0c98
commit 1ce46d5e4a
2 changed files with 55 additions and 1 deletions
dlls/crypt32

View File

@ -358,6 +358,51 @@ static BOOL CRYPT_CheckRootCert(HCERTCHAINENGINE hRoot,
return ret; return ret;
} }
static BOOL CRYPT_CanCertBeCA(PCCERT_CONTEXT cert, BOOL defaultIfNotSpecified)
{
BOOL ret;
PCERT_EXTENSION ext = CertFindExtension(szOID_BASIC_CONSTRAINTS,
cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension);
if (ext)
{
CERT_BASIC_CONSTRAINTS_INFO *info;
DWORD size = 0;
ret = CryptDecodeObjectEx(X509_ASN_ENCODING, szOID_BASIC_CONSTRAINTS,
ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_ALLOC_FLAG,
NULL, (LPBYTE)&info, &size);
if (ret)
{
if (info->SubjectType.cbData == 1)
ret = info->SubjectType.pbData[0] & CERT_CA_SUBJECT_FLAG;
LocalFree(info);
}
}
else
{
ext = CertFindExtension(szOID_BASIC_CONSTRAINTS2,
cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension);
if (ext)
{
CERT_BASIC_CONSTRAINTS2_INFO *info;
DWORD size = 0;
ret = CryptDecodeObjectEx(X509_ASN_ENCODING,
szOID_BASIC_CONSTRAINTS2, ext->Value.pbData, ext->Value.cbData,
CRYPT_DECODE_ALLOC_FLAG, NULL, (LPBYTE)&info, &size);
if (ret)
{
ret = info->fCA;
LocalFree(info);
}
}
else
ret = defaultIfNotSpecified;
}
return ret;
}
static BOOL CRYPT_CheckSimpleChain(PCertificateChainEngine engine, static BOOL CRYPT_CheckSimpleChain(PCertificateChainEngine engine,
PCERT_SIMPLE_CHAIN chain, LPFILETIME time) PCERT_SIMPLE_CHAIN chain, LPFILETIME time)
{ {
@ -371,6 +416,15 @@ static BOOL CRYPT_CheckSimpleChain(PCertificateChainEngine engine,
chain->rgpElement[i]->pCertContext->pCertInfo) != 0) chain->rgpElement[i]->pCertContext->pCertInfo) != 0)
chain->rgpElement[i]->TrustStatus.dwErrorStatus |= chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
CERT_TRUST_IS_NOT_TIME_VALID; CERT_TRUST_IS_NOT_TIME_VALID;
if (i != 0)
{
BOOL ca;
ca = CRYPT_CanCertBeCA(chain->rgpElement[i]->pCertContext, TRUE);
if (!ca)
chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
CERT_TRUST_INVALID_BASIC_CONSTRAINTS;
}
/* FIXME: check valid usages and name constraints */ /* FIXME: check valid usages and name constraints */
CRYPT_CombineTrustStatus(&chain->TrustStatus, CRYPT_CombineTrustStatus(&chain->TrustStatus,
&chain->rgpElement[i]->TrustStatus); &chain->rgpElement[i]->TrustStatus);

View File

@ -1502,7 +1502,7 @@ static ChainCheck chainCheck[] = {
{ CERT_TRUST_INVALID_BASIC_CONSTRAINTS | CERT_TRUST_IS_UNTRUSTED_ROOT | { CERT_TRUST_INVALID_BASIC_CONSTRAINTS | CERT_TRUST_IS_UNTRUSTED_ROOT |
CERT_TRUST_IS_NOT_TIME_VALID, 0 }, CERT_TRUST_IS_NOT_TIME_VALID, 0 },
1, simpleStatus3 }, 1, simpleStatus3 },
TODO_ERROR | TODO_INFO }, TODO_INFO },
{ { sizeof(chain4) / sizeof(chain4[0]), chain4 }, { { sizeof(chain4) / sizeof(chain4[0]), chain4 },
{ { 0, CERT_TRUST_HAS_PREFERRED_ISSUER }, { { 0, CERT_TRUST_HAS_PREFERRED_ISSUER },
{ CERT_TRUST_INVALID_BASIC_CONSTRAINTS | CERT_TRUST_IS_UNTRUSTED_ROOT | { CERT_TRUST_INVALID_BASIC_CONSTRAINTS | CERT_TRUST_IS_UNTRUSTED_ROOT |