From 00370826a2b304b84c9329f46580d86452201d63 Mon Sep 17 00:00:00 2001
From: Donat Enikeev <donat@enikeev.net>
Date: Sun, 16 Oct 2016 19:51:34 +0300
Subject: [PATCH 3/4] test save cert in collection

Signed-off-by: Donat Enikeev <donat@enikeev.net>
---
 dlls/crypt32/tests/store.c | 108 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 108 insertions(+)

diff --git a/dlls/crypt32/tests/store.c b/dlls/crypt32/tests/store.c
index e811fbe..545c4be 100644
--- a/dlls/crypt32/tests/store.c
+++ b/dlls/crypt32/tests/store.c
@@ -347,6 +347,112 @@ static const BYTE serializedStoreWithCert[] = {
  0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00 };
 
+/**
+ * @see testCollectionStore() additionally
+ * this test checks that certificate falls into correct store of a collection
+ * depending on the access flags and priorities
+ */
+static void testStoresInCollection(void)
+{
+    PCCERT_CONTEXT ocert1, ocert2, ocert3, icert1, icert2, icert3;
+    HCERTSTORE collection, ro_store, rw_store, rw_store_2;
+    static const WCHAR WineTestRO_W[] = { 'W','i','n','e','T','e','s','t','_','R','O',0 };
+    static const WCHAR WineTestRW_W[] = { 'W','i','n','e','T','e','s','t','_','R','W',0 };
+    static const WCHAR WineTestRW2_W[] = { 'W','i','n','e','T','e','s','t','_','R','W','2',0 };
+    BOOL ret;
+
+
+    if (!pCertAddStoreToCollection)
+    {
+        win_skip("CertAddStoreToCollection() is not available\n");
+        return;
+    }
+    collection = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
+        CERT_STORE_CREATE_NEW_FLAG, NULL);
+    ok(collection != NULL, "Failed to init collection store, last error %x\n", GetLastError());
+    /* Add read-only store to collection with very high priority*/
+    ro_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0,
+        CERT_SYSTEM_STORE_CURRENT_USER, WineTestRO_W);
+    ok(ro_store != NULL, "Failed to init ro store, last error %x\n", GetLastError());
+    ret = CertAddStoreToCollection(collection, ro_store, 0, 1000);
+    ok (ret, "Failed to add read-only store to collection, last erro %x\n", GetLastError());
+    ocert1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert));
+    ok (ocert1 != NULL, "Create cert context failed, last error %x\n", GetLastError());
+    ret = CertAddCertificateContextToStore(collection, ocert1, 0, NULL);
+    ok (!ret, "Unexpectedly added cert to the collection with a single read-only store %x\n", GetLastError());
+    /* Add read-write store to collection with the lowest priority*/
+    rw_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0,
+        CERT_SYSTEM_STORE_CURRENT_USER, WineTestRW_W);
+    ok (rw_store != NULL, "Failed to open rw store, %x\n", GetLastError());
+    ret = CertAddStoreToCollection(collection, rw_store, CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
+    ok (ret, "Failed to add rw store to collection, %x\n", GetLastError());
+    /** Adding certificate to collection should fall into rw store,
+     *  even though prioirty of the ro_store is higher */
+    ocert2 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2, sizeof(bigCert2));
+    ok (ocert2 != NULL, "Failed to create cert context %x\n", GetLastError());
+    ret = CertAddCertificateContextToStore(collection, ocert2, CERT_STORE_ADD_REPLACE_EXISTING, NULL);
+    ok (ret, "Failed to add cert 2 to the collection %x\n", GetLastError());
+    icert1 = CertEnumCertificatesInStore(ro_store, NULL);
+    ok (!icert1, "Unexpectedly read-only ro_store contains just added cert\n");
+    icert2 = CertEnumCertificatesInStore(rw_store, NULL);
+    ok (icert2 && icert2->cbCertEncoded==ocert2->cbCertEncoded,
+        "Unexpected cert in the rw store\n");
+    icert2 = CertEnumCertificatesInStore(collection, NULL);
+    ok (icert2 && icert2->cbCertEncoded==ocert2->cbCertEncoded,
+        "Unexpected cert in the collection\n");
+    /** adding one more rw store with higher priority*/
+    rw_store_2 = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0,
+        CERT_SYSTEM_STORE_CURRENT_USER, WineTestRW2_W);
+    ok (rw_store_2 != NULL, "Failed to init second rw store %x\n", GetLastError());
+    ret = CertAddStoreToCollection(collection, rw_store_2, CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 50);
+    ok (ret, "Failed to add rw_store_2 to collection%x\n",GetLastError());
+    ocert3 = CertCreateCertificateContext(X509_ASN_ENCODING, signedBigCert, sizeof(signedBigCert));
+    ok (ocert3 != NULL, "Failed to create cert 3 context %x \n", GetLastError());
+    ret = CertAddCertificateContextToStore(collection, ocert3, CERT_STORE_ADD_REPLACE_EXISTING, NULL);
+    ok (ret, "Failed to add cert3 to the store %x\n",GetLastError());
+    /** checking certificates in the stores */
+    icert1 = CertEnumCertificatesInStore(ro_store, 0);
+    ok (icert1 == NULL, "Unexpectedly found cert in the read-only store\n");
+    icert2 = CertEnumCertificatesInStore(rw_store, NULL);
+    ok (icert2 && icert2->cbCertEncoded == ocert2->cbCertEncoded,
+        "Missing or unexpected cert in the rw_store\n");
+    icert3 = CertEnumCertificatesInStore(rw_store_2, NULL);
+    ok (icert3 && icert3->cbCertEncoded==icert3->cbCertEncoded,
+        "Missing or unexpected cert in the rw_store_2\n");
+    /** checking certificates in the collection */
+    icert3 = CertEnumCertificatesInStore(collection, NULL);
+    ok (icert3 && icert3->cbCertEncoded==ocert3->cbCertEncoded,
+        "Unexpected cert in the collection %p %x\n",icert3, GetLastError());
+    icert2 = CertEnumCertificatesInStore(collection, icert3);
+    ok (icert2 && icert2->cbCertEncoded==ocert2->cbCertEncoded,
+        "Unexpected cert in the collection %p %x\n",icert2, GetLastError());
+    icert1 = CertEnumCertificatesInStore(collection, icert2);
+    ok (icert1==NULL,"Unexpected cert in the collection %p %x\n",icert1, GetLastError());
+    /* closing stores */
+    CertCloseStore(collection,0);
+    CertCloseStore(ro_store,0);
+    CertCloseStore(rw_store,0);
+    CertCloseStore(rw_store_2,0);
+    /* reopening registry stores to check whether certs had been saved (they are NOT in wine) */
+    rw_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0,
+        CERT_SYSTEM_STORE_CURRENT_USER,WineTestRW_W);
+    icert2 = CertEnumCertificatesInStore(rw_store, NULL);
+    todo_wine
+        ok(icert2 && icert2->cbCertEncoded==ocert2->cbCertEncoded, "Unexpected cert saved\n");
+    rw_store_2 = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0,
+        CERT_SYSTEM_STORE_CURRENT_USER,WineTestRW2_W);
+    icert3 = CertEnumCertificatesInStore(rw_store_2, NULL);
+    todo_wine
+        ok (icert3 && icert3->cbCertEncoded==ocert3->cbCertEncoded, "Unexpected cert saved\n");
+
+    CertFreeCertificateContext(ocert1);
+    CertFreeCertificateContext(ocert2);
+    CertFreeCertificateContext(ocert3);
+    CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0,CERT_STORE_DELETE_FLAG|CERT_SYSTEM_STORE_CURRENT_USER,WineTestRO_W);
+    CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0,CERT_STORE_DELETE_FLAG|CERT_SYSTEM_STORE_CURRENT_USER,WineTestRW_W);
+    CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0,CERT_STORE_DELETE_FLAG|CERT_SYSTEM_STORE_CURRENT_USER,WineTestRW2_W);
+}
+
 static void testCollectionStore(void)
 {
     HCERTSTORE store1, store2, collection, collection2;
@@ -2894,6 +3000,8 @@ START_TEST(store)
     /* various combinations of CertOpenStore */
     testMemStore();
     testCollectionStore();
+    testStoresInCollection();
+
     testRegStore();
     testSystemRegStore();
     testSystemStore();
-- 
2.7.4

