Juan Lang : crypt32: Check whether each signing certificate can be a
CA.
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Aug 31 14:01:21 CDT 2007
Module: wine
Branch: master
Commit: 1ce46d5e4a38b9be67b442747ab6952a0bf44a88
URL: http://source.winehq.org/git/wine.git/?a=commit;h=1ce46d5e4a38b9be67b442747ab6952a0bf44a88
Author: Juan Lang <juan.lang at gmail.com>
Date: Thu Aug 30 17:59:13 2007 -0700
crypt32: Check whether each signing certificate can be a CA.
---
dlls/crypt32/chain.c | 54 ++++++++++++++++++++++++++++++++++++++++++++
dlls/crypt32/tests/chain.c | 2 +-
2 files changed, 55 insertions(+), 1 deletions(-)
diff --git a/dlls/crypt32/chain.c b/dlls/crypt32/chain.c
index 4372a8d..5a2b8ef 100644
--- a/dlls/crypt32/chain.c
+++ b/dlls/crypt32/chain.c
@@ -358,6 +358,51 @@ static BOOL CRYPT_CheckRootCert(HCERTCHAINENGINE hRoot,
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,
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]->TrustStatus.dwErrorStatus |=
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 */
CRYPT_CombineTrustStatus(&chain->TrustStatus,
&chain->rgpElement[i]->TrustStatus);
diff --git a/dlls/crypt32/tests/chain.c b/dlls/crypt32/tests/chain.c
index 507ab24..a7e1928 100644
--- a/dlls/crypt32/tests/chain.c
+++ b/dlls/crypt32/tests/chain.c
@@ -1502,7 +1502,7 @@ static ChainCheck chainCheck[] = {
{ CERT_TRUST_INVALID_BASIC_CONSTRAINTS | CERT_TRUST_IS_UNTRUSTED_ROOT |
CERT_TRUST_IS_NOT_TIME_VALID, 0 },
1, simpleStatus3 },
- TODO_ERROR | TODO_INFO },
+ TODO_INFO },
{ { sizeof(chain4) / sizeof(chain4[0]), chain4 },
{ { 0, CERT_TRUST_HAS_PREFERRED_ISSUER },
{ CERT_TRUST_INVALID_BASIC_CONSTRAINTS | CERT_TRUST_IS_UNTRUSTED_ROOT |
More information about the wine-cvs
mailing list