Juan Lang : crypt32: Implement CertGetCRLFromStore.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Jun 22 06:17:07 CDT 2006


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

Author: Juan Lang <juan_lang at yahoo.com>
Date:   Wed Jun 21 20:50:11 2006 -0700

crypt32: Implement CertGetCRLFromStore.

- implement CertGetCRLFromStore, with tests
- update tests for CRL revocation functions to show name isn't checked

---

 dlls/crypt32/crl.c        |   42 +++++++++++++++++++++-
 dlls/crypt32/crypt32.spec |    2 +
 dlls/crypt32/tests/crl.c  |   86 +++++++++++++++++++++++++++++++++++++++++++++
 include/wincrypt.h        |    3 ++
 4 files changed, 131 insertions(+), 2 deletions(-)

diff --git a/dlls/crypt32/crl.c b/dlls/crypt32/crl.c
index 283b742..bd0136a 100644
--- a/dlls/crypt32/crl.c
+++ b/dlls/crypt32/crl.c
@@ -184,6 +184,47 @@ PCCRL_CONTEXT WINAPI CertFindCRLInStore(
     return ret;
 }
 
+PCCRL_CONTEXT WINAPI CertGetCRLFromStore(HCERTSTORE hCertStore,
+ PCCERT_CONTEXT pIssuerContext, PCCRL_CONTEXT pPrevCrlContext, DWORD *pdwFlags)
+{
+    static const DWORD supportedFlags = CERT_STORE_SIGNATURE_FLAG |
+     CERT_STORE_TIME_VALIDITY_FLAG | CERT_STORE_BASE_CRL_FLAG |
+     CERT_STORE_DELTA_CRL_FLAG;
+    PCCRL_CONTEXT ret;
+
+    TRACE("(%p, %p, %p, %08lx)\n", hCertStore, pIssuerContext, pPrevCrlContext,
+     *pdwFlags);
+
+    if (*pdwFlags & ~supportedFlags)
+    {
+        SetLastError(E_INVALIDARG);
+        return NULL;
+    }
+    if (pIssuerContext)
+        ret = CertFindCRLInStore(hCertStore, pIssuerContext->dwCertEncodingType,
+         0, CRL_FIND_ISSUED_BY, pIssuerContext, pPrevCrlContext);
+    else
+        ret = CertFindCRLInStore(hCertStore, 0, 0, CRL_FIND_ANY, NULL,
+         pPrevCrlContext);
+    if (ret)
+    {
+        if (*pdwFlags & CERT_STORE_TIME_VALIDITY_FLAG)
+        {
+            if (0 == CertVerifyCRLTimeValidity(NULL, ret->pCrlInfo))
+                *pdwFlags &= ~CERT_STORE_TIME_VALIDITY_FLAG;
+        }
+        if (*pdwFlags & CERT_STORE_SIGNATURE_FLAG)
+        {
+            if (CryptVerifyCertificateSignatureEx(0, ret->dwCertEncodingType,
+             CRYPT_VERIFY_CERT_SIGN_SUBJECT_CRL, (void *)ret,
+             CRYPT_VERIFY_CERT_SIGN_ISSUER_CERT, (void *)pIssuerContext, 0,
+             NULL))
+                *pdwFlags &= ~CERT_STORE_SIGNATURE_FLAG;
+        }
+    }
+    return ret;
+}
+
 PCCRL_CONTEXT WINAPI CertDuplicateCRLContext(PCCRL_CONTEXT pCrlContext)
 {
     TRACE("(%p)\n", pCrlContext);
@@ -437,7 +478,6 @@ static PCRL_ENTRY CRYPT_FindCertificateI
     DWORD i;
     PCRL_ENTRY entry = NULL;
 
-    /* FIXME: do I need to compare the issuers of the cert and CRL? */
     for (i = 0; !entry && i < crl->cCRLEntry; i++)
         if (CertCompareIntegerBlob(&crl->rgCRLEntry[i].SerialNumber,
          &cert->SerialNumber))
diff --git a/dlls/crypt32/crypt32.spec b/dlls/crypt32/crypt32.spec
index 9d33c2b..120061b 100644
--- a/dlls/crypt32/crypt32.spec
+++ b/dlls/crypt32/crypt32.spec
@@ -48,7 +48,7 @@
 @ stub CertFreeCertificateChainEngine
 @ stdcall CertFreeCertificateContext(ptr)
 @ stdcall CertGetCRLContextProperty(ptr long ptr ptr)
-@ stub CertGetCRLFromStore
+@ stdcall CertGetCRLFromStore(ptr ptr ptr ptr)
 @ stdcall CertGetCTLContextProperty(ptr long ptr ptr)
 @ stub CertGetCertificateChain
 @ stdcall CertGetCertificateContextProperty(ptr long ptr ptr)
diff --git a/dlls/crypt32/tests/crl.c b/dlls/crypt32/tests/crl.c
index 5d02e88..5d0ddc6 100644
--- a/dlls/crypt32/tests/crl.c
+++ b/dlls/crypt32/tests/crl.c
@@ -249,6 +249,67 @@ static void testFindCRL(void)
     CertCloseStore(store, 0);
 }
 
