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