[PATCH 1/2] crypt32/tests: whether apps could write to the registry HKLM Root certificates store

Donat Enikeev donat at enikeev.net
Tue Oct 18 07:59:15 CDT 2016


And, additionally, whether CertAddStoreToCollection() respects read-only flag and priorities

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

diff --git a/dlls/crypt32/tests/store.c b/dlls/crypt32/tests/store.c
index 4483936..c9989ff 100644
--- a/dlls/crypt32/tests/store.c
+++ b/dlls/crypt32/tests/store.c
@@ -345,6 +345,220 @@ 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 };
 
+/* Testing whether HKLM\Root store in the collection is availble for adding new certs*/
+static void testRootStoresInCollection(void)
+{
+    PCCERT_CONTEXT cert1, cert2;
+    HCERTSTORE collection;
+    WCHAR keyName[MAX_PATH];
+    static const WCHAR rootW[] = {'R','o','o','t',0},
+        certificatesW[] = {'C','e','r','t','i','f','i','c','a','t','e','s',0 },
+        slashW[] = { '\\',0 },
+        bigCert_hashStrW[] = {
+        '6','E','3','0','9','0','7','1','5','F','D','9','2','3',
+        '5','6','E','B','A','E','2','5','4','0','E','6','2','2',
+        'D','A','1','9','2','6','0','2','A','6','0','8',0};
+    HKEY key;
+    BOOL ret;
+    DWORD res;
+
+    /* Special case of HKLM Root store, with system certificates merged via collection*/
+    collection = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0,
+        CERT_SYSTEM_STORE_LOCAL_MACHINE, rootW);
+    if (!collection)
+    {
+        win_skip("Insufficient privileges for the test, skipping\n");
+        return;
+    }
+    ok (collection!=NULL, "Failed to open root store %x", GetLastError());
+    cert1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert));
+    ok (cert1 != NULL, "Create cert context failed %x\n", GetLastError());
+    ret = CertAddCertificateContextToStore(collection, cert1, CERT_STORE_ADD_REPLACE_EXISTING, NULL);
+    ok (ret, "Adding to root collection failed %x\n", GetLastError());
+    CertFreeCertificateContext(cert1);
+    CertCloseStore(collection, 0);
+
+    lstrcpyW(keyName, CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH);
+    lstrcatW(keyName, slashW);
+    lstrcatW(keyName, rootW);
+    lstrcatW(keyName, slashW);
+    lstrcatW(keyName, certificatesW);
+    lstrcatW(keyName, slashW);
+    lstrcatW(keyName, bigCert_hashStrW);
+
+    res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyName, 0, KEY_ALL_ACCESS, &key);
+    ok (!res, "The cert hasn't been saved %x\n", GetLastError());
+    if (!res) RegCloseKey(key);
+
+    /* deleting cert from store */
+    collection = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0,
+        CERT_SYSTEM_STORE_LOCAL_MACHINE, rootW);
+    ok (collection!=NULL, "Failed to open root store %x", GetLastError());
+    cert1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert));
+    ok (cert1 != NULL, "Create cert context failed %x\n", GetLastError());
+    cert2 = CertFindCertificateInStore(collection, X509_ASN_ENCODING, 0, CERT_FIND_EXISTING, cert1, NULL);
+    ok (cert2 != NULL, "Failed to find cert in the store %x\n", GetLastError());
+    ret = CertDeleteCertificateFromStore(cert2);
+    ok (ret, "Failed to delete certificate from store %x\n", GetLastError());
+    CertFreeCertificateContext(cert1);
+    CertFreeCertificateContext(cert2);
+    CertCloseStore(collection, 0);
+
+    res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyName, 0, KEY_ALL_ACCESS, &key);
+    ok (res, "The cert's registry entry should be absent %x\n", GetLastError());
+    if (res) RegCloseKey(key);
+}
+
+/**
+ * @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 cert1, cert2, tcert1;
+    HCERTSTORE collection, ro_store, rw_store, rw_store_2, tstore;
+    static const WCHAR WineTestRO_W[] = { 'W','i','n','e','T','e','s','t','_','R','O',0 },
+                       WineTestRW_W[] = { 'W','i','n','e','T','e','s','t','_','R','W',0 },
+                       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;
+    }
+    if (0) {
+    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 %x\n", GetLastError());
+
+    ret = CertAddStoreToCollection(collection, ro_store, 0, 1000);
+    ok (ret, "Failed to add read-only store to collection %x\n", GetLastError());
+
+    cert1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert));
+    ok (cert1 != NULL, "Create cert context failed %x\n", GetLastError());
+    ret = CertAddCertificateContextToStore(collection, cert1, CERT_STORE_ADD_ALWAYS, NULL);
+    ok (!ret, "Added cert to collection with 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 */
+    ret = CertAddCertificateContextToStore(collection, cert1, CERT_STORE_ADD_REPLACE_EXISTING, NULL);
+    ok (ret, "Failed to add cert to the collection %x\n", GetLastError());
+
+    tcert1 = CertEnumCertificatesInStore(ro_store, NULL);
+    ok (!tcert1, "Read-only ro_store contains cert\n");
+
+    tcert1 = CertEnumCertificatesInStore(rw_store, NULL);
+    ok (cert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded,
+        "Unexpected cert in the rw store\n");
+    CertFreeCertificateContext(tcert1);
+
+    tcert1 = CertEnumCertificatesInStore(collection, NULL);
+    ok (tcert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded,
+        "Unexpected cert in the collection\n");
+    CertFreeCertificateContext(tcert1);
+
+    /** 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());
+
+    cert2 = CertCreateCertificateContext(X509_ASN_ENCODING, signedBigCert, sizeof(signedBigCert));
+    ok (cert2 != NULL, "Failed to create cert context %x \n", GetLastError());
+    ret = CertAddCertificateContextToStore(collection, cert2, CERT_STORE_ADD_REPLACE_EXISTING, NULL);
+    ok (ret, "Failed to add cert3 to the store %x\n",GetLastError());
+
+    /** checking certificates in the stores */
+    tcert1 = CertEnumCertificatesInStore(ro_store, 0);
+    ok (tcert1 == NULL, "Read-only store not empty\n");
+
+    tcert1 = CertEnumCertificatesInStore(rw_store, NULL);
+    ok (tcert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded,
+        "Unexpected cert in the rw_store\n");
+    CertFreeCertificateContext(tcert1);
+
+    tcert1 = CertEnumCertificatesInStore(rw_store_2, NULL);
+    ok (tcert1 && tcert1->cbCertEncoded == cert2->cbCertEncoded,
+        "Unexpected cert in the rw_store_2\n");
+    CertFreeCertificateContext(tcert1);
+
+    /** checking certificates in the collection */
+    tcert1 = CertEnumCertificatesInStore(collection, NULL);
+    ok (tcert1 && tcert1->cbCertEncoded == cert2->cbCertEncoded,
+        "cert2 expected in the collection got %p, %x\n",tcert1, GetLastError());
+    tcert1 = CertEnumCertificatesInStore(collection, tcert1);
+    ok (tcert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded,
+        "cert1 expected in the collection got %p, %x\n",tcert1, GetLastError());
+    tcert1 = CertEnumCertificatesInStore(collection, tcert1);
+    ok (tcert1==NULL,"Unexpected cert in the collection %p %x\n",tcert1, GetLastError());
+
+    /* checking whether certs had been saved (they are NOT in wine until stores are closed*/
+    tstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0,
+        CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, WineTestRW_W);
+    ok (tstore!=NULL, "Failed to open existing rw store\n");
+    tcert1 = CertEnumCertificatesInStore(tstore, NULL);
+    todo_wine
+        ok(tcert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded, "cert1 wasn't saved\n");
+    CertFreeCertificateContext(tcert1);
+    CertCloseStore(tstore,0);
+
+    tstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0,
+        CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, WineTestRW2_W);
+    ok (tstore!=NULL, "Failed to open existing rw2 store\n");
+    tcert1 = CertEnumCertificatesInStore(tstore, NULL);
+    todo_wine
+        ok (tcert1 && tcert1->cbCertEncoded == cert2->cbCertEncoded, "cert2 wasn't saved\n");
+    CertFreeCertificateContext(tcert1);
+    CertCloseStore(tstore,0);
+
+    /* now closing stores, certs are only then saved */
+    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 should be this time)*/
+    rw_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0,
+        CERT_SYSTEM_STORE_CURRENT_USER, WineTestRW_W);
+    tcert1 = CertEnumCertificatesInStore(rw_store, NULL);
+    ok (tcert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded,
+        "Unexpected cert in store %p\n", tcert1);
+    CertFreeCertificateContext(tcert1);
+    CertCloseStore(rw_store,0);
+
+    rw_store_2 = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0,
+        CERT_SYSTEM_STORE_CURRENT_USER, WineTestRW2_W);
+    tcert1 = CertEnumCertificatesInStore(rw_store_2, NULL);
+    ok (tcert1 && tcert1->cbCertEncoded == cert2->cbCertEncoded,
+        "Unexpected cert in store %p\n", tcert1);
+    CertFreeCertificateContext(tcert1);
+    CertCloseStore(rw_store_2,0);
+
+    CertFreeCertificateContext(cert1);
+    CertFreeCertificateContext(cert2);
+    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;
@@ -2812,6 +3026,9 @@ START_TEST(store)
     /* various combinations of CertOpenStore */
     testMemStore();
     testCollectionStore();
+    testStoresInCollection();
+    testRootStoresInCollection();
+
     testRegStore();
     testSystemRegStore();
     testSystemStore();
-- 
2.7.4




More information about the wine-patches mailing list