Juan Lang : crypt32: Implement CertVerifyCRLTimeValidity and partially implement CertVerifySubjectCertificateContext .

Alexandre Julliard julliard at wine.codeweavers.com
Fri May 26 13:55:31 CDT 2006


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

Author: Juan Lang <juan_lang at yahoo.com>
Date:   Fri May 26 09:48:13 2006 -0700

crypt32: Implement CertVerifyCRLTimeValidity and partially implement CertVerifySubjectCertificateContext.

---

 dlls/crypt32/cert.c       |   66 ++++++++++++++++++++++++++++++--------------
 dlls/crypt32/crl.c        |   23 +++++++++++++++
 dlls/crypt32/crypt32.spec |    4 +--
 dlls/crypt32/tests/cert.c |   68 +++++++++++++++++++++++++++++++++++++++++++++
 include/wincrypt.h        |    5 +++
 5 files changed, 143 insertions(+), 23 deletions(-)

diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c
index f529668..f4c7a42 100644
--- a/dlls/crypt32/cert.c
+++ b/dlls/crypt32/cert.c
@@ -195,8 +195,7 @@ static BOOL WINAPI CertContext_GetProper
     TRACE("(%p, %ld, %p, %p)\n", context, dwPropId, pvData, pcbData);
 
     if (properties)
-        ret = ContextPropertyList_FindProperty(properties, dwPropId,
-         &blob);
+        ret = ContextPropertyList_FindProperty(properties, dwPropId, &blob);
     else
         ret = FALSE;
     if (ret)
@@ -737,44 +736,69 @@ PCCERT_CONTEXT WINAPI CertGetSubjectCert
      CERT_FIND_SUBJECT_CERT, pCertId, NULL);
 }
 
