Module: wine Branch: master Commit: 913affe4efa990a9e3e40b5a5b168d5da7667f66 URL: http://source.winehq.org/git/wine.git/?a=commit;h=913affe4efa990a9e3e40b5a5b...
Author: Juan Lang juan.lang@gmail.com Date: Wed Feb 11 10:07:33 2009 -0800
crypt32: Don't assume intermediate certificates are allowed to be CAs.
---
dlls/crypt32/chain.c | 21 ++++++++++++++++----- dlls/crypt32/tests/chain.c | 6 ++---- 2 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/dlls/crypt32/chain.c b/dlls/crypt32/chain.c index 64aba77..30b1422 100644 --- a/dlls/crypt32/chain.c +++ b/dlls/crypt32/chain.c @@ -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 && diff --git a/dlls/crypt32/tests/chain.c b/dlls/crypt32/tests/chain.c index 0b5263b..6197841 100644 --- a/dlls/crypt32/tests/chain.c +++ b/dlls/crypt32/tests/chain.c @@ -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 },