diff --git a/dlls/crypt32/crl.c b/dlls/crypt32/crl.c index 4686e114036..8eb587aec68 100644 --- a/dlls/crypt32/crl.c +++ b/dlls/crypt32/crl.c @@ -37,18 +37,43 @@ static void CRL_free(context_t *context) LocalFree(crl->ctx.pCrlInfo); } +static const context_vtbl_t crl_vtbl; + 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; - } + if(use_link) { + crl = (crl_t*)Context_CreateLinkContext(sizeof(CRL_CONTEXT), context, store); + if(!crl) + return NULL; + }else { + const crl_t *cloned = (const crl_t*)context; + void *new_context; + DWORD size = 0; + BOOL res; - crl = (crl_t*)Context_CreateLinkContext(sizeof(CRL_CONTEXT), context, store); - if(!crl) - return NULL; + new_context = Context_CreateDataContext(sizeof(CRL_CONTEXT), &crl_vtbl, store); + if(!new_context) + return NULL; + crl = crl_from_ptr(new_context); + + Context_CopyProperties(&crl->ctx, &cloned->ctx); + + crl->ctx.dwCertEncodingType = cloned->ctx.dwCertEncodingType; + crl->ctx.pbCrlEncoded = CryptMemAlloc(cloned->ctx.cbCrlEncoded); + memcpy(crl->ctx.pbCrlEncoded, cloned->ctx.pbCrlEncoded, cloned->ctx.cbCrlEncoded); + crl->ctx.cbCrlEncoded = cloned->ctx.cbCrlEncoded; + + /* FIXME: We don't need to decode the object here, we could just clone crl info. */ + res = CryptDecodeObjectEx(crl->ctx.dwCertEncodingType, X509_CERT_CRL_TO_BE_SIGNED, + crl->ctx.pbCrlEncoded, crl->ctx.cbCrlEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, + &crl->ctx.pCrlInfo, &size); + if(!res) { + CertFreeCRLContext(&crl->ctx); + return NULL; + } + } crl->ctx.hCertStore = store; return &crl->base; diff --git a/dlls/crypt32/store.c b/dlls/crypt32/store.c index 70c9150b5f0..7e22b95eab6 100644 --- a/dlls/crypt32/store.c +++ b/dlls/crypt32/store.c @@ -1074,7 +1074,7 @@ BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore, if (store) { context_t *ret_context; ret = store->vtbl->crls.addContext(store, context_from_ptr(toAdd), - existing ? context_from_ptr(existing) : NULL, ppStoreContext ? &ret_context : NULL, TRUE); + existing ? context_from_ptr(existing) : NULL, ppStoreContext ? &ret_context : NULL, FALSE); if (ret && ppStoreContext) *ppStoreContext = context_ptr(ret_context); }else if (ppStoreContext) { diff --git a/dlls/crypt32/tests/crl.c b/dlls/crypt32/tests/crl.c index f39d02e6c14..9515c381154 100644 --- a/dlls/crypt32/tests/crl.c +++ b/dlls/crypt32/tests/crl.c @@ -144,7 +144,7 @@ static void testAddCRL(void) { HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); - PCCRL_CONTEXT context; + PCCRL_CONTEXT context, context2; BOOL ret; DWORD GLE; @@ -229,6 +229,24 @@ static void testAddCRL(void) ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError()); CertCloseStore(store, 0); + + store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); + ok(store != NULL, "CertOpenStore failed\n"); + + context = CertCreateCRLContext(X509_ASN_ENCODING, CRL, sizeof(CRL)); + ok(context != NULL, "CertCreateCRLContext failed\n"); + + ret = CertAddCRLContextToStore(store, context, CERT_STORE_ADD_NEW, &context2); + ok(ret, "CertAddCRLContextToStore failed\n"); + ok(context2 != NULL && context2 != context, "unexpected context2\n"); + + ok(context->pbCrlEncoded != context2->pbCrlEncoded, "Unexpected pbCrlEncoded\n"); + ok(context->cbCrlEncoded == context2->cbCrlEncoded, "Unexpected cbCrlEncoded\n"); + ok(context->pCrlInfo != context2->pCrlInfo, "Unexpected pCrlInfo\n"); + + CertFreeCRLContext(context2); + CertFreeCRLContext(context); + CertCloseStore(store, 0); } static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,