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