CONTEXT_STORE certs;
CONTEXT_STORE crls;
PFN_CERT_STORE_PROV_CONTROL control; /* optional */
+ PCONTEXT_PROPERTY_LIST properties;
} WINECRYPT_CERTSTORE, *PWINECRYPT_CERTSTORE;
typedef struct _WINE_MEMSTORE
}
store->cryptProv = hCryptProv;
store->dwOpenFlags = dwFlags;
+ store->properties = NULL;
+}
+
+static void CRYPT_FreeStore(PWINECRYPT_CERTSTORE store)
+{
+ if (store->properties)
+ ContextPropertyList_Free(store->properties);
+ CryptMemFree(store);
}
static BOOL CRYPT_MemAddCert(PWINECRYPT_CERTSTORE store, void *cert,
ContextList_Free(store->certs);
ContextList_Free(store->crls);
- CryptMemFree(store);
+ CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
}
static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv,
}
cs->cs.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&cs->cs);
- CryptMemFree(cs);
+ CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
}
static void *CRYPT_CollectionCreateContextFromChild(PWINE_COLLECTIONSTORE store,
store->provCloseStore(store->hStoreProv, dwFlags);
if (!(store->dwStoreProvFlags & CERT_STORE_PROV_EXTERNAL_FLAG))
CertCloseStore(store->memStore, dwFlags);
- CryptMemFree(store);
+ CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
}
static BOOL CRYPT_ProvAddCert(PWINECRYPT_CERTSTORE store, void *cert,
return ret;
}
+BOOL WINAPI CertGetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
+ void *pvData, DWORD *pcbData)
+{
+ PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
+ BOOL ret = FALSE;
+
+ TRACE("(%p, %d, %p, %p)\n", hCertStore, dwPropId, pvData, pcbData);
+
+ switch (dwPropId)
+ {
+ case CERT_ACCESS_STATE_PROP_ID:
+ if (!pvData)
+ {
+ *pcbData = sizeof(DWORD);
+ ret = TRUE;
+ }
+ else if (*pcbData < sizeof(DWORD))
+ {
+ SetLastError(ERROR_MORE_DATA);
+ *pcbData = sizeof(DWORD);
+ }
+ else
+ {
+ *(DWORD *)pvData = CertStore_GetAccessState(hCertStore);
+ ret = TRUE;
+ }
+ break;
+ default:
+ if (store->properties)
+ {
+ CRYPT_DATA_BLOB blob;
+
+ ret = ContextPropertyList_FindProperty(store->properties, dwPropId,
+ &blob);
+ if (ret)
+ {
+ if (!pvData)
+ *pcbData = blob.cbData;
+ else if (*pcbData < blob.cbData)
+ {
+ SetLastError(ERROR_MORE_DATA);
+ *pcbData = blob.cbData;
+ ret = FALSE;
+ }
+ else
+ {
+ memcpy(pvData, blob.pbData, blob.cbData);
+ *pcbData = blob.cbData;
+ }
+ }
+ else
+ SetLastError(CRYPT_E_NOT_FOUND);
+ }
+ else
+ SetLastError(CRYPT_E_NOT_FOUND);
+ }
+ return ret;
+}
+
+BOOL WINAPI CertSetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
+ DWORD dwFlags, const void *pvData)
+{
+ PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
+ BOOL ret = FALSE;
+
+ TRACE("(%p, %d, %08x, %p)\n", hCertStore, dwPropId, dwFlags, pvData);
+
+ if (!store->properties)
+ store->properties = ContextPropertyList_Create();
+ switch (dwPropId)
+ {
+ case CERT_ACCESS_STATE_PROP_ID:
+ SetLastError(E_INVALIDARG);
+ break;
+ default:
+ if (pvData)
+ {
+ const CRYPT_DATA_BLOB *blob = (const CRYPT_DATA_BLOB *)pvData;
+
+ ret = ContextPropertyList_SetProperty(store->properties, dwPropId,
+ blob->pbData, blob->cbData);
+ }
+ else
+ {
+ ContextPropertyList_RemoveProperty(store->properties, dwPropId);
+ ret = TRUE;
+ }
+ }
+ return ret;
+}
+
DWORD WINAPI CertEnumCTLContextProperties(PCCTL_CONTEXT pCTLContext,
DWORD dwPropId)
{
"Expected at least 3 stores\n");
}
+static void testStoreProperty(void)
+{
+ HCERTSTORE store;
+ BOOL ret;
+ DWORD propID, size = 0, state;
+ CRYPT_DATA_BLOB blob;
+
+ /* Crash
+ ret = CertGetStoreProperty(NULL, 0, NULL, NULL);
+ ret = CertGetStoreProperty(NULL, 0, NULL, &size);
+ ret = CertGetStoreProperty(store, 0, NULL, NULL);
+ */
+
+ store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
+ CERT_STORE_CREATE_NEW_FLAG, NULL);
+ /* Check a missing prop ID */
+ SetLastError(0xdeadbeef);
+ ret = CertGetStoreProperty(store, 0, NULL, &size);
+ ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
+ "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
+ /* Contrary to MSDN, CERT_ACCESS_STATE_PROP_ID is supported for stores.. */
+ size = sizeof(state);
+ ret = CertGetStoreProperty(store, CERT_ACCESS_STATE_PROP_ID, &state, &size);
+ ok(ret, "CertGetStoreProperty failed for CERT_ACCESS_STATE_PROP_ID: %08x\n",
+ GetLastError());
+ ok(!state, "Expected a non-persisted store\n");
+ /* and CERT_STORE_LOCALIZED_NAME_PROP_ID isn't supported by default. */
+ size = 0;
+ ret = CertGetStoreProperty(store, CERT_STORE_LOCALIZED_NAME_PROP_ID, NULL,
+ &size);
+ ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
+ "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
+ /* Delete an arbitrary property on a store */
+ ret = CertSetStoreProperty(store, CERT_FIRST_USER_PROP_ID, 0, NULL);
+ ok(ret, "CertSetStoreProperty failed: %08x\n", GetLastError());
+ /* Set an arbitrary property on a store */
+ blob.pbData = (LPBYTE)&state;
+ blob.cbData = sizeof(state);
+ ret = CertSetStoreProperty(store, CERT_FIRST_USER_PROP_ID, 0, &blob);
+ ok(ret, "CertSetStoreProperty failed: %08x\n", GetLastError());
+ /* Get an arbitrary property that's been set */
+ ret = CertGetStoreProperty(store, CERT_FIRST_USER_PROP_ID, NULL, &size);
+ ok(ret, "CertGetStoreProperty failed: %08x\n", GetLastError());
+ ok(size == sizeof(state), "Unexpected data size %d\n", size);
+ ret = CertGetStoreProperty(store, CERT_FIRST_USER_PROP_ID, &propID, &size);
+ ok(ret, "CertGetStoreProperty failed: %08x\n", GetLastError());
+ ok(propID == state, "CertGetStoreProperty got the wrong value\n");
+ /* Delete it again */
+ ret = CertSetStoreProperty(store, CERT_FIRST_USER_PROP_ID, 0, NULL);
+ ok(ret, "CertSetStoreProperty failed: %08x\n", GetLastError());
+ /* And check that it's missing */
+ SetLastError(0xdeadbeef);
+ ret = CertGetStoreProperty(store, CERT_FIRST_USER_PROP_ID, NULL, &size);
+ ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
+ "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
+ CertCloseStore(store, 0);
+
+ /* Recheck on the My store.. */
+ store = CertOpenSystemStoreW(0, MyW);
+ size = sizeof(state);
+ ret = CertGetStoreProperty(store, CERT_ACCESS_STATE_PROP_ID, &state, &size);
+ ok(ret, "CertGetStoreProperty failed for CERT_ACCESS_STATE_PROP_ID: %08x\n",
+ GetLastError());
+ ok(state, "Expected a persisted store\n");
+ SetLastError(0xdeadbeef);
+ size = 0;
+ ret = CertGetStoreProperty(store, CERT_STORE_LOCALIZED_NAME_PROP_ID, NULL,
+ &size);
+ ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
+ "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
+ CertCloseStore(store, 0);
+}
+
static void testAddSerialized(void)
{
BOOL ret;
testCertOpenSystemStore();
testCertEnumSystemStore();
+ testStoreProperty();
testAddSerialized();
}