+BOOL WINAPI CertVerifySubjectCertificateContext(PCCERT_CONTEXT pSubject,
+ PCCERT_CONTEXT pIssuer, DWORD *pdwFlags)
+{
+    static const DWORD supportedFlags = CERT_STORE_REVOCATION_FLAG |
+     CERT_STORE_SIGNATURE_FLAG | CERT_STORE_TIME_VALIDITY_FLAG;
+
+    if (*pdwFlags & ~supportedFlags)
+    {
+        SetLastError(E_INVALIDARG);
+        return FALSE;
+    }
+    if (*pdwFlags & CERT_STORE_REVOCATION_FLAG)
+    {
+        PCCRL_CONTEXT crl = CertFindCRLInStore(pSubject->hCertStore,
+         pSubject->dwCertEncodingType, 0, CRL_FIND_ISSUED_BY, pSubject, NULL);
+
+        if (crl)
+        {
+            FIXME("check CRL for subject\n");
+        }
+        else
+            *pdwFlags |= CERT_STORE_NO_CRL_FLAG;
+    }
+    if (*pdwFlags & CERT_STORE_TIME_VALIDITY_FLAG)
+    {
+        if (0 == CertVerifyTimeValidity(NULL, pSubject->pCertInfo))
+            *pdwFlags &= ~CERT_STORE_TIME_VALIDITY_FLAG;
+    }
+    if (*pdwFlags & CERT_STORE_SIGNATURE_FLAG)
+    {
+        if (CryptVerifyCertificateSignatureEx(0, pSubject->dwCertEncodingType,
+         CRYPT_VERIFY_CERT_SIGN_SUBJECT_CERT, (void *)pSubject,
+         CRYPT_VERIFY_CERT_SIGN_ISSUER_CERT, (void *)pIssuer, 0, NULL))
+            *pdwFlags &= ~CERT_STORE_SIGNATURE_FLAG;
+    }
+    return TRUE;
+}
+
 PCCERT_CONTEXT WINAPI CertGetIssuerCertificateFromStore(HCERTSTORE hCertStore,
  PCCERT_CONTEXT pSubjectContext, PCCERT_CONTEXT pPrevIssuerContext,
  DWORD *pdwFlags)
 {
-    static const DWORD supportedFlags = CERT_STORE_REVOCATION_FLAG |
-     CERT_STORE_SIGNATURE_FLAG | CERT_STORE_TIME_VALIDITY_FLAG;
     PCCERT_CONTEXT ret;
 
     TRACE("(%p, %p, %p, %08lx)\n", hCertStore, pSubjectContext,
      pPrevIssuerContext, *pdwFlags);
 
-    if (*pdwFlags & ~supportedFlags)
+    if (!pSubjectContext)
     {
         SetLastError(E_INVALIDARG);
         return NULL;
     }
+
     ret = CertFindCertificateInStore(hCertStore,
      pSubjectContext->dwCertEncodingType, 0, CERT_FIND_ISSUER_OF,
      pSubjectContext, pPrevIssuerContext);
     if (ret)
     {
-        if (*pdwFlags & CERT_STORE_REVOCATION_FLAG)
-        {
-            FIXME("revocation check requires CRL support\n");
-            *pdwFlags |= CERT_STORE_NO_CRL_FLAG;
-        }
-        if (*pdwFlags & CERT_STORE_TIME_VALIDITY_FLAG)
-        {
-            if (0 == CertVerifyTimeValidity(NULL, pSubjectContext->pCertInfo))
-                *pdwFlags &= ~CERT_STORE_TIME_VALIDITY_FLAG;
-        }
-        if (*pdwFlags & CERT_STORE_SIGNATURE_FLAG)
+        if (!CertVerifySubjectCertificateContext(pSubjectContext, ret,
+         pdwFlags))
         {
-            if (CryptVerifyCertificateSignatureEx(0,
-             pSubjectContext->dwCertEncodingType,
-             CRYPT_VERIFY_CERT_SIGN_SUBJECT_CERT, (void *)pSubjectContext,
-             CRYPT_VERIFY_CERT_SIGN_ISSUER_CERT, (void *)ret, 0, NULL))
-                *pdwFlags &= ~CERT_STORE_SIGNATURE_FLAG;
+            CertFreeCertificateContext(ret);
+            ret = NULL;
         }
     }
 
diff --git a/dlls/crypt32/crl.c b/dlls/crypt32/crl.c
index 3c60578..dd2918c 100644
--- a/dlls/crypt32/crl.c
+++ b/dlls/crypt32/crl.c
@@ -443,3 +443,26 @@ BOOL WINAPI CertSetCRLContextProperty(PC
     TRACE("returning %d\n", ret);
     return ret;
 }
+
+LONG WINAPI CertVerifyCRLTimeValidity(LPFILETIME pTimeToVerify,
+ PCRL_INFO pCrlInfo)
+{
+    FILETIME fileTime;
+    LONG ret;
+
+    if (!pTimeToVerify)
+    {
+        SYSTEMTIME sysTime;
+
+        GetSystemTime(&sysTime);
+        SystemTimeToFileTime(&sysTime, &fileTime);
+        pTimeToVerify = &fileTime;
+    }
+    if ((ret = CompareFileTime(pTimeToVerify, &pCrlInfo->ThisUpdate)) >= 0)
+    {
+        ret = CompareFileTime(pTimeToVerify, &pCrlInfo->NextUpdate);
+        if (ret < 0)
+            ret = 0;
+    }
+    return ret;
+}
diff --git a/dlls/crypt32/crypt32.spec b/dlls/crypt32/crypt32.spec
index 8900bec..a525c65 100644
--- a/dlls/crypt32/crypt32.spec
+++ b/dlls/crypt32/crypt32.spec
@@ -81,10 +81,10 @@
 @ stub CertStrToNameA
 @ stub CertStrToNameW
 @ stub CertVerifyCRLRevocation
-@ stub CertVerifyCRLTimeValidity
+@ stdcall CertVerifyCRLTimeValidity(ptr ptr)
 @ stub CertVerifyCTLUsage
 @ stub CertVerifyRevocation
-@ stub CertVerifySubjectCertificateContext
+@ stdcall CertVerifySubjectCertificateContext(ptr ptr ptr)
 @ stdcall CertVerifyTimeValidity(ptr ptr)
 @ stub CertVerifyValidityNesting
 @ stub CreateFileU
diff --git a/dlls/crypt32/tests/cert.c b/dlls/crypt32/tests/cert.c
index 656fb94..776d117 100644
--- a/dlls/crypt32/tests/cert.c
+++ b/dlls/crypt32/tests/cert.c
@@ -836,6 +836,73 @@ void testCompareCert(void)
     ok(!ret, "Expected certs not to be equal\n");
 }
 
