Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3726 lines
125 KiB

  1. //-------------------------------------------------------------
  2. // Copyright (C) Microsoft Corporation, 1996 - 1999
  3. //
  4. // File: import.cpp
  5. //
  6. // Contents: The cpp file to implement the import wizard
  7. //
  8. // History: 5-11-1997 xiaohs created
  9. //
  10. //--------------------------------------------------------------
  11. #include "wzrdpvk.h"
  12. #include "import.h"
  13. #include "xenroll.h"
  14. extern HMODULE g_hmodxEnroll;
  15. typedef IEnroll2 * (WINAPI *PFNPIEnroll2GetNoCOM)();
  16. //-------------------------------------------------------------------------
  17. // DecodeGenericBlob
  18. //-------------------------------------------------------------------------
  19. DWORD DecodeGenericBlob (IN PCERT_EXTENSION pCertExtension,
  20. IN LPCSTR lpszStructType,
  21. IN OUT void ** ppStructInfo)
  22. {
  23. DWORD dwResult = 0;
  24. DWORD cbStructInfo = 0;
  25. // check parameters.
  26. if (!pCertExtension || !lpszStructType || !ppStructInfo)
  27. {
  28. return E_POINTER;
  29. }
  30. //
  31. // Determine decoded length.
  32. //
  33. if(!CryptDecodeObject(X509_ASN_ENCODING,
  34. lpszStructType,
  35. pCertExtension->Value.pbData,
  36. pCertExtension->Value.cbData,
  37. 0,
  38. NULL,
  39. &cbStructInfo))
  40. {
  41. return GetLastError();
  42. }
  43. //
  44. // Allocate memory.
  45. //
  46. if (!(*ppStructInfo = malloc(cbStructInfo)))
  47. {
  48. return E_OUTOFMEMORY;
  49. }
  50. //
  51. // Decode data.
  52. //
  53. if(!CryptDecodeObject(X509_ASN_ENCODING,
  54. lpszStructType,
  55. pCertExtension->Value.pbData,
  56. pCertExtension->Value.cbData,
  57. 0,
  58. *ppStructInfo,
  59. &cbStructInfo))
  60. {
  61. free(*ppStructInfo);
  62. return GetLastError();
  63. }
  64. return S_OK;
  65. }
  66. //-------------------------------------------------------------------------
  67. // IsCACert
  68. //-------------------------------------------------------------------------
  69. BOOL IsCACert(IN PCCERT_CONTEXT pCertContext)
  70. {
  71. BOOL bResult = FALSE;
  72. PCERT_BASIC_CONSTRAINTS2_INFO pInfo = NULL;
  73. PCERT_EXTENSION pBasicConstraints = NULL;
  74. if (pCertContext)
  75. {
  76. //
  77. // Find the basic constraints extension.
  78. //
  79. if (pBasicConstraints = CertFindExtension(szOID_BASIC_CONSTRAINTS2,
  80. pCertContext->pCertInfo->cExtension,
  81. pCertContext->pCertInfo->rgExtension))
  82. {
  83. //
  84. // Decode the basic constraints extension.
  85. //
  86. if (S_OK == DecodeGenericBlob(pBasicConstraints,
  87. X509_BASIC_CONSTRAINTS2,
  88. (void **) &pInfo))
  89. {
  90. bResult = pInfo->fCA;
  91. free(pInfo);
  92. }
  93. }
  94. else
  95. {
  96. //
  97. // Extension not found. So, for maximum backward compatibility, we assume CA
  98. // for V1 cert, and end user for > V1 cert.
  99. //
  100. bResult = CERT_V1 == pCertContext->pCertInfo->dwVersion;
  101. }
  102. }
  103. return bResult;
  104. }
  105. //-------------------------------------------------------------------------
  106. // Based on the expected content type, get the file filter
  107. //-------------------------------------------------------------------------
  108. BOOL FileExist(LPWSTR pwszFileName)
  109. {
  110. HANDLE hFile=NULL;
  111. if(NULL == pwszFileName)
  112. return FALSE;
  113. if ((hFile = ExpandAndCreateFileU(pwszFileName,
  114. GENERIC_READ,
  115. FILE_SHARE_READ,
  116. NULL, // lpsa
  117. OPEN_EXISTING,
  118. FILE_ATTRIBUTE_NORMAL,
  119. NULL)) == INVALID_HANDLE_VALUE)
  120. return FALSE;
  121. CloseHandle(hFile);
  122. return TRUE;
  123. }
  124. //-------------------------------------------------------------------------
  125. // Based on the expected content type, get the file filter
  126. //-------------------------------------------------------------------------
  127. UINT GetFileFilerIDS(DWORD dwFlags)
  128. {
  129. BOOL fCert=FALSE;
  130. BOOL fCRL=FALSE;
  131. BOOL fCTL=FALSE;
  132. if(CRYPTUI_WIZ_IMPORT_ALLOW_CERT & dwFlags)
  133. fCert=TRUE;
  134. if(CRYPTUI_WIZ_IMPORT_ALLOW_CRL & dwFlags)
  135. fCRL=TRUE;
  136. if(CRYPTUI_WIZ_IMPORT_ALLOW_CTL & dwFlags)
  137. fCTL=TRUE;
  138. if(fCert && fCRL & fCTL)
  139. return IDS_IMPORT_FILE_FILTER;
  140. if(fCert && fCRL)
  141. return IDS_IMPORT_CER_CRL_FILTER;
  142. if(fCert && fCTL)
  143. return IDS_IMPORT_CER_CTL_FILTER;
  144. if(fCRL && fCTL)
  145. return IDS_IMPORT_CTL_CRL_FILTER;
  146. if(fCert)
  147. return IDS_IMPORT_CER_FILTER;
  148. if(fCRL)
  149. return IDS_IMPORT_CRL_FILTER;
  150. if(fCTL)
  151. return IDS_IMPORT_CTL_FILTER;
  152. return IDS_IMPORT_FILE_FILTER;
  153. }
  154. //-------------------------------------------------------------------------
  155. // Check for the content of the store
  156. //-------------------------------------------------------------------------
  157. BOOL CheckForContent(HCERTSTORE hSrcStore, DWORD dwFlags, BOOL fFromWizard, UINT *pIDS)
  158. {
  159. BOOL fResult=FALSE;
  160. UINT ids=IDS_INVALID_WIZARD_INPUT;
  161. DWORD dwExpectedContent=0;
  162. DWORD dwActualContent=0;
  163. PCCERT_CONTEXT pCertContext=NULL;
  164. PCCTL_CONTEXT pCTLContext=NULL;
  165. PCCRL_CONTEXT pCRLContext=NULL;
  166. DWORD dwCRLFlag=0;
  167. if(!pIDS)
  168. return FALSE;
  169. if(!hSrcStore)
  170. {
  171. ids=IDS_INVALID_WIZARD_INPUT;
  172. goto CLEANUP;
  173. }
  174. //get the expected content
  175. if(dwFlags & CRYPTUI_WIZ_IMPORT_ALLOW_CERT)
  176. dwExpectedContent |= IMPORT_CONTENT_CERT;
  177. if(dwFlags & CRYPTUI_WIZ_IMPORT_ALLOW_CRL)
  178. dwExpectedContent |= IMPORT_CONTENT_CRL;
  179. if(dwFlags & CRYPTUI_WIZ_IMPORT_ALLOW_CTL)
  180. dwExpectedContent |= IMPORT_CONTENT_CTL;
  181. //get the actual content
  182. if(pCertContext=CertEnumCertificatesInStore(hSrcStore, NULL))
  183. dwActualContent |= IMPORT_CONTENT_CERT;
  184. if(pCTLContext=CertEnumCTLsInStore(hSrcStore, NULL))
  185. dwActualContent |= IMPORT_CONTENT_CTL;
  186. if(pCRLContext=CertGetCRLFromStore(hSrcStore,
  187. NULL,
  188. NULL,
  189. &dwCRLFlag))
  190. dwActualContent |= IMPORT_CONTENT_CRL;
  191. //the actual content should be a subset of expected content
  192. if(dwActualContent !=(dwExpectedContent & dwActualContent))
  193. {
  194. ids=IDS_IMPORT_OBJECT_NOT_EXPECTED;
  195. goto CLEANUP;
  196. }
  197. //make sure the actual content is not empty
  198. if(0 == dwActualContent)
  199. {
  200. if(fFromWizard)
  201. ids=IDS_IMPORT_OBJECT_EMPTY;
  202. else
  203. ids=IDS_IMPORT_PFX_EMPTY;
  204. goto CLEANUP;
  205. }
  206. fResult=TRUE;
  207. CLEANUP:
  208. if(pCertContext)
  209. CertFreeCertificateContext(pCertContext);
  210. if(pCTLContext)
  211. CertFreeCTLContext(pCTLContext);
  212. if(pCRLContext)
  213. CertFreeCRLContext(pCRLContext);
  214. if(pIDS)
  215. *pIDS=ids;
  216. return fResult;
  217. }
  218. //-------------------------------------------------------------------------
  219. //Get the store name(s) based on the store handle
  220. //-------------------------------------------------------------------------
  221. BOOL GetStoreName(HCERTSTORE hCertStore,
  222. LPWSTR *ppwszStoreName)
  223. {
  224. DWORD dwSize=0;
  225. //init
  226. *ppwszStoreName=NULL;
  227. if(NULL==hCertStore)
  228. return FALSE;
  229. if(!CertGetStoreProperty(
  230. hCertStore,
  231. CERT_STORE_LOCALIZED_NAME_PROP_ID,
  232. NULL,
  233. &dwSize) || (0==dwSize))
  234. return FALSE;
  235. *ppwszStoreName=(LPWSTR)WizardAlloc(dwSize);
  236. if(NULL==*ppwszStoreName)
  237. return FALSE;
  238. **ppwszStoreName=L'\0';
  239. if(CertGetStoreProperty(
  240. hCertStore,
  241. CERT_STORE_LOCALIZED_NAME_PROP_ID,
  242. *ppwszStoreName,
  243. &dwSize))
  244. return TRUE;
  245. WizardFree(*ppwszStoreName);
  246. *ppwszStoreName=NULL;
  247. return FALSE;
  248. }
  249. //-------------------------------------------------------------------------
  250. //Get the store name(s) for the store selected by the wizard
  251. //-------------------------------------------------------------------------
  252. /*BOOL GetDefaultStoreName(CERT_IMPORT_INFO *pCertImportInfo,
  253. HCERTSTORE hSrcStore,
  254. LPWSTR *ppwszStoreName,
  255. UINT *pidsStatus)
  256. {
  257. HCERTSTORE hMyStore=NULL;
  258. HCERTSTORE hCAStore=NULL;
  259. HCERTSTORE hTrustStore=NULL;
  260. HCERTSTORE hRootStore=NULL;
  261. PCCERT_CONTEXT pCertContext=NULL;
  262. PCCERT_CONTEXT pCertPre=NULL;
  263. PCCRL_CONTEXT pCRLContext=NULL;
  264. PCCTL_CONTEXT pCTLContext=NULL;
  265. DWORD dwCRLFlag=0;
  266. BOOL fResult=FALSE;
  267. LPWSTR pwszStoreName=NULL;
  268. HCERTSTORE hCertStore=NULL;
  269. DWORD dwData=0;
  270. DWORD dwCertOpenStoreFlags;
  271. //init
  272. *ppwszStoreName=NULL;
  273. if(NULL==hSrcStore)
  274. return FALSE;
  275. if (pCertImportInfo->fPFX &&
  276. (pCertImportInfo->dwFlag & CRYPTUI_WIZ_IMPORT_TO_LOCALMACHINE))
  277. {
  278. dwCertOpenStoreFlags = CERT_SYSTEM_STORE_LOCAL_MACHINE;
  279. }
  280. else
  281. {
  282. dwCertOpenStoreFlags = CERT_SYSTEM_STORE_CURRENT_USER;
  283. }
  284. *ppwszStoreName=(LPWSTR)WizardAlloc(sizeof(WCHAR));
  285. **ppwszStoreName=L'\0';
  286. //we need to find a correct store on user's behalf
  287. //put the CTLs in the trust store
  288. if(pCTLContext=CertEnumCTLsInStore(hSrcStore, NULL))
  289. {
  290. //open trust store if necessary
  291. if(NULL==hTrustStore)
  292. {
  293. if(!(hTrustStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
  294. g_dwMsgAndCertEncodingType,
  295. NULL,
  296. dwCertOpenStoreFlags |CERT_STORE_SET_LOCALIZED_NAME_FLAG,
  297. L"trust")))
  298. {
  299. *pidsStatus=IDS_FAIL_OPEN_TRUST;
  300. goto CLEANUP;
  301. }
  302. //get the store name
  303. if(GetStoreName(hTrustStore, &pwszStoreName))
  304. {
  305. *ppwszStoreName=(LPWSTR)WizardRealloc(*ppwszStoreName,
  306. sizeof(WCHAR)*(wcslen(*ppwszStoreName)+wcslen(pwszStoreName)+wcslen(L", ") +3));
  307. if(NULL==*ppwszStoreName)
  308. {
  309. *pidsStatus=IDS_OUT_OF_MEMORY;
  310. goto CLEANUP;
  311. }
  312. wcscat(*ppwszStoreName, pwszStoreName);
  313. }
  314. }
  315. }
  316. //free memory
  317. if(pwszStoreName)
  318. {
  319. WizardFree(pwszStoreName);
  320. pwszStoreName=NULL;
  321. }
  322. //put CRL in the CA store
  323. if(pCRLContext=CertGetCRLFromStore(hSrcStore,
  324. NULL,
  325. NULL,
  326. &dwCRLFlag))
  327. {
  328. //open ca store if necessary
  329. if(NULL==hCAStore)
  330. {
  331. if(!(hCAStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
  332. g_dwMsgAndCertEncodingType,
  333. NULL,
  334. dwCertOpenStoreFlags | CERT_STORE_SET_LOCALIZED_NAME_FLAG,
  335. L"ca")))
  336. {
  337. *pidsStatus=IDS_FAIL_OPEN_CA;
  338. goto CLEANUP;
  339. }
  340. //get the store name
  341. if(GetStoreName(hCAStore, &pwszStoreName))
  342. {
  343. *ppwszStoreName=(LPWSTR)WizardRealloc(*ppwszStoreName,
  344. sizeof(WCHAR)*(wcslen(*ppwszStoreName)+wcslen(pwszStoreName)+wcslen(L", ") +3));
  345. if(NULL==*ppwszStoreName)
  346. {
  347. *pidsStatus=IDS_OUT_OF_MEMORY;
  348. goto CLEANUP;
  349. }
  350. if(wcslen(*ppwszStoreName) !=0 )
  351. wcscat(*ppwszStoreName, L", ");
  352. wcscat(*ppwszStoreName, pwszStoreName);
  353. }
  354. }
  355. }
  356. //free memory
  357. if(pwszStoreName)
  358. {
  359. WizardFree(pwszStoreName);
  360. pwszStoreName=NULL;
  361. }
  362. //add the certificate with private key to my store; and the rest
  363. //to the ca store
  364. while(pCertContext=CertEnumCertificatesInStore(hSrcStore, pCertPre))
  365. {
  366. //break if we have opened both MY and CA store and hRootStore
  367. if(hCAStore && hMyStore && hRootStore)
  368. break;
  369. if(TrustIsCertificateSelfSigned(pCertContext,
  370. pCertContext->dwCertEncodingType,
  371. 0))
  372. {
  373. //open the root store if necessary
  374. if(NULL==hRootStore)
  375. {
  376. if(!(hRootStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
  377. g_dwMsgAndCertEncodingType,
  378. NULL,
  379. dwCertOpenStoreFlags | CERT_STORE_SET_LOCALIZED_NAME_FLAG,
  380. L"root")) )
  381. {
  382. *pidsStatus=IDS_FAIL_OPEN_ROOT;
  383. goto CLEANUP;
  384. }
  385. hCertStore=hRootStore;
  386. }
  387. else
  388. {
  389. pCertPre=pCertContext;
  390. continue;
  391. }
  392. }
  393. else
  394. {
  395. //check if the certificate has the property on it
  396. //make sure the private key matches the certificate
  397. //search for both machine key and user keys
  398. if(CertGetCertificateContextProperty(
  399. pCertContext,
  400. CERT_KEY_PROV_INFO_PROP_ID,
  401. NULL,
  402. &dwData) &&
  403. CryptFindCertificateKeyProvInfo(
  404. pCertContext,
  405. 0,
  406. NULL))
  407. {
  408. //open my store if necessary
  409. if(NULL==hMyStore)
  410. {
  411. if(!(hMyStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
  412. g_dwMsgAndCertEncodingType,
  413. NULL,
  414. dwCertOpenStoreFlags |CERT_STORE_SET_LOCALIZED_NAME_FLAG,
  415. L"my")))
  416. {
  417. *pidsStatus=IDS_FAIL_OPEN_MY;
  418. goto CLEANUP;
  419. }
  420. hCertStore=hMyStore;
  421. }
  422. else
  423. {
  424. pCertPre=pCertContext;
  425. continue;
  426. }
  427. }
  428. else
  429. {
  430. //open ca store if necessary
  431. if(NULL==hCAStore)
  432. {
  433. if(!(hCAStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
  434. g_dwMsgAndCertEncodingType,
  435. NULL,
  436. dwCertOpenStoreFlags |CERT_STORE_SET_LOCALIZED_NAME_FLAG,
  437. L"ca")) )
  438. {
  439. *pidsStatus=IDS_FAIL_OPEN_CA;
  440. goto CLEANUP;
  441. }
  442. hCertStore=hCAStore;
  443. }
  444. else
  445. {
  446. pCertPre=pCertContext;
  447. continue;
  448. }
  449. }
  450. }
  451. //get the store name
  452. if(GetStoreName(hCertStore, &pwszStoreName))
  453. {
  454. *ppwszStoreName=(LPWSTR)WizardRealloc(*ppwszStoreName,
  455. sizeof(WCHAR)*(wcslen(*ppwszStoreName)+wcslen(pwszStoreName)+wcslen(L", ") +1));
  456. if(NULL==*ppwszStoreName)
  457. {
  458. *pidsStatus=IDS_OUT_OF_MEMORY;
  459. goto CLEANUP;
  460. }
  461. if(wcslen(*ppwszStoreName) !=0 )
  462. wcscat(*ppwszStoreName, L", ");
  463. wcscat(*ppwszStoreName, pwszStoreName);
  464. }
  465. pCertPre=pCertContext;
  466. }
  467. fResult=TRUE;
  468. CLEANUP:
  469. if(pCertContext)
  470. CertFreeCertificateContext(pCertContext);
  471. if(pCTLContext)
  472. CertFreeCTLContext(pCTLContext);
  473. if(pCRLContext)
  474. CertFreeCRLContext(pCRLContext);
  475. if(hMyStore)
  476. CertCloseStore(hMyStore, 0);
  477. if(hCAStore)
  478. CertCloseStore(hCAStore, 0);
  479. if(hTrustStore)
  480. CertCloseStore(hTrustStore, 0);
  481. if(hRootStore)
  482. CertCloseStore(hRootStore, 0);
  483. //free memory
  484. if(pwszStoreName)
  485. {
  486. WizardFree(pwszStoreName);
  487. pwszStoreName=NULL;
  488. }
  489. return fResult;
  490. }
  491. */
  492. //-------------------------------------------------------------------------
  493. //Get the store name and insert it to the ListView
  494. //-------------------------------------------------------------------------
  495. void SetImportStoreName(HWND hwndControl,
  496. HCERTSTORE hCertStore)
  497. {
  498. LPWSTR pwszStoreName=NULL;
  499. DWORD dwSize=0;
  500. // LV_ITEMW lvItem;
  501. // LV_COLUMNW lvC;
  502. if(!CertGetStoreProperty(
  503. hCertStore,
  504. CERT_STORE_LOCALIZED_NAME_PROP_ID,
  505. NULL,
  506. &dwSize) || (0==dwSize))
  507. {
  508. //Get the <Unknown> string
  509. pwszStoreName=(LPWSTR)WizardAlloc(MAX_TITLE_LENGTH * sizeof(WCHAR));
  510. if(pwszStoreName)
  511. {
  512. *pwszStoreName=L'\0';
  513. LoadStringU(g_hmodThisDll, IDS_UNKNOWN, pwszStoreName, MAX_TITLE_LENGTH);
  514. }
  515. }
  516. else
  517. {
  518. pwszStoreName=(LPWSTR)WizardAlloc(dwSize);
  519. if(pwszStoreName)
  520. {
  521. *pwszStoreName=L'\0';
  522. CertGetStoreProperty(
  523. hCertStore,
  524. CERT_STORE_LOCALIZED_NAME_PROP_ID,
  525. pwszStoreName,
  526. &dwSize);
  527. }
  528. }
  529. if(pwszStoreName)
  530. SetWindowTextU(hwndControl,pwszStoreName);
  531. if(pwszStoreName)
  532. WizardFree(pwszStoreName);
  533. //clear the ListView
  534. /*ListView_DeleteAllItems(hwndControl);
  535. //insert one column to the store name ListView
  536. //set the store name
  537. //only one column is needed
  538. memset(&lvC, 0, sizeof(LV_COLUMNW));
  539. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  540. lvC.fmt = LVCFMT_LEFT; // Left-align the column.
  541. lvC.cx = 20; // Width of the column, in pixels.
  542. lvC.pszText = L""; // The text for the column.
  543. lvC.iSubItem=0;
  544. if (ListView_InsertColumnU(hwndControl, 0, &lvC) == -1)
  545. {
  546. if(pwszStoreName)
  547. WizardFree(pwszStoreName);
  548. return;
  549. }
  550. //insert the store name
  551. memset(&lvItem, 0, sizeof(LV_ITEMW));
  552. // set up the fields in the list view item struct that don't change from item to item
  553. lvItem.mask = LVIF_TEXT | LVIF_STATE ;
  554. lvItem.state = 0;
  555. lvItem.stateMask = 0;
  556. lvItem.iItem=0;
  557. lvItem.iSubItem=0;
  558. lvItem.pszText=pwszStoreName;
  559. ListView_InsertItemU(hwndControl, &lvItem);
  560. //autosize the column
  561. ListView_SetColumnWidth(hwndControl, 0, LVSCW_AUTOSIZE); */
  562. }
  563. //-------------------------------------------------------------------------
  564. // Check to see if this is an EFS only cert.
  565. //-------------------------------------------------------------------------
  566. BOOL IsEFSOnly(PCCERT_CONTEXT pCertContext)
  567. {
  568. BOOL fResult = FALSE;
  569. PCERT_ENHKEY_USAGE pEKU = NULL;
  570. DWORD cbEKU = 0;
  571. DWORD dwError = 0;
  572. if (!pCertContext)
  573. {
  574. dwError = ERROR_INVALID_PARAMETER;
  575. goto CLEANUP;
  576. }
  577. if (!CertGetEnhancedKeyUsage(pCertContext,
  578. CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG,
  579. NULL,
  580. &cbEKU))
  581. {
  582. dwError = GetLastError();
  583. goto CLEANUP;
  584. }
  585. if (!(pEKU = (PCERT_ENHKEY_USAGE) malloc(cbEKU)))
  586. {
  587. dwError = ERROR_NOT_ENOUGH_MEMORY;
  588. goto CLEANUP;
  589. }
  590. if (!CertGetEnhancedKeyUsage(pCertContext,
  591. CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG,
  592. pEKU,
  593. &cbEKU))
  594. {
  595. dwError = GetLastError();
  596. goto CLEANUP;
  597. }
  598. if ((1 == pEKU->cUsageIdentifier) &&
  599. (0 == strcmp(pEKU->rgpszUsageIdentifier[0], szOID_KP_EFS)))
  600. {
  601. fResult = TRUE;
  602. }
  603. CLEANUP:
  604. if (pEKU)
  605. {
  606. free(pEKU);
  607. }
  608. SetLastError(dwError);
  609. return fResult;
  610. }
  611. #if (0) //DSIE: dead code.
  612. //-------------------------------------------------------------------------
  613. //Search for the duplicated elements in the destination store
  614. //-------------------------------------------------------------------------
  615. BOOL ExistInDes(HCERTSTORE hSrcStore,
  616. HCERTSTORE hDesStore)
  617. {
  618. BOOL fResult=FALSE;
  619. DWORD dwCRLFlag=0;
  620. PCCERT_CONTEXT pCertContext=NULL;
  621. PCCERT_CONTEXT pCertPre=NULL;
  622. PCCERT_CONTEXT pFindCert=NULL;
  623. PCCRL_CONTEXT pCRLContext=NULL;
  624. PCCRL_CONTEXT pCRLPre=NULL;
  625. PCCRL_CONTEXT pFindCRL=NULL;
  626. PCCTL_CONTEXT pCTLContext=NULL;
  627. PCCTL_CONTEXT pCTLPre=NULL;
  628. PCCTL_CONTEXT pFindCTL=NULL;
  629. //add the certs
  630. while(pCertContext=CertEnumCertificatesInStore(hSrcStore, pCertPre))
  631. {
  632. if((pFindCert=CertFindCertificateInStore(hDesStore,
  633. X509_ASN_ENCODING,
  634. 0,
  635. CERT_FIND_EXISTING,
  636. pCertContext,
  637. NULL)))
  638. {
  639. fResult=TRUE;
  640. goto CLEANUP;
  641. }
  642. pCertPre=pCertContext;
  643. }
  644. //add the CTLs
  645. while(pCTLContext=CertEnumCTLsInStore(hSrcStore, pCTLPre))
  646. {
  647. if((pFindCTL=CertFindCTLInStore(hDesStore,
  648. g_dwMsgAndCertEncodingType,
  649. 0,
  650. CTL_FIND_EXISTING,
  651. pCTLContext,
  652. NULL)))
  653. {
  654. fResult=TRUE;
  655. goto CLEANUP;
  656. }
  657. pCTLPre=pCTLContext;
  658. }
  659. //add the CRLs
  660. while(pCRLContext=CertGetCRLFromStore(hSrcStore,
  661. NULL,
  662. pCRLPre,
  663. &dwCRLFlag))
  664. {
  665. if((pFindCRL=CertFindCRLInStore(hDesStore,
  666. X509_ASN_ENCODING,
  667. 0,
  668. CRL_FIND_EXISTING,
  669. pCRLContext,
  670. NULL)))
  671. {
  672. fResult=TRUE;
  673. goto CLEANUP;
  674. }
  675. pCRLPre=pCRLContext;
  676. }
  677. //we can not find a match
  678. CLEANUP:
  679. if(pCertContext)
  680. CertFreeCertificateContext(pCertContext);
  681. if(pFindCert)
  682. CertFreeCertificateContext(pFindCert);
  683. if(pCTLContext)
  684. CertFreeCTLContext(pCTLContext);
  685. if(pFindCTL)
  686. CertFreeCTLContext(pFindCTL);
  687. if(pCRLContext)
  688. CertFreeCRLContext(pCRLContext);
  689. if(pFindCRL)
  690. CertFreeCRLContext(pFindCRL);
  691. return fResult;
  692. }
  693. #endif
  694. //-------------------------------------------------------------------------
  695. //populate the list box in the order of FileName, FileType, and Store information
  696. //-------------------------------------------------------------------------
  697. void DisplayImportConfirmation(HWND hwndControl,
  698. CERT_IMPORT_INFO *pCertImportInfo)
  699. {
  700. DWORD dwIndex=0;
  701. DWORD dwSize=0;
  702. UINT ids=0;
  703. LPWSTR pwszStoreName=NULL;
  704. WCHAR wszFileType[MAX_STRING_SIZE];
  705. WCHAR wszSelectedByWizard[MAX_STRING_SIZE];
  706. LV_ITEMW lvItem;
  707. BOOL fNewItem=FALSE;
  708. //delete all the old items in the listView
  709. ListView_DeleteAllItems(hwndControl);
  710. //get the ids of the format type
  711. switch(pCertImportInfo->dwContentType)
  712. {
  713. case CERT_QUERY_CONTENT_CERT:
  714. ids=IDS_ENCODE_CERT;
  715. break;
  716. case CERT_QUERY_CONTENT_CTL:
  717. ids=IDS_ENCODE_CTL;
  718. break;
  719. case CERT_QUERY_CONTENT_CRL:
  720. ids=IDS_ENCODE_CRL;
  721. break;
  722. case CERT_QUERY_CONTENT_SERIALIZED_STORE:
  723. ids=IDS_SERIALIZED_STORE;
  724. break;
  725. case CERT_QUERY_CONTENT_SERIALIZED_CERT:
  726. ids=IDS_SERIALIZED_CERT;
  727. break;
  728. case CERT_QUERY_CONTENT_SERIALIZED_CTL:
  729. ids=IDS_SERIALIZED_CTL;
  730. break;
  731. case CERT_QUERY_CONTENT_SERIALIZED_CRL:
  732. ids=IDS_SERIALIZED_CRL;
  733. break;
  734. case CERT_QUERY_CONTENT_PKCS7_SIGNED :
  735. ids=IDS_PKCS7_SIGNED;
  736. break;
  737. case CERT_QUERY_CONTENT_PFX:
  738. ids=IDS_PFX_BLOB;
  739. break;
  740. default:
  741. // case CERT_QUERY_CONTENT_PKCS7_UNSIGNED
  742. // case CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED
  743. // case CERT_QUERY_CONTENT_PKCS10
  744. ids=IDS_NONE;
  745. break;
  746. }
  747. //get the format type
  748. LoadStringU(g_hmodThisDll, ids, wszFileType, MAX_STRING_SIZE);
  749. //get the store name
  750. if(pCertImportInfo->hDesStore)
  751. {
  752. if(!CertGetStoreProperty(
  753. pCertImportInfo->hDesStore,
  754. CERT_STORE_LOCALIZED_NAME_PROP_ID,
  755. NULL,
  756. &dwSize) || (0==dwSize))
  757. {
  758. //Get the <Unknown> string
  759. pwszStoreName=(LPWSTR)WizardAlloc(MAX_TITLE_LENGTH);
  760. if(pwszStoreName)
  761. {
  762. *pwszStoreName=L'\0';
  763. LoadStringU(g_hmodThisDll, IDS_UNKNOWN, pwszStoreName, MAX_TITLE_LENGTH);
  764. }
  765. }
  766. else
  767. {
  768. pwszStoreName=(LPWSTR)WizardAlloc(dwSize);
  769. if(pwszStoreName)
  770. {
  771. *pwszStoreName=L'\0';
  772. CertGetStoreProperty(
  773. pCertImportInfo->hDesStore,
  774. CERT_STORE_LOCALIZED_NAME_PROP_ID,
  775. pwszStoreName,
  776. &dwSize);
  777. }
  778. }
  779. }
  780. //insert row by row
  781. memset(&lvItem, 0, sizeof(LV_ITEMW));
  782. // set up the fields in the list view item struct that don't change from item to item
  783. lvItem.mask = LVIF_TEXT | LVIF_STATE ;
  784. lvItem.state = 0;
  785. lvItem.stateMask = 0;
  786. lvItem.iItem=0;
  787. lvItem.iSubItem=0;
  788. //file name
  789. if(pCertImportInfo->pwszFileName)
  790. {
  791. lvItem.iItem=lvItem.iItem ? lvItem.iItem++ : 0;
  792. lvItem.iSubItem=0;
  793. ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_FILE_NAME, NULL);
  794. //content
  795. lvItem.iSubItem++;
  796. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
  797. pCertImportInfo->pwszFileName);
  798. }
  799. //file type
  800. if(wszFileType)
  801. {
  802. lvItem.iItem=lvItem.iItem ? lvItem.iItem++ : 0;
  803. lvItem.iSubItem=0;
  804. ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_CONTENT_TYPE, NULL);
  805. //content
  806. lvItem.iSubItem++;
  807. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
  808. wszFileType);
  809. }
  810. //StoreName
  811. lvItem.iItem=lvItem.iItem ? lvItem.iItem++ : 0;
  812. lvItem.iSubItem=0;
  813. if(NULL==pCertImportInfo->hDesStore || (FALSE==pCertImportInfo->fSelectedDesStore))
  814. {
  815. ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_STORE_BY_WIZARD, NULL);
  816. /* if(pCertImportInfo->pwszDefaultStoreName)
  817. {
  818. lvItem.iSubItem++;
  819. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
  820. pCertImportInfo->pwszDefaultStoreName);
  821. }
  822. else */
  823. //get the format type
  824. if(LoadStringU(g_hmodThisDll, IDS_SELECTED_BY_WIZARD, wszSelectedByWizard, MAX_STRING_SIZE))
  825. {
  826. lvItem.iSubItem++;
  827. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
  828. wszSelectedByWizard);
  829. }
  830. }
  831. else
  832. {
  833. ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_STORE_BY_USER, NULL);
  834. //content
  835. if(pwszStoreName)
  836. {
  837. lvItem.iSubItem++;
  838. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
  839. pwszStoreName);
  840. }
  841. }
  842. //auto size the columns in the ListView
  843. ListView_SetColumnWidth(hwndControl, 0, LVSCW_AUTOSIZE);
  844. ListView_SetColumnWidth(hwndControl, 1, LVSCW_AUTOSIZE);
  845. if(pwszStoreName)
  846. WizardFree(pwszStoreName);
  847. return;
  848. }
  849. //*************************************************************************
  850. //
  851. // The winproc for import wizards
  852. //************************************************************************
  853. //-----------------------------------------------------------------------
  854. //Import_Welcome
  855. //-----------------------------------------------------------------------
  856. INT_PTR APIENTRY Import_Welcome(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  857. {
  858. CERT_IMPORT_INFO *pCertImportInfo=NULL;
  859. PROPSHEETPAGE *pPropSheet=NULL;
  860. switch (msg)
  861. {
  862. case WM_INITDIALOG:
  863. //set the wizard information so that it can be shared
  864. pPropSheet = (PROPSHEETPAGE *) lParam;
  865. pCertImportInfo = (CERT_IMPORT_INFO *) (pPropSheet->lParam);
  866. //make sure pCertImportInfo is a valid pointer
  867. if(NULL==pCertImportInfo)
  868. break;
  869. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertImportInfo);
  870. SetControlFont(pCertImportInfo->hBigBold, hwndDlg,IDC_WIZARD_STATIC_BIG_BOLD1);
  871. SetControlFont(pCertImportInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
  872. SetControlFont(pCertImportInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD2);
  873. break;
  874. case WM_NOTIFY:
  875. switch (((NMHDR FAR *) lParam)->code)
  876. {
  877. case PSN_KILLACTIVE:
  878. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  879. return TRUE;
  880. break;
  881. case PSN_RESET:
  882. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  883. break;
  884. case PSN_SETACTIVE:
  885. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
  886. break;
  887. case PSN_WIZBACK:
  888. break;
  889. case PSN_WIZNEXT:
  890. break;
  891. default:
  892. return FALSE;
  893. }
  894. break;
  895. default:
  896. return FALSE;
  897. }
  898. return TRUE;
  899. }
  900. //-----------------------------------------------------------------------
  901. // Import_File
  902. //-----------------------------------------------------------------------
  903. INT_PTR APIENTRY Import_File(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  904. {
  905. CERT_IMPORT_INFO *pCertImportInfo=NULL;
  906. PROPSHEETPAGE *pPropSheet=NULL;
  907. OPENFILENAMEW OpenFileName;
  908. WCHAR szFileName[_MAX_PATH];
  909. HWND hwndControl=NULL;
  910. DWORD dwChar=0;
  911. LPWSTR pwszInitialDir = NULL;
  912. WCHAR szFilter[MAX_STRING_SIZE + MAX_STRING_SIZE]; //"Certificate File (*.cer)\0*.cer\0Certificate File (*.crt)\0*.crt\0All Files\0*.*\0"
  913. DWORD dwSize=0;
  914. UINT ids=0;
  915. switch (msg)
  916. {
  917. case WM_INITDIALOG:
  918. //set the wizard information so that it can be shared
  919. pPropSheet = (PROPSHEETPAGE *) lParam;
  920. pCertImportInfo = (CERT_IMPORT_INFO *) (pPropSheet->lParam);
  921. //make sure pCertImportInfo is a valid pointer
  922. if(NULL==pCertImportInfo)
  923. break;
  924. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertImportInfo);
  925. SetControlFont(pCertImportInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
  926. //set up the file name if pre-selected
  927. SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1, pCertImportInfo->pwszFileName);
  928. break;
  929. case WM_COMMAND:
  930. if(HIWORD(wParam) == BN_CLICKED)
  931. {
  932. if(LOWORD(wParam) == IDC_WIZARD_BUTTON1)
  933. {
  934. if(NULL==(pCertImportInfo=(CERT_IMPORT_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  935. break;
  936. //the browse button is clicked. Open the FileOpen dialogue
  937. memset(&OpenFileName, 0, sizeof(OpenFileName));
  938. *szFileName=L'\0';
  939. OpenFileName.lStructSize=sizeof(OpenFileName);
  940. OpenFileName.hwndOwner=hwndDlg;
  941. OpenFileName.nFilterIndex = 1;
  942. //get the file filer ID
  943. ids=GetFileFilerIDS(pCertImportInfo->dwFlag);
  944. //load the filter string
  945. if(LoadFilterString(g_hmodThisDll, ids, szFilter, MAX_STRING_SIZE + MAX_STRING_SIZE))
  946. {
  947. OpenFileName.lpstrFilter = szFilter;
  948. }
  949. dwChar = (DWORD)SendDlgItemMessage(hwndDlg, IDC_WIZARD_EDIT1, WM_GETTEXTLENGTH, 0, 0);
  950. if (NULL != (pwszInitialDir = (LPWSTR) WizardAlloc((dwChar+1)*sizeof(WCHAR))))
  951. {
  952. GetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1, pwszInitialDir, dwChar+1);
  953. }
  954. OpenFileName.lpstrInitialDir = pwszInitialDir;
  955. OpenFileName.lpstrFile=szFileName;
  956. OpenFileName.nMaxFile=_MAX_PATH;
  957. OpenFileName.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;
  958. //user has selected a file name
  959. if(WizGetOpenFileName(&OpenFileName))
  960. {
  961. //set the edit box
  962. SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1, szFileName);
  963. }
  964. if(pwszInitialDir != NULL)
  965. {
  966. WizardFree(pwszInitialDir);
  967. pwszInitialDir = NULL;
  968. }
  969. }
  970. }
  971. break;
  972. case WM_NOTIFY:
  973. switch (((NMHDR FAR *) lParam)->code)
  974. {
  975. case PSN_KILLACTIVE:
  976. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  977. return TRUE;
  978. break;
  979. case PSN_RESET:
  980. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  981. break;
  982. case PSN_SETACTIVE:
  983. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
  984. break;
  985. case PSN_WIZBACK:
  986. break;
  987. case PSN_WIZNEXT:
  988. if(NULL==(pCertImportInfo=(CERT_IMPORT_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  989. break;
  990. //make sure a file is selected
  991. if(0==(dwChar=(DWORD)SendDlgItemMessage(hwndDlg,
  992. IDC_WIZARD_EDIT1,
  993. WM_GETTEXTLENGTH, 0, 0)))
  994. {
  995. I_MessageBox(hwndDlg, IDS_HAS_TO_SELECT_FILE,
  996. IDS_IMPORT_WIZARD_TITLE,
  997. NULL,
  998. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  999. //make the file page stay
  1000. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  1001. break;
  1002. }
  1003. //get the file name
  1004. if(pCertImportInfo->pwszFileName)
  1005. {
  1006. //delete the old file name
  1007. if(TRUE==pCertImportInfo->fFreeFileName)
  1008. {
  1009. WizardFree(pCertImportInfo->pwszFileName);
  1010. pCertImportInfo->pwszFileName=NULL;
  1011. }
  1012. }
  1013. pCertImportInfo->pwszFileName=(LPWSTR)WizardAlloc((dwChar+1)*sizeof(WCHAR));
  1014. if(NULL!=(pCertImportInfo->pwszFileName))
  1015. {
  1016. GetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,
  1017. pCertImportInfo->pwszFileName,
  1018. dwChar+1);
  1019. pCertImportInfo->fFreeFileName=TRUE;
  1020. //make sure the file is valid
  1021. //delete the old store
  1022. if(pCertImportInfo->hSrcStore && (TRUE==pCertImportInfo->fFreeSrcStore))
  1023. {
  1024. CertCloseStore(pCertImportInfo->hSrcStore, 0);
  1025. pCertImportInfo->hSrcStore=NULL;
  1026. }
  1027. //we import anything but PKCS10 or signed document
  1028. if(!ExpandAndCryptQueryObject(
  1029. CERT_QUERY_OBJECT_FILE,
  1030. pCertImportInfo->pwszFileName,
  1031. dwExpectedContentType,
  1032. CERT_QUERY_FORMAT_FLAG_ALL,
  1033. 0,
  1034. NULL,
  1035. &(pCertImportInfo->dwContentType),
  1036. NULL,
  1037. &(pCertImportInfo->hSrcStore),
  1038. NULL,
  1039. NULL))
  1040. {
  1041. if(FileExist(pCertImportInfo->pwszFileName))
  1042. I_MessageBox(hwndDlg, IDS_FAIL_TO_RECOGNIZE_ENTER,
  1043. IDS_IMPORT_WIZARD_TITLE,
  1044. NULL,
  1045. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  1046. else
  1047. I_MessageBox(hwndDlg, IDS_NON_EXIST_FILE,
  1048. IDS_IMPORT_WIZARD_TITLE,
  1049. NULL,
  1050. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  1051. //make the file page stay
  1052. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  1053. break;
  1054. }
  1055. //we re-mark the pPFX
  1056. pCertImportInfo->fPFX=FALSE;
  1057. //get the blobs from the pfx file
  1058. if(CERT_QUERY_CONTENT_PFX==pCertImportInfo->dwContentType)
  1059. {
  1060. //we can not import PFX Files for remote case
  1061. if(pCertImportInfo->dwFlag & CRYPTUI_WIZ_IMPORT_REMOTE_DEST_STORE)
  1062. {
  1063. //output the message
  1064. I_MessageBox(hwndDlg, IDS_IMPORT_NO_PFX_FOR_REMOTE,
  1065. IDS_IMPORT_WIZARD_TITLE,
  1066. NULL,
  1067. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  1068. //make the file page stay
  1069. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  1070. break;
  1071. }
  1072. if((pCertImportInfo->blobData).pbData)
  1073. {
  1074. UnmapViewOfFile((pCertImportInfo->blobData).pbData);
  1075. (pCertImportInfo->blobData).pbData=NULL;
  1076. }
  1077. if(S_OK !=RetrieveBLOBFromFile(
  1078. pCertImportInfo->pwszFileName,
  1079. &((pCertImportInfo->blobData).cbData),
  1080. &((pCertImportInfo->blobData).pbData)))
  1081. {
  1082. //output the message
  1083. I_MessageBox(hwndDlg, IDS_FAIL_READ_FILE_ENTER,
  1084. IDS_IMPORT_WIZARD_TITLE,
  1085. NULL,
  1086. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  1087. //make the file page stay
  1088. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  1089. break;
  1090. }
  1091. //make sure that the soure store's content match with
  1092. //the expectation
  1093. if(0==((pCertImportInfo->dwFlag) & CRYPTUI_WIZ_IMPORT_ALLOW_CERT))
  1094. {
  1095. //output the message
  1096. I_MessageBox(hwndDlg,
  1097. IDS_IMPORT_OBJECT_NOT_EXPECTED,
  1098. IDS_IMPORT_WIZARD_TITLE,
  1099. NULL,
  1100. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  1101. //make the file page stay
  1102. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  1103. break;
  1104. }
  1105. }
  1106. else
  1107. {
  1108. //if the content is PKCS7, get the BLOB
  1109. if(CERT_QUERY_CONTENT_PKCS7_SIGNED==pCertImportInfo->dwContentType)
  1110. {
  1111. if((pCertImportInfo->blobData).pbData)
  1112. {
  1113. UnmapViewOfFile((pCertImportInfo->blobData).pbData);
  1114. (pCertImportInfo->blobData).pbData=NULL;
  1115. }
  1116. if(S_OK !=RetrieveBLOBFromFile(
  1117. pCertImportInfo->pwszFileName,
  1118. &((pCertImportInfo->blobData).cbData),
  1119. &((pCertImportInfo->blobData).pbData)))
  1120. {
  1121. //output the message
  1122. I_MessageBox(hwndDlg, IDS_FAIL_READ_FILE_ENTER,
  1123. IDS_IMPORT_WIZARD_TITLE,
  1124. NULL,
  1125. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  1126. //make the file page stay
  1127. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  1128. break;
  1129. }
  1130. }
  1131. //make sure we do have a source store
  1132. if(NULL==pCertImportInfo->hSrcStore)
  1133. {
  1134. //output the message
  1135. I_MessageBox(hwndDlg, IDS_FAIL_TO_RECOGNIZE_ENTER,
  1136. IDS_IMPORT_WIZARD_TITLE,
  1137. NULL,
  1138. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  1139. //make the file page stay
  1140. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  1141. break;
  1142. }
  1143. //remember to free the Src store
  1144. pCertImportInfo->fFreeSrcStore=TRUE;
  1145. //make sure that the soure store's content match with
  1146. //the expectation
  1147. ids=0;
  1148. if(!CheckForContent(pCertImportInfo->hSrcStore,
  1149. pCertImportInfo->dwFlag,
  1150. TRUE,
  1151. &ids))
  1152. {
  1153. //output the message
  1154. I_MessageBox(hwndDlg,
  1155. ids,
  1156. IDS_IMPORT_WIZARD_TITLE,
  1157. NULL,
  1158. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  1159. //make the file page stay
  1160. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  1161. break;
  1162. }
  1163. }
  1164. }
  1165. //skip the next page if password is not necessary
  1166. if(CERT_QUERY_CONTENT_PFX != pCertImportInfo->dwContentType)
  1167. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_IMPORT_STORE);
  1168. break;
  1169. default:
  1170. return FALSE;
  1171. }
  1172. break;
  1173. default:
  1174. return FALSE;
  1175. }
  1176. return TRUE;
  1177. }
  1178. //-----------------------------------------------------------------------
  1179. // Import_Password
  1180. //-----------------------------------------------------------------------
  1181. INT_PTR APIENTRY Import_Password(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  1182. {
  1183. CERT_IMPORT_INFO *pCertImportInfo=NULL;
  1184. PROPSHEETPAGE *pPropSheet=NULL;
  1185. HWND hwndControl=NULL;
  1186. DWORD dwChar;
  1187. UINT ids=0;
  1188. switch (msg)
  1189. {
  1190. case WM_INITDIALOG:
  1191. HRESULT hr;
  1192. HKEY hKey;
  1193. DWORD cb;
  1194. DWORD dwKeyValue;
  1195. DWORD dwType;
  1196. //set the wizard information so that it can be shared
  1197. pPropSheet = (PROPSHEETPAGE *) lParam;
  1198. pCertImportInfo = (CERT_IMPORT_INFO *) (pPropSheet->lParam);
  1199. //make sure pCertImportInfo is a valid pointer
  1200. if(NULL==pCertImportInfo)
  1201. break;
  1202. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertImportInfo);
  1203. SetControlFont(pCertImportInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
  1204. //init the passWord
  1205. SendDlgItemMessage(hwndDlg, IDC_WIZARD_EDIT1, EM_LIMITTEXT, (WPARAM) 64, (LPARAM) 0);
  1206. SetDlgItemTextU(
  1207. hwndDlg,
  1208. IDC_WIZARD_EDIT1,
  1209. (pCertImportInfo->pwszPassword != NULL) ? pCertImportInfo->pwszPassword : L"");
  1210. #if (1) //DSIE: Bug 333621
  1211. SendDlgItemMessage(hwndDlg, IDC_WIZARD_EDIT1, EM_LIMITTEXT, (WPARAM) 32, (LPARAM) 0);
  1212. #endif
  1213. //init the passWord flag
  1214. if(pCertImportInfo->dwPasswordFlags & CRYPT_EXPORTABLE)
  1215. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK_EXPORTKEY), BM_SETCHECK, 1, 0);
  1216. else
  1217. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK_EXPORTKEY), BM_SETCHECK, 0, 0);
  1218. if(pCertImportInfo->dwPasswordFlags & CRYPT_USER_PROTECTED)
  1219. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2), BM_SETCHECK, 1, 0);
  1220. else
  1221. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2), BM_SETCHECK, 0, 0);
  1222. //now, we need to grey out the user protection check box for the local
  1223. //machine import
  1224. if(pCertImportInfo->dwFlag & CRYPTUI_WIZ_IMPORT_TO_LOCALMACHINE)
  1225. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2), FALSE);
  1226. else
  1227. {
  1228. //
  1229. // Not Import to Local Machine
  1230. // Open the CRYPTOAPI_PRIVATE_KEY_OPTIONS registry key under HKLM
  1231. //
  1232. hKey = NULL;
  1233. hr = RegOpenKeyEx(
  1234. HKEY_LOCAL_MACHINE,
  1235. szKEY_CRYPTOAPI_PRIVATE_KEY_OPTIONS,
  1236. 0,
  1237. KEY_QUERY_VALUE,
  1238. &hKey);
  1239. if ( S_OK != hr )
  1240. goto error;
  1241. //
  1242. // Query the registry key for FORCE_KEY_PROTECTION value
  1243. //
  1244. cb = sizeof(dwKeyValue);
  1245. hr = RegQueryValueEx(
  1246. hKey,
  1247. szFORCE_KEY_PROTECTION,
  1248. NULL,
  1249. &dwType,
  1250. (BYTE *) &dwKeyValue,
  1251. &cb);
  1252. if( S_OK == hr && REG_DWORD == dwType && sizeof(dwKeyValue) == cb )
  1253. {
  1254. switch( dwKeyValue )
  1255. {
  1256. case dwFORCE_KEY_PROTECTION_DISABLED:
  1257. // do not force key protection
  1258. break;
  1259. case dwFORCE_KEY_PROTECTION_USER_SELECT:
  1260. // allow the user to select key protection UI, default = yes
  1261. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2), BM_SETCHECK, 1, 0);
  1262. break;
  1263. case dwFORCE_KEY_PROTECTION_HIGH:
  1264. // set to force key protection and grey out choice so that user cannot change value
  1265. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2), FALSE);
  1266. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2), BM_SETCHECK, 1, 0);
  1267. break;
  1268. default:
  1269. // Unknown value in registry
  1270. break;
  1271. }
  1272. }
  1273. error:
  1274. if( NULL != hKey ){
  1275. RegCloseKey(hKey);
  1276. }
  1277. }
  1278. break;
  1279. case WM_COMMAND:
  1280. break;
  1281. case WM_NOTIFY:
  1282. switch (((NMHDR FAR *) lParam)->code)
  1283. {
  1284. case PSN_KILLACTIVE:
  1285. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  1286. return TRUE;
  1287. break;
  1288. case PSN_RESET:
  1289. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  1290. break;
  1291. case PSN_SETACTIVE:
  1292. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
  1293. break;
  1294. case PSN_WIZBACK:
  1295. break;
  1296. case PSN_WIZNEXT:
  1297. if(NULL==(pCertImportInfo=(CERT_IMPORT_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  1298. break;
  1299. //free the memory
  1300. if(pCertImportInfo->pwszPassword)
  1301. {
  1302. // DSIE: Bug 534689.
  1303. SecureZeroMemory(pCertImportInfo->pwszPassword,
  1304. lstrlenW(pCertImportInfo->pwszPassword) * sizeof(WCHAR));
  1305. WizardFree(pCertImportInfo->pwszPassword);
  1306. pCertImportInfo->pwszPassword=NULL;
  1307. }
  1308. //get the password
  1309. if(0!=(dwChar=(DWORD)SendDlgItemMessage(hwndDlg,
  1310. IDC_WIZARD_EDIT1,
  1311. WM_GETTEXTLENGTH, 0, 0)))
  1312. {
  1313. pCertImportInfo->pwszPassword=(LPWSTR)WizardAlloc(sizeof(WCHAR)*(dwChar+1));
  1314. if(NULL!=pCertImportInfo->pwszPassword)
  1315. {
  1316. GetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1,
  1317. pCertImportInfo->pwszPassword,
  1318. dwChar+1);
  1319. }
  1320. else
  1321. break;
  1322. }
  1323. else
  1324. pCertImportInfo->pwszPassword=NULL;
  1325. //if user request to export the private key
  1326. if(TRUE==SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK_EXPORTKEY), BM_GETCHECK, 0, 0))
  1327. pCertImportInfo->dwPasswordFlags |=CRYPT_EXPORTABLE;
  1328. else
  1329. pCertImportInfo->dwPasswordFlags &= (~CRYPT_EXPORTABLE);
  1330. if(TRUE==SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2), BM_GETCHECK, 0, 0))
  1331. pCertImportInfo->dwPasswordFlags |=CRYPT_USER_PROTECTED;
  1332. else
  1333. pCertImportInfo->dwPasswordFlags &= (~CRYPT_USER_PROTECTED);
  1334. //delete the old certificate store
  1335. if(pCertImportInfo->hSrcStore && (TRUE==pCertImportInfo->fFreeSrcStore))
  1336. {
  1337. CertCloseStore(pCertImportInfo->hSrcStore, 0);
  1338. pCertImportInfo->hSrcStore=NULL;
  1339. }
  1340. //decode the PFX blob
  1341. if(NULL==(pCertImportInfo->blobData).pbData)
  1342. break;
  1343. //convert the PFX BLOB to a certificate store
  1344. pCertImportInfo->fPFX=PFXVerifyPassword(
  1345. (CRYPT_DATA_BLOB *)&(pCertImportInfo->blobData),
  1346. pCertImportInfo->pwszPassword,
  1347. 0);
  1348. if((FALSE==pCertImportInfo->fPFX) && (NULL == pCertImportInfo->pwszPassword))
  1349. {
  1350. //we try to use "" for no password case
  1351. pCertImportInfo->pwszPassword=(LPWSTR)WizardAlloc(sizeof(WCHAR));
  1352. if(NULL != pCertImportInfo->pwszPassword)
  1353. {
  1354. *(pCertImportInfo->pwszPassword)=L'\0';
  1355. pCertImportInfo->fPFX=PFXVerifyPassword(
  1356. (CRYPT_DATA_BLOB *)&(pCertImportInfo->blobData),
  1357. pCertImportInfo->pwszPassword,
  1358. 0);
  1359. }
  1360. }
  1361. if(FALSE==pCertImportInfo->fPFX)
  1362. {
  1363. //output the message
  1364. I_MessageBox(hwndDlg, IDS_INVALID_PASSWORD,
  1365. IDS_IMPORT_WIZARD_TITLE,
  1366. NULL,
  1367. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  1368. //make the file page stay
  1369. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  1370. break;
  1371. }
  1372. break;
  1373. default:
  1374. return FALSE;
  1375. }
  1376. break;
  1377. default:
  1378. return FALSE;
  1379. }
  1380. return TRUE;
  1381. }
  1382. //-----------------------------------------------------------------------
  1383. // Import_Store
  1384. //-----------------------------------------------------------------------
  1385. INT_PTR APIENTRY Import_Store(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  1386. {
  1387. CERT_IMPORT_INFO *pCertImportInfo=NULL;
  1388. PROPSHEETPAGE *pPropSheet=NULL;
  1389. HWND hwndControl=NULL;
  1390. DWORD dwSize=0;
  1391. CRYPTUI_SELECTSTORE_STRUCT CertStoreSelect;
  1392. STORENUMERATION_STRUCT StoreEnumerationStruct;
  1393. STORESFORSELCTION_STRUCT StoresForSelectionStruct;
  1394. HCERTSTORE hCertStore=NULL;
  1395. HDC hdc=NULL;
  1396. COLORREF colorRef;
  1397. LV_COLUMNW lvC;
  1398. UINT idsError=0;
  1399. switch (msg)
  1400. {
  1401. case WM_INITDIALOG:
  1402. //set the wizard information so that it can be shared
  1403. pPropSheet = (PROPSHEETPAGE *) lParam;
  1404. pCertImportInfo = (CERT_IMPORT_INFO *) (pPropSheet->lParam);
  1405. //make sure pCertImportInfo is a valid pointer
  1406. if(NULL==pCertImportInfo)
  1407. break;
  1408. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertImportInfo);
  1409. SetControlFont(pCertImportInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1);
  1410. //getthe background color of the parent window
  1411. //the background of the list view for store name is grayed
  1412. /*
  1413. if(hdc=GetWindowDC(hwndDlg))
  1414. {
  1415. if(CLR_INVALID!=(colorRef=GetBkColor(hdc)))
  1416. {
  1417. ListView_SetBkColor(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), CLR_NONE);
  1418. ListView_SetTextBkColor(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), CLR_NONE);
  1419. }
  1420. } */
  1421. //mark the store selection
  1422. if(pCertImportInfo->hDesStore)
  1423. {
  1424. //disable the 1st radio button
  1425. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_SETCHECK, 0, 0);
  1426. //select raio2
  1427. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO2), BM_SETCHECK, 1, 0);
  1428. //enable the windows for select a certificate store
  1429. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_STATIC1), TRUE);
  1430. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON1), TRUE);
  1431. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), TRUE);
  1432. //mark the store name
  1433. hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1);
  1434. if(hwndControl)
  1435. SetImportStoreName(hwndControl, pCertImportInfo->hDesStore);
  1436. //diable the radio buttons if CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST
  1437. //is set
  1438. if(pCertImportInfo->dwFlag & CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST_STORE)
  1439. {
  1440. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), FALSE);
  1441. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON1), FALSE);
  1442. }
  1443. }
  1444. else
  1445. {
  1446. //select the 1st radio button
  1447. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_SETCHECK, 1, 0);
  1448. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO2), BM_SETCHECK, 0, 0);
  1449. //disable the windows for select a certificate store
  1450. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_STATIC1), FALSE);
  1451. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON1), FALSE);
  1452. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), FALSE);
  1453. }
  1454. break;
  1455. case WM_COMMAND:
  1456. if(HIWORD(wParam) == BN_CLICKED)
  1457. {
  1458. switch (LOWORD(wParam))
  1459. {
  1460. case IDC_WIZARD_RADIO1:
  1461. //select the 1st radio button
  1462. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_SETCHECK, 1, 0);
  1463. //disable raio2
  1464. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO2), BM_SETCHECK, 0, 0);
  1465. //disable the windows for select a certificate store
  1466. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_STATIC1), FALSE);
  1467. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON1), FALSE);
  1468. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), FALSE);
  1469. break;
  1470. case IDC_WIZARD_RADIO2:
  1471. //disable the 1st radio button
  1472. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_SETCHECK, 0, 0);
  1473. //select raio2
  1474. SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO2), BM_SETCHECK, 1, 0);
  1475. //enable the windows for select a certificate store
  1476. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_STATIC1), TRUE);
  1477. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON1), TRUE);
  1478. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), TRUE);
  1479. //if no change of the desination is set, we need to diable the browse
  1480. //button and 1st radio button
  1481. if(NULL!=(pCertImportInfo=(CERT_IMPORT_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  1482. {
  1483. if(pCertImportInfo->dwFlag & CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST_STORE)
  1484. {
  1485. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), FALSE);
  1486. EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON1), FALSE);
  1487. }
  1488. }
  1489. break;
  1490. case IDC_WIZARD_BUTTON1:
  1491. if(NULL==(pCertImportInfo=(CERT_IMPORT_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  1492. {
  1493. break;
  1494. }
  1495. //get the hwndControl for the list view
  1496. hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1);
  1497. //call the store selection dialogue
  1498. memset(&CertStoreSelect, 0, sizeof(CertStoreSelect));
  1499. memset(&StoresForSelectionStruct, 0, sizeof(StoresForSelectionStruct));
  1500. memset(&StoreEnumerationStruct, 0, sizeof(StoreEnumerationStruct));
  1501. StoreEnumerationStruct.dwFlags=CERT_STORE_MAXIMUM_ALLOWED_FLAG;
  1502. StoreEnumerationStruct.pvSystemStoreLocationPara=NULL;
  1503. StoresForSelectionStruct.cEnumerationStructs = 1;
  1504. StoresForSelectionStruct.rgEnumerationStructs = &StoreEnumerationStruct;
  1505. // if a pfx import is taking place, then make sure the correct
  1506. // stores are displayed for selection
  1507. if ((TRUE == pCertImportInfo->fPFX) &&
  1508. (pCertImportInfo->dwFlag & CRYPTUI_WIZ_IMPORT_TO_LOCALMACHINE))
  1509. {
  1510. StoreEnumerationStruct.dwFlags |= CERT_SYSTEM_STORE_LOCAL_MACHINE;
  1511. }
  1512. else
  1513. {
  1514. StoreEnumerationStruct.dwFlags |= CERT_SYSTEM_STORE_CURRENT_USER;
  1515. }
  1516. CertStoreSelect.dwSize=sizeof(CertStoreSelect);
  1517. CertStoreSelect.hwndParent=hwndDlg;
  1518. CertStoreSelect.dwFlags=CRYPTUI_VALIDATE_STORES_AS_WRITABLE | CRYPTUI_ALLOW_PHYSICAL_STORE_VIEW | CRYPTUI_DISPLAY_WRITE_ONLY_STORES;
  1519. CertStoreSelect.pStoresForSelection = &StoresForSelectionStruct;
  1520. hCertStore=CryptUIDlgSelectStore(&CertStoreSelect);
  1521. if(hCertStore)
  1522. {
  1523. //delete the old destination certificate store
  1524. if(pCertImportInfo->hDesStore && (TRUE==pCertImportInfo->fFreeDesStore))
  1525. {
  1526. CertCloseStore(pCertImportInfo->hDesStore, 0);
  1527. pCertImportInfo->hDesStore=NULL;
  1528. }
  1529. pCertImportInfo->hDesStore=hCertStore;
  1530. pCertImportInfo->fFreeDesStore=TRUE;
  1531. //get the store name
  1532. if(hwndControl)
  1533. SetImportStoreName(hwndControl, pCertImportInfo->hDesStore);
  1534. }
  1535. break;
  1536. default:
  1537. break;
  1538. }
  1539. }
  1540. break;
  1541. case WM_NOTIFY:
  1542. switch (((NMHDR FAR *) lParam)->code)
  1543. {
  1544. case PSN_KILLACTIVE:
  1545. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  1546. return TRUE;
  1547. break;
  1548. case PSN_RESET:
  1549. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  1550. break;
  1551. case PSN_SETACTIVE:
  1552. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
  1553. break;
  1554. case PSN_WIZBACK:
  1555. if(NULL==(pCertImportInfo=(CERT_IMPORT_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  1556. {
  1557. break;
  1558. }
  1559. //skip the next page if password is not necessary
  1560. if(CERT_QUERY_CONTENT_PFX != pCertImportInfo->dwContentType)
  1561. {
  1562. //jump to the welcome page if the source is not from a file
  1563. if((pCertImportInfo->hSrcStore && (NULL==pCertImportInfo->pwszFileName)) ||
  1564. ((pCertImportInfo->fKnownSrc)&&(pCertImportInfo->pwszFileName)&&(CERT_QUERY_CONTENT_PKCS7_SIGNED == pCertImportInfo->dwContentType))
  1565. )
  1566. {
  1567. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_IMPORT_WELCOME);
  1568. }
  1569. else
  1570. {
  1571. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_IMPORT_FILE);
  1572. }
  1573. }
  1574. break;
  1575. case PSN_WIZNEXT:
  1576. if(NULL==(pCertImportInfo=(CERT_IMPORT_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  1577. {
  1578. break;
  1579. }
  1580. //make sure that we have select some store
  1581. if(TRUE==SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_GETCHECK, 0, 0))
  1582. {
  1583. //mark that the des store is not selected
  1584. pCertImportInfo->fSelectedDesStore=FALSE;
  1585. /*if(pCertImportInfo->pwszDefaultStoreName)
  1586. {
  1587. WizardFree(pCertImportInfo->pwszDefaultStoreName);
  1588. pCertImportInfo->pwszDefaultStoreName=NULL;
  1589. }*/
  1590. //we will not know the default store name
  1591. //if PFX was selected
  1592. /*if(pCertImportInfo->hSrcStore)
  1593. {
  1594. if(!GetDefaultStoreName(
  1595. pCertImportInfo,
  1596. pCertImportInfo->hSrcStore,
  1597. &(pCertImportInfo->pwszDefaultStoreName),
  1598. &idsError))
  1599. {
  1600. //output the message
  1601. I_MessageBox(hwndDlg, idsError,
  1602. IDS_IMPORT_WIZARD_TITLE,
  1603. NULL,
  1604. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  1605. //make the file page stay
  1606. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  1607. break;
  1608. }
  1609. } */
  1610. }
  1611. else
  1612. {
  1613. //make sure we have something selected
  1614. if(NULL==pCertImportInfo->hDesStore)
  1615. {
  1616. //output the message
  1617. I_MessageBox(hwndDlg, IDS_HAS_TO_SELECT_STORE,
  1618. IDS_IMPORT_WIZARD_TITLE,
  1619. NULL,
  1620. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  1621. //make the file page stay
  1622. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  1623. break;
  1624. }
  1625. else
  1626. {
  1627. pCertImportInfo->fSelectedDesStore=TRUE;
  1628. }
  1629. }
  1630. break;
  1631. default:
  1632. return FALSE;
  1633. }
  1634. break;
  1635. default:
  1636. return FALSE;
  1637. }
  1638. return TRUE;
  1639. }
  1640. //-----------------------------------------------------------------------
  1641. // Import_Completion
  1642. //-----------------------------------------------------------------------
  1643. INT_PTR APIENTRY Import_Completion(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  1644. {
  1645. CERT_IMPORT_INFO *pCertImportInfo=NULL;
  1646. PROPSHEETPAGE *pPropSheet=NULL;
  1647. HWND hwndControl=NULL;
  1648. LV_COLUMNW lvC;
  1649. HDC hdc=NULL;
  1650. COLORREF colorRef;
  1651. switch (msg)
  1652. {
  1653. case WM_INITDIALOG:
  1654. //set the wizard information so that it can be shared
  1655. pPropSheet = (PROPSHEETPAGE *) lParam;
  1656. pCertImportInfo = (CERT_IMPORT_INFO *) (pPropSheet->lParam);
  1657. //make sure pCertImportInfo is a valid pointer
  1658. if(NULL==pCertImportInfo)
  1659. break;
  1660. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertImportInfo);
  1661. SetControlFont(pCertImportInfo->hBigBold, hwndDlg,IDC_WIZARD_STATIC_BIG_BOLD1);
  1662. //getthe background color of the parent window
  1663. /*
  1664. if(hdc=GetWindowDC(hwndDlg))
  1665. {
  1666. if(CLR_INVALID!=(colorRef=GetBkColor(hdc)))
  1667. {
  1668. ListView_SetBkColor(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), CLR_NONE);
  1669. ListView_SetTextBkColor(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), CLR_NONE);
  1670. }
  1671. } */
  1672. //insert two columns for the confirmation
  1673. if(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1))
  1674. {
  1675. //1st one is the label for the confirmation
  1676. memset(&lvC, 0, sizeof(LV_COLUMNW));
  1677. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  1678. lvC.fmt = LVCFMT_LEFT; // Left-align the column.
  1679. lvC.cx = 20; // Width of the column, in pixels.
  1680. lvC.pszText = L""; // The text for the column.
  1681. lvC.iSubItem=0;
  1682. ListView_InsertColumnU(hwndControl, 0, &lvC);
  1683. //2nd column is the content
  1684. memset(&lvC, 0, sizeof(LV_COLUMNW));
  1685. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  1686. lvC.fmt = LVCFMT_LEFT; // Left-align the column.
  1687. lvC.cx = 20; // Width of the column, in pixels.
  1688. lvC.pszText = L""; // The text for the column.
  1689. lvC.iSubItem= 1;
  1690. ListView_InsertColumnU(hwndControl, 1, &lvC);
  1691. }
  1692. break;
  1693. case WM_COMMAND:
  1694. break;
  1695. case WM_NOTIFY:
  1696. switch (((NMHDR FAR *) lParam)->code)
  1697. {
  1698. case PSN_KILLACTIVE:
  1699. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  1700. return TRUE;
  1701. break;
  1702. case PSN_RESET:
  1703. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  1704. break;
  1705. case PSN_SETACTIVE:
  1706. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK|PSWIZB_FINISH);
  1707. if(NULL==(pCertImportInfo=(CERT_IMPORT_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  1708. {
  1709. break;
  1710. }
  1711. //populate the list box in the order of
  1712. //FileName, FileType, and store info
  1713. if(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1))
  1714. {
  1715. DisplayImportConfirmation(hwndControl, pCertImportInfo);
  1716. ListView_SetItemState(hwndControl,
  1717. 0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  1718. }
  1719. break;
  1720. case PSN_WIZBACK:
  1721. break;
  1722. case PSN_WIZFINISH:
  1723. break;
  1724. default:
  1725. return FALSE;
  1726. }
  1727. break;
  1728. default:
  1729. return FALSE;
  1730. }
  1731. return TRUE;
  1732. }
  1733. //--------------------------------------------------------------------------------
  1734. //
  1735. // Add a specified Cert/CTL/CRL context to specified destination store, and prompt
  1736. // user for permission if attempting to replace an older context over a newer
  1737. // context, if UI is allowed.
  1738. //
  1739. //---------------------------------------------------------------------------------
  1740. DWORD AddContextToStore(IN DWORD dwContextType,
  1741. IN HWND hwndParent,
  1742. IN PVOID pContext,
  1743. IN BOOL fUIAllowed,
  1744. IN HCERTSTORE hDstStore)
  1745. {
  1746. DWORD dwRetCode = 0;
  1747. switch (dwContextType)
  1748. {
  1749. case CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_CONTEXT:
  1750. {
  1751. //
  1752. // Add cert context to store.
  1753. //
  1754. if (!CertAddCertificateContextToStore(hDstStore,
  1755. (PCCERT_CONTEXT) pContext,
  1756. CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES,
  1757. NULL))
  1758. {
  1759. dwRetCode = GetLastError();
  1760. break;
  1761. }
  1762. break;
  1763. }
  1764. case CRYPTUI_WIZ_IMPORT_SUBJECT_CTL_CONTEXT:
  1765. {
  1766. if (!CertAddCTLContextToStore(hDstStore,
  1767. (PCCTL_CONTEXT) pContext,
  1768. CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES,
  1769. NULL))
  1770. {
  1771. //
  1772. // If there is a newer copy in the store, then prompt user for permission
  1773. // to replace, if UI is allowed.
  1774. //
  1775. if ((!fUIAllowed) && (CRYPT_E_EXISTS != GetLastError()))
  1776. {
  1777. dwRetCode = GetLastError();
  1778. break;
  1779. }
  1780. if (IDYES != I_MessageBox(hwndParent,
  1781. IDS_IMPORT_REPLACE_EXISTING_NEWER_CTL,
  1782. IDS_IMPORT_WIZARD_TITLE,
  1783. NULL,
  1784. MB_YESNO | MB_ICONINFORMATION | MB_DEFBUTTON2))
  1785. {
  1786. dwRetCode = ERROR_CANCELLED;
  1787. break;
  1788. }
  1789. //
  1790. // Try with REPLACE_EXISTING disposition.
  1791. //
  1792. if (!CertAddCTLContextToStore(hDstStore,
  1793. (PCCTL_CONTEXT) pContext,
  1794. CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES,
  1795. NULL))
  1796. {
  1797. dwRetCode = GetLastError();
  1798. break;
  1799. }
  1800. }
  1801. break;
  1802. }
  1803. case CRYPTUI_WIZ_IMPORT_SUBJECT_CRL_CONTEXT:
  1804. {
  1805. if (!CertAddCRLContextToStore(hDstStore,
  1806. (PCCRL_CONTEXT) pContext,
  1807. CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES,
  1808. NULL))
  1809. {
  1810. //
  1811. // If there is a newer copy in the store, then prompt user for permission
  1812. // to replace, if UI is allowed.
  1813. //
  1814. if ((!fUIAllowed) && (CRYPT_E_EXISTS != GetLastError()))
  1815. {
  1816. dwRetCode = GetLastError();
  1817. break;
  1818. }
  1819. if (IDYES != I_MessageBox(hwndParent,
  1820. IDS_IMPORT_REPLACE_EXISTING_NEWER_CRL,
  1821. IDS_IMPORT_WIZARD_TITLE,
  1822. NULL,
  1823. MB_YESNO | MB_ICONINFORMATION | MB_DEFBUTTON2))
  1824. {
  1825. dwRetCode = ERROR_CANCELLED;
  1826. break;
  1827. }
  1828. //
  1829. // Try with REPLACE_EXISTING disposition.
  1830. //
  1831. if (!CertAddCRLContextToStore(hDstStore,
  1832. (PCCRL_CONTEXT) pContext,
  1833. CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES,
  1834. NULL))
  1835. {
  1836. dwRetCode = GetLastError();
  1837. break;
  1838. }
  1839. }
  1840. break;
  1841. }
  1842. default:
  1843. {
  1844. dwRetCode = ERROR_INVALID_PARAMETER;
  1845. break;
  1846. }
  1847. }
  1848. return dwRetCode;
  1849. }
  1850. //--------------------------------------------------------------------------------
  1851. //
  1852. // Add CTLs from source store to destination store.
  1853. //
  1854. //---------------------------------------------------------------------------------
  1855. DWORD AddCTLsToStore(HWND hwndParent,
  1856. HCERTSTORE hSrcStore,
  1857. HCERTSTORE hDstStore,
  1858. BOOL fUIAllowed,
  1859. UINT * pidsStatus)
  1860. {
  1861. DWORD dwError = 0;
  1862. PCCTL_CONTEXT pCTLPre = NULL;
  1863. PCCTL_CONTEXT pCTLContext = NULL;
  1864. PCCTL_CONTEXT pFindCTL = NULL;
  1865. //DSIE: Bug 22633.
  1866. BOOL bCancelled = FALSE;
  1867. // Add the CTLs
  1868. while (pCTLContext = CertEnumCTLsInStore(hSrcStore, pCTLPre))
  1869. {
  1870. bCancelled = FALSE;
  1871. if (0 != (dwError = AddContextToStore(CRYPTUI_WIZ_IMPORT_SUBJECT_CTL_CONTEXT,
  1872. hwndParent,
  1873. (PVOID) pCTLContext,
  1874. fUIAllowed,
  1875. hDstStore)))
  1876. {
  1877. if (ERROR_CANCELLED == dwError)
  1878. {
  1879. bCancelled = TRUE;
  1880. }
  1881. else
  1882. {
  1883. // Check to see if there is alreay a read-only duplicated copy in the store?
  1884. // If so, ignore the error.
  1885. if (NULL == (pFindCTL = CertFindCTLInStore(hDstStore,
  1886. g_dwMsgAndCertEncodingType,
  1887. 0,
  1888. CTL_FIND_EXISTING,
  1889. pCTLContext,
  1890. NULL)))
  1891. {
  1892. *pidsStatus = IDS_IMPORT_FAIL_MOVE_CONTENT;
  1893. goto CLEANUP;
  1894. }
  1895. CertFreeCTLContext(pFindCTL);
  1896. pFindCTL = NULL;
  1897. }
  1898. dwError = 0;
  1899. }
  1900. pCTLPre = pCTLContext;
  1901. }
  1902. //
  1903. // As the way we have it now, we can only check the last operation!
  1904. //
  1905. if (bCancelled)
  1906. {
  1907. dwError = ERROR_CANCELLED;
  1908. *pidsStatus = IDS_IMPORT_CANCELLED;
  1909. }
  1910. else
  1911. {
  1912. *pidsStatus = IDS_IMPORT_SUCCEEDED;
  1913. }
  1914. CLEANUP:
  1915. if (pCTLContext)
  1916. {
  1917. CertFreeCTLContext(pCTLContext);
  1918. }
  1919. return dwError;
  1920. }
  1921. //--------------------------------------------------------------------------------
  1922. //
  1923. // Add CRLs from source store to destination store.
  1924. //
  1925. //---------------------------------------------------------------------------------
  1926. DWORD AddCRLsToStore(HWND hwndParent,
  1927. HCERTSTORE hSrcStore,
  1928. HCERTSTORE hDstStore,
  1929. BOOL fUIAllowed,
  1930. UINT * pidsStatus)
  1931. {
  1932. DWORD dwError = 0;
  1933. DWORD dwCRLFlag = 0;
  1934. PCCRL_CONTEXT pCRLPre = NULL;
  1935. PCCRL_CONTEXT pCRLContext = NULL;
  1936. PCCRL_CONTEXT pFindCRL = NULL;
  1937. //DSIE: Bug 22633.
  1938. BOOL bCancelled = FALSE;
  1939. // Add the CRLs
  1940. while (pCRLContext = CertGetCRLFromStore(hSrcStore, NULL, pCRLPre, &dwCRLFlag))
  1941. {
  1942. bCancelled = FALSE;
  1943. if (0 != (dwError = AddContextToStore(CRYPTUI_WIZ_IMPORT_SUBJECT_CRL_CONTEXT,
  1944. hwndParent,
  1945. (PVOID) pCRLContext,
  1946. fUIAllowed,
  1947. hDstStore)))
  1948. {
  1949. if (ERROR_CANCELLED == dwError)
  1950. {
  1951. bCancelled = TRUE;
  1952. }
  1953. else
  1954. {
  1955. // Check to see if there is alreay a read-only duplicated copy in the store?
  1956. // If so, ignore the error.
  1957. if (NULL == (pFindCRL = CertFindCRLInStore(hDstStore,
  1958. g_dwMsgAndCertEncodingType,
  1959. 0,
  1960. CRL_FIND_EXISTING,
  1961. pCRLContext,
  1962. NULL)))
  1963. {
  1964. *pidsStatus = IDS_IMPORT_FAIL_MOVE_CONTENT;
  1965. goto CLEANUP;
  1966. }
  1967. CertFreeCRLContext(pFindCRL);
  1968. pFindCRL = NULL;
  1969. }
  1970. dwError = 0;
  1971. }
  1972. pCRLPre = pCRLContext;
  1973. }
  1974. //
  1975. // As the way we have it now, we can only check the last operation!
  1976. //
  1977. if (bCancelled)
  1978. {
  1979. dwError = ERROR_CANCELLED;
  1980. *pidsStatus = IDS_IMPORT_CANCELLED;
  1981. }
  1982. else
  1983. {
  1984. *pidsStatus = IDS_IMPORT_SUCCEEDED;
  1985. }
  1986. CLEANUP:
  1987. if (pCRLContext)
  1988. {
  1989. CertFreeCRLContext(pCRLContext);
  1990. }
  1991. return dwError;
  1992. }
  1993. //--------------------------------------------------------------------------------
  1994. //
  1995. // Add certs from source store to destination store.
  1996. //
  1997. //---------------------------------------------------------------------------------
  1998. DWORD AddCertsToStore(HWND hwndParent,
  1999. HCERTSTORE hSrcStore,
  2000. HCERTSTORE hDstStore,
  2001. BOOL fUIAllowed,
  2002. UINT * pidsStatus)
  2003. {
  2004. DWORD dwError = 0;
  2005. PCCERT_CONTEXT pCertPre = NULL;
  2006. PCCERT_CONTEXT pCertContext = NULL;
  2007. PCCERT_CONTEXT pFindCert = NULL;
  2008. //DSIE: Bug 22633.
  2009. BOOL bCancelled = FALSE;
  2010. // Add the certs
  2011. while (pCertContext = CertEnumCertificatesInStore(hSrcStore, pCertPre))
  2012. {
  2013. bCancelled = FALSE;
  2014. if (0 != (dwError = AddContextToStore(CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_CONTEXT,
  2015. hwndParent,
  2016. (PVOID) pCertContext,
  2017. fUIAllowed,
  2018. hDstStore)))
  2019. {
  2020. if (ERROR_CANCELLED == dwError)
  2021. {
  2022. bCancelled = TRUE;
  2023. }
  2024. else
  2025. {
  2026. // Check to see if there is alreay a read-only duplicated copy in the store?
  2027. // If so, ignore the error.
  2028. if (NULL == (pFindCert = CertFindCertificateInStore(hDstStore,
  2029. g_dwMsgAndCertEncodingType,
  2030. 0,
  2031. CERT_FIND_EXISTING,
  2032. pCertContext,
  2033. NULL)))
  2034. {
  2035. *pidsStatus = IDS_IMPORT_FAIL_MOVE_CONTENT;
  2036. goto CLEANUP;
  2037. }
  2038. CertFreeCertificateContext(pFindCert);
  2039. pFindCert = NULL;
  2040. }
  2041. dwError = 0;
  2042. }
  2043. pCertPre = pCertContext;
  2044. }
  2045. //
  2046. // As the way we have it now, we can only check the last operation!
  2047. //
  2048. if (bCancelled)
  2049. {
  2050. dwError = ERROR_CANCELLED;
  2051. *pidsStatus = IDS_IMPORT_CANCELLED;
  2052. }
  2053. else
  2054. {
  2055. *pidsStatus = IDS_IMPORT_SUCCEEDED;
  2056. }
  2057. CLEANUP:
  2058. if (pCertContext)
  2059. {
  2060. CertFreeCertificateContext(pCertContext);
  2061. }
  2062. return dwError;
  2063. }
  2064. //-------------------------------------------------------------------------
  2065. //
  2066. // Move Certs/CRls/CTLs from the source store to the destination
  2067. //
  2068. //-------------------------------------------------------------------------
  2069. DWORD MoveItem(CERT_IMPORT_INFO * pCertImportInfo,
  2070. UINT * pidsStatus)
  2071. {
  2072. DWORD dwError = 0;
  2073. // Add the CTLs.
  2074. if (0 != (dwError = AddCTLsToStore(pCertImportInfo->hwndParent,
  2075. pCertImportInfo->hSrcStore,
  2076. pCertImportInfo->hDesStore,
  2077. pCertImportInfo->dwFlag & CRYPTUI_WIZ_NO_UI ? TRUE : FALSE,
  2078. pidsStatus)))
  2079. {
  2080. goto CLEANUP;
  2081. }
  2082. // Add the CRLs.
  2083. if (0 != (dwError = AddCRLsToStore(pCertImportInfo->hwndParent,
  2084. pCertImportInfo->hSrcStore,
  2085. pCertImportInfo->hDesStore,
  2086. pCertImportInfo->dwFlag & CRYPTUI_WIZ_NO_UI ? TRUE : FALSE,
  2087. pidsStatus)))
  2088. {
  2089. goto CLEANUP;
  2090. }
  2091. // Add the certs.
  2092. if (0 != (dwError = AddCertsToStore(pCertImportInfo->hwndParent,
  2093. pCertImportInfo->hSrcStore,
  2094. pCertImportInfo->hDesStore,
  2095. pCertImportInfo->dwFlag & CRYPTUI_WIZ_NO_UI ? TRUE : FALSE,
  2096. pidsStatus)))
  2097. {
  2098. goto CLEANUP;
  2099. }
  2100. CLEANUP:
  2101. return dwError;
  2102. }
  2103. //**************************************************************************
  2104. //
  2105. // The entry point for import wizard
  2106. //**************************************************************************
  2107. //-----------------------------------------------------------------------
  2108. //
  2109. // CryptUIWizImport
  2110. //
  2111. // The import wizard to import public key related files to a certificate
  2112. // store
  2113. //
  2114. // dwFlags can be set to any combination of the following flags:
  2115. // CRYPTUI_WIZ_NO_UI No UI will be shown. Otherwise, User will be
  2116. // prompted by a wizard.
  2117. // CRYPTUI_WIZ_IMPORT_ALLOW_CERT Allow importing certificate
  2118. // CRYPTUI_WIZ_IMPORT_ALLOW_CRL Allow importing CRL(certificate revocation list)
  2119. // CRYPTUI_WIZ_IMPORT_ALLOW_CTL Allow importing CTL(certificate trust list)
  2120. // CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST_STORE user will not be allowed to change
  2121. // the hDesCertStore in the wizard page
  2122. // CRYPTUI_WIZ_IMPORT_TO_LOCALMACHINE the contents should be imported to local machine
  2123. // (currently only applicable for PFX imports)
  2124. // CRYPTUI_WIZ_IMPORT_TO_CURRENTUSER the contents should be imported to current user
  2125. // (currently only applicable for PFX imports)
  2126. //
  2127. // Please notice that if neither of following three flags is in dwFlags, default to is
  2128. // allow everything.
  2129. // CRYPTUI_WIZ_IMPORT_ALLOW_CERT
  2130. // CRYPTUI_WIZ_IMPORT_ALLOW_CRL
  2131. // CRYPTUI_WIZ_IMPORT_ALLOW_CTL
  2132. //
  2133. // Also, note that the CRYPTUI_WIZ_IMPORT_TO_LOCALMACHINE and CRYPTUI_WIZ_IMPORT_TO_CURRENTUSER
  2134. // flags are used force the content of a pfx blob into either local machine or current user.
  2135. // If neither of these flags are used and hDesCertStore is NULL then:
  2136. // 1) The private key in the pfx blob will be forced to be imported into current user.
  2137. // 2) If CRYPTUI_WIZ_NO_UI is NOT set, the wizard will prompt the user to select a certificate
  2138. // store from the current user stores.
  2139. //
  2140. //
  2141. //
  2142. // If CRYPTUI_WIZ_NO_UI is set in dwFlags:
  2143. // hwndParent: Ignored
  2144. // pwszWizardTitle: Ignored
  2145. // pImportSubject: IN Required: The subject to import.
  2146. // hDestCertStore: IN Optional: The destination certficate store
  2147. //
  2148. // If CRYPTUI_WIZ_NO_UI is not set in dwFlags:
  2149. // hwndPrarent: IN Optional: The parent window for the wizard
  2150. // pwszWizardTitle: IN Optional: The title of the wizard
  2151. // If NULL, the default will be IDS_BUILDCTL_WIZARD_TITLE
  2152. // pImportSubject: IN Optional: The file name to import.
  2153. // If NULL, the wizard will prompt user to enter the file name
  2154. // hDestCertStore: IN Optional: The destination certificate store where the file wil be
  2155. // imported to. If NULL, the wizard will prompt user to select
  2156. // a certificate store
  2157. //------------------------------------------------------------------------
  2158. BOOL
  2159. WINAPI
  2160. CryptUIWizImport(
  2161. DWORD dwFlags,
  2162. HWND hwndParent,
  2163. LPCWSTR pwszWizardTitle,
  2164. PCCRYPTUI_WIZ_IMPORT_SRC_INFO pImportSubject,
  2165. HCERTSTORE hDestCertStore
  2166. )
  2167. {
  2168. BOOL fResult=FALSE;
  2169. HRESULT hr=E_FAIL;
  2170. CERT_IMPORT_INFO CertImportInfo;
  2171. HCERTSTORE hTempStore=NULL;
  2172. UINT ids=IDS_INVALID_WIZARD_INPUT;
  2173. UINT idsContent=0;
  2174. PROPSHEETPAGEW rgImportSheet[IMPORT_PROP_SHEET];
  2175. PROPSHEETHEADERW importHeader;
  2176. ENROLL_PAGE_INFO rgImportPageInfo[]=
  2177. {(LPCWSTR)MAKEINTRESOURCE(IDD_IMPORT_WELCOME), Import_Welcome,
  2178. (LPCWSTR)MAKEINTRESOURCE(IDD_IMPORT_FILE), Import_File,
  2179. (LPCWSTR)MAKEINTRESOURCE(IDD_IMPORT_PASSWORD), Import_Password,
  2180. (LPCWSTR)MAKEINTRESOURCE(IDD_IMPORT_STORE), Import_Store,
  2181. (LPCWSTR)MAKEINTRESOURCE(IDD_IMPORT_COMPLETION), Import_Completion,
  2182. };
  2183. DWORD dwIndex=0;
  2184. DWORD dwPropCount=0;
  2185. WCHAR wszTitle[MAX_TITLE_LENGTH];
  2186. DWORD dwError=0;
  2187. int intMsg=0;
  2188. INT_PTR iReturn=-1;
  2189. //init
  2190. memset(&CertImportInfo, 0, sizeof(CERT_IMPORT_INFO));
  2191. memset(rgImportSheet, 0, sizeof(PROPSHEETPAGEW)*IMPORT_PROP_SHEET);
  2192. memset(&importHeader, 0, sizeof(PROPSHEETHEADERW));
  2193. //make sure if UIless option is set, all required information
  2194. //is provided
  2195. if(dwFlags & CRYPTUI_WIZ_NO_UI)
  2196. {
  2197. if(NULL==pImportSubject)
  2198. goto InvalidArgErr;
  2199. }
  2200. if ((dwFlags & CRYPTUI_WIZ_IMPORT_TO_LOCALMACHINE) &&
  2201. (dwFlags & CRYPTUI_WIZ_IMPORT_TO_CURRENTUSER))
  2202. {
  2203. goto InvalidArgErr;
  2204. }
  2205. //make sure that default is to allow everything
  2206. if((0 == (dwFlags & CRYPTUI_WIZ_IMPORT_ALLOW_CERT)) &&
  2207. (0 == (dwFlags & CRYPTUI_WIZ_IMPORT_ALLOW_CRL)) &&
  2208. (0 == (dwFlags & CRYPTUI_WIZ_IMPORT_ALLOW_CTL)))
  2209. dwFlags |= CRYPTUI_WIZ_IMPORT_ALLOW_CERT | CRYPTUI_WIZ_IMPORT_ALLOW_CRL | CRYPTUI_WIZ_IMPORT_ALLOW_CTL;
  2210. //if hDestCertStore is NULL, no need to set the remote flag
  2211. if(NULL == hDestCertStore)
  2212. dwFlags &= (~CRYPTUI_WIZ_IMPORT_REMOTE_DEST_STORE);
  2213. CertImportInfo.hwndParent=hwndParent;
  2214. CertImportInfo.dwFlag=dwFlags;
  2215. //set the subject
  2216. if(pImportSubject)
  2217. {
  2218. if(pImportSubject->dwSize != sizeof(CRYPTUI_WIZ_IMPORT_SRC_INFO))
  2219. goto InvalidArgErr;
  2220. //copy the passWord and flags for PFX BLOBs
  2221. CertImportInfo.dwPasswordFlags=pImportSubject->dwFlags;
  2222. if(pImportSubject->pwszPassword)
  2223. CertImportInfo.pwszPassword=WizardAllocAndCopyWStr((LPWSTR)(pImportSubject->pwszPassword));
  2224. else
  2225. CertImportInfo.pwszPassword=NULL;
  2226. //open a temparory certificate store
  2227. hTempStore=CertOpenStore(CERT_STORE_PROV_MEMORY,
  2228. g_dwMsgAndCertEncodingType,
  2229. NULL,
  2230. 0,
  2231. NULL);
  2232. if(!hTempStore)
  2233. goto CertOpenStoreErr;
  2234. switch(pImportSubject->dwSubjectChoice)
  2235. {
  2236. case CRYPTUI_WIZ_IMPORT_SUBJECT_FILE:
  2237. if(NULL==pImportSubject->pwszFileName)
  2238. goto InvalidArgErr;
  2239. CertImportInfo.pwszFileName=(LPWSTR)(pImportSubject->pwszFileName);
  2240. CertImportInfo.fFreeFileName=FALSE;
  2241. //get the content type of the file
  2242. //we import anything but PKCS10 or signed document
  2243. ExpandAndCryptQueryObject(
  2244. CERT_QUERY_OBJECT_FILE,
  2245. CertImportInfo.pwszFileName,
  2246. dwExpectedContentType,
  2247. CERT_QUERY_FORMAT_FLAG_ALL,
  2248. 0,
  2249. NULL,
  2250. &(CertImportInfo.dwContentType),
  2251. NULL,
  2252. &(CertImportInfo.hSrcStore),
  2253. NULL,
  2254. NULL);
  2255. //if this is a PKCS7 file, get the blob
  2256. if(CERT_QUERY_CONTENT_PKCS7_SIGNED == CertImportInfo.dwContentType )
  2257. {
  2258. if(S_OK !=(hr=RetrieveBLOBFromFile(
  2259. CertImportInfo.pwszFileName,
  2260. &(CertImportInfo.blobData.cbData),
  2261. &(CertImportInfo.blobData.pbData))))
  2262. goto ReadFromFileErr;
  2263. }
  2264. else
  2265. {
  2266. //get the blobs from the pfx file
  2267. if(CERT_QUERY_CONTENT_PFX==CertImportInfo.dwContentType)
  2268. {
  2269. //we can not import PFX Files for remote case
  2270. if(dwFlags & CRYPTUI_WIZ_IMPORT_REMOTE_DEST_STORE)
  2271. {
  2272. ids=IDS_IMPORT_NO_PFX_FOR_REMOTE;
  2273. goto InvalidArgErr;
  2274. }
  2275. if(S_OK !=(hr=RetrieveBLOBFromFile(
  2276. CertImportInfo.pwszFileName,
  2277. &(CertImportInfo.blobData.cbData),
  2278. &(CertImportInfo.blobData.pbData))))
  2279. goto ReadFromFileErr;
  2280. //convert the PFX BLOB to a certificate store
  2281. CertImportInfo.fPFX=PFXVerifyPassword(
  2282. (CRYPT_DATA_BLOB *)&(CertImportInfo.blobData),
  2283. CertImportInfo.pwszPassword,
  2284. 0);
  2285. //PFX blob only contains certificates
  2286. if(0==((CertImportInfo.dwFlag) & CRYPTUI_WIZ_IMPORT_ALLOW_CERT))
  2287. {
  2288. ids=IDS_IMPORT_OBJECT_NOT_EXPECTED;
  2289. goto InvalidArgErr;
  2290. }
  2291. }
  2292. }
  2293. //make sure we do have a source store
  2294. if(CertImportInfo.hSrcStore)
  2295. {
  2296. //remember to free the Src store
  2297. CertImportInfo.fFreeSrcStore=TRUE;
  2298. CertImportInfo.fKnownSrc=TRUE;
  2299. }
  2300. break;
  2301. case CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_CONTEXT:
  2302. if(NULL==pImportSubject->pCertContext)
  2303. goto InvalidArgErr;
  2304. //add certificate to the hash
  2305. if(!CertAddCertificateContextToStore(
  2306. hTempStore,
  2307. pImportSubject->pCertContext,
  2308. CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES,
  2309. NULL))
  2310. goto AddCertErr;
  2311. CertImportInfo.hSrcStore=hTempStore;
  2312. CertImportInfo.fFreeSrcStore=FALSE;
  2313. CertImportInfo.dwContentType=CERT_QUERY_CONTENT_CERT;
  2314. CertImportInfo.fKnownSrc=TRUE;
  2315. break;
  2316. case CRYPTUI_WIZ_IMPORT_SUBJECT_CTL_CONTEXT:
  2317. if(NULL==pImportSubject->pCTLContext)
  2318. goto InvalidArgErr;
  2319. //add CTL to the hash
  2320. if(!CertAddCTLContextToStore(
  2321. hTempStore,
  2322. pImportSubject->pCTLContext,
  2323. CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES,
  2324. NULL))
  2325. goto Crypt32Err;
  2326. CertImportInfo.hSrcStore=hTempStore;
  2327. CertImportInfo.fFreeSrcStore=FALSE;
  2328. CertImportInfo.dwContentType=CERT_QUERY_CONTENT_CTL;
  2329. CertImportInfo.fKnownSrc=TRUE;
  2330. break;
  2331. case CRYPTUI_WIZ_IMPORT_SUBJECT_CRL_CONTEXT:
  2332. if(NULL==pImportSubject->pCRLContext)
  2333. goto InvalidArgErr;
  2334. //add CRL to the hash
  2335. if(!CertAddCRLContextToStore(
  2336. hTempStore,
  2337. pImportSubject->pCRLContext,
  2338. CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES,
  2339. NULL))
  2340. goto Crypt32Err;
  2341. CertImportInfo.hSrcStore=hTempStore;
  2342. CertImportInfo.fFreeSrcStore=FALSE;
  2343. CertImportInfo.fKnownSrc=TRUE;
  2344. CertImportInfo.dwContentType=CERT_QUERY_CONTENT_CRL;
  2345. break;
  2346. case CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_STORE:
  2347. if(NULL==pImportSubject->hCertStore)
  2348. goto InvalidArgErr;
  2349. CertImportInfo.hSrcStore=pImportSubject->hCertStore;
  2350. CertImportInfo.fFreeSrcStore=FALSE;
  2351. CertImportInfo.dwContentType=0;
  2352. CertImportInfo.fKnownSrc=TRUE;
  2353. break;
  2354. default:
  2355. goto InvalidArgErr;
  2356. }
  2357. }
  2358. else
  2359. {
  2360. CertImportInfo.fKnownSrc=FALSE;
  2361. }
  2362. //if user has supplied a source store, it should contain the correct
  2363. //information
  2364. if(NULL != CertImportInfo.hSrcStore)
  2365. {
  2366. //make sure that the destination store has the right content
  2367. if(!CheckForContent(CertImportInfo.hSrcStore, dwFlags, FALSE, &idsContent))
  2368. {
  2369. ids=idsContent;
  2370. goto InvalidArgErr;
  2371. }
  2372. }
  2373. else
  2374. {
  2375. //check for the PFX
  2376. if(TRUE == CertImportInfo.fPFX)
  2377. {
  2378. //PFX blob only contains certificates
  2379. if(0==((CertImportInfo.dwFlag) & CRYPTUI_WIZ_IMPORT_ALLOW_CERT))
  2380. {
  2381. ids=IDS_IMPORT_OBJECT_NOT_EXPECTED;
  2382. goto InvalidArgErr;
  2383. }
  2384. }
  2385. }
  2386. //set the destination store if supplied
  2387. if(hDestCertStore)
  2388. {
  2389. CertImportInfo.hDesStore=hDestCertStore;
  2390. CertImportInfo.fFreeDesStore=FALSE;
  2391. CertImportInfo.fKnownDes=TRUE;
  2392. CertImportInfo.fSelectedDesStore=TRUE;
  2393. }
  2394. else
  2395. {
  2396. CertImportInfo.fKnownDes=FALSE;
  2397. CertImportInfo.fSelectedDesStore=FALSE;
  2398. }
  2399. //supply the UI work
  2400. if((dwFlags & CRYPTUI_WIZ_NO_UI) == 0)
  2401. {
  2402. //set up the fonts
  2403. if(!SetupFonts(g_hmodThisDll,
  2404. NULL,
  2405. &(CertImportInfo.hBigBold),
  2406. &(CertImportInfo.hBold)))
  2407. goto Win32Err;
  2408. //init the common control
  2409. if(!WizardInit(TRUE) ||
  2410. (sizeof(rgImportPageInfo)/sizeof(rgImportPageInfo[0])!=IMPORT_PROP_SHEET)
  2411. )
  2412. goto InvalidArgErr;
  2413. //set up the property sheet and the property header
  2414. dwPropCount=0;
  2415. for(dwIndex=0; dwIndex<IMPORT_PROP_SHEET; dwIndex++)
  2416. {
  2417. if(pImportSubject)
  2418. {
  2419. //skip the IDD_IMPORT_FILE page if subject is known and it is not
  2420. //a fileName
  2421. if(((1==dwIndex) || (2==dwIndex)) &&
  2422. (NULL==CertImportInfo.pwszFileName) &&
  2423. (CertImportInfo.hSrcStore)
  2424. )
  2425. continue;
  2426. //or, if this is a PKCS7 file name, we skip the file name
  2427. //page. This is strictly for UI freeze.
  2428. if(((1==dwIndex) || (2==dwIndex)) &&
  2429. (CertImportInfo.pwszFileName)&&
  2430. (CERT_QUERY_CONTENT_PKCS7_SIGNED == CertImportInfo.dwContentType)
  2431. )
  2432. continue;
  2433. }
  2434. rgImportSheet[dwPropCount].dwSize=sizeof(rgImportSheet[dwPropCount]);
  2435. if(pwszWizardTitle)
  2436. rgImportSheet[dwPropCount].dwFlags=PSP_USETITLE;
  2437. else
  2438. rgImportSheet[dwPropCount].dwFlags=0;
  2439. rgImportSheet[dwPropCount].hInstance=g_hmodThisDll;
  2440. rgImportSheet[dwPropCount].pszTemplate=rgImportPageInfo[dwIndex].pszTemplate;
  2441. if(pwszWizardTitle)
  2442. {
  2443. rgImportSheet[dwPropCount].pszTitle=pwszWizardTitle;
  2444. }
  2445. else
  2446. rgImportSheet[dwPropCount].pszTitle=NULL;
  2447. rgImportSheet[dwPropCount].pfnDlgProc=rgImportPageInfo[dwIndex].pfnDlgProc;
  2448. rgImportSheet[dwPropCount].lParam=(LPARAM)&CertImportInfo;
  2449. dwPropCount++;
  2450. }
  2451. //set up the header information
  2452. importHeader.dwSize=sizeof(importHeader);
  2453. importHeader.dwFlags=PSH_PROPSHEETPAGE | PSH_WIZARD | PSH_NOAPPLYNOW;
  2454. importHeader.hwndParent=hwndParent;
  2455. importHeader.hInstance=g_hmodThisDll;
  2456. if(pwszWizardTitle)
  2457. importHeader.pszCaption=pwszWizardTitle;
  2458. else
  2459. {
  2460. if(LoadStringU(g_hmodThisDll, IDS_IMPORT_WIZARD_TITLE, wszTitle, sizeof(wszTitle)/sizeof(wszTitle[0])))
  2461. importHeader.pszCaption=wszTitle;
  2462. }
  2463. importHeader.nPages=dwPropCount;
  2464. importHeader.nStartPage=0;
  2465. importHeader.ppsp=rgImportSheet;
  2466. //no need to create the wizard if there are only 2 pages:
  2467. //Welcome and Confirmation
  2468. if(dwPropCount > 2)
  2469. {
  2470. //create the wizard
  2471. iReturn=PropertySheetU(&importHeader);
  2472. if(-1 == iReturn)
  2473. goto Win32Err;
  2474. if(0 == iReturn)
  2475. {
  2476. fResult=TRUE;
  2477. //no need to say anything if the wizard is cancelled
  2478. ids=0;
  2479. goto CommonReturn;
  2480. }
  2481. }
  2482. }
  2483. //Open the destination store for PFX file
  2484. if(TRUE == CertImportInfo.fPFX)
  2485. {
  2486. // if the caller specified local machine then set the appropriate flag
  2487. if (dwFlags & CRYPTUI_WIZ_IMPORT_TO_LOCALMACHINE)
  2488. {
  2489. CertImportInfo.dwPasswordFlags |= CRYPT_MACHINE_KEYSET;
  2490. }
  2491. else if ((dwFlags & CRYPTUI_WIZ_IMPORT_TO_CURRENTUSER) ||
  2492. (hDestCertStore == NULL))
  2493. {
  2494. CertImportInfo.dwPasswordFlags |= CRYPT_USER_KEYSET;
  2495. }
  2496. CertImportInfo.hSrcStore=
  2497. PFXImportCertStore(
  2498. (CRYPT_DATA_BLOB *)&(CertImportInfo.blobData),
  2499. CertImportInfo.pwszPassword,
  2500. CertImportInfo.dwPasswordFlags);
  2501. if(CertImportInfo.hSrcStore)
  2502. {
  2503. //remember to free the Src store
  2504. CertImportInfo.fFreeSrcStore=TRUE;
  2505. CertImportInfo.fKnownSrc=TRUE;
  2506. }
  2507. else
  2508. {
  2509. DWORD dwLastError = GetLastError();
  2510. if (dwLastError == ERROR_UNSUPPORTED_TYPE)
  2511. {
  2512. ids=IDS_UNSUPPORTED_KEY;
  2513. }
  2514. else if (dwLastError == CRYPT_E_BAD_ENCODE)
  2515. {
  2516. ids=IDS_BAD_ENCODE;
  2517. }
  2518. //DSIE: Bug 22752
  2519. else if (dwLastError == ERROR_CANCELLED)
  2520. {
  2521. ids=IDS_IMPORT_FAIL_MOVE_CONTENT;
  2522. }
  2523. else
  2524. {
  2525. ids=IDS_IMPORT_FAIL_FIND_CONTENT;
  2526. }
  2527. goto InvalidArgErr;
  2528. }
  2529. //make sure the PFX blob is not empty
  2530. if(!CheckForContent(CertImportInfo.hSrcStore, dwFlags, FALSE, &idsContent))
  2531. {
  2532. ids=idsContent;
  2533. goto InvalidArgErr;
  2534. }
  2535. }
  2536. //make sure the source store is a valid value
  2537. if(NULL==(CertImportInfo.hSrcStore))
  2538. {
  2539. ids=IDS_IMPORT_FAIL_FIND_CONTENT;
  2540. goto InvalidArgErr;
  2541. }
  2542. //do the import work. Return a status
  2543. //we disable the parent window in case the root dialogue will show up
  2544. //this is to prevent re-entrency
  2545. if(hwndParent)
  2546. {
  2547. EnableWindow(hwndParent,FALSE);
  2548. }
  2549. if(S_OK !=(hr=I_ImportCertificate(&CertImportInfo, &ids)))
  2550. {
  2551. if(hwndParent)
  2552. {
  2553. EnableWindow(hwndParent,TRUE);
  2554. }
  2555. goto I_ImportErr;
  2556. }
  2557. if(hwndParent)
  2558. {
  2559. EnableWindow(hwndParent,TRUE);
  2560. }
  2561. fResult=TRUE;
  2562. CommonReturn:
  2563. //preserve the last error
  2564. dwError=GetLastError();
  2565. //pop up the confirmation box for failure
  2566. if(ids && ((dwFlags & CRYPTUI_WIZ_NO_UI) ==0))
  2567. {
  2568. //set the message of inable to gather enough info for PKCS10
  2569. if(IDS_IMPORT_SUCCEEDED == ids)
  2570. I_MessageBox(hwndParent, ids, IDS_IMPORT_WIZARD_TITLE,
  2571. NULL, MB_OK|MB_ICONINFORMATION);
  2572. else
  2573. {
  2574. if(IDS_IMPORT_PFX_EMPTY == ids)
  2575. I_MessageBox(hwndParent, ids, IDS_IMPORT_WIZARD_TITLE,
  2576. NULL, MB_OK|MB_ICONWARNING);
  2577. else
  2578. I_MessageBox(hwndParent, ids, IDS_IMPORT_WIZARD_TITLE,
  2579. NULL, MB_OK|MB_ICONERROR);
  2580. }
  2581. if(IDS_IMPORT_DUPLICATE == ids)
  2582. {
  2583. //remark the success case
  2584. I_MessageBox(hwndParent, IDS_IMPORT_SUCCEEDED, IDS_IMPORT_WIZARD_TITLE,
  2585. NULL, MB_OK|MB_ICONINFORMATION);
  2586. }
  2587. }
  2588. //destroy the hFont object
  2589. DestroyFonts(CertImportInfo.hBigBold,
  2590. CertImportInfo.hBold);
  2591. if(CertImportInfo.pwszFileName && (TRUE==CertImportInfo.fFreeFileName))
  2592. WizardFree(CertImportInfo.pwszFileName);
  2593. /* if(CertImportInfo.pwszDefaultStoreName)
  2594. WizardFree(CertImportInfo.pwszDefaultStoreName); */
  2595. if(CertImportInfo.hDesStore && (TRUE==CertImportInfo.fFreeDesStore))
  2596. CertCloseStore(CertImportInfo.hDesStore, 0);
  2597. if(CertImportInfo.hSrcStore && (TRUE==CertImportInfo.fFreeSrcStore))
  2598. CertCloseStore(CertImportInfo.hSrcStore, 0);
  2599. if(CertImportInfo.blobData.pbData)
  2600. UnmapViewOfFile(CertImportInfo.blobData.pbData);
  2601. if(CertImportInfo.pwszPassword)
  2602. {
  2603. SecureZeroMemory(CertImportInfo.pwszPassword, lstrlenW(CertImportInfo.pwszPassword) * sizeof(WCHAR));
  2604. WizardFree(CertImportInfo.pwszPassword);
  2605. }
  2606. if(hTempStore)
  2607. CertCloseStore(hTempStore, 0);
  2608. //reset the error
  2609. SetLastError(dwError);
  2610. return fResult;
  2611. ErrorReturn:
  2612. fResult=FALSE;
  2613. goto CommonReturn;
  2614. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  2615. TRACE_ERROR(CertOpenStoreErr);
  2616. SET_ERROR_VAR(ReadFromFileErr, hr);
  2617. TRACE_ERROR(AddCertErr);
  2618. TRACE_ERROR(Crypt32Err);
  2619. TRACE_ERROR(Win32Err);
  2620. SET_ERROR_VAR(I_ImportErr, hr);
  2621. }
  2622. //****************************************************************************
  2623. // Helper functions for import wizards
  2624. //
  2625. //*****************************************************************************
  2626. BOOL InstallViaXEnroll(CERT_IMPORT_INFO *pCertImportInfo)
  2627. {
  2628. BOOL fResult=FALSE;
  2629. IEnroll2 *pIEnroll2=NULL;
  2630. PFNPIEnroll2GetNoCOM pfnPIEnroll2GetNoCOM=NULL;
  2631. CRYPT_DATA_BLOB DataBlob;
  2632. PCCERT_CONTEXT pCert=NULL;
  2633. if(NULL == pCertImportInfo)
  2634. goto CLEANUP;
  2635. DataBlob.cbData=pCertImportInfo->blobData.cbData;
  2636. DataBlob.pbData=pCertImportInfo->blobData.pbData;
  2637. if((0 == DataBlob.cbData) || (NULL == DataBlob.pbData))
  2638. {
  2639. //this is a certificate case. Get the blob for the cert
  2640. if(NULL==pCertImportInfo->hSrcStore)
  2641. goto CLEANUP;
  2642. if(!(pCert=CertEnumCertificatesInStore(pCertImportInfo->hSrcStore, NULL)))
  2643. goto CLEANUP;
  2644. DataBlob.cbData=pCert->cbCertEncoded;
  2645. DataBlob.pbData=pCert->pbCertEncoded;
  2646. }
  2647. //load the library "xEnroll.dll".
  2648. if(NULL==g_hmodxEnroll)
  2649. {
  2650. if(NULL==(g_hmodxEnroll=LoadLibrary("xenroll.dll")))
  2651. {
  2652. goto CLEANUP;
  2653. }
  2654. }
  2655. //get the address for PIEnroll2GetNoCOM()
  2656. if(NULL==(pfnPIEnroll2GetNoCOM=(PFNPIEnroll2GetNoCOM)GetProcAddress(g_hmodxEnroll,
  2657. "PIEnroll2GetNoCOM")))
  2658. goto CLEANUP;
  2659. if(NULL==(pIEnroll2=pfnPIEnroll2GetNoCOM()))
  2660. goto CLEANUP;
  2661. //specify the destiniation store if user has specified one
  2662. if(pCertImportInfo->hDesStore && (TRUE==pCertImportInfo->fSelectedDesStore))
  2663. {
  2664. if(S_OK != (pIEnroll2->SetHStoreMy(pCertImportInfo->hDesStore)))
  2665. goto CLEANUP;
  2666. if(S_OK != (pIEnroll2->SetHStoreCA(pCertImportInfo->hDesStore)))
  2667. goto CLEANUP;
  2668. if(S_OK != (pIEnroll2->SetHStoreROOT(pCertImportInfo->hDesStore)))
  2669. goto CLEANUP;
  2670. }
  2671. if(S_OK != (pIEnroll2->acceptPKCS7Blob(&DataBlob)))
  2672. goto CLEANUP;
  2673. fResult=TRUE;
  2674. CLEANUP:
  2675. if(pIEnroll2)
  2676. pIEnroll2->Release();
  2677. if(pCert)
  2678. CertFreeCertificateContext(pCert);
  2679. return fResult;
  2680. }
  2681. //--------------------------------------------------------------------------------
  2682. //
  2683. // The import routine that does the work
  2684. //
  2685. //---------------------------------------------------------------------------------
  2686. HRESULT I_ImportCertificate(CERT_IMPORT_INFO * pCertImportInfo,
  2687. UINT * pidsStatus)
  2688. {
  2689. UINT idsStatus=0;
  2690. HCERTSTORE hMyStore=NULL;
  2691. HCERTSTORE hCAStore=NULL;
  2692. HCERTSTORE hTrustStore=NULL;
  2693. HCERTSTORE hRootStore=NULL;
  2694. HCERTSTORE hAddressBookStore=NULL;
  2695. HCERTSTORE hTrustedPeopleStore=NULL;
  2696. HCERTSTORE hCertStore=NULL;
  2697. PCCERT_CONTEXT pCertContext=NULL;
  2698. PCCERT_CONTEXT pCertPre=NULL;
  2699. PCCERT_CONTEXT pFindCert=NULL;
  2700. DWORD dwData=0;
  2701. DWORD dwCertOpenStoreFlags;
  2702. //DSIE: Bug 22633.
  2703. BOOL bCancelled = FALSE;
  2704. DWORD dwError = 0;
  2705. if (NULL == pCertImportInfo || NULL == pidsStatus)
  2706. return E_INVALIDARG;
  2707. if (NULL == pCertImportInfo->hSrcStore)
  2708. {
  2709. *pidsStatus = IDS_IMPORT_FAIL_FIND_CONTENT;
  2710. return E_FAIL;
  2711. }
  2712. if (pCertImportInfo->fPFX && (pCertImportInfo->dwFlag & CRYPTUI_WIZ_IMPORT_TO_LOCALMACHINE))
  2713. {
  2714. dwCertOpenStoreFlags = CERT_SYSTEM_STORE_LOCAL_MACHINE;
  2715. }
  2716. else
  2717. {
  2718. dwCertOpenStoreFlags = CERT_SYSTEM_STORE_CURRENT_USER;
  2719. }
  2720. // If the content type is PKS7 and use pass in or select a file name.
  2721. // We try to use xEnroll to accept it as an enrollment response.
  2722. if ((CERT_QUERY_CONTENT_PKCS7_SIGNED == pCertImportInfo->dwContentType) ||
  2723. (CERT_QUERY_CONTENT_CERT == pCertImportInfo->dwContentType))
  2724. {
  2725. if (InstallViaXEnroll(pCertImportInfo))
  2726. {
  2727. *pidsStatus = IDS_IMPORT_SUCCEEDED;
  2728. return S_OK;
  2729. }
  2730. }
  2731. // Do a store copy if hDesStore is selected.
  2732. if (pCertImportInfo->hDesStore && pCertImportInfo->fSelectedDesStore)
  2733. {
  2734. dwError = MoveItem(pCertImportInfo, pidsStatus);
  2735. goto CLEANUP;
  2736. }
  2737. // We need to find a correct store on user's behalf.
  2738. // Put the CTLs in the trust store.
  2739. if (!(hTrustStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
  2740. g_dwMsgAndCertEncodingType,
  2741. NULL,
  2742. dwCertOpenStoreFlags,
  2743. L"trust")))
  2744. {
  2745. dwError = GetLastError();
  2746. *pidsStatus = IDS_FAIL_OPEN_TRUST;
  2747. goto CLEANUP;
  2748. }
  2749. if (0 != (dwError = AddCTLsToStore(pCertImportInfo->hwndParent,
  2750. pCertImportInfo->hSrcStore,
  2751. hTrustStore,
  2752. pCertImportInfo->dwFlag & CRYPTUI_WIZ_NO_UI ? TRUE : FALSE,
  2753. pidsStatus)))
  2754. {
  2755. goto CLEANUP;
  2756. }
  2757. // Put CRL in the CA store.
  2758. if (!(hCAStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
  2759. g_dwMsgAndCertEncodingType,
  2760. NULL,
  2761. dwCertOpenStoreFlags,
  2762. L"ca")))
  2763. {
  2764. dwError = GetLastError();
  2765. *pidsStatus = IDS_FAIL_OPEN_CA;
  2766. goto CLEANUP;
  2767. }
  2768. if (0 != (dwError = AddCRLsToStore(pCertImportInfo->hwndParent,
  2769. pCertImportInfo->hSrcStore,
  2770. hCAStore,
  2771. pCertImportInfo->dwFlag & CRYPTUI_WIZ_NO_UI ? TRUE : FALSE,
  2772. pidsStatus)))
  2773. {
  2774. goto CLEANUP;
  2775. }
  2776. // Add the certificate with private key to my store; and the rest
  2777. // to the ca, root, or addressbook store.
  2778. while (pCertContext = CertEnumCertificatesInStore(pCertImportInfo->hSrcStore, pCertPre))
  2779. {
  2780. // Check if the certificate has the property on it.
  2781. // Make sure the private key matches the certificate
  2782. // Search for both machine key and user keys
  2783. if (CertGetCertificateContextProperty(pCertContext,
  2784. CERT_KEY_PROV_INFO_PROP_ID,
  2785. NULL, &dwData) &&
  2786. CryptFindCertificateKeyProvInfo(pCertContext,
  2787. 0,
  2788. NULL))
  2789. {
  2790. // Open my store if necessary.
  2791. if (!hMyStore)
  2792. {
  2793. if (!(hMyStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
  2794. g_dwMsgAndCertEncodingType,
  2795. NULL,
  2796. dwCertOpenStoreFlags,
  2797. L"my")))
  2798. {
  2799. dwError = GetLastError();
  2800. *pidsStatus = IDS_FAIL_OPEN_MY;
  2801. goto CLEANUP;
  2802. }
  2803. }
  2804. hCertStore = hMyStore;
  2805. }
  2806. // See if the certificate is self-signed.
  2807. // If it is selfsigned, goes to the root store
  2808. else if (TrustIsCertificateSelfSigned(pCertContext,
  2809. pCertContext->dwCertEncodingType,
  2810. 0))
  2811. {
  2812. // DSIE: Bug 375649.
  2813. // If EFS only cert, put it in TrustedPeople for self-signed cert,
  2814. // otherwise, go to the root store.
  2815. //
  2816. if (IsEFSOnly(pCertContext))
  2817. {
  2818. // Open the TrustedPeople store if necessary.
  2819. if (!hTrustedPeopleStore)
  2820. {
  2821. if (!(hTrustedPeopleStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
  2822. g_dwMsgAndCertEncodingType,
  2823. NULL,
  2824. dwCertOpenStoreFlags,
  2825. L"trustedpeople")))
  2826. {
  2827. dwError = GetLastError();
  2828. *pidsStatus = IDS_FAIL_OPEN_TRUSTEDPEOPLE;
  2829. goto CLEANUP;
  2830. }
  2831. }
  2832. hCertStore = hTrustedPeopleStore;
  2833. }
  2834. else
  2835. {
  2836. // Open the root store if necessary.
  2837. if (!hRootStore)
  2838. {
  2839. if (!(hRootStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
  2840. g_dwMsgAndCertEncodingType,
  2841. NULL,
  2842. dwCertOpenStoreFlags,
  2843. L"root")))
  2844. {
  2845. dwError = GetLastError();
  2846. *pidsStatus = IDS_FAIL_OPEN_ROOT;
  2847. goto CLEANUP;
  2848. }
  2849. }
  2850. hCertStore = hRootStore;
  2851. }
  2852. }
  2853. // Go to ca store if for ca cert, otherwise go to addressbook (other people) store.
  2854. else if (IsCACert(pCertContext))
  2855. {
  2856. // Open the ca store if necessary.
  2857. if (!hCertStore)
  2858. {
  2859. if (!(hCAStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
  2860. g_dwMsgAndCertEncodingType,
  2861. NULL,
  2862. dwCertOpenStoreFlags,
  2863. L"ca")))
  2864. {
  2865. dwError = GetLastError();
  2866. *pidsStatus = IDS_FAIL_OPEN_CA;
  2867. goto CLEANUP;
  2868. }
  2869. }
  2870. hCertStore = hCAStore;
  2871. }
  2872. else
  2873. {
  2874. // Open the other people store if necessary.
  2875. if (!hAddressBookStore)
  2876. {
  2877. if(!(hAddressBookStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
  2878. g_dwMsgAndCertEncodingType,
  2879. NULL,
  2880. dwCertOpenStoreFlags,
  2881. L"addressbook")))
  2882. {
  2883. dwError = GetLastError();
  2884. *pidsStatus = IDS_FAIL_OPEN_ADDRESSBOOK;
  2885. goto CLEANUP;
  2886. }
  2887. }
  2888. hCertStore = hAddressBookStore;
  2889. }
  2890. //DSIE: Bug 22633.
  2891. bCancelled = FALSE;
  2892. if (0 != (dwError = AddContextToStore(CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_CONTEXT,
  2893. pCertImportInfo->hwndParent,
  2894. (PVOID) pCertContext,
  2895. pCertImportInfo->dwFlag & CRYPTUI_WIZ_NO_UI ? TRUE : FALSE,
  2896. hCertStore)))
  2897. {
  2898. if (ERROR_CANCELLED == dwError)
  2899. {
  2900. bCancelled = TRUE;
  2901. }
  2902. else
  2903. {
  2904. // Check to see if there is alreay a read-only duplicated copy in the store?
  2905. // If so, ignore the error.
  2906. if (pFindCert = CertFindCertificateInStore(hCertStore,
  2907. g_dwMsgAndCertEncodingType,
  2908. 0,
  2909. CERT_FIND_EXISTING,
  2910. pCertContext,
  2911. NULL))
  2912. {
  2913. CertFreeCertificateContext(pFindCert);
  2914. pFindCert = NULL;
  2915. }
  2916. else if (hCertStore == hMyStore)
  2917. {
  2918. *pidsStatus = IDS_FAIL_ADD_CERT_MY;
  2919. goto CLEANUP;
  2920. }
  2921. else if (hCertStore == hRootStore)
  2922. {
  2923. *pidsStatus = IDS_FAIL_ADD_CERT_ROOT;
  2924. goto CLEANUP;
  2925. }
  2926. else if (hCertStore == hCAStore)
  2927. {
  2928. *pidsStatus = IDS_FAIL_ADD_CERT_CA;
  2929. goto CLEANUP;
  2930. }
  2931. else if (hCertStore == hAddressBookStore)
  2932. {
  2933. *pidsStatus = IDS_FAIL_ADD_CERT_OTHERPEOPLE;
  2934. goto CLEANUP;
  2935. }
  2936. else if (hCertStore == hTrustedPeopleStore)
  2937. {
  2938. *pidsStatus = IDS_FAIL_ADD_CERT_TRUSTEDPEOPLE;
  2939. goto CLEANUP;
  2940. }
  2941. }
  2942. dwError = 0;
  2943. }
  2944. pCertPre = pCertContext;
  2945. }
  2946. if (bCancelled)
  2947. {
  2948. dwError = ERROR_CANCELLED;
  2949. *pidsStatus = IDS_IMPORT_CANCELLED;
  2950. }
  2951. else
  2952. {
  2953. *pidsStatus = IDS_IMPORT_SUCCEEDED;
  2954. }
  2955. CLEANUP:
  2956. if(pCertContext)
  2957. CertFreeCertificateContext(pCertContext);
  2958. if(hMyStore)
  2959. CertCloseStore(hMyStore, 0);
  2960. if(hCAStore)
  2961. CertCloseStore(hCAStore, 0);
  2962. if(hTrustStore)
  2963. CertCloseStore(hTrustStore, 0);
  2964. if(hRootStore)
  2965. CertCloseStore(hRootStore, 0);
  2966. if(hAddressBookStore)
  2967. CertCloseStore(hAddressBookStore, 0);
  2968. if(hTrustedPeopleStore)
  2969. CertCloseStore(hTrustedPeopleStore, 0);
  2970. return HRESULT_FROM_WIN32(dwError);
  2971. }
  2972. //--------------------------------------------------------------------------------
  2973. //
  2974. //get the bytes from the file name
  2975. //
  2976. //---------------------------------------------------------------------------------
  2977. HRESULT RetrieveBLOBFromFile(LPWSTR pwszFileName,DWORD *pcb,BYTE **ppb)
  2978. {
  2979. HRESULT hr=E_FAIL;
  2980. HANDLE hFile=NULL;
  2981. HANDLE hFileMapping=NULL;
  2982. DWORD cbData=0;
  2983. BYTE *pbData=0;
  2984. DWORD cbHighSize=0;
  2985. if(!pcb || !ppb || !pwszFileName)
  2986. return E_INVALIDARG;
  2987. *ppb=NULL;
  2988. *pcb=0;
  2989. if ((hFile = ExpandAndCreateFileU(pwszFileName,
  2990. GENERIC_READ,
  2991. FILE_SHARE_READ,
  2992. NULL, // lpsa
  2993. OPEN_EXISTING,
  2994. FILE_ATTRIBUTE_NORMAL,
  2995. NULL)) == INVALID_HANDLE_VALUE)
  2996. {
  2997. hr=HRESULT_FROM_WIN32(GetLastError());
  2998. goto CLEANUP;
  2999. }
  3000. if((cbData = GetFileSize(hFile, &cbHighSize)) == 0xffffffff)
  3001. {
  3002. hr=HRESULT_FROM_WIN32(GetLastError());
  3003. goto CLEANUP;
  3004. }
  3005. //we do not handle file more than 4G bytes
  3006. if(cbHighSize != 0)
  3007. {
  3008. hr=E_FAIL;
  3009. goto CLEANUP;
  3010. }
  3011. //create a file mapping object
  3012. if(NULL == (hFileMapping=CreateFileMapping(
  3013. hFile,
  3014. NULL,
  3015. PAGE_READONLY,
  3016. 0,
  3017. 0,
  3018. NULL)))
  3019. {
  3020. hr=HRESULT_FROM_WIN32(GetLastError());
  3021. goto CLEANUP;
  3022. }
  3023. //create a view of the file
  3024. if(NULL == (pbData=(BYTE *)MapViewOfFile(
  3025. hFileMapping,
  3026. FILE_MAP_READ,
  3027. 0,
  3028. 0,
  3029. cbData)))
  3030. {
  3031. hr=HRESULT_FROM_WIN32(GetLastError());
  3032. goto CLEANUP;
  3033. }
  3034. hr=S_OK;
  3035. *pcb=cbData;
  3036. *ppb=pbData;
  3037. CLEANUP:
  3038. if(hFile)
  3039. CloseHandle(hFile);
  3040. if(hFileMapping)
  3041. CloseHandle(hFileMapping);
  3042. return hr;
  3043. }