crypt32: Don't assume intermediate certificates are allowed to be CAs.
This commit is contained in:
parent
ad2ea9d9cf
commit
913affe4ef
|
@ -412,8 +412,12 @@ static BOOL CRYPT_DecodeBasicConstraints(PCCERT_CONTEXT cert,
|
|||
}
|
||||
|
||||
/* Checks element's basic constraints to see if it can act as a CA, with
|
||||
* remainingCAs CAs left in this chain. Updates chainConstraints with the
|
||||
* element's constraints, if:
|
||||
* remainingCAs CAs left in this chain. A root certificate is assumed to be
|
||||
* allowed to be a CA whether or not the basic constraints extension is present,
|
||||
* whereas an intermediate CA cert is not. This matches the expected usage in
|
||||
* RFC 3280: a conforming intermediate CA MUST contain the basic constraints
|
||||
* extension. It also appears to match Microsoft's implementation.
|
||||
* Updates chainConstraints with the element's constraints, if:
|
||||
* 1. chainConstraints doesn't have a path length constraint, or
|
||||
* 2. element's path length constraint is smaller than chainConstraints's
|
||||
* Sets *pathLengthConstraintViolated to TRUE if a path length violation
|
||||
|
@ -423,13 +427,13 @@ static BOOL CRYPT_DecodeBasicConstraints(PCCERT_CONTEXT cert,
|
|||
*/
|
||||
static BOOL CRYPT_CheckBasicConstraintsForCA(PCCERT_CONTEXT cert,
|
||||
CERT_BASIC_CONSTRAINTS2_INFO *chainConstraints, DWORD remainingCAs,
|
||||
BOOL *pathLengthConstraintViolated)
|
||||
BOOL isRoot, BOOL *pathLengthConstraintViolated)
|
||||
{
|
||||
BOOL validBasicConstraints;
|
||||
CERT_BASIC_CONSTRAINTS2_INFO constraints;
|
||||
|
||||
if ((validBasicConstraints = CRYPT_DecodeBasicConstraints(cert,
|
||||
&constraints, TRUE)))
|
||||
&constraints, isRoot)))
|
||||
{
|
||||
if (!constraints.fCA)
|
||||
{
|
||||
|
@ -825,6 +829,13 @@ static void CRYPT_CheckSimpleChain(PCertificateChainEngine engine,
|
|||
CERT_TRUST_IS_NOT_TIME_VALID;
|
||||
if (i != 0)
|
||||
{
|
||||
BOOL isRoot;
|
||||
|
||||
if (i == chain->cElement - 1)
|
||||
isRoot = CRYPT_IsCertificateSelfSigned(
|
||||
chain->rgpElement[i]->pCertContext);
|
||||
else
|
||||
isRoot = FALSE;
|
||||
/* Check the signature of the cert this issued */
|
||||
if (!CryptVerifyCertificateSignatureEx(0, X509_ASN_ENCODING,
|
||||
CRYPT_VERIFY_CERT_SIGN_SUBJECT_CERT,
|
||||
|
@ -841,7 +852,7 @@ static void CRYPT_CheckSimpleChain(PCertificateChainEngine engine,
|
|||
CERT_TRUST_INVALID_BASIC_CONSTRAINTS;
|
||||
else if (!CRYPT_CheckBasicConstraintsForCA(
|
||||
chain->rgpElement[i]->pCertContext, &constraints, i - 1,
|
||||
&pathLengthConstraintViolated))
|
||||
isRoot, &pathLengthConstraintViolated))
|
||||
chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
|
||||
CERT_TRUST_INVALID_BASIC_CONSTRAINTS;
|
||||
else if (constraints.fPathLenConstraint &&
|
||||
|
|
|
@ -1566,8 +1566,7 @@ static ChainCheck chainCheck[] = {
|
|||
CERT_TRUST_HAS_PREFERRED_ISSUER },
|
||||
{ CERT_TRUST_INVALID_BASIC_CONSTRAINTS | CERT_TRUST_IS_UNTRUSTED_ROOT |
|
||||
CERT_TRUST_IS_NOT_TIME_VALID, 0 },
|
||||
1, simpleStatus8 },
|
||||
TODO_ERROR },
|
||||
1, simpleStatus8 }, 0 },
|
||||
/* Earlier versions of Windows incorrectly don't set
|
||||
* CERT_TRUST_INVALID_BASIC_CONSTRAINTS on this chain.
|
||||
*/
|
||||
|
@ -1795,8 +1794,7 @@ static const ChainPolicyCheck basicConstraintsPolicyCheck[] = {
|
|||
{ { sizeof(chain7) / sizeof(chain7[0]), chain7 },
|
||||
{ 0, 0, -1, -1, NULL }, 0 },
|
||||
{ { sizeof(chain8) / sizeof(chain8[0]), chain8 },
|
||||
{ 0, TRUST_E_BASIC_CONSTRAINTS, 0, 1, NULL },
|
||||
TODO_ERROR | TODO_CHAINS | TODO_ELEMENTS },
|
||||
{ 0, TRUST_E_BASIC_CONSTRAINTS, 0, 1, NULL }, 0 },
|
||||
{ { sizeof(chain9) / sizeof(chain9[0]), chain9 },
|
||||
{ 0, TRUST_E_BASIC_CONSTRAINTS, 0, 1, NULL }, 0 },
|
||||
{ { sizeof(chain10) / sizeof(chain10[0]), chain10 },
|
||||
|
|
Loading…
Reference in New Issue