You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
6465 lines
224 KiB
6465 lines
224 KiB
//depot/Lab03_N/ds/security/cryptoapi/ui/wizards/wizards.cpp#21 - edit change 8790 (text)
|
|
//-------------------------------------------------------------
|
|
// Copyright (C) Microsoft Corporation, 1996 - 1999
|
|
//
|
|
// File: wizards.cpp
|
|
//
|
|
// Contents: The cpp file to implement the wizards
|
|
//
|
|
// History: 16-10-1997 xiaohs created
|
|
//
|
|
//--------------------------------------------------------------
|
|
#include "wzrdpvk.h"
|
|
#include "certca.h"
|
|
#include "cautil.h"
|
|
#include "CertRequesterContext.h"
|
|
#include "CertDSManager.h"
|
|
#include "CertRequester.h"
|
|
|
|
// Used to provide singleton instances of useful COM objects in a demand-driven fashion.
|
|
// See wzrdpvk.h.
|
|
EnrollmentCOMObjectFactory *g_pEnrollFactory = NULL;
|
|
|
|
HINSTANCE g_hmodThisDll = NULL; // Handle to this DLL itself.
|
|
HMODULE g_hmodRichEdit = NULL;
|
|
HMODULE g_hmodxEnroll=NULL; // Handle to the xEnroll dll
|
|
|
|
|
|
typedef struct _CREATE_REQUEST_WIZARD_STATE {
|
|
HANDLE hRequest;
|
|
DWORD dwPurpose;
|
|
LPWSTR pwszMachineName;
|
|
DWORD dwStoreFlags;
|
|
} CREATE_REQUEST_WIZARD_STATE, *PCREATE_REQUEST_WIZARD_STATE;
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// library Entry Point
|
|
extern "C"
|
|
BOOL WINAPI Wizard_DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
|
{
|
|
if (dwReason == DLL_PROCESS_ATTACH)
|
|
g_hmodThisDll=hInstance;
|
|
|
|
if (dwReason == DLL_PROCESS_DETACH)
|
|
{
|
|
// If the rich edit dll was loaded, then unload it now
|
|
if (g_hmodRichEdit != NULL)
|
|
{
|
|
FreeLibrary(g_hmodRichEdit);
|
|
}
|
|
|
|
//if xEnroll.dll was loaded, unload it now
|
|
if(NULL != g_hmodxEnroll)
|
|
{
|
|
FreeLibrary(g_hmodxEnroll);
|
|
}
|
|
}
|
|
|
|
return TRUE; // ok
|
|
}
|
|
|
|
|
|
DWORD CryptUIStatusToIDSText(HRESULT hr, DWORD dwStatus)
|
|
{
|
|
switch(dwStatus)
|
|
{
|
|
case CRYPTUI_WIZ_CERT_REQUEST_STATUS_UNKNOWN: return IDS_UNKNOWN_WIZARD_ERROR;
|
|
case CRYPTUI_WIZ_CERT_REQUEST_STATUS_REQUEST_ERROR: return IDS_REQUEST_ERROR;
|
|
case CRYPTUI_WIZ_CERT_REQUEST_STATUS_REQUEST_DENIED: return IDS_REQUEST_DENIED;
|
|
case CRYPTUI_WIZ_CERT_REQUEST_STATUS_SUCCEEDED: return S_OK == hr ? IDS_REQUEST_SUCCEDDED : IDS_REQUEST_FAILED;
|
|
case CRYPTUI_WIZ_CERT_REQUEST_STATUS_ISSUED_SEPARATELY: return IDS_ISSUED_SEPERATE;
|
|
case CRYPTUI_WIZ_CERT_REQUEST_STATUS_UNDER_SUBMISSION: return IDS_UNDER_SUBMISSION;
|
|
case CRYPTUI_WIZ_CERT_REQUEST_STATUS_INSTALL_FAILED: return IDS_INSTALL_FAILED;
|
|
case CRYPTUI_WIZ_CERT_REQUEST_STATUS_CONNECTION_FAILED: return IDS_CONNET_CA_FAILED;
|
|
case CRYPTUI_WIZ_CERT_REQUEST_STATUS_INSTALL_CANCELLED: return IDS_INSTAL_CANCELLED;
|
|
case CRYPTUI_WIZ_CERT_REQUEST_STATUS_KEYSVC_FAILED: return IDS_RPC_CALL_FAILED;
|
|
default:
|
|
return IDS_UNKNOWN_WIZARD_ERROR;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// I_EnrollMessageBox
|
|
//
|
|
//
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
int I_EnrollMessageBox(
|
|
HWND hWnd,
|
|
UINT idsText,
|
|
HRESULT hr,
|
|
UINT idsCaption,
|
|
LPCWSTR pwszCaption,
|
|
UINT uType)
|
|
{
|
|
//we print out the error message (hr) for denied and error case
|
|
WCHAR wszText[MAX_STRING_SIZE];
|
|
WCHAR wszCaption[MAX_STRING_SIZE];
|
|
UINT intReturn=0;
|
|
|
|
LPWSTR wszErrorMsg=NULL;
|
|
LPWSTR wszTextErr=NULL;
|
|
|
|
//init
|
|
wszText[0]=L'\0';
|
|
wszCaption[0]=L'\0';
|
|
|
|
if((IDS_REQUEST_ERROR != idsText) && (IDS_REQUEST_DENIED != idsText) &&
|
|
(IDS_REQUEST_FAILED != idsText) && (IDS_UNKNOWN_WIZARD_ERROR != idsText) &&
|
|
(IDS_INSTALL_FAILED != idsText))
|
|
return I_MessageBox(hWnd, idsText, idsCaption, pwszCaption, uType);
|
|
|
|
|
|
//get the caption string
|
|
if(NULL == pwszCaption)
|
|
{
|
|
if(!LoadStringU(g_hmodThisDll, idsCaption, wszCaption, ARRAYSIZE(wszCaption)))
|
|
return 0;
|
|
}
|
|
|
|
//get the text string
|
|
if(!LoadStringU(g_hmodThisDll, idsText, wszText, ARRAYSIZE(wszText)))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
//cancatenate the error string with the error string.
|
|
//using W version because this is a NT5 only function call
|
|
if( FAILED(hr) && FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
NULL,
|
|
hr,
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
|
(LPWSTR) &wszErrorMsg,
|
|
0,
|
|
NULL))
|
|
{
|
|
|
|
wszTextErr=(LPWSTR)WizardAlloc(sizeof(WCHAR) *(wcslen(wszText) + wcslen(wszErrorMsg) + wcslen(L". ")+2));
|
|
|
|
if(!wszTextErr)
|
|
{
|
|
if(wszErrorMsg)
|
|
LocalFree(wszErrorMsg);
|
|
|
|
return 0;
|
|
}
|
|
|
|
wcscpy(wszTextErr, wszText);
|
|
|
|
wcscat(wszTextErr, wszErrorMsg);
|
|
|
|
}
|
|
else
|
|
{
|
|
wszTextErr=(LPWSTR)WizardAlloc((wcslen(wszText) + 2) * sizeof(WCHAR));
|
|
|
|
if(!wszTextErr)
|
|
{
|
|
if(wszErrorMsg)
|
|
LocalFree(wszErrorMsg);
|
|
|
|
return 0;
|
|
}
|
|
|
|
wcscpy(wszTextErr, wszText);
|
|
}
|
|
|
|
//message box
|
|
if(pwszCaption)
|
|
{
|
|
intReturn=MessageBoxExW(hWnd, wszTextErr, pwszCaption, uType, 0);
|
|
}
|
|
else
|
|
intReturn=MessageBoxExW(hWnd, wszTextErr, wszCaption, uType, 0);
|
|
|
|
if(wszErrorMsg)
|
|
LocalFree(wszErrorMsg);
|
|
|
|
if(wszTextErr)
|
|
WizardFree(wszTextErr);
|
|
|
|
return intReturn;
|
|
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
// WizardCopyAndFreeWStr
|
|
//
|
|
// Alloc and copy the new string and free the old string. If failed to
|
|
// alloc the memory, use the old string
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
LPWSTR WizardCopyAndFreeWStr(LPWSTR pwszNew, LPWSTR pwszOld)
|
|
{
|
|
LPWSTR pwsz=NULL;
|
|
|
|
pwsz=WizardAllocAndCopyWStr(pwszNew);
|
|
|
|
if(pwsz)
|
|
{
|
|
WizardFree(pwszOld);
|
|
}
|
|
else
|
|
{
|
|
pwsz=pwszOld;
|
|
}
|
|
|
|
return pwsz;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// GetCAContext
|
|
//
|
|
// Call the CA selection dialogue, get the selected CA name and update
|
|
// internal data. (pCertWizardInfo->pwszCALocation, pCertWizardInfo->
|
|
// pwszCAName, and pCertWizardInfo->dwCAindex).
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
PCRYPTUI_CA_CONTEXT GetCAContext(HWND hwndControl,
|
|
CERT_WIZARD_INFO *pCertWizardInfo)
|
|
{
|
|
DWORD dwCACount=0;
|
|
PCRYPTUI_WIZ_CERT_CA_INFO pCertCAInfo=NULL;
|
|
DWORD dwIndex=0;
|
|
BOOL fResult=FALSE;
|
|
CRYPTUI_SELECT_CA_STRUCT SelectCAStruct;
|
|
PCRYPTUI_CA_CONTEXT pCAContext=NULL;
|
|
BOOL fFoundCA=FALSE;
|
|
LPWSTR pwszOldName=NULL;
|
|
LPWSTR pwszOldLocation=NULL;
|
|
|
|
PCRYPTUI_CA_CONTEXT *prgCAContext=NULL;
|
|
LPWSTR pwszCADisplayName=NULL;
|
|
|
|
|
|
//init
|
|
memset(&SelectCAStruct, 0, sizeof(CRYPTUI_SELECT_CA_STRUCT));
|
|
|
|
if(NULL == pCertWizardInfo)
|
|
return NULL;
|
|
|
|
pCertCAInfo=pCertWizardInfo->pCertCAInfo;
|
|
|
|
if(NULL==pCertCAInfo)
|
|
return NULL;
|
|
|
|
if( (0==pCertCAInfo->dwCA) || (NULL == pCertCAInfo->rgCA))
|
|
return NULL;
|
|
|
|
|
|
//add all the CAs
|
|
prgCAContext=(PCRYPTUI_CA_CONTEXT *)WizardAlloc(
|
|
sizeof(PCRYPTUI_CA_CONTEXT) * (pCertCAInfo->dwCA));
|
|
|
|
if(NULL == prgCAContext)
|
|
goto MemoryErr;
|
|
|
|
//memset
|
|
memset(prgCAContext, 0, sizeof(PCRYPTUI_CA_CONTEXT) * (pCertCAInfo->dwCA));
|
|
|
|
//add the count
|
|
dwCACount = 0;
|
|
|
|
for(dwIndex=1; dwIndex <(pCertCAInfo->dwCA); dwIndex++)
|
|
{
|
|
//skip the 1st CA. it contains generic information
|
|
if((pCertCAInfo->rgCA)[dwIndex].pwszCAName && (pCertCAInfo->rgCA)[dwIndex].pwszCALocation)
|
|
{
|
|
|
|
//the CA has to support the selected CT
|
|
if(CASupportSpecifiedCertType(&((pCertCAInfo->rgCA)[dwIndex])))
|
|
{
|
|
|
|
prgCAContext[dwCACount]=(PCRYPTUI_CA_CONTEXT)WizardAlloc(
|
|
sizeof(CRYPTUI_CA_CONTEXT));
|
|
|
|
if(NULL==prgCAContext[dwCACount])
|
|
goto MemoryErr;
|
|
|
|
//memset
|
|
memset(prgCAContext[dwCACount], 0, sizeof(CRYPTUI_CA_CONTEXT));
|
|
|
|
prgCAContext[dwCACount]->dwSize=sizeof(CRYPTUI_CA_CONTEXT);
|
|
|
|
if(!CAUtilGetCADisplayName(
|
|
(pCertWizardInfo->fMachine) ? CA_FIND_LOCAL_SYSTEM:0,
|
|
(pCertCAInfo->rgCA)[dwIndex].pwszCAName,
|
|
(LPWSTR *)&(prgCAContext[dwCACount]->pwszCAName)))
|
|
{
|
|
prgCAContext[dwCACount]->pwszCAName=(LPCWSTR)WizardAllocAndCopyWStr(
|
|
(pCertCAInfo->rgCA)[dwIndex].pwszCAName);
|
|
}
|
|
|
|
prgCAContext[dwCACount]->pwszCAMachineName=(LPCWSTR)WizardAllocAndCopyWStr(
|
|
(pCertCAInfo->rgCA)[dwIndex].pwszCALocation);
|
|
|
|
//make sure we have the correct information
|
|
if((NULL==prgCAContext[dwCACount]->pwszCAName) ||
|
|
(NULL==prgCAContext[dwCACount]->pwszCAMachineName)
|
|
)
|
|
goto TraceErr;
|
|
|
|
//add the count of the CA
|
|
dwCACount++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(0 == dwCACount)
|
|
goto InvalidArgErr;
|
|
|
|
//call the CA selection dialogue
|
|
SelectCAStruct.dwSize=sizeof(CRYPTUI_SELECT_CA_STRUCT);
|
|
SelectCAStruct.hwndParent=hwndControl;
|
|
SelectCAStruct.cCAContext=dwCACount;
|
|
SelectCAStruct.rgCAContext=(PCCRYPTUI_CA_CONTEXT *)prgCAContext;
|
|
SelectCAStruct.pSelectCACallback=NULL;
|
|
SelectCAStruct.wszDisplayString=NULL;
|
|
|
|
pCAContext=(PCRYPTUI_CA_CONTEXT)CryptUIDlgSelectCA(&SelectCAStruct);
|
|
|
|
if(pCAContext)
|
|
{
|
|
if((NULL == (pCAContext->pwszCAName)) || (NULL == (pCAContext->pwszCAMachineName)))
|
|
goto MemoryErr;
|
|
|
|
//user has selected a CA. Find it in our list
|
|
fFoundCA=FALSE;
|
|
|
|
for(dwIndex=1; dwIndex <(pCertCAInfo->dwCA); dwIndex++)
|
|
{
|
|
//skip the 1st CA. it contains generic information
|
|
if((pCertCAInfo->rgCA)[dwIndex].pwszCAName && (pCertCAInfo->rgCA)[dwIndex].pwszCALocation)
|
|
{
|
|
//the CA has to support the selected CT
|
|
if(CASupportSpecifiedCertType(&((pCertCAInfo->rgCA)[dwIndex])))
|
|
{
|
|
if(0 == wcscmp((pCertCAInfo->rgCA)[dwIndex].pwszCALocation,
|
|
pCAContext->pwszCAMachineName))
|
|
{
|
|
|
|
if(CAUtilGetCADisplayName(
|
|
(pCertWizardInfo->fMachine) ? CA_FIND_LOCAL_SYSTEM:0,
|
|
(pCertCAInfo->rgCA)[dwIndex].pwszCAName,
|
|
&pwszCADisplayName))
|
|
{
|
|
if(0==wcscmp(pwszCADisplayName,
|
|
pCAContext->pwszCAName))
|
|
fFoundCA=TRUE;
|
|
}
|
|
else
|
|
{
|
|
if(0==wcscmp((pCertCAInfo->rgCA)[dwIndex].pwszCAName,
|
|
pCAContext->pwszCAName))
|
|
fFoundCA=TRUE;
|
|
}
|
|
|
|
//free the memory
|
|
if(pwszCADisplayName)
|
|
{
|
|
WizardFree(pwszCADisplayName);
|
|
pwszCADisplayName=NULL;
|
|
}
|
|
|
|
if(fFoundCA)
|
|
{
|
|
pwszOldName = pCertWizardInfo->pwszCAName;
|
|
pwszOldLocation = pCertWizardInfo->pwszCALocation;
|
|
|
|
pCertWizardInfo->pwszCALocation=
|
|
WizardCopyAndFreeWStr((pCertCAInfo->rgCA)[dwIndex].pwszCALocation,
|
|
pwszOldLocation);
|
|
|
|
pCertWizardInfo->pwszCAName=
|
|
WizardCopyAndFreeWStr((pCertCAInfo->rgCA)[dwIndex].pwszCAName,
|
|
pwszOldName);
|
|
|
|
//copy the new data
|
|
pCertWizardInfo->dwCAIndex=dwIndex;
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//we should find the selected the CA in our cached CA list
|
|
if(FALSE == fFoundCA)
|
|
goto TraceErr;
|
|
}
|
|
|
|
|
|
fResult=TRUE;
|
|
|
|
CommonReturn:
|
|
|
|
if(pwszCADisplayName)
|
|
{
|
|
WizardFree(pwszCADisplayName);
|
|
pwszCADisplayName=NULL;
|
|
}
|
|
|
|
//free the CA list
|
|
if(prgCAContext)
|
|
{
|
|
for(dwIndex=0; dwIndex<dwCACount; dwIndex++)
|
|
{
|
|
if(prgCAContext[dwIndex])
|
|
CryptUIDlgFreeCAContext(prgCAContext[dwIndex]);
|
|
}
|
|
|
|
WizardFree(prgCAContext);
|
|
}
|
|
|
|
return pCAContext;
|
|
|
|
ErrorReturn:
|
|
|
|
if(pCAContext)
|
|
{
|
|
CryptUIDlgFreeCAContext(pCAContext);
|
|
pCAContext=NULL;
|
|
}
|
|
|
|
fResult=FALSE;
|
|
goto CommonReturn;
|
|
|
|
TRACE_ERROR(TraceErr);
|
|
SET_ERROR(MemoryErr, E_OUTOFMEMORY);
|
|
SET_ERROR(InvalidArgErr, E_INVALIDARG);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// FormatMessageStr
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
int ListView_InsertItemU_IDS(HWND hwndList,
|
|
LV_ITEMW *plvItem,
|
|
UINT idsString,
|
|
LPWSTR pwszText)
|
|
{
|
|
WCHAR wszText[MAX_STRING_SIZE];
|
|
|
|
|
|
if(pwszText)
|
|
plvItem->pszText=pwszText;
|
|
else
|
|
{
|
|
if(!LoadStringU(g_hmodThisDll, idsString, wszText, MAX_STRING_SIZE))
|
|
return -1;
|
|
|
|
plvItem->pszText=wszText;
|
|
}
|
|
|
|
return ListView_InsertItemU(hwndList, plvItem);
|
|
}
|
|
|
|
|
|
//*******************************************************************************
|
|
// WinProc for the enrollment wizard
|
|
//
|
|
//*******************************************************************************
|
|
|
|
|
|
//--------------------------------------------------------------------------------
|
|
//
|
|
// Inserts an entry into our confirmation dialog's list view.
|
|
//
|
|
//--------------------------------------------------------------------------------
|
|
void ConfirmationListView_InsertItem(HWND hwndControl, LV_ITEMW *plvItem, UINT idsText, LPCWSTR pwszText)
|
|
{
|
|
plvItem->iSubItem=0;
|
|
|
|
if (0 == idsText)
|
|
{
|
|
plvItem->pszText = L"";
|
|
ListView_InsertItemU(hwndControl, plvItem);
|
|
}
|
|
else
|
|
ListView_InsertItemU_IDS(hwndControl, plvItem, idsText, NULL);
|
|
|
|
plvItem->iSubItem++;
|
|
ListView_SetItemTextU(hwndControl, plvItem->iItem, plvItem->iSubItem, pwszText);
|
|
plvItem->iItem++;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------
|
|
//populate the list box in the order of friendly name,
|
|
//UserName, CA, Purpose, and CSP
|
|
//-------------------------------------------------------------------------
|
|
void DisplayConfirmation(HWND hwndControl,
|
|
CERT_WIZARD_INFO *pCertWizardInfo)
|
|
{
|
|
WCHAR wszBuffer[MAX_TITLE_LENGTH];
|
|
WCHAR wszBuffer2[MAX_TITLE_LENGTH];
|
|
DWORD dwIndex=0;
|
|
UINT ids=0;
|
|
|
|
LPWSTR pwszCADisplayName = NULL;
|
|
|
|
LV_ITEMW lvItem;
|
|
CRYPTUI_WIZ_CERT_CA *pCertCA=NULL;
|
|
|
|
//delete all the old items in the listView
|
|
ListView_DeleteAllItems(hwndControl);
|
|
|
|
//insert row by row
|
|
memset(wszBuffer, 0, sizeof(wszBuffer));
|
|
memset(&lvItem, 0, sizeof(LV_ITEMW));
|
|
|
|
// set up the fields in the list view item struct that don't change from item to item
|
|
lvItem.mask = LVIF_TEXT | LVIF_STATE ;
|
|
lvItem.state = 0;
|
|
lvItem.stateMask = 0;
|
|
lvItem.iItem = 0;
|
|
|
|
// Friendly Name (only shown for enroll)
|
|
if (0 == (CRYPTUI_WIZ_CERT_RENEW & pCertWizardInfo->dwPurpose))
|
|
{
|
|
LPWSTR pwszFriendlyName = L"";
|
|
if(pCertWizardInfo->pwszFriendlyName)
|
|
{
|
|
pwszFriendlyName = pCertWizardInfo->pwszFriendlyName;
|
|
}
|
|
else
|
|
{
|
|
if (LoadStringU(g_hmodThisDll, IDS_NONE, wszBuffer, ARRAYSIZE(wszBuffer)))
|
|
pwszFriendlyName = &wszBuffer[0];
|
|
}
|
|
ConfirmationListView_InsertItem(hwndControl, &lvItem, IDS_FRIENDLY_NAME, pwszFriendlyName);
|
|
}
|
|
|
|
//Machine Name/SerivceName/ UserName
|
|
if(pCertWizardInfo->pwszAccountName)
|
|
{
|
|
ConfirmationListView_InsertItem(hwndControl, &lvItem, IDS_USER_NAME, pCertWizardInfo->pwszAccountName);
|
|
}
|
|
|
|
//machine name
|
|
if(pCertWizardInfo->pwszMachineName)
|
|
{
|
|
ConfirmationListView_InsertItem(hwndControl, &lvItem, IDS_COMPUTER_NAME, pCertWizardInfo->pwszMachineName);
|
|
}
|
|
|
|
//CA
|
|
//check if we know exactly which CA to send the request;
|
|
//or we are going through the loop
|
|
if ((TRUE == pCertWizardInfo->fUIAdv) || (TRUE == pCertWizardInfo->fCAInput))
|
|
{
|
|
if(pCertWizardInfo->pwszCAName)
|
|
{
|
|
LPWSTR pwszCAName = NULL;
|
|
|
|
if(pCertWizardInfo->pwszCADisplayName)
|
|
pwszCAName = pCertWizardInfo->pwszCADisplayName;
|
|
else if (CAUtilGetCADisplayName((pCertWizardInfo->fMachine) ? CA_FIND_LOCAL_SYSTEM:0, pCertWizardInfo->pwszCAName, &pwszCADisplayName))
|
|
pwszCAName = pwszCADisplayName;
|
|
else
|
|
pwszCAName = pCertWizardInfo->pwszCAName;
|
|
|
|
ConfirmationListView_InsertItem(hwndControl, &lvItem, IDS_CA, pwszCAName);
|
|
}
|
|
}
|
|
|
|
//populate the OID name and certtype name (only shown for enroll)
|
|
if (0 == (CRYPTUI_WIZ_CERT_RENEW & pCertWizardInfo->dwPurpose))
|
|
{
|
|
ids = IDS_PURPOSE;
|
|
pCertCA=&(pCertWizardInfo->pCertCAInfo->rgCA[pCertWizardInfo->dwCAIndex]);
|
|
for(dwIndex=0; dwIndex<pCertCA->dwOIDInfo; dwIndex++)
|
|
{
|
|
if(TRUE==((pCertCA->rgOIDInfo[dwIndex]).fSelected))
|
|
{
|
|
ConfirmationListView_InsertItem(hwndControl, &lvItem, ids, (pCertCA->rgOIDInfo[dwIndex]).pwszName);
|
|
ids = 0;
|
|
}
|
|
}
|
|
|
|
for(dwIndex=0; dwIndex<pCertCA->dwCertTypeInfo; dwIndex++)
|
|
{
|
|
if(TRUE==((pCertCA->rgCertTypeInfo[dwIndex]).fSelected))
|
|
{
|
|
ConfirmationListView_InsertItem(hwndControl, &lvItem, ids, (pCertCA->rgCertTypeInfo[dwIndex]).pwszCertTypeName);
|
|
ids = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(pCertWizardInfo->pwszProvider)
|
|
{
|
|
ConfirmationListView_InsertItem(hwndControl, &lvItem, IDS_CSP, pCertWizardInfo->pwszProvider);
|
|
}
|
|
|
|
// Advanced options:
|
|
if (TRUE == pCertWizardInfo->fUIAdv)
|
|
{
|
|
// Key creation options:
|
|
if (pCertWizardInfo->fNewKey)
|
|
{
|
|
// Minimum key size:
|
|
if (pCertWizardInfo->dwMinKeySize)
|
|
{
|
|
WCHAR * const rgParams[1] = { (WCHAR *)(ULONG_PTR) pCertWizardInfo->dwMinKeySize };
|
|
|
|
if (FormatMessageU(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
|
|
L"%1!d!%0", 0, 0, wszBuffer, ARRAYSIZE(wszBuffer), (va_list *)rgParams))
|
|
{
|
|
ConfirmationListView_InsertItem(hwndControl, &lvItem, IDS_MIN_KEYSIZE, wszBuffer);
|
|
}
|
|
}
|
|
|
|
// Is key exportable?
|
|
ids = (0 != (CRYPT_EXPORTABLE & pCertWizardInfo->dwGenKeyFlags)) ? IDS_YES : IDS_NO;
|
|
if (LoadStringU(g_hmodThisDll, ids, wszBuffer2, ARRAYSIZE(wszBuffer2)))
|
|
{
|
|
ConfirmationListView_InsertItem(hwndControl, &lvItem, IDS_KEY_EXPORTABLE, wszBuffer2);
|
|
}
|
|
|
|
// Is strong key protection enabled?
|
|
ids = (0 != (CRYPT_USER_PROTECTED & pCertWizardInfo->dwGenKeyFlags)) ? IDS_YES : IDS_NO;
|
|
if (LoadStringU(g_hmodThisDll, ids, wszBuffer, ARRAYSIZE(wszBuffer)))
|
|
{
|
|
ConfirmationListView_InsertItem(hwndControl, &lvItem, IDS_STRONG_PROTECTION, wszBuffer);
|
|
}
|
|
}
|
|
}
|
|
|
|
ListView_SetItemState(hwndControl, 0, LVIS_SELECTED, LVIS_SELECTED);
|
|
|
|
//autosize the columns
|
|
ListView_SetColumnWidth(hwndControl, 0, LVSCW_AUTOSIZE);
|
|
ListView_SetColumnWidth(hwndControl, 1, LVSCW_AUTOSIZE);
|
|
|
|
|
|
// CommonReturn:
|
|
if (NULL != pwszCADisplayName)
|
|
WizardFree(pwszCADisplayName);
|
|
|
|
return;
|
|
}
|
|
|
|
BOOL GetSelectedCertTypeInfo(IN CERT_WIZARD_INFO *pCertWizardInfo,
|
|
OUT ENROLL_CERT_TYPE_INFO **ppCertTypeInfo)
|
|
{
|
|
DWORD dwIndex;
|
|
PCRYPTUI_WIZ_CERT_CA pCertCA;
|
|
|
|
if (pCertWizardInfo == NULL)
|
|
return FALSE;
|
|
|
|
pCertCA=&(pCertWizardInfo->pCertCAInfo->rgCA[pCertWizardInfo->dwCAIndex]);
|
|
for(dwIndex=0; dwIndex<pCertCA->dwCertTypeInfo; dwIndex++)
|
|
{
|
|
if((pCertCA->rgCertTypeInfo)[dwIndex].fSelected)
|
|
{
|
|
*ppCertTypeInfo = &((pCertCA->rgCertTypeInfo)[dwIndex]);
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
//Initialize the CSP list
|
|
//-----------------------------------------------------------------------
|
|
BOOL InitCSPList(HWND hwndList,
|
|
CERT_WIZARD_INFO *pCertWizardInfo)
|
|
{
|
|
DWORD dwMinSize;
|
|
DWORD dwMaxSize;
|
|
DWORD dwInc;
|
|
LV_ITEMW lvItem;
|
|
CRYPTUI_WIZ_CERT_CA *pCertCA=NULL;
|
|
ENROLL_CERT_TYPE_INFO *pCertTypeInfo=NULL;
|
|
int iInsertedIndex=0;
|
|
|
|
if(!hwndList || !pCertWizardInfo)
|
|
return FALSE;
|
|
|
|
if(!(pCertWizardInfo->pCertCAInfo) || !(pCertWizardInfo->pwszCALocation) ||
|
|
!(pCertWizardInfo->pwszCAName))
|
|
return FALSE;
|
|
|
|
//delete all the old items in the listView
|
|
ListView_DeleteAllItems(hwndList);
|
|
|
|
//populate the list
|
|
memset(&lvItem, 0, sizeof(LV_ITEMW));
|
|
lvItem.mask=LVIF_TEXT | LVIF_STATE | LVIF_PARAM;
|
|
|
|
pCertCA=&(pCertWizardInfo->pCertCAInfo->rgCA[pCertWizardInfo->dwCAIndex]);
|
|
pCertTypeInfo = NULL;
|
|
GetSelectedCertTypeInfo(pCertWizardInfo, &pCertTypeInfo);
|
|
|
|
// Populate the CSP list with the intersection of:
|
|
// 1) The available CSPs on the local machine
|
|
// and 2) The CSPs specified on the template.
|
|
//
|
|
// If no template information is available, or the template does not specify
|
|
// a CSP, enumerate all CSPs.
|
|
//
|
|
for(DWORD dwLocalCSPIndex = 0; dwLocalCSPIndex < pCertWizardInfo->dwCSPCount; dwLocalCSPIndex++)
|
|
{
|
|
BOOL fUseCSP = FALSE;
|
|
|
|
if (NULL == pCertTypeInfo)
|
|
{
|
|
fUseCSP = TRUE;
|
|
}
|
|
else
|
|
{
|
|
for (DWORD dwTemplateCSPIndex = 0; dwTemplateCSPIndex < pCertTypeInfo->dwCSPCount; dwTemplateCSPIndex++)
|
|
{
|
|
if(dwLocalCSPIndex == pCertTypeInfo->rgdwCSP[dwTemplateCSPIndex])
|
|
{
|
|
// The CSP is specified in the template, so we can use it,
|
|
// if it supports an algorithm / key size that matches
|
|
// the template information.
|
|
if (GetValidKeySizes
|
|
((pCertWizardInfo->rgwszProvider)[dwLocalCSPIndex],
|
|
(pCertWizardInfo->rgdwProviderType)[dwLocalCSPIndex],
|
|
pCertTypeInfo->dwKeySpec,
|
|
&dwMinSize,
|
|
&dwMaxSize,
|
|
&dwInc))
|
|
{
|
|
fUseCSP = dwMaxSize >= pCertTypeInfo->dwMinKeySize;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (fUseCSP)
|
|
{
|
|
lvItem.iItem = dwLocalCSPIndex;
|
|
lvItem.pszText = (pCertWizardInfo->rgwszProvider)[dwLocalCSPIndex];
|
|
lvItem.cchTextMax = sizeof(WCHAR)*(1+wcslen((pCertWizardInfo->rgwszProvider)[dwLocalCSPIndex]));
|
|
lvItem.lParam = (LPARAM)dwLocalCSPIndex;
|
|
|
|
//insert the item,
|
|
iInsertedIndex = ListView_InsertItemU(hwndList, &lvItem);
|
|
|
|
// Highlight a CSP if it is already specified through the advanced
|
|
// options. If not, highlight the first CSP on the template.
|
|
//
|
|
BOOL fHighlightCSP = FALSE;
|
|
|
|
if (pCertWizardInfo->pwszProvider)
|
|
{
|
|
fHighlightCSP = 0 == _wcsicmp(pCertWizardInfo->pwszProvider, lvItem.pszText);
|
|
}
|
|
else
|
|
{
|
|
if (NULL != pCertTypeInfo && pCertTypeInfo->dwCSPCount > 0)
|
|
{
|
|
//we highlight the 1st one of the intersection if there is any
|
|
fHighlightCSP = dwLocalCSPIndex == pCertTypeInfo->rgdwCSP[0];
|
|
}
|
|
else
|
|
{
|
|
// We don't highlight a CSP in this case.
|
|
}
|
|
}
|
|
|
|
if (fHighlightCSP)
|
|
{
|
|
ListView_SetItemState
|
|
(hwndList,
|
|
iInsertedIndex,
|
|
LVIS_SELECTED,
|
|
LVIS_SELECTED);
|
|
|
|
ListView_EnsureVisible
|
|
(hwndList,
|
|
iInsertedIndex,
|
|
FALSE);
|
|
}
|
|
}
|
|
}
|
|
|
|
//make the column autosize
|
|
ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL CSPListIndexToCertWizardInfoIndex(IN HWND hwnd,
|
|
IN int nCSPIndex,
|
|
OUT DWORD *pdwWizardIndex)
|
|
{
|
|
LVITEM lvItem;
|
|
|
|
if (hwnd == NULL || nCSPIndex < 0)
|
|
return FALSE;
|
|
|
|
memset(&lvItem, 0, sizeof(LV_ITEM));
|
|
lvItem.mask = LVIF_PARAM;
|
|
lvItem.iItem = nCSPIndex;
|
|
|
|
if(!ListView_GetItem(hwnd, &lvItem))
|
|
return FALSE;
|
|
|
|
*pdwWizardIndex = (DWORD)lvItem.lParam;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL InitKeySizesList(IN HWND hWnd, // Required: The combo box to initialize.
|
|
IN DWORD dwCTMinKeySize, // Required: The min key size specified on the template
|
|
IN LPWSTR lpwszProvider, // Required: The CSP.
|
|
IN DWORD dwProvType, // Required: The provider type.
|
|
IN DWORD dwKeySpec // Required: Either AT_SIGNATURE or AT_KEYEXCHANGE.
|
|
)
|
|
{
|
|
static const DWORD dwSmallValidKeySizes[] = { 40, 56, 64, 128, 256, 384 };
|
|
static const DWORD dwLargeValidKeySizes[] = { 512, 1024, 2048, 4096, 8192, 16384 };
|
|
static const DWORD dwAllValidKeySizes[] = { 40, 56, 64, 128, 256, 384, 512, 1024, 2048, 4096, 8192, 16384 };
|
|
|
|
static const DWORD dwSmLen = sizeof(dwSmallValidKeySizes) / sizeof(DWORD);
|
|
static const DWORD dwLgLen = sizeof(dwLargeValidKeySizes) / sizeof(DWORD);
|
|
static const DWORD dwAllLen = sizeof(dwAllValidKeySizes) / sizeof(DWORD);
|
|
|
|
static const DWORD MAX_KEYSIZE_STRING_SIZE = sizeof(WCHAR) * 8;
|
|
static WCHAR ppwszStrings[dwAllLen][MAX_KEYSIZE_STRING_SIZE];
|
|
|
|
BOOL fIsLargeKey = FALSE;
|
|
BOOL fIsSmallKey = FALSE;
|
|
BOOL fResult = FALSE;
|
|
DWORD dwMinSize;
|
|
DWORD dwMaxSize;
|
|
DWORD dwInc;
|
|
const DWORD *pdwValidKeySizes;
|
|
DWORD dwValidKeySizesLen;
|
|
|
|
// Temporaries:
|
|
DWORD dwCurrent;
|
|
DWORD dwIndex;
|
|
|
|
|
|
// Validate inputs:
|
|
if (hWnd == NULL || lpwszProvider == NULL)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
goto Error;
|
|
}
|
|
|
|
// First, delete all items present in the list view.
|
|
// (This always succeeds).
|
|
SendMessage(hWnd, CB_RESETCONTENT, (WPARAM)0, (LPARAM)0);
|
|
|
|
if (!GetValidKeySizes
|
|
(lpwszProvider,
|
|
dwProvType,
|
|
dwKeySpec,
|
|
&dwMinSize,
|
|
&dwMaxSize,
|
|
&dwInc))
|
|
goto Error;
|
|
|
|
if (dwCTMinKeySize > dwMinSize) {
|
|
dwMinSize = dwCTMinKeySize;
|
|
}
|
|
|
|
fIsLargeKey = dwMinSize >= 512;
|
|
fIsSmallKey = dwMaxSize < 512;
|
|
|
|
if (fIsLargeKey)
|
|
{
|
|
pdwValidKeySizes = &dwLargeValidKeySizes[0];
|
|
dwValidKeySizesLen = dwLgLen;
|
|
}
|
|
else if (fIsSmallKey)
|
|
|
|
{
|
|
pdwValidKeySizes = &dwSmallValidKeySizes[0];
|
|
dwValidKeySizesLen = dwSmLen;
|
|
}
|
|
else
|
|
{
|
|
pdwValidKeySizes = &dwAllValidKeySizes[0];
|
|
dwValidKeySizesLen = dwAllLen;
|
|
}
|
|
|
|
for (dwCurrent = 0, dwIndex = 0; dwCurrent < dwValidKeySizesLen; dwCurrent++)
|
|
{
|
|
if (pdwValidKeySizes[dwCurrent] > dwMaxSize)
|
|
break;
|
|
|
|
if (pdwValidKeySizes[dwCurrent] < dwMinSize)
|
|
continue;
|
|
|
|
if ((dwInc == 0) || (0 == (pdwValidKeySizes[dwCurrent] % dwInc)))
|
|
{
|
|
if (CB_ERR == SendMessageW
|
|
(hWnd,
|
|
CB_ADDSTRING,
|
|
0,
|
|
(LPARAM)_ltow(pdwValidKeySizes[dwCurrent], &ppwszStrings[dwIndex][0], 10)))
|
|
goto Error;
|
|
|
|
if (CB_ERR == SendMessage
|
|
(hWnd,
|
|
CB_SETITEMDATA,
|
|
(WPARAM)dwIndex,
|
|
(LPARAM)pdwValidKeySizes[dwCurrent]))
|
|
goto Error;
|
|
|
|
// Default to 1024-bit keys if we can.
|
|
if (dwIndex == 0 || pdwValidKeySizes[dwCurrent] == 1024)
|
|
SendMessage(hWnd, CB_SETCURSEL, dwIndex, (LPARAM)0);
|
|
|
|
dwIndex++;
|
|
}
|
|
}
|
|
|
|
fResult = TRUE;
|
|
|
|
CommonReturn:
|
|
return fResult;
|
|
|
|
Error:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
//ExistInListView:
|
|
//
|
|
// Check to see if the cert type is alreayd in the list view
|
|
// based on its display name
|
|
//-----------------------------------------------------------------------
|
|
BOOL ExistInListView(HWND hwndList, LPWSTR pwszDisplayName)
|
|
{
|
|
BOOL fExist=FALSE;
|
|
LVFINDINFOW lvfi;
|
|
|
|
|
|
if((NULL == hwndList) || (NULL == pwszDisplayName))
|
|
return FALSE;
|
|
|
|
memset(&lvfi, 0, sizeof(LVFINDINFOW));
|
|
|
|
lvfi.flags=LVFI_STRING;
|
|
lvfi.psz=pwszDisplayName;
|
|
|
|
if(-1 == SendMessageW(hwndList,
|
|
LVM_FINDITEMW,
|
|
(WPARAM)-1,
|
|
(LPARAM)(&lvfi)))
|
|
fExist=FALSE;
|
|
else
|
|
fExist=TRUE;
|
|
|
|
return fExist;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------
|
|
// IsKeyProtected()
|
|
//
|
|
// Determines whether or not a key has strong key protection enabled.
|
|
// Should be used only with user keysets.
|
|
//
|
|
//--------------------------------------------------------------------------------
|
|
HRESULT IsKeyProtected(IN LPWSTR pwszContainerName,
|
|
IN LPWSTR pwszProviderName,
|
|
IN DWORD dwProvType,
|
|
OUT BOOL *pfIsProtected)
|
|
{
|
|
DWORD cbData;
|
|
DWORD dwImpType;
|
|
HCRYPTPROV hCryptProv = NULL;
|
|
HRESULT hr;
|
|
|
|
if (NULL == pwszContainerName || NULL == pwszProviderName || NULL == pfIsProtected)
|
|
goto InvalidArgError;
|
|
|
|
*pfIsProtected = FALSE;
|
|
|
|
// Get the provider context with no key access.
|
|
if (!CryptAcquireContextW(&hCryptProv, NULL, pwszProviderName, dwProvType, CRYPT_VERIFYCONTEXT))
|
|
goto CryptAcquireContextError;
|
|
|
|
cbData = sizeof(dwImpType);
|
|
if (!CryptGetProvParam(hCryptProv, PP_IMPTYPE, (PBYTE) &dwImpType, &cbData, 0))
|
|
goto CryptGetProvParamError;
|
|
|
|
// Assume hardware key is protected.
|
|
if (dwImpType & CRYPT_IMPL_HARDWARE) {
|
|
*pfIsProtected = TRUE;
|
|
} else {
|
|
|
|
// Reacquire context with silent flag.
|
|
CryptReleaseContext(hCryptProv, 0);
|
|
hCryptProv = NULL;
|
|
|
|
if (!CryptAcquireContextW(&hCryptProv, pwszContainerName, pwszProviderName, dwProvType, CRYPT_SILENT)) {
|
|
// CryptAcquireContextW with silent flag, assume user protected
|
|
*pfIsProtected = TRUE;
|
|
}
|
|
}
|
|
|
|
hr = S_OK;
|
|
ErrorReturn:
|
|
if (hCryptProv)
|
|
CryptReleaseContext(hCryptProv, 0);
|
|
return hr;
|
|
|
|
SET_HRESULT(CryptAcquireContextError, HRESULT_FROM_WIN32(GetLastError()));
|
|
SET_HRESULT(CryptGetProvParamError, HRESULT_FROM_WIN32(GetLastError()));
|
|
SET_HRESULT(InvalidArgError, E_INVALIDARG);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
//Initialize the usage OID/CertType list
|
|
//-----------------------------------------------------------------------
|
|
BOOL InitCertTypeList(HWND hwndList,
|
|
CERT_WIZARD_INFO *pCertWizardInfo)
|
|
{
|
|
BOOL fIsKeyProtected;
|
|
DWORD dwCAIndex=0;
|
|
DWORD dwCTIndex=0;
|
|
HRESULT hr;
|
|
LV_ITEMW lvItem;
|
|
BOOL fSelected=FALSE;
|
|
int iInsertedIndex=0;
|
|
DWORD dwValidCTCount=0;
|
|
ENROLL_CERT_TYPE_INFO *pCertTypeInfo=NULL;
|
|
|
|
if(!hwndList || !pCertWizardInfo)
|
|
return FALSE;
|
|
|
|
if(!(pCertWizardInfo->pCertCAInfo) || !(pCertWizardInfo->pwszCALocation) ||
|
|
!(pCertWizardInfo->pwszCAName))
|
|
return FALSE;
|
|
|
|
//delete all the old items in the listView
|
|
ListView_DeleteAllItems(hwndList);
|
|
|
|
//populate the list
|
|
memset(&lvItem, 0, sizeof(LV_ITEMW));
|
|
lvItem.mask=LVIF_TEXT | LVIF_STATE | LVIF_PARAM;
|
|
|
|
// if we're doing an enroll with same key, see whether it has strong key protection:
|
|
if (!pCertWizardInfo->fNewKey) {
|
|
hr = IsKeyProtected((LPWSTR)pCertWizardInfo->pwszKeyContainer,
|
|
(LPWSTR)pCertWizardInfo->pwszProvider,
|
|
pCertWizardInfo->dwProviderType,
|
|
&fIsKeyProtected);
|
|
if (FAILED(hr)) {
|
|
// assume no key protection
|
|
fIsKeyProtected = FALSE;
|
|
}
|
|
}
|
|
|
|
//populate the certType name
|
|
//we search for each CA
|
|
|
|
dwValidCTCount=0;
|
|
|
|
//we start from the 1st CA
|
|
for(dwCAIndex=1; dwCAIndex<pCertWizardInfo->pCertCAInfo->dwCA; dwCAIndex++)
|
|
{
|
|
for(dwCTIndex=0; dwCTIndex <(pCertWizardInfo->pCertCAInfo->rgCA)[dwCAIndex].dwCertTypeInfo; dwCTIndex++)
|
|
{
|
|
pCertTypeInfo=&((pCertWizardInfo->pCertCAInfo->rgCA)[dwCAIndex].rgCertTypeInfo[dwCTIndex]);
|
|
|
|
// if the template specifies strong key protection but our key doesn't have it, filter the template out
|
|
if (!pCertWizardInfo->fNewKey && !fIsKeyProtected && (CT_FLAG_STRONG_KEY_PROTECTION_REQUIRED & pCertTypeInfo->dwPrivateKeyFlags))
|
|
continue;
|
|
|
|
//make sure that we do not have duplicated entries
|
|
if(!ExistInListView(hwndList, pCertTypeInfo->pwszCertTypeName))
|
|
{
|
|
lvItem.iItem=dwValidCTCount;
|
|
|
|
lvItem.pszText=pCertTypeInfo->pwszCertTypeName;
|
|
lvItem.cchTextMax=sizeof(WCHAR)* (1+wcslen(pCertTypeInfo->pwszCertTypeName));
|
|
|
|
lvItem.lParam=(LPARAM)pCertTypeInfo->pwszDNName;
|
|
|
|
//insert the item,
|
|
iInsertedIndex=ListView_InsertItemU(hwndList, &lvItem);
|
|
|
|
//set the item to be selected
|
|
if(pCertTypeInfo->fSelected)
|
|
{
|
|
ListView_SetItemState(
|
|
hwndList,
|
|
iInsertedIndex,
|
|
LVIS_SELECTED,
|
|
LVIS_SELECTED);
|
|
fSelected=TRUE;
|
|
}
|
|
|
|
dwValidCTCount++;
|
|
}
|
|
}
|
|
}
|
|
|
|
//select the 1st item is nothing has been selected
|
|
if(FALSE == fSelected)
|
|
ListView_SetItemState(
|
|
hwndList,
|
|
0,
|
|
LVIS_SELECTED,
|
|
LVIS_SELECTED);
|
|
|
|
//make the column autosize
|
|
ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
// MarkSelectedCertType:
|
|
//
|
|
// Based on the user's certificate type selection, we mark the selected
|
|
// certType. Also, check to see based on the selected certificate type, if we
|
|
// have to show the CSP page. That is, use did not specify a CSP
|
|
// via the API, and the certificate type has no default CSP list.
|
|
|
|
//-----------------------------------------------------------------------
|
|
void MarkSelectedCertType(CERT_WIZARD_INFO *pCertWizardInfo,
|
|
LPWSTR pwszDNName)
|
|
{
|
|
DWORD dwCAIndex=0;
|
|
DWORD dwCTIndex=0;
|
|
PCRYPTUI_WIZ_CERT_CA pCertCA=NULL;
|
|
PCRYPTUI_WIZ_CERT_CA_INFO pCertCAInfo=NULL;
|
|
|
|
|
|
pCertCAInfo=pCertWizardInfo->pCertCAInfo;
|
|
|
|
if(NULL == pCertCAInfo)
|
|
return;
|
|
|
|
//we start from the 1st CA
|
|
for(dwCAIndex=1; dwCAIndex<pCertCAInfo->dwCA; dwCAIndex++)
|
|
{
|
|
pCertCA=&(pCertCAInfo->rgCA[dwCAIndex]);
|
|
|
|
for(dwCTIndex=0; dwCTIndex < pCertCA->dwCertTypeInfo; dwCTIndex++)
|
|
{
|
|
if(0 == wcscmp(pwszDNName, pCertCA->rgCertTypeInfo[dwCTIndex].pwszDNName))
|
|
{
|
|
pCertCA->rgCertTypeInfo[dwCTIndex].fSelected=TRUE;
|
|
|
|
if((NULL == pCertWizardInfo->pwszProvider)&&
|
|
(0==pCertCA->rgCertTypeInfo[dwCTIndex].dwCSPCount)
|
|
)
|
|
pCertWizardInfo->fUICSP=TRUE;
|
|
|
|
if (0 != (CT_FLAG_EXPORTABLE_KEY & pCertCA->rgCertTypeInfo[dwCTIndex].dwPrivateKeyFlags))
|
|
{
|
|
pCertWizardInfo->dwGenKeyFlags |= CRYPT_EXPORTABLE;
|
|
}
|
|
else
|
|
{
|
|
pCertWizardInfo->dwGenKeyFlags &= ~CRYPT_EXPORTABLE;
|
|
}
|
|
|
|
if (0 != (CT_FLAG_STRONG_KEY_PROTECTION_REQUIRED & pCertCA->rgCertTypeInfo[dwCTIndex].dwPrivateKeyFlags))
|
|
{
|
|
pCertWizardInfo->dwGenKeyFlags |= CRYPT_USER_PROTECTED;
|
|
}
|
|
else
|
|
{
|
|
pCertWizardInfo->dwGenKeyFlags &= ~CRYPT_USER_PROTECTED;
|
|
}
|
|
|
|
}
|
|
else
|
|
pCertCA->rgCertTypeInfo[dwCTIndex].fSelected=FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
// ResetDefaultCA:
|
|
//
|
|
// Based on the selected certificate type, we reset the default
|
|
// value for the Ceritification Authority
|
|
//-----------------------------------------------------------------------
|
|
void ResetDefaultCA(CERT_WIZARD_INFO *pCertWizardInfo)
|
|
{
|
|
LPWSTR pwszOldCALocation=NULL;
|
|
LPWSTR pwszOldCAName=NULL;
|
|
|
|
DWORD dwCAIndex=0;
|
|
PCRYPTUI_WIZ_CERT_CA pCertCA=NULL;
|
|
PCRYPTUI_WIZ_CERT_CA_INFO pCertCAInfo=NULL;
|
|
BOOL fFound=FALSE;
|
|
|
|
|
|
pCertCAInfo=pCertWizardInfo->pCertCAInfo;
|
|
|
|
if(NULL == pCertCAInfo)
|
|
return;
|
|
|
|
//if user has specified a CA, then this CA has priority other the rest
|
|
if(pCertWizardInfo->fCAInput)
|
|
{
|
|
|
|
dwCAIndex=pCertWizardInfo->dwOrgCA;
|
|
|
|
pCertCA=&(pCertCAInfo->rgCA[dwCAIndex]);
|
|
|
|
fFound=CASupportSpecifiedCertType(pCertCA);
|
|
|
|
}
|
|
|
|
//we do a generic search if the priority CA does not satisfy the requirements
|
|
if(FALSE == fFound)
|
|
{
|
|
//we start from the 1st CA
|
|
for(dwCAIndex=1; dwCAIndex<pCertCAInfo->dwCA; dwCAIndex++)
|
|
{
|
|
pCertCA=&(pCertCAInfo->rgCA[dwCAIndex]);
|
|
|
|
if(TRUE == (fFound=CASupportSpecifiedCertType(pCertCA)))
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(FALSE == fFound)
|
|
return;
|
|
|
|
//copy the old data
|
|
pwszOldCALocation=pCertWizardInfo->pwszCALocation;
|
|
pwszOldCAName=pCertWizardInfo->pwszCAName;
|
|
|
|
|
|
pCertWizardInfo->pwszCALocation=WizardAllocAndCopyWStr(pCertCAInfo->rgCA[dwCAIndex].pwszCALocation);
|
|
pCertWizardInfo->pwszCAName=WizardAllocAndCopyWStr(pCertCAInfo->rgCA[dwCAIndex].pwszCAName);
|
|
|
|
if(NULL == pCertWizardInfo->pwszCALocation ||
|
|
NULL == pCertWizardInfo->pwszCAName)
|
|
{
|
|
//free the memory
|
|
if(pCertWizardInfo->pwszCALocation)
|
|
WizardFree(pCertWizardInfo->pwszCALocation);
|
|
|
|
if(pCertWizardInfo->pwszCAName)
|
|
WizardFree(pCertWizardInfo->pwszCAName);
|
|
|
|
pCertWizardInfo->pwszCALocation=pwszOldCALocation;
|
|
pCertWizardInfo->pwszCAName=pwszOldCAName;
|
|
|
|
return;
|
|
}
|
|
|
|
pCertWizardInfo->dwCAIndex=dwCAIndex;
|
|
|
|
if(pwszOldCALocation)
|
|
WizardFree(pwszOldCALocation);
|
|
|
|
if(pwszOldCAName)
|
|
WizardFree(pwszOldCAName);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
//enable the window if small card if selected
|
|
//-----------------------------------------------------------------------
|
|
void EnableIfSmartCard(HWND hwndControl, HWND hwndChkBox)
|
|
{
|
|
LPWSTR pwszText=NULL;
|
|
|
|
WCHAR wszCSPName[MAX_STRING_SIZE];
|
|
DWORD dwChar=0;
|
|
int iItem=0;
|
|
|
|
//get the length of the selected item
|
|
iItem=(int)SendMessage(hwndControl, LB_GETCURSEL, 0, 0);
|
|
|
|
dwChar=(DWORD)SendMessage(hwndControl,
|
|
LB_GETTEXTLEN,
|
|
iItem,
|
|
0);
|
|
|
|
//allocate memory
|
|
if(NULL==(pwszText=(LPWSTR)WizardAlloc(sizeof(WCHAR)*(1+dwChar))))
|
|
return;
|
|
|
|
//get the selected CSP name
|
|
if(LB_ERR==Send_LB_GETTEXT(hwndControl,
|
|
iItem,
|
|
(LPARAM)pwszText))
|
|
goto CLEANUP;
|
|
|
|
//get the smart card name
|
|
if(!LoadStringU(g_hmodThisDll, IDS_SMART_CARD, wszCSPName, MAX_STRING_SIZE))
|
|
goto CLEANUP;
|
|
|
|
if(0==wcscmp(wszCSPName, pwszText))
|
|
//enable the box
|
|
EnableWindow(hwndChkBox, TRUE);
|
|
else
|
|
//gray out the box
|
|
EnableWindow(hwndChkBox, FALSE);
|
|
|
|
CLEANUP:
|
|
if(pwszText)
|
|
WizardFree(pwszText);
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
//The winProc for each of the enrollment wizard page
|
|
//
|
|
//-----------------------------------------------------------------------
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
//Welcome
|
|
//-----------------------------------------------------------------------
|
|
INT_PTR APIENTRY Enroll_Welcome(HWND hwndDlg, UINT msg, WPARAM /*wParam*/, LPARAM lParam)
|
|
{
|
|
CERT_WIZARD_INFO *pCertWizardInfo=NULL;
|
|
PROPSHEETPAGE *pPropSheet=NULL;
|
|
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
//set the wizard information so that it can be shared
|
|
pPropSheet = (PROPSHEETPAGE *) lParam;
|
|
pCertWizardInfo = (CERT_WIZARD_INFO *) (pPropSheet->lParam);
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertWizardInfo);
|
|
|
|
SetControlFont(pCertWizardInfo->hBigBold, hwndDlg,IDC_WIZARD_STATIC_BIG_BOLD1);
|
|
// SetControlFont(pCertWizardInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
|
|
// SetControlFont(pCertWizardInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD2);
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
switch (((NMHDR FAR *) lParam)->code)
|
|
{
|
|
|
|
case PSN_KILLACTIVE:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
return TRUE;
|
|
|
|
break;
|
|
|
|
case PSN_RESET:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
break;
|
|
|
|
case PSN_SETACTIVE:
|
|
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
|
|
break;
|
|
|
|
case PSN_WIZBACK:
|
|
break;
|
|
|
|
case PSN_WIZNEXT:
|
|
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
//Purpose
|
|
//-----------------------------------------------------------------------
|
|
INT_PTR APIENTRY Enroll_Purpose(HWND hwndDlg, UINT msg, WPARAM /*wParam*/, LPARAM lParam)
|
|
{
|
|
CERT_WIZARD_INFO *pCertWizardInfo=NULL;
|
|
PROPSHEETPAGE *pPropSheet=NULL;
|
|
HWND hwndControl=NULL;
|
|
DWORD dwIndex=0;
|
|
|
|
LV_COLUMNW lvC;
|
|
LV_ITEM lvItem;
|
|
|
|
NM_LISTVIEW FAR * pnmv=NULL;
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
//set the wizard information so that it can be shared
|
|
pPropSheet = (PROPSHEETPAGE *) lParam;
|
|
pCertWizardInfo = (CERT_WIZARD_INFO *) (pPropSheet->lParam);
|
|
|
|
//make sure pCertWizardInfo is a valid pointer
|
|
if(NULL==pCertWizardInfo)
|
|
break;
|
|
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertWizardInfo);
|
|
|
|
SetControlFont(pCertWizardInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
|
|
|
|
//by default, we do not use the advanced options
|
|
SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK1), BM_SETCHECK, 0, 0);
|
|
|
|
|
|
if(NULL!=(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
|
|
{
|
|
//insert a column into the list view
|
|
memset(&lvC, 0, sizeof(LV_COLUMNW));
|
|
|
|
lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
|
|
lvC.fmt = LVCFMT_LEFT; // Left-align the column.
|
|
lvC.cx = 20; //(dwMaxSize+2)*7; // Width of the column, in pixels.
|
|
lvC.pszText = L""; // The text for the column.
|
|
lvC.iSubItem=0;
|
|
|
|
if (ListView_InsertColumnU(hwndControl, 0, &lvC) == -1)
|
|
break;
|
|
|
|
//initizialize the cert type
|
|
InitCertTypeList(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1),
|
|
pCertWizardInfo);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
switch (((NMHDR FAR *) lParam)->code)
|
|
{
|
|
//the item has been selected
|
|
case LVN_ITEMCHANGED:
|
|
|
|
//get the window handle of the purpose list view
|
|
if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
|
|
break;
|
|
|
|
if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
pnmv = (LPNMLISTVIEW) lParam;
|
|
|
|
if(NULL==pnmv)
|
|
break;
|
|
|
|
//we try not to let user de-select cert template
|
|
if((pnmv->uOldState & LVIS_SELECTED) && (0 == (pnmv->uNewState & LVIS_SELECTED)))
|
|
{
|
|
//we should have something selected
|
|
if(-1 == ListView_GetNextItem(
|
|
hwndControl,
|
|
-1,
|
|
LVNI_SELECTED
|
|
))
|
|
{
|
|
//we should re-select the original item
|
|
ListView_SetItemState(
|
|
hwndControl,
|
|
pnmv->iItem,
|
|
LVIS_SELECTED,
|
|
LVIS_SELECTED);
|
|
|
|
pCertWizardInfo->iOrgCertType=pnmv->iItem;
|
|
}
|
|
}
|
|
|
|
//if something is selected, we disable all other selection
|
|
if(pnmv->uNewState & LVIS_SELECTED)
|
|
{
|
|
if(pnmv->iItem != pCertWizardInfo->iOrgCertType && -1 != pCertWizardInfo->iOrgCertType)
|
|
{
|
|
//we should de-select the original item
|
|
|
|
ListView_SetItemState(
|
|
hwndControl,
|
|
pCertWizardInfo->iOrgCertType,
|
|
0,
|
|
LVIS_SELECTED);
|
|
|
|
pCertWizardInfo->iOrgCertType=-1;
|
|
}
|
|
}
|
|
|
|
break;
|
|
case PSN_KILLACTIVE:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
return TRUE;
|
|
|
|
break;
|
|
|
|
case PSN_RESET:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
break;
|
|
|
|
case PSN_SETACTIVE:
|
|
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
|
|
|
|
if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//if the adv selection is made, it has to stay selected
|
|
if(pCertWizardInfo->fUIAdv)
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK1), FALSE);
|
|
|
|
break;
|
|
|
|
case PSN_WIZBACK:
|
|
|
|
break;
|
|
|
|
case PSN_WIZNEXT:
|
|
|
|
if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//get the window handle of the purpose list view
|
|
if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
|
|
break;
|
|
|
|
//now, mark the one that is selected
|
|
if(-1 != (dwIndex= ListView_GetNextItem(
|
|
hwndControl,
|
|
-1,
|
|
LVNI_SELECTED
|
|
)))
|
|
{
|
|
|
|
//get the selected certificate
|
|
memset(&lvItem, 0, sizeof(LV_ITEM));
|
|
lvItem.mask=LVIF_PARAM;
|
|
lvItem.iItem=(int)dwIndex;
|
|
|
|
if(ListView_GetItem(hwndControl,
|
|
&lvItem))
|
|
{
|
|
|
|
pCertWizardInfo->fCertTypeChanged=FALSE;
|
|
|
|
if(NULL == pCertWizardInfo->pwszSelectedCertTypeDN)
|
|
pCertWizardInfo->fCertTypeChanged=TRUE;
|
|
else
|
|
{
|
|
if(0 != wcscmp(pCertWizardInfo->pwszSelectedCertTypeDN,
|
|
(LPWSTR)lvItem.lParam))
|
|
pCertWizardInfo->fCertTypeChanged=TRUE;
|
|
}
|
|
|
|
if(pCertWizardInfo->fCertTypeChanged)
|
|
{
|
|
pCertWizardInfo->pwszSelectedCertTypeDN=(LPWSTR)(lvItem.lParam);
|
|
|
|
//we need to reset the CSP
|
|
if(FALSE == pCertWizardInfo->fKnownCSP)
|
|
{
|
|
pCertWizardInfo->pwszProvider=NULL;
|
|
pCertWizardInfo->dwProviderType=0;
|
|
}
|
|
else
|
|
{
|
|
//we convert to the original selected CSP information
|
|
pCertWizardInfo->dwProviderType=pCertWizardInfo->dwOrgCSPType;
|
|
pCertWizardInfo->pwszProvider=pCertWizardInfo->pwszOrgCSPName;
|
|
}
|
|
|
|
pCertWizardInfo->fUICSP=FALSE;
|
|
|
|
//mark the selected cert type and mark the rest as un-selected
|
|
MarkSelectedCertType(pCertWizardInfo,
|
|
(LPWSTR)lvItem.lParam);
|
|
|
|
//we need to reset the default CA information based on the new CertType
|
|
ResetDefaultCA(pCertWizardInfo);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
I_MessageBox(hwndDlg, IDS_NO_SELECTED_PURPOSE,
|
|
pCertWizardInfo->idsConfirmTitle,
|
|
pCertWizardInfo->pwszConfirmationTitle,
|
|
MB_ICONEXCLAMATION|MB_OK|MB_APPLMODAL);
|
|
|
|
//make the purpose page stay
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
|
|
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
I_MessageBox(hwndDlg, IDS_NO_SELECTED_PURPOSE,
|
|
pCertWizardInfo->idsConfirmTitle,
|
|
pCertWizardInfo->pwszConfirmationTitle,
|
|
MB_ICONEXCLAMATION|MB_OK|MB_APPLMODAL);
|
|
|
|
//make the purpose page stay
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
//check for the advanced options
|
|
if(TRUE==SendDlgItemMessage(hwndDlg,IDC_WIZARD_CHECK1, BM_GETCHECK, 0, 0))
|
|
pCertWizardInfo->fUIAdv=TRUE;
|
|
else
|
|
pCertWizardInfo->fUIAdv=FALSE;
|
|
|
|
//skip to the correct page based on the advanced options and CSP requirement
|
|
if(FALSE == pCertWizardInfo->fUIAdv)
|
|
{
|
|
if(TRUE == pCertWizardInfo->fUICSP)
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_CSP_SERVICE_PROVIDER);
|
|
else
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_NAME_DESCRIPTION);
|
|
}
|
|
else
|
|
{
|
|
if(FALSE == pCertWizardInfo->fNewKey)
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_CERTIFICATE_AUTHORITY);
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
//CSP
|
|
//-----------------------------------------------------------------------
|
|
INT_PTR APIENTRY Enroll_CSP(HWND hwndDlg, UINT msg, WPARAM /*wParam*/, LPARAM lParam)
|
|
{
|
|
CERT_WIZARD_INFO *pCertWizardInfo=NULL;
|
|
ENROLL_CERT_TYPE_INFO *pCertTypeInfo=NULL;
|
|
PROPSHEETPAGE *pPropSheet=NULL;
|
|
|
|
DWORD dwMinKeySize=0;
|
|
DWORD dwIndex=0;
|
|
int nSelected=0;
|
|
DWORD dwSelected=0;
|
|
HWND hwndControl=NULL;
|
|
|
|
LV_COLUMNW lvC;
|
|
LV_ITEM lvItem;
|
|
|
|
NM_LISTVIEW FAR * pnmv=NULL;
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
//set the wizard information so that it can be shared
|
|
pPropSheet = (PROPSHEETPAGE *) lParam;
|
|
pCertWizardInfo = (CERT_WIZARD_INFO *) (pPropSheet->lParam);
|
|
|
|
//make sure pCertWizardInfo is a valid pointer
|
|
if(NULL==pCertWizardInfo)
|
|
break;
|
|
|
|
// Get the selected cert type info
|
|
pCertTypeInfo = NULL;
|
|
GetSelectedCertTypeInfo(pCertWizardInfo, &pCertTypeInfo);
|
|
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertWizardInfo);
|
|
|
|
SetControlFont(pCertWizardInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
|
|
|
|
//set the check box for the exportable key option
|
|
if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_CHECK_EXPORTKEY)))
|
|
break;
|
|
|
|
// determine whether the exportable checkbox should be set
|
|
// The checkbox is set if:
|
|
// 1) The CT_FLAG_EXPORTABLE_KEY flag is set on the template AND
|
|
// 2) The user has not unchecked this checkbox
|
|
if (pCertWizardInfo->fNewKey && (0 != (CRYPT_EXPORTABLE & pCertWizardInfo->dwGenKeyFlags)))
|
|
SendMessage(hwndControl, BM_SETCHECK, BST_CHECKED, 0);
|
|
else
|
|
SendMessage(hwndControl, BM_SETCHECK, BST_UNCHECKED, 0);
|
|
|
|
if (NULL != pCertTypeInfo)
|
|
EnableWindow(hwndControl, 0 != (CT_FLAG_EXPORTABLE_KEY & pCertTypeInfo->dwPrivateKeyFlags));
|
|
|
|
//set the check box for the user protection option
|
|
if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2)))
|
|
break;
|
|
|
|
// determine whether the strong key protection checkbox should be set
|
|
if (0 != (CRYPT_USER_PROTECTED & pCertWizardInfo->dwGenKeyFlags)) {
|
|
// if this bit is set in the INITDIALOG handler, it's either
|
|
// from the template or the previous key. Enforce the setting
|
|
// by disabling the checkbox
|
|
SendMessage(hwndControl, BM_SETCHECK, BST_CHECKED, 0);
|
|
EnableWindow(hwndControl, FALSE);
|
|
} else {
|
|
SendMessage(hwndControl, BM_SETCHECK, BST_UNCHECKED, 0);
|
|
}
|
|
|
|
//gray out the user protection check box if we are not
|
|
//generating a new key or doing remote
|
|
if((FALSE == pCertWizardInfo->fNewKey) || (FALSE == pCertWizardInfo->fLocal) )
|
|
{
|
|
EnableWindow(hwndControl, FALSE);
|
|
}
|
|
|
|
//populate the CSP list with the following logic:
|
|
if(NULL!=(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
|
|
{
|
|
//insert a column into the list view
|
|
memset(&lvC, 0, sizeof(LV_COLUMNW));
|
|
|
|
lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
|
|
lvC.fmt = LVCFMT_LEFT; // Left-align the column.
|
|
lvC.cx = 20; //(dwMaxSize+2)*7; // Width of the column, in pixels.
|
|
lvC.pszText = L""; // The text for the column.
|
|
lvC.iSubItem=0;
|
|
|
|
if (ListView_InsertColumnU(hwndControl, 0, &lvC) == -1)
|
|
break;
|
|
|
|
InitCSPList(hwndControl, pCertWizardInfo);
|
|
|
|
// Determine which CSP is selected.
|
|
if(-1 != (nSelected= ListView_GetNextItem
|
|
(hwndControl,
|
|
-1,
|
|
LVNI_SELECTED
|
|
)))
|
|
{
|
|
|
|
// Done with CSP list. Populate the key sizes list.
|
|
if (CSPListIndexToCertWizardInfoIndex(hwndControl, nSelected, &dwIndex))
|
|
{
|
|
if (NULL!=(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_COMBO1)))
|
|
{
|
|
// Determine the selected cert type's min key size:
|
|
pCertTypeInfo = NULL;
|
|
if (GetSelectedCertTypeInfo(pCertWizardInfo, &pCertTypeInfo))
|
|
{
|
|
dwMinKeySize = NULL != pCertTypeInfo ? pCertTypeInfo->dwMinKeySize : 0;
|
|
InitKeySizesList(hwndControl,
|
|
dwMinKeySize,
|
|
(pCertWizardInfo->rgwszProvider)[dwIndex],
|
|
(pCertWizardInfo->rgdwProviderType)[dwIndex],
|
|
pCertTypeInfo->dwKeySpec);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
switch (((NMHDR FAR *) lParam)->code)
|
|
{
|
|
//the item has been selected
|
|
case LVN_ITEMCHANGED:
|
|
|
|
//get the window handle of the purpose list view
|
|
if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
|
|
break;
|
|
|
|
if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
pnmv = (LPNMLISTVIEW) lParam;
|
|
|
|
if(NULL==pnmv)
|
|
break;
|
|
|
|
//we try not to let user de-select cert template
|
|
if((pnmv->uOldState & LVIS_SELECTED) && (0 == (pnmv->uNewState & LVIS_SELECTED)))
|
|
{
|
|
//we should have something selected
|
|
if(-1 == ListView_GetNextItem(
|
|
hwndControl,
|
|
-1,
|
|
LVNI_SELECTED
|
|
))
|
|
{
|
|
//we should re-select the original item
|
|
ListView_SetItemState(
|
|
hwndControl,
|
|
pnmv->iItem,
|
|
LVIS_SELECTED,
|
|
LVIS_SELECTED);
|
|
|
|
pCertWizardInfo->iOrgCSP=pnmv->iItem;
|
|
}
|
|
}
|
|
|
|
//if something is selected, we disable all other selection
|
|
if(pnmv->uNewState & LVIS_SELECTED)
|
|
{
|
|
if(pnmv->iItem != pCertWizardInfo->iOrgCSP && -1 != pCertWizardInfo->iOrgCSP)
|
|
{
|
|
//we should de-select the original item
|
|
|
|
ListView_SetItemState(
|
|
hwndControl,
|
|
pCertWizardInfo->iOrgCSP,
|
|
0,
|
|
LVIS_SELECTED);
|
|
|
|
pCertWizardInfo->iOrgCSP=-1;
|
|
}
|
|
}
|
|
|
|
// Determine which CSP is selected.
|
|
if(-1 != (nSelected= ListView_GetNextItem
|
|
(hwndControl,
|
|
-1,
|
|
LVNI_SELECTED
|
|
)))
|
|
{
|
|
|
|
// Done with CSP list. Populate the key sizes list.
|
|
if (CSPListIndexToCertWizardInfoIndex(hwndControl, nSelected, &dwIndex))
|
|
{
|
|
if (NULL!=(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_COMBO1)))
|
|
{
|
|
// Determine the selected cert type's min key size:
|
|
pCertTypeInfo = NULL;
|
|
if (GetSelectedCertTypeInfo(pCertWizardInfo, &pCertTypeInfo))
|
|
{
|
|
dwMinKeySize = NULL != pCertTypeInfo ? pCertTypeInfo->dwMinKeySize : 0;
|
|
InitKeySizesList(hwndControl,
|
|
dwMinKeySize,
|
|
(pCertWizardInfo->rgwszProvider)[dwIndex],
|
|
(pCertWizardInfo->rgdwProviderType)[dwIndex],
|
|
pCertTypeInfo->dwKeySpec);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
case PSN_KILLACTIVE:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
return TRUE;
|
|
|
|
break;
|
|
|
|
case PSN_RESET:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
break;
|
|
|
|
case PSN_SETACTIVE:
|
|
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
|
|
|
|
//reset the CSP list if CA selection has been changed
|
|
if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
if(TRUE==pCertWizardInfo->fCertTypeChanged)
|
|
{
|
|
// Get the selected cert type info
|
|
pCertTypeInfo = NULL;
|
|
GetSelectedCertTypeInfo(pCertWizardInfo, &pCertTypeInfo);
|
|
|
|
//set the check box for the exportable key option
|
|
if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_CHECK_EXPORTKEY)))
|
|
break;
|
|
|
|
// determine whether the exportable checkbox should be set
|
|
// The checkbox is set if:
|
|
// 1) The CT_FLAG_EXPORTABLE_KEY flag is set on the template AND
|
|
// 2) The user has not unchecked this checkbox
|
|
if (pCertWizardInfo->fNewKey && (0 != (CRYPT_EXPORTABLE & pCertWizardInfo->dwGenKeyFlags)))
|
|
SendMessage(hwndControl, BM_SETCHECK, BST_CHECKED, 0);
|
|
else
|
|
SendMessage(hwndControl, BM_SETCHECK, BST_UNCHECKED, 0);
|
|
|
|
if (NULL != pCertTypeInfo)
|
|
EnableWindow(hwndControl, 0 != (CT_FLAG_EXPORTABLE_KEY & pCertTypeInfo->dwPrivateKeyFlags));
|
|
|
|
|
|
//set the check box for the user protection option
|
|
if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2)))
|
|
break;
|
|
|
|
// determine whether the strong key protection checkbox should be set
|
|
if (pCertWizardInfo->fNewKey && (0 != (CRYPT_USER_PROTECTED & pCertWizardInfo->dwGenKeyFlags))) {
|
|
SendMessage(hwndControl, BM_SETCHECK, BST_CHECKED, 0);
|
|
EnableWindow(hwndControl, FALSE);
|
|
} else {
|
|
SendMessage(hwndControl, BM_SETCHECK, BST_UNCHECKED, 0);
|
|
}
|
|
|
|
if (pCertWizardInfo->fLocal) {
|
|
if (NULL != pCertTypeInfo) {
|
|
EnableWindow(hwndControl, 0 == (CT_FLAG_STRONG_KEY_PROTECTION_REQUIRED & pCertTypeInfo->dwPrivateKeyFlags));
|
|
}
|
|
} else {
|
|
EnableWindow(hwndControl, FALSE);
|
|
}
|
|
|
|
InitCSPList(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), pCertWizardInfo);
|
|
|
|
// Determine the selected cert type's min key size:
|
|
dwMinKeySize = NULL != pCertTypeInfo ? pCertTypeInfo->dwMinKeySize : 0;
|
|
}
|
|
|
|
// Determine which CSP is selected.
|
|
if(-1 != (nSelected=ListView_GetNextItem
|
|
(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1),
|
|
-1,
|
|
LVNI_SELECTED
|
|
)))
|
|
{
|
|
|
|
// Done with CSP list. Populate the key sizes list.
|
|
if (CSPListIndexToCertWizardInfoIndex(hwndControl, nSelected, &dwIndex))
|
|
{
|
|
if (NULL!=(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_COMBO1)))
|
|
{
|
|
if (GetSelectedCertTypeInfo(pCertWizardInfo, &pCertTypeInfo))
|
|
{
|
|
dwMinKeySize = NULL != pCertTypeInfo ? pCertTypeInfo->dwMinKeySize : 0;
|
|
InitKeySizesList(hwndControl,
|
|
dwMinKeySize,
|
|
(pCertWizardInfo->rgwszProvider)[dwIndex],
|
|
(pCertWizardInfo->rgdwProviderType)[dwIndex],
|
|
pCertTypeInfo->dwKeySpec);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
// Check whether we have any CSPs available...
|
|
if(-1 == (nSelected=ListView_GetNextItem
|
|
(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1),
|
|
-1,
|
|
LVNI_ALL
|
|
)))
|
|
{
|
|
// No CSPs! We can't enroll for this template.
|
|
I_MessageBox(hwndDlg,
|
|
IDS_NO_CSP_FOR_PURPOSE,
|
|
pCertWizardInfo->idsConfirmTitle,
|
|
pCertWizardInfo->pwszConfirmationTitle,
|
|
MB_ICONEXCLAMATION|MB_OK|MB_APPLMODAL);
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_PURPOSE);
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PSN_WIZBACK:
|
|
break;
|
|
|
|
case PSN_WIZNEXT:
|
|
if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//get the window handle of the export key
|
|
if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_CHECK_EXPORTKEY)))
|
|
break;
|
|
|
|
//mark the pose the cert to the CSP
|
|
if(TRUE==SendMessage(hwndControl, BM_GETCHECK, 0, 0))
|
|
pCertWizardInfo->dwGenKeyFlags |= CRYPT_EXPORTABLE;
|
|
else
|
|
pCertWizardInfo->dwGenKeyFlags &= ~CRYPT_EXPORTABLE;
|
|
|
|
|
|
|
|
//get the window handle of the user protection
|
|
if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2)))
|
|
break;
|
|
|
|
//mark the pose the cert to the CSP
|
|
if(TRUE==SendMessage(hwndControl, BM_GETCHECK, 0, 0))
|
|
pCertWizardInfo->dwGenKeyFlags |= CRYPT_USER_PROTECTED;
|
|
else
|
|
pCertWizardInfo->dwGenKeyFlags &= ~CRYPT_USER_PROTECTED;
|
|
|
|
// Set the key size based on the user's suggestion:
|
|
//
|
|
if (NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_COMBO1)))
|
|
break;
|
|
|
|
if (CB_ERR != (dwSelected = (DWORD)SendMessage(hwndControl, CB_GETCURSEL, 0, 0)))
|
|
{
|
|
pCertWizardInfo->dwMinKeySize = (DWORD)SendMessage(hwndControl, CB_GETITEMDATA, dwSelected, 0);
|
|
}
|
|
else
|
|
{
|
|
pCertWizardInfo->dwMinKeySize = 0;
|
|
}
|
|
|
|
//get the window handle for the CSP list
|
|
if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
|
|
break;
|
|
|
|
//now, mark the ones that are selected
|
|
if(-1 != (dwIndex= ListView_GetNextItem(
|
|
hwndControl,
|
|
-1,
|
|
LVNI_SELECTED
|
|
)))
|
|
{
|
|
|
|
//get the selected certificate
|
|
memset(&lvItem, 0, sizeof(LV_ITEM));
|
|
lvItem.mask=LVIF_PARAM;
|
|
lvItem.iItem=(int)dwIndex;
|
|
|
|
if(ListView_GetItem(hwndControl,
|
|
&lvItem))
|
|
{
|
|
pCertWizardInfo->dwProviderType=pCertWizardInfo->rgdwProviderType[(DWORD)(lvItem.lParam)];
|
|
pCertWizardInfo->pwszProvider=pCertWizardInfo->rgwszProvider[(DWORD)(lvItem.lParam)];
|
|
}
|
|
else
|
|
{
|
|
I_MessageBox(hwndDlg, IDS_NO_SELECTED_CSP,
|
|
pCertWizardInfo->idsConfirmTitle,
|
|
pCertWizardInfo->pwszConfirmationTitle,
|
|
MB_ICONERROR|MB_OK|MB_APPLMODAL);
|
|
|
|
//make the purpose page stay
|
|
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
|
|
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
I_MessageBox(hwndDlg, IDS_NO_SELECTED_CSP,
|
|
pCertWizardInfo->idsConfirmTitle,
|
|
pCertWizardInfo->pwszConfirmationTitle,
|
|
MB_ICONERROR|MB_OK|MB_APPLMODAL);
|
|
|
|
//make the purpose page stay
|
|
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
//skip to the correct page based on the advanced options and CSP requirement
|
|
if(FALSE == pCertWizardInfo->fUIAdv)
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_NAME_DESCRIPTION);
|
|
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
//CA
|
|
//-----------------------------------------------------------------------
|
|
INT_PTR APIENTRY Enroll_CA(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
CERT_WIZARD_INFO *pCertWizardInfo=NULL;
|
|
PROPSHEETPAGE *pPropSheet=NULL;
|
|
DWORD dwChar=0;
|
|
|
|
PCRYPTUI_CA_CONTEXT pCAContext=NULL;
|
|
LPWSTR pwszCADisplayName = NULL;
|
|
|
|
HCURSOR hPreCursor=NULL;
|
|
HCURSOR hWinPreCursor=NULL;
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
//set the wizard information so that it can be shared
|
|
pPropSheet = (PROPSHEETPAGE *) lParam;
|
|
pCertWizardInfo = (CERT_WIZARD_INFO *) (pPropSheet->lParam);
|
|
|
|
SetControlFont(pCertWizardInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
|
|
|
|
//make sure pCertWizardInfo is a valid pointer
|
|
if(NULL==pCertWizardInfo)
|
|
break;
|
|
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertWizardInfo);
|
|
|
|
//init the CA name and CA location
|
|
if(pCertWizardInfo->pwszCALocation)
|
|
SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT2,pCertWizardInfo->pwszCALocation);
|
|
|
|
if(pCertWizardInfo->pwszCAName)
|
|
{
|
|
//overwrite the cursor for this window class
|
|
hWinPreCursor=(HCURSOR)SetClassLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)NULL);
|
|
hPreCursor=SetCursor(LoadCursor(NULL, IDC_WAIT));
|
|
|
|
if(CAUtilGetCADisplayName((pCertWizardInfo->fMachine) ? CA_FIND_LOCAL_SYSTEM:0,
|
|
pCertWizardInfo->pwszCAName,
|
|
&pwszCADisplayName))
|
|
{
|
|
SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,pwszCADisplayName);
|
|
WizardFree(pwszCADisplayName);
|
|
pwszCADisplayName=NULL;
|
|
}
|
|
else
|
|
SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,pCertWizardInfo->pwszCAName);
|
|
|
|
//set the cursor back
|
|
SetCursor(hPreCursor);
|
|
SetWindowLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)hWinPreCursor);
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
if(HIWORD(wParam) == BN_CLICKED)
|
|
{
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDC_WIZARD_BUTTON1:
|
|
|
|
if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//overwrite the cursor for this window class
|
|
hWinPreCursor=(HCURSOR)SetClassLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)NULL);
|
|
hPreCursor=SetCursor(LoadCursor(NULL, IDC_WAIT));
|
|
|
|
//call the CA selection dialogue
|
|
pCAContext=GetCAContext(hwndDlg, pCertWizardInfo);
|
|
|
|
//set the cursor back
|
|
SetCursor(hPreCursor);
|
|
SetWindowLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)hWinPreCursor);
|
|
|
|
if(pCAContext)
|
|
{
|
|
//update the edit box
|
|
if(pCAContext->pwszCAMachineName)
|
|
SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT2,pCAContext->pwszCAMachineName);
|
|
|
|
if(pCAContext->pwszCAName)
|
|
SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,pCAContext->pwszCAName);
|
|
|
|
//free the CA context
|
|
CryptUIDlgFreeCAContext(pCAContext);
|
|
|
|
pCAContext=NULL;
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
switch (((NMHDR FAR *) lParam)->code)
|
|
{
|
|
|
|
case PSN_KILLACTIVE:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
return TRUE;
|
|
|
|
break;
|
|
|
|
case PSN_RESET:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
break;
|
|
|
|
case PSN_SETACTIVE:
|
|
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
|
|
|
|
//reset the CSP list if CA selection has been changed
|
|
if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
if(TRUE==pCertWizardInfo->fCertTypeChanged)
|
|
{
|
|
//reset the CA name and CA location
|
|
if(pCertWizardInfo->pwszCALocation)
|
|
SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT2,pCertWizardInfo->pwszCALocation);
|
|
|
|
if(pCertWizardInfo->pwszCAName)
|
|
{
|
|
|
|
//overwrite the cursor for this window class
|
|
hWinPreCursor=(HCURSOR)SetClassLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)NULL);
|
|
hPreCursor=SetCursor(LoadCursor(NULL, IDC_WAIT));
|
|
|
|
if(CAUtilGetCADisplayName((pCertWizardInfo->fMachine) ? CA_FIND_LOCAL_SYSTEM:0,
|
|
pCertWizardInfo->pwszCAName,
|
|
&pwszCADisplayName))
|
|
{
|
|
SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,pwszCADisplayName);
|
|
WizardFree(pwszCADisplayName);
|
|
pwszCADisplayName=NULL;
|
|
}
|
|
else
|
|
SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,pCertWizardInfo->pwszCAName);
|
|
|
|
//set the cursor back
|
|
SetCursor(hPreCursor);
|
|
SetWindowLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)hWinPreCursor);
|
|
}
|
|
}
|
|
|
|
//reset the certtype change flag to FALSE.
|
|
pCertWizardInfo->fCertTypeChanged = FALSE;
|
|
|
|
break;
|
|
|
|
case PSN_WIZBACK:
|
|
if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//skip to the correct page based on the advanced options and CSP requirement
|
|
if(FALSE == pCertWizardInfo->fNewKey)
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_PURPOSE);
|
|
break;
|
|
|
|
case PSN_WIZNEXT:
|
|
if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//cach the display name of the CA
|
|
if(0!=(dwChar=(DWORD)SendDlgItemMessage(hwndDlg,
|
|
IDC_WIZARD_EDIT1,
|
|
WM_GETTEXTLENGTH, 0, 0)))
|
|
{
|
|
if(pCertWizardInfo->pwszCADisplayName)
|
|
{
|
|
WizardFree(pCertWizardInfo->pwszCADisplayName);
|
|
pCertWizardInfo->pwszCADisplayName = NULL;
|
|
}
|
|
|
|
pCertWizardInfo->pwszCADisplayName=(LPWSTR)WizardAlloc(sizeof(WCHAR)*(dwChar+1));
|
|
|
|
if(NULL!=(pCertWizardInfo->pwszCADisplayName))
|
|
{
|
|
GetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,
|
|
pCertWizardInfo->pwszCADisplayName,
|
|
dwChar+1);
|
|
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
//FriendlyName
|
|
//-----------------------------------------------------------------------
|
|
INT_PTR APIENTRY Enroll_Name(HWND hwndDlg, UINT msg, WPARAM /*wParam*/, LPARAM lParam)
|
|
{
|
|
CERT_WIZARD_INFO *pCertWizardInfo=NULL;
|
|
PROPSHEETPAGE *pPropSheet=NULL;
|
|
DWORD dwChar=0;
|
|
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
//set the wizard information so that it can be shared
|
|
pPropSheet = (PROPSHEETPAGE *) lParam;
|
|
pCertWizardInfo = (CERT_WIZARD_INFO *) (pPropSheet->lParam);
|
|
//make sure pCertWizardInfo is a valid pointer
|
|
if(NULL==pCertWizardInfo)
|
|
break;
|
|
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertWizardInfo);
|
|
|
|
SetControlFont(pCertWizardInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
|
|
|
|
//initialize the friendlyname and description
|
|
if(pCertWizardInfo->pwszFriendlyName)
|
|
SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,pCertWizardInfo->pwszFriendlyName);
|
|
|
|
if(pCertWizardInfo->pwszDescription)
|
|
SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT2,pCertWizardInfo->pwszDescription);
|
|
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
switch (((NMHDR FAR *) lParam)->code)
|
|
{
|
|
|
|
case PSN_KILLACTIVE:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
return TRUE;
|
|
|
|
break;
|
|
|
|
case PSN_RESET:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
break;
|
|
|
|
case PSN_SETACTIVE:
|
|
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
|
|
break;
|
|
|
|
case PSN_WIZBACK:
|
|
if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//skip to the correct page based on the advanced options and CSP requirement
|
|
if(FALSE == pCertWizardInfo->fUIAdv)
|
|
{
|
|
if(TRUE == pCertWizardInfo->fUICSP)
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_CSP_SERVICE_PROVIDER);
|
|
else
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_PURPOSE);
|
|
}
|
|
|
|
break;
|
|
|
|
case PSN_WIZNEXT:
|
|
|
|
if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//free the original messages
|
|
if(pCertWizardInfo->pwszFriendlyName)
|
|
{
|
|
WizardFree(pCertWizardInfo->pwszFriendlyName);
|
|
pCertWizardInfo->pwszFriendlyName=NULL;
|
|
}
|
|
|
|
if(pCertWizardInfo->pwszDescription)
|
|
{
|
|
WizardFree(pCertWizardInfo->pwszDescription);
|
|
pCertWizardInfo->pwszDescription=NULL;
|
|
}
|
|
|
|
//get the friendlyName
|
|
if(0!=(dwChar=(DWORD)SendDlgItemMessage(hwndDlg,
|
|
IDC_WIZARD_EDIT1,
|
|
WM_GETTEXTLENGTH, 0, 0)))
|
|
{
|
|
pCertWizardInfo->pwszFriendlyName=(LPWSTR)WizardAlloc(sizeof(WCHAR)*(dwChar+1));
|
|
|
|
if(NULL!=(pCertWizardInfo->pwszFriendlyName))
|
|
{
|
|
GetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,
|
|
pCertWizardInfo->pwszFriendlyName,
|
|
dwChar+1);
|
|
|
|
}
|
|
}
|
|
|
|
//get the description
|
|
if(0!=(dwChar=(DWORD)SendDlgItemMessage(hwndDlg,
|
|
IDC_WIZARD_EDIT2,
|
|
WM_GETTEXTLENGTH, 0, 0)))
|
|
{
|
|
pCertWizardInfo->pwszDescription=(LPWSTR)WizardAlloc(sizeof(WCHAR)*(dwChar+1));
|
|
|
|
if(NULL!=(pCertWizardInfo->pwszDescription))
|
|
{
|
|
GetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT2,
|
|
pCertWizardInfo->pwszDescription,
|
|
dwChar+1);
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
//Completion
|
|
//-----------------------------------------------------------------------
|
|
INT_PTR APIENTRY Enroll_Completion(HWND hwndDlg, UINT msg, WPARAM /*wParam*/, LPARAM lParam)
|
|
{
|
|
CERT_WIZARD_INFO *pCertWizardInfo=NULL;
|
|
PROPSHEETPAGE *pPropSheet=NULL;
|
|
HWND hwndControl=NULL;
|
|
LV_COLUMNW lvC;
|
|
HCURSOR hPreCursor=NULL;
|
|
HCURSOR hWinPreCursor=NULL;
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
//set the wizard information so that it can be shared
|
|
pPropSheet = (PROPSHEETPAGE *) lParam;
|
|
pCertWizardInfo = (CERT_WIZARD_INFO *) (pPropSheet->lParam);
|
|
//make sure pCertWizardInfo is a valid pointer
|
|
if(NULL==pCertWizardInfo)
|
|
break;
|
|
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertWizardInfo);
|
|
|
|
SetControlFont(pCertWizardInfo->hBigBold, hwndDlg,IDC_WIZARD_STATIC_BIG_BOLD1);
|
|
|
|
//insert two columns
|
|
hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1);
|
|
|
|
memset(&lvC, 0, sizeof(LV_COLUMNW));
|
|
|
|
lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
|
|
lvC.fmt = LVCFMT_LEFT; // Left-align the column.
|
|
lvC.cx = 20; // Width of the column, in pixels.
|
|
lvC.pszText = L""; // The text for the column.
|
|
lvC.iSubItem=0;
|
|
|
|
if (ListView_InsertColumnU(hwndControl, 0, &lvC) == -1)
|
|
break;
|
|
|
|
//2nd column is the content
|
|
memset(&lvC, 0, sizeof(LV_COLUMNW));
|
|
|
|
lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
|
|
lvC.fmt = LVCFMT_LEFT; // Left-align the column.
|
|
lvC.cx = 10; //(dwMaxSize+2)*7; // Width of the column, in pixels.
|
|
lvC.pszText = L""; // The text for the column.
|
|
lvC.iSubItem= 1;
|
|
|
|
if (ListView_InsertColumnU(hwndControl, 1, &lvC) == -1)
|
|
break;
|
|
|
|
|
|
break;
|
|
case WM_COMMAND:
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
switch (((NMHDR FAR *) lParam)->code)
|
|
{
|
|
|
|
case PSN_KILLACTIVE:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
return TRUE;
|
|
|
|
break;
|
|
|
|
case PSN_RESET:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
break;
|
|
|
|
case PSN_SETACTIVE:
|
|
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK|PSWIZB_FINISH);
|
|
|
|
if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//populate the list box in the order of friendly name,
|
|
//overwrite the cursor for this window class
|
|
hWinPreCursor=(HCURSOR)SetClassLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)NULL);
|
|
hPreCursor=SetCursor(LoadCursor(NULL, IDC_WAIT));
|
|
|
|
//UserName, CA, Purpose, and CSP
|
|
//Get the window handle for the CSP list
|
|
if(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1))
|
|
DisplayConfirmation(hwndControl, pCertWizardInfo);
|
|
|
|
//set the cursor back
|
|
SetCursor(hPreCursor);
|
|
SetWindowLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)hWinPreCursor);
|
|
|
|
break;
|
|
|
|
case PSN_WIZBACK:
|
|
break;
|
|
|
|
case PSN_WIZFINISH:
|
|
{
|
|
CertRequester *pCertRequester = NULL;
|
|
CertRequesterContext *pCertRequesterContext = NULL;
|
|
|
|
if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//overwrite the cursor for this window class
|
|
hWinPreCursor=(HCURSOR)SetClassLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)NULL);
|
|
hPreCursor=SetCursor(LoadCursor(NULL, IDC_WAIT));
|
|
|
|
//set the parent window to the hwndDlg so that
|
|
//confirmat to install dlg use hwndDlg as the
|
|
//parent window
|
|
pCertWizardInfo->hwndParent=hwndDlg;
|
|
|
|
if (NULL == (pCertRequester = (CertRequester *) pCertWizardInfo->hRequester))
|
|
break;
|
|
if (NULL == (pCertRequesterContext = pCertRequester->GetContext()))
|
|
break;
|
|
|
|
|
|
//call the enrollment wizard
|
|
pCertWizardInfo->hr = pCertRequesterContext->Enroll(&(pCertWizardInfo->dwStatus), (HANDLE *)&(pCertWizardInfo->pNewCertContext));
|
|
if (0 == pCertWizardInfo->idsText) {
|
|
pCertWizardInfo->idsText = CryptUIStatusToIDSText(pCertWizardInfo->hr, pCertWizardInfo->dwStatus);
|
|
}
|
|
|
|
if(S_OK != pCertWizardInfo->hr)
|
|
break;
|
|
|
|
//set the cursor back
|
|
SetCursor(hPreCursor);
|
|
SetWindowLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)hWinPreCursor);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
|
|
}
|
|
break;
|
|
|
|
default:
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//*******************************************************************************
|
|
// WinProc for the enrollment wizard
|
|
//
|
|
//*******************************************************************************
|
|
|
|
//-----------------------------------------------------------------------
|
|
//Renew_Welcome
|
|
//-----------------------------------------------------------------------
|
|
INT_PTR APIENTRY Renew_Welcome(HWND hwndDlg, UINT msg, WPARAM /*wParam*/, LPARAM lParam)
|
|
{
|
|
CERT_WIZARD_INFO *pCertWizardInfo=NULL;
|
|
PROPSHEETPAGE *pPropSheet=NULL;
|
|
|
|
PCRYPTUI_WIZ_CERT_CA pCertCA=NULL;
|
|
DWORD dwIndex=0;
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
//set the wizard information so that it can be shared
|
|
pPropSheet = (PROPSHEETPAGE *) lParam;
|
|
pCertWizardInfo = (CERT_WIZARD_INFO *) (pPropSheet->lParam);
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertWizardInfo);
|
|
|
|
SetControlFont(pCertWizardInfo->hBigBold, hwndDlg,IDC_WIZARD_STATIC_BIG_BOLD1);
|
|
// SetControlFont(pCertWizardInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
|
|
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
switch (((NMHDR FAR *) lParam)->code)
|
|
{
|
|
|
|
case PSN_KILLACTIVE:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
return TRUE;
|
|
|
|
break;
|
|
|
|
case PSN_RESET:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
break;
|
|
|
|
case PSN_SETACTIVE:
|
|
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
|
|
break;
|
|
|
|
case PSN_WIZBACK:
|
|
break;
|
|
|
|
case PSN_WIZNEXT:
|
|
if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//decide the default CA to use since the CertType will not
|
|
//be changed
|
|
ResetDefaultCA(pCertWizardInfo);
|
|
|
|
//decide if we need to show the CSP page
|
|
pCertCA=&(pCertWizardInfo->pCertCAInfo->rgCA[pCertWizardInfo->dwCAIndex]);
|
|
|
|
for(dwIndex=0; dwIndex<pCertCA->dwCertTypeInfo; dwIndex++)
|
|
{
|
|
if(pCertCA->rgCertTypeInfo[dwIndex].fSelected)
|
|
{
|
|
if(NULL == pCertWizardInfo->pwszProvider)
|
|
{
|
|
if(0 == pCertCA->rgCertTypeInfo[dwIndex].dwCSPCount)
|
|
pCertWizardInfo->fUICSP=TRUE;
|
|
}
|
|
|
|
//copy the selected CertTypeName
|
|
pCertWizardInfo->pwszSelectedCertTypeDN=pCertCA->rgCertTypeInfo[dwIndex].pwszDNName;
|
|
|
|
break;
|
|
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
//-----------------------------------------------------------------------
|
|
//Renew_Options
|
|
//-----------------------------------------------------------------------
|
|
INT_PTR APIENTRY Renew_Options(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
CERT_WIZARD_INFO *pCertWizardInfo=NULL;
|
|
PROPSHEETPAGE *pPropSheet=NULL;
|
|
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
//set the wizard information so that it can be shared
|
|
pPropSheet = (PROPSHEETPAGE *) lParam;
|
|
pCertWizardInfo = (CERT_WIZARD_INFO *) (pPropSheet->lParam);
|
|
|
|
SetControlFont(pCertWizardInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
|
|
|
|
//make sure pCertWizardInfo is a valid pointer
|
|
if(NULL==pCertWizardInfo)
|
|
break;
|
|
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertWizardInfo);
|
|
|
|
//set the initial selection as using the default selections
|
|
SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_SETCHECK, 1, 0);
|
|
SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO2), BM_SETCHECK, 0, 0);
|
|
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
if(HIWORD(wParam) == BN_CLICKED)
|
|
{
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDC_WIZARD_RADIO1:
|
|
SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_SETCHECK, 1, 0);
|
|
SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO2), BM_SETCHECK, 0, 0);
|
|
break;
|
|
|
|
case IDC_WIZARD_RADIO2:
|
|
SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_SETCHECK, 0, 0);
|
|
SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO2), BM_SETCHECK, 1, 0);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
switch (((NMHDR FAR *) lParam)->code)
|
|
{
|
|
|
|
case PSN_KILLACTIVE:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
return TRUE;
|
|
|
|
break;
|
|
|
|
case PSN_RESET:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
break;
|
|
|
|
case PSN_SETACTIVE:
|
|
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
|
|
|
|
if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//if the adv selection is made, it has to stay selected
|
|
if(pCertWizardInfo->fUIAdv)
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), FALSE);
|
|
|
|
break;
|
|
|
|
case PSN_WIZBACK:
|
|
break;
|
|
|
|
case PSN_WIZNEXT:
|
|
if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//check for the advanced options
|
|
if(TRUE==SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_GETCHECK, 0, 0))
|
|
pCertWizardInfo->fUIAdv=FALSE;
|
|
else
|
|
pCertWizardInfo->fUIAdv=TRUE;
|
|
|
|
|
|
//skip to the correct page based on the advanced options and CSP requirement
|
|
if(FALSE == pCertWizardInfo->fUIAdv)
|
|
{
|
|
if(TRUE == pCertWizardInfo->fUICSP)
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_RENEW_SERVICE_PROVIDER);
|
|
else
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_RENEW_COMPLETION);
|
|
}
|
|
else
|
|
{
|
|
if(FALSE == pCertWizardInfo->fNewKey)
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_RENEW_CA);
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
// Renew_CSP
|
|
//-----------------------------------------------------------------------
|
|
INT_PTR APIENTRY Renew_CSP(HWND hwndDlg, UINT msg, WPARAM /*wParam*/, LPARAM lParam)
|
|
{
|
|
CERT_WIZARD_INFO *pCertWizardInfo=NULL;
|
|
PROPSHEETPAGE *pPropSheet=NULL;
|
|
ENROLL_CERT_TYPE_INFO *pCertTypeInfo=NULL;
|
|
|
|
DWORD dwMinKeySize=0;
|
|
DWORD dwIndex=0;
|
|
DWORD dwSelected=0;
|
|
int nSelected=0;
|
|
HWND hwndControl=NULL;
|
|
|
|
LV_COLUMNW lvC;
|
|
LV_ITEM lvItem;
|
|
|
|
NM_LISTVIEW FAR * pnmv=NULL;
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
|
|
|
|
//set the wizard information so that it can be shared
|
|
pPropSheet = (PROPSHEETPAGE *) lParam;
|
|
pCertWizardInfo = (CERT_WIZARD_INFO *) (pPropSheet->lParam);
|
|
|
|
//make sure pCertWizardInfo is a valid pointer
|
|
if(NULL==pCertWizardInfo)
|
|
break;
|
|
|
|
// Get the selected cert type info
|
|
pCertTypeInfo = NULL;
|
|
GetSelectedCertTypeInfo(pCertWizardInfo, &pCertTypeInfo);
|
|
if (NULL != pCertTypeInfo)
|
|
MarkSelectedCertType(pCertWizardInfo, pCertTypeInfo->pwszDNName);
|
|
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertWizardInfo);
|
|
|
|
SetControlFont(pCertWizardInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
|
|
|
|
//set the check box for the exportable key option
|
|
if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_CHECK_EXPORTKEY)))
|
|
break;
|
|
|
|
// determine whether the exportable checkbox should be set
|
|
// The checkbox is set if:
|
|
// 1) The CT_FLAG_EXPORTABLE_KEY flag is set on the template AND
|
|
// 2) The user has not unchecked this checkbox
|
|
if (pCertWizardInfo->fNewKey && (0 != (CRYPT_EXPORTABLE & pCertWizardInfo->dwGenKeyFlags)))
|
|
SendMessage(hwndControl, BM_SETCHECK, BST_CHECKED, 0);
|
|
else
|
|
SendMessage(hwndControl, BM_SETCHECK, BST_UNCHECKED, 0);
|
|
|
|
if (NULL != pCertTypeInfo)
|
|
EnableWindow(hwndControl, 0 != (CT_FLAG_EXPORTABLE_KEY & pCertTypeInfo->dwPrivateKeyFlags));
|
|
|
|
//set the check box for the user protection option
|
|
if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2)))
|
|
break;
|
|
|
|
//set the check box for the user protection option
|
|
if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2)))
|
|
break;
|
|
|
|
// determine whether the strong key protection checkbox should be set
|
|
if (0 != (CRYPT_USER_PROTECTED & pCertWizardInfo->dwGenKeyFlags)) {
|
|
// if this bit is set in the INITDIALOG handler, it's either
|
|
// from the template or the previous key. Enforce the setting
|
|
// by disabling the checkbox
|
|
SendMessage(hwndControl, BM_SETCHECK, BST_CHECKED, 0);
|
|
EnableWindow(hwndControl, FALSE);
|
|
} else {
|
|
SendMessage(hwndControl, BM_SETCHECK, BST_UNCHECKED, 0);
|
|
}
|
|
|
|
//gray out the user protection check box if we are not
|
|
//generating a new key or doing remote
|
|
if((FALSE == pCertWizardInfo->fNewKey) || (FALSE == pCertWizardInfo->fLocal) )
|
|
{
|
|
EnableWindow(hwndControl, FALSE);
|
|
}
|
|
|
|
//populate the CSP list with the following logic:
|
|
|
|
if(NULL!=(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
|
|
{
|
|
//insert a column into the list view
|
|
memset(&lvC, 0, sizeof(LV_COLUMNW));
|
|
|
|
lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
|
|
lvC.fmt = LVCFMT_LEFT; // Left-align the column.
|
|
lvC.cx = 20; //(dwMaxSize+2)*7; // Width of the column, in pixels.
|
|
lvC.pszText = L""; // The text for the column.
|
|
lvC.iSubItem=0;
|
|
|
|
if (ListView_InsertColumnU(hwndControl, 0, &lvC) == -1)
|
|
break;
|
|
|
|
InitCSPList(hwndControl, pCertWizardInfo);
|
|
|
|
if(-1 != (nSelected= ListView_GetNextItem
|
|
(hwndControl,
|
|
-1,
|
|
LVNI_SELECTED
|
|
)))
|
|
{
|
|
|
|
// Done with CSP list. Populate the key sizes list.
|
|
if (CSPListIndexToCertWizardInfoIndex(hwndControl, nSelected, &dwIndex))
|
|
{
|
|
if (NULL!=(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_COMBO1)))
|
|
{
|
|
// Determine the selected cert type's min key size:
|
|
pCertTypeInfo = NULL;
|
|
if (GetSelectedCertTypeInfo(pCertWizardInfo, &pCertTypeInfo))
|
|
{
|
|
dwMinKeySize = NULL != pCertTypeInfo ? pCertTypeInfo->dwMinKeySize : 0;
|
|
InitKeySizesList(hwndControl,
|
|
dwMinKeySize,
|
|
(pCertWizardInfo->rgwszProvider)[dwIndex],
|
|
(pCertWizardInfo->rgdwProviderType)[dwIndex],
|
|
pCertTypeInfo->dwKeySpec);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
switch (((NMHDR FAR *) lParam)->code)
|
|
{
|
|
//the item has been selected
|
|
case LVN_ITEMCHANGED:
|
|
|
|
//get the window handle of the purpose list view
|
|
if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
|
|
break;
|
|
|
|
if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
pnmv = (LPNMLISTVIEW) lParam;
|
|
|
|
if(NULL==pnmv)
|
|
break;
|
|
|
|
//we try not to let user de-select cert template
|
|
if((pnmv->uOldState & LVIS_SELECTED) && (0 == (pnmv->uNewState & LVIS_SELECTED)))
|
|
{
|
|
//we should have something selected
|
|
if(-1 == ListView_GetNextItem(
|
|
hwndControl,
|
|
-1,
|
|
LVNI_SELECTED
|
|
))
|
|
{
|
|
//we should re-select the original item
|
|
ListView_SetItemState(
|
|
hwndControl,
|
|
pnmv->iItem,
|
|
LVIS_SELECTED,
|
|
LVIS_SELECTED);
|
|
|
|
pCertWizardInfo->iOrgCSP=pnmv->iItem;
|
|
}
|
|
}
|
|
|
|
//if something is selected, we disable all other selection
|
|
if(pnmv->uNewState & LVIS_SELECTED)
|
|
{
|
|
if(pnmv->iItem != pCertWizardInfo->iOrgCSP && -1 != pCertWizardInfo->iOrgCSP)
|
|
{
|
|
//we should de-select the original item
|
|
|
|
ListView_SetItemState(
|
|
hwndControl,
|
|
pCertWizardInfo->iOrgCSP,
|
|
0,
|
|
LVIS_SELECTED);
|
|
|
|
pCertWizardInfo->iOrgCSP=-1;
|
|
}
|
|
}
|
|
// Determine which CSP is selected.
|
|
if(-1 != (nSelected= ListView_GetNextItem
|
|
(hwndControl,
|
|
-1,
|
|
LVNI_SELECTED
|
|
)))
|
|
{
|
|
|
|
// Done with CSP list. Populate the key sizes list.
|
|
if (CSPListIndexToCertWizardInfoIndex(hwndControl, nSelected, &dwIndex))
|
|
{
|
|
if (NULL!=(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_COMBO1)))
|
|
{
|
|
pCertTypeInfo = NULL;
|
|
if (GetSelectedCertTypeInfo(pCertWizardInfo, &pCertTypeInfo))
|
|
{
|
|
dwMinKeySize = NULL != pCertTypeInfo ? pCertTypeInfo->dwMinKeySize : 0;
|
|
InitKeySizesList(hwndControl,
|
|
dwMinKeySize,
|
|
(pCertWizardInfo->rgwszProvider)[dwIndex],
|
|
(pCertWizardInfo->rgdwProviderType)[dwIndex],
|
|
pCertTypeInfo->dwKeySpec);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
case PSN_KILLACTIVE:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
return TRUE;
|
|
|
|
break;
|
|
|
|
case PSN_RESET:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
break;
|
|
|
|
case PSN_SETACTIVE:
|
|
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
|
|
|
|
//reset the CSP list if CA selection has been changed
|
|
if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
if(TRUE==pCertWizardInfo->fCertTypeChanged)
|
|
{
|
|
pCertTypeInfo = NULL;
|
|
GetSelectedCertTypeInfo(pCertWizardInfo, &pCertTypeInfo);
|
|
|
|
//set the check box for the exportable key option
|
|
if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_CHECK_EXPORTKEY)))
|
|
break;
|
|
|
|
// determine whether the exportable checkbox should be set
|
|
// The checkbox is set if:
|
|
// 1) The CT_FLAG_EXPORTABLE_KEY flag is set on the template AND
|
|
// 2) The user has not unchecked this checkbox
|
|
if (pCertWizardInfo->fNewKey && (0 != (CRYPT_EXPORTABLE & pCertWizardInfo->dwGenKeyFlags)))
|
|
SendMessage(hwndControl, BM_SETCHECK, BST_CHECKED, 0);
|
|
else
|
|
SendMessage(hwndControl, BM_SETCHECK, BST_UNCHECKED, 0);
|
|
|
|
if (NULL != pCertTypeInfo)
|
|
EnableWindow(hwndControl, 0 != (CT_FLAG_EXPORTABLE_KEY & pCertTypeInfo->dwPrivateKeyFlags));
|
|
|
|
InitCSPList(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), pCertWizardInfo);
|
|
}
|
|
|
|
// Determine which CSP is selected.
|
|
if(-1 != (nSelected=ListView_GetNextItem
|
|
(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1),
|
|
-1,
|
|
LVNI_SELECTED
|
|
)))
|
|
{
|
|
|
|
// Done with CSP list. Populate the key sizes list.
|
|
if (CSPListIndexToCertWizardInfoIndex(hwndControl, nSelected, &dwIndex))
|
|
{
|
|
if (NULL!=(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_COMBO1)))
|
|
{
|
|
pCertTypeInfo = NULL;
|
|
if (GetSelectedCertTypeInfo(pCertWizardInfo, &pCertTypeInfo))
|
|
{
|
|
// Determine the selected cert type's min key size:
|
|
dwMinKeySize = NULL != pCertTypeInfo ? pCertTypeInfo->dwMinKeySize : 0;
|
|
InitKeySizesList(hwndControl,
|
|
dwMinKeySize,
|
|
(pCertWizardInfo->rgwszProvider)[dwIndex],
|
|
(pCertWizardInfo->rgdwProviderType)[dwIndex],
|
|
pCertTypeInfo->dwKeySpec);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
if(-1 == (nSelected=ListView_GetNextItem
|
|
(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1),
|
|
-1,
|
|
LVNI_ALL
|
|
)))
|
|
{
|
|
// No CSPs! We can't enroll for this template.
|
|
I_MessageBox(hwndDlg,
|
|
IDS_NO_CSP_FOR_PURPOSE,
|
|
pCertWizardInfo->idsConfirmTitle,
|
|
pCertWizardInfo->pwszConfirmationTitle,
|
|
MB_ICONEXCLAMATION|MB_OK|MB_APPLMODAL);
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_RENEW_OPTIONS);
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case PSN_WIZBACK:
|
|
break;
|
|
|
|
case PSN_WIZNEXT:
|
|
if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//get the window handle of the exportkey
|
|
if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_CHECK_EXPORTKEY)))
|
|
break;
|
|
|
|
//mark the pose the cert to the CSP
|
|
if(TRUE==SendMessage(hwndControl, BM_GETCHECK, 0, 0))
|
|
pCertWizardInfo->dwGenKeyFlags |= CRYPT_EXPORTABLE;
|
|
else
|
|
pCertWizardInfo->dwGenKeyFlags &= ~CRYPT_EXPORTABLE;
|
|
|
|
|
|
|
|
//get the window handle of the user protection
|
|
if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2)))
|
|
break;
|
|
|
|
//mark the pose the cert to the CSP
|
|
if(TRUE==SendMessage(hwndControl, BM_GETCHECK, 0, 0))
|
|
pCertWizardInfo->dwGenKeyFlags |= CRYPT_USER_PROTECTED;
|
|
else
|
|
pCertWizardInfo->dwGenKeyFlags &= ~CRYPT_USER_PROTECTED;
|
|
|
|
// Set the key size based on the user's suggestion:
|
|
//
|
|
if (NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_COMBO1)))
|
|
break;
|
|
|
|
if (CB_ERR != (dwSelected = (DWORD)SendMessage(hwndControl, CB_GETCURSEL, 0, 0)))
|
|
{
|
|
pCertWizardInfo->dwMinKeySize = (DWORD)SendMessage(hwndControl, CB_GETITEMDATA, dwSelected, 0);
|
|
}
|
|
else
|
|
{
|
|
pCertWizardInfo->dwMinKeySize = 0;
|
|
}
|
|
|
|
|
|
//get the window handle for the CSP list
|
|
if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
|
|
break;
|
|
|
|
//now, mark the ones that are selected
|
|
if(-1 != (dwIndex= ListView_GetNextItem(
|
|
hwndControl,
|
|
-1,
|
|
LVNI_SELECTED
|
|
)))
|
|
{
|
|
|
|
//get the selected certificate
|
|
memset(&lvItem, 0, sizeof(LV_ITEM));
|
|
lvItem.mask=LVIF_PARAM;
|
|
lvItem.iItem=(int)dwIndex;
|
|
|
|
if(ListView_GetItem(hwndControl,
|
|
&lvItem))
|
|
{
|
|
pCertWizardInfo->dwProviderType=pCertWizardInfo->rgdwProviderType[(DWORD)(lvItem.lParam)];
|
|
pCertWizardInfo->pwszProvider=pCertWizardInfo->rgwszProvider[(DWORD)(lvItem.lParam)];
|
|
}
|
|
else
|
|
{
|
|
I_MessageBox(hwndDlg, IDS_NO_SELECTED_CSP,
|
|
pCertWizardInfo->idsConfirmTitle,
|
|
pCertWizardInfo->pwszConfirmationTitle,
|
|
MB_ICONERROR|MB_OK|MB_APPLMODAL);
|
|
|
|
//make the purpose page stay
|
|
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
|
|
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
I_MessageBox(hwndDlg, IDS_NO_SELECTED_CSP,
|
|
pCertWizardInfo->idsConfirmTitle,
|
|
pCertWizardInfo->pwszConfirmationTitle,
|
|
MB_ICONERROR|MB_OK|MB_APPLMODAL);
|
|
|
|
//make the purpose page stay
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
//skip to the correct page based on the advanced options and CSP requirement
|
|
if(FALSE == pCertWizardInfo->fUIAdv)
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_RENEW_COMPLETION);
|
|
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
//Renew_CA
|
|
//-----------------------------------------------------------------------
|
|
INT_PTR APIENTRY Renew_CA(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
CERT_WIZARD_INFO *pCertWizardInfo=NULL;
|
|
PROPSHEETPAGE *pPropSheet=NULL;
|
|
DWORD dwChar=0;
|
|
|
|
PCRYPTUI_CA_CONTEXT pCAContext=NULL;
|
|
LPWSTR pwszCADisplayName=NULL;
|
|
|
|
HCURSOR hPreCursor=NULL;
|
|
HCURSOR hWinPreCursor=NULL;
|
|
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
//set the wizard information so that it can be shared
|
|
pPropSheet = (PROPSHEETPAGE *) lParam;
|
|
pCertWizardInfo = (CERT_WIZARD_INFO *) (pPropSheet->lParam);
|
|
|
|
SetControlFont(pCertWizardInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
|
|
|
|
//make sure pCertWizardInfo is a valid pointer
|
|
if(NULL==pCertWizardInfo)
|
|
break;
|
|
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertWizardInfo);
|
|
|
|
//init the CA name and CA location
|
|
if(pCertWizardInfo->pwszCALocation)
|
|
SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT2,pCertWizardInfo->pwszCALocation);
|
|
|
|
if(pCertWizardInfo->pwszCAName)
|
|
{
|
|
//overwrite the cursor for this window class
|
|
hWinPreCursor=(HCURSOR)SetClassLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)NULL);
|
|
hPreCursor=SetCursor(LoadCursor(NULL, IDC_WAIT));
|
|
|
|
|
|
if(CAUtilGetCADisplayName((pCertWizardInfo->fMachine) ? CA_FIND_LOCAL_SYSTEM:0,
|
|
pCertWizardInfo->pwszCAName,
|
|
&pwszCADisplayName))
|
|
{
|
|
SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,pwszCADisplayName);
|
|
WizardFree(pwszCADisplayName);
|
|
pwszCADisplayName=NULL;
|
|
}
|
|
else
|
|
SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,pCertWizardInfo->pwszCAName);
|
|
|
|
//set the cursor back
|
|
SetCursor(hPreCursor);
|
|
SetWindowLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)hWinPreCursor);
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
if(HIWORD(wParam) == BN_CLICKED)
|
|
{
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDC_WIZARD_BUTTON1:
|
|
|
|
if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//overwrite the cursor for this window class
|
|
hWinPreCursor=(HCURSOR)SetClassLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)NULL);
|
|
hPreCursor=SetCursor(LoadCursor(NULL, IDC_WAIT));
|
|
|
|
//call the CA selection dialogue
|
|
pCAContext=GetCAContext(hwndDlg, pCertWizardInfo);
|
|
|
|
//set the cursor back
|
|
SetCursor(hPreCursor);
|
|
SetWindowLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)hWinPreCursor);
|
|
|
|
if(pCAContext)
|
|
{
|
|
//update the edit box
|
|
if(pCAContext->pwszCAMachineName)
|
|
SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT2,pCAContext->pwszCAMachineName);
|
|
|
|
if(pCAContext->pwszCAName)
|
|
SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,pCAContext->pwszCAName);
|
|
|
|
//free the CA context
|
|
CryptUIDlgFreeCAContext(pCAContext);
|
|
|
|
pCAContext=NULL;
|
|
|
|
}
|
|
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
switch (((NMHDR FAR *) lParam)->code)
|
|
{
|
|
|
|
case PSN_KILLACTIVE:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
return TRUE;
|
|
|
|
break;
|
|
|
|
case PSN_RESET:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
break;
|
|
|
|
case PSN_SETACTIVE:
|
|
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
|
|
break;
|
|
|
|
case PSN_WIZBACK:
|
|
if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//skip to the correct page based on the advanced options and CSP requirement
|
|
if(FALSE == pCertWizardInfo->fNewKey)
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_RENEW_OPTIONS);
|
|
break;
|
|
|
|
case PSN_WIZNEXT:
|
|
|
|
if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//cach the display name of the CA
|
|
if(0!=(dwChar=(DWORD)SendDlgItemMessage(hwndDlg,
|
|
IDC_WIZARD_EDIT1,
|
|
WM_GETTEXTLENGTH, 0, 0)))
|
|
{
|
|
if(pCertWizardInfo->pwszCADisplayName)
|
|
{
|
|
WizardFree(pCertWizardInfo->pwszCADisplayName);
|
|
pCertWizardInfo->pwszCADisplayName = NULL;
|
|
}
|
|
|
|
pCertWizardInfo->pwszCADisplayName=(LPWSTR)WizardAlloc(sizeof(WCHAR)*(dwChar+1));
|
|
|
|
if(NULL!=(pCertWizardInfo->pwszCADisplayName))
|
|
{
|
|
GetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,
|
|
pCertWizardInfo->pwszCADisplayName,
|
|
dwChar+1);
|
|
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
// Renew_Completion
|
|
//-----------------------------------------------------------------------
|
|
INT_PTR APIENTRY Renew_Completion(HWND hwndDlg, UINT msg, WPARAM /*wParam*/, LPARAM lParam)
|
|
{
|
|
CERT_WIZARD_INFO *pCertWizardInfo=NULL;
|
|
PROPSHEETPAGE *pPropSheet=NULL;
|
|
HWND hwndControl=NULL;
|
|
LV_COLUMNW lvC;
|
|
|
|
HCURSOR hPreCursor=NULL;
|
|
HCURSOR hWinPreCursor=NULL;
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
//set the wizard information so that it can be shared
|
|
pPropSheet = (PROPSHEETPAGE *) lParam;
|
|
pCertWizardInfo = (CERT_WIZARD_INFO *) (pPropSheet->lParam);
|
|
//make sure pCertWizardInfo is a valid pointer
|
|
if(NULL==pCertWizardInfo)
|
|
break;
|
|
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertWizardInfo);
|
|
|
|
SetControlFont(pCertWizardInfo->hBigBold, hwndDlg,IDC_WIZARD_STATIC_BIG_BOLD1);
|
|
|
|
//insert two columns
|
|
hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1);
|
|
|
|
memset(&lvC, 0, sizeof(LV_COLUMNW));
|
|
|
|
lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
|
|
lvC.fmt = LVCFMT_LEFT; // Left-align the column.
|
|
lvC.cx = 20; // Width of the column, in pixels.
|
|
lvC.pszText = L""; // The text for the column.
|
|
lvC.iSubItem=0;
|
|
|
|
if (ListView_InsertColumnU(hwndControl, 0, &lvC) == -1)
|
|
break;
|
|
|
|
//2nd column is the content
|
|
memset(&lvC, 0, sizeof(LV_COLUMNW));
|
|
|
|
lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
|
|
lvC.fmt = LVCFMT_LEFT; // Left-align the column.
|
|
lvC.cx = 10; //(dwMaxSize+2)*7; // Width of the column, in pixels.
|
|
lvC.pszText = L""; // The text for the column.
|
|
lvC.iSubItem= 1;
|
|
|
|
if (ListView_InsertColumnU(hwndControl, 1, &lvC) == -1)
|
|
break;
|
|
|
|
break;
|
|
case WM_COMMAND:
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
switch (((NMHDR FAR *) lParam)->code)
|
|
{
|
|
|
|
case PSN_KILLACTIVE:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
return TRUE;
|
|
|
|
break;
|
|
|
|
case PSN_RESET:
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
|
|
break;
|
|
|
|
case PSN_SETACTIVE:
|
|
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK|PSWIZB_FINISH);
|
|
|
|
if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//overwrite the cursor for this window class
|
|
hWinPreCursor=(HCURSOR)SetClassLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)NULL);
|
|
hPreCursor=SetCursor(LoadCursor(NULL, IDC_WAIT));
|
|
|
|
//populate the list box in the order of
|
|
//UserName, CSP, and Publish to the DS
|
|
//Get the window handle for the CSP list
|
|
if(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1))
|
|
DisplayConfirmation(hwndControl, pCertWizardInfo);
|
|
|
|
//set the cursor back
|
|
SetCursor(hPreCursor);
|
|
SetWindowLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)hWinPreCursor);
|
|
|
|
break;
|
|
|
|
case PSN_WIZBACK:
|
|
if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//skip to the correct page based on the advanced options and CSP requirement
|
|
if(FALSE == pCertWizardInfo->fUIAdv)
|
|
{
|
|
if(TRUE == pCertWizardInfo->fUICSP)
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_RENEW_SERVICE_PROVIDER);
|
|
else
|
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_RENEW_OPTIONS);
|
|
}
|
|
|
|
break;
|
|
|
|
case PSN_WIZFINISH:
|
|
{
|
|
CertRequester *pCertRequester = NULL;
|
|
CertRequesterContext *pCertRequesterContext = NULL;
|
|
|
|
if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
|
|
break;
|
|
|
|
//overwrite the cursor for this window class
|
|
hWinPreCursor=(HCURSOR)SetClassLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)NULL);
|
|
|
|
hPreCursor=SetCursor(LoadCursor(NULL, IDC_WAIT));
|
|
|
|
//set the parent window to the hwndDlg so that
|
|
//confirmat to install dlg use hwndDlg as the
|
|
//parent window
|
|
pCertWizardInfo->hwndParent=hwndDlg;
|
|
|
|
if (NULL == (pCertRequester = (CertRequester *) pCertWizardInfo->hRequester))
|
|
break;
|
|
if (NULL == (pCertRequesterContext = pCertRequester->GetContext()))
|
|
break;
|
|
|
|
//call the enrollment wizard
|
|
pCertWizardInfo->hr = pCertRequesterContext->Enroll(&(pCertWizardInfo->dwStatus), (HANDLE *)&(pCertWizardInfo->pNewCertContext));
|
|
if (0 == pCertWizardInfo->idsText) {
|
|
pCertWizardInfo->idsText = CryptUIStatusToIDSText(pCertWizardInfo->hr, pCertWizardInfo->dwStatus);
|
|
}
|
|
|
|
if(S_OK != pCertWizardInfo->hr)
|
|
break;
|
|
|
|
//set the cursor back
|
|
SetCursor(hPreCursor);
|
|
SetWindowLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)hWinPreCursor);
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
|
|
}
|
|
break;
|
|
|
|
default:
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Two-stage no-DS entry point for certificate enrollment and renewal.
|
|
//
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
BOOL
|
|
WINAPI
|
|
CryptUIWizCreateCertRequestNoDS
|
|
(IN DWORD dwFlags,
|
|
IN HWND hwndParent,
|
|
IN PCCRYPTUI_WIZ_CREATE_CERT_REQUEST_INFO pCreateCertRequestInfo,
|
|
OUT HANDLE *phRequest)
|
|
{
|
|
|
|
BOOL fAllocateCSP = FALSE;
|
|
BOOL fResult = FALSE;
|
|
CertRequester *pCertRequester = NULL;
|
|
CertRequesterContext *pCertRequesterContext = NULL;
|
|
CERT_WIZARD_INFO CertWizardInfo;
|
|
CRYPT_KEY_PROV_INFO *pKeyProvInfo = NULL;
|
|
LPWSTR pwszAllocatedCSP = NULL;
|
|
LPWSTR pwszMachineName = NULL;
|
|
UINT idsText = IDS_INVALID_INFO_FOR_PKCS10;
|
|
|
|
// STATIC INITIALIZATION: initialize our object factory.
|
|
#if DBG
|
|
assert(NULL == g_pEnrollFactory);
|
|
#endif
|
|
|
|
// Initialization:
|
|
memset(&CertWizardInfo, 0, sizeof(CertWizardInfo));
|
|
*phRequest = NULL;
|
|
|
|
|
|
g_pEnrollFactory = new EnrollmentCOMObjectFactory;
|
|
if (NULL == g_pEnrollFactory)
|
|
goto MemoryErr;
|
|
|
|
// Input validation:
|
|
if (NULL == pCreateCertRequestInfo || NULL == phRequest)
|
|
goto InvalidArgErr;
|
|
|
|
if (pCreateCertRequestInfo->dwSize != sizeof(CRYPTUI_WIZ_CREATE_CERT_REQUEST_INFO))
|
|
goto InvalidArgErr;
|
|
|
|
if ((pCreateCertRequestInfo->dwPurpose != CRYPTUI_WIZ_CERT_ENROLL) &&
|
|
(pCreateCertRequestInfo->dwPurpose != CRYPTUI_WIZ_CERT_RENEW))
|
|
goto InvalidArgErr;
|
|
|
|
if (0 == (CRYPTUI_WIZ_NO_UI & dwFlags))
|
|
goto InvalidArgErr;
|
|
|
|
|
|
if (pCreateCertRequestInfo->fMachineContext)
|
|
{
|
|
dwFlags |= CRYPTUI_WIZ_NO_INSTALL_ROOT;
|
|
|
|
pwszMachineName = (LPWSTR)WizardAlloc(sizeof(WCHAR) * (MAX_COMPUTERNAME_LENGTH+1));
|
|
if (NULL == pwszMachineName)
|
|
goto MemoryErr;
|
|
|
|
DWORD dwSize = MAX_COMPUTERNAME_LENGTH+1;
|
|
if (!GetComputerNameU(pwszMachineName, &dwSize))
|
|
{
|
|
idsText = IDS_FAIL_TO_GET_COMPUTER_NAME;
|
|
goto GetComputerNameUError;
|
|
}
|
|
}
|
|
|
|
// Copy the dwFlags.
|
|
CertWizardInfo.dwFlags = dwFlags;
|
|
|
|
if (S_OK != (CertRequester::MakeCertRequester
|
|
(NULL,
|
|
pwszMachineName,
|
|
pCreateCertRequestInfo->dwCertOpenStoreFlag,
|
|
pCreateCertRequestInfo->dwPurpose,
|
|
&CertWizardInfo,
|
|
&pCertRequester,
|
|
&idsText)))
|
|
goto InvalidArgErr;
|
|
|
|
pCertRequesterContext = pCertRequester->GetContext();
|
|
|
|
// We can pass in a parent hwnd -- however, this is used only
|
|
// as the parent of CSP ui:
|
|
if (NULL != hwndParent)
|
|
{
|
|
if ((0 == (CRYPTUI_WIZ_NO_UI & dwFlags)) ||
|
|
(0 != (CRYPTUI_WIZ_IGNORE_NO_UI_FLAG_FOR_CSPS & dwFlags)))
|
|
{
|
|
if (!CryptSetProvParam(0 /*all CSPs*/, PP_CLIENT_HWND, (LPBYTE)&hwndParent, sizeof(hwndParent)))
|
|
{
|
|
goto CryptSetProvParamError;
|
|
}
|
|
}
|
|
}
|
|
|
|
// We're not using the wizard UI, so we don't need to change the cursor.
|
|
CertWizardInfo.fCursorChanged = FALSE;
|
|
|
|
// Enroll or renew
|
|
CertWizardInfo.dwPurpose = pCreateCertRequestInfo->dwPurpose;
|
|
|
|
// The CA name and location must be provided:
|
|
CertWizardInfo.fCAInput = TRUE;
|
|
if(NULL == pCreateCertRequestInfo->pwszCALocation || NULL == pCreateCertRequestInfo->pwszCAName)
|
|
goto InvalidArgErr;
|
|
|
|
CertWizardInfo.pwszCALocation = (LPWSTR)pCreateCertRequestInfo->pwszCALocation;
|
|
CertWizardInfo.pwszCAName = (LPWSTR)pCreateCertRequestInfo->pwszCAName;
|
|
|
|
// We always enroll for certs in our current context:
|
|
CertWizardInfo.fLocal = TRUE;
|
|
|
|
if (!CheckPVKInfoNoDS
|
|
(dwFlags,
|
|
pCreateCertRequestInfo->dwPvkChoice,
|
|
pCreateCertRequestInfo->pPvkCert,
|
|
pCreateCertRequestInfo->pPvkNew,
|
|
pCreateCertRequestInfo->pPvkExisting,
|
|
CRYPTUI_WIZ_CERT_REQUEST_CERT_TYPE,
|
|
&CertWizardInfo,
|
|
&pKeyProvInfo))
|
|
goto InvalidArgErr;
|
|
|
|
//make sure the CSP selected is supported by the local machine
|
|
//populate the pwszProvider in CertWizardInfo if it is NULL
|
|
if (S_OK != pCertRequesterContext->GetDefaultCSP(&fAllocateCSP))
|
|
{
|
|
idsText = pCertRequesterContext->GetErrorString();
|
|
goto InvalidArgErr;
|
|
}
|
|
|
|
if (fAllocateCSP)
|
|
pwszAllocatedCSP = CertWizardInfo.pwszProvider;
|
|
|
|
if (S_OK != pCertRequesterContext->BuildCSPList())
|
|
{
|
|
idsText = IDS_FAIL_TO_GET_CSP_LIST;
|
|
goto TraceErr;
|
|
}
|
|
|
|
if (0 != CertWizardInfo.dwProviderType || NULL != CertWizardInfo.pwszProvider)
|
|
{
|
|
if (!CSPSupported(&CertWizardInfo))
|
|
{
|
|
idsText = IDS_CSP_NOT_SUPPORTED;
|
|
goto InvalidArgErr;
|
|
}
|
|
}
|
|
|
|
//set it see if the provider is known
|
|
if(NULL != CertWizardInfo.pwszProvider)
|
|
{
|
|
CertWizardInfo.fKnownCSP = TRUE;
|
|
CertWizardInfo.dwOrgCSPType = CertWizardInfo.dwProviderType;
|
|
CertWizardInfo.pwszOrgCSPName = CertWizardInfo.pwszProvider;
|
|
}
|
|
else
|
|
{
|
|
CertWizardInfo.fKnownCSP=FALSE;
|
|
}
|
|
|
|
//check the dwCertChoice for the enroll case
|
|
if(CRYPTUI_WIZ_CERT_ENROLL & (pCreateCertRequestInfo->dwPurpose))
|
|
{
|
|
// We're enrolling based on cert type.
|
|
// Check that we have a valid cert type:
|
|
|
|
if(!CAUtilValidCertTypeNoDS(pCreateCertRequestInfo->hCertType, // The cert type we'll use to enroll.
|
|
NULL, // The DN Name of the cert type. We don't know it.
|
|
&CertWizardInfo // Our wizard info.
|
|
))
|
|
{
|
|
idsText=IDS_NO_PERMISSION_FOR_CERTTYPE;
|
|
goto CheckCertTypeErr;
|
|
}
|
|
}
|
|
|
|
if (pCreateCertRequestInfo->dwPurpose & CRYPTUI_WIZ_CERT_RENEW)
|
|
{
|
|
DWORD dwSize;
|
|
|
|
CertWizardInfo.pCertContext = pCreateCertRequestInfo->pRenewCertContext;
|
|
|
|
//the certificate has to have the property
|
|
if(!CertGetCertificateContextProperty
|
|
(CertWizardInfo.pCertContext,
|
|
CERT_KEY_PROV_INFO_PROP_ID,
|
|
NULL,
|
|
&dwSize) || (0==dwSize))
|
|
{
|
|
idsText=IDS_NO_PVK_FOR_RENEW_CERT;
|
|
goto InvalidArgErr;
|
|
}
|
|
}
|
|
|
|
//reset the initial ids valud
|
|
idsText=IDS_INVALID_INFO_FOR_PKCS10;
|
|
|
|
fResult = CreateCertRequestNoSearchCANoDS
|
|
(&CertWizardInfo,
|
|
dwFlags,
|
|
pCreateCertRequestInfo->hCertType,
|
|
phRequest);
|
|
|
|
if(FALSE==fResult)
|
|
goto CertRequestErr;
|
|
|
|
// Save the machine name with the request handle:
|
|
((PCREATE_REQUEST_WIZARD_STATE)*phRequest)->pwszMachineName = pwszMachineName;
|
|
((PCREATE_REQUEST_WIZARD_STATE)*phRequest)->dwStoreFlags = CertWizardInfo.dwStoreFlags;
|
|
pwszMachineName = NULL;
|
|
fResult=TRUE;
|
|
|
|
CommonReturn:
|
|
if (NULL != pKeyProvInfo) { WizardFree(pKeyProvInfo); }
|
|
if (fAllocateCSP && NULL != pwszAllocatedCSP) { WizardFree(pwszAllocatedCSP); }
|
|
if (NULL != pwszMachineName) { WizardFree(pwszMachineName); }
|
|
if (NULL != pCertRequester) { delete(pCertRequester); }
|
|
|
|
if (NULL != g_pEnrollFactory)
|
|
{
|
|
delete g_pEnrollFactory;
|
|
g_pEnrollFactory = NULL;
|
|
}
|
|
|
|
FreeProviders(CertWizardInfo.dwCSPCount,
|
|
CertWizardInfo.rgdwProviderType,
|
|
CertWizardInfo.rgwszProvider);
|
|
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
|
|
SET_ERROR(InvalidArgErr, ERROR_INVALID_PARAMETER);
|
|
SET_ERROR(MemoryErr, ERROR_NOT_ENOUGH_MEMORY);
|
|
TRACE_ERROR(CryptSetProvParamError);
|
|
TRACE_ERROR(CertRequestErr);
|
|
TRACE_ERROR(CheckCertTypeErr);
|
|
TRACE_ERROR(GetComputerNameUError);
|
|
TRACE_ERROR(TraceErr);
|
|
}
|
|
|
|
BOOL
|
|
WINAPI
|
|
CryptUIWizSubmitCertRequestNoDS
|
|
(IN HANDLE hRequest,
|
|
IN HWND hwndParent,
|
|
IN LPCWSTR pwszCAName,
|
|
IN LPCWSTR pwszCALocation,
|
|
OUT DWORD *pdwStatus,
|
|
OUT PCCERT_CONTEXT *ppCertContext // Optional
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
|
|
// STATIC INITIALIZATION: initialize our object factory
|
|
#if DBG
|
|
assert(NULL == g_pEnrollFactory);
|
|
#endif
|
|
g_pEnrollFactory = new EnrollmentCOMObjectFactory;
|
|
if (NULL == g_pEnrollFactory)
|
|
goto MemoryErr;
|
|
|
|
// We can pass in a parent hwnd -- however, this is used only
|
|
// as the parent of CSP ui:
|
|
if (NULL != hwndParent)
|
|
{
|
|
if (!CryptSetProvParam(0 /*all CSPs*/, PP_CLIENT_HWND, (LPBYTE)&hwndParent, sizeof(hwndParent)))
|
|
{
|
|
goto CryptSetProvParamError;
|
|
}
|
|
}
|
|
|
|
fResult = SubmitCertRequestNoSearchCANoDS
|
|
(hRequest,
|
|
pwszCAName,
|
|
pwszCALocation,
|
|
pdwStatus,
|
|
ppCertContext);
|
|
|
|
CommonReturn:
|
|
if (NULL != g_pEnrollFactory)
|
|
{
|
|
delete g_pEnrollFactory;
|
|
g_pEnrollFactory = NULL;
|
|
}
|
|
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
|
|
TRACE_ERROR(CryptSetProvParamError);
|
|
SET_ERROR(MemoryErr, ERROR_NOT_ENOUGH_MEMORY);
|
|
}
|
|
|
|
void
|
|
WINAPI
|
|
CryptUIWizFreeCertRequestNoDS
|
|
(IN HANDLE hRequest)
|
|
{
|
|
// STATIC INITIALIZATION: initialize our object factory
|
|
#if DBG
|
|
assert(NULL == g_pEnrollFactory);
|
|
#endif
|
|
g_pEnrollFactory = new EnrollmentCOMObjectFactory;
|
|
if (NULL == g_pEnrollFactory)
|
|
return; // Not much we can do about this ...
|
|
|
|
FreeCertRequestNoSearchCANoDS(hRequest);
|
|
|
|
if (NULL != g_pEnrollFactory)
|
|
{
|
|
delete g_pEnrollFactory;
|
|
g_pEnrollFactory = NULL;
|
|
}
|
|
}
|
|
|
|
BOOL
|
|
WINAPI
|
|
CryptUIWizQueryCertRequestNoDS
|
|
(IN HANDLE hRequest, OUT CRYPTUI_WIZ_QUERY_CERT_REQUEST_INFO *pQueryInfo)
|
|
{
|
|
BOOL fResult;
|
|
CERT_WIZARD_INFO CertWizardInfo;
|
|
CertRequester *pCertRequester;
|
|
HRESULT hr;
|
|
PCREATE_REQUEST_WIZARD_STATE pState;
|
|
UINT idsText;
|
|
|
|
if (NULL == hRequest || NULL == pQueryInfo)
|
|
goto InvalidArgErr;
|
|
|
|
memset(&CertWizardInfo, 0, sizeof(CertWizardInfo));
|
|
// Specify this set of flags to indicate that cryptui doesn't need to prepare
|
|
// access check information. Doing so could cause lots of extraneous logoff/logon events.
|
|
CertWizardInfo.dwFlags = CRYPTUI_WIZ_ALLOW_ALL_TEMPLATES | CRYPTUI_WIZ_ALLOW_ALL_CAS;
|
|
|
|
pState = (PCREATE_REQUEST_WIZARD_STATE)hRequest;
|
|
|
|
if (S_OK != (hr = CertRequester::MakeCertRequester
|
|
(NULL,
|
|
pState->pwszMachineName,
|
|
pState->dwStoreFlags,
|
|
pState->dwPurpose,
|
|
&CertWizardInfo,
|
|
&pCertRequester,
|
|
&idsText
|
|
)))
|
|
goto MakeCertRequesterErr;
|
|
|
|
if (S_OK != (hr = pCertRequester->GetContext()->QueryRequestStatus(pState->hRequest, pQueryInfo)))
|
|
goto QueryRequestStatusErr;
|
|
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
|
|
SET_ERROR(InvalidArgErr, E_INVALIDARG);
|
|
SET_ERROR(MakeCertRequesterErr, hr);
|
|
SET_ERROR(QueryRequestStatusErr, hr);
|
|
}
|
|
|
|
|
|
HRESULT getTemplateName(PCCERT_CONTEXT pCertContext, LPWSTR *ppwszName) {
|
|
CERT_NAME_VALUE *pCertTemplateNameValue = NULL;
|
|
DWORD cbCertTemplateNameValue;
|
|
DWORD cbRequired;
|
|
HRESULT hr = S_OK;
|
|
PCERT_EXTENSION pCertTemplateExtension = NULL;
|
|
|
|
if (NULL == (pCertTemplateExtension = CertFindExtension
|
|
(szOID_ENROLL_CERTTYPE_EXTENSION,
|
|
pCertContext->pCertInfo->cExtension,
|
|
pCertContext->pCertInfo->rgExtension)))
|
|
goto CertFindExtensionError;
|
|
|
|
if (!CryptDecodeObject
|
|
(pCertContext->dwCertEncodingType,
|
|
X509_UNICODE_ANY_STRING,
|
|
pCertTemplateExtension->Value.pbData,
|
|
pCertTemplateExtension->Value.cbData,
|
|
0,
|
|
NULL,
|
|
&cbCertTemplateNameValue) || (cbCertTemplateNameValue == 0))
|
|
goto CryptDecodeObjectError;
|
|
|
|
pCertTemplateNameValue = (CERT_NAME_VALUE *)WizardAlloc(cbCertTemplateNameValue);
|
|
if (NULL == pCertTemplateNameValue)
|
|
goto MemoryErr;
|
|
|
|
if (!CryptDecodeObject
|
|
(pCertContext->dwCertEncodingType,
|
|
X509_UNICODE_ANY_STRING,
|
|
pCertTemplateExtension->Value.pbData,
|
|
pCertTemplateExtension->Value.cbData,
|
|
0,
|
|
(void *)(pCertTemplateNameValue),
|
|
&cbCertTemplateNameValue))
|
|
goto CryptDecodeObjectError;
|
|
|
|
cbRequired = sizeof(WCHAR) * (wcslen((LPWSTR)(pCertTemplateNameValue->Value.pbData)) + 1);
|
|
*ppwszName = (LPWSTR)WizardAlloc(cbRequired);
|
|
if (NULL == *ppwszName)
|
|
goto MemoryErr;
|
|
|
|
// Assign the OUT parameter:
|
|
wcscpy(*ppwszName, (LPWSTR)(pCertTemplateNameValue->Value.pbData));
|
|
hr = S_OK;
|
|
ErrorReturn:
|
|
if (NULL != pCertTemplateNameValue) { WizardFree(pCertTemplateNameValue); }
|
|
return hr;
|
|
|
|
SET_HRESULT(CertFindExtensionError, HRESULT_FROM_WIN32(GetLastError()));
|
|
SET_HRESULT(CryptDecodeObjectError, HRESULT_FROM_WIN32(GetLastError()));
|
|
SET_HRESULT(MemoryErr, E_OUTOFMEMORY);
|
|
}
|
|
|
|
HRESULT decodeTemplateOID(PCERT_EXTENSION pCertExtension, LPSTR *ppszOID, DWORD dwEncodingType) {
|
|
CERT_TEMPLATE_EXT *pCertTemplateExt = NULL;
|
|
DWORD cbCertTemplateExt = 0;
|
|
DWORD cbRequired;
|
|
HRESULT hr;
|
|
|
|
if (FALSE == CryptDecodeObject
|
|
(dwEncodingType,
|
|
X509_CERTIFICATE_TEMPLATE,
|
|
pCertExtension->Value.pbData,
|
|
pCertExtension->Value.cbData,
|
|
0,
|
|
NULL,
|
|
&cbCertTemplateExt) || (cbCertTemplateExt == 0))
|
|
goto CryptDecodeObjectError;
|
|
|
|
pCertTemplateExt = (CERT_TEMPLATE_EXT *)WizardAlloc(cbCertTemplateExt);
|
|
if (NULL == pCertTemplateExt)
|
|
goto MemoryErr;
|
|
|
|
if (FALSE == CryptDecodeObject
|
|
(dwEncodingType,
|
|
X509_CERTIFICATE_TEMPLATE,
|
|
pCertExtension->Value.pbData,
|
|
pCertExtension->Value.cbData,
|
|
0,
|
|
(void *)(pCertTemplateExt),
|
|
&cbCertTemplateExt))
|
|
goto CryptDecodeObjectError;
|
|
|
|
cbRequired = strlen(pCertTemplateExt->pszObjId) + sizeof(CHAR);
|
|
*ppszOID = (LPSTR)WizardAlloc(cbRequired);
|
|
if (NULL == *ppszOID)
|
|
goto MemoryErr;
|
|
|
|
strcpy(*ppszOID, pCertTemplateExt->pszObjId);
|
|
hr = S_OK;
|
|
ErrorReturn:
|
|
if (NULL != pCertTemplateExt) { LocalFree(pCertTemplateExt); }
|
|
return hr;
|
|
|
|
SET_HRESULT(CryptDecodeObjectError, HRESULT_FROM_WIN32(GetLastError()));
|
|
SET_HRESULT(MemoryErr, E_OUTOFMEMORY);
|
|
}
|
|
|
|
HRESULT getTemplateOID(PCCERT_CONTEXT pCertContext, LPSTR *ppszOID) {
|
|
HRESULT hr;
|
|
PCERT_EXTENSION pCertExtension = NULL;
|
|
|
|
if (NULL == (pCertExtension = CertFindExtension
|
|
(szOID_CERTIFICATE_TEMPLATE,
|
|
pCertContext->pCertInfo->cExtension,
|
|
pCertContext->pCertInfo->rgExtension)))
|
|
goto CertFindExtensionError;
|
|
|
|
hr = decodeTemplateOID(pCertExtension, ppszOID, pCertContext->dwCertEncodingType);
|
|
ErrorReturn:
|
|
return hr;
|
|
|
|
SET_HRESULT(CertFindExtensionError, HRESULT_FROM_WIN32(GetLastError()));
|
|
}
|
|
|
|
BOOL ContainsCertTemplateOid(PCERT_EXTENSIONS pCertExtensions, LPWSTR pwszTemplateOid)
|
|
{
|
|
BOOL fResult = FALSE;
|
|
LPSTR pszOid = NULL;
|
|
LPWSTR pwszOid = NULL;
|
|
PCERT_EXTENSION pCertExtension = NULL;
|
|
|
|
if (NULL == (pCertExtension = CertFindExtension(szOID_CERTIFICATE_TEMPLATE, pCertExtensions->cExtension, pCertExtensions->rgExtension)))
|
|
goto CertFindExtensionError;
|
|
|
|
if (S_OK != decodeTemplateOID(pCertExtension, &pszOid, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING))
|
|
goto decodeTemplateOIDError;
|
|
|
|
if (S_OK != WizardSZToWSZ(pszOid, &pwszOid))
|
|
goto MemoryError;
|
|
|
|
fResult = 0 == wcscmp(pwszOid, pwszTemplateOid);
|
|
ErrorReturn:
|
|
if (NULL != pszOid) { WizardFree(pszOid); }
|
|
if (NULL != pwszOid) { WizardFree(pwszOid); }
|
|
|
|
return fResult;
|
|
|
|
TRACE_ERROR(CertFindExtensionError);
|
|
TRACE_ERROR(decodeTemplateOIDError);
|
|
TRACE_ERROR(MemoryError);
|
|
}
|
|
|
|
|
|
//********************************************************************************
|
|
// Enrollment and renew
|
|
//
|
|
// UI or ULless dll entry points
|
|
//
|
|
//
|
|
//********************************************************************************
|
|
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
// CryptUIWizCertRequest
|
|
//
|
|
// Request a certificate via a wizard.
|
|
//
|
|
// dwFlags: IN Required
|
|
// If CRYPTUI_WIZ_NO_UI is set in dwFlags, no UI will be shown.
|
|
//
|
|
// hwndParent: IN Optional
|
|
// The parent window for the UI. Ignored if CRYPTUI_WIZ_NO_UI is set in dwFlags
|
|
//
|
|
// pwszWizardTitle: IN Optional
|
|
// The title of the wizard. Ignored if CRYPTUI_WIZ_NO_UI is set in dwFlags
|
|
//
|
|
// pCertRequestInfo: IN Required
|
|
// A pointer to CRYPTUI_WIZ_CERT_REQUEST_INFO struct
|
|
//
|
|
// ppCertContext: Out Optional
|
|
// The enrolled certificate. The certificate is in a memory store.
|
|
//
|
|
// pdwStatus: Out Optional.
|
|
// The return status of the certificate cerver. The dwStatus can be one of
|
|
/// the following:
|
|
// CRYPTUI_WIZ_CERT_REQUEST_STATUS_SUCCEEDED
|
|
// CRYPTUI_WIZ_CERT_REQUEST_STATUS_REQUEST_ERROR
|
|
// CRYPTUI_WIZ_CERT_REQUEST_STATUS_REQUEST_DENIED
|
|
// CRYPTUI_WIZ_CERT_REQUEST_STATUS_ISSUED_SEPERATELY
|
|
// CRYPTUI_WIZ_CERT_REQUEST_STATUS_UNDER_SUBMISSION
|
|
//------------------------------------------------------------------------
|
|
BOOL
|
|
WINAPI
|
|
CryptUIWizCertRequest(
|
|
IN DWORD dwFlags,
|
|
IN OPTIONAL HWND hwndParent, //IN Optional: The parent window handle
|
|
IN OPTIONAL LPCWSTR pwszWizardTitle, //IN Optional: The title of the wizard
|
|
IN PCCRYPTUI_WIZ_CERT_REQUEST_INFO pRequestInfo,
|
|
OUT OPTIONAL PCCERT_CONTEXT *ppCertContext, //OUT Optional: The enrolled certificate. The certificate is in a
|
|
OUT OPTIONAL DWORD *pdwStatus //OUT Optional: The status of the certificate request
|
|
)
|
|
{
|
|
BOOL fResult=FALSE;
|
|
DWORD dwLastError=ERROR_SUCCESS;
|
|
UINT idsText=IDS_INVALID_INFO_FOR_PKCS10;
|
|
CERT_WIZARD_INFO CertWizardInfo;
|
|
CertRequester *pCertRequester = NULL;
|
|
CertRequesterContext *pCertRequesterContext = NULL;
|
|
BOOL fAllocateCSP=FALSE;
|
|
LPWSTR pwszAllocatedCSP=NULL;
|
|
PCERT_ENHKEY_USAGE pEKUsage=NULL;
|
|
HRESULT hr;
|
|
|
|
UINT uMsgType=MB_OK|MB_ICONINFORMATION;
|
|
|
|
CRYPT_KEY_PROV_INFO *pKeyProvInfo=NULL;
|
|
|
|
|
|
DWORD dwCertChoice=0;
|
|
void *pData=NULL;
|
|
CRYPTUI_WIZ_CERT_TYPE CertType;
|
|
CERT_NAME_VALUE *pCertType=NULL;
|
|
BOOL fResetCertType=FALSE;
|
|
|
|
LPWSTR pwszCTName=NULL;
|
|
CRYPTUI_WIZ_CERT_TYPE CertTypeInfo;
|
|
|
|
CRYPTUI_WIZ_CERT_REQUEST_INFO CertRequestInfoStruct;
|
|
PCCRYPTUI_WIZ_CERT_REQUEST_INFO pCertRequestInfo=NULL;
|
|
|
|
|
|
//memset
|
|
memset(&CertWizardInfo, 0, sizeof(CertWizardInfo));
|
|
memset(&CertTypeInfo, 0, sizeof(CertTypeInfo));
|
|
memset(&CertRequestInfoStruct, 0, sizeof(CRYPTUI_WIZ_CERT_REQUEST_INFO));
|
|
memset(&CertType, 0, sizeof(CertType));
|
|
|
|
// STATIC INITIALIZATION: initialize our object factory
|
|
#if DBG
|
|
assert(NULL == g_pEnrollFactory);
|
|
#endif
|
|
g_pEnrollFactory = new EnrollmentCOMObjectFactory;
|
|
if (NULL == g_pEnrollFactory)
|
|
goto MemoryErr;
|
|
|
|
//we need to make our own copy of the input data because we will have to change
|
|
//the struct for:
|
|
//1. Renew case
|
|
//2. Map the input cert type name to the REAL GUID- defined cert type name
|
|
|
|
pCertRequestInfo=&CertRequestInfoStruct;
|
|
memcpy((void *)pCertRequestInfo, pRequestInfo,sizeof(CRYPTUI_WIZ_CERT_REQUEST_INFO));
|
|
|
|
//init the output parameter
|
|
if(ppCertContext)
|
|
*ppCertContext=NULL;
|
|
|
|
if(pdwStatus)
|
|
*pdwStatus=CRYPTUI_WIZ_CERT_REQUEST_STATUS_UNKNOWN;
|
|
|
|
|
|
//check in the input parameters
|
|
if(NULL==pCertRequestInfo)
|
|
goto InvalidArgErr;
|
|
|
|
//make sure the dwSize is correct
|
|
if(pCertRequestInfo->dwSize != sizeof(CRYPTUI_WIZ_CERT_REQUEST_INFO))
|
|
goto InvalidArgErr;
|
|
|
|
//check the purpose
|
|
if((pCertRequestInfo->dwPurpose != CRYPTUI_WIZ_CERT_ENROLL) &&
|
|
(pCertRequestInfo->dwPurpose != CRYPTUI_WIZ_CERT_RENEW))
|
|
goto InvalidArgErr;
|
|
|
|
//copy the dwFlags
|
|
CertWizardInfo.dwFlags=dwFlags;
|
|
|
|
if (S_OK != (CertRequester::MakeCertRequester
|
|
(pCertRequestInfo->pwszAccountName,
|
|
pCertRequestInfo->pwszMachineName,
|
|
pCertRequestInfo->dwCertOpenStoreFlag,
|
|
pCertRequestInfo->dwPurpose,
|
|
&CertWizardInfo,
|
|
&pCertRequester,
|
|
&idsText)))
|
|
goto InvalidArgErr;
|
|
|
|
pCertRequesterContext = pCertRequester->GetContext();
|
|
|
|
//if UILess is required, set the flags so that the root cert
|
|
//will be put into the CA store
|
|
if(CRYPTUI_WIZ_NO_UI & dwFlags)
|
|
dwFlags |= CRYPTUI_WIZ_NO_INSTALL_ROOT;
|
|
|
|
|
|
//if UI is required, we change the cursor shape to the hour glass
|
|
CertWizardInfo.fCursorChanged=FALSE;
|
|
if(NULL != hwndParent)
|
|
{
|
|
if (0 == (CRYPTUI_WIZ_NO_UI & dwFlags))
|
|
{
|
|
//overwrite the cursor for this window class
|
|
CertWizardInfo.hWinPrevCursor=(HCURSOR)SetClassLongPtr(hwndParent, GCLP_HCURSOR, (LONG_PTR)NULL);
|
|
|
|
CertWizardInfo.hPrevCursor=SetCursor(LoadCursor(NULL, IDC_WAIT));
|
|
|
|
CertWizardInfo.fCursorChanged=TRUE;
|
|
|
|
// BUGBUG: spec says to use sizeof(DWORD) -- is this correct for 64-bit?
|
|
if (!CryptSetProvParam(0 /*all CSPs*/, PP_CLIENT_HWND, (LPBYTE)&hwndParent, sizeof(hwndParent)))
|
|
{
|
|
goto CryptSetProvParamError;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// We've passed a window handle, but have specified no ui.
|
|
// We may want this window handle to be the parent window for
|
|
// CSP UI:
|
|
if (0 != (CRYPTUI_WIZ_IGNORE_NO_UI_FLAG_FOR_CSPS & dwFlags))
|
|
{
|
|
// BUGBUG: spec says to use sizeof(DWORD) -- is this correct for 64-bit?
|
|
if (!CryptSetProvParam(0 /*all CSPs*/, PP_CLIENT_HWND, (LPBYTE)&hwndParent, sizeof(hwndParent)))
|
|
{
|
|
goto CryptSetProvParamError;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//check the CA information
|
|
//pwszCALocation and pwszCAName have to be set at the same time
|
|
CertWizardInfo.fCAInput=FALSE;
|
|
|
|
if(pCertRequestInfo->pwszCALocation)
|
|
{
|
|
if(NULL==(pCertRequestInfo->pwszCAName))
|
|
goto InvalidArgErr;
|
|
|
|
//mark that we known the CA in advance
|
|
CertWizardInfo.fCAInput=TRUE;
|
|
}
|
|
else
|
|
{
|
|
if(pCertRequestInfo->pwszCAName)
|
|
goto InvalidArgErr;
|
|
}
|
|
|
|
CertWizardInfo.dwPurpose=pCertRequestInfo->dwPurpose;
|
|
|
|
//make sure NO root UI will pop up in remote enrollment
|
|
if(FALSE == CertWizardInfo.fLocal)
|
|
dwFlags |= CRYPTUI_WIZ_NO_INSTALL_ROOT;
|
|
|
|
//check for the private key information
|
|
if(!CheckPVKInfo(dwFlags,
|
|
pCertRequestInfo,
|
|
&CertWizardInfo,
|
|
&pKeyProvInfo))
|
|
{
|
|
idsText=IDS_INVALID_PVK_FOR_PKCS10;
|
|
|
|
goto InvalidArgErr;
|
|
|
|
}
|
|
|
|
//for non-enterprise enrollment, we default the CSP to RSA_FULL
|
|
if(CRYPTUI_WIZ_CERT_REQUEST_KEY_USAGE == pCertRequestInfo->dwCertChoice)
|
|
{
|
|
if(0 == CertWizardInfo.dwProviderType)
|
|
CertWizardInfo.dwProviderType=PROV_RSA_FULL;
|
|
}
|
|
|
|
//make sure the CSP selected is supported by the local machine
|
|
//populate the pwszProvider in CertWizardInfo if it is NULL
|
|
if(S_OK != pCertRequesterContext->GetDefaultCSP(&fAllocateCSP))
|
|
{
|
|
idsText = pCertRequesterContext->GetErrorString();
|
|
goto InvalidArgErr;
|
|
}
|
|
|
|
//copy the allocated string
|
|
if(fAllocateCSP)
|
|
pwszAllocatedCSP=CertWizardInfo.pwszProvider;
|
|
|
|
//build the list of local machine's CSP
|
|
if (S_OK != pCertRequesterContext->BuildCSPList())
|
|
{
|
|
idsText = IDS_FAIL_TO_GET_CSP_LIST;
|
|
goto TraceErr;
|
|
}
|
|
|
|
//make sure the selected on is in the list
|
|
if(0 != CertWizardInfo.dwProviderType ||
|
|
NULL != CertWizardInfo.pwszProvider)
|
|
{
|
|
if(!CSPSupported(&CertWizardInfo))
|
|
{
|
|
idsText=IDS_CSP_NOT_SUPPORTED;
|
|
goto InvalidArgErr;
|
|
}
|
|
}
|
|
|
|
|
|
//set it see if the provider is know
|
|
if(CertWizardInfo.pwszProvider)
|
|
{
|
|
CertWizardInfo.fKnownCSP = TRUE;
|
|
CertWizardInfo.dwOrgCSPType = CertWizardInfo.dwProviderType;
|
|
CertWizardInfo.pwszOrgCSPName = CertWizardInfo.pwszProvider;
|
|
}
|
|
else
|
|
CertWizardInfo.fKnownCSP=FALSE;
|
|
|
|
//check for the renew case.
|
|
//1. The certificate has to be valid
|
|
//2. The certificate has to has a valid cert type extension
|
|
|
|
if(CRYPTUI_WIZ_CERT_RENEW == pCertRequestInfo->dwPurpose)
|
|
{
|
|
LPSTR pszTemplateOid = NULL;
|
|
LPWSTR pwszTemplateName = NULL;
|
|
|
|
//for renew, the pRenewCertContext has to be set
|
|
if(NULL==pCertRequestInfo->pRenewCertContext)
|
|
{
|
|
idsText=IDS_NO_CERTIFICATE_FOR_RENEW;
|
|
goto InvalidArgErr;
|
|
}
|
|
|
|
|
|
// First, try the CERTIFICATE_TEMPLATE extension. This will work
|
|
// only for V2 templates:
|
|
if (S_OK == getTemplateOID(pCertRequestInfo->pRenewCertContext, &pszTemplateOid))
|
|
{
|
|
// Convert the template oid to a WCHAR * and store it.
|
|
hr = WizardSZToWSZ(pszTemplateOid, &pwszTemplateName);
|
|
WizardFree(pszTemplateOid);
|
|
if (S_OK != hr)
|
|
goto WizardSZToWSZError;
|
|
|
|
}
|
|
else
|
|
{
|
|
// We probably have a V1 template, try to get the template name:
|
|
if (S_OK != getTemplateName(pCertRequestInfo->pRenewCertContext, &pwszTemplateName))
|
|
{
|
|
// No v1 or v2 extension that tells which certtype we've enrolled for. This is
|
|
// not a valid certificate for renew:
|
|
idsText = IDS_INVALID_CERTIFICATE_TO_RENEW;
|
|
goto TraceErr;
|
|
}
|
|
|
|
// We successfully acquired the cert type name.
|
|
}
|
|
|
|
CertType.dwSize = sizeof(CertType);
|
|
CertType.cCertType = 1;
|
|
CertType.rgwszCertType = &pwszTemplateName;
|
|
|
|
((CRYPTUI_WIZ_CERT_REQUEST_INFO *)pCertRequestInfo)->dwCertChoice=CRYPTUI_WIZ_CERT_REQUEST_CERT_TYPE;
|
|
((CRYPTUI_WIZ_CERT_REQUEST_INFO *)pCertRequestInfo)->pCertType=&CertType;
|
|
|
|
//remember to set the old value back
|
|
fResetCertType = TRUE;
|
|
|
|
//make sure the user has the permission to ask for those
|
|
//request
|
|
if(!CAUtilValidCertType(pCertRequestInfo, &CertWizardInfo))
|
|
{
|
|
idsText=IDS_NO_PERMISSION_FOR_CERTTYPE;
|
|
goto CheckCertTypeErr;
|
|
}
|
|
}
|
|
|
|
//check the dwCertChoice for the enroll case
|
|
if(CRYPTUI_WIZ_CERT_ENROLL & (pCertRequestInfo->dwPurpose))
|
|
{
|
|
switch(pCertRequestInfo->dwCertChoice)
|
|
{
|
|
case CRYPTUI_WIZ_CERT_REQUEST_KEY_USAGE:
|
|
|
|
if(NULL==(pCertRequestInfo->pKeyUsage))
|
|
goto InvalidArgErr;
|
|
|
|
//has to specify some use oid
|
|
if(0==(pCertRequestInfo->pKeyUsage)->cUsageIdentifier)
|
|
goto InvalidArgErr;
|
|
|
|
break;
|
|
|
|
case CRYPTUI_WIZ_CERT_REQUEST_CERT_TYPE:
|
|
|
|
if(NULL==(pCertRequestInfo->pCertType))
|
|
goto InvalidArgErr;
|
|
|
|
if(pCertRequestInfo->pCertType->dwSize != sizeof(CRYPTUI_WIZ_CERT_TYPE))
|
|
goto InvalidArgErr;
|
|
|
|
//we only allow one cert type for now
|
|
if(1 !=pCertRequestInfo->pCertType->cCertType)
|
|
goto InvalidArgErr;
|
|
|
|
|
|
//make sure the user has the permission to ask for those
|
|
//request
|
|
if(!CAUtilValidCertType(pCertRequestInfo, &CertWizardInfo))
|
|
{
|
|
idsText=IDS_NO_PERMISSION_FOR_CERTTYPE;
|
|
goto CheckCertTypeErr;
|
|
}
|
|
|
|
break;
|
|
|
|
//dwCertChoice is optional only for the UI case
|
|
case 0:
|
|
if(dwFlags & CRYPTUI_WIZ_NO_UI)
|
|
goto InvalidArgErr;
|
|
break;
|
|
|
|
default:
|
|
goto InvalidArgErr;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
//for UI mode, we only do certificate type enrollment/renewal
|
|
if(0 == (dwFlags & CRYPTUI_WIZ_NO_UI))
|
|
{
|
|
if(CRYPTUI_WIZ_CERT_REQUEST_KEY_USAGE == (pCertRequestInfo->dwCertChoice))
|
|
{
|
|
idsText=IDS_INVALID_CERTIFICATE_TO_RENEW;
|
|
goto InvalidArgErr;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//for UILess mode, if user enroll for EKUs, they
|
|
//have to specify a CA name
|
|
if(CRYPTUI_WIZ_CERT_REQUEST_KEY_USAGE == (pCertRequestInfo->dwCertChoice))
|
|
{
|
|
//user has to supply the CA information
|
|
if((NULL==pCertRequestInfo->pwszCAName) ||
|
|
(NULL==pCertRequestInfo->pwszCALocation)
|
|
)
|
|
{
|
|
idsText=IDS_HAS_TO_PROVIDE_CA;
|
|
goto InvalidArgErr;
|
|
}
|
|
}
|
|
}
|
|
|
|
//reset the initial ids valud
|
|
idsText=IDS_INVALID_INFO_FOR_PKCS10;
|
|
|
|
fResult=CertRequestSearchCA(
|
|
&CertWizardInfo,
|
|
dwFlags,
|
|
hwndParent,
|
|
pwszWizardTitle,
|
|
pCertRequestInfo,
|
|
ppCertContext,
|
|
pdwStatus,
|
|
&idsText);
|
|
|
|
|
|
if(FALSE==fResult)
|
|
goto CertRequestErr;
|
|
|
|
fResult=TRUE;
|
|
|
|
CommonReturn:
|
|
if(TRUE == fResetCertType)
|
|
{
|
|
((CRYPTUI_WIZ_CERT_REQUEST_INFO *)pCertRequestInfo)->dwCertChoice=dwCertChoice;
|
|
((CRYPTUI_WIZ_CERT_REQUEST_INFO *)pCertRequestInfo)->pCertType=(PCCRYPTUI_WIZ_CERT_TYPE)pData;
|
|
}
|
|
|
|
//free the memory
|
|
if(pwszCTName)
|
|
WizardFree(pwszCTName);
|
|
|
|
if(pCertType)
|
|
WizardFree(pCertType);
|
|
|
|
if(pEKUsage)
|
|
WizardFree(pEKUsage);
|
|
|
|
if(pKeyProvInfo)
|
|
WizardFree(pKeyProvInfo);
|
|
|
|
//free pwszProvider
|
|
if(fAllocateCSP)
|
|
{
|
|
if(pwszAllocatedCSP)
|
|
WizardFree(pwszAllocatedCSP);
|
|
}
|
|
|
|
//free the CSP list: rgdwProviderType and rgwszProvider;
|
|
FreeProviders(CertWizardInfo.dwCSPCount,
|
|
CertWizardInfo.rgdwProviderType,
|
|
CertWizardInfo.rgwszProvider);
|
|
|
|
if (NULL != g_pEnrollFactory)
|
|
{
|
|
delete g_pEnrollFactory;
|
|
g_pEnrollFactory = NULL;
|
|
}
|
|
|
|
//reset the cursor shape
|
|
if(TRUE == CertWizardInfo.fCursorChanged)
|
|
{
|
|
SetCursor(CertWizardInfo.hPrevCursor);
|
|
SetWindowLongPtr(hwndParent, GCLP_HCURSOR, (LONG_PTR)(CertWizardInfo.hWinPrevCursor));
|
|
}
|
|
|
|
|
|
//pop up the confirmation box for failure if UI is required
|
|
if(idsText && (((dwFlags & CRYPTUI_WIZ_NO_UI) == 0)) )
|
|
{
|
|
//set the message of inable to gather enough info for PKCS10
|
|
if(IDS_REQUEST_SUCCEDDED == idsText ||
|
|
IDS_ISSUED_SEPERATE == idsText ||
|
|
IDS_UNDER_SUBMISSION == idsText)
|
|
uMsgType=MB_OK|MB_ICONINFORMATION;
|
|
else
|
|
uMsgType=MB_OK|MB_ICONERROR;
|
|
|
|
|
|
if(idsText != IDS_INSTAL_CANCELLED)
|
|
{
|
|
I_EnrollMessageBox(hwndParent, idsText, CertWizardInfo.hr,
|
|
(CRYPTUI_WIZ_CERT_RENEW == pCertRequestInfo->dwPurpose) ? IDS_RENEW_CONFIRM : IDS_ENROLL_CONFIRM,
|
|
pwszWizardTitle,
|
|
uMsgType);
|
|
}
|
|
|
|
}
|
|
|
|
if (!fResult)
|
|
SetLastError(dwLastError);
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
dwLastError = GetLastError();
|
|
fResult=FALSE;
|
|
goto CommonReturn;
|
|
|
|
SET_ERROR(InvalidArgErr, E_INVALIDARG);
|
|
SET_ERROR(MemoryErr, E_OUTOFMEMORY);
|
|
SET_ERROR(WizardSZToWSZError, hr);
|
|
TRACE_ERROR(CertRequestErr);
|
|
TRACE_ERROR(CheckCertTypeErr);
|
|
TRACE_ERROR(CryptSetProvParamError);
|
|
TRACE_ERROR(TraceErr);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
//The call back function for enum
|
|
//-----------------------------------------------------------------------
|
|
static BOOL WINAPI EnumOidCallback(
|
|
IN PCCRYPT_OID_INFO pInfo,
|
|
IN void *pvArg
|
|
)
|
|
{
|
|
|
|
OID_INFO_CALL_BACK *pCallBackInfo=NULL;
|
|
BOOL fResult=FALSE;
|
|
|
|
pCallBackInfo=(OID_INFO_CALL_BACK *)pvArg;
|
|
if(NULL==pvArg || NULL==pInfo)
|
|
goto InvalidArgErr;
|
|
|
|
//increment the oid list
|
|
(*(pCallBackInfo->pdwOIDCount))++;
|
|
|
|
//get more memory for the pointer list
|
|
*(pCallBackInfo->pprgOIDInfo)=(ENROLL_OID_INFO *)WizardRealloc(*(pCallBackInfo->pprgOIDInfo),
|
|
(*(pCallBackInfo->pdwOIDCount)) * sizeof(ENROLL_OID_INFO));
|
|
|
|
if(NULL==*(pCallBackInfo->pprgOIDInfo))
|
|
goto MemoryErr;
|
|
|
|
//memset
|
|
memset(&((*(pCallBackInfo->pprgOIDInfo))[*(pCallBackInfo->pdwOIDCount)-1]), 0, sizeof(ENROLL_OID_INFO));
|
|
|
|
(*(pCallBackInfo->pprgOIDInfo))[*(pCallBackInfo->pdwOIDCount)-1].pszOID=WizardAllocAndCopyStr((LPSTR)(pInfo->pszOID));
|
|
(*(pCallBackInfo->pprgOIDInfo))[*(pCallBackInfo->pdwOIDCount)-1].pwszName=WizardAllocAndCopyWStr((LPWSTR)(pInfo->pwszName));
|
|
(*(pCallBackInfo->pprgOIDInfo))[*(pCallBackInfo->pdwOIDCount)-1].fSelected=FALSE;
|
|
|
|
if(NULL==(*(pCallBackInfo->pprgOIDInfo))[*(pCallBackInfo->pdwOIDCount)-1].pszOID ||
|
|
NULL==(*(pCallBackInfo->pprgOIDInfo))[*(pCallBackInfo->pdwOIDCount)-1].pwszName)
|
|
goto MemoryErr;
|
|
|
|
fResult=TRUE;
|
|
|
|
CommonReturn:
|
|
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
|
|
fResult=FALSE;
|
|
goto CommonReturn;
|
|
|
|
SET_ERROR(InvalidArgErr, E_INVALIDARG);
|
|
SET_ERROR(MemoryErr, E_OUTOFMEMORY);
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Get the list of supported OIDs and mark the one that caller has requested
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
BOOL InitCertCAOID(PCCRYPTUI_WIZ_CERT_REQUEST_INFO pCertRequestInfo,
|
|
DWORD *pdwOIDInfo,
|
|
ENROLL_OID_INFO **pprgOIDInfo)
|
|
{
|
|
BOOL fResult=FALSE;
|
|
DWORD dwIndex=0;
|
|
OID_INFO_CALL_BACK OidInfoCallBack;
|
|
DWORD dwOIDRequested=0;
|
|
BOOL fFound=FALSE;
|
|
LPWSTR pwszName=NULL;
|
|
|
|
|
|
if(!pCertRequestInfo || !pdwOIDInfo || !pprgOIDInfo)
|
|
goto InvalidArgErr;
|
|
|
|
//init
|
|
*pdwOIDInfo=0;
|
|
*pprgOIDInfo=NULL;
|
|
|
|
OidInfoCallBack.pdwOIDCount=pdwOIDInfo;
|
|
OidInfoCallBack.pprgOIDInfo=pprgOIDInfo;
|
|
|
|
//no need for renew
|
|
/*if(0==(CRYPTUI_WIZ_CERT_ENROLL & (pCertRequestInfo->dwPurpose)))
|
|
{
|
|
fResult=TRUE;
|
|
goto CommonReturn;
|
|
} */
|
|
|
|
//no need for the request for cert types
|
|
if(CRYPTUI_WIZ_CERT_REQUEST_CERT_TYPE == pCertRequestInfo->dwCertChoice)
|
|
{
|
|
fResult=TRUE;
|
|
goto CommonReturn;
|
|
}
|
|
|
|
//enum all the enhanced key usages
|
|
if(!CryptEnumOIDInfo(
|
|
CRYPT_ENHKEY_USAGE_OID_GROUP_ID,
|
|
0,
|
|
&OidInfoCallBack,
|
|
EnumOidCallback))
|
|
goto TraceErr;
|
|
|
|
//mark those requested by the user as selected
|
|
if(CRYPTUI_WIZ_CERT_REQUEST_KEY_USAGE == pCertRequestInfo->dwCertChoice)
|
|
{
|
|
for(dwOIDRequested=0; dwOIDRequested<pCertRequestInfo->pKeyUsage->cUsageIdentifier; dwOIDRequested++)
|
|
{
|
|
fFound=FALSE;
|
|
|
|
for(dwIndex=0; dwIndex<*pdwOIDInfo; dwIndex++)
|
|
{
|
|
if(0==strcmp(pCertRequestInfo->pKeyUsage->rgpszUsageIdentifier[dwOIDRequested],
|
|
(*pprgOIDInfo)[dwIndex].pszOID))
|
|
{
|
|
fFound=TRUE;
|
|
(*pprgOIDInfo)[dwIndex].fSelected=TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//add the requested oid to the list if not in the numerated enhanced key usage
|
|
if(FALSE==fFound)
|
|
{
|
|
(*pdwOIDInfo)++;
|
|
|
|
//get more memory for the pointer list
|
|
*pprgOIDInfo=(ENROLL_OID_INFO *)WizardRealloc(*pprgOIDInfo,
|
|
(*pdwOIDInfo) * sizeof(ENROLL_OID_INFO));
|
|
|
|
if(NULL==(*pprgOIDInfo))
|
|
goto MemoryErr;
|
|
|
|
//memset
|
|
memset(&((*pprgOIDInfo)[*pdwOIDInfo-1]), 0, sizeof(ENROLL_OID_INFO));
|
|
|
|
(*pprgOIDInfo)[(*pdwOIDInfo)-1].pszOID=
|
|
WizardAllocAndCopyStr(pCertRequestInfo->pKeyUsage->rgpszUsageIdentifier[dwOIDRequested]);
|
|
if (NULL == (*pprgOIDInfo)[(*pdwOIDInfo)-1].pszOID)
|
|
goto MemoryErr;
|
|
|
|
pwszName=MkWStr((*pprgOIDInfo)[(*pdwOIDInfo)-1].pszOID);
|
|
|
|
if(NULL==pwszName)
|
|
goto MemoryErr;
|
|
|
|
(*pprgOIDInfo)[(*pdwOIDInfo)-1].pwszName=WizardAllocAndCopyWStr(pwszName);
|
|
(*pprgOIDInfo)[(*pdwOIDInfo)-1].fSelected=TRUE;
|
|
|
|
if(NULL==(*pprgOIDInfo)[(*pdwOIDInfo)-1].pszOID ||
|
|
NULL==(*pprgOIDInfo)[(*pdwOIDInfo)-1].pwszName)
|
|
goto MemoryErr;
|
|
|
|
}
|
|
|
|
if(pwszName)
|
|
{
|
|
FreeWStr(pwszName);
|
|
pwszName=NULL;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
fResult=TRUE;
|
|
|
|
CommonReturn:
|
|
|
|
//free the memory
|
|
if(pwszName)
|
|
FreeWStr(pwszName);
|
|
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
|
|
if(pCertRequestInfo && pdwOIDInfo && pprgOIDInfo)
|
|
{
|
|
FreeCertCAOID(*pdwOIDInfo,
|
|
*pprgOIDInfo);
|
|
|
|
*pdwOIDInfo=0;
|
|
*pprgOIDInfo=NULL;
|
|
}
|
|
|
|
fResult=FALSE;
|
|
goto CommonReturn;
|
|
|
|
SET_ERROR(InvalidArgErr, E_INVALIDARG);
|
|
TRACE_ERROR(TraceErr);
|
|
SET_ERROR(MemoryErr, E_OUTOFMEMORY);
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Free the array of enroll OID info
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
BOOL FreeCertCAOID(DWORD dwOIDInfo,
|
|
ENROLL_OID_INFO *pOIDInfo)
|
|
{
|
|
DWORD dwIndex=0;
|
|
|
|
if(pOIDInfo)
|
|
{
|
|
for(dwIndex=0; dwIndex < dwOIDInfo; dwIndex++)
|
|
{
|
|
if(pOIDInfo[dwIndex].pszOID)
|
|
WizardFree(pOIDInfo[dwIndex].pszOID);
|
|
|
|
if(pOIDInfo[dwIndex].pwszName)
|
|
WizardFree(pOIDInfo[dwIndex].pwszName);
|
|
}
|
|
|
|
WizardFree(pOIDInfo);
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Init a CERT_CA struct
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
BOOL InitCertCA(CERT_WIZARD_INFO *pCertWizardInfo,
|
|
PCRYPTUI_WIZ_CERT_CA pCertCA,
|
|
LPWSTR pwszCALocation,
|
|
LPWSTR pwszCAName,
|
|
BOOL fCASelected,
|
|
PCCRYPTUI_WIZ_CERT_REQUEST_INFO pCertRequestInfo,
|
|
DWORD dwOIDInfo,
|
|
ENROLL_OID_INFO *pOIDInfo,
|
|
BOOL fSearchForCertType)
|
|
{
|
|
BOOL fResult=FALSE;
|
|
LPWSTR *ppwszDisplayCertType=NULL;
|
|
LPWSTR *ppwszCertType=NULL;
|
|
DWORD *pdwKeySpec=NULL;
|
|
DWORD *pdwMinKeySize=NULL;
|
|
DWORD *pdwCSPCount=NULL;
|
|
DWORD **ppdwCSPList=NULL;
|
|
DWORD *pdwRASignature=NULL;
|
|
DWORD *pdwEnrollmentFlags;
|
|
DWORD *pdwSubjectNameFlags;
|
|
DWORD *pdwPrivateKeyFlags;
|
|
DWORD *pdwGeneralFlags;
|
|
DWORD dwCertType=0;
|
|
PCERT_EXTENSIONS *ppCertExtensions=NULL;
|
|
DWORD dwIndex=0;
|
|
DWORD dwCertTypeRequested=0;
|
|
BOOL fFound=FALSE;
|
|
LPWSTR pwszCertTypeName=NULL;
|
|
DWORD dwFoundCertType=0;
|
|
|
|
if (!pCertCA || !pCertRequestInfo)
|
|
goto InvalidArgErr;
|
|
|
|
//memset
|
|
memset(pCertCA, 0, sizeof(CRYPTUI_WIZ_CERT_CA));
|
|
|
|
pCertCA->dwSize=sizeof(CRYPTUI_WIZ_CERT_CA);
|
|
pCertCA->pwszCALocation=pwszCALocation;
|
|
pCertCA->pwszCAName=pwszCAName;
|
|
pCertCA->fSelected=fCASelected;
|
|
|
|
//set up the OID information if requested
|
|
switch (pCertRequestInfo->dwCertChoice)
|
|
{
|
|
case CRYPTUI_WIZ_CERT_REQUEST_KEY_USAGE:
|
|
|
|
if(dwOIDInfo==0 || NULL==pOIDInfo)
|
|
goto InvalidArgErr;
|
|
|
|
pCertCA->dwOIDInfo=dwOIDInfo;
|
|
pCertCA->rgOIDInfo=pOIDInfo;
|
|
|
|
break;
|
|
|
|
case CRYPTUI_WIZ_CERT_REQUEST_CERT_TYPE:
|
|
//if we are required to search the CertType. get all the certTypes
|
|
//from the CA. Otherwize, just use the CertType provided
|
|
if(fSearchForCertType && pwszCALocation && pwszCAName)
|
|
{
|
|
|
|
//get the list of cert type names and extensions supported by the CA
|
|
if(!CAUtilGetCertTypeNameAndExtensions(
|
|
pCertWizardInfo,
|
|
pCertRequestInfo,
|
|
pwszCALocation,
|
|
pwszCAName,
|
|
&dwCertType,
|
|
&ppwszCertType,
|
|
&ppwszDisplayCertType,
|
|
&ppCertExtensions,
|
|
&pdwKeySpec,
|
|
&pdwMinKeySize,
|
|
&pdwCSPCount,
|
|
&ppdwCSPList,
|
|
&pdwRASignature,
|
|
&pdwEnrollmentFlags,
|
|
&pdwSubjectNameFlags,
|
|
&pdwPrivateKeyFlags,
|
|
&pdwGeneralFlags))
|
|
goto TraceErr;
|
|
|
|
//add the certType name and extenisions to the struct
|
|
for(dwIndex=0; dwIndex < dwCertType; dwIndex++)
|
|
{
|
|
fFound=FALSE;
|
|
|
|
|
|
//search for the certTypes that requested by the user
|
|
//we are guaranteed that the certificat type user requested
|
|
//is supported by the CA
|
|
for(dwCertTypeRequested=0; dwCertTypeRequested < pCertRequestInfo->pCertType->cCertType;
|
|
dwCertTypeRequested++)
|
|
{
|
|
|
|
fFound = 0 == wcscmp(ppwszCertType[dwIndex], pCertRequestInfo->pCertType->rgwszCertType[dwCertTypeRequested]);
|
|
fFound |= ContainsCertTemplateOid(ppCertExtensions[dwIndex], pCertRequestInfo->pCertType->rgwszCertType[dwCertTypeRequested]);
|
|
|
|
if (fFound)
|
|
{
|
|
dwFoundCertType++;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
if(!AddCertTypeToCertCA(&(pCertCA->dwCertTypeInfo),
|
|
&(pCertCA->rgCertTypeInfo),
|
|
ppwszCertType[dwIndex],
|
|
ppwszDisplayCertType[dwIndex],
|
|
ppCertExtensions[dwIndex],
|
|
fFound,
|
|
pdwKeySpec[dwIndex],
|
|
pdwMinKeySize[dwIndex],
|
|
pdwCSPCount[dwIndex],
|
|
ppdwCSPList[dwIndex],
|
|
pdwRASignature[dwIndex],
|
|
pdwEnrollmentFlags[dwIndex],
|
|
pdwSubjectNameFlags[dwIndex],
|
|
pdwPrivateKeyFlags[dwIndex],
|
|
pdwGeneralFlags[dwIndex]
|
|
))
|
|
goto TraceErr;
|
|
}
|
|
|
|
//make sure all the requested cert types are supported
|
|
//Only do so if the CA information is input through
|
|
//the API
|
|
// if(dwFoundCertType < pCertRequestInfo->pCertType->cCertType)
|
|
// goto InvalidArgErr;
|
|
}
|
|
else
|
|
{
|
|
for(dwCertTypeRequested=0; dwCertTypeRequested < pCertRequestInfo->pCertType->cCertType;
|
|
dwCertTypeRequested++)
|
|
{
|
|
|
|
//get the cert type name
|
|
pwszCertTypeName=WizardAllocAndCopyWStr(pCertRequestInfo->pCertType->rgwszCertType[dwCertTypeRequested]);
|
|
|
|
if(!pwszCertTypeName)
|
|
goto MemoryErr;
|
|
|
|
if(!AddCertTypeToCertCA(&(pCertCA->dwCertTypeInfo),
|
|
&(pCertCA->rgCertTypeInfo),
|
|
NULL,
|
|
pwszCertTypeName,
|
|
NULL,
|
|
TRUE,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0
|
|
)) //select it
|
|
goto TraceErr;
|
|
|
|
//no need to free pwszCertTyptName. It is included
|
|
//in pCertCA->rgCertTypeInfo
|
|
}
|
|
}
|
|
break;
|
|
|
|
//dwCertChoice is optional
|
|
case 0:
|
|
//if we are required to search the CertType. get all the certTypes
|
|
//from the CA. Otherwize, use the OID
|
|
if(fSearchForCertType && pwszCALocation && pwszCAName)
|
|
{
|
|
//get the list of cert type names and extensions supported by the CA
|
|
if(!CAUtilGetCertTypeNameAndExtensions(
|
|
pCertWizardInfo,
|
|
pCertRequestInfo,
|
|
pwszCALocation,
|
|
pwszCAName,
|
|
&dwCertType,
|
|
&ppwszCertType,
|
|
&ppwszDisplayCertType,
|
|
&ppCertExtensions,
|
|
&pdwKeySpec,
|
|
&pdwMinKeySize,
|
|
&pdwCSPCount,
|
|
&ppdwCSPList,
|
|
&pdwRASignature,
|
|
&pdwEnrollmentFlags,
|
|
&pdwSubjectNameFlags,
|
|
&pdwPrivateKeyFlags,
|
|
&pdwGeneralFlags))
|
|
goto TraceErr;
|
|
|
|
//add the certType name and extenisions to the struct
|
|
for(dwIndex=0; dwIndex < dwCertType; dwIndex++)
|
|
{
|
|
if(!AddCertTypeToCertCA(&(pCertCA->dwCertTypeInfo),
|
|
&(pCertCA->rgCertTypeInfo),
|
|
ppwszCertType[dwIndex],
|
|
ppwszDisplayCertType[dwIndex],
|
|
ppCertExtensions[dwIndex],
|
|
FALSE,
|
|
pdwKeySpec[dwIndex],
|
|
pdwMinKeySize[dwIndex],
|
|
pdwCSPCount[dwIndex],
|
|
ppdwCSPList[dwIndex],
|
|
pdwRASignature[dwIndex],
|
|
pdwEnrollmentFlags[dwIndex],
|
|
pdwSubjectNameFlags[dwIndex],
|
|
pdwPrivateKeyFlags[dwIndex],
|
|
pdwGeneralFlags[dwIndex]
|
|
))
|
|
goto TraceErr;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(dwOIDInfo==0 || NULL==pOIDInfo)
|
|
goto InvalidArgErr;
|
|
|
|
pCertCA->dwOIDInfo=dwOIDInfo;
|
|
pCertCA->rgOIDInfo=pOIDInfo;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
goto InvalidArgErr;
|
|
|
|
}
|
|
|
|
fResult=TRUE;
|
|
|
|
CommonReturn:
|
|
|
|
//free the memory
|
|
if(ppwszCertType)
|
|
WizardFree(ppwszCertType);
|
|
|
|
if(ppwszDisplayCertType)
|
|
WizardFree(ppwszDisplayCertType);
|
|
|
|
if(ppCertExtensions)
|
|
WizardFree(ppCertExtensions);
|
|
|
|
if(pdwKeySpec)
|
|
WizardFree(pdwKeySpec);
|
|
|
|
if(pdwMinKeySize)
|
|
WizardFree(pdwMinKeySize);
|
|
|
|
if(pdwCSPCount)
|
|
WizardFree(pdwCSPCount);
|
|
|
|
if(ppdwCSPList)
|
|
WizardFree(ppdwCSPList);
|
|
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
|
|
//free the individual elements
|
|
if(ppdwCSPList)
|
|
{
|
|
for(dwIndex=0; dwIndex < dwCertType; dwIndex++)
|
|
{
|
|
if(ppdwCSPList[dwIndex])
|
|
WizardFree(ppdwCSPList[dwIndex]);
|
|
}
|
|
}
|
|
|
|
if(ppwszCertType)
|
|
{
|
|
for(dwIndex=0; dwIndex <dwCertType; dwIndex++)
|
|
{
|
|
if(ppwszCertType[dwIndex])
|
|
WizardFree(ppwszCertType[dwIndex]);
|
|
}
|
|
}
|
|
|
|
if(ppwszDisplayCertType)
|
|
{
|
|
for(dwIndex=0; dwIndex <dwCertType; dwIndex++)
|
|
{
|
|
if(ppwszDisplayCertType[dwIndex])
|
|
WizardFree(ppwszDisplayCertType[dwIndex]);
|
|
}
|
|
}
|
|
|
|
if(ppCertExtensions)
|
|
{
|
|
for(dwIndex=0; dwIndex <dwCertType; dwIndex++)
|
|
{
|
|
if(ppCertExtensions[dwIndex])
|
|
CAFreeCertTypeExtensions(NULL, ppCertExtensions[dwIndex]);
|
|
}
|
|
}
|
|
|
|
if(pCertCA)
|
|
{
|
|
if(pCertCA->rgCertTypeInfo)
|
|
WizardFree(pCertCA->rgCertTypeInfo);
|
|
|
|
memset(pCertCA, 0, sizeof(CRYPTUI_WIZ_CERT_CA));
|
|
}
|
|
|
|
if(pwszCertTypeName)
|
|
WizardFree(pwszCertTypeName);
|
|
|
|
fResult=FALSE;
|
|
goto CommonReturn;
|
|
|
|
SET_ERROR(InvalidArgErr, E_INVALIDARG);
|
|
TRACE_ERROR(TraceErr);
|
|
SET_ERROR(MemoryErr, E_OUTOFMEMORY);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Free an array of ENROLL_CERT_TYPE_INFO struct
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
BOOL FreeCertCACertType(DWORD dwCertTypeInfo,
|
|
ENROLL_CERT_TYPE_INFO *rgCertTypeInfo)
|
|
{
|
|
DWORD dwIndex=0;
|
|
|
|
if(rgCertTypeInfo)
|
|
{
|
|
for(dwIndex=0; dwIndex <dwCertTypeInfo; dwIndex++)
|
|
{
|
|
if(rgCertTypeInfo[dwIndex].pwszDNName)
|
|
WizardFree(rgCertTypeInfo[dwIndex].pwszDNName);
|
|
|
|
if(rgCertTypeInfo[dwIndex].pwszCertTypeName)
|
|
WizardFree(rgCertTypeInfo[dwIndex].pwszCertTypeName);
|
|
|
|
if(rgCertTypeInfo[dwIndex].pCertTypeExtensions)
|
|
CAFreeCertTypeExtensions(NULL, rgCertTypeInfo[dwIndex].pCertTypeExtensions);
|
|
|
|
if(rgCertTypeInfo[dwIndex].rgdwCSP)
|
|
WizardFree(rgCertTypeInfo[dwIndex].rgdwCSP);
|
|
}
|
|
|
|
WizardFree(rgCertTypeInfo);
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// Add a certType to the ENROLL_CERT_TYPE_INFO struct
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
BOOL AddCertTypeToCertCA(DWORD *pdwCertTypeInfo,
|
|
ENROLL_CERT_TYPE_INFO **ppCertTypeInfo,
|
|
LPWSTR pwszDNName,
|
|
LPWSTR pwszCertType,
|
|
PCERT_EXTENSIONS pCertExtensions,
|
|
BOOL fSelected,
|
|
DWORD dwKeySpec,
|
|
DWORD dwMinKeySize,
|
|
DWORD dwCSPCount,
|
|
DWORD *pdwCSPList,
|
|
DWORD dwRASignature,
|
|
DWORD dwEnrollmentFlags,
|
|
DWORD dwSubjectNameFlags,
|
|
DWORD dwPrivateKeyFlags,
|
|
DWORD dwGeneralFlags
|
|
)
|
|
{
|
|
BOOL fResult=FALSE;
|
|
|
|
if(!pdwCertTypeInfo || !ppCertTypeInfo)
|
|
goto InvalidArgErr;
|
|
|
|
*ppCertTypeInfo=(ENROLL_CERT_TYPE_INFO *)WizardRealloc(*ppCertTypeInfo,
|
|
(*pdwCertTypeInfo+1) * sizeof(ENROLL_CERT_TYPE_INFO));
|
|
|
|
if(NULL==*ppCertTypeInfo)
|
|
goto MemoryErr;
|
|
|
|
(*pdwCertTypeInfo)++;
|
|
|
|
|
|
((*ppCertTypeInfo)[*pdwCertTypeInfo-1]).fSelected=fSelected;
|
|
((*ppCertTypeInfo)[*pdwCertTypeInfo-1]).pwszDNName=pwszDNName;
|
|
((*ppCertTypeInfo)[*pdwCertTypeInfo-1]).pwszCertTypeName=pwszCertType;
|
|
((*ppCertTypeInfo)[*pdwCertTypeInfo-1]).pCertTypeExtensions=pCertExtensions;
|
|
((*ppCertTypeInfo)[*pdwCertTypeInfo-1]).dwKeySpec=dwKeySpec;
|
|
((*ppCertTypeInfo)[*pdwCertTypeInfo-1]).dwMinKeySize=dwMinKeySize;
|
|
((*ppCertTypeInfo)[*pdwCertTypeInfo-1]).dwCSPCount=dwCSPCount;
|
|
((*ppCertTypeInfo)[*pdwCertTypeInfo-1]).rgdwCSP=pdwCSPList;
|
|
((*ppCertTypeInfo)[*pdwCertTypeInfo-1]).dwRASignature=dwRASignature;
|
|
((*ppCertTypeInfo)[*pdwCertTypeInfo-1]).dwEnrollmentFlags=dwEnrollmentFlags;
|
|
((*ppCertTypeInfo)[*pdwCertTypeInfo-1]).dwSubjectNameFlags=dwSubjectNameFlags;
|
|
((*ppCertTypeInfo)[*pdwCertTypeInfo-1]).dwPrivateKeyFlags=dwPrivateKeyFlags;
|
|
((*ppCertTypeInfo)[*pdwCertTypeInfo-1]).dwGeneralFlags=dwGeneralFlags;
|
|
|
|
fResult=TRUE;
|
|
|
|
CommonReturn:
|
|
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
|
|
|
|
fResult=FALSE;
|
|
goto CommonReturn;
|
|
|
|
SET_ERROR(InvalidArgErr, E_INVALIDARG);
|
|
SET_ERROR(MemoryErr, E_OUTOFMEMORY);
|
|
}
|
|
|
|
BOOL
|
|
WINAPI
|
|
CreateCertRequestNoSearchCANoDS
|
|
(
|
|
IN CERT_WIZARD_INFO *pCertWizardInfo,
|
|
IN DWORD /*dwFlags*/,
|
|
IN HCERTTYPE hCertType,
|
|
OUT HANDLE *pResult
|
|
)
|
|
{
|
|
BOOL fResult = FALSE;
|
|
CRYPTUI_WIZ_CERT_CA_INFO CertCAInfo;
|
|
CRYPTUI_WIZ_CERT_CA rgCertCA[2];
|
|
HRESULT hr;
|
|
|
|
// Declare cert type properties / flags / extensions:
|
|
LPWSTR pwszCertType;
|
|
LPWSTR pwszDisplayCertType;
|
|
PCERT_EXTENSIONS pCertExtensions;
|
|
DWORD dwKeySpec;
|
|
DWORD dwMinKeySize;
|
|
DWORD dwCSPCount;
|
|
DWORD *pdwCSPList;
|
|
DWORD dwRASignature;
|
|
DWORD dwEnrollmentFlags;
|
|
DWORD dwSubjectNameFlags;
|
|
DWORD dwPrivateKeyFlags;
|
|
DWORD dwGeneralFlags;
|
|
CertRequester *pCertRequester = NULL;
|
|
CertRequesterContext *pCertRequesterContext = NULL;
|
|
|
|
// Invalid validation
|
|
if (NULL == pCertWizardInfo || NULL == pCertWizardInfo->hRequester || NULL == hCertType || NULL == pResult)
|
|
return FALSE;
|
|
|
|
// Init:
|
|
*pResult = NULL;
|
|
|
|
//memset
|
|
memset(&CertCAInfo, 0, sizeof(CertCAInfo));
|
|
memset(rgCertCA, 0, sizeof(rgCertCA));
|
|
|
|
//set up the CA info
|
|
CertCAInfo.dwSize = sizeof(CertCAInfo);
|
|
CertCAInfo.dwCA = 2; // 1 dummy CA + 1 real CA
|
|
CertCAInfo.rgCA = rgCertCA;
|
|
|
|
CertCAInfo.rgCA[1].dwSize = sizeof(CertCAInfo.rgCA[1]);
|
|
CertCAInfo.rgCA[1].pwszCAName = pCertWizardInfo->pwszCAName;
|
|
CertCAInfo.rgCA[1].pwszCALocation = pCertWizardInfo->pwszCALocation;
|
|
CertCAInfo.rgCA[1].fSelected = TRUE;
|
|
pCertWizardInfo->dwCAIndex = 1; // We're using the first CA.
|
|
|
|
// NOTE: No need to set up the OID info: we're requesting based on cert type.
|
|
|
|
//get the list of cert type names and extensions supported by the CA
|
|
if(!CAUtilGetCertTypeNameAndExtensionsNoDS
|
|
(pCertWizardInfo,
|
|
NULL,
|
|
hCertType,
|
|
&pwszCertType,
|
|
&pwszDisplayCertType,
|
|
&pCertExtensions,
|
|
&dwKeySpec,
|
|
&dwMinKeySize,
|
|
&dwCSPCount,
|
|
&pdwCSPList,
|
|
&dwRASignature,
|
|
&dwEnrollmentFlags,
|
|
&dwSubjectNameFlags,
|
|
&dwPrivateKeyFlags,
|
|
&dwGeneralFlags))
|
|
{
|
|
if (GetLastError() == ERROR_SUCCESS)
|
|
{
|
|
// No code error occured, we just can't use this cert template.
|
|
// Since this code path relies on being able to use this particular
|
|
// cert template, bubble this up as an invalid arg err.
|
|
goto InvalidArgErr;
|
|
}
|
|
else
|
|
{
|
|
// An error occured.
|
|
goto CAUtilGetCertTypeNameAndExtensionsNoDSErr;
|
|
}
|
|
}
|
|
|
|
|
|
if(!AddCertTypeToCertCA(&(CertCAInfo.rgCA[1].dwCertTypeInfo),
|
|
&(CertCAInfo.rgCA[1].rgCertTypeInfo),
|
|
pwszCertType,
|
|
pwszDisplayCertType,
|
|
pCertExtensions,
|
|
TRUE,
|
|
dwKeySpec,
|
|
dwMinKeySize,
|
|
dwCSPCount,
|
|
pdwCSPList,
|
|
dwRASignature,
|
|
dwEnrollmentFlags,
|
|
dwSubjectNameFlags,
|
|
dwPrivateKeyFlags,
|
|
dwGeneralFlags))
|
|
goto AddCertTypeToCertCAErr;
|
|
|
|
|
|
// We're only _creating_ a request, not submitting it.
|
|
pCertWizardInfo->dwFlags |= CRYPTUI_WIZ_CREATE_ONLY;
|
|
pCertWizardInfo->pCertCAInfo = &CertCAInfo;
|
|
|
|
if (NULL == (pCertRequester = (CertRequester *)pCertWizardInfo->hRequester))
|
|
goto UnexpectedErr;
|
|
if (NULL == (pCertRequesterContext = pCertRequester->GetContext()))
|
|
goto UnexpectedErr;
|
|
|
|
if (S_OK != (hr = pCertRequesterContext->Enroll(NULL, pResult)))
|
|
goto EnrollErr;
|
|
|
|
// Bundle state we need to carry across the create/submit boundary:
|
|
{
|
|
PCREATE_REQUEST_WIZARD_STATE pState = (PCREATE_REQUEST_WIZARD_STATE)WizardAlloc(sizeof(CREATE_REQUEST_WIZARD_STATE));
|
|
if (NULL == pState)
|
|
goto MemoryErr;
|
|
|
|
pState->hRequest = *pResult;
|
|
pState->dwPurpose = pCertWizardInfo->dwPurpose;
|
|
|
|
*pResult = (HANDLE)pState;
|
|
}
|
|
|
|
fResult=TRUE;
|
|
|
|
CommonReturn:
|
|
FreeCertCACertType(CertCAInfo.rgCA[0].dwCertTypeInfo, CertCAInfo.rgCA[0].rgCertTypeInfo);
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult=FALSE;
|
|
goto CommonReturn;
|
|
|
|
TRACE_ERROR(AddCertTypeToCertCAErr);
|
|
TRACE_ERROR(CAUtilGetCertTypeNameAndExtensionsNoDSErr);
|
|
SET_ERROR(EnrollErr, hr);
|
|
SET_ERROR(InvalidArgErr, E_INVALIDARG);
|
|
SET_ERROR(MemoryErr, E_OUTOFMEMORY);
|
|
SET_ERROR(UnexpectedErr, E_UNEXPECTED);
|
|
}
|
|
|
|
BOOL
|
|
WINAPI
|
|
SubmitCertRequestNoSearchCANoDS
|
|
(IN HANDLE hRequest,
|
|
IN LPCWSTR pwszCAName,
|
|
IN LPCWSTR pwszCALocation,
|
|
OUT DWORD *pdwStatus,
|
|
OUT OPTIONAL PCCERT_CONTEXT *ppCertContext
|
|
)
|
|
{
|
|
BOOL fResult = FALSE;
|
|
CertRequester *pCertRequester = NULL;
|
|
CertRequesterContext *pCertRequesterContext = NULL;
|
|
CERT_WIZARD_INFO CertWizardInfo;
|
|
DWORD dwPurpose;
|
|
HANDLE hCertRequest = NULL;
|
|
HRESULT hr;
|
|
PCREATE_REQUEST_WIZARD_STATE pState = NULL;
|
|
UINT idsText; // Not used
|
|
|
|
// Invalid validation
|
|
if (NULL == hRequest || NULL == pwszCAName || NULL == pwszCALocation || NULL == pdwStatus)
|
|
return FALSE;
|
|
|
|
memset(&CertWizardInfo, 0, sizeof(CertWizardInfo));
|
|
// Specify this set of flags to indicate that cryptui doesn't need to prepare
|
|
// access check information. Doing so could cause lots of extraneous logoff/logon events.
|
|
CertWizardInfo.dwFlags = CRYPTUI_WIZ_ALLOW_ALL_TEMPLATES | CRYPTUI_WIZ_ALLOW_ALL_CAS;
|
|
|
|
pState = (PCREATE_REQUEST_WIZARD_STATE)hRequest;
|
|
hCertRequest = pState->hRequest;
|
|
dwPurpose = pState->dwPurpose;
|
|
|
|
if (S_OK != (CertRequester::MakeCertRequester
|
|
(NULL,
|
|
pState->pwszMachineName,
|
|
pState->dwStoreFlags,
|
|
dwPurpose,
|
|
&CertWizardInfo,
|
|
&pCertRequester,
|
|
&idsText
|
|
)))
|
|
goto InvalidArgErr;
|
|
|
|
pCertRequesterContext = pCertRequester->GetContext();
|
|
|
|
// Set up the wizard information necessary for a submit operation:
|
|
CertWizardInfo.dwFlags &= ~(CRYPTUI_WIZ_CREATE_ONLY | CRYPTUI_WIZ_FREE_ONLY);
|
|
CertWizardInfo.dwFlags |= CRYPTUI_WIZ_SUBMIT_ONLY;
|
|
CertWizardInfo.dwPurpose = dwPurpose;
|
|
CertWizardInfo.pwszCAName = (LPWSTR)pwszCAName;
|
|
CertWizardInfo.pwszCALocation = (LPWSTR)pwszCALocation;
|
|
CertWizardInfo.fCAInput = TRUE;
|
|
|
|
if (S_OK != (hr = pCertRequesterContext->Enroll(pdwStatus, &hCertRequest)))
|
|
goto EnrollErr;
|
|
|
|
if (NULL != ppCertContext)
|
|
*ppCertContext = (PCCERT_CONTEXT)hCertRequest;
|
|
|
|
// Success
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
if (NULL != pCertRequester) { delete pCertRequester; }
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
|
|
SET_ERROR(EnrollErr, hr);
|
|
SET_ERROR(InvalidArgErr, ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
void
|
|
WINAPI
|
|
FreeCertRequestNoSearchCANoDS
|
|
(IN HANDLE hRequest)
|
|
{
|
|
CERT_WIZARD_INFO CertWizardInfo;
|
|
CertRequester *pCertRequester = NULL;
|
|
CertRequesterContext *pCertRequesterContext = NULL;
|
|
DWORD dwPurpose;
|
|
HANDLE hCertRequest;
|
|
HRESULT hr;
|
|
PCREATE_REQUEST_WIZARD_STATE pState;
|
|
UINT idsText;
|
|
|
|
if (NULL == hRequest)
|
|
return;
|
|
|
|
memset(&CertWizardInfo, 0, sizeof(CertWizardInfo));
|
|
// Specify this set of flags to indicate that cryptui doesn't need to prepare
|
|
// access check information. Doing so could cause lots of extraneous logoff/logon events.
|
|
CertWizardInfo.dwFlags = CRYPTUI_WIZ_ALLOW_ALL_TEMPLATES | CRYPTUI_WIZ_ALLOW_ALL_CAS;
|
|
|
|
pState = (PCREATE_REQUEST_WIZARD_STATE)hRequest;
|
|
hCertRequest = pState->hRequest;
|
|
dwPurpose = pState->dwPurpose;
|
|
|
|
if (S_OK != (CertRequester::MakeCertRequester
|
|
(NULL,
|
|
pState->pwszMachineName,
|
|
pState->dwStoreFlags,
|
|
dwPurpose,
|
|
&CertWizardInfo,
|
|
&pCertRequester,
|
|
&idsText
|
|
)))
|
|
goto InvalidArgErr;
|
|
|
|
pCertRequesterContext = pCertRequester->GetContext();
|
|
CertWizardInfo.dwFlags &= ~(CRYPTUI_WIZ_CREATE_ONLY | CRYPTUI_WIZ_SUBMIT_ONLY);
|
|
CertWizardInfo.dwFlags |= CRYPTUI_WIZ_FREE_ONLY;
|
|
CertWizardInfo.dwPurpose = dwPurpose;
|
|
|
|
if (S_OK != (hr = pCertRequesterContext->Enroll(NULL, &hCertRequest)))
|
|
goto EnrollErr;
|
|
|
|
if (NULL != pState->pwszMachineName) { WizardFree(pState->pwszMachineName); }
|
|
WizardFree(pState);
|
|
|
|
ErrorReturn:
|
|
return;
|
|
|
|
TRACE_ERROR(EnrollErr);
|
|
TRACE_ERROR(InvalidArgErr);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// This is the layer of CertRequest wizard builds up the CA information
|
|
// without searching for it on the network.
|
|
//
|
|
// It pass the information throught to the CryptUIWizCertRequestWithCAInfo API
|
|
//----------------------------------------------------------------------------
|
|
BOOL
|
|
WINAPI
|
|
CertRequestNoSearchCA(
|
|
BOOL fSearchCertType,
|
|
CERT_WIZARD_INFO *pCertWizardInfo,
|
|
DWORD dwFlags,
|
|
HWND hwndParent,
|
|
LPCWSTR pwszWizardTitle,
|
|
PCCRYPTUI_WIZ_CERT_REQUEST_INFO pCertRequestInfo,
|
|
PCCERT_CONTEXT *ppCertContext,
|
|
DWORD *pCAdwStatus,
|
|
UINT *pIds
|
|
)
|
|
{
|
|
BOOL fResult=FALSE;
|
|
DWORD dwError=0;
|
|
DWORD dwIndex=0;
|
|
|
|
DWORD dwOIDInfo=0;
|
|
ENROLL_OID_INFO *pOIDInfo=NULL;
|
|
|
|
CRYPTUI_WIZ_CERT_CA_INFO CertCAInfo;
|
|
CRYPTUI_WIZ_CERT_CA rgCertCA[2];
|
|
|
|
//memset
|
|
memset(&CertCAInfo, 0, sizeof(CRYPTUI_WIZ_CERT_CA_INFO));
|
|
memset(rgCertCA, 0, 2*sizeof(CRYPTUI_WIZ_CERT_CA));
|
|
|
|
//set up the CA info
|
|
CertCAInfo.dwSize=sizeof(CertCAInfo);
|
|
CertCAInfo.dwCA=2;
|
|
CertCAInfo.rgCA=rgCertCA;
|
|
|
|
|
|
//user has to supply the CA information
|
|
if((NULL==pCertRequestInfo->pwszCAName) ||
|
|
(NULL==pCertRequestInfo->pwszCALocation)
|
|
)
|
|
{
|
|
*pIds=IDS_HAS_TO_PROVIDE_CA;
|
|
goto InvalidArgErr;
|
|
}
|
|
|
|
|
|
//set up the OID info
|
|
if(!InitCertCAOID(pCertRequestInfo,
|
|
&dwOIDInfo,
|
|
&pOIDInfo))
|
|
goto TraceErr;
|
|
|
|
|
|
//set up the CA array
|
|
//the 1st one is the default one without CA information
|
|
if(!InitCertCA(pCertWizardInfo, &rgCertCA[0], NULL, NULL, FALSE, pCertRequestInfo,
|
|
dwOIDInfo, pOIDInfo, fSearchCertType))
|
|
{
|
|
*pIds=IDS_ENROLL_NO_CERT_TYPE;
|
|
goto TraceErr;
|
|
}
|
|
|
|
//the second one indicate the information for the real CA
|
|
CertCAInfo.dwCA=2;
|
|
|
|
if(!InitCertCA(pCertWizardInfo, &rgCertCA[1], (LPWSTR)(pCertRequestInfo->pwszCALocation),
|
|
(LPWSTR)(pCertRequestInfo->pwszCAName), TRUE, pCertRequestInfo,
|
|
dwOIDInfo, pOIDInfo, fSearchCertType))
|
|
{
|
|
*pIds=IDS_ENROLL_NO_CERT_TYPE;
|
|
goto TraceErr;
|
|
}
|
|
|
|
|
|
fResult=CryptUIWizCertRequestWithCAInfo(
|
|
pCertWizardInfo,
|
|
dwFlags,
|
|
hwndParent,
|
|
pwszWizardTitle,
|
|
pCertRequestInfo,
|
|
&CertCAInfo,
|
|
ppCertContext,
|
|
pCAdwStatus,
|
|
pIds);
|
|
|
|
if(FALSE==fResult)
|
|
goto TraceErr;
|
|
|
|
|
|
fResult=TRUE;
|
|
|
|
CommonReturn:
|
|
//preserve the last error
|
|
dwError=GetLastError();
|
|
|
|
//free memory
|
|
for(dwIndex=0; dwIndex< CertCAInfo.dwCA; dwIndex++)
|
|
FreeCertCACertType(CertCAInfo.rgCA[dwIndex].dwCertTypeInfo,
|
|
CertCAInfo.rgCA[dwIndex].rgCertTypeInfo);
|
|
|
|
FreeCertCAOID(dwOIDInfo, pOIDInfo);
|
|
|
|
//reset the error
|
|
SetLastError(dwError);
|
|
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
|
|
fResult=FALSE;
|
|
goto CommonReturn;
|
|
|
|
SET_ERROR(InvalidArgErr, E_INVALIDARG);
|
|
TRACE_ERROR(TraceErr);
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// This is the layer of CertRequest wizard builds up the CA information
|
|
// by searching for it on the network.
|
|
//
|
|
// It pass the information throught to the CryptUIWizCertRequestWithCAInfo API
|
|
//----------------------------------------------------------------------------
|
|
BOOL
|
|
WINAPI
|
|
CertRequestSearchCA(
|
|
CERT_WIZARD_INFO *pCertWizardInfo,
|
|
DWORD dwFlags,
|
|
HWND hwndParent,
|
|
LPCWSTR pwszWizardTitle,
|
|
PCCRYPTUI_WIZ_CERT_REQUEST_INFO pCertRequestInfo,
|
|
PCCERT_CONTEXT *ppCertContext,
|
|
DWORD *pCAdwStatus,
|
|
UINT *pIds
|
|
)
|
|
{
|
|
BOOL fResult=FALSE;
|
|
DWORD dwError=0;
|
|
DWORD dwIndex=0;
|
|
DWORD dwCACount=0;
|
|
BOOL fFound=FALSE;
|
|
|
|
LPWSTR *ppwszCAName=0;
|
|
LPWSTR *ppwszCALocation=0;
|
|
|
|
CRYPTUI_WIZ_CERT_CA_INFO CertCAInfo;
|
|
CRYPTUI_WIZ_CERT_CA *rgCertCA=NULL;
|
|
|
|
DWORD dwOIDInfo=0;
|
|
ENROLL_OID_INFO *pOIDInfo=NULL;
|
|
|
|
CRYPTUI_WIZ_CERT_REQUEST_INFO CertRequestInfo;
|
|
DWORD dwValidCA=0;
|
|
|
|
//memset
|
|
memset(&CertCAInfo, 0, sizeof(CRYPTUI_WIZ_CERT_CA_INFO));
|
|
memset(&CertRequestInfo, 0, sizeof(CRYPTUI_WIZ_CERT_REQUEST_INFO));
|
|
|
|
//set up the CA info
|
|
CertCAInfo.dwSize=sizeof(CertCAInfo);
|
|
|
|
//see if CA information is provided
|
|
if(pCertRequestInfo->pwszCALocation &&
|
|
pCertRequestInfo->pwszCAName)
|
|
{
|
|
//no need to do anything if UILess
|
|
if(dwFlags & CRYPTUI_WIZ_NO_UI)
|
|
{
|
|
if(!CertRequestNoSearchCA( TRUE, //search for certype
|
|
pCertWizardInfo,
|
|
dwFlags,
|
|
hwndParent,
|
|
pwszWizardTitle,
|
|
pCertRequestInfo,
|
|
ppCertContext,
|
|
pCAdwStatus,
|
|
pIds))
|
|
goto TraceErr;
|
|
}
|
|
else
|
|
{
|
|
//UI version of the enrollment with known CA informatin
|
|
//get a CA which can issue the required certificate type
|
|
//or the OIDs. The ca has to support some certificate type
|
|
//unless user specifically asked for OID
|
|
if(!CAUtilRetrieveCAFromCertType(
|
|
pCertWizardInfo,
|
|
pCertRequestInfo,
|
|
TRUE, //need multiple CAs
|
|
0, //ask for the CN
|
|
&dwCACount,
|
|
&ppwszCALocation,
|
|
&ppwszCAName) )
|
|
{
|
|
*pIds=IDS_NO_CA_FOR_ENROLL;
|
|
goto TraceErr;
|
|
}
|
|
|
|
//set up the OID info
|
|
if(!InitCertCAOID(pCertRequestInfo,
|
|
&dwOIDInfo,
|
|
&pOIDInfo))
|
|
goto TraceErr;
|
|
|
|
//allocation the memory
|
|
rgCertCA=(CRYPTUI_WIZ_CERT_CA *)WizardAlloc((dwCACount + 2) *
|
|
sizeof(CRYPTUI_WIZ_CERT_CA));
|
|
|
|
if(NULL==rgCertCA)
|
|
goto OutOfMemoryErr;
|
|
|
|
//memset
|
|
memset(rgCertCA, 0, (dwCACount + 2) * sizeof(CRYPTUI_WIZ_CERT_CA));
|
|
|
|
//the 1st one is the default one without CA information
|
|
if(!InitCertCA(pCertWizardInfo, &rgCertCA[0], NULL, NULL, FALSE, pCertRequestInfo,
|
|
dwOIDInfo, pOIDInfo, TRUE) )
|
|
{
|
|
*pIds=IDS_ENROLL_NO_CERT_TYPE;
|
|
goto TraceErr;
|
|
}
|
|
|
|
dwValidCA=0;
|
|
|
|
//the rest is the CA information
|
|
for(dwIndex=0; dwIndex<dwCACount; dwIndex++)
|
|
{
|
|
|
|
if(0==_wcsicmp(ppwszCALocation[dwIndex], pCertRequestInfo->pwszCALocation) &&
|
|
0==_wcsicmp(ppwszCAName[dwIndex], pCertRequestInfo->pwszCAName)
|
|
)
|
|
{
|
|
fFound=TRUE;
|
|
|
|
//mark CA as selected
|
|
if(!InitCertCA(pCertWizardInfo, &rgCertCA[dwValidCA+1], ppwszCALocation[dwIndex],
|
|
ppwszCAName[dwIndex], TRUE,
|
|
pCertRequestInfo, dwOIDInfo, pOIDInfo, TRUE))
|
|
//we contine to the next CA
|
|
continue;
|
|
|
|
dwValidCA++;
|
|
}
|
|
else
|
|
{
|
|
if(!InitCertCA(pCertWizardInfo, &rgCertCA[dwValidCA+1], ppwszCALocation[dwIndex],
|
|
ppwszCAName[dwIndex], FALSE,
|
|
pCertRequestInfo, dwOIDInfo, pOIDInfo, TRUE))
|
|
continue;
|
|
|
|
dwValidCA++;
|
|
}
|
|
}
|
|
|
|
if(0==dwValidCA)
|
|
{
|
|
*pIds=IDS_ENROLL_NO_CERT_TYPE;
|
|
goto TraceErr;
|
|
}
|
|
|
|
//we need the add the CA to the list
|
|
if(!fFound)
|
|
{
|
|
//we require the CA has to be on DS
|
|
*pIds=IDS_INVALID_CA_FOR_ENROLL;
|
|
goto TraceErr;
|
|
}
|
|
|
|
// CertCAInfo.dwCA=(fFound) ? (dwCACount + 1) : (dwCACount+2);
|
|
CertCAInfo.dwCA=dwValidCA + 1;
|
|
CertCAInfo.rgCA=rgCertCA;
|
|
|
|
fResult=CryptUIWizCertRequestWithCAInfo(
|
|
pCertWizardInfo,
|
|
dwFlags,
|
|
hwndParent,
|
|
pwszWizardTitle,
|
|
pCertRequestInfo,
|
|
&CertCAInfo,
|
|
ppCertContext,
|
|
pCAdwStatus,
|
|
pIds);
|
|
if(!fResult)
|
|
goto TraceErr;
|
|
}
|
|
|
|
}
|
|
//the CA Information is not provided
|
|
else
|
|
{
|
|
//get a list of CAs which can issue the required certificate type
|
|
//or the OIDs
|
|
if(!CAUtilRetrieveCAFromCertType(
|
|
pCertWizardInfo,
|
|
pCertRequestInfo,
|
|
TRUE, //need multiple CAs
|
|
0, //ask for the CN
|
|
&dwCACount,
|
|
&ppwszCALocation,
|
|
&ppwszCAName))
|
|
{
|
|
*pIds=IDS_NO_CA_FOR_ENROLL;
|
|
goto TraceErr;
|
|
}
|
|
|
|
//init the OID
|
|
//set up the OID info
|
|
if(!InitCertCAOID(pCertRequestInfo,
|
|
&dwOIDInfo,
|
|
&pOIDInfo))
|
|
goto TraceErr;
|
|
|
|
//allocation the memory
|
|
rgCertCA=(CRYPTUI_WIZ_CERT_CA *)WizardAlloc((dwCACount + 1) *
|
|
sizeof(CRYPTUI_WIZ_CERT_CA));
|
|
|
|
if(NULL==rgCertCA)
|
|
goto OutOfMemoryErr;
|
|
|
|
//memset
|
|
memset(rgCertCA, 0, (dwCACount + 1) * sizeof(CRYPTUI_WIZ_CERT_CA));
|
|
|
|
//the 1st one is the default one without CA information
|
|
if(!InitCertCA(pCertWizardInfo, &rgCertCA[0], NULL, NULL, FALSE, pCertRequestInfo,
|
|
dwOIDInfo, pOIDInfo, TRUE))
|
|
{
|
|
*pIds=IDS_ENROLL_NO_CERT_TYPE;
|
|
goto TraceErr;
|
|
}
|
|
|
|
dwValidCA=0;
|
|
|
|
//the rest is the CA information
|
|
for(dwIndex=0; dwIndex<dwCACount; dwIndex++)
|
|
{
|
|
//mark the 1st CA as selected
|
|
if(!InitCertCA(pCertWizardInfo, &rgCertCA[dwValidCA+1], ppwszCALocation[dwIndex],
|
|
ppwszCAName[dwIndex], (dwValidCA == 0) ? TRUE : FALSE,
|
|
pCertRequestInfo, dwOIDInfo, pOIDInfo, TRUE) )
|
|
continue;
|
|
|
|
dwValidCA++;
|
|
|
|
}
|
|
|
|
if(0==dwValidCA)
|
|
{
|
|
*pIds=IDS_ENROLL_NO_CERT_TYPE;
|
|
goto TraceErr;
|
|
}
|
|
|
|
|
|
CertCAInfo.dwCA=dwValidCA + 1;
|
|
CertCAInfo.rgCA=rgCertCA;
|
|
|
|
|
|
|
|
|
|
fResult=CryptUIWizCertRequestWithCAInfo(
|
|
pCertWizardInfo,
|
|
dwFlags,
|
|
hwndParent,
|
|
pwszWizardTitle,
|
|
pCertRequestInfo,
|
|
&CertCAInfo,
|
|
ppCertContext,
|
|
pCAdwStatus,
|
|
pIds);
|
|
|
|
if(!fResult)
|
|
goto TraceErr;
|
|
}
|
|
|
|
fResult=TRUE;
|
|
|
|
CommonReturn:
|
|
//preserve the last error
|
|
dwError=GetLastError();
|
|
|
|
//free memory
|
|
|
|
//free the OID information
|
|
FreeCertCAOID(dwOIDInfo, pOIDInfo);
|
|
|
|
if(CertCAInfo.rgCA)
|
|
{
|
|
for(dwIndex=0; dwIndex<CertCAInfo.dwCA; dwIndex++)
|
|
{
|
|
FreeCertCACertType(CertCAInfo.rgCA[dwIndex].dwCertTypeInfo,
|
|
CertCAInfo.rgCA[dwIndex].rgCertTypeInfo);
|
|
}
|
|
|
|
WizardFree(CertCAInfo.rgCA);
|
|
}
|
|
|
|
|
|
if(ppwszCAName)
|
|
{
|
|
for(dwIndex=0; dwIndex < dwCACount; dwIndex++)
|
|
{
|
|
if(ppwszCAName[dwIndex])
|
|
WizardFree(ppwszCAName[dwIndex]);
|
|
}
|
|
|
|
WizardFree(ppwszCAName);
|
|
}
|
|
|
|
if(ppwszCALocation)
|
|
{
|
|
for(dwIndex=0; dwIndex < dwCACount; dwIndex++)
|
|
{
|
|
if(ppwszCALocation[dwIndex])
|
|
WizardFree(ppwszCALocation[dwIndex]);
|
|
}
|
|
|
|
WizardFree(ppwszCALocation);
|
|
}
|
|
//reset the error
|
|
SetLastError(dwError);
|
|
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
|
|
fResult=FALSE;
|
|
goto CommonReturn;
|
|
|
|
SET_ERROR(OutOfMemoryErr, E_OUTOFMEMORY);
|
|
TRACE_ERROR(TraceErr);
|
|
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// We make sure that the if the CA info is specified via the API, it
|
|
// support the specified cert type
|
|
//----------------------------------------------------------------------------
|
|
BOOL CASupportSpecifiedCertType(CRYPTUI_WIZ_CERT_CA *pCertCA)
|
|
{
|
|
DWORD dwIndex=0;
|
|
|
|
if(NULL == pCertCA)
|
|
return FALSE;
|
|
|
|
for(dwIndex=0; dwIndex<pCertCA->dwCertTypeInfo; dwIndex++)
|
|
{
|
|
if(TRUE==(pCertCA->rgCertTypeInfo)[dwIndex].fSelected)
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// This is the layer of CertRequest wizard that is independent of CA object on the DS.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
BOOL
|
|
WINAPI
|
|
CryptUIWizCertRequestWithCAInfo(
|
|
CERT_WIZARD_INFO *pCertWizardInfo,
|
|
DWORD dwFlags,
|
|
HWND hwndParent,
|
|
LPCWSTR pwszWizardTitle,
|
|
PCCRYPTUI_WIZ_CERT_REQUEST_INFO pCertRequestInfo,
|
|
PCCRYPTUI_WIZ_CERT_CA_INFO pCertRequestCAInfo,
|
|
PCCERT_CONTEXT *ppCertContext,
|
|
DWORD *pdwStatus,
|
|
UINT *pIds)
|
|
{
|
|
|
|
PROPSHEETPAGEW rgEnrollSheet[ENROLL_PROP_SHEET];
|
|
PROPSHEETHEADERW enrollHeader;
|
|
DWORD dwIndex=0;
|
|
DWORD dwSize=0;
|
|
ENROLL_PAGE_INFO rgEnrollPageInfo[]=
|
|
{(LPCWSTR)MAKEINTRESOURCE(IDD_WELCOME), Enroll_Welcome,
|
|
(LPCWSTR)MAKEINTRESOURCE(IDD_PURPOSE), Enroll_Purpose,
|
|
(LPCWSTR)MAKEINTRESOURCE(IDD_CSP_SERVICE_PROVIDER), Enroll_CSP,
|
|
(LPCWSTR)MAKEINTRESOURCE(IDD_CERTIFICATE_AUTHORITY), Enroll_CA,
|
|
(LPCWSTR)MAKEINTRESOURCE(IDD_NAME_DESCRIPTION), Enroll_Name,
|
|
(LPCWSTR)MAKEINTRESOURCE(IDD_COMPLETION), Enroll_Completion,
|
|
};
|
|
|
|
PROPSHEETPAGEW rgRenewSheet[RENEW_PROP_SHEET];
|
|
PROPSHEETHEADERW renewHeader;
|
|
ENROLL_PAGE_INFO rgRenewPageInfo[]=
|
|
{(LPCWSTR)MAKEINTRESOURCE(IDD_RENEW_WELCOME), Renew_Welcome,
|
|
(LPCWSTR)MAKEINTRESOURCE(IDD_RENEW_OPTIONS), Renew_Options,
|
|
(LPCWSTR)MAKEINTRESOURCE(IDD_RENEW_SERVICE_PROVIDER), Renew_CSP,
|
|
(LPCWSTR)MAKEINTRESOURCE(IDD_RENEW_CA), Renew_CA,
|
|
(LPCWSTR)MAKEINTRESOURCE(IDD_RENEW_COMPLETION), Renew_Completion,
|
|
};
|
|
|
|
|
|
WCHAR wszTitle[MAX_TITLE_LENGTH];
|
|
HRESULT hr=E_FAIL;
|
|
BOOL fResult=FALSE;
|
|
DWORD dwError=0;
|
|
UINT idsText=IDS_INVALID_INFO_FOR_PKCS10;
|
|
DWORD dwStatus=CRYPTUI_WIZ_CERT_REQUEST_STATUS_UNKNOWN;
|
|
|
|
|
|
//memset
|
|
memset(rgEnrollSheet, 0, sizeof(PROPSHEETPAGEW)*ENROLL_PROP_SHEET);
|
|
memset(&enrollHeader, 0, sizeof(PROPSHEETHEADERW));
|
|
|
|
memset(rgRenewSheet, 0, sizeof(PROPSHEETPAGEW)*RENEW_PROP_SHEET);
|
|
memset(&renewHeader, 0, sizeof(PROPSHEETHEADERW));
|
|
|
|
|
|
//error checking
|
|
if(NULL== pCertRequestInfo ||
|
|
NULL == pCertRequestCAInfo)
|
|
goto InvalidArgErr;
|
|
|
|
//the CA name is a must
|
|
if(1>=(pCertRequestCAInfo->dwCA))
|
|
{
|
|
idsText=IDS_NO_CA_FOR_CSP;
|
|
goto InvalidArgErr;
|
|
}
|
|
|
|
|
|
//for each ca information, we can not have both OID and certType information
|
|
for(dwIndex=0; dwIndex <pCertRequestCAInfo->dwCA; dwIndex++)
|
|
{
|
|
if((0==pCertRequestCAInfo->rgCA[dwIndex].dwOIDInfo) &&
|
|
(0==pCertRequestCAInfo->rgCA[dwIndex].dwCertTypeInfo))
|
|
{
|
|
//we are in trouble
|
|
goto InvalidArgErr;
|
|
}
|
|
|
|
if((0!=pCertRequestCAInfo->rgCA[dwIndex].dwOIDInfo) &&
|
|
(0!=pCertRequestCAInfo->rgCA[dwIndex].dwCertTypeInfo))
|
|
goto InvalidArgErr;
|
|
}
|
|
|
|
//make sure the genKey flag does not include CRYPT_USER_PROTECTED
|
|
//if we are doing a remote enrollment/renew
|
|
if(FALSE == pCertWizardInfo->fLocal)
|
|
{
|
|
if(CRYPT_USER_PROTECTED & pCertWizardInfo->dwGenKeyFlags)
|
|
{
|
|
idsText=IDS_NO_USER_PROTECTED_FOR_REMOTE;
|
|
goto InvalidArgErr;
|
|
}
|
|
}
|
|
|
|
|
|
//for UI enrollment
|
|
//get a list of CAs, based on the CSP user selected
|
|
//and the availability of CAs on the DS
|
|
if(pCertRequestInfo->dwPurpose & CRYPTUI_WIZ_CERT_RENEW)
|
|
{
|
|
|
|
pCertWizardInfo->pCertContext=pCertRequestInfo->pRenewCertContext;
|
|
|
|
//the certificate has to be the property
|
|
if(!CertGetCertificateContextProperty(
|
|
pCertWizardInfo->pCertContext,
|
|
CERT_KEY_PROV_INFO_PROP_ID,
|
|
NULL,
|
|
&dwSize) || (0==dwSize))
|
|
{
|
|
idsText=IDS_NO_PVK_FOR_RENEW_CERT;
|
|
goto InvalidArgErr;
|
|
}
|
|
}
|
|
|
|
//set up the information
|
|
pCertWizardInfo->dwFlags=dwFlags;
|
|
pCertWizardInfo->dwPurpose=pCertRequestInfo->dwPurpose;
|
|
pCertWizardInfo->hwndParent=hwndParent;
|
|
pCertWizardInfo->pCertCAInfo=(CRYPTUI_WIZ_CERT_CA_INFO *)pCertRequestCAInfo;
|
|
pCertWizardInfo->iOrgCertType=-1; //the original cert type selection is -1
|
|
pCertWizardInfo->iOrgCSP=-1; //the original CSP selection is -1
|
|
pCertWizardInfo->pwszCADisplayName=NULL;
|
|
|
|
//get the CA name and CA location
|
|
for(dwIndex=0; dwIndex < pCertRequestCAInfo->dwCA; dwIndex++)
|
|
{
|
|
if(TRUE==pCertRequestCAInfo->rgCA[dwIndex].fSelected)
|
|
{
|
|
if(NULL==pCertRequestCAInfo->rgCA[dwIndex].pwszCALocation ||
|
|
NULL==pCertRequestCAInfo->rgCA[dwIndex].pwszCAName)
|
|
goto InvalidArgErr;
|
|
|
|
//copy the CA name and location
|
|
pCertWizardInfo->pwszCALocation=WizardAllocAndCopyWStr(pCertRequestCAInfo->rgCA[dwIndex].pwszCALocation);
|
|
pCertWizardInfo->pwszCAName=WizardAllocAndCopyWStr(pCertRequestCAInfo->rgCA[dwIndex].pwszCAName);
|
|
|
|
//memory check
|
|
if(NULL== pCertWizardInfo->pwszCALocation ||
|
|
NULL== pCertWizardInfo->pwszCAName)
|
|
goto MemoryErr;
|
|
|
|
pCertWizardInfo->dwCAIndex=dwIndex;
|
|
pCertWizardInfo->dwOrgCA=dwIndex;
|
|
}
|
|
}
|
|
|
|
//make sure that have CA information
|
|
if(NULL== pCertWizardInfo->pwszCALocation ||
|
|
NULL== pCertWizardInfo->pwszCAName ||
|
|
0 == pCertWizardInfo->dwCAIndex ||
|
|
0 == pCertWizardInfo->dwOrgCA)
|
|
{
|
|
idsText=IDS_NO_CA_FOR_ENROLL;
|
|
goto FailErr;
|
|
}
|
|
|
|
//if user has selected a CA and CertType, we want to
|
|
//make sure that the CA specified do support the
|
|
//CertType
|
|
if(TRUE == pCertWizardInfo->fCAInput)
|
|
{
|
|
//make sure that the CA has a selected cert type in it
|
|
if(!(CASupportSpecifiedCertType(&(pCertWizardInfo->pCertCAInfo->rgCA[pCertWizardInfo->dwCAIndex]))))
|
|
{
|
|
idsText=IDS_ENROLL_NO_CERT_TYPE;
|
|
goto FailErr;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Ensure that we default to a CA that supports
|
|
ResetDefaultCA(pCertWizardInfo);
|
|
}
|
|
|
|
|
|
pCertWizardInfo->fConfirmation = !(dwFlags & CRYPTUI_WIZ_NO_UI);
|
|
pCertWizardInfo->pwszConfirmationTitle = pwszWizardTitle;
|
|
|
|
if(pCertRequestInfo->dwPurpose & CRYPTUI_WIZ_CERT_ENROLL)
|
|
pCertWizardInfo->idsConfirmTitle=IDS_ENROLL_CONFIRM;
|
|
else
|
|
pCertWizardInfo->idsConfirmTitle=IDS_RENEW_CONFIRM;
|
|
|
|
pCertWizardInfo->pAuthentication=pCertRequestInfo->pAuthentication;
|
|
pCertWizardInfo->pwszRequestString=pCertRequestInfo->pCertRequestString;
|
|
pCertWizardInfo->pwszDesStore=pCertRequestInfo->pwszDesStore;
|
|
pCertWizardInfo->pwszCertDNName=pCertRequestInfo->pwszCertDNName;
|
|
pCertWizardInfo->pszHashAlg=pCertRequestInfo->pszHashAlg;
|
|
pCertWizardInfo->dwPostOption=pCertRequestInfo->dwPostOption;
|
|
|
|
if(pCertRequestInfo->pwszFriendlyName)
|
|
pCertWizardInfo->pwszFriendlyName=WizardAllocAndCopyWStr((LPWSTR)(pCertRequestInfo->pwszFriendlyName));
|
|
if(pCertRequestInfo->pwszDescription)
|
|
pCertWizardInfo->pwszDescription=WizardAllocAndCopyWStr((LPWSTR)(pCertRequestInfo->pwszDescription));
|
|
|
|
pCertWizardInfo->pCertRequestExtensions=pCertRequestInfo->pCertRequestExtensions;
|
|
|
|
//set up the fonts for the UI case
|
|
if( 0 == (dwFlags & CRYPTUI_WIZ_NO_UI) )
|
|
{
|
|
if(!SetupFonts(g_hmodThisDll,
|
|
NULL,
|
|
&(pCertWizardInfo->hBigBold),
|
|
&(pCertWizardInfo->hBold)))
|
|
{
|
|
idsText=IDS_FAIL_INIT_DLL;
|
|
goto Win32Err;
|
|
}
|
|
|
|
//we change the cursor shape from the hour glass to its original shape
|
|
if((hwndParent) && (TRUE == pCertWizardInfo->fCursorChanged))
|
|
{
|
|
//set the cursor back
|
|
SetCursor(pCertWizardInfo->hPrevCursor);
|
|
SetWindowLongPtr(hwndParent, GCLP_HCURSOR, (LONG_PTR)(pCertWizardInfo->hWinPrevCursor));
|
|
pCertWizardInfo->fCursorChanged = FALSE;
|
|
}
|
|
}
|
|
|
|
//init the common control for the UI enrollmnet
|
|
if((pCertRequestInfo->dwPurpose & CRYPTUI_WIZ_CERT_ENROLL) &&
|
|
((dwFlags & CRYPTUI_WIZ_NO_UI) == 0)
|
|
)
|
|
{
|
|
|
|
if(!WizardInit() ||
|
|
(sizeof(rgEnrollPageInfo)/sizeof(rgEnrollPageInfo[0])!=ENROLL_PROP_SHEET)
|
|
)
|
|
{
|
|
idsText=IDS_FAIL_INIT_DLL;
|
|
goto InvalidArgErr;
|
|
}
|
|
|
|
//set up the property sheet and the property header
|
|
for(dwIndex=0; dwIndex<ENROLL_PROP_SHEET; dwIndex++)
|
|
{
|
|
rgEnrollSheet[dwIndex].dwSize=sizeof(rgEnrollSheet[dwIndex]);
|
|
|
|
if(pwszWizardTitle)
|
|
rgEnrollSheet[dwIndex].dwFlags=PSP_USETITLE;
|
|
else
|
|
rgEnrollSheet[dwIndex].dwFlags=0;
|
|
|
|
rgEnrollSheet[dwIndex].hInstance=g_hmodThisDll;
|
|
rgEnrollSheet[dwIndex].pszTemplate=rgEnrollPageInfo[dwIndex].pszTemplate;
|
|
|
|
if(pwszWizardTitle)
|
|
{
|
|
rgEnrollSheet[dwIndex].pszTitle=pwszWizardTitle;
|
|
}
|
|
else
|
|
rgEnrollSheet[dwIndex].pszTitle=NULL;
|
|
|
|
rgEnrollSheet[dwIndex].pfnDlgProc=rgEnrollPageInfo[dwIndex].pfnDlgProc;
|
|
|
|
rgEnrollSheet[dwIndex].lParam=(LPARAM)pCertWizardInfo;
|
|
}
|
|
|
|
//set up the header information
|
|
enrollHeader.dwSize=sizeof(enrollHeader);
|
|
enrollHeader.dwFlags=PSH_PROPSHEETPAGE | PSH_WIZARD | PSH_NOAPPLYNOW;
|
|
enrollHeader.hwndParent=hwndParent;
|
|
enrollHeader.hInstance=g_hmodThisDll;
|
|
|
|
if(pwszWizardTitle)
|
|
enrollHeader.pszCaption=pwszWizardTitle;
|
|
else
|
|
{
|
|
if(LoadStringU(g_hmodThisDll, IDS_ENROLL_WIZARD_TITLE, wszTitle, sizeof(wszTitle)/sizeof(wszTitle[0])))
|
|
enrollHeader.pszCaption=wszTitle;
|
|
}
|
|
|
|
enrollHeader.nPages=ENROLL_PROP_SHEET;
|
|
enrollHeader.nStartPage=0;
|
|
enrollHeader.ppsp=rgEnrollSheet;
|
|
|
|
//create the wizard
|
|
if(!PropertySheetU(&enrollHeader))
|
|
{
|
|
//cancel button is pushed
|
|
fResult=TRUE;
|
|
idsText=0;
|
|
goto CommonReturn;
|
|
}
|
|
else
|
|
{
|
|
//finish button is pushed
|
|
//get the result of the enrollment wizard
|
|
idsText=pCertWizardInfo->idsText;
|
|
dwStatus=pCertWizardInfo->dwStatus;
|
|
|
|
if(S_OK != (hr=pCertWizardInfo->hr))
|
|
goto I_EnrollErr;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
//call the UI renew
|
|
if((pCertRequestInfo->dwPurpose & CRYPTUI_WIZ_CERT_RENEW) &&
|
|
((dwFlags & CRYPTUI_WIZ_NO_UI) == 0)
|
|
)
|
|
{
|
|
//init the common control
|
|
if(!WizardInit() ||
|
|
(sizeof(rgRenewPageInfo)/sizeof(rgRenewPageInfo[0])!=RENEW_PROP_SHEET)
|
|
)
|
|
{
|
|
idsText=IDS_FAIL_INIT_DLL;
|
|
goto InvalidArgErr;
|
|
}
|
|
|
|
//set up the property pages and the property header
|
|
for(dwIndex=0; dwIndex<RENEW_PROP_SHEET; dwIndex++)
|
|
{
|
|
rgRenewSheet[dwIndex].dwSize=sizeof(rgRenewSheet[dwIndex]);
|
|
|
|
if(pwszWizardTitle)
|
|
rgRenewSheet[dwIndex].dwFlags=PSP_USETITLE;
|
|
else
|
|
rgRenewSheet[dwIndex].dwFlags=0;
|
|
|
|
rgRenewSheet[dwIndex].hInstance=g_hmodThisDll;
|
|
rgRenewSheet[dwIndex].pszTemplate=rgRenewPageInfo[dwIndex].pszTemplate;
|
|
|
|
if(pwszWizardTitle)
|
|
{
|
|
rgRenewSheet[dwIndex].pszTitle=pwszWizardTitle;
|
|
}
|
|
else
|
|
rgRenewSheet[dwIndex].pszTitle=NULL;
|
|
|
|
rgRenewSheet[dwIndex].pfnDlgProc=rgRenewPageInfo[dwIndex].pfnDlgProc;
|
|
|
|
rgRenewSheet[dwIndex].lParam=(LPARAM)pCertWizardInfo;
|
|
}
|
|
|
|
//set up the header information
|
|
renewHeader.dwSize=sizeof(renewHeader);
|
|
renewHeader.dwFlags=PSH_PROPSHEETPAGE | PSH_WIZARD | PSH_NOAPPLYNOW;
|
|
renewHeader.hwndParent=hwndParent;
|
|
renewHeader.hInstance=g_hmodThisDll;
|
|
|
|
if(pwszWizardTitle)
|
|
renewHeader.pszCaption=pwszWizardTitle;
|
|
else
|
|
{
|
|
if(LoadStringU(g_hmodThisDll, IDS_RENEW_WIZARD_TITLE, wszTitle, sizeof(wszTitle)/sizeof(wszTitle[0])))
|
|
renewHeader.pszCaption=wszTitle;
|
|
}
|
|
|
|
renewHeader.nPages=RENEW_PROP_SHEET;
|
|
renewHeader.nStartPage=0;
|
|
renewHeader.ppsp=rgRenewSheet;
|
|
|
|
//create the wizard
|
|
if(!PropertySheetU(&renewHeader))
|
|
{
|
|
//cancel button is pushed
|
|
fResult=TRUE;
|
|
idsText=0;
|
|
goto CommonReturn;
|
|
}
|
|
else
|
|
{
|
|
//finish button is pushed
|
|
//get the result of the enrollment wizard
|
|
idsText=pCertWizardInfo->idsText;
|
|
dwStatus=pCertWizardInfo->dwStatus;
|
|
|
|
if(S_OK != (hr=pCertWizardInfo->hr))
|
|
goto I_EnrollErr;
|
|
}
|
|
|
|
}
|
|
//UIless enroll or renew
|
|
else
|
|
{
|
|
CertRequester *pCertRequester = NULL;
|
|
CertRequesterContext *pCertRequesterContext = NULL;
|
|
|
|
if (NULL == (pCertRequester = (CertRequester *) pCertWizardInfo->hRequester))
|
|
{
|
|
hr = E_UNEXPECTED;
|
|
goto I_EnrollErr;
|
|
}
|
|
if (NULL == (pCertRequesterContext = pCertRequester->GetContext()))
|
|
{
|
|
hr = E_UNEXPECTED;
|
|
goto I_EnrollErr;
|
|
}
|
|
|
|
hr = pCertRequesterContext->Enroll(&dwStatus, (HANDLE *)&(pCertWizardInfo->pNewCertContext));
|
|
if (0 == pCertWizardInfo->idsText) {
|
|
idsText = CryptUIStatusToIDSText(hr, dwStatus);
|
|
}
|
|
|
|
if(S_OK != hr)
|
|
goto I_EnrollErr;
|
|
}
|
|
}
|
|
|
|
if(S_OK !=hr)
|
|
goto I_EnrollErr;
|
|
|
|
fResult=TRUE;
|
|
|
|
CommonReturn:
|
|
|
|
//preserve the last error
|
|
dwError=GetLastError();
|
|
|
|
if(pIds)
|
|
*pIds=idsText;
|
|
|
|
|
|
//we have to free the friendlyName and description field
|
|
if(pCertWizardInfo->pwszFriendlyName)
|
|
WizardFree(pCertWizardInfo->pwszFriendlyName);
|
|
|
|
if(pCertWizardInfo->pwszDescription)
|
|
WizardFree(pCertWizardInfo->pwszDescription);
|
|
|
|
//free the CA name and CA location
|
|
if(pCertWizardInfo->pwszCALocation)
|
|
WizardFree(pCertWizardInfo->pwszCALocation);
|
|
|
|
if(pCertWizardInfo->pwszCAName)
|
|
WizardFree(pCertWizardInfo->pwszCAName);
|
|
|
|
if(pCertWizardInfo->pwszCADisplayName)
|
|
WizardFree(pCertWizardInfo->pwszCADisplayName);
|
|
|
|
//destroy the hFont object
|
|
DestroyFonts(pCertWizardInfo->hBigBold,
|
|
pCertWizardInfo->hBold);
|
|
|
|
//return the value
|
|
if(pdwStatus)
|
|
{
|
|
//remember it is the CA status
|
|
switch (dwStatus)
|
|
{
|
|
case CRYPTUI_WIZ_CERT_REQUEST_STATUS_INSTALL_FAILED:
|
|
case CRYPTUI_WIZ_CERT_REQUEST_STATUS_INSTALL_CANCELLED:
|
|
dwStatus=CRYPTUI_WIZ_CERT_REQUEST_STATUS_CERT_ISSUED;
|
|
break;
|
|
case CRYPTUI_WIZ_CERT_REQUEST_STATUS_KEYSVC_FAILED:
|
|
dwStatus=CRYPTUI_WIZ_CERT_REQUEST_STATUS_UNKNOWN;
|
|
break;
|
|
}
|
|
*pdwStatus=dwStatus;
|
|
}
|
|
|
|
if(ppCertContext)
|
|
*ppCertContext=pCertWizardInfo->pNewCertContext;
|
|
else
|
|
{
|
|
//free the certificate context
|
|
if(pCertWizardInfo->pNewCertContext)
|
|
CertFreeCertificateContext(pCertWizardInfo->pNewCertContext);
|
|
}
|
|
|
|
//reset the error
|
|
SetLastError(dwError);
|
|
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
|
|
fResult=FALSE;
|
|
goto CommonReturn;
|
|
|
|
SET_ERROR(InvalidArgErr, E_INVALIDARG);
|
|
TRACE_ERROR(Win32Err);
|
|
SET_ERROR_VAR(I_EnrollErr, hr);
|
|
SET_ERROR(MemoryErr, E_OUTOFMEMORY);
|
|
SET_ERROR(FailErr, E_FAIL);
|
|
}
|
|
|
|
|