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.

1636 lines
56 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1995 - 1996
  6. //
  7. // File: tstore.cpp
  8. //
  9. // Contents: Cert Store API Tests
  10. //
  11. // See Usage() for list of test options.
  12. //
  13. //
  14. // Functions: main
  15. //
  16. // History: 04-Mar-96 philh created
  17. // 07-Jun-96 HelleS Added printing the command line
  18. // 20-Aug-96 jeffspel name changes
  19. //
  20. //--------------------------------------------------------------------------
  21. #include <windows.h>
  22. #include <assert.h>
  23. #include "wincrypt.h"
  24. #include "certtest.h"
  25. #include "crypthlp.h"
  26. #include <stdlib.h>
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <memory.h>
  30. #include <time.h>
  31. //
  32. // FIsWinNT: check OS type on x86. On non-x86, assume WinNT
  33. //
  34. #ifdef _M_IX86
  35. static BOOL WINAPI FIsWinNT(void) {
  36. static BOOL fIKnow = FALSE;
  37. static BOOL fIsWinNT = FALSE;
  38. OSVERSIONINFO osVer;
  39. if(fIKnow)
  40. return(fIsWinNT);
  41. memset(&osVer, 0, sizeof(OSVERSIONINFO));
  42. osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  43. if( GetVersionEx(&osVer) )
  44. fIsWinNT = (osVer.dwPlatformId == VER_PLATFORM_WIN32_NT);
  45. // even on an error, this is as good as it gets
  46. fIKnow = TRUE;
  47. return(fIsWinNT);
  48. }
  49. #else
  50. static BOOL WINAPI FIsWinNT(void) {
  51. return(TRUE);
  52. }
  53. #endif
  54. static void PrintExpectedError(LPCSTR pszMsg)
  55. {
  56. DWORD dwErr = GetLastError();
  57. printf("%s got expected error => 0x%x (%d) \n", pszMsg, dwErr, dwErr);
  58. }
  59. void PrintNoError(LPCSTR pszMsg)
  60. {
  61. printf("%s failed => expected error\n", pszMsg);
  62. }
  63. static BOOL AddCert(HCERTSTORE hStore, LPSTR pszAddFilename,
  64. DWORD dwAddDisposition, BOOL fExpectError)
  65. {
  66. BYTE *pbEncoded;
  67. DWORD cbEncoded;
  68. BOOL fResult;
  69. PCCERT_CONTEXT pCert = NULL;
  70. if (!ReadDERFromFile(pszAddFilename, &pbEncoded, &cbEncoded)) {
  71. PrintLastError("AddCert");
  72. return FALSE;
  73. }
  74. fResult = FALSE;
  75. if (!CertAddEncodedCertificateToStore(hStore, dwCertEncodingType,
  76. pbEncoded, cbEncoded, dwAddDisposition, &pCert)) {
  77. if (fExpectError)
  78. PrintExpectedError("CertAddEncodedCertificateToStore");
  79. else
  80. PrintLastError("CertAddEncodedCertificateToStore");
  81. } else {
  82. if (fExpectError)
  83. PrintNoError("CertAddEncodedCertificateToStore");
  84. else
  85. fResult = TRUE;
  86. printf("===== Added Cert =====\n");
  87. DisplayCert(pCert, 0, 0);
  88. CertFreeCertificateContext(pCert);
  89. }
  90. TestFree(pbEncoded);
  91. return fResult;
  92. }
  93. static BOOL ReadCert(
  94. HCERTSTORE hStore,
  95. LPSTR pszReadFilename,
  96. DWORD dwDisplayFlags)
  97. {
  98. BOOL fResult;
  99. BYTE *pbEncoded;
  100. DWORD cbEncoded;
  101. PCCERT_CONTEXT pCert;
  102. if (!ReadDERFromFile(pszReadFilename, &pbEncoded, &cbEncoded)) {
  103. PrintLastError("ReadCert");
  104. return FALSE;
  105. }
  106. pCert = CertCreateCertificateContext(
  107. dwCertEncodingType,
  108. pbEncoded,
  109. cbEncoded
  110. );
  111. if (pCert == NULL) {
  112. fResult = FALSE;
  113. PrintLastError("CertCreateCertificateContext");
  114. } else {
  115. fResult = TRUE;
  116. DisplayCert2(hStore, pCert, dwDisplayFlags);
  117. CertFreeCertificateContext(pCert);
  118. }
  119. TestFree(pbEncoded);
  120. return fResult;
  121. }
  122. // Attempt to read as a file containing an embedded PKCS#7 via SIP
  123. static HCERTSTORE OpenSIPStoreFile(
  124. LPSTR pszStoreFilename)
  125. {
  126. HCERTSTORE hStore = NULL;
  127. LPWSTR pwszStoreFilename = NULL;
  128. CRYPT_DATA_BLOB SignedData;
  129. memset(&SignedData, 0, sizeof(SignedData));
  130. DWORD dwGetEncodingType;
  131. GUID gSubject;
  132. SIP_DISPATCH_INFO SipDispatch;
  133. SIP_SUBJECTINFO SubjectInfo;
  134. if (NULL == (pwszStoreFilename = AllocAndSzToWsz(pszStoreFilename)))
  135. goto CommonReturn;
  136. if (!CryptSIPRetrieveSubjectGuid(
  137. pwszStoreFilename,
  138. NULL, // hFile
  139. &gSubject)) goto CommonReturn;
  140. memset(&SipDispatch, 0, sizeof(SipDispatch));
  141. SipDispatch.cbSize = sizeof(SipDispatch);
  142. if (!CryptSIPLoad(
  143. &gSubject,
  144. 0, // dwFlags
  145. &SipDispatch)) goto CommonReturn;
  146. memset(&SubjectInfo, 0, sizeof(SubjectInfo));
  147. SubjectInfo.cbSize = sizeof(SubjectInfo);
  148. SubjectInfo.pgSubjectType = (GUID*) &gSubject;
  149. SubjectInfo.hFile = INVALID_HANDLE_VALUE;
  150. SubjectInfo.pwsFileName = pwszStoreFilename;
  151. // SubjectInfo.pwsDisplayName =
  152. // SubjectInfo.lpSIPInfo =
  153. // SubjectInfo.dwReserved =
  154. // SubjectInfo.hProv =
  155. // SubjectInfo.DigestAlgorithm =
  156. // SubjectInfo.dwFlags =
  157. SubjectInfo.dwEncodingType = dwMsgAndCertEncodingType;
  158. // SubjectInfo.lpAddInfo =
  159. if (!SipDispatch.pfGet(
  160. &SubjectInfo,
  161. &dwGetEncodingType,
  162. 0, // dwIndex
  163. &SignedData.cbData,
  164. NULL // pbSignedData
  165. ) || 0 == SignedData.cbData)
  166. goto CommonReturn;
  167. if (NULL == (SignedData.pbData = (BYTE *) TestAlloc(SignedData.cbData)))
  168. goto CommonReturn;
  169. if (!SipDispatch.pfGet(
  170. &SubjectInfo,
  171. &dwGetEncodingType,
  172. 0, // dwIndex
  173. &SignedData.cbData,
  174. SignedData.pbData
  175. ))
  176. goto CommonReturn;
  177. hStore = CertOpenStore(
  178. CERT_STORE_PROV_PKCS7,
  179. dwMsgAndCertEncodingType,
  180. 0, // hCryptProv
  181. 0, // dwFlags
  182. (const void *) &SignedData
  183. );
  184. if (hStore) {
  185. WCHAR wszGUID[128];
  186. StringFromGUID2(gSubject, wszGUID, 128);
  187. printf("Opening Store as SIP Subject GUID:: %S \n", wszGUID);
  188. }
  189. CommonReturn:
  190. TestFree(pwszStoreFilename);
  191. TestFree(SignedData.pbData);
  192. return hStore;
  193. }
  194. static HCERTSTORE OpenCertStoreFile(
  195. LPSTR pszStoreFilename)
  196. {
  197. HCERTSTORE hStore;
  198. if (hStore = OpenSIPStoreFile(pszStoreFilename))
  199. return hStore;
  200. return NULL;
  201. }
  202. static BOOL AddCrl(HCERTSTORE hStore, LPSTR pszAddFilename,
  203. DWORD dwAddDisposition, BOOL fExpectError)
  204. {
  205. BYTE *pbEncoded;
  206. DWORD cbEncoded;
  207. BOOL fResult;
  208. PCCRL_CONTEXT pCrl = NULL;
  209. if (!ReadDERFromFile(pszAddFilename, &pbEncoded, &cbEncoded)) {
  210. PrintLastError("AddCrl");
  211. return FALSE;
  212. }
  213. fResult = FALSE;
  214. if (!CertAddEncodedCRLToStore(hStore, dwCertEncodingType, pbEncoded,
  215. cbEncoded, dwAddDisposition, &pCrl)) {
  216. if (fExpectError)
  217. PrintExpectedError("CertAddEncodedCRLToStore");
  218. else
  219. PrintLastError("CertAddEncodedCRLToStore");
  220. } else {
  221. if (fExpectError)
  222. PrintNoError("CertAddEncodedCRLToStore");
  223. else
  224. fResult = TRUE;
  225. printf("===== Added CRL =====\n");
  226. DisplayCrl(pCrl, 0);
  227. CertFreeCRLContext(pCrl);
  228. }
  229. TestFree(pbEncoded);
  230. return fResult;
  231. }
  232. static BOOL ReadCrl(
  233. LPSTR pszReadFilename,
  234. DWORD dwDisplayFlags)
  235. {
  236. BOOL fResult;
  237. BYTE *pbEncoded;
  238. DWORD cbEncoded;
  239. PCCRL_CONTEXT pCrl;
  240. if (!ReadDERFromFile(pszReadFilename, &pbEncoded, &cbEncoded)) {
  241. PrintLastError("ReadCrl");
  242. return FALSE;
  243. }
  244. pCrl = CertCreateCRLContext(
  245. dwCertEncodingType,
  246. pbEncoded,
  247. cbEncoded
  248. );
  249. if (pCrl == NULL) {
  250. fResult = FALSE;
  251. PrintLastError("CertCreateCRLContext");
  252. } else {
  253. fResult = TRUE;
  254. DisplayCrl(pCrl, dwDisplayFlags);
  255. CertFreeCRLContext(pCrl);
  256. }
  257. TestFree(pbEncoded);
  258. return fResult;
  259. }
  260. // Attempt to read as a file containing an encoded CRL.
  261. static HCERTSTORE OpenCrlStoreFile(
  262. LPSTR pszStoreFilename)
  263. {
  264. HCERTSTORE hStore;
  265. BYTE *pbEncoded;
  266. DWORD cbEncoded;
  267. if (!ReadDERFromFile(pszStoreFilename, &pbEncoded, &cbEncoded))
  268. return NULL;
  269. if (NULL == (hStore = CertOpenStore(
  270. CERT_STORE_PROV_MEMORY,
  271. 0, // dwEncodingType
  272. 0, // hCryptProv
  273. 0, // dwFlags
  274. NULL // pvPara
  275. )))
  276. return NULL;
  277. if (!CertAddEncodedCRLToStore(
  278. hStore,
  279. dwCertEncodingType,
  280. pbEncoded,
  281. cbEncoded,
  282. CERT_STORE_ADD_ALWAYS,
  283. NULL // ppCrlContext
  284. )) {
  285. CertCloseStore(hStore, 0);
  286. hStore = NULL;
  287. }
  288. TestFree(pbEncoded);
  289. return hStore;
  290. }
  291. static BOOL AddRootCtl(
  292. HCERTSTORE hStore,
  293. PCCTL_CONTEXT pCtl,
  294. DWORD dwAddDisposition,
  295. BOOL fExpectError
  296. )
  297. {
  298. BOOL fResult;
  299. DWORD i;
  300. DWORD cCtlEntry = pCtl->pCtlInfo->cCTLEntry;
  301. PCTL_ENTRY pCtlEntry = pCtl->pCtlInfo->rgCTLEntry;
  302. HCERTSTORE hMsgStore = NULL;
  303. hMsgStore = CertOpenStore(
  304. CERT_STORE_PROV_MSG,
  305. dwMsgAndCertEncodingType,
  306. 0, // hCryptProv
  307. 0, // dwFlags
  308. (const void *) pCtl->hCryptMsg
  309. );
  310. if (NULL == hMsgStore) {
  311. PrintLastError("Open Msg Store");
  312. goto ErrorReturn;
  313. }
  314. // Loop through entries. Either add or remove the certificate from the
  315. // store
  316. for (i = 0; i< cCtlEntry; i++, pCtlEntry++) {
  317. PCRYPT_ATTRIBUTE pDelAttr;
  318. pDelAttr = CertFindAttribute(
  319. szOID_REMOVE_CERTIFICATE,
  320. pCtlEntry->cAttribute,
  321. pCtlEntry->rgAttribute
  322. );
  323. if (pDelAttr) {
  324. BYTE rgbDelValue[] = {0x02, 0x1, 0x1};
  325. if (0 == pDelAttr->cValue || 3 != pDelAttr->rgValue[0].cbData ||
  326. 0 != memcmp(pDelAttr->rgValue[0].pbData, rgbDelValue, 3))
  327. printf("Failed ==> bad delete attribute for Cert[%d]\n", i);
  328. else {
  329. PCCERT_CONTEXT pDelCert;
  330. pDelCert = CertFindCertificateInStore(
  331. hStore,
  332. 0, // dwCertEncodingType
  333. 0, // dwFindFlags
  334. CERT_FIND_SHA1_HASH,
  335. (const void *) &pCtlEntry->SubjectIdentifier,
  336. NULL //pPrevCertContext
  337. );
  338. if (pDelCert) {
  339. if (CertDeleteCertificateFromStore(pDelCert))
  340. printf("===== Deleted Root Cert[%d] =====\n", i);
  341. else
  342. printf("Failed ==> delete Cert[%d]\n", i);
  343. }
  344. }
  345. } else {
  346. PCCERT_CONTEXT pAddCert;
  347. pAddCert = CertFindCertificateInStore(
  348. hMsgStore,
  349. 0, // dwCertEncodingType
  350. 0, // dwFindFlags
  351. CERT_FIND_SHA1_HASH,
  352. (const void *) &pCtlEntry->SubjectIdentifier,
  353. NULL //pPrevCertContext
  354. );
  355. if (pAddCert) {
  356. if (!CertSetCertificateContextPropertiesFromCTLEntry(
  357. pAddCert,
  358. pCtlEntry,
  359. CERT_SET_PROPERTY_IGNORE_PERSIST_ERROR_FLAG
  360. ))
  361. printf("Failed ==> SetPropFromCTLEntry for Cert [%d]\n",
  362. i);
  363. else {
  364. if (!CertAddCertificateContextToStore(
  365. hStore,
  366. pAddCert,
  367. dwAddDisposition,
  368. NULL // ppStoreContext
  369. ))
  370. printf("Failed ==> Add Cert [%d]\n", i);
  371. else
  372. printf("===== Added Root Cert[%d] =====\n", i);
  373. }
  374. CertFreeCertificateContext(pAddCert);
  375. } else
  376. printf("Failed ==> No Cert [%d]\n", i);
  377. }
  378. }
  379. fResult = TRUE;
  380. CommonReturn:
  381. if (hMsgStore)
  382. CertCloseStore(hMsgStore, 0);
  383. return fResult;
  384. ErrorReturn:
  385. fResult = FALSE;
  386. goto CommonReturn;
  387. }
  388. static BOOL AddCtl(HCERTSTORE hStore, LPSTR pszAddFilename,
  389. DWORD dwAddDisposition, BOOL fExpectError)
  390. {
  391. BYTE *pbEncoded;
  392. DWORD cbEncoded;
  393. BOOL fResult;
  394. PCCTL_CONTEXT pCtl = NULL;
  395. if (!ReadDERFromFile(pszAddFilename, &pbEncoded, &cbEncoded)) {
  396. PrintLastError("AddCtl");
  397. return FALSE;
  398. }
  399. // Determine if Root CTL
  400. pCtl = CertCreateCTLContext(
  401. dwMsgAndCertEncodingType,
  402. pbEncoded,
  403. cbEncoded
  404. );
  405. if (pCtl) {
  406. PCTL_USAGE pSubjectUsage = &pCtl->pCtlInfo->SubjectUsage;
  407. if (0 == pSubjectUsage->cUsageIdentifier ||
  408. 0 != strcmp(pSubjectUsage->rgpszUsageIdentifier[0],
  409. szOID_ROOT_LIST_SIGNER)) {
  410. CertFreeCTLContext(pCtl);
  411. pCtl = NULL;
  412. }
  413. }
  414. fResult = FALSE;
  415. if (pCtl) {
  416. fResult = AddRootCtl(
  417. hStore,
  418. pCtl,
  419. dwAddDisposition,
  420. fExpectError
  421. );
  422. CertFreeCTLContext(pCtl);
  423. } else if (!CertAddEncodedCTLToStore(hStore, dwMsgAndCertEncodingType, pbEncoded,
  424. cbEncoded, dwAddDisposition, &pCtl)) {
  425. if (fExpectError)
  426. PrintExpectedError("CertAddEncodedCTLToStore");
  427. else
  428. PrintLastError("CertAddEncodedCTLToStore");
  429. } else {
  430. if (fExpectError)
  431. PrintNoError("CertAddEncodedCTLToStore");
  432. else
  433. fResult = TRUE;
  434. printf("===== Added CTL =====\n");
  435. DisplayCtl(pCtl, 0, hStore);
  436. CertFreeCTLContext(pCtl);
  437. }
  438. TestFree(pbEncoded);
  439. return fResult;
  440. }
  441. static BOOL ReadCtl(
  442. LPSTR pszReadFilename,
  443. DWORD dwDisplayFlags)
  444. {
  445. BOOL fResult;
  446. BYTE *pbEncoded;
  447. DWORD cbEncoded;
  448. PCCTL_CONTEXT pCtl;
  449. if (!ReadDERFromFile(pszReadFilename, &pbEncoded, &cbEncoded)) {
  450. PrintLastError("ReadCtl");
  451. return FALSE;
  452. }
  453. pCtl = CertCreateCTLContext(
  454. dwMsgAndCertEncodingType,
  455. pbEncoded,
  456. cbEncoded
  457. );
  458. if (pCtl == NULL) {
  459. fResult = FALSE;
  460. PrintLastError("CertCreateCTLContext");
  461. } else {
  462. fResult = TRUE;
  463. DisplayCtl(pCtl, dwDisplayFlags, NULL);
  464. CertFreeCTLContext(pCtl);
  465. }
  466. TestFree(pbEncoded);
  467. return fResult;
  468. }
  469. // Attempt to read as a file containing an encoded CTL.
  470. static HCERTSTORE OpenCtlStoreFile(
  471. LPSTR pszStoreFilename)
  472. {
  473. HCERTSTORE hStore;
  474. BYTE *pbEncoded;
  475. DWORD cbEncoded;
  476. if (!ReadDERFromFile(pszStoreFilename, &pbEncoded, &cbEncoded))
  477. return NULL;
  478. if (NULL == (hStore = CertOpenStore(
  479. CERT_STORE_PROV_MEMORY,
  480. 0, // dwEncodingType
  481. 0, // hCryptProv
  482. 0, // dwFlags
  483. NULL // pvPara
  484. )))
  485. goto CommonReturn;
  486. if (!CertAddEncodedCTLToStore(
  487. hStore,
  488. dwMsgAndCertEncodingType,
  489. pbEncoded,
  490. cbEncoded,
  491. CERT_STORE_ADD_ALWAYS,
  492. NULL // ppCtlContext
  493. )) {
  494. CertCloseStore(hStore, 0);
  495. hStore = NULL;
  496. }
  497. CommonReturn:
  498. TestFree(pbEncoded);
  499. return hStore;
  500. }
  501. static PCCERT_CONTEXT GetNthCert(
  502. IN HCERTSTORE hStore,
  503. IN DWORD N
  504. )
  505. {
  506. PCCERT_CONTEXT pCert = NULL;
  507. while (pCert = CertEnumCertificatesInStore(hStore, pCert)) {
  508. if (0 == N--)
  509. break;
  510. }
  511. return pCert;
  512. }
  513. static void SetKeyProvParams(
  514. IN PCCERT_CONTEXT pCert
  515. )
  516. {
  517. CRYPT_KEY_PROV_INFO Info;
  518. CRYPT_KEY_PROV_PARAM Param[3];
  519. DWORD i;
  520. BYTE rgb[11*3];
  521. Info.pwszContainerName = L"Test Container With Parameters";
  522. Info.pwszProvName = L"test provider with parameters";
  523. Info.dwProvType = 77;
  524. Info.dwFlags = 0x12345678;
  525. Info.cProvParam = 3;
  526. Info.rgProvParam = Param;
  527. Info.dwKeySpec = 66;
  528. for (i = 0; i < sizeof(rgb); i++)
  529. rgb[i] = (BYTE) i;
  530. for (i = 0; i < 3; i++) {
  531. Param[i].dwParam = 0x10 + i;
  532. if (i == 0)
  533. Param[i].pbData = NULL;
  534. else
  535. Param[i].pbData = rgb;
  536. Param[i].cbData = i * 11;
  537. Param[i].dwFlags = 1 << i;
  538. }
  539. if (!CertSetCertificateContextProperty(
  540. pCert,
  541. CERT_KEY_PROV_INFO_PROP_ID,
  542. 0, // dwFlags
  543. &Info
  544. ))
  545. PrintLastError("CertSetCertificateContextProperty(KeyProvParams)");
  546. }
  547. static void Usage(void)
  548. {
  549. printf("Usage: tstore [options] <StoreName>\n");
  550. printf("Options are:\n");
  551. printf(" -h - This message\n");
  552. printf(" -b - Brief\n");
  553. printf(" -c - Verify ALL checks enabled\n");
  554. printf(" -cSign - Verify Signature check enabled\n");
  555. printf(" -cTime - Verify Time Validity check enabled\n");
  556. printf(" -d - Delete cert/CRL/CTL\n");
  557. printf(" -dALL - Delete all certs/CRLs/CTLs\n");
  558. printf(" -P - Set or Delete property\n");
  559. printf(" -PKey - Find or Delete KeyProvInfo property\n");
  560. printf(" -PSilentKey - Silent Find or Delete KeyProvInfo property\n");
  561. printf(" -PArchive - Find or Delete Archive property\n");
  562. printf(" -PKeyProvParam - Set KeyProvInfo with parameters\n");
  563. printf(" -F - Test Force store close\n");
  564. printf(" -e<number> - Cert encoding type\n");
  565. printf(" -f<number> - Open dwFlags\n");
  566. printf(" -E - Error is expected for add, delete or set\n");
  567. printf(" -i<number> - Cert/CRL/CTL index\n");
  568. printf(" -l - List (Default)\n");
  569. printf(" -R - Revocation (CRL)\n");
  570. printf(" -T - Trust (CTL)\n");
  571. printf(" -N - Enable change Notify\n");
  572. printf(" -C - Commit before close\n");
  573. printf(" -CForce - Force Commit before close\n");
  574. printf(" -CClear - Clear Commit before close\n");
  575. printf(" -s - Open the \"StoreName\" System store\n");
  576. printf(" -s<StoreProviderName> - Open using store provider\n");
  577. printf(" -v - Verbose\n");
  578. printf(" -u - UI Dialog Viewer\n");
  579. printf(" -a<filename> - Add encoded cert/CRL/CTL from file\n");
  580. printf(" -A<filename> - Add (replace) encoded cert/CRL/CTL from file\n");
  581. printf(" -I<filename> - Add (inherit properties) encoded cert/CRL/CTL from file\n");
  582. printf(" -p<filename> - Put encoded cert/CRL/CTL to file\n");
  583. printf(" -r<filename> - Read encoded cert/CRL/CTL from file\n");
  584. printf(" -t - Save thumprints (digests/hashes) in store\n");
  585. printf(" -K - Display Public Key Thumbprint\n");
  586. printf(" -S[<SaveFilename>] - Save store to file\n");
  587. printf(" -7[<SaveFilename>] - PKCS# 7 formated save\n");
  588. printf("\n");
  589. printf("Default: list of certs for the store\n");
  590. }
  591. int _cdecl main(int argc, char * argv[])
  592. {
  593. DWORD dwDisplayFlags = 0;
  594. LONG lIndex = -1;
  595. BOOL fDelete = FALSE;
  596. BOOL fDeleteAll = FALSE;
  597. DWORD dwOpenFlags = 0;
  598. BOOL fExpectError = FALSE;
  599. BOOL fProperty = FALSE;
  600. BOOL fKeyProperty = FALSE;
  601. BOOL fKeyProvParam = FALSE;
  602. BOOL fSilentKey = FALSE;
  603. BOOL fArchiveProperty = FALSE;
  604. DWORD dwContextType = CERT_STORE_CERTIFICATE_CONTEXT;
  605. BOOL fThumbprint = FALSE;
  606. BOOL fSystemStore = FALSE;
  607. BOOL fForceClose = FALSE;
  608. BOOL fSave = FALSE;
  609. BOOL fPKCS7Save = FALSE;
  610. DWORD dwAddDisposition = CERT_STORE_ADD_USE_EXISTING;
  611. LPSTR pszAddFilename = NULL;
  612. LPSTR pszPutFilename = NULL;
  613. LPSTR pszReadFilename = NULL;
  614. LPSTR pszStoreFilename = NULL;
  615. LPSTR pszSaveFilename = NULL;
  616. LPSTR pszStoreProvider = NULL;
  617. HCERTSTORE hStore;
  618. BOOL fNotify = FALSE;
  619. HANDLE hEvent = NULL;
  620. BOOL fCommit = FALSE;
  621. DWORD dwCommitFlags = 0;
  622. BOOL fDeferClose = FALSE;
  623. #define DEFER_CERT_CNT 5
  624. PCCERT_CONTEXT rgpDeferCert[DEFER_CERT_CNT];
  625. memset(rgpDeferCert, 0, sizeof(rgpDeferCert));
  626. while (--argc>0)
  627. {
  628. if (**++argv == '-')
  629. {
  630. switch(argv[0][1])
  631. {
  632. case 'c':
  633. dwDisplayFlags |= DISPLAY_CHECK_FLAG;
  634. if (argv[0][2]) {
  635. if (0 == _stricmp(argv[0]+2, "Sign"))
  636. dwDisplayFlags |= DISPLAY_CHECK_SIGN_FLAG;
  637. else if (0 == _stricmp(argv[0]+2, "Time"))
  638. dwDisplayFlags |= DISPLAY_CHECK_TIME_FLAG;
  639. else {
  640. printf("Need to specify -cSign | -cTime\n");
  641. Usage();
  642. return -1;
  643. }
  644. }
  645. break;
  646. case 'b':
  647. dwDisplayFlags |= DISPLAY_BRIEF_FLAG;
  648. break;
  649. case 'v':
  650. dwDisplayFlags |= DISPLAY_VERBOSE_FLAG;
  651. break;
  652. case 'u':
  653. dwDisplayFlags |= DISPLAY_UI_FLAG;
  654. break;
  655. case 'K':
  656. dwDisplayFlags |= DISPLAY_KEY_THUMB_FLAG;
  657. break;
  658. case 'd':
  659. if (argv[0][2]) {
  660. if (0 != _stricmp(argv[0]+2, "ALL")) {
  661. printf("Need to specify -dALL\n");
  662. Usage();
  663. return -1;
  664. }
  665. fDeleteAll = TRUE;
  666. } else
  667. fDelete = TRUE;
  668. break;
  669. case 'P':
  670. if (argv[0][2]) {
  671. if (0 == _stricmp(argv[0]+2, "Key"))
  672. fKeyProperty = TRUE;
  673. else if (0 == _stricmp(argv[0]+2, "Archive"))
  674. fArchiveProperty = TRUE;
  675. else if (0 == _stricmp(argv[0]+2, "KeyProvParam"))
  676. fKeyProvParam = TRUE;
  677. else if (0 == _stricmp(argv[0]+2, "SilentKey")) {
  678. fKeyProperty = TRUE;
  679. fSilentKey = TRUE;
  680. } else {
  681. printf("Need to specify -PKey\n");
  682. Usage();
  683. return -1;
  684. }
  685. } else
  686. fProperty = TRUE;
  687. break;
  688. case 'F':
  689. fForceClose = TRUE;
  690. break;
  691. case 'R':
  692. dwContextType = CERT_STORE_CRL_CONTEXT;
  693. break;
  694. case 'T':
  695. dwContextType = CERT_STORE_CTL_CONTEXT;
  696. break;
  697. case 'N':
  698. fNotify = TRUE;
  699. break;
  700. case 'C':
  701. if (argv[0][2]) {
  702. if (0 == _stricmp(argv[0]+2, "Force"))
  703. dwCommitFlags |= CERT_STORE_CTRL_COMMIT_FORCE_FLAG;
  704. else if (0 == _stricmp(argv[0]+2, "Clear"))
  705. dwCommitFlags |= CERT_STORE_CTRL_COMMIT_CLEAR_FLAG;
  706. else {
  707. printf("Need to specify -CForce or -CClear\n");
  708. Usage();
  709. return -1;
  710. }
  711. }
  712. fCommit = TRUE;
  713. break;
  714. case 's':
  715. if (argv[0][2])
  716. pszStoreProvider = argv[0]+2;
  717. fSystemStore = TRUE;
  718. break;
  719. case 't':
  720. fThumbprint = TRUE;
  721. break;
  722. case 'l':
  723. break;
  724. case 'e':
  725. dwCertEncodingType = (DWORD) strtoul(argv[0]+2, NULL, 0);
  726. break;
  727. case 'f':
  728. dwOpenFlags = (DWORD) strtoul(argv[0]+2, NULL, 0);
  729. break;
  730. case 'E':
  731. fExpectError = TRUE;
  732. break;
  733. case 'i':
  734. lIndex = (DWORD) strtol(argv[0]+2, NULL, 0);
  735. break;
  736. case 'a':
  737. case 'A':
  738. case 'I':
  739. pszAddFilename = argv[0]+2;
  740. if (*pszAddFilename == '\0') {
  741. printf("Need to specify filename\n");
  742. Usage();
  743. return -1;
  744. }
  745. if (argv[0][1] == 'A')
  746. dwAddDisposition = CERT_STORE_ADD_REPLACE_EXISTING;
  747. else if (argv[0][1] == 'I')
  748. dwAddDisposition =
  749. CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES;
  750. else
  751. dwAddDisposition = CERT_STORE_ADD_USE_EXISTING;
  752. break;
  753. case 'p':
  754. pszPutFilename = argv[0]+2;
  755. if (*pszPutFilename == '\0') {
  756. printf("Need to specify filename\n");
  757. Usage();
  758. return -1;
  759. }
  760. break;
  761. case 'r':
  762. pszReadFilename = argv[0]+2;
  763. if (*pszReadFilename == '\0') {
  764. printf("Need to specify filename\n");
  765. Usage();
  766. return -1;
  767. }
  768. break;
  769. case '7':
  770. fPKCS7Save = TRUE;
  771. case 'S':
  772. fSave = TRUE;
  773. if (argv[0][2])
  774. pszSaveFilename = argv[0]+2;
  775. break;
  776. case 'h':
  777. default:
  778. Usage();
  779. return -1;
  780. }
  781. } else
  782. pszStoreFilename = argv[0];
  783. }
  784. if (dwDisplayFlags & DISPLAY_VERBOSE_FLAG)
  785. dwDisplayFlags &= ~DISPLAY_BRIEF_FLAG;
  786. if (pszStoreFilename == NULL) {
  787. printf("missing store filename\n");
  788. Usage();
  789. return -1;
  790. }
  791. if (pszSaveFilename == NULL) {
  792. if (!fSystemStore)
  793. pszSaveFilename = pszStoreFilename;
  794. else if (fSave) {
  795. printf("missing save filename\n");
  796. Usage();
  797. return -1;
  798. }
  799. }
  800. if (lIndex < 0 && (fDelete || pszPutFilename)) {
  801. printf("Must specify index value\n");
  802. Usage();
  803. return -1;
  804. }
  805. printf("command line: %s\n", GetCommandLine());
  806. {
  807. DWORD dwFileVersionMS; /* e.g. 0x00030075 = "3.75" */
  808. DWORD dwFileVersionLS; /* e.g. 0x00000031 = "0.31" */
  809. if (I_CryptGetFileVersion(L"crypt32.dll",
  810. &dwFileVersionMS, &dwFileVersionLS))
  811. printf("crypt32.dll file version:: %d.%d.%d.%d\n",
  812. (dwFileVersionMS >> 16) & 0xFFFF,
  813. dwFileVersionMS & 0xFFFF,
  814. (dwFileVersionLS >> 16) & 0xFFFF,
  815. dwFileVersionLS & 0xFFFF
  816. );
  817. else
  818. PrintLastError("I_CryptGetFileVersion(crypt32.dll)");
  819. }
  820. hStore = NULL;
  821. if (pszStoreProvider) {
  822. LPWSTR pwszStore;
  823. if (pwszStore = AllocAndSzToWsz(pszStoreFilename)) {
  824. hStore = CertOpenStore(
  825. pszStoreProvider,
  826. 0, // dwEncodingType
  827. 0, // hCryptProv
  828. dwOpenFlags,
  829. pwszStore
  830. );
  831. TestFree(pwszStore);
  832. }
  833. if (hStore == NULL) {
  834. if (dwOpenFlags & CERT_STORE_DELETE_FLAG) {
  835. if (0 == GetLastError())
  836. printf("Successful delete store\n");
  837. else
  838. PrintLastError("CertOpenStore(CERT_STORE_DELETE_FLAG)");
  839. return 0;
  840. } else {
  841. PrintLastError("CertOpenStore");
  842. return -1;
  843. }
  844. }
  845. } else if (!fSystemStore) {
  846. // Attempt to open as encoded certificate CRL or CTL file
  847. switch (dwContextType) {
  848. case CERT_STORE_CRL_CONTEXT:
  849. hStore = OpenCrlStoreFile(pszStoreFilename);
  850. break;
  851. case CERT_STORE_CTL_CONTEXT:
  852. hStore = OpenCtlStoreFile(pszStoreFilename);
  853. break;
  854. case CERT_STORE_CERTIFICATE_CONTEXT:
  855. hStore = OpenCertStoreFile(pszStoreFilename);
  856. default:
  857. break;
  858. }
  859. }
  860. if (NULL == hStore) {
  861. // Attempt to open the store
  862. if (!fSystemStore && fCommit) {
  863. dwOpenFlags |= CERT_FILE_STORE_COMMIT_ENABLE_FLAG;
  864. pszSaveFilename = NULL;
  865. }
  866. dwOpenFlags |= CERT_STORE_SET_LOCALIZED_NAME_FLAG;
  867. hStore = OpenStoreEx(fSystemStore, pszStoreFilename, dwOpenFlags);
  868. if (hStore == NULL)
  869. return -1;
  870. }
  871. if (dwOpenFlags & CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG) {
  872. printf("CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG was set\n");
  873. if (!fForceClose)
  874. fDeferClose = TRUE;
  875. }
  876. #if 0
  877. if (fNotify && fSystemStore && !FIsWinNT()) {
  878. printf("Change Notify not supported for Win95 Registry\n");
  879. fNotify = FALSE;
  880. }
  881. #endif
  882. if (fNotify) {
  883. // Create event to be notified
  884. if (NULL == (hEvent = CreateEvent(
  885. NULL, // lpsa
  886. FALSE, // fManualReset
  887. FALSE, // fInitialState
  888. NULL))) // lpszEventName
  889. PrintLastError("CreateEvent");
  890. else {
  891. // Register the event to be signaled when the store changes
  892. if (!CertControlStore(
  893. hStore,
  894. 0, // dwFlags
  895. CERT_STORE_CTRL_NOTIFY_CHANGE,
  896. &hEvent
  897. )) {
  898. PrintLastError("CertControlStore(NOTIFY_CHANGE)");
  899. fNotify = FALSE;
  900. } else
  901. Sleep(5); // Allow callback thread to be scheduled
  902. }
  903. }
  904. if (pszReadFilename) {
  905. printf("Reading\n");
  906. switch (dwContextType) {
  907. case CERT_STORE_CRL_CONTEXT:
  908. ReadCrl(pszReadFilename, dwDisplayFlags);
  909. break;
  910. case CERT_STORE_CTL_CONTEXT:
  911. ReadCtl(pszReadFilename, dwDisplayFlags);
  912. break;
  913. default:
  914. ReadCert(hStore, pszReadFilename, dwDisplayFlags);
  915. }
  916. } else if (pszAddFilename) {
  917. BOOL fResult;
  918. printf("Adding\n");
  919. switch (dwContextType) {
  920. case CERT_STORE_CRL_CONTEXT:
  921. fResult = AddCrl(hStore, pszAddFilename, dwAddDisposition,
  922. fExpectError);
  923. break;
  924. case CERT_STORE_CTL_CONTEXT:
  925. fResult = AddCtl(hStore, pszAddFilename, dwAddDisposition,
  926. fExpectError);
  927. break;
  928. default:
  929. fResult = AddCert(hStore, pszAddFilename, dwAddDisposition,
  930. fExpectError);
  931. }
  932. if (fResult)
  933. fSave = TRUE;
  934. } else if (fDeleteAll & !fArchiveProperty) {
  935. printf("Deleting All\n");
  936. if (CERT_STORE_CRL_CONTEXT == dwContextType) {
  937. PCCRL_CONTEXT pCrl;
  938. while (pCrl = CertEnumCRLsInStore(hStore, NULL)) {
  939. if (!CertDeleteCRLFromStore(pCrl)) {
  940. if (fExpectError)
  941. PrintExpectedError("CertDeleteCRLFromStore");
  942. else
  943. PrintLastError("CertDeleteCRLFromStore");
  944. break;
  945. } else if (fExpectError)
  946. PrintNoError("CertDeleteCRLFromStore");
  947. else
  948. fSave = TRUE;
  949. }
  950. } else if (CERT_STORE_CTL_CONTEXT == dwContextType) {
  951. PCCTL_CONTEXT pCtl;
  952. while (pCtl = CertEnumCTLsInStore(hStore, NULL)) {
  953. if (!CertDeleteCTLFromStore(pCtl)) {
  954. if (fExpectError)
  955. PrintExpectedError("CertDeleteCTLFromStore");
  956. else
  957. PrintLastError("CertDeleteCTLFromStore");
  958. break;
  959. } else if (fExpectError)
  960. PrintNoError("CertDeleteCTLFromStore");
  961. else
  962. fSave = TRUE;
  963. }
  964. } else {
  965. PCCERT_CONTEXT pCert;
  966. while (pCert = CertEnumCertificatesInStore(hStore, NULL)) {
  967. if (!CertDeleteCertificateFromStore(pCert)) {
  968. if (fExpectError)
  969. PrintExpectedError("CertDeleteCertificateFromStore");
  970. else
  971. PrintLastError("CertDeleteCertificateFromStore");
  972. break;
  973. } else if (fExpectError)
  974. PrintNoError("CertDeleteCertificateFromStore");
  975. else
  976. fSave = TRUE;
  977. }
  978. }
  979. } else if (CERT_STORE_CRL_CONTEXT == dwContextType) {
  980. BOOL fFound = FALSE;
  981. LONG i;
  982. PCCRL_CONTEXT pCrl = NULL;
  983. DWORD dwFlags;
  984. for (i = 0;; i++) {
  985. dwFlags = CERT_STORE_TIME_VALIDITY_FLAG;
  986. pCrl = CertGetCRLFromStore(
  987. hStore,
  988. NULL, // pIssuerContext
  989. pCrl,
  990. &dwFlags);
  991. if (pCrl == NULL)
  992. break;
  993. if ((lIndex >= 0) && (lIndex != i))
  994. continue;
  995. fFound = TRUE;
  996. if (fProperty) {
  997. CRYPT_DATA_BLOB Data;
  998. BYTE rgbAux[] = {0xDE, 0xAD, 0xBE, 0xEF};
  999. Data.pbData = rgbAux;
  1000. Data.cbData = sizeof(rgbAux);
  1001. if (!CertSetCRLContextProperty(
  1002. pCrl,
  1003. CERT_FIRST_USER_PROP_ID,
  1004. 0, // dwFlags
  1005. &Data
  1006. )) {
  1007. if (fExpectError)
  1008. PrintExpectedError("CertSetCRLContextProperty");
  1009. else
  1010. PrintLastError("CertSetCRLContextProperty");
  1011. } else if (fExpectError)
  1012. PrintNoError("CertSetCRLContextProperty");
  1013. else
  1014. fSave = TRUE;
  1015. }
  1016. if (fDelete) {
  1017. printf("Deleting\n");
  1018. if (!CertDeleteCRLFromStore(pCrl)) {
  1019. if (fExpectError)
  1020. PrintExpectedError("CertDeleteCRLFromStore");
  1021. else
  1022. PrintLastError("CertDeleteCRLFromStore");
  1023. } else if (fExpectError)
  1024. PrintNoError("CertDeleteCRLFromStore");
  1025. else
  1026. fSave = TRUE;
  1027. break;
  1028. } else if (pszPutFilename) {
  1029. printf("Putting\n");
  1030. if (!WriteDERToFile(
  1031. pszPutFilename,
  1032. pCrl->pbCrlEncoded,
  1033. pCrl->cbCrlEncoded
  1034. ))
  1035. PrintLastError("Put CRL::WriteDERToFile");
  1036. CertFreeCRLContext(pCrl);
  1037. break;
  1038. } else {
  1039. if (fThumbprint)
  1040. fSave = TRUE;
  1041. printf("===== %d =====\n", i);
  1042. DisplayCrl(pCrl, dwDisplayFlags);
  1043. DisplayVerifyFlags("CRL", dwFlags);
  1044. if (lIndex == i) {
  1045. CertFreeCRLContext(pCrl);
  1046. break;
  1047. }
  1048. }
  1049. }
  1050. if (!fFound)
  1051. printf("CRL not found\n");
  1052. } else if (CERT_STORE_CTL_CONTEXT == dwContextType) {
  1053. BOOL fFound = FALSE;
  1054. LONG i;
  1055. PCCTL_CONTEXT pCtl = NULL;
  1056. for (i = 0;; i++) {
  1057. pCtl = CertEnumCTLsInStore(
  1058. hStore,
  1059. pCtl);
  1060. if (pCtl == NULL)
  1061. break;
  1062. if ((lIndex >= 0) && (lIndex != i))
  1063. continue;
  1064. fFound = TRUE;
  1065. if (fProperty) {
  1066. CRYPT_DATA_BLOB Data;
  1067. BYTE rgbAux[] = {0xDE, 0xAD, 0xBE, 0xEF};
  1068. Data.pbData = rgbAux;
  1069. Data.cbData = sizeof(rgbAux);
  1070. if (!CertSetCTLContextProperty(
  1071. pCtl,
  1072. CERT_FIRST_USER_PROP_ID,
  1073. 0, // dwFlags
  1074. &Data
  1075. )) {
  1076. if (fExpectError)
  1077. PrintExpectedError("CertSetCTLContextProperty");
  1078. else
  1079. PrintLastError("CertSetCTLContextProperty");
  1080. } else if (fExpectError)
  1081. PrintNoError("CertSetCTLContextProperty");
  1082. else
  1083. fSave = TRUE;
  1084. }
  1085. if (fDelete) {
  1086. printf("Deleting\n");
  1087. if (!CertDeleteCTLFromStore(pCtl)) {
  1088. if (fExpectError)
  1089. PrintExpectedError("CertDeleteCTLFromStore");
  1090. else
  1091. PrintLastError("CertDeleteCTLFromStore");
  1092. } else if (fExpectError)
  1093. PrintNoError("CertDeleteCTLFromStore");
  1094. else
  1095. fSave = TRUE;
  1096. break;
  1097. } else if (pszPutFilename) {
  1098. printf("Putting\n");
  1099. if (!WriteDERToFile(
  1100. pszPutFilename,
  1101. pCtl->pbCtlEncoded,
  1102. pCtl->cbCtlEncoded
  1103. ))
  1104. PrintLastError("Put CTL::WriteDERToFile");
  1105. CertFreeCTLContext(pCtl);
  1106. break;
  1107. } else {
  1108. if (fThumbprint)
  1109. fSave = TRUE;
  1110. printf("===== %d =====\n", i);
  1111. DisplayCtl(pCtl, dwDisplayFlags, hStore);
  1112. if (lIndex == i) {
  1113. CertFreeCTLContext(pCtl);
  1114. break;
  1115. }
  1116. }
  1117. }
  1118. if (!fFound)
  1119. printf("CTL not found\n");
  1120. } else {
  1121. BOOL fFound = FALSE;
  1122. LONG i;
  1123. PCCERT_CONTEXT pCert = NULL;
  1124. pCert = NULL;
  1125. for (i = 0;; i++) {
  1126. pCert = CertEnumCertificatesInStore(
  1127. hStore,
  1128. pCert);
  1129. if (pCert == NULL)
  1130. break;
  1131. if ((lIndex >= 0) && (lIndex != i))
  1132. continue;
  1133. fFound = TRUE;
  1134. if (fForceClose)
  1135. CertDuplicateCertificateContext(pCert);
  1136. else if (fDeferClose) {
  1137. CertFreeCertificateContext(rgpDeferCert[0]);
  1138. rgpDeferCert[0] = CertDuplicateCertificateContext(pCert);
  1139. }
  1140. if (fProperty && !fDelete) {
  1141. CRYPT_DATA_BLOB Data;
  1142. BYTE rgbAux[] = {0xDE, 0xAD, 0xBE, 0xEF};
  1143. Data.pbData = rgbAux;
  1144. Data.cbData = sizeof(rgbAux);
  1145. if (!CertSetCertificateContextProperty(
  1146. pCert,
  1147. CERT_FIRST_USER_PROP_ID,
  1148. 0, // dwFlags
  1149. &Data
  1150. )) {
  1151. if (fExpectError)
  1152. PrintExpectedError("CertSetCertificateContextProperty");
  1153. else
  1154. PrintLastError("CertSetCertificateContextProperty");
  1155. } else if (fExpectError)
  1156. PrintNoError("CertSetCertificateContextProperty");
  1157. else
  1158. fSave = TRUE;
  1159. // Test that we properly update the PROV_HANDLE and KEY_SPEC
  1160. // properties
  1161. HCRYPTPROV hProv = (HCRYPTPROV) 0x12345678;
  1162. HCRYPTPROV hProv2 = 0;
  1163. DWORD dwKeySpec = 0xdeadbeef;
  1164. DWORD dwKeySpec2 = 0;
  1165. if (!CertSetCertificateContextProperty(
  1166. pCert,
  1167. CERT_KEY_PROV_HANDLE_PROP_ID,
  1168. CERT_STORE_NO_CRYPT_RELEASE_FLAG,
  1169. (void *) hProv
  1170. ))
  1171. PrintLastError(
  1172. "CertSetCertificateContextProperty(PROV_HANDLE)");
  1173. else if (!CertSetCertificateContextProperty(
  1174. pCert,
  1175. CERT_KEY_SPEC_PROP_ID,
  1176. 0, // dwFlags
  1177. &dwKeySpec
  1178. ))
  1179. PrintLastError(
  1180. "CertSetCertificateContextProperty(KEY_SPEC)");
  1181. else {
  1182. DWORD cbData = sizeof(hProv);
  1183. CERT_KEY_CONTEXT KeyContext;
  1184. if (!CertGetCertificateContextProperty(
  1185. pCert,
  1186. CERT_KEY_PROV_HANDLE_PROP_ID,
  1187. &hProv2,
  1188. &cbData))
  1189. PrintLastError(
  1190. "CertGetCertificateContextProperty(PROV_HANDLE)");
  1191. else if (hProv2 != hProv)
  1192. PrintLastError(
  1193. "PROV_HANDLE property not updated properly\n");
  1194. cbData = sizeof(dwKeySpec);
  1195. if (!CertGetCertificateContextProperty(
  1196. pCert,
  1197. CERT_KEY_SPEC_PROP_ID,
  1198. &dwKeySpec2,
  1199. &cbData))
  1200. PrintLastError(
  1201. "CertGetCertificateContextProperty(KEY_SPEC)");
  1202. else if (dwKeySpec2 != dwKeySpec)
  1203. PrintLastError(
  1204. "KEY_SPEC property not updated properly\n");
  1205. cbData = sizeof(KeyContext);
  1206. if (!CertGetCertificateContextProperty(
  1207. pCert,
  1208. CERT_KEY_CONTEXT_PROP_ID,
  1209. &KeyContext,
  1210. &cbData))
  1211. PrintLastError(
  1212. "CertGetCertificateContextProperty(KEY_CONTEXT)");
  1213. else if (KeyContext.dwKeySpec != dwKeySpec ||
  1214. KeyContext.hCryptProv != hProv)
  1215. PrintLastError(
  1216. "KEY_CONTEXT property not updated properly\n");
  1217. }
  1218. hProv = 0;
  1219. if (!CertSetCertificateContextProperty(
  1220. pCert,
  1221. CERT_KEY_PROV_HANDLE_PROP_ID,
  1222. 0, // dwFlags
  1223. (void *) hProv
  1224. ))
  1225. PrintLastError(
  1226. "CertSetCertificateContextProperty(PROV_HANDLE)");
  1227. }
  1228. if (fKeyProperty && !fDelete) {
  1229. if (!CryptFindCertificateKeyProvInfo(
  1230. pCert,
  1231. fSilentKey ? CRYPT_FIND_SILENT_KEYSET_FLAG : 0,
  1232. NULL // pvReserved
  1233. )) {
  1234. if (fExpectError)
  1235. PrintExpectedError("CryptFindCertificateKeyProvInfo");
  1236. else
  1237. PrintLastError("CryptFindCertificateKeyProvInfo");
  1238. } else {
  1239. printf("Found KEY_PROV_INFO property\n");
  1240. if (fExpectError)
  1241. PrintNoError("CryptFindCertificateKeyProvInfo");
  1242. else {
  1243. HCRYPTPROV hProv1 = 0;
  1244. HCRYPTPROV hProv2 = 0;
  1245. DWORD dwKeySpec1;
  1246. DWORD dwKeySpec2;
  1247. BOOL fCallerFreeProv;
  1248. fSave = TRUE;
  1249. dwKeySpec1 = 0x12341111;
  1250. fCallerFreeProv = TRUE;
  1251. if (!CryptAcquireCertificatePrivateKey(
  1252. pCert,
  1253. (fSilentKey ? CRYPT_ACQUIRE_SILENT_FLAG : 0) |
  1254. CRYPT_ACQUIRE_CACHE_FLAG |
  1255. CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
  1256. NULL, // pvReserved
  1257. &hProv1,
  1258. &dwKeySpec1,
  1259. &fCallerFreeProv
  1260. ))
  1261. PrintLastError("CryptAcquireCertificatePrivateKey");
  1262. else if (fCallerFreeProv)
  1263. printf("failed => cached acquire returned FreeProv\n");
  1264. dwKeySpec2 = 0x12342222;
  1265. fCallerFreeProv = FALSE;
  1266. if (!CryptAcquireCertificatePrivateKey(
  1267. pCert,
  1268. (fSilentKey ? CRYPT_ACQUIRE_SILENT_FLAG : 0) |
  1269. CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
  1270. NULL, // pvReserved
  1271. &hProv2,
  1272. &dwKeySpec2,
  1273. &fCallerFreeProv
  1274. ))
  1275. PrintLastError("CryptAcquireCertificatePrivateKey");
  1276. else {
  1277. if (!fCallerFreeProv)
  1278. printf("failed => uncached acquire didn't return FreeProv\n");
  1279. if (hProv2 == hProv1)
  1280. printf("failed => uncached == cached hProv\n");
  1281. if (dwKeySpec2 != dwKeySpec1)
  1282. printf("failed => uncached != cached dwKeySpec\n");
  1283. CryptReleaseContext(hProv2, 0);
  1284. }
  1285. if (hProv1) {
  1286. dwKeySpec2 = 0x12343333;
  1287. fCallerFreeProv = TRUE;
  1288. if (!CryptAcquireCertificatePrivateKey(
  1289. pCert,
  1290. (fSilentKey ? CRYPT_ACQUIRE_SILENT_FLAG : 0) |
  1291. CRYPT_ACQUIRE_CACHE_FLAG |
  1292. CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
  1293. NULL, // pvReserved
  1294. &hProv2,
  1295. &dwKeySpec2,
  1296. &fCallerFreeProv
  1297. ))
  1298. PrintLastError("CryptAcquireCertificatePrivateKey");
  1299. else {
  1300. if (fCallerFreeProv)
  1301. printf("failed => uncached acquire returned FreeProv\n");
  1302. if (hProv2 != hProv1)
  1303. printf("failed => cached != cached hProv\n");
  1304. if (dwKeySpec2 != dwKeySpec1)
  1305. printf("failed => cached != cached dwKeySpec\n");
  1306. }
  1307. }
  1308. }
  1309. }
  1310. }
  1311. if (fArchiveProperty) {
  1312. CRYPT_DATA_BLOB ArchiveBlob = { 0, NULL };
  1313. if (!CertSetCertificateContextProperty(
  1314. pCert,
  1315. CERT_ARCHIVED_PROP_ID,
  1316. 0, // dwFlags
  1317. (fDelete || fDeleteAll) ? NULL : &ArchiveBlob
  1318. )) {
  1319. if (fExpectError)
  1320. PrintExpectedError(
  1321. "CertSetCertificateContextProperty(ARCHIVE)");
  1322. else
  1323. PrintLastError(
  1324. "CertSetCertificateContextProperty(ARCHIVE)");
  1325. }
  1326. } else if (fDelete) {
  1327. if (fProperty || fKeyProperty) {
  1328. DWORD PropId;
  1329. if (fKeyProperty) {
  1330. printf("Deleting KEY_PROV_INFO property\n");
  1331. PropId = CERT_KEY_PROV_INFO_PROP_ID;
  1332. } else {
  1333. printf("Deleting property\n");
  1334. PropId = CERT_FIRST_USER_PROP_ID;
  1335. }
  1336. if (!CertSetCertificateContextProperty(
  1337. pCert,
  1338. PropId,
  1339. 0, // dwFlags
  1340. NULL
  1341. )) {
  1342. if (fExpectError)
  1343. PrintExpectedError("CertSetCertificateContextProperty");
  1344. else
  1345. PrintLastError("CertSetCertificateContextProperty");
  1346. } else if (fExpectError)
  1347. PrintNoError("CertSetCertificateContextProperty");
  1348. else
  1349. fSave = TRUE;
  1350. CertFreeCertificateContext(pCert);
  1351. } else {
  1352. printf("Deleting\n");
  1353. if (!CertDeleteCertificateFromStore(pCert)) {
  1354. if (fExpectError)
  1355. PrintExpectedError("CertDeleteCertificateFromStore");
  1356. else
  1357. PrintLastError("CertDeleteCertificateFromStore");
  1358. } else if (fExpectError)
  1359. PrintNoError("CertDeleteCertificateFromStore");
  1360. else
  1361. fSave = TRUE;
  1362. }
  1363. break;
  1364. } else if (pszPutFilename) {
  1365. printf("Putting\n");
  1366. if (!WriteDERToFile(
  1367. pszPutFilename,
  1368. pCert->pbCertEncoded,
  1369. pCert->cbCertEncoded
  1370. ))
  1371. PrintLastError("Put Cert::WriteDERToFile");
  1372. CertFreeCertificateContext(pCert);
  1373. break;
  1374. } else {
  1375. if (fKeyProvParam) {
  1376. printf("Setting KeyProvInfo parameters\n");
  1377. SetKeyProvParams(pCert);
  1378. }
  1379. if (fThumbprint)
  1380. fSave = TRUE;
  1381. printf("===== %d =====\n", i);
  1382. DisplayCert(pCert, dwDisplayFlags);
  1383. if (lIndex == i) {
  1384. CertFreeCertificateContext(pCert);
  1385. break;
  1386. }
  1387. }
  1388. }
  1389. if (!fFound)
  1390. printf("Certificate not found\n");
  1391. if (fForceClose) {
  1392. // Do incomplete enumerations to test out external store
  1393. // logic
  1394. pCert = GetNthCert(hStore, 0);
  1395. CertFreeCertificateContext(pCert);
  1396. pCert = GetNthCert(hStore, 0);
  1397. GetNthCert(hStore, (i-1)/2);
  1398. GetNthCert(hStore, i-1);
  1399. } else if (fDeferClose) {
  1400. rgpDeferCert[1] = GetNthCert(hStore, 0);
  1401. CertFreeCertificateContext(rgpDeferCert[1]);
  1402. rgpDeferCert[1] = GetNthCert(hStore, 0);
  1403. rgpDeferCert[2] = GetNthCert(hStore, (i-1)/2);
  1404. rgpDeferCert[3] = GetNthCert(hStore, i-1);
  1405. }
  1406. }
  1407. if (fSave && pszSaveFilename)
  1408. SaveStoreEx(hStore, fPKCS7Save, pszSaveFilename);
  1409. if (fCommit) {
  1410. printf("Committing store changes::");
  1411. if (dwCommitFlags & CERT_STORE_CTRL_COMMIT_FORCE_FLAG)
  1412. printf(" FORCE");
  1413. if (dwCommitFlags & CERT_STORE_CTRL_COMMIT_CLEAR_FLAG)
  1414. printf(" CLEAR");
  1415. printf("\n");
  1416. if (!CertControlStore(
  1417. hStore,
  1418. dwCommitFlags,
  1419. CERT_STORE_CTRL_COMMIT,
  1420. NULL
  1421. ))
  1422. PrintLastError("CertControlStore(COMMIT)");
  1423. }
  1424. if (fNotify) {
  1425. BOOL fSignaled;
  1426. // Check if event was signaled
  1427. if (WAIT_TIMEOUT == WaitForSingleObjectEx(
  1428. hEvent,
  1429. 100, // dwMilliseconds
  1430. FALSE // bAlertable
  1431. ))
  1432. fSignaled = FALSE;
  1433. else
  1434. fSignaled = TRUE;
  1435. if (!fSignaled) {
  1436. printf("No store change notify\n");
  1437. if (pszAddFilename || fDeleteAll || fDelete || fProperty)
  1438. printf("failed => expected notify for add, delete or property\n");
  1439. } else {
  1440. printf("There was a store change notify\n");
  1441. if (!(pszAddFilename || fDeleteAll || fDelete || fProperty))
  1442. printf("failed => unexpected notify\n");
  1443. if (!CertControlStore(
  1444. hStore,
  1445. 0, // dwFlags
  1446. CERT_STORE_CTRL_RESYNC,
  1447. NULL // pvCtrlPara
  1448. ))
  1449. PrintLastError("CertControlStore(RESYNC)");
  1450. else {
  1451. printf("\n");
  1452. printf(">>>>> After Resync >>>>>\n");
  1453. DisplayStore(hStore, DISPLAY_BRIEF_FLAG);
  1454. }
  1455. }
  1456. }
  1457. if (hEvent)
  1458. CloseHandle(hEvent);
  1459. if (fForceClose) {
  1460. CertDuplicateStore(hStore);
  1461. if (CertCloseStore(hStore,
  1462. CERT_CLOSE_STORE_CHECK_FLAG | CERT_CLOSE_STORE_FORCE_FLAG))
  1463. printf("failed => CertCloseStore(FORCE) didn't fail as expected\n");
  1464. else
  1465. printf("CertCloseStore(FORCE) returned expected nonzero status: 0x%x\n",
  1466. GetLastError());
  1467. } else if (fDeferClose) {
  1468. // Check if any defered certificates
  1469. DWORD i;
  1470. fDeferClose = FALSE;
  1471. for (i = 0; i < DEFER_CERT_CNT; i++) {
  1472. if (rgpDeferCert[i]) {
  1473. fDeferClose = TRUE;
  1474. break;
  1475. }
  1476. }
  1477. if (fDeferClose) {
  1478. CertDuplicateStore(hStore);
  1479. CertCloseStore(hStore, 0);
  1480. if (CertCloseStore(hStore, CERT_CLOSE_STORE_CHECK_FLAG))
  1481. printf("failed => CertCloseStore(DEFER) didn't fail as expected\n");
  1482. else
  1483. printf("CertCloseStore(DEFER) returned expected nonzero status: 0x%x\n",
  1484. GetLastError());
  1485. for (i = 0; i < DEFER_CERT_CNT; i++) {
  1486. CertFreeCertificateContext(rgpDeferCert[i]);
  1487. }
  1488. } else {
  1489. if (!CertCloseStore(hStore, CERT_CLOSE_STORE_CHECK_FLAG))
  1490. PrintLastError("CertCloseStore(DEFER)");
  1491. }
  1492. } else {
  1493. if (!CertCloseStore(hStore, CERT_CLOSE_STORE_CHECK_FLAG))
  1494. PrintLastError("CertCloseStore");
  1495. }
  1496. return 0;
  1497. }