Commit 9fb1e4d6 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

crypt32: Keep reference to store in contexts.

parent 610c863e
...@@ -124,7 +124,7 @@ static context_t *Cert_clone(context_t *context, WINECRYPT_CERTSTORE *store, BOO ...@@ -124,7 +124,7 @@ static context_t *Cert_clone(context_t *context, WINECRYPT_CERTSTORE *store, BOO
cert_t *cert; cert_t *cert;
if(use_link) { if(use_link) {
cert = (cert_t*)Context_CreateLinkContext(sizeof(CERT_CONTEXT), context); cert = (cert_t*)Context_CreateLinkContext(sizeof(CERT_CONTEXT), context, store);
if(!cert) if(!cert)
return NULL; return NULL;
}else { }else {
...@@ -133,7 +133,7 @@ static context_t *Cert_clone(context_t *context, WINECRYPT_CERTSTORE *store, BOO ...@@ -133,7 +133,7 @@ static context_t *Cert_clone(context_t *context, WINECRYPT_CERTSTORE *store, BOO
DWORD size = 0; DWORD size = 0;
BOOL res; BOOL res;
new_context = Context_CreateDataContext(sizeof(CERT_CONTEXT), &cert_vtbl); new_context = Context_CreateDataContext(sizeof(CERT_CONTEXT), &cert_vtbl, store);
if(!new_context) if(!new_context)
return NULL; return NULL;
cert = cert_from_ptr(new_context); cert = cert_from_ptr(new_context);
...@@ -270,12 +270,10 @@ BOOL WINAPI add_cert_to_store(WINECRYPT_CERTSTORE *store, const CERT_CONTEXT *ce ...@@ -270,12 +270,10 @@ BOOL WINAPI add_cert_to_store(WINECRYPT_CERTSTORE *store, const CERT_CONTEXT *ce
if(inherit_props) if(inherit_props)
Context_CopyProperties(context_ptr(new_context), existing); Context_CopyProperties(context_ptr(new_context), existing);
if(ret_context) { if(ret_context)
Context_AddRef(new_context);
*ret_context = context_ptr(new_context); *ret_context = context_ptr(new_context);
}else if(new_context) { else if(new_context)
Context_Release(new_context); Context_Release(new_context);
}
TRACE("returning %d\n", ret); TRACE("returning %d\n", ret);
return ret; return ret;
...@@ -335,7 +333,7 @@ PCCERT_CONTEXT WINAPI CertCreateCertificateContext(DWORD dwCertEncodingType, ...@@ -335,7 +333,7 @@ PCCERT_CONTEXT WINAPI CertCreateCertificateContext(DWORD dwCertEncodingType,
{ {
BYTE *data = NULL; BYTE *data = NULL;
cert = Context_CreateDataContext(sizeof(CERT_CONTEXT), &cert_vtbl); cert = Context_CreateDataContext(sizeof(CERT_CONTEXT), &cert_vtbl, &empty_store);
if (!cert) if (!cert)
goto end; goto end;
data = CryptMemAlloc(cbCertEncoded); data = CryptMemAlloc(cbCertEncoded);
......
...@@ -71,6 +71,12 @@ static DWORD Collection_release(WINECRYPT_CERTSTORE *store, DWORD flags) ...@@ -71,6 +71,12 @@ static DWORD Collection_release(WINECRYPT_CERTSTORE *store, DWORD flags)
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
static void Collection_releaseContext(WINECRYPT_CERTSTORE *store, context_t *context)
{
/* We don't cache context links, so just free them. */
Context_Free(context);
}
static context_t *CRYPT_CollectionCreateContextFromChild(WINE_COLLECTIONSTORE *store, static context_t *CRYPT_CollectionCreateContextFromChild(WINE_COLLECTIONSTORE *store,
WINE_STORE_LIST_ENTRY *storeEntry, context_t *child) WINE_STORE_LIST_ENTRY *storeEntry, context_t *child)
{ {
...@@ -256,14 +262,11 @@ static BOOL Collection_deleteCert(WINECRYPT_CERTSTORE *store, context_t *context ...@@ -256,14 +262,11 @@ static BOOL Collection_deleteCert(WINECRYPT_CERTSTORE *store, context_t *context
{ {
cert_t *cert = (cert_t*)context; cert_t *cert = (cert_t*)context;
cert_t *linked; cert_t *linked;
BOOL ret;
TRACE("(%p, %p)\n", store, cert); TRACE("(%p, %p)\n", store, cert);
linked = (cert_t*)context->linked; linked = (cert_t*)context->linked;
ret = CertDeleteCertificateFromStore(&linked->ctx); return CertDeleteCertificateFromStore(&linked->ctx);
Context_Release(&cert->base);
return ret;
} }
static BOOL Collection_addCRL(WINECRYPT_CERTSTORE *store, context_t *crl, static BOOL Collection_addCRL(WINECRYPT_CERTSTORE *store, context_t *crl,
...@@ -327,14 +330,11 @@ static context_t *Collection_enumCRL(WINECRYPT_CERTSTORE *store, context_t *prev ...@@ -327,14 +330,11 @@ static context_t *Collection_enumCRL(WINECRYPT_CERTSTORE *store, context_t *prev
static BOOL Collection_deleteCRL(WINECRYPT_CERTSTORE *store, context_t *context) static BOOL Collection_deleteCRL(WINECRYPT_CERTSTORE *store, context_t *context)
{ {
crl_t *crl = (crl_t*)context, *linked; crl_t *crl = (crl_t*)context, *linked;
BOOL ret;
TRACE("(%p, %p)\n", store, crl); TRACE("(%p, %p)\n", store, crl);
linked = (crl_t*)context->linked; linked = (crl_t*)context->linked;
ret = CertDeleteCRLFromStore(&linked->ctx); return CertDeleteCRLFromStore(&linked->ctx);
Context_Release(&crl->base);
return ret;
} }
static BOOL Collection_addCTL(WINECRYPT_CERTSTORE *store, context_t *ctl, static BOOL Collection_addCTL(WINECRYPT_CERTSTORE *store, context_t *ctl,
...@@ -398,14 +398,11 @@ static context_t *Collection_enumCTL(WINECRYPT_CERTSTORE *store, context_t *prev ...@@ -398,14 +398,11 @@ static context_t *Collection_enumCTL(WINECRYPT_CERTSTORE *store, context_t *prev
static BOOL Collection_deleteCTL(WINECRYPT_CERTSTORE *store, context_t *context) static BOOL Collection_deleteCTL(WINECRYPT_CERTSTORE *store, context_t *context)
{ {
ctl_t *ctl = (ctl_t*)context, *linked; ctl_t *ctl = (ctl_t*)context, *linked;
BOOL ret;
TRACE("(%p, %p)\n", store, ctl); TRACE("(%p, %p)\n", store, ctl);
linked = (ctl_t*)context->linked; linked = (ctl_t*)context->linked;
ret = CertDeleteCTLFromStore(&linked->ctx); return CertDeleteCTLFromStore(&linked->ctx);
Context_Release(&ctl->base);
return ret;
} }
static BOOL Collection_control(WINECRYPT_CERTSTORE *cert_store, DWORD dwFlags, static BOOL Collection_control(WINECRYPT_CERTSTORE *cert_store, DWORD dwFlags,
...@@ -448,6 +445,7 @@ static BOOL Collection_control(WINECRYPT_CERTSTORE *cert_store, DWORD dwFlags, ...@@ -448,6 +445,7 @@ static BOOL Collection_control(WINECRYPT_CERTSTORE *cert_store, DWORD dwFlags,
static const store_vtbl_t CollectionStoreVtbl = { static const store_vtbl_t CollectionStoreVtbl = {
Collection_addref, Collection_addref,
Collection_release, Collection_release,
Collection_releaseContext,
Collection_control, Collection_control,
{ {
Collection_addCert, Collection_addCert,
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(context); WINE_DEFAULT_DEBUG_CHANNEL(context);
void *Context_CreateDataContext(size_t contextSize, const context_vtbl_t *vtbl) void *Context_CreateDataContext(size_t contextSize, const context_vtbl_t *vtbl, WINECRYPT_CERTSTORE *store)
{ {
context_t *context; context_t *context;
...@@ -33,9 +33,6 @@ void *Context_CreateDataContext(size_t contextSize, const context_vtbl_t *vtbl) ...@@ -33,9 +33,6 @@ void *Context_CreateDataContext(size_t contextSize, const context_vtbl_t *vtbl)
if (!context) if (!context)
return NULL; return NULL;
context->vtbl = vtbl;
context->ref = 1;
context->linked = NULL;
context->properties = ContextPropertyList_Create(); context->properties = ContextPropertyList_Create();
if (!context->properties) if (!context->properties)
{ {
...@@ -43,11 +40,18 @@ void *Context_CreateDataContext(size_t contextSize, const context_vtbl_t *vtbl) ...@@ -43,11 +40,18 @@ void *Context_CreateDataContext(size_t contextSize, const context_vtbl_t *vtbl)
return NULL; return NULL;
} }
context->vtbl = vtbl;
context->ref = 1;
context->linked = NULL;
store->vtbl->addref(store);
context->store = store;
TRACE("returning %p\n", context); TRACE("returning %p\n", context);
return context_ptr(context); return context_ptr(context);
} }
context_t *Context_CreateLinkContext(unsigned int contextSize, context_t *linked) context_t *Context_CreateLinkContext(unsigned int contextSize, context_t *linked, WINECRYPT_CERTSTORE *store)
{ {
context_t *context; context_t *context;
...@@ -64,36 +68,54 @@ context_t *Context_CreateLinkContext(unsigned int contextSize, context_t *linked ...@@ -64,36 +68,54 @@ context_t *Context_CreateLinkContext(unsigned int contextSize, context_t *linked
context->properties = linked->properties; context->properties = linked->properties;
Context_AddRef(linked); Context_AddRef(linked);
store->vtbl->addref(store);
context->store = store;
TRACE("returning %p\n", context); TRACE("returning %p\n", context);
return context; return context;
} }
void Context_AddRef(context_t *context) void Context_AddRef(context_t *context)
{ {
InterlockedIncrement(&context->ref); LONG ref = InterlockedIncrement(&context->ref);
TRACE("(%p) ref=%d\n", context, context->ref); TRACE("(%p) ref=%d\n", context, context->ref);
if(ref == 1) {
/* This is the first external (non-store) reference. Increase store ref cnt. */
context->store->vtbl->addref(context->store);
}
} }
void Context_Release(context_t *context) void Context_Free(context_t *context)
{ {
if (context->ref <= 0) TRACE("(%p)\n", context);
{
ERR("%p's ref count is %d\n", context, context->ref); assert(!context->ref);
if (!context->linked) {
ContextPropertyList_Free(context->properties);
context->vtbl->free(context);
}else {
Context_Release(context->linked);
} }
if (InterlockedDecrement(&context->ref) == 0)
{ CryptMemFree(context);
TRACE("freeing %p\n", context); }
if (!context->linked)
{ void Context_Release(context_t *context)
ContextPropertyList_Free(context->properties); {
context->vtbl->free(context); LONG ref = InterlockedDecrement(&context->ref);
} else {
Context_Release(context->linked); TRACE("(%p) ref=%d\n", context, ref);
} assert(ref >= 0);
CryptMemFree(context);
if (!ref) {
/* This is the last reference, but the context still may be in a store.
* We release our store reference, but leave it up to store to free or keep the context. */
context->store->vtbl->releaseContext(context->store, context);
context->store->vtbl->release(context->store, 0);
} }
else
TRACE("%p's ref count is %d\n", context, context->ref);
} }
void Context_CopyProperties(const void *to, const void *from) void Context_CopyProperties(const void *to, const void *from)
......
...@@ -46,7 +46,7 @@ static context_t *CRL_clone(context_t *context, WINECRYPT_CERTSTORE *store, BOOL ...@@ -46,7 +46,7 @@ static context_t *CRL_clone(context_t *context, WINECRYPT_CERTSTORE *store, BOOL
return NULL; return NULL;
} }
crl = (crl_t*)Context_CreateLinkContext(sizeof(CRL_CONTEXT), context); crl = (crl_t*)Context_CreateLinkContext(sizeof(CRL_CONTEXT), context, store);
if(!crl) if(!crl)
return NULL; return NULL;
...@@ -82,7 +82,7 @@ PCCRL_CONTEXT WINAPI CertCreateCRLContext(DWORD dwCertEncodingType, ...@@ -82,7 +82,7 @@ PCCRL_CONTEXT WINAPI CertCreateCRLContext(DWORD dwCertEncodingType,
{ {
BYTE *data = NULL; BYTE *data = NULL;
crl = Context_CreateDataContext(sizeof(CRL_CONTEXT), &crl_vtbl); crl = Context_CreateDataContext(sizeof(CRL_CONTEXT), &crl_vtbl, &empty_store);
if (!crl) if (!crl)
goto end; goto end;
data = CryptMemAlloc(cbCrlEncoded); data = CryptMemAlloc(cbCrlEncoded);
......
...@@ -174,6 +174,7 @@ typedef struct { ...@@ -174,6 +174,7 @@ typedef struct {
struct _context_t { struct _context_t {
const context_vtbl_t *vtbl; const context_vtbl_t *vtbl;
LONG ref; LONG ref;
struct WINE_CRYPTCERTSTORE *store;
struct _context_t *linked; struct _context_t *linked;
CONTEXT_PROPERTY_LIST *properties; CONTEXT_PROPERTY_LIST *properties;
union { union {
...@@ -297,6 +298,7 @@ typedef enum _CertStoreType { ...@@ -297,6 +298,7 @@ typedef enum _CertStoreType {
typedef struct { typedef struct {
void (*addref)(struct WINE_CRYPTCERTSTORE*); void (*addref)(struct WINE_CRYPTCERTSTORE*);
DWORD (*release)(struct WINE_CRYPTCERTSTORE*,DWORD); DWORD (*release)(struct WINE_CRYPTCERTSTORE*,DWORD);
void (*releaseContext)(struct WINE_CRYPTCERTSTORE*,context_t*);
BOOL (*control)(struct WINE_CRYPTCERTSTORE*,DWORD,DWORD,void const*); BOOL (*control)(struct WINE_CRYPTCERTSTORE*,DWORD,DWORD,void const*);
CONTEXT_FUNCS certs; CONTEXT_FUNCS certs;
CONTEXT_FUNCS crls; CONTEXT_FUNCS crls;
...@@ -387,24 +389,21 @@ DWORD cert_name_to_str_with_indent(DWORD dwCertEncodingType, DWORD indent, ...@@ -387,24 +389,21 @@ DWORD cert_name_to_str_with_indent(DWORD dwCertEncodingType, DWORD indent,
* which should be one of CERT_CONTEXT, CRL_CONTEXT, or CTL_CONTEXT. * which should be one of CERT_CONTEXT, CRL_CONTEXT, or CTL_CONTEXT.
* Free with Context_Release. * Free with Context_Release.
*/ */
void *Context_CreateDataContext(size_t contextSize, const context_vtbl_t *vtbl) DECLSPEC_HIDDEN; void *Context_CreateDataContext(size_t contextSize, const context_vtbl_t *vtbl, struct WINE_CRYPTCERTSTORE*) DECLSPEC_HIDDEN;
/* Creates a new link context. The context refers to linked /* Creates a new link context. The context refers to linked
* rather than owning its own properties. If addRef is TRUE (which ordinarily * rather than owning its own properties. If addRef is TRUE (which ordinarily
* it should be) linked is addref'd. * it should be) linked is addref'd.
* Free with Context_Release. * Free with Context_Release.
*/ */
context_t *Context_CreateLinkContext(unsigned contextSize, context_t *linked) DECLSPEC_HIDDEN; context_t *Context_CreateLinkContext(unsigned contextSize, context_t *linked, struct WINE_CRYPTCERTSTORE*) DECLSPEC_HIDDEN;
/* Copies properties from fromContext to toContext. */ /* Copies properties from fromContext to toContext. */
void Context_CopyProperties(const void *to, const void *from) DECLSPEC_HIDDEN; void Context_CopyProperties(const void *to, const void *from) DECLSPEC_HIDDEN;
void Context_AddRef(context_t*) DECLSPEC_HIDDEN; void Context_AddRef(context_t*) DECLSPEC_HIDDEN;
/* Decrements context's ref count. If context is a link context, releases its
* linked context as well.
*/
void Context_Release(context_t *context) DECLSPEC_HIDDEN; void Context_Release(context_t *context) DECLSPEC_HIDDEN;
void Context_Free(context_t*) DECLSPEC_HIDDEN;
/** /**
* Context property list functions * Context property list functions
......
...@@ -48,7 +48,7 @@ static context_t *CTL_clone(context_t *context, WINECRYPT_CERTSTORE *store, BOOL ...@@ -48,7 +48,7 @@ static context_t *CTL_clone(context_t *context, WINECRYPT_CERTSTORE *store, BOOL
return NULL; return NULL;
} }
ctl = (ctl_t*)Context_CreateLinkContext(sizeof(CTL_CONTEXT), context); ctl = (ctl_t*)Context_CreateLinkContext(sizeof(CTL_CONTEXT), context, store);
if(!ctl) if(!ctl)
return NULL; return NULL;
...@@ -440,7 +440,7 @@ PCCTL_CONTEXT WINAPI CertCreateCTLContext(DWORD dwMsgAndCertEncodingType, ...@@ -440,7 +440,7 @@ PCCTL_CONTEXT WINAPI CertCreateCTLContext(DWORD dwMsgAndCertEncodingType,
&ctlInfo, &size); &ctlInfo, &size);
if (ret) if (ret)
{ {
ctl = Context_CreateDataContext(sizeof(CTL_CONTEXT), &ctl_vtbl); ctl = Context_CreateDataContext(sizeof(CTL_CONTEXT), &ctl_vtbl, &empty_store);
if (ctl) if (ctl)
{ {
BYTE *data = CryptMemAlloc(cbCtlEncoded); BYTE *data = CryptMemAlloc(cbCtlEncoded);
......
...@@ -15,7 +15,10 @@ ...@@ -15,7 +15,10 @@
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include <stdarg.h> #include <stdarg.h>
#include <assert.h>
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
#include "wincrypt.h" #include "wincrypt.h"
...@@ -68,6 +71,13 @@ static DWORD ProvStore_release(WINECRYPT_CERTSTORE *cert_store, DWORD flags) ...@@ -68,6 +71,13 @@ static DWORD ProvStore_release(WINECRYPT_CERTSTORE *cert_store, DWORD flags)
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
static void ProvStore_releaseContext(WINECRYPT_CERTSTORE *store, context_t *context)
{
/* As long as we don't have contexts properly stored (and hack around hCertStore
in add* and enum* functions), this function should never be called. */
assert(0);
}
static BOOL ProvStore_addCert(WINECRYPT_CERTSTORE *store, context_t *cert, static BOOL ProvStore_addCert(WINECRYPT_CERTSTORE *store, context_t *cert,
context_t *toReplace, context_t **ppStoreContext, BOOL use_link) context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
{ {
...@@ -277,6 +287,7 @@ static BOOL ProvStore_control(WINECRYPT_CERTSTORE *cert_store, DWORD dwFlags, DW ...@@ -277,6 +287,7 @@ static BOOL ProvStore_control(WINECRYPT_CERTSTORE *cert_store, DWORD dwFlags, DW
static const store_vtbl_t ProvStoreVtbl = { static const store_vtbl_t ProvStoreVtbl = {
ProvStore_addref, ProvStore_addref,
ProvStore_release, ProvStore_release,
ProvStore_releaseContext,
ProvStore_control, ProvStore_control,
{ {
ProvStore_addCert, ProvStore_addCert,
......
...@@ -160,17 +160,17 @@ static BOOL MemStore_addContext(WINE_MEMSTORE *store, struct list *list, context ...@@ -160,17 +160,17 @@ static BOOL MemStore_addContext(WINE_MEMSTORE *store, struct list *list, context
context->u.entry.prev->next = &context->u.entry; context->u.entry.prev->next = &context->u.entry;
context->u.entry.next->prev = &context->u.entry; context->u.entry.next->prev = &context->u.entry;
list_init(&existing->u.entry); list_init(&existing->u.entry);
Context_Release(existing); if(!existing->ref)
Context_Release(existing);
}else { }else {
list_add_head(list, &context->u.entry); list_add_head(list, &context->u.entry);
} }
LeaveCriticalSection(&store->cs); LeaveCriticalSection(&store->cs);
if(ret_context) { if(ret_context)
Context_AddRef(context);
*ret_context = context; *ret_context = context;
} else
Context_Release(context);
return TRUE; return TRUE;
} }
...@@ -210,8 +210,8 @@ static BOOL MemStore_deleteContext(WINE_MEMSTORE *store, context_t *context) ...@@ -210,8 +210,8 @@ static BOOL MemStore_deleteContext(WINE_MEMSTORE *store, context_t *context)
} }
LeaveCriticalSection(&store->cs); LeaveCriticalSection(&store->cs);
if(in_list) if(in_list && !context->ref)
Context_Release(context); Context_Free(context);
return TRUE; return TRUE;
} }
...@@ -223,10 +223,17 @@ static void free_contexts(struct list *list) ...@@ -223,10 +223,17 @@ static void free_contexts(struct list *list)
{ {
TRACE("freeing %p\n", context); TRACE("freeing %p\n", context);
list_remove(&context->u.entry); list_remove(&context->u.entry);
Context_Release(context); Context_Free(context);
} }
} }
static void MemStore_releaseContext(WINECRYPT_CERTSTORE *store, context_t *context)
{
/* Free the context only if it's not in a list. Otherwise it may be reused later. */
if(list_empty(&context->u.entry))
Context_Free(context);
}
static BOOL MemStore_addCert(WINECRYPT_CERTSTORE *store, context_t *cert, static BOOL MemStore_addCert(WINECRYPT_CERTSTORE *store, context_t *cert,
context_t *toReplace, context_t **ppStoreContext, BOOL use_link) context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
{ {
...@@ -348,6 +355,7 @@ static BOOL MemStore_control(WINECRYPT_CERTSTORE *store, DWORD dwFlags, ...@@ -348,6 +355,7 @@ static BOOL MemStore_control(WINECRYPT_CERTSTORE *store, DWORD dwFlags,
static const store_vtbl_t MemStoreVtbl = { static const store_vtbl_t MemStoreVtbl = {
MemStore_addref, MemStore_addref,
MemStore_release, MemStore_release,
MemStore_releaseContext,
MemStore_control, MemStore_control,
{ {
MemStore_addCert, MemStore_addCert,
...@@ -1401,6 +1409,11 @@ static DWORD EmptyStore_release(WINECRYPT_CERTSTORE *store, DWORD flags) ...@@ -1401,6 +1409,11 @@ static DWORD EmptyStore_release(WINECRYPT_CERTSTORE *store, DWORD flags)
return E_UNEXPECTED; return E_UNEXPECTED;
} }
static void EmptyStore_releaseContext(WINECRYPT_CERTSTORE *store, context_t *context)
{
Context_Free(context);
}
static BOOL EmptyStore_add(WINECRYPT_CERTSTORE *store, context_t *context, static BOOL EmptyStore_add(WINECRYPT_CERTSTORE *store, context_t *context,
context_t *replace, context_t **ret_context, BOOL use_link) context_t *replace, context_t **ret_context, BOOL use_link)
{ {
...@@ -1439,6 +1452,7 @@ static BOOL EmptyStore_control(WINECRYPT_CERTSTORE *store, DWORD flags, DWORD ct ...@@ -1439,6 +1452,7 @@ static BOOL EmptyStore_control(WINECRYPT_CERTSTORE *store, DWORD flags, DWORD ct
static const store_vtbl_t EmptyStoreVtbl = { static const store_vtbl_t EmptyStoreVtbl = {
EmptyStore_addref, EmptyStore_addref,
EmptyStore_release, EmptyStore_release,
EmptyStore_releaseContext,
EmptyStore_control, EmptyStore_control,
{ {
EmptyStore_add, EmptyStore_add,
......
...@@ -93,6 +93,26 @@ static const BYTE bigCert2[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, ...@@ -93,6 +93,26 @@ static const BYTE bigCert2[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 }; 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
static const BYTE signedCTLWithCTLInnerContent[] = {
0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
0x57,0x6c,0x0b,0x47,0xb8 };
static BOOL (WINAPI *pCertAddStoreToCollection)(HCERTSTORE,HCERTSTORE,DWORD,DWORD); static BOOL (WINAPI *pCertAddStoreToCollection)(HCERTSTORE,HCERTSTORE,DWORD,DWORD);
...@@ -2571,6 +2591,9 @@ static void testEmptyStore(void) ...@@ -2571,6 +2591,9 @@ static void testEmptyStore(void)
static void testCloseStore(void) static void testCloseStore(void)
{ {
const CERT_CONTEXT *cert;
const CRL_CONTEXT *crl;
const CTL_CONTEXT *ctl;
HCERTSTORE store, store2; HCERTSTORE store, store2;
BOOL res; BOOL res;
...@@ -2592,6 +2615,71 @@ static void testCloseStore(void) ...@@ -2592,6 +2615,71 @@ static void testCloseStore(void)
res = CertCloseStore(store2, CERT_CLOSE_STORE_CHECK_FLAG); res = CertCloseStore(store2, CERT_CLOSE_STORE_CHECK_FLAG);
ok(res, "CertCloseStore failed\n"); ok(res, "CertCloseStore failed\n");
store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
ok(store != NULL, "CertOpenStore failed\n");
res = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, bigCert,
sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &cert);
ok(res, "CertAddEncodedCertificateToStore failed\n");
/* There is still a reference from cert */
res = CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG);
ok(!res && GetLastError() == CRYPT_E_PENDING_CLOSE, "CertCloseStore failed\n");
res = CertFreeCertificateContext(cert);
ok(res, "CertFreeCertificateContext failed\n");
store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
ok(store != NULL, "CertOpenStore failed\n");
res = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, &crl);
ok(res, "CertAddEncodedCRLToStore failed\n");
/* There is still a reference from CRL */
res = CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG);
ok(!res && GetLastError() == CRYPT_E_PENDING_CLOSE, "CertCloseStore failed\n");
res = CertFreeCRLContext(crl);
ok(res, "CertFreeCRLContext failed\n");
store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
ok(store != NULL, "CertOpenStore failed\n");
res = CertAddEncodedCTLToStore(store, X509_ASN_ENCODING, signedCTLWithCTLInnerContent,
sizeof(signedCTLWithCTLInnerContent), CERT_STORE_ADD_ALWAYS, &ctl);
ok(res, "CertAddEncodedCTLToStore failed\n");
/* There is still a reference from CTL */
res = CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG);
ok(!res && GetLastError() == CRYPT_E_PENDING_CLOSE, "CertCloseStore returned: %x(%u)\n", res, GetLastError());
res = CertFreeCTLContext(ctl);
ok(res, "CertFreeCTLContext failed\n");
/* Add all kinds of contexts, then release external references and make sure that store is properly closed. */
store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
ok(store != NULL, "CertOpenStore failed\n");
res = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, bigCert,
sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &cert);
ok(res, "CertAddEncodedCertificateToStore failed\n");
res = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, &crl);
ok(res, "CertAddEncodedCRLToStore failed\n");
res = CertAddEncodedCTLToStore(store, X509_ASN_ENCODING, signedCTLWithCTLInnerContent,
sizeof(signedCTLWithCTLInnerContent), CERT_STORE_ADD_ALWAYS, &ctl);
ok(res, "CertAddEncodedCTLToStore failed\n");
CertFreeCertificateContext(cert);
CertFreeCRLContext(crl);
CertFreeCTLContext(ctl);
res = CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG);
ok(res, "CertCloseStore failed\n");
} }
static void test_I_UpdateStore(void) static void test_I_UpdateStore(void)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment