From 2601f58acb75758f6b3755da08c8571513143532 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Thu, 17 Oct 2013 11:06:44 +0200 Subject: [PATCH] crypt32: Don't use links to certs in memory store. --- dlls/crypt32/cert.c | 158 +++++++++++++++++++-------------- dlls/crypt32/collectionstore.c | 12 +-- dlls/crypt32/context.c | 4 +- dlls/crypt32/crl.c | 7 +- dlls/crypt32/crypt32_private.h | 22 +++-- dlls/crypt32/ctl.c | 9 +- dlls/crypt32/provstore.c | 18 ++-- dlls/crypt32/store.c | 17 ++-- 8 files changed, 140 insertions(+), 107 deletions(-) diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c index 60cff2d7181..e81927e3905 100644 --- a/dlls/crypt32/cert.c +++ b/dlls/crypt32/cert.c @@ -109,6 +109,8 @@ BOOL WINAPI CertAddEncodedCertificateToSystemStoreW(LPCWSTR pszCertStoreName, return ret; } +static const context_vtbl_t cert_vtbl; + static void Cert_free(context_t *context) { cert_t *cert = (cert_t*)context; @@ -117,13 +119,41 @@ static void Cert_free(context_t *context) LocalFree(cert->ctx.pCertInfo); } -static context_t *Cert_clone(context_t *context, WINECRYPT_CERTSTORE *store) +static context_t *Cert_clone(context_t *context, WINECRYPT_CERTSTORE *store, BOOL use_link) { cert_t *cert; - cert = (cert_t*)Context_CreateLinkContext(sizeof(CERT_CONTEXT), context); - if(!cert) - return NULL; + if(use_link) { + cert = (cert_t*)Context_CreateLinkContext(sizeof(CERT_CONTEXT), context); + if(!cert) + return NULL; + }else { + const cert_t *cloned = (const cert_t*)context; + void *new_context; + DWORD size = 0; + BOOL res; + + new_context = Context_CreateDataContext(sizeof(CERT_CONTEXT), &cert_vtbl); + if(!new_context) + return NULL; + cert = cert_from_ptr(new_context); + + Context_CopyProperties(&cert->ctx, &cloned->ctx); + + cert->ctx.dwCertEncodingType = cloned->ctx.dwCertEncodingType; + cert->ctx.pbCertEncoded = CryptMemAlloc(cloned->ctx.cbCertEncoded); + memcpy(cert->ctx.pbCertEncoded, cloned->ctx.pbCertEncoded, cloned->ctx.cbCertEncoded); + cert->ctx.cbCertEncoded = cloned->ctx.cbCertEncoded; + + /* FIXME: We don't need to decode the object here, we could just clone cert info. */ + res = CryptDecodeObjectEx(cert->ctx.dwCertEncodingType, X509_CERT_TO_BE_SIGNED, + cert->ctx.pbCertEncoded, cert->ctx.cbCertEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, + &cert->ctx.pCertInfo, &size); + if(!res) { + CertFreeCertificateContext(&cert->ctx); + return NULL; + } + } cert->ctx.hCertStore = store; return &cert->base; @@ -134,18 +164,14 @@ static const context_vtbl_t cert_vtbl = { Cert_clone }; -BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore, - PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition, - PCCERT_CONTEXT *ppStoreContext) +BOOL WINAPI add_cert_to_store(WINECRYPT_CERTSTORE *store, const CERT_CONTEXT *cert, + DWORD add_disposition, BOOL use_link, PCCERT_CONTEXT *ret_context) { - WINECRYPT_CERTSTORE *store = hCertStore; - BOOL ret = TRUE; - PCCERT_CONTEXT toAdd = NULL, existing = NULL; + const CERT_CONTEXT *existing = NULL; + BOOL ret = TRUE, inherit_props = FALSE; + CERT_CONTEXT *new_context = NULL; - TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCertContext, - dwAddDisposition, ppStoreContext); - - switch (dwAddDisposition) + switch (add_disposition) { case CERT_STORE_ADD_ALWAYS: break; @@ -159,109 +185,110 @@ BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore, BYTE hashToAdd[20]; DWORD size = sizeof(hashToAdd); - ret = CertGetCertificateContextProperty(pCertContext, CERT_HASH_PROP_ID, + ret = CertGetCertificateContextProperty(cert, CERT_HASH_PROP_ID, hashToAdd, &size); if (ret) { CRYPT_HASH_BLOB blob = { sizeof(hashToAdd), hashToAdd }; - existing = CertFindCertificateInStore(hCertStore, - pCertContext->dwCertEncodingType, 0, CERT_FIND_SHA1_HASH, &blob, - NULL); + existing = CertFindCertificateInStore(store, cert->dwCertEncodingType, 0, + CERT_FIND_SHA1_HASH, &blob, NULL); } break; } default: - FIXME("Unimplemented add disposition %d\n", dwAddDisposition); + FIXME("Unimplemented add disposition %d\n", add_disposition); SetLastError(E_INVALIDARG); - ret = FALSE; + return FALSE; } - switch (dwAddDisposition) + switch (add_disposition) { case CERT_STORE_ADD_ALWAYS: - toAdd = CertDuplicateCertificateContext(pCertContext); break; case CERT_STORE_ADD_NEW: if (existing) { TRACE("found matching certificate, not adding\n"); SetLastError(CRYPT_E_EXISTS); - ret = FALSE; + return FALSE; } - else - toAdd = CertDuplicateCertificateContext(pCertContext); break; case CERT_STORE_ADD_REPLACE_EXISTING: - toAdd = CertDuplicateCertificateContext(pCertContext); break; case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES: - toAdd = CertDuplicateCertificateContext(pCertContext); + if (use_link) + FIXME("CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES: semi-stub for links\n"); if (existing) - Context_CopyProperties(toAdd, existing); + inherit_props = TRUE; break; case CERT_STORE_ADD_USE_EXISTING: + if(use_link) + FIXME("CERT_STORE_ADD_USE_EXISTING: semi-stub for links\n"); if (existing) { - Context_CopyProperties(existing, pCertContext); - if (ppStoreContext) - *ppStoreContext = CertDuplicateCertificateContext(existing); + Context_CopyProperties(existing, cert); + if (ret_context) + *ret_context = CertDuplicateCertificateContext(existing); + return TRUE; } - else - toAdd = CertDuplicateCertificateContext(pCertContext); break; case CERT_STORE_ADD_NEWER: - if (existing) + if (existing && CompareFileTime(&existing->pCertInfo->NotBefore, &cert->pCertInfo->NotBefore) >= 0) { - if (CompareFileTime(&existing->pCertInfo->NotBefore, - &pCertContext->pCertInfo->NotBefore) >= 0) - { - TRACE("existing certificate is newer, not adding\n"); - SetLastError(CRYPT_E_EXISTS); - ret = FALSE; - } - else - toAdd = CertDuplicateCertificateContext(pCertContext); + TRACE("existing certificate is newer, not adding\n"); + SetLastError(CRYPT_E_EXISTS); + return FALSE; } - else - toAdd = CertDuplicateCertificateContext(pCertContext); break; case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES: if (existing) { - if (CompareFileTime(&existing->pCertInfo->NotBefore, - &pCertContext->pCertInfo->NotBefore) >= 0) + if (CompareFileTime(&existing->pCertInfo->NotBefore, &cert->pCertInfo->NotBefore) >= 0) { TRACE("existing certificate is newer, not adding\n"); SetLastError(CRYPT_E_EXISTS); - ret = FALSE; - } - else - { - toAdd = CertDuplicateCertificateContext(pCertContext); - Context_CopyProperties(toAdd, existing); + return FALSE; } + inherit_props = TRUE; } - else - toAdd = CertDuplicateCertificateContext(pCertContext); break; } - if (toAdd) - { - if (store) - ret = store->vtbl->certs.addContext(store, (void *)toAdd, - (void *)existing, (const void **)ppStoreContext); - else if (ppStoreContext) - *ppStoreContext = CertDuplicateCertificateContext(toAdd); - CertFreeCertificateContext(toAdd); + /* FIXME: We have tests that this works, but what should we really do in this case? */ + if(!store) { + if(ret_context) + *ret_context = CertDuplicateCertificateContext(cert); + return TRUE; } - CertFreeCertificateContext(existing); + + ret = store->vtbl->certs.addContext(store, (void*)cert, (void*)existing, + (ret_context || inherit_props) ? (const void **)&new_context : NULL, use_link); + if(!ret) + return FALSE; + + if(inherit_props) + Context_CopyProperties(new_context, existing); + + if(ret_context) + *ret_context = CertDuplicateCertificateContext(new_context); + else if(new_context) + CertFreeCertificateContext(new_context); TRACE("returning %d\n", ret); return ret; } +BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pCertContext, + DWORD dwAddDisposition, PCCERT_CONTEXT *ppStoreContext) +{ + WINECRYPT_CERTSTORE *store = hCertStore; + + TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCertContext, dwAddDisposition, ppStoreContext); + + return add_cert_to_store(store, pCertContext, dwAddDisposition, FALSE, ppStoreContext); +} + BOOL WINAPI CertAddCertificateLinkToStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition, PCCERT_CONTEXT *ppCertContext) @@ -279,8 +306,7 @@ BOOL WINAPI CertAddCertificateLinkToStore(HCERTSTORE hCertStore, SetLastError(E_INVALIDARG); return FALSE; } - return CertAddCertificateContextToStore(hCertStore, pCertContext, - dwAddDisposition, ppCertContext); + return add_cert_to_store(hCertStore, pCertContext, dwAddDisposition, TRUE, ppCertContext); } PCCERT_CONTEXT WINAPI CertCreateCertificateContext(DWORD dwCertEncodingType, diff --git a/dlls/crypt32/collectionstore.c b/dlls/crypt32/collectionstore.c index bc1602638f5..69e29b6008f 100644 --- a/dlls/crypt32/collectionstore.c +++ b/dlls/crypt32/collectionstore.c @@ -76,7 +76,7 @@ static void *CRYPT_CollectionCreateContextFromChild(WINE_COLLECTIONSTORE *store, { context_t *ret; - ret = child->vtbl->clone(child, &store->hdr); + ret = child->vtbl->clone(child, &store->hdr, TRUE); if (!ret) return NULL; @@ -105,7 +105,7 @@ static BOOL CRYPT_CollectionAddContext(WINE_COLLECTIONSTORE *store, contextFuncs = (CONTEXT_FUNCS*)((LPBYTE)storeEntry->store->vtbl + contextFuncsOffset); ret = contextFuncs->addContext(storeEntry->store, context, - context_ptr(existingLinked), (const void **)&childContext); + context_ptr(existingLinked), (const void **)&childContext, TRUE); } else { @@ -122,7 +122,7 @@ static BOOL CRYPT_CollectionAddContext(WINE_COLLECTIONSTORE *store, storeEntry = entry; ret = contextFuncs->addContext(entry->store, context, NULL, - (const void **)&childContext); + (const void **)&childContext, TRUE); break; } } @@ -201,7 +201,7 @@ static void *CRYPT_CollectionAdvanceEnum(WINE_COLLECTIONSTORE *store, } static BOOL Collection_addCert(WINECRYPT_CERTSTORE *store, void *cert, - void *toReplace, const void **ppStoreContext) + void *toReplace, const void **ppStoreContext, BOOL use_link) { BOOL ret; void *childContext = NULL; @@ -274,7 +274,7 @@ static BOOL Collection_deleteCert(WINECRYPT_CERTSTORE *store, context_t *context } static BOOL Collection_addCRL(WINECRYPT_CERTSTORE *store, void *crl, - void *toReplace, const void **ppStoreContext) + void *toReplace, const void **ppStoreContext, BOOL use_link) { BOOL ret; void *childContext = NULL; @@ -345,7 +345,7 @@ static BOOL Collection_deleteCRL(WINECRYPT_CERTSTORE *store, context_t *context) } static BOOL Collection_addCTL(WINECRYPT_CERTSTORE *store, void *ctl, - void *toReplace, const void **ppStoreContext) + void *toReplace, const void **ppStoreContext, BOOL use_link) { BOOL ret; void *childContext = NULL; diff --git a/dlls/crypt32/context.c b/dlls/crypt32/context.c index bb919f28429..65e9fab916e 100644 --- a/dlls/crypt32/context.c +++ b/dlls/crypt32/context.c @@ -162,13 +162,13 @@ struct ContextList *ContextList_Create( return list; } -void *ContextList_Add(struct ContextList *list, void *toLink, void *toReplace, struct WINE_CRYPTCERTSTORE *store) +void *ContextList_Add(struct ContextList *list, void *toLink, void *toReplace, struct WINE_CRYPTCERTSTORE *store, BOOL use_link) { context_t *context; TRACE("(%p, %p, %p)\n", list, toLink, toReplace); - context = context_from_ptr(toLink)->vtbl->clone(BASE_CONTEXT_FROM_CONTEXT(toLink), store); + context = context_from_ptr(toLink)->vtbl->clone(BASE_CONTEXT_FROM_CONTEXT(toLink), store, use_link); if (context) { TRACE("adding %p\n", context); diff --git a/dlls/crypt32/crl.c b/dlls/crypt32/crl.c index 75fdc8e9025..482a0e2efc0 100644 --- a/dlls/crypt32/crl.c +++ b/dlls/crypt32/crl.c @@ -37,10 +37,15 @@ static void CRL_free(context_t *context) LocalFree(crl->ctx.pCrlInfo); } -static context_t *CRL_clone(context_t *context, WINECRYPT_CERTSTORE *store) +static context_t *CRL_clone(context_t *context, WINECRYPT_CERTSTORE *store, BOOL use_link) { crl_t *crl; + if(!use_link) { + FIXME("Only links supported\n"); + return NULL; + } + crl = (crl_t*)Context_CreateLinkContext(sizeof(CRL_CONTEXT), context); if(!crl) return NULL; diff --git a/dlls/crypt32/crypt32_private.h b/dlls/crypt32/crypt32_private.h index 33e13a8c2fc..08971e7fa8d 100644 --- a/dlls/crypt32/crypt32_private.h +++ b/dlls/crypt32/crypt32_private.h @@ -168,7 +168,7 @@ typedef struct _context_t context_t; typedef struct { void (*free)(context_t*); - struct _context_t *(*clone)(context_t*,struct WINE_CRYPTCERTSTORE*); + struct _context_t *(*clone)(context_t*,struct WINE_CRYPTCERTSTORE*,BOOL); } context_vtbl_t; typedef struct _context_t { @@ -267,18 +267,15 @@ typedef struct WINE_CRYPTCERTSTORE * (*StoreOpenFunc)(HCRYPTPROV hCryptProv, /* Called to enumerate the next context in a store. */ typedef void * (*EnumFunc)(struct WINE_CRYPTCERTSTORE *store, void *pPrev); -/* Called to add a context to a store. If toReplace is not NULL, - * context replaces toReplace in the store, and access checks should not be - * performed. Otherwise context is a new context, and it should only be - * added if the store allows it. If ppStoreContext is not NULL, the added - * context should be returned in *ppStoreContext. - */ -typedef BOOL (*AddFunc)(struct WINE_CRYPTCERTSTORE *store, void *context, - void *toReplace, const void **ppStoreContext); - typedef struct _CONTEXT_FUNCS { - AddFunc addContext; + /* Called to add a context to a store. If toReplace is not NULL, + * context replaces toReplace in the store, and access checks should not be + * performed. Otherwise context is a new context, and it should only be + * added if the store allows it. If ppStoreContext is not NULL, the added + * context should be returned in *ppStoreContext. + */ + BOOL (*addContext)(struct WINE_CRYPTCERTSTORE*,void*,void*,const void**,BOOL); EnumFunc enumContext; BOOL (*delete)(struct WINE_CRYPTCERTSTORE*,context_t*); } CONTEXT_FUNCS; @@ -452,7 +449,8 @@ struct ContextList; struct ContextList *ContextList_Create( const WINE_CONTEXT_INTERFACE *contextInterface, size_t contextSize) DECLSPEC_HIDDEN; -void *ContextList_Add(struct ContextList *list, void *toLink, void *toReplace, struct WINE_CRYPTCERTSTORE *store) DECLSPEC_HIDDEN; +void *ContextList_Add(struct ContextList *list, void *toLink, void *toReplace, + struct WINE_CRYPTCERTSTORE *store, BOOL use_link) DECLSPEC_HIDDEN; void *ContextList_Enum(struct ContextList *list, void *pPrev) DECLSPEC_HIDDEN; diff --git a/dlls/crypt32/ctl.c b/dlls/crypt32/ctl.c index ed92f9022b9..5f2b28f59f8 100644 --- a/dlls/crypt32/ctl.c +++ b/dlls/crypt32/ctl.c @@ -39,10 +39,15 @@ static void CTL_free(context_t *context) LocalFree(ctl->ctx.pCtlInfo); } -static context_t *CTL_clone(context_t *context, WINECRYPT_CERTSTORE *store) +static context_t *CTL_clone(context_t *context, WINECRYPT_CERTSTORE *store, BOOL use_link) { ctl_t *ctl; + if(!use_link) { + FIXME("Only links supported\n"); + return NULL; + } + ctl = (ctl_t*)Context_CreateLinkContext(sizeof(CTL_CONTEXT), context); if(!ctl) return NULL; @@ -154,7 +159,7 @@ BOOL WINAPI CertAddCTLContextToStore(HCERTSTORE hCertStore, { if (store) ret = store->vtbl->ctls.addContext(store, (void *)toAdd, - (void *)existing, (const void **)ppStoreContext); + (void *)existing, (const void **)ppStoreContext, TRUE); else if (ppStoreContext) *ppStoreContext = CertDuplicateCTLContext(toAdd); CertFreeCTLContext(toAdd); diff --git a/dlls/crypt32/provstore.c b/dlls/crypt32/provstore.c index a03a6190040..2b8c7967571 100644 --- a/dlls/crypt32/provstore.c +++ b/dlls/crypt32/provstore.c @@ -69,7 +69,7 @@ static DWORD ProvStore_release(WINECRYPT_CERTSTORE *cert_store, DWORD flags) } static BOOL ProvStore_addCert(WINECRYPT_CERTSTORE *store, void *cert, - void *toReplace, const void **ppStoreContext) + void *toReplace, const void **ppStoreContext, BOOL use_link) { WINE_PROVIDERSTORE *ps = (WINE_PROVIDERSTORE*)store; BOOL ret; @@ -78,7 +78,7 @@ static BOOL ProvStore_addCert(WINECRYPT_CERTSTORE *store, void *cert, if (toReplace) ret = ps->memStore->vtbl->certs.addContext(ps->memStore, cert, toReplace, - ppStoreContext); + ppStoreContext, TRUE); else { ret = TRUE; @@ -87,7 +87,7 @@ static BOOL ProvStore_addCert(WINECRYPT_CERTSTORE *store, void *cert, CERT_STORE_PROV_WRITE_ADD_FLAG); if (ret) ret = ps->memStore->vtbl->certs.addContext(ps->memStore, cert, NULL, - ppStoreContext); + ppStoreContext, TRUE); } /* dirty trick: replace the returned context's hCertStore with * store. @@ -128,7 +128,7 @@ static BOOL ProvStore_deleteCert(WINECRYPT_CERTSTORE *store, context_t *context) } static BOOL ProvStore_addCRL(WINECRYPT_CERTSTORE *store, void *crl, - void *toReplace, const void **ppStoreContext) + void *toReplace, const void **ppStoreContext, BOOL use_link) { WINE_PROVIDERSTORE *ps = (WINE_PROVIDERSTORE*)store; BOOL ret; @@ -137,7 +137,7 @@ static BOOL ProvStore_addCRL(WINECRYPT_CERTSTORE *store, void *crl, if (toReplace) ret = ps->memStore->vtbl->crls.addContext(ps->memStore, crl, toReplace, - ppStoreContext); + ppStoreContext, TRUE); else { if (ps->hdr.dwOpenFlags & CERT_STORE_READONLY_FLAG) @@ -153,7 +153,7 @@ static BOOL ProvStore_addCRL(WINECRYPT_CERTSTORE *store, void *crl, CERT_STORE_PROV_WRITE_ADD_FLAG); if (ret) ret = ps->memStore->vtbl->crls.addContext(ps->memStore, crl, NULL, - ppStoreContext); + ppStoreContext, TRUE); } } /* dirty trick: replace the returned context's hCertStore with @@ -195,7 +195,7 @@ static BOOL ProvStore_deleteCRL(WINECRYPT_CERTSTORE *store, context_t *crl) } static BOOL ProvStore_addCTL(WINECRYPT_CERTSTORE *store, void *ctl, - void *toReplace, const void **ppStoreContext) + void *toReplace, const void **ppStoreContext, BOOL use_link) { WINE_PROVIDERSTORE *ps = (WINE_PROVIDERSTORE*)store; BOOL ret; @@ -204,7 +204,7 @@ static BOOL ProvStore_addCTL(WINECRYPT_CERTSTORE *store, void *ctl, if (toReplace) ret = ps->memStore->vtbl->ctls.addContext(ps->memStore, ctl, toReplace, - ppStoreContext); + ppStoreContext, TRUE); else { if (ps->hdr.dwOpenFlags & CERT_STORE_READONLY_FLAG) @@ -220,7 +220,7 @@ static BOOL ProvStore_addCTL(WINECRYPT_CERTSTORE *store, void *ctl, CERT_STORE_PROV_WRITE_ADD_FLAG); if (ret) ret = ps->memStore->vtbl->ctls.addContext(ps->memStore, ctl, NULL, - ppStoreContext); + ppStoreContext, TRUE); } } /* dirty trick: replace the returned context's hCertStore with diff --git a/dlls/crypt32/store.c b/dlls/crypt32/store.c index 4f27e6295d2..08c2a30922d 100644 --- a/dlls/crypt32/store.c +++ b/dlls/crypt32/store.c @@ -143,14 +143,14 @@ BOOL WINAPI I_CertUpdateStore(HCERTSTORE store1, HCERTSTORE store2, DWORD unk0, } static BOOL MemStore_addCert(WINECRYPT_CERTSTORE *store, void *cert, - void *toReplace, const void **ppStoreContext) + void *toReplace, const void **ppStoreContext, BOOL use_link) { WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store; PCERT_CONTEXT context; TRACE("(%p, %p, %p, %p)\n", store, cert, toReplace, ppStoreContext); - context = ContextList_Add(ms->certs, cert, toReplace, store); + context = ContextList_Add(ms->certs, cert, toReplace, store, use_link); if (!context) return FALSE; @@ -185,14 +185,14 @@ static BOOL MemStore_deleteCert(WINECRYPT_CERTSTORE *store, context_t *context) } static BOOL MemStore_addCRL(WINECRYPT_CERTSTORE *store, void *crl, - void *toReplace, const void **ppStoreContext) + void *toReplace, const void **ppStoreContext, BOOL use_link) { WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store; PCRL_CONTEXT context; TRACE("(%p, %p, %p, %p)\n", store, crl, toReplace, ppStoreContext); - context = ContextList_Add(ms->crls, crl, toReplace, store); + context = ContextList_Add(ms->crls, crl, toReplace, store, use_link); if (!context) return FALSE; @@ -227,14 +227,14 @@ static BOOL MemStore_deleteCRL(WINECRYPT_CERTSTORE *store, context_t *context) } static BOOL MemStore_addCTL(WINECRYPT_CERTSTORE *store, void *ctl, - void *toReplace, const void **ppStoreContext) + void *toReplace, const void **ppStoreContext, BOOL use_link) { WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store; PCTL_CONTEXT context; TRACE("(%p, %p, %p, %p)\n", store, ctl, toReplace, ppStoreContext); - context = ContextList_Add(ms->ctls, ctl, toReplace, store); + context = ContextList_Add(ms->ctls, ctl, toReplace, store, use_link); if (!context) return FALSE; @@ -1022,8 +1022,7 @@ BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore, if (toAdd) { if (store) - ret = store->vtbl->crls.addContext(store, (void *)toAdd, - (void *)existing, (const void **)ppStoreContext); + ret = store->vtbl->crls.addContext(store, (void*)toAdd, (void*)existing, (const void **)ppStoreContext, TRUE); else if (ppStoreContext) *ppStoreContext = CertDuplicateCRLContext(toAdd); CertFreeCRLContext(toAdd); @@ -1356,7 +1355,7 @@ static DWORD EmptyStore_release(WINECRYPT_CERTSTORE *store, DWORD flags) } static BOOL EmptyStore_add(WINECRYPT_CERTSTORE *store, void *context, - void *replace, const void **ret_context) + void *replace, const void **ret_context, BOOL use_link) { TRACE("(%p, %p, %p, %p)\n", store, context, replace, ret_context);