crypt32: Use public functions during serialization rather than relying

on the internal format of a certificate.
oldstable
Juan Lang 2006-02-23 17:47:12 -08:00 committed by Alexandre Julliard
parent 690f98408b
commit b48f865f7d
1 changed files with 113 additions and 43 deletions

View File

@ -20,8 +20,6 @@
* - As you can see in the stubs below, support for CRLs and CTLs is missing. * - As you can see in the stubs below, support for CRLs and CTLs is missing.
* Mostly this should be copy-paste work, and some code (e.g. extended * Mostly this should be copy-paste work, and some code (e.g. extended
* properties) could be shared between them. * properties) could be shared between them.
* - Opening a cert store provider should be morphed to support loading
* external DLLs.
* - The concept of physical stores and locations isn't implemented. (This * - The concept of physical stores and locations isn't implemented. (This
* doesn't mean registry stores et al aren't implemented. See the PSDK for * doesn't mean registry stores et al aren't implemented. See the PSDK for
* registering and enumerating physical stores and locations.) * registering and enumerating physical stores and locations.)
@ -219,9 +217,10 @@ typedef struct _WINE_CERT_PROP_HEADER
/* Stores an extended property in a cert. */ /* Stores an extended property in a cert. */
typedef struct _WINE_CERT_PROPERTY typedef struct _WINE_CERT_PROPERTY
{ {
WINE_CERT_PROP_HEADER hdr; DWORD propID;
LPBYTE pbData; DWORD cbData;
struct list entry; LPBYTE pbData;
struct list entry;
} WINE_CERT_PROPERTY, *PWINE_CERT_PROPERTY; } WINE_CERT_PROPERTY, *PWINE_CERT_PROPERTY;
/* A mem store has a list of these. They're also returned by the mem store /* A mem store has a list of these. They're also returned by the mem store
@ -2059,14 +2058,14 @@ DWORD WINAPI CertEnumCertificateContextProperties(PCCERT_CONTEXT pCertContext,
LIST_FOR_EACH_ENTRY(cursor, &ref->context->extendedProperties, LIST_FOR_EACH_ENTRY(cursor, &ref->context->extendedProperties,
WINE_CERT_PROPERTY, entry) WINE_CERT_PROPERTY, entry)
{ {
if (cursor->hdr.propID == dwPropId) if (cursor->propID == dwPropId)
break; break;
} }
if (cursor) if (cursor)
{ {
if (cursor->entry.next != &ref->context->extendedProperties) if (cursor->entry.next != &ref->context->extendedProperties)
ret = LIST_ENTRY(cursor->entry.next, WINE_CERT_PROPERTY, ret = LIST_ENTRY(cursor->entry.next, WINE_CERT_PROPERTY,
entry)->hdr.propID; entry)->propID;
else else
ret = 0; ret = 0;
} }
@ -2075,7 +2074,7 @@ DWORD WINAPI CertEnumCertificateContextProperties(PCCERT_CONTEXT pCertContext,
} }
else if (!list_empty(&ref->context->extendedProperties)) else if (!list_empty(&ref->context->extendedProperties))
ret = LIST_ENTRY(ref->context->extendedProperties.next, ret = LIST_ENTRY(ref->context->extendedProperties.next,
WINE_CERT_PROPERTY, entry)->hdr.propID; WINE_CERT_PROPERTY, entry)->propID;
else else
ret = 0; ret = 0;
LeaveCriticalSection(&ref->context->cs); LeaveCriticalSection(&ref->context->cs);
@ -2112,22 +2111,22 @@ static BOOL WINAPI CRYPT_GetCertificateContextProperty(
LIST_FOR_EACH_ENTRY(prop, &context->extendedProperties, LIST_FOR_EACH_ENTRY(prop, &context->extendedProperties,
WINE_CERT_PROPERTY, entry) WINE_CERT_PROPERTY, entry)
{ {
if (prop->hdr.propID == dwPropId) if (prop->propID == dwPropId)
{ {
if (!pvData) if (!pvData)
{ {
*pcbData = prop->hdr.cb; *pcbData = prop->cbData;
ret = TRUE; ret = TRUE;
} }
else if (*pcbData < prop->hdr.cb) else if (*pcbData < prop->cbData)
{ {
SetLastError(ERROR_MORE_DATA); SetLastError(ERROR_MORE_DATA);
*pcbData = prop->hdr.cb; *pcbData = prop->cbData;
} }
else else
{ {
memcpy(pvData, prop->pbData, prop->hdr.cb); memcpy(pvData, prop->pbData, prop->cbData);
*pcbData = prop->hdr.cb; *pcbData = prop->cbData;
ret = TRUE; ret = TRUE;
} }
found = TRUE; found = TRUE;
@ -2254,7 +2253,7 @@ static BOOL CRYPT_SaveCertificateContextProperty(PWINE_CERT_CONTEXT context,
LIST_FOR_EACH_ENTRY(prop, &context->extendedProperties, LIST_FOR_EACH_ENTRY(prop, &context->extendedProperties,
WINE_CERT_PROPERTY, entry) WINE_CERT_PROPERTY, entry)
{ {
if (prop->hdr.propID == dwPropId) if (prop->propID == dwPropId)
{ {
found = TRUE; found = TRUE;
break; break;
@ -2263,7 +2262,7 @@ static BOOL CRYPT_SaveCertificateContextProperty(PWINE_CERT_CONTEXT context,
if (found) if (found)
{ {
CryptMemFree(prop->pbData); CryptMemFree(prop->pbData);
prop->hdr.cb = cbData; prop->cbData = cbData;
prop->pbData = data; prop->pbData = data;
ret = TRUE; ret = TRUE;
} }
@ -2272,9 +2271,8 @@ static BOOL CRYPT_SaveCertificateContextProperty(PWINE_CERT_CONTEXT context,
prop = CryptMemAlloc(sizeof(WINE_CERT_PROPERTY)); prop = CryptMemAlloc(sizeof(WINE_CERT_PROPERTY));
if (prop) if (prop)
{ {
prop->hdr.propID = dwPropId; prop->propID = dwPropId;
prop->hdr.unknown = 1; prop->cbData = cbData;
prop->hdr.cb = cbData;
list_init(&prop->entry); list_init(&prop->entry);
prop->pbData = data; prop->pbData = data;
list_add_tail(&context->extendedProperties, &prop->entry); list_add_tail(&context->extendedProperties, &prop->entry);
@ -2303,7 +2301,7 @@ static BOOL WINAPI CRYPT_SetCertificateContextProperty(
LIST_FOR_EACH_ENTRY_SAFE(prop, next, &context->extendedProperties, LIST_FOR_EACH_ENTRY_SAFE(prop, next, &context->extendedProperties,
WINE_CERT_PROPERTY, entry) WINE_CERT_PROPERTY, entry)
{ {
if (prop->hdr.propID == dwPropId) if (prop->propID == dwPropId)
{ {
list_remove(&prop->entry); list_remove(&prop->entry);
CryptMemFree(prop->pbData); CryptMemFree(prop->pbData);
@ -2440,18 +2438,44 @@ BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore,
ref->context->cert.pbCertEncoded, ref->context->cert.cbCertEncoded); ref->context->cert.pbCertEncoded, ref->context->cert.cbCertEncoded);
if (cert) if (cert)
{ {
PWINE_CERT_PROPERTY prop; DWORD prop = 0, bufSize = 0;
LPBYTE buf = NULL;
ret = TRUE; ret = TRUE;
EnterCriticalSection(&ref->context->cs); EnterCriticalSection(&ref->context->cs);
LIST_FOR_EACH_ENTRY(prop, &ref->context->extendedProperties, do {
WINE_CERT_PROPERTY, entry) prop = CertEnumCertificateContextProperties((PCCERT_CONTEXT)ref,
{ prop);
ret = CRYPT_SaveCertificateContextProperty(cert, prop->hdr.propID, if (prop)
prop->pbData, prop->hdr.cb); {
if (!ret) DWORD propSize = 0;
break;
} ret = CertGetCertificateContextProperty(pCertContext, prop,
NULL, &propSize);
if (ret)
{
if (bufSize < propSize)
{
if (buf)
buf = CryptMemRealloc(buf, propSize);
else
buf = CryptMemAlloc(propSize);
bufSize = propSize;
}
if (buf)
{
ret = CertGetCertificateContextProperty(pCertContext,
prop, buf, &propSize);
if (ret)
ret = CRYPT_SaveCertificateContextProperty(cert,
prop, buf, bufSize);
}
else
ret = FALSE;
}
}
} while (ret && prop != 0);
CryptMemFree(buf);
LeaveCriticalSection(&ref->context->cs); LeaveCriticalSection(&ref->context->cs);
if (ret) if (ret)
{ {
@ -2739,12 +2763,24 @@ BOOL WINAPI CertSerializeCertificateStoreElement(PCCERT_CONTEXT pCertContext,
PWINE_CERT_CONTEXT_REF ref = (PWINE_CERT_CONTEXT_REF)pCertContext; PWINE_CERT_CONTEXT_REF ref = (PWINE_CERT_CONTEXT_REF)pCertContext;
DWORD bytesNeeded = sizeof(WINE_CERT_PROP_HEADER) + DWORD bytesNeeded = sizeof(WINE_CERT_PROP_HEADER) +
pCertContext->cbCertEncoded; pCertContext->cbCertEncoded;
PWINE_CERT_PROPERTY prop; DWORD prop = 0;
EnterCriticalSection(&ref->context->cs); EnterCriticalSection(&ref->context->cs);
LIST_FOR_EACH_ENTRY(prop, &ref->context->extendedProperties,
WINE_CERT_PROPERTY, entry) ret = TRUE;
bytesNeeded += sizeof(WINE_CERT_PROP_HEADER) + prop->hdr.cb; do {
prop = CertEnumCertificateContextProperties(pCertContext, prop);
if (prop)
{
DWORD propSize = 0;
ret = CertGetCertificateContextProperty(pCertContext,
prop, NULL, &propSize);
if (ret)
bytesNeeded += sizeof(WINE_CERT_PROP_HEADER) + propSize;
}
} while (ret && prop != 0);
if (!pbElement) if (!pbElement)
{ {
*pcbElement = bytesNeeded; *pcbElement = bytesNeeded;
@ -2759,25 +2795,59 @@ BOOL WINAPI CertSerializeCertificateStoreElement(PCCERT_CONTEXT pCertContext,
else else
{ {
PWINE_CERT_PROP_HEADER hdr; PWINE_CERT_PROP_HEADER hdr;
DWORD bufSize = 0;
LPBYTE buf = NULL;
LIST_FOR_EACH_ENTRY(prop, &ref->context->extendedProperties, prop = 0;
WINE_CERT_PROPERTY, entry) do {
{ prop = CertEnumCertificateContextProperties(pCertContext, prop);
memcpy(pbElement, &prop->hdr, sizeof(WINE_CERT_PROP_HEADER)); if (prop)
pbElement += sizeof(WINE_CERT_PROP_HEADER);
if (prop->hdr.cb)
{ {
memcpy(pbElement, prop->pbData, prop->hdr.cb); DWORD propSize = 0;
pbElement += prop->hdr.cb;
ret = CertGetCertificateContextProperty(pCertContext,
prop, NULL, &propSize);
if (ret)
{
if (bufSize < propSize)
{
if (buf)
buf = CryptMemRealloc(buf, propSize);
else
buf = CryptMemAlloc(propSize);
bufSize = propSize;
}
if (buf)
{
ret = CertGetCertificateContextProperty(
pCertContext, prop, buf, &propSize);
if (ret)
{
hdr = (PWINE_CERT_PROP_HEADER)pbElement;
hdr->propID = prop;
hdr->unknown = 1;
hdr->cb = propSize;
pbElement += sizeof(WINE_CERT_PROP_HEADER);
if (propSize)
{
memcpy(pbElement, buf, propSize);
pbElement += propSize;
}
}
}
else
ret = FALSE;
}
} }
} } while (ret && prop != 0);
CryptMemFree(buf);
hdr = (PWINE_CERT_PROP_HEADER)pbElement; hdr = (PWINE_CERT_PROP_HEADER)pbElement;
hdr->propID = CERT_CERT_PROP_ID; hdr->propID = CERT_CERT_PROP_ID;
hdr->unknown = 1; hdr->unknown = 1;
hdr->cb = pCertContext->cbCertEncoded; hdr->cb = pCertContext->cbCertEncoded;
memcpy(pbElement + sizeof(WINE_CERT_PROP_HEADER), memcpy(pbElement + sizeof(WINE_CERT_PROP_HEADER),
pCertContext->pbCertEncoded, pCertContext->cbCertEncoded); pCertContext->pbCertEncoded, pCertContext->cbCertEncoded);
ret = TRUE;
} }
LeaveCriticalSection(&ref->context->cs); LeaveCriticalSection(&ref->context->cs);
} }