Juan Lang : crypt32: Don' t assume intermediate certificates are allowed to be CAs.
Alexandre Julliard
julliard at winehq.org
Thu Feb 12 11:14:43 CST 2009
Module: wine
Branch: master
Commit: 913affe4efa990a9e3e40b5a5b168d5da7667f66
URL: http://source.winehq.org/git/wine.git/?a=commit;h=913affe4efa990a9e3e40b5a5b168d5da7667f66
Author: Juan Lang <juan.lang at 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 },
More information about the wine-cvs
mailing list