crypt32/tests: Test CertAddCertificateLinkToStore.

oldstable
Juan Lang 2010-05-14 15:43:12 -07:00 committed by Alexandre Julliard
parent c232af490e
commit 0dfb0299f6
1 changed files with 357 additions and 0 deletions

View File

@ -2063,6 +2063,362 @@ static void testAddSerialized(void)
CertCloseStore(store, 0);
}
static void compareStore(HCERTSTORE store, LPCSTR name, const BYTE *pb,
DWORD cb)
{
BOOL ret;
CRYPT_DATA_BLOB blob = { 0, NULL };
ret = CertSaveStore(store, X509_ASN_ENCODING, CERT_STORE_SAVE_AS_STORE,
CERT_STORE_SAVE_TO_MEMORY, &blob, 0);
ok(blob.cbData == cb, "%s: expected size %d, got %d\n", name, cb,
blob.cbData);
blob.pbData = HeapAlloc(GetProcessHeap(), 0, blob.cbData);
if (blob.pbData)
{
ret = CertSaveStore(store, X509_ASN_ENCODING, CERT_STORE_SAVE_AS_STORE,
CERT_STORE_SAVE_TO_MEMORY, &blob, 0);
ok(ret, "CertSaveStore failed: %08x\n", GetLastError());
ok(!memcmp(pb, blob.pbData, cb), "%s: unexpected value\n", name);
HeapFree(GetProcessHeap(), 0, blob.pbData);
}
}
static const BYTE serializedCertWithFriendlyName[] = {
0x0b,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x57,0x00,0x69,
0x00,0x6e,0x00,0x65,0x00,0x54,0x00,0x65,0x00,0x73,0x00,0x74,0x00,0x00,0x00,
0x20,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x30,0x7a,0x02,
0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,
0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,
0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
0x01 };
static const BYTE serializedStoreWithCertWithFriendlyName[] = {
0x00,0x00,0x00,0x00,0x43,0x45,0x52,0x54,0x0b,0x00,0x00,0x00,0x01,0x00,0x00,
0x00,0x12,0x00,0x00,0x00,0x57,0x00,0x69,0x00,0x6e,0x00,0x65,0x00,0x54,0x00,
0x65,0x00,0x73,0x00,0x74,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x01,0x00,0x00,
0x00,0x7c,0x00,0x00,0x00,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,
0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,
0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00 };
static const BYTE serializedStoreWithCertAndHash[] = {
0x00,0x00,0x00,0x00,0x43,0x45,0x52,0x54,0x03,0x00,0x00,0x00,0x01,0x00,0x00,
0x00,0x14,0x00,0x00,0x00,0x6e,0x30,0x90,0x71,0x5f,0xd9,0x23,0x56,0xeb,0xae,
0x25,0x40,0xe6,0x22,0xda,0x19,0x26,0x02,0xa6,0x08,0x20,0x00,0x00,0x00,0x01,
0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,
0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,
0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
static void testAddCertificateLink(void)
{
BOOL ret;
HCERTSTORE store1, store2;
PCCERT_CONTEXT source, linked;
DWORD size;
LPBYTE buf;
CERT_NAME_BLOB blob;
static const WCHAR szPrefix[] = { 'c','e','r',0 };
static const WCHAR szDot[] = { '.',0 };
static const WCHAR WineTestW[] = { 'W','i','n','e','T','e','s','t',0 };
WCHAR filename1[MAX_PATH], filename2[MAX_PATH];
HANDLE file;
if (0)
{
/* Crashes, i.e. the store is dereferenced without checking. */
ret = CertAddCertificateLinkToStore(NULL, NULL, 0, NULL);
}
/* Adding a certificate link to a store requires a valid add disposition */
store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
CERT_STORE_CREATE_NEW_FLAG, NULL);
SetLastError(0xdeadbeef);
ret = CertAddCertificateLinkToStore(store1, NULL, 0, NULL);
todo_wine
ok(!ret && GetLastError() == E_INVALIDARG,
"expected E_INVALIDARG, got %08x\n", GetLastError());
source = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
sizeof(bigCert));
SetLastError(0xdeadbeef);
ret = CertAddCertificateLinkToStore(store1, source, 0, NULL);
todo_wine
ok(!ret && GetLastError() == E_INVALIDARG,
"expected E_INVALIDARG, got %08x\n", GetLastError());
ret = CertAddCertificateLinkToStore(store1, source, CERT_STORE_ADD_ALWAYS,
NULL);
todo_wine
ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError());
if (0)
{
/* Crashes, i.e. the source certificate is dereferenced without
* checking when a valid add disposition is given.
*/
ret = CertAddCertificateLinkToStore(store1, NULL, CERT_STORE_ADD_ALWAYS,
NULL);
}
CertCloseStore(store1, 0);
store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
CERT_STORE_CREATE_NEW_FLAG, NULL);
ret = CertAddCertificateLinkToStore(store1, source, CERT_STORE_ADD_ALWAYS,
&linked);
todo_wine
ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError());
if (ret)
{
ok(linked->hCertStore == store1, "unexpected store");
ret = CertSerializeCertificateStoreElement(linked, 0, NULL, &size);
ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n",
GetLastError());
buf = HeapAlloc(GetProcessHeap(), 0, size);
if (buf)
{
ret = CertSerializeCertificateStoreElement(linked, 0, buf, &size);
/* The serialized linked certificate is identical to the serialized
* original certificate.
*/
ok(size == sizeof(serializedCert), "Wrong size %d\n", size);
ok(!memcmp(serializedCert, buf, size),
"Unexpected serialized cert\n");
HeapFree(GetProcessHeap(), 0, buf);
}
/* Set a friendly name on the source certificate... */
blob.pbData = (LPBYTE)WineTestW;
blob.cbData = sizeof(WineTestW);
ret = CertSetCertificateContextProperty(source,
CERT_FRIENDLY_NAME_PROP_ID, 0, &blob);
ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
GetLastError());
/* and the linked certificate has the same friendly name. */
ret = CertGetCertificateContextProperty(linked,
CERT_FRIENDLY_NAME_PROP_ID, NULL, &size);
ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
GetLastError());
buf = HeapAlloc(GetProcessHeap(), 0, size);
if (buf)
{
ret = CertGetCertificateContextProperty(linked,
CERT_FRIENDLY_NAME_PROP_ID, buf, &size);
ok(!lstrcmpW((LPCWSTR)buf, WineTestW),
"unexpected friendly name\n");
HeapFree(GetProcessHeap(), 0, buf);
}
CertFreeCertificateContext(linked);
}
CertFreeCertificateContext(source);
CertCloseStore(store1, 0);
/* Test adding a cert to a file store, committing the change to the store,
* and creating a link to the resulting cert.
*/
if (!GetTempFileNameW(szDot, szPrefix, 0, filename1))
return;
DeleteFileW(filename1);
file = CreateFileW(filename1, GENERIC_READ | GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (file == INVALID_HANDLE_VALUE)
return;
store1 = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
CERT_FILE_STORE_COMMIT_ENABLE_FLAG, file);
ok(store1 != NULL, "CertOpenStore failed: %08x\n", GetLastError());
CloseHandle(file);
ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING,
bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &source);
ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
GetLastError());
/* Test adding a link to a memory store. */
store2 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
CERT_STORE_CREATE_NEW_FLAG, NULL);
ret = CertAddCertificateLinkToStore(store2, source, CERT_STORE_ADD_ALWAYS,
&linked);
todo_wine
ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError());
if (ret)
{
ok(linked->hCertStore == store2, "unexpected store");
ret = CertSerializeCertificateStoreElement(linked, 0, NULL, &size);
ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n",
GetLastError());
buf = HeapAlloc(GetProcessHeap(), 0, size);
if (buf)
{
ret = CertSerializeCertificateStoreElement(linked, 0, buf, &size);
/* The serialized linked certificate is identical to the serialized
* original certificate.
*/
ok(size == sizeof(serializedCert), "Wrong size %d\n", size);
ok(!memcmp(serializedCert, buf, size),
"Unexpected serialized cert\n");
HeapFree(GetProcessHeap(), 0, buf);
}
/* Set a friendly name on the source certificate... */
blob.pbData = (LPBYTE)WineTestW;
blob.cbData = sizeof(WineTestW);
ret = CertSetCertificateContextProperty(source,
CERT_FRIENDLY_NAME_PROP_ID, 0, &blob);
ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
GetLastError());
/* and the linked certificate has the same friendly name. */
ret = CertGetCertificateContextProperty(linked,
CERT_FRIENDLY_NAME_PROP_ID, NULL, &size);
ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
GetLastError());
buf = HeapAlloc(GetProcessHeap(), 0, size);
if (buf)
{
ret = CertGetCertificateContextProperty(linked,
CERT_FRIENDLY_NAME_PROP_ID, buf, &size);
ok(!lstrcmpW((LPCWSTR)buf, WineTestW),
"unexpected friendly name\n");
HeapFree(GetProcessHeap(), 0, buf);
}
CertFreeCertificateContext(linked);
}
CertCloseStore(store2, 0);
if (!GetTempFileNameW(szDot, szPrefix, 0, filename2))
return;
DeleteFileW(filename2);
file = CreateFileW(filename2, GENERIC_READ | GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (file == INVALID_HANDLE_VALUE)
return;
store2 = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
CERT_FILE_STORE_COMMIT_ENABLE_FLAG, file);
ok(store2 != NULL, "CertOpenStore failed: %08x\n", GetLastError());
CloseHandle(file);
/* Test adding a link to a file store. */
ret = CertAddCertificateLinkToStore(store2, source, CERT_STORE_ADD_ALWAYS,
&linked);
todo_wine
ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError());
if (ret)
{
ok(linked->hCertStore == store2, "unexpected store");
ret = CertSerializeCertificateStoreElement(linked, 0, NULL, &size);
ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n",
GetLastError());
buf = HeapAlloc(GetProcessHeap(), 0, size);
if (buf)
{
ret = CertSerializeCertificateStoreElement(linked, 0, buf, &size);
/* The serialized linked certificate now contains the friendly
* name property.
*/
ok(size == sizeof(serializedCertWithFriendlyName),
"Wrong size %d\n", size);
ok(!memcmp(serializedCertWithFriendlyName, buf, size),
"Unexpected serialized cert\n");
HeapFree(GetProcessHeap(), 0, buf);
}
CertFreeCertificateContext(linked);
compareStore(store2, "file store -> file store",
serializedStoreWithCertWithFriendlyName,
sizeof(serializedStoreWithCertWithFriendlyName));
}
CertCloseStore(store2, 0);
DeleteFileW(filename2);
CertFreeCertificateContext(source);
CertCloseStore(store1, 0);
DeleteFileW(filename1);
/* Test adding a link to a system store (which is a collection store.) */
store1 = CertOpenSystemStoreA(0, "My");
source = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
sizeof(bigCert));
SetLastError(0xdeadbeef);
ret = CertAddCertificateLinkToStore(store1, source, CERT_STORE_ADD_ALWAYS,
&linked);
todo_wine
ok(!ret && GetLastError() == E_INVALIDARG,
"expected E_INVALIDARG, got %08x\n", GetLastError());
CertFreeCertificateContext(source);
/* Test adding a link to a file store, where the linked certificate is
* in a system store.
*/
ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING,
bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &source);
ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
GetLastError());
if (!GetTempFileNameW(szDot, szPrefix, 0, filename1))
return;
DeleteFileW(filename1);
file = CreateFileW(filename1, GENERIC_READ | GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (file == INVALID_HANDLE_VALUE)
return;
store2 = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
CERT_FILE_STORE_COMMIT_ENABLE_FLAG, file);
ok(store2 != NULL, "CertOpenStore failed: %08x\n", GetLastError());
CloseHandle(file);
ret = CertAddCertificateLinkToStore(store2, source, CERT_STORE_ADD_ALWAYS,
&linked);
todo_wine
ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError());
if (ret)
{
ok(linked->hCertStore == store2, "unexpected store");
ret = pCertControlStore(store2, 0, CERT_STORE_CTRL_COMMIT, NULL);
ok(ret, "CertControlStore failed: %d\n", ret);
compareStore(store2, "file store -> system store",
serializedStoreWithCertAndHash,
sizeof(serializedStoreWithCertAndHash));
CertFreeCertificateContext(linked);
}
CertCloseStore(store2, 0);
DeleteFileW(filename1);
/* Test adding a link to a registry store, where the linked certificate is
* in a system store.
*/
store2 = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0,
CERT_SYSTEM_STORE_CURRENT_USER, WineTestW);
ok(store2 != NULL, "CertOpenStore failed: %08x\n", GetLastError());
ret = CertAddCertificateLinkToStore(store2, source, CERT_STORE_ADD_ALWAYS,
&linked);
todo_wine
ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError());
if (ret)
{
ok(linked->hCertStore == store2, "unexpected store");
CertDeleteCertificateFromStore(linked);
}
CertCloseStore(store2, 0);
CertFreeCertificateContext(source);
CertCloseStore(store1, 0);
}
static DWORD countCertsInStore(HCERTSTORE store)
{
PCCERT_CONTEXT cert = NULL;
@ -2191,6 +2547,7 @@ START_TEST(store)
testStoreProperty();
testAddSerialized();
testAddCertificateLink();
test_I_UpdateStore();
}