Source code of Windows XP (NT5)
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.

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