Juan Lang : wininet: Differentiate checking online and offline CRLs.

Alexandre Julliard julliard at winehq.org
Mon Mar 14 14:29:33 CDT 2011


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

Author: Juan Lang <juan.lang at gmail.com>
Date:   Fri Mar 11 16:26:02 2011 -0800

wininet: Differentiate checking online and offline CRLs.

---

 dlls/cryptnet/cryptnet_main.c  |   71 +++++++++++++++++++++++++++++----------
 dlls/cryptnet/tests/cryptnet.c |    5 ---
 2 files changed, 53 insertions(+), 23 deletions(-)

diff --git a/dlls/cryptnet/cryptnet_main.c b/dlls/cryptnet/cryptnet_main.c
index 3b9a044..97d0ad8 100644
--- a/dlls/cryptnet/cryptnet_main.c
+++ b/dlls/cryptnet/cryptnet_main.c
@@ -1557,29 +1557,25 @@ BOOL WINAPI CryptRetrieveObjectByUrlW(LPCWSTR pszURL, LPCSTR pszObjectOid,
     return ret;
 }
 
-static DWORD verify_cert_revocation_with_crl(PCCERT_CONTEXT cert,
+static DWORD verify_cert_revocation_with_crl_online(PCCERT_CONTEXT cert,
  PCCRL_CONTEXT crl, DWORD index, FILETIME *pTime,
  PCERT_REVOCATION_STATUS pRevStatus)
 {
     DWORD error;
+    PCRL_ENTRY entry = NULL;
 
-    if (CertVerifyCRLTimeValidity(pTime, crl->pCrlInfo))
+    CertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
+    if (entry)
     {
-        /* The CRL isn't time valid */
-        error = CRYPT_E_NO_REVOCATION_CHECK;
+        error = CRYPT_E_REVOKED;
+        pRevStatus->dwIndex = index;
     }
     else
     {
-        PCRL_ENTRY entry = NULL;
-
-        CertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
-        if (entry)
-        {
-            error = CRYPT_E_REVOKED;
-            pRevStatus->dwIndex = index;
-        }
-        else
-            error = ERROR_SUCCESS;
+        /* Since the CRL was retrieved for the cert being checked, then it's
+         * guaranteed to be fresh, and the cert is not revoked.
+         */
+        error = ERROR_SUCCESS;
     }
     return error;
 }
@@ -1625,8 +1621,8 @@ static DWORD verify_cert_revocation_from_dist_points_ext(
                  NULL, NULL, NULL, NULL);
                 if (ret)
                 {
-                    error = verify_cert_revocation_with_crl(cert, crl, index,
-                     pTime, pRevStatus);
+                    error = verify_cert_revocation_with_crl_online(cert, crl,
+                     index, pTime, pRevStatus);
                     if (!error && timeout)
                     {
                         DWORD time = GetTickCount();
@@ -1696,6 +1692,45 @@ static DWORD verify_cert_revocation_from_aia_ext(
     return error;
 }
 
+static DWORD verify_cert_revocation_with_crl_offline(PCCERT_CONTEXT cert,
+ PCCRL_CONTEXT crl, DWORD index, FILETIME *pTime,
+ PCERT_REVOCATION_STATUS pRevStatus)
+{
+    DWORD error;
+    LONG valid;
+
+    valid = CompareFileTime(pTime, &crl->pCrlInfo->ThisUpdate);
+    if (valid <= 0)
+    {
+        /* If this CRL is not older than the time being verified, there's no
+         * way to know whether the certificate was revoked.
+         */
+        TRACE("CRL not old enough\n");
+        error = CRYPT_E_REVOCATION_OFFLINE;
+    }
+    else
+    {
+        PCRL_ENTRY entry = NULL;
+
+        CertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
+        if (entry)
+        {
+            error = CRYPT_E_REVOKED;
+            pRevStatus->dwIndex = index;
+        }
+        else
+        {
+            /* Since the CRL was not retrieved for the cert being checked,
+             * there's no guarantee it's fresh, so the cert *might* be okay,
+             * but it's safer not to guess.
+             */
+            TRACE("certificate not found\n");
+            error = CRYPT_E_REVOCATION_OFFLINE;
+        }
+    }
+    return error;
+}
+
 static DWORD verify_cert_revocation(PCCERT_CONTEXT cert, DWORD index,
  FILETIME *pTime, DWORD dwFlags, PCERT_REVOCATION_PARA pRevPara,
  PCERT_REVOCATION_STATUS pRevStatus)
@@ -1761,8 +1796,8 @@ static DWORD verify_cert_revocation(PCCERT_CONTEXT cert, DWORD index,
             }
             if (crl)
             {
-                error = verify_cert_revocation_with_crl(cert, crl, index,
-                 pTime, pRevStatus);
+                error = verify_cert_revocation_with_crl_offline(cert, crl,
+                 index, pTime, pRevStatus);
                 CertFreeCRLContext(crl);
             }
             else
diff --git a/dlls/cryptnet/tests/cryptnet.c b/dlls/cryptnet/tests/cryptnet.c
index 9ed9204..1be327e 100644
--- a/dlls/cryptnet/tests/cryptnet.c
+++ b/dlls/cryptnet/tests/cryptnet.c
@@ -733,7 +733,6 @@ static void test_verifyRevocation(void)
     SetLastError(0xdeadbeef);
     ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE,
      1, (void **)&certs[1], 0, &revPara, &status);
-    todo_wine
     ok(!ret && (GetLastError() == CRYPT_E_REVOKED ||
      broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)),
      "expected CRYPT_E_REVOKED, got %08x\n", GetLastError());
@@ -748,7 +747,6 @@ static void test_verifyRevocation(void)
     SetLastError(0xdeadbeef);
     ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE,
      1, (void **)&certs[1], 0, &revPara, &status);
-    todo_wine
     ok(!ret && (GetLastError() == CRYPT_E_REVOCATION_OFFLINE ||
      broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)),
      "expected CRYPT_E_REVOCATION_OFFLINE, got %08x\n", GetLastError());
@@ -764,7 +762,6 @@ static void test_verifyRevocation(void)
     SetLastError(0xdeadbeef);
     ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE,
      1, (void **)&certs[1], 0, &revPara, &status);
-    todo_wine
     ok(!ret && (GetLastError() == CRYPT_E_REVOCATION_OFFLINE ||
      broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)),
      "expected CRYPT_E_REVOCATION_OFFLINE, got %08x\n", GetLastError());
@@ -772,7 +769,6 @@ static void test_verifyRevocation(void)
     SetLastError(0xdeadbeef);
     ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE,
      1, (void **)&certs[1], 0, &revPara, &status);
-    todo_wine
     ok(!ret && (GetLastError() == CRYPT_E_REVOCATION_OFFLINE ||
      broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)),
      "expected CRYPT_E_REVOCATION_OFFLINE, got %08x\n", GetLastError());
@@ -780,7 +776,6 @@ static void test_verifyRevocation(void)
     SetLastError(0xdeadbeef);
     ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE,
      1, (void **)&certs[1], 0, &revPara, &status);
-    todo_wine
     ok(!ret && (GetLastError() == CRYPT_E_REVOCATION_OFFLINE ||
      broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)),
      "expected CRYPT_E_REVOCATION_OFFLINE, got %08x\n", GetLastError());




More information about the wine-cvs mailing list