Juan Lang : cryptui: Choose appropriate destination store for a cert.

Alexandre Julliard julliard at winehq.org
Mon Oct 27 08:02:58 CDT 2008


Module: wine
Branch: master
Commit: ab9a53f68551072119d40f15041d796cfa864708
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=ab9a53f68551072119d40f15041d796cfa864708

Author: Juan Lang <juan.lang at gmail.com>
Date:   Fri Oct 24 14:37:02 2008 -0700

cryptui: Choose appropriate destination store for a cert.

---

 dlls/cryptui/main.c          |   74 ++++++++++++++++++++++++++++++++++++++++--
 dlls/cryptui/tests/cryptui.c |    9 ++---
 2 files changed, 74 insertions(+), 9 deletions(-)

diff --git a/dlls/cryptui/main.c b/dlls/cryptui/main.c
index ba1e33d..3b116f0 100644
--- a/dlls/cryptui/main.c
+++ b/dlls/cryptui/main.c
@@ -139,10 +139,79 @@ static PCCERT_CONTEXT make_cert_from_file(LPCWSTR fileName)
     return cert;
 }
 
+/* Decodes a cert's basic constraints extension (either szOID_BASIC_CONSTRAINTS
+ * or szOID_BASIC_CONSTRAINTS2, whichever is present) to determine if it
+ * should be a CA.  If neither extension is present, returns
+ * defaultIfNotSpecified.
+ */
+static BOOL is_ca_cert(PCCERT_CONTEXT cert, BOOL defaultIfNotSpecified)
+{
+    BOOL isCA = defaultIfNotSpecified;
+    PCERT_EXTENSION ext = CertFindExtension(szOID_BASIC_CONSTRAINTS,
+     cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension);
+
+    if (ext)
+    {
+        CERT_BASIC_CONSTRAINTS_INFO *info;
+        DWORD size = 0;
+
+        if (CryptDecodeObjectEx(X509_ASN_ENCODING, szOID_BASIC_CONSTRAINTS,
+         ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_ALLOC_FLAG,
+         NULL, (LPBYTE)&info, &size))
+        {
+            if (info->SubjectType.cbData == 1)
+                isCA = info->SubjectType.pbData[0] & CERT_CA_SUBJECT_FLAG;
+            LocalFree(info);
+        }
+    }
+    else
+    {
+        ext = CertFindExtension(szOID_BASIC_CONSTRAINTS2,
+         cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension);
+        if (ext)
+        {
+            CERT_BASIC_CONSTRAINTS2_INFO info;
+            DWORD size = sizeof(CERT_BASIC_CONSTRAINTS2_INFO);
+
+            if (CryptDecodeObjectEx(X509_ASN_ENCODING,
+             szOID_BASIC_CONSTRAINTS2, ext->Value.pbData, ext->Value.cbData,
+             0, NULL, &info, &size))
+                isCA = info.fCA;
+        }
+    }
+    return isCA;
+}
+
+static inline BOOL is_cert_self_signed(PCCERT_CONTEXT cert)
+{
+    return CertCompareCertificateName(cert->dwCertEncodingType,
+     &cert->pCertInfo->Subject, &cert->pCertInfo->Issuer);
+}
+
+static HCERTSTORE choose_store_for_cert(PCCERT_CONTEXT cert)
+{
+    static const WCHAR Root[] = {'R','o','o','t',0};
+    static const WCHAR AddressBook[] = { 'A','d','d','r','e','s','s',
+     'B','o','o','k',0 };
+    static const WCHAR CA[] = { 'C','A',0 };
+    LPCWSTR storeName;
+
+    if (is_ca_cert(cert, TRUE))
+    {
+        if (is_cert_self_signed(cert))
+            storeName = Root;
+        else
+            storeName = CA;
+    }
+    else
+        storeName = AddressBook;
+    return CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0,
+     CERT_SYSTEM_STORE_CURRENT_USER, storeName);
+}
+
 BOOL WINAPI CryptUIWizImport(DWORD dwFlags, HWND hwndParent, LPCWSTR pwszWizardTitle,
                              PCCRYPTUI_WIZ_IMPORT_SRC_INFO pImportSrc, HCERTSTORE hDestCertStore)
 {
-    static const WCHAR Root[] = {'R','o','o','t',0};
     BOOL ret;
     HCERTSTORE store;
     const CERT_CONTEXT *cert;
@@ -187,8 +256,7 @@ BOOL WINAPI CryptUIWizImport(DWORD dwFlags, HWND hwndParent, LPCWSTR pwszWizardT
     if (hDestCertStore) store = hDestCertStore;
     else
     {
-        FIXME("certificate store should be determined dynamically, picking Root store\n");
-        if (!(store = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, Root)))
+        if (!(store = choose_store_for_cert(cert)))
         {
             WARN("unable to open certificate store\n");
             CertFreeCertificateContext(cert);
diff --git a/dlls/cryptui/tests/cryptui.c b/dlls/cryptui/tests/cryptui.c
index b70011a..2ffc83e 100644
--- a/dlls/cryptui/tests/cryptui.c
+++ b/dlls/cryptui/tests/cryptui.c
@@ -396,7 +396,6 @@ static void test_crypt_ui_wiz_import(void)
     info.u.pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
      iTunesCert3, sizeof(iTunesCert3));
     ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL);
-    todo_wine
     ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
     if (ret)
     {
@@ -408,7 +407,7 @@ static void test_crypt_ui_wiz_import(void)
         if (addressBook)
         {
             find_and_delete_cert_in_store(addressBook, "AddressBook",
-             info.u.pCertContext, "iTunesCert3", TRUE);
+             info.u.pCertContext, "iTunesCert3", FALSE);
             CertCloseStore(addressBook, 0);
         }
     }
@@ -446,7 +445,6 @@ static void test_crypt_ui_wiz_import(void)
     info.u.pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
      iTunesCert1, sizeof(iTunesCert1));
     ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL);
-    todo_wine
     ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
     if (ret)
     {
@@ -458,7 +456,7 @@ static void test_crypt_ui_wiz_import(void)
         if (addressBook)
         {
             find_and_delete_cert_in_store(addressBook, "AddressBook",
-             info.u.pCertContext, "iTunesCert1", TRUE);
+             info.u.pCertContext, "iTunesCert1", FALSE);
             CertCloseStore(addressBook, 0);
         }
     }
@@ -467,7 +465,6 @@ static void test_crypt_ui_wiz_import(void)
     info.u.pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
      iTunesCert2, sizeof(iTunesCert2));
     ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL);
-    todo_wine
     ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
     if (ret)
     {
@@ -478,7 +475,7 @@ static void test_crypt_ui_wiz_import(void)
         if (ca)
         {
             find_and_delete_cert_in_store(ca, "CA",
-             info.u.pCertContext, "iTunesCert2", TRUE);
+             info.u.pCertContext, "iTunesCert2", FALSE);
             CertCloseStore(ca, 0);
         }
     }




More information about the wine-cvs mailing list