Juan Lang : cryptui: Show usages for selected cert in certificate manager dialog.

Alexandre Julliard julliard at winehq.org
Fri Jan 9 09:52:32 CST 2009


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

Author: Juan Lang <juan.lang at gmail.com>
Date:   Wed Jan  7 17:46:17 2009 -0800

cryptui: Show usages for selected cert in certificate manager dialog.

---

 dlls/cryptui/cryptui_En.rc |    2 +
 dlls/cryptui/cryptuires.h  |    2 +
 dlls/cryptui/main.c        |  132 ++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 132 insertions(+), 4 deletions(-)

diff --git a/dlls/cryptui/cryptui_En.rc b/dlls/cryptui/cryptui_En.rc
index 5d2f89e..a0a646e 100644
--- a/dlls/cryptui/cryptui_En.rc
+++ b/dlls/cryptui/cryptui_En.rc
@@ -100,6 +100,8 @@ STRINGTABLE DISCARDABLE
     IDS_ISSUER_COLUMN "Issued By"
     IDS_EXPIRATION_COLUMN "Expiration Date"
     IDS_FRIENDLY_NAME_COLUMN "Friendly Name"
+    IDS_ALLOWED_PURPOSE_ALL "<All>"
+    IDS_ALLOWED_PURPOSE_NONE "<None>"
     IDS_PURPOSE_SERVER_AUTH "Ensures the identify of a remote computer"
     IDS_PURPOSE_CLIENT_AUTH "Proves your identity to a remote computer"
     IDS_PURPOSE_CODE_SIGNING "Ensures software came from software publisher\nProtects software from alteration after publication"
diff --git a/dlls/cryptui/cryptuires.h b/dlls/cryptui/cryptuires.h
index b582e26..95c61a8 100644
--- a/dlls/cryptui/cryptuires.h
+++ b/dlls/cryptui/cryptuires.h
@@ -97,6 +97,8 @@
 #define IDS_ISSUER_COLUMN 1077
 #define IDS_EXPIRATION_COLUMN 1078
 #define IDS_FRIENDLY_NAME_COLUMN 1079
+#define IDS_ALLOWED_PURPOSE_ALL 1080
+#define IDS_ALLOWED_PURPOSE_NONE 1081
 
 #define IDS_PURPOSE_SERVER_AUTH 1100
 #define IDS_PURPOSE_CLIENT_AUTH 1101
diff --git a/dlls/cryptui/main.c b/dlls/cryptui/main.c
index 6955f0c..4e13a4f 100644
--- a/dlls/cryptui/main.c
+++ b/dlls/cryptui/main.c
@@ -779,27 +779,149 @@ static void cert_mgr_clear_cert_selection(HWND hwnd)
     refresh_store_certs(hwnd);
 }
 
-static void show_selected_cert(HWND hwnd, int index)
+static PCCERT_CONTEXT cert_mgr_index_to_cert(HWND hwnd, int index)
 {
+    PCCERT_CONTEXT cert = NULL;
     LVITEMW item;
-    HWND lv = GetDlgItem(hwnd, IDC_MGR_CERTS);
 
     item.mask = LVIF_PARAM;
     item.iItem = index;
     item.iSubItem = 0;
-    if (SendMessageW(lv, LVM_GETITEMW, 0, (LPARAM)&item))
+    if (SendMessageW(GetDlgItem(hwnd, IDC_MGR_CERTS), LVM_GETITEMW, 0,
+     (LPARAM)&item))
+        cert = (PCCERT_CONTEXT)item.lParam;
+    return cert;
+}
+
+static void show_selected_cert(HWND hwnd, int index)
+{
+    PCCERT_CONTEXT cert = cert_mgr_index_to_cert(hwnd, index);
+
+    if (cert)
     {
         CRYPTUI_VIEWCERTIFICATE_STRUCTW viewInfo;
 
         memset(&viewInfo, 0, sizeof(viewInfo));
         viewInfo.dwSize = sizeof(viewInfo);
         viewInfo.hwndParent = hwnd;
-        viewInfo.pCertContext = (PCCERT_CONTEXT)item.lParam;
+        viewInfo.pCertContext = cert;
         /* FIXME: this should be modal */
         CryptUIDlgViewCertificateW(&viewInfo, NULL);
     }
 }
 
