#include <stdarg.h>
#define NONAMELESSUNION
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
+#include "wine/winternl.h"
+#define CRYPT_OID_INFO_HAS_EXTRA_FIELDS
#include "wincrypt.h"
+#include "snmp.h"
+#include "bcrypt.h"
#include "winnls.h"
#include "rpc.h"
#include "wine/debug.h"
* 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
provNameLen = (lstrlenW(info->pwszProvName) + 1) * sizeof(WCHAR);
data += provNameLen;
- info->rgProvParam = (PCRYPT_KEY_PROV_PARAM)data;
- data += info->cProvParam * sizeof(CRYPT_KEY_PROV_PARAM);
-
- for (i = 0; i < info->cProvParam; i++)
+ if (info->cProvParam)
{
- info->rgProvParam[i].pbData = data;
- data += info->rgProvParam[i].cbData;
+ info->rgProvParam = (PCRYPT_KEY_PROV_PARAM)data;
+ data += info->cProvParam * sizeof(CRYPT_KEY_PROV_PARAM);
+
+ for (i = 0; i < info->cProvParam; i++)
+ {
+ info->rgProvParam[i].pbData = data;
+ data += info->rgProvParam[i].cbData;
+ }
}
+ else
+ info->rgProvParam = NULL;
}
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
{
case CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID:
case CERT_ENROLLMENT_PROP_ID:
case CERT_CROSS_CERT_DIST_POINTS_PROP_ID:
+ case CERT_OCSP_RESPONSE_PROP_ID:
case CERT_RENEWAL_PROP_ID:
{
if (pvData)
{
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;
{
CRYPT_KEY_PROV_INFO copy;
WCHAR containerW[MAX_PATH];
- BOOL matches = FALSE;
+ BOOL matches;
- MultiByteToWideChar(CP_ACP, 0, container, -1,
- containerW, sizeof(containerW) / sizeof(containerW[0]));
+ MultiByteToWideChar(CP_ACP, 0, container, -1, containerW, ARRAY_SIZE(containerW));
/* We make a copy of the CRYPT_KEY_PROV_INFO because the caller expects
* keyProvInfo->pwszContainerName to be NULL or a heap-allocated container
* name.
*/
- memcpy(©, keyProvInfo, sizeof(copy));
+ copy = *keyProvInfo;
copy.pwszContainerName = containerW;
matches = key_prov_info_matches_cert(pCert, ©);
if (matches)
BOOL WINAPI CryptFindCertificateKeyProvInfo(PCCERT_CONTEXT pCert,
DWORD dwFlags, void *pvReserved)
{
- BOOL matches = FALSE;
+ BOOL matches;
TRACE("(%p, %08x, %p)\n", pCert, dwFlags, pvReserved);
TRACE("(%08x, %p, %p)\n", dwCertEncodingType, pPublicKey1, pPublicKey2);
+ /* RSA public key data should start with ASN_SEQUENCE,
+ * otherwise it's not a RSA_CSP_PUBLICKEYBLOB.
+ */
+ if (!pPublicKey1->PublicKey.cbData || pPublicKey1->PublicKey.pbData[0] != ASN_SEQUENCE)
+ dwCertEncodingType = 0;
+
switch (GET_CERT_ENCODING_TYPE(dwCertEncodingType))
{
case 0: /* Seems to mean "raw binary bits" */
ret = FALSE;
if (CryptDecodeObject(dwCertEncodingType, RSA_CSP_PUBLICKEYBLOB,
pPublicKey1->PublicKey.pbData, pPublicKey1->PublicKey.cbData,
- 0, NULL, &length))
+ CRYPT_DECODE_ALLOC_FLAG, &pblob1, &length))
{
- pblob1 = CryptMemAlloc(length);
if (CryptDecodeObject(dwCertEncodingType, RSA_CSP_PUBLICKEYBLOB,
- pPublicKey1->PublicKey.pbData, pPublicKey1->PublicKey.cbData,
- 0, pblob1, &length))
+ pPublicKey2->PublicKey.pbData, pPublicKey2->PublicKey.cbData,
+ CRYPT_DECODE_ALLOC_FLAG, &pblob2, &length))
{
- if (CryptDecodeObject(dwCertEncodingType, RSA_CSP_PUBLICKEYBLOB,
- pPublicKey2->PublicKey.pbData, pPublicKey2->PublicKey.cbData,
- 0, NULL, &length))
- {
- pblob2 = CryptMemAlloc(length);
- if (CryptDecodeObject(dwCertEncodingType, RSA_CSP_PUBLICKEYBLOB,
- pPublicKey2->PublicKey.pbData, pPublicKey2->PublicKey.cbData,
- 0, pblob2, &length))
- {
- /* The RSAPUBKEY structure directly follows the BLOBHEADER */
- RSAPUBKEY *pk1 = (LPVOID)(pblob1 + 1),
- *pk2 = (LPVOID)(pblob2 + 1);
- ret = (pk1->bitlen == pk2->bitlen) && (pk1->pubexp == pk2->pubexp)
- && !memcmp(pk1 + 1, pk2 + 1, pk1->bitlen/8);
- }
- CryptMemFree(pblob2);
- }
+ /* The RSAPUBKEY structure directly follows the BLOBHEADER */
+ RSAPUBKEY *pk1 = (LPVOID)(pblob1 + 1),
+ *pk2 = (LPVOID)(pblob2 + 1);
+ ret = (pk1->bitlen == pk2->bitlen) && (pk1->pubexp == pk2->pubexp)
+ && !memcmp(pk1 + 1, pk2 + 1, pk1->bitlen/8);
+
+ LocalFree(pblob2);
}
- CryptMemFree(pblob1);
+ LocalFree(pblob1);
}
break;
}
else
{
+ PCCRYPT_OID_INFO info;
DWORD size;
PBYTE buf;
- BOOL ret = CryptDecodeObjectEx(dwCertEncodingType,
+ BOOL ret;
+
+ info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY, pPublicKey->Algorithm.pszObjId, 0);
+ if (info)
+ {
+ HCRYPTKEY key;
+
+ TRACE("public key algid %#x (%s)\n", info->u.Algid, debugstr_a(pPublicKey->Algorithm.pszObjId));
+
+ ret = CryptImportPublicKeyInfo(I_CryptGetDefaultCryptProv(info->u.Algid), dwCertEncodingType, pPublicKey, &key);
+ if (ret)
+ {
+ size = sizeof(len);
+ ret = CryptGetKeyParam(key, KP_KEYLEN, (BYTE *)&len, &size, 0);
+ CryptDestroyKey(key);
+ return len;
+ }
+ /* fallback to RSA */
+ }
+
+ ret = CryptDecodeObjectEx(dwCertEncodingType,
RSA_CSP_PUBLICKEYBLOB, pPublicKey->PublicKey.pbData,
pPublicKey->PublicKey.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
&size);
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;
}
if (find)
- ret = find(hCertStore, dwFlags, dwType, pvPara, pPrevCertContext);
+ ret = find(hCertStore, dwType, dwFlags, pvPara, pPrevCertContext);
else if (compare)
ret = cert_compare_certs_in_store(hCertStore, pPrevCertContext,
compare, dwType, dwFlags, pvPara);
CertFreeCertificateContext(ret);
ret = NULL;
}
+ if (CRYPT_IsCertificateSelfSigned(pSubjectContext))
+ {
+ CertFreeCertificateContext(ret);
+ ret = NULL;
+ SetLastError(CRYPT_E_SELF_SIGNED);
+ }
}
TRACE("returning %p\n", ret);
return ret;
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);
pbEncoded, cbEncoded, pbComputedHash, pcbComputedHash);
if (!hCryptProv)
- hCryptProv = CRYPT_GetDefaultProvider();
+ hCryptProv = I_CryptGetDefaultCryptProv(0);
if (!Algid)
Algid = CALG_SHA1;
if (ret)
dwCertEncodingType, pInfo, pbComputedHash, pcbComputedHash);
if (!hCryptProv)
- hCryptProv = CRYPT_GetDefaultProvider();
+ hCryptProv = I_CryptGetDefaultCryptProv(0);
if (!Algid)
Algid = CALG_MD5;
if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING)
HCRYPTHASH hHash;
if (!hCryptProv)
- hCryptProv = CRYPT_GetDefaultProvider();
+ hCryptProv = I_CryptGetDefaultCryptProv(0);
oidInfo = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
info->SignatureAlgorithm.pszObjId, 0);
if (!oidInfo)
if (info->dwGroupId == CRYPT_HASH_ALG_OID_GROUP_ID)
{
if (!hCryptProv)
- hCryptProv = CRYPT_GetDefaultProvider();
+ hCryptProv = I_CryptGetDefaultCryptProv(0);
ret = CryptCreateHash(hCryptProv, info->u.Algid, 0, 0, &hHash);
if (ret)
{
info.ToBeSigned.cbData = encodedSize;
info.ToBeSigned.pbData = encoded;
- memcpy(&info.SignatureAlgorithm,
- pSignatureAlgorithm,
- sizeof(info.SignatureAlgorithm));
+ info.SignatureAlgorithm = *pSignatureAlgorithm;
info.Signature.cbData = hashSize;
info.Signature.pbData = hash;
info.Signature.cUnusedBits = 0;
}
CryptMemFree(hash);
}
+ else
+ ret = FALSE;
}
}
CryptMemFree(encoded);
}
+ else
+ ret = FALSE;
}
return ret;
}
DWORD dwCertEncodingType, const BYTE *pbEncoded, DWORD cbEncoded,
PCERT_PUBLIC_KEY_INFO pPublicKey)
{
+ CRYPT_DATA_BLOB blob = { cbEncoded, (BYTE *)pbEncoded };
+
return CryptVerifyCertificateSignatureEx(hCryptProv, dwCertEncodingType,
- CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, (void *)pbEncoded,
+ CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &blob,
CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY, pPublicKey, 0, NULL);
}
-static BOOL CRYPT_VerifyCertSignatureFromPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv,
- DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pubKeyInfo,
- const CERT_SIGNED_CONTENT_INFO *signedCert)
+static BOOL CRYPT_VerifySignature(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEncodingType,
+ CERT_PUBLIC_KEY_INFO *pubKeyInfo, const CERT_SIGNED_CONTENT_INFO *signedCert, const CRYPT_OID_INFO *info)
{
BOOL ret;
HCRYPTKEY key;
- PCCRYPT_OID_INFO info;
ALG_ID pubKeyID, hashID;
- info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
- signedCert->SignatureAlgorithm.pszObjId, 0);
- if (!info || info->dwGroupId != CRYPT_SIGN_ALG_OID_GROUP_ID)
- {
- SetLastError(NTE_BAD_ALGID);
- return FALSE;
- }
hashID = info->u.Algid;
if (info->ExtraInfo.cbData >= sizeof(ALG_ID))
pubKeyID = *(ALG_ID *)info->ExtraInfo.pbData;
pubKeyID = hashID;
/* Load the default provider if necessary */
if (!hCryptProv)
- hCryptProv = CRYPT_GetDefaultProvider();
+ hCryptProv = I_CryptGetDefaultCryptProv(0);
ret = CryptImportPublicKeyInfoEx(hCryptProv, dwCertEncodingType,
pubKeyInfo, pubKeyID, 0, NULL, &key);
if (ret)
return ret;
}
+static BOOL CNG_CalcHash(const WCHAR *algorithm, const CERT_SIGNED_CONTENT_INFO *signedCert,
+ BYTE **hash_value, DWORD *hash_len)
+{
+ BCRYPT_HASH_HANDLE hash = NULL;
+ BCRYPT_ALG_HANDLE alg = NULL;
+ NTSTATUS status;
+ DWORD size;
+
+ if ((status = BCryptOpenAlgorithmProvider(&alg, algorithm, NULL, 0)))
+ goto done;
+
+ if ((status = BCryptCreateHash(alg, &hash, NULL, 0, NULL, 0, 0)))
+ goto done;
+
+ if ((status = BCryptHashData(hash, signedCert->ToBeSigned.pbData, signedCert->ToBeSigned.cbData, 0)))
+ goto done;
+
+ if ((status = BCryptGetProperty(hash, BCRYPT_HASH_LENGTH, (BYTE *)hash_len, sizeof(*hash_len), &size, 0)))
+ goto done;
+
+ if (!(*hash_value = CryptMemAlloc(*hash_len)))
+ {
+ status = STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ if ((status = BCryptFinishHash(hash, *hash_value, *hash_len, 0)))
+ {
+ CryptMemFree(*hash_value);
+ goto done;
+ }
+
+done:
+ if (hash) BCryptDestroyHash(hash);
+ if (alg) BCryptCloseAlgorithmProvider(alg, 0);
+ if (status) SetLastError(RtlNtStatusToDosError(status));
+ return status == 0;
+}
+
+static BOOL CNG_ImportECCPubKey(CERT_PUBLIC_KEY_INFO *pubKeyInfo, BCRYPT_KEY_HANDLE *key)
+{
+ DWORD blob_magic, ecckey_len, size;
+ BCRYPT_ALG_HANDLE alg = NULL;
+ BCRYPT_ECCKEY_BLOB *ecckey;
+ const WCHAR *sign_algo;
+ char **ecc_curve;
+ NTSTATUS status;
+
+ if (!pubKeyInfo->PublicKey.cbData)
+ {
+ SetLastError(NTE_BAD_ALGID);
+ return FALSE;
+ }
+
+ if (pubKeyInfo->PublicKey.pbData[0] != 0x4)
+ {
+ FIXME("Compressed ECC curves (%02x) not yet supported\n", pubKeyInfo->PublicKey.pbData[0]);
+ SetLastError(NTE_BAD_ALGID);
+ return FALSE;
+ }
+
+ if (!CryptDecodeObjectEx(X509_ASN_ENCODING, X509_OBJECT_IDENTIFIER, pubKeyInfo->Algorithm.Parameters.pbData,
+ pubKeyInfo->Algorithm.Parameters.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &ecc_curve, &size))
+ return FALSE;
+
+ if (!strcmp(*ecc_curve, szOID_ECC_CURVE_P256))
+ {
+ sign_algo = BCRYPT_ECDSA_P256_ALGORITHM;
+ blob_magic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC;
+ }
+ else if (!strcmp(*ecc_curve, szOID_ECC_CURVE_P384))
+ {
+ sign_algo = BCRYPT_ECDSA_P384_ALGORITHM;
+ blob_magic = BCRYPT_ECDSA_PUBLIC_P384_MAGIC;
+ }
+ else
+ {
+ FIXME("Unsupported ecc curve type: %s\n", *ecc_curve);
+ sign_algo = NULL;
+ blob_magic = 0;
+ }
+ LocalFree(ecc_curve);
+
+ if (!sign_algo)
+ {
+ SetLastError(NTE_BAD_ALGID);
+ return FALSE;
+ }
+
+ if ((status = BCryptOpenAlgorithmProvider(&alg, sign_algo, NULL, 0)))
+ goto done;
+
+ ecckey_len = sizeof(BCRYPT_ECCKEY_BLOB) + pubKeyInfo->PublicKey.cbData - 1;
+ if (!(ecckey = CryptMemAlloc(ecckey_len)))
+ {
+ status = STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ ecckey->dwMagic = blob_magic;
+ ecckey->cbKey = (pubKeyInfo->PublicKey.cbData - 1) / 2;
+ memcpy(ecckey + 1, pubKeyInfo->PublicKey.pbData + 1, pubKeyInfo->PublicKey.cbData - 1);
+
+ status = BCryptImportKeyPair(alg, NULL, BCRYPT_ECCPUBLIC_BLOB, key, (BYTE*)ecckey, ecckey_len, 0);
+ CryptMemFree(ecckey);
+
+done:
+ if (alg) BCryptCloseAlgorithmProvider(alg, 0);
+ if (status) SetLastError(RtlNtStatusToDosError(status));
+ return !status;
+}
+
+static BOOL CNG_ImportPubKey(CERT_PUBLIC_KEY_INFO *pubKeyInfo, BCRYPT_KEY_HANDLE *key)
+{
+ if (!strcmp(pubKeyInfo->Algorithm.pszObjId, szOID_ECC_PUBLIC_KEY))
+ return CNG_ImportECCPubKey(pubKeyInfo, key);
+
+ FIXME("Unsupported public key type: %s\n", debugstr_a(pubKeyInfo->Algorithm.pszObjId));
+ SetLastError(NTE_BAD_ALGID);
+ return FALSE;
+}
+
+static BOOL CNG_PrepareSignatureECC(BYTE *encoded_sig, DWORD encoded_size, BYTE **sig_value, DWORD *sig_len)
+{
+ CERT_ECC_SIGNATURE *ecc_sig;
+ DWORD size;
+ int i;
+
+ if (!CryptDecodeObjectEx(X509_ASN_ENCODING, X509_ECC_SIGNATURE, encoded_sig, encoded_size,
+ CRYPT_DECODE_ALLOC_FLAG, NULL, &ecc_sig, &size))
+ return FALSE;
+
+ if (!ecc_sig->r.cbData || !ecc_sig->s.cbData)
+ {
+ LocalFree(ecc_sig);
+ SetLastError(ERROR_INVALID_DATA);
+ return FALSE;
+ }
+
+ *sig_len = ecc_sig->r.cbData + ecc_sig->s.cbData;
+ if (!(*sig_value = CryptMemAlloc(*sig_len)))
+ {
+ LocalFree(ecc_sig);
+ SetLastError(ERROR_OUTOFMEMORY);
+ return FALSE;
+ }
+
+ for (i = 0; i < ecc_sig->r.cbData; i++)
+ (*sig_value)[i] = ecc_sig->r.pbData[ecc_sig->r.cbData - i - 1];
+ for (i = 0; i < ecc_sig->s.cbData; i++)
+ (*sig_value)[ecc_sig->r.cbData + i] = ecc_sig->s.pbData[ecc_sig->s.cbData - i - 1];
+
+ LocalFree(ecc_sig);
+ return TRUE;
+}
+
+static BOOL CNG_PrepareSignature(CERT_PUBLIC_KEY_INFO *pubKeyInfo, const CERT_SIGNED_CONTENT_INFO *signedCert,
+ BYTE **sig_value, DWORD *sig_len)
+{
+ BYTE *encoded_sig;
+ BOOL ret = FALSE;
+ int i;
+
+ if (!signedCert->Signature.cbData)
+ {
+ SetLastError(ERROR_INVALID_DATA);
+ return FALSE;
+ }
+
+ if (!(encoded_sig = CryptMemAlloc(signedCert->Signature.cbData)))
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return FALSE;
+ }
+
+ for (i = 0; i < signedCert->Signature.cbData; i++)
+ encoded_sig[i] = signedCert->Signature.pbData[signedCert->Signature.cbData - i - 1];
+
+ if (!strcmp(pubKeyInfo->Algorithm.pszObjId, szOID_ECC_PUBLIC_KEY))
+ ret = CNG_PrepareSignatureECC(encoded_sig, signedCert->Signature.cbData, sig_value, sig_len);
+ else
+ {
+ FIXME("Unsupported public key type: %s\n", debugstr_a(pubKeyInfo->Algorithm.pszObjId));
+ SetLastError(NTE_BAD_ALGID);
+ }
+
+ CryptMemFree(encoded_sig);
+ return ret;
+}
+
+static BOOL CNG_VerifySignature(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEncodingType,
+ CERT_PUBLIC_KEY_INFO *pubKeyInfo, const CERT_SIGNED_CONTENT_INFO *signedCert, const CRYPT_OID_INFO *info)
+{
+ BCRYPT_KEY_HANDLE key = NULL;
+ BYTE *hash_value = NULL, *sig_value;
+ DWORD hash_len, sig_len;
+ NTSTATUS status;
+ BOOL ret;
+
+ ret = CNG_ImportPubKey(pubKeyInfo, &key);
+ if (ret)
+ {
+ ret = CNG_CalcHash(info->pwszCNGAlgid, signedCert, &hash_value, &hash_len);
+ if (ret)
+ {
+ ret = CNG_PrepareSignature(pubKeyInfo, signedCert, &sig_value, &sig_len);
+ if (ret)
+ {
+ status = BCryptVerifySignature(key, NULL, hash_value, hash_len, sig_value, sig_len, 0);
+ if (status)
+ {
+ FIXME("Failed to verify signature: %08x\n", status);
+ SetLastError(RtlNtStatusToDosError(status));
+ ret = FALSE;
+ }
+ CryptMemFree(sig_value);
+ }
+ CryptMemFree(hash_value);
+ }
+ BCryptDestroyKey(key);
+ }
+
+ return ret;
+}
+
+static BOOL CRYPT_VerifyCertSignatureFromPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEncodingType,
+ CERT_PUBLIC_KEY_INFO *pubKeyInfo, const CERT_SIGNED_CONTENT_INFO *signedCert)
+{
+ CCRYPT_OID_INFO *info;
+
+ info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY, signedCert->SignatureAlgorithm.pszObjId, 0);
+ if (!info || info->dwGroupId != CRYPT_SIGN_ALG_OID_GROUP_ID)
+ {
+ SetLastError(NTE_BAD_ALGID);
+ return FALSE;
+ }
+
+ if (info->u.Algid == CALG_OID_INFO_CNG_ONLY)
+ return CNG_VerifySignature(hCryptProv, dwCertEncodingType, pubKeyInfo, signedCert, info);
+ else
+ return CRYPT_VerifySignature(hCryptProv, dwCertEncodingType, pubKeyInfo, signedCert, info);
+}
+
BOOL WINAPI CryptVerifyCertificateSignatureEx(HCRYPTPROV_LEGACY hCryptProv,
DWORD dwCertEncodingType, DWORD dwSubjectType, void *pvSubject,
DWORD dwIssuerType, void *pvIssuer, DWORD dwFlags, void *pvReserved)
static BOOL CRYPT_IsBitInFieldSet(const struct BitField *field, DWORD bit)
{
- BOOL set = FALSE;
+ BOOL set;
DWORD indexIndex = bit / BITS_PER_DWORD;
assert(field->cIndexes);
CryptMemFree(szProvider);
}
}
- size = sizeof(info.dwKeySpec);
/* in case no CRYPT_KEY_PROV_INFO given,
* we always use AT_SIGNATURE key spec
*/
signedInfo.ToBeSigned.cbData = blob->cbData;
signedInfo.ToBeSigned.pbData = blob->pbData;
- memcpy(&signedInfo.SignatureAlgorithm, sigAlgo,
- sizeof(signedInfo.SignatureAlgorithm));
+ signedInfo.SignatureAlgorithm = *sigAlgo;
signedInfo.Signature.cbData = sigSize;
signedInfo.Signature.pbData = sig;
signedInfo.Signature.cUnusedBits = 0;
info->SerialNumber.cbData = pSerialNumber->cbData;
info->SerialNumber.pbData = pSerialNumber->pbData;
if (pSignatureAlgorithm)
- memcpy(&info->SignatureAlgorithm, pSignatureAlgorithm,
- sizeof(info->SignatureAlgorithm));
+ info->SignatureAlgorithm = *pSignatureAlgorithm;
else
{
info->SignatureAlgorithm.pszObjId = oid;
}
info->Subject.cbData = pSubjectIssuerBlob->cbData;
info->Subject.pbData = pSubjectIssuerBlob->pbData;
- memcpy(&info->SubjectPublicKeyInfo, pubKey,
- sizeof(info->SubjectPublicKeyInfo));
+ info->SubjectPublicKeyInfo = *pubKey;
if (pExtensions)
{
info->cExtension = pExtensions->cExtension;
PCCERT_CONTEXT context = NULL;
BOOL ret, releaseContext = FALSE;
PCERT_PUBLIC_KEY_INFO pubKey = NULL;
- DWORD pubKeySize = 0,dwKeySpec = AT_SIGNATURE;
+ DWORD pubKeySize = 0, dwKeySpec;
TRACE("(%08lx, %p, %08x, %p, %p, %p, %p, %p)\n", hProv,
pSubjectIssuerBlob, dwFlags, pKeyProvInfo, pSignatureAlgorithm, pStartTime,
return NULL;
}
+ dwKeySpec = pKeyProvInfo ? pKeyProvInfo->dwKeySpec : AT_SIGNATURE;
if (!hProv)
{
if (!pKeyProvInfo)
if (!ret)
return NULL;
}
- dwKeySpec = pKeyProvInfo->dwKeySpec;
/* check if the key is here */
ret = CryptGetUserKey(hProv,dwKeySpec,&hKey);
if(!ret)
releaseContext = TRUE;
}
}
- else if (pKeyProvInfo)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return NULL;
- }
- CryptExportPublicKeyInfo(hProv, dwKeySpec, X509_ASN_ENCODING, NULL,
+ ret = CryptExportPublicKeyInfo(hProv, dwKeySpec, X509_ASN_ENCODING, NULL,
&pubKeySize);
+ if (!ret)
+ goto end;
pubKey = CryptMemAlloc(pubKeySize);
if (pubKey)
{
}
CryptMemFree(pubKey);
}
+end:
if (releaseContext)
CryptReleaseContext(hProv, 0);
return context;
return NULL;
}
}
+
+BOOL WINAPI CryptSetKeyIdentifierProperty(const CRYPT_HASH_BLOB *pKeyIdentifier, DWORD dwPropId,
+ DWORD dwFlags, LPCWSTR pwszComputerName, void *pvReserved, const void *pvData)
+{
+ FIXME("(%p, 0x%x, 0x%x, %s, %p, %p): stub\n", pKeyIdentifier, dwPropId, dwFlags,
+ debugstr_w(pwszComputerName), pvReserved, pvData);
+ return FALSE;
+}