crypt32: Check whether each signing certificate can be a CA.
This commit is contained in:
parent
51948b0c98
commit
1ce46d5e4a
|
@ -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);
|
||||||
|
|
|
@ -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 |
|
||||||
|
|
Loading…
Reference in New Issue