+static void cert_mgr_show_cert_usages(HWND hwnd, int index)
+{
+    HWND text = GetDlgItem(hwnd, IDC_MGR_PURPOSES);
+    PCCERT_CONTEXT cert = cert_mgr_index_to_cert(hwnd, index);
+    PCERT_ENHKEY_USAGE usage;
+    DWORD size;
+
+    /* Get enhanced key usage.  Have to check for a property and an extension
+     * separately, because CertGetEnhancedKeyUsage will succeed and return an
+     * empty usage if neither is set.  Unfortunately an empty usage implies
+     * no usage is allowed, so we have to distinguish between the two cases.
+     */
+    if (CertGetEnhancedKeyUsage(cert, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG,
+     NULL, &size))
+    {
+        usage = HeapAlloc(GetProcessHeap(), 0, size);
+        if (!CertGetEnhancedKeyUsage(cert,
+         CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, usage, &size))
+        {
+            HeapFree(GetProcessHeap(), 0, usage);
+            usage = NULL;
+        }
+    }
+    else if (CertGetEnhancedKeyUsage(cert, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG,
+     NULL, &size))
+    {
+        usage = HeapAlloc(GetProcessHeap(), 0, size);
+        if (!CertGetEnhancedKeyUsage(cert,
+         CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, usage, &size))
+        {
+            HeapFree(GetProcessHeap(), 0, usage);
+            usage = NULL;
+        }
+    }
+    else
+        usage = NULL;
+    if (usage)
+    {
+        if (usage->cUsageIdentifier)
+        {
+            static const WCHAR commaSpace[] = { ',',' ',0 };
+            DWORD i, len = 1;
+            LPWSTR str, ptr;
+
+            for (i = 0; i < usage->cUsageIdentifier; i++)
+            {
+                PCCRYPT_OID_INFO info =
+                 CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
+                 usage->rgpszUsageIdentifier[i],
+                 CRYPT_ENHKEY_USAGE_OID_GROUP_ID);
+
+                if (info)
+                    len += strlenW(info->pwszName);
+                else
+                    len += strlen(usage->rgpszUsageIdentifier[i]);
+                if (i < usage->cUsageIdentifier - 1)
+                    len += strlenW(commaSpace);
+            }
+            str = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+            if (str)
+            {
+                for (i = 0, ptr = str; i < usage->cUsageIdentifier; i++)
+                {
+                    PCCRYPT_OID_INFO info =
+                     CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
+                     usage->rgpszUsageIdentifier[i],
+                     CRYPT_ENHKEY_USAGE_OID_GROUP_ID);
+
+                    if (info)
+                    {
+                        strcpyW(ptr, info->pwszName);
+                        ptr += strlenW(info->pwszName);
+                    }
+                    else
+                    {
+                        LPCSTR src = usage->rgpszUsageIdentifier[i];
+
+                        for (; *src; ptr++, src++)
+                            *ptr = *src;
+                        *ptr = 0;
+                    }
+                    if (i < usage->cUsageIdentifier - 1)
+                    {
+                        strcpyW(ptr, commaSpace);
+                        ptr += strlenW(commaSpace);
+                    }
+                }
+                *ptr = 0;
+                SendMessageW(text, WM_SETTEXT, 0, (LPARAM)str);
+                HeapFree(GetProcessHeap(), 0, str);
+            }
+            HeapFree(GetProcessHeap(), 0, usage);
+        }
+        else
+        {
+            WCHAR buf[MAX_STRING_LEN];
+
+            LoadStringW(hInstance, IDS_ALLOWED_PURPOSE_NONE, buf,
+             sizeof(buf) / sizeof(buf[0]));
+            SendMessageW(text, WM_SETTEXT, 0, (LPARAM)buf);
+        }
+    }
+    else
+    {
+        WCHAR buf[MAX_STRING_LEN];
+
+        LoadStringW(hInstance, IDS_ALLOWED_PURPOSE_ALL, buf,
+         sizeof(buf) / sizeof(buf[0]));
+        SendMessageW(text, WM_SETTEXT, 0, (LPARAM)buf);
+    }
+}
+
 static LRESULT CALLBACK cert_mgr_dlg_proc(HWND hwnd, UINT msg, WPARAM wp,
  LPARAM lp)
 {
@@ -857,6 +979,8 @@ static LRESULT CALLBACK cert_mgr_dlg_proc(HWND hwnd, UINT msg, WPARAM wp,
                 EnableWindow(GetDlgItem(hwnd, IDC_MGR_EXPORT), numSelected > 0);
                 EnableWindow(GetDlgItem(hwnd, IDC_MGR_REMOVE), numSelected > 0);
                 EnableWindow(GetDlgItem(hwnd, IDC_MGR_VIEW), numSelected == 1);
+                if (numSelected == 1)
+                    cert_mgr_show_cert_usages(hwnd, nm->iItem);
             }
             break;
         }




More information about the wine-cvs mailing list