* Sync with Wine 1.7.17.
CORE-8080
svn path=/trunk/; revision=62883
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)
* 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
* 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,
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,
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;
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)
{
{
CRYPT_DATA_BLOB blob = { *pcbData, pvData };
- ret = CertContext_SetProperty(context, dwPropId, 0, &blob);
+ ret = CertContext_SetProperty(cert, dwPropId, 0, &blob);
}
return ret;
}
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)
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)
{
{
ret = CertContext_CopyParam(pvData, pcbData, value.pbData,
value.cbData);
- CertContext_SetProperty(context, dwPropId, 0, &value);
+ CertContext_SetProperty(cert, dwPropId, 0, &value);
}
}
else
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);
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,
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);
}
}
}
-static BOOL CertContext_SetKeyProvInfoProperty(PCONTEXT_PROPERTY_LIST properties,
+static BOOL CertContext_SetKeyProvInfoProperty(CONTEXT_PROPERTY_LIST *properties,
const CRYPT_KEY_PROV_INFO *info)
{
BOOL ret;
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
{
{
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;
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;
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)
{
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;
}
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;
ret = !memcmp(buf, id->u.KeyId.pbData, size);
CryptMemFree(buf);
}
+ else
+ ret = FALSE;
}
else
ret = FALSE;
ret = !memcmp(buf, hash->pbData, size);
CryptMemFree(buf);
}
+ else
+ ret = FALSE;
}
else
ret = FALSE;
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);
}
CryptMemFree(hash);
}
+ else
+ ret = FALSE;
}
}
CryptMemFree(encoded);
}
+ else
+ ret = FALSE;
}
return ret;
}
#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
DWORD dwUrlRetrievalTimeout;
DWORD MaximumCachedCertificates;
DWORD CycleDetectionModulus;
-} CertificateChainEngine, *PCertificateChainEngine;
+} CertificateChainEngine;
static inline void CRYPT_AddStoresToCollection(HCERTSTORE collection,
DWORD cStores, HCERTSTORE *stores)
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;
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;
-}
-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);
- }
+ *phChainEngine = CRYPT_CreateChainEngine(NULL, CERT_SYSTEM_STORE_CURRENT_USER, pConfig);
+ return *phChainEngine != NULL;
}
-static HCERTCHAINENGINE CRYPT_GetDefaultChainEngine(void)
+void WINAPI CertFreeCertificateChainEngine(HCERTCHAINENGINE hChainEngine)
{
- 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;
+ TRACE("(%p)\n", hChainEngine);
+ 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
CERT_CHAIN_CONTEXT context;
HCERTSTORE world;
LONG ref;
-} CertificateChain, *PCertificateChain;
+} CertificateChain;
static BOOL CRYPT_IsCertificateSelfSigned(PCCERT_CONTEXT cert)
{
ret = !memcmp(buf, info->KeyId.pbData, size);
CryptMemFree(buf);
}
+ else
+ ret = FALSE;
}
else
ret = FALSE;
CertFreeCertificateContext(trustedRoot);
}
-static void CRYPT_CheckRootCert(HCERTCHAINENGINE hRoot,
+static void CRYPT_CheckRootCert(HCERTSTORE hRoot,
PCERT_CHAIN_ELEMENT rootElement)
{
PCCERT_CONTEXT root = rootElement->pCertContext;
* 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)
{
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;
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];
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;
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");
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");
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");
{
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");
}
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;
}
* 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;
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)
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;
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);
}
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;
/* 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)
{
return copy;
}
-static void CRYPT_FreeLowerQualityChains(PCertificateChain chain)
+static void CRYPT_FreeLowerQualityChains(CertificateChain *chain)
{
DWORD i;
chain->context.rgpLowerQualityChainContext = NULL;
}
-static void CRYPT_FreeChainContext(PCertificateChain chain)
+static void CRYPT_FreeChainContext(CertificateChain *chain)
{
DWORD i;
/* 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)
{
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)
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)
{
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);
* 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;
*/
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))
{
return chain;
}
-static BOOL CRYPT_AddAlternateChainToChain(PCertificateChain chain,
+static BOOL CRYPT_AddAlternateChainToChain(CertificateChain *chain,
const CertificateChain *alternate)
{
BOOL ret;
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,
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)
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.
PCCERT_CHAIN_CONTEXT WINAPI CertDuplicateCertificateChain(
PCCERT_CHAIN_CONTEXT pChainContext)
{
- PCertificateChain chain = (PCertificateChain)pChainContext;
+ CertificateChain *chain = (CertificateChain*)pChainContext;
TRACE("(%p)\n", pChainContext);
VOID WINAPI CertFreeCertificateChain(PCCERT_CHAIN_CONTEXT pChainContext)
{
- PCertificateChain chain = (PCertificateChain)pChainContext;
+ CertificateChain *chain = (CertificateChain*)pChainContext;
TRACE("(%p)\n", pChainContext);
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);
+}
+
+static DWORD Collection_release(WINECRYPT_CERTSTORE *store, DWORD flags)
+{
+ WINE_COLLECTIONSTORE *cs = (WINE_COLLECTIONSTORE*)store;
+ WINE_STORE_LIST_ENTRY *entry, *next;
+ LONG ref;
+
+ if(flags)
+ FIXME("Unimplemented flags %x\n", flags);
- TRACE("(%p, %08x)\n", store, dwFlags);
+ 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)
+ 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);
+}
+
+static context_t *CRYPT_CollectionCreateContextFromChild(WINE_COLLECTIONSTORE *store,
+ WINE_STORE_LIST_ENTRY *storeEntry, context_t *child)
+{
+ context_t *ret;
- if (ret)
- *(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(ret, contextSize)
- = storeEntry;
+ 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;
}
}
* 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)
/* 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
{
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);
-
- if (context)
- context->hCertStore = store;
- *ppStoreContext = context;
+ WINE_STORE_LIST_ENTRY *storeEntry = childContext->u.ptr;
+ cert_t *context = (cert_t*)CRYPT_CollectionCreateContextFromChild(cs, storeEntry,
+ childContext);
+
+ *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
{
}
}
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;
-
- TRACE("(%p, %p)\n", store, pCertContext);
-
- /* 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;
+ cert_t *cert = (cert_t*)context;
+ cert_t *linked;
+
+ TRACE("(%p, %p)\n", store, cert);
+
+ 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);
-
- if (context)
- context->hCertStore = store;
- *ppStoreContext = context;
+ WINE_STORE_LIST_ENTRY *storeEntry = childContext->u.ptr;
+ crl_t *context = (crl_t*)CRYPT_CollectionCreateContextFromChild(cs, storeEntry,
+ childContext);
+
+ *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
{
}
}
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;
-
- TRACE("(%p, %p)\n", store, pCrlContext);
-
- /* 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;
+ crl_t *crl = (crl_t*)context, *linked;
+
+ TRACE("(%p, %p)\n", store, crl);
+
+ 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);
-
- if (context)
- context->hCertStore = store;
- *ppStoreContext = context;
+ WINE_STORE_LIST_ENTRY *storeEntry = childContext->u.ptr;
+ ctl_t *context = (ctl_t*)CRYPT_CollectionCreateContextFromChild(cs, storeEntry,
+ childContext);
+
+ *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
{
}
}
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;
-
- TRACE("(%p, %p)\n", store, pCtlContext);
-
- /* 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;
+ ctl_t *ctl = (ctl_t*)context, *linked;
+
+ TRACE("(%p, %p)\n", store, ctl);
+
+ 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;
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;
}
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)
{
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,
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,
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);
WINE_DEFAULT_DEBUG_CHANNEL(context);
-typedef enum _ContextType {
- ContextTypeData,
- ContextTypeLink,
-} ContextType;
-
-typedef struct _BASE_CONTEXT
-{
- LONG ref;
- ContextType type;
-} BASE_CONTEXT, *PBASE_CONTEXT;
-
-typedef struct _DATA_CONTEXT
-{
- LONG ref;
- ContextType type; /* always ContextTypeData */
- PCONTEXT_PROPERTY_LIST properties;
-} DATA_CONTEXT, *PDATA_CONTEXT;
-
-typedef struct _LINK_CONTEXT
+context_t *Context_CreateDataContext(size_t contextSize, const context_vtbl_t *vtbl, WINECRYPT_CERTSTORE *store)
{
- LONG ref;
- ContextType type; /* always ContextTypeLink */
- PBASE_CONTEXT linked;
-} LINK_CONTEXT, *PLINK_CONTEXT;
+ context_t *context;
-#define CONTEXT_FROM_BASE_CONTEXT(p, s) ((LPBYTE)(p) - (s))
-#define BASE_CONTEXT_FROM_CONTEXT(p, s) (PBASE_CONTEXT)((LPBYTE)(p) + (s))
+ context = CryptMemAlloc(sizeof(context_t) + contextSize);
+ if (!context)
+ return NULL;
-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);
-
- TRACE("(%d, %p, %d)\n", contextSize, linked, extra);
+ context->vtbl = vtbl;
+ context->ref = 1;
+ context->linked = NULL;
- if (context)
- {
- PLINK_CONTEXT linkContext = (PLINK_CONTEXT)BASE_CONTEXT_FROM_CONTEXT(
- context, contextSize);
- PBASE_CONTEXT linkedBase = BASE_CONTEXT_FROM_CONTEXT(linked,
- contextSize);
+ store->vtbl->addref(store);
+ context->store = store;
- 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);
+ TRACE("returning %p\n", context);
+ return context;
}
-PCONTEXT_PROPERTY_LIST Context_GetProperties(const void *context, size_t contextSize)
+void Context_AddRef(context_t *context)
{
- PBASE_CONTEXT ptr = BASE_CONTEXT_FROM_CONTEXT(context, contextSize);
+ LONG ref = InterlockedIncrement(&context->ref);
- while (ptr && ptr->type == ContextTypeLink)
- ptr = ((PLINK_CONTEXT)ptr)->linked;
- return (ptr && ptr->type == ContextTypeData) ?
- ((PDATA_CONTEXT)ptr)->properties : NULL;
-}
+ TRACE("(%p) ref=%d\n", context, context->ref);
-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(ref == 1) {
+ /* This is the first external (non-store) reference. Increase store ref cnt. */
+ context->store->vtbl->addref(context->store);
}
- 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)
+void Context_Free(context_t *context)
{
- PCONTEXT_PROPERTY_LIST toProperties, fromProperties;
+ TRACE("(%p)\n", context);
- 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;
-};
+ assert(!context->ref);
-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);
+ if (!context->linked) {
+ ContextPropertyList_Free(context->properties);
+ context->vtbl->free(context);
+ }else {
+ Context_Release(context->linked);
}
- 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);
- }
- return context;
+ CryptMemFree(context);
}
-void *ContextList_Enum(struct ContextList *list, void *pPrev)
+void Context_Release(context_t *context)
{
- struct list *listNext;
- void *ret;
+ LONG ref = InterlockedDecrement(&context->ref);
- EnterCriticalSection(&list->cs);
- if (pPrev)
- {
- struct list *prevEntry = ContextList_ContextToEntry(list, pPrev);
+ TRACE("(%p) ref=%d\n", context, ref);
+ assert(ref >= 0);
- listNext = list_next(&list->contexts, prevEntry);
- list->contextInterface->free(pPrev);
- }
- 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)
-{
- struct list *entry = ContextList_ContextToEntry(list, context);
- BOOL inList = FALSE;
+ if (!ref) {
+ WINECRYPT_CERTSTORE *store = context->store;
- EnterCriticalSection(&list->cs);
- if (!list_empty(entry))
- {
- list_remove(entry);
- inList = TRUE;
+ /* 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);
- if (inList)
- list_init(entry);
- return inList;
}
-static void ContextList_Empty(struct ContextList *list)
+void Context_CopyProperties(const void *to, const void *from)
{
- struct list *entry, *next;
-
- EnterCriticalSection(&list->cs);
- LIST_FOR_EACH_SAFE(entry, next, &list->contexts)
- {
- const void *context = ContextList_EntryToContext(list, entry);
+ CONTEXT_PROPERTY_LIST *toProperties, *fromProperties;
- TRACE("removing %p\n", context);
- list_remove(entry);
- list->contextInterface->free(context);
- }
- LeaveCriticalSection(&list->cs);
-}
-
-void ContextList_Free(struct ContextList *list)
-{
- ContextList_Empty(list);
- list->cs.DebugInfo->Spare[0] = 0;
- DeleteCriticalSection(&list->cs);
- CryptMemFree(list);
+ toProperties = context_from_ptr(to)->properties;
+ fromProperties = context_from_ptr(from)->properties;
+ assert(toProperties && fromProperties);
+ ContextPropertyList_Copy(toProperties, fromProperties);
}
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,
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,
{
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)
{
{
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)
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:
}
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
{
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:
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;
}
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.
*/
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);
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 */
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
* - 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
* 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;
-
-/* 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_CopyProperties(const void *to, const void *from) 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;
-
-/**
- * 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 ContextPropertyList_Free(CONTEXT_PROPERTY_LIST *list) DECLSPEC_HIDDEN;
-void ContextList_Free(struct ContextList *list) DECLSPEC_HIDDEN;
+extern WINECRYPT_CERTSTORE empty_store;
+void init_empty_store(void) DECLSPEC_HIDDEN;
/**
* Utilities.
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;
if (newer < 0)
{
toAdd = CertDuplicateCTLContext(pCtlContext);
- CtlContext_CopyProperties(existing, pCtlContext);
+ Context_CopyProperties(existing, pCtlContext);
}
else
{
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);
}
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);
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)
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,
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;
&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);
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
{
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)
{
{
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)
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);
}
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
{
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:
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;
}
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 == '.' ||
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)
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;
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;
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;
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;
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;
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;
{
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;
}
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,
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)
{
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);
return store;
}
-PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv,
+WINECRYPT_CERTSTORE *CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv,
DWORD dwFlags, const void *pvPara)
{
HCERTSTORE store = 0;
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));
case DLL_PROCESS_ATTACH:
hInstance = hInst;
DisableThreadLibraryCalls(hInst);
+ init_empty_store();
crypt_oid_init();
break;
case DLL_PROCESS_DETACH:
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)
{
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
{
} 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)
{
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);
}
*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);
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 |
{ 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 },
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
{
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)
{
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)
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);
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;
data = NULL;
if (!cbData || data)
{
- PCONTEXT_PROPERTY prop;
+ CONTEXT_PROPERTY *prop;
BOOL found = FALSE;
EnterCriticalSection(&list->cs);
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,
/* 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)
{
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)
{
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;
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;
+ LONG ref = InterlockedIncrement(&store->ref);
+ TRACE("ref = %d\n", ref);
+}
+
+static DWORD ProvStore_release(WINECRYPT_CERTSTORE *cert_store, DWORD flags)
+{
+ WINE_PROVIDERSTORE *store = (WINE_PROVIDERSTORE*)cert_store;
+ LONG ref;
+
+ if(flags)
+ FIXME("Unimplemented flags %x\n", flags);
- TRACE("(%p, %08x)\n", store, dwFlags);
+ ref = InterlockedDecrement(&store->hdr.ref);
+ TRACE("(%p) ref=%d\n", store, ref);
+
+ if(ref)
+ return ERROR_SUCCESS;
if (store->provCloseStore)
- store->provCloseStore(store->hStoreProv, dwFlags);
+ store->provCloseStore(store->hStoreProv, flags);
if (!(store->dwStoreProvFlags & CERT_STORE_PROV_EXTERNAL_FLAG))
- CertCloseStore(store->memStore, dwFlags);
- CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
+ 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 CRYPT_ProvAddCert(PWINECRYPT_CERTSTORE store, void *cert,
- void *toReplace, const void **ppStoreContext)
+static BOOL ProvStore_addCert(WINECRYPT_CERTSTORE *store, context_t *cert,
+ 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, 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)
{
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)
{
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)
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)
{
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];
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);
{
BYTE hash[20];
struct list entry;
-} WINE_HASH_TO_DELETE, *PWINE_HASH_TO_DELETE;
+} WINE_HASH_TO_DELETE;
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)
{
else
TRACE("hash doesn't match, ignoring\n");
}
- contextInterface->free(context);
+ Context_Release(context_from_ptr(context));
}
}
}
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,
{
if (listToDelete[i])
{
- PWINE_HASH_TO_DELETE toDelete, next;
+ WINE_HASH_TO_DELETE *toDelete, *next;
WCHAR asciiHash[20 * 2 + 1];
EnterCriticalSection(&store->cs);
/* 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;
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)
CryptMemFree(store);
}
-static BOOL CRYPT_RegWriteContext(PWINE_REGSTOREINFO store,
+static BOOL CRYPT_RegWriteContext(WINE_REGSTOREINFO *store,
const void *context, DWORD dwFlags)
{
BOOL ret;
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;
}
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)
{
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);
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);
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);
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);
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);
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);
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,
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);
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)
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;
{
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");
"/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",
};
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);
if (CRYPT_rootStore != root)
CertCloseStore(root, 0);
}
- CertDuplicateStore(CRYPT_rootStore);
+ CRYPT_rootStore->vtbl->addref(CRYPT_rootStore);
return CRYPT_rootStore;
}
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;
}
else
{
- PWINE_CERT_PROP_HEADER hdr;
+ WINE_CERT_PROP_HEADER *hdr;
DWORD bufSize = 0;
LPBYTE buf = NULL;
&propSize);
if (ret)
{
- hdr = (PWINE_CERT_PROP_HEADER)pbElement;
+ hdr = (WINE_CERT_PROP_HEADER*)pbElement;
hdr->propID = prop;
hdr->unknown = 1;
hdr->cb = propSize;
} 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;
}
else
{
- contextInterface->free(context);
+ Context_Release(context_from_ptr(context));
context = NULL;
}
}
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)
{
if (contextInterface && context)
{
/* Free the last context added */
- contextInterface->free(context);
+ Context_Release(context_from_ptr(context));
}
CryptMemFree(buf);
ret = TRUE;
ret = TRUE;
} while (ret && context != NULL);
if (context)
- contextInterface->free(context);
+ Context_Release(context_from_ptr(context));
return ret;
}
*pdwContentType = type;
ret = contextInterface->addContextToStore(hCertStore, context,
dwAddDisposition, ppvContext);
- contextInterface->free(context);
+ Context_Release(context_from_ptr(context));
}
else
ret = FALSE;
(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);
}
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)
{
- WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
- PCERT_CONTEXT context;
+ context_t *context;
- TRACE("(%p, %p, %p, %p)\n", store, cert, toReplace, ppStoreContext);
+ 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;
+ }
- context = ContextList_Add(ms->certs, cert, toReplace);
- if (context)
+ 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)
{
- context->hCertStore = store;
- if (ppStoreContext)
- *ppStoreContext = CertDuplicateCertificateContext(context);
+ TRACE("freeing %p\n", context);
+ list_remove(&context->u.entry);
+ Context_Free(context);
}
- return context != 0;
}
-static void *CRYPT_MemEnumCert(PWINECRYPT_CERTSTORE store, void *pPrev)
+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;
- void *ret;
- TRACE("(%p, %p)\n", store, pPrev);
+ TRACE("(%p, %p, %p, %p)\n", store, cert, toReplace, ppStoreContext);
+ return MemStore_addContext(ms, &ms->certs, cert, toReplace, ppStoreContext, use_link);
+}
- ret = ContextList_Enum(ms->certs, pPrev);
- if (!ret)
- SetLastError(CRYPT_E_NOT_FOUND);
+static context_t *MemStore_enumCert(WINECRYPT_CERTSTORE *store, context_t *prev)
+{
+ WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
- TRACE("returning %p\n", ret);
- return ret;
+ TRACE("(%p, %p)\n", store, prev);
+
+ 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,
- DWORD dwCtrlType, void const *pvCtrlPara)
+static void MemStore_addref(WINECRYPT_CERTSTORE *store)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ LONG ref = InterlockedIncrement(&store->ref);
+ TRACE("ref = %d\n", ref);
}
-static void WINAPI CRYPT_MemCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
+static DWORD MemStore_release(WINECRYPT_CERTSTORE *cert_store, DWORD flags)
{
- WINE_MEMSTORE *store = hCertStore;
-
- TRACE("(%p, %08x)\n", store, dwFlags);
- if (dwFlags)
- FIXME("Unimplemented flags: %08x\n", dwFlags);
+ 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;
+}
- ContextList_Free(store->certs);
- ContextList_Free(store->crls);
- ContextList_Free(store->ctls);
- CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
+static BOOL MemStore_control(WINECRYPT_CERTSTORE *store, DWORD dwFlags,
+ DWORD dwCtrlType, void const *pvCtrlPara)
+{
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
}
+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);
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;
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));
return ret;
}
-static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv,
+static WINECRYPT_CERTSTORE *CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv,
DWORD dwFlags, const void *pvPara)
{
HCERTSTORE store = 0;
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));
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);
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 :
return store;
}
-static PWINECRYPT_CERTSTORE CRYPT_SerializedOpenStore(HCRYPTPROV hCryptProv,
+static WINECRYPT_CERTSTORE *CRYPT_SerializedOpenStore(HCRYPTPROV hCryptProv,
DWORD dwFlags, const void *pvPara)
{
HCERTSTORE store;
}
}
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)
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)
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;
-#define CrlContext_CopyProperties(to, from) \
- Context_CopyProperties((to), (from), sizeof(CRL_CONTEXT))
+ if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
+ return FALSE;
+
+ return hcs->vtbl->certs.delete(hcs, &cert_from_ptr(pCertContext)->base);
+}
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;
if (newer < 0)
{
toAdd = CertDuplicateCRLContext(pCrlContext);
- CrlContext_CopyProperties(toAdd, existing);
+ Context_CopyProperties(toAdd, existing);
}
else
{
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);
}
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;
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)
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)
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);
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;
}
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;
}
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);
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);
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);
+}
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)
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