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.

5763 lines
191 KiB

  1. //-------------------------------------------------------------
  2. // Copyright (C) Microsoft Corporation, 1996 - 1999
  3. //
  4. // File: buildctl.cpp
  5. //
  6. // Contents: The cpp file to implement the makectl wizard
  7. //
  8. // History: 10-11-1997 xiaohs created
  9. //
  10. //--------------------------------------------------------------
  11. #include "wzrdpvk.h"
  12. #include "buildctl.h"
  13. #include "wintrustp.h"
  14. //***********************************************************************
  15. //
  16. // WinProc helper functions
  17. //**********************************************************************
  18. //--------------------------------------------------------------------------
  19. //
  20. // CheckReplace
  21. //
  22. //--------------------------------------------------------------------------
  23. BOOL CheckReplace(HWND hwndDlg, LPWSTR pwszFileName)
  24. {
  25. BOOL fReplace=FALSE;
  26. WCHAR wszTitle[MAX_STRING_SIZE];
  27. WCHAR wszText[MAX_STRING_SIZE];
  28. WCHAR wszFileText[MAX_STRING_SIZE];
  29. if(NULL == pwszFileName || NULL == hwndDlg)
  30. goto CLEANUP;
  31. //title
  32. #if (0) //DSIE: Bug 160615
  33. if(!LoadStringU(g_hmodThisDll, IDS_BUILDCTL_WIZARD_TITLE, wszTitle, sizeof(wszTitle)))
  34. #else
  35. if(!LoadStringU(g_hmodThisDll, IDS_BUILDCTL_WIZARD_TITLE, wszTitle, sizeof(wszTitle) / sizeof(wszTitle[0])))
  36. #endif
  37. goto CLEANUP;
  38. //text
  39. #if (0) //DSIE: Bug 160616
  40. if(!LoadStringU(g_hmodThisDll, IDS_REPLACE_FILE, wszText, sizeof(wszText)))
  41. #else
  42. if(!LoadStringU(g_hmodThisDll, IDS_REPLACE_FILE, wszText, sizeof(wszText) / sizeof(wszText[0])))
  43. #endif
  44. goto CLEANUP;
  45. if(0 == swprintf(wszFileText, wszText, pwszFileName))
  46. goto CLEANUP;
  47. if(IDNO==MessageBoxExW(hwndDlg, wszFileText, wszTitle,
  48. MB_YESNO|MB_ICONWARNING|MB_DEFBUTTON2|MB_APPLMODAL, 0))
  49. fReplace=FALSE;
  50. else
  51. fReplace=TRUE;
  52. CLEANUP:
  53. return fReplace;
  54. }
  55. //--------------------------------------------------------------------------
  56. //
  57. // DuratioinWithinLimit: We limit the CTL to 99 months.
  58. //
  59. //--------------------------------------------------------------------------
  60. BOOL DurationWithinLimit(DWORD dwMonths, DWORD dwDays)
  61. {
  62. BOOL fResult=FALSE;
  63. FILETIME ThisUpdate;
  64. FILETIME NextUpdate;
  65. DWORD dwNewMonth=0;
  66. DWORD dwNewDay=0;
  67. if((0==dwMonths) && (0==dwDays))
  68. return TRUE;
  69. //This update field
  70. GetSystemTimeAsFileTime(&ThisUpdate);
  71. AddDurationToFileTime(dwMonths,
  72. dwDays,
  73. &ThisUpdate,
  74. &NextUpdate);
  75. SubstractDurationFromFileTime(
  76. &NextUpdate,
  77. &ThisUpdate,
  78. &dwNewMonth,
  79. &dwNewDay);
  80. if((dwNewMonth > 99) ||
  81. (dwNewMonth == 99 && dwNewDay !=0))
  82. return FALSE;
  83. return TRUE;
  84. }
  85. //--------------------------------------------------------------------------
  86. //
  87. // FormatMessageIDSU
  88. //
  89. //--------------------------------------------------------------------------
  90. BOOL FormatMessageIDSU(LPWSTR *ppwszFormat,UINT ids, ...)
  91. {
  92. WCHAR wszFormat[MAX_STRING_SIZE];
  93. LPWSTR pwszMsg=NULL;
  94. BOOL fResult=FALSE;
  95. va_list argList;
  96. va_start(argList, ids);
  97. #if (0) //DSIE: Bug 160614
  98. if(!LoadStringU(g_hmodThisDll, ids, wszFormat, sizeof(wszFormat)))
  99. #else
  100. if(!LoadStringU(g_hmodThisDll, ids, wszFormat, sizeof(wszFormat) / sizeof(wszFormat[0])))
  101. #endif
  102. goto LoadStringError;
  103. if(!FormatMessageU(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
  104. wszFormat,
  105. 0,
  106. 0,
  107. (LPWSTR)&pwszMsg,
  108. 0,
  109. &argList))
  110. goto FormatMessageError;
  111. if(!(*ppwszFormat=WizardAllocAndCopyWStr(pwszMsg)))
  112. goto SZtoWSZError;
  113. fResult=TRUE;
  114. CommonReturn:
  115. va_end(argList);
  116. if(pwszMsg)
  117. LocalFree((HLOCAL)pwszMsg);
  118. return fResult;
  119. ErrorReturn:
  120. fResult=FALSE;
  121. goto CommonReturn;
  122. TRACE_ERROR(LoadStringError);
  123. TRACE_ERROR(FormatMessageError);
  124. TRACE_ERROR(SZtoWSZError);
  125. }
  126. /* // get format string from resources
  127. CHAR szFormat[256];
  128. va_list argList;
  129. LPSTR pszMsg=NULL;
  130. DWORD cbMsg=0;
  131. BOOL fResult=FALSE;
  132. HRESULT hr=S_OK;
  133. if(!LoadStringA(g_hmodThisDll, ids, szFormat, sizeof(szFormat)))
  134. goto LoadStringError;
  135. // format message into requested buffer
  136. va_start(argList, ids);
  137. cbMsg = FormatMessageA(
  138. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
  139. szFormat,
  140. 0, // dwMessageId
  141. 0, // dwLanguageId
  142. (LPSTR) &pszMsg,
  143. 0, // minimum size to allocate
  144. &argList);
  145. va_end(argList);
  146. if(!cbMsg)
  147. goto FormatMessageError;
  148. //copy the sz to wsz
  149. if(!(*ppwszFormat=MkWStr(pszMsg)))
  150. goto SZtoWSZError;
  151. fResult=TRUE;
  152. CommonReturn:
  153. if(pszMsg)
  154. LocalFree((HLOCAL)pszMsg);
  155. return fResult;
  156. ErrorReturn:
  157. fResult=FALSE;
  158. goto CommonReturn;
  159. TRACE_ERROR(LoadStringError);
  160. TRACE_ERROR(FormatMessageError);
  161. TRACE_ERROR(SZtoWSZError);
  162. } */
  163. //----------------------------------------------------------------------------
  164. // GetValidityString
  165. //
  166. //----------------------------------------------------------------------------
  167. BOOL GetValidityString(DWORD dwValidMonths,
  168. DWORD dwValidDays,
  169. LPWSTR *ppwszString)
  170. {
  171. BOOL fResult=FALSE;
  172. if(!ppwszString)
  173. return FALSE;
  174. *ppwszString=NULL;
  175. if((0==dwValidMonths) && (0==dwValidDays))
  176. return FALSE;
  177. if(dwValidMonths && dwValidDays)
  178. fResult=FormatMessageIDSU(ppwszString, IDS_CTL_VALID_MONTH_DAY,
  179. dwValidMonths, dwValidDays);
  180. else
  181. {
  182. if(dwValidMonths)
  183. fResult=FormatMessageIDSU(ppwszString, IDS_CTL_VALID_MONTH, dwValidMonths);
  184. else
  185. fResult=FormatMessageIDSU(ppwszString, IDS_CTL_VALID_DAY, dwValidDays);
  186. }
  187. return fResult;
  188. }
  189. //----------------------------------------------------------------------------
  190. // Make sure that user has typed
  191. //
  192. //----------------------------------------------------------------------------
  193. BOOL ValidDuration(LPWSTR pwszDuration)
  194. {
  195. DWORD i=0;
  196. if(NULL==pwszDuration)
  197. return FALSE;
  198. //only numerical numbers should be allowed
  199. for (i=0; i< (DWORD)(wcslen(pwszDuration)); i++)
  200. {
  201. if ((pwszDuration[i] < L'0') || (pwszDuration[i] > L'9'))
  202. return FALSE;
  203. }
  204. return TRUE;
  205. }
  206. //----------------------------------------------------------------------------
  207. // SetStoreName
  208. //
  209. //----------------------------------------------------------------------------
  210. void SetStoreName(HWND hwndControl,
  211. HCERTSTORE hDesStore)
  212. {
  213. LPWSTR pwszStoreName=NULL;
  214. // LV_COLUMNW lvC;
  215. // LV_ITEMW lvItem;
  216. DWORD dwSize=0;
  217. //get the store name
  218. if(!CertGetStoreProperty(
  219. hDesStore,
  220. CERT_STORE_LOCALIZED_NAME_PROP_ID,
  221. NULL,
  222. &dwSize) || (0==dwSize))
  223. {
  224. //DSIE: Prefix bug 427201.
  225. //Get the <Unknown> string
  226. pwszStoreName=(LPWSTR)WizardAlloc(MAX_TITLE_LENGTH * sizeof(WCHAR));
  227. if(pwszStoreName)
  228. {
  229. *pwszStoreName=L'\0';
  230. LoadStringU(g_hmodThisDll, IDS_UNKNOWN, pwszStoreName, MAX_TITLE_LENGTH);
  231. }
  232. }
  233. else
  234. {
  235. pwszStoreName=(LPWSTR)WizardAlloc(dwSize);
  236. if(pwszStoreName)
  237. {
  238. *pwszStoreName=L'\0';
  239. CertGetStoreProperty(
  240. hDesStore,
  241. CERT_STORE_LOCALIZED_NAME_PROP_ID,
  242. pwszStoreName,
  243. &dwSize);
  244. }
  245. }
  246. if(pwszStoreName)
  247. SetWindowTextU(hwndControl,pwszStoreName);
  248. if(pwszStoreName)
  249. WizardFree(pwszStoreName);
  250. /* //clear the ListView
  251. ListView_DeleteAllItems(hwndControl);
  252. //set the store name
  253. //only one column is needed
  254. memset(&lvC, 0, sizeof(LV_COLUMNW));
  255. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  256. lvC.fmt = LVCFMT_LEFT; // Left-align the column.
  257. lvC.cx =10; //(wcslen(pwszStoreName)+2)*7; // Width of the column, in pixels.
  258. lvC.pszText = L""; // The text for the column.
  259. lvC.iSubItem=0;
  260. if (ListView_InsertColumnU(hwndControl, 0, &lvC) == -1)
  261. {
  262. if(pwszStoreName)
  263. WizardFree(pwszStoreName);
  264. return;
  265. }
  266. //insert the store name
  267. memset(&lvItem, 0, sizeof(LV_ITEMW));
  268. // set up the fields in the list view item struct that don't change from item to item
  269. lvItem.mask = LVIF_TEXT | LVIF_STATE ;
  270. lvItem.state = 0;
  271. lvItem.stateMask = 0;
  272. lvItem.iItem=0;
  273. lvItem.iSubItem=0;
  274. lvItem.pszText=pwszStoreName;
  275. ListView_InsertItemU(hwndControl, &lvItem);
  276. //automatically resize the column
  277. ListView_SetColumnWidth(hwndControl, 0, LVSCW_AUTOSIZE); */
  278. }
  279. BOOL SameCert(PCCERT_CONTEXT pCertOne, PCCERT_CONTEXT pCertTwo)
  280. {
  281. if(!pCertOne || !pCertTwo)
  282. return FALSE;
  283. if(pCertOne->cbCertEncoded != pCertTwo->cbCertEncoded)
  284. return FALSE;
  285. if(0 == memcmp(pCertOne->pbCertEncoded, pCertTwo->pbCertEncoded, pCertTwo->cbCertEncoded))
  286. return TRUE;
  287. return FALSE;
  288. }
  289. //----------------------------------------------------------------------------
  290. // Delete a certificate from the pCertBuildCTLInfo
  291. //
  292. //----------------------------------------------------------------------------
  293. BOOL DeleteCertFromBuildCTL(CERT_BUILDCTL_INFO *pCertBuildCTLInfo,
  294. PCCERT_CONTEXT pCertContext)
  295. {
  296. //we need to remove the cert from our array
  297. PCCERT_CONTEXT *prgCertContext=NULL;
  298. DWORD dwIndex=0;
  299. DWORD dwNewIndex=0;
  300. int iIndex=-1;
  301. if(!pCertBuildCTLInfo || !pCertContext)
  302. return FALSE;
  303. //consider the case of only one cert left
  304. if(pCertBuildCTLInfo->dwCertCount == 1)
  305. {
  306. pCertBuildCTLInfo->dwCertCount=0;
  307. //free the certificate context
  308. CertFreeCertificateContext(pCertBuildCTLInfo->prgCertContext[0]);
  309. WizardFree(pCertBuildCTLInfo->prgCertContext);
  310. pCertBuildCTLInfo->prgCertContext=NULL;
  311. }
  312. else
  313. {
  314. prgCertContext=pCertBuildCTLInfo->prgCertContext;
  315. //re-allocate the memory
  316. pCertBuildCTLInfo->prgCertContext=(PCCERT_CONTEXT *)WizardAlloc(sizeof(PCCERT_CONTEXT) *
  317. (pCertBuildCTLInfo->dwCertCount-1));
  318. //if we are out of memory
  319. if(NULL==pCertBuildCTLInfo->prgCertContext)
  320. {
  321. //reset
  322. pCertBuildCTLInfo->prgCertContext=prgCertContext;
  323. return FALSE;
  324. }
  325. //copy the certificate context over
  326. dwNewIndex=0;
  327. for(dwIndex=0; dwIndex<pCertBuildCTLInfo->dwCertCount; dwIndex++)
  328. {
  329. //find the cert to delete, and do not copy it to the new array
  330. if(SameCert(prgCertContext[dwIndex], pCertContext))
  331. {
  332. iIndex=dwIndex;
  333. continue;
  334. }
  335. pCertBuildCTLInfo->prgCertContext[dwNewIndex]=prgCertContext[dwIndex];
  336. dwNewIndex++;
  337. }
  338. //remember that we are one cert less
  339. pCertBuildCTLInfo->dwCertCount=dwNewIndex;
  340. if(prgCertContext)
  341. {
  342. //free the certificate context
  343. if(-1 != iIndex)
  344. CertFreeCertificateContext(prgCertContext[iIndex]);
  345. WizardFree(prgCertContext);
  346. }
  347. }
  348. return TRUE;
  349. }
  350. //----------------------------------------------------------------------------
  351. // Add certificate to the pCertBuildCTLInfo
  352. //
  353. //----------------------------------------------------------------------------
  354. BOOL AddCertToBuildCTL(PCCERT_CONTEXT pCertContext,
  355. CERT_BUILDCTL_INFO *pCertBuildCTLInfo)
  356. {
  357. DWORD dwIndex=0;
  358. //check to see if the certificate is alreayd in the CTL
  359. for(dwIndex=0; dwIndex < pCertBuildCTLInfo->dwCertCount; dwIndex++)
  360. {
  361. if(pCertContext->cbCertEncoded ==
  362. (pCertBuildCTLInfo->prgCertContext[dwIndex])->cbCertEncoded)
  363. {
  364. if(0==memcmp(pCertContext->pbCertEncoded,
  365. (pCertBuildCTLInfo->prgCertContext[dwIndex])->pbCertEncoded,
  366. pCertContext->cbCertEncoded))
  367. //return FALSE if a duplicate exists
  368. return FALSE;
  369. }
  370. }
  371. pCertBuildCTLInfo->prgCertContext=(PCCERT_CONTEXT *)WizardRealloc(
  372. pCertBuildCTLInfo->prgCertContext,
  373. sizeof(PCCERT_CONTEXT *)*(pCertBuildCTLInfo->dwCertCount +1));
  374. if(NULL==pCertBuildCTLInfo->prgCertContext)
  375. {
  376. pCertBuildCTLInfo->dwCertCount=0;
  377. return FALSE;
  378. }
  379. pCertBuildCTLInfo->prgCertContext[pCertBuildCTLInfo->dwCertCount]=pCertContext;
  380. pCertBuildCTLInfo->dwCertCount++;
  381. return TRUE;
  382. }
  383. //----------------------------------------------------------------------------
  384. // Add certificate to the ListView
  385. //
  386. //----------------------------------------------------------------------------
  387. BOOL AddCertToList(HWND hwndControl,
  388. PCCERT_CONTEXT pCertContext,
  389. int iItem)
  390. {
  391. BOOL fResult=FALSE;
  392. LV_ITEMW lvItem;
  393. DWORD dwChar=0;
  394. WCHAR wszNone[MAX_TITLE_LENGTH];
  395. LPWSTR pwszName=NULL;
  396. if(!hwndControl || !pCertContext)
  397. return FALSE;
  398. // set up the fields in the list view item struct that don't change from item to item
  399. lvItem.mask = LVIF_TEXT | LVIF_STATE |LVIF_PARAM;
  400. lvItem.state = 0;
  401. lvItem.stateMask = 0;
  402. lvItem.iItem=iItem;
  403. lvItem.iSubItem=0;
  404. lvItem.lParam = (LPARAM)(pCertContext);
  405. //load the string for NONE
  406. if(!LoadStringU(g_hmodThisDll, IDS_NONE, wszNone, MAX_TITLE_LENGTH))
  407. wszNone[0]=L'\0';
  408. //Subject
  409. dwChar=CertGetNameStringW(
  410. pCertContext,
  411. CERT_NAME_SIMPLE_DISPLAY_TYPE,
  412. 0,
  413. NULL,
  414. NULL,
  415. 0);
  416. if ((dwChar != 0) && (NULL != (pwszName = (LPWSTR)WizardAlloc(dwChar * sizeof(WCHAR)))))
  417. {
  418. CertGetNameStringW(
  419. pCertContext,
  420. CERT_NAME_SIMPLE_DISPLAY_TYPE,
  421. 0,
  422. NULL,
  423. pwszName,
  424. dwChar);
  425. lvItem.pszText=pwszName;
  426. ListView_InsertItemU(hwndControl, &lvItem);
  427. }
  428. else
  429. {
  430. lvItem.pszText=wszNone;
  431. ListView_InsertItemU(hwndControl, &lvItem);
  432. }
  433. //WizardFree the memory
  434. if(pwszName)
  435. {
  436. WizardFree(pwszName);
  437. pwszName=NULL;
  438. }
  439. //Issuer
  440. lvItem.iSubItem++;
  441. dwChar=CertGetNameStringW(
  442. pCertContext,
  443. CERT_NAME_SIMPLE_DISPLAY_TYPE,
  444. CERT_NAME_ISSUER_FLAG,
  445. NULL,
  446. NULL,
  447. 0);
  448. if ((dwChar != 0) && (NULL != (pwszName = (LPWSTR)WizardAlloc(dwChar * sizeof(WCHAR)))))
  449. {
  450. CertGetNameStringW(
  451. pCertContext,
  452. CERT_NAME_SIMPLE_DISPLAY_TYPE,
  453. CERT_NAME_ISSUER_FLAG,
  454. NULL,
  455. pwszName,
  456. dwChar);
  457. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
  458. pwszName);
  459. }
  460. else
  461. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
  462. wszNone);
  463. //free the memory
  464. if(pwszName)
  465. {
  466. WizardFree(pwszName);
  467. pwszName=NULL;
  468. }
  469. //purpose
  470. lvItem.iSubItem++;
  471. if(MyFormatEnhancedKeyUsageString(&pwszName,pCertContext, FALSE, FALSE))
  472. {
  473. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
  474. pwszName);
  475. }
  476. //free the memory
  477. if(pwszName)
  478. {
  479. WizardFree(pwszName);
  480. pwszName=NULL;
  481. }
  482. //Expiration
  483. lvItem.iSubItem++;
  484. if(WizardFormatDateString(&pwszName,pCertContext->pCertInfo->NotAfter, FALSE))
  485. {
  486. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
  487. pwszName);
  488. }
  489. else
  490. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
  491. wszNone);
  492. //free the memory
  493. if(pwszName)
  494. {
  495. WizardFree(pwszName);
  496. pwszName=NULL;
  497. }
  498. return TRUE;
  499. }
  500. //----------------------------------------------------------------------------
  501. // Make sure the cert has the same usage as the ones defined in CTL.
  502. //
  503. //----------------------------------------------------------------------------
  504. BOOL CertMatchCTL(CERT_BUILDCTL_INFO *pCertBuildCTLInfo,
  505. PCCERT_CONTEXT pCertContext)
  506. {
  507. BOOL fResult=FALSE;
  508. int cNumOID=0;
  509. LPSTR *rgOID=NULL;
  510. DWORD cbOID=0;
  511. DWORD dwIndex=0;
  512. DWORD dwOIDIndex=0;
  513. if(!pCertBuildCTLInfo || !pCertContext)
  514. return FALSE;
  515. //we have to have some oids in the list
  516. if(0==pCertBuildCTLInfo->dwPurposeCount || NULL==pCertBuildCTLInfo->prgPurpose)
  517. return FALSE;
  518. //get the OIDs from the cert
  519. if(!CertGetValidUsages(
  520. 1,
  521. &pCertContext,
  522. &cNumOID,
  523. NULL,
  524. &cbOID))
  525. return FALSE;
  526. rgOID=(LPSTR *)WizardAlloc(cbOID);
  527. if(NULL==rgOID)
  528. return FALSE;
  529. if(!CertGetValidUsages(
  530. 1,
  531. &pCertContext,
  532. &cNumOID,
  533. rgOID,
  534. &cbOID))
  535. goto CLEANUP;
  536. if(-1==cNumOID)
  537. {
  538. fResult=TRUE;
  539. goto CLEANUP;
  540. }
  541. //make sure the array of OIDs match the ones in the CTL
  542. for(dwIndex=0; dwIndex<pCertBuildCTLInfo->dwPurposeCount; dwIndex++)
  543. {
  544. if(NULL==pCertBuildCTLInfo->prgPurpose[dwIndex])
  545. continue;
  546. if(FALSE==pCertBuildCTLInfo->prgPurpose[dwIndex]->fSelected)
  547. continue;
  548. if(NULL==pCertBuildCTLInfo->prgPurpose[dwIndex]->pszOID)
  549. continue;
  550. //we need to find at least one match from the oids supported by the cert
  551. for(dwOIDIndex=0; dwOIDIndex<(DWORD)cNumOID; dwOIDIndex++)
  552. {
  553. if(0==strcmp(pCertBuildCTLInfo->prgPurpose[dwIndex]->pszOID,
  554. rgOID[dwOIDIndex]))
  555. {
  556. fResult=TRUE;
  557. goto CLEANUP;
  558. }
  559. }
  560. }
  561. //we are hopeless at this point
  562. fResult=FALSE;
  563. CLEANUP:
  564. if(rgOID)
  565. WizardFree(rgOID);
  566. return fResult;
  567. }
  568. //----------------------------------------------------------------------------
  569. // Find a cert from stores .
  570. //
  571. //----------------------------------------------------------------------------
  572. static PCCERT_CONTEXT FindCertContextInStores(
  573. PCTL_ENTRY pCtlEntry,
  574. DWORD chStores1,
  575. HCERTSTORE *rghStores1,
  576. DWORD chStores2,
  577. HCERTSTORE *rghStores2,
  578. HCERTSTORE hExtraStore,
  579. DWORD dwFindType)
  580. {
  581. DWORD i;
  582. PCCERT_CONTEXT pCertContext = NULL;
  583. if (dwFindType == 0)
  584. {
  585. return NULL;
  586. }
  587. i = 0;
  588. while ((i<chStores1) && (pCertContext == NULL))
  589. {
  590. pCertContext = CertFindCertificateInStore(
  591. rghStores1[i++],
  592. X509_ASN_ENCODING,
  593. 0,
  594. dwFindType,
  595. (void *)&(pCtlEntry->SubjectIdentifier),
  596. NULL);
  597. }
  598. i = 0;
  599. while ((i<chStores2) && (pCertContext == NULL))
  600. {
  601. pCertContext = CertFindCertificateInStore(
  602. rghStores2[i++],
  603. X509_ASN_ENCODING,
  604. 0,
  605. dwFindType,
  606. (void *)&(pCtlEntry->SubjectIdentifier),
  607. NULL);
  608. }
  609. if (pCertContext == NULL)
  610. {
  611. pCertContext = CertFindCertificateInStore(
  612. hExtraStore,
  613. X509_ASN_ENCODING,
  614. 0,
  615. dwFindType,
  616. (void *)&(pCtlEntry->SubjectIdentifier),
  617. NULL);
  618. }
  619. return pCertContext;
  620. }
  621. //----------------------------------------------------------------------------
  622. // See if the certificate is valid
  623. //
  624. //----------------------------------------------------------------------------
  625. BOOL IsValidCert(HWND hwndDlg,
  626. PCCERT_CONTEXT pCertContext,
  627. CERT_BUILDCTL_INFO *pCertBuildCTLInfo,
  628. BOOL fMsg,
  629. BOOL fFromCTL)
  630. {
  631. //make sure the pCertContext is a self-signed certificate
  632. if(!TrustIsCertificateSelfSigned(pCertContext,
  633. pCertContext->dwCertEncodingType,
  634. 0))
  635. {
  636. if(fMsg)
  637. {
  638. if(fFromCTL)
  639. I_MessageBox(hwndDlg, IDS_NOT_SELF_SIGNED_FROM_CTL,
  640. IDS_BUILDCTL_WIZARD_TITLE,
  641. NULL,
  642. MB_ICONEXCLAMATION|MB_OK|MB_APPLMODAL);
  643. else
  644. I_MessageBox(hwndDlg, IDS_NOT_SELF_SIGNED,
  645. IDS_BUILDCTL_WIZARD_TITLE,
  646. NULL,
  647. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  648. }
  649. return FALSE;
  650. }
  651. //make sure the certifcate match what is defined on the CTL list
  652. if(!CertMatchCTL(pCertBuildCTLInfo, pCertContext))
  653. {
  654. if(fMsg)
  655. {
  656. if(fFromCTL)
  657. I_MessageBox(hwndDlg, IDS_NO_MATCH_USAGE_FROM_CTL,
  658. IDS_BUILDCTL_WIZARD_TITLE,
  659. NULL,
  660. MB_ICONEXCLAMATION|MB_OK|MB_APPLMODAL);
  661. else
  662. I_MessageBox(hwndDlg, IDS_NO_MATCH_USAGE,
  663. IDS_BUILDCTL_WIZARD_TITLE,
  664. NULL,
  665. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  666. }
  667. return FALSE;
  668. }
  669. return TRUE;
  670. }
  671. //----------------------------------------------------------------------------
  672. // Cert a ceritifcate from the file
  673. //
  674. //----------------------------------------------------------------------------
  675. static HCERTSTORE GetCertStoreFromFile(HWND hwndDlg,
  676. CERT_BUILDCTL_INFO *pCertBuildCTLInfo)
  677. {
  678. OPENFILENAMEW OpenFileName;
  679. WCHAR szFileName[_MAX_PATH];
  680. WCHAR szFilter[MAX_STRING_SIZE]; //"Certificate File (*.cer)\0*.cer\0Certificate File (*.crt)\0*.crt\0All Files\0*.*\0"
  681. BOOL fResult=FALSE;
  682. HCERTSTORE hCertStore=NULL;
  683. DWORD dwSize=0;
  684. DWORD dwContentType=0;
  685. if(!hwndDlg || !pCertBuildCTLInfo)
  686. return NULL;
  687. memset(&OpenFileName, 0, sizeof(OpenFileName));
  688. *szFileName=L'\0';
  689. OpenFileName.lStructSize = sizeof(OpenFileName);
  690. OpenFileName.hwndOwner = hwndDlg;
  691. OpenFileName.hInstance = NULL;
  692. //load the fileter string
  693. if(LoadFilterString(g_hmodThisDll, IDS_ALL_CER_FILTER, szFilter, MAX_STRING_SIZE))
  694. {
  695. OpenFileName.lpstrFilter = szFilter;
  696. }
  697. OpenFileName.lpstrCustomFilter = NULL;
  698. OpenFileName.nMaxCustFilter = 0;
  699. OpenFileName.nFilterIndex = 1;
  700. OpenFileName.lpstrFile = szFileName;
  701. OpenFileName.nMaxFile = _MAX_PATH;
  702. OpenFileName.lpstrFileTitle = NULL;
  703. OpenFileName.nMaxFileTitle = 0;
  704. OpenFileName.lpstrInitialDir = NULL;
  705. OpenFileName.lpstrTitle = NULL;
  706. OpenFileName.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;
  707. OpenFileName.nFileOffset = 0;
  708. OpenFileName.nFileExtension = 0;
  709. OpenFileName.lpstrDefExt = L"cer";
  710. OpenFileName.lCustData = NULL;
  711. OpenFileName.lpfnHook = NULL;
  712. OpenFileName.lpTemplateName = NULL;
  713. if (!WizGetOpenFileName(&OpenFileName))
  714. return NULL;
  715. if(!ExpandAndCryptQueryObject(CERT_QUERY_OBJECT_FILE,
  716. szFileName,
  717. CERT_QUERY_CONTENT_FLAG_CERT |
  718. CERT_QUERY_CONTENT_FLAG_CTL |
  719. CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT |
  720. CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE |
  721. CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED,
  722. CERT_QUERY_FORMAT_FLAG_ALL,
  723. 0,
  724. NULL,
  725. &dwContentType,
  726. NULL,
  727. &hCertStore,
  728. NULL,
  729. NULL) || (NULL==hCertStore))
  730. {
  731. I_MessageBox(hwndDlg, IDS_INVALID_CERT_FILE,
  732. IDS_BUILDCTL_WIZARD_TITLE,
  733. NULL,
  734. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  735. goto CLEANUP;
  736. }
  737. if(dwContentType & CERT_QUERY_CONTENT_CTL)
  738. {
  739. I_MessageBox(hwndDlg, IDS_INVALID_CERT_FILE,
  740. IDS_BUILDCTL_WIZARD_TITLE,
  741. NULL,
  742. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  743. goto CLEANUP;
  744. }
  745. fResult=TRUE;
  746. CLEANUP:
  747. if(TRUE==fResult)
  748. return hCertStore;
  749. if(hCertStore)
  750. CertCloseStore(hCertStore, 0);
  751. return NULL;
  752. }
  753. //----------------------------------------------------------------------------
  754. // CallBack fro cert selection call back
  755. //
  756. //----------------------------------------------------------------------------
  757. static BOOL WINAPI SelCertCallBack(
  758. PCCERT_CONTEXT pCertContext,
  759. BOOL *pfInitialSelectedCert,
  760. void *pvCallbackData)
  761. {
  762. if(!pvCallbackData || !pCertContext)
  763. return FALSE;
  764. //make sure that this is a valid certificate
  765. return IsValidCert(((CERT_SEL_LIST *)pvCallbackData)->hwndDlg,
  766. pCertContext,
  767. ((CERT_SEL_LIST *)pvCallbackData)->pCertBuildCTLInfo,
  768. FALSE,
  769. FALSE);
  770. }
  771. //////////////////////////////////////////////////////////////////////////////////////
  772. // The call back function for enum system stores for the signing certificate
  773. //////////////////////////////////////////////////////////////////////////////////////
  774. static BOOL WINAPI EnumSysStoreSignCertCallBack(
  775. const void* pwszSystemStore,
  776. DWORD dwFlags,
  777. PCERT_SYSTEM_STORE_INFO pStoreInfo,
  778. void *pvReserved,
  779. void *pvArg
  780. )
  781. {
  782. CERT_STORE_LIST *pCertStoreList=NULL;
  783. HCERTSTORE hCertStore=NULL;
  784. if(NULL==pvArg)
  785. return FALSE;
  786. pCertStoreList=(CERT_STORE_LIST *)pvArg;
  787. //open the store
  788. hCertStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
  789. g_dwMsgAndCertEncodingType,
  790. NULL,
  791. CERT_SYSTEM_STORE_CURRENT_USER |CERT_STORE_SET_LOCALIZED_NAME_FLAG,
  792. (LPWSTR)pwszSystemStore);
  793. if(!hCertStore)
  794. return FALSE;
  795. pCertStoreList->prgStore=(HCERTSTORE *)WizardRealloc(
  796. pCertStoreList->prgStore,
  797. sizeof(HCERTSTORE) *(pCertStoreList->dwStoreCount +1));
  798. if(NULL==pCertStoreList->prgStore)
  799. {
  800. CertCloseStore(hCertStore, 0);
  801. pCertStoreList->dwStoreCount=0;
  802. }
  803. pCertStoreList->prgStore[pCertStoreList->dwStoreCount]=hCertStore;
  804. pCertStoreList->dwStoreCount++;
  805. return TRUE;
  806. }
  807. //////////////////////////////////////////////////////////////////////////////////////
  808. // The call back function for enum system stores
  809. //////////////////////////////////////////////////////////////////////////////////////
  810. static BOOL WINAPI EnumSysStoreCallBack(
  811. const void* pwszSystemStore,
  812. DWORD dwFlags,
  813. PCERT_SYSTEM_STORE_INFO pStoreInfo,
  814. void *pvReserved,
  815. void *pvArg
  816. )
  817. {
  818. CERT_STORE_LIST *pCertStoreList=NULL;
  819. HCERTSTORE hCertStore=NULL;
  820. if(NULL==pvArg)
  821. return FALSE;
  822. pCertStoreList=(CERT_STORE_LIST *)pvArg;
  823. //open the store as read-only
  824. hCertStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
  825. g_dwMsgAndCertEncodingType,
  826. NULL,
  827. CERT_SYSTEM_STORE_CURRENT_USER |CERT_STORE_SET_LOCALIZED_NAME_FLAG|CERT_STORE_READONLY_FLAG,
  828. (LPWSTR)pwszSystemStore);
  829. //we can not open the store.
  830. if(!hCertStore)
  831. return TRUE;
  832. pCertStoreList->prgStore=(HCERTSTORE *)WizardRealloc(
  833. pCertStoreList->prgStore,
  834. sizeof(HCERTSTORE) *(pCertStoreList->dwStoreCount +1));
  835. if(NULL==pCertStoreList->prgStore)
  836. {
  837. CertCloseStore(hCertStore, 0);
  838. pCertStoreList->dwStoreCount=0;
  839. }
  840. else // DSIE: Bug 227267
  841. {
  842. pCertStoreList->prgStore[pCertStoreList->dwStoreCount]=hCertStore;
  843. pCertStoreList->dwStoreCount++;
  844. }
  845. return TRUE;
  846. }
  847. //----------------------------------------------------------------------------
  848. // Cert a ceritifcate from the store
  849. //
  850. //----------------------------------------------------------------------------
  851. static HCERTSTORE GetCertsFromStore(HWND hwndDlg,
  852. CERT_BUILDCTL_INFO *pCertBuildCTLInfo)
  853. {
  854. PCCERT_CONTEXT pCertContext=NULL;
  855. CRYPTUI_SELECTCERTIFICATE_STRUCT SelCert;
  856. CERT_SEL_LIST CertSelList;
  857. DWORD dwIndex=0;
  858. HCERTSTORE hCertStore;
  859. CERT_STORE_LIST CertStoreList;
  860. if(!hwndDlg || !pCertBuildCTLInfo)
  861. return NULL;
  862. //init
  863. memset(&CertStoreList, 0, sizeof(CertStoreList));
  864. memset(&SelCert, 0, sizeof(CRYPTUI_SELECTCERTIFICATE_STRUCT));
  865. memset(&CertSelList, 0, sizeof(CERT_SEL_LIST));
  866. //set up the parameter for call back for cert selection dialogue
  867. CertSelList.hwndDlg=hwndDlg;
  868. CertSelList.pCertBuildCTLInfo=pCertBuildCTLInfo;
  869. if (NULL == (hCertStore = CertOpenStore(
  870. CERT_STORE_PROV_MEMORY,
  871. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  872. NULL,
  873. 0,
  874. NULL)))
  875. {
  876. goto CLEANUP;
  877. }
  878. //set up the parameter to get a list of certificate
  879. if (!CertEnumSystemStore(
  880. CERT_SYSTEM_STORE_CURRENT_USER,
  881. NULL,
  882. &CertStoreList,
  883. EnumSysStoreCallBack))
  884. goto CLEANUP;
  885. //set up the parameter for cert selection dialogue
  886. SelCert.dwSize=sizeof(CRYPTUI_SELECTCERTIFICATE_STRUCT);
  887. SelCert.hwndParent=hwndDlg;
  888. SelCert.dwFlags = CRYPTUI_SELECTCERT_MULTISELECT;
  889. SelCert.pFilterCallback=SelCertCallBack;
  890. SelCert.pvCallbackData=&CertSelList;
  891. SelCert.cDisplayStores=CertStoreList.dwStoreCount;
  892. SelCert.rghDisplayStores=CertStoreList.prgStore;
  893. SelCert.hSelectedCertStore = hCertStore;
  894. CryptUIDlgSelectCertificate(&SelCert);
  895. CLEANUP:
  896. for(dwIndex=0; dwIndex<CertStoreList.dwStoreCount; dwIndex++)
  897. CertCloseStore(CertStoreList.prgStore[dwIndex], 0);
  898. if(CertStoreList.prgStore)
  899. WizardFree(CertStoreList.prgStore);
  900. return hCertStore;
  901. }
  902. //---------------------------------------------------------------------
  903. // Get the certificate list for the CTL
  904. //
  905. //---------------------------------------------------------------------
  906. void GetCertForCTL(HWND hwndParent,
  907. BOOL fMsg,
  908. CERT_BUILDCTL_INFO *pCertBuildCTLInfo,
  909. HCERTSTORE hCertStore)
  910. {
  911. DWORD dwIndex=0;
  912. DWORD dwCertIndex=0;
  913. DWORD dwFindType=0;
  914. CTL_INFO *pCTLInfo=NULL;
  915. PCCERT_CONTEXT pCertContext=NULL;
  916. PCCERT_CONTEXT pPreCertContext=NULL;
  917. HCERTSTORE rgHCertStore[4]={NULL, NULL, NULL, NULL};
  918. HCERTSTORE hExtraStore=NULL;
  919. BOOL fInvalidCertMsg=fMsg;
  920. BOOL fFoundInCTLMsg=fMsg;
  921. if(!pCertBuildCTLInfo)
  922. return;
  923. //add the certificate from the old CTL
  924. if(pCertBuildCTLInfo->pSrcCTL)
  925. {
  926. //open my, ca, trust, and root store
  927. if(rgHCertStore[dwIndex]=CertOpenStore(
  928. CERT_STORE_PROV_SYSTEM_W,
  929. g_dwMsgAndCertEncodingType,
  930. NULL,
  931. CERT_SYSTEM_STORE_CURRENT_USER,
  932. L"my"))
  933. dwIndex++;
  934. if(rgHCertStore[dwIndex]=CertOpenStore(
  935. CERT_STORE_PROV_SYSTEM_W,
  936. g_dwMsgAndCertEncodingType,
  937. NULL,
  938. CERT_SYSTEM_STORE_CURRENT_USER,
  939. L"trust"))
  940. dwIndex++;
  941. if(rgHCertStore[dwIndex]=CertOpenStore(
  942. CERT_STORE_PROV_SYSTEM_W,
  943. g_dwMsgAndCertEncodingType,
  944. NULL,
  945. CERT_SYSTEM_STORE_CURRENT_USER,
  946. L"ca"))
  947. dwIndex++;
  948. if(rgHCertStore[dwIndex]=CertOpenStore(
  949. CERT_STORE_PROV_SYSTEM_W,
  950. g_dwMsgAndCertEncodingType,
  951. NULL,
  952. CERT_SYSTEM_STORE_CURRENT_USER,
  953. L"root"))
  954. dwIndex++;
  955. //open the cert store
  956. hExtraStore = CertOpenStore(
  957. CERT_STORE_PROV_MSG,
  958. g_dwMsgAndCertEncodingType,
  959. NULL,
  960. 0,
  961. (const void *) (pCertBuildCTLInfo->pSrcCTL->hCryptMsg));
  962. //find the certificate hash
  963. pCTLInfo=pCertBuildCTLInfo->pSrcCTL->pCtlInfo;
  964. if(pCertBuildCTLInfo->dwHashPropID==CERT_SHA1_HASH_PROP_ID)
  965. dwFindType=CERT_FIND_SHA1_HASH;
  966. else
  967. dwFindType=CERT_FIND_MD5_HASH;
  968. //look through each entry in the CTL list
  969. for(dwCertIndex=0; dwCertIndex<pCTLInfo->cCTLEntry; dwCertIndex++)
  970. {
  971. pCertContext=FindCertContextInStores(
  972. &(pCTLInfo->rgCTLEntry[dwCertIndex]),
  973. dwIndex,
  974. rgHCertStore,
  975. 0,
  976. NULL,
  977. hExtraStore,
  978. dwFindType);
  979. if(NULL==pCertContext && TRUE==fFoundInCTLMsg)
  980. {
  981. I_MessageBox(hwndParent, IDS_NO_MATCH_IN_CTL,
  982. IDS_BUILDCTL_WIZARD_TITLE,
  983. NULL,
  984. MB_ICONEXCLAMATION|MB_OK|MB_APPLMODAL);
  985. //no need to give the message again
  986. fFoundInCTLMsg=FALSE;
  987. continue;
  988. }
  989. else if (NULL==pCertContext)
  990. {
  991. continue;
  992. }
  993. if(!IsValidCert(hwndParent,
  994. pCertContext,
  995. pCertBuildCTLInfo,
  996. fInvalidCertMsg,
  997. TRUE))
  998. {
  999. CertFreeCertificateContext(pCertContext);
  1000. pCertContext=0;
  1001. //no need to give message again
  1002. fInvalidCertMsg=FALSE;
  1003. continue;
  1004. }
  1005. if(!AddCertToBuildCTL(pCertContext, pCertBuildCTLInfo))
  1006. {
  1007. CertFreeCertificateContext(pCertContext);
  1008. pCertContext=NULL;
  1009. continue;
  1010. }
  1011. }
  1012. }
  1013. else
  1014. {
  1015. //add the certificate from the hCertStore to the CTL
  1016. if(NULL != hCertStore)
  1017. {
  1018. while(pCertContext=CertEnumCertificatesInStore(hCertStore, pPreCertContext))
  1019. {
  1020. if(!IsValidCert(hwndParent,
  1021. pCertContext,
  1022. pCertBuildCTLInfo,
  1023. FALSE, //do not want a message
  1024. FALSE)) //not build from a CTL
  1025. {
  1026. pPreCertContext=pCertContext;
  1027. continue;
  1028. }
  1029. //get a duplicate of the certificate context
  1030. pPreCertContext=CertDuplicateCertificateContext(pCertContext);
  1031. if(NULL==pPreCertContext)
  1032. {
  1033. pPreCertContext=pCertContext;
  1034. continue;
  1035. }
  1036. //add the duplicate to the list
  1037. if(!AddCertToBuildCTL(pPreCertContext, pCertBuildCTLInfo))
  1038. CertFreeCertificateContext(pPreCertContext);
  1039. //continue for the next iteration
  1040. pPreCertContext=pCertContext;
  1041. }
  1042. }
  1043. }
  1044. //free the certificate store
  1045. if(hExtraStore)
  1046. CertCloseStore(hExtraStore, 0);
  1047. for(dwIndex=0; dwIndex < 4; dwIndex++)
  1048. {
  1049. if(rgHCertStore[dwIndex])
  1050. CertCloseStore(rgHCertStore[dwIndex], 0);
  1051. }
  1052. }
  1053. //---------------------------------------------------------------------
  1054. // Init the certifcate list from the old CTL
  1055. //
  1056. //---------------------------------------------------------------------
  1057. void InitCertList(HWND hwndControl,
  1058. CERT_BUILDCTL_INFO *pCertBuildCTLInfo)
  1059. {
  1060. DWORD dwIndex=0;
  1061. if(!hwndControl || !pCertBuildCTLInfo)
  1062. return;
  1063. for(dwIndex=0; dwIndex<pCertBuildCTLInfo->dwCertCount; dwIndex++)
  1064. {
  1065. //add the certificat to the window
  1066. AddCertToList(hwndControl,(pCertBuildCTLInfo->prgCertContext)[dwIndex],
  1067. dwIndex);
  1068. }
  1069. }
  1070. //-----------------------------------------------------------------------
  1071. // The winProc for the new oid dialogue
  1072. //-----------------------------------------------------------------------
  1073. void FreeCerts(CERT_BUILDCTL_INFO *pCertBuildCTLInfo)
  1074. {
  1075. DWORD dwIndex=0;
  1076. if(!pCertBuildCTLInfo)
  1077. return;
  1078. if(pCertBuildCTLInfo->prgCertContext)
  1079. {
  1080. for(dwIndex=0; dwIndex<pCertBuildCTLInfo->dwCertCount; dwIndex++)
  1081. {
  1082. if(pCertBuildCTLInfo->prgCertContext[dwIndex])
  1083. CertFreeCertificateContext(pCertBuildCTLInfo->prgCertContext[dwIndex]);
  1084. }
  1085. WizardFree(pCertBuildCTLInfo->prgCertContext);
  1086. }
  1087. pCertBuildCTLInfo->dwCertCount=0;
  1088. pCertBuildCTLInfo->prgCertContext=NULL;
  1089. }
  1090. //////////////////////////////////////////////////////////////////////////////////////
  1091. // The winProc for the new oid dialogue
  1092. //////////////////////////////////////////////////////////////////////////////////////
  1093. INT_PTR APIENTRY CTLOIDDialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  1094. {
  1095. DWORD i;
  1096. char szText[MAX_STRING_SIZE];
  1097. LPSTR pszText=NULL;
  1098. int intMsg=0;
  1099. CERT_ENHKEY_USAGE KeyUsage;
  1100. DWORD cbData = 0;
  1101. LPSTR pszCheckOID=NULL;
  1102. switch ( msg ) {
  1103. case WM_COMMAND:
  1104. switch (LOWORD(wParam))
  1105. {
  1106. case IDOK:
  1107. if (GetDlgItemTextA(
  1108. hwndDlg,
  1109. IDC_WIZARD_EDIT1,
  1110. szText,
  1111. MAX_STRING_SIZE-1))
  1112. {
  1113. //
  1114. // make sure there are not weird characters
  1115. //
  1116. for (i=0; i<(DWORD)strlen(szText); i++)
  1117. {
  1118. if (((szText[i] < '0') || (szText[i] > '9')) && (szText[i] != '.'))
  1119. {
  1120. intMsg=I_MessageBox(hwndDlg, IDS_WIZARD_ERROR_OID,
  1121. IDS_BUILDCTL_WIZARD_TITLE,
  1122. NULL,
  1123. MB_OK | MB_ICONERROR|MB_APPLMODAL);
  1124. return FALSE;
  1125. }
  1126. }
  1127. //
  1128. // check the last char, and for the empty string
  1129. //
  1130. if ((szText[0] == '.') || (szText[strlen(szText)-1] == '.') || (strcmp(szText, "") == 0))
  1131. {
  1132. intMsg=I_MessageBox(hwndDlg, IDS_WIZARD_ERROR_OID,
  1133. IDS_BUILDCTL_WIZARD_TITLE,
  1134. NULL,
  1135. MB_OK | MB_ICONERROR|MB_APPLMODAL);
  1136. return FALSE;
  1137. }
  1138. //encode the OID to make sure the format of the OID is correct
  1139. pszCheckOID = szText;
  1140. KeyUsage.rgpszUsageIdentifier = &pszCheckOID;
  1141. KeyUsage.cUsageIdentifier = 1;
  1142. if (!CryptEncodeObject(
  1143. X509_ASN_ENCODING,
  1144. szOID_ENHANCED_KEY_USAGE,
  1145. &KeyUsage,
  1146. NULL,
  1147. &cbData))
  1148. {
  1149. intMsg=I_MessageBox(hwndDlg, IDS_WIZARD_ERROR_OID,
  1150. IDS_BUILDCTL_WIZARD_TITLE,
  1151. NULL,
  1152. MB_OK | MB_ICONERROR|MB_APPLMODAL);
  1153. return FALSE;
  1154. }
  1155. //
  1156. // allocate space for the string and pass the string back
  1157. //
  1158. pszText = (LPSTR) WizardAlloc(strlen(szText)+1);
  1159. if (pszText != NULL)
  1160. {
  1161. strcpy(pszText, szText);
  1162. }
  1163. }
  1164. EndDialog(hwndDlg, (INT_PTR)pszText);
  1165. break;
  1166. case IDCANCEL:
  1167. EndDialog(hwndDlg, 0);
  1168. break;
  1169. }
  1170. break;
  1171. }
  1172. return FALSE;
  1173. }
  1174. //-----------------------------------------------------------------------
  1175. //Free the purpose array
  1176. //-----------------------------------------------------------------------
  1177. void FreePurposeInfo(ENROLL_PURPOSE_INFO **prgPurposeInfo,
  1178. DWORD dwOIDCount)
  1179. {
  1180. DWORD dwIndex=0;
  1181. if(dwOIDCount==0 || NULL==prgPurposeInfo)
  1182. return;
  1183. for(dwIndex=0; dwIndex<dwOIDCount; dwIndex++)
  1184. {
  1185. if(prgPurposeInfo[dwIndex])
  1186. {
  1187. if(TRUE==prgPurposeInfo[dwIndex]->fFreeOID)
  1188. {
  1189. if((prgPurposeInfo[dwIndex])->pszOID)
  1190. WizardFree((prgPurposeInfo[dwIndex])->pszOID);
  1191. }
  1192. if(TRUE==prgPurposeInfo[dwIndex]->fFreeName)
  1193. {
  1194. //the name was obtained viz MkWstr
  1195. if((prgPurposeInfo[dwIndex])->pwszName)
  1196. FreeWStr((prgPurposeInfo[dwIndex])->pwszName);
  1197. }
  1198. WizardFree(prgPurposeInfo[dwIndex]);
  1199. }
  1200. }
  1201. WizardFree(prgPurposeInfo);
  1202. }
  1203. //-----------------------------------------------------------------------
  1204. //Search for the OID in the array
  1205. //-----------------------------------------------------------------------
  1206. BOOL SearchAndAddOID(LPSTR pszOID,
  1207. DWORD *pdwCount,
  1208. ENROLL_PURPOSE_INFO ***pprgPurposeInfo,
  1209. BOOL *pfFound,
  1210. BOOL fAllocateOID,
  1211. BOOL fMarkAsSelectedNew,
  1212. BOOL fMarkAsSelectedFound
  1213. )
  1214. {
  1215. DWORD dwIndex=0;
  1216. if(NULL==pszOID || NULL==pdwCount || NULL==pprgPurposeInfo)
  1217. return FALSE;
  1218. for(dwIndex=0; dwIndex< *pdwCount; dwIndex++)
  1219. {
  1220. //no need to go on if we find a match
  1221. if(0==strcmp(pszOID, (*pprgPurposeInfo)[dwIndex]->pszOID))
  1222. {
  1223. if(pfFound)
  1224. *pfFound=TRUE;
  1225. //mark the selected option
  1226. if(TRUE==fMarkAsSelectedFound)
  1227. (*pprgPurposeInfo)[dwIndex]->fSelected=TRUE;
  1228. return TRUE;
  1229. }
  1230. }
  1231. //we did not find a match
  1232. if(pfFound)
  1233. *pfFound=FALSE;
  1234. //now, we need to add the OID to the list
  1235. (*pdwCount)++;
  1236. //get more memory for the pointer list
  1237. *pprgPurposeInfo=(ENROLL_PURPOSE_INFO **)WizardRealloc(*pprgPurposeInfo,
  1238. (*pdwCount) * sizeof(ENROLL_PURPOSE_INFO *));
  1239. if(NULL==*pprgPurposeInfo)
  1240. return FALSE;
  1241. //wizardAlloc for each pointer
  1242. (*pprgPurposeInfo)[*pdwCount-1]=(ENROLL_PURPOSE_INFO *)WizardAlloc(sizeof(ENROLL_PURPOSE_INFO));
  1243. if(NULL==(*pprgPurposeInfo)[*pdwCount-1])
  1244. return FALSE;
  1245. memset((*pprgPurposeInfo)[*pdwCount-1], 0, sizeof(ENROLL_PURPOSE_INFO));
  1246. if(TRUE==fAllocateOID)
  1247. {
  1248. (*pprgPurposeInfo)[*pdwCount-1]->pszOID=(LPSTR)WizardAlloc(strlen(pszOID)+1);
  1249. if(NULL!=(*pprgPurposeInfo)[*pdwCount-1]->pszOID)
  1250. {
  1251. strcpy((*pprgPurposeInfo)[*pdwCount-1]->pszOID, pszOID);
  1252. (*pprgPurposeInfo)[*pdwCount-1]->fFreeOID=TRUE;
  1253. }
  1254. }
  1255. else
  1256. {
  1257. (*pprgPurposeInfo)[*pdwCount-1]->pszOID=pszOID;
  1258. (*pprgPurposeInfo)[*pdwCount-1]->fFreeOID=FALSE;
  1259. }
  1260. //get the name for the OID based on the oid string
  1261. if((*pprgPurposeInfo)[*pdwCount-1]->pszOID)
  1262. {
  1263. (*pprgPurposeInfo)[*pdwCount-1]->pwszName=MkWStr(pszOID);
  1264. (*pprgPurposeInfo)[*pdwCount-1]->fFreeName=TRUE;
  1265. }
  1266. //mark the OID as selected if specified
  1267. if(TRUE==fMarkAsSelectedNew)
  1268. (*pprgPurposeInfo)[*pdwCount-1]->fSelected=TRUE;
  1269. else
  1270. (*pprgPurposeInfo)[*pdwCount-1]->fSelected=FALSE;
  1271. return TRUE;
  1272. }
  1273. //-----------------------------------------------------------------------
  1274. //The call back function for enum
  1275. //-----------------------------------------------------------------------
  1276. static BOOL WINAPI EnumInfoCallback(
  1277. IN PCCRYPT_OID_INFO pInfo,
  1278. IN void *pvArg
  1279. )
  1280. {
  1281. PURPOSE_INFO_CALL_BACK *pCallBackInfo=NULL;
  1282. DWORD dwError=0;
  1283. pCallBackInfo=(PURPOSE_INFO_CALL_BACK *)pvArg;
  1284. if(NULL==pvArg || NULL==pInfo)
  1285. return FALSE;
  1286. //increment the oid list
  1287. (*(pCallBackInfo->pdwCount))++;
  1288. //get more memory for the pointer list
  1289. *(pCallBackInfo->pprgPurpose)=(ENROLL_PURPOSE_INFO **)WizardRealloc(*(pCallBackInfo->pprgPurpose),
  1290. (*(pCallBackInfo->pdwCount)) * sizeof(ENROLL_PURPOSE_INFO *));
  1291. if(NULL==*(pCallBackInfo->pprgPurpose))
  1292. {
  1293. dwError=GetLastError();
  1294. return FALSE;
  1295. }
  1296. //wizardAlloc for each pointer
  1297. (*(pCallBackInfo->pprgPurpose))[*(pCallBackInfo->pdwCount)-1]=(ENROLL_PURPOSE_INFO *)WizardAlloc(sizeof(ENROLL_PURPOSE_INFO));
  1298. if(NULL==(*(pCallBackInfo->pprgPurpose))[*(pCallBackInfo->pdwCount)-1])
  1299. return FALSE;
  1300. memset((*(pCallBackInfo->pprgPurpose))[*(pCallBackInfo->pdwCount)-1], 0, sizeof(ENROLL_PURPOSE_INFO));
  1301. (*(pCallBackInfo->pprgPurpose))[*(pCallBackInfo->pdwCount)-1]->pszOID=(LPSTR)(pInfo->pszOID);
  1302. (*(pCallBackInfo->pprgPurpose))[*(pCallBackInfo->pdwCount)-1]->pwszName=(LPWSTR)(pInfo->pwszName);
  1303. return TRUE;
  1304. }
  1305. //-----------------------------------------------------------------------
  1306. //Initialize usage OID to display
  1307. //-----------------------------------------------------------------------
  1308. BOOL GetOIDForCTL(CERT_BUILDCTL_INFO *pCertBuildCTLInfo,
  1309. DWORD cUsageID,
  1310. LPSTR *rgpszUsageID)
  1311. {
  1312. BOOL fResult=FALSE;
  1313. PURPOSE_INFO_CALL_BACK PurposeCallBack;
  1314. PCTL_INFO pCTLInfo=NULL;
  1315. DWORD dwIndex=0;
  1316. DWORD dwCount=0;
  1317. ENROLL_PURPOSE_INFO **prgPurposeInfo=NULL;
  1318. //init
  1319. memset(&PurposeCallBack, 0, sizeof(PURPOSE_INFO_CALL_BACK));
  1320. if(NULL==pCertBuildCTLInfo)
  1321. return FALSE;
  1322. //init
  1323. PurposeCallBack.pdwCount=&dwCount;
  1324. PurposeCallBack.pprgPurpose=&prgPurposeInfo;
  1325. //enum all the enhanced key usages
  1326. if(!CryptEnumOIDInfo(
  1327. CRYPT_ENHKEY_USAGE_OID_GROUP_ID,
  1328. 0,
  1329. &PurposeCallBack,
  1330. EnumInfoCallback))
  1331. goto CLEANUP;
  1332. //add the existing ones in the old CTL if they do not exist
  1333. //from the enum list
  1334. if(pCertBuildCTLInfo->pSrcCTL)
  1335. {
  1336. if(pCertBuildCTLInfo->pSrcCTL->pCtlInfo)
  1337. {
  1338. pCTLInfo=pCertBuildCTLInfo->pSrcCTL->pCtlInfo;
  1339. for(dwIndex=0; dwIndex<pCTLInfo->SubjectUsage.cUsageIdentifier; dwIndex++)
  1340. {
  1341. if(!SearchAndAddOID(pCTLInfo->SubjectUsage.rgpszUsageIdentifier[dwIndex],
  1342. &dwCount,
  1343. &prgPurposeInfo,
  1344. NULL,
  1345. FALSE,
  1346. TRUE, //mark as selected if new oid
  1347. TRUE)) //mark as selected if existing oid
  1348. goto CLEANUP;
  1349. }
  1350. }
  1351. }
  1352. else
  1353. {
  1354. //add the pre-defined OIDs
  1355. if((0!=cUsageID) && (NULL!=rgpszUsageID))
  1356. {
  1357. for(dwIndex=0; dwIndex<cUsageID; dwIndex++)
  1358. {
  1359. if(!SearchAndAddOID(rgpszUsageID[dwIndex],
  1360. &dwCount,
  1361. &prgPurposeInfo,
  1362. NULL,
  1363. FALSE, //do not allocate for the OID
  1364. TRUE, //mark as selected if new oid
  1365. TRUE)) //mark as selected if existing oid
  1366. goto CLEANUP;
  1367. }
  1368. }
  1369. }
  1370. fResult=TRUE;
  1371. CLEANUP:
  1372. if(FALSE==fResult)
  1373. {
  1374. if(prgPurposeInfo)
  1375. FreePurposeInfo(prgPurposeInfo, dwCount);
  1376. }
  1377. else
  1378. {
  1379. pCertBuildCTLInfo->dwPurposeCount=dwCount;
  1380. pCertBuildCTLInfo->prgPurpose=prgPurposeInfo;
  1381. }
  1382. return fResult;
  1383. }
  1384. //-----------------------------------------------------------------------
  1385. //Initialize the usage OID list
  1386. //-----------------------------------------------------------------------
  1387. BOOL InitBuildCTLOID(HWND hwndList,
  1388. CERT_BUILDCTL_INFO *pCertBuildCTLInfo)
  1389. {
  1390. DWORD dwCount=0;
  1391. ENROLL_PURPOSE_INFO **prgPurposeInfo=NULL;
  1392. DWORD dwIndex=0;
  1393. LV_ITEMW lvItem;
  1394. LV_COLUMNW lvC;
  1395. int dwMaxSize=0;
  1396. if(!hwndList || !pCertBuildCTLInfo)
  1397. return FALSE;
  1398. //get the list of OIDs from the old CTL and all possibilities
  1399. dwCount=pCertBuildCTLInfo->dwPurposeCount;
  1400. prgPurposeInfo=pCertBuildCTLInfo->prgPurpose;
  1401. //mark the list is selected by a check box
  1402. ListView_SetExtendedListViewStyle(hwndList, LVS_EX_CHECKBOXES);
  1403. //get the max length of the column
  1404. for(dwIndex=0; dwIndex<dwCount; dwIndex++)
  1405. {
  1406. if(dwMaxSize < wcslen((prgPurposeInfo[dwIndex])->pwszName))
  1407. dwMaxSize=wcslen((prgPurposeInfo[dwIndex])->pwszName);
  1408. }
  1409. //insert a column into the list view
  1410. memset(&lvC, 0, sizeof(LV_COLUMNW));
  1411. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  1412. lvC.fmt = LVCFMT_LEFT; // Left-align the column.
  1413. lvC.cx =10; // (dwMaxSize+2)*7; // Width of the column, in pixels.
  1414. lvC.pszText = L""; // The text for the column.
  1415. lvC.iSubItem=0;
  1416. if (ListView_InsertColumnU(hwndList, 0, &lvC) == -1)
  1417. return FALSE;
  1418. //populate the list
  1419. memset(&lvItem, 0, sizeof(LV_ITEMW));
  1420. lvItem.mask=LVIF_TEXT | LVIF_STATE;
  1421. for(dwIndex=0; dwIndex<dwCount; dwIndex++)
  1422. {
  1423. lvItem.iItem=dwIndex;
  1424. lvItem.pszText=(prgPurposeInfo[dwIndex])->pwszName;
  1425. lvItem.cchTextMax=sizeof(WCHAR)*(1+wcslen((prgPurposeInfo[dwIndex])->pwszName));
  1426. lvItem.stateMask = LVIS_STATEIMAGEMASK;
  1427. lvItem.state = (prgPurposeInfo[dwIndex])->fSelected ? 0x00002000 : 0x00001000;
  1428. //insert the list
  1429. // insert and set state
  1430. ListView_SetItemState(hwndList,
  1431. ListView_InsertItemU(hwndList, &lvItem),
  1432. (prgPurposeInfo[dwIndex])->fSelected ? 0x00002000 : 0x00001000,
  1433. LVIS_STATEIMAGEMASK);
  1434. }
  1435. //autosize the column
  1436. ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE);
  1437. return TRUE;
  1438. }
  1439. //-----------------------------------------------------------------------
  1440. //populate the list box in the order of
  1441. //Purpose, FileName, StoreName, FriendlyName,
  1442. //and any other things signing wizard display
  1443. //-----------------------------------------------------------------------
  1444. void DisplayBuildCTLConfirmation(HWND hwndControl,
  1445. CERT_BUILDCTL_INFO *pCertBuildCTLInfo)
  1446. {
  1447. DWORD dwIndex=0;
  1448. LPWSTR pwszStoreName=NULL;
  1449. WCHAR wszNone[MAX_TITLE_LENGTH];
  1450. BOOL fNewItem=FALSE;
  1451. DWORD dwSize=0;
  1452. LPWSTR pwszValidityString=NULL;
  1453. LV_COLUMNW lvC;
  1454. LV_ITEMW lvItem;
  1455. //pCertBuildCTLInfo has to be valid
  1456. if(!pCertBuildCTLInfo)
  1457. return;
  1458. //delete all the old items in the listView
  1459. ListView_DeleteAllItems(hwndControl);
  1460. //load the string <none>
  1461. if(!LoadStringU(g_hmodThisDll, IDS_NONE, wszNone, MAX_TITLE_LENGTH))
  1462. *wszNone=L'\0';
  1463. //get the storename
  1464. if(pCertBuildCTLInfo->hDesStore)
  1465. {
  1466. if(!CertGetStoreProperty(
  1467. pCertBuildCTLInfo->hDesStore,
  1468. CERT_STORE_LOCALIZED_NAME_PROP_ID,
  1469. NULL,
  1470. &dwSize) || (0==dwSize))
  1471. {
  1472. //Get the <Unknown> string
  1473. pwszStoreName=(LPWSTR)WizardAlloc(MAX_TITLE_LENGTH * sizeof(WCHAR));
  1474. if(pwszStoreName)
  1475. {
  1476. *pwszStoreName=L'\0';
  1477. LoadStringU(g_hmodThisDll, IDS_UNKNOWN, pwszStoreName, MAX_TITLE_LENGTH);
  1478. }
  1479. }
  1480. else
  1481. {
  1482. pwszStoreName=(LPWSTR)WizardAlloc(dwSize);
  1483. if(pwszStoreName)
  1484. {
  1485. *pwszStoreName=L'\0';
  1486. CertGetStoreProperty(
  1487. pCertBuildCTLInfo->hDesStore,
  1488. CERT_STORE_LOCALIZED_NAME_PROP_ID,
  1489. pwszStoreName,
  1490. &dwSize);
  1491. }
  1492. }
  1493. }
  1494. //insert row by row
  1495. memset(&lvItem, 0, sizeof(LV_ITEMW));
  1496. // set up the fields in the list view item struct that don't change from item to item
  1497. lvItem.mask = LVIF_TEXT | LVIF_STATE ;
  1498. lvItem.state = 0;
  1499. lvItem.stateMask = 0;
  1500. lvItem.iItem=0;
  1501. lvItem.iSubItem=0;
  1502. //Purpose. We are guaranteed to have at least one item in the purpose list
  1503. ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_CTL_PURPOSE, NULL);
  1504. for(dwIndex=0; dwIndex<pCertBuildCTLInfo->dwPurposeCount; dwIndex++)
  1505. {
  1506. if(TRUE==((pCertBuildCTLInfo->prgPurpose)[dwIndex]->fSelected))
  1507. {
  1508. if(TRUE==fNewItem)
  1509. {
  1510. //increase the row
  1511. lvItem.iItem++;
  1512. lvItem.pszText=L"";
  1513. lvItem.iSubItem=0;
  1514. ListView_InsertItemU(hwndControl, &lvItem);
  1515. }
  1516. else
  1517. fNewItem=TRUE;
  1518. lvItem.iSubItem++;
  1519. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
  1520. (pCertBuildCTLInfo->prgPurpose)[dwIndex]->pwszName);
  1521. }
  1522. }
  1523. //list ID
  1524. lvItem.iItem++;
  1525. lvItem.iSubItem=0;
  1526. ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_CTL_ID, NULL);
  1527. //content
  1528. lvItem.iSubItem++;
  1529. if(pCertBuildCTLInfo->pwszListID)
  1530. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,pCertBuildCTLInfo->pwszListID);
  1531. else
  1532. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,wszNone);
  1533. //validity
  1534. lvItem.iItem++;
  1535. lvItem.iSubItem=0;
  1536. ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_CTL_VALIDITY, NULL);
  1537. //content
  1538. lvItem.iSubItem++;
  1539. if(pCertBuildCTLInfo->dwValidMonths || pCertBuildCTLInfo->dwValidDays)
  1540. {
  1541. GetValidityString(pCertBuildCTLInfo->dwValidMonths, pCertBuildCTLInfo->dwValidDays,
  1542. &pwszValidityString);
  1543. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,pwszValidityString);
  1544. }
  1545. else
  1546. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,wszNone);
  1547. //only show the file name or store name if the destination page
  1548. //is not skipped
  1549. if(0 == (pCertBuildCTLInfo->dwFlag & CRYPTUI_WIZ_BUILDCTL_SKIP_DESTINATION))
  1550. {
  1551. //file name
  1552. if(pCertBuildCTLInfo->pwszFileName && (TRUE==(pCertBuildCTLInfo->fSelectedFileName)))
  1553. {
  1554. lvItem.iItem++;
  1555. lvItem.iSubItem=0;
  1556. ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_FILE_NAME, NULL);
  1557. //content
  1558. lvItem.iSubItem++;
  1559. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
  1560. pCertBuildCTLInfo->pwszFileName);
  1561. }
  1562. //StoreName
  1563. if(pCertBuildCTLInfo->hDesStore && (TRUE==pCertBuildCTLInfo->fSelectedDesStore))
  1564. {
  1565. if(pwszStoreName)
  1566. {
  1567. lvItem.iItem++;
  1568. lvItem.iSubItem=0;
  1569. ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_STORE_NAME, NULL);
  1570. //content
  1571. lvItem.iSubItem++;
  1572. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
  1573. pwszStoreName);
  1574. }
  1575. }
  1576. }
  1577. //FriendlyName and descripton will be displayed if the hDesStore is not NULL
  1578. // if(pCertBuildCTLInfo->hDesStore && (TRUE==pCertBuildCTLInfo->fSelectedDesStore))
  1579. // {
  1580. //friendlyName
  1581. lvItem.iItem++;
  1582. lvItem.iSubItem=0;
  1583. ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_FRIENDLY_NAME, NULL);
  1584. //content
  1585. lvItem.iSubItem++;
  1586. if(pCertBuildCTLInfo->pwszFriendlyName)
  1587. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,pCertBuildCTLInfo->pwszFriendlyName);
  1588. else
  1589. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,wszNone);
  1590. //description
  1591. lvItem.iItem++;
  1592. lvItem.iSubItem=0;
  1593. ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_DESCRIPTION, NULL);
  1594. //content
  1595. lvItem.iSubItem++;
  1596. if(pCertBuildCTLInfo->pwszDescription)
  1597. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,pCertBuildCTLInfo->pwszDescription);
  1598. else
  1599. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,wszNone);
  1600. //}
  1601. //autosize the columns
  1602. ListView_SetColumnWidth(hwndControl, 0, LVSCW_AUTOSIZE);
  1603. ListView_SetColumnWidth(hwndControl, 1, LVSCW_AUTOSIZE);
  1604. //free the memory
  1605. if(pwszStoreName)
  1606. WizardFree(pwszStoreName);
  1607. if(pwszValidityString)
  1608. WizardFree(pwszValidityString);
  1609. return;
  1610. }
  1611. //**************************************************************************
  1612. //
  1613. // The winProcs for the buildCtl wizard
  1614. //**************************************************************************
  1615. //-----------------------------------------------------------------------
  1616. //BuildCTL_Welcome
  1617. //-----------------------------------------------------------------------
  1618. INT_PTR APIENTRY BuildCTL_Welcome(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  1619. {
  1620. CERT_BUILDCTL_INFO *pCertBuildCTLInfo=NULL;
  1621. PROPSHEETPAGEW *pPropSheet=NULL;
  1622. switch (msg)
  1623. {
  1624. case WM_INITDIALOG:
  1625. //set the wizard information so that it can be shared
  1626. pPropSheet = (PROPSHEETPAGEW *) lParam;
  1627. pCertBuildCTLInfo = (CERT_BUILDCTL_INFO *) (pPropSheet->lParam);
  1628. //make sure pCertBuildCTLInfo is a valid pointer
  1629. if(NULL==pCertBuildCTLInfo)
  1630. break;
  1631. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertBuildCTLInfo);
  1632. SetControlFont(pCertBuildCTLInfo->hBigBold, hwndDlg,IDC_WIZARD_STATIC_BIG_BOLD1);
  1633. SetControlFont(pCertBuildCTLInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
  1634. break;
  1635. case WM_NOTIFY:
  1636. switch (((NMHDR FAR *) lParam)->code)
  1637. {
  1638. case PSN_KILLACTIVE:
  1639. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  1640. return TRUE;
  1641. break;
  1642. case PSN_RESET:
  1643. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  1644. break;
  1645. case PSN_SETACTIVE:
  1646. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
  1647. break;
  1648. case PSN_WIZBACK:
  1649. break;
  1650. case PSN_WIZNEXT:
  1651. if(NULL==(pCertBuildCTLInfo=(CERT_BUILDCTL_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  1652. break;
  1653. //check if we need to skip the 1st page
  1654. if(CRYPTUI_WIZ_BUILDCTL_SKIP_PURPOSE & pCertBuildCTLInfo->dwFlag)
  1655. {
  1656. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_BUILDCTL_CERTS);
  1657. }
  1658. break;
  1659. default:
  1660. return FALSE;
  1661. }
  1662. break;
  1663. default:
  1664. return FALSE;
  1665. }
  1666. return TRUE;
  1667. }
  1668. //-----------------------------------------------------------------------
  1669. //BuildCTL_Purpose
  1670. //-----------------------------------------------------------------------
  1671. INT_PTR APIENTRY BuildCTL_Purpose(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  1672. {
  1673. CERT_BUILDCTL_INFO *pCertBuildCTLInfo=NULL;
  1674. PROPSHEETPAGEW *pPropSheet=NULL;
  1675. HWND hwndControl=NULL;
  1676. DWORD dwCount=0;
  1677. DWORD dwIndex=0;
  1678. NM_LISTVIEW FAR * pnmv=NULL;
  1679. int intMsg=0;
  1680. LPSTR pszNewOID;
  1681. BOOL fFound=FALSE;
  1682. LV_ITEMW lvItem;
  1683. DWORD dwChar=0;
  1684. WCHAR wszMonth[BUILDCTL_DURATION_SIZE];
  1685. WCHAR wszDay[BUILDCTL_DURATION_SIZE];
  1686. BOOL fUserTypeDuration=FALSE;
  1687. LPWSTR pwszDuration=NULL;
  1688. switch (msg)
  1689. {
  1690. case WM_INITDIALOG:
  1691. //set the wizard information so that it can be shared
  1692. pPropSheet = (PROPSHEETPAGEW *) lParam;
  1693. pCertBuildCTLInfo = (CERT_BUILDCTL_INFO *) (pPropSheet->lParam);
  1694. //make sure pCertBuildCTLInfo is a valid pointer
  1695. if(NULL==pCertBuildCTLInfo)
  1696. break;
  1697. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertBuildCTLInfo);
  1698. SetControlFont(pCertBuildCTLInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
  1699. //initizialize the OID list
  1700. InitBuildCTLOID(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1),
  1701. pCertBuildCTLInfo);
  1702. //initialize the ListID
  1703. if(pCertBuildCTLInfo->pwszListID)
  1704. SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1, pCertBuildCTLInfo->pwszListID);
  1705. //mark that we are done with the init OID ListView
  1706. //if user de-select OIDs from now on, they will be prompted for the
  1707. //warning
  1708. pCertBuildCTLInfo->fCompleteInit=TRUE;
  1709. //init the dwValidMonth and dwValidDays
  1710. if(pCertBuildCTLInfo->dwValidMonths != 0)
  1711. {
  1712. _ltow(pCertBuildCTLInfo->dwValidMonths, wszMonth, 10);
  1713. SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT_MONTH, wszMonth);
  1714. }
  1715. if(pCertBuildCTLInfo->dwValidDays != 0)
  1716. {
  1717. _ltow(pCertBuildCTLInfo->dwValidDays, wszDay, 10);
  1718. SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT_DAY, wszDay);
  1719. }
  1720. break;
  1721. case WM_COMMAND:
  1722. if(HIWORD(wParam) == BN_CLICKED)
  1723. {
  1724. switch (LOWORD(wParam))
  1725. {
  1726. case IDC_WIZARD_BUTTON1:
  1727. if(NULL==(pCertBuildCTLInfo=(CERT_BUILDCTL_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  1728. {
  1729. break;
  1730. }
  1731. //get the window handle of the cert list view
  1732. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
  1733. break;
  1734. //prompt user to enter the user OID
  1735. pszNewOID = (LPSTR) DialogBoxU(
  1736. g_hmodThisDll,
  1737. (LPCWSTR)MAKEINTRESOURCE(IDD_BUILDCTL_USER_PURPOSE),
  1738. hwndDlg,
  1739. CTLOIDDialogProc);
  1740. //add the OID to the list
  1741. if(NULL != pszNewOID)
  1742. {
  1743. SearchAndAddOID(
  1744. pszNewOID,
  1745. &(pCertBuildCTLInfo->dwPurposeCount),
  1746. &(pCertBuildCTLInfo->prgPurpose),
  1747. &fFound,
  1748. TRUE,
  1749. TRUE, //mark as selected if new oid
  1750. FALSE); //do not mark as selected if existing oid
  1751. if(fFound==TRUE)
  1752. {
  1753. I_MessageBox(hwndDlg, IDS_EXISTING_OID,
  1754. IDS_BUILDCTL_WIZARD_TITLE,
  1755. NULL,
  1756. MB_ICONINFORMATION|MB_OK|MB_APPLMODAL);
  1757. }
  1758. else
  1759. {
  1760. //add the item to the list view
  1761. //populate the list
  1762. memset(&lvItem, 0, sizeof(LV_ITEMW));
  1763. lvItem.mask=LVIF_TEXT | LVIF_STATE;
  1764. lvItem.iItem=pCertBuildCTLInfo->dwPurposeCount-1;
  1765. lvItem.pszText=(pCertBuildCTLInfo->prgPurpose[pCertBuildCTLInfo->dwPurposeCount-1])->pwszName;
  1766. lvItem.cchTextMax=sizeof(WCHAR)*(1+wcslen
  1767. ((pCertBuildCTLInfo->prgPurpose[pCertBuildCTLInfo->dwPurposeCount-1])->pwszName));
  1768. lvItem.stateMask = LVIS_STATEIMAGEMASK;
  1769. lvItem.state = (pCertBuildCTLInfo->prgPurpose[pCertBuildCTLInfo->dwPurposeCount-1])->fSelected ? 0x00002000 : 0x00001000;
  1770. // insert and set state
  1771. //mark no warning for the user
  1772. pCertBuildCTLInfo->fCompleteInit=FALSE;
  1773. ListView_SetItemState(hwndControl,
  1774. ListView_InsertItemU(hwndControl, &lvItem),
  1775. (pCertBuildCTLInfo->prgPurpose[pCertBuildCTLInfo->dwPurposeCount-1])->fSelected ? 0x00002000 : 0x00001000,
  1776. LVIS_STATEIMAGEMASK);
  1777. //mark the end of setting
  1778. pCertBuildCTLInfo->fCompleteInit=TRUE;
  1779. //autosize the column
  1780. ListView_SetColumnWidth(hwndControl, 0, LVSCW_AUTOSIZE);
  1781. }
  1782. }
  1783. //free the pszNewOID
  1784. if(pszNewOID)
  1785. WizardFree(pszNewOID);
  1786. break;
  1787. }
  1788. }
  1789. break;
  1790. case WM_NOTIFY:
  1791. switch (((NMHDR FAR *) lParam)->code)
  1792. {
  1793. case PSN_KILLACTIVE:
  1794. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  1795. return TRUE;
  1796. break;
  1797. case PSN_RESET:
  1798. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  1799. break;
  1800. case PSN_SETACTIVE:
  1801. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
  1802. break;
  1803. case PSN_WIZBACK:
  1804. break;
  1805. case LVN_ITEMCHANGING:
  1806. if(NULL==(pCertBuildCTLInfo=(CERT_BUILDCTL_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  1807. {
  1808. break;
  1809. }
  1810. //the item has been chagned.
  1811. pnmv = (NM_LISTVIEW FAR *) lParam;
  1812. if(NULL==pnmv)
  1813. break;
  1814. //ingore if we have not complete the init yet
  1815. if(NULL == pCertBuildCTLInfo->prgPurpose)
  1816. //we allow change
  1817. return FALSE;
  1818. //ignore if we are not complete with the
  1819. //init yet
  1820. if(FALSE==pCertBuildCTLInfo->fCompleteInit)
  1821. return FALSE;
  1822. //see if the new item is de-selected
  1823. if(pnmv->uChanged & LVIF_STATE)
  1824. {
  1825. if(FALSE==(((pnmv->uNewState & LVIS_STATEIMAGEMASK)>> 12) -1))
  1826. {
  1827. if(TRUE==(pCertBuildCTLInfo->prgPurpose[pnmv->iItem])->fSelected)
  1828. {
  1829. //check to see if the user has selected any certs
  1830. if(0!=pCertBuildCTLInfo->dwCertCount)
  1831. {
  1832. //ask user if they are sure to change the subject
  1833. //of the CTL, thus the whole cert list will be gone
  1834. intMsg=I_MessageBox(hwndDlg, IDS_SURE_CERT_GONE,
  1835. IDS_BUILDCTL_WIZARD_TITLE,
  1836. NULL,
  1837. MB_ICONEXCLAMATION|MB_YESNO|MB_APPLMODAL);
  1838. if(IDYES==intMsg)
  1839. {
  1840. //free all the certificate context and
  1841. //clear the listView of the ceritificate
  1842. pCertBuildCTLInfo->fClearCerts=TRUE;
  1843. //we allow change
  1844. return FALSE;
  1845. }
  1846. //we disallow the change
  1847. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
  1848. return TRUE;
  1849. }
  1850. }
  1851. }
  1852. }
  1853. //we allow the chagne
  1854. return FALSE;
  1855. break;
  1856. case PSN_WIZNEXT:
  1857. if(NULL==(pCertBuildCTLInfo=(CERT_BUILDCTL_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  1858. break;
  1859. //get the window handle of the purpose list view
  1860. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
  1861. break;
  1862. //get the count of selected OIDs and mark them
  1863. dwCount=0;
  1864. for(dwIndex=0; dwIndex<pCertBuildCTLInfo->dwPurposeCount; dwIndex++)
  1865. {
  1866. //mark the selected OIDS. Keep track of
  1867. //if the OID selections have been changed
  1868. if(ListView_GetCheckState(hwndControl, dwIndex))
  1869. {
  1870. ((pCertBuildCTLInfo->prgPurpose)[dwIndex])->fSelected=TRUE;
  1871. dwCount++;
  1872. }
  1873. else
  1874. {
  1875. ((pCertBuildCTLInfo->prgPurpose)[dwIndex])->fSelected=FALSE;
  1876. }
  1877. }
  1878. if(0==dwCount)
  1879. {
  1880. I_MessageBox(hwndDlg, IDS_NO_SELECTED_CTL_PURPOSE,
  1881. IDS_BUILDCTL_WIZARD_TITLE,
  1882. NULL,
  1883. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  1884. //the page should stay
  1885. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  1886. break;
  1887. }
  1888. //get the list ID if user has specified it.
  1889. if(pCertBuildCTLInfo->pwszListID)
  1890. {
  1891. WizardFree(pCertBuildCTLInfo->pwszListID);
  1892. pCertBuildCTLInfo->pwszListID=NULL;
  1893. }
  1894. if(0!=(dwChar=(DWORD)SendDlgItemMessage(hwndDlg,
  1895. IDC_WIZARD_EDIT1,
  1896. WM_GETTEXTLENGTH, 0, 0)))
  1897. {
  1898. pCertBuildCTLInfo->pwszListID=(LPWSTR)WizardAlloc(sizeof(WCHAR)*(dwChar+1));
  1899. if(NULL!=pCertBuildCTLInfo->pwszListID)
  1900. {
  1901. GetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,
  1902. pCertBuildCTLInfo->pwszListID,
  1903. dwChar+1);
  1904. }
  1905. else
  1906. //we are out of memory and out of hope
  1907. break;
  1908. }
  1909. //get the valid month and valid days that user specified
  1910. if(0!=(dwChar=(DWORD)SendDlgItemMessage(hwndDlg,
  1911. IDC_WIZARD_EDIT_MONTH,
  1912. WM_GETTEXTLENGTH, 0, 0)))
  1913. {
  1914. fUserTypeDuration=TRUE;
  1915. pwszDuration=(LPWSTR)WizardAlloc(sizeof(WCHAR)*(dwChar+1));
  1916. if(NULL!=pwszDuration)
  1917. {
  1918. GetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT_MONTH,
  1919. pwszDuration,
  1920. dwChar+1);
  1921. }
  1922. else
  1923. //we are out of memory and out of hope
  1924. break;
  1925. //make sure the character are valid
  1926. /*if(!ValidDuration(pwszDuration))
  1927. {
  1928. I_MessageBox(hwndDlg, IDS_INVALID_MONTHS,
  1929. IDS_BUILDCTL_WIZARD_TITLE,
  1930. NULL,
  1931. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  1932. WizardFree(pwszDuration);
  1933. pwszDuration=NULL;
  1934. //the page should stay
  1935. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  1936. break;
  1937. }*/
  1938. pCertBuildCTLInfo->dwValidMonths=_wtol(pwszDuration);
  1939. /*if( (0 == pCertBuildCTLInfo->dwValidMonths && !ValidZero(pwszDuration)) ||
  1940. (0 > _wtol(pwszDuration))
  1941. )
  1942. {
  1943. if(!ValidZero(pwszDuration))
  1944. {
  1945. I_MessageBox(hwndDlg, IDS_INVALID_MONTHS,
  1946. IDS_BUILDCTL_WIZARD_TITLE,
  1947. NULL,
  1948. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  1949. WizardFree(pwszDuration);
  1950. pwszDuration=NULL;
  1951. //the page should stay
  1952. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  1953. break;
  1954. }
  1955. } */
  1956. }
  1957. else
  1958. pCertBuildCTLInfo->dwValidMonths=0;
  1959. //Free the memory
  1960. if(pwszDuration)
  1961. {
  1962. WizardFree(pwszDuration);
  1963. pwszDuration=NULL;
  1964. }
  1965. //valid days
  1966. if(0!=(dwChar=(DWORD)SendDlgItemMessage(hwndDlg,
  1967. IDC_WIZARD_EDIT_DAY,
  1968. WM_GETTEXTLENGTH, 0, 0)))
  1969. {
  1970. fUserTypeDuration=TRUE;
  1971. pwszDuration=(LPWSTR)WizardAlloc(sizeof(WCHAR)*(dwChar+1));
  1972. if(NULL!=pwszDuration)
  1973. {
  1974. GetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT_DAY,
  1975. pwszDuration,
  1976. dwChar+1);
  1977. }
  1978. else
  1979. //we are out of memory and out of hope
  1980. break;
  1981. //make sure the character are valid
  1982. /*if(!ValidDuration(pwszDuration))
  1983. {
  1984. I_MessageBox(hwndDlg, IDS_INVALID_DAYS,
  1985. IDS_BUILDCTL_WIZARD_TITLE,
  1986. NULL,
  1987. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  1988. WizardFree(pwszDuration);
  1989. pwszDuration=NULL;
  1990. //the page should stay
  1991. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  1992. break;
  1993. }*/
  1994. pCertBuildCTLInfo->dwValidDays=_wtol(pwszDuration);
  1995. /*if( (0 == pCertBuildCTLInfo->dwValidDays && !ValidZero(pwszDuration)) ||
  1996. (0 > _wtol(pwszDuration))
  1997. )
  1998. {
  1999. I_MessageBox(hwndDlg, IDS_INVALID_DAYS,
  2000. IDS_BUILDCTL_WIZARD_TITLE,
  2001. NULL,
  2002. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  2003. WizardFree(pwszDuration);
  2004. pwszDuration=NULL;
  2005. //the page should stay
  2006. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  2007. break;
  2008. }*/
  2009. }
  2010. else
  2011. pCertBuildCTLInfo->dwValidDays=0;
  2012. //Free the memory
  2013. if(pwszDuration)
  2014. {
  2015. WizardFree(pwszDuration);
  2016. pwszDuration=NULL;
  2017. }
  2018. //make sure that user did type in some valid duration
  2019. if(0 == pCertBuildCTLInfo->dwValidDays &&
  2020. 0 == pCertBuildCTLInfo->dwValidMonths &&
  2021. TRUE== fUserTypeDuration)
  2022. {
  2023. I_MessageBox(hwndDlg, IDS_INVALID_DURATION,
  2024. IDS_BUILDCTL_WIZARD_TITLE,
  2025. NULL,
  2026. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  2027. //the page should stay
  2028. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  2029. break;
  2030. }
  2031. //make sure that the dwValidMonth + dwValidDays
  2032. //will not exceed 99 month + some extra days
  2033. if(pCertBuildCTLInfo->dwValidDays ||
  2034. pCertBuildCTLInfo->dwValidMonths)
  2035. {
  2036. if(!DurationWithinLimit(pCertBuildCTLInfo->dwValidMonths,
  2037. pCertBuildCTLInfo->dwValidDays))
  2038. {
  2039. I_MessageBox(hwndDlg, IDS_EXCEED_LIMIT,
  2040. IDS_BUILDCTL_WIZARD_TITLE,
  2041. NULL,
  2042. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  2043. //the page should stay
  2044. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  2045. break;
  2046. }
  2047. }
  2048. break;
  2049. default:
  2050. return FALSE;
  2051. }
  2052. break;
  2053. default:
  2054. return FALSE;
  2055. }
  2056. return TRUE;
  2057. }
  2058. //-----------------------------------------------------------------------
  2059. //BuildCTL_Certs
  2060. //-----------------------------------------------------------------------
  2061. INT_PTR APIENTRY BuildCTL_Certs(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  2062. {
  2063. CERT_BUILDCTL_INFO *pCertBuildCTLInfo=NULL;
  2064. PROPSHEETPAGEW *pPropSheet=NULL;
  2065. HCERTSTORE hCertStore=NULL;
  2066. PCCERT_CONTEXT pCertContext=NULL;
  2067. PCCERT_CONTEXT pPreCertContext=NULL;
  2068. BOOL fSelfSigned=TRUE;
  2069. BOOL fCTLUsage=TRUE;
  2070. BOOL fEmptyStore=TRUE;
  2071. BOOL fDuplicateCert=TRUE;
  2072. HWND hwndControl=NULL;
  2073. DWORD dwCount=0;
  2074. DWORD dwIndex=0;
  2075. int listIndex=0;
  2076. WCHAR wszText[MAX_STRING_SIZE];
  2077. UINT rgIDS[]={IDS_COLUMN_SUBJECT,
  2078. IDS_COLUMN_ISSUER,
  2079. IDS_COLUMN_PURPOSE,
  2080. IDS_COLUMN_EXPIRE};
  2081. LV_COLUMNW lvC;
  2082. CRYPTUI_VIEWCERTIFICATE_STRUCT CertViewStruct;
  2083. DWORD dwSortParam=0;
  2084. LV_ITEM lvItem;
  2085. NM_LISTVIEW FAR * pnmv=NULL;
  2086. BOOL fErrorDisplayed=FALSE;
  2087. int i;
  2088. switch (msg)
  2089. {
  2090. case WM_INITDIALOG:
  2091. //set the wizard information so that it can be shared
  2092. pPropSheet = (PROPSHEETPAGEW *) lParam;
  2093. pCertBuildCTLInfo = (CERT_BUILDCTL_INFO *) (pPropSheet->lParam);
  2094. //make sure pCertBuildCTLInfo is a valid pointer
  2095. if(NULL==pCertBuildCTLInfo)
  2096. {
  2097. break;
  2098. }
  2099. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertBuildCTLInfo);
  2100. SetControlFont(pCertBuildCTLInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
  2101. // set the style in the list view so that it highlights an entire line
  2102. SendMessageA(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
  2103. //insert columns with headers into the listView control
  2104. dwCount=sizeof(rgIDS)/sizeof(rgIDS[0]);
  2105. //get the window handle of the cert list view
  2106. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
  2107. break;
  2108. //set up the common info for the column
  2109. memset(&lvC, 0, sizeof(LV_COLUMNW));
  2110. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  2111. lvC.fmt = LVCFMT_LEFT; // Left-align the column.
  2112. lvC.cx = 145; // Width of the column, in pixels.
  2113. lvC.iSubItem=0;
  2114. lvC.pszText = wszText; // The text for the column.
  2115. //inser the column one at a time
  2116. for(dwIndex=0; dwIndex<dwCount; dwIndex++)
  2117. {
  2118. //get the column header
  2119. wszText[0]=L'\0';
  2120. LoadStringU(g_hmodThisDll, rgIDS[dwIndex], wszText, MAX_STRING_SIZE);
  2121. ListView_InsertColumnU(hwndControl, dwIndex, &lvC);
  2122. }
  2123. //initlize the ListView by populate the original certs
  2124. //from the existing CTL
  2125. InitCertList(
  2126. hwndControl,
  2127. pCertBuildCTLInfo);
  2128. //get the item count
  2129. if(ListView_GetItemCount(hwndControl))
  2130. {
  2131. //sort the certificates by the 1st column
  2132. dwSortParam=pCertBuildCTLInfo->rgdwSortParam[0];
  2133. if(0!=dwSortParam)
  2134. {
  2135. //sort the 1st column
  2136. SendDlgItemMessage(hwndDlg,
  2137. IDC_WIZARD_LIST1,
  2138. LVM_SORTITEMS,
  2139. (WPARAM) (LPARAM) dwSortParam,
  2140. (LPARAM) (PFNLVCOMPARE)CompareCertificate);
  2141. }
  2142. }
  2143. else
  2144. {
  2145. //we reset the ordering order
  2146. pCertBuildCTLInfo->rgdwSortParam[0]=SORT_COLUMN_SUBJECT | SORT_COLUMN_DESCEND;
  2147. }
  2148. //Disable the Buttons for View or Delete if no selection
  2149. //has been made
  2150. //get the window handle of the cert list view
  2151. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
  2152. break;
  2153. //get the selected item
  2154. listIndex = ListView_GetNextItem(
  2155. hwndControl,
  2156. -1,
  2157. LVNI_SELECTED
  2158. );
  2159. if(-1 == listIndex)
  2160. {
  2161. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON3), FALSE);
  2162. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON4), FALSE);
  2163. }
  2164. break;
  2165. case WM_COMMAND:
  2166. if(HIWORD(wParam) == BN_CLICKED)
  2167. {
  2168. switch (LOWORD(wParam))
  2169. {
  2170. //add a certificate from a store
  2171. case IDC_WIZARD_BUTTON1:
  2172. if(NULL==(pCertBuildCTLInfo=(CERT_BUILDCTL_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  2173. break;
  2174. //get the window handle of the cert list view
  2175. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
  2176. break;
  2177. //get the certificate from the stores
  2178. if(hCertStore=GetCertsFromStore(hwndDlg, pCertBuildCTLInfo))
  2179. {
  2180. pCertContext = NULL;
  2181. while (NULL != (pCertContext = CertEnumCertificatesInStore(
  2182. hCertStore,
  2183. pCertContext)))
  2184. {
  2185. if(AddCertToBuildCTL(
  2186. CertDuplicateCertificateContext(pCertContext),
  2187. pCertBuildCTLInfo))
  2188. {
  2189. //add the certificat to the window
  2190. AddCertToList(hwndControl,pCertContext,
  2191. pCertBuildCTLInfo->dwCertCount-1);
  2192. }
  2193. else if (!fErrorDisplayed)
  2194. {
  2195. fErrorDisplayed = TRUE;
  2196. //warn the user that the certificate already exists
  2197. I_MessageBox(hwndDlg, IDS_EXIT_CERT_IN_CTL,
  2198. IDS_BUILDCTL_WIZARD_TITLE,
  2199. NULL,
  2200. MB_ICONINFORMATION|MB_OK|MB_APPLMODAL);
  2201. }
  2202. }
  2203. CertCloseStore(hCertStore, 0);
  2204. }
  2205. break;
  2206. //add a certificate from a file
  2207. case IDC_WIZARD_BUTTON2:
  2208. if(NULL==(pCertBuildCTLInfo=(CERT_BUILDCTL_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  2209. break;
  2210. //get the window handle of the cert list view
  2211. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
  2212. break;
  2213. //get the file name. Make sure the cert is correct
  2214. if(hCertStore=GetCertStoreFromFile(hwndDlg, pCertBuildCTLInfo))
  2215. {
  2216. while(pCertContext=CertEnumCertificatesInStore(
  2217. hCertStore,
  2218. pPreCertContext))
  2219. {
  2220. fEmptyStore=FALSE;
  2221. //make sure this is a valid certificate
  2222. //make sure the pCertContext is a self-signed certificate
  2223. if(!TrustIsCertificateSelfSigned(pCertContext, pCertContext->dwCertEncodingType, 0))
  2224. {
  2225. if(fSelfSigned)
  2226. {
  2227. I_MessageBox(hwndDlg, IDS_SOME_NOT_SELF_SIGNED,
  2228. IDS_BUILDCTL_WIZARD_TITLE,
  2229. NULL,
  2230. MB_ICONEXCLAMATION|MB_OK|MB_APPLMODAL);
  2231. //no need to pop up the information anymore
  2232. fSelfSigned=FALSE;
  2233. }
  2234. pPreCertContext=pCertContext;
  2235. continue;
  2236. }
  2237. //make sure the certifcate match what is defined on the CTL list
  2238. if(!CertMatchCTL(pCertBuildCTLInfo, pCertContext))
  2239. {
  2240. if(fCTLUsage)
  2241. {
  2242. I_MessageBox(hwndDlg, IDS_SOME_NO_MATCH_USAGE,
  2243. IDS_BUILDCTL_WIZARD_TITLE,
  2244. NULL,
  2245. MB_ICONEXCLAMATION|MB_OK|MB_APPLMODAL);
  2246. //no need to pop up the information anymore
  2247. fCTLUsage=FALSE;
  2248. }
  2249. pPreCertContext=pCertContext;
  2250. continue;
  2251. }
  2252. //get a duplicate copy
  2253. pPreCertContext=CertDuplicateCertificateContext(pCertContext);
  2254. if(NULL==pPreCertContext)
  2255. {
  2256. pPreCertContext=pCertContext;
  2257. continue;
  2258. }
  2259. if(AddCertToBuildCTL(pPreCertContext, pCertBuildCTLInfo))
  2260. {
  2261. //add the certificat to the window
  2262. AddCertToList(hwndControl,pPreCertContext,
  2263. pCertBuildCTLInfo->dwCertCount-1);
  2264. }
  2265. else
  2266. {
  2267. if(fDuplicateCert)
  2268. {
  2269. //warn the user that the certificate already exists
  2270. I_MessageBox(hwndDlg, IDS_EXIT_CERT_IN_CTL,
  2271. IDS_BUILDCTL_WIZARD_TITLE,
  2272. NULL,
  2273. MB_ICONINFORMATION|MB_OK|MB_APPLMODAL);
  2274. fDuplicateCert=FALSE;
  2275. }
  2276. CertFreeCertificateContext(pPreCertContext);
  2277. }
  2278. pPreCertContext=pCertContext;
  2279. }
  2280. //warn the user that the store is empty
  2281. if(TRUE == fEmptyStore)
  2282. {
  2283. I_MessageBox(hwndDlg, IDS_EMPTY_CERT_IN_FILE,
  2284. IDS_BUILDCTL_WIZARD_TITLE,
  2285. NULL,
  2286. MB_ICONEXCLAMATION|MB_OK|MB_APPLMODAL);
  2287. }
  2288. }
  2289. pPreCertContext=NULL;
  2290. pCertContext=NULL;
  2291. if(hCertStore)
  2292. CertCloseStore(hCertStore, 0);
  2293. hCertStore=NULL;
  2294. break;
  2295. //remove a certificate from the store
  2296. case IDC_WIZARD_BUTTON3:
  2297. if(NULL==(pCertBuildCTLInfo=(CERT_BUILDCTL_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  2298. break;
  2299. //get the window handle of the cert list view
  2300. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
  2301. break;
  2302. memset(&lvItem, 0, sizeof(lvItem));
  2303. lvItem.mask = LVIF_STATE | LVIF_PARAM;
  2304. lvItem.stateMask = LVIS_SELECTED;
  2305. for (i=(ListView_GetItemCount(hwndControl) - 1); i >=0; i--)
  2306. {
  2307. lvItem.iItem = i;
  2308. if (ListView_GetItem(hwndControl, &lvItem) &&
  2309. (lvItem.state & LVIS_SELECTED))
  2310. {
  2311. if(DeleteCertFromBuildCTL(pCertBuildCTLInfo, (PCCERT_CONTEXT)(lvItem.lParam)))
  2312. {
  2313. //delete the item from the list
  2314. ListView_DeleteItem(hwndControl, lvItem.iItem);
  2315. }
  2316. }
  2317. }
  2318. /* else
  2319. //output the message
  2320. I_MessageBox(hwndDlg, IDS_HAS_TO_SELECT_CERT,
  2321. IDS_BUILDCTL_WIZARD_TITLE,
  2322. NULL,
  2323. MB_ICONERROR|MB_OK|MB_APPLMODAL);*/
  2324. break;
  2325. //view a certificate
  2326. case IDC_WIZARD_BUTTON4:
  2327. if(NULL==(pCertBuildCTLInfo=(CERT_BUILDCTL_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  2328. {
  2329. break;
  2330. }
  2331. //get the window handle of the cert list view
  2332. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
  2333. break;
  2334. //get the selected cert
  2335. listIndex = ListView_GetNextItem(
  2336. hwndControl,
  2337. -1,
  2338. LVNI_SELECTED
  2339. );
  2340. if (listIndex != -1)
  2341. {
  2342. //get the selected certificate
  2343. memset(&lvItem, 0, sizeof(LV_ITEM));
  2344. lvItem.mask=LVIF_PARAM;
  2345. lvItem.iItem=listIndex;
  2346. if(ListView_GetItem(hwndControl, &lvItem))
  2347. {
  2348. //view certiificate
  2349. if(pCertBuildCTLInfo->dwCertCount > (DWORD)listIndex)
  2350. {
  2351. memset(&CertViewStruct, 0, sizeof(CRYPTUI_VIEWCERTIFICATE_STRUCT));
  2352. CertViewStruct.dwSize=sizeof(CRYPTUI_VIEWCERTIFICATE_STRUCT);
  2353. CertViewStruct.pCertContext=(PCCERT_CONTEXT)(lvItem.lParam);
  2354. CertViewStruct.hwndParent=hwndDlg;
  2355. CertViewStruct.dwFlags=CRYPTUI_DISABLE_EDITPROPERTIES;
  2356. CryptUIDlgViewCertificate(&CertViewStruct, NULL);
  2357. }
  2358. }
  2359. }
  2360. else
  2361. //output the message
  2362. I_MessageBox(hwndDlg, IDS_HAS_TO_SELECT_CERT,
  2363. IDS_BUILDCTL_WIZARD_TITLE,
  2364. NULL,
  2365. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  2366. break;
  2367. default:
  2368. break;
  2369. }
  2370. }
  2371. break;
  2372. case WM_NOTIFY:
  2373. switch (((NMHDR FAR *) lParam)->code)
  2374. {
  2375. //the column has been clicked
  2376. case LVN_COLUMNCLICK:
  2377. if(NULL==(pCertBuildCTLInfo=(CERT_BUILDCTL_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  2378. break;
  2379. //get the window handle of the purpose list view
  2380. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
  2381. break;
  2382. pnmv = (NM_LISTVIEW FAR *) lParam;
  2383. //get the column number
  2384. dwSortParam=0;
  2385. switch(pnmv->iSubItem)
  2386. {
  2387. case 0:
  2388. case 1:
  2389. case 2:
  2390. case 3:
  2391. dwSortParam=pCertBuildCTLInfo->rgdwSortParam[pnmv->iSubItem];
  2392. break;
  2393. default:
  2394. dwSortParam=0;
  2395. break;
  2396. }
  2397. if(0!=dwSortParam)
  2398. {
  2399. //remember to flip the ascend ording
  2400. if(dwSortParam & SORT_COLUMN_ASCEND)
  2401. {
  2402. dwSortParam &= 0x0000FFFF;
  2403. dwSortParam |= SORT_COLUMN_DESCEND;
  2404. }
  2405. else
  2406. {
  2407. if(dwSortParam & SORT_COLUMN_DESCEND)
  2408. {
  2409. dwSortParam &= 0x0000FFFF;
  2410. dwSortParam |= SORT_COLUMN_ASCEND;
  2411. }
  2412. }
  2413. //sort the column
  2414. SendDlgItemMessage(hwndDlg,
  2415. IDC_WIZARD_LIST1,
  2416. LVM_SORTITEMS,
  2417. (WPARAM) (LPARAM) dwSortParam,
  2418. (LPARAM) (PFNLVCOMPARE)CompareCertificate);
  2419. pCertBuildCTLInfo->rgdwSortParam[pnmv->iSubItem]=dwSortParam;
  2420. }
  2421. break;
  2422. case PSN_KILLACTIVE:
  2423. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  2424. return TRUE;
  2425. break;
  2426. case PSN_RESET:
  2427. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  2428. break;
  2429. case PSN_SETACTIVE:
  2430. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
  2431. if(NULL==(pCertBuildCTLInfo=(CERT_BUILDCTL_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  2432. {
  2433. break;
  2434. }
  2435. //get the window handle of the purpose list view
  2436. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
  2437. break;
  2438. //see if we need to clear the certs
  2439. if(TRUE==pCertBuildCTLInfo->fClearCerts)
  2440. {
  2441. pCertBuildCTLInfo->fClearCerts=FALSE;
  2442. //clear the list view
  2443. ListView_DeleteAllItems(hwndControl);
  2444. //free all the certificate context
  2445. FreeCerts(pCertBuildCTLInfo);
  2446. }
  2447. break;
  2448. case PSN_WIZBACK:
  2449. if(NULL==(pCertBuildCTLInfo=(CERT_BUILDCTL_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  2450. break;
  2451. //check if we need to skip the 1st page
  2452. if(CRYPTUI_WIZ_BUILDCTL_SKIP_PURPOSE & pCertBuildCTLInfo->dwFlag)
  2453. {
  2454. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_BUILDCTL_WELCOME);
  2455. }
  2456. break;
  2457. case PSN_WIZNEXT:
  2458. if(NULL==(pCertBuildCTLInfo=(CERT_BUILDCTL_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  2459. {
  2460. break;
  2461. }
  2462. if(0==pCertBuildCTLInfo->dwCertCount)
  2463. {
  2464. I_MessageBox(hwndDlg, IDS_HAS_TO_SELECT_CERT,
  2465. IDS_BUILDCTL_WIZARD_TITLE,
  2466. NULL,
  2467. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  2468. //the page should stay
  2469. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  2470. }
  2471. break;
  2472. case NM_DBLCLK:
  2473. switch (((NMHDR FAR *) lParam)->idFrom)
  2474. {
  2475. case IDC_WIZARD_LIST1:
  2476. if(NULL==(pCertBuildCTLInfo=(CERT_BUILDCTL_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  2477. break;
  2478. //get the window handle of the cert list view
  2479. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
  2480. break;
  2481. //get the selected cert
  2482. listIndex = ListView_GetNextItem(
  2483. hwndControl,
  2484. -1,
  2485. LVNI_SELECTED
  2486. );
  2487. if (listIndex != -1)
  2488. {
  2489. //get the selected certificate
  2490. memset(&lvItem, 0, sizeof(LV_ITEM));
  2491. lvItem.mask=LVIF_PARAM;
  2492. lvItem.iItem=listIndex;
  2493. if(ListView_GetItem(hwndControl, &lvItem))
  2494. {
  2495. //view certiificate
  2496. if(pCertBuildCTLInfo->dwCertCount > (DWORD)listIndex)
  2497. {
  2498. memset(&CertViewStruct, 0, sizeof(CRYPTUI_VIEWCERTIFICATE_STRUCT));
  2499. CertViewStruct.dwSize=sizeof(CRYPTUI_VIEWCERTIFICATE_STRUCT);
  2500. CertViewStruct.pCertContext=(PCCERT_CONTEXT)(lvItem.lParam);
  2501. CertViewStruct.hwndParent=hwndDlg;
  2502. CertViewStruct.dwFlags=CRYPTUI_DISABLE_EDITPROPERTIES;
  2503. CryptUIDlgViewCertificate(&CertViewStruct, NULL);
  2504. }
  2505. }
  2506. }
  2507. else
  2508. //output the message
  2509. I_MessageBox(hwndDlg, IDS_HAS_TO_SELECT_CERT,
  2510. IDS_BUILDCTL_WIZARD_TITLE,
  2511. NULL,
  2512. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  2513. break;
  2514. default:
  2515. break;
  2516. }
  2517. break;
  2518. /* case NM_CLICK:
  2519. {
  2520. switch (((NMHDR FAR *) lParam)->idFrom)
  2521. {
  2522. case IDC_WIZARD_LIST1:
  2523. //get the window handle of the cert list view
  2524. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)))
  2525. break;
  2526. //get the selected item
  2527. listIndex = ListView_GetNextItem(
  2528. hwndControl,
  2529. -1,
  2530. LVNI_SELECTED
  2531. );
  2532. if(-1 != listIndex)
  2533. {
  2534. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON3), TRUE);
  2535. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON4), TRUE);
  2536. }
  2537. break;
  2538. }
  2539. }
  2540. break; */
  2541. //the item has been selected
  2542. case LVN_ITEMCHANGED:
  2543. //
  2544. // if an item is selected, then enable the remove button, otherwise
  2545. // disable it
  2546. //
  2547. if (ListView_GetSelectedCount(GetDlgItem(hwndDlg,IDC_WIZARD_LIST1)) == 0)
  2548. {
  2549. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON3), FALSE);
  2550. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON4), FALSE);
  2551. }
  2552. else
  2553. {
  2554. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON3), TRUE);
  2555. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON4), TRUE);
  2556. }
  2557. break;
  2558. default:
  2559. return FALSE;
  2560. }
  2561. break;
  2562. default:
  2563. return FALSE;
  2564. }
  2565. return TRUE;
  2566. }
  2567. //-----------------------------------------------------------------------
  2568. // BuildCTL_Destination
  2569. //-----------------------------------------------------------------------
  2570. INT_PTR APIENTRY BuildCTL_Destination(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  2571. {
  2572. CERT_BUILDCTL_INFO *pCertBuildCTLInfo=NULL;
  2573. PROPSHEETPAGEW *pPropSheet=NULL;
  2574. HWND hwndControl=NULL;
  2575. OPENFILENAMEW OpenFileName;
  2576. WCHAR szFileName[_MAX_PATH];
  2577. static WCHAR wszFileName[_MAX_PATH];
  2578. WCHAR szFilter[MAX_STRING_SIZE]; //"Certificate Trust List (*.ctl)\0*.ctl\0All Files\0*.*\0"
  2579. DWORD dwSize=0;
  2580. LPWSTR pwszStoreName=NULL;
  2581. CRYPTUI_SELECTSTORE_STRUCT CertStoreSelect;
  2582. STORENUMERATION_STRUCT StoreEnumerationStruct;
  2583. STORESFORSELCTION_STRUCT StoresForSelectionStruct;
  2584. DWORD dwChar=0;
  2585. HCERTSTORE hCertStore=NULL;
  2586. LV_COLUMNW lvC;
  2587. LV_ITEMW lvItem;
  2588. HDC hdc=NULL;
  2589. COLORREF colorRef;
  2590. BOOL fAppendExt=FALSE;
  2591. switch (msg)
  2592. {
  2593. case WM_INITDIALOG:
  2594. //set the wizard information so that it can be shared
  2595. pPropSheet = (PROPSHEETPAGEW *) lParam;
  2596. pCertBuildCTLInfo = (CERT_BUILDCTL_INFO *) (pPropSheet->lParam);
  2597. //make sure pCertBuildCTLInfo is a valid pointer
  2598. if(NULL==pCertBuildCTLInfo)
  2599. break;
  2600. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertBuildCTLInfo);
  2601. SetControlFont(pCertBuildCTLInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
  2602. //getthe background color of the parent window
  2603. //the background of the list view for store name is grayed
  2604. /*
  2605. if(hdc=GetWindowDC(hwndDlg))
  2606. {
  2607. if(CLR_INVALID!=(colorRef=GetBkColor(hdc)))
  2608. {
  2609. ListView_SetBkColor(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), CLR_NONE);
  2610. ListView_SetTextBkColor(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), CLR_NONE);
  2611. }
  2612. } */
  2613. //pre-set the selections for the destinations
  2614. //set the store name if pre-selected
  2615. if(pCertBuildCTLInfo->hDesStore)
  2616. {
  2617. //select the 1st radio button
  2618. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_SETCHECK, 1, 0);
  2619. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO2), BM_SETCHECK, 0, 0);
  2620. //disable the windows for select a file
  2621. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_EDIT1), FALSE);
  2622. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON2), FALSE);
  2623. //set the store name if pre-selected
  2624. //get the hwndControl for the list view
  2625. hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1);
  2626. if(hwndControl)
  2627. SetStoreName(hwndControl,pCertBuildCTLInfo->hDesStore);
  2628. }
  2629. else
  2630. {
  2631. //select the 2nd radio button
  2632. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_SETCHECK, 0, 0);
  2633. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO2), BM_SETCHECK, 1, 0);
  2634. //disable the controls to select a store
  2635. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON1), FALSE);
  2636. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), FALSE);
  2637. if(pCertBuildCTLInfo->pwszFileName)
  2638. {
  2639. //pre-initialize the file name
  2640. SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1, pCertBuildCTLInfo->pwszFileName);
  2641. }
  2642. }
  2643. //init
  2644. memset(&wszFileName, 0, sizeof(wszFileName));
  2645. *wszFileName='\0';
  2646. break;
  2647. case WM_COMMAND:
  2648. if(HIWORD(wParam) == BN_CLICKED)
  2649. {
  2650. switch (LOWORD(wParam))
  2651. {
  2652. case IDC_WIZARD_RADIO1:
  2653. //select the 1st radio button
  2654. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_SETCHECK, 1, 0);
  2655. //enable the controls to select a store
  2656. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON1), TRUE);
  2657. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), TRUE);
  2658. //disable raio2
  2659. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO2), BM_SETCHECK, 0, 0);
  2660. //disable controls to select a file
  2661. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON2), FALSE);
  2662. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_EDIT1), FALSE);
  2663. break;
  2664. case IDC_WIZARD_RADIO2:
  2665. //disable the 1st radio button
  2666. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_SETCHECK, 0, 0);
  2667. //disable the controls to select a store
  2668. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON1), FALSE);
  2669. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), FALSE);
  2670. //enable raio2
  2671. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO2), BM_SETCHECK, 1, 0);
  2672. //enable controls to select a file
  2673. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON2), TRUE);
  2674. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_EDIT1), TRUE);
  2675. break;
  2676. case IDC_WIZARD_BUTTON1:
  2677. //the browse for store button is selected
  2678. if(NULL==(pCertBuildCTLInfo=(CERT_BUILDCTL_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  2679. {
  2680. break;
  2681. }
  2682. //get the hwndControl for the list view
  2683. hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1);
  2684. //call the store selection dialogue
  2685. memset(&CertStoreSelect, 0, sizeof(CertStoreSelect));
  2686. memset(&StoresForSelectionStruct, 0, sizeof(StoresForSelectionStruct));
  2687. memset(&StoreEnumerationStruct, 0, sizeof(StoreEnumerationStruct));
  2688. StoreEnumerationStruct.dwFlags=CERT_STORE_MAXIMUM_ALLOWED_FLAG | CERT_SYSTEM_STORE_CURRENT_USER;
  2689. StoreEnumerationStruct.pvSystemStoreLocationPara=NULL;
  2690. StoresForSelectionStruct.cEnumerationStructs = 1;
  2691. StoresForSelectionStruct.rgEnumerationStructs = &StoreEnumerationStruct;
  2692. CertStoreSelect.dwSize=sizeof(CRYPTUI_SELECTSTORE_STRUCT);
  2693. CertStoreSelect.hwndParent=hwndDlg;
  2694. CertStoreSelect.dwFlags=CRYPTUI_VALIDATE_STORES_AS_WRITABLE | CRYPTUI_ALLOW_PHYSICAL_STORE_VIEW | CRYPTUI_DISPLAY_WRITE_ONLY_STORES;
  2695. CertStoreSelect.pStoresForSelection = &StoresForSelectionStruct;
  2696. hCertStore=CryptUIDlgSelectStore(&CertStoreSelect);
  2697. if(hCertStore)
  2698. {
  2699. //delete the old destination certificate store
  2700. if(pCertBuildCTLInfo->hDesStore && (TRUE==pCertBuildCTLInfo->fFreeDesStore))
  2701. {
  2702. CertCloseStore(pCertBuildCTLInfo->hDesStore, 0);
  2703. pCertBuildCTLInfo->hDesStore=NULL;
  2704. }
  2705. pCertBuildCTLInfo->hDesStore=hCertStore;
  2706. pCertBuildCTLInfo->fFreeDesStore=TRUE;
  2707. //get the store name
  2708. SetStoreName(hwndControl,
  2709. pCertBuildCTLInfo->hDesStore);
  2710. }
  2711. break;
  2712. case IDC_WIZARD_BUTTON2:
  2713. //the browse file button is clicked. Open the FileOpen dialogue
  2714. memset(&OpenFileName, 0, sizeof(OpenFileName));
  2715. *szFileName=L'\0';
  2716. OpenFileName.lStructSize = sizeof(OpenFileName);
  2717. OpenFileName.hwndOwner = hwndDlg;
  2718. OpenFileName.hInstance = NULL;
  2719. //load the fileter string
  2720. if(LoadFilterString(g_hmodThisDll, IDS_CTL_FILTER, szFilter, MAX_STRING_SIZE))
  2721. {
  2722. OpenFileName.lpstrFilter = szFilter;
  2723. }
  2724. OpenFileName.lpstrCustomFilter = NULL;
  2725. OpenFileName.nMaxCustFilter = 0;
  2726. OpenFileName.nFilterIndex = 1;
  2727. OpenFileName.lpstrFile = szFileName;
  2728. OpenFileName.nMaxFile = _MAX_PATH;
  2729. OpenFileName.lpstrFileTitle = NULL;
  2730. OpenFileName.nMaxFileTitle = 0;
  2731. OpenFileName.lpstrInitialDir = NULL;
  2732. OpenFileName.lpstrTitle = NULL;
  2733. OpenFileName.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
  2734. OpenFileName.nFileOffset = 0;
  2735. OpenFileName.nFileExtension = 0;
  2736. OpenFileName.lpstrDefExt = L"ctl";
  2737. OpenFileName.lCustData = NULL;
  2738. OpenFileName.lpfnHook = NULL;
  2739. OpenFileName.lpTemplateName = NULL;
  2740. if (WizGetSaveFileName(&OpenFileName))
  2741. {
  2742. //set the edit box
  2743. SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1, szFileName);
  2744. //copy the selected file name
  2745. wcscpy(wszFileName, szFileName);
  2746. }
  2747. break;
  2748. default:
  2749. break;
  2750. }
  2751. }
  2752. break;
  2753. case WM_NOTIFY:
  2754. switch (((NMHDR FAR *) lParam)->code)
  2755. {
  2756. case PSN_KILLACTIVE:
  2757. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  2758. return TRUE;
  2759. break;
  2760. case PSN_RESET:
  2761. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  2762. break;
  2763. case PSN_SETACTIVE:
  2764. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
  2765. if(NULL==(pCertBuildCTLInfo=(CERT_BUILDCTL_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  2766. break;
  2767. if(pCertBuildCTLInfo->pwszFileName)
  2768. {
  2769. //pre-initialize the file name since extension might have been added
  2770. SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1, pCertBuildCTLInfo->pwszFileName);
  2771. }
  2772. break;
  2773. case PSN_WIZBACK:
  2774. break;
  2775. case PSN_WIZNEXT:
  2776. if(NULL==(pCertBuildCTLInfo=(CERT_BUILDCTL_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  2777. {
  2778. break;
  2779. }
  2780. //make sure that we have select some store
  2781. if(TRUE==SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_GETCHECK, 0, 0))
  2782. {
  2783. if(NULL==pCertBuildCTLInfo->hDesStore)
  2784. {
  2785. //output the message
  2786. I_MessageBox(hwndDlg, IDS_HAS_TO_SELECT_STORE,
  2787. IDS_BUILDCTL_WIZARD_TITLE,
  2788. NULL,
  2789. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  2790. //make the file page stay
  2791. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  2792. break;
  2793. }
  2794. else
  2795. {
  2796. //mark the hDesStore should be used
  2797. pCertBuildCTLInfo->fSelectedDesStore=TRUE;
  2798. pCertBuildCTLInfo->fSelectedFileName=FALSE;
  2799. }
  2800. }
  2801. else
  2802. {
  2803. //make sure a file is selected
  2804. if(0==(dwChar=(DWORD)SendDlgItemMessage(hwndDlg,
  2805. IDC_WIZARD_EDIT1,
  2806. WM_GETTEXTLENGTH, 0, 0)))
  2807. {
  2808. I_MessageBox(hwndDlg, IDS_HAS_TO_SELECT_FILE,
  2809. IDS_BUILDCTL_WIZARD_TITLE,
  2810. NULL,
  2811. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  2812. //make the file page stay
  2813. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  2814. break;
  2815. }
  2816. else
  2817. {
  2818. //mark the file name should be used
  2819. pCertBuildCTLInfo->fSelectedDesStore=FALSE;
  2820. pCertBuildCTLInfo->fSelectedFileName=TRUE;
  2821. //get the file name
  2822. if(pCertBuildCTLInfo->pwszFileName)
  2823. {
  2824. //delete the old file name
  2825. if(TRUE==pCertBuildCTLInfo->fFreeFileName)
  2826. {
  2827. WizardFree(pCertBuildCTLInfo->pwszFileName);
  2828. pCertBuildCTLInfo->pwszFileName=NULL;
  2829. }
  2830. }
  2831. pCertBuildCTLInfo->pwszFileName=(LPWSTR)WizardAlloc((dwChar+1)*sizeof(WCHAR));
  2832. if(NULL==pCertBuildCTLInfo->pwszFileName)
  2833. break;
  2834. pCertBuildCTLInfo->fFreeFileName=TRUE;
  2835. GetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,
  2836. pCertBuildCTLInfo->pwszFileName,
  2837. dwChar+1);
  2838. //we append .ctl file extension if user has not specify it
  2839. fAppendExt=FALSE;
  2840. if(wcslen(pCertBuildCTLInfo->pwszFileName) < 4)
  2841. fAppendExt=TRUE;
  2842. else
  2843. {
  2844. if (_wcsicmp(L".stl", &(pCertBuildCTLInfo->pwszFileName[wcslen(pCertBuildCTLInfo->pwszFileName)-4])) != 0)
  2845. fAppendExt=TRUE;
  2846. else
  2847. fAppendExt=FALSE;
  2848. }
  2849. if(TRUE == fAppendExt)
  2850. {
  2851. pCertBuildCTLInfo->pwszFileName = (LPWSTR)WizardRealloc(pCertBuildCTLInfo->pwszFileName,
  2852. (wcslen(pCertBuildCTLInfo->pwszFileName) + 4 + 1) * sizeof(WCHAR));
  2853. if(NULL==pCertBuildCTLInfo->pwszFileName)
  2854. break;
  2855. wcscat(pCertBuildCTLInfo->pwszFileName, L".stl");
  2856. }
  2857. //confirm to over write
  2858. if(0 != _wcsicmp(wszFileName, pCertBuildCTLInfo->pwszFileName))
  2859. {
  2860. if(FileExist(pCertBuildCTLInfo->pwszFileName))
  2861. {
  2862. if(FALSE == CheckReplace(hwndDlg, pCertBuildCTLInfo->pwszFileName))
  2863. {
  2864. //make the file page stay
  2865. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  2866. break;
  2867. }
  2868. }
  2869. }
  2870. }
  2871. }
  2872. //decide if we need to skip to the friendly name page
  2873. if(pCertBuildCTLInfo->hDesStore && (TRUE==pCertBuildCTLInfo->fSelectedDesStore))
  2874. {
  2875. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_BUILDCTL_NAME);
  2876. }
  2877. else
  2878. {
  2879. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_BUILDCTL_COMPLETION);
  2880. }
  2881. break;
  2882. default:
  2883. return FALSE;
  2884. }
  2885. break;
  2886. default:
  2887. return FALSE;
  2888. }
  2889. return TRUE;
  2890. }
  2891. //-----------------------------------------------------------------------
  2892. // BuildCTL_Name
  2893. //-----------------------------------------------------------------------
  2894. INT_PTR APIENTRY BuildCTL_Name(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  2895. {
  2896. CERT_BUILDCTL_INFO *pCertBuildCTLInfo=NULL;
  2897. PROPSHEETPAGEW *pPropSheet=NULL;
  2898. HWND hwndControl=NULL;
  2899. DWORD dwChar;
  2900. switch (msg)
  2901. {
  2902. case WM_INITDIALOG:
  2903. //set the wizard information so that it can be shared
  2904. pPropSheet = (PROPSHEETPAGEW *) lParam;
  2905. pCertBuildCTLInfo = (CERT_BUILDCTL_INFO *) (pPropSheet->lParam);
  2906. //make sure pCertBuildCTLInfo is a valid pointer
  2907. if(NULL==pCertBuildCTLInfo)
  2908. break;
  2909. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertBuildCTLInfo);
  2910. SetControlFont(pCertBuildCTLInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
  2911. //set the FriedlyName and description field
  2912. //if pwszFriendlyName is NULL, use the list ID
  2913. if(pCertBuildCTLInfo->pwszFriendlyName)
  2914. SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1, pCertBuildCTLInfo->pwszFriendlyName);
  2915. else
  2916. {
  2917. if(pCertBuildCTLInfo->pwszListID)
  2918. SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1, pCertBuildCTLInfo->pwszListID);
  2919. }
  2920. if(pCertBuildCTLInfo->pwszDescription)
  2921. SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT2, pCertBuildCTLInfo->pwszDescription);
  2922. break;
  2923. case WM_COMMAND:
  2924. break;
  2925. case WM_NOTIFY:
  2926. switch (((NMHDR FAR *) lParam)->code)
  2927. {
  2928. case PSN_KILLACTIVE:
  2929. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  2930. return TRUE;
  2931. break;
  2932. case PSN_RESET:
  2933. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  2934. break;
  2935. case PSN_SETACTIVE:
  2936. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
  2937. break;
  2938. case PSN_WIZBACK:
  2939. break;
  2940. case PSN_WIZNEXT:
  2941. if(NULL==(pCertBuildCTLInfo=(CERT_BUILDCTL_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  2942. {
  2943. break;
  2944. }
  2945. //free the friendly name and description
  2946. if(pCertBuildCTLInfo->pwszFriendlyName)
  2947. {
  2948. WizardFree(pCertBuildCTLInfo->pwszFriendlyName);
  2949. pCertBuildCTLInfo->pwszFriendlyName=NULL;
  2950. }
  2951. if(pCertBuildCTLInfo->pwszDescription)
  2952. {
  2953. WizardFree(pCertBuildCTLInfo->pwszDescription);
  2954. pCertBuildCTLInfo->pwszDescription=NULL;
  2955. }
  2956. //get the friendly name
  2957. if(0!=(dwChar=(DWORD)SendDlgItemMessage(hwndDlg,
  2958. IDC_WIZARD_EDIT1,
  2959. WM_GETTEXTLENGTH, 0, 0)))
  2960. {
  2961. pCertBuildCTLInfo->pwszFriendlyName=(LPWSTR)WizardAlloc(sizeof(WCHAR)*(dwChar+1));
  2962. if(NULL!=pCertBuildCTLInfo->pwszFriendlyName)
  2963. {
  2964. GetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,
  2965. pCertBuildCTLInfo->pwszFriendlyName,
  2966. dwChar+1);
  2967. }
  2968. else
  2969. //we are out of memory and out of hope
  2970. break;
  2971. }
  2972. //get the description
  2973. if(0!=(dwChar=(DWORD)SendDlgItemMessage(hwndDlg,
  2974. IDC_WIZARD_EDIT2,
  2975. WM_GETTEXTLENGTH, 0, 0)))
  2976. {
  2977. pCertBuildCTLInfo->pwszDescription=(LPWSTR)WizardAlloc(sizeof(WCHAR)*(dwChar+1));
  2978. if(NULL!=pCertBuildCTLInfo->pwszDescription)
  2979. {
  2980. GetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT2,
  2981. pCertBuildCTLInfo->pwszDescription,
  2982. dwChar+1);
  2983. }
  2984. else
  2985. //we are out of memory and out of hope
  2986. break;
  2987. }
  2988. break;
  2989. default:
  2990. return FALSE;
  2991. }
  2992. break;
  2993. default:
  2994. return FALSE;
  2995. }
  2996. return TRUE;
  2997. }
  2998. //-----------------------------------------------------------------------
  2999. // BuildCTL_Completion
  3000. //-----------------------------------------------------------------------
  3001. INT_PTR APIENTRY BuildCTL_Completion(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  3002. {
  3003. CERT_BUILDCTL_INFO *pCertBuildCTLInfo=NULL;
  3004. PROPSHEETPAGEW *pPropSheet=NULL;
  3005. HWND hwndControl=NULL;
  3006. LV_COLUMNW lvC;
  3007. HDC hdc=NULL;
  3008. COLORREF colorRef;
  3009. DWORD dwEncodedCTL=0;
  3010. BYTE *pbEncodedCTL=NULL;
  3011. DWORD cbEncodedCTL=0;
  3012. UINT ids=0;
  3013. switch (msg)
  3014. {
  3015. case WM_INITDIALOG:
  3016. //set the wizard information so that it can be shared
  3017. pPropSheet = (PROPSHEETPAGEW *) lParam;
  3018. pCertBuildCTLInfo = (CERT_BUILDCTL_INFO *) (pPropSheet->lParam);
  3019. //make sure pCertBuildCTLInfo is a valid pointer
  3020. if(NULL==pCertBuildCTLInfo)
  3021. break;
  3022. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertBuildCTLInfo);
  3023. SetControlFont(pCertBuildCTLInfo->hBigBold, hwndDlg,IDC_WIZARD_STATIC_BIG_BOLD1);
  3024. //getthe background color of the parent window
  3025. /*
  3026. if(hdc=GetWindowDC(hwndDlg))
  3027. {
  3028. if(CLR_INVALID!=(colorRef=GetBkColor(hdc)))
  3029. {
  3030. ListView_SetBkColor(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), CLR_NONE);
  3031. ListView_SetTextBkColor(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), CLR_NONE);
  3032. }
  3033. } */
  3034. //insert two columns
  3035. hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1);
  3036. if(NULL==hwndControl)
  3037. break;
  3038. //1st one is the label for the confirmation
  3039. memset(&lvC, 0, sizeof(LV_COLUMNW));
  3040. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  3041. lvC.fmt = LVCFMT_LEFT; // Left-align the column.
  3042. lvC.cx = 20; // Width of the column, in pixels.We will autosize later
  3043. lvC.pszText = L""; // The text for the column.
  3044. lvC.iSubItem=0;
  3045. if (ListView_InsertColumnU(hwndControl, 0, &lvC) == -1)
  3046. break;
  3047. //2nd column is the content
  3048. memset(&lvC, 0, sizeof(LV_COLUMNW));
  3049. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  3050. lvC.fmt = LVCFMT_LEFT; // Left-align the column.
  3051. lvC.cx = 10; //(dwMaxSize+2)*7; // Width of the column, in pixels.
  3052. //the width will be autosized later
  3053. lvC.pszText = L""; // The text for the column.
  3054. lvC.iSubItem= 1;
  3055. if (ListView_InsertColumnU(hwndControl, 1, &lvC) == -1)
  3056. break;
  3057. break;
  3058. case WM_COMMAND:
  3059. break;
  3060. case WM_NOTIFY:
  3061. switch (((NMHDR FAR *) lParam)->code)
  3062. {
  3063. case PSN_KILLACTIVE:
  3064. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  3065. return TRUE;
  3066. break;
  3067. case PSN_RESET:
  3068. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  3069. break;
  3070. case PSN_SETACTIVE:
  3071. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK|PSWIZB_FINISH);
  3072. if(NULL==(pCertBuildCTLInfo=(CERT_BUILDCTL_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  3073. {
  3074. break;
  3075. }
  3076. //populate the list box in the order of
  3077. //FileName, StoreName, Purpose, FriendlyName, Description
  3078. //and any other things signing wizard display
  3079. if(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1))
  3080. DisplayBuildCTLConfirmation(hwndControl, pCertBuildCTLInfo);
  3081. break;
  3082. case PSN_WIZBACK:
  3083. if(NULL==(pCertBuildCTLInfo=(CERT_BUILDCTL_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  3084. {
  3085. break;
  3086. }
  3087. //no need to worry if the pages are not included in the wizards
  3088. if(0==(pCertBuildCTLInfo->dwFlag & CRYPTUI_WIZ_BUILDCTL_SKIP_DESTINATION))
  3089. {
  3090. //skip the friendly name page if the desination does no include
  3091. //a store
  3092. if(pCertBuildCTLInfo->hDesStore && (TRUE==pCertBuildCTLInfo->fSelectedDesStore))
  3093. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_BUILDCTL_NAME);
  3094. else
  3095. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_BUILDCTL_DESTINATION);
  3096. }
  3097. break;
  3098. case PSN_WIZFINISH:
  3099. if(NULL==(pCertBuildCTLInfo=(CERT_BUILDCTL_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  3100. break;
  3101. //we need to build the CTL and return the pbEncoded and cbEncoded
  3102. if(!I_BuildCTL(pCertBuildCTLInfo,
  3103. &ids,
  3104. &pbEncodedCTL,
  3105. &cbEncodedCTL))
  3106. {
  3107. if(ids!=0)
  3108. I_MessageBox(hwndDlg, ids, IDS_BUILDCTL_WIZARD_TITLE,
  3109. NULL, MB_OK|MB_ICONINFORMATION);
  3110. }
  3111. else
  3112. {
  3113. if(0!=cbEncodedCTL && NULL!=pbEncodedCTL)
  3114. {
  3115. //set up the signing information
  3116. ((CRYPTUI_WIZ_DIGITAL_SIGN_BLOB_INFO *)(pCertBuildCTLInfo->pGetSignInfo->pDigitalSignInfo->pSignBlobInfo))->cbBlob=cbEncodedCTL;
  3117. ((CRYPTUI_WIZ_DIGITAL_SIGN_BLOB_INFO *)(pCertBuildCTLInfo->pGetSignInfo->pDigitalSignInfo->pSignBlobInfo))->pbBlob=pbEncodedCTL;
  3118. }
  3119. }
  3120. break;
  3121. default:
  3122. return FALSE;
  3123. }
  3124. break;
  3125. default:
  3126. return FALSE;
  3127. }
  3128. return TRUE;
  3129. }
  3130. //**************************************************************************
  3131. //
  3132. // The entry point for buildCTL wizard
  3133. //**************************************************************************
  3134. //----------------------------------------------------------------------------
  3135. // Check to see if the certificate is a valid signing CTL cert
  3136. //
  3137. //----------------------------------------------------------------------------
  3138. BOOL IsValidSigningCTLCert(PCCERT_CONTEXT pCertContext)
  3139. {
  3140. BOOL fResult=FALSE;
  3141. int cNumOID=0;
  3142. LPSTR *rgOID=NULL;
  3143. DWORD cbOID=0;
  3144. DWORD dwIndex=0;
  3145. DWORD cbData=0;
  3146. if(!pCertContext)
  3147. return FALSE;
  3148. //the certificate has to have the CERT_KEY_PROV_INFO_PROP_ID
  3149. if(!CertGetCertificateContextProperty(pCertContext,
  3150. CERT_KEY_PROV_INFO_PROP_ID,
  3151. NULL,
  3152. &cbData))
  3153. return FALSE;
  3154. if(0==cbData)
  3155. return FALSE;
  3156. //get the OIDs from the cert
  3157. if(!CertGetValidUsages(
  3158. 1,
  3159. &pCertContext,
  3160. &cNumOID,
  3161. NULL,
  3162. &cbOID))
  3163. return FALSE;
  3164. rgOID=(LPSTR *)WizardAlloc(cbOID);
  3165. if(NULL==rgOID)
  3166. return FALSE;
  3167. if(!CertGetValidUsages(
  3168. 1,
  3169. &pCertContext,
  3170. &cNumOID,
  3171. rgOID,
  3172. &cbOID))
  3173. goto CLEANUP;
  3174. //-1 means the certiifcate is food for everything
  3175. if(-1==cNumOID)
  3176. {
  3177. fResult=TRUE;
  3178. goto CLEANUP;
  3179. }
  3180. for(dwIndex=0; dwIndex<(DWORD)cNumOID; dwIndex++)
  3181. {
  3182. //the only good cert is the one with CTL signing OID
  3183. if(0==strcmp(szOID_KP_CTL_USAGE_SIGNING,
  3184. rgOID[dwIndex]))
  3185. {
  3186. fResult=TRUE;
  3187. goto CLEANUP;
  3188. }
  3189. }
  3190. //we are hopeless at this point
  3191. fResult=FALSE;
  3192. CLEANUP:
  3193. if(rgOID)
  3194. WizardFree(rgOID);
  3195. return fResult;
  3196. }
  3197. //----------------------------------------------------------------------------
  3198. // CallBack fro cert selection call back
  3199. //
  3200. //----------------------------------------------------------------------------
  3201. static BOOL WINAPI SelectCTLSignCertCallBack(
  3202. PCCERT_CONTEXT pCertContext,
  3203. BOOL *pfInitialSelectedCert,
  3204. void *pvCallbackData)
  3205. {
  3206. if(!pCertContext)
  3207. return FALSE;
  3208. //make sure that this is a valid certificate
  3209. return IsValidSigningCTLCert(pCertContext);
  3210. }
  3211. //-----------------------------------------------------------------------
  3212. //
  3213. // CryptUIWizBuildCTL
  3214. //
  3215. // Build a new CTL or modify an existing CTL. The UI for wizard will
  3216. // always show in this case
  3217. //
  3218. //
  3219. // dwFlags: IN Reserved: flags. Must be set 0
  3220. // hwndParnet: IN Optional: The parent window handle
  3221. // pwszWizardTitle: IN Optional: The title of the wizard
  3222. // pBuildCTLSrc: IN Optional: The source from which the CTL will be built
  3223. // pBuildCTLDest: IN Optional: The desination where the newly
  3224. // built CTL will be stored
  3225. // ppCTLContext: OUT Optaionl: The newly build CTL
  3226. //
  3227. //------------------------------------------------------------------------
  3228. BOOL
  3229. WINAPI
  3230. CryptUIWizBuildCTL(
  3231. DWORD dwFlags,
  3232. HWND hwndParent,
  3233. LPCWSTR pwszWizardTitle,
  3234. PCCRYPTUI_WIZ_BUILDCTL_SRC_INFO pBuildCTLSrc,
  3235. PCCRYPTUI_WIZ_BUILDCTL_DEST_INFO pBuildCTLDest,
  3236. PCCTL_CONTEXT *ppCTLContext
  3237. )
  3238. {
  3239. BOOL fResult=FALSE;
  3240. HRESULT hr=E_FAIL;
  3241. DWORD dwError=0;
  3242. CERT_BUILDCTL_INFO CertBuildCTLInfo;
  3243. UINT ids=IDS_INVALID_WIZARD_INPUT;
  3244. FILETIME CurrentFileTime;
  3245. PROPSHEETPAGEW *prgBuildCTLSheet=NULL;
  3246. PROPSHEETHEADERW buildCTLHeader;
  3247. ENROLL_PAGE_INFO rgBuildCTLPageInfo[]=
  3248. {(LPCWSTR)MAKEINTRESOURCE(IDD_BUILDCTL_WELCOME), BuildCTL_Welcome,
  3249. (LPCWSTR)MAKEINTRESOURCE(IDD_BUILDCTL_PURPOSE), BuildCTL_Purpose,
  3250. (LPCWSTR)MAKEINTRESOURCE(IDD_BUILDCTL_CERTS), BuildCTL_Certs,
  3251. (LPCWSTR)MAKEINTRESOURCE(IDD_BUILDCTL_DESTINATION), BuildCTL_Destination,
  3252. (LPCWSTR)MAKEINTRESOURCE(IDD_BUILDCTL_NAME), BuildCTL_Name,
  3253. (LPCWSTR)MAKEINTRESOURCE(IDD_BUILDCTL_COMPLETION), BuildCTL_Completion,
  3254. };
  3255. DWORD dwIndex=0;
  3256. DWORD dwPropCount=0;
  3257. WCHAR wszTitle[MAX_TITLE_LENGTH];
  3258. PCCRYPT_OID_INFO pOIDInfo;
  3259. PCCTL_CONTEXT pCTLContext=NULL;
  3260. PCCTL_CONTEXT pBldCTL=NULL;
  3261. PCCRYPTUI_WIZ_BUILDCTL_NEW_CTL_INFO pNewCTLInfo=NULL;
  3262. LPWSTR pwszListID=NULL;
  3263. PCERT_ENHKEY_USAGE pSubjectUsage=NULL;
  3264. DWORD cbData=0;
  3265. CRYPTUI_WIZ_GET_SIGN_PAGE_INFO GetSignInfo;
  3266. DWORD dwPages=0;
  3267. CRYPTUI_WIZ_DIGITAL_SIGN_INFO DigitalSignInfo;
  3268. PROPSHEETPAGEW *pwPages=NULL;
  3269. CRYPTUI_WIZ_DIGITAL_SIGN_BLOB_INFO SignBlob;
  3270. CRYPTUI_WIZ_DIGITAL_SIGN_STORE_INFO SignStoreInfo;
  3271. GUID CTLGuid=CRYPT_SUBJTYPE_CTL_IMAGE;
  3272. CRYPT_DATA_BLOB PropertyBlob;
  3273. HCERTSTORE hMyStore=NULL;
  3274. INT_PTR iReturn=-1;
  3275. // CERT_STORE_LIST CertStoreList;
  3276. //init
  3277. memset(&CertBuildCTLInfo, 0, sizeof(CERT_BUILDCTL_INFO));
  3278. memset(&buildCTLHeader, 0, sizeof(PROPSHEETHEADERW));
  3279. memset(&GetSignInfo, 0, sizeof(CRYPTUI_WIZ_GET_SIGN_PAGE_INFO));
  3280. memset(&DigitalSignInfo, 0, sizeof(CRYPTUI_WIZ_DIGITAL_SIGN_INFO));
  3281. memset(&SignBlob, 0, sizeof(CRYPTUI_WIZ_DIGITAL_SIGN_BLOB_INFO));
  3282. memset(&SignStoreInfo, 0, sizeof(CRYPTUI_WIZ_DIGITAL_SIGN_STORE_INFO));
  3283. memset(&PropertyBlob, 0, sizeof(CRYPT_DATA_BLOB));
  3284. //open all the system store system store
  3285. //memset(&CertStoreList, 0, sizeof(CertStoreList));
  3286. //input checking
  3287. if(ppCTLContext)
  3288. *ppCTLContext=NULL;
  3289. //get the basic information from the src info struct
  3290. if(pBuildCTLSrc)
  3291. {
  3292. if(pBuildCTLSrc->dwSize != sizeof(CRYPTUI_WIZ_BUILDCTL_SRC_INFO))
  3293. goto InvalidArgErr;
  3294. if(CRYPTUI_WIZ_BUILDCTL_SRC_EXISTING_CTL==pBuildCTLSrc->dwSourceChoice)
  3295. {
  3296. if(NULL==pBuildCTLSrc->pCTLContext)
  3297. goto InvalidArgErr;
  3298. pCTLContext=pBuildCTLSrc->pCTLContext;
  3299. CertBuildCTLInfo.pSrcCTL=pCTLContext;
  3300. }
  3301. else
  3302. {
  3303. if(CRYPTUI_WIZ_BUILDCTL_SRC_NEW_CTL==pBuildCTLSrc->dwSourceChoice)
  3304. {
  3305. if(NULL==pBuildCTLSrc->pNewCTLInfo)
  3306. goto InvalidArgErr;
  3307. pNewCTLInfo=pBuildCTLSrc->pNewCTLInfo;
  3308. }
  3309. else
  3310. goto InvalidArgErr;
  3311. }
  3312. }
  3313. //init the private structure based on input parameters
  3314. CertBuildCTLInfo.hwndParent=hwndParent;
  3315. CertBuildCTLInfo.dwFlag=dwFlags;
  3316. CertBuildCTLInfo.rgdwSortParam[0]=SORT_COLUMN_SUBJECT | SORT_COLUMN_ASCEND;
  3317. CertBuildCTLInfo.rgdwSortParam[1]=SORT_COLUMN_ISSUER | SORT_COLUMN_DESCEND;
  3318. CertBuildCTLInfo.rgdwSortParam[2]=SORT_COLUMN_PURPOSE | SORT_COLUMN_DESCEND;
  3319. CertBuildCTLInfo.rgdwSortParam[3]=SORT_COLUMN_EXPIRATION | SORT_COLUMN_DESCEND;
  3320. //get the listIdentifier
  3321. if(pCTLContext)
  3322. {
  3323. //copy the listID if it is the wchar format
  3324. if(0!=(pCTLContext->pCtlInfo->ListIdentifier.cbData))
  3325. {
  3326. //get the string presentation of the listID
  3327. if(ValidString(&(pCTLContext->pCtlInfo->ListIdentifier)))
  3328. {
  3329. CertBuildCTLInfo.pwszListID=WizardAllocAndCopyWStr((LPWSTR)(pCTLContext->pCtlInfo->ListIdentifier.pbData));
  3330. if(NULL==CertBuildCTLInfo.pwszListID)
  3331. goto MemoryErr;
  3332. }
  3333. else
  3334. {
  3335. //get the hex presentation of the listID
  3336. cbData=0;
  3337. if(CryptFormatObject(
  3338. X509_ASN_ENCODING,
  3339. 0,
  3340. 0,
  3341. NULL,
  3342. 0,
  3343. pCTLContext->pCtlInfo->ListIdentifier.pbData,
  3344. pCTLContext->pCtlInfo->ListIdentifier.cbData,
  3345. NULL,
  3346. &cbData) && (0!= cbData))
  3347. {
  3348. CertBuildCTLInfo.pwszListID=(LPWSTR)WizardAlloc(cbData);
  3349. if(NULL==CertBuildCTLInfo.pwszListID)
  3350. goto MemoryErr;
  3351. if(!CryptFormatObject(
  3352. X509_ASN_ENCODING,
  3353. 0,
  3354. 0,
  3355. NULL,
  3356. 0,
  3357. pCTLContext->pCtlInfo->ListIdentifier.pbData,
  3358. pCTLContext->pCtlInfo->ListIdentifier.cbData,
  3359. CertBuildCTLInfo.pwszListID,
  3360. &cbData))
  3361. goto Win32Err;
  3362. }
  3363. }
  3364. }
  3365. }
  3366. else
  3367. {
  3368. if(pNewCTLInfo)
  3369. {
  3370. if(pNewCTLInfo->pwszListIdentifier)
  3371. {
  3372. CertBuildCTLInfo.pwszListID=WizardAllocAndCopyWStr(pNewCTLInfo->pwszListIdentifier);
  3373. if(NULL==CertBuildCTLInfo.pwszListID)
  3374. goto MemoryErr;
  3375. }
  3376. }
  3377. }
  3378. //get the hash algorithm and dwHashPropID from the source CTL
  3379. if(pCTLContext)
  3380. {
  3381. //make sure we have the correct algorithm
  3382. if(NULL==pCTLContext->pCtlInfo->SubjectAlgorithm.pszObjId)
  3383. {
  3384. ids=IDS_INVALID_ALGORITHM_IN_CTL;
  3385. goto InvalidArgErr;
  3386. }
  3387. CertBuildCTLInfo.pszSubjectAlgorithm=(LPSTR)(pCTLContext->pCtlInfo->SubjectAlgorithm.pszObjId);
  3388. }
  3389. else
  3390. {
  3391. if(pNewCTLInfo)
  3392. CertBuildCTLInfo.pszSubjectAlgorithm=(LPSTR)(pNewCTLInfo->pszSubjectAlgorithm);
  3393. }
  3394. if(CertBuildCTLInfo.pszSubjectAlgorithm)
  3395. {
  3396. pOIDInfo = CryptFindOIDInfo(
  3397. CRYPT_OID_INFO_OID_KEY,
  3398. CertBuildCTLInfo.pszSubjectAlgorithm,
  3399. CRYPT_HASH_ALG_OID_GROUP_ID);
  3400. if(NULL==pOIDInfo)
  3401. {
  3402. ids=IDS_INVALID_ALGORITHM_IN_CTL;
  3403. goto Crypt32Err;
  3404. }
  3405. if (pOIDInfo->Algid == CALG_MD5)
  3406. {
  3407. CertBuildCTLInfo.dwHashPropID=CERT_MD5_HASH_PROP_ID;
  3408. }
  3409. else
  3410. {
  3411. if (pOIDInfo->Algid == CALG_SHA1)
  3412. {
  3413. CertBuildCTLInfo.dwHashPropID=CERT_SHA1_HASH_PROP_ID;
  3414. }
  3415. else
  3416. {
  3417. ids=IDS_INVALID_ALGORITHM_IN_CTL;
  3418. goto InvalidArgErr;
  3419. }
  3420. }
  3421. }
  3422. else
  3423. CertBuildCTLInfo.dwHashPropID=CERT_SHA1_HASH_PROP_ID;
  3424. //get the pSubjectUsage
  3425. if(pNewCTLInfo)
  3426. {
  3427. if(pNewCTLInfo->pSubjectUsage)
  3428. pSubjectUsage=pNewCTLInfo->pSubjectUsage;
  3429. }
  3430. //add the subject Usage and pre-select them from either
  3431. //the exising CTL or the user defined ones
  3432. if(!GetOIDForCTL(&CertBuildCTLInfo,
  3433. (pSubjectUsage) ? pSubjectUsage->cUsageIdentifier : 0,
  3434. (pSubjectUsage) ? pSubjectUsage->rgpszUsageIdentifier : NULL))
  3435. goto InvalidArgErr;
  3436. //get the Certficate contexts from either the existing CTL
  3437. //of the user defined one
  3438. GetCertForCTL(hwndParent,
  3439. TRUE, //always UI mode for now
  3440. &CertBuildCTLInfo,
  3441. (pNewCTLInfo)? pNewCTLInfo->hCertStore : NULL);
  3442. //get the dwValidMonths and dwValidDays
  3443. if(pCTLContext)
  3444. CertBuildCTLInfo.pNextUpdate=&(pCTLContext->pCtlInfo->NextUpdate);
  3445. else
  3446. {
  3447. if(pNewCTLInfo)
  3448. CertBuildCTLInfo.pNextUpdate=(FILETIME *)(&(pNewCTLInfo->NextUpdate));
  3449. }
  3450. //get the current FileTime
  3451. GetSystemTimeAsFileTime(&CurrentFileTime);
  3452. //get the difference
  3453. if(CertBuildCTLInfo.pNextUpdate)
  3454. {
  3455. SubstractDurationFromFileTime(
  3456. CertBuildCTLInfo.pNextUpdate,
  3457. &CurrentFileTime,
  3458. &(CertBuildCTLInfo.dwValidMonths),
  3459. &(CertBuildCTLInfo.dwValidDays));
  3460. //we limit to 99 month
  3461. if((CertBuildCTLInfo.dwValidMonths > 99) ||
  3462. (CertBuildCTLInfo.dwValidMonths == 99 && CertBuildCTLInfo.dwValidDays !=0))
  3463. {
  3464. CertBuildCTLInfo.dwValidMonths=0;
  3465. CertBuildCTLInfo.dwValidDays=0;
  3466. }
  3467. }
  3468. //get the FriendlyName and Description
  3469. if(pCTLContext)
  3470. {
  3471. //friendly Name
  3472. cbData=0;
  3473. if(CertGetCTLContextProperty(
  3474. pCTLContext,
  3475. CERT_FRIENDLY_NAME_PROP_ID,
  3476. NULL,
  3477. &cbData) && (0!=cbData))
  3478. {
  3479. CertBuildCTLInfo.pwszFriendlyName=(LPWSTR)WizardAlloc(cbData);
  3480. if(NULL==CertBuildCTLInfo.pwszFriendlyName)
  3481. goto MemoryErr;
  3482. if(!CertGetCTLContextProperty(
  3483. pCTLContext,
  3484. CERT_FRIENDLY_NAME_PROP_ID,
  3485. CertBuildCTLInfo.pwszFriendlyName,
  3486. &cbData))
  3487. goto Win32Err;
  3488. }
  3489. //Description
  3490. cbData=0;
  3491. if(CertGetCTLContextProperty(
  3492. pCTLContext,
  3493. CERT_DESCRIPTION_PROP_ID,
  3494. NULL,
  3495. &cbData) && (0!=cbData))
  3496. {
  3497. CertBuildCTLInfo.pwszDescription=(LPWSTR)WizardAlloc(cbData);
  3498. if(NULL==CertBuildCTLInfo.pwszDescription)
  3499. goto MemoryErr;
  3500. if(!CertGetCTLContextProperty(
  3501. pCTLContext,
  3502. CERT_DESCRIPTION_PROP_ID,
  3503. CertBuildCTLInfo.pwszDescription,
  3504. &cbData))
  3505. goto Win32Err;
  3506. }
  3507. }
  3508. else
  3509. {
  3510. if(pNewCTLInfo)
  3511. {
  3512. if(pNewCTLInfo->pwszFriendlyName)
  3513. {
  3514. CertBuildCTLInfo.pwszFriendlyName=WizardAllocAndCopyWStr(pNewCTLInfo->pwszFriendlyName);
  3515. if(NULL==CertBuildCTLInfo.pwszFriendlyName)
  3516. goto MemoryErr;
  3517. }
  3518. if(pNewCTLInfo->pwszDescription)
  3519. {
  3520. CertBuildCTLInfo.pwszDescription=WizardAllocAndCopyWStr(pNewCTLInfo->pwszDescription);
  3521. if(NULL==CertBuildCTLInfo.pwszDescription)
  3522. goto MemoryErr;
  3523. }
  3524. }
  3525. }
  3526. //get the destination
  3527. if(pBuildCTLDest)
  3528. {
  3529. CertBuildCTLInfo.fKnownDes=TRUE;
  3530. if(pBuildCTLDest->dwSize != sizeof(CRYPTUI_WIZ_BUILDCTL_DEST_INFO))
  3531. goto InvalidArgErr;
  3532. switch(pBuildCTLDest->dwDestinationChoice)
  3533. {
  3534. case CRYPTUI_WIZ_BUILDCTL_DEST_CERT_STORE:
  3535. if(NULL==pBuildCTLDest->hCertStore)
  3536. goto InvalidArgErr;
  3537. CertBuildCTLInfo.hDesStore=pBuildCTLDest->hCertStore;
  3538. CertBuildCTLInfo.fFreeDesStore=FALSE;
  3539. CertBuildCTLInfo.fSelectedDesStore=TRUE;
  3540. break;
  3541. case CRYPTUI_WIZ_BUILDCTL_DEST_FILE:
  3542. if(NULL==pBuildCTLDest->pwszFileName)
  3543. goto InvalidArgErr;
  3544. CertBuildCTLInfo.pwszFileName=(LPWSTR)(pBuildCTLDest->pwszFileName);
  3545. CertBuildCTLInfo.fFreeFileName=FALSE;
  3546. CertBuildCTLInfo.fSelectedFileName=TRUE;
  3547. break;
  3548. default:
  3549. goto InvalidArgErr;
  3550. break;
  3551. }
  3552. }
  3553. else
  3554. CertBuildCTLInfo.fKnownDes=FALSE;
  3555. //set up the fonts
  3556. if(!SetupFonts(g_hmodThisDll,
  3557. NULL,
  3558. &(CertBuildCTLInfo.hBigBold),
  3559. &(CertBuildCTLInfo.hBold)))
  3560. {
  3561. ids=IDS_FAIL_INIT_BUILDCTL;
  3562. goto Win32Err;
  3563. }
  3564. //init the common control
  3565. if(!WizardInit() ||
  3566. (sizeof(rgBuildCTLPageInfo)/sizeof(rgBuildCTLPageInfo[0])!=BUILDCTL_PROP_SHEET)
  3567. )
  3568. {
  3569. ids=IDS_FAIL_INIT_BUILDCTL;
  3570. goto InvalidArgErr;
  3571. }
  3572. //set up the parameter to get a list of certificate
  3573. //open the my store
  3574. if(NULL == (hMyStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
  3575. g_dwMsgAndCertEncodingType,
  3576. NULL,
  3577. CERT_SYSTEM_STORE_CURRENT_USER |CERT_STORE_SET_LOCALIZED_NAME_FLAG,
  3578. L"my")))
  3579. goto Win32Err;
  3580. /* if (!CertEnumSystemStore(
  3581. CERT_SYSTEM_STORE_CURRENT_USER,
  3582. NULL,
  3583. &CertStoreList,
  3584. EnumSysStoreSignCertCallBack))
  3585. goto Win32Err; */
  3586. //set up GetSignInfo
  3587. GetSignInfo.dwSize=sizeof(CRYPTUI_WIZ_GET_SIGN_PAGE_INFO);
  3588. GetSignInfo.dwPageChoice=CRYPTUI_WIZ_DIGITAL_SIGN_MINIMAL_SIGNING_OPTION_PAGES;
  3589. if(pwszWizardTitle)
  3590. GetSignInfo.pwszPageTitle=(LPWSTR)pwszWizardTitle;
  3591. else
  3592. {
  3593. if(LoadStringU(g_hmodThisDll, IDS_BUILDCTL_WIZARD_TITLE, wszTitle, sizeof(wszTitle)/sizeof(wszTitle[0])))
  3594. GetSignInfo.pwszPageTitle=wszTitle;
  3595. }
  3596. GetSignInfo.pDigitalSignInfo=&DigitalSignInfo;
  3597. //set up DigitalSignInfo
  3598. DigitalSignInfo.dwSize=sizeof(CRYPTUI_WIZ_DIGITAL_SIGN_INFO);
  3599. //we are always signing a BLOB
  3600. DigitalSignInfo.dwSubjectChoice=CRYPTUI_WIZ_DIGITAL_SIGN_SUBJECT_BLOB;
  3601. DigitalSignInfo.pSignBlobInfo=&SignBlob;
  3602. DigitalSignInfo.dwSigningCertChoice=CRYPTUI_WIZ_DIGITAL_SIGN_STORE;
  3603. DigitalSignInfo.pSigningCertStore=&SignStoreInfo;
  3604. DigitalSignInfo.dwAdditionalCertChoice=CRYPTUI_WIZ_DIGITAL_SIGN_ADD_CHAIN;
  3605. //set up SignStoreInfo
  3606. SignStoreInfo.dwSize=sizeof(CRYPTUI_WIZ_DIGITAL_SIGN_STORE_INFO);
  3607. SignStoreInfo.cCertStore=1; //CertStoreList.dwStoreCount;
  3608. SignStoreInfo.rghCertStore=&hMyStore; //CertStoreList.prgStore;
  3609. SignStoreInfo.pFilterCallback=SelectCTLSignCertCallBack;
  3610. //set up SignBlobInfo
  3611. SignBlob.dwSize=sizeof(CRYPTUI_WIZ_DIGITAL_SIGN_BLOB_INFO);
  3612. SignBlob.pGuidSubject=&CTLGuid;
  3613. //copy the GetSignInfo into the private data
  3614. CertBuildCTLInfo.pGetSignInfo=&GetSignInfo;
  3615. //we set up the wizard in two ways: with the signing page or without the
  3616. //signing page
  3617. if(dwFlags & CRYPTUI_WIZ_BUILDCTL_SKIP_SIGNING)
  3618. {
  3619. //set up the property sheet without signing
  3620. prgBuildCTLSheet=(PROPSHEETPAGEW *)WizardAlloc(sizeof(PROPSHEETPAGEW) *
  3621. BUILDCTL_PROP_SHEET);
  3622. if(NULL==prgBuildCTLSheet)
  3623. goto MemoryErr;
  3624. memset(prgBuildCTLSheet, 0, sizeof(PROPSHEETPAGEW) * BUILDCTL_PROP_SHEET);
  3625. dwPropCount=0;
  3626. for(dwIndex=0; dwIndex<BUILDCTL_PROP_SHEET; dwIndex++)
  3627. {
  3628. //skip the destination page is required
  3629. if(3 == dwIndex )
  3630. {
  3631. if(dwFlags & CRYPTUI_WIZ_BUILDCTL_SKIP_DESTINATION)
  3632. continue;
  3633. }
  3634. //skip the friendly name page if the desination page is skipped and the destination
  3635. //is a file name
  3636. if(4== dwIndex)
  3637. {
  3638. if(dwFlags & CRYPTUI_WIZ_BUILDCTL_SKIP_DESTINATION)
  3639. {
  3640. if(NULL==ppCTLContext)
  3641. {
  3642. if(pBuildCTLDest)
  3643. {
  3644. if(CRYPTUI_WIZ_BUILDCTL_DEST_FILE == pBuildCTLDest->dwDestinationChoice)
  3645. continue;
  3646. }
  3647. else
  3648. continue;
  3649. }
  3650. }
  3651. }
  3652. prgBuildCTLSheet[dwPropCount].dwSize=sizeof(prgBuildCTLSheet[dwPropCount]);
  3653. if(pwszWizardTitle)
  3654. prgBuildCTLSheet[dwPropCount].dwFlags=PSP_USETITLE;
  3655. else
  3656. prgBuildCTLSheet[dwPropCount].dwFlags=0;
  3657. prgBuildCTLSheet[dwPropCount].hInstance=g_hmodThisDll;
  3658. prgBuildCTLSheet[dwPropCount].pszTemplate=(LPCWSTR)(rgBuildCTLPageInfo[dwIndex].pszTemplate);
  3659. if(pwszWizardTitle)
  3660. {
  3661. prgBuildCTLSheet[dwPropCount].pszTitle=pwszWizardTitle;
  3662. }
  3663. else
  3664. prgBuildCTLSheet[dwPropCount].pszTitle=NULL;
  3665. prgBuildCTLSheet[dwPropCount].pfnDlgProc=rgBuildCTLPageInfo[dwIndex].pfnDlgProc;
  3666. prgBuildCTLSheet[dwPropCount].lParam=(LPARAM)&CertBuildCTLInfo;
  3667. dwPropCount++;
  3668. }
  3669. }
  3670. else
  3671. {
  3672. //get the pages
  3673. if(!CryptUIWizGetDigitalSignPages(&GetSignInfo,
  3674. &pwPages,
  3675. &dwPages))
  3676. goto Win32Err;
  3677. //set up the property sheet and the property header
  3678. prgBuildCTLSheet=(PROPSHEETPAGEW *)WizardAlloc(sizeof(PROPSHEETPAGEW) * (
  3679. BUILDCTL_PROP_SHEET + dwPages));
  3680. if(NULL==prgBuildCTLSheet)
  3681. goto MemoryErr;
  3682. memset(prgBuildCTLSheet, 0, sizeof(PROPSHEETPAGEW) * (BUILDCTL_PROP_SHEET + dwPages));
  3683. dwPropCount=0;
  3684. for(dwIndex=0; dwIndex<BUILDCTL_PROP_SHEET + dwPages; dwIndex++)
  3685. {
  3686. //copying the signing pages
  3687. if(dwIndex>=3 && dwIndex < (3+dwPages))
  3688. {
  3689. memcpy(&(prgBuildCTLSheet[dwPropCount]), &(pwPages[dwPropCount-3]), sizeof(PROPSHEETPAGEW));
  3690. dwPropCount++;
  3691. continue;
  3692. }
  3693. //skip the destination page is required
  3694. if((3+dwPages) == dwIndex )
  3695. {
  3696. if(dwFlags & CRYPTUI_WIZ_BUILDCTL_SKIP_DESTINATION)
  3697. continue;
  3698. }
  3699. //skip the friendly name page if the desination page is skipped and the destination
  3700. //is a file name
  3701. if((4+dwPages) == dwIndex)
  3702. {
  3703. if(dwFlags & CRYPTUI_WIZ_BUILDCTL_SKIP_DESTINATION)
  3704. {
  3705. if(NULL==ppCTLContext)
  3706. {
  3707. if(pBuildCTLDest)
  3708. {
  3709. if(CRYPTUI_WIZ_BUILDCTL_DEST_FILE == pBuildCTLDest->dwDestinationChoice)
  3710. continue;
  3711. }
  3712. else
  3713. continue;
  3714. }
  3715. }
  3716. }
  3717. prgBuildCTLSheet[dwPropCount].dwSize=sizeof(prgBuildCTLSheet[dwPropCount]);
  3718. if(pwszWizardTitle)
  3719. prgBuildCTLSheet[dwPropCount].dwFlags=PSP_USETITLE;
  3720. else
  3721. prgBuildCTLSheet[dwPropCount].dwFlags=0;
  3722. prgBuildCTLSheet[dwPropCount].hInstance=g_hmodThisDll;
  3723. prgBuildCTLSheet[dwPropCount].pszTemplate=(LPCWSTR)(rgBuildCTLPageInfo[dwIndex >= 3 ? dwIndex-dwPages : dwIndex].pszTemplate);
  3724. if(pwszWizardTitle)
  3725. {
  3726. prgBuildCTLSheet[dwPropCount].pszTitle=pwszWizardTitle;
  3727. }
  3728. else
  3729. prgBuildCTLSheet[dwPropCount].pszTitle=NULL;
  3730. prgBuildCTLSheet[dwPropCount].pfnDlgProc=rgBuildCTLPageInfo[dwIndex >= 3 ? dwIndex-dwPages : dwIndex].pfnDlgProc;
  3731. prgBuildCTLSheet[dwPropCount].lParam=(LPARAM)&CertBuildCTLInfo;
  3732. dwPropCount++;
  3733. }
  3734. }
  3735. //set up the header information
  3736. buildCTLHeader.dwSize=sizeof(buildCTLHeader);
  3737. buildCTLHeader.dwFlags=PSH_PROPSHEETPAGE | PSH_WIZARD | PSH_NOAPPLYNOW;
  3738. buildCTLHeader.hwndParent=hwndParent;
  3739. buildCTLHeader.hInstance=g_hmodThisDll;
  3740. if(pwszWizardTitle)
  3741. buildCTLHeader.pszCaption=pwszWizardTitle;
  3742. else
  3743. {
  3744. if(LoadStringU(g_hmodThisDll, IDS_BUILDCTL_WIZARD_TITLE, wszTitle, sizeof(wszTitle)/sizeof(wszTitle[0])))
  3745. buildCTLHeader.pszCaption=wszTitle;
  3746. }
  3747. buildCTLHeader.nPages=dwPropCount;
  3748. buildCTLHeader.nStartPage=0;
  3749. buildCTLHeader.ppsp=prgBuildCTLSheet;
  3750. //create the wizard
  3751. iReturn = PropertySheetU(&buildCTLHeader);
  3752. if(-1 == iReturn)
  3753. goto Win32Err;
  3754. if(0 == iReturn)
  3755. {
  3756. //user clicks cancel
  3757. fResult=TRUE;
  3758. //no need to say anything if the wizard is cancelled
  3759. ids=0;
  3760. if(ppCTLContext)
  3761. *ppCTLContext=NULL;
  3762. goto CommonReturn;
  3763. }
  3764. //get the resulting nonsigned CTL or signed CTL
  3765. if(dwFlags & CRYPTUI_WIZ_BUILDCTL_SKIP_SIGNING)
  3766. {
  3767. //get the created BLOB of the CTL
  3768. if( (0 == SignBlob.cbBlob) || (NULL==SignBlob.pbBlob) )
  3769. {
  3770. //the error msg should have shown.
  3771. ids=0;
  3772. goto CTLBlobErr;
  3773. }
  3774. //the CTL context from the encoded CTL
  3775. pBldCTL=CertCreateCTLContext(
  3776. g_dwMsgAndCertEncodingType,
  3777. SignBlob.pbBlob,
  3778. SignBlob.cbBlob);
  3779. }
  3780. else
  3781. {
  3782. //get the signing result
  3783. fResult=GetSignInfo.fResult;
  3784. if(!fResult || !(GetSignInfo.pSignContext))
  3785. {
  3786. ids=IDS_SIGN_CTL_FAILED;
  3787. if(0 == GetSignInfo.dwError)
  3788. GetSignInfo.dwError=E_FAIL;
  3789. goto SignErr;
  3790. }
  3791. //the CTL context from the encoded CTL
  3792. pBldCTL=CertCreateCTLContext(
  3793. g_dwMsgAndCertEncodingType,
  3794. (GetSignInfo.pSignContext)->pbBlob,
  3795. (GetSignInfo.pSignContext)->cbBlob);
  3796. }
  3797. if(NULL==pBldCTL)
  3798. goto Win32Err;
  3799. //set the properties
  3800. if(CertBuildCTLInfo.pwszFriendlyName)
  3801. {
  3802. PropertyBlob.cbData=sizeof(WCHAR)*(wcslen(CertBuildCTLInfo.pwszFriendlyName)+1);
  3803. PropertyBlob.pbData=(BYTE *)(CertBuildCTLInfo.pwszFriendlyName);
  3804. CertSetCTLContextProperty(
  3805. pBldCTL,
  3806. CERT_FRIENDLY_NAME_PROP_ID,
  3807. 0,
  3808. &PropertyBlob);
  3809. }
  3810. if(CertBuildCTLInfo.pwszDescription)
  3811. {
  3812. PropertyBlob.cbData=sizeof(WCHAR)*(wcslen(CertBuildCTLInfo.pwszDescription)+1);
  3813. PropertyBlob.pbData=(BYTE *)(CertBuildCTLInfo.pwszDescription);
  3814. CertSetCTLContextProperty(
  3815. pBldCTL,
  3816. CERT_DESCRIPTION_PROP_ID,
  3817. 0,
  3818. &PropertyBlob);
  3819. }
  3820. //save to the destination
  3821. if(CertBuildCTLInfo.hDesStore && (TRUE==CertBuildCTLInfo.fSelectedDesStore))
  3822. {
  3823. if(!CertAddCTLContextToStore(CertBuildCTLInfo.hDesStore,
  3824. pBldCTL,
  3825. CERT_STORE_ADD_REPLACE_EXISTING,
  3826. NULL))
  3827. {
  3828. ids=IDS_FAIL_TO_ADD_CTL_TO_STORE;
  3829. goto Win32Err;
  3830. }
  3831. }
  3832. //save to the file
  3833. if(CertBuildCTLInfo.pwszFileName && (TRUE==CertBuildCTLInfo.fSelectedFileName))
  3834. {
  3835. if(S_OK != OpenAndWriteToFile(
  3836. CertBuildCTLInfo.pwszFileName,
  3837. pBldCTL->pbCtlEncoded,
  3838. pBldCTL->cbCtlEncoded))
  3839. {
  3840. ids=IDS_FAIL_TO_ADD_CTL_TO_FILE;
  3841. goto Win32Err;
  3842. }
  3843. }
  3844. if(ppCTLContext)
  3845. {
  3846. *ppCTLContext=pBldCTL;
  3847. pBldCTL=NULL;
  3848. }
  3849. fResult=TRUE;
  3850. ids=IDS_BUILDCTL_SUCCEEDED;
  3851. CommonReturn:
  3852. //preserve the last error
  3853. dwError=GetLastError();
  3854. //pop up the confirmation box for failure
  3855. if(ids)
  3856. {
  3857. //set the message of inable to gather enough info for PKCS10
  3858. if(IDS_BUILDCTL_SUCCEEDED == ids)
  3859. I_MessageBox(hwndParent, ids, IDS_BUILDCTL_WIZARD_TITLE,
  3860. NULL, MB_OK|MB_ICONINFORMATION);
  3861. else
  3862. I_MessageBox(hwndParent, ids, IDS_BUILDCTL_WIZARD_TITLE,
  3863. NULL, MB_OK|MB_ICONERROR);
  3864. }
  3865. //free the BLOB to be signed. It is the encoded CTL BLOB without the
  3866. //signature
  3867. if(SignBlob.pbBlob)
  3868. WizardFree(SignBlob.pbBlob);
  3869. //free the signing context
  3870. if(GetSignInfo.pSignContext)
  3871. CryptUIWizFreeDigitalSignContext(GetSignInfo.pSignContext);
  3872. //free the store lsit
  3873. //free my store
  3874. if(hMyStore)
  3875. CertCloseStore(hMyStore, 0);
  3876. /* if(CertStoreList.prgStore)
  3877. {
  3878. for(dwIndex=0; dwIndex<CertStoreList.dwStoreCount; dwIndex++)
  3879. CertCloseStore(CertStoreList.prgStore[dwIndex], 0);
  3880. WizardFree(CertStoreList.prgStore);
  3881. } */
  3882. if(pwPages)
  3883. CryptUIWizFreeDigitalSignPages(pwPages, dwPages);
  3884. if(pBldCTL)
  3885. CertFreeCTLContext(pBldCTL);
  3886. //destroy the hFont object
  3887. DestroyFonts(CertBuildCTLInfo.hBigBold,
  3888. CertBuildCTLInfo.hBold);
  3889. //free the pCertBUILDCTLInfo struct
  3890. if(CertBuildCTLInfo.pwszFileName && (TRUE==CertBuildCTLInfo.fFreeFileName))
  3891. WizardFree(CertBuildCTLInfo.pwszFileName);
  3892. if(CertBuildCTLInfo.hDesStore && (TRUE==CertBuildCTLInfo.fFreeDesStore))
  3893. CertCloseStore(CertBuildCTLInfo.hDesStore, 0);
  3894. //free the friendly name and description
  3895. if(CertBuildCTLInfo.pwszFriendlyName)
  3896. WizardFree(CertBuildCTLInfo.pwszFriendlyName);
  3897. if(CertBuildCTLInfo.pwszDescription)
  3898. WizardFree(CertBuildCTLInfo.pwszDescription);
  3899. //free the listID
  3900. if(CertBuildCTLInfo.pwszListID)
  3901. WizardFree(CertBuildCTLInfo.pwszListID);
  3902. //free the certificates
  3903. FreeCerts(&CertBuildCTLInfo);
  3904. //free the purpose OID
  3905. FreePurposeInfo(CertBuildCTLInfo.prgPurpose,
  3906. CertBuildCTLInfo.dwPurposeCount);
  3907. if(prgBuildCTLSheet)
  3908. WizardFree(prgBuildCTLSheet);
  3909. //reset the error
  3910. SetLastError(dwError);
  3911. return fResult;
  3912. ErrorReturn:
  3913. fResult=FALSE;
  3914. goto CommonReturn;
  3915. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  3916. TRACE_ERROR(Crypt32Err);
  3917. TRACE_ERROR(Win32Err);
  3918. SET_ERROR(MemoryErr, E_OUTOFMEMORY);
  3919. SET_ERROR(SignErr, GetSignInfo.dwError);
  3920. TRACE_ERROR(CTLBlobErr);
  3921. }
  3922. //****************************************************************************
  3923. // Helper functions for BuildCTL wizards
  3924. //
  3925. //*****************************************************************************
  3926. //----------------------------------------------------------------------------
  3927. //
  3928. //Get the hash of the certificates from the list
  3929. //----------------------------------------------------------------------------
  3930. BOOL GetCertHash(CERT_BUILDCTL_INFO *pCertBuildCTLInfo,
  3931. BYTE ***prgpHash,
  3932. DWORD **prgcbHash,
  3933. DWORD *pdwCount)
  3934. {
  3935. BOOL fResult=FALSE;
  3936. BYTE *pbData=NULL;
  3937. DWORD cbData=0;
  3938. DWORD dwIndex=0;
  3939. //init
  3940. *prgpHash=NULL;
  3941. *prgcbHash=NULL;
  3942. *pdwCount=0;
  3943. if(!pCertBuildCTLInfo->prgCertContext)
  3944. return FALSE;
  3945. //now, we need to enum all the certs in the store
  3946. for(dwIndex=0; dwIndex<pCertBuildCTLInfo->dwCertCount; dwIndex++)
  3947. {
  3948. if(NULL==pCertBuildCTLInfo->prgCertContext[dwIndex])
  3949. continue;
  3950. //get the SHA1 hash of the certificate
  3951. if(!CertGetCertificateContextProperty(
  3952. pCertBuildCTLInfo->prgCertContext[dwIndex],
  3953. pCertBuildCTLInfo->dwHashPropID,
  3954. NULL,&cbData))
  3955. goto CLEANUP;
  3956. pbData=(BYTE *)WizardAlloc(cbData);
  3957. if(!pbData)
  3958. goto CLEANUP;
  3959. //get the SHA1 hash of the certificate
  3960. if(!CertGetCertificateContextProperty(
  3961. pCertBuildCTLInfo->prgCertContext[dwIndex],
  3962. pCertBuildCTLInfo->dwHashPropID,
  3963. pbData,&cbData))
  3964. goto CLEANUP;
  3965. //add to our global list
  3966. (*pdwCount)++;
  3967. //re-alloc memory
  3968. *prgpHash=(BYTE **)WizardRealloc(*prgpHash, sizeof(BYTE *)*(*pdwCount));
  3969. *prgcbHash=(DWORD *)WizardRealloc(*prgcbHash, sizeof(DWORD)*(*pdwCount));
  3970. if((!(*prgpHash)) || (!(*prgcbHash)))
  3971. goto CLEANUP;
  3972. (*prgpHash)[*pdwCount-1]=pbData;
  3973. (*prgcbHash)[*pdwCount-1]=cbData;
  3974. }
  3975. fResult=TRUE;
  3976. CLEANUP:
  3977. if(!fResult)
  3978. {
  3979. if(*prgpHash)
  3980. {
  3981. for(dwIndex=0; dwIndex<*pdwCount; dwIndex++)
  3982. WizardFree((*prgpHash)[dwIndex]);
  3983. WizardFree(*prgpHash);
  3984. *prgpHash=NULL;
  3985. }
  3986. if(*prgcbHash)
  3987. {
  3988. WizardFree(*prgcbHash);
  3989. *prgcbHash=NULL;
  3990. }
  3991. }
  3992. return fResult;
  3993. }
  3994. //-----------------------------------------------------------------------
  3995. //
  3996. // I_BuildCTL
  3997. //
  3998. // Build a new CTL or modify an existing CTL.
  3999. //------------------------------------------------------------------------
  4000. BOOL I_BuildCTL(CERT_BUILDCTL_INFO *pCertBuildCTLInfo,
  4001. UINT *pIDS,
  4002. BYTE **ppbEncodedCTL,
  4003. DWORD *pcbEncodedCTL)
  4004. {
  4005. BOOL fResult=FALSE;
  4006. CMSG_SIGNED_ENCODE_INFO sSignInfo;
  4007. CTL_INFO CTLInfo;
  4008. DWORD dwIndex=0;
  4009. DWORD cbEncodedCTL=0;
  4010. UINT ids=IDS_FAIL_TO_BUILD_CTL;
  4011. GUID guid;
  4012. PCCRYPT_OID_INFO pOIDInfo=NULL;
  4013. ALG_ID AlgID=0;
  4014. DWORD dwCount=0;
  4015. BYTE **rgpHash=NULL;
  4016. DWORD *rgcbHash=NULL;
  4017. unsigned char * pGUID=NULL;
  4018. LPWSTR pwszGUID=NULL;
  4019. BYTE *pbEncodedCTL=NULL;
  4020. //init
  4021. memset(&sSignInfo, 0, sizeof(CMSG_SIGNED_ENCODE_INFO));
  4022. sSignInfo.cbSize = sizeof(CMSG_SIGNED_ENCODE_INFO);
  4023. memset(&CTLInfo, 0, sizeof(CTL_INFO));
  4024. if(pbEncodedCTL)
  4025. *pbEncodedCTL=NULL;
  4026. //set up CTL
  4027. CTLInfo.dwVersion=CTL_V1;
  4028. //set up the subject Usage
  4029. for(dwIndex=0; dwIndex<pCertBuildCTLInfo->dwPurposeCount; dwIndex++)
  4030. {
  4031. if(pCertBuildCTLInfo->prgPurpose[dwIndex]->fSelected)
  4032. {
  4033. CTLInfo.SubjectUsage.cUsageIdentifier++;
  4034. CTLInfo.SubjectUsage.rgpszUsageIdentifier=(LPSTR *)WizardRealloc(
  4035. CTLInfo.SubjectUsage.rgpszUsageIdentifier,
  4036. sizeof(LPSTR) * CTLInfo.SubjectUsage.cUsageIdentifier);
  4037. if(!CTLInfo.SubjectUsage.rgpszUsageIdentifier)
  4038. goto MemoryErr;
  4039. CTLInfo.SubjectUsage.rgpszUsageIdentifier[CTLInfo.SubjectUsage.cUsageIdentifier-1]=
  4040. pCertBuildCTLInfo->prgPurpose[dwIndex]->pszOID;
  4041. }
  4042. }
  4043. //Set up ListIdentifier
  4044. //copy the listID if user has specified it
  4045. if(NULL==pCertBuildCTLInfo->pwszListID)
  4046. {
  4047. if(RPC_S_OK != UuidCreate(&guid))
  4048. goto TraceErr;
  4049. //make a wchar string out of the guid
  4050. if(RPC_S_OK != UuidToString(&guid, &pGUID))
  4051. goto TraceErr;
  4052. //conver the string to wchar
  4053. pwszGUID=MkWStr((char *)pGUID);
  4054. if(!pwszGUID)
  4055. goto TraceErr;
  4056. CTLInfo.ListIdentifier.cbData=sizeof(WCHAR)*(wcslen(pwszGUID)+1);
  4057. CTLInfo.ListIdentifier.pbData=(BYTE *)WizardAlloc(CTLInfo.ListIdentifier.cbData);
  4058. if(NULL==CTLInfo.ListIdentifier.pbData)
  4059. goto MemoryErr;
  4060. memcpy(CTLInfo.ListIdentifier.pbData,
  4061. pwszGUID,
  4062. CTLInfo.ListIdentifier.cbData);
  4063. }
  4064. else
  4065. {
  4066. CTLInfo.ListIdentifier.cbData=sizeof(WCHAR)*(wcslen(pCertBuildCTLInfo->pwszListID)+1);
  4067. CTLInfo.ListIdentifier.pbData=(BYTE *)WizardAlloc(CTLInfo.ListIdentifier.cbData);
  4068. if(NULL==CTLInfo.ListIdentifier.pbData)
  4069. goto MemoryErr;
  4070. memcpy(CTLInfo.ListIdentifier.pbData,
  4071. pCertBuildCTLInfo->pwszListID,
  4072. CTLInfo.ListIdentifier.cbData);
  4073. }
  4074. //This update field
  4075. GetSystemTimeAsFileTime(&(CTLInfo.ThisUpdate));
  4076. //Next Update field
  4077. //do not specify any value if user did not enter any
  4078. if(pCertBuildCTLInfo->dwValidMonths != 0 || pCertBuildCTLInfo->dwValidDays != 0)
  4079. {
  4080. AddDurationToFileTime(pCertBuildCTLInfo->dwValidMonths,
  4081. pCertBuildCTLInfo->dwValidDays,
  4082. &(CTLInfo.ThisUpdate),
  4083. &(CTLInfo.NextUpdate));
  4084. }
  4085. //subject Algorithm
  4086. if(pCertBuildCTLInfo->dwHashPropID==CERT_MD5_HASH_PROP_ID)
  4087. AlgID=CALG_MD5;
  4088. else
  4089. AlgID=CALG_SHA1;
  4090. pOIDInfo=CryptFindOIDInfo(
  4091. CRYPT_OID_INFO_ALGID_KEY,
  4092. &AlgID,
  4093. CRYPT_HASH_ALG_OID_GROUP_ID);
  4094. if(pOIDInfo)
  4095. CTLInfo.SubjectAlgorithm.pszObjId=(LPSTR)(pOIDInfo->pszOID);
  4096. else
  4097. goto FailErr;
  4098. //set up the list of entries
  4099. //get the array of hash of the certificate
  4100. if(!GetCertHash(pCertBuildCTLInfo,
  4101. &rgpHash,
  4102. &rgcbHash,
  4103. &dwCount))
  4104. goto FailErr;
  4105. CTLInfo.cCTLEntry=dwCount;
  4106. CTLInfo.rgCTLEntry=(CTL_ENTRY *)WizardAlloc(sizeof(CTL_ENTRY)*dwCount);
  4107. if(!(CTLInfo.rgCTLEntry))
  4108. goto MemoryErr;
  4109. //memset
  4110. memset(CTLInfo.rgCTLEntry, 0, sizeof(CTL_ENTRY)*dwCount);
  4111. for(dwIndex=0; dwIndex<dwCount; dwIndex++)
  4112. {
  4113. CTLInfo.rgCTLEntry[dwIndex].SubjectIdentifier.cbData=rgcbHash[dwIndex];
  4114. CTLInfo.rgCTLEntry[dwIndex].SubjectIdentifier.pbData=rgpHash[dwIndex];
  4115. }
  4116. //include all the certificates in the signer info
  4117. sSignInfo.cCertEncoded=pCertBuildCTLInfo->dwCertCount;
  4118. sSignInfo.rgCertEncoded=(PCERT_BLOB)WizardAlloc(sizeof(CERT_BLOB)*
  4119. sSignInfo.cCertEncoded);
  4120. if(NULL==sSignInfo.rgCertEncoded)
  4121. goto MemoryErr;
  4122. for(dwIndex=0; dwIndex<sSignInfo.cCertEncoded; dwIndex++)
  4123. {
  4124. sSignInfo.rgCertEncoded[dwIndex].cbData=pCertBuildCTLInfo->prgCertContext[dwIndex]->cbCertEncoded;
  4125. sSignInfo.rgCertEncoded[dwIndex].pbData=pCertBuildCTLInfo->prgCertContext[dwIndex]->pbCertEncoded;
  4126. }
  4127. //encode and sign the CTL
  4128. if(!CryptMsgEncodeAndSignCTL(g_dwMsgAndCertEncodingType,
  4129. &CTLInfo,
  4130. &sSignInfo,
  4131. 0,
  4132. NULL,
  4133. &cbEncodedCTL))
  4134. goto TraceErr;
  4135. //memory allocation
  4136. pbEncodedCTL=(BYTE *)WizardAlloc(cbEncodedCTL);
  4137. if(!(pbEncodedCTL))
  4138. goto MemoryErr;
  4139. if(!CryptMsgEncodeAndSignCTL(g_dwMsgAndCertEncodingType,
  4140. &CTLInfo,
  4141. &sSignInfo,
  4142. 0,
  4143. pbEncodedCTL,
  4144. &cbEncodedCTL))
  4145. goto TraceErr;
  4146. if(ppbEncodedCTL && pcbEncodedCTL)
  4147. {
  4148. *ppbEncodedCTL=pbEncodedCTL;
  4149. *pcbEncodedCTL=cbEncodedCTL;
  4150. pbEncodedCTL=NULL;
  4151. }
  4152. ids=IDS_BUILDCTL_SUCCEEDED;
  4153. fResult=TRUE;
  4154. CommonReturn:
  4155. if(CTLInfo.ListIdentifier.pbData)
  4156. WizardFree(CTLInfo.ListIdentifier.pbData);
  4157. if(CTLInfo.SubjectUsage.rgpszUsageIdentifier)
  4158. WizardFree(CTLInfo.SubjectUsage.rgpszUsageIdentifier);
  4159. if(pGUID)
  4160. RpcStringFree(&pGUID);
  4161. if(pwszGUID)
  4162. FreeWStr(pwszGUID);
  4163. if(CTLInfo.rgCTLEntry)
  4164. WizardFree(CTLInfo.rgCTLEntry);
  4165. if(sSignInfo.rgCertEncoded)
  4166. WizardFree(sSignInfo.rgCertEncoded);
  4167. if(rgpHash)
  4168. {
  4169. for(dwIndex=0; dwIndex<dwCount; dwIndex++)
  4170. WizardFree(rgpHash[dwIndex]);
  4171. WizardFree(rgpHash);
  4172. }
  4173. if(rgcbHash)
  4174. WizardFree(rgcbHash);
  4175. if(pbEncodedCTL)
  4176. WizardFree(pbEncodedCTL);
  4177. if(pIDS)
  4178. *pIDS=ids;
  4179. return fResult;
  4180. ErrorReturn:
  4181. fResult=FALSE;
  4182. goto CommonReturn;
  4183. SET_ERROR(MemoryErr, E_OUTOFMEMORY);
  4184. TRACE_ERROR(TraceErr);
  4185. SET_ERROR(FailErr, E_FAIL);
  4186. }
  4187. //////////////////////////////////////////////////////////////////////////////////////
  4188. //
  4189. //////////////////////////////////////////////////////////////////////////////////////
  4190. BOOL WizardGetOIDInfo(LPWSTR string, DWORD stringSize, LPSTR pszObjId)
  4191. {
  4192. PCCRYPT_OID_INFO pOIDInfo;
  4193. pOIDInfo = CryptFindOIDInfo(
  4194. CRYPT_OID_INFO_OID_KEY,
  4195. pszObjId,
  4196. 0);
  4197. if (pOIDInfo != NULL)
  4198. {
  4199. if ((DWORD)(wcslen(pOIDInfo->pwszName)+1) <= stringSize)
  4200. {
  4201. wcscpy(string, pOIDInfo->pwszName);
  4202. }
  4203. else
  4204. {
  4205. return FALSE;
  4206. }
  4207. }
  4208. else
  4209. {
  4210. return (MultiByteToWideChar(CP_ACP, 0, pszObjId, -1, string, stringSize) != 0);
  4211. }
  4212. return TRUE;
  4213. }
  4214. //////////////////////////////////////////////////////////////////////////////////////
  4215. //
  4216. //////////////////////////////////////////////////////////////////////////////////////
  4217. LPWSTR WizardAllocAndCopyWStr(LPWSTR pwsz)
  4218. {
  4219. LPWSTR pwszReturn;
  4220. if (NULL == (pwszReturn = (LPWSTR) WizardAlloc((wcslen(pwsz)+1) * sizeof(WCHAR))))
  4221. {
  4222. return NULL;
  4223. }
  4224. wcscpy(pwszReturn, pwsz);
  4225. return(pwszReturn);
  4226. }
  4227. //////////////////////////////////////////////////////////////////////////////////////
  4228. //
  4229. //////////////////////////////////////////////////////////////////////////////////////
  4230. BOOL WizardFormatDateString(LPWSTR *ppString, FILETIME ft, BOOL fIncludeTime)
  4231. {
  4232. int cch=0;
  4233. int cch2=0;
  4234. LPWSTR psz=NULL;
  4235. SYSTEMTIME st;
  4236. FILETIME localTime;
  4237. if (!FileTimeToLocalFileTime(&ft, &localTime))
  4238. {
  4239. return FALSE;
  4240. }
  4241. if (!FileTimeToSystemTime(&localTime, &st))
  4242. {
  4243. //
  4244. // if the conversion to local time failed, then just use the original time
  4245. //
  4246. if (!FileTimeToSystemTime(&ft, &st))
  4247. {
  4248. return FALSE;
  4249. }
  4250. }
  4251. cch = (GetTimeFormatU(LOCALE_USER_DEFAULT, 0, &st, NULL, NULL, 0) +
  4252. GetDateFormatU(LOCALE_USER_DEFAULT, 0, &st, NULL, NULL, 0) + 5);
  4253. if (NULL == (psz = (LPWSTR) WizardAlloc((cch+5) * sizeof(WCHAR))))
  4254. {
  4255. return FALSE;
  4256. }
  4257. cch2 = GetDateFormatU(LOCALE_USER_DEFAULT, 0, &st, NULL, psz, cch);
  4258. if (fIncludeTime)
  4259. {
  4260. psz[cch2-1] = ' ';
  4261. GetTimeFormatU(LOCALE_USER_DEFAULT, 0, &st, NULL,
  4262. &psz[cch2], cch-cch2);
  4263. }
  4264. *ppString = psz;
  4265. return TRUE;
  4266. }
  4267. //+-------------------------------------------------------------------------
  4268. // Write a blob to a file
  4269. //--------------------------------------------------------------------------
  4270. HRESULT OpenAndWriteToFile(
  4271. LPCWSTR pwszFileName,
  4272. PBYTE pb,
  4273. DWORD cb
  4274. )
  4275. {
  4276. HRESULT hr=E_FAIL;
  4277. HANDLE hFile=NULL;
  4278. DWORD dwBytesWritten=0;
  4279. if(!pwszFileName || !pb || (cb==0))
  4280. return E_INVALIDARG;
  4281. hFile = ExpandAndCreateFileU(pwszFileName,
  4282. GENERIC_WRITE,
  4283. 0, // fdwShareMode
  4284. NULL, // lpsa
  4285. CREATE_ALWAYS,
  4286. FILE_ATTRIBUTE_NORMAL, // fdwAttrsAndFlags
  4287. 0); // TemplateFile
  4288. if (INVALID_HANDLE_VALUE == hFile)
  4289. {
  4290. hr=HRESULT_FROM_WIN32(GetLastError());
  4291. }
  4292. else
  4293. {
  4294. if (!WriteFile(
  4295. hFile,
  4296. pb,
  4297. cb,
  4298. &dwBytesWritten,
  4299. NULL // lpOverlapped
  4300. ))
  4301. {
  4302. hr=HRESULT_FROM_WIN32(GetLastError());
  4303. }
  4304. else
  4305. {
  4306. if(dwBytesWritten != cb)
  4307. hr=E_FAIL;
  4308. else
  4309. hr=S_OK;
  4310. }
  4311. CloseHandle(hFile);
  4312. }
  4313. return hr;
  4314. }
  4315. //--------------------------------------------------------------------------------
  4316. // See if the DATA blob is a valid wchar string
  4317. //--------------------------------------------------------------------------------
  4318. BOOL ValidString(CRYPT_DATA_BLOB *pDataBlob)
  4319. {
  4320. LPWSTR pwsz=NULL;
  4321. DWORD dwIndex=0;
  4322. if(NULL==pDataBlob)
  4323. return FALSE;
  4324. if(pDataBlob->cbData < sizeof(WCHAR))
  4325. return FALSE;
  4326. //has to be NULL-terminated
  4327. pwsz=(LPWSTR)((DWORD_PTR)(pDataBlob->pbData)+(pDataBlob->cbData)-sizeof(WCHAR));
  4328. if(*pwsz != '\0')
  4329. return FALSE;
  4330. //has to include the exact number of wchars
  4331. if(0 != ((pDataBlob->cbData)%sizeof(WCHAR)))
  4332. return FALSE;
  4333. //each character, with exception of the last NULL terminater,
  4334. //has to be printable (20-7e) range
  4335. for(dwIndex=0; dwIndex<(pDataBlob->cbData)-sizeof(WCHAR); dwIndex=dwIndex+sizeof(WCHAR))
  4336. {
  4337. pwsz=(LPWSTR)((DWORD_PTR)(pDataBlob->pbData)+dwIndex);
  4338. if(0==iswprint(*pwsz))
  4339. return FALSE;
  4340. }
  4341. return TRUE;
  4342. }
  4343. //--------------------------------------------------------------------------------
  4344. // See if the user input is an 0 in the form of {white spaces}{sign}{0}
  4345. // pwszInput has to be NULL terminated
  4346. //--------------------------------------------------------------------------------
  4347. BOOL ValidZero(LPWSTR pwszInput)
  4348. {
  4349. BOOL fSpace=TRUE;
  4350. BOOL fSign=TRUE;
  4351. if(NULL==pwszInput)
  4352. return FALSE;
  4353. while(*pwszInput != L'\0')
  4354. {
  4355. if(iswspace(*pwszInput))
  4356. {
  4357. if(fSpace)
  4358. pwszInput++;
  4359. else
  4360. return FALSE;
  4361. }
  4362. else
  4363. {
  4364. if((L'+'==*pwszInput) || (L'-'==*pwszInput))
  4365. {
  4366. if(fSign)
  4367. {
  4368. fSign=FALSE;
  4369. fSpace=FALSE;
  4370. pwszInput++;
  4371. }
  4372. else
  4373. return FALSE;
  4374. }
  4375. else
  4376. {
  4377. if(L'0'==*pwszInput)
  4378. {
  4379. fSign=FALSE;
  4380. fSpace=FALSE;
  4381. pwszInput++;
  4382. }
  4383. else
  4384. return FALSE;
  4385. }
  4386. }
  4387. }
  4388. return TRUE;
  4389. }
  4390. //--------------------------------------------------------------------------------
  4391. // Get the number of days in a particular month of a particular year
  4392. //--------------------------------------------------------------------------------
  4393. DWORD DaysInMonth(DWORD dwYear, DWORD dwMonth)
  4394. {
  4395. switch (dwMonth)
  4396. {
  4397. case 1:
  4398. case 3:
  4399. case 5:
  4400. case 7:
  4401. case 8:
  4402. case 10:
  4403. case 12:
  4404. return 31;
  4405. break;
  4406. case 4:
  4407. case 6:
  4408. case 9:
  4409. case 11:
  4410. return 30;
  4411. break;
  4412. case 2:
  4413. //leap year
  4414. if((0 == dwYear % 4 && 0!= dwYear % 100) || 0 == dwYear % 400)
  4415. return 29;
  4416. else
  4417. return 28;
  4418. default:
  4419. return 0;
  4420. }
  4421. return 0;
  4422. }
  4423. //--------------------------------------------------------------------------------
  4424. // Substract the next update time from the current time
  4425. //--------------------------------------------------------------------------------
  4426. void SubstractDurationFromFileTime(
  4427. FILETIME *pNextUpdateTime,
  4428. FILETIME *pCurrentTime,
  4429. DWORD *pdwValidMonths,
  4430. DWORD *pdwValidDays)
  4431. {
  4432. SYSTEMTIME SystemNext;
  4433. SYSTEMTIME SystemCurrent;
  4434. *pdwValidMonths=0;
  4435. *pdwValidDays=0;
  4436. //return if the NextUpdateTime is NULL
  4437. if(0 ==pNextUpdateTime->dwLowDateTime && 0==pNextUpdateTime->dwHighDateTime)
  4438. return;
  4439. //the NextUpateTime has to be more than the current time
  4440. if((*(LONGLONG *)pNextUpdateTime) <= (*(LONGLONG *)pCurrentTime) )
  4441. return;
  4442. //convert to system time
  4443. if(!FileTimeToSystemTime(pNextUpdateTime, &SystemNext) ||
  4444. !FileTimeToSystemTime(pCurrentTime, &SystemCurrent))
  4445. return;
  4446. //compute the difference between the two systemtime
  4447. //in terms of month and days
  4448. if(SystemNext.wDay >= SystemCurrent.wDay)
  4449. *pdwValidDays=SystemNext.wDay - SystemCurrent.wDay;
  4450. else
  4451. {
  4452. SystemNext.wMonth--;
  4453. //consider the 1st month of the year
  4454. if(0 == SystemNext.wMonth)
  4455. {
  4456. SystemNext.wMonth=12;
  4457. SystemNext.wYear--;
  4458. }
  4459. *pdwValidDays=SystemNext.wDay + DaysInMonth(SystemNext.wYear, SystemNext.wMonth) - SystemCurrent.wDay;
  4460. }
  4461. *pdwValidMonths=(SystemNext.wYear * 12 + SystemNext.wMonth) -
  4462. (SystemCurrent.wYear * 12 + SystemCurrent.wMonth);
  4463. //if the resolution for day is too small, we just use one day
  4464. if((*pdwValidDays == 0) && (*pdwValidMonths==0))
  4465. *pdwValidDays=1;
  4466. }
  4467. //--------------------------------------------------------------------------------
  4468. // GetDaysForMonth
  4469. //--------------------------------------------------------------------------------
  4470. BOOL GetDaysForMonth(DWORD dwYear, DWORD dwMonth, DWORD *pdwDays)
  4471. {
  4472. BOOL fResult=FALSE;
  4473. if(NULL == pdwDays)
  4474. goto CLEANUP;
  4475. *pdwDays=0;
  4476. switch(dwMonth)
  4477. {
  4478. case 1:
  4479. case 3:
  4480. case 5:
  4481. case 7:
  4482. case 8:
  4483. case 10:
  4484. case 12:
  4485. *pdwDays=31;
  4486. break;
  4487. case 4:
  4488. case 6:
  4489. case 9:
  4490. case 11:
  4491. *pdwDays=30;
  4492. break;
  4493. case 2:
  4494. if((dwYear % 4 == 0 && dwYear % 100 !=0 ) ||
  4495. (dwYear % 400 ==0))
  4496. *pdwDays=29;
  4497. else
  4498. *pdwDays=28;
  4499. break;
  4500. default:
  4501. goto CLEANUP;
  4502. }
  4503. fResult=TRUE;
  4504. CLEANUP:
  4505. return fResult;
  4506. }
  4507. //--------------------------------------------------------------------------------
  4508. // Add the duration to the current fileTime
  4509. //--------------------------------------------------------------------------------
  4510. void AddDurationToFileTime(DWORD dwValidMonths,
  4511. DWORD dwValidDays,
  4512. FILETIME *pCurrentFileTime,
  4513. FILETIME *pNextFileTime)
  4514. {
  4515. SYSTEMTIME SystemCurrent;
  4516. FILETIME FileAdded;
  4517. LARGE_INTEGER dwSeconds;
  4518. LARGE_INTEGER StartTime;
  4519. DWORD dwActualdDays=0;
  4520. //init
  4521. memset(pNextFileTime, 0, sizeof(FILETIME));
  4522. //conver to the system time
  4523. if(!FileTimeToSystemTime(pCurrentFileTime, &SystemCurrent))
  4524. return;
  4525. //conver the month to year
  4526. while(dwValidMonths >= 12)
  4527. {
  4528. SystemCurrent.wYear++;
  4529. dwValidMonths=dwValidMonths-12;
  4530. }
  4531. SystemCurrent.wMonth = (WORD)(SystemCurrent.wMonth + dwValidMonths);
  4532. if(SystemCurrent.wMonth > 12)
  4533. {
  4534. SystemCurrent.wYear++;
  4535. SystemCurrent.wMonth = SystemCurrent.wMonth -12;
  4536. }
  4537. //make sure the number of days in a month is within the limit
  4538. if(GetDaysForMonth(SystemCurrent.wYear, SystemCurrent.wMonth, &dwActualdDays))
  4539. {
  4540. if(SystemCurrent.wDay > dwActualdDays)
  4541. {
  4542. SystemCurrent.wMonth++;
  4543. SystemCurrent.wDay = SystemCurrent.wDay- (WORD)(dwActualdDays);
  4544. }
  4545. }
  4546. //convert the system file to fileTime
  4547. if(!SystemTimeToFileTime(&SystemCurrent, &FileAdded))
  4548. return;
  4549. //convert the nan-seconds based on the file time
  4550. //// FILETIME is in units of 100 nanoseconds (10**-7)
  4551. dwSeconds.QuadPart=dwValidDays * 24 * 3600;
  4552. dwSeconds.QuadPart=dwSeconds.QuadPart * 10000000;
  4553. StartTime.LowPart=FileAdded.dwLowDateTime;
  4554. StartTime.HighPart=FileAdded.dwHighDateTime;
  4555. StartTime.QuadPart = StartTime.QuadPart + dwSeconds.QuadPart;
  4556. //copy the fileAdded value to *pNextFileTime
  4557. pNextFileTime->dwLowDateTime=StartTime.LowPart;
  4558. pNextFileTime->dwHighDateTime=StartTime.HighPart;
  4559. return;
  4560. }