Juan Lang : crypt32: Permit lack of key usage extension on root certificates.

Alexandre Julliard julliard at winehq.org
Mon Nov 9 15:14:13 CST 2009


Module: wine
Branch: master
Commit: d94e4d315a573db454eb4ec3761242ff8b3c24e2
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d94e4d315a573db454eb4ec3761242ff8b3c24e2

Author: Juan Lang <juan.lang at gmail.com>
Date:   Thu Nov  5 13:12:07 2009 -0800

crypt32: Permit lack of key usage extension on root certificates.

This reverts 60770fb011b0a60d7862e7fe9c7a6d24d68ac0ad, although it
updates the comments to give a reason.  Thanks to Matt Van Gundy for
pointing it out to me.

---

 dlls/crypt32/chain.c |   29 ++++++++++++++++++++---------
 1 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/dlls/crypt32/chain.c b/dlls/crypt32/chain.c
index c4ecfa4..c9ca356 100644
--- a/dlls/crypt32/chain.c
+++ b/dlls/crypt32/chain.c
@@ -1083,7 +1083,7 @@ static void dump_element(PCCERT_CONTEXT cert)
 }
 
 static BOOL CRYPT_KeyUsageValid(PCertificateChainEngine engine,
- PCCERT_CONTEXT cert, BOOL isCA, DWORD index)
+ PCCERT_CONTEXT cert, BOOL isRoot, BOOL isCA, DWORD index)
 {
     PCERT_EXTENSION ext;
     BOOL ret;
@@ -1132,20 +1132,24 @@ static BOOL CRYPT_KeyUsageValid(PCertificateChainEngine engine,
              * perhaps this is prudent.  On the other hand, MS also accepts V3
              * certs without key usage extensions.  We are more restrictive:
              * we accept locally installed V1 or V2 certs as CA certs.
+             * We also accept a lack of key usage extension on root certs,
+             * which is implied in RFC 5280, section 6.1:  the trust anchor's
+             * only requirement is that it was used to issue the next
+             * certificate in the chain.
              */
-            ret = FALSE;
-            if (cert->pCertInfo->dwVersion == CERT_V1 ||
+            if (isRoot)
+                ret = TRUE;
+            else if (cert->pCertInfo->dwVersion == CERT_V1 ||
              cert->pCertInfo->dwVersion == CERT_V2)
             {
                 PCCERT_CONTEXT localCert = CRYPT_FindCertInStore(
                  engine->hWorld, cert);
 
-                if (localCert)
-                {
-                    CertFreeCertificateContext(localCert);
-                    ret = TRUE;
-                }
+                ret = localCert != NULL;
+                CertFreeCertificateContext(localCert);
             }
+            else
+                ret = FALSE;
             if (!ret)
                 WARN_(chain)("no key usage extension on a CA cert\n");
         }
@@ -1273,8 +1277,15 @@ static void CRYPT_CheckSimpleChain(PCertificateChainEngine engine,
      chain->cElement, debugstr_w(filetime_to_str(time)));
     for (i = chain->cElement - 1; i >= 0; i--)
     {
+        BOOL isRoot;
+
         if (TRACE_ON(chain))
             dump_element(chain->rgpElement[i]->pCertContext);
+        if (i == chain->cElement - 1)
+            isRoot = CRYPT_IsCertificateSelfSigned(
+             chain->rgpElement[i]->pCertContext);
+        else
+            isRoot = FALSE;
         if (CertVerifyTimeValidity(time,
          chain->rgpElement[i]->pCertContext->pCertInfo) != 0)
             chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
@@ -1316,7 +1327,7 @@ static void CRYPT_CheckSimpleChain(PCertificateChainEngine engine,
                  CERT_TRUST_INVALID_BASIC_CONSTRAINTS;
         }
         if (!CRYPT_KeyUsageValid(engine, chain->rgpElement[i]->pCertContext,
-         constraints.fCA, i))
+         isRoot, constraints.fCA, i))
             chain->rgpElement[i]->TrustStatus.dwErrorStatus |=
              CERT_TRUST_IS_NOT_VALID_FOR_USAGE;
         if (i != 0)




More information about the wine-cvs mailing list