mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +00:00
[CRYPT32]
* Sync with Wine 1.7.17. CORE-8080 svn path=/trunk/; revision=62883
This commit is contained in:
parent
22b7b59d5a
commit
a5a8dd531d
22 changed files with 1643 additions and 1572 deletions
|
@ -46,5 +46,6 @@ add_library(crypt32 SHARED
|
|||
set_module_type(crypt32 win32dll)
|
||||
target_link_libraries(crypt32 wine ${PSEH_LIB} oldnames)
|
||||
add_importlibs(crypt32 user32 advapi32 msvcrt kernel32 ntdll)
|
||||
add_delay_importlibs(crypt32 cryptnet)
|
||||
add_pch(crypt32 crypt32_private.h SOURCE)
|
||||
add_cd_file(TARGET crypt32 DESTINATION reactos/system32 FOR all)
|
||||
|
|
|
@ -29,7 +29,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
|||
* CertGetCertificateContextProperty, and are particular to the store in which
|
||||
* the property exists (which is separate from the context.)
|
||||
*/
|
||||
static BOOL CertContext_GetProperty(void *context, DWORD dwPropId,
|
||||
static BOOL CertContext_GetProperty(cert_t *cert, DWORD dwPropId,
|
||||
void *pvData, DWORD *pcbData);
|
||||
|
||||
/* Internal version of CertSetCertificateContextProperty that sets properties
|
||||
|
@ -37,7 +37,7 @@ static BOOL CertContext_GetProperty(void *context, DWORD dwPropId,
|
|||
* type.) Doesn't handle special cases, since they're handled by
|
||||
* CertSetCertificateContextProperty anyway.
|
||||
*/
|
||||
static BOOL CertContext_SetProperty(void *context, DWORD dwPropId,
|
||||
static BOOL CertContext_SetProperty(cert_t *cert, DWORD dwPropId,
|
||||
DWORD dwFlags, const void *pvData);
|
||||
|
||||
BOOL WINAPI CertAddEncodedCertificateToStore(HCERTSTORE hCertStore,
|
||||
|
@ -100,12 +100,190 @@ 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;
|
||||
|
||||
CryptMemFree(cert->ctx.pbCertEncoded);
|
||||
LocalFree(cert->ctx.pCertInfo);
|
||||
}
|
||||
|
||||
static context_t *Cert_clone(context_t *context, WINECRYPT_CERTSTORE *store, BOOL use_link)
|
||||
{
|
||||
cert_t *cert;
|
||||
|
||||
if(use_link) {
|
||||
cert = (cert_t*)Context_CreateLinkContext(sizeof(CERT_CONTEXT), context, store);
|
||||
if(!cert)
|
||||
return NULL;
|
||||
}else {
|
||||
const cert_t *cloned = (const cert_t*)context;
|
||||
DWORD size = 0;
|
||||
BOOL res;
|
||||
|
||||
cert = (cert_t*)Context_CreateDataContext(sizeof(CERT_CONTEXT), &cert_vtbl, store);
|
||||
if(!cert)
|
||||
return NULL;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static const context_vtbl_t cert_vtbl = {
|
||||
Cert_free,
|
||||
Cert_clone
|
||||
};
|
||||
|
||||
static BOOL add_cert_to_store(WINECRYPT_CERTSTORE *store, const CERT_CONTEXT *cert,
|
||||
DWORD add_disposition, BOOL use_link, PCCERT_CONTEXT *ret_context)
|
||||
{
|
||||
const CERT_CONTEXT *existing = NULL;
|
||||
BOOL ret = TRUE, inherit_props = FALSE;
|
||||
context_t *new_context = NULL;
|
||||
|
||||
switch (add_disposition)
|
||||
{
|
||||
case CERT_STORE_ADD_ALWAYS:
|
||||
break;
|
||||
case CERT_STORE_ADD_NEW:
|
||||
case CERT_STORE_ADD_REPLACE_EXISTING:
|
||||
case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
|
||||
case CERT_STORE_ADD_USE_EXISTING:
|
||||
case CERT_STORE_ADD_NEWER:
|
||||
case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES:
|
||||
{
|
||||
BYTE hashToAdd[20];
|
||||
DWORD size = sizeof(hashToAdd);
|
||||
|
||||
ret = CertGetCertificateContextProperty(cert, CERT_HASH_PROP_ID,
|
||||
hashToAdd, &size);
|
||||
if (ret)
|
||||
{
|
||||
CRYPT_HASH_BLOB blob = { sizeof(hashToAdd), hashToAdd };
|
||||
|
||||
existing = CertFindCertificateInStore(store, cert->dwCertEncodingType, 0,
|
||||
CERT_FIND_SHA1_HASH, &blob, NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
FIXME("Unimplemented add disposition %d\n", add_disposition);
|
||||
SetLastError(E_INVALIDARG);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
switch (add_disposition)
|
||||
{
|
||||
case CERT_STORE_ADD_ALWAYS:
|
||||
break;
|
||||
case CERT_STORE_ADD_NEW:
|
||||
if (existing)
|
||||
{
|
||||
TRACE("found matching certificate, not adding\n");
|
||||
SetLastError(CRYPT_E_EXISTS);
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case CERT_STORE_ADD_REPLACE_EXISTING:
|
||||
break;
|
||||
case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
|
||||
if (use_link)
|
||||
FIXME("CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES: semi-stub for links\n");
|
||||
if (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, cert);
|
||||
if (ret_context)
|
||||
*ret_context = CertDuplicateCertificateContext(existing);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case CERT_STORE_ADD_NEWER:
|
||||
if (existing && CompareFileTime(&existing->pCertInfo->NotBefore, &cert->pCertInfo->NotBefore) >= 0)
|
||||
{
|
||||
TRACE("existing certificate is newer, not adding\n");
|
||||
SetLastError(CRYPT_E_EXISTS);
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES:
|
||||
if (existing)
|
||||
{
|
||||
if (CompareFileTime(&existing->pCertInfo->NotBefore, &cert->pCertInfo->NotBefore) >= 0)
|
||||
{
|
||||
TRACE("existing certificate is newer, not adding\n");
|
||||
SetLastError(CRYPT_E_EXISTS);
|
||||
return FALSE;
|
||||
}
|
||||
inherit_props = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
ret = store->vtbl->certs.addContext(store, context_from_ptr(cert), existing ? context_from_ptr(existing) : NULL,
|
||||
(ret_context || inherit_props) ? &new_context : NULL, use_link);
|
||||
if(!ret)
|
||||
return FALSE;
|
||||
|
||||
if(inherit_props)
|
||||
Context_CopyProperties(context_ptr(new_context), existing);
|
||||
|
||||
if(ret_context)
|
||||
*ret_context = context_ptr(new_context);
|
||||
else if(new_context)
|
||||
Context_Release(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)
|
||||
{
|
||||
static int calls;
|
||||
PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
|
||||
WINECRYPT_CERTSTORE *store = (WINECRYPT_CERTSTORE*)hCertStore;
|
||||
|
||||
if (!(calls++))
|
||||
FIXME("(%p, %p, %08x, %p): semi-stub\n", hCertStore, pCertContext,
|
||||
|
@ -117,14 +295,14 @@ 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,
|
||||
const BYTE *pbCertEncoded, DWORD cbCertEncoded)
|
||||
{
|
||||
PCERT_CONTEXT cert = NULL;
|
||||
cert_t *cert = NULL;
|
||||
BYTE *data = NULL;
|
||||
BOOL ret;
|
||||
PCERT_INFO certInfo = NULL;
|
||||
DWORD size = 0;
|
||||
|
@ -141,81 +319,65 @@ PCCERT_CONTEXT WINAPI CertCreateCertificateContext(DWORD dwCertEncodingType,
|
|||
ret = CryptDecodeObjectEx(dwCertEncodingType, X509_CERT_TO_BE_SIGNED,
|
||||
pbCertEncoded, cbCertEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
|
||||
&certInfo, &size);
|
||||
if (ret)
|
||||
{
|
||||
BYTE *data = NULL;
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
cert = Context_CreateDataContext(sizeof(CERT_CONTEXT));
|
||||
if (!cert)
|
||||
goto end;
|
||||
data = CryptMemAlloc(cbCertEncoded);
|
||||
if (!data)
|
||||
{
|
||||
CertFreeCertificateContext(cert);
|
||||
cert = NULL;
|
||||
goto end;
|
||||
}
|
||||
memcpy(data, pbCertEncoded, cbCertEncoded);
|
||||
cert->dwCertEncodingType = dwCertEncodingType;
|
||||
cert->pbCertEncoded = data;
|
||||
cert->cbCertEncoded = cbCertEncoded;
|
||||
cert->pCertInfo = certInfo;
|
||||
cert->hCertStore = 0;
|
||||
cert = (cert_t*)Context_CreateDataContext(sizeof(CERT_CONTEXT), &cert_vtbl, &empty_store);
|
||||
if (!cert)
|
||||
return NULL;
|
||||
data = CryptMemAlloc(cbCertEncoded);
|
||||
if (!data)
|
||||
{
|
||||
Context_Release(&cert->base);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
end:
|
||||
return cert;
|
||||
memcpy(data, pbCertEncoded, cbCertEncoded);
|
||||
cert->ctx.dwCertEncodingType = dwCertEncodingType;
|
||||
cert->ctx.pbCertEncoded = data;
|
||||
cert->ctx.cbCertEncoded = cbCertEncoded;
|
||||
cert->ctx.pCertInfo = certInfo;
|
||||
cert->ctx.hCertStore = &empty_store;
|
||||
|
||||
return &cert->ctx;
|
||||
}
|
||||
|
||||
PCCERT_CONTEXT WINAPI CertDuplicateCertificateContext(
|
||||
PCCERT_CONTEXT pCertContext)
|
||||
PCCERT_CONTEXT WINAPI CertDuplicateCertificateContext(PCCERT_CONTEXT pCertContext)
|
||||
{
|
||||
TRACE("(%p)\n", pCertContext);
|
||||
|
||||
if (!pCertContext)
|
||||
return NULL;
|
||||
|
||||
Context_AddRef((void *)pCertContext, sizeof(CERT_CONTEXT));
|
||||
Context_AddRef(&cert_from_ptr(pCertContext)->base);
|
||||
return pCertContext;
|
||||
}
|
||||
|
||||
static void CertDataContext_Free(void *context)
|
||||
{
|
||||
PCERT_CONTEXT certContext = context;
|
||||
|
||||
CryptMemFree(certContext->pbCertEncoded);
|
||||
LocalFree(certContext->pCertInfo);
|
||||
}
|
||||
|
||||
BOOL WINAPI CertFreeCertificateContext(PCCERT_CONTEXT pCertContext)
|
||||
{
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(%p)\n", pCertContext);
|
||||
|
||||
if (pCertContext)
|
||||
ret = Context_Release((void *)pCertContext, sizeof(CERT_CONTEXT),
|
||||
CertDataContext_Free);
|
||||
return ret;
|
||||
Context_Release(&cert_from_ptr(pCertContext)->base);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DWORD WINAPI CertEnumCertificateContextProperties(PCCERT_CONTEXT pCertContext,
|
||||
DWORD dwPropId)
|
||||
{
|
||||
PCONTEXT_PROPERTY_LIST properties = Context_GetProperties(
|
||||
pCertContext, sizeof(CERT_CONTEXT));
|
||||
cert_t *cert = cert_from_ptr(pCertContext);
|
||||
DWORD ret;
|
||||
|
||||
TRACE("(%p, %d)\n", pCertContext, dwPropId);
|
||||
|
||||
if (properties)
|
||||
ret = ContextPropertyList_EnumPropIDs(properties, dwPropId);
|
||||
if (cert->base.properties)
|
||||
ret = ContextPropertyList_EnumPropIDs(cert->base.properties, dwPropId);
|
||||
else
|
||||
ret = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CertContext_GetHashProp(void *context, DWORD dwPropId,
|
||||
static BOOL CertContext_GetHashProp(cert_t *cert, DWORD dwPropId,
|
||||
ALG_ID algID, const BYTE *toHash, DWORD toHashLen, void *pvData,
|
||||
DWORD *pcbData)
|
||||
{
|
||||
|
@ -225,7 +387,7 @@ static BOOL CertContext_GetHashProp(void *context, DWORD dwPropId,
|
|||
{
|
||||
CRYPT_DATA_BLOB blob = { *pcbData, pvData };
|
||||
|
||||
ret = CertContext_SetProperty(context, dwPropId, 0, &blob);
|
||||
ret = CertContext_SetProperty(cert, dwPropId, 0, &blob);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -251,19 +413,16 @@ static BOOL CertContext_CopyParam(void *pvData, DWORD *pcbData, const void *pb,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CertContext_GetProperty(void *context, DWORD dwPropId,
|
||||
static BOOL CertContext_GetProperty(cert_t *cert, DWORD dwPropId,
|
||||
void *pvData, DWORD *pcbData)
|
||||
{
|
||||
PCCERT_CONTEXT pCertContext = context;
|
||||
PCONTEXT_PROPERTY_LIST properties =
|
||||
Context_GetProperties(context, sizeof(CERT_CONTEXT));
|
||||
BOOL ret;
|
||||
CRYPT_DATA_BLOB blob;
|
||||
|
||||
TRACE("(%p, %d, %p, %p)\n", context, dwPropId, pvData, pcbData);
|
||||
TRACE("(%p, %d, %p, %p)\n", cert, dwPropId, pvData, pcbData);
|
||||
|
||||
if (properties)
|
||||
ret = ContextPropertyList_FindProperty(properties, dwPropId, &blob);
|
||||
if (cert->base.properties)
|
||||
ret = ContextPropertyList_FindProperty(cert->base.properties, dwPropId, &blob);
|
||||
else
|
||||
ret = FALSE;
|
||||
if (ret)
|
||||
|
@ -274,49 +433,49 @@ static BOOL CertContext_GetProperty(void *context, DWORD dwPropId,
|
|||
switch (dwPropId)
|
||||
{
|
||||
case CERT_SHA1_HASH_PROP_ID:
|
||||
ret = CertContext_GetHashProp(context, dwPropId, CALG_SHA1,
|
||||
pCertContext->pbCertEncoded, pCertContext->cbCertEncoded, pvData,
|
||||
ret = CertContext_GetHashProp(cert, dwPropId, CALG_SHA1,
|
||||
cert->ctx.pbCertEncoded, cert->ctx.cbCertEncoded, pvData,
|
||||
pcbData);
|
||||
break;
|
||||
case CERT_MD5_HASH_PROP_ID:
|
||||
ret = CertContext_GetHashProp(context, dwPropId, CALG_MD5,
|
||||
pCertContext->pbCertEncoded, pCertContext->cbCertEncoded, pvData,
|
||||
ret = CertContext_GetHashProp(cert, dwPropId, CALG_MD5,
|
||||
cert->ctx.pbCertEncoded, cert->ctx.cbCertEncoded, pvData,
|
||||
pcbData);
|
||||
break;
|
||||
case CERT_SUBJECT_NAME_MD5_HASH_PROP_ID:
|
||||
ret = CertContext_GetHashProp(context, dwPropId, CALG_MD5,
|
||||
pCertContext->pCertInfo->Subject.pbData,
|
||||
pCertContext->pCertInfo->Subject.cbData,
|
||||
ret = CertContext_GetHashProp(cert, dwPropId, CALG_MD5,
|
||||
cert->ctx.pCertInfo->Subject.pbData,
|
||||
cert->ctx.pCertInfo->Subject.cbData,
|
||||
pvData, pcbData);
|
||||
break;
|
||||
case CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID:
|
||||
ret = CertContext_GetHashProp(context, dwPropId, CALG_MD5,
|
||||
pCertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData,
|
||||
pCertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData,
|
||||
ret = CertContext_GetHashProp(cert, dwPropId, CALG_MD5,
|
||||
cert->ctx.pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData,
|
||||
cert->ctx.pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData,
|
||||
pvData, pcbData);
|
||||
break;
|
||||
case CERT_ISSUER_SERIAL_NUMBER_MD5_HASH_PROP_ID:
|
||||
ret = CertContext_GetHashProp(context, dwPropId, CALG_MD5,
|
||||
pCertContext->pCertInfo->SerialNumber.pbData,
|
||||
pCertContext->pCertInfo->SerialNumber.cbData,
|
||||
ret = CertContext_GetHashProp(cert, dwPropId, CALG_MD5,
|
||||
cert->ctx.pCertInfo->SerialNumber.pbData,
|
||||
cert->ctx.pCertInfo->SerialNumber.cbData,
|
||||
pvData, pcbData);
|
||||
break;
|
||||
case CERT_SIGNATURE_HASH_PROP_ID:
|
||||
ret = CryptHashToBeSigned(0, pCertContext->dwCertEncodingType,
|
||||
pCertContext->pbCertEncoded, pCertContext->cbCertEncoded, pvData,
|
||||
ret = CryptHashToBeSigned(0, cert->ctx.dwCertEncodingType,
|
||||
cert->ctx.pbCertEncoded, cert->ctx.cbCertEncoded, pvData,
|
||||
pcbData);
|
||||
if (ret && pvData)
|
||||
{
|
||||
CRYPT_DATA_BLOB blob = { *pcbData, pvData };
|
||||
|
||||
ret = CertContext_SetProperty(context, dwPropId, 0, &blob);
|
||||
ret = CertContext_SetProperty(cert, dwPropId, 0, &blob);
|
||||
}
|
||||
break;
|
||||
case CERT_KEY_IDENTIFIER_PROP_ID:
|
||||
{
|
||||
PCERT_EXTENSION ext = CertFindExtension(
|
||||
szOID_SUBJECT_KEY_IDENTIFIER, pCertContext->pCertInfo->cExtension,
|
||||
pCertContext->pCertInfo->rgExtension);
|
||||
szOID_SUBJECT_KEY_IDENTIFIER, cert->ctx.pCertInfo->cExtension,
|
||||
cert->ctx.pCertInfo->rgExtension);
|
||||
|
||||
if (ext)
|
||||
{
|
||||
|
@ -331,7 +490,7 @@ static BOOL CertContext_GetProperty(void *context, DWORD dwPropId,
|
|||
{
|
||||
ret = CertContext_CopyParam(pvData, pcbData, value.pbData,
|
||||
value.cbData);
|
||||
CertContext_SetProperty(context, dwPropId, 0, &value);
|
||||
CertContext_SetProperty(cert, dwPropId, 0, &value);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -372,6 +531,7 @@ void CRYPT_FixKeyProvInfoPointers(PCRYPT_KEY_PROV_INFO info)
|
|||
BOOL WINAPI CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext,
|
||||
DWORD dwPropId, void *pvData, DWORD *pcbData)
|
||||
{
|
||||
cert_t *cert = cert_from_ptr(pCertContext);
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %d, %p, %p)\n", pCertContext, dwPropId, pvData, pcbData);
|
||||
|
@ -386,22 +546,14 @@ BOOL WINAPI CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext,
|
|||
ret = FALSE;
|
||||
break;
|
||||
case CERT_ACCESS_STATE_PROP_ID:
|
||||
if (pCertContext->hCertStore)
|
||||
ret = CertGetStoreProperty(pCertContext->hCertStore, dwPropId,
|
||||
pvData, pcbData);
|
||||
else
|
||||
{
|
||||
DWORD state = 0;
|
||||
|
||||
ret = CertContext_CopyParam(pvData, pcbData, &state, sizeof(state));
|
||||
}
|
||||
ret = CertGetStoreProperty(cert->ctx.hCertStore, dwPropId, pvData, pcbData);
|
||||
break;
|
||||
case CERT_KEY_PROV_HANDLE_PROP_ID:
|
||||
{
|
||||
CERT_KEY_CONTEXT keyContext;
|
||||
DWORD size = sizeof(keyContext);
|
||||
|
||||
ret = CertContext_GetProperty((void *)pCertContext,
|
||||
ret = CertContext_GetProperty(cert,
|
||||
CERT_KEY_CONTEXT_PROP_ID, &keyContext, &size);
|
||||
if (ret)
|
||||
ret = CertContext_CopyParam(pvData, pcbData, &keyContext.hCryptProv,
|
||||
|
@ -409,13 +561,13 @@ BOOL WINAPI CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext,
|
|||
break;
|
||||
}
|
||||
case CERT_KEY_PROV_INFO_PROP_ID:
|
||||
ret = CertContext_GetProperty((void *)pCertContext, dwPropId, pvData,
|
||||
ret = CertContext_GetProperty(cert, dwPropId, pvData,
|
||||
pcbData);
|
||||
if (ret && pvData)
|
||||
CRYPT_FixKeyProvInfoPointers(pvData);
|
||||
break;
|
||||
default:
|
||||
ret = CertContext_GetProperty((void *)pCertContext, dwPropId, pvData,
|
||||
ret = CertContext_GetProperty(cert, dwPropId, pvData,
|
||||
pcbData);
|
||||
}
|
||||
|
||||
|
@ -472,7 +624,7 @@ static void CRYPT_CopyKeyProvInfo(PCRYPT_KEY_PROV_INFO to,
|
|||
}
|
||||
}
|
||||
|
||||
static BOOL CertContext_SetKeyProvInfoProperty(PCONTEXT_PROPERTY_LIST properties,
|
||||
static BOOL CertContext_SetKeyProvInfoProperty(CONTEXT_PROPERTY_LIST *properties,
|
||||
const CRYPT_KEY_PROV_INFO *info)
|
||||
{
|
||||
BOOL ret;
|
||||
|
@ -503,16 +655,14 @@ static BOOL CertContext_SetKeyProvInfoProperty(PCONTEXT_PROPERTY_LIST properties
|
|||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CertContext_SetProperty(void *context, DWORD dwPropId,
|
||||
static BOOL CertContext_SetProperty(cert_t *cert, DWORD dwPropId,
|
||||
DWORD dwFlags, const void *pvData)
|
||||
{
|
||||
PCONTEXT_PROPERTY_LIST properties =
|
||||
Context_GetProperties(context, sizeof(CERT_CONTEXT));
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %d, %08x, %p)\n", context, dwPropId, dwFlags, pvData);
|
||||
TRACE("(%p, %d, %08x, %p)\n", cert, dwPropId, dwFlags, pvData);
|
||||
|
||||
if (!properties)
|
||||
if (!cert->base.properties)
|
||||
ret = FALSE;
|
||||
else
|
||||
{
|
||||
|
@ -541,23 +691,23 @@ static BOOL CertContext_SetProperty(void *context, DWORD dwPropId,
|
|||
{
|
||||
const CRYPT_DATA_BLOB *blob = pvData;
|
||||
|
||||
ret = ContextPropertyList_SetProperty(properties, dwPropId,
|
||||
ret = ContextPropertyList_SetProperty(cert->base.properties, dwPropId,
|
||||
blob->pbData, blob->cbData);
|
||||
}
|
||||
else
|
||||
{
|
||||
ContextPropertyList_RemoveProperty(properties, dwPropId);
|
||||
ContextPropertyList_RemoveProperty(cert->base.properties, dwPropId);
|
||||
ret = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CERT_DATE_STAMP_PROP_ID:
|
||||
if (pvData)
|
||||
ret = ContextPropertyList_SetProperty(properties, dwPropId,
|
||||
ret = ContextPropertyList_SetProperty(cert->base.properties, dwPropId,
|
||||
pvData, sizeof(FILETIME));
|
||||
else
|
||||
{
|
||||
ContextPropertyList_RemoveProperty(properties, dwPropId);
|
||||
ContextPropertyList_RemoveProperty(cert->base.properties, dwPropId);
|
||||
ret = TRUE;
|
||||
}
|
||||
break;
|
||||
|
@ -573,22 +723,22 @@ static BOOL CertContext_SetProperty(void *context, DWORD dwPropId,
|
|||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
ret = ContextPropertyList_SetProperty(properties, dwPropId,
|
||||
ret = ContextPropertyList_SetProperty(cert->base.properties, dwPropId,
|
||||
(const BYTE *)keyContext, keyContext->cbSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
ContextPropertyList_RemoveProperty(properties, dwPropId);
|
||||
ContextPropertyList_RemoveProperty(cert->base.properties, dwPropId);
|
||||
ret = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CERT_KEY_PROV_INFO_PROP_ID:
|
||||
if (pvData)
|
||||
ret = CertContext_SetKeyProvInfoProperty(properties, pvData);
|
||||
ret = CertContext_SetKeyProvInfoProperty(cert->base.properties, pvData);
|
||||
else
|
||||
{
|
||||
ContextPropertyList_RemoveProperty(properties, dwPropId);
|
||||
ContextPropertyList_RemoveProperty(cert->base.properties, dwPropId);
|
||||
ret = TRUE;
|
||||
}
|
||||
break;
|
||||
|
@ -597,7 +747,7 @@ static BOOL CertContext_SetProperty(void *context, DWORD dwPropId,
|
|||
CERT_KEY_CONTEXT keyContext;
|
||||
DWORD size = sizeof(keyContext);
|
||||
|
||||
ret = CertContext_GetProperty(context, CERT_KEY_CONTEXT_PROP_ID,
|
||||
ret = CertContext_GetProperty(cert, CERT_KEY_CONTEXT_PROP_ID,
|
||||
&keyContext, &size);
|
||||
if (ret)
|
||||
{
|
||||
|
@ -612,7 +762,7 @@ static BOOL CertContext_SetProperty(void *context, DWORD dwPropId,
|
|||
keyContext.hCryptProv = 0;
|
||||
keyContext.dwKeySpec = AT_SIGNATURE;
|
||||
}
|
||||
ret = CertContext_SetProperty(context, CERT_KEY_CONTEXT_PROP_ID,
|
||||
ret = CertContext_SetProperty(cert, CERT_KEY_CONTEXT_PROP_ID,
|
||||
0, &keyContext);
|
||||
break;
|
||||
}
|
||||
|
@ -645,7 +795,7 @@ BOOL WINAPI CertSetCertificateContextProperty(PCCERT_CONTEXT pCertContext,
|
|||
SetLastError(E_INVALIDARG);
|
||||
return FALSE;
|
||||
}
|
||||
ret = CertContext_SetProperty((void *)pCertContext, dwPropId, dwFlags,
|
||||
ret = CertContext_SetProperty(cert_from_ptr(pCertContext), dwPropId, dwFlags,
|
||||
pvData);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
|
@ -1307,6 +1457,8 @@ static BOOL compare_cert_by_cert_id(PCCERT_CONTEXT pCertContext, DWORD dwType,
|
|||
ret = !memcmp(buf, id->u.KeyId.pbData, size);
|
||||
CryptMemFree(buf);
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
|
@ -1347,6 +1499,8 @@ static BOOL compare_cert_by_signature_hash(PCCERT_CONTEXT pCertContext, DWORD dw
|
|||
ret = !memcmp(buf, hash->pbData, size);
|
||||
CryptMemFree(buf);
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
|
@ -1730,7 +1884,7 @@ typedef struct _OLD_CERT_REVOCATION_STATUS {
|
|||
DWORD dwIndex;
|
||||
DWORD dwError;
|
||||
DWORD dwReason;
|
||||
} OLD_CERT_REVOCATION_STATUS, *POLD_CERT_REVOCATION_STATUS;
|
||||
} OLD_CERT_REVOCATION_STATUS;
|
||||
|
||||
typedef BOOL (WINAPI *CertVerifyRevocationFunc)(DWORD, DWORD, DWORD,
|
||||
void **, DWORD, PCERT_REVOCATION_PARA, PCERT_REVOCATION_STATUS);
|
||||
|
@ -2216,10 +2370,14 @@ BOOL WINAPI CryptSignAndEncodeCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCrypt
|
|||
}
|
||||
CryptMemFree(hash);
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
CryptMemFree(encoded);
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -26,8 +26,6 @@ WINE_DECLARE_DEBUG_CHANNEL(chain);
|
|||
|
||||
#define DEFAULT_CYCLE_MODULUS 7
|
||||
|
||||
static HCERTCHAINENGINE CRYPT_defaultChainEngine;
|
||||
|
||||
/* This represents a subset of a certificate chain engine: it doesn't include
|
||||
* the "hOther" store described by MSDN, because I'm not sure how that's used.
|
||||
* It also doesn't include the "hTrust" store, because I don't yet implement
|
||||
|
@ -42,7 +40,7 @@ typedef struct _CertificateChainEngine
|
|||
DWORD dwUrlRetrievalTimeout;
|
||||
DWORD MaximumCachedCertificates;
|
||||
DWORD CycleDetectionModulus;
|
||||
} CertificateChainEngine, *PCertificateChainEngine;
|
||||
} CertificateChainEngine;
|
||||
|
||||
static inline void CRYPT_AddStoresToCollection(HCERTSTORE collection,
|
||||
DWORD cStores, HCERTSTORE *stores)
|
||||
|
@ -107,45 +105,102 @@ static BOOL CRYPT_CheckRestrictedRoot(HCERTSTORE store)
|
|||
return ret;
|
||||
}
|
||||
|
||||
HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE root,
|
||||
PCERT_CHAIN_ENGINE_CONFIG pConfig)
|
||||
HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE root, DWORD system_store, const CERT_CHAIN_ENGINE_CONFIG *config)
|
||||
{
|
||||
CertificateChainEngine *engine;
|
||||
HCERTSTORE worldStores[4];
|
||||
|
||||
static const WCHAR caW[] = { 'C','A',0 };
|
||||
static const WCHAR myW[] = { 'M','y',0 };
|
||||
static const WCHAR trustW[] = { 'T','r','u','s','t',0 };
|
||||
PCertificateChainEngine engine =
|
||||
CryptMemAlloc(sizeof(CertificateChainEngine));
|
||||
|
||||
if (engine)
|
||||
{
|
||||
HCERTSTORE worldStores[4];
|
||||
|
||||
engine->ref = 1;
|
||||
engine->hRoot = root;
|
||||
engine->hWorld = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
|
||||
CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
worldStores[0] = CertDuplicateStore(engine->hRoot);
|
||||
worldStores[1] = CertOpenSystemStoreW(0, caW);
|
||||
worldStores[2] = CertOpenSystemStoreW(0, myW);
|
||||
worldStores[3] = CertOpenSystemStoreW(0, trustW);
|
||||
CRYPT_AddStoresToCollection(engine->hWorld,
|
||||
sizeof(worldStores) / sizeof(worldStores[0]), worldStores);
|
||||
CRYPT_AddStoresToCollection(engine->hWorld,
|
||||
pConfig->cAdditionalStore, pConfig->rghAdditionalStore);
|
||||
CRYPT_CloseStores(sizeof(worldStores) / sizeof(worldStores[0]),
|
||||
worldStores);
|
||||
engine->dwFlags = pConfig->dwFlags;
|
||||
engine->dwUrlRetrievalTimeout = pConfig->dwUrlRetrievalTimeout;
|
||||
engine->MaximumCachedCertificates =
|
||||
pConfig->MaximumCachedCertificates;
|
||||
if (pConfig->CycleDetectionModulus)
|
||||
engine->CycleDetectionModulus = pConfig->CycleDetectionModulus;
|
||||
if(!root) {
|
||||
if(config->cbSize >= sizeof(CERT_CHAIN_ENGINE_CONFIG) && config->hExclusiveRoot)
|
||||
root = CertDuplicateStore(config->hExclusiveRoot);
|
||||
else if (config->hRestrictedRoot)
|
||||
root = CertDuplicateStore(config->hRestrictedRoot);
|
||||
else
|
||||
engine->CycleDetectionModulus = DEFAULT_CYCLE_MODULUS;
|
||||
root = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, rootW);
|
||||
if(!root)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
engine = CryptMemAlloc(sizeof(CertificateChainEngine));
|
||||
if(!engine) {
|
||||
CertCloseStore(root, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
engine->ref = 1;
|
||||
engine->hRoot = root;
|
||||
engine->hWorld = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
worldStores[0] = CertDuplicateStore(engine->hRoot);
|
||||
worldStores[1] = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, caW);
|
||||
worldStores[2] = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, myW);
|
||||
worldStores[3] = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, trustW);
|
||||
|
||||
CRYPT_AddStoresToCollection(engine->hWorld, sizeof(worldStores) / sizeof(worldStores[0]), worldStores);
|
||||
CRYPT_AddStoresToCollection(engine->hWorld, config->cAdditionalStore, config->rghAdditionalStore);
|
||||
CRYPT_CloseStores(sizeof(worldStores) / sizeof(worldStores[0]), worldStores);
|
||||
|
||||
engine->dwFlags = config->dwFlags;
|
||||
engine->dwUrlRetrievalTimeout = config->dwUrlRetrievalTimeout;
|
||||
engine->MaximumCachedCertificates = config->MaximumCachedCertificates;
|
||||
if(config->CycleDetectionModulus)
|
||||
engine->CycleDetectionModulus = config->CycleDetectionModulus;
|
||||
else
|
||||
engine->CycleDetectionModulus = DEFAULT_CYCLE_MODULUS;
|
||||
|
||||
return engine;
|
||||
}
|
||||
|
||||
static CertificateChainEngine *default_cu_engine, *default_lm_engine;
|
||||
|
||||
static CertificateChainEngine *get_chain_engine(HCERTCHAINENGINE handle, BOOL allow_default)
|
||||
{
|
||||
const CERT_CHAIN_ENGINE_CONFIG config = { sizeof(config) };
|
||||
|
||||
if(handle == HCCE_CURRENT_USER) {
|
||||
if(!allow_default)
|
||||
return NULL;
|
||||
|
||||
if(!default_cu_engine) {
|
||||
handle = CRYPT_CreateChainEngine(NULL, CERT_SYSTEM_STORE_CURRENT_USER, &config);
|
||||
InterlockedCompareExchangePointer((void**)&default_cu_engine, handle, NULL);
|
||||
if(default_cu_engine != handle)
|
||||
CertFreeCertificateChainEngine(handle);
|
||||
}
|
||||
|
||||
return default_cu_engine;
|
||||
}
|
||||
|
||||
if(handle == HCCE_LOCAL_MACHINE) {
|
||||
if(!allow_default)
|
||||
return NULL;
|
||||
|
||||
if(!default_lm_engine) {
|
||||
handle = CRYPT_CreateChainEngine(NULL, CERT_SYSTEM_STORE_LOCAL_MACHINE, &config);
|
||||
InterlockedCompareExchangePointer((void**)&default_lm_engine, handle, NULL);
|
||||
if(default_lm_engine != handle)
|
||||
CertFreeCertificateChainEngine(handle);
|
||||
}
|
||||
|
||||
return default_lm_engine;
|
||||
}
|
||||
|
||||
return (CertificateChainEngine*)handle;
|
||||
}
|
||||
|
||||
static void free_chain_engine(CertificateChainEngine *engine)
|
||||
{
|
||||
if(!engine || InterlockedDecrement(&engine->ref))
|
||||
return;
|
||||
|
||||
CertCloseStore(engine->hWorld, 0);
|
||||
CertCloseStore(engine->hRoot, 0);
|
||||
CryptMemFree(engine);
|
||||
}
|
||||
|
||||
typedef struct _CERT_CHAIN_ENGINE_CONFIG_NO_EXCLUSIVE_ROOT
|
||||
{
|
||||
DWORD cbSize;
|
||||
|
@ -173,66 +228,27 @@ BOOL WINAPI CertCreateCertificateChainEngine(PCERT_CHAIN_ENGINE_CONFIG pConfig,
|
|||
SetLastError(E_INVALIDARG);
|
||||
return FALSE;
|
||||
}
|
||||
*phChainEngine = NULL;
|
||||
ret = CRYPT_CheckRestrictedRoot(pConfig->hRestrictedRoot);
|
||||
if (ret)
|
||||
if (!ret)
|
||||
{
|
||||
HCERTSTORE root;
|
||||
HCERTCHAINENGINE engine;
|
||||
|
||||
if (pConfig->cbSize >= sizeof(CERT_CHAIN_ENGINE_CONFIG) &&
|
||||
pConfig->hExclusiveRoot)
|
||||
root = CertDuplicateStore(pConfig->hExclusiveRoot);
|
||||
else if (pConfig->hRestrictedRoot)
|
||||
root = CertDuplicateStore(pConfig->hRestrictedRoot);
|
||||
else
|
||||
root = CertOpenSystemStoreW(0, rootW);
|
||||
engine = CRYPT_CreateChainEngine(root, pConfig);
|
||||
if (engine)
|
||||
{
|
||||
*phChainEngine = engine;
|
||||
ret = TRUE;
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
*phChainEngine = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
return ret;
|
||||
|
||||
*phChainEngine = CRYPT_CreateChainEngine(NULL, CERT_SYSTEM_STORE_CURRENT_USER, pConfig);
|
||||
return *phChainEngine != NULL;
|
||||
}
|
||||
|
||||
VOID WINAPI CertFreeCertificateChainEngine(HCERTCHAINENGINE hChainEngine)
|
||||
void WINAPI CertFreeCertificateChainEngine(HCERTCHAINENGINE hChainEngine)
|
||||
{
|
||||
PCertificateChainEngine engine = (PCertificateChainEngine)hChainEngine;
|
||||
|
||||
TRACE("(%p)\n", hChainEngine);
|
||||
|
||||
if (engine && InterlockedDecrement(&engine->ref) == 0)
|
||||
{
|
||||
CertCloseStore(engine->hWorld, 0);
|
||||
CertCloseStore(engine->hRoot, 0);
|
||||
CryptMemFree(engine);
|
||||
}
|
||||
}
|
||||
|
||||
static HCERTCHAINENGINE CRYPT_GetDefaultChainEngine(void)
|
||||
{
|
||||
if (!CRYPT_defaultChainEngine)
|
||||
{
|
||||
CERT_CHAIN_ENGINE_CONFIG config = { 0 };
|
||||
HCERTCHAINENGINE engine;
|
||||
|
||||
config.cbSize = sizeof(config);
|
||||
CertCreateCertificateChainEngine(&config, &engine);
|
||||
InterlockedCompareExchangePointer(&CRYPT_defaultChainEngine, engine,
|
||||
NULL);
|
||||
if (CRYPT_defaultChainEngine != engine)
|
||||
CertFreeCertificateChainEngine(engine);
|
||||
}
|
||||
return CRYPT_defaultChainEngine;
|
||||
free_chain_engine(get_chain_engine(hChainEngine, FALSE));
|
||||
}
|
||||
|
||||
void default_chain_engine_free(void)
|
||||
{
|
||||
CertFreeCertificateChainEngine(CRYPT_defaultChainEngine);
|
||||
free_chain_engine(default_cu_engine);
|
||||
free_chain_engine(default_lm_engine);
|
||||
}
|
||||
|
||||
typedef struct _CertificateChain
|
||||
|
@ -240,7 +256,7 @@ typedef struct _CertificateChain
|
|||
CERT_CHAIN_CONTEXT context;
|
||||
HCERTSTORE world;
|
||||
LONG ref;
|
||||
} CertificateChain, *PCertificateChain;
|
||||
} CertificateChain;
|
||||
|
||||
static BOOL CRYPT_IsCertificateSelfSigned(PCCERT_CONTEXT cert)
|
||||
{
|
||||
|
@ -299,6 +315,8 @@ static BOOL CRYPT_IsCertificateSelfSigned(PCCERT_CONTEXT cert)
|
|||
ret = !memcmp(buf, info->KeyId.pbData, size);
|
||||
CryptMemFree(buf);
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
|
@ -470,7 +488,7 @@ static void CRYPT_CheckTrustedStatus(HCERTSTORE hRoot,
|
|||
CertFreeCertificateContext(trustedRoot);
|
||||
}
|
||||
|
||||
static void CRYPT_CheckRootCert(HCERTCHAINENGINE hRoot,
|
||||
static void CRYPT_CheckRootCert(HCERTSTORE hRoot,
|
||||
PCERT_CHAIN_ELEMENT rootElement)
|
||||
{
|
||||
PCCERT_CONTEXT root = rootElement->pCertContext;
|
||||
|
@ -559,7 +577,7 @@ static BOOL CRYPT_DecodeBasicConstraints(PCCERT_CONTEXT cert,
|
|||
* Returns TRUE if the element can be a CA, and the length of the remaining
|
||||
* chain is valid.
|
||||
*/
|
||||
static BOOL CRYPT_CheckBasicConstraintsForCA(PCertificateChainEngine engine,
|
||||
static BOOL CRYPT_CheckBasicConstraintsForCA(CertificateChainEngine *engine,
|
||||
PCCERT_CONTEXT cert, CERT_BASIC_CONSTRAINTS2_INFO *chainConstraints,
|
||||
DWORD remainingCAs, BOOL isRoot, BOOL *pathLengthConstraintViolated)
|
||||
{
|
||||
|
@ -1705,7 +1723,7 @@ static void dump_element(PCCERT_CONTEXT cert)
|
|||
dump_extension(&cert->pCertInfo->rgExtension[i]);
|
||||
}
|
||||
|
||||
static BOOL CRYPT_KeyUsageValid(PCertificateChainEngine engine,
|
||||
static BOOL CRYPT_KeyUsageValid(CertificateChainEngine *engine,
|
||||
PCCERT_CONTEXT cert, BOOL isRoot, BOOL isCA, DWORD index)
|
||||
{
|
||||
PCERT_EXTENSION ext;
|
||||
|
@ -1861,7 +1879,7 @@ static BOOL CRYPT_IsCertVersionValid(PCCERT_CONTEXT cert)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void CRYPT_CheckSimpleChain(PCertificateChainEngine engine,
|
||||
static void CRYPT_CheckSimpleChain(CertificateChainEngine *engine,
|
||||
PCERT_SIMPLE_CHAIN chain, LPFILETIME time)
|
||||
{
|
||||
PCERT_CHAIN_ELEMENT rootElement = chain->rgpElement[chain->cElement - 1];
|
||||
|
@ -1964,8 +1982,83 @@ static void CRYPT_CheckSimpleChain(PCertificateChainEngine engine,
|
|||
CRYPT_CombineTrustStatus(&chain->TrustStatus, &rootElement->TrustStatus);
|
||||
}
|
||||
|
||||
static PCCERT_CONTEXT CRYPT_GetIssuer(HCERTSTORE store, PCCERT_CONTEXT subject,
|
||||
PCCERT_CONTEXT prevIssuer, DWORD *infoStatus)
|
||||
static PCCERT_CONTEXT CRYPT_FindIssuer(const CertificateChainEngine *engine, const CERT_CONTEXT *cert,
|
||||
HCERTSTORE store, DWORD type, void *para, DWORD flags, 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) {
|
||||
TRACE("Found in store %p\n", issuer);
|
||||
return issuer;
|
||||
}
|
||||
|
||||
/* FIXME: For alternate issuers, we don't search world store nor try to retrieve issuer from URL.
|
||||
* This needs more tests.
|
||||
*/
|
||||
if(prev_issuer)
|
||||
return NULL;
|
||||
|
||||
if(engine->hWorld) {
|
||||
issuer = CertFindCertificateInStore(engine->hWorld, cert->dwCertEncodingType, 0, type, para, NULL);
|
||||
if(issuer) {
|
||||
TRACE("Found in world %p\n", issuer);
|
||||
return issuer;
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
(flags & CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL) ? CRYPT_CACHE_ONLY_RETRIEVAL : CRYPT_AIA_RETRIEVAL,
|
||||
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,
|
||||
HCERTSTORE store, PCCERT_CONTEXT subject, PCCERT_CONTEXT prevIssuer,
|
||||
DWORD flags, DWORD *infoStatus)
|
||||
{
|
||||
PCCERT_CONTEXT issuer = NULL;
|
||||
PCERT_EXTENSION ext;
|
||||
|
@ -1993,9 +2086,8 @@ static PCCERT_CONTEXT CRYPT_GetIssuer(HCERTSTORE store, PCCERT_CONTEXT subject,
|
|||
sizeof(CERT_NAME_BLOB));
|
||||
memcpy(&id.u.IssuerSerialNumber.SerialNumber,
|
||||
&info->CertSerialNumber, sizeof(CRYPT_INTEGER_BLOB));
|
||||
issuer = CertFindCertificateInStore(store,
|
||||
subject->dwCertEncodingType, 0, CERT_FIND_CERT_ID, &id,
|
||||
prevIssuer);
|
||||
|
||||
issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_CERT_ID, &id, flags, prevIssuer);
|
||||
if (issuer)
|
||||
{
|
||||
TRACE_(chain)("issuer found by issuer/serial number\n");
|
||||
|
@ -2005,10 +2097,9 @@ static PCCERT_CONTEXT CRYPT_GetIssuer(HCERTSTORE store, PCCERT_CONTEXT subject,
|
|||
else if (info->KeyId.cbData)
|
||||
{
|
||||
id.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
|
||||
|
||||
memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB));
|
||||
issuer = CertFindCertificateInStore(store,
|
||||
subject->dwCertEncodingType, 0, CERT_FIND_CERT_ID, &id,
|
||||
prevIssuer);
|
||||
issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_CERT_ID, &id, flags, prevIssuer);
|
||||
if (issuer)
|
||||
{
|
||||
TRACE_(chain)("issuer found by key id\n");
|
||||
|
@ -2052,9 +2143,8 @@ static PCCERT_CONTEXT CRYPT_GetIssuer(HCERTSTORE store, PCCERT_CONTEXT subject,
|
|||
memcpy(&id.u.IssuerSerialNumber.SerialNumber,
|
||||
&info->AuthorityCertSerialNumber,
|
||||
sizeof(CRYPT_INTEGER_BLOB));
|
||||
issuer = CertFindCertificateInStore(store,
|
||||
subject->dwCertEncodingType, 0, CERT_FIND_CERT_ID, &id,
|
||||
prevIssuer);
|
||||
|
||||
issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_CERT_ID, &id, flags, prevIssuer);
|
||||
if (issuer)
|
||||
{
|
||||
TRACE_(chain)("issuer found by directory name\n");
|
||||
|
@ -2068,9 +2158,7 @@ static PCCERT_CONTEXT CRYPT_GetIssuer(HCERTSTORE store, PCCERT_CONTEXT subject,
|
|||
{
|
||||
id.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
|
||||
memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB));
|
||||
issuer = CertFindCertificateInStore(store,
|
||||
subject->dwCertEncodingType, 0, CERT_FIND_CERT_ID, &id,
|
||||
prevIssuer);
|
||||
issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_CERT_ID, &id, flags, prevIssuer);
|
||||
if (issuer)
|
||||
{
|
||||
TRACE_(chain)("issuer found by key id\n");
|
||||
|
@ -2082,9 +2170,8 @@ static PCCERT_CONTEXT CRYPT_GetIssuer(HCERTSTORE store, PCCERT_CONTEXT subject,
|
|||
}
|
||||
else
|
||||
{
|
||||
issuer = CertFindCertificateInStore(store,
|
||||
subject->dwCertEncodingType, 0, CERT_FIND_SUBJECT_NAME,
|
||||
&subject->pCertInfo->Issuer, prevIssuer);
|
||||
issuer = CRYPT_FindIssuer(engine, subject, store, CERT_FIND_SUBJECT_NAME,
|
||||
&subject->pCertInfo->Issuer, flags, prevIssuer);
|
||||
TRACE_(chain)("issuer found by name\n");
|
||||
*infoStatus = CERT_TRUST_HAS_NAME_MATCH_ISSUER;
|
||||
}
|
||||
|
@ -2095,7 +2182,7 @@ static PCCERT_CONTEXT CRYPT_GetIssuer(HCERTSTORE store, PCCERT_CONTEXT subject,
|
|||
* until reaching a self-signed cert, or until no issuer can be found.
|
||||
*/
|
||||
static BOOL CRYPT_BuildSimpleChain(const CertificateChainEngine *engine,
|
||||
HCERTSTORE world, PCERT_SIMPLE_CHAIN chain)
|
||||
HCERTSTORE world, DWORD flags, PCERT_SIMPLE_CHAIN chain)
|
||||
{
|
||||
BOOL ret = TRUE;
|
||||
PCCERT_CONTEXT cert = chain->rgpElement[chain->cElement - 1]->pCertContext;
|
||||
|
@ -2103,7 +2190,7 @@ static BOOL CRYPT_BuildSimpleChain(const CertificateChainEngine *engine,
|
|||
while (ret && !CRYPT_IsSimpleChainCyclic(chain) &&
|
||||
!CRYPT_IsCertificateSelfSigned(cert))
|
||||
{
|
||||
PCCERT_CONTEXT issuer = CRYPT_GetIssuer(world, cert, NULL,
|
||||
PCCERT_CONTEXT issuer = CRYPT_GetIssuer(engine, world, cert, NULL, flags,
|
||||
&chain->rgpElement[chain->cElement - 1]->TrustStatus.dwInfoStatus);
|
||||
|
||||
if (issuer)
|
||||
|
@ -2133,8 +2220,8 @@ static LPCSTR debugstr_filetime(LPFILETIME pTime)
|
|||
return wine_dbg_sprintf("%p (%s)", pTime, filetime_to_str(pTime));
|
||||
}
|
||||
|
||||
static BOOL CRYPT_GetSimpleChainForCert(PCertificateChainEngine engine,
|
||||
HCERTSTORE world, PCCERT_CONTEXT cert, LPFILETIME pTime,
|
||||
static BOOL CRYPT_GetSimpleChainForCert(CertificateChainEngine *engine,
|
||||
HCERTSTORE world, PCCERT_CONTEXT cert, LPFILETIME pTime, DWORD flags,
|
||||
PCERT_SIMPLE_CHAIN *ppChain)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
|
@ -2150,7 +2237,7 @@ static BOOL CRYPT_GetSimpleChainForCert(PCertificateChainEngine engine,
|
|||
ret = CRYPT_AddCertToSimpleChain(engine, chain, cert, 0);
|
||||
if (ret)
|
||||
{
|
||||
ret = CRYPT_BuildSimpleChain(engine, world, chain);
|
||||
ret = CRYPT_BuildSimpleChain(engine, world, flags, chain);
|
||||
if (ret)
|
||||
CRYPT_CheckSimpleChain(engine, chain, pTime);
|
||||
}
|
||||
|
@ -2164,11 +2251,10 @@ static BOOL CRYPT_GetSimpleChainForCert(PCertificateChainEngine engine,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_BuildCandidateChainFromCert(HCERTCHAINENGINE hChainEngine,
|
||||
PCCERT_CONTEXT cert, LPFILETIME pTime, HCERTSTORE hAdditionalStore,
|
||||
PCertificateChain *ppChain)
|
||||
static BOOL CRYPT_BuildCandidateChainFromCert(CertificateChainEngine *engine,
|
||||
PCCERT_CONTEXT cert, LPFILETIME pTime, HCERTSTORE hAdditionalStore, DWORD flags,
|
||||
CertificateChain **ppChain)
|
||||
{
|
||||
PCertificateChainEngine engine = (PCertificateChainEngine)hChainEngine;
|
||||
PCERT_SIMPLE_CHAIN simpleChain = NULL;
|
||||
HCERTSTORE world;
|
||||
BOOL ret;
|
||||
|
@ -2181,10 +2267,9 @@ static BOOL CRYPT_BuildCandidateChainFromCert(HCERTCHAINENGINE hChainEngine,
|
|||
/* FIXME: only simple chains are supported for now, as CTLs aren't
|
||||
* supported yet.
|
||||
*/
|
||||
if ((ret = CRYPT_GetSimpleChainForCert(engine, world, cert, pTime,
|
||||
&simpleChain)))
|
||||
if ((ret = CRYPT_GetSimpleChainForCert(engine, world, cert, pTime, flags, &simpleChain)))
|
||||
{
|
||||
PCertificateChain chain = CryptMemAlloc(sizeof(CertificateChain));
|
||||
CertificateChain *chain = CryptMemAlloc(sizeof(CertificateChain));
|
||||
|
||||
if (chain)
|
||||
{
|
||||
|
@ -2263,7 +2348,7 @@ static PCERT_SIMPLE_CHAIN CRYPT_CopySimpleChainToElement(
|
|||
return copy;
|
||||
}
|
||||
|
||||
static void CRYPT_FreeLowerQualityChains(PCertificateChain chain)
|
||||
static void CRYPT_FreeLowerQualityChains(CertificateChain *chain)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
|
@ -2274,7 +2359,7 @@ static void CRYPT_FreeLowerQualityChains(PCertificateChain chain)
|
|||
chain->context.rgpLowerQualityChainContext = NULL;
|
||||
}
|
||||
|
||||
static void CRYPT_FreeChainContext(PCertificateChain chain)
|
||||
static void CRYPT_FreeChainContext(CertificateChain *chain)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
|
@ -2289,10 +2374,10 @@ static void CRYPT_FreeChainContext(PCertificateChain chain)
|
|||
/* Makes and returns a copy of chain, up to and including element iElement of
|
||||
* simple chain iChain.
|
||||
*/
|
||||
static PCertificateChain CRYPT_CopyChainToElement(PCertificateChain chain,
|
||||
static CertificateChain *CRYPT_CopyChainToElement(CertificateChain *chain,
|
||||
DWORD iChain, DWORD iElement)
|
||||
{
|
||||
PCertificateChain copy = CryptMemAlloc(sizeof(CertificateChain));
|
||||
CertificateChain *copy = CryptMemAlloc(sizeof(CertificateChain));
|
||||
|
||||
if (copy)
|
||||
{
|
||||
|
@ -2354,21 +2439,20 @@ static PCertificateChain CRYPT_CopyChainToElement(PCertificateChain chain,
|
|||
return copy;
|
||||
}
|
||||
|
||||
static PCertificateChain CRYPT_BuildAlternateContextFromChain(
|
||||
HCERTCHAINENGINE hChainEngine, LPFILETIME pTime, HCERTSTORE hAdditionalStore,
|
||||
PCertificateChain chain)
|
||||
static CertificateChain *CRYPT_BuildAlternateContextFromChain(
|
||||
CertificateChainEngine *engine, LPFILETIME pTime, HCERTSTORE hAdditionalStore,
|
||||
DWORD flags, CertificateChain *chain)
|
||||
{
|
||||
PCertificateChainEngine engine = (PCertificateChainEngine)hChainEngine;
|
||||
PCertificateChain alternate;
|
||||
CertificateChain *alternate;
|
||||
|
||||
TRACE("(%p, %s, %p, %p)\n", hChainEngine, debugstr_filetime(pTime),
|
||||
TRACE("(%p, %s, %p, %p)\n", engine, debugstr_filetime(pTime),
|
||||
hAdditionalStore, chain);
|
||||
|
||||
/* Always start with the last "lower quality" chain to ensure a consistent
|
||||
* order of alternate creation:
|
||||
*/
|
||||
if (chain->context.cLowerQualityChainContext)
|
||||
chain = (PCertificateChain)chain->context.rgpLowerQualityChainContext[
|
||||
chain = (CertificateChain*)chain->context.rgpLowerQualityChainContext[
|
||||
chain->context.cLowerQualityChainContext - 1];
|
||||
/* A chain with only one element can't have any alternates */
|
||||
if (chain->context.cChain <= 1 && chain->context.rgpChain[0]->cElement <= 1)
|
||||
|
@ -2388,8 +2472,8 @@ static PCertificateChain CRYPT_BuildAlternateContextFromChain(
|
|||
PCCERT_CONTEXT prevIssuer = CertDuplicateCertificateContext(
|
||||
chain->context.rgpChain[i]->rgpElement[j + 1]->pCertContext);
|
||||
|
||||
alternateIssuer = CRYPT_GetIssuer(prevIssuer->hCertStore,
|
||||
subject, prevIssuer, &infoStatus);
|
||||
alternateIssuer = CRYPT_GetIssuer(engine, prevIssuer->hCertStore,
|
||||
subject, prevIssuer, flags, &infoStatus);
|
||||
}
|
||||
if (alternateIssuer)
|
||||
{
|
||||
|
@ -2408,7 +2492,7 @@ static PCertificateChain CRYPT_BuildAlternateContextFromChain(
|
|||
if (ret)
|
||||
{
|
||||
ret = CRYPT_BuildSimpleChain(engine, alternate->world,
|
||||
alternate->context.rgpChain[i]);
|
||||
flags, alternate->context.rgpChain[i]);
|
||||
if (ret)
|
||||
CRYPT_CheckSimpleChain(engine,
|
||||
alternate->context.rgpChain[i], pTime);
|
||||
|
@ -2467,8 +2551,8 @@ static DWORD CRYPT_ChainQuality(const CertificateChain *chain)
|
|||
* alternate chains. Returns the highest quality chain, with all other
|
||||
* chains as lower quality chains of it.
|
||||
*/
|
||||
static PCertificateChain CRYPT_ChooseHighestQualityChain(
|
||||
PCertificateChain chain)
|
||||
static CertificateChain *CRYPT_ChooseHighestQualityChain(
|
||||
CertificateChain *chain)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
|
@ -2480,8 +2564,8 @@ static PCertificateChain CRYPT_ChooseHighestQualityChain(
|
|||
*/
|
||||
for (i = 0; i < chain->context.cLowerQualityChainContext; i++)
|
||||
{
|
||||
PCertificateChain alternate =
|
||||
(PCertificateChain)chain->context.rgpLowerQualityChainContext[i];
|
||||
CertificateChain *alternate =
|
||||
(CertificateChain*)chain->context.rgpLowerQualityChainContext[i];
|
||||
|
||||
if (CRYPT_ChainQuality(alternate) > CRYPT_ChainQuality(chain))
|
||||
{
|
||||
|
@ -2499,7 +2583,7 @@ static PCertificateChain CRYPT_ChooseHighestQualityChain(
|
|||
return chain;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_AddAlternateChainToChain(PCertificateChain chain,
|
||||
static BOOL CRYPT_AddAlternateChainToChain(CertificateChain *chain,
|
||||
const CertificateChain *alternate)
|
||||
{
|
||||
BOOL ret;
|
||||
|
@ -2543,7 +2627,7 @@ static PCERT_CHAIN_ELEMENT CRYPT_FindIthElementInChain(
|
|||
typedef struct _CERT_CHAIN_PARA_NO_EXTRA_FIELDS {
|
||||
DWORD cbSize;
|
||||
CERT_USAGE_MATCH RequestedUsage;
|
||||
} CERT_CHAIN_PARA_NO_EXTRA_FIELDS, *PCERT_CHAIN_PARA_NO_EXTRA_FIELDS;
|
||||
} CERT_CHAIN_PARA_NO_EXTRA_FIELDS;
|
||||
|
||||
static void CRYPT_VerifyChainRevocation(PCERT_CHAIN_CONTEXT chain,
|
||||
LPFILETIME pTime, HCERTSTORE hAdditionalStore,
|
||||
|
@ -2792,13 +2876,18 @@ BOOL WINAPI CertGetCertificateChain(HCERTCHAINENGINE hChainEngine,
|
|||
PCERT_CHAIN_PARA pChainPara, DWORD dwFlags, LPVOID pvReserved,
|
||||
PCCERT_CHAIN_CONTEXT* ppChainContext)
|
||||
{
|
||||
CertificateChainEngine *engine;
|
||||
BOOL ret;
|
||||
PCertificateChain chain = NULL;
|
||||
CertificateChain *chain = NULL;
|
||||
|
||||
TRACE("(%p, %p, %s, %p, %p, %08x, %p, %p)\n", hChainEngine, pCertContext,
|
||||
debugstr_filetime(pTime), hAdditionalStore, pChainPara, dwFlags,
|
||||
pvReserved, ppChainContext);
|
||||
|
||||
engine = get_chain_engine(hChainEngine, TRUE);
|
||||
if (!engine)
|
||||
return FALSE;
|
||||
|
||||
if (ppChainContext)
|
||||
*ppChainContext = NULL;
|
||||
if (!pChainPara)
|
||||
|
@ -2812,21 +2901,19 @@ BOOL WINAPI CertGetCertificateChain(HCERTCHAINENGINE hChainEngine,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (!hChainEngine)
|
||||
hChainEngine = CRYPT_GetDefaultChainEngine();
|
||||
if (TRACE_ON(chain))
|
||||
dump_chain_para(pChainPara);
|
||||
/* FIXME: what about HCCE_LOCAL_MACHINE? */
|
||||
ret = CRYPT_BuildCandidateChainFromCert(hChainEngine, pCertContext, pTime,
|
||||
hAdditionalStore, &chain);
|
||||
ret = CRYPT_BuildCandidateChainFromCert(engine, pCertContext, pTime,
|
||||
hAdditionalStore, dwFlags, &chain);
|
||||
if (ret)
|
||||
{
|
||||
PCertificateChain alternate = NULL;
|
||||
CertificateChain *alternate = NULL;
|
||||
PCERT_CHAIN_CONTEXT pChain;
|
||||
|
||||
do {
|
||||
alternate = CRYPT_BuildAlternateContextFromChain(hChainEngine,
|
||||
pTime, hAdditionalStore, chain);
|
||||
alternate = CRYPT_BuildAlternateContextFromChain(engine,
|
||||
pTime, hAdditionalStore, dwFlags, chain);
|
||||
|
||||
/* Alternate contexts are added as "lower quality" contexts of
|
||||
* chain, to avoid loops in alternate chain creation.
|
||||
|
@ -2856,7 +2943,7 @@ BOOL WINAPI CertGetCertificateChain(HCERTCHAINENGINE hChainEngine,
|
|||
PCCERT_CHAIN_CONTEXT WINAPI CertDuplicateCertificateChain(
|
||||
PCCERT_CHAIN_CONTEXT pChainContext)
|
||||
{
|
||||
PCertificateChain chain = (PCertificateChain)pChainContext;
|
||||
CertificateChain *chain = (CertificateChain*)pChainContext;
|
||||
|
||||
TRACE("(%p)\n", pChainContext);
|
||||
|
||||
|
@ -2867,7 +2954,7 @@ PCCERT_CHAIN_CONTEXT WINAPI CertDuplicateCertificateChain(
|
|||
|
||||
VOID WINAPI CertFreeCertificateChain(PCCERT_CHAIN_CONTEXT pChainContext)
|
||||
{
|
||||
PCertificateChain chain = (PCertificateChain)pChainContext;
|
||||
CertificateChain *chain = (CertificateChain*)pChainContext;
|
||||
|
||||
TRACE("(%p)\n", pChainContext);
|
||||
|
||||
|
|
|
@ -22,92 +22,106 @@ WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
|||
|
||||
typedef struct _WINE_STORE_LIST_ENTRY
|
||||
{
|
||||
PWINECRYPT_CERTSTORE store;
|
||||
WINECRYPT_CERTSTORE *store;
|
||||
DWORD dwUpdateFlags;
|
||||
DWORD dwPriority;
|
||||
struct list entry;
|
||||
} WINE_STORE_LIST_ENTRY, *PWINE_STORE_LIST_ENTRY;
|
||||
} WINE_STORE_LIST_ENTRY;
|
||||
|
||||
typedef struct _WINE_COLLECTIONSTORE
|
||||
{
|
||||
WINECRYPT_CERTSTORE hdr;
|
||||
CRITICAL_SECTION cs;
|
||||
struct list stores;
|
||||
} WINE_COLLECTIONSTORE, *PWINE_COLLECTIONSTORE;
|
||||
} WINE_COLLECTIONSTORE;
|
||||
|
||||
static void WINAPI CRYPT_CollectionCloseStore(HCERTSTORE store, DWORD dwFlags)
|
||||
static void Collection_addref(WINECRYPT_CERTSTORE *store)
|
||||
{
|
||||
PWINE_COLLECTIONSTORE cs = store;
|
||||
PWINE_STORE_LIST_ENTRY entry, next;
|
||||
LONG ref = InterlockedIncrement(&store->ref);
|
||||
TRACE("ref = %d\n", ref);
|
||||
}
|
||||
|
||||
TRACE("(%p, %08x)\n", store, dwFlags);
|
||||
static DWORD Collection_release(WINECRYPT_CERTSTORE *store, DWORD flags)
|
||||
{
|
||||
WINE_COLLECTIONSTORE *cs = (WINE_COLLECTIONSTORE*)store;
|
||||
WINE_STORE_LIST_ENTRY *entry, *next;
|
||||
LONG ref;
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(entry, next, &cs->stores, WINE_STORE_LIST_ENTRY,
|
||||
entry)
|
||||
if(flags)
|
||||
FIXME("Unimplemented flags %x\n", flags);
|
||||
|
||||
ref = InterlockedDecrement(&cs->hdr.ref);
|
||||
TRACE("(%p) ref=%d\n", store, ref);
|
||||
if(ref)
|
||||
return ERROR_SUCCESS;
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(entry, next, &cs->stores, WINE_STORE_LIST_ENTRY, entry)
|
||||
{
|
||||
TRACE("closing %p\n", entry);
|
||||
CertCloseStore(entry->store, dwFlags);
|
||||
entry->store->vtbl->release(entry->store, flags);
|
||||
CryptMemFree(entry);
|
||||
}
|
||||
cs->cs.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&cs->cs);
|
||||
CRYPT_FreeStore(store);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static void *CRYPT_CollectionCreateContextFromChild(PWINE_COLLECTIONSTORE store,
|
||||
PWINE_STORE_LIST_ENTRY storeEntry, void *child, size_t contextSize,
|
||||
BOOL addRef)
|
||||
static void Collection_releaseContext(WINECRYPT_CERTSTORE *store, context_t *context)
|
||||
{
|
||||
void *ret = Context_CreateLinkContext(contextSize, child,
|
||||
sizeof(PWINE_STORE_LIST_ENTRY), addRef);
|
||||
/* We don't cache context links, so just free them. */
|
||||
Context_Free(context);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
*(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(ret, contextSize)
|
||||
= storeEntry;
|
||||
static context_t *CRYPT_CollectionCreateContextFromChild(WINE_COLLECTIONSTORE *store,
|
||||
WINE_STORE_LIST_ENTRY *storeEntry, context_t *child)
|
||||
{
|
||||
context_t *ret;
|
||||
|
||||
ret = child->vtbl->clone(child, &store->hdr, TRUE);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
ret->u.ptr = storeEntry;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_CollectionAddContext(PWINE_COLLECTIONSTORE store,
|
||||
unsigned int contextFuncsOffset, void *context, void *toReplace, unsigned int contextSize,
|
||||
void **pChildContext)
|
||||
static BOOL CRYPT_CollectionAddContext(WINE_COLLECTIONSTORE *store,
|
||||
unsigned int contextFuncsOffset, context_t *context, context_t *toReplace,
|
||||
context_t **pChildContext)
|
||||
{
|
||||
BOOL ret;
|
||||
void *childContext = NULL;
|
||||
PWINE_STORE_LIST_ENTRY storeEntry = NULL;
|
||||
context_t *childContext = NULL;
|
||||
WINE_STORE_LIST_ENTRY *storeEntry = NULL;
|
||||
|
||||
TRACE("(%p, %d, %p, %p, %d)\n", store, contextFuncsOffset, context,
|
||||
toReplace, contextSize);
|
||||
TRACE("(%p, %d, %p, %p)\n", store, contextFuncsOffset, context, toReplace);
|
||||
|
||||
ret = FALSE;
|
||||
if (toReplace)
|
||||
{
|
||||
void *existingLinked = Context_GetLinkedContext(toReplace, contextSize);
|
||||
PCONTEXT_FUNCS contextFuncs;
|
||||
context_t *existingLinked = toReplace->linked;
|
||||
CONTEXT_FUNCS *contextFuncs;
|
||||
|
||||
storeEntry = *(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(toReplace,
|
||||
contextSize);
|
||||
contextFuncs = (PCONTEXT_FUNCS)((LPBYTE)storeEntry->store +
|
||||
storeEntry = toReplace->u.ptr;
|
||||
contextFuncs = (CONTEXT_FUNCS*)((LPBYTE)storeEntry->store->vtbl +
|
||||
contextFuncsOffset);
|
||||
ret = contextFuncs->addContext(storeEntry->store, context,
|
||||
existingLinked, (const void **)&childContext);
|
||||
existingLinked, &childContext, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
PWINE_STORE_LIST_ENTRY entry, next;
|
||||
WINE_STORE_LIST_ENTRY *entry, *next;
|
||||
|
||||
EnterCriticalSection(&store->cs);
|
||||
LIST_FOR_EACH_ENTRY_SAFE(entry, next, &store->stores,
|
||||
WINE_STORE_LIST_ENTRY, entry)
|
||||
LIST_FOR_EACH_ENTRY_SAFE(entry, next, &store->stores, WINE_STORE_LIST_ENTRY, entry)
|
||||
{
|
||||
if (entry->dwUpdateFlags & CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG)
|
||||
{
|
||||
PCONTEXT_FUNCS contextFuncs = (PCONTEXT_FUNCS)(
|
||||
(LPBYTE)entry->store + contextFuncsOffset);
|
||||
CONTEXT_FUNCS *contextFuncs = (CONTEXT_FUNCS*)(
|
||||
(LPBYTE)entry->store->vtbl + contextFuncsOffset);
|
||||
|
||||
storeEntry = entry;
|
||||
ret = contextFuncs->addContext(entry->store, context, NULL,
|
||||
(const void **)&childContext);
|
||||
ret = contextFuncs->addContext(entry->store, context, NULL, &childContext, TRUE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -128,31 +142,34 @@ static BOOL CRYPT_CollectionAddContext(PWINE_COLLECTIONSTORE store,
|
|||
* Returns NULL if the collection contains no more items or on error.
|
||||
* Assumes the collection store's lock is held.
|
||||
*/
|
||||
static void *CRYPT_CollectionAdvanceEnum(PWINE_COLLECTIONSTORE store,
|
||||
PWINE_STORE_LIST_ENTRY storeEntry, const CONTEXT_FUNCS *contextFuncs,
|
||||
PCWINE_CONTEXT_INTERFACE contextInterface, void *pPrev, size_t contextSize)
|
||||
static context_t *CRYPT_CollectionAdvanceEnum(WINE_COLLECTIONSTORE *store,
|
||||
WINE_STORE_LIST_ENTRY *storeEntry, const CONTEXT_FUNCS *contextFuncs,
|
||||
context_t *prev)
|
||||
{
|
||||
void *ret, *child;
|
||||
context_t *child, *ret;
|
||||
struct list *storeNext = list_next(&store->stores, &storeEntry->entry);
|
||||
|
||||
TRACE("(%p, %p, %p)\n", store, storeEntry, pPrev);
|
||||
TRACE("(%p, %p, %p)\n", store, storeEntry, prev);
|
||||
|
||||
if (pPrev)
|
||||
if (prev)
|
||||
{
|
||||
/* Ref-counting funny business: "duplicate" (addref) the child, because
|
||||
* the free(pPrev) below can cause the ref count to become negative.
|
||||
*/
|
||||
child = Context_GetLinkedContext(pPrev, contextSize);
|
||||
contextInterface->duplicate(child);
|
||||
child = prev->linked;
|
||||
Context_AddRef(child);
|
||||
child = contextFuncs->enumContext(storeEntry->store, child);
|
||||
contextInterface->free(pPrev);
|
||||
pPrev = NULL;
|
||||
Context_Release(prev);
|
||||
prev = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
child = contextFuncs->enumContext(storeEntry->store, NULL);
|
||||
if (child)
|
||||
ret = CRYPT_CollectionCreateContextFromChild(store, storeEntry, child,
|
||||
contextSize, FALSE);
|
||||
}
|
||||
if (child) {
|
||||
ret = CRYPT_CollectionCreateContextFromChild(store, storeEntry, child);
|
||||
Context_Release(child);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (storeNext)
|
||||
|
@ -160,14 +177,14 @@ static void *CRYPT_CollectionAdvanceEnum(PWINE_COLLECTIONSTORE store,
|
|||
/* We always want the same function pointers (from certs, crls)
|
||||
* in the next store, so use the same offset into the next store.
|
||||
*/
|
||||
size_t offset = (const BYTE *)contextFuncs - (LPBYTE)storeEntry->store;
|
||||
PWINE_STORE_LIST_ENTRY storeNextEntry =
|
||||
size_t offset = (const BYTE *)contextFuncs - (LPBYTE)storeEntry->store->vtbl;
|
||||
WINE_STORE_LIST_ENTRY *storeNextEntry =
|
||||
LIST_ENTRY(storeNext, WINE_STORE_LIST_ENTRY, entry);
|
||||
PCONTEXT_FUNCS storeNextContexts =
|
||||
(PCONTEXT_FUNCS)((LPBYTE)storeNextEntry->store + offset);
|
||||
CONTEXT_FUNCS *storeNextContexts =
|
||||
(CONTEXT_FUNCS*)((LPBYTE)storeNextEntry->store->vtbl + offset);
|
||||
|
||||
ret = CRYPT_CollectionAdvanceEnum(store, storeNextEntry,
|
||||
storeNextContexts, contextInterface, NULL, contextSize);
|
||||
storeNextContexts, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -179,59 +196,52 @@ static void *CRYPT_CollectionAdvanceEnum(PWINE_COLLECTIONSTORE store,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_CollectionAddCert(PWINECRYPT_CERTSTORE store, void *cert,
|
||||
void *toReplace, const void **ppStoreContext)
|
||||
static BOOL Collection_addCert(WINECRYPT_CERTSTORE *store, context_t *cert,
|
||||
context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
|
||||
{
|
||||
BOOL ret;
|
||||
void *childContext = NULL;
|
||||
PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
|
||||
context_t *childContext = NULL;
|
||||
WINE_COLLECTIONSTORE *cs = (WINE_COLLECTIONSTORE*)store;
|
||||
|
||||
ret = CRYPT_CollectionAddContext(cs, offsetof(WINECRYPT_CERTSTORE, certs),
|
||||
cert, toReplace, sizeof(CERT_CONTEXT), &childContext);
|
||||
ret = CRYPT_CollectionAddContext(cs, offsetof(store_vtbl_t, certs),
|
||||
cert, toReplace, &childContext);
|
||||
if (ppStoreContext && childContext)
|
||||
{
|
||||
PWINE_STORE_LIST_ENTRY storeEntry = *(PWINE_STORE_LIST_ENTRY *)
|
||||
Context_GetExtra(childContext, sizeof(CERT_CONTEXT));
|
||||
PCERT_CONTEXT context =
|
||||
CRYPT_CollectionCreateContextFromChild(cs, storeEntry, childContext,
|
||||
sizeof(CERT_CONTEXT), TRUE);
|
||||
WINE_STORE_LIST_ENTRY *storeEntry = childContext->u.ptr;
|
||||
cert_t *context = (cert_t*)CRYPT_CollectionCreateContextFromChild(cs, storeEntry,
|
||||
childContext);
|
||||
|
||||
if (context)
|
||||
context->hCertStore = store;
|
||||
*ppStoreContext = context;
|
||||
*ppStoreContext = &context->base;
|
||||
}
|
||||
CertFreeCertificateContext(childContext);
|
||||
if (childContext)
|
||||
Context_Release(childContext);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *CRYPT_CollectionEnumCert(PWINECRYPT_CERTSTORE store, void *pPrev)
|
||||
static context_t *Collection_enumCert(WINECRYPT_CERTSTORE *store, context_t *prev)
|
||||
{
|
||||
PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
|
||||
void *ret;
|
||||
WINE_COLLECTIONSTORE *cs = (WINE_COLLECTIONSTORE*)store;
|
||||
context_t *ret;
|
||||
|
||||
TRACE("(%p, %p)\n", store, pPrev);
|
||||
TRACE("(%p, %p)\n", store, prev);
|
||||
|
||||
EnterCriticalSection(&cs->cs);
|
||||
if (pPrev)
|
||||
if (prev)
|
||||
{
|
||||
PWINE_STORE_LIST_ENTRY storeEntry =
|
||||
*(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(pPrev,
|
||||
sizeof(CERT_CONTEXT));
|
||||
WINE_STORE_LIST_ENTRY *storeEntry = prev->u.ptr;
|
||||
|
||||
ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
|
||||
&storeEntry->store->certs, pCertInterface, pPrev,
|
||||
sizeof(CERT_CONTEXT));
|
||||
&storeEntry->store->vtbl->certs, prev);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!list_empty(&cs->stores))
|
||||
{
|
||||
PWINE_STORE_LIST_ENTRY storeEntry = LIST_ENTRY(cs->stores.next,
|
||||
WINE_STORE_LIST_ENTRY *storeEntry = LIST_ENTRY(cs->stores.next,
|
||||
WINE_STORE_LIST_ENTRY, entry);
|
||||
|
||||
ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
|
||||
&storeEntry->store->certs, pCertInterface, NULL,
|
||||
sizeof(CERT_CONTEXT));
|
||||
&storeEntry->store->vtbl->certs, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -240,84 +250,67 @@ static void *CRYPT_CollectionEnumCert(PWINECRYPT_CERTSTORE store, void *pPrev)
|
|||
}
|
||||
}
|
||||
LeaveCriticalSection(&cs->cs);
|
||||
if (ret)
|
||||
((PCERT_CONTEXT)ret)->hCertStore = store;
|
||||
TRACE("returning %p\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_CollectionDeleteCert(PWINECRYPT_CERTSTORE store,
|
||||
void *pCertContext)
|
||||
static BOOL Collection_deleteCert(WINECRYPT_CERTSTORE *store, context_t *context)
|
||||
{
|
||||
BOOL ret;
|
||||
PCCERT_CONTEXT linked;
|
||||
cert_t *cert = (cert_t*)context;
|
||||
cert_t *linked;
|
||||
|
||||
TRACE("(%p, %p)\n", store, pCertContext);
|
||||
TRACE("(%p, %p)\n", store, cert);
|
||||
|
||||
/* Deleting the linked context results in its ref count getting
|
||||
* decreased, but the caller of this (CertDeleteCertificateFromStore) also
|
||||
* decreases pCertContext's ref count, by calling
|
||||
* CertFreeCertificateContext. Increase ref count of linked context to
|
||||
* compensate.
|
||||
*/
|
||||
linked = Context_GetLinkedContext(pCertContext, sizeof(CERT_CONTEXT));
|
||||
CertDuplicateCertificateContext(linked);
|
||||
ret = CertDeleteCertificateFromStore(linked);
|
||||
return ret;
|
||||
linked = (cert_t*)context->linked;
|
||||
return CertDeleteCertificateFromStore(&linked->ctx);
|
||||
}
|
||||
|
||||
static BOOL CRYPT_CollectionAddCRL(PWINECRYPT_CERTSTORE store, void *crl,
|
||||
void *toReplace, const void **ppStoreContext)
|
||||
static BOOL Collection_addCRL(WINECRYPT_CERTSTORE *store, context_t *crl,
|
||||
context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
|
||||
{
|
||||
BOOL ret;
|
||||
void *childContext = NULL;
|
||||
PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
|
||||
context_t *childContext = NULL;
|
||||
WINE_COLLECTIONSTORE *cs = (WINE_COLLECTIONSTORE*)store;
|
||||
|
||||
ret = CRYPT_CollectionAddContext(cs, offsetof(WINECRYPT_CERTSTORE, crls),
|
||||
crl, toReplace, sizeof(CRL_CONTEXT), &childContext);
|
||||
ret = CRYPT_CollectionAddContext(cs, offsetof(store_vtbl_t, crls),
|
||||
crl, toReplace, &childContext);
|
||||
if (ppStoreContext && childContext)
|
||||
{
|
||||
PWINE_STORE_LIST_ENTRY storeEntry = *(PWINE_STORE_LIST_ENTRY *)
|
||||
Context_GetExtra(childContext, sizeof(CRL_CONTEXT));
|
||||
PCRL_CONTEXT context =
|
||||
CRYPT_CollectionCreateContextFromChild(cs, storeEntry, childContext,
|
||||
sizeof(CRL_CONTEXT), TRUE);
|
||||
WINE_STORE_LIST_ENTRY *storeEntry = childContext->u.ptr;
|
||||
crl_t *context = (crl_t*)CRYPT_CollectionCreateContextFromChild(cs, storeEntry,
|
||||
childContext);
|
||||
|
||||
if (context)
|
||||
context->hCertStore = store;
|
||||
*ppStoreContext = context;
|
||||
*ppStoreContext = &context->base;
|
||||
}
|
||||
CertFreeCRLContext(childContext);
|
||||
if (childContext)
|
||||
Context_Release(childContext);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *CRYPT_CollectionEnumCRL(PWINECRYPT_CERTSTORE store, void *pPrev)
|
||||
static context_t *Collection_enumCRL(WINECRYPT_CERTSTORE *store, context_t *prev)
|
||||
{
|
||||
PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
|
||||
void *ret;
|
||||
WINE_COLLECTIONSTORE *cs = (WINE_COLLECTIONSTORE*)store;
|
||||
context_t *ret;
|
||||
|
||||
TRACE("(%p, %p)\n", store, pPrev);
|
||||
TRACE("(%p, %p)\n", store, prev);
|
||||
|
||||
EnterCriticalSection(&cs->cs);
|
||||
if (pPrev)
|
||||
if (prev)
|
||||
{
|
||||
PWINE_STORE_LIST_ENTRY storeEntry =
|
||||
*(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(pPrev,
|
||||
sizeof(CRL_CONTEXT));
|
||||
WINE_STORE_LIST_ENTRY *storeEntry = prev->u.ptr;
|
||||
|
||||
ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
|
||||
&storeEntry->store->crls, pCRLInterface, pPrev, sizeof(CRL_CONTEXT));
|
||||
&storeEntry->store->vtbl->crls, prev);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!list_empty(&cs->stores))
|
||||
{
|
||||
PWINE_STORE_LIST_ENTRY storeEntry = LIST_ENTRY(cs->stores.next,
|
||||
WINE_STORE_LIST_ENTRY *storeEntry = LIST_ENTRY(cs->stores.next,
|
||||
WINE_STORE_LIST_ENTRY, entry);
|
||||
|
||||
ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
|
||||
&storeEntry->store->crls, pCRLInterface, NULL,
|
||||
sizeof(CRL_CONTEXT));
|
||||
&storeEntry->store->vtbl->crls, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -326,83 +319,66 @@ static void *CRYPT_CollectionEnumCRL(PWINECRYPT_CERTSTORE store, void *pPrev)
|
|||
}
|
||||
}
|
||||
LeaveCriticalSection(&cs->cs);
|
||||
if (ret)
|
||||
((PCRL_CONTEXT)ret)->hCertStore = store;
|
||||
TRACE("returning %p\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_CollectionDeleteCRL(PWINECRYPT_CERTSTORE store,
|
||||
void *pCrlContext)
|
||||
static BOOL Collection_deleteCRL(WINECRYPT_CERTSTORE *store, context_t *context)
|
||||
{
|
||||
BOOL ret;
|
||||
PCCRL_CONTEXT linked;
|
||||
crl_t *crl = (crl_t*)context, *linked;
|
||||
|
||||
TRACE("(%p, %p)\n", store, pCrlContext);
|
||||
TRACE("(%p, %p)\n", store, crl);
|
||||
|
||||
/* Deleting the linked context results in its ref count getting
|
||||
* decreased, but the caller of this (CertDeleteCRLFromStore) also
|
||||
* decreases pCrlContext's ref count, by calling CertFreeCRLContext.
|
||||
* Increase ref count of linked context to compensate.
|
||||
*/
|
||||
linked = Context_GetLinkedContext(pCrlContext, sizeof(CRL_CONTEXT));
|
||||
CertDuplicateCRLContext(linked);
|
||||
ret = CertDeleteCRLFromStore(linked);
|
||||
return ret;
|
||||
linked = (crl_t*)context->linked;
|
||||
return CertDeleteCRLFromStore(&linked->ctx);
|
||||
}
|
||||
|
||||
static BOOL CRYPT_CollectionAddCTL(PWINECRYPT_CERTSTORE store, void *ctl,
|
||||
void *toReplace, const void **ppStoreContext)
|
||||
static BOOL Collection_addCTL(WINECRYPT_CERTSTORE *store, context_t *ctl,
|
||||
context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
|
||||
{
|
||||
BOOL ret;
|
||||
void *childContext = NULL;
|
||||
PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
|
||||
context_t *childContext = NULL;
|
||||
WINE_COLLECTIONSTORE *cs = (WINE_COLLECTIONSTORE*)store;
|
||||
|
||||
ret = CRYPT_CollectionAddContext(cs, offsetof(WINECRYPT_CERTSTORE, ctls),
|
||||
ctl, toReplace, sizeof(CTL_CONTEXT), &childContext);
|
||||
ret = CRYPT_CollectionAddContext(cs, offsetof(store_vtbl_t, ctls),
|
||||
ctl, toReplace, &childContext);
|
||||
if (ppStoreContext && childContext)
|
||||
{
|
||||
PWINE_STORE_LIST_ENTRY storeEntry = *(PWINE_STORE_LIST_ENTRY *)
|
||||
Context_GetExtra(childContext, sizeof(CTL_CONTEXT));
|
||||
PCTL_CONTEXT context =
|
||||
CRYPT_CollectionCreateContextFromChild(cs, storeEntry, childContext,
|
||||
sizeof(CTL_CONTEXT), TRUE);
|
||||
WINE_STORE_LIST_ENTRY *storeEntry = childContext->u.ptr;
|
||||
ctl_t *context = (ctl_t*)CRYPT_CollectionCreateContextFromChild(cs, storeEntry,
|
||||
childContext);
|
||||
|
||||
if (context)
|
||||
context->hCertStore = store;
|
||||
*ppStoreContext = context;
|
||||
*ppStoreContext = &context->base;
|
||||
}
|
||||
CertFreeCTLContext(childContext);
|
||||
if (childContext)
|
||||
Context_Release(childContext);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *CRYPT_CollectionEnumCTL(PWINECRYPT_CERTSTORE store, void *pPrev)
|
||||
static context_t *Collection_enumCTL(WINECRYPT_CERTSTORE *store, context_t *prev)
|
||||
{
|
||||
PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
|
||||
WINE_COLLECTIONSTORE *cs = (WINE_COLLECTIONSTORE*)store;
|
||||
void *ret;
|
||||
|
||||
TRACE("(%p, %p)\n", store, pPrev);
|
||||
TRACE("(%p, %p)\n", store, prev);
|
||||
|
||||
EnterCriticalSection(&cs->cs);
|
||||
if (pPrev)
|
||||
if (prev)
|
||||
{
|
||||
PWINE_STORE_LIST_ENTRY storeEntry =
|
||||
*(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(pPrev,
|
||||
sizeof(CTL_CONTEXT));
|
||||
WINE_STORE_LIST_ENTRY *storeEntry = prev->u.ptr;
|
||||
|
||||
ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
|
||||
&storeEntry->store->ctls, pCTLInterface, pPrev, sizeof(CTL_CONTEXT));
|
||||
&storeEntry->store->vtbl->ctls, prev);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!list_empty(&cs->stores))
|
||||
{
|
||||
PWINE_STORE_LIST_ENTRY storeEntry = LIST_ENTRY(cs->stores.next,
|
||||
WINE_STORE_LIST_ENTRY *storeEntry = LIST_ENTRY(cs->stores.next,
|
||||
WINE_STORE_LIST_ENTRY, entry);
|
||||
|
||||
ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
|
||||
&storeEntry->store->ctls, pCTLInterface, NULL,
|
||||
sizeof(CTL_CONTEXT));
|
||||
&storeEntry->store->vtbl->ctls, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -411,40 +387,28 @@ static void *CRYPT_CollectionEnumCTL(PWINECRYPT_CERTSTORE store, void *pPrev)
|
|||
}
|
||||
}
|
||||
LeaveCriticalSection(&cs->cs);
|
||||
if (ret)
|
||||
((PCTL_CONTEXT)ret)->hCertStore = store;
|
||||
TRACE("returning %p\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_CollectionDeleteCTL(PWINECRYPT_CERTSTORE store,
|
||||
void *pCtlContext)
|
||||
static BOOL Collection_deleteCTL(WINECRYPT_CERTSTORE *store, context_t *context)
|
||||
{
|
||||
BOOL ret;
|
||||
PCCTL_CONTEXT linked;
|
||||
ctl_t *ctl = (ctl_t*)context, *linked;
|
||||
|
||||
TRACE("(%p, %p)\n", store, pCtlContext);
|
||||
TRACE("(%p, %p)\n", store, ctl);
|
||||
|
||||
/* Deleting the linked context results in its ref count getting
|
||||
* decreased, but the caller of this (CertDeleteCTLFromStore) also
|
||||
* decreases pCtlContext's ref count, by calling CertFreeCTLContext.
|
||||
* Increase ref count of linked context to compensate.
|
||||
*/
|
||||
linked = Context_GetLinkedContext(pCtlContext, sizeof(CTL_CONTEXT));
|
||||
CertDuplicateCTLContext(linked);
|
||||
ret = CertDeleteCTLFromStore(linked);
|
||||
return ret;
|
||||
linked = (ctl_t*)context->linked;
|
||||
return CertDeleteCTLFromStore(&linked->ctx);
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_CollectionControl(HCERTSTORE hCertStore, DWORD dwFlags,
|
||||
static BOOL Collection_control(WINECRYPT_CERTSTORE *cert_store, DWORD dwFlags,
|
||||
DWORD dwCtrlType, void const *pvCtrlPara)
|
||||
{
|
||||
BOOL ret;
|
||||
PWINE_COLLECTIONSTORE store = hCertStore;
|
||||
PWINE_STORE_LIST_ENTRY entry;
|
||||
WINE_COLLECTIONSTORE *store = (WINE_COLLECTIONSTORE*)cert_store;
|
||||
WINE_STORE_LIST_ENTRY *entry;
|
||||
|
||||
TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
|
||||
pvCtrlPara);
|
||||
TRACE("(%p, %08x, %d, %p)\n", cert_store, dwFlags, dwCtrlType, pvCtrlPara);
|
||||
|
||||
if (!store)
|
||||
return TRUE;
|
||||
|
@ -463,10 +427,9 @@ static BOOL WINAPI CRYPT_CollectionControl(HCERTSTORE hCertStore, DWORD dwFlags,
|
|||
EnterCriticalSection(&store->cs);
|
||||
LIST_FOR_EACH_ENTRY(entry, &store->stores, WINE_STORE_LIST_ENTRY, entry)
|
||||
{
|
||||
if (entry->store->control)
|
||||
if (entry->store->vtbl->control)
|
||||
{
|
||||
ret = entry->store->control(entry->store, dwFlags, dwCtrlType,
|
||||
pvCtrlPara);
|
||||
ret = entry->store->vtbl->control(entry->store, dwFlags, dwCtrlType, pvCtrlPara);
|
||||
if (!ret)
|
||||
break;
|
||||
}
|
||||
|
@ -475,10 +438,30 @@ static BOOL WINAPI CRYPT_CollectionControl(HCERTSTORE hCertStore, DWORD dwFlags,
|
|||
return ret;
|
||||
}
|
||||
|
||||
PWINECRYPT_CERTSTORE CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv,
|
||||
static const store_vtbl_t CollectionStoreVtbl = {
|
||||
Collection_addref,
|
||||
Collection_release,
|
||||
Collection_releaseContext,
|
||||
Collection_control,
|
||||
{
|
||||
Collection_addCert,
|
||||
Collection_enumCert,
|
||||
Collection_deleteCert
|
||||
}, {
|
||||
Collection_addCRL,
|
||||
Collection_enumCRL,
|
||||
Collection_deleteCRL
|
||||
}, {
|
||||
Collection_addCTL,
|
||||
Collection_enumCTL,
|
||||
Collection_deleteCTL
|
||||
}
|
||||
};
|
||||
|
||||
WINECRYPT_CERTSTORE *CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
PWINE_COLLECTIONSTORE store;
|
||||
WINE_COLLECTIONSTORE *store;
|
||||
|
||||
if (dwFlags & CERT_STORE_DELETE_FLAG)
|
||||
{
|
||||
|
@ -491,32 +474,21 @@ PWINECRYPT_CERTSTORE CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv,
|
|||
if (store)
|
||||
{
|
||||
memset(store, 0, sizeof(WINE_COLLECTIONSTORE));
|
||||
CRYPT_InitStore(&store->hdr, dwFlags, StoreTypeCollection);
|
||||
store->hdr.closeStore = CRYPT_CollectionCloseStore;
|
||||
store->hdr.certs.addContext = CRYPT_CollectionAddCert;
|
||||
store->hdr.certs.enumContext = CRYPT_CollectionEnumCert;
|
||||
store->hdr.certs.deleteContext = CRYPT_CollectionDeleteCert;
|
||||
store->hdr.crls.addContext = CRYPT_CollectionAddCRL;
|
||||
store->hdr.crls.enumContext = CRYPT_CollectionEnumCRL;
|
||||
store->hdr.crls.deleteContext = CRYPT_CollectionDeleteCRL;
|
||||
store->hdr.ctls.addContext = CRYPT_CollectionAddCTL;
|
||||
store->hdr.ctls.enumContext = CRYPT_CollectionEnumCTL;
|
||||
store->hdr.ctls.deleteContext = CRYPT_CollectionDeleteCTL;
|
||||
store->hdr.control = CRYPT_CollectionControl;
|
||||
CRYPT_InitStore(&store->hdr, dwFlags, StoreTypeCollection, &CollectionStoreVtbl);
|
||||
InitializeCriticalSection(&store->cs);
|
||||
store->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PWINE_COLLECTIONSTORE->cs");
|
||||
list_init(&store->stores);
|
||||
}
|
||||
}
|
||||
return (PWINECRYPT_CERTSTORE)store;
|
||||
return (WINECRYPT_CERTSTORE*)store;
|
||||
}
|
||||
|
||||
BOOL WINAPI CertAddStoreToCollection(HCERTSTORE hCollectionStore,
|
||||
HCERTSTORE hSiblingStore, DWORD dwUpdateFlags, DWORD dwPriority)
|
||||
{
|
||||
PWINE_COLLECTIONSTORE collection = hCollectionStore;
|
||||
WINE_COLLECTIONSTORE *collection = hCollectionStore;
|
||||
WINECRYPT_CERTSTORE *sibling = hSiblingStore;
|
||||
PWINE_STORE_LIST_ENTRY entry;
|
||||
WINE_STORE_LIST_ENTRY *entry;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %p, %08x, %d)\n", hCollectionStore, hSiblingStore,
|
||||
|
@ -553,7 +525,7 @@ BOOL WINAPI CertAddStoreToCollection(HCERTSTORE hCollectionStore,
|
|||
EnterCriticalSection(&collection->cs);
|
||||
if (dwPriority)
|
||||
{
|
||||
PWINE_STORE_LIST_ENTRY cursor;
|
||||
WINE_STORE_LIST_ENTRY *cursor;
|
||||
BOOL added = FALSE;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(cursor, &collection->stores,
|
||||
|
@ -582,9 +554,9 @@ BOOL WINAPI CertAddStoreToCollection(HCERTSTORE hCollectionStore,
|
|||
void WINAPI CertRemoveStoreFromCollection(HCERTSTORE hCollectionStore,
|
||||
HCERTSTORE hSiblingStore)
|
||||
{
|
||||
PWINE_COLLECTIONSTORE collection = hCollectionStore;
|
||||
WINE_COLLECTIONSTORE *collection = hCollectionStore;
|
||||
WINECRYPT_CERTSTORE *sibling = hSiblingStore;
|
||||
PWINE_STORE_LIST_ENTRY store, next;
|
||||
WINE_STORE_LIST_ENTRY *store, *next;
|
||||
|
||||
TRACE("(%p, %p)\n", hCollectionStore, hSiblingStore);
|
||||
|
||||
|
|
|
@ -20,330 +20,107 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(context);
|
||||
|
||||
typedef enum _ContextType {
|
||||
ContextTypeData,
|
||||
ContextTypeLink,
|
||||
} ContextType;
|
||||
|
||||
typedef struct _BASE_CONTEXT
|
||||
context_t *Context_CreateDataContext(size_t contextSize, const context_vtbl_t *vtbl, WINECRYPT_CERTSTORE *store)
|
||||
{
|
||||
LONG ref;
|
||||
ContextType type;
|
||||
} BASE_CONTEXT, *PBASE_CONTEXT;
|
||||
context_t *context;
|
||||
|
||||
typedef struct _DATA_CONTEXT
|
||||
{
|
||||
LONG ref;
|
||||
ContextType type; /* always ContextTypeData */
|
||||
PCONTEXT_PROPERTY_LIST properties;
|
||||
} DATA_CONTEXT, *PDATA_CONTEXT;
|
||||
context = CryptMemAlloc(sizeof(context_t) + contextSize);
|
||||
if (!context)
|
||||
return NULL;
|
||||
|
||||
typedef struct _LINK_CONTEXT
|
||||
{
|
||||
LONG ref;
|
||||
ContextType type; /* always ContextTypeLink */
|
||||
PBASE_CONTEXT linked;
|
||||
} LINK_CONTEXT, *PLINK_CONTEXT;
|
||||
|
||||
#define CONTEXT_FROM_BASE_CONTEXT(p, s) ((LPBYTE)(p) - (s))
|
||||
#define BASE_CONTEXT_FROM_CONTEXT(p, s) (PBASE_CONTEXT)((LPBYTE)(p) + (s))
|
||||
|
||||
void *Context_CreateDataContext(size_t contextSize)
|
||||
{
|
||||
void *ret = CryptMemAlloc(contextSize + sizeof(DATA_CONTEXT));
|
||||
|
||||
if (ret)
|
||||
context->properties = ContextPropertyList_Create();
|
||||
if (!context->properties)
|
||||
{
|
||||
PDATA_CONTEXT context = (PDATA_CONTEXT)((LPBYTE)ret + contextSize);
|
||||
|
||||
context->ref = 1;
|
||||
context->type = ContextTypeData;
|
||||
context->properties = ContextPropertyList_Create();
|
||||
if (!context->properties)
|
||||
{
|
||||
CryptMemFree(ret);
|
||||
ret = NULL;
|
||||
}
|
||||
CryptMemFree(context);
|
||||
return NULL;
|
||||
}
|
||||
TRACE("returning %p\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *Context_CreateLinkContext(unsigned int contextSize, void *linked, unsigned int extra,
|
||||
BOOL addRef)
|
||||
{
|
||||
void *context = CryptMemAlloc(contextSize + sizeof(LINK_CONTEXT) + extra);
|
||||
context->vtbl = vtbl;
|
||||
context->ref = 1;
|
||||
context->linked = NULL;
|
||||
|
||||
TRACE("(%d, %p, %d)\n", contextSize, linked, extra);
|
||||
store->vtbl->addref(store);
|
||||
context->store = store;
|
||||
|
||||
if (context)
|
||||
{
|
||||
PLINK_CONTEXT linkContext = (PLINK_CONTEXT)BASE_CONTEXT_FROM_CONTEXT(
|
||||
context, contextSize);
|
||||
PBASE_CONTEXT linkedBase = BASE_CONTEXT_FROM_CONTEXT(linked,
|
||||
contextSize);
|
||||
|
||||
memcpy(context, linked, contextSize);
|
||||
linkContext->ref = 1;
|
||||
linkContext->type = ContextTypeLink;
|
||||
linkContext->linked = linkedBase;
|
||||
if (addRef)
|
||||
Context_AddRef(linked, contextSize);
|
||||
TRACE("%p's ref count is %d\n", context, linkContext->ref);
|
||||
}
|
||||
TRACE("returning %p\n", context);
|
||||
return context;
|
||||
}
|
||||
|
||||
void Context_AddRef(void *context, size_t contextSize)
|
||||
context_t *Context_CreateLinkContext(unsigned int contextSize, context_t *linked, WINECRYPT_CERTSTORE *store)
|
||||
{
|
||||
PBASE_CONTEXT baseContext = BASE_CONTEXT_FROM_CONTEXT(context, contextSize);
|
||||
context_t *context;
|
||||
|
||||
InterlockedIncrement(&baseContext->ref);
|
||||
TRACE("%p's ref count is %d\n", context, baseContext->ref);
|
||||
if (baseContext->type == ContextTypeLink)
|
||||
{
|
||||
void *linkedContext = Context_GetLinkedContext(context, contextSize);
|
||||
PBASE_CONTEXT linkedBase = BASE_CONTEXT_FROM_CONTEXT(linkedContext,
|
||||
contextSize);
|
||||
TRACE("(%d, %p)\n", contextSize, linked);
|
||||
|
||||
/* Add-ref the linked contexts too */
|
||||
while (linkedContext && linkedBase->type == ContextTypeLink)
|
||||
{
|
||||
InterlockedIncrement(&linkedBase->ref);
|
||||
TRACE("%p's ref count is %d\n", linkedContext, linkedBase->ref);
|
||||
linkedContext = Context_GetLinkedContext(linkedContext,
|
||||
contextSize);
|
||||
if (linkedContext)
|
||||
linkedBase = BASE_CONTEXT_FROM_CONTEXT(linkedContext,
|
||||
contextSize);
|
||||
else
|
||||
linkedBase = NULL;
|
||||
}
|
||||
if (linkedContext)
|
||||
{
|
||||
/* It's not a link context, so it wasn't add-ref'ed in the while
|
||||
* loop, so add-ref it here.
|
||||
*/
|
||||
linkedBase = BASE_CONTEXT_FROM_CONTEXT(linkedContext,
|
||||
contextSize);
|
||||
InterlockedIncrement(&linkedBase->ref);
|
||||
TRACE("%p's ref count is %d\n", linkedContext, linkedBase->ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
context = CryptMemAlloc(sizeof(context_t) + contextSize);
|
||||
if (!context)
|
||||
return NULL;
|
||||
|
||||
void *Context_GetExtra(const void *context, size_t contextSize)
|
||||
{
|
||||
PBASE_CONTEXT baseContext = BASE_CONTEXT_FROM_CONTEXT(context, contextSize);
|
||||
memcpy(context_ptr(context), context_ptr(linked), contextSize);
|
||||
context->vtbl = linked->vtbl;
|
||||
context->ref = 1;
|
||||
context->linked = linked;
|
||||
context->properties = linked->properties;
|
||||
Context_AddRef(linked);
|
||||
|
||||
assert(baseContext->type == ContextTypeLink);
|
||||
return (LPBYTE)baseContext + sizeof(LINK_CONTEXT);
|
||||
}
|
||||
store->vtbl->addref(store);
|
||||
context->store = store;
|
||||
|
||||
void *Context_GetLinkedContext(void *context, size_t contextSize)
|
||||
{
|
||||
PBASE_CONTEXT baseContext = BASE_CONTEXT_FROM_CONTEXT(context, contextSize);
|
||||
|
||||
assert(baseContext->type == ContextTypeLink);
|
||||
return CONTEXT_FROM_BASE_CONTEXT(((PLINK_CONTEXT)baseContext)->linked,
|
||||
contextSize);
|
||||
}
|
||||
|
||||
PCONTEXT_PROPERTY_LIST Context_GetProperties(const void *context, size_t contextSize)
|
||||
{
|
||||
PBASE_CONTEXT ptr = BASE_CONTEXT_FROM_CONTEXT(context, contextSize);
|
||||
|
||||
while (ptr && ptr->type == ContextTypeLink)
|
||||
ptr = ((PLINK_CONTEXT)ptr)->linked;
|
||||
return (ptr && ptr->type == ContextTypeData) ?
|
||||
((PDATA_CONTEXT)ptr)->properties : NULL;
|
||||
}
|
||||
|
||||
BOOL Context_Release(void *context, size_t contextSize,
|
||||
ContextFreeFunc dataContextFree)
|
||||
{
|
||||
PBASE_CONTEXT base = BASE_CONTEXT_FROM_CONTEXT(context, contextSize);
|
||||
BOOL ret = TRUE;
|
||||
|
||||
if (base->ref <= 0)
|
||||
{
|
||||
ERR("%p's ref count is %d\n", context, base->ref);
|
||||
return FALSE;
|
||||
}
|
||||
if (base->type == ContextTypeLink)
|
||||
{
|
||||
/* The linked context is of the same type as this, so release
|
||||
* it as well, using the same offset and data free function.
|
||||
*/
|
||||
ret = Context_Release(CONTEXT_FROM_BASE_CONTEXT(
|
||||
((PLINK_CONTEXT)base)->linked, contextSize), contextSize,
|
||||
dataContextFree);
|
||||
}
|
||||
if (InterlockedDecrement(&base->ref) == 0)
|
||||
{
|
||||
TRACE("freeing %p\n", context);
|
||||
if (base->type == ContextTypeData)
|
||||
{
|
||||
ContextPropertyList_Free(((PDATA_CONTEXT)base)->properties);
|
||||
dataContextFree(context);
|
||||
}
|
||||
CryptMemFree(context);
|
||||
}
|
||||
else
|
||||
TRACE("%p's ref count is %d\n", context, base->ref);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Context_CopyProperties(const void *to, const void *from,
|
||||
size_t contextSize)
|
||||
{
|
||||
PCONTEXT_PROPERTY_LIST toProperties, fromProperties;
|
||||
|
||||
toProperties = Context_GetProperties(to, contextSize);
|
||||
fromProperties = Context_GetProperties(from, contextSize);
|
||||
assert(toProperties && fromProperties);
|
||||
ContextPropertyList_Copy(toProperties, fromProperties);
|
||||
}
|
||||
|
||||
struct ContextList
|
||||
{
|
||||
PCWINE_CONTEXT_INTERFACE contextInterface;
|
||||
size_t contextSize;
|
||||
CRITICAL_SECTION cs;
|
||||
struct list contexts;
|
||||
};
|
||||
|
||||
struct ContextList *ContextList_Create(
|
||||
PCWINE_CONTEXT_INTERFACE contextInterface, size_t contextSize)
|
||||
{
|
||||
struct ContextList *list = CryptMemAlloc(sizeof(struct ContextList));
|
||||
|
||||
if (list)
|
||||
{
|
||||
list->contextInterface = contextInterface;
|
||||
list->contextSize = contextSize;
|
||||
InitializeCriticalSection(&list->cs);
|
||||
list->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ContextList.cs");
|
||||
list_init(&list->contexts);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
static inline struct list *ContextList_ContextToEntry(const struct ContextList *list,
|
||||
const void *context)
|
||||
{
|
||||
struct list *ret;
|
||||
|
||||
if (context)
|
||||
ret = Context_GetExtra(context, list->contextSize);
|
||||
else
|
||||
ret = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void *ContextList_EntryToContext(const struct ContextList *list,
|
||||
struct list *entry)
|
||||
{
|
||||
return (LPBYTE)entry - sizeof(LINK_CONTEXT) - list->contextSize;
|
||||
}
|
||||
|
||||
void *ContextList_Add(struct ContextList *list, void *toLink, void *toReplace)
|
||||
{
|
||||
void *context;
|
||||
|
||||
TRACE("(%p, %p, %p)\n", list, toLink, toReplace);
|
||||
|
||||
context = Context_CreateLinkContext(list->contextSize, toLink,
|
||||
sizeof(struct list), TRUE);
|
||||
if (context)
|
||||
{
|
||||
struct list *entry = ContextList_ContextToEntry(list, context);
|
||||
|
||||
TRACE("adding %p\n", context);
|
||||
EnterCriticalSection(&list->cs);
|
||||
if (toReplace)
|
||||
{
|
||||
struct list *existing = ContextList_ContextToEntry(list, toReplace);
|
||||
|
||||
entry->prev = existing->prev;
|
||||
entry->next = existing->next;
|
||||
entry->prev->next = entry;
|
||||
entry->next->prev = entry;
|
||||
existing->prev = existing->next = existing;
|
||||
list->contextInterface->free(toReplace);
|
||||
}
|
||||
else
|
||||
list_add_head(&list->contexts, entry);
|
||||
LeaveCriticalSection(&list->cs);
|
||||
}
|
||||
TRACE("returning %p\n", context);
|
||||
return context;
|
||||
}
|
||||
|
||||
void *ContextList_Enum(struct ContextList *list, void *pPrev)
|
||||
void Context_AddRef(context_t *context)
|
||||
{
|
||||
struct list *listNext;
|
||||
void *ret;
|
||||
LONG ref = InterlockedIncrement(&context->ref);
|
||||
|
||||
EnterCriticalSection(&list->cs);
|
||||
if (pPrev)
|
||||
{
|
||||
struct list *prevEntry = ContextList_ContextToEntry(list, pPrev);
|
||||
TRACE("(%p) ref=%d\n", context, context->ref);
|
||||
|
||||
listNext = list_next(&list->contexts, prevEntry);
|
||||
list->contextInterface->free(pPrev);
|
||||
if(ref == 1) {
|
||||
/* This is the first external (non-store) reference. Increase store ref cnt. */
|
||||
context->store->vtbl->addref(context->store);
|
||||
}
|
||||
else
|
||||
listNext = list_next(&list->contexts, &list->contexts);
|
||||
LeaveCriticalSection(&list->cs);
|
||||
|
||||
if (listNext)
|
||||
{
|
||||
ret = ContextList_EntryToContext(list, listNext);
|
||||
list->contextInterface->duplicate(ret);
|
||||
}
|
||||
else
|
||||
ret = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL ContextList_Remove(struct ContextList *list, void *context)
|
||||
void Context_Free(context_t *context)
|
||||
{
|
||||
struct list *entry = ContextList_ContextToEntry(list, context);
|
||||
BOOL inList = FALSE;
|
||||
TRACE("(%p)\n", context);
|
||||
|
||||
EnterCriticalSection(&list->cs);
|
||||
if (!list_empty(entry))
|
||||
{
|
||||
list_remove(entry);
|
||||
inList = TRUE;
|
||||
assert(!context->ref);
|
||||
|
||||
if (!context->linked) {
|
||||
ContextPropertyList_Free(context->properties);
|
||||
context->vtbl->free(context);
|
||||
}else {
|
||||
Context_Release(context->linked);
|
||||
}
|
||||
LeaveCriticalSection(&list->cs);
|
||||
if (inList)
|
||||
list_init(entry);
|
||||
return inList;
|
||||
|
||||
CryptMemFree(context);
|
||||
}
|
||||
|
||||
static void ContextList_Empty(struct ContextList *list)
|
||||
void Context_Release(context_t *context)
|
||||
{
|
||||
struct list *entry, *next;
|
||||
LONG ref = InterlockedDecrement(&context->ref);
|
||||
|
||||
EnterCriticalSection(&list->cs);
|
||||
LIST_FOR_EACH_SAFE(entry, next, &list->contexts)
|
||||
{
|
||||
const void *context = ContextList_EntryToContext(list, entry);
|
||||
TRACE("(%p) ref=%d\n", context, ref);
|
||||
assert(ref >= 0);
|
||||
|
||||
TRACE("removing %p\n", context);
|
||||
list_remove(entry);
|
||||
list->contextInterface->free(context);
|
||||
if (!ref) {
|
||||
WINECRYPT_CERTSTORE *store = context->store;
|
||||
|
||||
/* 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. */
|
||||
store->vtbl->releaseContext(store, context);
|
||||
store->vtbl->release(store, 0);
|
||||
}
|
||||
LeaveCriticalSection(&list->cs);
|
||||
}
|
||||
|
||||
void ContextList_Free(struct ContextList *list)
|
||||
void Context_CopyProperties(const void *to, const void *from)
|
||||
{
|
||||
ContextList_Empty(list);
|
||||
list->cs.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&list->cs);
|
||||
CryptMemFree(list);
|
||||
CONTEXT_PROPERTY_LIST *toProperties, *fromProperties;
|
||||
|
||||
toProperties = context_from_ptr(to)->properties;
|
||||
fromProperties = context_from_ptr(from)->properties;
|
||||
assert(toProperties && fromProperties);
|
||||
ContextPropertyList_Copy(toProperties, fromProperties);
|
||||
}
|
||||
|
|
|
@ -21,12 +21,66 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
||||
|
||||
static void CRL_free(context_t *context)
|
||||
{
|
||||
crl_t *crl = (crl_t*)context;
|
||||
|
||||
CryptMemFree(crl->ctx.pbCrlEncoded);
|
||||
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) {
|
||||
crl = (crl_t*)Context_CreateLinkContext(sizeof(CRL_CONTEXT), context, store);
|
||||
if(!crl)
|
||||
return NULL;
|
||||
}else {
|
||||
const crl_t *cloned = (const crl_t*)context;
|
||||
DWORD size = 0;
|
||||
BOOL res;
|
||||
|
||||
crl = (crl_t*)Context_CreateDataContext(sizeof(CRL_CONTEXT), &crl_vtbl, store);
|
||||
if(!crl)
|
||||
return NULL;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static const context_vtbl_t crl_vtbl = {
|
||||
CRL_free,
|
||||
CRL_clone
|
||||
};
|
||||
|
||||
PCCRL_CONTEXT WINAPI CertCreateCRLContext(DWORD dwCertEncodingType,
|
||||
const BYTE* pbCrlEncoded, DWORD cbCrlEncoded)
|
||||
{
|
||||
PCRL_CONTEXT crl = NULL;
|
||||
crl_t *crl = NULL;
|
||||
BOOL ret;
|
||||
PCRL_INFO crlInfo = NULL;
|
||||
BYTE *data = NULL;
|
||||
DWORD size = 0;
|
||||
|
||||
TRACE("(%08x, %p, %d)\n", dwCertEncodingType, pbCrlEncoded,
|
||||
|
@ -40,30 +94,28 @@ PCCRL_CONTEXT WINAPI CertCreateCRLContext(DWORD dwCertEncodingType,
|
|||
ret = CryptDecodeObjectEx(dwCertEncodingType, X509_CERT_CRL_TO_BE_SIGNED,
|
||||
pbCrlEncoded, cbCrlEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
|
||||
&crlInfo, &size);
|
||||
if (ret)
|
||||
{
|
||||
BYTE *data = NULL;
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
crl = Context_CreateDataContext(sizeof(CRL_CONTEXT));
|
||||
if (!crl)
|
||||
goto end;
|
||||
data = CryptMemAlloc(cbCrlEncoded);
|
||||
if (!data)
|
||||
{
|
||||
CertFreeCRLContext(crl);
|
||||
crl = NULL;
|
||||
goto end;
|
||||
}
|
||||
memcpy(data, pbCrlEncoded, cbCrlEncoded);
|
||||
crl->dwCertEncodingType = dwCertEncodingType;
|
||||
crl->pbCrlEncoded = data;
|
||||
crl->cbCrlEncoded = cbCrlEncoded;
|
||||
crl->pCrlInfo = crlInfo;
|
||||
crl->hCertStore = 0;
|
||||
crl = (crl_t*)Context_CreateDataContext(sizeof(CRL_CONTEXT), &crl_vtbl, &empty_store);
|
||||
if (!crl)
|
||||
return NULL;
|
||||
|
||||
data = CryptMemAlloc(cbCrlEncoded);
|
||||
if (!data)
|
||||
{
|
||||
Context_Release(&crl->base);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
end:
|
||||
return crl;
|
||||
memcpy(data, pbCrlEncoded, cbCrlEncoded);
|
||||
crl->ctx.dwCertEncodingType = dwCertEncodingType;
|
||||
crl->ctx.pbCrlEncoded = data;
|
||||
crl->ctx.cbCrlEncoded = cbCrlEncoded;
|
||||
crl->ctx.pCrlInfo = crlInfo;
|
||||
crl->ctx.hCertStore = &empty_store;
|
||||
|
||||
return &crl->ctx;
|
||||
}
|
||||
|
||||
BOOL WINAPI CertAddEncodedCRLToStore(HCERTSTORE hCertStore,
|
||||
|
@ -319,50 +371,31 @@ PCCRL_CONTEXT WINAPI CertDuplicateCRLContext(PCCRL_CONTEXT pCrlContext)
|
|||
{
|
||||
TRACE("(%p)\n", pCrlContext);
|
||||
if (pCrlContext)
|
||||
Context_AddRef((void *)pCrlContext, sizeof(CRL_CONTEXT));
|
||||
Context_AddRef(&crl_from_ptr(pCrlContext)->base);
|
||||
return pCrlContext;
|
||||
}
|
||||
|
||||
static void CrlDataContext_Free(void *context)
|
||||
BOOL WINAPI CertFreeCRLContext(PCCRL_CONTEXT pCrlContext)
|
||||
{
|
||||
PCRL_CONTEXT crlContext = context;
|
||||
|
||||
CryptMemFree(crlContext->pbCrlEncoded);
|
||||
LocalFree(crlContext->pCrlInfo);
|
||||
}
|
||||
|
||||
BOOL WINAPI CertFreeCRLContext( PCCRL_CONTEXT pCrlContext)
|
||||
{
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(%p)\n", pCrlContext);
|
||||
|
||||
if (pCrlContext)
|
||||
ret = Context_Release((void *)pCrlContext, sizeof(CRL_CONTEXT),
|
||||
CrlDataContext_Free);
|
||||
return ret;
|
||||
Context_Release(&crl_from_ptr(pCrlContext)->base);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DWORD WINAPI CertEnumCRLContextProperties(PCCRL_CONTEXT pCRLContext,
|
||||
DWORD dwPropId)
|
||||
{
|
||||
PCONTEXT_PROPERTY_LIST properties = Context_GetProperties(
|
||||
pCRLContext, sizeof(CRL_CONTEXT));
|
||||
DWORD ret;
|
||||
|
||||
TRACE("(%p, %d)\n", pCRLContext, dwPropId);
|
||||
|
||||
if (properties)
|
||||
ret = ContextPropertyList_EnumPropIDs(properties, dwPropId);
|
||||
else
|
||||
ret = 0;
|
||||
return ret;
|
||||
return ContextPropertyList_EnumPropIDs(crl_from_ptr(pCRLContext)->base.properties, dwPropId);
|
||||
}
|
||||
|
||||
static BOOL CRLContext_SetProperty(PCCRL_CONTEXT context, DWORD dwPropId,
|
||||
static BOOL CRLContext_SetProperty(crl_t *crl, DWORD dwPropId,
|
||||
DWORD dwFlags, const void *pvData);
|
||||
|
||||
static BOOL CRLContext_GetHashProp(PCCRL_CONTEXT context, DWORD dwPropId,
|
||||
static BOOL CRLContext_GetHashProp(crl_t *crl, DWORD dwPropId,
|
||||
ALG_ID algID, const BYTE *toHash, DWORD toHashLen, void *pvData,
|
||||
DWORD *pcbData)
|
||||
{
|
||||
|
@ -372,23 +405,21 @@ static BOOL CRLContext_GetHashProp(PCCRL_CONTEXT context, DWORD dwPropId,
|
|||
{
|
||||
CRYPT_DATA_BLOB blob = { *pcbData, pvData };
|
||||
|
||||
ret = CRLContext_SetProperty(context, dwPropId, 0, &blob);
|
||||
ret = CRLContext_SetProperty(crl, dwPropId, 0, &blob);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRLContext_GetProperty(PCCRL_CONTEXT context, DWORD dwPropId,
|
||||
static BOOL CRLContext_GetProperty(crl_t *crl, DWORD dwPropId,
|
||||
void *pvData, DWORD *pcbData)
|
||||
{
|
||||
PCONTEXT_PROPERTY_LIST properties =
|
||||
Context_GetProperties(context, sizeof(CRL_CONTEXT));
|
||||
BOOL ret;
|
||||
CRYPT_DATA_BLOB blob;
|
||||
|
||||
TRACE("(%p, %d, %p, %p)\n", context, dwPropId, pvData, pcbData);
|
||||
TRACE("(%p, %d, %p, %p)\n", crl, dwPropId, pvData, pcbData);
|
||||
|
||||
if (properties)
|
||||
ret = ContextPropertyList_FindProperty(properties, dwPropId, &blob);
|
||||
if (crl->base.properties)
|
||||
ret = ContextPropertyList_FindProperty(crl->base.properties, dwPropId, &blob);
|
||||
else
|
||||
ret = FALSE;
|
||||
if (ret)
|
||||
|
@ -413,13 +444,13 @@ static BOOL CRLContext_GetProperty(PCCRL_CONTEXT context, DWORD dwPropId,
|
|||
switch (dwPropId)
|
||||
{
|
||||
case CERT_SHA1_HASH_PROP_ID:
|
||||
ret = CRLContext_GetHashProp(context, dwPropId, CALG_SHA1,
|
||||
context->pbCrlEncoded, context->cbCrlEncoded, pvData,
|
||||
ret = CRLContext_GetHashProp(crl, dwPropId, CALG_SHA1,
|
||||
crl->ctx.pbCrlEncoded, crl->ctx.cbCrlEncoded, pvData,
|
||||
pcbData);
|
||||
break;
|
||||
case CERT_MD5_HASH_PROP_ID:
|
||||
ret = CRLContext_GetHashProp(context, dwPropId, CALG_MD5,
|
||||
context->pbCrlEncoded, context->cbCrlEncoded, pvData,
|
||||
ret = CRLContext_GetHashProp(crl, dwPropId, CALG_MD5,
|
||||
crl->ctx.pbCrlEncoded, crl->ctx.cbCrlEncoded, pvData,
|
||||
pcbData);
|
||||
break;
|
||||
default:
|
||||
|
@ -460,37 +491,27 @@ BOOL WINAPI CertGetCRLContextProperty(PCCRL_CONTEXT pCRLContext,
|
|||
}
|
||||
else
|
||||
{
|
||||
if (pCRLContext->hCertStore)
|
||||
ret = CertGetStoreProperty(pCRLContext->hCertStore, dwPropId,
|
||||
pvData, pcbData);
|
||||
else
|
||||
{
|
||||
*(DWORD *)pvData = 0;
|
||||
ret = TRUE;
|
||||
}
|
||||
ret = CertGetStoreProperty(pCRLContext->hCertStore, dwPropId, pvData, pcbData);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = CRLContext_GetProperty(pCRLContext, dwPropId, pvData,
|
||||
pcbData);
|
||||
ret = CRLContext_GetProperty(crl_from_ptr(pCRLContext), dwPropId, pvData, pcbData);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRLContext_SetProperty(PCCRL_CONTEXT context, DWORD dwPropId,
|
||||
static BOOL CRLContext_SetProperty(crl_t *crl, DWORD dwPropId,
|
||||
DWORD dwFlags, const void *pvData)
|
||||
{
|
||||
PCONTEXT_PROPERTY_LIST properties =
|
||||
Context_GetProperties(context, sizeof(CRL_CONTEXT));
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %d, %08x, %p)\n", context, dwPropId, dwFlags, pvData);
|
||||
TRACE("(%p, %d, %08x, %p)\n", crl, dwPropId, dwFlags, pvData);
|
||||
|
||||
if (!properties)
|
||||
if (!crl->base.properties)
|
||||
ret = FALSE;
|
||||
else if (!pvData)
|
||||
{
|
||||
ContextPropertyList_RemoveProperty(properties, dwPropId);
|
||||
ContextPropertyList_RemoveProperty(crl->base.properties, dwPropId);
|
||||
ret = TRUE;
|
||||
}
|
||||
else
|
||||
|
@ -517,12 +538,12 @@ static BOOL CRLContext_SetProperty(PCCRL_CONTEXT context, DWORD dwPropId,
|
|||
{
|
||||
PCRYPT_DATA_BLOB blob = (PCRYPT_DATA_BLOB)pvData;
|
||||
|
||||
ret = ContextPropertyList_SetProperty(properties, dwPropId,
|
||||
ret = ContextPropertyList_SetProperty(crl->base.properties, dwPropId,
|
||||
blob->pbData, blob->cbData);
|
||||
break;
|
||||
}
|
||||
case CERT_DATE_STAMP_PROP_ID:
|
||||
ret = ContextPropertyList_SetProperty(properties, dwPropId,
|
||||
ret = ContextPropertyList_SetProperty(crl->base.properties, dwPropId,
|
||||
pvData, sizeof(FILETIME));
|
||||
break;
|
||||
default:
|
||||
|
@ -554,7 +575,7 @@ BOOL WINAPI CertSetCRLContextProperty(PCCRL_CONTEXT pCRLContext,
|
|||
SetLastError(E_INVALIDARG);
|
||||
return FALSE;
|
||||
}
|
||||
ret = CRLContext_SetProperty(pCRLContext, dwPropId, dwFlags, pvData);
|
||||
ret = CRLContext_SetProperty(crl_from_ptr(pCRLContext), dwPropId, dwFlags, pvData);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -188,6 +188,70 @@ void crypt_sip_free(void) DECLSPEC_HIDDEN;
|
|||
void root_store_free(void) DECLSPEC_HIDDEN;
|
||||
void default_chain_engine_free(void) DECLSPEC_HIDDEN;
|
||||
|
||||
/* (Internal) certificate store types and functions */
|
||||
struct WINE_CRYPTCERTSTORE;
|
||||
|
||||
typedef struct _CONTEXT_PROPERTY_LIST CONTEXT_PROPERTY_LIST;
|
||||
|
||||
typedef struct _context_t context_t;
|
||||
|
||||
typedef struct {
|
||||
void (*free)(context_t*);
|
||||
struct _context_t *(*clone)(context_t*,struct WINE_CRYPTCERTSTORE*,BOOL);
|
||||
} context_vtbl_t;
|
||||
|
||||
struct _context_t {
|
||||
const context_vtbl_t *vtbl;
|
||||
LONG ref;
|
||||
struct WINE_CRYPTCERTSTORE *store;
|
||||
struct _context_t *linked;
|
||||
CONTEXT_PROPERTY_LIST *properties;
|
||||
union {
|
||||
struct list entry;
|
||||
void *ptr;
|
||||
} u;
|
||||
};
|
||||
|
||||
static inline context_t *context_from_ptr(const void *ptr)
|
||||
{
|
||||
return (context_t*)ptr-1;
|
||||
}
|
||||
|
||||
static inline void *context_ptr(context_t *context)
|
||||
{
|
||||
return context+1;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
context_t base;
|
||||
CERT_CONTEXT ctx;
|
||||
} cert_t;
|
||||
|
||||
static inline cert_t *cert_from_ptr(const CERT_CONTEXT *ptr)
|
||||
{
|
||||
return CONTAINING_RECORD(ptr, cert_t, ctx);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
context_t base;
|
||||
CRL_CONTEXT ctx;
|
||||
} crl_t;
|
||||
|
||||
static inline crl_t *crl_from_ptr(const CRL_CONTEXT *ptr)
|
||||
{
|
||||
return CONTAINING_RECORD(ptr, crl_t, ctx);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
context_t base;
|
||||
CTL_CONTEXT ctx;
|
||||
} ctl_t;
|
||||
|
||||
static inline ctl_t *ctl_from_ptr(const CTL_CONTEXT *ptr)
|
||||
{
|
||||
return CONTAINING_RECORD(ptr, ctl_t, ctx);
|
||||
}
|
||||
|
||||
/* Some typedefs that make it easier to abstract which type of context we're
|
||||
* working with.
|
||||
*/
|
||||
|
@ -198,7 +262,6 @@ typedef BOOL (WINAPI *AddContextToStoreFunc)(HCERTSTORE hCertStore,
|
|||
typedef BOOL (WINAPI *AddEncodedContextToStoreFunc)(HCERTSTORE hCertStore,
|
||||
DWORD dwCertEncodingType, const BYTE *pbEncoded, DWORD cbEncoded,
|
||||
DWORD dwAddDisposition, const void **ppContext);
|
||||
typedef const void *(WINAPI *DuplicateContextFunc)(const void *context);
|
||||
typedef const void *(WINAPI *EnumContextsInStoreFunc)(HCERTSTORE hCertStore,
|
||||
const void *pPrevContext);
|
||||
typedef DWORD (WINAPI *EnumPropertiesFunc)(const void *context, DWORD dwPropId);
|
||||
|
@ -208,7 +271,6 @@ 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 *FreeContextFunc)(const void *context);
|
||||
typedef BOOL (WINAPI *DeleteContextFunc)(const void *contex);
|
||||
|
||||
/* An abstract context (certificate, CRL, or CTL) interface */
|
||||
|
@ -217,57 +279,41 @@ typedef struct _WINE_CONTEXT_INTERFACE
|
|||
CreateContextFunc create;
|
||||
AddContextToStoreFunc addContextToStore;
|
||||
AddEncodedContextToStoreFunc addEncodedToStore;
|
||||
DuplicateContextFunc duplicate;
|
||||
EnumContextsInStoreFunc enumContextsInStore;
|
||||
EnumPropertiesFunc enumProps;
|
||||
GetContextPropertyFunc getProp;
|
||||
SetContextPropertyFunc setProp;
|
||||
SerializeElementFunc serialize;
|
||||
FreeContextFunc free;
|
||||
DeleteContextFunc deleteFromStore;
|
||||
} WINE_CONTEXT_INTERFACE, *PWINE_CONTEXT_INTERFACE;
|
||||
typedef const WINE_CONTEXT_INTERFACE *PCWINE_CONTEXT_INTERFACE;
|
||||
} WINE_CONTEXT_INTERFACE;
|
||||
|
||||
extern PCWINE_CONTEXT_INTERFACE pCertInterface DECLSPEC_HIDDEN;
|
||||
extern PCWINE_CONTEXT_INTERFACE pCRLInterface DECLSPEC_HIDDEN;
|
||||
extern PCWINE_CONTEXT_INTERFACE pCTLInterface DECLSPEC_HIDDEN;
|
||||
|
||||
/* (Internal) certificate store types and functions */
|
||||
struct WINE_CRYPTCERTSTORE;
|
||||
extern const WINE_CONTEXT_INTERFACE *pCertInterface DECLSPEC_HIDDEN;
|
||||
extern const WINE_CONTEXT_INTERFACE *pCRLInterface DECLSPEC_HIDDEN;
|
||||
extern const WINE_CONTEXT_INTERFACE *pCTLInterface DECLSPEC_HIDDEN;
|
||||
|
||||
typedef struct WINE_CRYPTCERTSTORE * (*StoreOpenFunc)(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara);
|
||||
|
||||
/* 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 BOOL (*DeleteFunc)(struct WINE_CRYPTCERTSTORE *store, void *context);
|
||||
|
||||
typedef struct _CONTEXT_FUNCS
|
||||
{
|
||||
AddFunc addContext;
|
||||
EnumFunc enumContext;
|
||||
DeleteFunc deleteContext;
|
||||
} CONTEXT_FUNCS, *PCONTEXT_FUNCS;
|
||||
/* 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*,context_t*,context_t*,context_t**,BOOL);
|
||||
context_t *(*enumContext)(struct WINE_CRYPTCERTSTORE *store, context_t *prev);
|
||||
BOOL (*delete)(struct WINE_CRYPTCERTSTORE*,context_t*);
|
||||
} CONTEXT_FUNCS;
|
||||
|
||||
typedef enum _CertStoreType {
|
||||
StoreTypeMem,
|
||||
StoreTypeCollection,
|
||||
StoreTypeProvider,
|
||||
StoreTypeEmpty
|
||||
} CertStoreType;
|
||||
|
||||
struct _CONTEXT_PROPERTY_LIST;
|
||||
typedef struct _CONTEXT_PROPERTY_LIST *PCONTEXT_PROPERTY_LIST;
|
||||
|
||||
#define WINE_CRYPTCERTSTORE_MAGIC 0x74726563
|
||||
|
||||
/* A cert store is polymorphic through the use of function pointers. A type
|
||||
|
@ -277,49 +323,55 @@ typedef struct _CONTEXT_PROPERTY_LIST *PCONTEXT_PROPERTY_LIST;
|
|||
* - control is optional, but should be implemented by any store that supports
|
||||
* persistence
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
void (*addref)(struct WINE_CRYPTCERTSTORE*);
|
||||
DWORD (*release)(struct WINE_CRYPTCERTSTORE*,DWORD);
|
||||
void (*releaseContext)(struct WINE_CRYPTCERTSTORE*,context_t*);
|
||||
BOOL (*control)(struct WINE_CRYPTCERTSTORE*,DWORD,DWORD,void const*);
|
||||
CONTEXT_FUNCS certs;
|
||||
CONTEXT_FUNCS crls;
|
||||
CONTEXT_FUNCS ctls;
|
||||
} store_vtbl_t;
|
||||
|
||||
typedef struct WINE_CRYPTCERTSTORE
|
||||
{
|
||||
DWORD dwMagic;
|
||||
LONG ref;
|
||||
DWORD dwOpenFlags;
|
||||
CertStoreType type;
|
||||
PFN_CERT_STORE_PROV_CLOSE closeStore;
|
||||
CONTEXT_FUNCS certs;
|
||||
CONTEXT_FUNCS crls;
|
||||
CONTEXT_FUNCS ctls;
|
||||
PFN_CERT_STORE_PROV_CONTROL control; /* optional */
|
||||
PCONTEXT_PROPERTY_LIST properties;
|
||||
} WINECRYPT_CERTSTORE, *PWINECRYPT_CERTSTORE;
|
||||
const store_vtbl_t *vtbl;
|
||||
CONTEXT_PROPERTY_LIST *properties;
|
||||
} WINECRYPT_CERTSTORE;
|
||||
|
||||
void CRYPT_InitStore(WINECRYPT_CERTSTORE *store, DWORD dwFlags,
|
||||
CertStoreType type) DECLSPEC_HIDDEN;
|
||||
void CRYPT_FreeStore(PWINECRYPT_CERTSTORE store) DECLSPEC_HIDDEN;
|
||||
CertStoreType type, const store_vtbl_t*) DECLSPEC_HIDDEN;
|
||||
void CRYPT_FreeStore(WINECRYPT_CERTSTORE *store) DECLSPEC_HIDDEN;
|
||||
BOOL WINAPI I_CertUpdateStore(HCERTSTORE store1, HCERTSTORE store2, DWORD unk0,
|
||||
DWORD unk1) DECLSPEC_HIDDEN;
|
||||
|
||||
PWINECRYPT_CERTSTORE CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv,
|
||||
WINECRYPT_CERTSTORE *CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara) DECLSPEC_HIDDEN;
|
||||
PWINECRYPT_CERTSTORE CRYPT_ProvCreateStore(DWORD dwFlags,
|
||||
PWINECRYPT_CERTSTORE memStore, const CERT_STORE_PROV_INFO *pProvInfo) DECLSPEC_HIDDEN;
|
||||
PWINECRYPT_CERTSTORE CRYPT_ProvOpenStore(LPCSTR lpszStoreProvider,
|
||||
WINECRYPT_CERTSTORE *CRYPT_ProvCreateStore(DWORD dwFlags,
|
||||
WINECRYPT_CERTSTORE *memStore, const CERT_STORE_PROV_INFO *pProvInfo) DECLSPEC_HIDDEN;
|
||||
WINECRYPT_CERTSTORE *CRYPT_ProvOpenStore(LPCSTR lpszStoreProvider,
|
||||
DWORD dwEncodingType, HCRYPTPROV hCryptProv, DWORD dwFlags,
|
||||
const void *pvPara) DECLSPEC_HIDDEN;
|
||||
PWINECRYPT_CERTSTORE CRYPT_RegOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags,
|
||||
WINECRYPT_CERTSTORE *CRYPT_RegOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags,
|
||||
const void *pvPara) DECLSPEC_HIDDEN;
|
||||
PWINECRYPT_CERTSTORE CRYPT_FileOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags,
|
||||
WINECRYPT_CERTSTORE *CRYPT_FileOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags,
|
||||
const void *pvPara) DECLSPEC_HIDDEN;
|
||||
PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreA(HCRYPTPROV hCryptProv,
|
||||
WINECRYPT_CERTSTORE *CRYPT_FileNameOpenStoreA(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara) DECLSPEC_HIDDEN;
|
||||
PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv,
|
||||
WINECRYPT_CERTSTORE *CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara) DECLSPEC_HIDDEN;
|
||||
PWINECRYPT_CERTSTORE CRYPT_RootOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags) DECLSPEC_HIDDEN;
|
||||
WINECRYPT_CERTSTORE *CRYPT_RootOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Allocates and initializes a certificate chain engine, but without creating
|
||||
* the root store. Instead, it uses root, and assumes the caller has done any
|
||||
* checking necessary.
|
||||
*/
|
||||
HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE root,
|
||||
PCERT_CHAIN_ENGINE_CONFIG pConfig) DECLSPEC_HIDDEN;
|
||||
HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE, DWORD, const CERT_CHAIN_ENGINE_CONFIG*) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Helper function for store reading functions and
|
||||
* CertAddSerializedElementToStore. Returns a context of the appropriate type
|
||||
|
@ -365,89 +417,49 @@ DWORD cert_name_to_str_with_indent(DWORD dwCertEncodingType, DWORD indent,
|
|||
* which should be one of CERT_CONTEXT, CRL_CONTEXT, or CTL_CONTEXT.
|
||||
* Free with Context_Release.
|
||||
*/
|
||||
void *Context_CreateDataContext(size_t contextSize) DECLSPEC_HIDDEN;
|
||||
context_t *Context_CreateDataContext(size_t contextSize, const context_vtbl_t *vtbl, struct WINE_CRYPTCERTSTORE*) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Creates a new link context with extra bytes. 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
|
||||
* it should be) linked is addref'd.
|
||||
* Free with Context_Release.
|
||||
*/
|
||||
void *Context_CreateLinkContext(unsigned int contextSize, void *linked, unsigned int extra,
|
||||
BOOL addRef) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Returns a pointer to the extra bytes allocated with context, which must be
|
||||
* a link context.
|
||||
*/
|
||||
void *Context_GetExtra(const void *context, size_t contextSize) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Gets the context linked to by context, which must be a link context. */
|
||||
void *Context_GetLinkedContext(void *context, size_t contextSize) DECLSPEC_HIDDEN;
|
||||
context_t *Context_CreateLinkContext(unsigned contextSize, context_t *linked, struct WINE_CRYPTCERTSTORE*) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Copies properties from fromContext to toContext. */
|
||||
void Context_CopyProperties(const void *to, const void *from,
|
||||
size_t contextSize) DECLSPEC_HIDDEN;
|
||||
void Context_CopyProperties(const void *to, const void *from) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Returns context's properties, or the linked context's properties if context
|
||||
* is a link context.
|
||||
*/
|
||||
PCONTEXT_PROPERTY_LIST Context_GetProperties(const void *context, size_t contextSize) DECLSPEC_HIDDEN;
|
||||
|
||||
void Context_AddRef(void *context, size_t contextSize) DECLSPEC_HIDDEN;
|
||||
|
||||
typedef void (*ContextFreeFunc)(void *context);
|
||||
|
||||
/* Decrements context's ref count. If context is a link context, releases its
|
||||
* linked context as well.
|
||||
* If a data context has its ref count reach 0, calls dataContextFree on it.
|
||||
* Returns FALSE if the reference count is <= 0 when called.
|
||||
*/
|
||||
BOOL Context_Release(void *context, size_t contextSize,
|
||||
ContextFreeFunc dataContextFree) DECLSPEC_HIDDEN;
|
||||
void Context_AddRef(context_t*) DECLSPEC_HIDDEN;
|
||||
void Context_Release(context_t *context) DECLSPEC_HIDDEN;
|
||||
void Context_Free(context_t*) DECLSPEC_HIDDEN;
|
||||
|
||||
/**
|
||||
* Context property list functions
|
||||
*/
|
||||
|
||||
PCONTEXT_PROPERTY_LIST ContextPropertyList_Create(void) DECLSPEC_HIDDEN;
|
||||
CONTEXT_PROPERTY_LIST *ContextPropertyList_Create(void) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Searches for the property with ID id in the context. Returns TRUE if found,
|
||||
* and copies the property's length and a pointer to its data to blob.
|
||||
* Otherwise returns FALSE.
|
||||
*/
|
||||
BOOL ContextPropertyList_FindProperty(PCONTEXT_PROPERTY_LIST list, DWORD id,
|
||||
BOOL ContextPropertyList_FindProperty(CONTEXT_PROPERTY_LIST *list, DWORD id,
|
||||
PCRYPT_DATA_BLOB blob) DECLSPEC_HIDDEN;
|
||||
|
||||
BOOL ContextPropertyList_SetProperty(PCONTEXT_PROPERTY_LIST list, DWORD id,
|
||||
BOOL ContextPropertyList_SetProperty(CONTEXT_PROPERTY_LIST *list, DWORD id,
|
||||
const BYTE *pbData, size_t cbData) DECLSPEC_HIDDEN;
|
||||
|
||||
void ContextPropertyList_RemoveProperty(PCONTEXT_PROPERTY_LIST list, DWORD id) DECLSPEC_HIDDEN;
|
||||
void ContextPropertyList_RemoveProperty(CONTEXT_PROPERTY_LIST *list, DWORD id) DECLSPEC_HIDDEN;
|
||||
|
||||
DWORD ContextPropertyList_EnumPropIDs(PCONTEXT_PROPERTY_LIST list, DWORD id) DECLSPEC_HIDDEN;
|
||||
DWORD ContextPropertyList_EnumPropIDs(CONTEXT_PROPERTY_LIST *list, DWORD id) DECLSPEC_HIDDEN;
|
||||
|
||||
void ContextPropertyList_Copy(PCONTEXT_PROPERTY_LIST to,
|
||||
PCONTEXT_PROPERTY_LIST from) DECLSPEC_HIDDEN;
|
||||
void ContextPropertyList_Copy(CONTEXT_PROPERTY_LIST *to,
|
||||
CONTEXT_PROPERTY_LIST *from) DECLSPEC_HIDDEN;
|
||||
|
||||
void ContextPropertyList_Free(PCONTEXT_PROPERTY_LIST list) DECLSPEC_HIDDEN;
|
||||
void ContextPropertyList_Free(CONTEXT_PROPERTY_LIST *list) DECLSPEC_HIDDEN;
|
||||
|
||||
/**
|
||||
* Context list functions. A context list is a simple list of link contexts.
|
||||
*/
|
||||
struct ContextList;
|
||||
|
||||
struct ContextList *ContextList_Create(
|
||||
PCWINE_CONTEXT_INTERFACE contextInterface, size_t contextSize) DECLSPEC_HIDDEN;
|
||||
|
||||
void *ContextList_Add(struct ContextList *list, void *toLink, void *toReplace) DECLSPEC_HIDDEN;
|
||||
|
||||
void *ContextList_Enum(struct ContextList *list, void *pPrev) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Removes a context from the list. Returns TRUE if the context was removed,
|
||||
* or FALSE if not. (The context may have been duplicated, so subsequent
|
||||
* removes have no effect.)
|
||||
*/
|
||||
BOOL ContextList_Remove(struct ContextList *list, void *context) DECLSPEC_HIDDEN;
|
||||
|
||||
void ContextList_Free(struct ContextList *list) DECLSPEC_HIDDEN;
|
||||
extern WINECRYPT_CERTSTORE empty_store;
|
||||
void init_empty_store(void) DECLSPEC_HIDDEN;
|
||||
|
||||
/**
|
||||
* Utilities.
|
||||
|
|
|
@ -21,14 +21,43 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
||||
|
||||
#define CtlContext_CopyProperties(to, from) \
|
||||
Context_CopyProperties((to), (from), sizeof(CTL_CONTEXT))
|
||||
static void CTL_free(context_t *context)
|
||||
{
|
||||
ctl_t *ctl = (ctl_t*)context;
|
||||
|
||||
CryptMsgClose(ctl->ctx.hCryptMsg);
|
||||
CryptMemFree(ctl->ctx.pbCtlEncoded);
|
||||
CryptMemFree(ctl->ctx.pbCtlContext);
|
||||
LocalFree(ctl->ctx.pCtlInfo);
|
||||
}
|
||||
|
||||
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, store);
|
||||
if(!ctl)
|
||||
return NULL;
|
||||
|
||||
ctl->ctx.hCertStore = store;
|
||||
return &ctl->base;
|
||||
}
|
||||
|
||||
static const context_vtbl_t ctl_vtbl = {
|
||||
CTL_free,
|
||||
CTL_clone
|
||||
};
|
||||
|
||||
BOOL WINAPI CertAddCTLContextToStore(HCERTSTORE hCertStore,
|
||||
PCCTL_CONTEXT pCtlContext, DWORD dwAddDisposition,
|
||||
PCCTL_CONTEXT* ppStoreContext)
|
||||
{
|
||||
PWINECRYPT_CERTSTORE store = hCertStore;
|
||||
WINECRYPT_CERTSTORE *store = hCertStore;
|
||||
BOOL ret = TRUE;
|
||||
PCCTL_CONTEXT toAdd = NULL, existing = NULL;
|
||||
|
||||
|
@ -83,7 +112,7 @@ BOOL WINAPI CertAddCTLContextToStore(HCERTSTORE hCertStore,
|
|||
if (newer < 0)
|
||||
{
|
||||
toAdd = CertDuplicateCTLContext(pCtlContext);
|
||||
CtlContext_CopyProperties(existing, pCtlContext);
|
||||
Context_CopyProperties(existing, pCtlContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -101,12 +130,12 @@ BOOL WINAPI CertAddCTLContextToStore(HCERTSTORE hCertStore,
|
|||
case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
|
||||
toAdd = CertDuplicateCTLContext(pCtlContext);
|
||||
if (existing)
|
||||
CtlContext_CopyProperties(toAdd, existing);
|
||||
Context_CopyProperties(toAdd, existing);
|
||||
break;
|
||||
case CERT_STORE_ADD_USE_EXISTING:
|
||||
if (existing)
|
||||
{
|
||||
CtlContext_CopyProperties(existing, pCtlContext);
|
||||
Context_CopyProperties(existing, pCtlContext);
|
||||
if (ppStoreContext)
|
||||
*ppStoreContext = CertDuplicateCTLContext(existing);
|
||||
}
|
||||
|
@ -120,11 +149,16 @@ BOOL WINAPI CertAddCTLContextToStore(HCERTSTORE hCertStore,
|
|||
|
||||
if (toAdd)
|
||||
{
|
||||
if (store)
|
||||
ret = store->ctls.addContext(store, (void *)toAdd,
|
||||
(void *)existing, (const void **)ppStoreContext);
|
||||
else if (ppStoreContext)
|
||||
if (store) {
|
||||
context_t *ret_ctx;
|
||||
|
||||
ret = store->vtbl->ctls.addContext(store, context_from_ptr(toAdd),
|
||||
existing ? context_from_ptr(existing) : NULL, ppStoreContext ? &ret_ctx : NULL, TRUE);
|
||||
if(ret && ppStoreContext)
|
||||
*ppStoreContext = context_ptr(ret_ctx);
|
||||
}else if (ppStoreContext) {
|
||||
*ppStoreContext = CertDuplicateCTLContext(toAdd);
|
||||
}
|
||||
CertFreeCTLContext(toAdd);
|
||||
}
|
||||
CertFreeCTLContext(existing);
|
||||
|
@ -156,11 +190,10 @@ BOOL WINAPI CertAddEncodedCTLToStore(HCERTSTORE hCertStore,
|
|||
return ret;
|
||||
}
|
||||
|
||||
PCCTL_CONTEXT WINAPI CertEnumCTLsInStore(HCERTSTORE hCertStore,
|
||||
PCCTL_CONTEXT pPrev)
|
||||
PCCTL_CONTEXT WINAPI CertEnumCTLsInStore(HCERTSTORE hCertStore, PCCTL_CONTEXT pPrev)
|
||||
{
|
||||
ctl_t *prev = pPrev ? ctl_from_ptr(pPrev) : NULL, *ret;
|
||||
WINECRYPT_CERTSTORE *hcs = hCertStore;
|
||||
PCCTL_CONTEXT ret;
|
||||
|
||||
TRACE("(%p, %p)\n", hCertStore, pPrev);
|
||||
if (!hCertStore)
|
||||
|
@ -168,8 +201,8 @@ PCCTL_CONTEXT WINAPI CertEnumCTLsInStore(HCERTSTORE hCertStore,
|
|||
else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
|
||||
ret = NULL;
|
||||
else
|
||||
ret = (PCCTL_CONTEXT)hcs->ctls.enumContext(hcs, (void *)pPrev);
|
||||
return ret;
|
||||
ret = (ctl_t*)hcs->vtbl->ctls.enumContext(hcs, prev ? &prev->base : NULL);
|
||||
return ret ? &ret->ctx : NULL;
|
||||
}
|
||||
|
||||
typedef BOOL (*CtlCompareFunc)(PCCTL_CONTEXT pCtlContext, DWORD dwType,
|
||||
|
@ -300,32 +333,30 @@ PCCTL_CONTEXT WINAPI CertFindCTLInStore(HCERTSTORE hCertStore,
|
|||
|
||||
BOOL WINAPI CertDeleteCTLFromStore(PCCTL_CONTEXT pCtlContext)
|
||||
{
|
||||
WINECRYPT_CERTSTORE *hcs;
|
||||
ctl_t *ctl = ctl_from_ptr(pCtlContext);
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p)\n", pCtlContext);
|
||||
|
||||
if (!pCtlContext)
|
||||
ret = TRUE;
|
||||
else if (!pCtlContext->hCertStore)
|
||||
ret = CertFreeCTLContext(pCtlContext);
|
||||
else
|
||||
{
|
||||
PWINECRYPT_CERTSTORE hcs = pCtlContext->hCertStore;
|
||||
return TRUE;
|
||||
|
||||
if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
|
||||
ret = FALSE;
|
||||
else
|
||||
ret = hcs->ctls.deleteContext(hcs, (void *)pCtlContext);
|
||||
if (ret)
|
||||
ret = CertFreeCTLContext(pCtlContext);
|
||||
}
|
||||
hcs = pCtlContext->hCertStore;
|
||||
|
||||
if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
|
||||
return FALSE;
|
||||
|
||||
ret = hcs->vtbl->ctls.delete(hcs, &ctl->base);
|
||||
if (ret)
|
||||
ret = CertFreeCTLContext(pCtlContext);
|
||||
return ret;
|
||||
}
|
||||
|
||||
PCCTL_CONTEXT WINAPI CertCreateCTLContext(DWORD dwMsgAndCertEncodingType,
|
||||
const BYTE *pbCtlEncoded, DWORD cbCtlEncoded)
|
||||
{
|
||||
PCTL_CONTEXT ctl = NULL;
|
||||
ctl_t *ctl = NULL;
|
||||
HCRYPTMSG msg;
|
||||
BOOL ret;
|
||||
BYTE *content = NULL;
|
||||
|
@ -398,7 +429,7 @@ PCCTL_CONTEXT WINAPI CertCreateCTLContext(DWORD dwMsgAndCertEncodingType,
|
|||
&ctlInfo, &size);
|
||||
if (ret)
|
||||
{
|
||||
ctl = Context_CreateDataContext(sizeof(CTL_CONTEXT));
|
||||
ctl = (ctl_t*)Context_CreateDataContext(sizeof(CTL_CONTEXT), &ctl_vtbl, &empty_store);
|
||||
if (ctl)
|
||||
{
|
||||
BYTE *data = CryptMemAlloc(cbCtlEncoded);
|
||||
|
@ -406,15 +437,15 @@ PCCTL_CONTEXT WINAPI CertCreateCTLContext(DWORD dwMsgAndCertEncodingType,
|
|||
if (data)
|
||||
{
|
||||
memcpy(data, pbCtlEncoded, cbCtlEncoded);
|
||||
ctl->dwMsgAndCertEncodingType =
|
||||
ctl->ctx.dwMsgAndCertEncodingType =
|
||||
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
|
||||
ctl->pbCtlEncoded = data;
|
||||
ctl->cbCtlEncoded = cbCtlEncoded;
|
||||
ctl->pCtlInfo = ctlInfo;
|
||||
ctl->hCertStore = NULL;
|
||||
ctl->hCryptMsg = msg;
|
||||
ctl->pbCtlContext = content;
|
||||
ctl->cbCtlContext = contentSize;
|
||||
ctl->ctx.pbCtlEncoded = data;
|
||||
ctl->ctx.cbCtlEncoded = cbCtlEncoded;
|
||||
ctl->ctx.pCtlInfo = ctlInfo;
|
||||
ctl->ctx.hCertStore = &empty_store;
|
||||
ctl->ctx.hCryptMsg = msg;
|
||||
ctl->ctx.pbCtlContext = content;
|
||||
ctl->ctx.cbCtlContext = contentSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -439,65 +470,53 @@ PCCTL_CONTEXT WINAPI CertCreateCTLContext(DWORD dwMsgAndCertEncodingType,
|
|||
end:
|
||||
if (!ret)
|
||||
{
|
||||
CertFreeCTLContext(ctl);
|
||||
if(ctl)
|
||||
Context_Release(&ctl->base);
|
||||
ctl = NULL;
|
||||
LocalFree(ctlInfo);
|
||||
CryptMemFree(content);
|
||||
CryptMsgClose(msg);
|
||||
return NULL;
|
||||
}
|
||||
return ctl;
|
||||
return &ctl->ctx;
|
||||
}
|
||||
|
||||
PCCTL_CONTEXT WINAPI CertDuplicateCTLContext(PCCTL_CONTEXT pCtlContext)
|
||||
{
|
||||
TRACE("(%p)\n", pCtlContext);
|
||||
if (pCtlContext)
|
||||
Context_AddRef((void *)pCtlContext, sizeof(CTL_CONTEXT));
|
||||
Context_AddRef(&ctl_from_ptr(pCtlContext)->base);
|
||||
return pCtlContext;
|
||||
}
|
||||
|
||||
static void CTLDataContext_Free(void *context)
|
||||
{
|
||||
PCTL_CONTEXT ctlContext = context;
|
||||
|
||||
CryptMsgClose(ctlContext->hCryptMsg);
|
||||
CryptMemFree(ctlContext->pbCtlEncoded);
|
||||
CryptMemFree(ctlContext->pbCtlContext);
|
||||
LocalFree(ctlContext->pCtlInfo);
|
||||
}
|
||||
|
||||
BOOL WINAPI CertFreeCTLContext(PCCTL_CONTEXT pCTLContext)
|
||||
{
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(%p)\n", pCTLContext);
|
||||
|
||||
if (pCTLContext)
|
||||
ret = Context_Release((void *)pCTLContext, sizeof(CTL_CONTEXT),
|
||||
CTLDataContext_Free);
|
||||
return ret;
|
||||
Context_Release(&ctl_from_ptr(pCTLContext)->base);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DWORD WINAPI CertEnumCTLContextProperties(PCCTL_CONTEXT pCTLContext,
|
||||
DWORD dwPropId)
|
||||
{
|
||||
PCONTEXT_PROPERTY_LIST properties = Context_GetProperties(
|
||||
pCTLContext, sizeof(CTL_CONTEXT));
|
||||
ctl_t *ctl = ctl_from_ptr(pCTLContext);
|
||||
DWORD ret;
|
||||
|
||||
TRACE("(%p, %d)\n", pCTLContext, dwPropId);
|
||||
|
||||
if (properties)
|
||||
ret = ContextPropertyList_EnumPropIDs(properties, dwPropId);
|
||||
if (ctl->base.properties)
|
||||
ret = ContextPropertyList_EnumPropIDs(ctl->base.properties, dwPropId);
|
||||
else
|
||||
ret = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CTLContext_SetProperty(PCCTL_CONTEXT context, DWORD dwPropId,
|
||||
static BOOL CTLContext_SetProperty(ctl_t *ctl, DWORD dwPropId,
|
||||
DWORD dwFlags, const void *pvData);
|
||||
|
||||
static BOOL CTLContext_GetHashProp(PCCTL_CONTEXT context, DWORD dwPropId,
|
||||
static BOOL CTLContext_GetHashProp(ctl_t *ctl, DWORD dwPropId,
|
||||
ALG_ID algID, const BYTE *toHash, DWORD toHashLen, void *pvData,
|
||||
DWORD *pcbData)
|
||||
{
|
||||
|
@ -507,23 +526,21 @@ static BOOL CTLContext_GetHashProp(PCCTL_CONTEXT context, DWORD dwPropId,
|
|||
{
|
||||
CRYPT_DATA_BLOB blob = { *pcbData, pvData };
|
||||
|
||||
ret = CTLContext_SetProperty(context, dwPropId, 0, &blob);
|
||||
ret = CTLContext_SetProperty(ctl, dwPropId, 0, &blob);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CTLContext_GetProperty(PCCTL_CONTEXT context, DWORD dwPropId,
|
||||
static BOOL CTLContext_GetProperty(ctl_t *ctl, DWORD dwPropId,
|
||||
void *pvData, DWORD *pcbData)
|
||||
{
|
||||
PCONTEXT_PROPERTY_LIST properties =
|
||||
Context_GetProperties(context, sizeof(CTL_CONTEXT));
|
||||
BOOL ret;
|
||||
CRYPT_DATA_BLOB blob;
|
||||
|
||||
TRACE("(%p, %d, %p, %p)\n", context, dwPropId, pvData, pcbData);
|
||||
TRACE("(%p, %d, %p, %p)\n", ctl, dwPropId, pvData, pcbData);
|
||||
|
||||
if (properties)
|
||||
ret = ContextPropertyList_FindProperty(properties, dwPropId, &blob);
|
||||
if (ctl->base.properties)
|
||||
ret = ContextPropertyList_FindProperty(ctl->base.properties, dwPropId, &blob);
|
||||
else
|
||||
ret = FALSE;
|
||||
if (ret)
|
||||
|
@ -548,12 +565,12 @@ static BOOL CTLContext_GetProperty(PCCTL_CONTEXT context, DWORD dwPropId,
|
|||
switch (dwPropId)
|
||||
{
|
||||
case CERT_SHA1_HASH_PROP_ID:
|
||||
ret = CTLContext_GetHashProp(context, dwPropId, CALG_SHA1,
|
||||
context->pbCtlEncoded, context->cbCtlEncoded, pvData, pcbData);
|
||||
ret = CTLContext_GetHashProp(ctl, dwPropId, CALG_SHA1,
|
||||
ctl->ctx.pbCtlEncoded, ctl->ctx.cbCtlEncoded, pvData, pcbData);
|
||||
break;
|
||||
case CERT_MD5_HASH_PROP_ID:
|
||||
ret = CTLContext_GetHashProp(context, dwPropId, CALG_MD5,
|
||||
context->pbCtlEncoded, context->cbCtlEncoded, pvData, pcbData);
|
||||
ret = CTLContext_GetHashProp(ctl, dwPropId, CALG_MD5,
|
||||
ctl->ctx.pbCtlEncoded, ctl->ctx.cbCtlEncoded, pvData, pcbData);
|
||||
break;
|
||||
default:
|
||||
SetLastError(CRYPT_E_NOT_FOUND);
|
||||
|
@ -593,37 +610,28 @@ BOOL WINAPI CertGetCTLContextProperty(PCCTL_CONTEXT pCTLContext,
|
|||
}
|
||||
else
|
||||
{
|
||||
if (pCTLContext->hCertStore)
|
||||
ret = CertGetStoreProperty(pCTLContext->hCertStore, dwPropId,
|
||||
pvData, pcbData);
|
||||
else
|
||||
{
|
||||
*(DWORD *)pvData = 0;
|
||||
ret = TRUE;
|
||||
}
|
||||
ret = CertGetStoreProperty(pCTLContext->hCertStore, dwPropId, pvData, pcbData);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = CTLContext_GetProperty(pCTLContext, dwPropId, pvData,
|
||||
ret = CTLContext_GetProperty(ctl_from_ptr(pCTLContext), dwPropId, pvData,
|
||||
pcbData);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CTLContext_SetProperty(PCCTL_CONTEXT context, DWORD dwPropId,
|
||||
static BOOL CTLContext_SetProperty(ctl_t *ctl, DWORD dwPropId,
|
||||
DWORD dwFlags, const void *pvData)
|
||||
{
|
||||
PCONTEXT_PROPERTY_LIST properties =
|
||||
Context_GetProperties(context, sizeof(CTL_CONTEXT));
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %d, %08x, %p)\n", context, dwPropId, dwFlags, pvData);
|
||||
TRACE("(%p, %d, %08x, %p)\n", ctl, dwPropId, dwFlags, pvData);
|
||||
|
||||
if (!properties)
|
||||
if (!ctl->base.properties)
|
||||
ret = FALSE;
|
||||
else if (!pvData)
|
||||
{
|
||||
ContextPropertyList_RemoveProperty(properties, dwPropId);
|
||||
ContextPropertyList_RemoveProperty(ctl->base.properties, dwPropId);
|
||||
ret = TRUE;
|
||||
}
|
||||
else
|
||||
|
@ -650,12 +658,12 @@ static BOOL CTLContext_SetProperty(PCCTL_CONTEXT context, DWORD dwPropId,
|
|||
{
|
||||
PCRYPT_DATA_BLOB blob = (PCRYPT_DATA_BLOB)pvData;
|
||||
|
||||
ret = ContextPropertyList_SetProperty(properties, dwPropId,
|
||||
ret = ContextPropertyList_SetProperty(ctl->base.properties, dwPropId,
|
||||
blob->pbData, blob->cbData);
|
||||
break;
|
||||
}
|
||||
case CERT_DATE_STAMP_PROP_ID:
|
||||
ret = ContextPropertyList_SetProperty(properties, dwPropId,
|
||||
ret = ContextPropertyList_SetProperty(ctl->base.properties, dwPropId,
|
||||
pvData, sizeof(FILETIME));
|
||||
break;
|
||||
default:
|
||||
|
@ -687,7 +695,7 @@ BOOL WINAPI CertSetCTLContextProperty(PCCTL_CONTEXT pCTLContext,
|
|||
SetLastError(E_INVALIDARG);
|
||||
return FALSE;
|
||||
}
|
||||
ret = CTLContext_SetProperty(pCTLContext, dwPropId, dwFlags, pvData);
|
||||
ret = CTLContext_SetProperty(ctl_from_ptr(pCTLContext), dwPropId, dwFlags, pvData);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -2060,7 +2060,7 @@ static BOOL CRYPT_AsnEncodeNumericString(const CERT_NAME_VALUE *value,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static inline int isprintableW(WCHAR wc)
|
||||
static inline BOOL isprintableW(WCHAR wc)
|
||||
{
|
||||
return isalnumW(wc) || isspaceW(wc) || wc == '\'' || wc == '(' ||
|
||||
wc == ')' || wc == '+' || wc == ',' || wc == '-' || wc == '.' ||
|
||||
|
|
|
@ -27,11 +27,11 @@ typedef struct _WINE_FILESTOREINFO
|
|||
HANDLE file;
|
||||
DWORD type;
|
||||
BOOL dirty;
|
||||
} WINE_FILESTOREINFO, *PWINE_FILESTOREINFO;
|
||||
} WINE_FILESTOREINFO;
|
||||
|
||||
static void WINAPI CRYPT_FileCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
|
||||
{
|
||||
PWINE_FILESTOREINFO store = hCertStore;
|
||||
WINE_FILESTOREINFO *store = hCertStore;
|
||||
|
||||
TRACE("(%p, %08x)\n", store, dwFlags);
|
||||
if (store->dirty)
|
||||
|
@ -44,7 +44,7 @@ static void WINAPI CRYPT_FileCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
|
|||
static BOOL WINAPI CRYPT_FileWriteCert(HCERTSTORE hCertStore,
|
||||
PCCERT_CONTEXT cert, DWORD dwFlags)
|
||||
{
|
||||
PWINE_FILESTOREINFO store = hCertStore;
|
||||
WINE_FILESTOREINFO *store = hCertStore;
|
||||
|
||||
TRACE("(%p, %p, %d)\n", hCertStore, cert, dwFlags);
|
||||
store->dirty = TRUE;
|
||||
|
@ -54,7 +54,7 @@ static BOOL WINAPI CRYPT_FileWriteCert(HCERTSTORE hCertStore,
|
|||
static BOOL WINAPI CRYPT_FileDeleteCert(HCERTSTORE hCertStore,
|
||||
PCCERT_CONTEXT pCertContext, DWORD dwFlags)
|
||||
{
|
||||
PWINE_FILESTOREINFO store = hCertStore;
|
||||
WINE_FILESTOREINFO *store = hCertStore;
|
||||
|
||||
TRACE("(%p, %p, %08x)\n", hCertStore, pCertContext, dwFlags);
|
||||
store->dirty = TRUE;
|
||||
|
@ -64,7 +64,7 @@ static BOOL WINAPI CRYPT_FileDeleteCert(HCERTSTORE hCertStore,
|
|||
static BOOL WINAPI CRYPT_FileWriteCRL(HCERTSTORE hCertStore,
|
||||
PCCRL_CONTEXT crl, DWORD dwFlags)
|
||||
{
|
||||
PWINE_FILESTOREINFO store = hCertStore;
|
||||
WINE_FILESTOREINFO *store = hCertStore;
|
||||
|
||||
TRACE("(%p, %p, %d)\n", hCertStore, crl, dwFlags);
|
||||
store->dirty = TRUE;
|
||||
|
@ -74,7 +74,7 @@ static BOOL WINAPI CRYPT_FileWriteCRL(HCERTSTORE hCertStore,
|
|||
static BOOL WINAPI CRYPT_FileDeleteCRL(HCERTSTORE hCertStore,
|
||||
PCCRL_CONTEXT pCrlContext, DWORD dwFlags)
|
||||
{
|
||||
PWINE_FILESTOREINFO store = hCertStore;
|
||||
WINE_FILESTOREINFO *store = hCertStore;
|
||||
|
||||
TRACE("(%p, %p, %08x)\n", hCertStore, pCrlContext, dwFlags);
|
||||
store->dirty = TRUE;
|
||||
|
@ -84,7 +84,7 @@ static BOOL WINAPI CRYPT_FileDeleteCRL(HCERTSTORE hCertStore,
|
|||
static BOOL WINAPI CRYPT_FileWriteCTL(HCERTSTORE hCertStore,
|
||||
PCCTL_CONTEXT ctl, DWORD dwFlags)
|
||||
{
|
||||
PWINE_FILESTOREINFO store = hCertStore;
|
||||
WINE_FILESTOREINFO *store = hCertStore;
|
||||
|
||||
TRACE("(%p, %p, %d)\n", hCertStore, ctl, dwFlags);
|
||||
store->dirty = TRUE;
|
||||
|
@ -94,7 +94,7 @@ static BOOL WINAPI CRYPT_FileWriteCTL(HCERTSTORE hCertStore,
|
|||
static BOOL WINAPI CRYPT_FileDeleteCTL(HCERTSTORE hCertStore,
|
||||
PCCTL_CONTEXT pCtlContext, DWORD dwFlags)
|
||||
{
|
||||
PWINE_FILESTOREINFO store = hCertStore;
|
||||
WINE_FILESTOREINFO *store = hCertStore;
|
||||
|
||||
TRACE("(%p, %p, %08x)\n", hCertStore, pCtlContext, dwFlags);
|
||||
store->dirty = TRUE;
|
||||
|
@ -113,8 +113,11 @@ static BOOL CRYPT_ReadBlobFromFile(HANDLE file, PCERT_BLOB blob)
|
|||
{
|
||||
DWORD read;
|
||||
|
||||
ret = ReadFile(file, blob->pbData, blob->cbData, &read, NULL);
|
||||
ret = ReadFile(file, blob->pbData, blob->cbData, &read, NULL) && read == blob->cbData;
|
||||
if (!ret) CryptMemFree(blob->pbData);
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -122,7 +125,7 @@ static BOOL CRYPT_ReadBlobFromFile(HANDLE file, PCERT_BLOB blob)
|
|||
static BOOL WINAPI CRYPT_FileControl(HCERTSTORE hCertStore, DWORD dwFlags,
|
||||
DWORD dwCtrlType, void const *pvCtrlPara)
|
||||
{
|
||||
PWINE_FILESTOREINFO store = hCertStore;
|
||||
WINE_FILESTOREINFO *store = hCertStore;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
|
||||
|
@ -206,11 +209,11 @@ static void *fileProvFuncs[] = {
|
|||
CRYPT_FileControl,
|
||||
};
|
||||
|
||||
static PWINECRYPT_CERTSTORE CRYPT_CreateFileStore(DWORD dwFlags,
|
||||
static WINECRYPT_CERTSTORE *CRYPT_CreateFileStore(DWORD dwFlags,
|
||||
HCERTSTORE memStore, HANDLE file, DWORD type)
|
||||
{
|
||||
PWINECRYPT_CERTSTORE store = NULL;
|
||||
PWINE_FILESTOREINFO info = CryptMemAlloc(sizeof(WINE_FILESTOREINFO));
|
||||
WINECRYPT_CERTSTORE *store = NULL;
|
||||
WINE_FILESTOREINFO *info = CryptMemAlloc(sizeof(WINE_FILESTOREINFO));
|
||||
|
||||
if (info)
|
||||
{
|
||||
|
@ -231,10 +234,10 @@ static PWINECRYPT_CERTSTORE CRYPT_CreateFileStore(DWORD dwFlags,
|
|||
return store;
|
||||
}
|
||||
|
||||
PWINECRYPT_CERTSTORE CRYPT_FileOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags,
|
||||
WINECRYPT_CERTSTORE *CRYPT_FileOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags,
|
||||
const void *pvPara)
|
||||
{
|
||||
PWINECRYPT_CERTSTORE store = NULL;
|
||||
WINECRYPT_CERTSTORE *store = NULL;
|
||||
HANDLE file = (HANDLE)pvPara;
|
||||
|
||||
TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
|
||||
|
@ -281,7 +284,7 @@ PWINECRYPT_CERTSTORE CRYPT_FileOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags,
|
|||
return store;
|
||||
}
|
||||
|
||||
PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv,
|
||||
WINECRYPT_CERTSTORE *CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
HCERTSTORE store = 0;
|
||||
|
@ -372,11 +375,11 @@ PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv,
|
|||
return store;
|
||||
}
|
||||
|
||||
PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreA(HCRYPTPROV hCryptProv,
|
||||
WINECRYPT_CERTSTORE *CRYPT_FileNameOpenStoreA(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
int len;
|
||||
PWINECRYPT_CERTSTORE ret = NULL;
|
||||
WINECRYPT_CERTSTORE *ret = NULL;
|
||||
|
||||
TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
|
||||
debugstr_a(pvPara));
|
||||
|
|
|
@ -33,6 +33,7 @@ BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, PVOID pvReserved)
|
|||
case DLL_PROCESS_ATTACH:
|
||||
hInstance = hInst;
|
||||
DisableThreadLibraryCalls(hInst);
|
||||
init_empty_store();
|
||||
crypt_oid_init();
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
|
|
|
@ -591,20 +591,20 @@ typedef struct _CMSG_SIGNER_ENCODE_INFO_WITH_CMS
|
|||
CERT_ID SignerId;
|
||||
CRYPT_ALGORITHM_IDENTIFIER HashEncryptionAlgorithm;
|
||||
void *pvHashEncryptionAuxInfo;
|
||||
} CMSG_SIGNER_ENCODE_INFO_WITH_CMS, *PCMSG_SIGNER_ENCODE_INFO_WITH_CMS;
|
||||
} CMSG_SIGNER_ENCODE_INFO_WITH_CMS;
|
||||
|
||||
typedef struct _CMSG_SIGNED_ENCODE_INFO_WITH_CMS
|
||||
{
|
||||
DWORD cbSize;
|
||||
DWORD cSigners;
|
||||
PCMSG_SIGNER_ENCODE_INFO_WITH_CMS rgSigners;
|
||||
CMSG_SIGNER_ENCODE_INFO_WITH_CMS *rgSigners;
|
||||
DWORD cCertEncoded;
|
||||
PCERT_BLOB rgCertEncoded;
|
||||
DWORD cCrlEncoded;
|
||||
PCRL_BLOB rgCrlEncoded;
|
||||
DWORD cAttrCertEncoded;
|
||||
PCERT_BLOB rgAttrCertEncoded;
|
||||
} CMSG_SIGNED_ENCODE_INFO_WITH_CMS, *PCMSG_SIGNED_ENCODE_INFO_WITH_CMS;
|
||||
} CMSG_SIGNED_ENCODE_INFO_WITH_CMS;
|
||||
|
||||
static BOOL CRYPT_IsValidSigner(const CMSG_SIGNER_ENCODE_INFO_WITH_CMS *signer)
|
||||
{
|
||||
|
@ -1462,7 +1462,7 @@ typedef struct _CMSG_ENVELOPED_ENCODE_INFO_WITH_CMS
|
|||
PCERT_BLOB rgAttrCertEncoded;
|
||||
DWORD cUnprotectedAttr;
|
||||
PCRYPT_ATTRIBUTE rgUnprotectedAttr;
|
||||
} CMSG_ENVELOPED_ENCODE_INFO_WITH_CMS, *PCMSG_ENVELOPED_ENCODE_INFO_WITH_CMS;
|
||||
} CMSG_ENVELOPED_ENCODE_INFO_WITH_CMS;
|
||||
|
||||
typedef struct _CEnvelopedEncodeMsg
|
||||
{
|
||||
|
@ -2059,7 +2059,7 @@ typedef struct _CDecodeMsg
|
|||
} u;
|
||||
CRYPT_DATA_BLOB msg_data;
|
||||
CRYPT_DATA_BLOB detached_data;
|
||||
PCONTEXT_PROPERTY_LIST properties;
|
||||
CONTEXT_PROPERTY_LIST *properties;
|
||||
} CDecodeMsg;
|
||||
|
||||
static void CDecodeMsg_Close(HCRYPTMSG hCryptMsg)
|
||||
|
|
|
@ -44,8 +44,11 @@ static BOOL CRYPT_ReadBlobFromFile(LPCWSTR fileName, PCERT_BLOB blob)
|
|||
{
|
||||
DWORD read;
|
||||
|
||||
ret = ReadFile(file, blob->pbData, blob->cbData, &read, NULL);
|
||||
ret = ReadFile(file, blob->pbData, blob->cbData, &read, NULL) && read == blob->cbData;
|
||||
if (!ret) CryptMemFree(blob->pbData);
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
}
|
||||
CloseHandle(file);
|
||||
}
|
||||
|
@ -263,12 +266,15 @@ static BOOL CRYPT_QuerySerializedContextObject(DWORD dwObjectType,
|
|||
*phCertStore = CertDuplicateStore(
|
||||
*(HCERTSTORE *)((const BYTE *)context + certStoreOffset));
|
||||
if (ppvContext)
|
||||
*ppvContext = contextInterface->duplicate(context);
|
||||
{
|
||||
*ppvContext = context;
|
||||
Context_AddRef(context_from_ptr(context));
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
if (contextInterface && context)
|
||||
contextInterface->free(context);
|
||||
Context_Release(context_from_ptr(context));
|
||||
if (blob == &fileBlob)
|
||||
CryptMemFree(blob->pbData);
|
||||
TRACE("returning %d\n", ret);
|
||||
|
|
|
@ -1093,6 +1093,7 @@ static const WCHAR SpcFinancialCriteria[] = { 'S','p','c','F','i','n','a','n','c
|
|||
static const WCHAR SpcMinimalCriteria[] = { 'S','p','c','M','i','n','i','m','a','l','C','r','i','t','e','r','i','a',0 };
|
||||
static const WCHAR Email[] = { 'E','m','a','i','l',0 };
|
||||
static const WCHAR GN[] = { 'G','N',0 };
|
||||
static const WCHAR SERIALNUMBER[] = { 'S','E','R','I','A','L','N','U','M','B','E','R',0 };
|
||||
|
||||
static const DWORD noNullFlag = CRYPT_OID_NO_NULL_ALGORITHM_PARA_FLAG;
|
||||
static const DWORD mosaicFlags = CRYPT_OID_INHIBIT_SIGNATURE_FORMAT_FLAG |
|
||||
|
@ -1212,6 +1213,7 @@ static const struct OIDInfoConstructor {
|
|||
{ 5, szOID_TELEPHONE_NUMBER, 0, Phone, &printableStringBlob },
|
||||
{ 5, szOID_X21_ADDRESS, 0, X21Address, &numericStringBlob },
|
||||
{ 5, szOID_DN_QUALIFIER, 0, dnQualifier, NULL },
|
||||
{ 5, szOID_DEVICE_SERIAL_NUMBER, 0, SERIALNUMBER, NULL },
|
||||
|
||||
{ 6, szOID_AUTHORITY_KEY_IDENTIFIER2, 0, (LPCWSTR)IDS_AUTHORITY_KEY_ID, NULL },
|
||||
{ 6, szOID_AUTHORITY_KEY_IDENTIFIER, 0, (LPCWSTR)IDS_AUTHORITY_KEY_ID, NULL },
|
||||
|
|
|
@ -20,11 +20,11 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
||||
|
||||
typedef struct _CONTEXT_PROPERTY_LIST
|
||||
struct _CONTEXT_PROPERTY_LIST
|
||||
{
|
||||
CRITICAL_SECTION cs;
|
||||
struct list properties;
|
||||
} CONTEXT_PROPERTY_LIST;
|
||||
};
|
||||
|
||||
typedef struct _CONTEXT_PROPERTY
|
||||
{
|
||||
|
@ -32,11 +32,11 @@ typedef struct _CONTEXT_PROPERTY
|
|||
DWORD cbData;
|
||||
LPBYTE pbData;
|
||||
struct list entry;
|
||||
} CONTEXT_PROPERTY, *PCONTEXT_PROPERTY;
|
||||
} CONTEXT_PROPERTY;
|
||||
|
||||
PCONTEXT_PROPERTY_LIST ContextPropertyList_Create(void)
|
||||
CONTEXT_PROPERTY_LIST *ContextPropertyList_Create(void)
|
||||
{
|
||||
PCONTEXT_PROPERTY_LIST list = CryptMemAlloc(sizeof(CONTEXT_PROPERTY_LIST));
|
||||
CONTEXT_PROPERTY_LIST *list = CryptMemAlloc(sizeof(CONTEXT_PROPERTY_LIST));
|
||||
|
||||
if (list)
|
||||
{
|
||||
|
@ -47,9 +47,9 @@ PCONTEXT_PROPERTY_LIST ContextPropertyList_Create(void)
|
|||
return list;
|
||||
}
|
||||
|
||||
void ContextPropertyList_Free(PCONTEXT_PROPERTY_LIST list)
|
||||
void ContextPropertyList_Free(CONTEXT_PROPERTY_LIST *list)
|
||||
{
|
||||
PCONTEXT_PROPERTY prop, next;
|
||||
CONTEXT_PROPERTY *prop, *next;
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(prop, next, &list->properties, CONTEXT_PROPERTY,
|
||||
entry)
|
||||
|
@ -63,10 +63,10 @@ void ContextPropertyList_Free(PCONTEXT_PROPERTY_LIST list)
|
|||
CryptMemFree(list);
|
||||
}
|
||||
|
||||
BOOL ContextPropertyList_FindProperty(PCONTEXT_PROPERTY_LIST list, DWORD id,
|
||||
BOOL ContextPropertyList_FindProperty(CONTEXT_PROPERTY_LIST *list, DWORD id,
|
||||
PCRYPT_DATA_BLOB blob)
|
||||
{
|
||||
PCONTEXT_PROPERTY prop;
|
||||
CONTEXT_PROPERTY *prop;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
TRACE("(%p, %d, %p)\n", list, id, blob);
|
||||
|
@ -86,7 +86,7 @@ BOOL ContextPropertyList_FindProperty(PCONTEXT_PROPERTY_LIST list, DWORD id,
|
|||
return ret;
|
||||
}
|
||||
|
||||
BOOL ContextPropertyList_SetProperty(PCONTEXT_PROPERTY_LIST list, DWORD id,
|
||||
BOOL ContextPropertyList_SetProperty(CONTEXT_PROPERTY_LIST *list, DWORD id,
|
||||
const BYTE *pbData, size_t cbData)
|
||||
{
|
||||
LPBYTE data;
|
||||
|
@ -102,7 +102,7 @@ BOOL ContextPropertyList_SetProperty(PCONTEXT_PROPERTY_LIST list, DWORD id,
|
|||
data = NULL;
|
||||
if (!cbData || data)
|
||||
{
|
||||
PCONTEXT_PROPERTY prop;
|
||||
CONTEXT_PROPERTY *prop;
|
||||
BOOL found = FALSE;
|
||||
|
||||
EnterCriticalSection(&list->cs);
|
||||
|
@ -140,9 +140,9 @@ BOOL ContextPropertyList_SetProperty(PCONTEXT_PROPERTY_LIST list, DWORD id,
|
|||
return ret;
|
||||
}
|
||||
|
||||
void ContextPropertyList_RemoveProperty(PCONTEXT_PROPERTY_LIST list, DWORD id)
|
||||
void ContextPropertyList_RemoveProperty(CONTEXT_PROPERTY_LIST *list, DWORD id)
|
||||
{
|
||||
PCONTEXT_PROPERTY prop, next;
|
||||
CONTEXT_PROPERTY *prop, *next;
|
||||
|
||||
EnterCriticalSection(&list->cs);
|
||||
LIST_FOR_EACH_ENTRY_SAFE(prop, next, &list->properties, CONTEXT_PROPERTY,
|
||||
|
@ -162,19 +162,22 @@ void ContextPropertyList_RemoveProperty(PCONTEXT_PROPERTY_LIST list, DWORD id)
|
|||
/* Since the properties are stored in a list, this is a tad inefficient
|
||||
* (O(n^2)) since I have to find the previous position every time.
|
||||
*/
|
||||
DWORD ContextPropertyList_EnumPropIDs(PCONTEXT_PROPERTY_LIST list, DWORD id)
|
||||
DWORD ContextPropertyList_EnumPropIDs(CONTEXT_PROPERTY_LIST *list, DWORD id)
|
||||
{
|
||||
DWORD ret;
|
||||
|
||||
EnterCriticalSection(&list->cs);
|
||||
if (id)
|
||||
{
|
||||
PCONTEXT_PROPERTY cursor = NULL;
|
||||
CONTEXT_PROPERTY *cursor = NULL, *prop;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(cursor, &list->properties, CONTEXT_PROPERTY, entry)
|
||||
LIST_FOR_EACH_ENTRY(prop, &list->properties, CONTEXT_PROPERTY, entry)
|
||||
{
|
||||
if (cursor->propID == id)
|
||||
if (prop->propID == id)
|
||||
{
|
||||
cursor = prop;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cursor)
|
||||
{
|
||||
|
@ -196,10 +199,9 @@ DWORD ContextPropertyList_EnumPropIDs(PCONTEXT_PROPERTY_LIST list, DWORD id)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void ContextPropertyList_Copy(PCONTEXT_PROPERTY_LIST to,
|
||||
PCONTEXT_PROPERTY_LIST from)
|
||||
void ContextPropertyList_Copy(CONTEXT_PROPERTY_LIST *to, CONTEXT_PROPERTY_LIST *from)
|
||||
{
|
||||
PCONTEXT_PROPERTY prop;
|
||||
CONTEXT_PROPERTY *prop;
|
||||
|
||||
EnterCriticalSection(&from->cs);
|
||||
LIST_FOR_EACH_ENTRY(prop, &from->properties, CONTEXT_PROPERTY, entry)
|
||||
|
|
|
@ -24,7 +24,7 @@ typedef struct _WINE_PROVIDERSTORE
|
|||
{
|
||||
WINECRYPT_CERTSTORE hdr;
|
||||
DWORD dwStoreProvFlags;
|
||||
PWINECRYPT_CERTSTORE memStore;
|
||||
WINECRYPT_CERTSTORE *memStore;
|
||||
HCERTSTOREPROV hStoreProv;
|
||||
PFN_CERT_STORE_PROV_CLOSE provCloseStore;
|
||||
PFN_CERT_STORE_PROV_WRITE_CERT provWriteCert;
|
||||
|
@ -34,91 +34,112 @@ typedef struct _WINE_PROVIDERSTORE
|
|||
PFN_CERT_STORE_PROV_WRITE_CTL provWriteCtl;
|
||||
PFN_CERT_STORE_PROV_DELETE_CTL provDeleteCtl;
|
||||
PFN_CERT_STORE_PROV_CONTROL provControl;
|
||||
} WINE_PROVIDERSTORE, *PWINE_PROVIDERSTORE;
|
||||
} WINE_PROVIDERSTORE;
|
||||
|
||||
static void WINAPI CRYPT_ProvCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
|
||||
static void ProvStore_addref(WINECRYPT_CERTSTORE *store)
|
||||
{
|
||||
PWINE_PROVIDERSTORE store = hCertStore;
|
||||
|
||||
TRACE("(%p, %08x)\n", store, dwFlags);
|
||||
|
||||
if (store->provCloseStore)
|
||||
store->provCloseStore(store->hStoreProv, dwFlags);
|
||||
if (!(store->dwStoreProvFlags & CERT_STORE_PROV_EXTERNAL_FLAG))
|
||||
CertCloseStore(store->memStore, dwFlags);
|
||||
CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
|
||||
LONG ref = InterlockedIncrement(&store->ref);
|
||||
TRACE("ref = %d\n", ref);
|
||||
}
|
||||
|
||||
static BOOL CRYPT_ProvAddCert(PWINECRYPT_CERTSTORE store, void *cert,
|
||||
void *toReplace, const void **ppStoreContext)
|
||||
static DWORD ProvStore_release(WINECRYPT_CERTSTORE *cert_store, DWORD flags)
|
||||
{
|
||||
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
|
||||
WINE_PROVIDERSTORE *store = (WINE_PROVIDERSTORE*)cert_store;
|
||||
LONG ref;
|
||||
|
||||
if(flags)
|
||||
FIXME("Unimplemented flags %x\n", flags);
|
||||
|
||||
ref = InterlockedDecrement(&store->hdr.ref);
|
||||
TRACE("(%p) ref=%d\n", store, ref);
|
||||
|
||||
if(ref)
|
||||
return ERROR_SUCCESS;
|
||||
|
||||
if (store->provCloseStore)
|
||||
store->provCloseStore(store->hStoreProv, flags);
|
||||
if (!(store->dwStoreProvFlags & CERT_STORE_PROV_EXTERNAL_FLAG))
|
||||
store->memStore->vtbl->release(store->memStore, flags);
|
||||
CRYPT_FreeStore(&store->hdr);
|
||||
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,
|
||||
context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
|
||||
{
|
||||
WINE_PROVIDERSTORE *ps = (WINE_PROVIDERSTORE*)store;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %p, %p, %p)\n", store, cert, toReplace, ppStoreContext);
|
||||
|
||||
if (toReplace)
|
||||
ret = ps->memStore->certs.addContext(ps->memStore, cert, toReplace,
|
||||
ppStoreContext);
|
||||
ret = ps->memStore->vtbl->certs.addContext(ps->memStore, cert, toReplace,
|
||||
ppStoreContext, TRUE);
|
||||
else
|
||||
{
|
||||
ret = TRUE;
|
||||
if (ps->provWriteCert)
|
||||
ret = ps->provWriteCert(ps->hStoreProv, cert,
|
||||
CERT_STORE_PROV_WRITE_ADD_FLAG);
|
||||
ret = ps->provWriteCert(ps->hStoreProv, context_ptr(cert), CERT_STORE_PROV_WRITE_ADD_FLAG);
|
||||
if (ret)
|
||||
ret = ps->memStore->certs.addContext(ps->memStore, cert, NULL,
|
||||
ppStoreContext);
|
||||
ret = ps->memStore->vtbl->certs.addContext(ps->memStore, cert, NULL,
|
||||
ppStoreContext, TRUE);
|
||||
}
|
||||
/* dirty trick: replace the returned context's hCertStore with
|
||||
* store.
|
||||
*/
|
||||
if (ret && ppStoreContext)
|
||||
(*(PCERT_CONTEXT *)ppStoreContext)->hCertStore = store;
|
||||
(*(cert_t**)ppStoreContext)->ctx.hCertStore = store;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *CRYPT_ProvEnumCert(PWINECRYPT_CERTSTORE store, void *pPrev)
|
||||
static context_t *ProvStore_enumCert(WINECRYPT_CERTSTORE *store, context_t *prev)
|
||||
{
|
||||
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
|
||||
void *ret;
|
||||
WINE_PROVIDERSTORE *ps = (WINE_PROVIDERSTORE*)store;
|
||||
cert_t *ret;
|
||||
|
||||
ret = ps->memStore->certs.enumContext(ps->memStore, pPrev);
|
||||
if (ret)
|
||||
{
|
||||
/* same dirty trick: replace the returned context's hCertStore with
|
||||
* store.
|
||||
*/
|
||||
((PCERT_CONTEXT)ret)->hCertStore = store;
|
||||
}
|
||||
return ret;
|
||||
ret = (cert_t*)ps->memStore->vtbl->certs.enumContext(ps->memStore, prev);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
/* same dirty trick: replace the returned context's hCertStore with
|
||||
* store.
|
||||
*/
|
||||
ret->ctx.hCertStore = store;
|
||||
return &ret->base;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_ProvDeleteCert(PWINECRYPT_CERTSTORE store, void *cert)
|
||||
static BOOL ProvStore_deleteCert(WINECRYPT_CERTSTORE *store, context_t *context)
|
||||
{
|
||||
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
|
||||
WINE_PROVIDERSTORE *ps = (WINE_PROVIDERSTORE*)store;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(%p, %p)\n", store, cert);
|
||||
TRACE("(%p, %p)\n", store, context);
|
||||
|
||||
if (ps->provDeleteCert)
|
||||
ret = ps->provDeleteCert(ps->hStoreProv, cert, 0);
|
||||
ret = ps->provDeleteCert(ps->hStoreProv, context_ptr(context), 0);
|
||||
if (ret)
|
||||
ret = ps->memStore->certs.deleteContext(ps->memStore, cert);
|
||||
ret = ps->memStore->vtbl->certs.delete(ps->memStore, context);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_ProvAddCRL(PWINECRYPT_CERTSTORE store, void *crl,
|
||||
void *toReplace, const void **ppStoreContext)
|
||||
static BOOL ProvStore_addCRL(WINECRYPT_CERTSTORE *store, context_t *crl,
|
||||
context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
|
||||
{
|
||||
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
|
||||
WINE_PROVIDERSTORE *ps = (WINE_PROVIDERSTORE*)store;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %p, %p, %p)\n", store, crl, toReplace, ppStoreContext);
|
||||
|
||||
if (toReplace)
|
||||
ret = ps->memStore->crls.addContext(ps->memStore, crl, toReplace,
|
||||
ppStoreContext);
|
||||
ret = ps->memStore->vtbl->crls.addContext(ps->memStore, crl, toReplace,
|
||||
ppStoreContext, TRUE);
|
||||
else
|
||||
{
|
||||
if (ps->hdr.dwOpenFlags & CERT_STORE_READONLY_FLAG)
|
||||
|
@ -130,62 +151,62 @@ static BOOL CRYPT_ProvAddCRL(PWINECRYPT_CERTSTORE store, void *crl,
|
|||
{
|
||||
ret = TRUE;
|
||||
if (ps->provWriteCrl)
|
||||
ret = ps->provWriteCrl(ps->hStoreProv, crl,
|
||||
ret = ps->provWriteCrl(ps->hStoreProv, context_ptr(crl),
|
||||
CERT_STORE_PROV_WRITE_ADD_FLAG);
|
||||
if (ret)
|
||||
ret = ps->memStore->crls.addContext(ps->memStore, crl, NULL,
|
||||
ppStoreContext);
|
||||
ret = ps->memStore->vtbl->crls.addContext(ps->memStore, crl, NULL,
|
||||
ppStoreContext, TRUE);
|
||||
}
|
||||
}
|
||||
/* dirty trick: replace the returned context's hCertStore with
|
||||
* store.
|
||||
*/
|
||||
if (ret && ppStoreContext)
|
||||
(*(PCRL_CONTEXT *)ppStoreContext)->hCertStore = store;
|
||||
(*(crl_t**)ppStoreContext)->ctx.hCertStore = store;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *CRYPT_ProvEnumCRL(PWINECRYPT_CERTSTORE store, void *pPrev)
|
||||
static context_t *ProvStore_enumCRL(WINECRYPT_CERTSTORE *store, context_t *prev)
|
||||
{
|
||||
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
|
||||
void *ret;
|
||||
WINE_PROVIDERSTORE *ps = (WINE_PROVIDERSTORE*)store;
|
||||
crl_t *ret;
|
||||
|
||||
ret = ps->memStore->crls.enumContext(ps->memStore, pPrev);
|
||||
if (ret)
|
||||
{
|
||||
/* same dirty trick: replace the returned context's hCertStore with
|
||||
* store.
|
||||
*/
|
||||
((PCRL_CONTEXT)ret)->hCertStore = store;
|
||||
}
|
||||
return ret;
|
||||
ret = (crl_t*)ps->memStore->vtbl->crls.enumContext(ps->memStore, prev);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
/* same dirty trick: replace the returned context's hCertStore with
|
||||
* store.
|
||||
*/
|
||||
ret->ctx.hCertStore = store;
|
||||
return &ret->base;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_ProvDeleteCRL(PWINECRYPT_CERTSTORE store, void *crl)
|
||||
static BOOL ProvStore_deleteCRL(WINECRYPT_CERTSTORE *store, context_t *crl)
|
||||
{
|
||||
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
|
||||
WINE_PROVIDERSTORE *ps = (WINE_PROVIDERSTORE*)store;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(%p, %p)\n", store, crl);
|
||||
|
||||
if (ps->provDeleteCrl)
|
||||
ret = ps->provDeleteCrl(ps->hStoreProv, crl, 0);
|
||||
ret = ps->provDeleteCrl(ps->hStoreProv, context_ptr(crl), 0);
|
||||
if (ret)
|
||||
ret = ps->memStore->crls.deleteContext(ps->memStore, crl);
|
||||
ret = ps->memStore->vtbl->crls.delete(ps->memStore, crl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_ProvAddCTL(PWINECRYPT_CERTSTORE store, void *ctl,
|
||||
void *toReplace, const void **ppStoreContext)
|
||||
static BOOL ProvStore_addCTL(WINECRYPT_CERTSTORE *store, context_t *ctl,
|
||||
context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
|
||||
{
|
||||
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
|
||||
WINE_PROVIDERSTORE *ps = (WINE_PROVIDERSTORE*)store;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %p, %p, %p)\n", store, ctl, toReplace, ppStoreContext);
|
||||
|
||||
if (toReplace)
|
||||
ret = ps->memStore->ctls.addContext(ps->memStore, ctl, toReplace,
|
||||
ppStoreContext);
|
||||
ret = ps->memStore->vtbl->ctls.addContext(ps->memStore, ctl, toReplace,
|
||||
ppStoreContext, TRUE);
|
||||
else
|
||||
{
|
||||
if (ps->hdr.dwOpenFlags & CERT_STORE_READONLY_FLAG)
|
||||
|
@ -197,58 +218,57 @@ static BOOL CRYPT_ProvAddCTL(PWINECRYPT_CERTSTORE store, void *ctl,
|
|||
{
|
||||
ret = TRUE;
|
||||
if (ps->provWriteCtl)
|
||||
ret = ps->provWriteCtl(ps->hStoreProv, ctl,
|
||||
ret = ps->provWriteCtl(ps->hStoreProv, context_ptr(ctl),
|
||||
CERT_STORE_PROV_WRITE_ADD_FLAG);
|
||||
if (ret)
|
||||
ret = ps->memStore->ctls.addContext(ps->memStore, ctl, NULL,
|
||||
ppStoreContext);
|
||||
ret = ps->memStore->vtbl->ctls.addContext(ps->memStore, ctl, NULL,
|
||||
ppStoreContext, TRUE);
|
||||
}
|
||||
}
|
||||
/* dirty trick: replace the returned context's hCertStore with
|
||||
* store.
|
||||
*/
|
||||
if (ret && ppStoreContext)
|
||||
(*(PCTL_CONTEXT *)ppStoreContext)->hCertStore = store;
|
||||
(*(ctl_t**)ppStoreContext)->ctx.hCertStore = store;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *CRYPT_ProvEnumCTL(PWINECRYPT_CERTSTORE store, void *pPrev)
|
||||
static context_t *ProvStore_enumCTL(WINECRYPT_CERTSTORE *store, context_t *prev)
|
||||
{
|
||||
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
|
||||
void *ret;
|
||||
WINE_PROVIDERSTORE *ps = (WINE_PROVIDERSTORE*)store;
|
||||
ctl_t *ret;
|
||||
|
||||
ret = ps->memStore->ctls.enumContext(ps->memStore, pPrev);
|
||||
if (ret)
|
||||
{
|
||||
/* same dirty trick: replace the returned context's hCertStore with
|
||||
* store.
|
||||
*/
|
||||
((PCTL_CONTEXT)ret)->hCertStore = store;
|
||||
}
|
||||
return ret;
|
||||
ret = (ctl_t*)ps->memStore->vtbl->ctls.enumContext(ps->memStore, prev);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
/* same dirty trick: replace the returned context's hCertStore with
|
||||
* store.
|
||||
*/
|
||||
ret->ctx.hCertStore = store;
|
||||
return &ret->base;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_ProvDeleteCTL(PWINECRYPT_CERTSTORE store, void *ctl)
|
||||
static BOOL ProvStore_deleteCTL(WINECRYPT_CERTSTORE *store, context_t *ctl)
|
||||
{
|
||||
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
|
||||
WINE_PROVIDERSTORE *ps = (WINE_PROVIDERSTORE*)store;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(%p, %p)\n", store, ctl);
|
||||
|
||||
if (ps->provDeleteCtl)
|
||||
ret = ps->provDeleteCtl(ps->hStoreProv, ctl, 0);
|
||||
ret = ps->provDeleteCtl(ps->hStoreProv, context_ptr(ctl), 0);
|
||||
if (ret)
|
||||
ret = ps->memStore->ctls.deleteContext(ps->memStore, ctl);
|
||||
ret = ps->memStore->vtbl->ctls.delete(ps->memStore, ctl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_ProvControl(HCERTSTORE hCertStore, DWORD dwFlags,
|
||||
DWORD dwCtrlType, void const *pvCtrlPara)
|
||||
static BOOL ProvStore_control(WINECRYPT_CERTSTORE *cert_store, DWORD dwFlags, DWORD dwCtrlType, void const *pvCtrlPara)
|
||||
{
|
||||
PWINE_PROVIDERSTORE store = hCertStore;
|
||||
WINE_PROVIDERSTORE *store = (WINE_PROVIDERSTORE*)cert_store;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
|
||||
TRACE("(%p, %08x, %d, %p)\n", store, dwFlags, dwCtrlType,
|
||||
pvCtrlPara);
|
||||
|
||||
if (store->provControl)
|
||||
|
@ -257,14 +277,34 @@ static BOOL WINAPI CRYPT_ProvControl(HCERTSTORE hCertStore, DWORD dwFlags,
|
|||
return ret;
|
||||
}
|
||||
|
||||
PWINECRYPT_CERTSTORE CRYPT_ProvCreateStore(DWORD dwFlags,
|
||||
PWINECRYPT_CERTSTORE memStore, const CERT_STORE_PROV_INFO *pProvInfo)
|
||||
static const store_vtbl_t ProvStoreVtbl = {
|
||||
ProvStore_addref,
|
||||
ProvStore_release,
|
||||
ProvStore_releaseContext,
|
||||
ProvStore_control,
|
||||
{
|
||||
ProvStore_addCert,
|
||||
ProvStore_enumCert,
|
||||
ProvStore_deleteCert
|
||||
}, {
|
||||
ProvStore_addCRL,
|
||||
ProvStore_enumCRL,
|
||||
ProvStore_deleteCRL
|
||||
}, {
|
||||
ProvStore_addCTL,
|
||||
ProvStore_enumCTL,
|
||||
ProvStore_deleteCTL
|
||||
}
|
||||
};
|
||||
|
||||
WINECRYPT_CERTSTORE *CRYPT_ProvCreateStore(DWORD dwFlags,
|
||||
WINECRYPT_CERTSTORE *memStore, const CERT_STORE_PROV_INFO *pProvInfo)
|
||||
{
|
||||
PWINE_PROVIDERSTORE ret = CryptMemAlloc(sizeof(WINE_PROVIDERSTORE));
|
||||
WINE_PROVIDERSTORE *ret = CryptMemAlloc(sizeof(WINE_PROVIDERSTORE));
|
||||
|
||||
if (ret)
|
||||
{
|
||||
CRYPT_InitStore(&ret->hdr, dwFlags, StoreTypeProvider);
|
||||
CRYPT_InitStore(&ret->hdr, dwFlags, StoreTypeProvider, &ProvStoreVtbl);
|
||||
ret->dwStoreProvFlags = pProvInfo->dwStoreProvFlags;
|
||||
if (ret->dwStoreProvFlags & CERT_STORE_PROV_EXTERNAL_FLAG)
|
||||
{
|
||||
|
@ -274,17 +314,6 @@ PWINECRYPT_CERTSTORE CRYPT_ProvCreateStore(DWORD dwFlags,
|
|||
else
|
||||
ret->memStore = memStore;
|
||||
ret->hStoreProv = pProvInfo->hStoreProv;
|
||||
ret->hdr.closeStore = CRYPT_ProvCloseStore;
|
||||
ret->hdr.certs.addContext = CRYPT_ProvAddCert;
|
||||
ret->hdr.certs.enumContext = CRYPT_ProvEnumCert;
|
||||
ret->hdr.certs.deleteContext = CRYPT_ProvDeleteCert;
|
||||
ret->hdr.crls.addContext = CRYPT_ProvAddCRL;
|
||||
ret->hdr.crls.enumContext = CRYPT_ProvEnumCRL;
|
||||
ret->hdr.crls.deleteContext = CRYPT_ProvDeleteCRL;
|
||||
ret->hdr.ctls.addContext = CRYPT_ProvAddCTL;
|
||||
ret->hdr.ctls.enumContext = CRYPT_ProvEnumCTL;
|
||||
ret->hdr.ctls.deleteContext = CRYPT_ProvDeleteCTL;
|
||||
ret->hdr.control = CRYPT_ProvControl;
|
||||
if (pProvInfo->cStoreProvFunc > CERT_STORE_PROV_CLOSE_FUNC)
|
||||
ret->provCloseStore =
|
||||
pProvInfo->rgpvStoreProvFunc[CERT_STORE_PROV_CLOSE_FUNC];
|
||||
|
@ -333,16 +362,16 @@ PWINECRYPT_CERTSTORE CRYPT_ProvCreateStore(DWORD dwFlags,
|
|||
else
|
||||
ret->provControl = NULL;
|
||||
}
|
||||
return (PWINECRYPT_CERTSTORE)ret;
|
||||
return (WINECRYPT_CERTSTORE*)ret;
|
||||
}
|
||||
|
||||
PWINECRYPT_CERTSTORE CRYPT_ProvOpenStore(LPCSTR lpszStoreProvider,
|
||||
WINECRYPT_CERTSTORE *CRYPT_ProvOpenStore(LPCSTR lpszStoreProvider,
|
||||
DWORD dwEncodingType, HCRYPTPROV hCryptProv, DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
static HCRYPTOIDFUNCSET set = NULL;
|
||||
PFN_CERT_DLL_OPEN_STORE_PROV_FUNC provOpenFunc;
|
||||
HCRYPTOIDFUNCADDR hFunc;
|
||||
PWINECRYPT_CERTSTORE ret = NULL;
|
||||
WINECRYPT_CERTSTORE *ret = NULL;
|
||||
|
||||
if (!set)
|
||||
set = CryptInitOIDFunctionSet(CRYPT_OID_OPEN_STORE_PROV_FUNC, 0);
|
||||
|
|
|
@ -24,7 +24,7 @@ typedef struct _WINE_HASH_TO_DELETE
|
|||
{
|
||||
BYTE hash[20];
|
||||
struct list entry;
|
||||
} WINE_HASH_TO_DELETE, *PWINE_HASH_TO_DELETE;
|
||||
} WINE_HASH_TO_DELETE;
|
||||
|
||||
typedef struct _WINE_REGSTOREINFO
|
||||
{
|
||||
|
@ -36,7 +36,7 @@ typedef struct _WINE_REGSTOREINFO
|
|||
struct list certsToDelete;
|
||||
struct list crlsToDelete;
|
||||
struct list ctlsToDelete;
|
||||
} WINE_REGSTOREINFO, *PWINE_REGSTOREINFO;
|
||||
} WINE_REGSTOREINFO;
|
||||
|
||||
static void CRYPT_HashToStr(const BYTE *hash, LPWSTR asciiHash)
|
||||
{
|
||||
|
@ -135,7 +135,7 @@ static void CRYPT_RegReadSerializedFromReg(HKEY key, DWORD contextType,
|
|||
else
|
||||
TRACE("hash doesn't match, ignoring\n");
|
||||
}
|
||||
contextInterface->free(context);
|
||||
Context_Release(context_from_ptr(context));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -234,11 +234,11 @@ static BOOL CRYPT_SerializeContextsToReg(HKEY key,
|
|||
ret = TRUE;
|
||||
} while (ret && context != NULL);
|
||||
if (context)
|
||||
contextInterface->free(context);
|
||||
Context_Release(context_from_ptr(context));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_RegWriteToReg(PWINE_REGSTOREINFO store)
|
||||
static BOOL CRYPT_RegWriteToReg(WINE_REGSTOREINFO *store)
|
||||
{
|
||||
static const WCHAR * const subKeys[] = { CertsW, CRLsW, CTLsW };
|
||||
const WINE_CONTEXT_INTERFACE * const interfaces[] = { pCertInterface,
|
||||
|
@ -258,7 +258,7 @@ static BOOL CRYPT_RegWriteToReg(PWINE_REGSTOREINFO store)
|
|||
{
|
||||
if (listToDelete[i])
|
||||
{
|
||||
PWINE_HASH_TO_DELETE toDelete, next;
|
||||
WINE_HASH_TO_DELETE *toDelete, *next;
|
||||
WCHAR asciiHash[20 * 2 + 1];
|
||||
|
||||
EnterCriticalSection(&store->cs);
|
||||
|
@ -296,7 +296,7 @@ static BOOL CRYPT_RegWriteToReg(PWINE_REGSTOREINFO store)
|
|||
/* If force is true or the registry store is dirty, writes the contents of the
|
||||
* store to the registry.
|
||||
*/
|
||||
static BOOL CRYPT_RegFlushStore(PWINE_REGSTOREINFO store, BOOL force)
|
||||
static BOOL CRYPT_RegFlushStore(WINE_REGSTOREINFO *store, BOOL force)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
|
@ -311,7 +311,7 @@ static BOOL CRYPT_RegFlushStore(PWINE_REGSTOREINFO store, BOOL force)
|
|||
|
||||
static void WINAPI CRYPT_RegCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
|
||||
{
|
||||
PWINE_REGSTOREINFO store = hCertStore;
|
||||
WINE_REGSTOREINFO *store = hCertStore;
|
||||
|
||||
TRACE("(%p, %08x)\n", store, dwFlags);
|
||||
if (dwFlags)
|
||||
|
@ -324,7 +324,7 @@ static void WINAPI CRYPT_RegCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
|
|||
CryptMemFree(store);
|
||||
}
|
||||
|
||||
static BOOL CRYPT_RegWriteContext(PWINE_REGSTOREINFO store,
|
||||
static BOOL CRYPT_RegWriteContext(WINE_REGSTOREINFO *store,
|
||||
const void *context, DWORD dwFlags)
|
||||
{
|
||||
BOOL ret;
|
||||
|
@ -339,9 +339,9 @@ static BOOL CRYPT_RegWriteContext(PWINE_REGSTOREINFO store,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_RegDeleteContext(PWINE_REGSTOREINFO store,
|
||||
static BOOL CRYPT_RegDeleteContext(WINE_REGSTOREINFO *store,
|
||||
struct list *deleteList, const void *context,
|
||||
PCWINE_CONTEXT_INTERFACE contextInterface)
|
||||
const WINE_CONTEXT_INTERFACE *contextInterface)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
|
@ -352,8 +352,7 @@ static BOOL CRYPT_RegDeleteContext(PWINE_REGSTOREINFO store,
|
|||
}
|
||||
else
|
||||
{
|
||||
PWINE_HASH_TO_DELETE toDelete =
|
||||
CryptMemAlloc(sizeof(WINE_HASH_TO_DELETE));
|
||||
WINE_HASH_TO_DELETE *toDelete = CryptMemAlloc(sizeof(WINE_HASH_TO_DELETE));
|
||||
|
||||
if (toDelete)
|
||||
{
|
||||
|
@ -384,7 +383,7 @@ static BOOL CRYPT_RegDeleteContext(PWINE_REGSTOREINFO store,
|
|||
static BOOL WINAPI CRYPT_RegWriteCert(HCERTSTORE hCertStore,
|
||||
PCCERT_CONTEXT cert, DWORD dwFlags)
|
||||
{
|
||||
PWINE_REGSTOREINFO store = hCertStore;
|
||||
WINE_REGSTOREINFO *store = hCertStore;
|
||||
|
||||
TRACE("(%p, %p, %d)\n", hCertStore, cert, dwFlags);
|
||||
|
||||
|
@ -394,7 +393,7 @@ static BOOL WINAPI CRYPT_RegWriteCert(HCERTSTORE hCertStore,
|
|||
static BOOL WINAPI CRYPT_RegDeleteCert(HCERTSTORE hCertStore,
|
||||
PCCERT_CONTEXT pCertContext, DWORD dwFlags)
|
||||
{
|
||||
PWINE_REGSTOREINFO store = hCertStore;
|
||||
WINE_REGSTOREINFO *store = hCertStore;
|
||||
|
||||
TRACE("(%p, %p, %08x)\n", store, pCertContext, dwFlags);
|
||||
|
||||
|
@ -405,7 +404,7 @@ static BOOL WINAPI CRYPT_RegDeleteCert(HCERTSTORE hCertStore,
|
|||
static BOOL WINAPI CRYPT_RegWriteCRL(HCERTSTORE hCertStore,
|
||||
PCCRL_CONTEXT crl, DWORD dwFlags)
|
||||
{
|
||||
PWINE_REGSTOREINFO store = hCertStore;
|
||||
WINE_REGSTOREINFO *store = hCertStore;
|
||||
|
||||
TRACE("(%p, %p, %d)\n", hCertStore, crl, dwFlags);
|
||||
|
||||
|
@ -415,7 +414,7 @@ static BOOL WINAPI CRYPT_RegWriteCRL(HCERTSTORE hCertStore,
|
|||
static BOOL WINAPI CRYPT_RegDeleteCRL(HCERTSTORE hCertStore,
|
||||
PCCRL_CONTEXT pCrlContext, DWORD dwFlags)
|
||||
{
|
||||
PWINE_REGSTOREINFO store = hCertStore;
|
||||
WINE_REGSTOREINFO *store = hCertStore;
|
||||
|
||||
TRACE("(%p, %p, %08x)\n", store, pCrlContext, dwFlags);
|
||||
|
||||
|
@ -426,7 +425,7 @@ static BOOL WINAPI CRYPT_RegDeleteCRL(HCERTSTORE hCertStore,
|
|||
static BOOL WINAPI CRYPT_RegWriteCTL(HCERTSTORE hCertStore,
|
||||
PCCTL_CONTEXT ctl, DWORD dwFlags)
|
||||
{
|
||||
PWINE_REGSTOREINFO store = hCertStore;
|
||||
WINE_REGSTOREINFO *store = hCertStore;
|
||||
|
||||
TRACE("(%p, %p, %d)\n", hCertStore, ctl, dwFlags);
|
||||
|
||||
|
@ -436,7 +435,7 @@ static BOOL WINAPI CRYPT_RegWriteCTL(HCERTSTORE hCertStore,
|
|||
static BOOL WINAPI CRYPT_RegDeleteCTL(HCERTSTORE hCertStore,
|
||||
PCCTL_CONTEXT pCtlContext, DWORD dwFlags)
|
||||
{
|
||||
PWINE_REGSTOREINFO store = hCertStore;
|
||||
WINE_REGSTOREINFO *store = hCertStore;
|
||||
|
||||
TRACE("(%p, %p, %08x)\n", store, pCtlContext, dwFlags);
|
||||
|
||||
|
@ -447,7 +446,7 @@ static BOOL WINAPI CRYPT_RegDeleteCTL(HCERTSTORE hCertStore,
|
|||
static BOOL WINAPI CRYPT_RegControl(HCERTSTORE hCertStore, DWORD dwFlags,
|
||||
DWORD dwCtrlType, void const *pvCtrlPara)
|
||||
{
|
||||
PWINE_REGSTOREINFO store = hCertStore;
|
||||
WINE_REGSTOREINFO *store = hCertStore;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
|
||||
|
@ -499,10 +498,10 @@ static void *regProvFuncs[] = {
|
|||
CRYPT_RegControl,
|
||||
};
|
||||
|
||||
PWINECRYPT_CERTSTORE CRYPT_RegOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags,
|
||||
WINECRYPT_CERTSTORE *CRYPT_RegOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags,
|
||||
const void *pvPara)
|
||||
{
|
||||
PWINECRYPT_CERTSTORE store = NULL;
|
||||
WINECRYPT_CERTSTORE *store = NULL;
|
||||
|
||||
TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
|
||||
|
||||
|
@ -527,13 +526,13 @@ PWINECRYPT_CERTSTORE CRYPT_RegOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags,
|
|||
dwFlags & CERT_STORE_READONLY_FLAG ? KEY_READ : KEY_ALL_ACCESS,
|
||||
TRUE, 0))
|
||||
{
|
||||
PWINECRYPT_CERTSTORE memStore;
|
||||
WINECRYPT_CERTSTORE *memStore;
|
||||
|
||||
memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, hCryptProv,
|
||||
CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
if (memStore)
|
||||
{
|
||||
PWINE_REGSTOREINFO regInfo = CryptMemAlloc(
|
||||
WINE_REGSTOREINFO *regInfo = CryptMemAlloc(
|
||||
sizeof(WINE_REGSTOREINFO));
|
||||
|
||||
if (regInfo)
|
||||
|
|
|
@ -236,7 +236,7 @@ static void check_and_store_certs(HCERTSTORE from, HCERTSTORE to)
|
|||
TRACE("\n");
|
||||
|
||||
CertDuplicateStore(to);
|
||||
engine = CRYPT_CreateChainEngine(to, &chainEngineConfig);
|
||||
engine = CRYPT_CreateChainEngine(to, CERT_SYSTEM_STORE_CURRENT_USER, &chainEngineConfig);
|
||||
if (engine)
|
||||
{
|
||||
PCCERT_CONTEXT cert = NULL;
|
||||
|
@ -247,9 +247,10 @@ static void check_and_store_certs(HCERTSTORE from, HCERTSTORE to)
|
|||
{
|
||||
CERT_CHAIN_PARA chainPara = { sizeof(chainPara), { 0 } };
|
||||
PCCERT_CHAIN_CONTEXT chain;
|
||||
BOOL ret = CertGetCertificateChain(engine, cert, NULL, from,
|
||||
&chainPara, 0, NULL, &chain);
|
||||
BOOL ret;
|
||||
|
||||
ret = CertGetCertificateChain(engine, cert, NULL, from,
|
||||
&chainPara, CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL, NULL, &chain);
|
||||
if (!ret)
|
||||
TRACE("rejecting %s: %s\n", get_cert_common_name(cert),
|
||||
"chain creation failed");
|
||||
|
@ -478,6 +479,7 @@ static const char * const CRYPT_knownLocations[] = {
|
|||
"/etc/ssl/certs/ca-certificates.crt",
|
||||
"/etc/ssl/certs",
|
||||
"/etc/pki/tls/certs/ca-bundle.crt",
|
||||
"/usr/share/ca-certificates/ca-bundle.crt",
|
||||
"/usr/local/share/certs/",
|
||||
"/etc/sfw/openssl/certs",
|
||||
};
|
||||
|
@ -803,9 +805,9 @@ static HCERTSTORE create_root_store(void)
|
|||
return root;
|
||||
}
|
||||
|
||||
static PWINECRYPT_CERTSTORE CRYPT_rootStore;
|
||||
static WINECRYPT_CERTSTORE *CRYPT_rootStore;
|
||||
|
||||
PWINECRYPT_CERTSTORE CRYPT_RootOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags)
|
||||
WINECRYPT_CERTSTORE *CRYPT_RootOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags)
|
||||
{
|
||||
TRACE("(%ld, %08x)\n", hCryptProv, dwFlags);
|
||||
|
||||
|
@ -824,7 +826,7 @@ PWINECRYPT_CERTSTORE CRYPT_RootOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags)
|
|||
if (CRYPT_rootStore != root)
|
||||
CertCloseStore(root, 0);
|
||||
}
|
||||
CertDuplicateStore(CRYPT_rootStore);
|
||||
CRYPT_rootStore->vtbl->addref(CRYPT_rootStore);
|
||||
return CRYPT_rootStore;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,11 +28,11 @@ typedef struct _WINE_CERT_PROP_HEADER
|
|||
DWORD propID;
|
||||
DWORD unknown; /* always 1 */
|
||||
DWORD cb;
|
||||
} WINE_CERT_PROP_HEADER, *PWINE_CERT_PROP_HEADER;
|
||||
} WINE_CERT_PROP_HEADER;
|
||||
|
||||
static BOOL CRYPT_SerializeStoreElement(const void *context,
|
||||
const BYTE *encodedContext, DWORD cbEncodedContext, DWORD contextPropID,
|
||||
PCWINE_CONTEXT_INTERFACE contextInterface, DWORD dwFlags, BOOL omitHashes,
|
||||
const WINE_CONTEXT_INTERFACE *contextInterface, DWORD dwFlags, BOOL omitHashes,
|
||||
BYTE *pbElement, DWORD *pcbElement)
|
||||
{
|
||||
BOOL ret;
|
||||
|
@ -71,7 +71,7 @@ static BOOL CRYPT_SerializeStoreElement(const void *context,
|
|||
}
|
||||
else
|
||||
{
|
||||
PWINE_CERT_PROP_HEADER hdr;
|
||||
WINE_CERT_PROP_HEADER *hdr;
|
||||
DWORD bufSize = 0;
|
||||
LPBYTE buf = NULL;
|
||||
|
||||
|
@ -100,7 +100,7 @@ static BOOL CRYPT_SerializeStoreElement(const void *context,
|
|||
&propSize);
|
||||
if (ret)
|
||||
{
|
||||
hdr = (PWINE_CERT_PROP_HEADER)pbElement;
|
||||
hdr = (WINE_CERT_PROP_HEADER*)pbElement;
|
||||
hdr->propID = prop;
|
||||
hdr->unknown = 1;
|
||||
hdr->cb = propSize;
|
||||
|
@ -119,7 +119,7 @@ static BOOL CRYPT_SerializeStoreElement(const void *context,
|
|||
} while (ret && prop != 0);
|
||||
CryptMemFree(buf);
|
||||
|
||||
hdr = (PWINE_CERT_PROP_HEADER)pbElement;
|
||||
hdr = (WINE_CERT_PROP_HEADER*)pbElement;
|
||||
hdr->propID = contextPropID;
|
||||
hdr->unknown = 1;
|
||||
hdr->cb = cbEncodedContext;
|
||||
|
@ -400,7 +400,7 @@ const void *CRYPT_ReadSerializedElement(const BYTE *pbElement, DWORD cbElement,
|
|||
}
|
||||
else
|
||||
{
|
||||
contextInterface->free(context);
|
||||
Context_Release(context_from_ptr(context));
|
||||
context = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -452,7 +452,7 @@ static BOOL CRYPT_ReadSerializedStore(void *handle,
|
|||
propHdr.propID == CERT_CTL_PROP_ID))
|
||||
{
|
||||
/* We have a new context, so free the existing one */
|
||||
contextInterface->free(context);
|
||||
Context_Release(context_from_ptr(context));
|
||||
}
|
||||
if (propHdr.cb > bufSize)
|
||||
{
|
||||
|
@ -513,7 +513,7 @@ static BOOL CRYPT_ReadSerializedStore(void *handle,
|
|||
if (contextInterface && context)
|
||||
{
|
||||
/* Free the last context added */
|
||||
contextInterface->free(context);
|
||||
Context_Release(context_from_ptr(context));
|
||||
}
|
||||
CryptMemFree(buf);
|
||||
ret = TRUE;
|
||||
|
@ -629,7 +629,7 @@ static BOOL CRYPT_SerializeContextsToStream(SerializedOutputFunc output,
|
|||
ret = TRUE;
|
||||
} while (ret && context != NULL);
|
||||
if (context)
|
||||
contextInterface->free(context);
|
||||
Context_Release(context_from_ptr(context));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -987,7 +987,7 @@ BOOL WINAPI CertAddSerializedElementToStore(HCERTSTORE hCertStore,
|
|||
*pdwContentType = type;
|
||||
ret = contextInterface->addContextToStore(hCertStore, context,
|
||||
dwAddDisposition, ppvContext);
|
||||
contextInterface->free(context);
|
||||
Context_Release(context_from_ptr(context));
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
|
|
|
@ -31,69 +31,65 @@ static const WINE_CONTEXT_INTERFACE gCertInterface = {
|
|||
(CreateContextFunc)CertCreateCertificateContext,
|
||||
(AddContextToStoreFunc)CertAddCertificateContextToStore,
|
||||
(AddEncodedContextToStoreFunc)CertAddEncodedCertificateToStore,
|
||||
(DuplicateContextFunc)CertDuplicateCertificateContext,
|
||||
(EnumContextsInStoreFunc)CertEnumCertificatesInStore,
|
||||
(EnumPropertiesFunc)CertEnumCertificateContextProperties,
|
||||
(GetContextPropertyFunc)CertGetCertificateContextProperty,
|
||||
(SetContextPropertyFunc)CertSetCertificateContextProperty,
|
||||
(SerializeElementFunc)CertSerializeCertificateStoreElement,
|
||||
(FreeContextFunc)CertFreeCertificateContext,
|
||||
(DeleteContextFunc)CertDeleteCertificateFromStore,
|
||||
};
|
||||
PCWINE_CONTEXT_INTERFACE pCertInterface = &gCertInterface;
|
||||
const WINE_CONTEXT_INTERFACE *pCertInterface = &gCertInterface;
|
||||
|
||||
static const WINE_CONTEXT_INTERFACE gCRLInterface = {
|
||||
(CreateContextFunc)CertCreateCRLContext,
|
||||
(AddContextToStoreFunc)CertAddCRLContextToStore,
|
||||
(AddEncodedContextToStoreFunc)CertAddEncodedCRLToStore,
|
||||
(DuplicateContextFunc)CertDuplicateCRLContext,
|
||||
(EnumContextsInStoreFunc)CertEnumCRLsInStore,
|
||||
(EnumPropertiesFunc)CertEnumCRLContextProperties,
|
||||
(GetContextPropertyFunc)CertGetCRLContextProperty,
|
||||
(SetContextPropertyFunc)CertSetCRLContextProperty,
|
||||
(SerializeElementFunc)CertSerializeCRLStoreElement,
|
||||
(FreeContextFunc)CertFreeCRLContext,
|
||||
(DeleteContextFunc)CertDeleteCRLFromStore,
|
||||
};
|
||||
PCWINE_CONTEXT_INTERFACE pCRLInterface = &gCRLInterface;
|
||||
const WINE_CONTEXT_INTERFACE *pCRLInterface = &gCRLInterface;
|
||||
|
||||
static const WINE_CONTEXT_INTERFACE gCTLInterface = {
|
||||
(CreateContextFunc)CertCreateCTLContext,
|
||||
(AddContextToStoreFunc)CertAddCTLContextToStore,
|
||||
(AddEncodedContextToStoreFunc)CertAddEncodedCTLToStore,
|
||||
(DuplicateContextFunc)CertDuplicateCTLContext,
|
||||
(EnumContextsInStoreFunc)CertEnumCTLsInStore,
|
||||
(EnumPropertiesFunc)CertEnumCTLContextProperties,
|
||||
(GetContextPropertyFunc)CertGetCTLContextProperty,
|
||||
(SetContextPropertyFunc)CertSetCTLContextProperty,
|
||||
(SerializeElementFunc)CertSerializeCTLStoreElement,
|
||||
(FreeContextFunc)CertFreeCTLContext,
|
||||
(DeleteContextFunc)CertDeleteCTLFromStore,
|
||||
};
|
||||
PCWINE_CONTEXT_INTERFACE pCTLInterface = &gCTLInterface;
|
||||
const WINE_CONTEXT_INTERFACE *pCTLInterface = &gCTLInterface;
|
||||
|
||||
typedef struct _WINE_MEMSTORE
|
||||
{
|
||||
WINECRYPT_CERTSTORE hdr;
|
||||
struct ContextList *certs;
|
||||
struct ContextList *crls;
|
||||
struct ContextList *ctls;
|
||||
} WINE_MEMSTORE, *PWINE_MEMSTORE;
|
||||
CRITICAL_SECTION cs;
|
||||
struct list certs;
|
||||
struct list crls;
|
||||
struct list ctls;
|
||||
} WINE_MEMSTORE;
|
||||
|
||||
void CRYPT_InitStore(WINECRYPT_CERTSTORE *store, DWORD dwFlags,
|
||||
CertStoreType type)
|
||||
void CRYPT_InitStore(WINECRYPT_CERTSTORE *store, DWORD dwFlags, CertStoreType type, const store_vtbl_t *vtbl)
|
||||
{
|
||||
store->ref = 1;
|
||||
store->dwMagic = WINE_CRYPTCERTSTORE_MAGIC;
|
||||
store->type = type;
|
||||
store->dwOpenFlags = dwFlags;
|
||||
store->vtbl = vtbl;
|
||||
store->properties = NULL;
|
||||
}
|
||||
|
||||
void CRYPT_FreeStore(PWINECRYPT_CERTSTORE store)
|
||||
void CRYPT_FreeStore(WINECRYPT_CERTSTORE *store)
|
||||
{
|
||||
if (store->properties)
|
||||
ContextPropertyList_Free(store->properties);
|
||||
store->dwMagic = 0;
|
||||
CryptMemFree(store);
|
||||
}
|
||||
|
||||
|
@ -134,166 +130,239 @@ BOOL WINAPI I_CertUpdateStore(HCERTSTORE store1, HCERTSTORE store2, DWORD unk0,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_MemAddCert(PWINECRYPT_CERTSTORE store, void *cert,
|
||||
void *toReplace, const void **ppStoreContext)
|
||||
static BOOL MemStore_addContext(WINE_MEMSTORE *store, struct list *list, context_t *orig_context,
|
||||
context_t *existing, context_t **ret_context, BOOL use_link)
|
||||
{
|
||||
context_t *context;
|
||||
|
||||
context = orig_context->vtbl->clone(orig_context, &store->hdr, use_link);
|
||||
if (!context)
|
||||
return FALSE;
|
||||
|
||||
TRACE("adding %p\n", context);
|
||||
EnterCriticalSection(&store->cs);
|
||||
if (existing) {
|
||||
context->u.entry.prev = existing->u.entry.prev;
|
||||
context->u.entry.next = existing->u.entry.next;
|
||||
context->u.entry.prev->next = &context->u.entry;
|
||||
context->u.entry.next->prev = &context->u.entry;
|
||||
list_init(&existing->u.entry);
|
||||
if(!existing->ref)
|
||||
Context_Release(existing);
|
||||
}else {
|
||||
list_add_head(list, &context->u.entry);
|
||||
}
|
||||
LeaveCriticalSection(&store->cs);
|
||||
|
||||
if(ret_context)
|
||||
*ret_context = context;
|
||||
else
|
||||
Context_Release(context);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static context_t *MemStore_enumContext(WINE_MEMSTORE *store, struct list *list, context_t *prev)
|
||||
{
|
||||
struct list *next;
|
||||
context_t *ret;
|
||||
|
||||
EnterCriticalSection(&store->cs);
|
||||
if (prev) {
|
||||
next = list_next(list, &prev->u.entry);
|
||||
Context_Release(prev);
|
||||
}else {
|
||||
next = list_next(list, list);
|
||||
}
|
||||
LeaveCriticalSection(&store->cs);
|
||||
|
||||
if (!next) {
|
||||
SetLastError(CRYPT_E_NOT_FOUND);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = LIST_ENTRY(next, context_t, u.entry);
|
||||
Context_AddRef(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL MemStore_deleteContext(WINE_MEMSTORE *store, context_t *context)
|
||||
{
|
||||
BOOL in_list = FALSE;
|
||||
|
||||
EnterCriticalSection(&store->cs);
|
||||
if (!list_empty(&context->u.entry)) {
|
||||
list_remove(&context->u.entry);
|
||||
list_init(&context->u.entry);
|
||||
in_list = TRUE;
|
||||
}
|
||||
LeaveCriticalSection(&store->cs);
|
||||
|
||||
if(in_list && !context->ref)
|
||||
Context_Free(context);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void free_contexts(struct list *list)
|
||||
{
|
||||
context_t *context, *next;
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(context, next, list, context_t, u.entry)
|
||||
{
|
||||
TRACE("freeing %p\n", context);
|
||||
list_remove(&context->u.entry);
|
||||
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,
|
||||
context_t *toReplace, context_t **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);
|
||||
if (context)
|
||||
{
|
||||
context->hCertStore = store;
|
||||
if (ppStoreContext)
|
||||
*ppStoreContext = CertDuplicateCertificateContext(context);
|
||||
}
|
||||
return context != 0;
|
||||
return MemStore_addContext(ms, &ms->certs, cert, toReplace, ppStoreContext, use_link);
|
||||
}
|
||||
|
||||
static void *CRYPT_MemEnumCert(PWINECRYPT_CERTSTORE store, void *pPrev)
|
||||
static context_t *MemStore_enumCert(WINECRYPT_CERTSTORE *store, context_t *prev)
|
||||
{
|
||||
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
|
||||
void *ret;
|
||||
|
||||
TRACE("(%p, %p)\n", store, pPrev);
|
||||
TRACE("(%p, %p)\n", store, prev);
|
||||
|
||||
ret = ContextList_Enum(ms->certs, pPrev);
|
||||
if (!ret)
|
||||
SetLastError(CRYPT_E_NOT_FOUND);
|
||||
|
||||
TRACE("returning %p\n", ret);
|
||||
return ret;
|
||||
return MemStore_enumContext(ms, &ms->certs, prev);
|
||||
}
|
||||
|
||||
static BOOL CRYPT_MemDeleteCert(PWINECRYPT_CERTSTORE store, void *pCertContext)
|
||||
static BOOL MemStore_deleteCert(WINECRYPT_CERTSTORE *store, context_t *context)
|
||||
{
|
||||
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
|
||||
BOOL ret;
|
||||
|
||||
if (ContextList_Remove(ms->certs, pCertContext))
|
||||
ret = CertFreeCertificateContext(pCertContext);
|
||||
else
|
||||
ret = TRUE;
|
||||
return ret;
|
||||
TRACE("(%p, %p)\n", store, context);
|
||||
|
||||
return MemStore_deleteContext(ms, context);
|
||||
}
|
||||
|
||||
static BOOL CRYPT_MemAddCrl(PWINECRYPT_CERTSTORE store, void *crl,
|
||||
void *toReplace, const void **ppStoreContext)
|
||||
static BOOL MemStore_addCRL(WINECRYPT_CERTSTORE *store, context_t *crl,
|
||||
context_t *toReplace, context_t **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);
|
||||
if (context)
|
||||
{
|
||||
context->hCertStore = store;
|
||||
if (ppStoreContext)
|
||||
*ppStoreContext = CertDuplicateCRLContext(context);
|
||||
}
|
||||
return context != 0;
|
||||
return MemStore_addContext(ms, &ms->crls, crl, toReplace, ppStoreContext, use_link);
|
||||
}
|
||||
|
||||
static void *CRYPT_MemEnumCrl(PWINECRYPT_CERTSTORE store, void *pPrev)
|
||||
static context_t *MemStore_enumCRL(WINECRYPT_CERTSTORE *store, context_t *prev)
|
||||
{
|
||||
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
|
||||
void *ret;
|
||||
|
||||
TRACE("(%p, %p)\n", store, pPrev);
|
||||
TRACE("(%p, %p)\n", store, prev);
|
||||
|
||||
ret = ContextList_Enum(ms->crls, pPrev);
|
||||
if (!ret)
|
||||
SetLastError(CRYPT_E_NOT_FOUND);
|
||||
|
||||
TRACE("returning %p\n", ret);
|
||||
return ret;
|
||||
return MemStore_enumContext(ms, &ms->crls, prev);
|
||||
}
|
||||
|
||||
static BOOL CRYPT_MemDeleteCrl(PWINECRYPT_CERTSTORE store, void *pCrlContext)
|
||||
static BOOL MemStore_deleteCRL(WINECRYPT_CERTSTORE *store, context_t *context)
|
||||
{
|
||||
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
|
||||
BOOL ret;
|
||||
|
||||
if (ContextList_Remove(ms->crls, pCrlContext))
|
||||
ret = CertFreeCRLContext(pCrlContext);
|
||||
else
|
||||
ret = TRUE;
|
||||
return ret;
|
||||
TRACE("(%p, %p)\n", store, context);
|
||||
|
||||
return MemStore_deleteContext(ms, context);
|
||||
}
|
||||
|
||||
static BOOL CRYPT_MemAddCtl(PWINECRYPT_CERTSTORE store, void *ctl,
|
||||
void *toReplace, const void **ppStoreContext)
|
||||
static BOOL MemStore_addCTL(WINECRYPT_CERTSTORE *store, context_t *ctl,
|
||||
context_t *toReplace, context_t **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);
|
||||
if (context)
|
||||
{
|
||||
context->hCertStore = store;
|
||||
if (ppStoreContext)
|
||||
*ppStoreContext = CertDuplicateCTLContext(context);
|
||||
}
|
||||
return context != 0;
|
||||
return MemStore_addContext(ms, &ms->ctls, ctl, toReplace, ppStoreContext, use_link);
|
||||
}
|
||||
|
||||
static void *CRYPT_MemEnumCtl(PWINECRYPT_CERTSTORE store, void *pPrev)
|
||||
static context_t *MemStore_enumCTL(WINECRYPT_CERTSTORE *store, context_t *prev)
|
||||
{
|
||||
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
|
||||
void *ret;
|
||||
|
||||
TRACE("(%p, %p)\n", store, pPrev);
|
||||
TRACE("(%p, %p)\n", store, prev);
|
||||
|
||||
ret = ContextList_Enum(ms->ctls, pPrev);
|
||||
if (!ret)
|
||||
SetLastError(CRYPT_E_NOT_FOUND);
|
||||
|
||||
TRACE("returning %p\n", ret);
|
||||
return ret;
|
||||
return MemStore_enumContext(ms, &ms->ctls, prev);
|
||||
}
|
||||
|
||||
static BOOL CRYPT_MemDeleteCtl(PWINECRYPT_CERTSTORE store, void *pCtlContext)
|
||||
static BOOL MemStore_deleteCTL(WINECRYPT_CERTSTORE *store, context_t *context)
|
||||
{
|
||||
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
|
||||
BOOL ret;
|
||||
|
||||
if (ContextList_Remove(ms->ctls, pCtlContext))
|
||||
ret = CertFreeCTLContext(pCtlContext);
|
||||
else
|
||||
ret = TRUE;
|
||||
return ret;
|
||||
TRACE("(%p, %p)\n", store, context);
|
||||
|
||||
return MemStore_deleteContext(ms, context);
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_MemControl(HCERTSTORE hCertStore, DWORD dwFlags,
|
||||
static void MemStore_addref(WINECRYPT_CERTSTORE *store)
|
||||
{
|
||||
LONG ref = InterlockedIncrement(&store->ref);
|
||||
TRACE("ref = %d\n", ref);
|
||||
}
|
||||
|
||||
static DWORD MemStore_release(WINECRYPT_CERTSTORE *cert_store, DWORD flags)
|
||||
{
|
||||
WINE_MEMSTORE *store = (WINE_MEMSTORE*)cert_store;
|
||||
LONG ref;
|
||||
|
||||
if(flags & ~CERT_CLOSE_STORE_CHECK_FLAG)
|
||||
FIXME("Unimplemented flags %x\n", flags);
|
||||
|
||||
ref = InterlockedDecrement(&store->hdr.ref);
|
||||
TRACE("(%p) ref=%d\n", store, ref);
|
||||
if(ref)
|
||||
return (flags & CERT_CLOSE_STORE_CHECK_FLAG) ? CRYPT_E_PENDING_CLOSE : ERROR_SUCCESS;
|
||||
|
||||
free_contexts(&store->certs);
|
||||
free_contexts(&store->crls);
|
||||
free_contexts(&store->ctls);
|
||||
store->cs.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&store->cs);
|
||||
CRYPT_FreeStore(&store->hdr);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static BOOL MemStore_control(WINECRYPT_CERTSTORE *store, DWORD dwFlags,
|
||||
DWORD dwCtrlType, void const *pvCtrlPara)
|
||||
{
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void WINAPI CRYPT_MemCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
|
||||
{
|
||||
WINE_MEMSTORE *store = hCertStore;
|
||||
|
||||
TRACE("(%p, %08x)\n", store, dwFlags);
|
||||
if (dwFlags)
|
||||
FIXME("Unimplemented flags: %08x\n", dwFlags);
|
||||
|
||||
ContextList_Free(store->certs);
|
||||
ContextList_Free(store->crls);
|
||||
ContextList_Free(store->ctls);
|
||||
CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
|
||||
}
|
||||
static const store_vtbl_t MemStoreVtbl = {
|
||||
MemStore_addref,
|
||||
MemStore_release,
|
||||
MemStore_releaseContext,
|
||||
MemStore_control,
|
||||
{
|
||||
MemStore_addCert,
|
||||
MemStore_enumCert,
|
||||
MemStore_deleteCert
|
||||
}, {
|
||||
MemStore_addCRL,
|
||||
MemStore_enumCRL,
|
||||
MemStore_deleteCRL
|
||||
}, {
|
||||
MemStore_addCTL,
|
||||
MemStore_enumCTL,
|
||||
MemStore_deleteCTL
|
||||
}
|
||||
};
|
||||
|
||||
static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
PWINE_MEMSTORE store;
|
||||
WINE_MEMSTORE *store;
|
||||
|
||||
TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
|
||||
|
||||
|
@ -308,41 +377,29 @@ static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv,
|
|||
if (store)
|
||||
{
|
||||
memset(store, 0, sizeof(WINE_MEMSTORE));
|
||||
CRYPT_InitStore(&store->hdr, dwFlags, StoreTypeMem);
|
||||
store->hdr.closeStore = CRYPT_MemCloseStore;
|
||||
store->hdr.certs.addContext = CRYPT_MemAddCert;
|
||||
store->hdr.certs.enumContext = CRYPT_MemEnumCert;
|
||||
store->hdr.certs.deleteContext = CRYPT_MemDeleteCert;
|
||||
store->hdr.crls.addContext = CRYPT_MemAddCrl;
|
||||
store->hdr.crls.enumContext = CRYPT_MemEnumCrl;
|
||||
store->hdr.crls.deleteContext = CRYPT_MemDeleteCrl;
|
||||
store->hdr.ctls.addContext = CRYPT_MemAddCtl;
|
||||
store->hdr.ctls.enumContext = CRYPT_MemEnumCtl;
|
||||
store->hdr.ctls.deleteContext = CRYPT_MemDeleteCtl;
|
||||
store->hdr.control = CRYPT_MemControl;
|
||||
store->certs = ContextList_Create(pCertInterface,
|
||||
sizeof(CERT_CONTEXT));
|
||||
store->crls = ContextList_Create(pCRLInterface,
|
||||
sizeof(CRL_CONTEXT));
|
||||
store->ctls = ContextList_Create(pCTLInterface,
|
||||
sizeof(CTL_CONTEXT));
|
||||
CRYPT_InitStore(&store->hdr, dwFlags, StoreTypeMem, &MemStoreVtbl);
|
||||
InitializeCriticalSection(&store->cs);
|
||||
store->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ContextList.cs");
|
||||
list_init(&store->certs);
|
||||
list_init(&store->crls);
|
||||
list_init(&store->ctls);
|
||||
/* Mem store doesn't need crypto provider, so close it */
|
||||
if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
|
||||
CryptReleaseContext(hCryptProv, 0);
|
||||
}
|
||||
}
|
||||
return (PWINECRYPT_CERTSTORE)store;
|
||||
return (WINECRYPT_CERTSTORE*)store;
|
||||
}
|
||||
|
||||
static const WCHAR rootW[] = { 'R','o','o','t',0 };
|
||||
|
||||
static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv,
|
||||
static WINECRYPT_CERTSTORE *CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
static const WCHAR fmt[] = { '%','s','\\','%','s',0 };
|
||||
LPCWSTR storeName = pvPara;
|
||||
LPWSTR storePath;
|
||||
PWINECRYPT_CERTSTORE store = NULL;
|
||||
WINECRYPT_CERTSTORE *store = NULL;
|
||||
HKEY root;
|
||||
LPCWSTR base;
|
||||
|
||||
|
@ -448,11 +505,11 @@ static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv,
|
|||
return store;
|
||||
}
|
||||
|
||||
static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreA(HCRYPTPROV hCryptProv,
|
||||
static WINECRYPT_CERTSTORE *CRYPT_SysRegOpenStoreA(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
int len;
|
||||
PWINECRYPT_CERTSTORE ret = NULL;
|
||||
WINECRYPT_CERTSTORE *ret = NULL;
|
||||
|
||||
TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
|
||||
debugstr_a(pvPara));
|
||||
|
@ -477,7 +534,7 @@ static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreA(HCRYPTPROV hCryptProv,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv,
|
||||
static WINECRYPT_CERTSTORE *CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
HCERTSTORE store = 0;
|
||||
|
@ -549,11 +606,11 @@ static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv,
|
|||
return store;
|
||||
}
|
||||
|
||||
static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv,
|
||||
static WINECRYPT_CERTSTORE *CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
int len;
|
||||
PWINECRYPT_CERTSTORE ret = NULL;
|
||||
WINECRYPT_CERTSTORE *ret = NULL;
|
||||
|
||||
TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
|
||||
debugstr_a(pvPara));
|
||||
|
@ -590,12 +647,12 @@ static void *msgProvFuncs[] = {
|
|||
CRYPT_MsgCloseStore,
|
||||
};
|
||||
|
||||
static PWINECRYPT_CERTSTORE CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv,
|
||||
static WINECRYPT_CERTSTORE *CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
PWINECRYPT_CERTSTORE store = NULL;
|
||||
WINECRYPT_CERTSTORE *store = NULL;
|
||||
HCRYPTMSG msg = (HCRYPTMSG)pvPara;
|
||||
PWINECRYPT_CERTSTORE memStore;
|
||||
WINECRYPT_CERTSTORE *memStore;
|
||||
|
||||
TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
|
||||
|
||||
|
@ -669,11 +726,11 @@ static PWINECRYPT_CERTSTORE CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv,
|
|||
return store;
|
||||
}
|
||||
|
||||
static PWINECRYPT_CERTSTORE CRYPT_PKCSOpenStore(HCRYPTPROV hCryptProv,
|
||||
static WINECRYPT_CERTSTORE *CRYPT_PKCSOpenStore(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
HCRYPTMSG msg;
|
||||
PWINECRYPT_CERTSTORE store = NULL;
|
||||
WINECRYPT_CERTSTORE *store = NULL;
|
||||
const CRYPT_DATA_BLOB *data = pvPara;
|
||||
BOOL ret;
|
||||
DWORD msgOpenFlags = dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG ? 0 :
|
||||
|
@ -710,7 +767,7 @@ static PWINECRYPT_CERTSTORE CRYPT_PKCSOpenStore(HCRYPTPROV hCryptProv,
|
|||
return store;
|
||||
}
|
||||
|
||||
static PWINECRYPT_CERTSTORE CRYPT_SerializedOpenStore(HCRYPTPROV hCryptProv,
|
||||
static WINECRYPT_CERTSTORE *CRYPT_SerializedOpenStore(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
HCERTSTORE store;
|
||||
|
@ -735,10 +792,10 @@ static PWINECRYPT_CERTSTORE CRYPT_SerializedOpenStore(HCRYPTPROV hCryptProv,
|
|||
}
|
||||
}
|
||||
TRACE("returning %p\n", store);
|
||||
return (PWINECRYPT_CERTSTORE)store;
|
||||
return (WINECRYPT_CERTSTORE*)store;
|
||||
}
|
||||
|
||||
static PWINECRYPT_CERTSTORE CRYPT_PhysOpenStoreW(HCRYPTPROV hCryptProv,
|
||||
static WINECRYPT_CERTSTORE *CRYPT_PhysOpenStoreW(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
|
||||
|
@ -862,142 +919,10 @@ HCERTSTORE WINAPI CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv,
|
|||
CERT_SYSTEM_STORE_CURRENT_USER, szSubSystemProtocol);
|
||||
}
|
||||
|
||||
#define CertContext_CopyProperties(to, from) \
|
||||
Context_CopyProperties((to), (from), sizeof(CERT_CONTEXT))
|
||||
|
||||
BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore,
|
||||
PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition,
|
||||
PCCERT_CONTEXT *ppStoreContext)
|
||||
{
|
||||
PWINECRYPT_CERTSTORE store = hCertStore;
|
||||
BOOL ret = TRUE;
|
||||
PCCERT_CONTEXT toAdd = NULL, existing = NULL;
|
||||
|
||||
TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCertContext,
|
||||
dwAddDisposition, ppStoreContext);
|
||||
|
||||
switch (dwAddDisposition)
|
||||
{
|
||||
case CERT_STORE_ADD_ALWAYS:
|
||||
break;
|
||||
case CERT_STORE_ADD_NEW:
|
||||
case CERT_STORE_ADD_REPLACE_EXISTING:
|
||||
case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
|
||||
case CERT_STORE_ADD_USE_EXISTING:
|
||||
case CERT_STORE_ADD_NEWER:
|
||||
case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES:
|
||||
{
|
||||
BYTE hashToAdd[20];
|
||||
DWORD size = sizeof(hashToAdd);
|
||||
|
||||
ret = CertGetCertificateContextProperty(pCertContext, 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);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
FIXME("Unimplemented add disposition %d\n", dwAddDisposition);
|
||||
SetLastError(E_INVALIDARG);
|
||||
ret = FALSE;
|
||||
}
|
||||
|
||||
switch (dwAddDisposition)
|
||||
{
|
||||
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;
|
||||
}
|
||||
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 (existing)
|
||||
CertContext_CopyProperties(toAdd, existing);
|
||||
break;
|
||||
case CERT_STORE_ADD_USE_EXISTING:
|
||||
if (existing)
|
||||
{
|
||||
CertContext_CopyProperties(existing, pCertContext);
|
||||
if (ppStoreContext)
|
||||
*ppStoreContext = CertDuplicateCertificateContext(existing);
|
||||
}
|
||||
else
|
||||
toAdd = CertDuplicateCertificateContext(pCertContext);
|
||||
break;
|
||||
case CERT_STORE_ADD_NEWER:
|
||||
if (existing)
|
||||
{
|
||||
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);
|
||||
}
|
||||
else
|
||||
toAdd = CertDuplicateCertificateContext(pCertContext);
|
||||
break;
|
||||
case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES:
|
||||
if (existing)
|
||||
{
|
||||
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);
|
||||
CertContext_CopyProperties(toAdd, existing);
|
||||
}
|
||||
}
|
||||
else
|
||||
toAdd = CertDuplicateCertificateContext(pCertContext);
|
||||
break;
|
||||
}
|
||||
|
||||
if (toAdd)
|
||||
{
|
||||
if (store)
|
||||
ret = store->certs.addContext(store, (void *)toAdd,
|
||||
(void *)existing, (const void **)ppStoreContext);
|
||||
else if (ppStoreContext)
|
||||
*ppStoreContext = CertDuplicateCertificateContext(toAdd);
|
||||
CertFreeCertificateContext(toAdd);
|
||||
}
|
||||
CertFreeCertificateContext(existing);
|
||||
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(HCERTSTORE hCertStore,
|
||||
PCCERT_CONTEXT pPrev)
|
||||
PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pPrev)
|
||||
{
|
||||
cert_t *prev = pPrev ? cert_from_ptr(pPrev) : NULL, *ret;
|
||||
WINECRYPT_CERTSTORE *hcs = hCertStore;
|
||||
PCCERT_CONTEXT ret;
|
||||
|
||||
TRACE("(%p, %p)\n", hCertStore, pPrev);
|
||||
if (!hCertStore)
|
||||
|
@ -1005,42 +930,32 @@ PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(HCERTSTORE hCertStore,
|
|||
else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
|
||||
ret = NULL;
|
||||
else
|
||||
ret = (PCCERT_CONTEXT)hcs->certs.enumContext(hcs, (void *)pPrev);
|
||||
return ret;
|
||||
ret = (cert_t*)hcs->vtbl->certs.enumContext(hcs, prev ? &prev->base : NULL);
|
||||
return ret ? &ret->ctx : NULL;
|
||||
}
|
||||
|
||||
BOOL WINAPI CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext)
|
||||
{
|
||||
BOOL ret;
|
||||
WINECRYPT_CERTSTORE *hcs;
|
||||
|
||||
TRACE("(%p)\n", pCertContext);
|
||||
|
||||
if (!pCertContext)
|
||||
ret = TRUE;
|
||||
else if (!pCertContext->hCertStore)
|
||||
ret = CertFreeCertificateContext(pCertContext);
|
||||
else
|
||||
{
|
||||
PWINECRYPT_CERTSTORE hcs = pCertContext->hCertStore;
|
||||
return TRUE;
|
||||
|
||||
if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
|
||||
ret = FALSE;
|
||||
else
|
||||
ret = hcs->certs.deleteContext(hcs, (void *)pCertContext);
|
||||
if (ret)
|
||||
ret = CertFreeCertificateContext(pCertContext);
|
||||
}
|
||||
return ret;
|
||||
hcs = pCertContext->hCertStore;
|
||||
|
||||
if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
|
||||
return FALSE;
|
||||
|
||||
return hcs->vtbl->certs.delete(hcs, &cert_from_ptr(pCertContext)->base);
|
||||
}
|
||||
|
||||
#define CrlContext_CopyProperties(to, from) \
|
||||
Context_CopyProperties((to), (from), sizeof(CRL_CONTEXT))
|
||||
|
||||
BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore,
|
||||
PCCRL_CONTEXT pCrlContext, DWORD dwAddDisposition,
|
||||
PCCRL_CONTEXT* ppStoreContext)
|
||||
{
|
||||
PWINECRYPT_CERTSTORE store = hCertStore;
|
||||
WINECRYPT_CERTSTORE *store = hCertStore;
|
||||
BOOL ret = TRUE;
|
||||
PCCRL_CONTEXT toAdd = NULL, existing = NULL;
|
||||
|
||||
|
@ -1101,7 +1016,7 @@ BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore,
|
|||
if (newer < 0)
|
||||
{
|
||||
toAdd = CertDuplicateCRLContext(pCrlContext);
|
||||
CrlContext_CopyProperties(toAdd, existing);
|
||||
Context_CopyProperties(toAdd, existing);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1119,12 +1034,12 @@ BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore,
|
|||
case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
|
||||
toAdd = CertDuplicateCRLContext(pCrlContext);
|
||||
if (existing)
|
||||
CrlContext_CopyProperties(toAdd, existing);
|
||||
Context_CopyProperties(toAdd, existing);
|
||||
break;
|
||||
case CERT_STORE_ADD_USE_EXISTING:
|
||||
if (existing)
|
||||
{
|
||||
CrlContext_CopyProperties(existing, pCrlContext);
|
||||
Context_CopyProperties(existing, pCrlContext);
|
||||
if (ppStoreContext)
|
||||
*ppStoreContext = CertDuplicateCRLContext(existing);
|
||||
}
|
||||
|
@ -1138,14 +1053,19 @@ BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore,
|
|||
|
||||
if (toAdd)
|
||||
{
|
||||
if (store)
|
||||
ret = store->crls.addContext(store, (void *)toAdd,
|
||||
(void *)existing, (const void **)ppStoreContext);
|
||||
else if (ppStoreContext)
|
||||
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, FALSE);
|
||||
if (ret && ppStoreContext)
|
||||
*ppStoreContext = context_ptr(ret_context);
|
||||
}else if (ppStoreContext) {
|
||||
*ppStoreContext = CertDuplicateCRLContext(toAdd);
|
||||
}
|
||||
CertFreeCRLContext(toAdd);
|
||||
}
|
||||
CertFreeCRLContext(existing);
|
||||
if (existing)
|
||||
CertFreeCRLContext(existing);
|
||||
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
|
@ -1153,33 +1073,29 @@ BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore,
|
|||
|
||||
BOOL WINAPI CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext)
|
||||
{
|
||||
WINECRYPT_CERTSTORE *hcs;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p)\n", pCrlContext);
|
||||
|
||||
if (!pCrlContext)
|
||||
ret = TRUE;
|
||||
else if (!pCrlContext->hCertStore)
|
||||
ret = CertFreeCRLContext(pCrlContext);
|
||||
else
|
||||
{
|
||||
PWINECRYPT_CERTSTORE hcs = pCrlContext->hCertStore;
|
||||
return TRUE;
|
||||
|
||||
if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
|
||||
ret = FALSE;
|
||||
else
|
||||
ret = hcs->crls.deleteContext(hcs, (void *)pCrlContext);
|
||||
if (ret)
|
||||
ret = CertFreeCRLContext(pCrlContext);
|
||||
}
|
||||
hcs = pCrlContext->hCertStore;
|
||||
|
||||
if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
|
||||
return FALSE;
|
||||
|
||||
ret = hcs->vtbl->crls.delete(hcs, &crl_from_ptr(pCrlContext)->base);
|
||||
if (ret)
|
||||
ret = CertFreeCRLContext(pCrlContext);
|
||||
return ret;
|
||||
}
|
||||
|
||||
PCCRL_CONTEXT WINAPI CertEnumCRLsInStore(HCERTSTORE hCertStore,
|
||||
PCCRL_CONTEXT pPrev)
|
||||
PCCRL_CONTEXT WINAPI CertEnumCRLsInStore(HCERTSTORE hCertStore, PCCRL_CONTEXT pPrev)
|
||||
{
|
||||
crl_t *ret, *prev = pPrev ? crl_from_ptr(pPrev) : NULL;
|
||||
WINECRYPT_CERTSTORE *hcs = hCertStore;
|
||||
PCCRL_CONTEXT ret;
|
||||
|
||||
TRACE("(%p, %p)\n", hCertStore, pPrev);
|
||||
if (!hCertStore)
|
||||
|
@ -1187,8 +1103,8 @@ PCCRL_CONTEXT WINAPI CertEnumCRLsInStore(HCERTSTORE hCertStore,
|
|||
else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
|
||||
ret = NULL;
|
||||
else
|
||||
ret = (PCCRL_CONTEXT)hcs->crls.enumContext(hcs, (void *)pPrev);
|
||||
return ret;
|
||||
ret = (crl_t*)hcs->vtbl->crls.enumContext(hcs, prev ? &prev->base : NULL);
|
||||
return ret ? &ret->ctx : NULL;
|
||||
}
|
||||
|
||||
HCERTSTORE WINAPI CertDuplicateStore(HCERTSTORE hCertStore)
|
||||
|
@ -1198,13 +1114,14 @@ HCERTSTORE WINAPI CertDuplicateStore(HCERTSTORE hCertStore)
|
|||
TRACE("(%p)\n", hCertStore);
|
||||
|
||||
if (hcs && hcs->dwMagic == WINE_CRYPTCERTSTORE_MAGIC)
|
||||
InterlockedIncrement(&hcs->ref);
|
||||
hcs->vtbl->addref(hcs);
|
||||
return hCertStore;
|
||||
}
|
||||
|
||||
BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
|
||||
{
|
||||
WINECRYPT_CERTSTORE *hcs = hCertStore;
|
||||
DWORD res;
|
||||
|
||||
TRACE("(%p, %08x)\n", hCertStore, dwFlags);
|
||||
|
||||
|
@ -1214,16 +1131,12 @@ BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
|
|||
if ( hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC )
|
||||
return FALSE;
|
||||
|
||||
if (hcs->ref <= 0)
|
||||
ERR("%p's ref count is %d\n", hcs, hcs->ref);
|
||||
if (InterlockedDecrement(&hcs->ref) == 0)
|
||||
{
|
||||
TRACE("%p's ref count is 0, freeing\n", hcs);
|
||||
hcs->dwMagic = 0;
|
||||
hcs->closeStore(hcs, dwFlags);
|
||||
res = hcs->vtbl->release(hcs, dwFlags);
|
||||
if (res != ERROR_SUCCESS) {
|
||||
SetLastError(res);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
TRACE("%p's ref count is %d\n", hcs, hcs->ref);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1242,8 +1155,8 @@ BOOL WINAPI CertControlStore(HCERTSTORE hCertStore, DWORD dwFlags,
|
|||
ret = FALSE;
|
||||
else
|
||||
{
|
||||
if (hcs->control)
|
||||
ret = hcs->control(hCertStore, dwFlags, dwCtrlType, pvCtrlPara);
|
||||
if (hcs->vtbl->control)
|
||||
ret = hcs->vtbl->control(hcs, dwFlags, dwCtrlType, pvCtrlPara);
|
||||
else
|
||||
ret = TRUE;
|
||||
}
|
||||
|
@ -1253,7 +1166,7 @@ BOOL WINAPI CertControlStore(HCERTSTORE hCertStore, DWORD dwFlags,
|
|||
BOOL WINAPI CertGetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
|
||||
void *pvData, DWORD *pcbData)
|
||||
{
|
||||
PWINECRYPT_CERTSTORE store = hCertStore;
|
||||
WINECRYPT_CERTSTORE *store = hCertStore;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
TRACE("(%p, %d, %p, %p)\n", hCertStore, dwPropId, pvData, pcbData);
|
||||
|
@ -1317,7 +1230,7 @@ BOOL WINAPI CertGetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
|
|||
BOOL WINAPI CertSetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
|
||||
DWORD dwFlags, const void *pvData)
|
||||
{
|
||||
PWINECRYPT_CERTSTORE store = hCertStore;
|
||||
WINECRYPT_CERTSTORE *store = hCertStore;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
TRACE("(%p, %d, %08x, %p)\n", hCertStore, dwPropId, dwFlags, pvData);
|
||||
|
@ -1463,3 +1376,81 @@ BOOL WINAPI CertRegisterPhysicalStore(const void *pvSystemStore, DWORD dwFlags,
|
|||
dwFlags, debugstr_w(pwszStoreName), pStoreInfo, pvReserved);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void EmptyStore_addref(WINECRYPT_CERTSTORE *store)
|
||||
{
|
||||
TRACE("(%p)\n", store);
|
||||
}
|
||||
|
||||
static DWORD EmptyStore_release(WINECRYPT_CERTSTORE *store, DWORD flags)
|
||||
{
|
||||
TRACE("(%p)\n", store);
|
||||
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,
|
||||
context_t *replace, context_t **ret_context, BOOL use_link)
|
||||
{
|
||||
TRACE("(%p, %p, %p, %p)\n", store, context, replace, ret_context);
|
||||
|
||||
/* FIXME: We should clone the context */
|
||||
if(ret_context) {
|
||||
Context_AddRef(context);
|
||||
*ret_context = context;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static context_t *EmptyStore_enum(WINECRYPT_CERTSTORE *store, context_t *prev)
|
||||
{
|
||||
TRACE("(%p, %p)\n", store, prev);
|
||||
|
||||
SetLastError(CRYPT_E_NOT_FOUND);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static BOOL EmptyStore_delete(WINECRYPT_CERTSTORE *store, context_t *context)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL EmptyStore_control(WINECRYPT_CERTSTORE *store, DWORD flags, DWORD ctrl_type, void const *ctrl_para)
|
||||
{
|
||||
TRACE("()\n");
|
||||
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static const store_vtbl_t EmptyStoreVtbl = {
|
||||
EmptyStore_addref,
|
||||
EmptyStore_release,
|
||||
EmptyStore_releaseContext,
|
||||
EmptyStore_control,
|
||||
{
|
||||
EmptyStore_add,
|
||||
EmptyStore_enum,
|
||||
EmptyStore_delete
|
||||
}, {
|
||||
EmptyStore_add,
|
||||
EmptyStore_enum,
|
||||
EmptyStore_delete
|
||||
}, {
|
||||
EmptyStore_add,
|
||||
EmptyStore_enum,
|
||||
EmptyStore_delete
|
||||
}
|
||||
};
|
||||
|
||||
WINECRYPT_CERTSTORE empty_store;
|
||||
|
||||
void init_empty_store(void)
|
||||
{
|
||||
CRYPT_InitStore(&empty_store, CERT_STORE_READONLY_FLAG, StoreTypeEmpty, &EmptyStoreVtbl);
|
||||
}
|
||||
|
|
|
@ -448,7 +448,7 @@ DWORD WINAPI CertNameToStrA(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
|
|||
for (j = 0; (!psz || ret < csz) && j < rdn->cRDNAttr; j++)
|
||||
{
|
||||
DWORD chars;
|
||||
char prefixBuf[10]; /* big enough for GivenName */
|
||||
char prefixBuf[13]; /* big enough for SERIALNUMBER */
|
||||
LPCSTR prefix = NULL;
|
||||
|
||||
if ((dwStrType & 0x000000ff) == CERT_OID_NAME_STR)
|
||||
|
|
|
@ -64,7 +64,7 @@ reactos/dll/win32/comctl32 # Synced to Wine 1.7.17
|
|||
reactos/dll/win32/comdlg32 # Synced to Wine 1.7.17
|
||||
reactos/dll/win32/compstui # Synced to Wine-1.7.1
|
||||
reactos/dll/win32/credui # Synced to Wine-1.7.1
|
||||
reactos/dll/win32/crypt32 # Synced to Wine-1.7.1
|
||||
reactos/dll/win32/crypt32 # Synced to Wine-1.7.17
|
||||
reactos/dll/win32/cryptdlg # Synced to Wine-1.7.1
|
||||
reactos/dll/win32/cryptdll # Synced to Wine-1.7.1
|
||||
reactos/dll/win32/cryptnet # Synced to Wine-1.7.1
|
||||
|
|
Loading…
Reference in a new issue