+static const BYTE bigCertWithDifferentSubject[] = { 0x30, 0x7a, 0x02, 0x01, 0x02,
+ 0x30, 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67,
+ 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
+ 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15,
+ 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c,
+ 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06,
+ 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55,
+ 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02,
+ 0x01, 0x01 };
+
+static void testVerifySubjectCert(void)
+{
+    BOOL ret;
+    DWORD flags;
+    PCCERT_CONTEXT context1, context2;
+
+    /* Crashes
+    ret = CertVerifySubjectCertificateContext(NULL, NULL, NULL);
+     */
+    flags = 0;
+    ret = CertVerifySubjectCertificateContext(NULL, NULL, &flags);
+    ok(ret, "CertVerifySubjectCertificateContext failed; %08lx\n",
+     GetLastError());
+    flags = CERT_STORE_NO_CRL_FLAG;
+    ret = CertVerifySubjectCertificateContext(NULL, NULL, &flags);
+    ok(!ret && GetLastError() == E_INVALIDARG,
+     "Expected E_INVALIDARG, got %08lx\n", GetLastError());
+
+    flags = 0;
+    context1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
+     sizeof(bigCert));
+    ret = CertVerifySubjectCertificateContext(NULL, context1, &flags);
+    ok(ret, "CertVerifySubjectCertificateContext failed; %08lx\n",
+     GetLastError());
+    ret = CertVerifySubjectCertificateContext(context1, NULL, &flags);
+    ok(ret, "CertVerifySubjectCertificateContext failed; %08lx\n",
+     GetLastError());
+    ret = CertVerifySubjectCertificateContext(context1, context1, &flags);
+    ok(ret, "CertVerifySubjectCertificateContext failed; %08lx\n",
+     GetLastError());
+
+    context2 = CertCreateCertificateContext(X509_ASN_ENCODING,
+     bigCertWithDifferentSubject, sizeof(bigCertWithDifferentSubject));
+    SetLastError(0xdeadbeef);
+    ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
+    ok(ret, "CertVerifySubjectCertificateContext failed; %08lx\n",
+     GetLastError());
+    flags = CERT_STORE_REVOCATION_FLAG;
+    ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
+    ok(ret, "CertVerifySubjectCertificateContext failed; %08lx\n",
+     GetLastError());
+    ok(flags == (CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG),
+     "Expected CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG, got %08lx\n",
+     flags);
+    flags = CERT_STORE_SIGNATURE_FLAG;
+    ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
+    ok(ret, "CertVerifySubjectCertificateContext failed; %08lx\n",
+     GetLastError());
+    ok(flags == CERT_STORE_SIGNATURE_FLAG,
+     "Expected CERT_STORE_SIGNATURE_FLAG, got %08lx\n", flags);
+    CertFreeCertificateContext(context2);
+
+    CertFreeCertificateContext(context1);
+}
+
 START_TEST(cert)
 {
     init_function_pointers();
@@ -847,4 +914,5 @@ START_TEST(cert)
     testCompareIntegerBlob();
     testComparePublicKeyInfo();
     testCompareCert();
+    testVerifySubjectCert();
 }
diff --git a/include/wincrypt.h b/include/wincrypt.h
index a5f4269..771ec99 100644
--- a/include/wincrypt.h
+++ b/include/wincrypt.h
@@ -2840,6 +2840,11 @@ PCERT_EXTENSION WINAPI CertFindExtension
  CERT_EXTENSION rgExtensions[]);
 PCERT_RDN_ATTR WINAPI CertFindRDNAttr(LPCSTR pszObjId, PCERT_NAME_INFO pName);
 
+BOOL WINAPI CertVerifySubjectCertificateContext(PCCERT_CONTEXT pSubject,
+ PCCERT_CONTEXT pIssuer, DWORD *pdwFlags);
+
+LONG WINAPI CertVerifyCRLTimeValidity(LPFILETIME pTimeToVerify,
+ PCRL_INFO pCrlInfo);
 LONG WINAPI CertVerifyTimeValidity(LPFILETIME pTimeToVerify,
  PCERT_INFO pCertInfo);
 




More information about the wine-cvs mailing list