Module: wine Branch: master Commit: e7490ad0821356ee7d20ffc4fd357ed826383ae6 URL: http://source.winehq.org/git/wine.git/?a=commit;h=e7490ad0821356ee7d20ffc4fd...
Author: Juan Lang juan.lang@gmail.com Date: Wed Dec 17 08:51:27 2008 -0800
cryptui: Show issuer statement in cert properties dialog.
---
dlls/cryptui/Makefile.in | 2 +- dlls/cryptui/cryptui_En.rc | 11 +++ dlls/cryptui/cryptuires.h | 4 + dlls/cryptui/main.c | 208 +++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 223 insertions(+), 2 deletions(-)
diff --git a/dlls/cryptui/Makefile.in b/dlls/cryptui/Makefile.in index 078cb33..d81a8e5 100644 --- a/dlls/cryptui/Makefile.in +++ b/dlls/cryptui/Makefile.in @@ -4,7 +4,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = cryptui.dll IMPORTS = uuid crypt32 ole32 comctl32 user32 kernel32 -DELAYIMPORTS = wintrust +DELAYIMPORTS = wintrust urlmon IMPORTLIB = cryptui
C_SRCS = \ diff --git a/dlls/cryptui/cryptui_En.rc b/dlls/cryptui/cryptui_En.rc index f220679..d0ef8b1 100644 --- a/dlls/cryptui/cryptui_En.rc +++ b/dlls/cryptui/cryptui_En.rc @@ -81,3 +81,14 @@ BEGIN PUSHBUTTON "&Install Certificate...", IDC_ADDTOSTORE,103,216,70,14 PUSHBUTTON "Issuer &Statement", IDC_ISSUERSTATEMENT,177,216,70,14 END + +IDD_USERNOTICE DIALOG DISCARDABLE 0, 0, 255, 256 +CAPTION "Disclaimer" +STYLE WS_VISIBLE +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "", IDC_USERNOTICE,"RichEdit20W", + WS_BORDER|ES_READONLY|ES_MULTILINE|WS_DISABLED,6,10,241,200 + PUSHBUTTON "Close", IDOK,103,216,70,14 + PUSHBUTTON "More &Info", IDC_CPS,177,216,70,14 +END diff --git a/dlls/cryptui/cryptuires.h b/dlls/cryptui/cryptuires.h index 7cdb534..e499e0b 100644 --- a/dlls/cryptui/cryptuires.h +++ b/dlls/cryptui/cryptuires.h @@ -60,6 +60,7 @@ #define IDS_PURPOSE_DS_EMAIL_REPLICATION 1125
#define IDD_GENERAL 100 +#define IDD_USERNOTICE 103
#define IDB_CERT 201 #define IDB_CERT_ERROR 202 @@ -74,4 +75,7 @@ #define IDC_ADDTOSTORE 2005 #define IDC_ISSUERSTATEMENT 2006
+#define IDC_USERNOTICE 2300 +#define IDC_CPS 2301 + #endif /* ndef __CRYPTUIRES_H_ */ diff --git a/dlls/cryptui/main.c b/dlls/cryptui/main.c index 148f91d..f04875f 100644 --- a/dlls/cryptui/main.c +++ b/dlls/cryptui/main.c @@ -34,6 +34,8 @@ #include "richole.h" #include "cryptuiapi.h" #include "cryptuires.h" +#include "urlmon.h" +#include "hlink.h" #include "wine/debug.h" #include "wine/unicode.h"
@@ -614,6 +616,117 @@ static void set_policy_text(HWND text, } }
+static CRYPT_OBJID_BLOB *find_policy_qualifier(CERT_POLICIES_INFO *policies, + LPCSTR policyOid) +{ + CRYPT_OBJID_BLOB *ret = NULL; + DWORD i; + + for (i = 0; !ret && i < policies->cPolicyInfo; i++) + { + DWORD j; + + for (j = 0; !ret && j < policies->rgPolicyInfo[i].cPolicyQualifier; j++) + if (!strcmp(policies->rgPolicyInfo[i].rgPolicyQualifier[j]. + pszPolicyQualifierId, policyOid)) + ret = &policies->rgPolicyInfo[i].rgPolicyQualifier[j]. + Qualifier; + } + return ret; +} + +static WCHAR *get_cps_str_from_qualifier(CRYPT_OBJID_BLOB *qualifier) +{ + LPWSTR qualifierStr = NULL; + CERT_NAME_VALUE *qualifierValue; + DWORD size; + + if (CryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME_VALUE, + qualifier->pbData, qualifier->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, + &qualifierValue, &size)) + { + size = CertRDNValueToStrW(qualifierValue->dwValueType, + &qualifierValue->Value, NULL, 0); + qualifierStr = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR)); + if (qualifierStr) + CertRDNValueToStrW(qualifierValue->dwValueType, + &qualifierValue->Value, qualifierStr, size); + LocalFree(qualifierValue); + } + return qualifierStr; +} + +static WCHAR *get_user_notice_from_qualifier(CRYPT_OBJID_BLOB *qualifier) +{ + LPWSTR str = NULL; + CERT_POLICY_QUALIFIER_USER_NOTICE *qualifierValue; + DWORD size; + + if (CryptDecodeObjectEx(X509_ASN_ENCODING, + X509_PKIX_POLICY_QUALIFIER_USERNOTICE, + qualifier->pbData, qualifier->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, + &qualifierValue, &size)) + { + str = HeapAlloc(GetProcessHeap(), 0, + (strlenW(qualifierValue->pszDisplayText) + 1) * sizeof(WCHAR)); + if (str) + strcpyW(str, qualifierValue->pszDisplayText); + LocalFree(qualifierValue); + } + return str; +} + +struct IssuerStatement +{ + LPWSTR cps; + LPWSTR userNotice; +}; + +static void set_issuer_statement(HWND hwnd, + PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo) +{ + PCERT_EXTENSION policyExt; + + if (!(pCertViewInfo->dwFlags & CRYPTUI_DISABLE_ISSUERSTATEMENT) && + (policyExt = CertFindExtension(szOID_CERT_POLICIES, + pCertViewInfo->pCertContext->pCertInfo->cExtension, + pCertViewInfo->pCertContext->pCertInfo->rgExtension))) + { + CERT_POLICIES_INFO *policies; + DWORD size; + + if (CryptDecodeObjectEx(X509_ASN_ENCODING, policyExt->pszObjId, + policyExt->Value.pbData, policyExt->Value.cbData, + CRYPT_DECODE_ALLOC_FLAG, NULL, &policies, &size)) + { + CRYPT_OBJID_BLOB *qualifier; + LPWSTR cps = NULL, userNotice = NULL; + + if ((qualifier = find_policy_qualifier(policies, + szOID_PKIX_POLICY_QUALIFIER_CPS))) + cps = get_cps_str_from_qualifier(qualifier); + if ((qualifier = find_policy_qualifier(policies, + szOID_PKIX_POLICY_QUALIFIER_USERNOTICE))) + userNotice = get_user_notice_from_qualifier(qualifier); + if (cps || userNotice) + { + struct IssuerStatement *issuerStatement = + HeapAlloc(GetProcessHeap(), 0, sizeof(struct IssuerStatement)); + + if (issuerStatement) + { + issuerStatement->cps = cps; + issuerStatement->userNotice = userNotice; + EnableWindow(GetDlgItem(hwnd, IDC_ISSUERSTATEMENT), TRUE); + SetWindowLongPtrW(hwnd, DWLP_USER, + (ULONG_PTR)issuerStatement); + } + } + LocalFree(policies); + } + } +} + static void set_cert_info(HWND hwnd, PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo) { @@ -669,7 +782,7 @@ static void set_cert_info(HWND hwnd, else { set_policy_text(text, pCertViewInfo); - FIXME("show issuer statement\n"); + set_issuer_statement(hwnd, pCertViewInfo); } }
@@ -754,6 +867,55 @@ static void set_general_info(HWND hwnd, set_cert_validity_period(hwnd, pCertViewInfo->pCertContext); }
+static LRESULT CALLBACK user_notice_dlg_proc(HWND hwnd, UINT msg, WPARAM wp, + LPARAM lp) +{ + LRESULT ret = 0; + HWND text; + struct IssuerStatement *issuerStatement; + + switch (msg) + { + case WM_INITDIALOG: + text = GetDlgItem(hwnd, IDC_USERNOTICE); + issuerStatement = (struct IssuerStatement *)lp; + add_unformatted_text_to_control(text, issuerStatement->userNotice, + strlenW(issuerStatement->userNotice)); + if (issuerStatement->cps) + SetWindowLongPtrW(hwnd, DWLP_USER, (LPARAM)issuerStatement->cps); + else + EnableWindow(GetDlgItem(hwnd, IDC_CPS), FALSE); + break; + case WM_COMMAND: + switch (wp) + { + case IDOK: + EndDialog(hwnd, IDOK); + ret = TRUE; + break; + case IDC_CPS: + { + IBindCtx *bctx = NULL; + LPWSTR cps; + + CreateBindCtx(0, &bctx); + cps = (LPWSTR)GetWindowLongPtrW(hwnd, DWLP_USER); + HlinkSimpleNavigateToString(cps, NULL, NULL, NULL, bctx, NULL, + HLNF_OPENINNEWWINDOW, 0); + IBindCtx_Release(bctx); + break; + } + } + } + return ret; +} + +static void show_user_notice(HWND hwnd, struct IssuerStatement *issuerStatement) +{ + DialogBoxParamW(hInstance, MAKEINTRESOURCEW(IDD_USERNOTICE), hwnd, + user_notice_dlg_proc, (LPARAM)issuerStatement); +} + static LRESULT CALLBACK general_dlg_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { @@ -778,17 +940,61 @@ static LRESULT CALLBACK general_dlg_proc(HWND hwnd, UINT msg, WPARAM wp, case IDC_ADDTOSTORE: FIXME("call CryptUIWizImport\n"); break; + case IDC_ISSUERSTATEMENT: + { + struct IssuerStatement *issuerStatement = + (struct IssuerStatement *)GetWindowLongPtrW(hwnd, DWLP_USER); + + if (issuerStatement) + { + if (issuerStatement->userNotice) + show_user_notice(hwnd, issuerStatement); + else if (issuerStatement->cps) + { + IBindCtx *bctx = NULL; + + CreateBindCtx(0, &bctx); + HlinkSimpleNavigateToString(issuerStatement->cps, NULL, + NULL, NULL, bctx, NULL, HLNF_OPENINNEWWINDOW, 0); + IBindCtx_Release(bctx); + } + } + break; + } } break; } return 0; }
+static UINT CALLBACK general_callback_proc(HWND hwnd, UINT msg, + PROPSHEETPAGEW *page) +{ + struct IssuerStatement *issuerStatement; + + switch (msg) + { + case PSPCB_RELEASE: + issuerStatement = + (struct IssuerStatement *)GetWindowLongPtrW(hwnd, DWLP_USER); + if (issuerStatement) + { + HeapFree(GetProcessHeap(), 0, issuerStatement->cps); + HeapFree(GetProcessHeap(), 0, issuerStatement->userNotice); + HeapFree(GetProcessHeap(), 0, issuerStatement); + } + break; + } + return 1; +} + static void init_general_page(PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo, PROPSHEETPAGEW *page) { memset(page, 0, sizeof(PROPSHEETPAGEW)); page->dwSize = sizeof(PROPSHEETPAGEW); + page->dwFlags = PSP_USECALLBACK; + page->pfnCallback = general_callback_proc; page->hInstance = hInstance; page->u.pszTemplate = MAKEINTRESOURCEW(IDD_GENERAL); page->pfnDlgProc = general_dlg_proc;