Leaked source code of windows server 2003
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

  1. //depot/Lab03_N/ds/security/cryptoapi/ui/wizards/wizards.cpp#21 - edit change 8790 (text)
  2. //-------------------------------------------------------------
  3. // Copyright (C) Microsoft Corporation, 1996 - 1999
  4. //
  5. // File: wizards.cpp
  6. //
  7. // Contents: The cpp file to implement the wizards
  8. //
  9. // History: 16-10-1997 xiaohs created
  10. //
  11. //--------------------------------------------------------------
  12. #include "wzrdpvk.h"
  13. #include "certca.h"
  14. #include "cautil.h"
  15. #include "CertRequesterContext.h"
  16. #include "CertDSManager.h"
  17. #include "CertRequester.h"
  18. // Used to provide singleton instances of useful COM objects in a demand-driven fashion.
  19. // See wzrdpvk.h.
  20. EnrollmentCOMObjectFactory *g_pEnrollFactory = NULL;
  21. HINSTANCE g_hmodThisDll = NULL; // Handle to this DLL itself.
  22. HMODULE g_hmodRichEdit = NULL;
  23. HMODULE g_hmodxEnroll=NULL; // Handle to the xEnroll dll
  24. typedef struct _CREATE_REQUEST_WIZARD_STATE {
  25. HANDLE hRequest;
  26. DWORD dwPurpose;
  27. LPWSTR pwszMachineName;
  28. DWORD dwStoreFlags;
  29. } CREATE_REQUEST_WIZARD_STATE, *PCREATE_REQUEST_WIZARD_STATE;
  30. /////////////////////////////////////////////////////////////////////////////
  31. // library Entry Point
  32. extern "C"
  33. BOOL WINAPI Wizard_DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
  34. {
  35. if (dwReason == DLL_PROCESS_ATTACH)
  36. g_hmodThisDll=hInstance;
  37. if (dwReason == DLL_PROCESS_DETACH)
  38. {
  39. // If the rich edit dll was loaded, then unload it now
  40. if (g_hmodRichEdit != NULL)
  41. {
  42. FreeLibrary(g_hmodRichEdit);
  43. }
  44. //if xEnroll.dll was loaded, unload it now
  45. if(NULL != g_hmodxEnroll)
  46. {
  47. FreeLibrary(g_hmodxEnroll);
  48. }
  49. }
  50. return TRUE; // ok
  51. }
  52. DWORD CryptUIStatusToIDSText(HRESULT hr, DWORD dwStatus)
  53. {
  54. switch(dwStatus)
  55. {
  56. case CRYPTUI_WIZ_CERT_REQUEST_STATUS_UNKNOWN: return IDS_UNKNOWN_WIZARD_ERROR;
  57. case CRYPTUI_WIZ_CERT_REQUEST_STATUS_REQUEST_ERROR: return IDS_REQUEST_ERROR;
  58. case CRYPTUI_WIZ_CERT_REQUEST_STATUS_REQUEST_DENIED: return IDS_REQUEST_DENIED;
  59. case CRYPTUI_WIZ_CERT_REQUEST_STATUS_SUCCEEDED: return S_OK == hr ? IDS_REQUEST_SUCCEDDED : IDS_REQUEST_FAILED;
  60. case CRYPTUI_WIZ_CERT_REQUEST_STATUS_ISSUED_SEPARATELY: return IDS_ISSUED_SEPERATE;
  61. case CRYPTUI_WIZ_CERT_REQUEST_STATUS_UNDER_SUBMISSION: return IDS_UNDER_SUBMISSION;
  62. case CRYPTUI_WIZ_CERT_REQUEST_STATUS_INSTALL_FAILED: return IDS_INSTALL_FAILED;
  63. case CRYPTUI_WIZ_CERT_REQUEST_STATUS_CONNECTION_FAILED: return IDS_CONNET_CA_FAILED;
  64. case CRYPTUI_WIZ_CERT_REQUEST_STATUS_INSTALL_CANCELLED: return IDS_INSTAL_CANCELLED;
  65. case CRYPTUI_WIZ_CERT_REQUEST_STATUS_KEYSVC_FAILED: return IDS_RPC_CALL_FAILED;
  66. default:
  67. return IDS_UNKNOWN_WIZARD_ERROR;
  68. }
  69. }
  70. //--------------------------------------------------------------------------
  71. //
  72. // I_EnrollMessageBox
  73. //
  74. //
  75. //
  76. //--------------------------------------------------------------------------
  77. int I_EnrollMessageBox(
  78. HWND hWnd,
  79. UINT idsText,
  80. HRESULT hr,
  81. UINT idsCaption,
  82. LPCWSTR pwszCaption,
  83. UINT uType)
  84. {
  85. //we print out the error message (hr) for denied and error case
  86. WCHAR wszText[MAX_STRING_SIZE];
  87. WCHAR wszCaption[MAX_STRING_SIZE];
  88. UINT intReturn=0;
  89. LPWSTR wszErrorMsg=NULL;
  90. LPWSTR wszTextErr=NULL;
  91. //init
  92. wszText[0]=L'\0';
  93. wszCaption[0]=L'\0';
  94. if((IDS_REQUEST_ERROR != idsText) && (IDS_REQUEST_DENIED != idsText) &&
  95. (IDS_REQUEST_FAILED != idsText) && (IDS_UNKNOWN_WIZARD_ERROR != idsText) &&
  96. (IDS_INSTALL_FAILED != idsText))
  97. return I_MessageBox(hWnd, idsText, idsCaption, pwszCaption, uType);
  98. //get the caption string
  99. if(NULL == pwszCaption)
  100. {
  101. if(!LoadStringU(g_hmodThisDll, idsCaption, wszCaption, ARRAYSIZE(wszCaption)))
  102. return 0;
  103. }
  104. //get the text string
  105. if(!LoadStringU(g_hmodThisDll, idsText, wszText, ARRAYSIZE(wszText)))
  106. {
  107. return 0;
  108. }
  109. //cancatenate the error string with the error string.
  110. //using W version because this is a NT5 only function call
  111. if( FAILED(hr) && FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  112. FORMAT_MESSAGE_FROM_SYSTEM |
  113. FORMAT_MESSAGE_IGNORE_INSERTS,
  114. NULL,
  115. hr,
  116. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  117. (LPWSTR) &wszErrorMsg,
  118. 0,
  119. NULL))
  120. {
  121. wszTextErr=(LPWSTR)WizardAlloc(sizeof(WCHAR) *(wcslen(wszText) + wcslen(wszErrorMsg) + wcslen(L". ")+2));
  122. if(!wszTextErr)
  123. {
  124. if(wszErrorMsg)
  125. LocalFree(wszErrorMsg);
  126. return 0;
  127. }
  128. wcscpy(wszTextErr, wszText);
  129. wcscat(wszTextErr, wszErrorMsg);
  130. }
  131. else
  132. {
  133. wszTextErr=(LPWSTR)WizardAlloc((wcslen(wszText) + 2) * sizeof(WCHAR));
  134. if(!wszTextErr)
  135. {
  136. if(wszErrorMsg)
  137. LocalFree(wszErrorMsg);
  138. return 0;
  139. }
  140. wcscpy(wszTextErr, wszText);
  141. }
  142. //message box
  143. if(pwszCaption)
  144. {
  145. intReturn=MessageBoxExW(hWnd, wszTextErr, pwszCaption, uType, 0);
  146. }
  147. else
  148. intReturn=MessageBoxExW(hWnd, wszTextErr, wszCaption, uType, 0);
  149. if(wszErrorMsg)
  150. LocalFree(wszErrorMsg);
  151. if(wszTextErr)
  152. WizardFree(wszTextErr);
  153. return intReturn;
  154. }
  155. //--------------------------------------------------------------------------
  156. // WizardCopyAndFreeWStr
  157. //
  158. // Alloc and copy the new string and free the old string. If failed to
  159. // alloc the memory, use the old string
  160. //
  161. //--------------------------------------------------------------------------
  162. LPWSTR WizardCopyAndFreeWStr(LPWSTR pwszNew, LPWSTR pwszOld)
  163. {
  164. LPWSTR pwsz=NULL;
  165. pwsz=WizardAllocAndCopyWStr(pwszNew);
  166. if(pwsz)
  167. {
  168. WizardFree(pwszOld);
  169. }
  170. else
  171. {
  172. pwsz=pwszOld;
  173. }
  174. return pwsz;
  175. }
  176. //--------------------------------------------------------------------------
  177. //
  178. // GetCAContext
  179. //
  180. // Call the CA selection dialogue, get the selected CA name and update
  181. // internal data. (pCertWizardInfo->pwszCALocation, pCertWizardInfo->
  182. // pwszCAName, and pCertWizardInfo->dwCAindex).
  183. //
  184. //--------------------------------------------------------------------------
  185. PCRYPTUI_CA_CONTEXT GetCAContext(HWND hwndControl,
  186. CERT_WIZARD_INFO *pCertWizardInfo)
  187. {
  188. DWORD dwCACount=0;
  189. PCRYPTUI_WIZ_CERT_CA_INFO pCertCAInfo=NULL;
  190. DWORD dwIndex=0;
  191. BOOL fResult=FALSE;
  192. CRYPTUI_SELECT_CA_STRUCT SelectCAStruct;
  193. PCRYPTUI_CA_CONTEXT pCAContext=NULL;
  194. BOOL fFoundCA=FALSE;
  195. LPWSTR pwszOldName=NULL;
  196. LPWSTR pwszOldLocation=NULL;
  197. PCRYPTUI_CA_CONTEXT *prgCAContext=NULL;
  198. LPWSTR pwszCADisplayName=NULL;
  199. //init
  200. memset(&SelectCAStruct, 0, sizeof(CRYPTUI_SELECT_CA_STRUCT));
  201. if(NULL == pCertWizardInfo)
  202. return NULL;
  203. pCertCAInfo=pCertWizardInfo->pCertCAInfo;
  204. if(NULL==pCertCAInfo)
  205. return NULL;
  206. if( (0==pCertCAInfo->dwCA) || (NULL == pCertCAInfo->rgCA))
  207. return NULL;
  208. //add all the CAs
  209. prgCAContext=(PCRYPTUI_CA_CONTEXT *)WizardAlloc(
  210. sizeof(PCRYPTUI_CA_CONTEXT) * (pCertCAInfo->dwCA));
  211. if(NULL == prgCAContext)
  212. goto MemoryErr;
  213. //memset
  214. memset(prgCAContext, 0, sizeof(PCRYPTUI_CA_CONTEXT) * (pCertCAInfo->dwCA));
  215. //add the count
  216. dwCACount = 0;
  217. for(dwIndex=1; dwIndex <(pCertCAInfo->dwCA); dwIndex++)
  218. {
  219. //skip the 1st CA. it contains generic information
  220. if((pCertCAInfo->rgCA)[dwIndex].pwszCAName && (pCertCAInfo->rgCA)[dwIndex].pwszCALocation)
  221. {
  222. //the CA has to support the selected CT
  223. if(CASupportSpecifiedCertType(&((pCertCAInfo->rgCA)[dwIndex])))
  224. {
  225. prgCAContext[dwCACount]=(PCRYPTUI_CA_CONTEXT)WizardAlloc(
  226. sizeof(CRYPTUI_CA_CONTEXT));
  227. if(NULL==prgCAContext[dwCACount])
  228. goto MemoryErr;
  229. //memset
  230. memset(prgCAContext[dwCACount], 0, sizeof(CRYPTUI_CA_CONTEXT));
  231. prgCAContext[dwCACount]->dwSize=sizeof(CRYPTUI_CA_CONTEXT);
  232. if(!CAUtilGetCADisplayName(
  233. (pCertWizardInfo->fMachine) ? CA_FIND_LOCAL_SYSTEM:0,
  234. (pCertCAInfo->rgCA)[dwIndex].pwszCAName,
  235. (LPWSTR *)&(prgCAContext[dwCACount]->pwszCAName)))
  236. {
  237. prgCAContext[dwCACount]->pwszCAName=(LPCWSTR)WizardAllocAndCopyWStr(
  238. (pCertCAInfo->rgCA)[dwIndex].pwszCAName);
  239. }
  240. prgCAContext[dwCACount]->pwszCAMachineName=(LPCWSTR)WizardAllocAndCopyWStr(
  241. (pCertCAInfo->rgCA)[dwIndex].pwszCALocation);
  242. //make sure we have the correct information
  243. if((NULL==prgCAContext[dwCACount]->pwszCAName) ||
  244. (NULL==prgCAContext[dwCACount]->pwszCAMachineName)
  245. )
  246. goto TraceErr;
  247. //add the count of the CA
  248. dwCACount++;
  249. }
  250. }
  251. }
  252. if(0 == dwCACount)
  253. goto InvalidArgErr;
  254. //call the CA selection dialogue
  255. SelectCAStruct.dwSize=sizeof(CRYPTUI_SELECT_CA_STRUCT);
  256. SelectCAStruct.hwndParent=hwndControl;
  257. SelectCAStruct.cCAContext=dwCACount;
  258. SelectCAStruct.rgCAContext=(PCCRYPTUI_CA_CONTEXT *)prgCAContext;
  259. SelectCAStruct.pSelectCACallback=NULL;
  260. SelectCAStruct.wszDisplayString=NULL;
  261. pCAContext=(PCRYPTUI_CA_CONTEXT)CryptUIDlgSelectCA(&SelectCAStruct);
  262. if(pCAContext)
  263. {
  264. if((NULL == (pCAContext->pwszCAName)) || (NULL == (pCAContext->pwszCAMachineName)))
  265. goto MemoryErr;
  266. //user has selected a CA. Find it in our list
  267. fFoundCA=FALSE;
  268. for(dwIndex=1; dwIndex <(pCertCAInfo->dwCA); dwIndex++)
  269. {
  270. //skip the 1st CA. it contains generic information
  271. if((pCertCAInfo->rgCA)[dwIndex].pwszCAName && (pCertCAInfo->rgCA)[dwIndex].pwszCALocation)
  272. {
  273. //the CA has to support the selected CT
  274. if(CASupportSpecifiedCertType(&((pCertCAInfo->rgCA)[dwIndex])))
  275. {
  276. if(0 == wcscmp((pCertCAInfo->rgCA)[dwIndex].pwszCALocation,
  277. pCAContext->pwszCAMachineName))
  278. {
  279. if(CAUtilGetCADisplayName(
  280. (pCertWizardInfo->fMachine) ? CA_FIND_LOCAL_SYSTEM:0,
  281. (pCertCAInfo->rgCA)[dwIndex].pwszCAName,
  282. &pwszCADisplayName))
  283. {
  284. if(0==wcscmp(pwszCADisplayName,
  285. pCAContext->pwszCAName))
  286. fFoundCA=TRUE;
  287. }
  288. else
  289. {
  290. if(0==wcscmp((pCertCAInfo->rgCA)[dwIndex].pwszCAName,
  291. pCAContext->pwszCAName))
  292. fFoundCA=TRUE;
  293. }
  294. //free the memory
  295. if(pwszCADisplayName)
  296. {
  297. WizardFree(pwszCADisplayName);
  298. pwszCADisplayName=NULL;
  299. }
  300. if(fFoundCA)
  301. {
  302. pwszOldName = pCertWizardInfo->pwszCAName;
  303. pwszOldLocation = pCertWizardInfo->pwszCALocation;
  304. pCertWizardInfo->pwszCALocation=
  305. WizardCopyAndFreeWStr((pCertCAInfo->rgCA)[dwIndex].pwszCALocation,
  306. pwszOldLocation);
  307. pCertWizardInfo->pwszCAName=
  308. WizardCopyAndFreeWStr((pCertCAInfo->rgCA)[dwIndex].pwszCAName,
  309. pwszOldName);
  310. //copy the new data
  311. pCertWizardInfo->dwCAIndex=dwIndex;
  312. break;
  313. }
  314. }
  315. }
  316. }
  317. }
  318. //we should find the selected the CA in our cached CA list
  319. if(FALSE == fFoundCA)
  320. goto TraceErr;
  321. }
  322. fResult=TRUE;
  323. CommonReturn:
  324. if(pwszCADisplayName)
  325. {
  326. WizardFree(pwszCADisplayName);
  327. pwszCADisplayName=NULL;
  328. }
  329. //free the CA list
  330. if(prgCAContext)
  331. {
  332. for(dwIndex=0; dwIndex<dwCACount; dwIndex++)
  333. {
  334. if(prgCAContext[dwIndex])
  335. CryptUIDlgFreeCAContext(prgCAContext[dwIndex]);
  336. }
  337. WizardFree(prgCAContext);
  338. }
  339. return pCAContext;
  340. ErrorReturn:
  341. if(pCAContext)
  342. {
  343. CryptUIDlgFreeCAContext(pCAContext);
  344. pCAContext=NULL;
  345. }
  346. fResult=FALSE;
  347. goto CommonReturn;
  348. TRACE_ERROR(TraceErr);
  349. SET_ERROR(MemoryErr, E_OUTOFMEMORY);
  350. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  351. }
  352. //--------------------------------------------------------------------------
  353. //
  354. // FormatMessageStr
  355. //
  356. //--------------------------------------------------------------------------
  357. int ListView_InsertItemU_IDS(HWND hwndList,
  358. LV_ITEMW *plvItem,
  359. UINT idsString,
  360. LPWSTR pwszText)
  361. {
  362. WCHAR wszText[MAX_STRING_SIZE];
  363. if(pwszText)
  364. plvItem->pszText=pwszText;
  365. else
  366. {
  367. if(!LoadStringU(g_hmodThisDll, idsString, wszText, MAX_STRING_SIZE))
  368. return -1;
  369. plvItem->pszText=wszText;
  370. }
  371. return ListView_InsertItemU(hwndList, plvItem);
  372. }
  373. //*******************************************************************************
  374. // WinProc for the enrollment wizard
  375. //
  376. //*******************************************************************************
  377. //--------------------------------------------------------------------------------
  378. //
  379. // Inserts an entry into our confirmation dialog's list view.
  380. //
  381. //--------------------------------------------------------------------------------
  382. void ConfirmationListView_InsertItem(HWND hwndControl, LV_ITEMW *plvItem, UINT idsText, LPCWSTR pwszText)
  383. {
  384. plvItem->iSubItem=0;
  385. if (0 == idsText)
  386. {
  387. plvItem->pszText = L"";
  388. ListView_InsertItemU(hwndControl, plvItem);
  389. }
  390. else
  391. ListView_InsertItemU_IDS(hwndControl, plvItem, idsText, NULL);
  392. plvItem->iSubItem++;
  393. ListView_SetItemTextU(hwndControl, plvItem->iItem, plvItem->iSubItem, pwszText);
  394. plvItem->iItem++;
  395. }
  396. //-------------------------------------------------------------------------
  397. //populate the list box in the order of friendly name,
  398. //UserName, CA, Purpose, and CSP
  399. //-------------------------------------------------------------------------
  400. void DisplayConfirmation(HWND hwndControl,
  401. CERT_WIZARD_INFO *pCertWizardInfo)
  402. {
  403. WCHAR wszBuffer[MAX_TITLE_LENGTH];
  404. WCHAR wszBuffer2[MAX_TITLE_LENGTH];
  405. DWORD dwIndex=0;
  406. UINT ids=0;
  407. LPWSTR pwszCADisplayName = NULL;
  408. LV_ITEMW lvItem;
  409. CRYPTUI_WIZ_CERT_CA *pCertCA=NULL;
  410. //delete all the old items in the listView
  411. ListView_DeleteAllItems(hwndControl);
  412. //insert row by row
  413. memset(wszBuffer, 0, sizeof(wszBuffer));
  414. memset(&lvItem, 0, sizeof(LV_ITEMW));
  415. // set up the fields in the list view item struct that don't change from item to item
  416. lvItem.mask = LVIF_TEXT | LVIF_STATE ;
  417. lvItem.state = 0;
  418. lvItem.stateMask = 0;
  419. lvItem.iItem = 0;
  420. // Friendly Name (only shown for enroll)
  421. if (0 == (CRYPTUI_WIZ_CERT_RENEW & pCertWizardInfo->dwPurpose))
  422. {
  423. LPWSTR pwszFriendlyName = L"";
  424. if(pCertWizardInfo->pwszFriendlyName)
  425. {
  426. pwszFriendlyName = pCertWizardInfo->pwszFriendlyName;
  427. }
  428. else
  429. {
  430. if (LoadStringU(g_hmodThisDll, IDS_NONE, wszBuffer, ARRAYSIZE(wszBuffer)))
  431. pwszFriendlyName = &wszBuffer[0];
  432. }
  433. ConfirmationListView_InsertItem(hwndControl, &lvItem, IDS_FRIENDLY_NAME, pwszFriendlyName);
  434. }
  435. //Machine Name/SerivceName/ UserName
  436. if(pCertWizardInfo->pwszAccountName)
  437. {
  438. ConfirmationListView_InsertItem(hwndControl, &lvItem, IDS_USER_NAME, pCertWizardInfo->pwszAccountName);
  439. }
  440. //machine name
  441. if(pCertWizardInfo->pwszMachineName)
  442. {
  443. ConfirmationListView_InsertItem(hwndControl, &lvItem, IDS_COMPUTER_NAME, pCertWizardInfo->pwszMachineName);
  444. }
  445. //CA
  446. //check if we know exactly which CA to send the request;
  447. //or we are going through the loop
  448. if ((TRUE == pCertWizardInfo->fUIAdv) || (TRUE == pCertWizardInfo->fCAInput))
  449. {
  450. if(pCertWizardInfo->pwszCAName)
  451. {
  452. LPWSTR pwszCAName = NULL;
  453. if(pCertWizardInfo->pwszCADisplayName)
  454. pwszCAName = pCertWizardInfo->pwszCADisplayName;
  455. else if (CAUtilGetCADisplayName((pCertWizardInfo->fMachine) ? CA_FIND_LOCAL_SYSTEM:0, pCertWizardInfo->pwszCAName, &pwszCADisplayName))
  456. pwszCAName = pwszCADisplayName;
  457. else
  458. pwszCAName = pCertWizardInfo->pwszCAName;
  459. ConfirmationListView_InsertItem(hwndControl, &lvItem, IDS_CA, pwszCAName);
  460. }
  461. }
  462. //populate the OID name and certtype name (only shown for enroll)
  463. if (0 == (CRYPTUI_WIZ_CERT_RENEW & pCertWizardInfo->dwPurpose))
  464. {
  465. ids = IDS_PURPOSE;
  466. pCertCA=&(pCertWizardInfo->pCertCAInfo->rgCA[pCertWizardInfo->dwCAIndex]);
  467. for(dwIndex=0; dwIndex<pCertCA->dwOIDInfo; dwIndex++)
  468. {
  469. if(TRUE==((pCertCA->rgOIDInfo[dwIndex]).fSelected))
  470. {
  471. ConfirmationListView_InsertItem(hwndControl, &lvItem, ids, (pCertCA->rgOIDInfo[dwIndex]).pwszName);
  472. ids = 0;
  473. }
  474. }
  475. for(dwIndex=0; dwIndex<pCertCA->dwCertTypeInfo; dwIndex++)
  476. {
  477. if(TRUE==((pCertCA->rgCertTypeInfo[dwIndex]).fSelected))
  478. {
  479. ConfirmationListView_InsertItem(hwndControl, &lvItem, ids, (pCertCA->rgCertTypeInfo[dwIndex]).pwszCertTypeName);
  480. ids = 0;
  481. }
  482. }
  483. }
  484. if(pCertWizardInfo->pwszProvider)
  485. {
  486. ConfirmationListView_InsertItem(hwndControl, &lvItem, IDS_CSP, pCertWizardInfo->pwszProvider);
  487. }
  488. // Advanced options:
  489. if (TRUE == pCertWizardInfo->fUIAdv)
  490. {
  491. // Key creation options:
  492. if (pCertWizardInfo->fNewKey)
  493. {
  494. // Minimum key size:
  495. if (pCertWizardInfo->dwMinKeySize)
  496. {
  497. WCHAR * const rgParams[1] = { (WCHAR *)(ULONG_PTR) pCertWizardInfo->dwMinKeySize };
  498. if (FormatMessageU(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  499. L"%1!d!%0", 0, 0, wszBuffer, ARRAYSIZE(wszBuffer), (va_list *)rgParams))
  500. {
  501. ConfirmationListView_InsertItem(hwndControl, &lvItem, IDS_MIN_KEYSIZE, wszBuffer);
  502. }
  503. }
  504. // Is key exportable?
  505. ids = (0 != (CRYPT_EXPORTABLE & pCertWizardInfo->dwGenKeyFlags)) ? IDS_YES : IDS_NO;
  506. if (LoadStringU(g_hmodThisDll, ids, wszBuffer2, ARRAYSIZE(wszBuffer2)))
  507. {
  508. ConfirmationListView_InsertItem(hwndControl, &lvItem, IDS_KEY_EXPORTABLE, wszBuffer2);
  509. }
  510. // Is strong key protection enabled?
  511. ids = (0 != (CRYPT_USER_PROTECTED & pCertWizardInfo->dwGenKeyFlags)) ? IDS_YES : IDS_NO;
  512. if (LoadStringU(g_hmodThisDll, ids, wszBuffer, ARRAYSIZE(wszBuffer)))
  513. {
  514. ConfirmationListView_InsertItem(hwndControl, &lvItem, IDS_STRONG_PROTECTION, wszBuffer);
  515. }
  516. }
  517. }
  518. ListView_SetItemState(hwndControl, 0, LVIS_SELECTED, LVIS_SELECTED);
  519. //autosize the columns
  520. ListView_SetColumnWidth(hwndControl, 0, LVSCW_AUTOSIZE);
  521. ListView_SetColumnWidth(hwndControl, 1, LVSCW_AUTOSIZE);
  522. // CommonReturn:
  523. if (NULL != pwszCADisplayName)
  524. WizardFree(pwszCADisplayName);
  525. return;
  526. }
  527. BOOL GetSelectedCertTypeInfo(IN CERT_WIZARD_INFO *pCertWizardInfo,
  528. OUT ENROLL_CERT_TYPE_INFO **ppCertTypeInfo)
  529. {
  530. DWORD dwIndex;
  531. PCRYPTUI_WIZ_CERT_CA pCertCA;
  532. if (pCertWizardInfo == NULL)
  533. return FALSE;
  534. pCertCA=&(pCertWizardInfo->pCertCAInfo->rgCA[pCertWizardInfo->dwCAIndex]);
  535. for(dwIndex=0; dwIndex<pCertCA->dwCertTypeInfo; dwIndex++)
  536. {
  537. if((pCertCA->rgCertTypeInfo)[dwIndex].fSelected)
  538. {
  539. *ppCertTypeInfo = &((pCertCA->rgCertTypeInfo)[dwIndex]);
  540. return TRUE;
  541. }
  542. }
  543. return FALSE;
  544. }
  545. //-----------------------------------------------------------------------
  546. //Initialize the CSP list
  547. //-----------------------------------------------------------------------
  548. BOOL InitCSPList(HWND hwndList,
  549. CERT_WIZARD_INFO *pCertWizardInfo)
  550. {
  551. DWORD dwMinSize;
  552. DWORD dwMaxSize;
  553. DWORD dwInc;
  554. LV_ITEMW lvItem;
  555. CRYPTUI_WIZ_CERT_CA *pCertCA=NULL;
  556. ENROLL_CERT_TYPE_INFO *pCertTypeInfo=NULL;
  557. int iInsertedIndex=0;
  558. if(!hwndList || !pCertWizardInfo)
  559. return FALSE;
  560. if(!(pCertWizardInfo->pCertCAInfo) || !(pCertWizardInfo->pwszCALocation) ||
  561. !(pCertWizardInfo->pwszCAName))
  562. return FALSE;
  563. //delete all the old items in the listView
  564. ListView_DeleteAllItems(hwndList);
  565. //populate the list
  566. memset(&lvItem, 0, sizeof(LV_ITEMW));
  567. lvItem.mask=LVIF_TEXT | LVIF_STATE | LVIF_PARAM;
  568. pCertCA=&(pCertWizardInfo->pCertCAInfo->rgCA[pCertWizardInfo->dwCAIndex]);
  569. pCertTypeInfo = NULL;
  570. GetSelectedCertTypeInfo(pCertWizardInfo, &pCertTypeInfo);
  571. // Populate the CSP list with the intersection of:
  572. // 1) The available CSPs on the local machine
  573. // and 2) The CSPs specified on the template.
  574. //
  575. // If no template information is available, or the template does not specify
  576. // a CSP, enumerate all CSPs.
  577. //
  578. for(DWORD dwLocalCSPIndex = 0; dwLocalCSPIndex < pCertWizardInfo->dwCSPCount; dwLocalCSPIndex++)
  579. {
  580. BOOL fUseCSP = FALSE;
  581. if (NULL == pCertTypeInfo)
  582. {
  583. fUseCSP = TRUE;
  584. }
  585. else
  586. {
  587. for (DWORD dwTemplateCSPIndex = 0; dwTemplateCSPIndex < pCertTypeInfo->dwCSPCount; dwTemplateCSPIndex++)
  588. {
  589. if(dwLocalCSPIndex == pCertTypeInfo->rgdwCSP[dwTemplateCSPIndex])
  590. {
  591. // The CSP is specified in the template, so we can use it,
  592. // if it supports an algorithm / key size that matches
  593. // the template information.
  594. if (GetValidKeySizes
  595. ((pCertWizardInfo->rgwszProvider)[dwLocalCSPIndex],
  596. (pCertWizardInfo->rgdwProviderType)[dwLocalCSPIndex],
  597. pCertTypeInfo->dwKeySpec,
  598. &dwMinSize,
  599. &dwMaxSize,
  600. &dwInc))
  601. {
  602. fUseCSP = dwMaxSize >= pCertTypeInfo->dwMinKeySize;
  603. }
  604. break;
  605. }
  606. }
  607. }
  608. if (fUseCSP)
  609. {
  610. lvItem.iItem = dwLocalCSPIndex;
  611. lvItem.pszText = (pCertWizardInfo->rgwszProvider)[dwLocalCSPIndex];
  612. lvItem.cchTextMax = sizeof(WCHAR)*(1+wcslen((pCertWizardInfo->rgwszProvider)[dwLocalCSPIndex]));
  613. lvItem.lParam = (LPARAM)dwLocalCSPIndex;
  614. //insert the item,
  615. iInsertedIndex = ListView_InsertItemU(hwndList, &lvItem);
  616. // Highlight a CSP if it is already specified through the advanced
  617. // options. If not, highlight the first CSP on the template.
  618. //
  619. BOOL fHighlightCSP = FALSE;
  620. if (pCertWizardInfo->pwszProvider)
  621. {
  622. fHighlightCSP = 0 == _wcsicmp(pCertWizardInfo->pwszProvider, lvItem.pszText);
  623. }
  624. else
  625. {
  626. if (NULL != pCertTypeInfo && pCertTypeInfo->dwCSPCount > 0)
  627. {
  628. //we highlight the 1st one of the intersection if there is any
  629. fHighlightCSP = dwLocalCSPIndex == pCertTypeInfo->rgdwCSP[0];
  630. }
  631. else
  632. {
  633. // We don't highlight a CSP in this case.
  634. }
  635. }
  636. if (fHighlightCSP)
  637. {
  638. ListView_SetItemState
  639. (hwndList,
  640. iInsertedIndex,
  641. LVIS_SELECTED,
  642. LVIS_SELECTED);
  643. ListView_EnsureVisible
  644. (hwndList,
  645. iInsertedIndex,
  646. FALSE);
  647. }
  648. }
  649. }
  650. //make the column autosize
  651. ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE);
  652. return TRUE;
  653. }
  654. BOOL CSPListIndexToCertWizardInfoIndex(IN HWND hwnd,
  655. IN int nCSPIndex,
  656. OUT DWORD *pdwWizardIndex)
  657. {
  658. LVITEM lvItem;
  659. if (hwnd == NULL || nCSPIndex < 0)
  660. return FALSE;
  661. memset(&lvItem, 0, sizeof(LV_ITEM));
  662. lvItem.mask = LVIF_PARAM;
  663. lvItem.iItem = nCSPIndex;
  664. if(!ListView_GetItem(hwnd, &lvItem))
  665. return FALSE;
  666. *pdwWizardIndex = (DWORD)lvItem.lParam;
  667. return TRUE;
  668. }
  669. BOOL InitKeySizesList(IN HWND hWnd, // Required: The combo box to initialize.
  670. IN DWORD dwCTMinKeySize, // Required: The min key size specified on the template
  671. IN LPWSTR lpwszProvider, // Required: The CSP.
  672. IN DWORD dwProvType, // Required: The provider type.
  673. IN DWORD dwKeySpec // Required: Either AT_SIGNATURE or AT_KEYEXCHANGE.
  674. )
  675. {
  676. static const DWORD dwSmallValidKeySizes[] = { 40, 56, 64, 128, 256, 384 };
  677. static const DWORD dwLargeValidKeySizes[] = { 512, 1024, 2048, 4096, 8192, 16384 };
  678. static const DWORD dwAllValidKeySizes[] = { 40, 56, 64, 128, 256, 384, 512, 1024, 2048, 4096, 8192, 16384 };
  679. static const DWORD dwSmLen = sizeof(dwSmallValidKeySizes) / sizeof(DWORD);
  680. static const DWORD dwLgLen = sizeof(dwLargeValidKeySizes) / sizeof(DWORD);
  681. static const DWORD dwAllLen = sizeof(dwAllValidKeySizes) / sizeof(DWORD);
  682. static const DWORD MAX_KEYSIZE_STRING_SIZE = sizeof(WCHAR) * 8;
  683. static WCHAR ppwszStrings[dwAllLen][MAX_KEYSIZE_STRING_SIZE];
  684. BOOL fIsLargeKey = FALSE;
  685. BOOL fIsSmallKey = FALSE;
  686. BOOL fResult = FALSE;
  687. DWORD dwMinSize;
  688. DWORD dwMaxSize;
  689. DWORD dwInc;
  690. const DWORD *pdwValidKeySizes;
  691. DWORD dwValidKeySizesLen;
  692. // Temporaries:
  693. DWORD dwCurrent;
  694. DWORD dwIndex;
  695. // Validate inputs:
  696. if (hWnd == NULL || lpwszProvider == NULL)
  697. {
  698. SetLastError(ERROR_INVALID_PARAMETER);
  699. goto Error;
  700. }
  701. // First, delete all items present in the list view.
  702. // (This always succeeds).
  703. SendMessage(hWnd, CB_RESETCONTENT, (WPARAM)0, (LPARAM)0);
  704. if (!GetValidKeySizes
  705. (lpwszProvider,
  706. dwProvType,
  707. dwKeySpec,
  708. &dwMinSize,
  709. &dwMaxSize,
  710. &dwInc))
  711. goto Error;
  712. if (dwCTMinKeySize > dwMinSize) {
  713. dwMinSize = dwCTMinKeySize;
  714. }
  715. fIsLargeKey = dwMinSize >= 512;
  716. fIsSmallKey = dwMaxSize < 512;
  717. if (fIsLargeKey)
  718. {
  719. pdwValidKeySizes = &dwLargeValidKeySizes[0];
  720. dwValidKeySizesLen = dwLgLen;
  721. }
  722. else if (fIsSmallKey)
  723. {
  724. pdwValidKeySizes = &dwSmallValidKeySizes[0];
  725. dwValidKeySizesLen = dwSmLen;
  726. }
  727. else
  728. {
  729. pdwValidKeySizes = &dwAllValidKeySizes[0];
  730. dwValidKeySizesLen = dwAllLen;
  731. }
  732. for (dwCurrent = 0, dwIndex = 0; dwCurrent < dwValidKeySizesLen; dwCurrent++)
  733. {
  734. if (pdwValidKeySizes[dwCurrent] > dwMaxSize)
  735. break;
  736. if (pdwValidKeySizes[dwCurrent] < dwMinSize)
  737. continue;
  738. if ((dwInc == 0) || (0 == (pdwValidKeySizes[dwCurrent] % dwInc)))
  739. {
  740. if (CB_ERR == SendMessageW
  741. (hWnd,
  742. CB_ADDSTRING,
  743. 0,
  744. (LPARAM)_ltow(pdwValidKeySizes[dwCurrent], &ppwszStrings[dwIndex][0], 10)))
  745. goto Error;
  746. if (CB_ERR == SendMessage
  747. (hWnd,
  748. CB_SETITEMDATA,
  749. (WPARAM)dwIndex,
  750. (LPARAM)pdwValidKeySizes[dwCurrent]))
  751. goto Error;
  752. // Default to 1024-bit keys if we can.
  753. if (dwIndex == 0 || pdwValidKeySizes[dwCurrent] == 1024)
  754. SendMessage(hWnd, CB_SETCURSEL, dwIndex, (LPARAM)0);
  755. dwIndex++;
  756. }
  757. }
  758. fResult = TRUE;
  759. CommonReturn:
  760. return fResult;
  761. Error:
  762. fResult = FALSE;
  763. goto CommonReturn;
  764. }
  765. //-----------------------------------------------------------------------
  766. //ExistInListView:
  767. //
  768. // Check to see if the cert type is alreayd in the list view
  769. // based on its display name
  770. //-----------------------------------------------------------------------
  771. BOOL ExistInListView(HWND hwndList, LPWSTR pwszDisplayName)
  772. {
  773. BOOL fExist=FALSE;
  774. LVFINDINFOW lvfi;
  775. if((NULL == hwndList) || (NULL == pwszDisplayName))
  776. return FALSE;
  777. memset(&lvfi, 0, sizeof(LVFINDINFOW));
  778. lvfi.flags=LVFI_STRING;
  779. lvfi.psz=pwszDisplayName;
  780. if(-1 == SendMessageW(hwndList,
  781. LVM_FINDITEMW,
  782. (WPARAM)-1,
  783. (LPARAM)(&lvfi)))
  784. fExist=FALSE;
  785. else
  786. fExist=TRUE;
  787. return fExist;
  788. }
  789. //--------------------------------------------------------------------------------
  790. // IsKeyProtected()
  791. //
  792. // Determines whether or not a key has strong key protection enabled.
  793. // Should be used only with user keysets.
  794. //
  795. //--------------------------------------------------------------------------------
  796. HRESULT IsKeyProtected(IN LPWSTR pwszContainerName,
  797. IN LPWSTR pwszProviderName,
  798. IN DWORD dwProvType,
  799. OUT BOOL *pfIsProtected)
  800. {
  801. DWORD cbData;
  802. DWORD dwImpType;
  803. HCRYPTPROV hCryptProv = NULL;
  804. HRESULT hr;
  805. if (NULL == pwszContainerName || NULL == pwszProviderName || NULL == pfIsProtected)
  806. goto InvalidArgError;
  807. *pfIsProtected = FALSE;
  808. // Get the provider context with no key access.
  809. if (!CryptAcquireContextW(&hCryptProv, NULL, pwszProviderName, dwProvType, CRYPT_VERIFYCONTEXT))
  810. goto CryptAcquireContextError;
  811. cbData = sizeof(dwImpType);
  812. if (!CryptGetProvParam(hCryptProv, PP_IMPTYPE, (PBYTE) &dwImpType, &cbData, 0))
  813. goto CryptGetProvParamError;
  814. // Assume hardware key is protected.
  815. if (dwImpType & CRYPT_IMPL_HARDWARE) {
  816. *pfIsProtected = TRUE;
  817. } else {
  818. // Reacquire context with silent flag.
  819. CryptReleaseContext(hCryptProv, 0);
  820. hCryptProv = NULL;
  821. if (!CryptAcquireContextW(&hCryptProv, pwszContainerName, pwszProviderName, dwProvType, CRYPT_SILENT)) {
  822. // CryptAcquireContextW with silent flag, assume user protected
  823. *pfIsProtected = TRUE;
  824. }
  825. }
  826. hr = S_OK;
  827. ErrorReturn:
  828. if (hCryptProv)
  829. CryptReleaseContext(hCryptProv, 0);
  830. return hr;
  831. SET_HRESULT(CryptAcquireContextError, HRESULT_FROM_WIN32(GetLastError()));
  832. SET_HRESULT(CryptGetProvParamError, HRESULT_FROM_WIN32(GetLastError()));
  833. SET_HRESULT(InvalidArgError, E_INVALIDARG);
  834. }
  835. //-----------------------------------------------------------------------
  836. //Initialize the usage OID/CertType list
  837. //-----------------------------------------------------------------------
  838. BOOL InitCertTypeList(HWND hwndList,
  839. CERT_WIZARD_INFO *pCertWizardInfo)
  840. {
  841. BOOL fIsKeyProtected;
  842. DWORD dwCAIndex=0;
  843. DWORD dwCTIndex=0;
  844. HRESULT hr;
  845. LV_ITEMW lvItem;
  846. BOOL fSelected=FALSE;
  847. int iInsertedIndex=0;
  848. DWORD dwValidCTCount=0;
  849. ENROLL_CERT_TYPE_INFO *pCertTypeInfo=NULL;
  850. if(!hwndList || !pCertWizardInfo)
  851. return FALSE;
  852. if(!(pCertWizardInfo->pCertCAInfo) || !(pCertWizardInfo->pwszCALocation) ||
  853. !(pCertWizardInfo->pwszCAName))
  854. return FALSE;
  855. //delete all the old items in the listView
  856. ListView_DeleteAllItems(hwndList);
  857. //populate the list
  858. memset(&lvItem, 0, sizeof(LV_ITEMW));
  859. lvItem.mask=LVIF_TEXT | LVIF_STATE | LVIF_PARAM;
  860. // if we're doing an enroll with same key, see whether it has strong key protection:
  861. if (!pCertWizardInfo->fNewKey) {
  862. hr = IsKeyProtected((LPWSTR)pCertWizardInfo->pwszKeyContainer,
  863. (LPWSTR)pCertWizardInfo->pwszProvider,
  864. pCertWizardInfo->dwProviderType,
  865. &fIsKeyProtected);
  866. if (FAILED(hr)) {
  867. // assume no key protection
  868. fIsKeyProtected = FALSE;
  869. }
  870. }
  871. //populate the certType name
  872. //we search for each CA
  873. dwValidCTCount=0;
  874. //we start from the 1st CA
  875. for(dwCAIndex=1; dwCAIndex<pCertWizardInfo->pCertCAInfo->dwCA; dwCAIndex++)
  876. {
  877. for(dwCTIndex=0; dwCTIndex <(pCertWizardInfo->pCertCAInfo->rgCA)[dwCAIndex].dwCertTypeInfo; dwCTIndex++)
  878. {
  879. pCertTypeInfo=&((pCertWizardInfo->pCertCAInfo->rgCA)[dwCAIndex].rgCertTypeInfo[dwCTIndex]);
  880. // if the template specifies strong key protection but our key doesn't have it, filter the template out
  881. if (!pCertWizardInfo->fNewKey && !fIsKeyProtected && (CT_FLAG_STRONG_KEY_PROTECTION_REQUIRED & pCertTypeInfo->dwPrivateKeyFlags))
  882. continue;
  883. //make sure that we do not have duplicated entries
  884. if(!ExistInListView(hwndList, pCertTypeInfo->pwszCertTypeName))
  885. {
  886. lvItem.iItem=dwValidCTCount;
  887. lvItem.pszText=pCertTypeInfo->pwszCertTypeName;
  888. lvItem.cchTextMax=sizeof(WCHAR)* (1+wcslen(pCertTypeInfo->pwszCertTypeName));
  889. lvItem.lParam=(LPARAM)pCertTypeInfo->pwszDNName;
  890. //insert the item,
  891. iInsertedIndex=ListView_InsertItemU(hwndList, &lvItem);
  892. //set the item to be selected
  893. if(pCertTypeInfo->fSelected)
  894. {
  895. ListView_SetItemState(
  896. hwndList,
  897. iInsertedIndex,
  898. LVIS_SELECTED,
  899. LVIS_SELECTED);
  900. fSelected=TRUE;
  901. }
  902. dwValidCTCount++;
  903. }
  904. }
  905. }
  906. //select the 1st item is nothing has been selected
  907. if(FALSE == fSelected)
  908. ListView_SetItemState(
  909. hwndList,
  910. 0,
  911. LVIS_SELECTED,
  912. LVIS_SELECTED);
  913. //make the column autosize
  914. ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE);
  915. return TRUE;
  916. }
  917. //-----------------------------------------------------------------------
  918. // MarkSelectedCertType:
  919. //
  920. // Based on the user's certificate type selection, we mark the selected
  921. // certType. Also, check to see based on the selected certificate type, if we
  922. // have to show the CSP page. That is, use did not specify a CSP
  923. // via the API, and the certificate type has no default CSP list.
  924. //-----------------------------------------------------------------------
  925. void MarkSelectedCertType(CERT_WIZARD_INFO *pCertWizardInfo,
  926. LPWSTR pwszDNName)
  927. {
  928. DWORD dwCAIndex=0;
  929. DWORD dwCTIndex=0;
  930. PCRYPTUI_WIZ_CERT_CA pCertCA=NULL;
  931. PCRYPTUI_WIZ_CERT_CA_INFO pCertCAInfo=NULL;
  932. pCertCAInfo=pCertWizardInfo->pCertCAInfo;
  933. if(NULL == pCertCAInfo)
  934. return;
  935. //we start from the 1st CA
  936. for(dwCAIndex=1; dwCAIndex<pCertCAInfo->dwCA; dwCAIndex++)
  937. {
  938. pCertCA=&(pCertCAInfo->rgCA[dwCAIndex]);
  939. for(dwCTIndex=0; dwCTIndex < pCertCA->dwCertTypeInfo; dwCTIndex++)
  940. {
  941. if(0 == wcscmp(pwszDNName, pCertCA->rgCertTypeInfo[dwCTIndex].pwszDNName))
  942. {
  943. pCertCA->rgCertTypeInfo[dwCTIndex].fSelected=TRUE;
  944. if((NULL == pCertWizardInfo->pwszProvider)&&
  945. (0==pCertCA->rgCertTypeInfo[dwCTIndex].dwCSPCount)
  946. )
  947. pCertWizardInfo->fUICSP=TRUE;
  948. if (0 != (CT_FLAG_EXPORTABLE_KEY & pCertCA->rgCertTypeInfo[dwCTIndex].dwPrivateKeyFlags))
  949. {
  950. pCertWizardInfo->dwGenKeyFlags |= CRYPT_EXPORTABLE;
  951. }
  952. else
  953. {
  954. pCertWizardInfo->dwGenKeyFlags &= ~CRYPT_EXPORTABLE;
  955. }
  956. if (0 != (CT_FLAG_STRONG_KEY_PROTECTION_REQUIRED & pCertCA->rgCertTypeInfo[dwCTIndex].dwPrivateKeyFlags))
  957. {
  958. pCertWizardInfo->dwGenKeyFlags |= CRYPT_USER_PROTECTED;
  959. }
  960. else
  961. {
  962. pCertWizardInfo->dwGenKeyFlags &= ~CRYPT_USER_PROTECTED;
  963. }
  964. }
  965. else
  966. pCertCA->rgCertTypeInfo[dwCTIndex].fSelected=FALSE;
  967. }
  968. }
  969. }
  970. //-----------------------------------------------------------------------
  971. // ResetDefaultCA:
  972. //
  973. // Based on the selected certificate type, we reset the default
  974. // value for the Ceritification Authority
  975. //-----------------------------------------------------------------------
  976. void ResetDefaultCA(CERT_WIZARD_INFO *pCertWizardInfo)
  977. {
  978. LPWSTR pwszOldCALocation=NULL;
  979. LPWSTR pwszOldCAName=NULL;
  980. DWORD dwCAIndex=0;
  981. PCRYPTUI_WIZ_CERT_CA pCertCA=NULL;
  982. PCRYPTUI_WIZ_CERT_CA_INFO pCertCAInfo=NULL;
  983. BOOL fFound=FALSE;
  984. pCertCAInfo=pCertWizardInfo->pCertCAInfo;
  985. if(NULL == pCertCAInfo)
  986. return;
  987. //if user has specified a CA, then this CA has priority other the rest
  988. if(pCertWizardInfo->fCAInput)
  989. {
  990. dwCAIndex=pCertWizardInfo->dwOrgCA;
  991. pCertCA=&(pCertCAInfo->rgCA[dwCAIndex]);
  992. fFound=CASupportSpecifiedCertType(pCertCA);
  993. }
  994. //we do a generic search if the priority CA does not satisfy the requirements
  995. if(FALSE == fFound)
  996. {
  997. //we start from the 1st CA
  998. for(dwCAIndex=1; dwCAIndex<pCertCAInfo->dwCA; dwCAIndex++)
  999. {
  1000. pCertCA=&(pCertCAInfo->rgCA[dwCAIndex]);
  1001. if(TRUE == (fFound=CASupportSpecifiedCertType(pCertCA)))
  1002. break;
  1003. }
  1004. }
  1005. if(FALSE == fFound)
  1006. return;
  1007. //copy the old data
  1008. pwszOldCALocation=pCertWizardInfo->pwszCALocation;
  1009. pwszOldCAName=pCertWizardInfo->pwszCAName;
  1010. pCertWizardInfo->pwszCALocation=WizardAllocAndCopyWStr(pCertCAInfo->rgCA[dwCAIndex].pwszCALocation);
  1011. pCertWizardInfo->pwszCAName=WizardAllocAndCopyWStr(pCertCAInfo->rgCA[dwCAIndex].pwszCAName);
  1012. if(NULL == pCertWizardInfo->pwszCALocation ||
  1013. NULL == pCertWizardInfo->pwszCAName)
  1014. {
  1015. //free the memory
  1016. if(pCertWizardInfo->pwszCALocation)
  1017. WizardFree(pCertWizardInfo->pwszCALocation);
  1018. if(pCertWizardInfo->pwszCAName)
  1019. WizardFree(pCertWizardInfo->pwszCAName);
  1020. pCertWizardInfo->pwszCALocation=pwszOldCALocation;
  1021. pCertWizardInfo->pwszCAName=pwszOldCAName;
  1022. return;
  1023. }
  1024. pCertWizardInfo->dwCAIndex=dwCAIndex;
  1025. if(pwszOldCALocation)
  1026. WizardFree(pwszOldCALocation);
  1027. if(pwszOldCAName)
  1028. WizardFree(pwszOldCAName);
  1029. }
  1030. //-----------------------------------------------------------------------
  1031. //enable the window if small card if selected
  1032. //-----------------------------------------------------------------------
  1033. void EnableIfSmartCard(HWND hwndControl, HWND hwndChkBox)
  1034. {
  1035. LPWSTR pwszText=NULL;
  1036. WCHAR wszCSPName[MAX_STRING_SIZE];
  1037. DWORD dwChar=0;
  1038. int iItem=0;
  1039. //get the length of the selected item
  1040. iItem=(int)SendMessage(hwndControl, LB_GETCURSEL, 0, 0);
  1041. dwChar=(DWORD)SendMessage(hwndControl,
  1042. LB_GETTEXTLEN,
  1043. iItem,
  1044. 0);
  1045. //allocate memory
  1046. if(NULL==(pwszText=(LPWSTR)WizardAlloc(sizeof(WCHAR)*(1+dwChar))))
  1047. return;
  1048. //get the selected CSP name
  1049. if(LB_ERR==Send_LB_GETTEXT(hwndControl,
  1050. iItem,
  1051. (LPARAM)pwszText))
  1052. goto CLEANUP;
  1053. //get the smart card name
  1054. if(!LoadStringU(g_hmodThisDll, IDS_SMART_CARD, wszCSPName, MAX_STRING_SIZE))
  1055. goto CLEANUP;
  1056. if(0==wcscmp(wszCSPName, pwszText))
  1057. //enable the box
  1058. EnableWindow(hwndChkBox, TRUE);
  1059. else
  1060. //gray out the box
  1061. EnableWindow(hwndChkBox, FALSE);
  1062. CLEANUP:
  1063. if(pwszText)
  1064. WizardFree(pwszText);
  1065. }
  1066. //-----------------------------------------------------------------------
  1067. //
  1068. //The winProc for each of the enrollment wizard page
  1069. //
  1070. //-----------------------------------------------------------------------
  1071. //-----------------------------------------------------------------------
  1072. //Welcome
  1073. //-----------------------------------------------------------------------
  1074. INT_PTR APIENTRY Enroll_Welcome(HWND hwndDlg, UINT msg, WPARAM /*wParam*/, LPARAM lParam)
  1075. {
  1076. CERT_WIZARD_INFO *pCertWizardInfo=NULL;
  1077. PROPSHEETPAGE *pPropSheet=NULL;
  1078. switch (msg)
  1079. {
  1080. case WM_INITDIALOG:
  1081. //set the wizard information so that it can be shared
  1082. pPropSheet = (PROPSHEETPAGE *) lParam;
  1083. pCertWizardInfo = (CERT_WIZARD_INFO *) (pPropSheet->lParam);
  1084. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertWizardInfo);
  1085. SetControlFont(pCertWizardInfo->hBigBold, hwndDlg,IDC_WIZARD_STATIC_BIG_BOLD1);
  1086. // SetControlFont(pCertWizardInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
  1087. // SetControlFont(pCertWizardInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD2);
  1088. break;
  1089. case WM_NOTIFY:
  1090. switch (((NMHDR FAR *) lParam)->code)
  1091. {
  1092. case PSN_KILLACTIVE:
  1093. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  1094. return TRUE;
  1095. break;
  1096. case PSN_RESET:
  1097. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  1098. break;
  1099. case PSN_SETACTIVE:
  1100. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
  1101. break;
  1102. case PSN_WIZBACK:
  1103. break;
  1104. case PSN_WIZNEXT:
  1105. break;
  1106. default:
  1107. return FALSE;
  1108. }
  1109. break;
  1110. default:
  1111. return FALSE;
  1112. }
  1113. return TRUE;
  1114. }
  1115. //-----------------------------------------------------------------------
  1116. //Purpose
  1117. //-----------------------------------------------------------------------
  1118. INT_PTR APIENTRY Enroll_Purpose(HWND hwndDlg, UINT msg, WPARAM /*wParam*/, LPARAM lParam)
  1119. {
  1120. CERT_WIZARD_INFO *pCertWizardInfo=NULL;
  1121. PROPSHEETPAGE *pPropSheet=NULL;
  1122. HWND hwndControl=NULL;
  1123. DWORD dwIndex=0;
  1124. LV_COLUMNW lvC;
  1125. LV_ITEM lvItem;
  1126. NM_LISTVIEW FAR * pnmv=NULL;
  1127. switch (msg)
  1128. {
  1129. case WM_INITDIALOG:
  1130. //set the wizard information so that it can be shared
  1131. pPropSheet = (PROPSHEETPAGE *) lParam;
  1132. pCertWizardInfo = (CERT_WIZARD_INFO *) (pPropSheet->lParam);
  1133. //make sure pCertWizardInfo is a valid pointer
  1134. if(NULL==pCertWizardInfo)
  1135. break;
  1136. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertWizardInfo);
  1137. SetControlFont(pCertWizardInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
  1138. //by default, we do not use the advanced options
  1139. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK1), BM_SETCHECK, 0, 0);
  1140. if(NULL!=(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
  1141. {
  1142. //insert a column into the list view
  1143. memset(&lvC, 0, sizeof(LV_COLUMNW));
  1144. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  1145. lvC.fmt = LVCFMT_LEFT; // Left-align the column.
  1146. lvC.cx = 20; //(dwMaxSize+2)*7; // Width of the column, in pixels.
  1147. lvC.pszText = L""; // The text for the column.
  1148. lvC.iSubItem=0;
  1149. if (ListView_InsertColumnU(hwndControl, 0, &lvC) == -1)
  1150. break;
  1151. //initizialize the cert type
  1152. InitCertTypeList(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1),
  1153. pCertWizardInfo);
  1154. }
  1155. break;
  1156. case WM_COMMAND:
  1157. break;
  1158. case WM_NOTIFY:
  1159. switch (((NMHDR FAR *) lParam)->code)
  1160. {
  1161. //the item has been selected
  1162. case LVN_ITEMCHANGED:
  1163. //get the window handle of the purpose list view
  1164. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
  1165. break;
  1166. if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  1167. break;
  1168. pnmv = (LPNMLISTVIEW) lParam;
  1169. if(NULL==pnmv)
  1170. break;
  1171. //we try not to let user de-select cert template
  1172. if((pnmv->uOldState & LVIS_SELECTED) && (0 == (pnmv->uNewState & LVIS_SELECTED)))
  1173. {
  1174. //we should have something selected
  1175. if(-1 == ListView_GetNextItem(
  1176. hwndControl,
  1177. -1,
  1178. LVNI_SELECTED
  1179. ))
  1180. {
  1181. //we should re-select the original item
  1182. ListView_SetItemState(
  1183. hwndControl,
  1184. pnmv->iItem,
  1185. LVIS_SELECTED,
  1186. LVIS_SELECTED);
  1187. pCertWizardInfo->iOrgCertType=pnmv->iItem;
  1188. }
  1189. }
  1190. //if something is selected, we disable all other selection
  1191. if(pnmv->uNewState & LVIS_SELECTED)
  1192. {
  1193. if(pnmv->iItem != pCertWizardInfo->iOrgCertType && -1 != pCertWizardInfo->iOrgCertType)
  1194. {
  1195. //we should de-select the original item
  1196. ListView_SetItemState(
  1197. hwndControl,
  1198. pCertWizardInfo->iOrgCertType,
  1199. 0,
  1200. LVIS_SELECTED);
  1201. pCertWizardInfo->iOrgCertType=-1;
  1202. }
  1203. }
  1204. break;
  1205. case PSN_KILLACTIVE:
  1206. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  1207. return TRUE;
  1208. break;
  1209. case PSN_RESET:
  1210. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  1211. break;
  1212. case PSN_SETACTIVE:
  1213. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
  1214. if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  1215. break;
  1216. //if the adv selection is made, it has to stay selected
  1217. if(pCertWizardInfo->fUIAdv)
  1218. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK1), FALSE);
  1219. break;
  1220. case PSN_WIZBACK:
  1221. break;
  1222. case PSN_WIZNEXT:
  1223. if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  1224. break;
  1225. //get the window handle of the purpose list view
  1226. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
  1227. break;
  1228. //now, mark the one that is selected
  1229. if(-1 != (dwIndex= ListView_GetNextItem(
  1230. hwndControl,
  1231. -1,
  1232. LVNI_SELECTED
  1233. )))
  1234. {
  1235. //get the selected certificate
  1236. memset(&lvItem, 0, sizeof(LV_ITEM));
  1237. lvItem.mask=LVIF_PARAM;
  1238. lvItem.iItem=(int)dwIndex;
  1239. if(ListView_GetItem(hwndControl,
  1240. &lvItem))
  1241. {
  1242. pCertWizardInfo->fCertTypeChanged=FALSE;
  1243. if(NULL == pCertWizardInfo->pwszSelectedCertTypeDN)
  1244. pCertWizardInfo->fCertTypeChanged=TRUE;
  1245. else
  1246. {
  1247. if(0 != wcscmp(pCertWizardInfo->pwszSelectedCertTypeDN,
  1248. (LPWSTR)lvItem.lParam))
  1249. pCertWizardInfo->fCertTypeChanged=TRUE;
  1250. }
  1251. if(pCertWizardInfo->fCertTypeChanged)
  1252. {
  1253. pCertWizardInfo->pwszSelectedCertTypeDN=(LPWSTR)(lvItem.lParam);
  1254. //we need to reset the CSP
  1255. if(FALSE == pCertWizardInfo->fKnownCSP)
  1256. {
  1257. pCertWizardInfo->pwszProvider=NULL;
  1258. pCertWizardInfo->dwProviderType=0;
  1259. }
  1260. else
  1261. {
  1262. //we convert to the original selected CSP information
  1263. pCertWizardInfo->dwProviderType=pCertWizardInfo->dwOrgCSPType;
  1264. pCertWizardInfo->pwszProvider=pCertWizardInfo->pwszOrgCSPName;
  1265. }
  1266. pCertWizardInfo->fUICSP=FALSE;
  1267. //mark the selected cert type and mark the rest as un-selected
  1268. MarkSelectedCertType(pCertWizardInfo,
  1269. (LPWSTR)lvItem.lParam);
  1270. //we need to reset the default CA information based on the new CertType
  1271. ResetDefaultCA(pCertWizardInfo);
  1272. }
  1273. }
  1274. else
  1275. {
  1276. I_MessageBox(hwndDlg, IDS_NO_SELECTED_PURPOSE,
  1277. pCertWizardInfo->idsConfirmTitle,
  1278. pCertWizardInfo->pwszConfirmationTitle,
  1279. MB_ICONEXCLAMATION|MB_OK|MB_APPLMODAL);
  1280. //make the purpose page stay
  1281. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  1282. break;
  1283. }
  1284. }
  1285. else
  1286. {
  1287. I_MessageBox(hwndDlg, IDS_NO_SELECTED_PURPOSE,
  1288. pCertWizardInfo->idsConfirmTitle,
  1289. pCertWizardInfo->pwszConfirmationTitle,
  1290. MB_ICONEXCLAMATION|MB_OK|MB_APPLMODAL);
  1291. //make the purpose page stay
  1292. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  1293. break;
  1294. }
  1295. //check for the advanced options
  1296. if(TRUE==SendDlgItemMessage(hwndDlg,IDC_WIZARD_CHECK1, BM_GETCHECK, 0, 0))
  1297. pCertWizardInfo->fUIAdv=TRUE;
  1298. else
  1299. pCertWizardInfo->fUIAdv=FALSE;
  1300. //skip to the correct page based on the advanced options and CSP requirement
  1301. if(FALSE == pCertWizardInfo->fUIAdv)
  1302. {
  1303. if(TRUE == pCertWizardInfo->fUICSP)
  1304. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_CSP_SERVICE_PROVIDER);
  1305. else
  1306. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_NAME_DESCRIPTION);
  1307. }
  1308. else
  1309. {
  1310. if(FALSE == pCertWizardInfo->fNewKey)
  1311. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_CERTIFICATE_AUTHORITY);
  1312. }
  1313. break;
  1314. default:
  1315. return FALSE;
  1316. }
  1317. break;
  1318. default:
  1319. return FALSE;
  1320. }
  1321. return TRUE;
  1322. }
  1323. //-----------------------------------------------------------------------
  1324. //CSP
  1325. //-----------------------------------------------------------------------
  1326. INT_PTR APIENTRY Enroll_CSP(HWND hwndDlg, UINT msg, WPARAM /*wParam*/, LPARAM lParam)
  1327. {
  1328. CERT_WIZARD_INFO *pCertWizardInfo=NULL;
  1329. ENROLL_CERT_TYPE_INFO *pCertTypeInfo=NULL;
  1330. PROPSHEETPAGE *pPropSheet=NULL;
  1331. DWORD dwMinKeySize=0;
  1332. DWORD dwIndex=0;
  1333. int nSelected=0;
  1334. DWORD dwSelected=0;
  1335. HWND hwndControl=NULL;
  1336. LV_COLUMNW lvC;
  1337. LV_ITEM lvItem;
  1338. NM_LISTVIEW FAR * pnmv=NULL;
  1339. switch (msg)
  1340. {
  1341. case WM_INITDIALOG:
  1342. //set the wizard information so that it can be shared
  1343. pPropSheet = (PROPSHEETPAGE *) lParam;
  1344. pCertWizardInfo = (CERT_WIZARD_INFO *) (pPropSheet->lParam);
  1345. //make sure pCertWizardInfo is a valid pointer
  1346. if(NULL==pCertWizardInfo)
  1347. break;
  1348. // Get the selected cert type info
  1349. pCertTypeInfo = NULL;
  1350. GetSelectedCertTypeInfo(pCertWizardInfo, &pCertTypeInfo);
  1351. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertWizardInfo);
  1352. SetControlFont(pCertWizardInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
  1353. //set the check box for the exportable key option
  1354. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_CHECK_EXPORTKEY)))
  1355. break;
  1356. // determine whether the exportable checkbox should be set
  1357. // The checkbox is set if:
  1358. // 1) The CT_FLAG_EXPORTABLE_KEY flag is set on the template AND
  1359. // 2) The user has not unchecked this checkbox
  1360. if (pCertWizardInfo->fNewKey && (0 != (CRYPT_EXPORTABLE & pCertWizardInfo->dwGenKeyFlags)))
  1361. SendMessage(hwndControl, BM_SETCHECK, BST_CHECKED, 0);
  1362. else
  1363. SendMessage(hwndControl, BM_SETCHECK, BST_UNCHECKED, 0);
  1364. if (NULL != pCertTypeInfo)
  1365. EnableWindow(hwndControl, 0 != (CT_FLAG_EXPORTABLE_KEY & pCertTypeInfo->dwPrivateKeyFlags));
  1366. //set the check box for the user protection option
  1367. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2)))
  1368. break;
  1369. // determine whether the strong key protection checkbox should be set
  1370. if (0 != (CRYPT_USER_PROTECTED & pCertWizardInfo->dwGenKeyFlags)) {
  1371. // if this bit is set in the INITDIALOG handler, it's either
  1372. // from the template or the previous key. Enforce the setting
  1373. // by disabling the checkbox
  1374. SendMessage(hwndControl, BM_SETCHECK, BST_CHECKED, 0);
  1375. EnableWindow(hwndControl, FALSE);
  1376. } else {
  1377. SendMessage(hwndControl, BM_SETCHECK, BST_UNCHECKED, 0);
  1378. }
  1379. //gray out the user protection check box if we are not
  1380. //generating a new key or doing remote
  1381. if((FALSE == pCertWizardInfo->fNewKey) || (FALSE == pCertWizardInfo->fLocal) )
  1382. {
  1383. EnableWindow(hwndControl, FALSE);
  1384. }
  1385. //populate the CSP list with the following logic:
  1386. if(NULL!=(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
  1387. {
  1388. //insert a column into the list view
  1389. memset(&lvC, 0, sizeof(LV_COLUMNW));
  1390. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  1391. lvC.fmt = LVCFMT_LEFT; // Left-align the column.
  1392. lvC.cx = 20; //(dwMaxSize+2)*7; // Width of the column, in pixels.
  1393. lvC.pszText = L""; // The text for the column.
  1394. lvC.iSubItem=0;
  1395. if (ListView_InsertColumnU(hwndControl, 0, &lvC) == -1)
  1396. break;
  1397. InitCSPList(hwndControl, pCertWizardInfo);
  1398. // Determine which CSP is selected.
  1399. if(-1 != (nSelected= ListView_GetNextItem
  1400. (hwndControl,
  1401. -1,
  1402. LVNI_SELECTED
  1403. )))
  1404. {
  1405. // Done with CSP list. Populate the key sizes list.
  1406. if (CSPListIndexToCertWizardInfoIndex(hwndControl, nSelected, &dwIndex))
  1407. {
  1408. if (NULL!=(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_COMBO1)))
  1409. {
  1410. // Determine the selected cert type's min key size:
  1411. pCertTypeInfo = NULL;
  1412. if (GetSelectedCertTypeInfo(pCertWizardInfo, &pCertTypeInfo))
  1413. {
  1414. dwMinKeySize = NULL != pCertTypeInfo ? pCertTypeInfo->dwMinKeySize : 0;
  1415. InitKeySizesList(hwndControl,
  1416. dwMinKeySize,
  1417. (pCertWizardInfo->rgwszProvider)[dwIndex],
  1418. (pCertWizardInfo->rgdwProviderType)[dwIndex],
  1419. pCertTypeInfo->dwKeySpec);
  1420. }
  1421. }
  1422. }
  1423. }
  1424. }
  1425. break;
  1426. case WM_COMMAND:
  1427. break;
  1428. case WM_NOTIFY:
  1429. switch (((NMHDR FAR *) lParam)->code)
  1430. {
  1431. //the item has been selected
  1432. case LVN_ITEMCHANGED:
  1433. //get the window handle of the purpose list view
  1434. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
  1435. break;
  1436. if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  1437. break;
  1438. pnmv = (LPNMLISTVIEW) lParam;
  1439. if(NULL==pnmv)
  1440. break;
  1441. //we try not to let user de-select cert template
  1442. if((pnmv->uOldState & LVIS_SELECTED) && (0 == (pnmv->uNewState & LVIS_SELECTED)))
  1443. {
  1444. //we should have something selected
  1445. if(-1 == ListView_GetNextItem(
  1446. hwndControl,
  1447. -1,
  1448. LVNI_SELECTED
  1449. ))
  1450. {
  1451. //we should re-select the original item
  1452. ListView_SetItemState(
  1453. hwndControl,
  1454. pnmv->iItem,
  1455. LVIS_SELECTED,
  1456. LVIS_SELECTED);
  1457. pCertWizardInfo->iOrgCSP=pnmv->iItem;
  1458. }
  1459. }
  1460. //if something is selected, we disable all other selection
  1461. if(pnmv->uNewState & LVIS_SELECTED)
  1462. {
  1463. if(pnmv->iItem != pCertWizardInfo->iOrgCSP && -1 != pCertWizardInfo->iOrgCSP)
  1464. {
  1465. //we should de-select the original item
  1466. ListView_SetItemState(
  1467. hwndControl,
  1468. pCertWizardInfo->iOrgCSP,
  1469. 0,
  1470. LVIS_SELECTED);
  1471. pCertWizardInfo->iOrgCSP=-1;
  1472. }
  1473. }
  1474. // Determine which CSP is selected.
  1475. if(-1 != (nSelected= ListView_GetNextItem
  1476. (hwndControl,
  1477. -1,
  1478. LVNI_SELECTED
  1479. )))
  1480. {
  1481. // Done with CSP list. Populate the key sizes list.
  1482. if (CSPListIndexToCertWizardInfoIndex(hwndControl, nSelected, &dwIndex))
  1483. {
  1484. if (NULL!=(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_COMBO1)))
  1485. {
  1486. // Determine the selected cert type's min key size:
  1487. pCertTypeInfo = NULL;
  1488. if (GetSelectedCertTypeInfo(pCertWizardInfo, &pCertTypeInfo))
  1489. {
  1490. dwMinKeySize = NULL != pCertTypeInfo ? pCertTypeInfo->dwMinKeySize : 0;
  1491. InitKeySizesList(hwndControl,
  1492. dwMinKeySize,
  1493. (pCertWizardInfo->rgwszProvider)[dwIndex],
  1494. (pCertWizardInfo->rgdwProviderType)[dwIndex],
  1495. pCertTypeInfo->dwKeySpec);
  1496. }
  1497. }
  1498. }
  1499. }
  1500. break;
  1501. case PSN_KILLACTIVE:
  1502. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  1503. return TRUE;
  1504. break;
  1505. case PSN_RESET:
  1506. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  1507. break;
  1508. case PSN_SETACTIVE:
  1509. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
  1510. //reset the CSP list if CA selection has been changed
  1511. if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  1512. break;
  1513. if(TRUE==pCertWizardInfo->fCertTypeChanged)
  1514. {
  1515. // Get the selected cert type info
  1516. pCertTypeInfo = NULL;
  1517. GetSelectedCertTypeInfo(pCertWizardInfo, &pCertTypeInfo);
  1518. //set the check box for the exportable key option
  1519. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_CHECK_EXPORTKEY)))
  1520. break;
  1521. // determine whether the exportable checkbox should be set
  1522. // The checkbox is set if:
  1523. // 1) The CT_FLAG_EXPORTABLE_KEY flag is set on the template AND
  1524. // 2) The user has not unchecked this checkbox
  1525. if (pCertWizardInfo->fNewKey && (0 != (CRYPT_EXPORTABLE & pCertWizardInfo->dwGenKeyFlags)))
  1526. SendMessage(hwndControl, BM_SETCHECK, BST_CHECKED, 0);
  1527. else
  1528. SendMessage(hwndControl, BM_SETCHECK, BST_UNCHECKED, 0);
  1529. if (NULL != pCertTypeInfo)
  1530. EnableWindow(hwndControl, 0 != (CT_FLAG_EXPORTABLE_KEY & pCertTypeInfo->dwPrivateKeyFlags));
  1531. //set the check box for the user protection option
  1532. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2)))
  1533. break;
  1534. // determine whether the strong key protection checkbox should be set
  1535. if (pCertWizardInfo->fNewKey && (0 != (CRYPT_USER_PROTECTED & pCertWizardInfo->dwGenKeyFlags))) {
  1536. SendMessage(hwndControl, BM_SETCHECK, BST_CHECKED, 0);
  1537. EnableWindow(hwndControl, FALSE);
  1538. } else {
  1539. SendMessage(hwndControl, BM_SETCHECK, BST_UNCHECKED, 0);
  1540. }
  1541. if (pCertWizardInfo->fLocal) {
  1542. if (NULL != pCertTypeInfo) {
  1543. EnableWindow(hwndControl, 0 == (CT_FLAG_STRONG_KEY_PROTECTION_REQUIRED & pCertTypeInfo->dwPrivateKeyFlags));
  1544. }
  1545. } else {
  1546. EnableWindow(hwndControl, FALSE);
  1547. }
  1548. InitCSPList(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), pCertWizardInfo);
  1549. // Determine the selected cert type's min key size:
  1550. dwMinKeySize = NULL != pCertTypeInfo ? pCertTypeInfo->dwMinKeySize : 0;
  1551. }
  1552. // Determine which CSP is selected.
  1553. if(-1 != (nSelected=ListView_GetNextItem
  1554. (hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1),
  1555. -1,
  1556. LVNI_SELECTED
  1557. )))
  1558. {
  1559. // Done with CSP list. Populate the key sizes list.
  1560. if (CSPListIndexToCertWizardInfoIndex(hwndControl, nSelected, &dwIndex))
  1561. {
  1562. if (NULL!=(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_COMBO1)))
  1563. {
  1564. if (GetSelectedCertTypeInfo(pCertWizardInfo, &pCertTypeInfo))
  1565. {
  1566. dwMinKeySize = NULL != pCertTypeInfo ? pCertTypeInfo->dwMinKeySize : 0;
  1567. InitKeySizesList(hwndControl,
  1568. dwMinKeySize,
  1569. (pCertWizardInfo->rgwszProvider)[dwIndex],
  1570. (pCertWizardInfo->rgdwProviderType)[dwIndex],
  1571. pCertTypeInfo->dwKeySpec);
  1572. }
  1573. }
  1574. }
  1575. }
  1576. else
  1577. {
  1578. // Check whether we have any CSPs available...
  1579. if(-1 == (nSelected=ListView_GetNextItem
  1580. (hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1),
  1581. -1,
  1582. LVNI_ALL
  1583. )))
  1584. {
  1585. // No CSPs! We can't enroll for this template.
  1586. I_MessageBox(hwndDlg,
  1587. IDS_NO_CSP_FOR_PURPOSE,
  1588. pCertWizardInfo->idsConfirmTitle,
  1589. pCertWizardInfo->pwszConfirmationTitle,
  1590. MB_ICONEXCLAMATION|MB_OK|MB_APPLMODAL);
  1591. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_PURPOSE);
  1592. }
  1593. }
  1594. break;
  1595. case PSN_WIZBACK:
  1596. break;
  1597. case PSN_WIZNEXT:
  1598. if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  1599. break;
  1600. //get the window handle of the export key
  1601. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_CHECK_EXPORTKEY)))
  1602. break;
  1603. //mark the pose the cert to the CSP
  1604. if(TRUE==SendMessage(hwndControl, BM_GETCHECK, 0, 0))
  1605. pCertWizardInfo->dwGenKeyFlags |= CRYPT_EXPORTABLE;
  1606. else
  1607. pCertWizardInfo->dwGenKeyFlags &= ~CRYPT_EXPORTABLE;
  1608. //get the window handle of the user protection
  1609. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2)))
  1610. break;
  1611. //mark the pose the cert to the CSP
  1612. if(TRUE==SendMessage(hwndControl, BM_GETCHECK, 0, 0))
  1613. pCertWizardInfo->dwGenKeyFlags |= CRYPT_USER_PROTECTED;
  1614. else
  1615. pCertWizardInfo->dwGenKeyFlags &= ~CRYPT_USER_PROTECTED;
  1616. // Set the key size based on the user's suggestion:
  1617. //
  1618. if (NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_COMBO1)))
  1619. break;
  1620. if (CB_ERR != (dwSelected = (DWORD)SendMessage(hwndControl, CB_GETCURSEL, 0, 0)))
  1621. {
  1622. pCertWizardInfo->dwMinKeySize = (DWORD)SendMessage(hwndControl, CB_GETITEMDATA, dwSelected, 0);
  1623. }
  1624. else
  1625. {
  1626. pCertWizardInfo->dwMinKeySize = 0;
  1627. }
  1628. //get the window handle for the CSP list
  1629. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
  1630. break;
  1631. //now, mark the ones that are selected
  1632. if(-1 != (dwIndex= ListView_GetNextItem(
  1633. hwndControl,
  1634. -1,
  1635. LVNI_SELECTED
  1636. )))
  1637. {
  1638. //get the selected certificate
  1639. memset(&lvItem, 0, sizeof(LV_ITEM));
  1640. lvItem.mask=LVIF_PARAM;
  1641. lvItem.iItem=(int)dwIndex;
  1642. if(ListView_GetItem(hwndControl,
  1643. &lvItem))
  1644. {
  1645. pCertWizardInfo->dwProviderType=pCertWizardInfo->rgdwProviderType[(DWORD)(lvItem.lParam)];
  1646. pCertWizardInfo->pwszProvider=pCertWizardInfo->rgwszProvider[(DWORD)(lvItem.lParam)];
  1647. }
  1648. else
  1649. {
  1650. I_MessageBox(hwndDlg, IDS_NO_SELECTED_CSP,
  1651. pCertWizardInfo->idsConfirmTitle,
  1652. pCertWizardInfo->pwszConfirmationTitle,
  1653. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  1654. //make the purpose page stay
  1655. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  1656. break;
  1657. }
  1658. }
  1659. else
  1660. {
  1661. I_MessageBox(hwndDlg, IDS_NO_SELECTED_CSP,
  1662. pCertWizardInfo->idsConfirmTitle,
  1663. pCertWizardInfo->pwszConfirmationTitle,
  1664. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  1665. //make the purpose page stay
  1666. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  1667. break;
  1668. }
  1669. //skip to the correct page based on the advanced options and CSP requirement
  1670. if(FALSE == pCertWizardInfo->fUIAdv)
  1671. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_NAME_DESCRIPTION);
  1672. break;
  1673. default:
  1674. return FALSE;
  1675. }
  1676. break;
  1677. default:
  1678. return FALSE;
  1679. }
  1680. return TRUE;
  1681. }
  1682. //-----------------------------------------------------------------------
  1683. //CA
  1684. //-----------------------------------------------------------------------
  1685. INT_PTR APIENTRY Enroll_CA(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  1686. {
  1687. CERT_WIZARD_INFO *pCertWizardInfo=NULL;
  1688. PROPSHEETPAGE *pPropSheet=NULL;
  1689. DWORD dwChar=0;
  1690. PCRYPTUI_CA_CONTEXT pCAContext=NULL;
  1691. LPWSTR pwszCADisplayName = NULL;
  1692. HCURSOR hPreCursor=NULL;
  1693. HCURSOR hWinPreCursor=NULL;
  1694. switch (msg)
  1695. {
  1696. case WM_INITDIALOG:
  1697. //set the wizard information so that it can be shared
  1698. pPropSheet = (PROPSHEETPAGE *) lParam;
  1699. pCertWizardInfo = (CERT_WIZARD_INFO *) (pPropSheet->lParam);
  1700. SetControlFont(pCertWizardInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
  1701. //make sure pCertWizardInfo is a valid pointer
  1702. if(NULL==pCertWizardInfo)
  1703. break;
  1704. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertWizardInfo);
  1705. //init the CA name and CA location
  1706. if(pCertWizardInfo->pwszCALocation)
  1707. SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT2,pCertWizardInfo->pwszCALocation);
  1708. if(pCertWizardInfo->pwszCAName)
  1709. {
  1710. //overwrite the cursor for this window class
  1711. hWinPreCursor=(HCURSOR)SetClassLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)NULL);
  1712. hPreCursor=SetCursor(LoadCursor(NULL, IDC_WAIT));
  1713. if(CAUtilGetCADisplayName((pCertWizardInfo->fMachine) ? CA_FIND_LOCAL_SYSTEM:0,
  1714. pCertWizardInfo->pwszCAName,
  1715. &pwszCADisplayName))
  1716. {
  1717. SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,pwszCADisplayName);
  1718. WizardFree(pwszCADisplayName);
  1719. pwszCADisplayName=NULL;
  1720. }
  1721. else
  1722. SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,pCertWizardInfo->pwszCAName);
  1723. //set the cursor back
  1724. SetCursor(hPreCursor);
  1725. SetWindowLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)hWinPreCursor);
  1726. }
  1727. break;
  1728. case WM_COMMAND:
  1729. if(HIWORD(wParam) == BN_CLICKED)
  1730. {
  1731. switch (LOWORD(wParam))
  1732. {
  1733. case IDC_WIZARD_BUTTON1:
  1734. if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  1735. break;
  1736. //overwrite the cursor for this window class
  1737. hWinPreCursor=(HCURSOR)SetClassLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)NULL);
  1738. hPreCursor=SetCursor(LoadCursor(NULL, IDC_WAIT));
  1739. //call the CA selection dialogue
  1740. pCAContext=GetCAContext(hwndDlg, pCertWizardInfo);
  1741. //set the cursor back
  1742. SetCursor(hPreCursor);
  1743. SetWindowLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)hWinPreCursor);
  1744. if(pCAContext)
  1745. {
  1746. //update the edit box
  1747. if(pCAContext->pwszCAMachineName)
  1748. SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT2,pCAContext->pwszCAMachineName);
  1749. if(pCAContext->pwszCAName)
  1750. SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,pCAContext->pwszCAName);
  1751. //free the CA context
  1752. CryptUIDlgFreeCAContext(pCAContext);
  1753. pCAContext=NULL;
  1754. }
  1755. break;
  1756. default:
  1757. break;
  1758. }
  1759. }
  1760. break;
  1761. case WM_NOTIFY:
  1762. switch (((NMHDR FAR *) lParam)->code)
  1763. {
  1764. case PSN_KILLACTIVE:
  1765. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  1766. return TRUE;
  1767. break;
  1768. case PSN_RESET:
  1769. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  1770. break;
  1771. case PSN_SETACTIVE:
  1772. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
  1773. //reset the CSP list if CA selection has been changed
  1774. if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  1775. break;
  1776. if(TRUE==pCertWizardInfo->fCertTypeChanged)
  1777. {
  1778. //reset the CA name and CA location
  1779. if(pCertWizardInfo->pwszCALocation)
  1780. SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT2,pCertWizardInfo->pwszCALocation);
  1781. if(pCertWizardInfo->pwszCAName)
  1782. {
  1783. //overwrite the cursor for this window class
  1784. hWinPreCursor=(HCURSOR)SetClassLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)NULL);
  1785. hPreCursor=SetCursor(LoadCursor(NULL, IDC_WAIT));
  1786. if(CAUtilGetCADisplayName((pCertWizardInfo->fMachine) ? CA_FIND_LOCAL_SYSTEM:0,
  1787. pCertWizardInfo->pwszCAName,
  1788. &pwszCADisplayName))
  1789. {
  1790. SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,pwszCADisplayName);
  1791. WizardFree(pwszCADisplayName);
  1792. pwszCADisplayName=NULL;
  1793. }
  1794. else
  1795. SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,pCertWizardInfo->pwszCAName);
  1796. //set the cursor back
  1797. SetCursor(hPreCursor);
  1798. SetWindowLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)hWinPreCursor);
  1799. }
  1800. }
  1801. //reset the certtype change flag to FALSE.
  1802. pCertWizardInfo->fCertTypeChanged = FALSE;
  1803. break;
  1804. case PSN_WIZBACK:
  1805. if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  1806. break;
  1807. //skip to the correct page based on the advanced options and CSP requirement
  1808. if(FALSE == pCertWizardInfo->fNewKey)
  1809. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_PURPOSE);
  1810. break;
  1811. case PSN_WIZNEXT:
  1812. if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  1813. break;
  1814. //cach the display name of the CA
  1815. if(0!=(dwChar=(DWORD)SendDlgItemMessage(hwndDlg,
  1816. IDC_WIZARD_EDIT1,
  1817. WM_GETTEXTLENGTH, 0, 0)))
  1818. {
  1819. if(pCertWizardInfo->pwszCADisplayName)
  1820. {
  1821. WizardFree(pCertWizardInfo->pwszCADisplayName);
  1822. pCertWizardInfo->pwszCADisplayName = NULL;
  1823. }
  1824. pCertWizardInfo->pwszCADisplayName=(LPWSTR)WizardAlloc(sizeof(WCHAR)*(dwChar+1));
  1825. if(NULL!=(pCertWizardInfo->pwszCADisplayName))
  1826. {
  1827. GetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,
  1828. pCertWizardInfo->pwszCADisplayName,
  1829. dwChar+1);
  1830. }
  1831. }
  1832. break;
  1833. default:
  1834. return FALSE;
  1835. }
  1836. break;
  1837. default:
  1838. return FALSE;
  1839. }
  1840. return TRUE;
  1841. }
  1842. //-----------------------------------------------------------------------
  1843. //FriendlyName
  1844. //-----------------------------------------------------------------------
  1845. INT_PTR APIENTRY Enroll_Name(HWND hwndDlg, UINT msg, WPARAM /*wParam*/, LPARAM lParam)
  1846. {
  1847. CERT_WIZARD_INFO *pCertWizardInfo=NULL;
  1848. PROPSHEETPAGE *pPropSheet=NULL;
  1849. DWORD dwChar=0;
  1850. switch (msg)
  1851. {
  1852. case WM_INITDIALOG:
  1853. //set the wizard information so that it can be shared
  1854. pPropSheet = (PROPSHEETPAGE *) lParam;
  1855. pCertWizardInfo = (CERT_WIZARD_INFO *) (pPropSheet->lParam);
  1856. //make sure pCertWizardInfo is a valid pointer
  1857. if(NULL==pCertWizardInfo)
  1858. break;
  1859. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertWizardInfo);
  1860. SetControlFont(pCertWizardInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
  1861. //initialize the friendlyname and description
  1862. if(pCertWizardInfo->pwszFriendlyName)
  1863. SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,pCertWizardInfo->pwszFriendlyName);
  1864. if(pCertWizardInfo->pwszDescription)
  1865. SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT2,pCertWizardInfo->pwszDescription);
  1866. break;
  1867. case WM_COMMAND:
  1868. break;
  1869. case WM_NOTIFY:
  1870. switch (((NMHDR FAR *) lParam)->code)
  1871. {
  1872. case PSN_KILLACTIVE:
  1873. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  1874. return TRUE;
  1875. break;
  1876. case PSN_RESET:
  1877. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  1878. break;
  1879. case PSN_SETACTIVE:
  1880. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
  1881. break;
  1882. case PSN_WIZBACK:
  1883. if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  1884. break;
  1885. //skip to the correct page based on the advanced options and CSP requirement
  1886. if(FALSE == pCertWizardInfo->fUIAdv)
  1887. {
  1888. if(TRUE == pCertWizardInfo->fUICSP)
  1889. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_CSP_SERVICE_PROVIDER);
  1890. else
  1891. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_PURPOSE);
  1892. }
  1893. break;
  1894. case PSN_WIZNEXT:
  1895. if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  1896. break;
  1897. //free the original messages
  1898. if(pCertWizardInfo->pwszFriendlyName)
  1899. {
  1900. WizardFree(pCertWizardInfo->pwszFriendlyName);
  1901. pCertWizardInfo->pwszFriendlyName=NULL;
  1902. }
  1903. if(pCertWizardInfo->pwszDescription)
  1904. {
  1905. WizardFree(pCertWizardInfo->pwszDescription);
  1906. pCertWizardInfo->pwszDescription=NULL;
  1907. }
  1908. //get the friendlyName
  1909. if(0!=(dwChar=(DWORD)SendDlgItemMessage(hwndDlg,
  1910. IDC_WIZARD_EDIT1,
  1911. WM_GETTEXTLENGTH, 0, 0)))
  1912. {
  1913. pCertWizardInfo->pwszFriendlyName=(LPWSTR)WizardAlloc(sizeof(WCHAR)*(dwChar+1));
  1914. if(NULL!=(pCertWizardInfo->pwszFriendlyName))
  1915. {
  1916. GetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,
  1917. pCertWizardInfo->pwszFriendlyName,
  1918. dwChar+1);
  1919. }
  1920. }
  1921. //get the description
  1922. if(0!=(dwChar=(DWORD)SendDlgItemMessage(hwndDlg,
  1923. IDC_WIZARD_EDIT2,
  1924. WM_GETTEXTLENGTH, 0, 0)))
  1925. {
  1926. pCertWizardInfo->pwszDescription=(LPWSTR)WizardAlloc(sizeof(WCHAR)*(dwChar+1));
  1927. if(NULL!=(pCertWizardInfo->pwszDescription))
  1928. {
  1929. GetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT2,
  1930. pCertWizardInfo->pwszDescription,
  1931. dwChar+1);
  1932. }
  1933. }
  1934. break;
  1935. default:
  1936. return FALSE;
  1937. }
  1938. break;
  1939. default:
  1940. return FALSE;
  1941. }
  1942. return TRUE;
  1943. }
  1944. //-----------------------------------------------------------------------
  1945. //Completion
  1946. //-----------------------------------------------------------------------
  1947. INT_PTR APIENTRY Enroll_Completion(HWND hwndDlg, UINT msg, WPARAM /*wParam*/, LPARAM lParam)
  1948. {
  1949. CERT_WIZARD_INFO *pCertWizardInfo=NULL;
  1950. PROPSHEETPAGE *pPropSheet=NULL;
  1951. HWND hwndControl=NULL;
  1952. LV_COLUMNW lvC;
  1953. HCURSOR hPreCursor=NULL;
  1954. HCURSOR hWinPreCursor=NULL;
  1955. switch (msg)
  1956. {
  1957. case WM_INITDIALOG:
  1958. //set the wizard information so that it can be shared
  1959. pPropSheet = (PROPSHEETPAGE *) lParam;
  1960. pCertWizardInfo = (CERT_WIZARD_INFO *) (pPropSheet->lParam);
  1961. //make sure pCertWizardInfo is a valid pointer
  1962. if(NULL==pCertWizardInfo)
  1963. break;
  1964. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertWizardInfo);
  1965. SetControlFont(pCertWizardInfo->hBigBold, hwndDlg,IDC_WIZARD_STATIC_BIG_BOLD1);
  1966. //insert two columns
  1967. hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1);
  1968. memset(&lvC, 0, sizeof(LV_COLUMNW));
  1969. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  1970. lvC.fmt = LVCFMT_LEFT; // Left-align the column.
  1971. lvC.cx = 20; // Width of the column, in pixels.
  1972. lvC.pszText = L""; // The text for the column.
  1973. lvC.iSubItem=0;
  1974. if (ListView_InsertColumnU(hwndControl, 0, &lvC) == -1)
  1975. break;
  1976. //2nd column is the content
  1977. memset(&lvC, 0, sizeof(LV_COLUMNW));
  1978. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  1979. lvC.fmt = LVCFMT_LEFT; // Left-align the column.
  1980. lvC.cx = 10; //(dwMaxSize+2)*7; // Width of the column, in pixels.
  1981. lvC.pszText = L""; // The text for the column.
  1982. lvC.iSubItem= 1;
  1983. if (ListView_InsertColumnU(hwndControl, 1, &lvC) == -1)
  1984. break;
  1985. break;
  1986. case WM_COMMAND:
  1987. break;
  1988. case WM_NOTIFY:
  1989. switch (((NMHDR FAR *) lParam)->code)
  1990. {
  1991. case PSN_KILLACTIVE:
  1992. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  1993. return TRUE;
  1994. break;
  1995. case PSN_RESET:
  1996. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  1997. break;
  1998. case PSN_SETACTIVE:
  1999. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK|PSWIZB_FINISH);
  2000. if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  2001. break;
  2002. //populate the list box in the order of friendly name,
  2003. //overwrite the cursor for this window class
  2004. hWinPreCursor=(HCURSOR)SetClassLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)NULL);
  2005. hPreCursor=SetCursor(LoadCursor(NULL, IDC_WAIT));
  2006. //UserName, CA, Purpose, and CSP
  2007. //Get the window handle for the CSP list
  2008. if(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1))
  2009. DisplayConfirmation(hwndControl, pCertWizardInfo);
  2010. //set the cursor back
  2011. SetCursor(hPreCursor);
  2012. SetWindowLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)hWinPreCursor);
  2013. break;
  2014. case PSN_WIZBACK:
  2015. break;
  2016. case PSN_WIZFINISH:
  2017. {
  2018. CertRequester *pCertRequester = NULL;
  2019. CertRequesterContext *pCertRequesterContext = NULL;
  2020. if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  2021. break;
  2022. //overwrite the cursor for this window class
  2023. hWinPreCursor=(HCURSOR)SetClassLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)NULL);
  2024. hPreCursor=SetCursor(LoadCursor(NULL, IDC_WAIT));
  2025. //set the parent window to the hwndDlg so that
  2026. //confirmat to install dlg use hwndDlg as the
  2027. //parent window
  2028. pCertWizardInfo->hwndParent=hwndDlg;
  2029. if (NULL == (pCertRequester = (CertRequester *) pCertWizardInfo->hRequester))
  2030. break;
  2031. if (NULL == (pCertRequesterContext = pCertRequester->GetContext()))
  2032. break;
  2033. //call the enrollment wizard
  2034. pCertWizardInfo->hr = pCertRequesterContext->Enroll(&(pCertWizardInfo->dwStatus), (HANDLE *)&(pCertWizardInfo->pNewCertContext));
  2035. if (0 == pCertWizardInfo->idsText) {
  2036. pCertWizardInfo->idsText = CryptUIStatusToIDSText(pCertWizardInfo->hr, pCertWizardInfo->dwStatus);
  2037. }
  2038. if(S_OK != pCertWizardInfo->hr)
  2039. break;
  2040. //set the cursor back
  2041. SetCursor(hPreCursor);
  2042. SetWindowLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)hWinPreCursor);
  2043. }
  2044. break;
  2045. default:
  2046. return FALSE;
  2047. }
  2048. break;
  2049. default:
  2050. return FALSE;
  2051. }
  2052. return TRUE;
  2053. }
  2054. //*******************************************************************************
  2055. // WinProc for the enrollment wizard
  2056. //
  2057. //*******************************************************************************
  2058. //-----------------------------------------------------------------------
  2059. //Renew_Welcome
  2060. //-----------------------------------------------------------------------
  2061. INT_PTR APIENTRY Renew_Welcome(HWND hwndDlg, UINT msg, WPARAM /*wParam*/, LPARAM lParam)
  2062. {
  2063. CERT_WIZARD_INFO *pCertWizardInfo=NULL;
  2064. PROPSHEETPAGE *pPropSheet=NULL;
  2065. PCRYPTUI_WIZ_CERT_CA pCertCA=NULL;
  2066. DWORD dwIndex=0;
  2067. switch (msg)
  2068. {
  2069. case WM_INITDIALOG:
  2070. //set the wizard information so that it can be shared
  2071. pPropSheet = (PROPSHEETPAGE *) lParam;
  2072. pCertWizardInfo = (CERT_WIZARD_INFO *) (pPropSheet->lParam);
  2073. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertWizardInfo);
  2074. SetControlFont(pCertWizardInfo->hBigBold, hwndDlg,IDC_WIZARD_STATIC_BIG_BOLD1);
  2075. // SetControlFont(pCertWizardInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
  2076. break;
  2077. case WM_NOTIFY:
  2078. switch (((NMHDR FAR *) lParam)->code)
  2079. {
  2080. case PSN_KILLACTIVE:
  2081. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  2082. return TRUE;
  2083. break;
  2084. case PSN_RESET:
  2085. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  2086. break;
  2087. case PSN_SETACTIVE:
  2088. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
  2089. break;
  2090. case PSN_WIZBACK:
  2091. break;
  2092. case PSN_WIZNEXT:
  2093. if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  2094. break;
  2095. //decide the default CA to use since the CertType will not
  2096. //be changed
  2097. ResetDefaultCA(pCertWizardInfo);
  2098. //decide if we need to show the CSP page
  2099. pCertCA=&(pCertWizardInfo->pCertCAInfo->rgCA[pCertWizardInfo->dwCAIndex]);
  2100. for(dwIndex=0; dwIndex<pCertCA->dwCertTypeInfo; dwIndex++)
  2101. {
  2102. if(pCertCA->rgCertTypeInfo[dwIndex].fSelected)
  2103. {
  2104. if(NULL == pCertWizardInfo->pwszProvider)
  2105. {
  2106. if(0 == pCertCA->rgCertTypeInfo[dwIndex].dwCSPCount)
  2107. pCertWizardInfo->fUICSP=TRUE;
  2108. }
  2109. //copy the selected CertTypeName
  2110. pCertWizardInfo->pwszSelectedCertTypeDN=pCertCA->rgCertTypeInfo[dwIndex].pwszDNName;
  2111. break;
  2112. }
  2113. }
  2114. break;
  2115. default:
  2116. return FALSE;
  2117. }
  2118. break;
  2119. default:
  2120. return FALSE;
  2121. }
  2122. return TRUE;
  2123. }
  2124. //-----------------------------------------------------------------------
  2125. //Renew_Options
  2126. //-----------------------------------------------------------------------
  2127. INT_PTR APIENTRY Renew_Options(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  2128. {
  2129. CERT_WIZARD_INFO *pCertWizardInfo=NULL;
  2130. PROPSHEETPAGE *pPropSheet=NULL;
  2131. switch (msg)
  2132. {
  2133. case WM_INITDIALOG:
  2134. //set the wizard information so that it can be shared
  2135. pPropSheet = (PROPSHEETPAGE *) lParam;
  2136. pCertWizardInfo = (CERT_WIZARD_INFO *) (pPropSheet->lParam);
  2137. SetControlFont(pCertWizardInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
  2138. //make sure pCertWizardInfo is a valid pointer
  2139. if(NULL==pCertWizardInfo)
  2140. break;
  2141. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertWizardInfo);
  2142. //set the initial selection as using the default selections
  2143. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_SETCHECK, 1, 0);
  2144. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO2), BM_SETCHECK, 0, 0);
  2145. break;
  2146. case WM_COMMAND:
  2147. if(HIWORD(wParam) == BN_CLICKED)
  2148. {
  2149. switch (LOWORD(wParam))
  2150. {
  2151. case IDC_WIZARD_RADIO1:
  2152. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_SETCHECK, 1, 0);
  2153. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO2), BM_SETCHECK, 0, 0);
  2154. break;
  2155. case IDC_WIZARD_RADIO2:
  2156. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_SETCHECK, 0, 0);
  2157. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO2), BM_SETCHECK, 1, 0);
  2158. break;
  2159. default:
  2160. break;
  2161. }
  2162. }
  2163. break;
  2164. case WM_NOTIFY:
  2165. switch (((NMHDR FAR *) lParam)->code)
  2166. {
  2167. case PSN_KILLACTIVE:
  2168. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  2169. return TRUE;
  2170. break;
  2171. case PSN_RESET:
  2172. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  2173. break;
  2174. case PSN_SETACTIVE:
  2175. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
  2176. if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  2177. break;
  2178. //if the adv selection is made, it has to stay selected
  2179. if(pCertWizardInfo->fUIAdv)
  2180. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), FALSE);
  2181. break;
  2182. case PSN_WIZBACK:
  2183. break;
  2184. case PSN_WIZNEXT:
  2185. if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  2186. break;
  2187. //check for the advanced options
  2188. if(TRUE==SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_GETCHECK, 0, 0))
  2189. pCertWizardInfo->fUIAdv=FALSE;
  2190. else
  2191. pCertWizardInfo->fUIAdv=TRUE;
  2192. //skip to the correct page based on the advanced options and CSP requirement
  2193. if(FALSE == pCertWizardInfo->fUIAdv)
  2194. {
  2195. if(TRUE == pCertWizardInfo->fUICSP)
  2196. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_RENEW_SERVICE_PROVIDER);
  2197. else
  2198. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_RENEW_COMPLETION);
  2199. }
  2200. else
  2201. {
  2202. if(FALSE == pCertWizardInfo->fNewKey)
  2203. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_RENEW_CA);
  2204. }
  2205. break;
  2206. default:
  2207. return FALSE;
  2208. }
  2209. break;
  2210. default:
  2211. return FALSE;
  2212. }
  2213. return TRUE;
  2214. }
  2215. //-----------------------------------------------------------------------
  2216. // Renew_CSP
  2217. //-----------------------------------------------------------------------
  2218. INT_PTR APIENTRY Renew_CSP(HWND hwndDlg, UINT msg, WPARAM /*wParam*/, LPARAM lParam)
  2219. {
  2220. CERT_WIZARD_INFO *pCertWizardInfo=NULL;
  2221. PROPSHEETPAGE *pPropSheet=NULL;
  2222. ENROLL_CERT_TYPE_INFO *pCertTypeInfo=NULL;
  2223. DWORD dwMinKeySize=0;
  2224. DWORD dwIndex=0;
  2225. DWORD dwSelected=0;
  2226. int nSelected=0;
  2227. HWND hwndControl=NULL;
  2228. LV_COLUMNW lvC;
  2229. LV_ITEM lvItem;
  2230. NM_LISTVIEW FAR * pnmv=NULL;
  2231. switch (msg)
  2232. {
  2233. case WM_INITDIALOG:
  2234. //set the wizard information so that it can be shared
  2235. pPropSheet = (PROPSHEETPAGE *) lParam;
  2236. pCertWizardInfo = (CERT_WIZARD_INFO *) (pPropSheet->lParam);
  2237. //make sure pCertWizardInfo is a valid pointer
  2238. if(NULL==pCertWizardInfo)
  2239. break;
  2240. // Get the selected cert type info
  2241. pCertTypeInfo = NULL;
  2242. GetSelectedCertTypeInfo(pCertWizardInfo, &pCertTypeInfo);
  2243. if (NULL != pCertTypeInfo)
  2244. MarkSelectedCertType(pCertWizardInfo, pCertTypeInfo->pwszDNName);
  2245. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertWizardInfo);
  2246. SetControlFont(pCertWizardInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
  2247. //set the check box for the exportable key option
  2248. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_CHECK_EXPORTKEY)))
  2249. break;
  2250. // determine whether the exportable checkbox should be set
  2251. // The checkbox is set if:
  2252. // 1) The CT_FLAG_EXPORTABLE_KEY flag is set on the template AND
  2253. // 2) The user has not unchecked this checkbox
  2254. if (pCertWizardInfo->fNewKey && (0 != (CRYPT_EXPORTABLE & pCertWizardInfo->dwGenKeyFlags)))
  2255. SendMessage(hwndControl, BM_SETCHECK, BST_CHECKED, 0);
  2256. else
  2257. SendMessage(hwndControl, BM_SETCHECK, BST_UNCHECKED, 0);
  2258. if (NULL != pCertTypeInfo)
  2259. EnableWindow(hwndControl, 0 != (CT_FLAG_EXPORTABLE_KEY & pCertTypeInfo->dwPrivateKeyFlags));
  2260. //set the check box for the user protection option
  2261. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2)))
  2262. break;
  2263. //set the check box for the user protection option
  2264. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2)))
  2265. break;
  2266. // determine whether the strong key protection checkbox should be set
  2267. if (0 != (CRYPT_USER_PROTECTED & pCertWizardInfo->dwGenKeyFlags)) {
  2268. // if this bit is set in the INITDIALOG handler, it's either
  2269. // from the template or the previous key. Enforce the setting
  2270. // by disabling the checkbox
  2271. SendMessage(hwndControl, BM_SETCHECK, BST_CHECKED, 0);
  2272. EnableWindow(hwndControl, FALSE);
  2273. } else {
  2274. SendMessage(hwndControl, BM_SETCHECK, BST_UNCHECKED, 0);
  2275. }
  2276. //gray out the user protection check box if we are not
  2277. //generating a new key or doing remote
  2278. if((FALSE == pCertWizardInfo->fNewKey) || (FALSE == pCertWizardInfo->fLocal) )
  2279. {
  2280. EnableWindow(hwndControl, FALSE);
  2281. }
  2282. //populate the CSP list with the following logic:
  2283. if(NULL!=(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
  2284. {
  2285. //insert a column into the list view
  2286. memset(&lvC, 0, sizeof(LV_COLUMNW));
  2287. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  2288. lvC.fmt = LVCFMT_LEFT; // Left-align the column.
  2289. lvC.cx = 20; //(dwMaxSize+2)*7; // Width of the column, in pixels.
  2290. lvC.pszText = L""; // The text for the column.
  2291. lvC.iSubItem=0;
  2292. if (ListView_InsertColumnU(hwndControl, 0, &lvC) == -1)
  2293. break;
  2294. InitCSPList(hwndControl, pCertWizardInfo);
  2295. if(-1 != (nSelected= ListView_GetNextItem
  2296. (hwndControl,
  2297. -1,
  2298. LVNI_SELECTED
  2299. )))
  2300. {
  2301. // Done with CSP list. Populate the key sizes list.
  2302. if (CSPListIndexToCertWizardInfoIndex(hwndControl, nSelected, &dwIndex))
  2303. {
  2304. if (NULL!=(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_COMBO1)))
  2305. {
  2306. // Determine the selected cert type's min key size:
  2307. pCertTypeInfo = NULL;
  2308. if (GetSelectedCertTypeInfo(pCertWizardInfo, &pCertTypeInfo))
  2309. {
  2310. dwMinKeySize = NULL != pCertTypeInfo ? pCertTypeInfo->dwMinKeySize : 0;
  2311. InitKeySizesList(hwndControl,
  2312. dwMinKeySize,
  2313. (pCertWizardInfo->rgwszProvider)[dwIndex],
  2314. (pCertWizardInfo->rgdwProviderType)[dwIndex],
  2315. pCertTypeInfo->dwKeySpec);
  2316. }
  2317. }
  2318. }
  2319. }
  2320. }
  2321. break;
  2322. case WM_COMMAND:
  2323. break;
  2324. case WM_NOTIFY:
  2325. switch (((NMHDR FAR *) lParam)->code)
  2326. {
  2327. //the item has been selected
  2328. case LVN_ITEMCHANGED:
  2329. //get the window handle of the purpose list view
  2330. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
  2331. break;
  2332. if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  2333. break;
  2334. pnmv = (LPNMLISTVIEW) lParam;
  2335. if(NULL==pnmv)
  2336. break;
  2337. //we try not to let user de-select cert template
  2338. if((pnmv->uOldState & LVIS_SELECTED) && (0 == (pnmv->uNewState & LVIS_SELECTED)))
  2339. {
  2340. //we should have something selected
  2341. if(-1 == ListView_GetNextItem(
  2342. hwndControl,
  2343. -1,
  2344. LVNI_SELECTED
  2345. ))
  2346. {
  2347. //we should re-select the original item
  2348. ListView_SetItemState(
  2349. hwndControl,
  2350. pnmv->iItem,
  2351. LVIS_SELECTED,
  2352. LVIS_SELECTED);
  2353. pCertWizardInfo->iOrgCSP=pnmv->iItem;
  2354. }
  2355. }
  2356. //if something is selected, we disable all other selection
  2357. if(pnmv->uNewState & LVIS_SELECTED)
  2358. {
  2359. if(pnmv->iItem != pCertWizardInfo->iOrgCSP && -1 != pCertWizardInfo->iOrgCSP)
  2360. {
  2361. //we should de-select the original item
  2362. ListView_SetItemState(
  2363. hwndControl,
  2364. pCertWizardInfo->iOrgCSP,
  2365. 0,
  2366. LVIS_SELECTED);
  2367. pCertWizardInfo->iOrgCSP=-1;
  2368. }
  2369. }
  2370. // Determine which CSP is selected.
  2371. if(-1 != (nSelected= ListView_GetNextItem
  2372. (hwndControl,
  2373. -1,
  2374. LVNI_SELECTED
  2375. )))
  2376. {
  2377. // Done with CSP list. Populate the key sizes list.
  2378. if (CSPListIndexToCertWizardInfoIndex(hwndControl, nSelected, &dwIndex))
  2379. {
  2380. if (NULL!=(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_COMBO1)))
  2381. {
  2382. pCertTypeInfo = NULL;
  2383. if (GetSelectedCertTypeInfo(pCertWizardInfo, &pCertTypeInfo))
  2384. {
  2385. dwMinKeySize = NULL != pCertTypeInfo ? pCertTypeInfo->dwMinKeySize : 0;
  2386. InitKeySizesList(hwndControl,
  2387. dwMinKeySize,
  2388. (pCertWizardInfo->rgwszProvider)[dwIndex],
  2389. (pCertWizardInfo->rgdwProviderType)[dwIndex],
  2390. pCertTypeInfo->dwKeySpec);
  2391. }
  2392. }
  2393. }
  2394. }
  2395. break;
  2396. case PSN_KILLACTIVE:
  2397. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  2398. return TRUE;
  2399. break;
  2400. case PSN_RESET:
  2401. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  2402. break;
  2403. case PSN_SETACTIVE:
  2404. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
  2405. //reset the CSP list if CA selection has been changed
  2406. if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  2407. break;
  2408. if(TRUE==pCertWizardInfo->fCertTypeChanged)
  2409. {
  2410. pCertTypeInfo = NULL;
  2411. GetSelectedCertTypeInfo(pCertWizardInfo, &pCertTypeInfo);
  2412. //set the check box for the exportable key option
  2413. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_CHECK_EXPORTKEY)))
  2414. break;
  2415. // determine whether the exportable checkbox should be set
  2416. // The checkbox is set if:
  2417. // 1) The CT_FLAG_EXPORTABLE_KEY flag is set on the template AND
  2418. // 2) The user has not unchecked this checkbox
  2419. if (pCertWizardInfo->fNewKey && (0 != (CRYPT_EXPORTABLE & pCertWizardInfo->dwGenKeyFlags)))
  2420. SendMessage(hwndControl, BM_SETCHECK, BST_CHECKED, 0);
  2421. else
  2422. SendMessage(hwndControl, BM_SETCHECK, BST_UNCHECKED, 0);
  2423. if (NULL != pCertTypeInfo)
  2424. EnableWindow(hwndControl, 0 != (CT_FLAG_EXPORTABLE_KEY & pCertTypeInfo->dwPrivateKeyFlags));
  2425. InitCSPList(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), pCertWizardInfo);
  2426. }
  2427. // Determine which CSP is selected.
  2428. if(-1 != (nSelected=ListView_GetNextItem
  2429. (hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1),
  2430. -1,
  2431. LVNI_SELECTED
  2432. )))
  2433. {
  2434. // Done with CSP list. Populate the key sizes list.
  2435. if (CSPListIndexToCertWizardInfoIndex(hwndControl, nSelected, &dwIndex))
  2436. {
  2437. if (NULL!=(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_COMBO1)))
  2438. {
  2439. pCertTypeInfo = NULL;
  2440. if (GetSelectedCertTypeInfo(pCertWizardInfo, &pCertTypeInfo))
  2441. {
  2442. // Determine the selected cert type's min key size:
  2443. dwMinKeySize = NULL != pCertTypeInfo ? pCertTypeInfo->dwMinKeySize : 0;
  2444. InitKeySizesList(hwndControl,
  2445. dwMinKeySize,
  2446. (pCertWizardInfo->rgwszProvider)[dwIndex],
  2447. (pCertWizardInfo->rgdwProviderType)[dwIndex],
  2448. pCertTypeInfo->dwKeySpec);
  2449. }
  2450. }
  2451. }
  2452. }
  2453. else
  2454. {
  2455. if(-1 == (nSelected=ListView_GetNextItem
  2456. (hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1),
  2457. -1,
  2458. LVNI_ALL
  2459. )))
  2460. {
  2461. // No CSPs! We can't enroll for this template.
  2462. I_MessageBox(hwndDlg,
  2463. IDS_NO_CSP_FOR_PURPOSE,
  2464. pCertWizardInfo->idsConfirmTitle,
  2465. pCertWizardInfo->pwszConfirmationTitle,
  2466. MB_ICONEXCLAMATION|MB_OK|MB_APPLMODAL);
  2467. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_RENEW_OPTIONS);
  2468. }
  2469. }
  2470. break;
  2471. case PSN_WIZBACK:
  2472. break;
  2473. case PSN_WIZNEXT:
  2474. if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  2475. break;
  2476. //get the window handle of the exportkey
  2477. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_CHECK_EXPORTKEY)))
  2478. break;
  2479. //mark the pose the cert to the CSP
  2480. if(TRUE==SendMessage(hwndControl, BM_GETCHECK, 0, 0))
  2481. pCertWizardInfo->dwGenKeyFlags |= CRYPT_EXPORTABLE;
  2482. else
  2483. pCertWizardInfo->dwGenKeyFlags &= ~CRYPT_EXPORTABLE;
  2484. //get the window handle of the user protection
  2485. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2)))
  2486. break;
  2487. //mark the pose the cert to the CSP
  2488. if(TRUE==SendMessage(hwndControl, BM_GETCHECK, 0, 0))
  2489. pCertWizardInfo->dwGenKeyFlags |= CRYPT_USER_PROTECTED;
  2490. else
  2491. pCertWizardInfo->dwGenKeyFlags &= ~CRYPT_USER_PROTECTED;
  2492. // Set the key size based on the user's suggestion:
  2493. //
  2494. if (NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_COMBO1)))
  2495. break;
  2496. if (CB_ERR != (dwSelected = (DWORD)SendMessage(hwndControl, CB_GETCURSEL, 0, 0)))
  2497. {
  2498. pCertWizardInfo->dwMinKeySize = (DWORD)SendMessage(hwndControl, CB_GETITEMDATA, dwSelected, 0);
  2499. }
  2500. else
  2501. {
  2502. pCertWizardInfo->dwMinKeySize = 0;
  2503. }
  2504. //get the window handle for the CSP list
  2505. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
  2506. break;
  2507. //now, mark the ones that are selected
  2508. if(-1 != (dwIndex= ListView_GetNextItem(
  2509. hwndControl,
  2510. -1,
  2511. LVNI_SELECTED
  2512. )))
  2513. {
  2514. //get the selected certificate
  2515. memset(&lvItem, 0, sizeof(LV_ITEM));
  2516. lvItem.mask=LVIF_PARAM;
  2517. lvItem.iItem=(int)dwIndex;
  2518. if(ListView_GetItem(hwndControl,
  2519. &lvItem))
  2520. {
  2521. pCertWizardInfo->dwProviderType=pCertWizardInfo->rgdwProviderType[(DWORD)(lvItem.lParam)];
  2522. pCertWizardInfo->pwszProvider=pCertWizardInfo->rgwszProvider[(DWORD)(lvItem.lParam)];
  2523. }
  2524. else
  2525. {
  2526. I_MessageBox(hwndDlg, IDS_NO_SELECTED_CSP,
  2527. pCertWizardInfo->idsConfirmTitle,
  2528. pCertWizardInfo->pwszConfirmationTitle,
  2529. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  2530. //make the purpose page stay
  2531. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  2532. break;
  2533. }
  2534. }
  2535. else
  2536. {
  2537. I_MessageBox(hwndDlg, IDS_NO_SELECTED_CSP,
  2538. pCertWizardInfo->idsConfirmTitle,
  2539. pCertWizardInfo->pwszConfirmationTitle,
  2540. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  2541. //make the purpose page stay
  2542. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  2543. break;
  2544. }
  2545. //skip to the correct page based on the advanced options and CSP requirement
  2546. if(FALSE == pCertWizardInfo->fUIAdv)
  2547. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_RENEW_COMPLETION);
  2548. break;
  2549. default:
  2550. return FALSE;
  2551. }
  2552. break;
  2553. default:
  2554. return FALSE;
  2555. }
  2556. return TRUE;
  2557. }
  2558. //-----------------------------------------------------------------------
  2559. //Renew_CA
  2560. //-----------------------------------------------------------------------
  2561. INT_PTR APIENTRY Renew_CA(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  2562. {
  2563. CERT_WIZARD_INFO *pCertWizardInfo=NULL;
  2564. PROPSHEETPAGE *pPropSheet=NULL;
  2565. DWORD dwChar=0;
  2566. PCRYPTUI_CA_CONTEXT pCAContext=NULL;
  2567. LPWSTR pwszCADisplayName=NULL;
  2568. HCURSOR hPreCursor=NULL;
  2569. HCURSOR hWinPreCursor=NULL;
  2570. switch (msg)
  2571. {
  2572. case WM_INITDIALOG:
  2573. //set the wizard information so that it can be shared
  2574. pPropSheet = (PROPSHEETPAGE *) lParam;
  2575. pCertWizardInfo = (CERT_WIZARD_INFO *) (pPropSheet->lParam);
  2576. SetControlFont(pCertWizardInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
  2577. //make sure pCertWizardInfo is a valid pointer
  2578. if(NULL==pCertWizardInfo)
  2579. break;
  2580. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertWizardInfo);
  2581. //init the CA name and CA location
  2582. if(pCertWizardInfo->pwszCALocation)
  2583. SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT2,pCertWizardInfo->pwszCALocation);
  2584. if(pCertWizardInfo->pwszCAName)
  2585. {
  2586. //overwrite the cursor for this window class
  2587. hWinPreCursor=(HCURSOR)SetClassLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)NULL);
  2588. hPreCursor=SetCursor(LoadCursor(NULL, IDC_WAIT));
  2589. if(CAUtilGetCADisplayName((pCertWizardInfo->fMachine) ? CA_FIND_LOCAL_SYSTEM:0,
  2590. pCertWizardInfo->pwszCAName,
  2591. &pwszCADisplayName))
  2592. {
  2593. SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,pwszCADisplayName);
  2594. WizardFree(pwszCADisplayName);
  2595. pwszCADisplayName=NULL;
  2596. }
  2597. else
  2598. SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,pCertWizardInfo->pwszCAName);
  2599. //set the cursor back
  2600. SetCursor(hPreCursor);
  2601. SetWindowLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)hWinPreCursor);
  2602. }
  2603. break;
  2604. case WM_COMMAND:
  2605. if(HIWORD(wParam) == BN_CLICKED)
  2606. {
  2607. switch (LOWORD(wParam))
  2608. {
  2609. case IDC_WIZARD_BUTTON1:
  2610. if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  2611. break;
  2612. //overwrite the cursor for this window class
  2613. hWinPreCursor=(HCURSOR)SetClassLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)NULL);
  2614. hPreCursor=SetCursor(LoadCursor(NULL, IDC_WAIT));
  2615. //call the CA selection dialogue
  2616. pCAContext=GetCAContext(hwndDlg, pCertWizardInfo);
  2617. //set the cursor back
  2618. SetCursor(hPreCursor);
  2619. SetWindowLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)hWinPreCursor);
  2620. if(pCAContext)
  2621. {
  2622. //update the edit box
  2623. if(pCAContext->pwszCAMachineName)
  2624. SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT2,pCAContext->pwszCAMachineName);
  2625. if(pCAContext->pwszCAName)
  2626. SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,pCAContext->pwszCAName);
  2627. //free the CA context
  2628. CryptUIDlgFreeCAContext(pCAContext);
  2629. pCAContext=NULL;
  2630. }
  2631. break;
  2632. default:
  2633. break;
  2634. }
  2635. }
  2636. break;
  2637. case WM_NOTIFY:
  2638. switch (((NMHDR FAR *) lParam)->code)
  2639. {
  2640. case PSN_KILLACTIVE:
  2641. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  2642. return TRUE;
  2643. break;
  2644. case PSN_RESET:
  2645. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  2646. break;
  2647. case PSN_SETACTIVE:
  2648. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
  2649. break;
  2650. case PSN_WIZBACK:
  2651. if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  2652. break;
  2653. //skip to the correct page based on the advanced options and CSP requirement
  2654. if(FALSE == pCertWizardInfo->fNewKey)
  2655. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_RENEW_OPTIONS);
  2656. break;
  2657. case PSN_WIZNEXT:
  2658. if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  2659. break;
  2660. //cach the display name of the CA
  2661. if(0!=(dwChar=(DWORD)SendDlgItemMessage(hwndDlg,
  2662. IDC_WIZARD_EDIT1,
  2663. WM_GETTEXTLENGTH, 0, 0)))
  2664. {
  2665. if(pCertWizardInfo->pwszCADisplayName)
  2666. {
  2667. WizardFree(pCertWizardInfo->pwszCADisplayName);
  2668. pCertWizardInfo->pwszCADisplayName = NULL;
  2669. }
  2670. pCertWizardInfo->pwszCADisplayName=(LPWSTR)WizardAlloc(sizeof(WCHAR)*(dwChar+1));
  2671. if(NULL!=(pCertWizardInfo->pwszCADisplayName))
  2672. {
  2673. GetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,
  2674. pCertWizardInfo->pwszCADisplayName,
  2675. dwChar+1);
  2676. }
  2677. }
  2678. break;
  2679. default:
  2680. return FALSE;
  2681. }
  2682. break;
  2683. default:
  2684. return FALSE;
  2685. }
  2686. return TRUE;
  2687. }
  2688. //-----------------------------------------------------------------------
  2689. // Renew_Completion
  2690. //-----------------------------------------------------------------------
  2691. INT_PTR APIENTRY Renew_Completion(HWND hwndDlg, UINT msg, WPARAM /*wParam*/, LPARAM lParam)
  2692. {
  2693. CERT_WIZARD_INFO *pCertWizardInfo=NULL;
  2694. PROPSHEETPAGE *pPropSheet=NULL;
  2695. HWND hwndControl=NULL;
  2696. LV_COLUMNW lvC;
  2697. HCURSOR hPreCursor=NULL;
  2698. HCURSOR hWinPreCursor=NULL;
  2699. switch (msg)
  2700. {
  2701. case WM_INITDIALOG:
  2702. //set the wizard information so that it can be shared
  2703. pPropSheet = (PROPSHEETPAGE *) lParam;
  2704. pCertWizardInfo = (CERT_WIZARD_INFO *) (pPropSheet->lParam);
  2705. //make sure pCertWizardInfo is a valid pointer
  2706. if(NULL==pCertWizardInfo)
  2707. break;
  2708. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertWizardInfo);
  2709. SetControlFont(pCertWizardInfo->hBigBold, hwndDlg,IDC_WIZARD_STATIC_BIG_BOLD1);
  2710. //insert two columns
  2711. hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1);
  2712. memset(&lvC, 0, sizeof(LV_COLUMNW));
  2713. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  2714. lvC.fmt = LVCFMT_LEFT; // Left-align the column.
  2715. lvC.cx = 20; // Width of the column, in pixels.
  2716. lvC.pszText = L""; // The text for the column.
  2717. lvC.iSubItem=0;
  2718. if (ListView_InsertColumnU(hwndControl, 0, &lvC) == -1)
  2719. break;
  2720. //2nd column is the content
  2721. memset(&lvC, 0, sizeof(LV_COLUMNW));
  2722. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  2723. lvC.fmt = LVCFMT_LEFT; // Left-align the column.
  2724. lvC.cx = 10; //(dwMaxSize+2)*7; // Width of the column, in pixels.
  2725. lvC.pszText = L""; // The text for the column.
  2726. lvC.iSubItem= 1;
  2727. if (ListView_InsertColumnU(hwndControl, 1, &lvC) == -1)
  2728. break;
  2729. break;
  2730. case WM_COMMAND:
  2731. break;
  2732. case WM_NOTIFY:
  2733. switch (((NMHDR FAR *) lParam)->code)
  2734. {
  2735. case PSN_KILLACTIVE:
  2736. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  2737. return TRUE;
  2738. break;
  2739. case PSN_RESET:
  2740. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  2741. break;
  2742. case PSN_SETACTIVE:
  2743. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK|PSWIZB_FINISH);
  2744. if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  2745. break;
  2746. //overwrite the cursor for this window class
  2747. hWinPreCursor=(HCURSOR)SetClassLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)NULL);
  2748. hPreCursor=SetCursor(LoadCursor(NULL, IDC_WAIT));
  2749. //populate the list box in the order of
  2750. //UserName, CSP, and Publish to the DS
  2751. //Get the window handle for the CSP list
  2752. if(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1))
  2753. DisplayConfirmation(hwndControl, pCertWizardInfo);
  2754. //set the cursor back
  2755. SetCursor(hPreCursor);
  2756. SetWindowLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)hWinPreCursor);
  2757. break;
  2758. case PSN_WIZBACK:
  2759. if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  2760. break;
  2761. //skip to the correct page based on the advanced options and CSP requirement
  2762. if(FALSE == pCertWizardInfo->fUIAdv)
  2763. {
  2764. if(TRUE == pCertWizardInfo->fUICSP)
  2765. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_RENEW_SERVICE_PROVIDER);
  2766. else
  2767. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_RENEW_OPTIONS);
  2768. }
  2769. break;
  2770. case PSN_WIZFINISH:
  2771. {
  2772. CertRequester *pCertRequester = NULL;
  2773. CertRequesterContext *pCertRequesterContext = NULL;
  2774. if(NULL==(pCertWizardInfo=(CERT_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  2775. break;
  2776. //overwrite the cursor for this window class
  2777. hWinPreCursor=(HCURSOR)SetClassLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)NULL);
  2778. hPreCursor=SetCursor(LoadCursor(NULL, IDC_WAIT));
  2779. //set the parent window to the hwndDlg so that
  2780. //confirmat to install dlg use hwndDlg as the
  2781. //parent window
  2782. pCertWizardInfo->hwndParent=hwndDlg;
  2783. if (NULL == (pCertRequester = (CertRequester *) pCertWizardInfo->hRequester))
  2784. break;
  2785. if (NULL == (pCertRequesterContext = pCertRequester->GetContext()))
  2786. break;
  2787. //call the enrollment wizard
  2788. pCertWizardInfo->hr = pCertRequesterContext->Enroll(&(pCertWizardInfo->dwStatus), (HANDLE *)&(pCertWizardInfo->pNewCertContext));
  2789. if (0 == pCertWizardInfo->idsText) {
  2790. pCertWizardInfo->idsText = CryptUIStatusToIDSText(pCertWizardInfo->hr, pCertWizardInfo->dwStatus);
  2791. }
  2792. if(S_OK != pCertWizardInfo->hr)
  2793. break;
  2794. //set the cursor back
  2795. SetCursor(hPreCursor);
  2796. SetWindowLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)hWinPreCursor);
  2797. }
  2798. break;
  2799. default:
  2800. return FALSE;
  2801. }
  2802. break;
  2803. default:
  2804. return FALSE;
  2805. }
  2806. return TRUE;
  2807. }
  2808. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2809. //
  2810. // Two-stage no-DS entry point for certificate enrollment and renewal.
  2811. //
  2812. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2813. BOOL
  2814. WINAPI
  2815. CryptUIWizCreateCertRequestNoDS
  2816. (IN DWORD dwFlags,
  2817. IN HWND hwndParent,
  2818. IN PCCRYPTUI_WIZ_CREATE_CERT_REQUEST_INFO pCreateCertRequestInfo,
  2819. OUT HANDLE *phRequest)
  2820. {
  2821. BOOL fAllocateCSP = FALSE;
  2822. BOOL fResult = FALSE;
  2823. CertRequester *pCertRequester = NULL;
  2824. CertRequesterContext *pCertRequesterContext = NULL;
  2825. CERT_WIZARD_INFO CertWizardInfo;
  2826. CRYPT_KEY_PROV_INFO *pKeyProvInfo = NULL;
  2827. LPWSTR pwszAllocatedCSP = NULL;
  2828. LPWSTR pwszMachineName = NULL;
  2829. UINT idsText = IDS_INVALID_INFO_FOR_PKCS10;
  2830. // STATIC INITIALIZATION: initialize our object factory.
  2831. #if DBG
  2832. assert(NULL == g_pEnrollFactory);
  2833. #endif
  2834. // Initialization:
  2835. memset(&CertWizardInfo, 0, sizeof(CertWizardInfo));
  2836. *phRequest = NULL;
  2837. g_pEnrollFactory = new EnrollmentCOMObjectFactory;
  2838. if (NULL == g_pEnrollFactory)
  2839. goto MemoryErr;
  2840. // Input validation:
  2841. if (NULL == pCreateCertRequestInfo || NULL == phRequest)
  2842. goto InvalidArgErr;
  2843. if (pCreateCertRequestInfo->dwSize != sizeof(CRYPTUI_WIZ_CREATE_CERT_REQUEST_INFO))
  2844. goto InvalidArgErr;
  2845. if ((pCreateCertRequestInfo->dwPurpose != CRYPTUI_WIZ_CERT_ENROLL) &&
  2846. (pCreateCertRequestInfo->dwPurpose != CRYPTUI_WIZ_CERT_RENEW))
  2847. goto InvalidArgErr;
  2848. if (0 == (CRYPTUI_WIZ_NO_UI & dwFlags))
  2849. goto InvalidArgErr;
  2850. if (pCreateCertRequestInfo->fMachineContext)
  2851. {
  2852. dwFlags |= CRYPTUI_WIZ_NO_INSTALL_ROOT;
  2853. pwszMachineName = (LPWSTR)WizardAlloc(sizeof(WCHAR) * (MAX_COMPUTERNAME_LENGTH+1));
  2854. if (NULL == pwszMachineName)
  2855. goto MemoryErr;
  2856. DWORD dwSize = MAX_COMPUTERNAME_LENGTH+1;
  2857. if (!GetComputerNameU(pwszMachineName, &dwSize))
  2858. {
  2859. idsText = IDS_FAIL_TO_GET_COMPUTER_NAME;
  2860. goto GetComputerNameUError;
  2861. }
  2862. }
  2863. // Copy the dwFlags.
  2864. CertWizardInfo.dwFlags = dwFlags;
  2865. if (S_OK != (CertRequester::MakeCertRequester
  2866. (NULL,
  2867. pwszMachineName,
  2868. pCreateCertRequestInfo->dwCertOpenStoreFlag,
  2869. pCreateCertRequestInfo->dwPurpose,
  2870. &CertWizardInfo,
  2871. &pCertRequester,
  2872. &idsText)))
  2873. goto InvalidArgErr;
  2874. pCertRequesterContext = pCertRequester->GetContext();
  2875. // We can pass in a parent hwnd -- however, this is used only
  2876. // as the parent of CSP ui:
  2877. if (NULL != hwndParent)
  2878. {
  2879. if ((0 == (CRYPTUI_WIZ_NO_UI & dwFlags)) ||
  2880. (0 != (CRYPTUI_WIZ_IGNORE_NO_UI_FLAG_FOR_CSPS & dwFlags)))
  2881. {
  2882. if (!CryptSetProvParam(0 /*all CSPs*/, PP_CLIENT_HWND, (LPBYTE)&hwndParent, sizeof(hwndParent)))
  2883. {
  2884. goto CryptSetProvParamError;
  2885. }
  2886. }
  2887. }
  2888. // We're not using the wizard UI, so we don't need to change the cursor.
  2889. CertWizardInfo.fCursorChanged = FALSE;
  2890. // Enroll or renew
  2891. CertWizardInfo.dwPurpose = pCreateCertRequestInfo->dwPurpose;
  2892. // The CA name and location must be provided:
  2893. CertWizardInfo.fCAInput = TRUE;
  2894. if(NULL == pCreateCertRequestInfo->pwszCALocation || NULL == pCreateCertRequestInfo->pwszCAName)
  2895. goto InvalidArgErr;
  2896. CertWizardInfo.pwszCALocation = (LPWSTR)pCreateCertRequestInfo->pwszCALocation;
  2897. CertWizardInfo.pwszCAName = (LPWSTR)pCreateCertRequestInfo->pwszCAName;
  2898. // We always enroll for certs in our current context:
  2899. CertWizardInfo.fLocal = TRUE;
  2900. if (!CheckPVKInfoNoDS
  2901. (dwFlags,
  2902. pCreateCertRequestInfo->dwPvkChoice,
  2903. pCreateCertRequestInfo->pPvkCert,
  2904. pCreateCertRequestInfo->pPvkNew,
  2905. pCreateCertRequestInfo->pPvkExisting,
  2906. CRYPTUI_WIZ_CERT_REQUEST_CERT_TYPE,
  2907. &CertWizardInfo,
  2908. &pKeyProvInfo))
  2909. goto InvalidArgErr;
  2910. //make sure the CSP selected is supported by the local machine
  2911. //populate the pwszProvider in CertWizardInfo if it is NULL
  2912. if (S_OK != pCertRequesterContext->GetDefaultCSP(&fAllocateCSP))
  2913. {
  2914. idsText = pCertRequesterContext->GetErrorString();
  2915. goto InvalidArgErr;
  2916. }
  2917. if (fAllocateCSP)
  2918. pwszAllocatedCSP = CertWizardInfo.pwszProvider;
  2919. if (S_OK != pCertRequesterContext->BuildCSPList())
  2920. {
  2921. idsText = IDS_FAIL_TO_GET_CSP_LIST;
  2922. goto TraceErr;
  2923. }
  2924. if (0 != CertWizardInfo.dwProviderType || NULL != CertWizardInfo.pwszProvider)
  2925. {
  2926. if (!CSPSupported(&CertWizardInfo))
  2927. {
  2928. idsText = IDS_CSP_NOT_SUPPORTED;
  2929. goto InvalidArgErr;
  2930. }
  2931. }
  2932. //set it see if the provider is known
  2933. if(NULL != CertWizardInfo.pwszProvider)
  2934. {
  2935. CertWizardInfo.fKnownCSP = TRUE;
  2936. CertWizardInfo.dwOrgCSPType = CertWizardInfo.dwProviderType;
  2937. CertWizardInfo.pwszOrgCSPName = CertWizardInfo.pwszProvider;
  2938. }
  2939. else
  2940. {
  2941. CertWizardInfo.fKnownCSP=FALSE;
  2942. }
  2943. //check the dwCertChoice for the enroll case
  2944. if(CRYPTUI_WIZ_CERT_ENROLL & (pCreateCertRequestInfo->dwPurpose))
  2945. {
  2946. // We're enrolling based on cert type.
  2947. // Check that we have a valid cert type:
  2948. if(!CAUtilValidCertTypeNoDS(pCreateCertRequestInfo->hCertType, // The cert type we'll use to enroll.
  2949. NULL, // The DN Name of the cert type. We don't know it.
  2950. &CertWizardInfo // Our wizard info.
  2951. ))
  2952. {
  2953. idsText=IDS_NO_PERMISSION_FOR_CERTTYPE;
  2954. goto CheckCertTypeErr;
  2955. }
  2956. }
  2957. if (pCreateCertRequestInfo->dwPurpose & CRYPTUI_WIZ_CERT_RENEW)
  2958. {
  2959. DWORD dwSize;
  2960. CertWizardInfo.pCertContext = pCreateCertRequestInfo->pRenewCertContext;
  2961. //the certificate has to have the property
  2962. if(!CertGetCertificateContextProperty
  2963. (CertWizardInfo.pCertContext,
  2964. CERT_KEY_PROV_INFO_PROP_ID,
  2965. NULL,
  2966. &dwSize) || (0==dwSize))
  2967. {
  2968. idsText=IDS_NO_PVK_FOR_RENEW_CERT;
  2969. goto InvalidArgErr;
  2970. }
  2971. }
  2972. //reset the initial ids valud
  2973. idsText=IDS_INVALID_INFO_FOR_PKCS10;
  2974. fResult = CreateCertRequestNoSearchCANoDS
  2975. (&CertWizardInfo,
  2976. dwFlags,
  2977. pCreateCertRequestInfo->hCertType,
  2978. phRequest);
  2979. if(FALSE==fResult)
  2980. goto CertRequestErr;
  2981. // Save the machine name with the request handle:
  2982. ((PCREATE_REQUEST_WIZARD_STATE)*phRequest)->pwszMachineName = pwszMachineName;
  2983. ((PCREATE_REQUEST_WIZARD_STATE)*phRequest)->dwStoreFlags = CertWizardInfo.dwStoreFlags;
  2984. pwszMachineName = NULL;
  2985. fResult=TRUE;
  2986. CommonReturn:
  2987. if (NULL != pKeyProvInfo) { WizardFree(pKeyProvInfo); }
  2988. if (fAllocateCSP && NULL != pwszAllocatedCSP) { WizardFree(pwszAllocatedCSP); }
  2989. if (NULL != pwszMachineName) { WizardFree(pwszMachineName); }
  2990. if (NULL != pCertRequester) { delete(pCertRequester); }
  2991. if (NULL != g_pEnrollFactory)
  2992. {
  2993. delete g_pEnrollFactory;
  2994. g_pEnrollFactory = NULL;
  2995. }
  2996. FreeProviders(CertWizardInfo.dwCSPCount,
  2997. CertWizardInfo.rgdwProviderType,
  2998. CertWizardInfo.rgwszProvider);
  2999. return fResult;
  3000. ErrorReturn:
  3001. fResult = FALSE;
  3002. goto CommonReturn;
  3003. SET_ERROR(InvalidArgErr, ERROR_INVALID_PARAMETER);
  3004. SET_ERROR(MemoryErr, ERROR_NOT_ENOUGH_MEMORY);
  3005. TRACE_ERROR(CryptSetProvParamError);
  3006. TRACE_ERROR(CertRequestErr);
  3007. TRACE_ERROR(CheckCertTypeErr);
  3008. TRACE_ERROR(GetComputerNameUError);
  3009. TRACE_ERROR(TraceErr);
  3010. }
  3011. BOOL
  3012. WINAPI
  3013. CryptUIWizSubmitCertRequestNoDS
  3014. (IN HANDLE hRequest,
  3015. IN HWND hwndParent,
  3016. IN LPCWSTR pwszCAName,
  3017. IN LPCWSTR pwszCALocation,
  3018. OUT DWORD *pdwStatus,
  3019. OUT PCCERT_CONTEXT *ppCertContext // Optional
  3020. )
  3021. {
  3022. BOOL fResult;
  3023. // STATIC INITIALIZATION: initialize our object factory
  3024. #if DBG
  3025. assert(NULL == g_pEnrollFactory);
  3026. #endif
  3027. g_pEnrollFactory = new EnrollmentCOMObjectFactory;
  3028. if (NULL == g_pEnrollFactory)
  3029. goto MemoryErr;
  3030. // We can pass in a parent hwnd -- however, this is used only
  3031. // as the parent of CSP ui:
  3032. if (NULL != hwndParent)
  3033. {
  3034. if (!CryptSetProvParam(0 /*all CSPs*/, PP_CLIENT_HWND, (LPBYTE)&hwndParent, sizeof(hwndParent)))
  3035. {
  3036. goto CryptSetProvParamError;
  3037. }
  3038. }
  3039. fResult = SubmitCertRequestNoSearchCANoDS
  3040. (hRequest,
  3041. pwszCAName,
  3042. pwszCALocation,
  3043. pdwStatus,
  3044. ppCertContext);
  3045. CommonReturn:
  3046. if (NULL != g_pEnrollFactory)
  3047. {
  3048. delete g_pEnrollFactory;
  3049. g_pEnrollFactory = NULL;
  3050. }
  3051. return fResult;
  3052. ErrorReturn:
  3053. fResult = FALSE;
  3054. goto CommonReturn;
  3055. TRACE_ERROR(CryptSetProvParamError);
  3056. SET_ERROR(MemoryErr, ERROR_NOT_ENOUGH_MEMORY);
  3057. }
  3058. void
  3059. WINAPI
  3060. CryptUIWizFreeCertRequestNoDS
  3061. (IN HANDLE hRequest)
  3062. {
  3063. // STATIC INITIALIZATION: initialize our object factory
  3064. #if DBG
  3065. assert(NULL == g_pEnrollFactory);
  3066. #endif
  3067. g_pEnrollFactory = new EnrollmentCOMObjectFactory;
  3068. if (NULL == g_pEnrollFactory)
  3069. return; // Not much we can do about this ...
  3070. FreeCertRequestNoSearchCANoDS(hRequest);
  3071. if (NULL != g_pEnrollFactory)
  3072. {
  3073. delete g_pEnrollFactory;
  3074. g_pEnrollFactory = NULL;
  3075. }
  3076. }
  3077. BOOL
  3078. WINAPI
  3079. CryptUIWizQueryCertRequestNoDS
  3080. (IN HANDLE hRequest, OUT CRYPTUI_WIZ_QUERY_CERT_REQUEST_INFO *pQueryInfo)
  3081. {
  3082. BOOL fResult;
  3083. CERT_WIZARD_INFO CertWizardInfo;
  3084. CertRequester *pCertRequester;
  3085. HRESULT hr;
  3086. PCREATE_REQUEST_WIZARD_STATE pState;
  3087. UINT idsText;
  3088. if (NULL == hRequest || NULL == pQueryInfo)
  3089. goto InvalidArgErr;
  3090. memset(&CertWizardInfo, 0, sizeof(CertWizardInfo));
  3091. // Specify this set of flags to indicate that cryptui doesn't need to prepare
  3092. // access check information. Doing so could cause lots of extraneous logoff/logon events.
  3093. CertWizardInfo.dwFlags = CRYPTUI_WIZ_ALLOW_ALL_TEMPLATES | CRYPTUI_WIZ_ALLOW_ALL_CAS;
  3094. pState = (PCREATE_REQUEST_WIZARD_STATE)hRequest;
  3095. if (S_OK != (hr = CertRequester::MakeCertRequester
  3096. (NULL,
  3097. pState->pwszMachineName,
  3098. pState->dwStoreFlags,
  3099. pState->dwPurpose,
  3100. &CertWizardInfo,
  3101. &pCertRequester,
  3102. &idsText
  3103. )))
  3104. goto MakeCertRequesterErr;
  3105. if (S_OK != (hr = pCertRequester->GetContext()->QueryRequestStatus(pState->hRequest, pQueryInfo)))
  3106. goto QueryRequestStatusErr;
  3107. fResult = TRUE;
  3108. CommonReturn:
  3109. return fResult;
  3110. ErrorReturn:
  3111. fResult = FALSE;
  3112. goto CommonReturn;
  3113. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  3114. SET_ERROR(MakeCertRequesterErr, hr);
  3115. SET_ERROR(QueryRequestStatusErr, hr);
  3116. }
  3117. HRESULT getTemplateName(PCCERT_CONTEXT pCertContext, LPWSTR *ppwszName) {
  3118. CERT_NAME_VALUE *pCertTemplateNameValue = NULL;
  3119. DWORD cbCertTemplateNameValue;
  3120. DWORD cbRequired;
  3121. HRESULT hr = S_OK;
  3122. PCERT_EXTENSION pCertTemplateExtension = NULL;
  3123. if (NULL == (pCertTemplateExtension = CertFindExtension
  3124. (szOID_ENROLL_CERTTYPE_EXTENSION,
  3125. pCertContext->pCertInfo->cExtension,
  3126. pCertContext->pCertInfo->rgExtension)))
  3127. goto CertFindExtensionError;
  3128. if (!CryptDecodeObject
  3129. (pCertContext->dwCertEncodingType,
  3130. X509_UNICODE_ANY_STRING,
  3131. pCertTemplateExtension->Value.pbData,
  3132. pCertTemplateExtension->Value.cbData,
  3133. 0,
  3134. NULL,
  3135. &cbCertTemplateNameValue) || (cbCertTemplateNameValue == 0))
  3136. goto CryptDecodeObjectError;
  3137. pCertTemplateNameValue = (CERT_NAME_VALUE *)WizardAlloc(cbCertTemplateNameValue);
  3138. if (NULL == pCertTemplateNameValue)
  3139. goto MemoryErr;
  3140. if (!CryptDecodeObject
  3141. (pCertContext->dwCertEncodingType,
  3142. X509_UNICODE_ANY_STRING,
  3143. pCertTemplateExtension->Value.pbData,
  3144. pCertTemplateExtension->Value.cbData,
  3145. 0,
  3146. (void *)(pCertTemplateNameValue),
  3147. &cbCertTemplateNameValue))
  3148. goto CryptDecodeObjectError;
  3149. cbRequired = sizeof(WCHAR) * (wcslen((LPWSTR)(pCertTemplateNameValue->Value.pbData)) + 1);
  3150. *ppwszName = (LPWSTR)WizardAlloc(cbRequired);
  3151. if (NULL == *ppwszName)
  3152. goto MemoryErr;
  3153. // Assign the OUT parameter:
  3154. wcscpy(*ppwszName, (LPWSTR)(pCertTemplateNameValue->Value.pbData));
  3155. hr = S_OK;
  3156. ErrorReturn:
  3157. if (NULL != pCertTemplateNameValue) { WizardFree(pCertTemplateNameValue); }
  3158. return hr;
  3159. SET_HRESULT(CertFindExtensionError, HRESULT_FROM_WIN32(GetLastError()));
  3160. SET_HRESULT(CryptDecodeObjectError, HRESULT_FROM_WIN32(GetLastError()));
  3161. SET_HRESULT(MemoryErr, E_OUTOFMEMORY);
  3162. }
  3163. HRESULT decodeTemplateOID(PCERT_EXTENSION pCertExtension, LPSTR *ppszOID, DWORD dwEncodingType) {
  3164. CERT_TEMPLATE_EXT *pCertTemplateExt = NULL;
  3165. DWORD cbCertTemplateExt = 0;
  3166. DWORD cbRequired;
  3167. HRESULT hr;
  3168. if (FALSE == CryptDecodeObject
  3169. (dwEncodingType,
  3170. X509_CERTIFICATE_TEMPLATE,
  3171. pCertExtension->Value.pbData,
  3172. pCertExtension->Value.cbData,
  3173. 0,
  3174. NULL,
  3175. &cbCertTemplateExt) || (cbCertTemplateExt == 0))
  3176. goto CryptDecodeObjectError;
  3177. pCertTemplateExt = (CERT_TEMPLATE_EXT *)WizardAlloc(cbCertTemplateExt);
  3178. if (NULL == pCertTemplateExt)
  3179. goto MemoryErr;
  3180. if (FALSE == CryptDecodeObject
  3181. (dwEncodingType,
  3182. X509_CERTIFICATE_TEMPLATE,
  3183. pCertExtension->Value.pbData,
  3184. pCertExtension->Value.cbData,
  3185. 0,
  3186. (void *)(pCertTemplateExt),
  3187. &cbCertTemplateExt))
  3188. goto CryptDecodeObjectError;
  3189. cbRequired = strlen(pCertTemplateExt->pszObjId) + sizeof(CHAR);
  3190. *ppszOID = (LPSTR)WizardAlloc(cbRequired);
  3191. if (NULL == *ppszOID)
  3192. goto MemoryErr;
  3193. strcpy(*ppszOID, pCertTemplateExt->pszObjId);
  3194. hr = S_OK;
  3195. ErrorReturn:
  3196. if (NULL != pCertTemplateExt) { LocalFree(pCertTemplateExt); }
  3197. return hr;
  3198. SET_HRESULT(CryptDecodeObjectError, HRESULT_FROM_WIN32(GetLastError()));
  3199. SET_HRESULT(MemoryErr, E_OUTOFMEMORY);
  3200. }
  3201. HRESULT getTemplateOID(PCCERT_CONTEXT pCertContext, LPSTR *ppszOID) {
  3202. HRESULT hr;
  3203. PCERT_EXTENSION pCertExtension = NULL;
  3204. if (NULL == (pCertExtension = CertFindExtension
  3205. (szOID_CERTIFICATE_TEMPLATE,
  3206. pCertContext->pCertInfo->cExtension,
  3207. pCertContext->pCertInfo->rgExtension)))
  3208. goto CertFindExtensionError;
  3209. hr = decodeTemplateOID(pCertExtension, ppszOID, pCertContext->dwCertEncodingType);
  3210. ErrorReturn:
  3211. return hr;
  3212. SET_HRESULT(CertFindExtensionError, HRESULT_FROM_WIN32(GetLastError()));
  3213. }
  3214. BOOL ContainsCertTemplateOid(PCERT_EXTENSIONS pCertExtensions, LPWSTR pwszTemplateOid)
  3215. {
  3216. BOOL fResult = FALSE;
  3217. LPSTR pszOid = NULL;
  3218. LPWSTR pwszOid = NULL;
  3219. PCERT_EXTENSION pCertExtension = NULL;
  3220. if (NULL == (pCertExtension = CertFindExtension(szOID_CERTIFICATE_TEMPLATE, pCertExtensions->cExtension, pCertExtensions->rgExtension)))
  3221. goto CertFindExtensionError;
  3222. if (S_OK != decodeTemplateOID(pCertExtension, &pszOid, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING))
  3223. goto decodeTemplateOIDError;
  3224. if (S_OK != WizardSZToWSZ(pszOid, &pwszOid))
  3225. goto MemoryError;
  3226. fResult = 0 == wcscmp(pwszOid, pwszTemplateOid);
  3227. ErrorReturn:
  3228. if (NULL != pszOid) { WizardFree(pszOid); }
  3229. if (NULL != pwszOid) { WizardFree(pwszOid); }
  3230. return fResult;
  3231. TRACE_ERROR(CertFindExtensionError);
  3232. TRACE_ERROR(decodeTemplateOIDError);
  3233. TRACE_ERROR(MemoryError);
  3234. }
  3235. //********************************************************************************
  3236. // Enrollment and renew
  3237. //
  3238. // UI or ULless dll entry points
  3239. //
  3240. //
  3241. //********************************************************************************
  3242. //-----------------------------------------------------------------------
  3243. //
  3244. // CryptUIWizCertRequest
  3245. //
  3246. // Request a certificate via a wizard.
  3247. //
  3248. // dwFlags: IN Required
  3249. // If CRYPTUI_WIZ_NO_UI is set in dwFlags, no UI will be shown.
  3250. //
  3251. // hwndParent: IN Optional
  3252. // The parent window for the UI. Ignored if CRYPTUI_WIZ_NO_UI is set in dwFlags
  3253. //
  3254. // pwszWizardTitle: IN Optional
  3255. // The title of the wizard. Ignored if CRYPTUI_WIZ_NO_UI is set in dwFlags
  3256. //
  3257. // pCertRequestInfo: IN Required
  3258. // A pointer to CRYPTUI_WIZ_CERT_REQUEST_INFO struct
  3259. //
  3260. // ppCertContext: Out Optional
  3261. // The enrolled certificate. The certificate is in a memory store.
  3262. //
  3263. // pdwStatus: Out Optional.
  3264. // The return status of the certificate cerver. The dwStatus can be one of
  3265. /// the following:
  3266. // CRYPTUI_WIZ_CERT_REQUEST_STATUS_SUCCEEDED
  3267. // CRYPTUI_WIZ_CERT_REQUEST_STATUS_REQUEST_ERROR
  3268. // CRYPTUI_WIZ_CERT_REQUEST_STATUS_REQUEST_DENIED
  3269. // CRYPTUI_WIZ_CERT_REQUEST_STATUS_ISSUED_SEPERATELY
  3270. // CRYPTUI_WIZ_CERT_REQUEST_STATUS_UNDER_SUBMISSION
  3271. //------------------------------------------------------------------------
  3272. BOOL
  3273. WINAPI
  3274. CryptUIWizCertRequest(
  3275. IN DWORD dwFlags,
  3276. IN OPTIONAL HWND hwndParent, //IN Optional: The parent window handle
  3277. IN OPTIONAL LPCWSTR pwszWizardTitle, //IN Optional: The title of the wizard
  3278. IN PCCRYPTUI_WIZ_CERT_REQUEST_INFO pRequestInfo,
  3279. OUT OPTIONAL PCCERT_CONTEXT *ppCertContext, //OUT Optional: The enrolled certificate. The certificate is in a
  3280. OUT OPTIONAL DWORD *pdwStatus //OUT Optional: The status of the certificate request
  3281. )
  3282. {
  3283. BOOL fResult=FALSE;
  3284. DWORD dwLastError=ERROR_SUCCESS;
  3285. UINT idsText=IDS_INVALID_INFO_FOR_PKCS10;
  3286. CERT_WIZARD_INFO CertWizardInfo;
  3287. CertRequester *pCertRequester = NULL;
  3288. CertRequesterContext *pCertRequesterContext = NULL;
  3289. BOOL fAllocateCSP=FALSE;
  3290. LPWSTR pwszAllocatedCSP=NULL;
  3291. PCERT_ENHKEY_USAGE pEKUsage=NULL;
  3292. HRESULT hr;
  3293. UINT uMsgType=MB_OK|MB_ICONINFORMATION;
  3294. CRYPT_KEY_PROV_INFO *pKeyProvInfo=NULL;
  3295. DWORD dwCertChoice=0;
  3296. void *pData=NULL;
  3297. CRYPTUI_WIZ_CERT_TYPE CertType;
  3298. CERT_NAME_VALUE *pCertType=NULL;
  3299. BOOL fResetCertType=FALSE;
  3300. LPWSTR pwszCTName=NULL;
  3301. CRYPTUI_WIZ_CERT_TYPE CertTypeInfo;
  3302. CRYPTUI_WIZ_CERT_REQUEST_INFO CertRequestInfoStruct;
  3303. PCCRYPTUI_WIZ_CERT_REQUEST_INFO pCertRequestInfo=NULL;
  3304. //memset
  3305. memset(&CertWizardInfo, 0, sizeof(CertWizardInfo));
  3306. memset(&CertTypeInfo, 0, sizeof(CertTypeInfo));
  3307. memset(&CertRequestInfoStruct, 0, sizeof(CRYPTUI_WIZ_CERT_REQUEST_INFO));
  3308. memset(&CertType, 0, sizeof(CertType));
  3309. // STATIC INITIALIZATION: initialize our object factory
  3310. #if DBG
  3311. assert(NULL == g_pEnrollFactory);
  3312. #endif
  3313. g_pEnrollFactory = new EnrollmentCOMObjectFactory;
  3314. if (NULL == g_pEnrollFactory)
  3315. goto MemoryErr;
  3316. //we need to make our own copy of the input data because we will have to change
  3317. //the struct for:
  3318. //1. Renew case
  3319. //2. Map the input cert type name to the REAL GUID- defined cert type name
  3320. pCertRequestInfo=&CertRequestInfoStruct;
  3321. memcpy((void *)pCertRequestInfo, pRequestInfo,sizeof(CRYPTUI_WIZ_CERT_REQUEST_INFO));
  3322. //init the output parameter
  3323. if(ppCertContext)
  3324. *ppCertContext=NULL;
  3325. if(pdwStatus)
  3326. *pdwStatus=CRYPTUI_WIZ_CERT_REQUEST_STATUS_UNKNOWN;
  3327. //check in the input parameters
  3328. if(NULL==pCertRequestInfo)
  3329. goto InvalidArgErr;
  3330. //make sure the dwSize is correct
  3331. if(pCertRequestInfo->dwSize != sizeof(CRYPTUI_WIZ_CERT_REQUEST_INFO))
  3332. goto InvalidArgErr;
  3333. //check the purpose
  3334. if((pCertRequestInfo->dwPurpose != CRYPTUI_WIZ_CERT_ENROLL) &&
  3335. (pCertRequestInfo->dwPurpose != CRYPTUI_WIZ_CERT_RENEW))
  3336. goto InvalidArgErr;
  3337. //copy the dwFlags
  3338. CertWizardInfo.dwFlags=dwFlags;
  3339. if (S_OK != (CertRequester::MakeCertRequester
  3340. (pCertRequestInfo->pwszAccountName,
  3341. pCertRequestInfo->pwszMachineName,
  3342. pCertRequestInfo->dwCertOpenStoreFlag,
  3343. pCertRequestInfo->dwPurpose,
  3344. &CertWizardInfo,
  3345. &pCertRequester,
  3346. &idsText)))
  3347. goto InvalidArgErr;
  3348. pCertRequesterContext = pCertRequester->GetContext();
  3349. //if UILess is required, set the flags so that the root cert
  3350. //will be put into the CA store
  3351. if(CRYPTUI_WIZ_NO_UI & dwFlags)
  3352. dwFlags |= CRYPTUI_WIZ_NO_INSTALL_ROOT;
  3353. //if UI is required, we change the cursor shape to the hour glass
  3354. CertWizardInfo.fCursorChanged=FALSE;
  3355. if(NULL != hwndParent)
  3356. {
  3357. if (0 == (CRYPTUI_WIZ_NO_UI & dwFlags))
  3358. {
  3359. //overwrite the cursor for this window class
  3360. CertWizardInfo.hWinPrevCursor=(HCURSOR)SetClassLongPtr(hwndParent, GCLP_HCURSOR, (LONG_PTR)NULL);
  3361. CertWizardInfo.hPrevCursor=SetCursor(LoadCursor(NULL, IDC_WAIT));
  3362. CertWizardInfo.fCursorChanged=TRUE;
  3363. // BUGBUG: spec says to use sizeof(DWORD) -- is this correct for 64-bit?
  3364. if (!CryptSetProvParam(0 /*all CSPs*/, PP_CLIENT_HWND, (LPBYTE)&hwndParent, sizeof(hwndParent)))
  3365. {
  3366. goto CryptSetProvParamError;
  3367. }
  3368. }
  3369. else
  3370. {
  3371. // We've passed a window handle, but have specified no ui.
  3372. // We may want this window handle to be the parent window for
  3373. // CSP UI:
  3374. if (0 != (CRYPTUI_WIZ_IGNORE_NO_UI_FLAG_FOR_CSPS & dwFlags))
  3375. {
  3376. // BUGBUG: spec says to use sizeof(DWORD) -- is this correct for 64-bit?
  3377. if (!CryptSetProvParam(0 /*all CSPs*/, PP_CLIENT_HWND, (LPBYTE)&hwndParent, sizeof(hwndParent)))
  3378. {
  3379. goto CryptSetProvParamError;
  3380. }
  3381. }
  3382. }
  3383. }
  3384. //check the CA information
  3385. //pwszCALocation and pwszCAName have to be set at the same time
  3386. CertWizardInfo.fCAInput=FALSE;
  3387. if(pCertRequestInfo->pwszCALocation)
  3388. {
  3389. if(NULL==(pCertRequestInfo->pwszCAName))
  3390. goto InvalidArgErr;
  3391. //mark that we known the CA in advance
  3392. CertWizardInfo.fCAInput=TRUE;
  3393. }
  3394. else
  3395. {
  3396. if(pCertRequestInfo->pwszCAName)
  3397. goto InvalidArgErr;
  3398. }
  3399. CertWizardInfo.dwPurpose=pCertRequestInfo->dwPurpose;
  3400. //make sure NO root UI will pop up in remote enrollment
  3401. if(FALSE == CertWizardInfo.fLocal)
  3402. dwFlags |= CRYPTUI_WIZ_NO_INSTALL_ROOT;
  3403. //check for the private key information
  3404. if(!CheckPVKInfo(dwFlags,
  3405. pCertRequestInfo,
  3406. &CertWizardInfo,
  3407. &pKeyProvInfo))
  3408. {
  3409. idsText=IDS_INVALID_PVK_FOR_PKCS10;
  3410. goto InvalidArgErr;
  3411. }
  3412. //for non-enterprise enrollment, we default the CSP to RSA_FULL
  3413. if(CRYPTUI_WIZ_CERT_REQUEST_KEY_USAGE == pCertRequestInfo->dwCertChoice)
  3414. {
  3415. if(0 == CertWizardInfo.dwProviderType)
  3416. CertWizardInfo.dwProviderType=PROV_RSA_FULL;
  3417. }
  3418. //make sure the CSP selected is supported by the local machine
  3419. //populate the pwszProvider in CertWizardInfo if it is NULL
  3420. if(S_OK != pCertRequesterContext->GetDefaultCSP(&fAllocateCSP))
  3421. {
  3422. idsText = pCertRequesterContext->GetErrorString();
  3423. goto InvalidArgErr;
  3424. }
  3425. //copy the allocated string
  3426. if(fAllocateCSP)
  3427. pwszAllocatedCSP=CertWizardInfo.pwszProvider;
  3428. //build the list of local machine's CSP
  3429. if (S_OK != pCertRequesterContext->BuildCSPList())
  3430. {
  3431. idsText = IDS_FAIL_TO_GET_CSP_LIST;
  3432. goto TraceErr;
  3433. }
  3434. //make sure the selected on is in the list
  3435. if(0 != CertWizardInfo.dwProviderType ||
  3436. NULL != CertWizardInfo.pwszProvider)
  3437. {
  3438. if(!CSPSupported(&CertWizardInfo))
  3439. {
  3440. idsText=IDS_CSP_NOT_SUPPORTED;
  3441. goto InvalidArgErr;
  3442. }
  3443. }
  3444. //set it see if the provider is know
  3445. if(CertWizardInfo.pwszProvider)
  3446. {
  3447. CertWizardInfo.fKnownCSP = TRUE;
  3448. CertWizardInfo.dwOrgCSPType = CertWizardInfo.dwProviderType;
  3449. CertWizardInfo.pwszOrgCSPName = CertWizardInfo.pwszProvider;
  3450. }
  3451. else
  3452. CertWizardInfo.fKnownCSP=FALSE;
  3453. //check for the renew case.
  3454. //1. The certificate has to be valid
  3455. //2. The certificate has to has a valid cert type extension
  3456. if(CRYPTUI_WIZ_CERT_RENEW == pCertRequestInfo->dwPurpose)
  3457. {
  3458. LPSTR pszTemplateOid = NULL;
  3459. LPWSTR pwszTemplateName = NULL;
  3460. //for renew, the pRenewCertContext has to be set
  3461. if(NULL==pCertRequestInfo->pRenewCertContext)
  3462. {
  3463. idsText=IDS_NO_CERTIFICATE_FOR_RENEW;
  3464. goto InvalidArgErr;
  3465. }
  3466. // First, try the CERTIFICATE_TEMPLATE extension. This will work
  3467. // only for V2 templates:
  3468. if (S_OK == getTemplateOID(pCertRequestInfo->pRenewCertContext, &pszTemplateOid))
  3469. {
  3470. // Convert the template oid to a WCHAR * and store it.
  3471. hr = WizardSZToWSZ(pszTemplateOid, &pwszTemplateName);
  3472. WizardFree(pszTemplateOid);
  3473. if (S_OK != hr)
  3474. goto WizardSZToWSZError;
  3475. }
  3476. else
  3477. {
  3478. // We probably have a V1 template, try to get the template name:
  3479. if (S_OK != getTemplateName(pCertRequestInfo->pRenewCertContext, &pwszTemplateName))
  3480. {
  3481. // No v1 or v2 extension that tells which certtype we've enrolled for. This is
  3482. // not a valid certificate for renew:
  3483. idsText = IDS_INVALID_CERTIFICATE_TO_RENEW;
  3484. goto TraceErr;
  3485. }
  3486. // We successfully acquired the cert type name.
  3487. }
  3488. CertType.dwSize = sizeof(CertType);
  3489. CertType.cCertType = 1;
  3490. CertType.rgwszCertType = &pwszTemplateName;
  3491. ((CRYPTUI_WIZ_CERT_REQUEST_INFO *)pCertRequestInfo)->dwCertChoice=CRYPTUI_WIZ_CERT_REQUEST_CERT_TYPE;
  3492. ((CRYPTUI_WIZ_CERT_REQUEST_INFO *)pCertRequestInfo)->pCertType=&CertType;
  3493. //remember to set the old value back
  3494. fResetCertType = TRUE;
  3495. //make sure the user has the permission to ask for those
  3496. //request
  3497. if(!CAUtilValidCertType(pCertRequestInfo, &CertWizardInfo))
  3498. {
  3499. idsText=IDS_NO_PERMISSION_FOR_CERTTYPE;
  3500. goto CheckCertTypeErr;
  3501. }
  3502. }
  3503. //check the dwCertChoice for the enroll case
  3504. if(CRYPTUI_WIZ_CERT_ENROLL & (pCertRequestInfo->dwPurpose))
  3505. {
  3506. switch(pCertRequestInfo->dwCertChoice)
  3507. {
  3508. case CRYPTUI_WIZ_CERT_REQUEST_KEY_USAGE:
  3509. if(NULL==(pCertRequestInfo->pKeyUsage))
  3510. goto InvalidArgErr;
  3511. //has to specify some use oid
  3512. if(0==(pCertRequestInfo->pKeyUsage)->cUsageIdentifier)
  3513. goto InvalidArgErr;
  3514. break;
  3515. case CRYPTUI_WIZ_CERT_REQUEST_CERT_TYPE:
  3516. if(NULL==(pCertRequestInfo->pCertType))
  3517. goto InvalidArgErr;
  3518. if(pCertRequestInfo->pCertType->dwSize != sizeof(CRYPTUI_WIZ_CERT_TYPE))
  3519. goto InvalidArgErr;
  3520. //we only allow one cert type for now
  3521. if(1 !=pCertRequestInfo->pCertType->cCertType)
  3522. goto InvalidArgErr;
  3523. //make sure the user has the permission to ask for those
  3524. //request
  3525. if(!CAUtilValidCertType(pCertRequestInfo, &CertWizardInfo))
  3526. {
  3527. idsText=IDS_NO_PERMISSION_FOR_CERTTYPE;
  3528. goto CheckCertTypeErr;
  3529. }
  3530. break;
  3531. //dwCertChoice is optional only for the UI case
  3532. case 0:
  3533. if(dwFlags & CRYPTUI_WIZ_NO_UI)
  3534. goto InvalidArgErr;
  3535. break;
  3536. default:
  3537. goto InvalidArgErr;
  3538. }
  3539. }
  3540. //for UI mode, we only do certificate type enrollment/renewal
  3541. if(0 == (dwFlags & CRYPTUI_WIZ_NO_UI))
  3542. {
  3543. if(CRYPTUI_WIZ_CERT_REQUEST_KEY_USAGE == (pCertRequestInfo->dwCertChoice))
  3544. {
  3545. idsText=IDS_INVALID_CERTIFICATE_TO_RENEW;
  3546. goto InvalidArgErr;
  3547. }
  3548. }
  3549. else
  3550. {
  3551. //for UILess mode, if user enroll for EKUs, they
  3552. //have to specify a CA name
  3553. if(CRYPTUI_WIZ_CERT_REQUEST_KEY_USAGE == (pCertRequestInfo->dwCertChoice))
  3554. {
  3555. //user has to supply the CA information
  3556. if((NULL==pCertRequestInfo->pwszCAName) ||
  3557. (NULL==pCertRequestInfo->pwszCALocation)
  3558. )
  3559. {
  3560. idsText=IDS_HAS_TO_PROVIDE_CA;
  3561. goto InvalidArgErr;
  3562. }
  3563. }
  3564. }
  3565. //reset the initial ids valud
  3566. idsText=IDS_INVALID_INFO_FOR_PKCS10;
  3567. fResult=CertRequestSearchCA(
  3568. &CertWizardInfo,
  3569. dwFlags,
  3570. hwndParent,
  3571. pwszWizardTitle,
  3572. pCertRequestInfo,
  3573. ppCertContext,
  3574. pdwStatus,
  3575. &idsText);
  3576. if(FALSE==fResult)
  3577. goto CertRequestErr;
  3578. fResult=TRUE;
  3579. CommonReturn:
  3580. if(TRUE == fResetCertType)
  3581. {
  3582. ((CRYPTUI_WIZ_CERT_REQUEST_INFO *)pCertRequestInfo)->dwCertChoice=dwCertChoice;
  3583. ((CRYPTUI_WIZ_CERT_REQUEST_INFO *)pCertRequestInfo)->pCertType=(PCCRYPTUI_WIZ_CERT_TYPE)pData;
  3584. }
  3585. //free the memory
  3586. if(pwszCTName)
  3587. WizardFree(pwszCTName);
  3588. if(pCertType)
  3589. WizardFree(pCertType);
  3590. if(pEKUsage)
  3591. WizardFree(pEKUsage);
  3592. if(pKeyProvInfo)
  3593. WizardFree(pKeyProvInfo);
  3594. //free pwszProvider
  3595. if(fAllocateCSP)
  3596. {
  3597. if(pwszAllocatedCSP)
  3598. WizardFree(pwszAllocatedCSP);
  3599. }
  3600. //free the CSP list: rgdwProviderType and rgwszProvider;
  3601. FreeProviders(CertWizardInfo.dwCSPCount,
  3602. CertWizardInfo.rgdwProviderType,
  3603. CertWizardInfo.rgwszProvider);
  3604. if (NULL != g_pEnrollFactory)
  3605. {
  3606. delete g_pEnrollFactory;
  3607. g_pEnrollFactory = NULL;
  3608. }
  3609. //reset the cursor shape
  3610. if(TRUE == CertWizardInfo.fCursorChanged)
  3611. {
  3612. SetCursor(CertWizardInfo.hPrevCursor);
  3613. SetWindowLongPtr(hwndParent, GCLP_HCURSOR, (LONG_PTR)(CertWizardInfo.hWinPrevCursor));
  3614. }
  3615. //pop up the confirmation box for failure if UI is required
  3616. if(idsText && (((dwFlags & CRYPTUI_WIZ_NO_UI) == 0)) )
  3617. {
  3618. //set the message of inable to gather enough info for PKCS10
  3619. if(IDS_REQUEST_SUCCEDDED == idsText ||
  3620. IDS_ISSUED_SEPERATE == idsText ||
  3621. IDS_UNDER_SUBMISSION == idsText)
  3622. uMsgType=MB_OK|MB_ICONINFORMATION;
  3623. else
  3624. uMsgType=MB_OK|MB_ICONERROR;
  3625. if(idsText != IDS_INSTAL_CANCELLED)
  3626. {
  3627. I_EnrollMessageBox(hwndParent, idsText, CertWizardInfo.hr,
  3628. (CRYPTUI_WIZ_CERT_RENEW == pCertRequestInfo->dwPurpose) ? IDS_RENEW_CONFIRM : IDS_ENROLL_CONFIRM,
  3629. pwszWizardTitle,
  3630. uMsgType);
  3631. }
  3632. }
  3633. if (!fResult)
  3634. SetLastError(dwLastError);
  3635. return fResult;
  3636. ErrorReturn:
  3637. dwLastError = GetLastError();
  3638. fResult=FALSE;
  3639. goto CommonReturn;
  3640. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  3641. SET_ERROR(MemoryErr, E_OUTOFMEMORY);
  3642. SET_ERROR(WizardSZToWSZError, hr);
  3643. TRACE_ERROR(CertRequestErr);
  3644. TRACE_ERROR(CheckCertTypeErr);
  3645. TRACE_ERROR(CryptSetProvParamError);
  3646. TRACE_ERROR(TraceErr);
  3647. }
  3648. //-----------------------------------------------------------------------
  3649. //The call back function for enum
  3650. //-----------------------------------------------------------------------
  3651. static BOOL WINAPI EnumOidCallback(
  3652. IN PCCRYPT_OID_INFO pInfo,
  3653. IN void *pvArg
  3654. )
  3655. {
  3656. OID_INFO_CALL_BACK *pCallBackInfo=NULL;
  3657. BOOL fResult=FALSE;
  3658. pCallBackInfo=(OID_INFO_CALL_BACK *)pvArg;
  3659. if(NULL==pvArg || NULL==pInfo)
  3660. goto InvalidArgErr;
  3661. //increment the oid list
  3662. (*(pCallBackInfo->pdwOIDCount))++;
  3663. //get more memory for the pointer list
  3664. *(pCallBackInfo->pprgOIDInfo)=(ENROLL_OID_INFO *)WizardRealloc(*(pCallBackInfo->pprgOIDInfo),
  3665. (*(pCallBackInfo->pdwOIDCount)) * sizeof(ENROLL_OID_INFO));
  3666. if(NULL==*(pCallBackInfo->pprgOIDInfo))
  3667. goto MemoryErr;
  3668. //memset
  3669. memset(&((*(pCallBackInfo->pprgOIDInfo))[*(pCallBackInfo->pdwOIDCount)-1]), 0, sizeof(ENROLL_OID_INFO));
  3670. (*(pCallBackInfo->pprgOIDInfo))[*(pCallBackInfo->pdwOIDCount)-1].pszOID=WizardAllocAndCopyStr((LPSTR)(pInfo->pszOID));
  3671. (*(pCallBackInfo->pprgOIDInfo))[*(pCallBackInfo->pdwOIDCount)-1].pwszName=WizardAllocAndCopyWStr((LPWSTR)(pInfo->pwszName));
  3672. (*(pCallBackInfo->pprgOIDInfo))[*(pCallBackInfo->pdwOIDCount)-1].fSelected=FALSE;
  3673. if(NULL==(*(pCallBackInfo->pprgOIDInfo))[*(pCallBackInfo->pdwOIDCount)-1].pszOID ||
  3674. NULL==(*(pCallBackInfo->pprgOIDInfo))[*(pCallBackInfo->pdwOIDCount)-1].pwszName)
  3675. goto MemoryErr;
  3676. fResult=TRUE;
  3677. CommonReturn:
  3678. return fResult;
  3679. ErrorReturn:
  3680. fResult=FALSE;
  3681. goto CommonReturn;
  3682. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  3683. SET_ERROR(MemoryErr, E_OUTOFMEMORY);
  3684. }
  3685. //----------------------------------------------------------------------------
  3686. //
  3687. // Get the list of supported OIDs and mark the one that caller has requested
  3688. //
  3689. //
  3690. //----------------------------------------------------------------------------
  3691. BOOL InitCertCAOID(PCCRYPTUI_WIZ_CERT_REQUEST_INFO pCertRequestInfo,
  3692. DWORD *pdwOIDInfo,
  3693. ENROLL_OID_INFO **pprgOIDInfo)
  3694. {
  3695. BOOL fResult=FALSE;
  3696. DWORD dwIndex=0;
  3697. OID_INFO_CALL_BACK OidInfoCallBack;
  3698. DWORD dwOIDRequested=0;
  3699. BOOL fFound=FALSE;
  3700. LPWSTR pwszName=NULL;
  3701. if(!pCertRequestInfo || !pdwOIDInfo || !pprgOIDInfo)
  3702. goto InvalidArgErr;
  3703. //init
  3704. *pdwOIDInfo=0;
  3705. *pprgOIDInfo=NULL;
  3706. OidInfoCallBack.pdwOIDCount=pdwOIDInfo;
  3707. OidInfoCallBack.pprgOIDInfo=pprgOIDInfo;
  3708. //no need for renew
  3709. /*if(0==(CRYPTUI_WIZ_CERT_ENROLL & (pCertRequestInfo->dwPurpose)))
  3710. {
  3711. fResult=TRUE;
  3712. goto CommonReturn;
  3713. } */
  3714. //no need for the request for cert types
  3715. if(CRYPTUI_WIZ_CERT_REQUEST_CERT_TYPE == pCertRequestInfo->dwCertChoice)
  3716. {
  3717. fResult=TRUE;
  3718. goto CommonReturn;
  3719. }
  3720. //enum all the enhanced key usages
  3721. if(!CryptEnumOIDInfo(
  3722. CRYPT_ENHKEY_USAGE_OID_GROUP_ID,
  3723. 0,
  3724. &OidInfoCallBack,
  3725. EnumOidCallback))
  3726. goto TraceErr;
  3727. //mark those requested by the user as selected
  3728. if(CRYPTUI_WIZ_CERT_REQUEST_KEY_USAGE == pCertRequestInfo->dwCertChoice)
  3729. {
  3730. for(dwOIDRequested=0; dwOIDRequested<pCertRequestInfo->pKeyUsage->cUsageIdentifier; dwOIDRequested++)
  3731. {
  3732. fFound=FALSE;
  3733. for(dwIndex=0; dwIndex<*pdwOIDInfo; dwIndex++)
  3734. {
  3735. if(0==strcmp(pCertRequestInfo->pKeyUsage->rgpszUsageIdentifier[dwOIDRequested],
  3736. (*pprgOIDInfo)[dwIndex].pszOID))
  3737. {
  3738. fFound=TRUE;
  3739. (*pprgOIDInfo)[dwIndex].fSelected=TRUE;
  3740. break;
  3741. }
  3742. }
  3743. //add the requested oid to the list if not in the numerated enhanced key usage
  3744. if(FALSE==fFound)
  3745. {
  3746. (*pdwOIDInfo)++;
  3747. //get more memory for the pointer list
  3748. *pprgOIDInfo=(ENROLL_OID_INFO *)WizardRealloc(*pprgOIDInfo,
  3749. (*pdwOIDInfo) * sizeof(ENROLL_OID_INFO));
  3750. if(NULL==(*pprgOIDInfo))
  3751. goto MemoryErr;
  3752. //memset
  3753. memset(&((*pprgOIDInfo)[*pdwOIDInfo-1]), 0, sizeof(ENROLL_OID_INFO));
  3754. (*pprgOIDInfo)[(*pdwOIDInfo)-1].pszOID=
  3755. WizardAllocAndCopyStr(pCertRequestInfo->pKeyUsage->rgpszUsageIdentifier[dwOIDRequested]);
  3756. if (NULL == (*pprgOIDInfo)[(*pdwOIDInfo)-1].pszOID)
  3757. goto MemoryErr;
  3758. pwszName=MkWStr((*pprgOIDInfo)[(*pdwOIDInfo)-1].pszOID);
  3759. if(NULL==pwszName)
  3760. goto MemoryErr;
  3761. (*pprgOIDInfo)[(*pdwOIDInfo)-1].pwszName=WizardAllocAndCopyWStr(pwszName);
  3762. (*pprgOIDInfo)[(*pdwOIDInfo)-1].fSelected=TRUE;
  3763. if(NULL==(*pprgOIDInfo)[(*pdwOIDInfo)-1].pszOID ||
  3764. NULL==(*pprgOIDInfo)[(*pdwOIDInfo)-1].pwszName)
  3765. goto MemoryErr;
  3766. }
  3767. if(pwszName)
  3768. {
  3769. FreeWStr(pwszName);
  3770. pwszName=NULL;
  3771. }
  3772. }
  3773. }
  3774. fResult=TRUE;
  3775. CommonReturn:
  3776. //free the memory
  3777. if(pwszName)
  3778. FreeWStr(pwszName);
  3779. return fResult;
  3780. ErrorReturn:
  3781. if(pCertRequestInfo && pdwOIDInfo && pprgOIDInfo)
  3782. {
  3783. FreeCertCAOID(*pdwOIDInfo,
  3784. *pprgOIDInfo);
  3785. *pdwOIDInfo=0;
  3786. *pprgOIDInfo=NULL;
  3787. }
  3788. fResult=FALSE;
  3789. goto CommonReturn;
  3790. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  3791. TRACE_ERROR(TraceErr);
  3792. SET_ERROR(MemoryErr, E_OUTOFMEMORY);
  3793. }
  3794. //----------------------------------------------------------------------------
  3795. //
  3796. // Free the array of enroll OID info
  3797. //
  3798. //
  3799. //----------------------------------------------------------------------------
  3800. BOOL FreeCertCAOID(DWORD dwOIDInfo,
  3801. ENROLL_OID_INFO *pOIDInfo)
  3802. {
  3803. DWORD dwIndex=0;
  3804. if(pOIDInfo)
  3805. {
  3806. for(dwIndex=0; dwIndex < dwOIDInfo; dwIndex++)
  3807. {
  3808. if(pOIDInfo[dwIndex].pszOID)
  3809. WizardFree(pOIDInfo[dwIndex].pszOID);
  3810. if(pOIDInfo[dwIndex].pwszName)
  3811. WizardFree(pOIDInfo[dwIndex].pwszName);
  3812. }
  3813. WizardFree(pOIDInfo);
  3814. }
  3815. return TRUE;
  3816. }
  3817. //----------------------------------------------------------------------------
  3818. //
  3819. // Init a CERT_CA struct
  3820. //
  3821. //
  3822. //----------------------------------------------------------------------------
  3823. BOOL InitCertCA(CERT_WIZARD_INFO *pCertWizardInfo,
  3824. PCRYPTUI_WIZ_CERT_CA pCertCA,
  3825. LPWSTR pwszCALocation,
  3826. LPWSTR pwszCAName,
  3827. BOOL fCASelected,
  3828. PCCRYPTUI_WIZ_CERT_REQUEST_INFO pCertRequestInfo,
  3829. DWORD dwOIDInfo,
  3830. ENROLL_OID_INFO *pOIDInfo,
  3831. BOOL fSearchForCertType)
  3832. {
  3833. BOOL fResult=FALSE;
  3834. LPWSTR *ppwszDisplayCertType=NULL;
  3835. LPWSTR *ppwszCertType=NULL;
  3836. DWORD *pdwKeySpec=NULL;
  3837. DWORD *pdwMinKeySize=NULL;
  3838. DWORD *pdwCSPCount=NULL;
  3839. DWORD **ppdwCSPList=NULL;
  3840. DWORD *pdwRASignature=NULL;
  3841. DWORD *pdwEnrollmentFlags;
  3842. DWORD *pdwSubjectNameFlags;
  3843. DWORD *pdwPrivateKeyFlags;
  3844. DWORD *pdwGeneralFlags;
  3845. DWORD dwCertType=0;
  3846. PCERT_EXTENSIONS *ppCertExtensions=NULL;
  3847. DWORD dwIndex=0;
  3848. DWORD dwCertTypeRequested=0;
  3849. BOOL fFound=FALSE;
  3850. LPWSTR pwszCertTypeName=NULL;
  3851. DWORD dwFoundCertType=0;
  3852. if (!pCertCA || !pCertRequestInfo)
  3853. goto InvalidArgErr;
  3854. //memset
  3855. memset(pCertCA, 0, sizeof(CRYPTUI_WIZ_CERT_CA));
  3856. pCertCA->dwSize=sizeof(CRYPTUI_WIZ_CERT_CA);
  3857. pCertCA->pwszCALocation=pwszCALocation;
  3858. pCertCA->pwszCAName=pwszCAName;
  3859. pCertCA->fSelected=fCASelected;
  3860. //set up the OID information if requested
  3861. switch (pCertRequestInfo->dwCertChoice)
  3862. {
  3863. case CRYPTUI_WIZ_CERT_REQUEST_KEY_USAGE:
  3864. if(dwOIDInfo==0 || NULL==pOIDInfo)
  3865. goto InvalidArgErr;
  3866. pCertCA->dwOIDInfo=dwOIDInfo;
  3867. pCertCA->rgOIDInfo=pOIDInfo;
  3868. break;
  3869. case CRYPTUI_WIZ_CERT_REQUEST_CERT_TYPE:
  3870. //if we are required to search the CertType. get all the certTypes
  3871. //from the CA. Otherwize, just use the CertType provided
  3872. if(fSearchForCertType && pwszCALocation && pwszCAName)
  3873. {
  3874. //get the list of cert type names and extensions supported by the CA
  3875. if(!CAUtilGetCertTypeNameAndExtensions(
  3876. pCertWizardInfo,
  3877. pCertRequestInfo,
  3878. pwszCALocation,
  3879. pwszCAName,
  3880. &dwCertType,
  3881. &ppwszCertType,
  3882. &ppwszDisplayCertType,
  3883. &ppCertExtensions,
  3884. &pdwKeySpec,
  3885. &pdwMinKeySize,
  3886. &pdwCSPCount,
  3887. &ppdwCSPList,
  3888. &pdwRASignature,
  3889. &pdwEnrollmentFlags,
  3890. &pdwSubjectNameFlags,
  3891. &pdwPrivateKeyFlags,
  3892. &pdwGeneralFlags))
  3893. goto TraceErr;
  3894. //add the certType name and extenisions to the struct
  3895. for(dwIndex=0; dwIndex < dwCertType; dwIndex++)
  3896. {
  3897. fFound=FALSE;
  3898. //search for the certTypes that requested by the user
  3899. //we are guaranteed that the certificat type user requested
  3900. //is supported by the CA
  3901. for(dwCertTypeRequested=0; dwCertTypeRequested < pCertRequestInfo->pCertType->cCertType;
  3902. dwCertTypeRequested++)
  3903. {
  3904. fFound = 0 == wcscmp(ppwszCertType[dwIndex], pCertRequestInfo->pCertType->rgwszCertType[dwCertTypeRequested]);
  3905. fFound |= ContainsCertTemplateOid(ppCertExtensions[dwIndex], pCertRequestInfo->pCertType->rgwszCertType[dwCertTypeRequested]);
  3906. if (fFound)
  3907. {
  3908. dwFoundCertType++;
  3909. break;
  3910. }
  3911. }
  3912. if(!AddCertTypeToCertCA(&(pCertCA->dwCertTypeInfo),
  3913. &(pCertCA->rgCertTypeInfo),
  3914. ppwszCertType[dwIndex],
  3915. ppwszDisplayCertType[dwIndex],
  3916. ppCertExtensions[dwIndex],
  3917. fFound,
  3918. pdwKeySpec[dwIndex],
  3919. pdwMinKeySize[dwIndex],
  3920. pdwCSPCount[dwIndex],
  3921. ppdwCSPList[dwIndex],
  3922. pdwRASignature[dwIndex],
  3923. pdwEnrollmentFlags[dwIndex],
  3924. pdwSubjectNameFlags[dwIndex],
  3925. pdwPrivateKeyFlags[dwIndex],
  3926. pdwGeneralFlags[dwIndex]
  3927. ))
  3928. goto TraceErr;
  3929. }
  3930. //make sure all the requested cert types are supported
  3931. //Only do so if the CA information is input through
  3932. //the API
  3933. // if(dwFoundCertType < pCertRequestInfo->pCertType->cCertType)
  3934. // goto InvalidArgErr;
  3935. }
  3936. else
  3937. {
  3938. for(dwCertTypeRequested=0; dwCertTypeRequested < pCertRequestInfo->pCertType->cCertType;
  3939. dwCertTypeRequested++)
  3940. {
  3941. //get the cert type name
  3942. pwszCertTypeName=WizardAllocAndCopyWStr(pCertRequestInfo->pCertType->rgwszCertType[dwCertTypeRequested]);
  3943. if(!pwszCertTypeName)
  3944. goto MemoryErr;
  3945. if(!AddCertTypeToCertCA(&(pCertCA->dwCertTypeInfo),
  3946. &(pCertCA->rgCertTypeInfo),
  3947. NULL,
  3948. pwszCertTypeName,
  3949. NULL,
  3950. TRUE,
  3951. 0,
  3952. 0,
  3953. 0,
  3954. NULL,
  3955. 0,
  3956. 0,
  3957. 0,
  3958. 0,
  3959. 0
  3960. )) //select it
  3961. goto TraceErr;
  3962. //no need to free pwszCertTyptName. It is included
  3963. //in pCertCA->rgCertTypeInfo
  3964. }
  3965. }
  3966. break;
  3967. //dwCertChoice is optional
  3968. case 0:
  3969. //if we are required to search the CertType. get all the certTypes
  3970. //from the CA. Otherwize, use the OID
  3971. if(fSearchForCertType && pwszCALocation && pwszCAName)
  3972. {
  3973. //get the list of cert type names and extensions supported by the CA
  3974. if(!CAUtilGetCertTypeNameAndExtensions(
  3975. pCertWizardInfo,
  3976. pCertRequestInfo,
  3977. pwszCALocation,
  3978. pwszCAName,
  3979. &dwCertType,
  3980. &ppwszCertType,
  3981. &ppwszDisplayCertType,
  3982. &ppCertExtensions,
  3983. &pdwKeySpec,
  3984. &pdwMinKeySize,
  3985. &pdwCSPCount,
  3986. &ppdwCSPList,
  3987. &pdwRASignature,
  3988. &pdwEnrollmentFlags,
  3989. &pdwSubjectNameFlags,
  3990. &pdwPrivateKeyFlags,
  3991. &pdwGeneralFlags))
  3992. goto TraceErr;
  3993. //add the certType name and extenisions to the struct
  3994. for(dwIndex=0; dwIndex < dwCertType; dwIndex++)
  3995. {
  3996. if(!AddCertTypeToCertCA(&(pCertCA->dwCertTypeInfo),
  3997. &(pCertCA->rgCertTypeInfo),
  3998. ppwszCertType[dwIndex],
  3999. ppwszDisplayCertType[dwIndex],
  4000. ppCertExtensions[dwIndex],
  4001. FALSE,
  4002. pdwKeySpec[dwIndex],
  4003. pdwMinKeySize[dwIndex],
  4004. pdwCSPCount[dwIndex],
  4005. ppdwCSPList[dwIndex],
  4006. pdwRASignature[dwIndex],
  4007. pdwEnrollmentFlags[dwIndex],
  4008. pdwSubjectNameFlags[dwIndex],
  4009. pdwPrivateKeyFlags[dwIndex],
  4010. pdwGeneralFlags[dwIndex]
  4011. ))
  4012. goto TraceErr;
  4013. }
  4014. }
  4015. else
  4016. {
  4017. if(dwOIDInfo==0 || NULL==pOIDInfo)
  4018. goto InvalidArgErr;
  4019. pCertCA->dwOIDInfo=dwOIDInfo;
  4020. pCertCA->rgOIDInfo=pOIDInfo;
  4021. }
  4022. break;
  4023. default:
  4024. goto InvalidArgErr;
  4025. }
  4026. fResult=TRUE;
  4027. CommonReturn:
  4028. //free the memory
  4029. if(ppwszCertType)
  4030. WizardFree(ppwszCertType);
  4031. if(ppwszDisplayCertType)
  4032. WizardFree(ppwszDisplayCertType);
  4033. if(ppCertExtensions)
  4034. WizardFree(ppCertExtensions);
  4035. if(pdwKeySpec)
  4036. WizardFree(pdwKeySpec);
  4037. if(pdwMinKeySize)
  4038. WizardFree(pdwMinKeySize);
  4039. if(pdwCSPCount)
  4040. WizardFree(pdwCSPCount);
  4041. if(ppdwCSPList)
  4042. WizardFree(ppdwCSPList);
  4043. return fResult;
  4044. ErrorReturn:
  4045. //free the individual elements
  4046. if(ppdwCSPList)
  4047. {
  4048. for(dwIndex=0; dwIndex < dwCertType; dwIndex++)
  4049. {
  4050. if(ppdwCSPList[dwIndex])
  4051. WizardFree(ppdwCSPList[dwIndex]);
  4052. }
  4053. }
  4054. if(ppwszCertType)
  4055. {
  4056. for(dwIndex=0; dwIndex <dwCertType; dwIndex++)
  4057. {
  4058. if(ppwszCertType[dwIndex])
  4059. WizardFree(ppwszCertType[dwIndex]);
  4060. }
  4061. }
  4062. if(ppwszDisplayCertType)
  4063. {
  4064. for(dwIndex=0; dwIndex <dwCertType; dwIndex++)
  4065. {
  4066. if(ppwszDisplayCertType[dwIndex])
  4067. WizardFree(ppwszDisplayCertType[dwIndex]);
  4068. }
  4069. }
  4070. if(ppCertExtensions)
  4071. {
  4072. for(dwIndex=0; dwIndex <dwCertType; dwIndex++)
  4073. {
  4074. if(ppCertExtensions[dwIndex])
  4075. CAFreeCertTypeExtensions(NULL, ppCertExtensions[dwIndex]);
  4076. }
  4077. }
  4078. if(pCertCA)
  4079. {
  4080. if(pCertCA->rgCertTypeInfo)
  4081. WizardFree(pCertCA->rgCertTypeInfo);
  4082. memset(pCertCA, 0, sizeof(CRYPTUI_WIZ_CERT_CA));
  4083. }
  4084. if(pwszCertTypeName)
  4085. WizardFree(pwszCertTypeName);
  4086. fResult=FALSE;
  4087. goto CommonReturn;
  4088. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  4089. TRACE_ERROR(TraceErr);
  4090. SET_ERROR(MemoryErr, E_OUTOFMEMORY);
  4091. }
  4092. //----------------------------------------------------------------------------
  4093. //
  4094. // Free an array of ENROLL_CERT_TYPE_INFO struct
  4095. //
  4096. //
  4097. //----------------------------------------------------------------------------
  4098. BOOL FreeCertCACertType(DWORD dwCertTypeInfo,
  4099. ENROLL_CERT_TYPE_INFO *rgCertTypeInfo)
  4100. {
  4101. DWORD dwIndex=0;
  4102. if(rgCertTypeInfo)
  4103. {
  4104. for(dwIndex=0; dwIndex <dwCertTypeInfo; dwIndex++)
  4105. {
  4106. if(rgCertTypeInfo[dwIndex].pwszDNName)
  4107. WizardFree(rgCertTypeInfo[dwIndex].pwszDNName);
  4108. if(rgCertTypeInfo[dwIndex].pwszCertTypeName)
  4109. WizardFree(rgCertTypeInfo[dwIndex].pwszCertTypeName);
  4110. if(rgCertTypeInfo[dwIndex].pCertTypeExtensions)
  4111. CAFreeCertTypeExtensions(NULL, rgCertTypeInfo[dwIndex].pCertTypeExtensions);
  4112. if(rgCertTypeInfo[dwIndex].rgdwCSP)
  4113. WizardFree(rgCertTypeInfo[dwIndex].rgdwCSP);
  4114. }
  4115. WizardFree(rgCertTypeInfo);
  4116. }
  4117. return TRUE;
  4118. }
  4119. //----------------------------------------------------------------------------
  4120. //
  4121. // Add a certType to the ENROLL_CERT_TYPE_INFO struct
  4122. //
  4123. //
  4124. //----------------------------------------------------------------------------
  4125. BOOL AddCertTypeToCertCA(DWORD *pdwCertTypeInfo,
  4126. ENROLL_CERT_TYPE_INFO **ppCertTypeInfo,
  4127. LPWSTR pwszDNName,
  4128. LPWSTR pwszCertType,
  4129. PCERT_EXTENSIONS pCertExtensions,
  4130. BOOL fSelected,
  4131. DWORD dwKeySpec,
  4132. DWORD dwMinKeySize,
  4133. DWORD dwCSPCount,
  4134. DWORD *pdwCSPList,
  4135. DWORD dwRASignature,
  4136. DWORD dwEnrollmentFlags,
  4137. DWORD dwSubjectNameFlags,
  4138. DWORD dwPrivateKeyFlags,
  4139. DWORD dwGeneralFlags
  4140. )
  4141. {
  4142. BOOL fResult=FALSE;
  4143. if(!pdwCertTypeInfo || !ppCertTypeInfo)
  4144. goto InvalidArgErr;
  4145. *ppCertTypeInfo=(ENROLL_CERT_TYPE_INFO *)WizardRealloc(*ppCertTypeInfo,
  4146. (*pdwCertTypeInfo+1) * sizeof(ENROLL_CERT_TYPE_INFO));
  4147. if(NULL==*ppCertTypeInfo)
  4148. goto MemoryErr;
  4149. (*pdwCertTypeInfo)++;
  4150. ((*ppCertTypeInfo)[*pdwCertTypeInfo-1]).fSelected=fSelected;
  4151. ((*ppCertTypeInfo)[*pdwCertTypeInfo-1]).pwszDNName=pwszDNName;
  4152. ((*ppCertTypeInfo)[*pdwCertTypeInfo-1]).pwszCertTypeName=pwszCertType;
  4153. ((*ppCertTypeInfo)[*pdwCertTypeInfo-1]).pCertTypeExtensions=pCertExtensions;
  4154. ((*ppCertTypeInfo)[*pdwCertTypeInfo-1]).dwKeySpec=dwKeySpec;
  4155. ((*ppCertTypeInfo)[*pdwCertTypeInfo-1]).dwMinKeySize=dwMinKeySize;
  4156. ((*ppCertTypeInfo)[*pdwCertTypeInfo-1]).dwCSPCount=dwCSPCount;
  4157. ((*ppCertTypeInfo)[*pdwCertTypeInfo-1]).rgdwCSP=pdwCSPList;
  4158. ((*ppCertTypeInfo)[*pdwCertTypeInfo-1]).dwRASignature=dwRASignature;
  4159. ((*ppCertTypeInfo)[*pdwCertTypeInfo-1]).dwEnrollmentFlags=dwEnrollmentFlags;
  4160. ((*ppCertTypeInfo)[*pdwCertTypeInfo-1]).dwSubjectNameFlags=dwSubjectNameFlags;
  4161. ((*ppCertTypeInfo)[*pdwCertTypeInfo-1]).dwPrivateKeyFlags=dwPrivateKeyFlags;
  4162. ((*ppCertTypeInfo)[*pdwCertTypeInfo-1]).dwGeneralFlags=dwGeneralFlags;
  4163. fResult=TRUE;
  4164. CommonReturn:
  4165. return fResult;
  4166. ErrorReturn:
  4167. fResult=FALSE;
  4168. goto CommonReturn;
  4169. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  4170. SET_ERROR(MemoryErr, E_OUTOFMEMORY);
  4171. }
  4172. BOOL
  4173. WINAPI
  4174. CreateCertRequestNoSearchCANoDS
  4175. (
  4176. IN CERT_WIZARD_INFO *pCertWizardInfo,
  4177. IN DWORD /*dwFlags*/,
  4178. IN HCERTTYPE hCertType,
  4179. OUT HANDLE *pResult
  4180. )
  4181. {
  4182. BOOL fResult = FALSE;
  4183. CRYPTUI_WIZ_CERT_CA_INFO CertCAInfo;
  4184. CRYPTUI_WIZ_CERT_CA rgCertCA[2];
  4185. HRESULT hr;
  4186. // Declare cert type properties / flags / extensions:
  4187. LPWSTR pwszCertType;
  4188. LPWSTR pwszDisplayCertType;
  4189. PCERT_EXTENSIONS pCertExtensions;
  4190. DWORD dwKeySpec;
  4191. DWORD dwMinKeySize;
  4192. DWORD dwCSPCount;
  4193. DWORD *pdwCSPList;
  4194. DWORD dwRASignature;
  4195. DWORD dwEnrollmentFlags;
  4196. DWORD dwSubjectNameFlags;
  4197. DWORD dwPrivateKeyFlags;
  4198. DWORD dwGeneralFlags;
  4199. CertRequester *pCertRequester = NULL;
  4200. CertRequesterContext *pCertRequesterContext = NULL;
  4201. // Invalid validation
  4202. if (NULL == pCertWizardInfo || NULL == pCertWizardInfo->hRequester || NULL == hCertType || NULL == pResult)
  4203. return FALSE;
  4204. // Init:
  4205. *pResult = NULL;
  4206. //memset
  4207. memset(&CertCAInfo, 0, sizeof(CertCAInfo));
  4208. memset(rgCertCA, 0, sizeof(rgCertCA));
  4209. //set up the CA info
  4210. CertCAInfo.dwSize = sizeof(CertCAInfo);
  4211. CertCAInfo.dwCA = 2; // 1 dummy CA + 1 real CA
  4212. CertCAInfo.rgCA = rgCertCA;
  4213. CertCAInfo.rgCA[1].dwSize = sizeof(CertCAInfo.rgCA[1]);
  4214. CertCAInfo.rgCA[1].pwszCAName = pCertWizardInfo->pwszCAName;
  4215. CertCAInfo.rgCA[1].pwszCALocation = pCertWizardInfo->pwszCALocation;
  4216. CertCAInfo.rgCA[1].fSelected = TRUE;
  4217. pCertWizardInfo->dwCAIndex = 1; // We're using the first CA.
  4218. // NOTE: No need to set up the OID info: we're requesting based on cert type.
  4219. //get the list of cert type names and extensions supported by the CA
  4220. if(!CAUtilGetCertTypeNameAndExtensionsNoDS
  4221. (pCertWizardInfo,
  4222. NULL,
  4223. hCertType,
  4224. &pwszCertType,
  4225. &pwszDisplayCertType,
  4226. &pCertExtensions,
  4227. &dwKeySpec,
  4228. &dwMinKeySize,
  4229. &dwCSPCount,
  4230. &pdwCSPList,
  4231. &dwRASignature,
  4232. &dwEnrollmentFlags,
  4233. &dwSubjectNameFlags,
  4234. &dwPrivateKeyFlags,
  4235. &dwGeneralFlags))
  4236. {
  4237. if (GetLastError() == ERROR_SUCCESS)
  4238. {
  4239. // No code error occured, we just can't use this cert template.
  4240. // Since this code path relies on being able to use this particular
  4241. // cert template, bubble this up as an invalid arg err.
  4242. goto InvalidArgErr;
  4243. }
  4244. else
  4245. {
  4246. // An error occured.
  4247. goto CAUtilGetCertTypeNameAndExtensionsNoDSErr;
  4248. }
  4249. }
  4250. if(!AddCertTypeToCertCA(&(CertCAInfo.rgCA[1].dwCertTypeInfo),
  4251. &(CertCAInfo.rgCA[1].rgCertTypeInfo),
  4252. pwszCertType,
  4253. pwszDisplayCertType,
  4254. pCertExtensions,
  4255. TRUE,
  4256. dwKeySpec,
  4257. dwMinKeySize,
  4258. dwCSPCount,
  4259. pdwCSPList,
  4260. dwRASignature,
  4261. dwEnrollmentFlags,
  4262. dwSubjectNameFlags,
  4263. dwPrivateKeyFlags,
  4264. dwGeneralFlags))
  4265. goto AddCertTypeToCertCAErr;
  4266. // We're only _creating_ a request, not submitting it.
  4267. pCertWizardInfo->dwFlags |= CRYPTUI_WIZ_CREATE_ONLY;
  4268. pCertWizardInfo->pCertCAInfo = &CertCAInfo;
  4269. if (NULL == (pCertRequester = (CertRequester *)pCertWizardInfo->hRequester))
  4270. goto UnexpectedErr;
  4271. if (NULL == (pCertRequesterContext = pCertRequester->GetContext()))
  4272. goto UnexpectedErr;
  4273. if (S_OK != (hr = pCertRequesterContext->Enroll(NULL, pResult)))
  4274. goto EnrollErr;
  4275. // Bundle state we need to carry across the create/submit boundary:
  4276. {
  4277. PCREATE_REQUEST_WIZARD_STATE pState = (PCREATE_REQUEST_WIZARD_STATE)WizardAlloc(sizeof(CREATE_REQUEST_WIZARD_STATE));
  4278. if (NULL == pState)
  4279. goto MemoryErr;
  4280. pState->hRequest = *pResult;
  4281. pState->dwPurpose = pCertWizardInfo->dwPurpose;
  4282. *pResult = (HANDLE)pState;
  4283. }
  4284. fResult=TRUE;
  4285. CommonReturn:
  4286. FreeCertCACertType(CertCAInfo.rgCA[0].dwCertTypeInfo, CertCAInfo.rgCA[0].rgCertTypeInfo);
  4287. return fResult;
  4288. ErrorReturn:
  4289. fResult=FALSE;
  4290. goto CommonReturn;
  4291. TRACE_ERROR(AddCertTypeToCertCAErr);
  4292. TRACE_ERROR(CAUtilGetCertTypeNameAndExtensionsNoDSErr);
  4293. SET_ERROR(EnrollErr, hr);
  4294. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  4295. SET_ERROR(MemoryErr, E_OUTOFMEMORY);
  4296. SET_ERROR(UnexpectedErr, E_UNEXPECTED);
  4297. }
  4298. BOOL
  4299. WINAPI
  4300. SubmitCertRequestNoSearchCANoDS
  4301. (IN HANDLE hRequest,
  4302. IN LPCWSTR pwszCAName,
  4303. IN LPCWSTR pwszCALocation,
  4304. OUT DWORD *pdwStatus,
  4305. OUT OPTIONAL PCCERT_CONTEXT *ppCertContext
  4306. )
  4307. {
  4308. BOOL fResult = FALSE;
  4309. CertRequester *pCertRequester = NULL;
  4310. CertRequesterContext *pCertRequesterContext = NULL;
  4311. CERT_WIZARD_INFO CertWizardInfo;
  4312. DWORD dwPurpose;
  4313. HANDLE hCertRequest = NULL;
  4314. HRESULT hr;
  4315. PCREATE_REQUEST_WIZARD_STATE pState = NULL;
  4316. UINT idsText; // Not used
  4317. // Invalid validation
  4318. if (NULL == hRequest || NULL == pwszCAName || NULL == pwszCALocation || NULL == pdwStatus)
  4319. return FALSE;
  4320. memset(&CertWizardInfo, 0, sizeof(CertWizardInfo));
  4321. // Specify this set of flags to indicate that cryptui doesn't need to prepare
  4322. // access check information. Doing so could cause lots of extraneous logoff/logon events.
  4323. CertWizardInfo.dwFlags = CRYPTUI_WIZ_ALLOW_ALL_TEMPLATES | CRYPTUI_WIZ_ALLOW_ALL_CAS;
  4324. pState = (PCREATE_REQUEST_WIZARD_STATE)hRequest;
  4325. hCertRequest = pState->hRequest;
  4326. dwPurpose = pState->dwPurpose;
  4327. if (S_OK != (CertRequester::MakeCertRequester
  4328. (NULL,
  4329. pState->pwszMachineName,
  4330. pState->dwStoreFlags,
  4331. dwPurpose,
  4332. &CertWizardInfo,
  4333. &pCertRequester,
  4334. &idsText
  4335. )))
  4336. goto InvalidArgErr;
  4337. pCertRequesterContext = pCertRequester->GetContext();
  4338. // Set up the wizard information necessary for a submit operation:
  4339. CertWizardInfo.dwFlags &= ~(CRYPTUI_WIZ_CREATE_ONLY | CRYPTUI_WIZ_FREE_ONLY);
  4340. CertWizardInfo.dwFlags |= CRYPTUI_WIZ_SUBMIT_ONLY;
  4341. CertWizardInfo.dwPurpose = dwPurpose;
  4342. CertWizardInfo.pwszCAName = (LPWSTR)pwszCAName;
  4343. CertWizardInfo.pwszCALocation = (LPWSTR)pwszCALocation;
  4344. CertWizardInfo.fCAInput = TRUE;
  4345. if (S_OK != (hr = pCertRequesterContext->Enroll(pdwStatus, &hCertRequest)))
  4346. goto EnrollErr;
  4347. if (NULL != ppCertContext)
  4348. *ppCertContext = (PCCERT_CONTEXT)hCertRequest;
  4349. // Success
  4350. fResult = TRUE;
  4351. CommonReturn:
  4352. if (NULL != pCertRequester) { delete pCertRequester; }
  4353. return fResult;
  4354. ErrorReturn:
  4355. fResult = FALSE;
  4356. goto CommonReturn;
  4357. SET_ERROR(EnrollErr, hr);
  4358. SET_ERROR(InvalidArgErr, ERROR_INVALID_PARAMETER);
  4359. }
  4360. void
  4361. WINAPI
  4362. FreeCertRequestNoSearchCANoDS
  4363. (IN HANDLE hRequest)
  4364. {
  4365. CERT_WIZARD_INFO CertWizardInfo;
  4366. CertRequester *pCertRequester = NULL;
  4367. CertRequesterContext *pCertRequesterContext = NULL;
  4368. DWORD dwPurpose;
  4369. HANDLE hCertRequest;
  4370. HRESULT hr;
  4371. PCREATE_REQUEST_WIZARD_STATE pState;
  4372. UINT idsText;
  4373. if (NULL == hRequest)
  4374. return;
  4375. memset(&CertWizardInfo, 0, sizeof(CertWizardInfo));
  4376. // Specify this set of flags to indicate that cryptui doesn't need to prepare
  4377. // access check information. Doing so could cause lots of extraneous logoff/logon events.
  4378. CertWizardInfo.dwFlags = CRYPTUI_WIZ_ALLOW_ALL_TEMPLATES | CRYPTUI_WIZ_ALLOW_ALL_CAS;
  4379. pState = (PCREATE_REQUEST_WIZARD_STATE)hRequest;
  4380. hCertRequest = pState->hRequest;
  4381. dwPurpose = pState->dwPurpose;
  4382. if (S_OK != (CertRequester::MakeCertRequester
  4383. (NULL,
  4384. pState->pwszMachineName,
  4385. pState->dwStoreFlags,
  4386. dwPurpose,
  4387. &CertWizardInfo,
  4388. &pCertRequester,
  4389. &idsText
  4390. )))
  4391. goto InvalidArgErr;
  4392. pCertRequesterContext = pCertRequester->GetContext();
  4393. CertWizardInfo.dwFlags &= ~(CRYPTUI_WIZ_CREATE_ONLY | CRYPTUI_WIZ_SUBMIT_ONLY);
  4394. CertWizardInfo.dwFlags |= CRYPTUI_WIZ_FREE_ONLY;
  4395. CertWizardInfo.dwPurpose = dwPurpose;
  4396. if (S_OK != (hr = pCertRequesterContext->Enroll(NULL, &hCertRequest)))
  4397. goto EnrollErr;
  4398. if (NULL != pState->pwszMachineName) { WizardFree(pState->pwszMachineName); }
  4399. WizardFree(pState);
  4400. ErrorReturn:
  4401. return;
  4402. TRACE_ERROR(EnrollErr);
  4403. TRACE_ERROR(InvalidArgErr);
  4404. }
  4405. //----------------------------------------------------------------------------
  4406. //
  4407. // This is the layer of CertRequest wizard builds up the CA information
  4408. // without searching for it on the network.
  4409. //
  4410. // It pass the information throught to the CryptUIWizCertRequestWithCAInfo API
  4411. //----------------------------------------------------------------------------
  4412. BOOL
  4413. WINAPI
  4414. CertRequestNoSearchCA(
  4415. BOOL fSearchCertType,
  4416. CERT_WIZARD_INFO *pCertWizardInfo,
  4417. DWORD dwFlags,
  4418. HWND hwndParent,
  4419. LPCWSTR pwszWizardTitle,
  4420. PCCRYPTUI_WIZ_CERT_REQUEST_INFO pCertRequestInfo,
  4421. PCCERT_CONTEXT *ppCertContext,
  4422. DWORD *pCAdwStatus,
  4423. UINT *pIds
  4424. )
  4425. {
  4426. BOOL fResult=FALSE;
  4427. DWORD dwError=0;
  4428. DWORD dwIndex=0;
  4429. DWORD dwOIDInfo=0;
  4430. ENROLL_OID_INFO *pOIDInfo=NULL;
  4431. CRYPTUI_WIZ_CERT_CA_INFO CertCAInfo;
  4432. CRYPTUI_WIZ_CERT_CA rgCertCA[2];
  4433. //memset
  4434. memset(&CertCAInfo, 0, sizeof(CRYPTUI_WIZ_CERT_CA_INFO));
  4435. memset(rgCertCA, 0, 2*sizeof(CRYPTUI_WIZ_CERT_CA));
  4436. //set up the CA info
  4437. CertCAInfo.dwSize=sizeof(CertCAInfo);
  4438. CertCAInfo.dwCA=2;
  4439. CertCAInfo.rgCA=rgCertCA;
  4440. //user has to supply the CA information
  4441. if((NULL==pCertRequestInfo->pwszCAName) ||
  4442. (NULL==pCertRequestInfo->pwszCALocation)
  4443. )
  4444. {
  4445. *pIds=IDS_HAS_TO_PROVIDE_CA;
  4446. goto InvalidArgErr;
  4447. }
  4448. //set up the OID info
  4449. if(!InitCertCAOID(pCertRequestInfo,
  4450. &dwOIDInfo,
  4451. &pOIDInfo))
  4452. goto TraceErr;
  4453. //set up the CA array
  4454. //the 1st one is the default one without CA information
  4455. if(!InitCertCA(pCertWizardInfo, &rgCertCA[0], NULL, NULL, FALSE, pCertRequestInfo,
  4456. dwOIDInfo, pOIDInfo, fSearchCertType))
  4457. {
  4458. *pIds=IDS_ENROLL_NO_CERT_TYPE;
  4459. goto TraceErr;
  4460. }
  4461. //the second one indicate the information for the real CA
  4462. CertCAInfo.dwCA=2;
  4463. if(!InitCertCA(pCertWizardInfo, &rgCertCA[1], (LPWSTR)(pCertRequestInfo->pwszCALocation),
  4464. (LPWSTR)(pCertRequestInfo->pwszCAName), TRUE, pCertRequestInfo,
  4465. dwOIDInfo, pOIDInfo, fSearchCertType))
  4466. {
  4467. *pIds=IDS_ENROLL_NO_CERT_TYPE;
  4468. goto TraceErr;
  4469. }
  4470. fResult=CryptUIWizCertRequestWithCAInfo(
  4471. pCertWizardInfo,
  4472. dwFlags,
  4473. hwndParent,
  4474. pwszWizardTitle,
  4475. pCertRequestInfo,
  4476. &CertCAInfo,
  4477. ppCertContext,
  4478. pCAdwStatus,
  4479. pIds);
  4480. if(FALSE==fResult)
  4481. goto TraceErr;
  4482. fResult=TRUE;
  4483. CommonReturn:
  4484. //preserve the last error
  4485. dwError=GetLastError();
  4486. //free memory
  4487. for(dwIndex=0; dwIndex< CertCAInfo.dwCA; dwIndex++)
  4488. FreeCertCACertType(CertCAInfo.rgCA[dwIndex].dwCertTypeInfo,
  4489. CertCAInfo.rgCA[dwIndex].rgCertTypeInfo);
  4490. FreeCertCAOID(dwOIDInfo, pOIDInfo);
  4491. //reset the error
  4492. SetLastError(dwError);
  4493. return fResult;
  4494. ErrorReturn:
  4495. fResult=FALSE;
  4496. goto CommonReturn;
  4497. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  4498. TRACE_ERROR(TraceErr);
  4499. }
  4500. //----------------------------------------------------------------------------
  4501. //
  4502. // This is the layer of CertRequest wizard builds up the CA information
  4503. // by searching for it on the network.
  4504. //
  4505. // It pass the information throught to the CryptUIWizCertRequestWithCAInfo API
  4506. //----------------------------------------------------------------------------
  4507. BOOL
  4508. WINAPI
  4509. CertRequestSearchCA(
  4510. CERT_WIZARD_INFO *pCertWizardInfo,
  4511. DWORD dwFlags,
  4512. HWND hwndParent,
  4513. LPCWSTR pwszWizardTitle,
  4514. PCCRYPTUI_WIZ_CERT_REQUEST_INFO pCertRequestInfo,
  4515. PCCERT_CONTEXT *ppCertContext,
  4516. DWORD *pCAdwStatus,
  4517. UINT *pIds
  4518. )
  4519. {
  4520. BOOL fResult=FALSE;
  4521. DWORD dwError=0;
  4522. DWORD dwIndex=0;
  4523. DWORD dwCACount=0;
  4524. BOOL fFound=FALSE;
  4525. LPWSTR *ppwszCAName=0;
  4526. LPWSTR *ppwszCALocation=0;
  4527. CRYPTUI_WIZ_CERT_CA_INFO CertCAInfo;
  4528. CRYPTUI_WIZ_CERT_CA *rgCertCA=NULL;
  4529. DWORD dwOIDInfo=0;
  4530. ENROLL_OID_INFO *pOIDInfo=NULL;
  4531. CRYPTUI_WIZ_CERT_REQUEST_INFO CertRequestInfo;
  4532. DWORD dwValidCA=0;
  4533. //memset
  4534. memset(&CertCAInfo, 0, sizeof(CRYPTUI_WIZ_CERT_CA_INFO));
  4535. memset(&CertRequestInfo, 0, sizeof(CRYPTUI_WIZ_CERT_REQUEST_INFO));
  4536. //set up the CA info
  4537. CertCAInfo.dwSize=sizeof(CertCAInfo);
  4538. //see if CA information is provided
  4539. if(pCertRequestInfo->pwszCALocation &&
  4540. pCertRequestInfo->pwszCAName)
  4541. {
  4542. //no need to do anything if UILess
  4543. if(dwFlags & CRYPTUI_WIZ_NO_UI)
  4544. {
  4545. if(!CertRequestNoSearchCA( TRUE, //search for certype
  4546. pCertWizardInfo,
  4547. dwFlags,
  4548. hwndParent,
  4549. pwszWizardTitle,
  4550. pCertRequestInfo,
  4551. ppCertContext,
  4552. pCAdwStatus,
  4553. pIds))
  4554. goto TraceErr;
  4555. }
  4556. else
  4557. {
  4558. //UI version of the enrollment with known CA informatin
  4559. //get a CA which can issue the required certificate type
  4560. //or the OIDs. The ca has to support some certificate type
  4561. //unless user specifically asked for OID
  4562. if(!CAUtilRetrieveCAFromCertType(
  4563. pCertWizardInfo,
  4564. pCertRequestInfo,
  4565. TRUE, //need multiple CAs
  4566. 0, //ask for the CN
  4567. &dwCACount,
  4568. &ppwszCALocation,
  4569. &ppwszCAName) )
  4570. {
  4571. *pIds=IDS_NO_CA_FOR_ENROLL;
  4572. goto TraceErr;
  4573. }
  4574. //set up the OID info
  4575. if(!InitCertCAOID(pCertRequestInfo,
  4576. &dwOIDInfo,
  4577. &pOIDInfo))
  4578. goto TraceErr;
  4579. //allocation the memory
  4580. rgCertCA=(CRYPTUI_WIZ_CERT_CA *)WizardAlloc((dwCACount + 2) *
  4581. sizeof(CRYPTUI_WIZ_CERT_CA));
  4582. if(NULL==rgCertCA)
  4583. goto OutOfMemoryErr;
  4584. //memset
  4585. memset(rgCertCA, 0, (dwCACount + 2) * sizeof(CRYPTUI_WIZ_CERT_CA));
  4586. //the 1st one is the default one without CA information
  4587. if(!InitCertCA(pCertWizardInfo, &rgCertCA[0], NULL, NULL, FALSE, pCertRequestInfo,
  4588. dwOIDInfo, pOIDInfo, TRUE) )
  4589. {
  4590. *pIds=IDS_ENROLL_NO_CERT_TYPE;
  4591. goto TraceErr;
  4592. }
  4593. dwValidCA=0;
  4594. //the rest is the CA information
  4595. for(dwIndex=0; dwIndex<dwCACount; dwIndex++)
  4596. {
  4597. if(0==_wcsicmp(ppwszCALocation[dwIndex], pCertRequestInfo->pwszCALocation) &&
  4598. 0==_wcsicmp(ppwszCAName[dwIndex], pCertRequestInfo->pwszCAName)
  4599. )
  4600. {
  4601. fFound=TRUE;
  4602. //mark CA as selected
  4603. if(!InitCertCA(pCertWizardInfo, &rgCertCA[dwValidCA+1], ppwszCALocation[dwIndex],
  4604. ppwszCAName[dwIndex], TRUE,
  4605. pCertRequestInfo, dwOIDInfo, pOIDInfo, TRUE))
  4606. //we contine to the next CA
  4607. continue;
  4608. dwValidCA++;
  4609. }
  4610. else
  4611. {
  4612. if(!InitCertCA(pCertWizardInfo, &rgCertCA[dwValidCA+1], ppwszCALocation[dwIndex],
  4613. ppwszCAName[dwIndex], FALSE,
  4614. pCertRequestInfo, dwOIDInfo, pOIDInfo, TRUE))
  4615. continue;
  4616. dwValidCA++;
  4617. }
  4618. }
  4619. if(0==dwValidCA)
  4620. {
  4621. *pIds=IDS_ENROLL_NO_CERT_TYPE;
  4622. goto TraceErr;
  4623. }
  4624. //we need the add the CA to the list
  4625. if(!fFound)
  4626. {
  4627. //we require the CA has to be on DS
  4628. *pIds=IDS_INVALID_CA_FOR_ENROLL;
  4629. goto TraceErr;
  4630. }
  4631. // CertCAInfo.dwCA=(fFound) ? (dwCACount + 1) : (dwCACount+2);
  4632. CertCAInfo.dwCA=dwValidCA + 1;
  4633. CertCAInfo.rgCA=rgCertCA;
  4634. fResult=CryptUIWizCertRequestWithCAInfo(
  4635. pCertWizardInfo,
  4636. dwFlags,
  4637. hwndParent,
  4638. pwszWizardTitle,
  4639. pCertRequestInfo,
  4640. &CertCAInfo,
  4641. ppCertContext,
  4642. pCAdwStatus,
  4643. pIds);
  4644. if(!fResult)
  4645. goto TraceErr;
  4646. }
  4647. }
  4648. //the CA Information is not provided
  4649. else
  4650. {
  4651. //get a list of CAs which can issue the required certificate type
  4652. //or the OIDs
  4653. if(!CAUtilRetrieveCAFromCertType(
  4654. pCertWizardInfo,
  4655. pCertRequestInfo,
  4656. TRUE, //need multiple CAs
  4657. 0, //ask for the CN
  4658. &dwCACount,
  4659. &ppwszCALocation,
  4660. &ppwszCAName))
  4661. {
  4662. *pIds=IDS_NO_CA_FOR_ENROLL;
  4663. goto TraceErr;
  4664. }
  4665. //init the OID
  4666. //set up the OID info
  4667. if(!InitCertCAOID(pCertRequestInfo,
  4668. &dwOIDInfo,
  4669. &pOIDInfo))
  4670. goto TraceErr;
  4671. //allocation the memory
  4672. rgCertCA=(CRYPTUI_WIZ_CERT_CA *)WizardAlloc((dwCACount + 1) *
  4673. sizeof(CRYPTUI_WIZ_CERT_CA));
  4674. if(NULL==rgCertCA)
  4675. goto OutOfMemoryErr;
  4676. //memset
  4677. memset(rgCertCA, 0, (dwCACount + 1) * sizeof(CRYPTUI_WIZ_CERT_CA));
  4678. //the 1st one is the default one without CA information
  4679. if(!InitCertCA(pCertWizardInfo, &rgCertCA[0], NULL, NULL, FALSE, pCertRequestInfo,
  4680. dwOIDInfo, pOIDInfo, TRUE))
  4681. {
  4682. *pIds=IDS_ENROLL_NO_CERT_TYPE;
  4683. goto TraceErr;
  4684. }
  4685. dwValidCA=0;
  4686. //the rest is the CA information
  4687. for(dwIndex=0; dwIndex<dwCACount; dwIndex++)
  4688. {
  4689. //mark the 1st CA as selected
  4690. if(!InitCertCA(pCertWizardInfo, &rgCertCA[dwValidCA+1], ppwszCALocation[dwIndex],
  4691. ppwszCAName[dwIndex], (dwValidCA == 0) ? TRUE : FALSE,
  4692. pCertRequestInfo, dwOIDInfo, pOIDInfo, TRUE) )
  4693. continue;
  4694. dwValidCA++;
  4695. }
  4696. if(0==dwValidCA)
  4697. {
  4698. *pIds=IDS_ENROLL_NO_CERT_TYPE;
  4699. goto TraceErr;
  4700. }
  4701. CertCAInfo.dwCA=dwValidCA + 1;
  4702. CertCAInfo.rgCA=rgCertCA;
  4703. fResult=CryptUIWizCertRequestWithCAInfo(
  4704. pCertWizardInfo,
  4705. dwFlags,
  4706. hwndParent,
  4707. pwszWizardTitle,
  4708. pCertRequestInfo,
  4709. &CertCAInfo,
  4710. ppCertContext,
  4711. pCAdwStatus,
  4712. pIds);
  4713. if(!fResult)
  4714. goto TraceErr;
  4715. }
  4716. fResult=TRUE;
  4717. CommonReturn:
  4718. //preserve the last error
  4719. dwError=GetLastError();
  4720. //free memory
  4721. //free the OID information
  4722. FreeCertCAOID(dwOIDInfo, pOIDInfo);
  4723. if(CertCAInfo.rgCA)
  4724. {
  4725. for(dwIndex=0; dwIndex<CertCAInfo.dwCA; dwIndex++)
  4726. {
  4727. FreeCertCACertType(CertCAInfo.rgCA[dwIndex].dwCertTypeInfo,
  4728. CertCAInfo.rgCA[dwIndex].rgCertTypeInfo);
  4729. }
  4730. WizardFree(CertCAInfo.rgCA);
  4731. }
  4732. if(ppwszCAName)
  4733. {
  4734. for(dwIndex=0; dwIndex < dwCACount; dwIndex++)
  4735. {
  4736. if(ppwszCAName[dwIndex])
  4737. WizardFree(ppwszCAName[dwIndex]);
  4738. }
  4739. WizardFree(ppwszCAName);
  4740. }
  4741. if(ppwszCALocation)
  4742. {
  4743. for(dwIndex=0; dwIndex < dwCACount; dwIndex++)
  4744. {
  4745. if(ppwszCALocation[dwIndex])
  4746. WizardFree(ppwszCALocation[dwIndex]);
  4747. }
  4748. WizardFree(ppwszCALocation);
  4749. }
  4750. //reset the error
  4751. SetLastError(dwError);
  4752. return fResult;
  4753. ErrorReturn:
  4754. fResult=FALSE;
  4755. goto CommonReturn;
  4756. SET_ERROR(OutOfMemoryErr, E_OUTOFMEMORY);
  4757. TRACE_ERROR(TraceErr);
  4758. }
  4759. //----------------------------------------------------------------------------
  4760. //
  4761. // We make sure that the if the CA info is specified via the API, it
  4762. // support the specified cert type
  4763. //----------------------------------------------------------------------------
  4764. BOOL CASupportSpecifiedCertType(CRYPTUI_WIZ_CERT_CA *pCertCA)
  4765. {
  4766. DWORD dwIndex=0;
  4767. if(NULL == pCertCA)
  4768. return FALSE;
  4769. for(dwIndex=0; dwIndex<pCertCA->dwCertTypeInfo; dwIndex++)
  4770. {
  4771. if(TRUE==(pCertCA->rgCertTypeInfo)[dwIndex].fSelected)
  4772. return TRUE;
  4773. }
  4774. return FALSE;
  4775. }
  4776. //----------------------------------------------------------------------------
  4777. //
  4778. // This is the layer of CertRequest wizard that is independent of CA object on the DS.
  4779. //
  4780. //----------------------------------------------------------------------------
  4781. BOOL
  4782. WINAPI
  4783. CryptUIWizCertRequestWithCAInfo(
  4784. CERT_WIZARD_INFO *pCertWizardInfo,
  4785. DWORD dwFlags,
  4786. HWND hwndParent,
  4787. LPCWSTR pwszWizardTitle,
  4788. PCCRYPTUI_WIZ_CERT_REQUEST_INFO pCertRequestInfo,
  4789. PCCRYPTUI_WIZ_CERT_CA_INFO pCertRequestCAInfo,
  4790. PCCERT_CONTEXT *ppCertContext,
  4791. DWORD *pdwStatus,
  4792. UINT *pIds)
  4793. {
  4794. PROPSHEETPAGEW rgEnrollSheet[ENROLL_PROP_SHEET];
  4795. PROPSHEETHEADERW enrollHeader;
  4796. DWORD dwIndex=0;
  4797. DWORD dwSize=0;
  4798. ENROLL_PAGE_INFO rgEnrollPageInfo[]=
  4799. {(LPCWSTR)MAKEINTRESOURCE(IDD_WELCOME), Enroll_Welcome,
  4800. (LPCWSTR)MAKEINTRESOURCE(IDD_PURPOSE), Enroll_Purpose,
  4801. (LPCWSTR)MAKEINTRESOURCE(IDD_CSP_SERVICE_PROVIDER), Enroll_CSP,
  4802. (LPCWSTR)MAKEINTRESOURCE(IDD_CERTIFICATE_AUTHORITY), Enroll_CA,
  4803. (LPCWSTR)MAKEINTRESOURCE(IDD_NAME_DESCRIPTION), Enroll_Name,
  4804. (LPCWSTR)MAKEINTRESOURCE(IDD_COMPLETION), Enroll_Completion,
  4805. };
  4806. PROPSHEETPAGEW rgRenewSheet[RENEW_PROP_SHEET];
  4807. PROPSHEETHEADERW renewHeader;
  4808. ENROLL_PAGE_INFO rgRenewPageInfo[]=
  4809. {(LPCWSTR)MAKEINTRESOURCE(IDD_RENEW_WELCOME), Renew_Welcome,
  4810. (LPCWSTR)MAKEINTRESOURCE(IDD_RENEW_OPTIONS), Renew_Options,
  4811. (LPCWSTR)MAKEINTRESOURCE(IDD_RENEW_SERVICE_PROVIDER), Renew_CSP,
  4812. (LPCWSTR)MAKEINTRESOURCE(IDD_RENEW_CA), Renew_CA,
  4813. (LPCWSTR)MAKEINTRESOURCE(IDD_RENEW_COMPLETION), Renew_Completion,
  4814. };
  4815. WCHAR wszTitle[MAX_TITLE_LENGTH];
  4816. HRESULT hr=E_FAIL;
  4817. BOOL fResult=FALSE;
  4818. DWORD dwError=0;
  4819. UINT idsText=IDS_INVALID_INFO_FOR_PKCS10;
  4820. DWORD dwStatus=CRYPTUI_WIZ_CERT_REQUEST_STATUS_UNKNOWN;
  4821. //memset
  4822. memset(rgEnrollSheet, 0, sizeof(PROPSHEETPAGEW)*ENROLL_PROP_SHEET);
  4823. memset(&enrollHeader, 0, sizeof(PROPSHEETHEADERW));
  4824. memset(rgRenewSheet, 0, sizeof(PROPSHEETPAGEW)*RENEW_PROP_SHEET);
  4825. memset(&renewHeader, 0, sizeof(PROPSHEETHEADERW));
  4826. //error checking
  4827. if(NULL== pCertRequestInfo ||
  4828. NULL == pCertRequestCAInfo)
  4829. goto InvalidArgErr;
  4830. //the CA name is a must
  4831. if(1>=(pCertRequestCAInfo->dwCA))
  4832. {
  4833. idsText=IDS_NO_CA_FOR_CSP;
  4834. goto InvalidArgErr;
  4835. }
  4836. //for each ca information, we can not have both OID and certType information
  4837. for(dwIndex=0; dwIndex <pCertRequestCAInfo->dwCA; dwIndex++)
  4838. {
  4839. if((0==pCertRequestCAInfo->rgCA[dwIndex].dwOIDInfo) &&
  4840. (0==pCertRequestCAInfo->rgCA[dwIndex].dwCertTypeInfo))
  4841. {
  4842. //we are in trouble
  4843. goto InvalidArgErr;
  4844. }
  4845. if((0!=pCertRequestCAInfo->rgCA[dwIndex].dwOIDInfo) &&
  4846. (0!=pCertRequestCAInfo->rgCA[dwIndex].dwCertTypeInfo))
  4847. goto InvalidArgErr;
  4848. }
  4849. //make sure the genKey flag does not include CRYPT_USER_PROTECTED
  4850. //if we are doing a remote enrollment/renew
  4851. if(FALSE == pCertWizardInfo->fLocal)
  4852. {
  4853. if(CRYPT_USER_PROTECTED & pCertWizardInfo->dwGenKeyFlags)
  4854. {
  4855. idsText=IDS_NO_USER_PROTECTED_FOR_REMOTE;
  4856. goto InvalidArgErr;
  4857. }
  4858. }
  4859. //for UI enrollment
  4860. //get a list of CAs, based on the CSP user selected
  4861. //and the availability of CAs on the DS
  4862. if(pCertRequestInfo->dwPurpose & CRYPTUI_WIZ_CERT_RENEW)
  4863. {
  4864. pCertWizardInfo->pCertContext=pCertRequestInfo->pRenewCertContext;
  4865. //the certificate has to be the property
  4866. if(!CertGetCertificateContextProperty(
  4867. pCertWizardInfo->pCertContext,
  4868. CERT_KEY_PROV_INFO_PROP_ID,
  4869. NULL,
  4870. &dwSize) || (0==dwSize))
  4871. {
  4872. idsText=IDS_NO_PVK_FOR_RENEW_CERT;
  4873. goto InvalidArgErr;
  4874. }
  4875. }
  4876. //set up the information
  4877. pCertWizardInfo->dwFlags=dwFlags;
  4878. pCertWizardInfo->dwPurpose=pCertRequestInfo->dwPurpose;
  4879. pCertWizardInfo->hwndParent=hwndParent;
  4880. pCertWizardInfo->pCertCAInfo=(CRYPTUI_WIZ_CERT_CA_INFO *)pCertRequestCAInfo;
  4881. pCertWizardInfo->iOrgCertType=-1; //the original cert type selection is -1
  4882. pCertWizardInfo->iOrgCSP=-1; //the original CSP selection is -1
  4883. pCertWizardInfo->pwszCADisplayName=NULL;
  4884. //get the CA name and CA location
  4885. for(dwIndex=0; dwIndex < pCertRequestCAInfo->dwCA; dwIndex++)
  4886. {
  4887. if(TRUE==pCertRequestCAInfo->rgCA[dwIndex].fSelected)
  4888. {
  4889. if(NULL==pCertRequestCAInfo->rgCA[dwIndex].pwszCALocation ||
  4890. NULL==pCertRequestCAInfo->rgCA[dwIndex].pwszCAName)
  4891. goto InvalidArgErr;
  4892. //copy the CA name and location
  4893. pCertWizardInfo->pwszCALocation=WizardAllocAndCopyWStr(pCertRequestCAInfo->rgCA[dwIndex].pwszCALocation);
  4894. pCertWizardInfo->pwszCAName=WizardAllocAndCopyWStr(pCertRequestCAInfo->rgCA[dwIndex].pwszCAName);
  4895. //memory check
  4896. if(NULL== pCertWizardInfo->pwszCALocation ||
  4897. NULL== pCertWizardInfo->pwszCAName)
  4898. goto MemoryErr;
  4899. pCertWizardInfo->dwCAIndex=dwIndex;
  4900. pCertWizardInfo->dwOrgCA=dwIndex;
  4901. }
  4902. }
  4903. //make sure that have CA information
  4904. if(NULL== pCertWizardInfo->pwszCALocation ||
  4905. NULL== pCertWizardInfo->pwszCAName ||
  4906. 0 == pCertWizardInfo->dwCAIndex ||
  4907. 0 == pCertWizardInfo->dwOrgCA)
  4908. {
  4909. idsText=IDS_NO_CA_FOR_ENROLL;
  4910. goto FailErr;
  4911. }
  4912. //if user has selected a CA and CertType, we want to
  4913. //make sure that the CA specified do support the
  4914. //CertType
  4915. if(TRUE == pCertWizardInfo->fCAInput)
  4916. {
  4917. //make sure that the CA has a selected cert type in it
  4918. if(!(CASupportSpecifiedCertType(&(pCertWizardInfo->pCertCAInfo->rgCA[pCertWizardInfo->dwCAIndex]))))
  4919. {
  4920. idsText=IDS_ENROLL_NO_CERT_TYPE;
  4921. goto FailErr;
  4922. }
  4923. }
  4924. else
  4925. {
  4926. // Ensure that we default to a CA that supports
  4927. ResetDefaultCA(pCertWizardInfo);
  4928. }
  4929. pCertWizardInfo->fConfirmation = !(dwFlags & CRYPTUI_WIZ_NO_UI);
  4930. pCertWizardInfo->pwszConfirmationTitle = pwszWizardTitle;
  4931. if(pCertRequestInfo->dwPurpose & CRYPTUI_WIZ_CERT_ENROLL)
  4932. pCertWizardInfo->idsConfirmTitle=IDS_ENROLL_CONFIRM;
  4933. else
  4934. pCertWizardInfo->idsConfirmTitle=IDS_RENEW_CONFIRM;
  4935. pCertWizardInfo->pAuthentication=pCertRequestInfo->pAuthentication;
  4936. pCertWizardInfo->pwszRequestString=pCertRequestInfo->pCertRequestString;
  4937. pCertWizardInfo->pwszDesStore=pCertRequestInfo->pwszDesStore;
  4938. pCertWizardInfo->pwszCertDNName=pCertRequestInfo->pwszCertDNName;
  4939. pCertWizardInfo->pszHashAlg=pCertRequestInfo->pszHashAlg;
  4940. pCertWizardInfo->dwPostOption=pCertRequestInfo->dwPostOption;
  4941. if(pCertRequestInfo->pwszFriendlyName)
  4942. pCertWizardInfo->pwszFriendlyName=WizardAllocAndCopyWStr((LPWSTR)(pCertRequestInfo->pwszFriendlyName));
  4943. if(pCertRequestInfo->pwszDescription)
  4944. pCertWizardInfo->pwszDescription=WizardAllocAndCopyWStr((LPWSTR)(pCertRequestInfo->pwszDescription));
  4945. pCertWizardInfo->pCertRequestExtensions=pCertRequestInfo->pCertRequestExtensions;
  4946. //set up the fonts for the UI case
  4947. if( 0 == (dwFlags & CRYPTUI_WIZ_NO_UI) )
  4948. {
  4949. if(!SetupFonts(g_hmodThisDll,
  4950. NULL,
  4951. &(pCertWizardInfo->hBigBold),
  4952. &(pCertWizardInfo->hBold)))
  4953. {
  4954. idsText=IDS_FAIL_INIT_DLL;
  4955. goto Win32Err;
  4956. }
  4957. //we change the cursor shape from the hour glass to its original shape
  4958. if((hwndParent) && (TRUE == pCertWizardInfo->fCursorChanged))
  4959. {
  4960. //set the cursor back
  4961. SetCursor(pCertWizardInfo->hPrevCursor);
  4962. SetWindowLongPtr(hwndParent, GCLP_HCURSOR, (LONG_PTR)(pCertWizardInfo->hWinPrevCursor));
  4963. pCertWizardInfo->fCursorChanged = FALSE;
  4964. }
  4965. }
  4966. //init the common control for the UI enrollmnet
  4967. if((pCertRequestInfo->dwPurpose & CRYPTUI_WIZ_CERT_ENROLL) &&
  4968. ((dwFlags & CRYPTUI_WIZ_NO_UI) == 0)
  4969. )
  4970. {
  4971. if(!WizardInit() ||
  4972. (sizeof(rgEnrollPageInfo)/sizeof(rgEnrollPageInfo[0])!=ENROLL_PROP_SHEET)
  4973. )
  4974. {
  4975. idsText=IDS_FAIL_INIT_DLL;
  4976. goto InvalidArgErr;
  4977. }
  4978. //set up the property sheet and the property header
  4979. for(dwIndex=0; dwIndex<ENROLL_PROP_SHEET; dwIndex++)
  4980. {
  4981. rgEnrollSheet[dwIndex].dwSize=sizeof(rgEnrollSheet[dwIndex]);
  4982. if(pwszWizardTitle)
  4983. rgEnrollSheet[dwIndex].dwFlags=PSP_USETITLE;
  4984. else
  4985. rgEnrollSheet[dwIndex].dwFlags=0;
  4986. rgEnrollSheet[dwIndex].hInstance=g_hmodThisDll;
  4987. rgEnrollSheet[dwIndex].pszTemplate=rgEnrollPageInfo[dwIndex].pszTemplate;
  4988. if(pwszWizardTitle)
  4989. {
  4990. rgEnrollSheet[dwIndex].pszTitle=pwszWizardTitle;
  4991. }
  4992. else
  4993. rgEnrollSheet[dwIndex].pszTitle=NULL;
  4994. rgEnrollSheet[dwIndex].pfnDlgProc=rgEnrollPageInfo[dwIndex].pfnDlgProc;
  4995. rgEnrollSheet[dwIndex].lParam=(LPARAM)pCertWizardInfo;
  4996. }
  4997. //set up the header information
  4998. enrollHeader.dwSize=sizeof(enrollHeader);
  4999. enrollHeader.dwFlags=PSH_PROPSHEETPAGE | PSH_WIZARD | PSH_NOAPPLYNOW;
  5000. enrollHeader.hwndParent=hwndParent;
  5001. enrollHeader.hInstance=g_hmodThisDll;
  5002. if(pwszWizardTitle)
  5003. enrollHeader.pszCaption=pwszWizardTitle;
  5004. else
  5005. {
  5006. if(LoadStringU(g_hmodThisDll, IDS_ENROLL_WIZARD_TITLE, wszTitle, sizeof(wszTitle)/sizeof(wszTitle[0])))
  5007. enrollHeader.pszCaption=wszTitle;
  5008. }
  5009. enrollHeader.nPages=ENROLL_PROP_SHEET;
  5010. enrollHeader.nStartPage=0;
  5011. enrollHeader.ppsp=rgEnrollSheet;
  5012. //create the wizard
  5013. if(!PropertySheetU(&enrollHeader))
  5014. {
  5015. //cancel button is pushed
  5016. fResult=TRUE;
  5017. idsText=0;
  5018. goto CommonReturn;
  5019. }
  5020. else
  5021. {
  5022. //finish button is pushed
  5023. //get the result of the enrollment wizard
  5024. idsText=pCertWizardInfo->idsText;
  5025. dwStatus=pCertWizardInfo->dwStatus;
  5026. if(S_OK != (hr=pCertWizardInfo->hr))
  5027. goto I_EnrollErr;
  5028. }
  5029. }
  5030. else
  5031. {
  5032. //call the UI renew
  5033. if((pCertRequestInfo->dwPurpose & CRYPTUI_WIZ_CERT_RENEW) &&
  5034. ((dwFlags & CRYPTUI_WIZ_NO_UI) == 0)
  5035. )
  5036. {
  5037. //init the common control
  5038. if(!WizardInit() ||
  5039. (sizeof(rgRenewPageInfo)/sizeof(rgRenewPageInfo[0])!=RENEW_PROP_SHEET)
  5040. )
  5041. {
  5042. idsText=IDS_FAIL_INIT_DLL;
  5043. goto InvalidArgErr;
  5044. }
  5045. //set up the property pages and the property header
  5046. for(dwIndex=0; dwIndex<RENEW_PROP_SHEET; dwIndex++)
  5047. {
  5048. rgRenewSheet[dwIndex].dwSize=sizeof(rgRenewSheet[dwIndex]);
  5049. if(pwszWizardTitle)
  5050. rgRenewSheet[dwIndex].dwFlags=PSP_USETITLE;
  5051. else
  5052. rgRenewSheet[dwIndex].dwFlags=0;
  5053. rgRenewSheet[dwIndex].hInstance=g_hmodThisDll;
  5054. rgRenewSheet[dwIndex].pszTemplate=rgRenewPageInfo[dwIndex].pszTemplate;
  5055. if(pwszWizardTitle)
  5056. {
  5057. rgRenewSheet[dwIndex].pszTitle=pwszWizardTitle;
  5058. }
  5059. else
  5060. rgRenewSheet[dwIndex].pszTitle=NULL;
  5061. rgRenewSheet[dwIndex].pfnDlgProc=rgRenewPageInfo[dwIndex].pfnDlgProc;
  5062. rgRenewSheet[dwIndex].lParam=(LPARAM)pCertWizardInfo;
  5063. }
  5064. //set up the header information
  5065. renewHeader.dwSize=sizeof(renewHeader);
  5066. renewHeader.dwFlags=PSH_PROPSHEETPAGE | PSH_WIZARD | PSH_NOAPPLYNOW;
  5067. renewHeader.hwndParent=hwndParent;
  5068. renewHeader.hInstance=g_hmodThisDll;
  5069. if(pwszWizardTitle)
  5070. renewHeader.pszCaption=pwszWizardTitle;
  5071. else
  5072. {
  5073. if(LoadStringU(g_hmodThisDll, IDS_RENEW_WIZARD_TITLE, wszTitle, sizeof(wszTitle)/sizeof(wszTitle[0])))
  5074. renewHeader.pszCaption=wszTitle;
  5075. }
  5076. renewHeader.nPages=RENEW_PROP_SHEET;
  5077. renewHeader.nStartPage=0;
  5078. renewHeader.ppsp=rgRenewSheet;
  5079. //create the wizard
  5080. if(!PropertySheetU(&renewHeader))
  5081. {
  5082. //cancel button is pushed
  5083. fResult=TRUE;
  5084. idsText=0;
  5085. goto CommonReturn;
  5086. }
  5087. else
  5088. {
  5089. //finish button is pushed
  5090. //get the result of the enrollment wizard
  5091. idsText=pCertWizardInfo->idsText;
  5092. dwStatus=pCertWizardInfo->dwStatus;
  5093. if(S_OK != (hr=pCertWizardInfo->hr))
  5094. goto I_EnrollErr;
  5095. }
  5096. }
  5097. //UIless enroll or renew
  5098. else
  5099. {
  5100. CertRequester *pCertRequester = NULL;
  5101. CertRequesterContext *pCertRequesterContext = NULL;
  5102. if (NULL == (pCertRequester = (CertRequester *) pCertWizardInfo->hRequester))
  5103. {
  5104. hr = E_UNEXPECTED;
  5105. goto I_EnrollErr;
  5106. }
  5107. if (NULL == (pCertRequesterContext = pCertRequester->GetContext()))
  5108. {
  5109. hr = E_UNEXPECTED;
  5110. goto I_EnrollErr;
  5111. }
  5112. hr = pCertRequesterContext->Enroll(&dwStatus, (HANDLE *)&(pCertWizardInfo->pNewCertContext));
  5113. if (0 == pCertWizardInfo->idsText) {
  5114. idsText = CryptUIStatusToIDSText(hr, dwStatus);
  5115. }
  5116. if(S_OK != hr)
  5117. goto I_EnrollErr;
  5118. }
  5119. }
  5120. if(S_OK !=hr)
  5121. goto I_EnrollErr;
  5122. fResult=TRUE;
  5123. CommonReturn:
  5124. //preserve the last error
  5125. dwError=GetLastError();
  5126. if(pIds)
  5127. *pIds=idsText;
  5128. //we have to free the friendlyName and description field
  5129. if(pCertWizardInfo->pwszFriendlyName)
  5130. WizardFree(pCertWizardInfo->pwszFriendlyName);
  5131. if(pCertWizardInfo->pwszDescription)
  5132. WizardFree(pCertWizardInfo->pwszDescription);
  5133. //free the CA name and CA location
  5134. if(pCertWizardInfo->pwszCALocation)
  5135. WizardFree(pCertWizardInfo->pwszCALocation);
  5136. if(pCertWizardInfo->pwszCAName)
  5137. WizardFree(pCertWizardInfo->pwszCAName);
  5138. if(pCertWizardInfo->pwszCADisplayName)
  5139. WizardFree(pCertWizardInfo->pwszCADisplayName);
  5140. //destroy the hFont object
  5141. DestroyFonts(pCertWizardInfo->hBigBold,
  5142. pCertWizardInfo->hBold);
  5143. //return the value
  5144. if(pdwStatus)
  5145. {
  5146. //remember it is the CA status
  5147. switch (dwStatus)
  5148. {
  5149. case CRYPTUI_WIZ_CERT_REQUEST_STATUS_INSTALL_FAILED:
  5150. case CRYPTUI_WIZ_CERT_REQUEST_STATUS_INSTALL_CANCELLED:
  5151. dwStatus=CRYPTUI_WIZ_CERT_REQUEST_STATUS_CERT_ISSUED;
  5152. break;
  5153. case CRYPTUI_WIZ_CERT_REQUEST_STATUS_KEYSVC_FAILED:
  5154. dwStatus=CRYPTUI_WIZ_CERT_REQUEST_STATUS_UNKNOWN;
  5155. break;
  5156. }
  5157. *pdwStatus=dwStatus;
  5158. }
  5159. if(ppCertContext)
  5160. *ppCertContext=pCertWizardInfo->pNewCertContext;
  5161. else
  5162. {
  5163. //free the certificate context
  5164. if(pCertWizardInfo->pNewCertContext)
  5165. CertFreeCertificateContext(pCertWizardInfo->pNewCertContext);
  5166. }
  5167. //reset the error
  5168. SetLastError(dwError);
  5169. return fResult;
  5170. ErrorReturn:
  5171. fResult=FALSE;
  5172. goto CommonReturn;
  5173. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  5174. TRACE_ERROR(Win32Err);
  5175. SET_ERROR_VAR(I_EnrollErr, hr);
  5176. SET_ERROR(MemoryErr, E_OUTOFMEMORY);
  5177. SET_ERROR(FailErr, E_FAIL);
  5178. }