2460 lines
75 KiB
C++
2460 lines
75 KiB
C++
|
//*********************************************************************
|
||
|
//* Microsoft Windows **
|
||
|
//* Copyright(c) Microsoft Corp., 1995 **
|
||
|
//*********************************************************************
|
||
|
|
||
|
//
|
||
|
// content.cpp - "Content" property sheet
|
||
|
//
|
||
|
|
||
|
// HISTORY:
|
||
|
//
|
||
|
// 5/17/97 t-ashlm created
|
||
|
|
||
|
#include "inetcplp.h"
|
||
|
#include <wab.h>
|
||
|
#include <cryptui.h>
|
||
|
#include <msiehost.h>
|
||
|
#include <schannel.h>
|
||
|
|
||
|
#include <mluisupp.h>
|
||
|
|
||
|
//
|
||
|
// Private Functions and Structures
|
||
|
//
|
||
|
|
||
|
// WINTRUST / SOFTPUB
|
||
|
// definition from WINTRUST.H
|
||
|
// extern "C" BOOL WINAPI OpenPersonalTrustDBDialog(HWND hwndParent);
|
||
|
typedef BOOL (WINAPI *WINTRUSTDLGPROC)(HWND hwndParent);
|
||
|
WINTRUSTDLGPROC g_WinTrustDlgProc = (WINTRUSTDLGPROC)NULL;
|
||
|
SSL_EMPTY_CACHE_FN_W g_pfnSslEmptyCacheW = (SSL_EMPTY_CACHE_FN_W)NULL;
|
||
|
#ifdef WALLET
|
||
|
BOOL IsWallet3Installed();
|
||
|
BOOL IsWalletAddressAvailable(VOID);
|
||
|
BOOL IsWalletPaymentAvailable(VOID);
|
||
|
#endif
|
||
|
HRESULT ShowModalDialog(HWND hwndParent, IMoniker *pmk, VARIANT *pvarArgIn, TCHAR* pchOptions, VARIANT *pvArgOut);
|
||
|
HCERTSTORE PFXImportCertStore(CRYPT_DATA_BLOB* pPFX, LPCWSTR szPassword, DWORD dwFlags);
|
||
|
BOOL PFXExportCertStore(HCERTSTORE hStore, CRYPT_DATA_BLOB* pPFX, LPCWSTR szPassword, DWORD dwFlags);
|
||
|
BOOL _AorW_GetFileNameFromBrowse(HWND hDlg,
|
||
|
LPWSTR pszFilename,
|
||
|
UINT cchFilename,
|
||
|
LPCWSTR pszWorkingDir,
|
||
|
LPCWSTR pszExt,
|
||
|
LPCWSTR pszFilter,
|
||
|
LPCWSTR pszTitle);
|
||
|
|
||
|
INT_PTR CALLBACK AutoSuggestDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||
|
INT_PTR CALLBACK WalletDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||
|
|
||
|
|
||
|
//BUBUG: The following prototype should be rermoved when we have updated our Crypto API to latest version
|
||
|
BOOL WINAPI WTHelperIsInRootStore(PCCERT_CONTEXT pCertContext);
|
||
|
|
||
|
//////////////////////////////////////////////
|
||
|
// stolen from \inet\schannel\sspi\spreg.h
|
||
|
#define REG_SITECERT_BASE TEXT("System\\CurrentControlSet\\Control\\SecurityProviders\\SCHANNEL\\CertificationAuthorities")
|
||
|
#define REG_SITECERT_CERT_VAL TEXT("CACert")
|
||
|
|
||
|
#define SITECERTKEYLEN 80 // FEATURE: should probably grab this value somewhere
|
||
|
#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
|
||
|
|
||
|
#include <initguid.h>
|
||
|
|
||
|
// Use the wallet "payment" guid for JIT (different for alpha and x86...)
|
||
|
#ifdef _ALPHA_
|
||
|
// {B7FB4D5C-9FBE-11D0-8965-0000F822DEA9}
|
||
|
DEFINE_GUID(CLSID_WalletPayment, 0xb7fb4d5c, 0x9fbe, 0x11d0, 0x89, 0x65, 0x0, 0x0, 0xf8, 0x22, 0xde, 0xa9);
|
||
|
#else
|
||
|
// {87D3CB66-BA2E-11CF-B9D6-00A0C9083362}
|
||
|
DEFINE_GUID(CLSID_WalletPayment, 0x87d3cb66, 0xba2e, 0x11cf, 0xb9, 0xd6, 0x0, 0xa0, 0xc9, 0x08, 0x33, 0x62);
|
||
|
#endif
|
||
|
|
||
|
// WAB GUID for JIT
|
||
|
DEFINE_GUID(CLSID_WAB, 0x32714800, 0x2E5F, 0x11d0, 0x8B, 0x85, 0x00, 0xAA, 0x00, 0x44, 0xF9, 0x41);
|
||
|
|
||
|
#define EKU_CODESIGN_OFF 0
|
||
|
#define EKU_EMAIL_OFF 1
|
||
|
#define EKU_CLIENT_OFF 2
|
||
|
#define EKU_SERVER_OFF 3
|
||
|
#define EKU_DISABLE_OFF 4
|
||
|
|
||
|
|
||
|
const LPSTR g_rgszEnhkeyUsage[] =
|
||
|
{
|
||
|
szOID_PKIX_KP_CODE_SIGNING,
|
||
|
szOID_PKIX_KP_EMAIL_PROTECTION,
|
||
|
szOID_PKIX_KP_CLIENT_AUTH,
|
||
|
szOID_PKIX_KP_SERVER_AUTH,
|
||
|
szOID_YESNO_TRUST_ATTR,
|
||
|
NULL
|
||
|
};
|
||
|
|
||
|
|
||
|
typedef struct {
|
||
|
HWND hDlg; // handle to window
|
||
|
HRESULT hrUseRatings; // error=not installed; S_OK=enabled; S_FALSE=disabled
|
||
|
HINSTANCE hWinTrust; // WINTRUST/SOFTPUB library handle
|
||
|
HINSTANCE hSChannel; // schannel library handle
|
||
|
|
||
|
} CONTENTPAGE, *LPCONTENTPAGE;
|
||
|
|
||
|
BOOL ContentDlgApplyNow( LPCONTENTPAGE pCon );
|
||
|
BOOL ContentDlgEnableControls( IN HWND hDlg );
|
||
|
BOOL ContentDlgInit( IN HWND hDlg );
|
||
|
|
||
|
VOID DisplayWalletPaymentDialog(HWND hWnd);
|
||
|
VOID DisplayWalletAddressDialog(HWND hWnd);
|
||
|
|
||
|
STDAPI ResetProfileSharing(HWND hwnd);
|
||
|
EXTERN_C HRESULT ClearAutoSuggestForForms(DWORD dwClear);
|
||
|
|
||
|
|
||
|
//
|
||
|
// SecurityDlgEnableControls()
|
||
|
//
|
||
|
// Does initalization for Security Dlg.
|
||
|
//
|
||
|
// History:
|
||
|
//
|
||
|
// 6/17/96 t-gpease moved
|
||
|
//
|
||
|
BOOL ContentDlgEnableControls( IN HWND hDlg )
|
||
|
{
|
||
|
HKEY hkey=NULL;
|
||
|
|
||
|
if( g_restrict.fRatings )
|
||
|
{
|
||
|
EnableWindow( GetDlgItem(hDlg, IDC_RATINGS_TURN_ON), FALSE );
|
||
|
EnableWindow( GetDlgItem(hDlg, IDC_ADVANCED_RATINGS_BUTTON), FALSE );
|
||
|
#if 0 // don't diable the text
|
||
|
EnableDlgItem( hDlg, IDC_RATINGS_TEXT, FALSE);
|
||
|
EnableDlgItem( hDlg, IDC_ADVANCED_RATINGS_GROUPBOX, FALSE);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
if( g_restrict.fCertif || g_restrict.fCertifPub)
|
||
|
EnableWindow( GetDlgItem(hDlg, IDC_SECURITY_PUBLISHERS_BUTTON), FALSE );
|
||
|
|
||
|
if( g_restrict.fCertif || g_restrict.fCertifPers || g_restrict.fCertifSite)
|
||
|
EnableWindow( GetDlgItem(hDlg, IDC_SECURITY_SITES_BUTTON), FALSE );
|
||
|
|
||
|
if( g_restrict.fProfiles )
|
||
|
{
|
||
|
EnableWindow(GetDlgItem(hDlg, IDC_EDIT_PROFILE), FALSE);
|
||
|
}
|
||
|
|
||
|
if (hkey)
|
||
|
RegCloseKey(hkey);
|
||
|
|
||
|
#ifdef WALLET
|
||
|
if (g_restrict.fWallet)
|
||
|
{
|
||
|
EnableWindow(GetDlgItem(hDlg, IDC_PROGRAMS_WALLET_SETTINGS), FALSE);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
void InitRatingsButton(HWND hDlg, HRESULT hrEnabled)
|
||
|
{
|
||
|
TCHAR szBuf[MAX_RES_LEN+1];
|
||
|
|
||
|
UINT idString;
|
||
|
BOOL fEnableSettingsButton;
|
||
|
|
||
|
if (FAILED(hrEnabled)) {
|
||
|
/* Ratings are not installed. Disable the Settings button and
|
||
|
* set the other button to say "Enable".
|
||
|
*/
|
||
|
idString = IDS_RATINGS_TURN_ON;
|
||
|
fEnableSettingsButton = FALSE;
|
||
|
}
|
||
|
else {
|
||
|
idString = (hrEnabled == S_OK) ? IDS_RATINGS_TURN_OFF : IDS_RATINGS_TURN_ON;
|
||
|
fEnableSettingsButton = TRUE;
|
||
|
}
|
||
|
EnableWindow(GetDlgItem(hDlg, IDC_ADVANCED_RATINGS_BUTTON), fEnableSettingsButton);
|
||
|
|
||
|
if (MLLoadString(
|
||
|
idString,
|
||
|
szBuf, sizeof(szBuf)) > 0) {
|
||
|
SetDlgItemText(hDlg, IDC_RATINGS_TURN_ON, szBuf);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// ContentDlgInit()
|
||
|
//
|
||
|
// Does initalization for Content Dlg.
|
||
|
//
|
||
|
//
|
||
|
BOOL ContentDlgInit( HWND hDlg)
|
||
|
{
|
||
|
LPCONTENTPAGE pCon;
|
||
|
|
||
|
pCon = (LPCONTENTPAGE)LocalAlloc(LPTR, sizeof(*pCon));
|
||
|
if (!pCon)
|
||
|
{
|
||
|
EndDialog(hDlg, 0);
|
||
|
return FALSE; // no memory?
|
||
|
}
|
||
|
|
||
|
// tell dialog where to get info
|
||
|
SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pCon);
|
||
|
|
||
|
// save the handle to the page
|
||
|
pCon->hDlg = hDlg;
|
||
|
|
||
|
// Load the Ratings DLL (if possible)
|
||
|
g_hinstRatings = LoadLibrary(c_tszRatingsDLL);
|
||
|
|
||
|
// if not..
|
||
|
if (!g_hinstRatings)
|
||
|
g_restrict.fRatings = TRUE; // disable Ratings section
|
||
|
|
||
|
|
||
|
// set ratings dialog items...
|
||
|
|
||
|
// if MSRATING.DLL not around, then don't do this call. By not
|
||
|
// doing this, it will keep the "Enable Ratings" text on the button
|
||
|
// but greyed off.
|
||
|
if (g_hinstRatings)
|
||
|
pCon->hrUseRatings = RatingEnabledQuery();
|
||
|
|
||
|
InitRatingsButton(hDlg, pCon->hrUseRatings);
|
||
|
|
||
|
|
||
|
// if we can't find WINTRUST or SOFTPUB disable the
|
||
|
// "Publishers" button.
|
||
|
pCon->hWinTrust = LoadLibrary(TEXT("wintrust.dll"));
|
||
|
|
||
|
if ( pCon->hWinTrust )
|
||
|
{
|
||
|
g_WinTrustDlgProc =
|
||
|
(WINTRUSTDLGPROC) GetProcAddress(pCon->hWinTrust, "OpenPersonalTrustDBDialog");
|
||
|
|
||
|
// didn't find the procecdure
|
||
|
if (!g_WinTrustDlgProc)
|
||
|
{
|
||
|
// release library and try the other DLL.
|
||
|
FreeLibrary(pCon->hWinTrust);
|
||
|
|
||
|
//
|
||
|
// We can also find the same function on NT machines (and
|
||
|
// possibly future Win95s) in SOFTPUB.DLL so make another
|
||
|
// check there too.
|
||
|
//
|
||
|
pCon->hWinTrust = LoadLibrary(TEXT("softpub.dll"));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (pCon->hWinTrust && !g_WinTrustDlgProc)
|
||
|
g_WinTrustDlgProc = (WINTRUSTDLGPROC)
|
||
|
GetProcAddress(pCon->hWinTrust, "OpenPersonalTrustDBDialog");
|
||
|
|
||
|
// if after all this, we can't find the procedure...
|
||
|
if (!g_WinTrustDlgProc)
|
||
|
{
|
||
|
// disable the button
|
||
|
EnableDlgItem(hDlg, IDC_SECURITY_PUBLISHERS_BUTTON, FALSE);
|
||
|
}
|
||
|
|
||
|
// Only present UI for flushing the SSL cache on Whistler or greater
|
||
|
// This is the minimum version which has the default behavior of
|
||
|
// maintaining the SSL cache for all processes in a logon session.
|
||
|
//
|
||
|
// Note: This support was also added for Win2K SP2, but no cache
|
||
|
// clearing functionality was added. It's also not enabled
|
||
|
// by default.
|
||
|
if (IsOS(OS_WHISTLERORGREATER))
|
||
|
{
|
||
|
pCon->hSChannel = LoadLibrary(TEXT("SCHANNEL.DLL"));
|
||
|
if (pCon->hSChannel)
|
||
|
{
|
||
|
g_pfnSslEmptyCacheW = (SSL_EMPTY_CACHE_FN_W) GetProcAddress(pCon->hSChannel, "SslEmptyCacheW");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(!g_pfnSslEmptyCacheW)
|
||
|
{
|
||
|
ShowWindow(GetDlgItem(hDlg, IDC_SECURITY_CLEAR_SSL_CACHE_BUTTON), SW_HIDE);
|
||
|
EnableWindow( GetDlgItem(hDlg, IDC_SECURITY_CLEAR_SSL_CACHE_BUTTON), FALSE );
|
||
|
}
|
||
|
|
||
|
#ifdef WALLET
|
||
|
EnableDlgItem(hDlg, IDC_PROGRAMS_WALLET_SETTINGS, TRUE);
|
||
|
#endif
|
||
|
|
||
|
ContentDlgEnableControls(hDlg);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//
|
||
|
// ContentOnCommand()
|
||
|
//
|
||
|
// Handles Content Dialog's window messages
|
||
|
//
|
||
|
// History:
|
||
|
//
|
||
|
// 6/17/96 t-gpease created
|
||
|
//
|
||
|
void ContentOnCommand(LPCONTENTPAGE pCon, UINT id, UINT nCmd)
|
||
|
{
|
||
|
switch (id) {
|
||
|
|
||
|
case IDC_ADVANCED_RATINGS_BUTTON:
|
||
|
{
|
||
|
RatingSetupUI(pCon->hDlg, (LPCSTR) NULL);
|
||
|
}
|
||
|
break; // IDC_ADVANCED_RATINGS_BUTTON
|
||
|
|
||
|
case IDC_RATINGS_TURN_ON:
|
||
|
{
|
||
|
if (SUCCEEDED(RatingEnable(pCon->hDlg, (LPCSTR)NULL,
|
||
|
pCon->hrUseRatings != S_OK)))
|
||
|
{
|
||
|
pCon->hrUseRatings = RatingEnabledQuery();
|
||
|
InitRatingsButton(pCon->hDlg, pCon->hrUseRatings);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case IDC_SECURITY_CLEAR_SSL_CACHE_BUTTON:
|
||
|
{
|
||
|
if (g_pfnSslEmptyCacheW && (*g_pfnSslEmptyCacheW)(NULL, 0))
|
||
|
{
|
||
|
DWORD dwCount;
|
||
|
// Leverage a private cache header data counter
|
||
|
// that was never used to avoid passing a reg value.
|
||
|
if (IncrementUrlCacheHeaderData(CACHE_HEADER_DATA_DOWNLOAD_PARTIAL, &dwCount))
|
||
|
{
|
||
|
// Display message about clearing the cache OK.
|
||
|
TCHAR szText[MAX_PATH], szTitle[80];
|
||
|
|
||
|
MLLoadShellLangString(IDS_CLEAR_SSL_CACHE_TEXT, szText, ARRAYSIZE(szText));
|
||
|
MLLoadShellLangString(IDS_CLEAR_SSL_CACHE_TITLE, szTitle, ARRAYSIZE(szTitle));
|
||
|
|
||
|
MessageBox(pCon->hDlg, szText, szTitle, MB_ICONINFORMATION | MB_OK);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case IDC_SECURITY_SITES_BUTTON:
|
||
|
{
|
||
|
CRYPTUI_CERT_MGR_STRUCT ccm = {0};
|
||
|
ccm.dwSize = sizeof(ccm);
|
||
|
ccm.hwndParent = pCon->hDlg;
|
||
|
CryptUIDlgCertMgr(&ccm);
|
||
|
// if (!g_hinstCryptui)
|
||
|
// {
|
||
|
// EnableWindow(GetDlgItem(pCon->hDlg, IDC_SECURITY_SITES_BUTTON), FALSE);
|
||
|
// }
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case IDC_SECURITY_PUBLISHERS_BUTTON:
|
||
|
{
|
||
|
if (g_WinTrustDlgProc)
|
||
|
{
|
||
|
g_WinTrustDlgProc(pCon->hDlg);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
#ifdef WALLET
|
||
|
case IDC_PROGRAMS_WALLET_SETTINGS:
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
// See if wallet is installed at all
|
||
|
if (!IsWalletPaymentAvailable())
|
||
|
{
|
||
|
uCLSSPEC clsspec;
|
||
|
|
||
|
clsspec.tyspec = TYSPEC_CLSID;
|
||
|
clsspec.tagged_union.clsid = CLSID_WalletPayment;
|
||
|
|
||
|
// If wallet isn't installed, ask user if they'd like to install it
|
||
|
hr = FaultInIEFeature(NULL, &clsspec, NULL, FIEF_FLAG_FORCE_JITUI);
|
||
|
}
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
// Wallet is installed
|
||
|
if (IsWallet3Installed())
|
||
|
{
|
||
|
// if wallet 3.0 is installed, we want to invoke the wallet UI directly
|
||
|
DisplayWalletPaymentDialog(pCon->hDlg);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// otherwise we need to pop up this intermediate dialog
|
||
|
DialogBox(MLGetHinst(), MAKEINTRESOURCE(IDD_WALLET_SETTINGS), pCon->hDlg, WalletDlgProc);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
#endif
|
||
|
|
||
|
case IDC_AUTOSUGGEST_SETTINGS:
|
||
|
{
|
||
|
DialogBox(MLGetHinst(), MAKEINTRESOURCE(IDD_AUTOSUGGEST_SETTINGS), pCon->hDlg, AutoSuggestDlgProc);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case IDC_EDIT_PROFILE:
|
||
|
{
|
||
|
HMODULE hInstWAB = NULL;
|
||
|
LPWABOBJECT lpWABObject = NULL;
|
||
|
LPADRBOOK lpAdrBook = NULL;
|
||
|
HRESULT hr=S_OK;
|
||
|
|
||
|
// Ask user to JIT in WAB if it's not installed
|
||
|
uCLSSPEC clsspec;
|
||
|
|
||
|
clsspec.tyspec = TYSPEC_CLSID;
|
||
|
clsspec.tagged_union.clsid = CLSID_WAB;
|
||
|
|
||
|
// If WAB isn't installed, ask user if they'd like to install it
|
||
|
hr = FaultInIEFeature(NULL, &clsspec, NULL, FIEF_FLAG_FORCE_JITUI);
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Figure out the location of the wab dll and try opening it.
|
||
|
TCHAR szWABDllPath[MAX_PATH];
|
||
|
DWORD dwType = 0;
|
||
|
ULONG cbData = sizeof(szWABDllPath) * sizeof(TCHAR);
|
||
|
HKEY hKey = NULL;
|
||
|
SBinary SBMe = { 0, 0};
|
||
|
|
||
|
*szWABDllPath = '\0';
|
||
|
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, WAB_DLL_PATH_KEY, 0, KEY_READ, &hKey))
|
||
|
{
|
||
|
RegQueryValueEx( hKey, TEXT(""), NULL, &dwType, (LPBYTE) szWABDllPath, &cbData);
|
||
|
RegCloseKey(hKey);
|
||
|
}
|
||
|
|
||
|
if (lstrlen(szWABDllPath) > 0 )
|
||
|
{
|
||
|
hInstWAB = LoadLibrary(szWABDllPath);
|
||
|
}
|
||
|
|
||
|
if (hInstWAB)
|
||
|
{
|
||
|
LPWABOPEN lpfnWABOpen = (LPWABOPEN) GetProcAddress(hInstWAB, "WABOpen");
|
||
|
|
||
|
if (lpfnWABOpen)
|
||
|
{
|
||
|
hr = lpfnWABOpen(&lpAdrBook, &lpWABObject, NULL, 0);
|
||
|
|
||
|
if (NULL == lpAdrBook || NULL == lpWABObject)
|
||
|
hr = E_UNEXPECTED;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32(ERROR_DLL_NOT_FOUND); // Not the right dll anyway!!
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32(ERROR_DLL_NOT_FOUND);
|
||
|
}
|
||
|
|
||
|
DWORD dwAction = 0;
|
||
|
|
||
|
// Good so far, call GetMe. WAB may create a new entry in this call.
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
hr = lpWABObject->GetMe(lpAdrBook, 0, &dwAction, &SBMe, 0);
|
||
|
|
||
|
if (0 == SBMe.cb || NULL == SBMe.lpb)
|
||
|
hr = E_UNEXPECTED;
|
||
|
}
|
||
|
|
||
|
// This shows the final UI. If WAB created a new entry in GetMe, they
|
||
|
// already showed this UI and we don't need to do it again.
|
||
|
if (SUCCEEDED(hr) && !(dwAction & WABOBJECT_ME_NEW))
|
||
|
{
|
||
|
hr = lpAdrBook->Details( (LPULONG) &pCon->hDlg,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
SBMe.cb,
|
||
|
(LPENTRYID)SBMe.lpb,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
0);
|
||
|
|
||
|
}
|
||
|
if (lpWABObject)
|
||
|
{
|
||
|
if (SBMe.lpb != NULL)
|
||
|
lpWABObject->FreeBuffer(SBMe.lpb);
|
||
|
|
||
|
lpWABObject->Release();
|
||
|
}
|
||
|
|
||
|
if (lpAdrBook)
|
||
|
lpAdrBook->Release();
|
||
|
|
||
|
if (hInstWAB)
|
||
|
FreeLibrary(hInstWAB);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
} // ContentOnCommand()
|
||
|
|
||
|
|
||
|
/****************************************************************
|
||
|
Name: ContentDlgProc
|
||
|
|
||
|
SYNOPSIS: Set various security issue settings.
|
||
|
|
||
|
****************************************************************/
|
||
|
|
||
|
INT_PTR CALLBACK ContentDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
|
||
|
{
|
||
|
LPCONTENTPAGE pCon;
|
||
|
|
||
|
if (uMsg == WM_INITDIALOG)
|
||
|
return ContentDlgInit( hDlg );
|
||
|
else
|
||
|
pCon = (LPCONTENTPAGE) GetWindowLongPtr(hDlg, DWLP_USER);
|
||
|
|
||
|
if (!pCon)
|
||
|
return FALSE;
|
||
|
|
||
|
switch (uMsg)
|
||
|
{
|
||
|
case WM_COMMAND:
|
||
|
ContentOnCommand(pCon, LOWORD(wParam), HIWORD(wParam));
|
||
|
return TRUE;
|
||
|
|
||
|
case WM_NOTIFY:
|
||
|
{
|
||
|
NMHDR *lpnm = (NMHDR *) lParam;
|
||
|
|
||
|
ASSERT(lpnm);
|
||
|
switch (lpnm->code) {
|
||
|
case PSN_QUERYCANCEL:
|
||
|
case PSN_KILLACTIVE:
|
||
|
case PSN_RESET:
|
||
|
SetWindowLongPtr( pCon->hDlg, DWLP_MSGRESULT, FALSE );
|
||
|
return TRUE;
|
||
|
|
||
|
case PSN_APPLY:
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case WM_HELP: // F1
|
||
|
ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
|
||
|
HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
|
||
|
break;
|
||
|
|
||
|
case WM_CONTEXTMENU: // right mouse click
|
||
|
ResWinHelp( (HWND) wParam, IDS_HELPFILE,
|
||
|
HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
|
||
|
break;
|
||
|
|
||
|
case WM_DESTROY:
|
||
|
ASSERT(pCon);
|
||
|
if (pCon)
|
||
|
{
|
||
|
if (pCon->hWinTrust)
|
||
|
{
|
||
|
FreeLibrary(pCon->hWinTrust);
|
||
|
g_WinTrustDlgProc = NULL;
|
||
|
}
|
||
|
if (pCon->hSChannel)
|
||
|
{
|
||
|
FreeLibrary(pCon->hSChannel);
|
||
|
g_pfnSslEmptyCacheW = NULL;
|
||
|
}
|
||
|
LocalFree(pCon);
|
||
|
}
|
||
|
SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)NULL);
|
||
|
break;
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
typedef struct tagSITECERTDIALOGINFO {
|
||
|
HWND hDlg;
|
||
|
HWND hwndList;
|
||
|
HWND hwndCombo;
|
||
|
int iSel;
|
||
|
HCERTSTORE hCertStore;
|
||
|
BOOL fInitializing;
|
||
|
} SITECERTDIALOGINFO, *LPSITECERTDIALOGINFO;
|
||
|
|
||
|
BOOL _SearchKeyUsage(CERT_ENHKEY_USAGE *pUsage, LPSTR pszUsageIdentifier)
|
||
|
{
|
||
|
DWORD i;
|
||
|
|
||
|
for (i = 0; i < pUsage->cUsageIdentifier; i++)
|
||
|
{
|
||
|
if (StrCmpA(pUsage->rgpszUsageIdentifier[i], pszUsageIdentifier) == 0)
|
||
|
{
|
||
|
return(TRUE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
BOOL _IsKnownUsage(char *pszTest)
|
||
|
{
|
||
|
char **ppszKnown;
|
||
|
|
||
|
ppszKnown = (char **)g_rgszEnhkeyUsage;
|
||
|
|
||
|
while (*ppszKnown)
|
||
|
{
|
||
|
if (StrCmpA(*ppszKnown, pszTest) == 0)
|
||
|
{
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
ppszKnown++;
|
||
|
}
|
||
|
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
void __AddAllKnownEKU(PCCERT_CONTEXT pCert)
|
||
|
{
|
||
|
char **ppszKnown;
|
||
|
|
||
|
ppszKnown = (char **)g_rgszEnhkeyUsage;
|
||
|
|
||
|
while (*ppszKnown)
|
||
|
{
|
||
|
CertAddEnhancedKeyUsageIdentifier(pCert, *ppszKnown);
|
||
|
|
||
|
ppszKnown++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BOOL _AnyKnownUsage(CERT_ENHKEY_USAGE *pUsage)
|
||
|
{
|
||
|
DWORD i;
|
||
|
|
||
|
for (i = 0; i < pUsage->cUsageIdentifier; i++)
|
||
|
{
|
||
|
if (_IsKnownUsage(pUsage->rgpszUsageIdentifier[i]))
|
||
|
{
|
||
|
return(TRUE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
BOOL _IsUsageEnabled(PCCERT_CONTEXT pCertContext, LPSTR pszUsageIdentifier, BOOL * pfFound)
|
||
|
{
|
||
|
CERT_ENHKEY_USAGE *pUsage;
|
||
|
DWORD cbUsage;
|
||
|
|
||
|
|
||
|
*pfFound = FALSE;
|
||
|
|
||
|
//
|
||
|
// first, check the Extensions to see if we should even display it!
|
||
|
//
|
||
|
cbUsage = 0;
|
||
|
CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &cbUsage);
|
||
|
|
||
|
if (cbUsage > 0)
|
||
|
{
|
||
|
//
|
||
|
// we have some... make sure ours is in the list
|
||
|
//
|
||
|
if (!(pUsage = (CERT_ENHKEY_USAGE *)LocalAlloc(LPTR, cbUsage)))
|
||
|
{
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &cbUsage);
|
||
|
|
||
|
if (!(_SearchKeyUsage(pUsage, pszUsageIdentifier)))
|
||
|
{
|
||
|
LocalFree((void *)pUsage);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
LocalFree((void *)pUsage);
|
||
|
}
|
||
|
|
||
|
*pfFound = TRUE; // the cert should go in the list!
|
||
|
|
||
|
//
|
||
|
// ethier there where no assertions made by the CA or we found it! continue on...
|
||
|
//
|
||
|
|
||
|
//
|
||
|
// second, check the properties to see if we should check the box
|
||
|
//
|
||
|
cbUsage = 0;
|
||
|
CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, NULL, &cbUsage);
|
||
|
|
||
|
if (cbUsage > 0)
|
||
|
{
|
||
|
//
|
||
|
// we have properties... make sure we aren't disabled
|
||
|
//
|
||
|
if (!(pUsage = (CERT_ENHKEY_USAGE *)LocalAlloc(LPTR, cbUsage)))
|
||
|
{
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, pUsage, &cbUsage);
|
||
|
|
||
|
if (_SearchKeyUsage(pUsage, g_rgszEnhkeyUsage[EKU_DISABLE_OFF]))
|
||
|
{
|
||
|
//
|
||
|
// the user has disabled the cert... keep it in the list un-checked
|
||
|
//
|
||
|
LocalFree((void *)pUsage);
|
||
|
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
if (!(_SearchKeyUsage(pUsage, pszUsageIdentifier)))
|
||
|
{
|
||
|
//
|
||
|
// the user has set some, but, disabled this one... keep in the list un-checked
|
||
|
//
|
||
|
LocalFree((void *)pUsage);
|
||
|
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
LocalFree((void *)pUsage);
|
||
|
}
|
||
|
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL SiteCert_InitListView(LPSITECERTDIALOGINFO pscdi)
|
||
|
{
|
||
|
PCCERT_CONTEXT pCertContext = NULL;
|
||
|
|
||
|
// delete all items currently in the listview
|
||
|
// we'll get called back via LVN_DELETEITEM with the lParam so we can free the cert context
|
||
|
ListView_DeleteAllItems(pscdi->hwndList);
|
||
|
|
||
|
pscdi->hCertStore = CertOpenSystemStoreA(NULL, "ROOT");
|
||
|
|
||
|
if (pscdi->hCertStore)
|
||
|
{
|
||
|
LPSTR pszEnhkeyUsage;
|
||
|
|
||
|
INT_PTR iSel;
|
||
|
|
||
|
iSel = SendMessage(pscdi->hwndCombo, CB_GETCURSEL, 0,0);
|
||
|
|
||
|
pszEnhkeyUsage = (LPSTR)SendMessage(pscdi->hwndCombo, CB_GETITEMDATA, iSel, 0);
|
||
|
|
||
|
while (pCertContext = CertEnumCertificatesInStore(pscdi->hCertStore, pCertContext))
|
||
|
{
|
||
|
CHAR szCertA[MAX_PATH];
|
||
|
TCHAR szCert[MAX_PATH];
|
||
|
DWORD cbszCert = ARRAYSIZE(szCertA);
|
||
|
DWORD dwEnabled;
|
||
|
BOOL fFound;
|
||
|
|
||
|
dwEnabled = _IsUsageEnabled(pCertContext, (LPSTR)pszEnhkeyUsage, &fFound);
|
||
|
|
||
|
// if not found, then continue with next
|
||
|
if (!fFound)
|
||
|
continue;
|
||
|
|
||
|
//ParseX509EncodedCertificateForListBoxEntry(pCertContext->pbCertEncoded, pCertContext->cbCertEncoded, szCert, &cbszCert);
|
||
|
ParseX509EncodedCertificateForListBoxEntry((BYTE *)pCertContext, -1, szCertA, &cbszCert);
|
||
|
#ifdef UNICODE
|
||
|
SHAnsiToUnicode(szCertA, szCert, ARRAYSIZE(szCert));
|
||
|
#else
|
||
|
StrCpy(szCert, szCertA);
|
||
|
#endif
|
||
|
LV_ITEM lvi = { 0 };
|
||
|
|
||
|
lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM;
|
||
|
lvi.iItem = -1;
|
||
|
lvi.pszText = szCert; // (LPSTR)pCertContext->pCertInfo->Subject.pbData;
|
||
|
lvi.cchTextMax = ARRAYSIZE(szCert); // pCertContext->pCertInfo->Subject.cbData;
|
||
|
|
||
|
lvi.stateMask = LVIS_STATEIMAGEMASK;
|
||
|
lvi.state = dwEnabled ? 0x00002000 : 0x00001000;
|
||
|
lvi.lParam = (LPARAM)CertDuplicateCertificateContext(pCertContext);
|
||
|
|
||
|
// insert and set state
|
||
|
ListView_SetItemState(pscdi->hwndList,
|
||
|
ListView_InsertItem(pscdi->hwndList, &lvi),
|
||
|
dwEnabled ? 0x00002000 : 0x00001000,
|
||
|
LVIS_STATEIMAGEMASK);
|
||
|
|
||
|
}
|
||
|
// show the items
|
||
|
ListView_RedrawItems(pscdi->hwndList, 0, ListView_GetItemCount(pscdi->hwndList));
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
////
|
||
|
//// 08-Sep-1997: pberkman
|
||
|
////
|
||
|
//// PRIVATE function: _SiteCertAdjustProperties
|
||
|
////
|
||
|
//// based on what the user just checked/unchecked, set the
|
||
|
//// appropriate OID usage or remove it.
|
||
|
////
|
||
|
void _SiteCertAdjustProperties(LPSITECERTDIALOGINFO pscdi, NM_LISTVIEW *pListView)
|
||
|
{
|
||
|
DWORD_PTR dwSel;
|
||
|
char *pszOID;
|
||
|
DWORD cbUsage;
|
||
|
CERT_ENHKEY_USAGE *pUsage;
|
||
|
|
||
|
|
||
|
//
|
||
|
// if we are in the initdialog get out!
|
||
|
//
|
||
|
if (pscdi->fInitializing)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// make sure we have the property set
|
||
|
//
|
||
|
dwSel = SendMessage(pscdi->hwndCombo, CB_GETCURSEL, 0, 0);
|
||
|
|
||
|
if (dwSel == CB_ERR)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
pszOID = (char*) SendMessage(pscdi->hwndCombo, CB_GETITEMDATA, (WPARAM)dwSel, 0);
|
||
|
|
||
|
if (!(pszOID) || ((DWORD_PTR)pszOID == CB_ERR))
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (pListView->uNewState & 0x00001000) // unchecked
|
||
|
{
|
||
|
|
||
|
//
|
||
|
// the user unchecked one of the certs.
|
||
|
//
|
||
|
// 1. if there are no properties, add all others -- HACKHACK!
|
||
|
//
|
||
|
cbUsage = 0;
|
||
|
CertGetEnhancedKeyUsage((PCCERT_CONTEXT)pListView->lParam, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG,
|
||
|
NULL, &cbUsage);
|
||
|
|
||
|
if (cbUsage == 0)
|
||
|
{
|
||
|
// add all
|
||
|
__AddAllKnownEKU((PCCERT_CONTEXT)pListView->lParam);
|
||
|
|
||
|
// remove this one
|
||
|
CertRemoveEnhancedKeyUsageIdentifier((PCCERT_CONTEXT)pListView->lParam, pszOID);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (!(pUsage = (CERT_ENHKEY_USAGE *)LocalAlloc(LPTR, cbUsage)))
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
CertGetEnhancedKeyUsage((PCCERT_CONTEXT)pListView->lParam, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG,
|
||
|
pUsage, &cbUsage);
|
||
|
//
|
||
|
// 2. if there are properties.
|
||
|
// a. if this is the last known one, and it matches this, delete it and add the "disable"
|
||
|
//
|
||
|
if (pUsage->cUsageIdentifier == 1)
|
||
|
{
|
||
|
if (StrCmpA(pUsage->rgpszUsageIdentifier[0], pszOID) == 0)
|
||
|
{
|
||
|
CertRemoveEnhancedKeyUsageIdentifier((PCCERT_CONTEXT)pListView->lParam, pszOID);
|
||
|
CertAddEnhancedKeyUsageIdentifier((PCCERT_CONTEXT)pListView->lParam,
|
||
|
g_rgszEnhkeyUsage[EKU_DISABLE_OFF]);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//
|
||
|
// b. if there are more than one, just try to remove this one
|
||
|
//
|
||
|
CertRemoveEnhancedKeyUsageIdentifier((PCCERT_CONTEXT)pListView->lParam, pszOID);
|
||
|
}
|
||
|
|
||
|
LocalFree((void *)pUsage);
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (pListView->uNewState & 0x00002000) // checked
|
||
|
{
|
||
|
CertAddEnhancedKeyUsageIdentifier((PCCERT_CONTEXT)pListView->lParam, pszOID);
|
||
|
|
||
|
//
|
||
|
// just in case, remove the disable!
|
||
|
//
|
||
|
CertRemoveEnhancedKeyUsageIdentifier((PCCERT_CONTEXT)pListView->lParam,
|
||
|
g_rgszEnhkeyUsage[EKU_DISABLE_OFF]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BOOL SiteCert_OnNotify(LPSITECERTDIALOGINFO pscdi, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
NM_LISTVIEW *pnmlv = (NM_LISTVIEW *)lParam;
|
||
|
|
||
|
switch (pnmlv->hdr.code) {
|
||
|
case LVN_ITEMCHANGED:
|
||
|
{
|
||
|
// check the current state of selection
|
||
|
int iSel = ListView_GetNextItem(pscdi->hwndList, -1, LVNI_SELECTED);
|
||
|
|
||
|
// check to see if we need to enable/disable the "DELETE" and "VIEW" buttons
|
||
|
EnableWindow(GetDlgItem(pscdi->hDlg, IDC_DELETECERT), iSel != -1);
|
||
|
EnableWindow(GetDlgItem(pscdi->hDlg, IDC_VIEWCERT), iSel != -1);
|
||
|
|
||
|
if ((pnmlv->uChanged & LVIF_STATE) && (GetFocus() == pscdi->hwndList))
|
||
|
{
|
||
|
_SiteCertAdjustProperties(pscdi, pnmlv);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
case LVN_DELETEITEM:
|
||
|
CertFreeCertificateContext((PCCERT_CONTEXT)pnmlv->lParam);
|
||
|
break;
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
typedef struct tagNEWSITECERTINFO
|
||
|
{
|
||
|
LPVOID lpvCertData;
|
||
|
DWORD cbCert;
|
||
|
|
||
|
BOOL fCertEnabled;
|
||
|
BOOL fNetworkClient;
|
||
|
BOOL fNetworkServer;
|
||
|
BOOL fSecureEmail;
|
||
|
BOOL fSoftwarePublishing;
|
||
|
|
||
|
} NEWSITECERTINFO, *LPNEWSITECERTINFO;
|
||
|
|
||
|
|
||
|
BOOL NewSiteCert_AddCert(LPNEWSITECERTINFO pnsci)
|
||
|
{
|
||
|
|
||
|
HCERTSTORE hCertStore = NULL;
|
||
|
PCCERT_CONTEXT pCertContext;
|
||
|
BOOL fRet = FALSE;
|
||
|
|
||
|
hCertStore = CertOpenSystemStoreA(NULL, "ROOT");
|
||
|
|
||
|
if (hCertStore)
|
||
|
{
|
||
|
pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
|
||
|
(LPBYTE)(pnsci->lpvCertData),
|
||
|
pnsci->cbCert);
|
||
|
|
||
|
if (pCertContext)
|
||
|
{
|
||
|
if (CertCompareCertificateName(X509_ASN_ENCODING,
|
||
|
&pCertContext->pCertInfo->Subject,
|
||
|
&pCertContext->pCertInfo->Issuer))
|
||
|
{
|
||
|
|
||
|
CertFreeCertificateContext(pCertContext);
|
||
|
|
||
|
fRet = CertAddEncodedCertificateToStore(hCertStore,
|
||
|
X509_ASN_ENCODING,
|
||
|
(LPBYTE)(pnsci->lpvCertData),
|
||
|
pnsci->cbCert,
|
||
|
CERT_STORE_ADD_REPLACE_EXISTING,
|
||
|
&pCertContext);
|
||
|
if (fRet)
|
||
|
{
|
||
|
# define l_USAGE_MAX 24
|
||
|
|
||
|
CERT_ENHKEY_USAGE ceku = {0};
|
||
|
LPSTR rgpszUsageIdentifier[l_USAGE_MAX];
|
||
|
|
||
|
if (pnsci->fNetworkClient)
|
||
|
{
|
||
|
rgpszUsageIdentifier[ceku.cUsageIdentifier] = g_rgszEnhkeyUsage[EKU_CLIENT_OFF];
|
||
|
if (rgpszUsageIdentifier[ceku.cUsageIdentifier])
|
||
|
ceku.cUsageIdentifier++;
|
||
|
}
|
||
|
if (pnsci->fNetworkServer)
|
||
|
{
|
||
|
rgpszUsageIdentifier[ceku.cUsageIdentifier] = g_rgszEnhkeyUsage[EKU_SERVER_OFF];
|
||
|
if (rgpszUsageIdentifier[ceku.cUsageIdentifier])
|
||
|
ceku.cUsageIdentifier++;
|
||
|
}
|
||
|
if (pnsci->fSecureEmail)
|
||
|
{
|
||
|
rgpszUsageIdentifier[ceku.cUsageIdentifier] = g_rgszEnhkeyUsage[EKU_EMAIL_OFF];
|
||
|
if (rgpszUsageIdentifier[ceku.cUsageIdentifier])
|
||
|
ceku.cUsageIdentifier++;
|
||
|
}
|
||
|
if (pnsci->fSoftwarePublishing)
|
||
|
{
|
||
|
rgpszUsageIdentifier[ceku.cUsageIdentifier] = g_rgszEnhkeyUsage[EKU_CODESIGN_OFF];
|
||
|
if (rgpszUsageIdentifier[ceku.cUsageIdentifier])
|
||
|
ceku.cUsageIdentifier++;
|
||
|
}
|
||
|
|
||
|
if (!(pnsci->fCertEnabled))
|
||
|
{
|
||
|
// turn everything off!!!
|
||
|
rgpszUsageIdentifier[ceku.cUsageIdentifier] = g_rgszEnhkeyUsage[EKU_DISABLE_OFF];
|
||
|
if (rgpszUsageIdentifier[ceku.cUsageIdentifier])
|
||
|
ceku.cUsageIdentifier++;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// now, add any "unknown" extensions that the CA may have put on just
|
||
|
// so verification will succeed!
|
||
|
//
|
||
|
CERT_ENHKEY_USAGE *pUsage;
|
||
|
DWORD cbUsage;
|
||
|
DWORD i;
|
||
|
|
||
|
pUsage = NULL;
|
||
|
cbUsage = 0;
|
||
|
CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &cbUsage);
|
||
|
|
||
|
if (cbUsage > 0)
|
||
|
{
|
||
|
if (pUsage = (PCERT_ENHKEY_USAGE)LocalAlloc(LMEM_FIXED, cbUsage))
|
||
|
{
|
||
|
CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG,
|
||
|
pUsage, &cbUsage);
|
||
|
|
||
|
for (i = 0; i < pUsage->cUsageIdentifier; i++)
|
||
|
{
|
||
|
if (ceku.cUsageIdentifier >= l_USAGE_MAX)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (pUsage->rgpszUsageIdentifier[i])
|
||
|
{
|
||
|
if (!(_IsKnownUsage(pUsage->rgpszUsageIdentifier[i])))
|
||
|
{
|
||
|
rgpszUsageIdentifier[ceku.cUsageIdentifier] = pUsage->rgpszUsageIdentifier[i];
|
||
|
ceku.cUsageIdentifier++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ceku.rgpszUsageIdentifier = (LPSTR *)rgpszUsageIdentifier;
|
||
|
fRet = CertSetEnhancedKeyUsage(pCertContext, &ceku);
|
||
|
|
||
|
if (pUsage)
|
||
|
{
|
||
|
LocalFree((void *)pUsage);
|
||
|
}
|
||
|
|
||
|
CertFreeCertificateContext(pCertContext);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
CertCloseStore(hCertStore, CERT_CLOSE_STORE_CHECK_FLAG);
|
||
|
}
|
||
|
return fRet;
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
////
|
||
|
//// 15-Aug-1997: pberkman
|
||
|
////
|
||
|
//// PRIVATE function: NewSiteCert_SetAvailableAuthorityCheckboxes
|
||
|
////
|
||
|
//// set the check boxes in the "New Site Certificate" dialog box
|
||
|
//// based on the Authority Extensions and Properties.
|
||
|
////
|
||
|
//// if there are no Authority Ext or Prop's, then the certificate
|
||
|
//// has the potential for the user to enable for all. Otherwise,
|
||
|
//// the user can ONLY select the ones that the issuer (or MS) has
|
||
|
//// entrusted the certificate for.
|
||
|
////
|
||
|
typedef struct l_CERTUSAGES_
|
||
|
{
|
||
|
char *pszOID;
|
||
|
DWORD dwControlId;
|
||
|
BOOL fEnabled;
|
||
|
|
||
|
} l_CERTUSAGES;
|
||
|
|
||
|
BOOL NewSiteCert_SetAvailableAuthorityCheckboxes(HWND hDlg, LPNEWSITECERTINFO pnsci,
|
||
|
BOOL fInitialize)
|
||
|
{
|
||
|
l_CERTUSAGES asUsages[] =
|
||
|
{
|
||
|
szOID_PKIX_KP_CLIENT_AUTH, IDC_CHECK_NETWORK_CLIENT, FALSE,
|
||
|
szOID_PKIX_KP_SERVER_AUTH, IDC_CHECK_NETWORK_SERVER, FALSE,
|
||
|
szOID_PKIX_KP_EMAIL_PROTECTION, IDC_CHECK_SECURE_EMAIL, FALSE,
|
||
|
szOID_PKIX_KP_CODE_SIGNING, IDC_CHECK_SOFTWARE_PUBLISHING, FALSE,
|
||
|
NULL, 0, FALSE
|
||
|
};
|
||
|
|
||
|
l_CERTUSAGES *psUsages;
|
||
|
PCCERT_CONTEXT pCertContext;
|
||
|
DWORD cbUsage;
|
||
|
PCERT_ENHKEY_USAGE pUsage;
|
||
|
|
||
|
if (fInitialize)
|
||
|
{
|
||
|
CheckDlgButton(hDlg, IDC_CHECK_ENABLE_CERT, BST_CHECKED);
|
||
|
|
||
|
CheckDlgButton(hDlg, IDC_CHECK_NETWORK_CLIENT, BST_CHECKED);
|
||
|
CheckDlgButton(hDlg, IDC_CHECK_NETWORK_SERVER, BST_CHECKED);
|
||
|
CheckDlgButton(hDlg, IDC_CHECK_SECURE_EMAIL, BST_CHECKED);
|
||
|
CheckDlgButton(hDlg, IDC_CHECK_SOFTWARE_PUBLISHING, BST_CHECKED);
|
||
|
}
|
||
|
|
||
|
pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
|
||
|
(LPBYTE)(pnsci->lpvCertData),
|
||
|
pnsci->cbCert);
|
||
|
|
||
|
if (!(pCertContext))
|
||
|
{
|
||
|
psUsages = &asUsages[0];
|
||
|
|
||
|
while (psUsages->pszOID)
|
||
|
{
|
||
|
EnableWindow(GetDlgItem(hDlg, psUsages->dwControlId), TRUE);
|
||
|
|
||
|
psUsages++;
|
||
|
}
|
||
|
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
cbUsage = 0;
|
||
|
|
||
|
CertGetEnhancedKeyUsage(pCertContext, 0, NULL, &cbUsage);
|
||
|
|
||
|
if (cbUsage < 1)
|
||
|
{
|
||
|
// none defined... leave all enabled.
|
||
|
CertFreeCertificateContext(pCertContext);
|
||
|
psUsages = &asUsages[0];
|
||
|
|
||
|
while (psUsages->pszOID)
|
||
|
{
|
||
|
EnableWindow(GetDlgItem(hDlg, psUsages->dwControlId), TRUE);
|
||
|
|
||
|
psUsages++;
|
||
|
}
|
||
|
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
if (!(pUsage = (PCERT_ENHKEY_USAGE)LocalAlloc(LMEM_FIXED, cbUsage)))
|
||
|
{
|
||
|
CertFreeCertificateContext(pCertContext);
|
||
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
if (!(CertGetEnhancedKeyUsage(pCertContext, 0, pUsage, &cbUsage)))
|
||
|
{
|
||
|
CertFreeCertificateContext(pCertContext);
|
||
|
LocalFree(pUsage);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
if (pUsage->cUsageIdentifier == 0)
|
||
|
{
|
||
|
CertFreeCertificateContext(pCertContext);
|
||
|
LocalFree(pUsage);
|
||
|
// none defined... leave all enabled.
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
CertFreeCertificateContext(pCertContext);
|
||
|
|
||
|
for (int i = 0; i < (int)pUsage->cUsageIdentifier; i++)
|
||
|
{
|
||
|
psUsages = &asUsages[0];
|
||
|
|
||
|
while (psUsages->pszOID)
|
||
|
{
|
||
|
if (StrCmpA(pUsage->rgpszUsageIdentifier[i], psUsages->pszOID) == 0)
|
||
|
{
|
||
|
psUsages->fEnabled = TRUE;
|
||
|
}
|
||
|
psUsages++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
LocalFree(pUsage);
|
||
|
|
||
|
psUsages = &asUsages[0];
|
||
|
|
||
|
while (psUsages->pszOID)
|
||
|
{
|
||
|
if (fInitialize)
|
||
|
{
|
||
|
CheckDlgButton(hDlg, psUsages->dwControlId,
|
||
|
(psUsages->fEnabled) ? BST_CHECKED : BST_UNCHECKED);
|
||
|
}
|
||
|
|
||
|
EnableWindow(GetDlgItem(hDlg, psUsages->dwControlId), psUsages->fEnabled);
|
||
|
|
||
|
psUsages++;
|
||
|
}
|
||
|
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
void NewSiteCert_CenterDialog(HWND hDlg)
|
||
|
{
|
||
|
RECT rcDlg;
|
||
|
RECT rcArea;
|
||
|
RECT rcCenter;
|
||
|
HWND hWndParent;
|
||
|
HWND hWndCenter;
|
||
|
DWORD dwStyle;
|
||
|
int w_Dlg;
|
||
|
int h_Dlg;
|
||
|
int xLeft;
|
||
|
int yTop;
|
||
|
|
||
|
GetWindowRect(hDlg, &rcDlg);
|
||
|
|
||
|
dwStyle = (DWORD)GetWindowLong(hDlg, GWL_STYLE);
|
||
|
|
||
|
if (dwStyle & WS_CHILD)
|
||
|
{
|
||
|
hWndCenter = GetParent(hDlg);
|
||
|
|
||
|
hWndParent = GetParent(hDlg);
|
||
|
|
||
|
GetClientRect(hWndParent, &rcArea);
|
||
|
GetClientRect(hWndCenter, &rcCenter);
|
||
|
MapWindowPoints(hWndCenter, hWndParent, (POINT *)&rcCenter, 2);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hWndCenter = GetWindow(hDlg, GW_OWNER);
|
||
|
|
||
|
if (hWndCenter)
|
||
|
{
|
||
|
dwStyle = (DWORD)GetWindowLong(hWndCenter, GWL_STYLE);
|
||
|
|
||
|
if (!(dwStyle & WS_VISIBLE) || (dwStyle & WS_MINIMIZE))
|
||
|
{
|
||
|
hWndCenter = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcArea, NULL);
|
||
|
|
||
|
if (hWndCenter)
|
||
|
{
|
||
|
GetWindowRect(hWndCenter, &rcCenter);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
rcCenter = rcArea;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
w_Dlg = rcDlg.right - rcDlg.left;
|
||
|
h_Dlg = rcDlg.bottom - rcDlg.top;
|
||
|
|
||
|
xLeft = (rcCenter.left + rcCenter.right) / 2 - w_Dlg / 2;
|
||
|
yTop = (rcCenter.top + rcCenter.bottom) / 2 - h_Dlg / 2;
|
||
|
|
||
|
if (xLeft < rcArea.left)
|
||
|
{
|
||
|
xLeft = rcArea.left;
|
||
|
}
|
||
|
else if ((xLeft + w_Dlg) > rcArea.right)
|
||
|
{
|
||
|
xLeft = rcArea.right - w_Dlg;
|
||
|
}
|
||
|
|
||
|
if (yTop < rcArea.top)
|
||
|
{
|
||
|
yTop = rcArea.top;
|
||
|
}
|
||
|
else if ((yTop + h_Dlg) > rcArea.bottom)
|
||
|
{
|
||
|
yTop = rcArea.bottom - h_Dlg;
|
||
|
}
|
||
|
|
||
|
SetWindowPos(hDlg, NULL, xLeft, yTop, -1, -1, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
|
||
|
}
|
||
|
|
||
|
|
||
|
INT_PTR CALLBACK NewSiteCert_DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
|
||
|
{
|
||
|
LPNEWSITECERTINFO pnsci = (LPNEWSITECERTINFO)GetWindowLongPtr(hDlg, DWLP_USER);
|
||
|
|
||
|
switch (uMsg) {
|
||
|
case WM_INITDIALOG:
|
||
|
{
|
||
|
DWORD dwFileSize;
|
||
|
DWORD cbRead;
|
||
|
HANDLE hf;
|
||
|
LPTSTR lpszCmdLine = (LPTSTR)lParam;
|
||
|
DWORD dwError;
|
||
|
|
||
|
hf = CreateFile(lpszCmdLine, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||
|
if (hf == INVALID_HANDLE_VALUE)
|
||
|
{
|
||
|
dwError = GetLastError();
|
||
|
goto initError;
|
||
|
}
|
||
|
|
||
|
dwFileSize = GetFileSize(hf, NULL);
|
||
|
if (dwFileSize == (unsigned)-1)
|
||
|
goto initError;
|
||
|
|
||
|
pnsci = (LPNEWSITECERTINFO)LocalAlloc(LPTR, sizeof(*pnsci));
|
||
|
if (!pnsci)
|
||
|
goto initError;
|
||
|
|
||
|
pnsci->lpvCertData = LocalAlloc(LPTR, dwFileSize);
|
||
|
if (!pnsci->lpvCertData)
|
||
|
goto initError;
|
||
|
|
||
|
pnsci->cbCert = dwFileSize;
|
||
|
|
||
|
if (!ReadFile(hf, pnsci->lpvCertData, dwFileSize, &cbRead, NULL) || cbRead != dwFileSize)
|
||
|
goto initError;
|
||
|
|
||
|
SetWindowLongPtr(hDlg, DWLP_USER, (LPARAM)pnsci); // save pointer to cert
|
||
|
|
||
|
//
|
||
|
// ok check to make sure that 1) it's a cert file and 2) it's a root!
|
||
|
//
|
||
|
PCCERT_CONTEXT pCertContext;
|
||
|
|
||
|
dwError = S_FALSE;
|
||
|
|
||
|
pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
|
||
|
(LPBYTE)(pnsci->lpvCertData),
|
||
|
pnsci->cbCert);
|
||
|
|
||
|
if (pCertContext)
|
||
|
{
|
||
|
if (CertCompareCertificateName(X509_ASN_ENCODING,
|
||
|
&pCertContext->pCertInfo->Subject,
|
||
|
&pCertContext->pCertInfo->Issuer))
|
||
|
{
|
||
|
dwError = S_OK;
|
||
|
}
|
||
|
|
||
|
CertFreeCertificateContext(pCertContext);
|
||
|
}
|
||
|
|
||
|
if (dwError != S_OK)
|
||
|
{
|
||
|
goto initError;
|
||
|
}
|
||
|
|
||
|
NewSiteCert_SetAvailableAuthorityCheckboxes(hDlg, pnsci, TRUE);
|
||
|
|
||
|
NewSiteCert_CenterDialog(hDlg);
|
||
|
|
||
|
break;
|
||
|
|
||
|
initError:
|
||
|
TCHAR szTitle[MAX_PATH + 1];
|
||
|
TCHAR szError[MAX_PATH + 1];
|
||
|
|
||
|
MLLoadShellLangString(IDS_CERT_FILE_INVALID, &szError[0], MAX_PATH);
|
||
|
MLLoadShellLangString(IDS_ERROR, &szTitle[0], MAX_PATH);
|
||
|
MessageBox(GetFocus(), &szError[0], &szTitle[0], MB_OK | MB_ICONERROR);
|
||
|
|
||
|
EndDialog(hDlg, IDCANCEL);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
case WM_COMMAND:
|
||
|
switch (LOWORD(wParam))
|
||
|
{
|
||
|
case IDOK:
|
||
|
{
|
||
|
pnsci->fCertEnabled = IsDlgButtonChecked(hDlg, IDC_CHECK_ENABLE_CERT);
|
||
|
pnsci->fNetworkClient = IsDlgButtonChecked(hDlg, IDC_CHECK_NETWORK_CLIENT);
|
||
|
pnsci->fNetworkServer = IsDlgButtonChecked(hDlg, IDC_CHECK_NETWORK_SERVER);
|
||
|
pnsci->fSecureEmail = IsDlgButtonChecked(hDlg, IDC_CHECK_SECURE_EMAIL);
|
||
|
pnsci->fSoftwarePublishing = IsDlgButtonChecked(hDlg, IDC_CHECK_SOFTWARE_PUBLISHING);
|
||
|
|
||
|
NewSiteCert_AddCert(pnsci);
|
||
|
|
||
|
EndDialog(hDlg, IDOK);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case IDCANCEL:
|
||
|
EndDialog(hDlg, IDCANCEL);
|
||
|
break;
|
||
|
|
||
|
case IDC_VIEWCERT:
|
||
|
ShowX509EncodedCertificate(hDlg, (LPBYTE)pnsci->lpvCertData, pnsci->cbCert);
|
||
|
break;
|
||
|
|
||
|
case IDC_CHECK_ENABLE_CERT:
|
||
|
|
||
|
if (HIWORD(wParam) == BN_CLICKED)
|
||
|
{
|
||
|
BOOL fEnableCert;
|
||
|
|
||
|
fEnableCert = IsDlgButtonChecked(hDlg, IDC_CHECK_ENABLE_CERT);
|
||
|
|
||
|
if (!(fEnableCert))
|
||
|
{
|
||
|
EnableWindow(GetDlgItem(hDlg, IDC_CHECK_NETWORK_CLIENT), fEnableCert);
|
||
|
EnableWindow(GetDlgItem(hDlg, IDC_CHECK_NETWORK_SERVER), fEnableCert);
|
||
|
EnableWindow(GetDlgItem(hDlg, IDC_CHECK_SECURE_EMAIL), fEnableCert);
|
||
|
EnableWindow(GetDlgItem(hDlg, IDC_CHECK_SOFTWARE_PUBLISHING), fEnableCert);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
NewSiteCert_SetAvailableAuthorityCheckboxes(hDlg, pnsci, FALSE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return(FALSE);
|
||
|
|
||
|
default:
|
||
|
return FALSE;
|
||
|
}
|
||
|
return TRUE;
|
||
|
break;
|
||
|
|
||
|
case WM_HELP: // F1
|
||
|
ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
|
||
|
HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
|
||
|
break;
|
||
|
|
||
|
case WM_CONTEXTMENU: // right mouse click
|
||
|
ResWinHelp( (HWND) wParam, IDS_HELPFILE,
|
||
|
HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
|
||
|
break;
|
||
|
|
||
|
case WM_DESTROY:
|
||
|
if (pnsci)
|
||
|
{
|
||
|
if (pnsci->lpvCertData)
|
||
|
LocalFree(pnsci->lpvCertData);
|
||
|
LocalFree(pnsci);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
STDAPI SiteCert_RunFromCmdLine(HINSTANCE hinst, HINSTANCE hPrevInstance, LPTSTR lpszCmdLine, int nCmdShow)
|
||
|
{
|
||
|
|
||
|
if ((!lpszCmdLine) || (*lpszCmdLine == TEXT('\0')))
|
||
|
return -1;
|
||
|
|
||
|
DialogBoxParam(MLGetHinst(), MAKEINTRESOURCE(IDD_NEWSITECERT),
|
||
|
NULL, NewSiteCert_DlgProc, (LPARAM)lpszCmdLine);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
// Helper function for ExportPFX
|
||
|
#define NUM_KNOWN_STORES 5
|
||
|
BOOL OpenAndAllocKnownStores(DWORD *pchStores, HCERTSTORE **ppahStores)
|
||
|
{
|
||
|
HCERTSTORE hStore;
|
||
|
int i;
|
||
|
static const LPCTSTR rszStoreNames[NUM_KNOWN_STORES] = {
|
||
|
TEXT("ROOT"),
|
||
|
TEXT("TRUST"),
|
||
|
TEXT("CA"),
|
||
|
TEXT("MY"),
|
||
|
TEXT("SPC")
|
||
|
};
|
||
|
|
||
|
*pchStores = 0;
|
||
|
|
||
|
if (NULL == ((*ppahStores) = (HCERTSTORE *) LocalAlloc(LPTR, sizeof(HCERTSTORE) * NUM_KNOWN_STORES)))
|
||
|
{
|
||
|
return (FALSE);
|
||
|
}
|
||
|
|
||
|
for (i=0; i< NUM_KNOWN_STORES; i++)
|
||
|
{
|
||
|
(*ppahStores)[i] = NULL;
|
||
|
if (hStore = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
|
||
|
0,
|
||
|
0,
|
||
|
CERT_SYSTEM_STORE_CURRENT_USER |
|
||
|
CERT_STORE_READONLY_FLAG |
|
||
|
CERT_STORE_NO_CRYPT_RELEASE_FLAG,
|
||
|
rszStoreNames[i]))
|
||
|
(*ppahStores)[(*pchStores)++] = hStore;
|
||
|
}
|
||
|
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
// Helper function for ExportPFX
|
||
|
void CloseAndFreeKnownStores(HCERTSTORE *pahStores)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
for (i=0; i<NUM_KNOWN_STORES; i++)
|
||
|
{
|
||
|
if (pahStores[i] != NULL)
|
||
|
{
|
||
|
CertCloseStore(pahStores[i], 0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
LocalFree(pahStores);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
enum {PFX_IMPORT, PFX_EXPORT};
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
HWND hDlg; // handle to window
|
||
|
DWORD dwImportExport; // import or export?
|
||
|
BOOL fUseExisting; // use existing cert if collision on import
|
||
|
PCCERT_CONTEXT pCertContext; // context to export or NULL
|
||
|
LPWSTR pwszPassword; // password for import/export
|
||
|
LPWSTR pwszPassword2; // prompt user twice on exports!
|
||
|
LPTSTR pszPath; // file for import/export
|
||
|
|
||
|
} IMPORTEXPORT, *LPIMPORTEXPORT;
|
||
|
|
||
|
#define MAX_PASSWORD 32
|
||
|
|
||
|
// CreateCertFile: change working directory to "MyDocs", do CreateFile, restore old working directory
|
||
|
HANDLE CreateCertFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
||
|
DWORD dwCreationDistribution, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
|
||
|
{
|
||
|
TCHAR szOldDir[MAX_PATH];
|
||
|
TCHAR szCertDir[MAX_PATH];
|
||
|
HANDLE hFile;
|
||
|
LPITEMIDLIST pidl;
|
||
|
|
||
|
GetCurrentDirectory(ARRAYSIZE(szOldDir), szOldDir);
|
||
|
if (SHGetSpecialFolderLocation(NULL, CSIDL_PERSONAL, &pidl) == NOERROR)
|
||
|
{
|
||
|
SHGetPathFromIDList(pidl, szCertDir);
|
||
|
SetCurrentDirectory(szCertDir);
|
||
|
ILFree(pidl);
|
||
|
}
|
||
|
hFile = CreateFile(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
|
||
|
dwCreationDistribution, dwFlagsAndAttributes, hTemplateFile);
|
||
|
SetCurrentDirectory(szOldDir);
|
||
|
|
||
|
return hFile;
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// 09-Sep-1997 pberkman:
|
||
|
// determine if the exact cert is in the passed store
|
||
|
//
|
||
|
|
||
|
BOOL __IsCertInStore(PCCERT_CONTEXT pCertContext, HCERTSTORE hStore)
|
||
|
{
|
||
|
//
|
||
|
// can't do it the fast way -- do it the slow way!
|
||
|
//
|
||
|
BYTE *pbHash;
|
||
|
DWORD cbHash;
|
||
|
CRYPT_HASH_BLOB sBlob;
|
||
|
PCCERT_CONTEXT pWorkContext;
|
||
|
|
||
|
cbHash = 0;
|
||
|
|
||
|
if (!(CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, NULL, &cbHash)))
|
||
|
{
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
if (cbHash < 1)
|
||
|
{
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
if (!(pbHash = new BYTE[cbHash]))
|
||
|
{
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
if (!(CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, pbHash, &cbHash)))
|
||
|
{
|
||
|
delete pbHash;
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
sBlob.cbData = cbHash;
|
||
|
sBlob.pbData = pbHash;
|
||
|
|
||
|
pWorkContext = CertFindCertificateInStore(hStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0,
|
||
|
CERT_FIND_SHA1_HASH, &sBlob, NULL);
|
||
|
|
||
|
delete pbHash;
|
||
|
|
||
|
if (pWorkContext)
|
||
|
{
|
||
|
CertFreeCertificateContext(pWorkContext);
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// 09-Sep-1997 pberkman:
|
||
|
// importing a cert from a file.
|
||
|
//
|
||
|
|
||
|
BOOL ImportPFX(LPIMPORTEXPORT pImp)
|
||
|
{
|
||
|
# define MY_STORE 0
|
||
|
# define CA_STORE 1
|
||
|
# define ROOT_STORE 2
|
||
|
# define MAX_STORE 3
|
||
|
HCERTSTORE pahStores[MAX_STORE];
|
||
|
HCERTSTORE hCertStore;
|
||
|
BOOL fAdded;
|
||
|
DWORD dwAddFlags;
|
||
|
|
||
|
HANDLE hFile;
|
||
|
CRYPT_DATA_BLOB sData;
|
||
|
|
||
|
BOOL fRet;
|
||
|
PCCERT_CONTEXT pCertCtxt;
|
||
|
DWORD cbRead;
|
||
|
DWORD dwImportFlags;
|
||
|
int i;
|
||
|
|
||
|
fRet = FALSE;
|
||
|
dwImportFlags = CRYPT_EXPORTABLE;
|
||
|
pCertCtxt = NULL;
|
||
|
hCertStore = NULL;
|
||
|
|
||
|
for (i = 0; i < MAX_STORE; i++)
|
||
|
{
|
||
|
pahStores[i] = NULL;
|
||
|
}
|
||
|
|
||
|
ZeroMemory(&sData, sizeof(CRYPT_DATA_BLOB));
|
||
|
|
||
|
hFile = CreateCertFile(pImp->pszPath, GENERIC_READ, FILE_SHARE_READ,
|
||
|
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||
|
|
||
|
if (hFile == INVALID_HANDLE_VALUE)
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
dwAddFlags = (pImp->fUseExisting) ? CERT_STORE_ADD_USE_EXISTING :
|
||
|
CERT_STORE_ADD_REPLACE_EXISTING;
|
||
|
|
||
|
sData.cbData = GetFileSize(hFile, NULL);
|
||
|
sData.pbData = (PBYTE)LocalAlloc(LMEM_FIXED, sData.cbData);
|
||
|
|
||
|
if (!(sData.pbData))
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
if (!(ReadFile(hFile, sData.pbData, sData.cbData, &cbRead, NULL)))
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
if ((pImp->pwszPassword) && (!(*pImp->pwszPassword))) // if no password, use null.
|
||
|
{
|
||
|
pImp->pwszPassword = NULL;
|
||
|
}
|
||
|
|
||
|
if (!(hCertStore = PFXImportCertStore(&sData, pImp->pwszPassword, dwImportFlags)))
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// now we have in memory hStore enumerate the cert contexts
|
||
|
// and drop them into destination store
|
||
|
//
|
||
|
if (!(pahStores[MY_STORE] = CertOpenSystemStoreA(NULL, "MY")) ||
|
||
|
!(pahStores[CA_STORE] = CertOpenSystemStoreA(NULL, "CA")) ||
|
||
|
!(pahStores[ROOT_STORE] = CertOpenSystemStoreA(NULL, "ROOT")))
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
while (pCertCtxt = CertEnumCertificatesInStore(hCertStore, pCertCtxt))
|
||
|
{
|
||
|
fAdded = FALSE;
|
||
|
cbRead = 0;
|
||
|
CertGetCertificateContextProperty(pCertCtxt, CERT_KEY_PROV_INFO_PROP_ID, NULL, &cbRead);
|
||
|
|
||
|
if (cbRead > 0) // pfx added a public key prop
|
||
|
{
|
||
|
CertAddCertificateContextToStore(pahStores[MY_STORE], pCertCtxt, dwAddFlags, NULL);
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// first, check if we already have this cert in one of our stores
|
||
|
//
|
||
|
for (i = 0; i < MAX_STORE; i++)
|
||
|
{
|
||
|
if (__IsCertInStore(pCertCtxt, pahStores[i]))
|
||
|
{
|
||
|
//
|
||
|
// the same cert, exactly, is already in one of our stores!
|
||
|
//
|
||
|
fAdded = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!(fAdded))
|
||
|
{
|
||
|
CertAddCertificateContextToStore(pahStores[CA_STORE], pCertCtxt, dwAddFlags, NULL);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fRet = TRUE;
|
||
|
|
||
|
Cleanup:
|
||
|
|
||
|
if (sData.pbData)
|
||
|
{
|
||
|
LocalFree(sData.pbData);
|
||
|
}
|
||
|
|
||
|
if (hFile != INVALID_HANDLE_VALUE)
|
||
|
{
|
||
|
CloseHandle(hFile);
|
||
|
}
|
||
|
|
||
|
if (hCertStore)
|
||
|
{
|
||
|
CertCloseStore(hCertStore, 0);
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < MAX_STORE; i++)
|
||
|
{
|
||
|
if (pahStores[i])
|
||
|
{
|
||
|
CertCloseStore(pahStores[i], 0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return(fRet);
|
||
|
}
|
||
|
|
||
|
typedef PCCERT_CONTEXT (* PFNWTHELPER) (PCCERT_CONTEXT /* pChildContext */,
|
||
|
DWORD /* chStores */,
|
||
|
HCERTSTORE * /* pahStores */,
|
||
|
FILETIME * /* psftVerifyAsOf*/,
|
||
|
DWORD /* dwEncoding */,
|
||
|
DWORD * /* pdwConfidence */,
|
||
|
DWORD * /* pdwError */ );
|
||
|
|
||
|
|
||
|
|
||
|
BOOL ExportPFX(LPIMPORTEXPORT pImp)
|
||
|
{
|
||
|
BOOL fRet = FALSE;
|
||
|
HANDLE hFile = NULL;
|
||
|
CRYPT_DATA_BLOB sData;
|
||
|
DWORD cbRead;
|
||
|
HCERTSTORE hSrcCertStore;
|
||
|
DWORD dwExportFlags = 4; // 4 == EXPORT_PRIVATE_KEYS;
|
||
|
TCHAR szText[MAX_PATH], szTitle[80];
|
||
|
PCCERT_CONTEXT pTempCertContext;
|
||
|
HCERTSTORE *phCertStores = NULL;
|
||
|
DWORD chCertStores = 0;
|
||
|
DWORD dwConfidence;
|
||
|
DWORD dwError;
|
||
|
HINSTANCE hiWintrust = NULL;
|
||
|
PFNWTHELPER WTHelperCertFindIssuerCertificate;
|
||
|
|
||
|
|
||
|
if (!pImp->pCertContext)
|
||
|
return FALSE;
|
||
|
|
||
|
ZeroMemory(&sData, sizeof(CRYPT_DATA_BLOB));
|
||
|
|
||
|
// create an in memory store
|
||
|
hSrcCertStore = CertOpenStore(CERT_STORE_PROV_MEMORY,
|
||
|
PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
|
||
|
0,
|
||
|
0,
|
||
|
NULL);
|
||
|
|
||
|
if (!CertAddCertificateContextToStore(hSrcCertStore, pImp->pCertContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL))
|
||
|
goto Cleanup;
|
||
|
|
||
|
// Load helper function from wintrust.dll
|
||
|
hiWintrust = LoadLibrary(TEXT("WINTRUST.DLL"));
|
||
|
WTHelperCertFindIssuerCertificate = (PFNWTHELPER) GetProcAddress(hiWintrust,"WTHelperCertFindIssuerCertificate");
|
||
|
if (WTHelperCertFindIssuerCertificate)
|
||
|
{
|
||
|
// Load all the top level stores, so we can export from them if necessary
|
||
|
if (OpenAndAllocKnownStores(&chCertStores, &phCertStores))
|
||
|
{
|
||
|
// Find the intermediate certifcates, and add them to the store that we will be exporting
|
||
|
pTempCertContext = pImp->pCertContext;
|
||
|
while (NULL != ( pTempCertContext = WTHelperCertFindIssuerCertificate(pTempCertContext,
|
||
|
chCertStores,
|
||
|
phCertStores,
|
||
|
NULL,
|
||
|
X509_ASN_ENCODING,
|
||
|
&dwConfidence,
|
||
|
&dwError)))
|
||
|
{
|
||
|
CertAddCertificateContextToStore(hSrcCertStore, pTempCertContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL);
|
||
|
|
||
|
// Break out if we find a root (self-signed) cert
|
||
|
if (CertCompareCertificateName(X509_ASN_ENCODING,
|
||
|
&pTempCertContext->pCertInfo->Subject,
|
||
|
&pTempCertContext->pCertInfo->Issuer))
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
CloseAndFreeKnownStores(phCertStores);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// This first call simply gets the size of the crypt blob
|
||
|
//
|
||
|
if (!PFXExportCertStore(hSrcCertStore, &sData, pImp->pwszPassword, dwExportFlags))
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
// Alloc based on cbData
|
||
|
sData.pbData = (PBYTE)LocalAlloc(LMEM_FIXED, sData.cbData);
|
||
|
|
||
|
//
|
||
|
// Now actually get the data
|
||
|
//
|
||
|
if (!(*pImp->pwszPassword)) // no password use null
|
||
|
pImp->pwszPassword = NULL;
|
||
|
|
||
|
if (!PFXExportCertStore(hSrcCertStore, &sData, pImp->pwszPassword, dwExportFlags))
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
// Open the PFX file
|
||
|
hFile = CreateCertFile(pImp->pszPath,
|
||
|
GENERIC_WRITE,
|
||
|
FILE_SHARE_READ,
|
||
|
NULL,
|
||
|
OPEN_ALWAYS,
|
||
|
FILE_ATTRIBUTE_NORMAL,
|
||
|
NULL);
|
||
|
|
||
|
if (hFile == INVALID_HANDLE_VALUE) {
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
// Write to it
|
||
|
if (!WriteFile(hFile,
|
||
|
sData.pbData,
|
||
|
sData.cbData,
|
||
|
&cbRead,
|
||
|
NULL)) {
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
// Display message about certs exporting OK.
|
||
|
MLLoadShellLangString(IDS_CERT_EXPORTOKTEXT, szText, ARRAYSIZE(szText));
|
||
|
MLLoadShellLangString(IDS_CERT_EXPORTOKTITLE, szTitle, ARRAYSIZE(szTitle));
|
||
|
|
||
|
MessageBox(pImp->hDlg, szText, szTitle, MB_ICONINFORMATION | MB_OK);
|
||
|
|
||
|
fRet = TRUE;
|
||
|
|
||
|
Cleanup:
|
||
|
if (hiWintrust)
|
||
|
FreeLibrary(hiWintrust);
|
||
|
if (hSrcCertStore)
|
||
|
CertCloseStore(hSrcCertStore, 0);
|
||
|
if (hFile != INVALID_HANDLE_VALUE)
|
||
|
CloseHandle(hFile);
|
||
|
if (sData.pbData)
|
||
|
LocalFree(sData.pbData);
|
||
|
|
||
|
return fRet;
|
||
|
}
|
||
|
|
||
|
INT_PTR CALLBACK ImportExportDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
|
||
|
{
|
||
|
LPIMPORTEXPORT pImp;
|
||
|
|
||
|
if (uMsg == WM_INITDIALOG)
|
||
|
{
|
||
|
pImp = (LPIMPORTEXPORT)lParam; // this is passed in to us
|
||
|
if (!pImp)
|
||
|
{
|
||
|
EndDialog(hDlg, 0);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
// tell dialog where to get info
|
||
|
SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pImp);
|
||
|
|
||
|
// save handle to the page
|
||
|
pImp->hDlg = hDlg;
|
||
|
|
||
|
// limit the password to 32 chars
|
||
|
SendMessage(GetDlgItem(hDlg, IDC_PASSWORD), EM_LIMITTEXT, MAX_PASSWORD, 0);
|
||
|
|
||
|
//
|
||
|
// 03-Oct-1997 pberkman: always verify password!
|
||
|
//
|
||
|
if (pImp->dwImportExport == PFX_EXPORT)
|
||
|
{
|
||
|
SendMessage(GetDlgItem(hDlg, IDC_PASSWORD2), EM_LIMITTEXT, MAX_PASSWORD, 0);
|
||
|
}
|
||
|
|
||
|
SHAutoComplete(GetDlgItem(hDlg, IDC_FILENAME), SHACF_DEFAULT); // This control exists in both IDD_PFX_IMPORT and IDD_PFX_EXPORT
|
||
|
|
||
|
// only set these on import, since they don't exist on export =)
|
||
|
// =========================================================================
|
||
|
// 03-Oct-1997 pberkman: no user decisions!
|
||
|
//
|
||
|
// if (pImp->dwImportExport == PFX_IMPORT)
|
||
|
// {
|
||
|
// CheckRadioButton(hDlg, IDC_USE_EXISTING, IDC_USE_FILE, IDC_USE_EXISTING);
|
||
|
// }
|
||
|
// ==========================================================================
|
||
|
SetFocus(GetDlgItem(hDlg, IDC_PASSWORD));
|
||
|
|
||
|
} // WM_INITDIALOG
|
||
|
|
||
|
else
|
||
|
pImp = (LPIMPORTEXPORT)GetWindowLongPtr(hDlg, DWLP_USER);
|
||
|
|
||
|
if (!pImp)
|
||
|
return FALSE;
|
||
|
|
||
|
switch (uMsg)
|
||
|
{
|
||
|
case WM_COMMAND:
|
||
|
switch (LOWORD(wParam))
|
||
|
{
|
||
|
case IDC_CERT_BROWSE:
|
||
|
{
|
||
|
TCHAR szFilenameBrowse[MAX_PATH];
|
||
|
TCHAR szExt[MAX_PATH];
|
||
|
TCHAR szFilter[MAX_PATH];
|
||
|
int ret;
|
||
|
LPITEMIDLIST pidl;
|
||
|
TCHAR szWorkingDir[MAX_PATH];
|
||
|
|
||
|
szFilenameBrowse[0] = 0;
|
||
|
MLLoadString(IDS_PFX_EXT, szExt, ARRAYSIZE(szExt));
|
||
|
int cchFilter = MLLoadString(IDS_PFX_FILTER, szFilter, ARRAYSIZE(szFilter)-1);
|
||
|
|
||
|
// Make sure we have a double null termination on the filter
|
||
|
szFilter[cchFilter + 1] = 0;
|
||
|
|
||
|
if (SHGetSpecialFolderLocation(hDlg, CSIDL_PERSONAL, &pidl) == NOERROR)
|
||
|
{
|
||
|
SHGetPathFromIDList(pidl, szWorkingDir);
|
||
|
ILFree(pidl);
|
||
|
}
|
||
|
|
||
|
ret = _AorW_GetFileNameFromBrowse(hDlg, szFilenameBrowse, ARRAYSIZE(szFilenameBrowse), szWorkingDir,
|
||
|
szExt, szFilter, NULL);
|
||
|
|
||
|
if (ret > 0)
|
||
|
{
|
||
|
SetDlgItemText(hDlg, IDC_FILENAME, szFilenameBrowse);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case IDOK:
|
||
|
{
|
||
|
TCHAR szPassword[MAX_PASSWORD];
|
||
|
TCHAR szPassword2[MAX_PASSWORD];
|
||
|
TCHAR szPath[MAX_PATH];
|
||
|
BOOL bRet;
|
||
|
|
||
|
szPassword[0] = NULL;
|
||
|
GetWindowText(GetDlgItem(hDlg, IDC_PASSWORD), szPassword, ARRAYSIZE(szPassword));
|
||
|
GetWindowText(GetDlgItem(hDlg, IDC_FILENAME), szPath, ARRAYSIZE(szPath));
|
||
|
|
||
|
//
|
||
|
// 03-Oct-1997 pberkman: always double check password!
|
||
|
//
|
||
|
if (pImp->dwImportExport == PFX_EXPORT)
|
||
|
{
|
||
|
szPassword2[0] = NULL;
|
||
|
GetWindowText(GetDlgItem(hDlg, IDC_PASSWORD2), szPassword2, ARRAYSIZE(szPassword2));
|
||
|
|
||
|
if (StrCmp(szPassword, szPassword2) != 0)
|
||
|
{
|
||
|
TCHAR szTitle[MAX_PATH + 1];
|
||
|
TCHAR szError[MAX_PATH + 1];
|
||
|
|
||
|
MLLoadShellLangString(IDS_PASSWORDS_NOMATCH, &szError[0], MAX_PATH);
|
||
|
MLLoadShellLangString(IDS_ERROR, &szTitle[0], MAX_PATH);
|
||
|
MessageBox(GetFocus(), &szError[0], &szTitle[0], MB_OK | MB_ICONERROR);
|
||
|
|
||
|
SetFocus(GetDlgItem(hDlg, IDC_PASSWORD));
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Add a default extension on export
|
||
|
if (pImp->dwImportExport == PFX_EXPORT)
|
||
|
if (szPath[0] != TEXT('\0') && PathAddExtension(szPath, TEXT(".PFX")))
|
||
|
SetWindowText(GetDlgItem(hDlg, IDC_FILENAME), szPath);
|
||
|
|
||
|
#ifndef UNICODE
|
||
|
WCHAR wszPassword[MAX_PASSWORD];
|
||
|
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szPassword, -1, wszPassword, ARRAYSIZE(wszPassword));
|
||
|
pImp->pwszPassword = wszPassword;
|
||
|
#else
|
||
|
pImp->pwszPassword = szPassword;
|
||
|
#endif
|
||
|
pImp->pszPath = szPath;
|
||
|
|
||
|
if (pImp->dwImportExport == PFX_IMPORT)
|
||
|
{
|
||
|
// =========================================================================
|
||
|
// 03-Oct-1997 pberkman: no user decisions!
|
||
|
//
|
||
|
// pImp->fUseExisting = IsDlgButtonChecked(hDlg, IDC_USE_EXISTING);
|
||
|
// =========================================================================
|
||
|
pImp->fUseExisting = FALSE;
|
||
|
bRet = ImportPFX(pImp);
|
||
|
|
||
|
if (!(bRet) && (GetLastError() == NTE_BAD_DATA))
|
||
|
{
|
||
|
// message....
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bRet = ExportPFX(pImp);
|
||
|
}
|
||
|
|
||
|
EndDialog(hDlg, bRet);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case IDCANCEL:
|
||
|
EndDialog(hDlg, TRUE); // Cancel is not an error
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case WM_NOTIFY:
|
||
|
break;
|
||
|
// No context sensitive help yet...
|
||
|
#if 0
|
||
|
case WM_HELP: // F1
|
||
|
ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
|
||
|
HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
|
||
|
break;
|
||
|
|
||
|
case WM_CONTEXTMENU: // right mouse click
|
||
|
ResWinHelp( (HWND) wParam, IDS_HELPFILE,
|
||
|
HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
|
||
|
break;
|
||
|
#endif
|
||
|
case WM_DESTROY:
|
||
|
SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)NULL);
|
||
|
break;
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
#ifdef UNIX
|
||
|
EXTERN_C
|
||
|
#endif
|
||
|
INT_PTR ImportExportPFX(HWND hwndParent, DWORD dwImportExport, LPBYTE pbCert, DWORD cbCert)
|
||
|
{
|
||
|
IMPORTEXPORT imp;
|
||
|
|
||
|
if (pbCert)
|
||
|
{
|
||
|
CRYPT_HASH_BLOB hashBlob;
|
||
|
HCERTSTORE hMy = CertOpenSystemStoreA(NULL, "MY");
|
||
|
DWORD cbSHA1Hash;
|
||
|
LPBYTE pbSHA1Hash;
|
||
|
|
||
|
if (!hMy)
|
||
|
return FALSE;
|
||
|
|
||
|
if (CryptHashCertificate(NULL, 0, 0, pbCert, cbCert, NULL, &cbSHA1Hash))
|
||
|
{
|
||
|
pbSHA1Hash = (LPBYTE)LocalAlloc(LPTR, cbSHA1Hash);
|
||
|
if (!pbSHA1Hash)
|
||
|
return FALSE;
|
||
|
|
||
|
if (CryptHashCertificate(NULL, 0, 0, pbCert, cbCert, pbSHA1Hash, &cbSHA1Hash))
|
||
|
{
|
||
|
hashBlob.cbData = cbSHA1Hash;
|
||
|
hashBlob.pbData = pbSHA1Hash;
|
||
|
imp.pCertContext = CertFindCertificateInStore(hMy, X509_ASN_ENCODING, 0, CERT_FIND_HASH, &hashBlob, NULL);
|
||
|
if (!(imp.pCertContext))
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
LocalFree(pbSHA1Hash);
|
||
|
}
|
||
|
|
||
|
CertCloseStore(hMy, 0);
|
||
|
}
|
||
|
|
||
|
imp.dwImportExport = dwImportExport;
|
||
|
|
||
|
return DialogBoxParam(MLGetHinst(),
|
||
|
dwImportExport == PFX_IMPORT ? MAKEINTRESOURCE(IDD_PFX_IMPORT) : MAKEINTRESOURCE(IDD_PFX_EXPORT),
|
||
|
hwndParent, ImportExportDlgProc, (LPARAM)&imp);
|
||
|
}
|
||
|
|
||
|
//BUBUG: The following function should be rermoved when we have updated our Crypto API to latest
|
||
|
BOOL WINAPI WTHelperIsInRootStore(PCCERT_CONTEXT pCertContext)
|
||
|
{
|
||
|
HCERTSTORE hStore;
|
||
|
|
||
|
if (!(hStore = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
|
||
|
0,
|
||
|
NULL,
|
||
|
CERT_SYSTEM_STORE_CURRENT_USER |
|
||
|
CERT_STORE_READONLY_FLAG |
|
||
|
CERT_STORE_NO_CRYPT_RELEASE_FLAG,
|
||
|
"ROOT")))
|
||
|
{
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// can't do it the fast way -- do it the slow way!
|
||
|
//
|
||
|
BYTE *pbHash;
|
||
|
DWORD cbHash;
|
||
|
CRYPT_HASH_BLOB sBlob;
|
||
|
PCCERT_CONTEXT pWorkContext;
|
||
|
|
||
|
cbHash = 0;
|
||
|
|
||
|
if (!(CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, NULL, &cbHash)))
|
||
|
{
|
||
|
CertCloseStore(hStore, 0);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
if (cbHash < 1)
|
||
|
{
|
||
|
CertCloseStore(hStore, 0);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
if (!(pbHash = new BYTE[cbHash]))
|
||
|
{
|
||
|
CertCloseStore(hStore, 0);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
if (!(CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, pbHash, &cbHash)))
|
||
|
{
|
||
|
delete pbHash;
|
||
|
CertCloseStore(hStore, 0);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
sBlob.cbData = cbHash;
|
||
|
sBlob.pbData = pbHash;
|
||
|
|
||
|
pWorkContext = CertFindCertificateInStore(hStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0,
|
||
|
CERT_FIND_SHA1_HASH, &sBlob, NULL);
|
||
|
|
||
|
delete pbHash;
|
||
|
|
||
|
if (pWorkContext)
|
||
|
{
|
||
|
CertFreeCertificateContext(pWorkContext);
|
||
|
CertCloseStore(hStore, 0);
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
CertCloseStore(hStore, 0);
|
||
|
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
|
||
|
//============================================================================
|
||
|
const TCHAR c_szRegKeySMIEM[] = TEXT("Software\\Microsoft\\Internet Explorer\\Main");
|
||
|
const TCHAR c_szRegValFormSuggest[] = TEXT("Use FormSuggest");
|
||
|
const TCHAR c_szRegValFormSuggestPW[] = TEXT("FormSuggest Passwords");
|
||
|
const TCHAR c_szRegValFormSuggestPWAsk[] = TEXT("FormSuggest PW Ask");
|
||
|
|
||
|
const TCHAR c_szYes[] = TEXT("yes");
|
||
|
const TCHAR c_szNo[] = TEXT("no");
|
||
|
|
||
|
inline void SetValueHelper(HWND hDlg, int id, LPTSTR *ppszData, DWORD *pcbData)
|
||
|
{
|
||
|
if (IsDlgButtonChecked(hDlg, id))
|
||
|
{
|
||
|
*ppszData = (LPTSTR)c_szYes;
|
||
|
*pcbData = sizeof(c_szYes);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*ppszData = (LPTSTR)c_szNo;
|
||
|
*pcbData = sizeof(c_szNo);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
INT_PTR CALLBACK AutoSuggestDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
switch (uMsg)
|
||
|
{
|
||
|
case WM_INITDIALOG:
|
||
|
{
|
||
|
CheckDlgButton(hDlg, IDC_AUTOSUGGEST_ENABLEADDR,
|
||
|
(SHRegGetBoolUSValue(REGSTR_PATH_AUTOCOMPLETE, REGSTR_VAL_USEAUTOSUGGEST, FALSE, /*default:*/TRUE)) ?
|
||
|
BST_CHECKED : BST_UNCHECKED);
|
||
|
|
||
|
if (g_restrict.fFormSuggest)
|
||
|
{
|
||
|
EnableDlgItem(hDlg, IDC_AUTOSUGGEST_ENABLEFORM, FALSE);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CheckDlgButton(hDlg, IDC_AUTOSUGGEST_ENABLEFORM,
|
||
|
(SHRegGetBoolUSValue(c_szRegKeySMIEM, c_szRegValFormSuggest, FALSE, /*default:*/FALSE)) ?
|
||
|
BST_CHECKED : BST_UNCHECKED);
|
||
|
}
|
||
|
|
||
|
if (g_restrict.fFormPasswords)
|
||
|
{
|
||
|
EnableDlgItem(hDlg, IDC_AUTOSUGGEST_SAVEPASSWORDS, FALSE);
|
||
|
EnableDlgItem(hDlg, IDC_AUTOSUGGEST_PROMPTPASSWORDS, FALSE);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CheckDlgButton(hDlg, IDC_AUTOSUGGEST_PROMPTPASSWORDS,
|
||
|
(SHRegGetBoolUSValue(c_szRegKeySMIEM, c_szRegValFormSuggestPWAsk, FALSE, /*default:*/TRUE)) ?
|
||
|
BST_CHECKED : BST_UNCHECKED);
|
||
|
|
||
|
if (SHRegGetBoolUSValue(c_szRegKeySMIEM, c_szRegValFormSuggestPW, FALSE, /*default:*/TRUE))
|
||
|
{
|
||
|
CheckDlgButton(hDlg, IDC_AUTOSUGGEST_SAVEPASSWORDS, BST_CHECKED);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
EnableDlgItem(hDlg, IDC_AUTOSUGGEST_PROMPTPASSWORDS, FALSE);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
|
||
|
case WM_COMMAND:
|
||
|
{
|
||
|
switch (LOWORD(wParam))
|
||
|
{
|
||
|
case IDC_AUTOSUGGEST_SAVEPASSWORDS:
|
||
|
EnableDlgItem(hDlg, IDC_AUTOSUGGEST_PROMPTPASSWORDS,
|
||
|
IsDlgButtonChecked(hDlg, IDC_AUTOSUGGEST_SAVEPASSWORDS));
|
||
|
break;
|
||
|
|
||
|
case IDC_AUTOSUGGEST_CLEARFORM:
|
||
|
case IDC_AUTOSUGGEST_CLEARPASSWORDS:
|
||
|
{
|
||
|
BOOL fPasswords = (LOWORD(wParam) == IDC_AUTOSUGGEST_CLEARPASSWORDS);
|
||
|
DWORD dwClear = (fPasswords) ?
|
||
|
IECMDID_ARG_CLEAR_FORMS_PASSWORDS_ONLY : IECMDID_ARG_CLEAR_FORMS_ALL_BUT_PASSWORDS;
|
||
|
|
||
|
if (IDOK == MsgBox(hDlg, ((fPasswords) ? IDS_CLEAR_FORMPASSWORDS : IDS_CLEAR_FORMSUGGEST), MB_ICONQUESTION, MB_OKCANCEL))
|
||
|
{
|
||
|
HCURSOR hOldCursor = NULL;
|
||
|
HCURSOR hNewCursor = NULL;
|
||
|
|
||
|
#ifndef UNIX
|
||
|
hNewCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_WAIT));
|
||
|
#else
|
||
|
// IEUNIX - Getting rid of redundant MAKEINTRESOURCE
|
||
|
hNewCursor = LoadCursor(NULL, IDC_WAIT);
|
||
|
#endif
|
||
|
|
||
|
if (hNewCursor)
|
||
|
hOldCursor = SetCursor(hNewCursor);
|
||
|
|
||
|
// Clear all strings
|
||
|
ClearAutoSuggestForForms(dwClear);
|
||
|
|
||
|
// Also reset profile assistant sharing (very discoverable here)
|
||
|
if (!g_restrict.fProfiles)
|
||
|
{
|
||
|
ResetProfileSharing(hDlg);
|
||
|
}
|
||
|
|
||
|
if(hOldCursor)
|
||
|
SetCursor(hOldCursor);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case IDOK:
|
||
|
{
|
||
|
DWORD cbData; LPTSTR pszData;
|
||
|
|
||
|
SetValueHelper(hDlg, IDC_AUTOSUGGEST_ENABLEADDR, &pszData, &cbData);
|
||
|
SHSetValue(HKEY_CURRENT_USER, REGSTR_PATH_AUTOCOMPLETE, REGSTR_VAL_USEAUTOSUGGEST,
|
||
|
REG_SZ, pszData, cbData);
|
||
|
|
||
|
if (!g_restrict.fFormSuggest)
|
||
|
{
|
||
|
SetValueHelper(hDlg, IDC_AUTOSUGGEST_ENABLEFORM, &pszData, &cbData);
|
||
|
SHSetValue(HKEY_CURRENT_USER, c_szRegKeySMIEM, c_szRegValFormSuggest,
|
||
|
REG_SZ, pszData, cbData);
|
||
|
}
|
||
|
|
||
|
if (!g_restrict.fFormPasswords)
|
||
|
{
|
||
|
SetValueHelper(hDlg, IDC_AUTOSUGGEST_SAVEPASSWORDS, &pszData, &cbData);
|
||
|
SHSetValue(HKEY_CURRENT_USER, c_szRegKeySMIEM, c_szRegValFormSuggestPW,
|
||
|
REG_SZ, pszData, cbData);
|
||
|
|
||
|
SetValueHelper(hDlg, IDC_AUTOSUGGEST_PROMPTPASSWORDS, &pszData, &cbData);
|
||
|
SHSetValue(HKEY_CURRENT_USER, c_szRegKeySMIEM, c_szRegValFormSuggestPWAsk,
|
||
|
REG_SZ, pszData, cbData);
|
||
|
}
|
||
|
}
|
||
|
// fall through
|
||
|
case IDCANCEL:
|
||
|
{
|
||
|
EndDialog(hDlg, LOWORD(wParam));
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return TRUE;
|
||
|
|
||
|
case WM_HELP: // F1
|
||
|
ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
|
||
|
HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
|
||
|
break;
|
||
|
|
||
|
case WM_CONTEXTMENU: // right mouse click
|
||
|
ResWinHelp( (HWND) wParam, IDS_HELPFILE,
|
||
|
HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
|
||
|
break;
|
||
|
|
||
|
case WM_DESTROY:
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
#ifdef WALLET
|
||
|
// This intermediate dialog is only displayed for wallet 2.x users
|
||
|
INT_PTR CALLBACK WalletDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
switch (uMsg)
|
||
|
{
|
||
|
case WM_INITDIALOG:
|
||
|
{
|
||
|
EnableDlgItem(hDlg, IDC_PROGRAMS_WALLET_PAYBUTTON, IsWalletPaymentAvailable());
|
||
|
EnableDlgItem(hDlg, IDC_PROGRAMS_WALLET_ADDRBUTTON, IsWalletAddressAvailable());
|
||
|
}
|
||
|
return TRUE;
|
||
|
|
||
|
case WM_COMMAND:
|
||
|
{
|
||
|
switch (LOWORD(wParam))
|
||
|
{
|
||
|
case IDC_PROGRAMS_WALLET_PAYBUTTON:
|
||
|
DisplayWalletPaymentDialog(hDlg);
|
||
|
break;
|
||
|
|
||
|
case IDC_PROGRAMS_WALLET_ADDRBUTTON:
|
||
|
DisplayWalletAddressDialog(hDlg);
|
||
|
break;
|
||
|
|
||
|
case IDOK:
|
||
|
case IDCANCEL:
|
||
|
{
|
||
|
EndDialog(hDlg, LOWORD(wParam));
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return TRUE;
|
||
|
|
||
|
case WM_HELP: // F1
|
||
|
ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
|
||
|
HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
|
||
|
break;
|
||
|
|
||
|
case WM_CONTEXTMENU: // right mouse click
|
||
|
ResWinHelp( (HWND) wParam, IDS_HELPFILE,
|
||
|
HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
|
||
|
break;
|
||
|
|
||
|
case WM_DESTROY:
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
#endif
|