crypt32: Implement CertGetStoreProperty and CertSetStoreProperty.
This commit is contained in:
parent
0170a41e69
commit
4c6988e8f0
|
@ -59,6 +59,7 @@
|
|||
@ stdcall CertGetNameStringA(ptr long long ptr ptr long)
|
||||
@ stdcall CertGetNameStringW(ptr long long ptr ptr long)
|
||||
@ stdcall CertGetPublicKeyLength(long ptr)
|
||||
@ stdcall CertGetStoreProperty(long long ptr ptr)
|
||||
@ stdcall CertGetSubjectCertificateFromStore(ptr long ptr)
|
||||
@ stdcall CertGetValidUsages(long ptr ptr ptr ptr)
|
||||
@ stub CertIsRDNAttrsInCertificateName
|
||||
|
@ -81,6 +82,7 @@
|
|||
@ stdcall CertSetCTLContextProperty(ptr long long ptr)
|
||||
@ stdcall CertSetCertificateContextProperty(ptr long long ptr)
|
||||
@ stdcall CertSetEnhancedKeyUsage(ptr ptr)
|
||||
@ stdcall CertSetStoreProperty(ptr long long ptr)
|
||||
@ stdcall CertStrToNameA(long str long ptr ptr ptr ptr)
|
||||
@ stdcall CertStrToNameW(long wstr long ptr ptr ptr ptr)
|
||||
@ stdcall CertVerifyCRLRevocation(long ptr long ptr)
|
||||
|
|
|
@ -138,6 +138,7 @@ typedef struct WINE_CRYPTCERTSTORE
|
|||
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
|
||||
|
@ -216,6 +217,14 @@ static void CRYPT_InitStore(WINECRYPT_CERTSTORE *store, HCRYPTPROV hCryptProv,
|
|||
}
|
||||
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,
|
||||
|
@ -316,7 +325,7 @@ static void WINAPI CRYPT_MemCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
|
|||
|
||||
ContextList_Free(store->certs);
|
||||
ContextList_Free(store->crls);
|
||||
CryptMemFree(store);
|
||||
CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
|
||||
}
|
||||
|
||||
static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv,
|
||||
|
@ -371,7 +380,7 @@ static void WINAPI CRYPT_CollectionCloseStore(HCERTSTORE store, DWORD dwFlags)
|
|||
}
|
||||
cs->cs.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&cs->cs);
|
||||
CryptMemFree(cs);
|
||||
CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
|
||||
}
|
||||
|
||||
static void *CRYPT_CollectionCreateContextFromChild(PWINE_COLLECTIONSTORE store,
|
||||
|
@ -692,7 +701,7 @@ static void WINAPI CRYPT_ProvCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
|
|||
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,
|
||||
|
@ -2476,6 +2485,97 @@ BOOL WINAPI CertControlStore(HCERTSTORE hCertStore, DWORD dwFlags,
|
|||
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)
|
||||
{
|
||||
|
|
|
@ -1426,6 +1426,79 @@ static void testCertEnumSystemStore(void)
|
|||
"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;
|
||||
|
@ -1593,6 +1666,7 @@ START_TEST(store)
|
|||
|
||||
testCertOpenSystemStore();
|
||||
testCertEnumSystemStore();
|
||||
testStoreProperty();
|
||||
|
||||
testAddSerialized();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue