Jacek Caban : crypt32: Added support for retrieving issuers from URL cache.

Alexandre Julliard julliard at winehq.org
Fri Sep 6 12:39:51 CDT 2013


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Sep  6 13:08:59 2013 +0200

crypt32: Added support for retrieving issuers from URL cache.

---

 dlls/crypt32/Makefile.in   |    1 +
 dlls/crypt32/chain.c       |   48 +++++++++++++++++++++++++++++++++++++++++++-
 dlls/crypt32/tests/chain.c |    2 +
 3 files changed, 50 insertions(+), 1 deletions(-)

diff --git a/dlls/crypt32/Makefile.in b/dlls/crypt32/Makefile.in
index 9c85a47..f84ecf4 100644
--- a/dlls/crypt32/Makefile.in
+++ b/dlls/crypt32/Makefile.in
@@ -2,6 +2,7 @@ EXTRADEFS = -D_CRYPT32_
 MODULE    = crypt32.dll
 IMPORTLIB = crypt32
 IMPORTS   = user32 advapi32
+DELAYIMPORTS = cryptnet
 EXTRALIBS = @SECURITYLIB@
 
 C_SRCS = \
diff --git a/dlls/crypt32/chain.c b/dlls/crypt32/chain.c
index 4a8933b..bbd0aca 100644
--- a/dlls/crypt32/chain.c
+++ b/dlls/crypt32/chain.c
@@ -1974,7 +1974,10 @@ static void CRYPT_CheckSimpleChain(CertificateChainEngine *engine,
 static PCCERT_CONTEXT CRYPT_FindIssuer(const CertificateChainEngine *engine, const CERT_CONTEXT *cert,
         HCERTSTORE store, DWORD type, void *para, PCCERT_CONTEXT prev_issuer)
 {
+    CRYPT_URL_ARRAY *urls;
     PCCERT_CONTEXT issuer;
+    DWORD size;
+    BOOL res;
 
     issuer = CertFindCertificateInStore(store, cert->dwCertEncodingType, 0, type, para, prev_issuer);
     if(issuer) {
@@ -1996,7 +1999,50 @@ static PCCERT_CONTEXT CRYPT_FindIssuer(const CertificateChainEngine *engine, con
         }
     }
 
-    return NULL;
+    res = CryptGetObjectUrl(URL_OID_CERTIFICATE_ISSUER, (void*)cert, 0, NULL, &size, NULL, NULL, NULL);
+    if(!res)
+        return NULL;
+
+    urls = HeapAlloc(GetProcessHeap(), 0, size);
+    if(!urls)
+        return NULL;
+
+    res = CryptGetObjectUrl(URL_OID_CERTIFICATE_ISSUER, (void*)cert, 0, urls, &size, NULL, NULL, NULL);
+    if(res)
+    {
+        CERT_CONTEXT *new_cert;
+        HCERTSTORE new_store;
+        unsigned i;
+
+        for(i=0; i < urls->cUrl; i++)
+        {
+            TRACE("Trying URL %s\n", debugstr_w(urls->rgwszUrl[i]));
+
+            res = CryptRetrieveObjectByUrlW(urls->rgwszUrl[i], CONTEXT_OID_CERTIFICATE,
+             CRYPT_CACHE_ONLY_RETRIEVAL /* FIXME */,
+             0, (void**)&new_cert, NULL, NULL, NULL, NULL);
+            if(!res)
+            {
+                TRACE("CryptRetrieveObjectByUrlW failed: %u\n", GetLastError());
+                continue;
+            }
+
+            /* FIXME: Use new_cert->hCertStore once cert ref count bug is fixed. */
+            new_store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
+            CertAddCertificateContextToStore(new_store, new_cert, CERT_STORE_ADD_NEW, NULL);
+            issuer = CertFindCertificateInStore(new_store, cert->dwCertEncodingType, 0, type, para, NULL);
+            CertFreeCertificateContext(new_cert);
+            CertCloseStore(new_store, 0);
+            if(issuer)
+            {
+                TRACE("Found downloaded issuer %p\n", issuer);
+                break;
+            }
+        }
+    }
+
+    HeapFree(GetProcessHeap(), 0, urls);
+    return issuer;
 }
 
 static PCCERT_CONTEXT CRYPT_GetIssuer(const CertificateChainEngine *engine,
diff --git a/dlls/crypt32/tests/chain.c b/dlls/crypt32/tests/chain.c
index a89c636..96eafa2 100644
--- a/dlls/crypt32/tests/chain.c
+++ b/dlls/crypt32/tests/chain.c
@@ -4005,6 +4005,7 @@ static void testGetCertChain(void)
     }
 
     ok(!chain->TrustStatus.dwErrorStatus, "chain->TrustStatus.dwErrorStatus = %x\n", chain->TrustStatus.dwErrorStatus);
+    todo_wine
     ok(chain->TrustStatus.dwInfoStatus == CERT_TRUST_HAS_PREFERRED_ISSUER, "chain->TrustStatus.dwInfoStatus = %x\n",
        chain->TrustStatus.dwInfoStatus);
 
@@ -4016,6 +4017,7 @@ static void testGetCertChain(void)
     ok(simple_chain->cbSize == sizeof(*simple_chain), "simple_chain->cbSize = %u\n", simple_chain->cbSize);
     ok(!simple_chain->TrustStatus.dwErrorStatus, "simple_chain->TrustStatus.dwErrorStatus = %x\n",
        simple_chain->TrustStatus.dwErrorStatus);
+    todo_wine
     ok(simple_chain->TrustStatus.dwInfoStatus == CERT_TRUST_HAS_PREFERRED_ISSUER,
        "simple_chain->TrustStatus.dwInfoStatus = %x\n", simple_chain->TrustStatus.dwInfoStatus);
     ok(simple_chain->cElement == 3, "simple_chain->cElement = %u\n", simple_chain->cElement);




More information about the wine-cvs mailing list