From: Paul Gofman pgofman@codeweavers.com
--- dlls/crypt32/crypt32_private.h | 10 ++++- dlls/crypt32/store.c | 68 +++++++++++++++++++++++++--------- 2 files changed, 58 insertions(+), 20 deletions(-)
diff --git a/dlls/crypt32/crypt32_private.h b/dlls/crypt32/crypt32_private.h index 6548dd36ab0..f5918ef0359 100644 --- a/dlls/crypt32/crypt32_private.h +++ b/dlls/crypt32/crypt32_private.h @@ -254,7 +254,10 @@ typedef BOOL (WINAPI *SetContextPropertyFunc)(const void *context, DWORD dwPropID, DWORD dwFlags, const void *pvData); typedef BOOL (WINAPI *SerializeElementFunc)(const void *context, DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement); -typedef BOOL (WINAPI *DeleteContextFunc)(const void *contex); +typedef BOOL (WINAPI *DeleteContextFromStoreFunc)(const void *contex); +typedef const void * (*FindContextByContextFunc)(HCERTSTORE store, const void *context); +typedef const void * (WINAPI *DuplicateContextFunc)(const void *context); +typedef void (WINAPI *FreeContextFunc)(const void *context);
/* An abstract context (certificate, CRL, or CTL) interface */ typedef struct _WINE_CONTEXT_INTERFACE @@ -267,7 +270,10 @@ typedef struct _WINE_CONTEXT_INTERFACE GetContextPropertyFunc getProp; SetContextPropertyFunc setProp; SerializeElementFunc serialize; - DeleteContextFunc deleteFromStore; + DeleteContextFromStoreFunc deleteFromStore; + FindContextByContextFunc findContextByContext; + DuplicateContextFunc duplicateContext; + FreeContextFunc freeContext; } WINE_CONTEXT_INTERFACE;
extern const WINE_CONTEXT_INTERFACE *pCertInterface; diff --git a/dlls/crypt32/store.c b/dlls/crypt32/store.c index ee07ad58994..0a96a337eab 100644 --- a/dlls/crypt32/store.c +++ b/dlls/crypt32/store.c @@ -37,6 +37,29 @@
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
+static const void *cert_find_context_by_context(HCERTSTORE store, const void *context) +{ + BYTE hash[20]; + DWORD size = sizeof(hash); + CRYPT_HASH_BLOB blob = { sizeof(hash), hash }; + const CERT_CONTEXT *cert = context; + + if (!CertGetCertificateContextProperty(cert, CERT_HASH_PROP_ID, hash, &size)) + return NULL; + + return CertFindCertificateInStore(store, cert->dwCertEncodingType, 0, CERT_FIND_SHA1_HASH, &blob, NULL); +} + +static const void *crl_find_context_by_context(HCERTSTORE store, const void *context) +{ + return CertFindCRLInStore(store, 0, 0, CRL_FIND_EXISTING, context, NULL); +} + +static const void *ctl_find_context_by_context(HCERTSTORE store, const void *context) +{ + return CertFindCTLInStore(store, 0, 0, CTL_FIND_EXISTING, context, NULL); +} + static const WINE_CONTEXT_INTERFACE gCertInterface = { (CreateContextFunc)CertCreateCertificateContext, (AddContextToStoreFunc)CertAddCertificateContextToStore, @@ -46,7 +69,10 @@ static const WINE_CONTEXT_INTERFACE gCertInterface = { (GetContextPropertyFunc)CertGetCertificateContextProperty, (SetContextPropertyFunc)CertSetCertificateContextProperty, (SerializeElementFunc)CertSerializeCertificateStoreElement, - (DeleteContextFunc)CertDeleteCertificateFromStore, + (DeleteContextFromStoreFunc)CertDeleteCertificateFromStore, + cert_find_context_by_context, + (DuplicateContextFunc)CertDuplicateCertificateContext, + (FreeContextFunc)CertFreeCertificateContext, }; const WINE_CONTEXT_INTERFACE *pCertInterface = &gCertInterface;
@@ -59,7 +85,10 @@ static const WINE_CONTEXT_INTERFACE gCRLInterface = { (GetContextPropertyFunc)CertGetCRLContextProperty, (SetContextPropertyFunc)CertSetCRLContextProperty, (SerializeElementFunc)CertSerializeCRLStoreElement, - (DeleteContextFunc)CertDeleteCRLFromStore, + (DeleteContextFromStoreFunc)CertDeleteCRLFromStore, + crl_find_context_by_context, + (DuplicateContextFunc)CertDuplicateCRLContext, + (FreeContextFunc)CertFreeCRLContext, }; const WINE_CONTEXT_INTERFACE *pCRLInterface = &gCRLInterface;
@@ -72,7 +101,10 @@ static const WINE_CONTEXT_INTERFACE gCTLInterface = { (GetContextPropertyFunc)CertGetCTLContextProperty, (SetContextPropertyFunc)CertSetCTLContextProperty, (SerializeElementFunc)CertSerializeCTLStoreElement, - (DeleteContextFunc)CertDeleteCTLFromStore, + (DeleteContextFromStoreFunc)CertDeleteCTLFromStore, + ctl_find_context_by_context, + (DuplicateContextFunc)CertDuplicateCTLContext, + (FreeContextFunc)CertFreeCTLContext, }; const WINE_CONTEXT_INTERFACE *pCTLInterface = &gCTLInterface;
@@ -118,24 +150,24 @@ BOOL WINAPI I_CertUpdateStore(HCERTSTORE store1, HCERTSTORE store2, DWORD unk0, warned = TRUE; }
- /* Poor-man's resync: empty first store, then add everything from second - * store to it. - */ for (i = 0; i < ARRAY_SIZE(interfaces); i++) { - const void *context; + const void *context, *context2;
- do { - context = interfaces[i]->enumContextsInStore(store1, NULL); - if (context) - interfaces[i]->deleteFromStore(context); - } while (context); - do { - context = interfaces[i]->enumContextsInStore(store2, context); - if (context) - interfaces[i]->addContextToStore(store1, context, - CERT_STORE_ADD_ALWAYS, NULL); - } while (context); + context = NULL; + while ((context = interfaces[i]->enumContextsInStore(store1, context))) + { + if ((context2 = interfaces[i]->findContextByContext(store2, context))) + { + interfaces[i]->freeContext(context2); + continue; + } + context2 = interfaces[i]->duplicateContext(context); + interfaces[i]->deleteFromStore(context2); + } + context = NULL; + while ((context = interfaces[i]->enumContextsInStore(store2, context))) + interfaces[i]->addContextToStore(store1, context, CERT_STORE_ADD_REPLACE_EXISTING, NULL); } return TRUE; }