crypt32: Move context properties to a separate file.
diff --git a/dlls/crypt32/Makefile.in b/dlls/crypt32/Makefile.in
index 9338b31..e107292 100644
--- a/dlls/crypt32/Makefile.in
+++ b/dlls/crypt32/Makefile.in
@@ -11,6 +11,7 @@
cert.c \
encode.c \
oid.c \
+ proplist.c \
protectdata.c \
serialize.c \
store.c \
diff --git a/dlls/crypt32/crypt32_private.h b/dlls/crypt32/crypt32_private.h
index ee0228c..25c41e4 100644
--- a/dlls/crypt32/crypt32_private.h
+++ b/dlls/crypt32/crypt32_private.h
@@ -41,4 +41,31 @@
const void *CRYPT_ReadSerializedElement(const BYTE *pbElement,
DWORD cbElement, DWORD dwContextTypeFlags, DWORD *pdwContentType);
+/**
+ * Context property list functions
+ */
+struct _CONTEXT_PROPERTY_LIST;
+typedef struct _CONTEXT_PROPERTY_LIST *PCONTEXT_PROPERTY_LIST;
+
+PCONTEXT_PROPERTY_LIST ContextPropertyList_Create(void);
+
+/* 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,
+ PCRYPT_DATA_BLOB blob);
+
+BOOL ContextPropertyList_SetProperty(PCONTEXT_PROPERTY_LIST list, DWORD id,
+ const BYTE *pbData, size_t cbData);
+
+void ContextPropertyList_RemoveProperty(PCONTEXT_PROPERTY_LIST list, DWORD id);
+
+DWORD ContextPropertyList_EnumPropIDs(PCONTEXT_PROPERTY_LIST list, DWORD id);
+
+void ContextPropertyList_Copy(PCONTEXT_PROPERTY_LIST to,
+ PCONTEXT_PROPERTY_LIST from);
+
+void ContextPropertyList_Free(PCONTEXT_PROPERTY_LIST list);
+
#endif
diff --git a/dlls/crypt32/proplist.c b/dlls/crypt32/proplist.c
new file mode 100644
index 0000000..ec9e242
--- /dev/null
+++ b/dlls/crypt32/proplist.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2004-2006 Juan Lang
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <assert.h>
+#include <stdarg.h>
+#include "windef.h"
+#include "winbase.h"
+#include "wincrypt.h"
+#include "wine/debug.h"
+#include "wine/list.h"
+#include "crypt32_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(crypt);
+
+typedef struct _CONTEXT_PROPERTY_LIST
+{
+ CRITICAL_SECTION cs;
+ struct list properties;
+} CONTEXT_PROPERTY_LIST;
+
+typedef struct _CONTEXT_PROPERTY
+{
+ DWORD propID;
+ DWORD cbData;
+ LPBYTE pbData;
+ struct list entry;
+} CONTEXT_PROPERTY, *PCONTEXT_PROPERTY;
+
+PCONTEXT_PROPERTY_LIST ContextPropertyList_Create(void)
+{
+ PCONTEXT_PROPERTY_LIST list = CryptMemAlloc(sizeof(CONTEXT_PROPERTY_LIST));
+
+ if (list)
+ {
+ InitializeCriticalSection(&list->cs);
+ list_init(&list->properties);
+ }
+ return list;
+}
+
+void ContextPropertyList_Free(PCONTEXT_PROPERTY_LIST list)
+{
+ PCONTEXT_PROPERTY prop, next;
+
+ LIST_FOR_EACH_ENTRY_SAFE(prop, next, &list->properties, CONTEXT_PROPERTY,
+ entry)
+ {
+ list_remove(&prop->entry);
+ CryptMemFree(prop->pbData);
+ CryptMemFree(prop);
+ }
+ DeleteCriticalSection(&list->cs);
+ CryptMemFree(list);
+}
+
+BOOL ContextPropertyList_FindProperty(PCONTEXT_PROPERTY_LIST list, DWORD id,
+ PCRYPT_DATA_BLOB blob)
+{
+ PCONTEXT_PROPERTY prop;
+ BOOL ret = FALSE;
+
+ TRACE("(%p, %ld, %p)\n", list, id, blob);
+
+ EnterCriticalSection(&list->cs);
+ LIST_FOR_EACH_ENTRY(prop, &list->properties, CONTEXT_PROPERTY, entry)
+ {
+ if (prop->propID == id)
+ {
+ blob->cbData = prop->cbData;
+ blob->pbData = prop->pbData;
+ ret = TRUE;
+ break;
+ }
+ }
+ LeaveCriticalSection(&list->cs);
+ return ret;
+}
+
+BOOL ContextPropertyList_SetProperty(PCONTEXT_PROPERTY_LIST list, DWORD id,
+ const BYTE *pbData, size_t cbData)
+{
+ LPBYTE data;
+ BOOL ret = FALSE;
+
+ if (cbData)
+ {
+ data = CryptMemAlloc(cbData);
+ if (data)
+ memcpy(data, pbData, cbData);
+ }
+ else
+ data = NULL;
+ if (!cbData || data)
+ {
+ PCONTEXT_PROPERTY prop;
+ BOOL found = FALSE;
+
+ EnterCriticalSection(&list->cs);
+ LIST_FOR_EACH_ENTRY(prop, &list->properties, CONTEXT_PROPERTY, entry)
+ {
+ if (prop->propID == id)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ if (found)
+ {
+ CryptMemFree(prop->pbData);
+ prop->cbData = cbData;
+ prop->pbData = data;
+ ret = TRUE;
+ }
+ else
+ {
+ prop = CryptMemAlloc(sizeof(CONTEXT_PROPERTY));
+ if (prop)
+ {
+ prop->propID = id;
+ prop->cbData = cbData;
+ list_init(&prop->entry);
+ prop->pbData = data;
+ list_add_tail(&list->properties, &prop->entry);
+ ret = TRUE;
+ }
+ else
+ CryptMemFree(data);
+ }
+ LeaveCriticalSection(&list->cs);
+ }
+ return ret;
+}
+
+void ContextPropertyList_RemoveProperty(PCONTEXT_PROPERTY_LIST list, DWORD id)
+{
+ PCONTEXT_PROPERTY prop, next;
+
+ EnterCriticalSection(&list->cs);
+ LIST_FOR_EACH_ENTRY_SAFE(prop, next, &list->properties, CONTEXT_PROPERTY,
+ entry)
+ {
+ if (prop->propID == id)
+ {
+ list_remove(&prop->entry);
+ CryptMemFree(prop->pbData);
+ CryptMemFree(prop);
+ }
+ }
+ LeaveCriticalSection(&list->cs);
+}
+
+/* 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 ret;
+
+ EnterCriticalSection(&list->cs);
+ if (id)
+ {
+ PCONTEXT_PROPERTY cursor = NULL;
+
+ LIST_FOR_EACH_ENTRY(cursor, &list->properties, CONTEXT_PROPERTY, entry)
+ {
+ if (cursor->propID == id)
+ break;
+ }
+ if (cursor)
+ {
+ if (cursor->entry.next != &list->properties)
+ ret = LIST_ENTRY(cursor->entry.next, CONTEXT_PROPERTY,
+ entry)->propID;
+ else
+ ret = 0;
+ }
+ else
+ ret = 0;
+ }
+ else if (!list_empty(&list->properties))
+ ret = LIST_ENTRY(list->properties.next, CONTEXT_PROPERTY,
+ entry)->propID;
+ else
+ ret = 0;
+ LeaveCriticalSection(&list->cs);
+ return ret;
+}
+
+void ContextPropertyList_Copy(PCONTEXT_PROPERTY_LIST to,
+ PCONTEXT_PROPERTY_LIST from)
+{
+ PCONTEXT_PROPERTY prop;
+
+ EnterCriticalSection(&from->cs);
+ LIST_FOR_EACH_ENTRY(prop, &from->properties, CONTEXT_PROPERTY, entry)
+ {
+ ContextPropertyList_SetProperty(to, prop->propID, prop->pbData,
+ prop->cbData);
+ }
+ LeaveCriticalSection(&from->cs);
+}
diff --git a/dlls/crypt32/store.c b/dlls/crypt32/store.c
index fe37a56..92f3ee6 100644
--- a/dlls/crypt32/store.c
+++ b/dlls/crypt32/store.c
@@ -182,27 +182,19 @@
*/
typedef struct _WINE_CERT_CONTEXT
{
- CERT_CONTEXT cert;
- LONG ref;
- CRITICAL_SECTION cs;
- struct list extendedProperties;
+ CERT_CONTEXT cert;
+ LONG ref;
+ PCONTEXT_PROPERTY_LIST properties;
} WINE_CERT_CONTEXT, *PWINE_CERT_CONTEXT;
+typedef const struct _WINE_CERT_CONTEXT PCWINE_CERT_CONTEXT;
typedef struct _WINE_CERT_CONTEXT_REF
{
CERT_CONTEXT cert;
LONG ref;
- WINE_CERT_CONTEXT *context;
+ PWINE_CERT_CONTEXT context;
} WINE_CERT_CONTEXT_REF, *PWINE_CERT_CONTEXT_REF;
-
-/* Stores an extended property in a cert. */
-typedef struct _WINE_CERT_PROPERTY
-{
- DWORD propID;
- DWORD cbData;
- LPBYTE pbData;
- struct list entry;
-} WINE_CERT_PROPERTY, *PWINE_CERT_PROPERTY;
+typedef const struct _WINE_CERT_CONTEXT_REF PCWINE_CERT_CONTEXT_REF;
/* A mem store has a list of these. They're also returned by the mem store
* during enumeration.
@@ -554,7 +546,6 @@
store->hdr.addCert = CRYPT_MemAddCert;
store->hdr.enumCert = CRYPT_MemEnumCert;
store->hdr.deleteCert = CRYPT_MemDeleteCert;
- store->hdr.freeCert = NULL;
store->hdr.control = NULL;
InitializeCriticalSection(&store->cs);
list_init(&store->certs);
@@ -1905,8 +1896,7 @@
cert->cert.pCertInfo = certInfo;
cert->cert.hCertStore = 0;
cert->ref = 0;
- InitializeCriticalSection(&cert->cs);
- list_init(&cert->extendedProperties);
+ cert->properties = ContextPropertyList_Create();
}
end:
@@ -1915,18 +1905,9 @@
static void CRYPT_FreeCert(PWINE_CERT_CONTEXT context)
{
- PWINE_CERT_PROPERTY prop, next;
-
CryptMemFree(context->cert.pbCertEncoded);
LocalFree(context->cert.pCertInfo);
- DeleteCriticalSection(&context->cs);
- LIST_FOR_EACH_ENTRY_SAFE(prop, next, &context->extendedProperties,
- WINE_CERT_PROPERTY, entry)
- {
- list_remove(&prop->entry);
- CryptMemFree(prop->pbData);
- CryptMemFree(prop);
- }
+ ContextPropertyList_Free(context->properties);
CryptMemFree(context);
}
@@ -1946,46 +1927,14 @@
return (PCCERT_CONTEXT)ret;
}
-/* 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 WINAPI CertEnumCertificateContextProperties(PCCERT_CONTEXT pCertContext,
DWORD dwPropId)
{
PWINE_CERT_CONTEXT_REF ref = (PWINE_CERT_CONTEXT_REF)pCertContext;
- DWORD ret;
TRACE("(%p, %ld)\n", pCertContext, dwPropId);
- EnterCriticalSection(&ref->context->cs);
- if (dwPropId)
- {
- PWINE_CERT_PROPERTY cursor = NULL;
-
- LIST_FOR_EACH_ENTRY(cursor, &ref->context->extendedProperties,
- WINE_CERT_PROPERTY, entry)
- {
- if (cursor->propID == dwPropId)
- break;
- }
- if (cursor)
- {
- if (cursor->entry.next != &ref->context->extendedProperties)
- ret = LIST_ENTRY(cursor->entry.next, WINE_CERT_PROPERTY,
- entry)->propID;
- else
- ret = 0;
- }
- else
- ret = 0;
- }
- else if (!list_empty(&ref->context->extendedProperties))
- ret = LIST_ENTRY(ref->context->extendedProperties.next,
- WINE_CERT_PROPERTY, entry)->propID;
- else
- ret = 0;
- LeaveCriticalSection(&ref->context->cs);
- return ret;
+ return ContextPropertyList_EnumPropIDs(ref->context->properties, dwPropId);
}
static BOOL CRYPT_GetCertHashProp(PWINE_CERT_CONTEXT context, DWORD dwPropId,
@@ -2007,40 +1956,33 @@
static BOOL WINAPI CRYPT_GetCertificateContextProperty(
PWINE_CERT_CONTEXT context, DWORD dwPropId, void *pvData, DWORD *pcbData)
{
- PWINE_CERT_PROPERTY prop;
- BOOL ret, found;
+ BOOL ret;
+ CRYPT_DATA_BLOB blob;
TRACE("(%p, %ld, %p, %p)\n", context, dwPropId, pvData, pcbData);
- EnterCriticalSection(&context->cs);
- ret = FALSE;
- found = FALSE;
- LIST_FOR_EACH_ENTRY(prop, &context->extendedProperties,
- WINE_CERT_PROPERTY, entry)
+ ret = ContextPropertyList_FindProperty(context->properties, dwPropId,
+ &blob);
+ if (ret)
{
- if (prop->propID == dwPropId)
+ if (!pvData)
{
- if (!pvData)
- {
- *pcbData = prop->cbData;
- ret = TRUE;
- }
- else if (*pcbData < prop->cbData)
- {
- SetLastError(ERROR_MORE_DATA);
- *pcbData = prop->cbData;
- }
- else
- {
- memcpy(pvData, prop->pbData, prop->cbData);
- *pcbData = prop->cbData;
- ret = TRUE;
- }
- found = TRUE;
- break;
+ *pcbData = blob.cbData;
+ ret = TRUE;
+ }
+ else if (*pcbData < blob.cbData)
+ {
+ SetLastError(ERROR_MORE_DATA);
+ *pcbData = blob.cbData;
+ }
+ else
+ {
+ memcpy(pvData, blob.pbData, blob.cbData);
+ *pcbData = blob.cbData;
+ ret = TRUE;
}
}
- if (!found)
+ else
{
/* Implicit properties */
switch (dwPropId)
@@ -2076,7 +2018,6 @@
SetLastError(CRYPT_E_NOT_FOUND);
}
}
- LeaveCriticalSection(&context->cs);
TRACE("returning %d\n", ret);
return ret;
}
@@ -2134,65 +2075,6 @@
return ret;
}
-/* Copies cbData bytes from pbData to the context's property with ID
- * dwPropId.
- */
-static BOOL CRYPT_SaveCertificateContextProperty(PWINE_CERT_CONTEXT context,
- DWORD dwPropId, const BYTE *pbData, size_t cbData)
-{
- BOOL ret = FALSE;
- LPBYTE data;
-
- if (cbData)
- {
- data = CryptMemAlloc(cbData);
- if (data)
- memcpy(data, pbData, cbData);
- }
- else
- data = NULL;
- if (!cbData || data)
- {
- PWINE_CERT_PROPERTY prop;
- BOOL found = FALSE;
-
- EnterCriticalSection(&context->cs);
- LIST_FOR_EACH_ENTRY(prop, &context->extendedProperties,
- WINE_CERT_PROPERTY, entry)
- {
- if (prop->propID == dwPropId)
- {
- found = TRUE;
- break;
- }
- }
- if (found)
- {
- CryptMemFree(prop->pbData);
- prop->cbData = cbData;
- prop->pbData = data;
- ret = TRUE;
- }
- else
- {
- prop = CryptMemAlloc(sizeof(WINE_CERT_PROPERTY));
- if (prop)
- {
- prop->propID = dwPropId;
- prop->cbData = cbData;
- list_init(&prop->entry);
- prop->pbData = data;
- list_add_tail(&context->extendedProperties, &prop->entry);
- ret = TRUE;
- }
- else
- CryptMemFree(data);
- }
- LeaveCriticalSection(&context->cs);
- }
- return ret;
-}
-
static BOOL WINAPI CRYPT_SetCertificateContextProperty(
PWINE_CERT_CONTEXT context, DWORD dwPropId, DWORD dwFlags, const void *pvData)
{
@@ -2202,20 +2084,7 @@
if (!pvData)
{
- PWINE_CERT_PROPERTY prop, next;
-
- EnterCriticalSection(&context->cs);
- LIST_FOR_EACH_ENTRY_SAFE(prop, next, &context->extendedProperties,
- WINE_CERT_PROPERTY, entry)
- {
- if (prop->propID == dwPropId)
- {
- list_remove(&prop->entry);
- CryptMemFree(prop->pbData);
- CryptMemFree(prop);
- }
- }
- LeaveCriticalSection(&context->cs);
+ ContextPropertyList_RemoveProperty(context->properties, dwPropId);
ret = TRUE;
}
else
@@ -2242,12 +2111,12 @@
{
PCRYPT_DATA_BLOB blob = (PCRYPT_DATA_BLOB)pvData;
- ret = CRYPT_SaveCertificateContextProperty(context, dwPropId,
+ ret = ContextPropertyList_SetProperty(context->properties, dwPropId,
blob->pbData, blob->cbData);
break;
}
case CERT_DATE_STAMP_PROP_ID:
- ret = CRYPT_SaveCertificateContextProperty(context, dwPropId,
+ ret = ContextPropertyList_SetProperty(context->properties, dwPropId,
pvData, sizeof(FILETIME));
break;
default:
@@ -2319,51 +2188,12 @@
return FALSE;
}
- cert = CRYPT_CreateCertificateContext(ref->context->cert.dwCertEncodingType,
- ref->context->cert.pbCertEncoded, ref->context->cert.cbCertEncoded);
+ cert = CRYPT_CreateCertificateContext(ref->cert.dwCertEncodingType,
+ ref->cert.pbCertEncoded, ref->cert.cbCertEncoded);
if (cert)
{
- DWORD prop = 0, bufSize = 0;
- LPBYTE buf = NULL;
-
- ret = TRUE;
- EnterCriticalSection(&ref->context->cs);
- do {
- prop = CertEnumCertificateContextProperties((PCCERT_CONTEXT)ref,
- prop);
- if (prop)
- {
- DWORD propSize = 0;
-
- 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);
- if (ret)
- ret = store->addCert(store, cert, dwAddDisposition, ppStoreContext);
+ ContextPropertyList_Copy(cert->properties, ref->context->properties);
+ ret = store->addCert(store, cert, dwAddDisposition, ppStoreContext);
if (!ret)
CRYPT_FreeCert(cert);
}