+static void testGetCRLFromStore(void)
+{
+    HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
+     CERT_STORE_CREATE_NEW_FLAG, NULL);
+    PCCRL_CONTEXT context;
+    PCCERT_CONTEXT cert;
+    DWORD flags;
+    BOOL ret;
+
+    if (!store) return;
+
+    /* Crash
+    context = CertGetCRLFromStore(NULL, NULL, NULL, NULL);
+    context = CertGetCRLFromStore(store, NULL, NULL, NULL);
+     */
+
+    /* Bogus flags */
+    flags = 0xffffffff;
+    context = CertGetCRLFromStore(store, NULL, NULL, &flags);
+    ok(!context && GetLastError() == E_INVALIDARG,
+     "Expected E_INVALIDARG, got %08lx\n", GetLastError());
+
+    /* Test an empty store */
+    flags = 0;
+    context = CertGetCRLFromStore(store, NULL, NULL, &flags);
+    ok(context == NULL && GetLastError() == CRYPT_E_NOT_FOUND,
+     "Expected CRYPT_E_NOT_FOUND, got %08lx\n", GetLastError());
+
+    ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
+     sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
+    ok(ret, "CertAddEncodedCRLToStore failed: %08lx\n", GetLastError());
+
+    /* NULL matches any CRL */
+    flags = 0;
+    context = CertGetCRLFromStore(store, NULL, NULL, &flags);
+    ok(context != NULL, "Expected a context\n");
+    CertFreeCRLContext(context);
+
+    /* This cert's issuer isn't in */
+    cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
+     sizeof(bigCert2));
+    ok(cert != NULL, "CertCreateCertificateContext failed: %08lx\n",
+     GetLastError());
+    context = CertGetCRLFromStore(store, cert, NULL, &flags);
+    ok(context == NULL && GetLastError() == CRYPT_E_NOT_FOUND,
+     "Expected CRYPT_E_NOT_FOUND, got %08lx\n", GetLastError());
+    CertFreeCertificateContext(cert);
+
+    /* But this one is */
+    cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
+     sizeof(bigCert));
+    ok(cert != NULL, "CertCreateCertificateContext failed: %08lx\n",
+     GetLastError());
+    context = CertGetCRLFromStore(store, cert, NULL, &flags);
+    ok(context != NULL, "Expected a context\n");
+    CertFreeCRLContext(context);
+    CertFreeCertificateContext(cert);
+
+    CertCloseStore(store, 0);
+}
+
 static void checkCRLHash(const BYTE *data, DWORD dataLen, ALG_ID algID,
  PCCRL_CONTEXT context, DWORD propID)
 {
@@ -513,6 +574,13 @@ static void testIsValidCRLForCert(void)
     CertFreeCertificateContext(cert1);
 }
 
+static const BYTE crlWithDifferentIssuer[] = {
+ 0x30,0x47,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
+ 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x41,0x6c,0x65,0x78,0x20,0x4c,0x61,0x6e,
+ 0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
+ 0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,
+ 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a };
+
 static void testFindCertInCRL(void)
 {
     BOOL ret;
@@ -549,6 +617,14 @@ static void testFindCertInCRL(void)
     ok(entry != NULL, "Expected to find an entry in CRL\n");
     CertFreeCRLContext(crl);
 
+    /* Entry found even though CRL issuer doesn't match cert issuer */
+    crl = CertCreateCRLContext(X509_ASN_ENCODING, crlWithDifferentIssuer,
+     sizeof(crlWithDifferentIssuer));
+    ret = CertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
+    ok(ret, "CertFindCertificateInCRL failed: %08lx\n", GetLastError());
+    ok(entry != NULL, "Expected to find an entry in CRL\n");
+    CertFreeCRLContext(crl);
+
     CertFreeCertificateContext(cert);
 }
 
@@ -583,6 +659,15 @@ static void testVerifyCRLRevocation(void
     ok(!ret, "CertVerifyCRLRevocation should have been revoked\n");
     CertFreeCRLContext(crl);
 
+    /* Check against CRL with different issuer and entry for the cert */
+    crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
+     sizeof(v1CRLWithIssuerAndEntry));
+    ok(crl != NULL, "CertCreateCRLContext failed: %08lx\n", GetLastError());
+    ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 1,
+     (PCRL_INFO *)&crl->pCrlInfo);
+    ok(!ret, "CertVerifyCRLRevocation should have been revoked\n");
+    CertFreeCRLContext(crl);
+
     /* Check against CRL without entry for the cert */
     crl = CertCreateCRLContext(X509_ASN_ENCODING, verisignCRL,
      sizeof(verisignCRL));
@@ -602,6 +687,7 @@ START_TEST(crl)
     testCreateCRL();
     testAddCRL();
     testFindCRL();
+    testGetCRLFromStore();
 
     testCRLProperties();
 
diff --git a/include/wincrypt.h b/include/wincrypt.h
index 66b0e57..9a16154 100644
--- a/include/wincrypt.h
+++ b/include/wincrypt.h
@@ -2881,6 +2881,9 @@ PCCERT_CONTEXT WINAPI CertGetIssuerCerti
 PCCERT_CONTEXT WINAPI CertGetSubjectCertificateFromStore(HCERTSTORE hCertStore,
  DWORD dwCertEncodingType, PCERT_INFO pCertId);
 
+PCCRL_CONTEXT WINAPI CertGetCRLFromStore(HCERTSTORE hCertStore,
+ PCCERT_CONTEXT pIssuerContext, PCCRL_CONTEXT pPrevCrlContext, DWORD *pdwFlags);
+
 BOOL WINAPI CertSerializeCertificateStoreElement(PCCERT_CONTEXT pCertContext,
  DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement);
 




More information about the wine-cvs mailing list