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.

1482 lines
49 KiB

  1. //+-------------------------------------------------------------------------
  2. // Microsoft Windows
  3. //
  4. // Copyright (C) Microsoft Corporation, 1995 - 1996
  5. //
  6. // File: tstore3.cpp
  7. //
  8. // Contents: Cert Store API Tests:
  9. // - CertGetSubjectCertificateFromStore: serial numbers with
  10. // leading 0's or 0xFF's
  11. // - Open two system stores. Ensure certs and CRLs are
  12. // written through
  13. // - CertStoreSave: test SaveToMemory for serialized and PKCS7
  14. // - Call CertOpenSystemStoreW
  15. // - Get hash property for a created context
  16. // - Do a CertVerifySubjectCertificateContext for a
  17. // certificate in a store and a certificate context.
  18. // Should pass for both a store certificate and
  19. // a certificate context. The certificate context
  20. // uses the default hCryptProv.
  21. // - Close a store with a not freed certificate context.
  22. // Should get a warning at closing.
  23. // - Delete and recalculate the hash property for a
  24. // certificate context after the store has been closed.
  25. // - Delete the certificate context after the store has
  26. // been closed
  27. // - Duplicate a certificate. Delete it from the store.
  28. // Also delete its duplicate. Close the store.
  29. // - Check that CertCloseStore preserves last error
  30. // - Win95 test (Win95 has following registry limitations:
  31. // Max single key value of 16K, max total value length
  32. // per key of 64K)
  33. //
  34. // - Write 8 certificates > 10k to same system store
  35. // - Write same certificate to two system stores
  36. // - Set large property > 16K to force certificates to
  37. // be saved to a file.
  38. // - Verify written properties.
  39. // - Delete large property. File should be deleted and
  40. // certificate stored in registry.
  41. // - Rewrite large property. Delete certificate.
  42. // - Check CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG
  43. //
  44. // Functions: main
  45. //
  46. // History: 11-Jan-97 philh created
  47. //--------------------------------------------------------------------------
  48. #include <windows.h>
  49. #include <assert.h>
  50. #include "wincrypt.h"
  51. #include "certtest.h"
  52. #include <stdlib.h>
  53. #include <stdio.h>
  54. #include <string.h>
  55. #include <memory.h>
  56. #include <time.h>
  57. #define SIGNATURE_ALG_OBJID szOID_RSA_MD5RSA
  58. #define TEST_ISSUER_NAME "TestIssuer"
  59. static HCRYPTPROV hCryptProv = 0;
  60. static void PrintExpectedError(LPCSTR pszMsg)
  61. {
  62. DWORD dwErr = GetLastError();
  63. printf("%s got expected error => 0x%x (%d) \n", pszMsg, dwErr, dwErr);
  64. }
  65. void PrintNoError(LPCSTR pszMsg)
  66. {
  67. printf("%s failed => expected error\n", pszMsg);
  68. }
  69. static BOOL EncodeIssuer(
  70. OUT BYTE **ppbIssuerEncoded,
  71. OUT DWORD *pcbIssuerEncoded
  72. )
  73. {
  74. BOOL fResult;
  75. BYTE *pbIssuerEncoded = NULL;
  76. DWORD cbIssuerEncoded;
  77. CERT_RDN_ATTR rgAttr[1];
  78. CERT_RDN rgRDN[1];
  79. CERT_NAME_INFO Name;
  80. Name.cRDN = 1;
  81. Name.rgRDN = rgRDN;
  82. rgRDN[0].cRDNAttr = 1;
  83. rgRDN[0].rgRDNAttr = rgAttr;
  84. rgAttr[0].pszObjId = szOID_COMMON_NAME;
  85. rgAttr[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
  86. rgAttr[0].Value.pbData = (BYTE *) TEST_ISSUER_NAME;
  87. rgAttr[0].Value.cbData = strlen(TEST_ISSUER_NAME);
  88. CryptEncodeObject(
  89. dwCertEncodingType,
  90. X509_NAME,
  91. &Name,
  92. NULL, // pbEncoded
  93. &cbIssuerEncoded
  94. );
  95. if (cbIssuerEncoded == 0) {
  96. PrintLastError("EncodeIssuer::CryptEncodeObject(cbEncoded == 0)");
  97. goto ErrorReturn;
  98. }
  99. pbIssuerEncoded = (BYTE *) TestAlloc(cbIssuerEncoded);
  100. if (pbIssuerEncoded == NULL) goto ErrorReturn;
  101. if (!CryptEncodeObject(
  102. dwCertEncodingType,
  103. X509_NAME,
  104. &Name,
  105. pbIssuerEncoded,
  106. &cbIssuerEncoded
  107. )) {
  108. PrintLastError("EncodeIssuer::CryptEncodeObject");
  109. goto ErrorReturn;
  110. }
  111. fResult = TRUE;
  112. CommonReturn:
  113. *ppbIssuerEncoded = pbIssuerEncoded;
  114. *pcbIssuerEncoded = cbIssuerEncoded;
  115. return fResult;
  116. ErrorReturn:
  117. fResult = FALSE;
  118. if (pbIssuerEncoded) {
  119. TestFree(pbIssuerEncoded);
  120. pbIssuerEncoded = 0;
  121. }
  122. cbIssuerEncoded = 0;
  123. goto CommonReturn;
  124. }
  125. static BOOL GetPublicKey(
  126. PCERT_PUBLIC_KEY_INFO *ppPubKeyInfo)
  127. {
  128. BOOL fResult;
  129. PCERT_PUBLIC_KEY_INFO pPubKeyInfo = NULL;
  130. DWORD cbPubKeyInfo;
  131. DWORD dwKeySpec;
  132. dwKeySpec = AT_SIGNATURE;
  133. CryptExportPublicKeyInfo(
  134. hCryptProv,
  135. dwKeySpec,
  136. dwCertEncodingType,
  137. NULL, // pPubKeyInfo
  138. &cbPubKeyInfo
  139. );
  140. if (cbPubKeyInfo == 0) {
  141. PrintLastError("GetPublicKey::CryptExportPublicKeyInfo(cb == 0)");
  142. goto ErrorReturn;
  143. }
  144. pPubKeyInfo = (PCERT_PUBLIC_KEY_INFO) TestAlloc(cbPubKeyInfo);
  145. if (pPubKeyInfo == NULL) goto ErrorReturn;
  146. if (!CryptExportPublicKeyInfo(
  147. hCryptProv,
  148. dwKeySpec,
  149. dwCertEncodingType,
  150. pPubKeyInfo,
  151. &cbPubKeyInfo
  152. )) {
  153. PrintLastError("GetPublicKey::CryptExportPublicKeyInfo");
  154. goto ErrorReturn;
  155. }
  156. fResult = TRUE;
  157. CommonReturn:
  158. *ppPubKeyInfo = pPubKeyInfo;
  159. return fResult;
  160. ErrorReturn:
  161. fResult = FALSE;
  162. if (pPubKeyInfo) {
  163. TestFree(pPubKeyInfo);
  164. pPubKeyInfo = NULL;
  165. }
  166. goto CommonReturn;
  167. }
  168. static BOOL EncodeCert(
  169. IN PCRYPT_INTEGER_BLOB pSerialNumber,
  170. OUT BYTE **ppbCertEncoded,
  171. OUT DWORD *pcbCertEncoded
  172. )
  173. {
  174. BOOL fResult;
  175. BYTE *pbIssuerEncoded = NULL;
  176. DWORD cbIssuerEncoded;
  177. PCERT_PUBLIC_KEY_INFO pPubKeyInfo = NULL;
  178. BYTE *pbCertEncoded = NULL;
  179. DWORD cbCertEncoded;
  180. CERT_INFO Cert;
  181. if (!EncodeIssuer(&pbIssuerEncoded, &cbIssuerEncoded)) goto ErrorReturn;
  182. // PUBLIC KEY
  183. if (!GetPublicKey(&pPubKeyInfo)) goto ErrorReturn;
  184. // CERT
  185. memset(&Cert, 0, sizeof(Cert));
  186. Cert.dwVersion = CERT_V3;
  187. Cert.SerialNumber = *pSerialNumber;
  188. Cert.SignatureAlgorithm.pszObjId = SIGNATURE_ALG_OBJID;
  189. Cert.Issuer.pbData = pbIssuerEncoded;
  190. Cert.Issuer.cbData = cbIssuerEncoded;
  191. {
  192. SYSTEMTIME SystemTime;
  193. GetSystemTime(&SystemTime);
  194. SystemTimeToFileTime(&SystemTime, &Cert.NotBefore);
  195. SystemTime.wYear++;
  196. if (!SystemTimeToFileTime(&SystemTime, &Cert.NotAfter)) {
  197. SystemTime.wDay = 1;
  198. SystemTimeToFileTime(&SystemTime, &Cert.NotAfter);
  199. }
  200. }
  201. Cert.Subject.pbData = pbIssuerEncoded;
  202. Cert.Subject.cbData = cbIssuerEncoded;
  203. Cert.SubjectPublicKeyInfo = *pPubKeyInfo;
  204. CryptSignAndEncodeCertificate(
  205. hCryptProv,
  206. AT_SIGNATURE,
  207. dwCertEncodingType,
  208. X509_CERT_TO_BE_SIGNED,
  209. &Cert,
  210. &Cert.SignatureAlgorithm,
  211. NULL, // pvHashAuxInfo
  212. NULL, // pbEncoded
  213. &cbCertEncoded
  214. );
  215. if (cbCertEncoded == 0) {
  216. PrintLastError("CryptSignAndEncodeCertificate(cbEncoded == 0)");
  217. goto ErrorReturn;
  218. }
  219. pbCertEncoded = (BYTE *) TestAlloc(cbCertEncoded);
  220. if (pbCertEncoded == NULL) goto ErrorReturn;
  221. if (!CryptSignAndEncodeCertificate(
  222. hCryptProv,
  223. AT_SIGNATURE,
  224. dwCertEncodingType,
  225. X509_CERT_TO_BE_SIGNED,
  226. &Cert,
  227. &Cert.SignatureAlgorithm,
  228. NULL, // pvHashAuxInfo
  229. pbCertEncoded,
  230. &cbCertEncoded
  231. )) {
  232. PrintLastError("CryptSignAndEncodeCertificate");
  233. goto ErrorReturn;
  234. }
  235. fResult = TRUE;
  236. CommonReturn:
  237. if (pbIssuerEncoded)
  238. TestFree(pbIssuerEncoded);
  239. if (pPubKeyInfo)
  240. TestFree(pPubKeyInfo);
  241. *ppbCertEncoded = pbCertEncoded;
  242. *pcbCertEncoded = cbCertEncoded;
  243. return fResult;
  244. ErrorReturn:
  245. fResult = FALSE;
  246. if (pbCertEncoded) {
  247. TestFree(pbCertEncoded);
  248. pbCertEncoded = 0;
  249. }
  250. cbCertEncoded = 0;
  251. goto CommonReturn;
  252. }
  253. static PCCERT_CONTEXT GetSubject(
  254. IN HCERTSTORE hStore,
  255. IN PCRYPT_INTEGER_BLOB pSerialNumber
  256. )
  257. {
  258. BOOL fResult = TRUE;
  259. PCCERT_CONTEXT pCert;
  260. CERT_INFO CertInfo;
  261. memset(&CertInfo, 0, sizeof(CertInfo));
  262. if (!EncodeIssuer(&CertInfo.Issuer.pbData, &CertInfo.Issuer.cbData))
  263. return NULL;
  264. CertInfo.SerialNumber = *pSerialNumber;
  265. pCert = CertGetSubjectCertificateFromStore(hStore, dwCertEncodingType,
  266. &CertInfo);
  267. if (NULL == pCert)
  268. PrintLastError("GetSubject");
  269. TestFree(CertInfo.Issuer.pbData);
  270. return pCert;
  271. }
  272. static BOOL TestGetSubject(
  273. IN LPSTR pszMsg,
  274. IN HCERTSTORE hStore,
  275. IN DWORD cSerialNumber,
  276. IN CRYPT_INTEGER_BLOB rgSerialNumber[],
  277. IN BOOL rgfExpectedGet[]
  278. )
  279. {
  280. BOOL fResult = TRUE;
  281. DWORD i;
  282. CERT_INFO CertInfo;
  283. memset(&CertInfo, 0, sizeof(CertInfo));
  284. if (!EncodeIssuer(&CertInfo.Issuer.pbData, &CertInfo.Issuer.cbData))
  285. return FALSE;
  286. for (i = 0; i < cSerialNumber; i++) {
  287. PCCERT_CONTEXT pCert;
  288. CertInfo.SerialNumber = rgSerialNumber[i];
  289. pCert = CertGetSubjectCertificateFromStore(hStore, dwCertEncodingType,
  290. &CertInfo);
  291. if (pCert) {
  292. if (!rgfExpectedGet[i]) {
  293. fResult = FALSE;
  294. printf("%s SerialNumber[%d] failed => expected error\n",
  295. pszMsg, i);
  296. }
  297. CertFreeCertificateContext(pCert);
  298. } else if (rgfExpectedGet[i]) {
  299. DWORD dwErr = GetLastError();
  300. fResult = FALSE;
  301. printf("%s SerialNumber[%d] failed => 0x%x (%d) \n", pszMsg, i,
  302. dwErr, dwErr);
  303. }
  304. }
  305. TestFree(CertInfo.Issuer.pbData);
  306. return fResult;
  307. }
  308. static DWORD WINAPI VerifyCertSignThreadProc(
  309. LPVOID lpThreadParameter
  310. )
  311. {
  312. PCCERT_CONTEXT pCert0 = (PCCERT_CONTEXT) lpThreadParameter;
  313. DWORD dwFlags = CERT_STORE_SIGNATURE_FLAG | CERT_STORE_TIME_VALIDITY_FLAG;
  314. if (!CertVerifySubjectCertificateContext(pCert0, pCert0, &dwFlags))
  315. PrintLastError("CertVerifySubjectCertificateContext(Thread, SIGNATURE)");
  316. else if (dwFlags != 0) {
  317. printf("CertVerifySubjectCertificateContext(Thread, SIGNATURE) failed =>");
  318. printf("dwFlags = 0x%x\n", dwFlags);
  319. }
  320. return 0;
  321. }
  322. static BOOL DoTest()
  323. {
  324. BOOL fResult;
  325. DWORD dwErr;
  326. BYTE *pbCertEncoded = NULL;
  327. DWORD cbCertEncoded;
  328. CERT_INFO CertInfo;
  329. memset(&CertInfo, 0, sizeof(CertInfo));
  330. PCCERT_CONTEXT pCert = NULL;
  331. PCCERT_CONTEXT pCert0 = NULL;
  332. PCCERT_CONTEXT pCertDup = NULL;
  333. HCERTSTORE hStore1 = NULL;
  334. HCERTSTORE hStore2 = NULL;
  335. HCERTSTORE hStore3 = NULL;
  336. CRYPT_DATA_BLOB SerializeStore;
  337. memset(&SerializeStore, 0, sizeof(SerializeStore));
  338. HCERTSTORE hSerializeStore = NULL;
  339. CRYPT_DATA_BLOB PKCS7Store;
  340. memset(&PKCS7Store, 0, sizeof(PKCS7Store));
  341. HCERTSTORE hPKCS7Store = NULL;
  342. DWORD i;
  343. DWORD dwFlags;
  344. CRYPT_DATA_BLOB SmallStore;
  345. #define DELTA_LESS_LENGTH 8
  346. BYTE rgbSerial0[] = {0x7f, 0x7e, 0x7d, 0x7c, 0x7b};
  347. BYTE rgbSerial1[] = {0x81, 0x82, 0x83};
  348. BYTE rgbSerial2[] = {0x00, 0x00, 0x7f, 0x7e, 0x7d, 0x7c, 0x7b};
  349. BYTE rgbSerial3[] = {0xFF, 0xFF, 0xFF, 0x81, 0x82, 0x83};
  350. BYTE rgbSerial4[] = {0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x00, 0x00};
  351. BYTE rgbSerial5[] = {0x81, 0x82, 0x83, 0xFF, 0xFF, 0xFF};
  352. BYTE rgbSerial6[] = {0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0xFF};
  353. BYTE rgbSerial7[] = {0x81, 0x82, 0x83, 0x00};
  354. CRYPT_INTEGER_BLOB rgSerialNumber[] = {
  355. sizeof(rgbSerial0), rgbSerial0,
  356. sizeof(rgbSerial1), rgbSerial1,
  357. sizeof(rgbSerial2), rgbSerial2,
  358. sizeof(rgbSerial3), rgbSerial3,
  359. sizeof(rgbSerial4), rgbSerial4,
  360. sizeof(rgbSerial5), rgbSerial5,
  361. sizeof(rgbSerial6), rgbSerial6,
  362. sizeof(rgbSerial7), rgbSerial7,
  363. };
  364. BOOL rgfExpectedGet[] = {
  365. TRUE,
  366. TRUE,
  367. FALSE,
  368. FALSE,
  369. TRUE,
  370. TRUE,
  371. FALSE,
  372. FALSE
  373. };
  374. BOOL rgfDeleteExpectedGet[] = {
  375. TRUE,
  376. FALSE
  377. };
  378. BYTE rgbAux0[] = {0x00};
  379. BYTE rgbAux1[] = {0x11, 0x11};
  380. BYTE rgbAux2[] = {0x22, 0x22, 0x22};
  381. BYTE rgbAux[8];
  382. CRYPT_DATA_BLOB AuxData;
  383. BYTE rgbStoreHash[MAX_HASH_LEN];
  384. DWORD cbStoreHash;
  385. BYTE rgbStoreHash2[MAX_HASH_LEN];
  386. DWORD cbStoreHash2;
  387. BYTE rgbContextHash[MAX_HASH_LEN];
  388. DWORD cbContextHash;
  389. if (!EncodeIssuer(&CertInfo.Issuer.pbData, &CertInfo.Issuer.cbData))
  390. goto ErrorReturn;
  391. if (NULL == (hStore1 = CertOpenSystemStoreW(hCryptProv, L"Test"))) {
  392. PrintLastError("CertOpenSystemStoreW(Test)");
  393. goto ErrorReturn;
  394. }
  395. // Delete all certs in the store
  396. pCert = NULL;
  397. while (pCert = CertEnumCertificatesInStore(hStore1, pCert)) {
  398. PCCERT_CONTEXT pDeleteCert = CertDuplicateCertificateContext(pCert);
  399. CertDeleteCertificateFromStore(pDeleteCert);
  400. }
  401. // Add two certs to the store
  402. for (i = 0; i < 2; i++) {
  403. if (!EncodeCert(&rgSerialNumber[i], &pbCertEncoded, &cbCertEncoded))
  404. goto ErrorReturn;
  405. if (!CertAddEncodedCertificateToStore(
  406. hStore1,
  407. dwCertEncodingType,
  408. pbCertEncoded,
  409. cbCertEncoded,
  410. CERT_STORE_ADD_NEW,
  411. NULL)) { // ppCertContext
  412. PrintLastError("CertAddEncodedCertificateToStore");
  413. goto ErrorReturn;
  414. }
  415. if (0 == i) {
  416. // Create certificate context for future use
  417. if (NULL == (pCert0 = CertCreateCertificateContext(
  418. dwCertEncodingType,
  419. pbCertEncoded,
  420. cbCertEncoded))) {
  421. PrintLastError("CertCreateCertificateContext");
  422. goto ErrorReturn;
  423. }
  424. }
  425. TestFree(pbCertEncoded);
  426. pbCertEncoded = NULL;
  427. }
  428. TestGetSubject(
  429. "Store1",
  430. hStore1,
  431. sizeof(rgSerialNumber)/sizeof(rgSerialNumber[0]),
  432. rgSerialNumber,
  433. rgfExpectedGet
  434. );
  435. // All the certificates should have been pushed through to the
  436. // registry
  437. if (NULL == (hStore2 = CertOpenSystemStoreA(0, "Test"))) {
  438. PrintLastError("CertOpenSystemStoreA(Test)");
  439. goto ErrorReturn;
  440. }
  441. TestGetSubject(
  442. "Store2",
  443. hStore2,
  444. sizeof(rgSerialNumber)/sizeof(rgSerialNumber[0]),
  445. rgSerialNumber,
  446. rgfExpectedGet
  447. );
  448. CertInfo.SerialNumber = rgSerialNumber[4];
  449. // Update different properties on the same certificate via different
  450. // stores
  451. if (NULL == (pCert = CertGetSubjectCertificateFromStore(
  452. hStore1, dwCertEncodingType, &CertInfo))) {
  453. PrintLastError("CertGetSubjectCertificateFromStore");
  454. goto ErrorReturn;
  455. }
  456. AuxData.pbData = rgbAux0;
  457. AuxData.cbData = sizeof(rgbAux0);
  458. if (!CertSetCertificateContextProperty(
  459. pCert,
  460. CERT_FIRST_USER_PROP_ID + 0,
  461. 0, // dwFlags
  462. &AuxData
  463. )) {
  464. PrintLastError("CertSetCertificateContextProperty");
  465. goto ErrorReturn;
  466. }
  467. CertFreeCertificateContext(pCert);
  468. pCert = NULL;
  469. if (NULL == (pCert = CertGetSubjectCertificateFromStore(
  470. hStore2, dwCertEncodingType, &CertInfo))) {
  471. PrintLastError("CertGetSubjectCertificateFromStore");
  472. goto ErrorReturn;
  473. }
  474. AuxData.pbData = rgbAux1;
  475. AuxData.cbData = sizeof(rgbAux1);
  476. if (!CertSetCertificateContextProperty(
  477. pCert,
  478. CERT_FIRST_USER_PROP_ID + 1,
  479. 0, // dwFlags
  480. &AuxData
  481. )) {
  482. PrintLastError("CertSetCertificateContextProperty");
  483. goto ErrorReturn;
  484. }
  485. CertFreeCertificateContext(pCert);
  486. pCert = NULL;
  487. // Reopen store. The properties should have been pushed through
  488. // to the registry.
  489. if (NULL == (hStore3 = CertOpenSystemStoreA(0, "Test"))) {
  490. PrintLastError("CertOpenSystemStoreA(Test)");
  491. goto ErrorReturn;
  492. }
  493. TestGetSubject(
  494. "Store3",
  495. hStore3,
  496. sizeof(rgSerialNumber)/sizeof(rgSerialNumber[0]),
  497. rgSerialNumber,
  498. rgfExpectedGet
  499. );
  500. // Display certs in the store
  501. pCert = NULL;
  502. i = 0;
  503. printf("###### Test Store Certificates Before Delete ######\n");
  504. while (pCert = CertEnumCertificatesInStore(hStore3, pCert)) {
  505. printf("===== %d =====\n", i);
  506. DisplayCert(pCert, DISPLAY_BRIEF_FLAG);
  507. i++;
  508. }
  509. // Save certificates to in memory serialized store and in memory
  510. // PKCS #7 store
  511. if (!CertSaveStore(
  512. hStore3,
  513. 0, // dwCertEncodingType,
  514. CERT_STORE_SAVE_AS_STORE,
  515. CERT_STORE_SAVE_TO_MEMORY,
  516. &SerializeStore,
  517. 0)) { // dwFlags
  518. PrintLastError("CertSaveStore(CERT_STORE_SAVE_AS_STORE)");
  519. goto ErrorReturn;
  520. }
  521. if (NULL == (SerializeStore.pbData = (BYTE *) TestAlloc(
  522. SerializeStore.cbData)))
  523. goto ErrorReturn;
  524. if (!CertSaveStore(
  525. hStore3,
  526. 0, // dwCertEncodingType,
  527. CERT_STORE_SAVE_AS_STORE,
  528. CERT_STORE_SAVE_TO_MEMORY,
  529. &SerializeStore,
  530. 0)) { // dwFlags
  531. PrintLastError("CertSaveStore(CERT_STORE_SAVE_AS_STORE)");
  532. goto ErrorReturn;
  533. }
  534. // The following should fail with ERROR_MORE_DATA
  535. SmallStore = SerializeStore;
  536. SmallStore.cbData -= DELTA_LESS_LENGTH;
  537. if (CertSaveStore(
  538. hStore3,
  539. 0, // dwCertEncodingType,
  540. CERT_STORE_SAVE_AS_STORE,
  541. CERT_STORE_SAVE_TO_MEMORY,
  542. &SmallStore,
  543. 0)) // dwFlags
  544. PrintNoError("CertSaveStore(CERT_STORE_SAVE_AS_STORE, insufficient length)");
  545. else {
  546. DWORD dwErr = GetLastError();
  547. PrintExpectedError("CertSaveStore(CERT_STORE_SAVE_AS_STORE, insufficient length)");
  548. if (ERROR_MORE_DATA != dwErr) {
  549. printf("CertSaveStore(CERT_STORE_SAVE_AS_STORE) failed => ");
  550. printf("LastError = %d, expected = %d\n", dwErr, ERROR_MORE_DATA);
  551. }
  552. }
  553. if (SmallStore.cbData != SerializeStore.cbData) {
  554. printf("CertSaveStore(CERT_STORE_SAVE_AS_STORE) failed => ");
  555. printf("cbData = %d, expected = %d\n",
  556. SmallStore.cbData, SerializeStore.cbData);
  557. } else {
  558. printf("cbData = %d, expected = %d\n",
  559. SmallStore.cbData, SerializeStore.cbData);
  560. }
  561. if (!CertSaveStore(
  562. hStore3,
  563. 0, // dwCertEncodingType,
  564. CERT_STORE_SAVE_AS_STORE,
  565. CERT_STORE_SAVE_TO_MEMORY,
  566. &SerializeStore,
  567. 0)) { // dwFlags
  568. PrintLastError("CertSaveStore(CERT_STORE_SAVE_AS_STORE)");
  569. goto ErrorReturn;
  570. }
  571. if (!CertSaveStore(
  572. hStore3,
  573. dwCertEncodingType | dwMsgEncodingType,
  574. CERT_STORE_SAVE_AS_PKCS7,
  575. CERT_STORE_SAVE_TO_MEMORY,
  576. &PKCS7Store,
  577. 0)) { // dwFlags
  578. PrintLastError("CertSaveStore(CERT_STORE_SAVE_AS_PKCS7)");
  579. goto ErrorReturn;
  580. }
  581. if (NULL == (PKCS7Store.pbData = (BYTE *) TestAlloc(
  582. PKCS7Store.cbData)))
  583. goto ErrorReturn;
  584. if (!CertSaveStore(
  585. hStore3,
  586. dwCertEncodingType | dwMsgEncodingType,
  587. CERT_STORE_SAVE_AS_PKCS7,
  588. CERT_STORE_SAVE_TO_MEMORY,
  589. &PKCS7Store,
  590. 0)) { // dwFlags
  591. PrintLastError("CertSaveStore(CERT_STORE_SAVE_AS_PKCS7)");
  592. goto ErrorReturn;
  593. }
  594. // The following should fail with ERROR_MORE_DATA
  595. SmallStore = PKCS7Store;
  596. SmallStore.cbData -= DELTA_LESS_LENGTH;
  597. if (CertSaveStore(
  598. hStore3,
  599. dwCertEncodingType | dwMsgEncodingType,
  600. CERT_STORE_SAVE_AS_PKCS7,
  601. CERT_STORE_SAVE_TO_MEMORY,
  602. &SmallStore,
  603. 0))
  604. PrintNoError("CertSaveStore(CERT_STORE_SAVE_AS_PKCS7, insufficient length)");
  605. else {
  606. DWORD dwErr = GetLastError();
  607. PrintExpectedError("CertSaveStore(CERT_STORE_SAVE_AS_PKCS7, insufficient length)");
  608. if (ERROR_MORE_DATA != dwErr) {
  609. printf("CertSaveStore(CERT_STORE_SAVE_AS_PKCS7) failed => ");
  610. printf("LastError = %d, expected = %d\n", dwErr, ERROR_MORE_DATA);
  611. }
  612. }
  613. if (SmallStore.cbData != PKCS7Store.cbData) {
  614. printf("CertSaveStore(CERT_STORE_SAVE_AS_PKCS7) failed => ");
  615. printf("cbData = %d, expected = %d\n",
  616. SmallStore.cbData, PKCS7Store.cbData);
  617. } else {
  618. printf("cbData = %d, expected = %d\n",
  619. SmallStore.cbData, PKCS7Store.cbData);
  620. }
  621. if (!CertSaveStore(
  622. hStore3,
  623. dwCertEncodingType | dwMsgEncodingType,
  624. CERT_STORE_SAVE_AS_PKCS7,
  625. CERT_STORE_SAVE_TO_MEMORY,
  626. &PKCS7Store,
  627. 0)) { // dwFlags
  628. PrintLastError("CertSaveStore(CERT_STORE_SAVE_AS_PKCS7)");
  629. goto ErrorReturn;
  630. }
  631. CertCloseStore(hStore3, 0);
  632. hStore3 = NULL;
  633. // Open in memory serialized store.
  634. if (NULL == (hSerializeStore = CertOpenStore(
  635. CERT_STORE_PROV_SERIALIZED,
  636. 0, // dwEncodingType
  637. 0, // hCryptProv
  638. 0, // dwFlags
  639. (const void *) &SerializeStore))) {
  640. PrintLastError("CertOpenStore(SERIALIZED)");
  641. goto ErrorReturn;
  642. }
  643. TestGetSubject(
  644. "SerializeStore",
  645. hSerializeStore,
  646. sizeof(rgSerialNumber)/sizeof(rgSerialNumber[0]),
  647. rgSerialNumber,
  648. rgfExpectedGet
  649. );
  650. // Display certs in the store
  651. pCert = NULL;
  652. i = 0;
  653. printf("###### Serialized Store Certificates ######\n");
  654. while (pCert = CertEnumCertificatesInStore(hSerializeStore, pCert)) {
  655. printf("===== %d =====\n", i);
  656. DisplayCert(pCert, DISPLAY_VERBOSE_FLAG);
  657. i++;
  658. }
  659. // Open in memory PKCS7 store.
  660. if (NULL == (hPKCS7Store = CertOpenStore(
  661. CERT_STORE_PROV_PKCS7,
  662. dwCertEncodingType | dwMsgEncodingType,
  663. 0, // hCryptProv
  664. 0, // dwFlags
  665. (const void *) &PKCS7Store))) {
  666. PrintLastError("CertOpenStore(SERIALIZED)");
  667. goto ErrorReturn;
  668. }
  669. TestGetSubject(
  670. "PKCS7Store",
  671. hPKCS7Store,
  672. sizeof(rgSerialNumber)/sizeof(rgSerialNumber[0]),
  673. rgSerialNumber,
  674. rgfExpectedGet
  675. );
  676. // Display certs in the store
  677. pCert = NULL;
  678. i = 0;
  679. printf("###### PKCS7 Store Certificates ######\n");
  680. while (pCert = CertEnumCertificatesInStore(hPKCS7Store, pCert)) {
  681. printf("===== %d =====\n", i);
  682. DisplayCert(pCert, DISPLAY_VERBOSE_FLAG);
  683. i++;
  684. }
  685. // Delete the certificate in one store and update its property
  686. // in the other store. Should get an error.
  687. CertInfo.SerialNumber = rgSerialNumber[1];
  688. if (NULL == (pCert = CertGetSubjectCertificateFromStore(
  689. hStore1, dwCertEncodingType, &CertInfo))) {
  690. PrintLastError("CertGetSubjectCertificateFromStore");
  691. goto ErrorReturn;
  692. }
  693. if (!CertDeleteCertificateFromStore(pCert)) {
  694. PrintLastError("CertDeleteCertificateFromStore");
  695. goto ErrorReturn;
  696. }
  697. if (NULL == (pCert = CertGetSubjectCertificateFromStore(
  698. hStore2, dwCertEncodingType, &CertInfo))) {
  699. PrintLastError("CertGetSubjectCertificateFromStore");
  700. goto ErrorReturn;
  701. }
  702. AuxData.pbData = rgbAux2;
  703. AuxData.cbData = sizeof(rgbAux2);
  704. if (!CertSetCertificateContextProperty(
  705. pCert,
  706. CERT_FIRST_USER_PROP_ID + 2,
  707. 0, // dwFlags
  708. &AuxData
  709. ))
  710. PrintExpectedError("CertSetCertificateContextProperty(deleted in other store)");
  711. else
  712. PrintNoError("CertSetCertificateContextProperty(deleted in other store)");
  713. CertFreeCertificateContext(pCert);
  714. pCert = NULL;
  715. // Reopen store. The certificate delete should have pushed through
  716. // to the registry.
  717. if (NULL == (hStore3 = CertOpenSystemStoreA(0, "Test"))) {
  718. PrintLastError("CertOpenSystemStoreA(Test)");
  719. goto ErrorReturn;
  720. }
  721. TestGetSubject(
  722. "After Delete Store3",
  723. hStore3,
  724. sizeof(rgfDeleteExpectedGet)/sizeof(rgfDeleteExpectedGet[0]),
  725. rgSerialNumber,
  726. rgfDeleteExpectedGet
  727. );
  728. // Display certs in the store
  729. pCert = NULL;
  730. i = 0;
  731. printf("###### Test Store Certificates After Delete ######\n");
  732. while (pCert = CertEnumCertificatesInStore(hStore3, pCert)) {
  733. printf("===== %d =====\n", i);
  734. DisplayCert(pCert, DISPLAY_VERBOSE_FLAG);
  735. i++;
  736. }
  737. // Check that we can get the hash property for a created context.
  738. // Compare with the hash of the same certificate in a store.
  739. CertInfo.SerialNumber = rgSerialNumber[0];
  740. if (NULL == (pCert = CertGetSubjectCertificateFromStore(
  741. hSerializeStore, dwCertEncodingType, &CertInfo))) {
  742. PrintLastError("CertGetSubjectCertificateFromStore(SerializeStore)");
  743. goto ErrorReturn;
  744. }
  745. cbStoreHash = MAX_HASH_LEN;
  746. if (!CertGetCertificateContextProperty(pCert, CERT_SHA1_HASH_PROP_ID,
  747. rgbStoreHash, &cbStoreHash)) {
  748. PrintLastError("CertGetCertificateContextProperty(SerializeStore)");
  749. goto ErrorReturn;
  750. }
  751. cbContextHash = MAX_HASH_LEN;
  752. if (!CertGetCertificateContextProperty(pCert0, CERT_SHA1_HASH_PROP_ID,
  753. rgbContextHash, &cbContextHash))
  754. PrintLastError("CertGetCertificateContextProperty(created context)");
  755. else if (cbContextHash != cbStoreHash ||
  756. 0 != memcmp(rgbContextHash, rgbStoreHash, cbContextHash)) {
  757. printf("CertGetCertificateContextProperty(created context) failed => ");
  758. printf("hash didn't compare with store's hash\n");
  759. }
  760. // Do a CertVerifySubjectCertificateContext for a
  761. // certificate in a store and a certificate context.
  762. // Should pass for both a store certificate and
  763. // a certificate context. The certificate context
  764. // uses the default provider.
  765. dwFlags = CERT_STORE_SIGNATURE_FLAG | CERT_STORE_TIME_VALIDITY_FLAG;
  766. if (!CertVerifySubjectCertificateContext(pCert, pCert, &dwFlags))
  767. PrintLastError("CertVerifySubjectCertificateContext(in store)");
  768. else if (dwFlags != 0) {
  769. printf("CertVerifySubjectCertificateContext(in store) failed =>");
  770. printf("dwFlags = 0x%x\n", dwFlags);
  771. }
  772. dwFlags = CERT_STORE_TIME_VALIDITY_FLAG;
  773. if (!CertVerifySubjectCertificateContext(pCert0, pCert0, &dwFlags))
  774. PrintLastError("CertVerifySubjectCertificateContext(context, TIME_VALIDITY)");
  775. else if (dwFlags != 0) {
  776. printf("CertVerifySubjectCertificateContext(context, TIME_VALIDITY) failed =>");
  777. printf("dwFlags = 0x%x\n", dwFlags);
  778. }
  779. dwFlags = CERT_STORE_SIGNATURE_FLAG | CERT_STORE_TIME_VALIDITY_FLAG;
  780. if (!CertVerifySubjectCertificateContext(pCert0, pCert0, &dwFlags))
  781. PrintLastError("CertVerifySubjectCertificateContext(context, SIGNATURE)");
  782. else if (dwFlags != 0) {
  783. printf("CertVerifySubjectCertificateContext(context, SIGNATURE) failed =>");
  784. printf("dwFlags = 0x%x\n", dwFlags);
  785. }
  786. {
  787. // Install DefaultContext applicable to all threads in process.
  788. // Create another thread that does the verify. For testing purposes,
  789. // will modify the CryptVerifyCertificateSignature to sleep while
  790. // holding a refCount on the DefaultContext. Will do an Uninstall
  791. // that should cause us to wait until the Verify returns.
  792. HCRYPTPROV hProv = 0;
  793. if (!CryptAcquireContext(
  794. &hProv,
  795. NULL, // pszContainer
  796. NULL, // pszProvider,
  797. PROV_RSA_FULL,
  798. CRYPT_VERIFYCONTEXT // dwFlags
  799. )) {
  800. PrintLastError(
  801. "CryptAcquireContext(PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)");
  802. } else {
  803. HCRYPTDEFAULTCONTEXT hDefaultContext;
  804. if (!CryptInstallDefaultContext(
  805. hProv,
  806. CRYPT_DEFAULT_CONTEXT_CERT_SIGN_OID,
  807. (const void *) szOID_RSA_MD5RSA,
  808. CRYPT_DEFAULT_CONTEXT_PROCESS_FLAG,
  809. NULL, // pvReserved
  810. &hDefaultContext
  811. )) {
  812. PrintLastError("CryptInstallDefaultContext");
  813. } else {
  814. HANDLE hThread;
  815. DWORD dwThreadId;
  816. if (NULL == (hThread = CreateThread(
  817. NULL, // lpThreadAttributes
  818. 0, // dwStackSize
  819. VerifyCertSignThreadProc,
  820. (void *) pCert0,
  821. 0, // dwCreationFlags
  822. &dwThreadId
  823. )))
  824. PrintLastError("CreateThread");
  825. else
  826. CloseHandle(hThread);
  827. Sleep(500);
  828. if (!CryptUninstallDefaultContext(
  829. hDefaultContext,
  830. 0, // dwFlags
  831. NULL // pvReserved
  832. ))
  833. PrintLastError("CryptUninstallDefaultContext");
  834. }
  835. CryptReleaseContext(hProv, 0);
  836. }
  837. }
  838. // Close a store with a not freed certificate context. Should get a warning
  839. // at closing.
  840. fResult = CertCloseStore(hSerializeStore, CERT_CLOSE_STORE_CHECK_FLAG);
  841. hSerializeStore = NULL;
  842. if (fResult)
  843. PrintNoError("CertCloseStore(with not freed certificate)");
  844. else
  845. PrintExpectedError("CertCloseStore(with not freed certificate)");
  846. // Delete and recalculate the hash property for a certificate context
  847. // after the store has been closed.
  848. if (!CertSetCertificateContextProperty(
  849. pCert,
  850. CERT_SHA1_HASH_PROP_ID,
  851. 0, // dwFlags
  852. NULL // pvData
  853. ))
  854. PrintLastError("CertSetCertificateContextProperty(SHA1, delete after close store)");
  855. cbStoreHash2 = MAX_HASH_LEN;
  856. if (!CertGetCertificateContextProperty(pCert, CERT_SHA1_HASH_PROP_ID,
  857. rgbStoreHash2, &cbStoreHash2))
  858. PrintLastError("CertGetCertificateContextProperty(SHA1, after close store)");
  859. else if (cbStoreHash2 != cbStoreHash ||
  860. 0 != memcmp(rgbStoreHash2, rgbStoreHash, cbStoreHash2)) {
  861. printf("CertGetCertificateContextProperty(SHA1, after close store) failed => ");
  862. printf("hash didn't compare with store's hash\n");
  863. }
  864. // Delete the certificate context after the store has been closed
  865. if (!CertDeleteCertificateFromStore(pCert))
  866. PrintLastError("CertDeleteCertificateFromStore(after close store)");
  867. pCert = NULL;
  868. // Duplicate a certificate. Delete it from the store. Also delete its
  869. // duplicate. Close the store.
  870. if (NULL == (pCert = CertGetSubjectCertificateFromStore(
  871. hPKCS7Store, dwCertEncodingType, &CertInfo))) {
  872. PrintLastError("CertGetSubjectCertificateFromStore(PKCS7)");
  873. goto ErrorReturn;
  874. }
  875. pCertDup = CertDuplicateCertificateContext(pCert);
  876. if (!CertDeleteCertificateFromStore(pCert))
  877. PrintLastError("CertDeleteCertificateFromStore(PKCS7)");
  878. pCert = NULL;
  879. if (!CertDeleteCertificateFromStore(pCertDup))
  880. PrintLastError("CertDeleteCertificateFromStore(PKCS7, duplicated cert)");
  881. pCertDup = NULL;
  882. // Also check that last error is preserved for no errors
  883. #define EXPECTED_LAST_ERROR 0x11223344
  884. SetLastError(EXPECTED_LAST_ERROR);
  885. fResult = CertCloseStore(hPKCS7Store, CERT_CLOSE_STORE_CHECK_FLAG);
  886. hPKCS7Store = NULL;
  887. if (!fResult)
  888. PrintError("CertCloseStore(PKCS7, after two deletes)");
  889. else if (EXPECTED_LAST_ERROR != (dwErr = GetLastError())) {
  890. printf("CertCloseStore failed => globbered last error.");
  891. printf(" Expected 0x%x (%d), got 0x%x (%d)\n",
  892. EXPECTED_LAST_ERROR, EXPECTED_LAST_ERROR, dwErr, dwErr);
  893. }
  894. fResult = TRUE;
  895. CommonReturn:
  896. if (pbCertEncoded)
  897. TestFree(pbCertEncoded);
  898. if (CertInfo.Issuer.pbData)
  899. TestFree(CertInfo.Issuer.pbData);
  900. if (SerializeStore.pbData)
  901. TestFree(SerializeStore.pbData);
  902. if (PKCS7Store.pbData)
  903. TestFree(PKCS7Store.pbData);
  904. if (hStore1)
  905. CertCloseStore(hStore1, 0);
  906. if (hStore2)
  907. CertCloseStore(hStore2, 0);
  908. if (hStore3)
  909. CertCloseStore(hStore3, 0);
  910. if (hSerializeStore)
  911. CertCloseStore(hSerializeStore, 0);
  912. if (hPKCS7Store)
  913. CertCloseStore(hPKCS7Store, 0);
  914. if (pCert)
  915. CertFreeCertificateContext(pCert);
  916. if (pCert0)
  917. CertFreeCertificateContext(pCert0);
  918. if (pCertDup)
  919. CertFreeCertificateContext(pCertDup);
  920. return fResult;
  921. ErrorReturn:
  922. fResult = FALSE;
  923. goto CommonReturn;
  924. }
  925. static BOOL DoWin95Test()
  926. {
  927. #define WIN95_ADD_CERT_CNT 8
  928. #define WIN95_ADD_CB_PROP 10000
  929. #define WIN95_STORE_CNT 2
  930. LPWSTR rgpwszStore[WIN95_STORE_CNT] = {
  931. L"Test0",
  932. L"Test1"
  933. };
  934. #define WIN95_PROP_CNT 5
  935. DWORD rgcbProp[WIN95_PROP_CNT][WIN95_STORE_CNT] = {
  936. 100, 200, // 0
  937. 0x5000, 0x6000, // 1
  938. 0x1000, 0x6300, // 2
  939. 0x30, 0x300, // 3
  940. 0x4300, 0x4200 // 4
  941. };
  942. DWORD dwSerialNumber;
  943. CRYPT_INTEGER_BLOB SerialNumber = {
  944. sizeof(dwSerialNumber), (BYTE *) &dwSerialNumber
  945. };
  946. BOOL fResult;
  947. BYTE *pbCertEncoded = NULL;
  948. DWORD cbCertEncoded;
  949. PCCERT_CONTEXT pCert = NULL;
  950. HCERTSTORE hStore = NULL;
  951. CRYPT_DATA_BLOB Prop;
  952. BYTE *pbProp = NULL;
  953. DWORD cbProp;
  954. DWORD cb;
  955. DWORD i, j, k;
  956. DWORD cAdd;
  957. if (NULL == (hStore = CertOpenSystemStoreW(NULL, L"Test"))) {
  958. PrintLastError("CertOpenSystemStoreW");
  959. goto ErrorReturn;
  960. }
  961. // Delete all certs in the store
  962. pCert = NULL;
  963. while (pCert = CertEnumCertificatesInStore(hStore, pCert)) {
  964. PCCERT_CONTEXT pDeleteCert = CertDuplicateCertificateContext(pCert);
  965. CertDeleteCertificateFromStore(pDeleteCert);
  966. }
  967. if (NULL == (pbProp = (BYTE *) TestAlloc(
  968. WIN95_ADD_CB_PROP + WIN95_ADD_CERT_CNT)))
  969. goto ErrorReturn;
  970. // Add certs each having a property of 10,000 + cAdd bytes in length
  971. for (cAdd = 0; cAdd < WIN95_ADD_CERT_CNT; cAdd++) {
  972. dwSerialNumber = cAdd;
  973. if (!EncodeCert(&SerialNumber, &pbCertEncoded, &cbCertEncoded))
  974. goto ErrorReturn;
  975. // Add encoded certificate to store.
  976. fResult = CertAddEncodedCertificateToStore(
  977. hStore,
  978. dwCertEncodingType,
  979. pbCertEncoded,
  980. cbCertEncoded,
  981. CERT_STORE_ADD_NEW,
  982. &pCert);
  983. TestFree(pbCertEncoded);
  984. pbCertEncoded = NULL;
  985. if (!fResult) {
  986. printf("AddEncodedCertificate[%d]", cAdd);
  987. PrintLastError("");
  988. break;
  989. }
  990. Prop.pbData = pbProp;
  991. Prop.cbData = WIN95_ADD_CB_PROP + cAdd;
  992. for (k = 0; k < WIN95_ADD_CB_PROP + cAdd; k++)
  993. pbProp[k] = (BYTE) cAdd;
  994. fResult = CertSetCertificateContextProperty(
  995. pCert,
  996. CERT_FIRST_USER_PROP_ID,
  997. 0, // dwFlags
  998. &Prop
  999. );
  1000. CertFreeCertificateContext(pCert);
  1001. pCert = NULL;
  1002. if (!fResult) {
  1003. printf("SetProperty for AddedCertificate[%d]", cAdd);
  1004. PrintLastError("");
  1005. break;
  1006. }
  1007. }
  1008. CertCloseStore(hStore, 0);
  1009. hStore = NULL;
  1010. // Verify that we can successfully read the added certs.
  1011. if (NULL == (hStore = CertOpenSystemStoreW(NULL, L"Test"))) {
  1012. PrintLastError("CertOpenSystemStoreW");
  1013. goto ErrorReturn;
  1014. }
  1015. while (cAdd--) {
  1016. dwSerialNumber = cAdd;
  1017. pCert = GetSubject(hStore, &SerialNumber);
  1018. if (NULL == pCert) {
  1019. printf("GetAddedCertificate[%d]\n", cAdd);
  1020. PrintLastError("");
  1021. } else {
  1022. cbProp = WIN95_ADD_CB_PROP + WIN95_ADD_CERT_CNT;
  1023. if (!CertGetCertificateContextProperty(
  1024. pCert,
  1025. CERT_FIRST_USER_PROP_ID,
  1026. pbProp,
  1027. &cbProp)) {
  1028. printf("GetProperty for AddedCertificate[%d]", cAdd);
  1029. PrintLastError("");
  1030. } else if (cbProp != WIN95_ADD_CB_PROP + cAdd) {
  1031. printf("GetProperty for AddedCertificate[%d] failed => ", cAdd);
  1032. printf("cbProp = %d, not expected = %d\n",
  1033. cbProp, WIN95_ADD_CB_PROP + cAdd);
  1034. } else {
  1035. for (k = 0; k < cbProp; k++) {
  1036. if (pbProp[k] != (BYTE) cAdd) {
  1037. printf("GetProperty for AddedCertificate[%d] failed => ", cAdd);
  1038. printf("not expected value\n");
  1039. break;
  1040. }
  1041. }
  1042. }
  1043. CertFreeCertificateContext(pCert);
  1044. pCert = NULL;
  1045. }
  1046. }
  1047. CertCloseStore(hStore, 0);
  1048. hStore = NULL;
  1049. TestFree(pbProp);
  1050. pbProp = NULL;
  1051. dwSerialNumber = 0x12345678;
  1052. if (!EncodeCert(&SerialNumber, &pbCertEncoded, &cbCertEncoded))
  1053. goto ErrorReturn;
  1054. for (j = 0; j < WIN95_STORE_CNT; j++) {
  1055. if (NULL == (hStore = CertOpenSystemStoreW(
  1056. NULL, rgpwszStore[j]))) {
  1057. printf("%s => ", rgpwszStore[j]);
  1058. PrintLastError("CertOpenSystemStoreW");
  1059. goto ErrorReturn;
  1060. }
  1061. // Delete all certs in the store
  1062. pCert = NULL;
  1063. while (pCert = CertEnumCertificatesInStore(hStore, pCert)) {
  1064. PCCERT_CONTEXT pDeleteCert = CertDuplicateCertificateContext(pCert);
  1065. CertDeleteCertificateFromStore(pDeleteCert);
  1066. }
  1067. // Add encoded certificate to store.
  1068. if (!CertAddEncodedCertificateToStore(
  1069. hStore,
  1070. dwCertEncodingType,
  1071. pbCertEncoded,
  1072. cbCertEncoded,
  1073. CERT_STORE_ADD_NEW,
  1074. &pCert)) { // ppCertContext
  1075. printf("%s => ", rgpwszStore[j]);
  1076. PrintLastError("CertAddEncodedCertificateToStore");
  1077. goto ErrorReturn;
  1078. }
  1079. cb = rgcbProp[0][j];
  1080. if (NULL == (pbProp = (BYTE *) TestAlloc(cb)))
  1081. goto ErrorReturn;
  1082. Prop.pbData = pbProp;
  1083. Prop.cbData = cb;
  1084. for (k = 0; k < cb; k++)
  1085. pbProp[k] = (BYTE) (j + 1);
  1086. if (!CertSetCertificateContextProperty(
  1087. pCert,
  1088. CERT_FIRST_USER_PROP_ID,
  1089. 0, // dwFlags
  1090. &Prop
  1091. )) {
  1092. printf("%s => ", rgpwszStore[j]);
  1093. PrintLastError("CertSetCertificateContextProperty");
  1094. goto ErrorReturn;
  1095. }
  1096. TestFree(pbProp);
  1097. pbProp = NULL;
  1098. CertFreeCertificateContext(pCert);
  1099. pCert = NULL;
  1100. CertCloseStore(hStore, 0);
  1101. hStore = NULL;
  1102. }
  1103. TestFree(pbCertEncoded);
  1104. pbCertEncoded = NULL;
  1105. // Loop and read previous property. compare. write new property.
  1106. for (i = 1; i < WIN95_PROP_CNT; i++) {
  1107. for (j = 0; j < WIN95_STORE_CNT; j++) {
  1108. if (NULL == (hStore = CertOpenSystemStoreW(
  1109. NULL, rgpwszStore[j]))) {
  1110. printf("Prop[%d] Store[%d] ", i, j);
  1111. PrintLastError("CertOpenSystemStoreW");
  1112. goto ErrorReturn;
  1113. }
  1114. pCert = GetSubject(hStore, &SerialNumber);
  1115. if (NULL == pCert) {
  1116. printf("Prop[%d] Store[%d] ", i, j);
  1117. PrintLastError("GetSubject");
  1118. goto ErrorReturn;
  1119. }
  1120. if (!CertGetCertificateContextProperty(
  1121. pCert,
  1122. CERT_FIRST_USER_PROP_ID,
  1123. NULL, // pbProp
  1124. &cbProp)) {
  1125. printf("Prop[%d] Store[%d] ", i, j);
  1126. PrintLastError("CertGetCertificateContextProperty");
  1127. goto ErrorReturn;
  1128. }
  1129. cb = rgcbProp[i-1][j];
  1130. if (cbProp != cb) {
  1131. printf("Prop[%d] Store[%d] ", i, j);
  1132. printf("GetProperty failed => ");
  1133. printf("cbProp = %d, not expected = %d\n", cbProp, cb);
  1134. goto ErrorReturn;
  1135. }
  1136. if (NULL == (pbProp = (BYTE *) TestAlloc(cbProp)))
  1137. goto ErrorReturn;
  1138. if (!CertGetCertificateContextProperty(
  1139. pCert,
  1140. CERT_FIRST_USER_PROP_ID,
  1141. pbProp,
  1142. &cbProp)) {
  1143. printf("Prop[%d] Store[%d] ", i, j);
  1144. PrintLastError("CertGetCertificateContextProperty");
  1145. goto ErrorReturn;
  1146. }
  1147. for (k = 0; k < cbProp; k++) {
  1148. if (pbProp[k] != (BYTE) (j + 1)) {
  1149. printf("Prop[%d] Store[%d] ", i, j);
  1150. printf("GetProperty failed => ");
  1151. printf("not expected value\n");
  1152. goto ErrorReturn;
  1153. }
  1154. }
  1155. TestFree(pbProp);
  1156. pbProp = NULL;
  1157. cb = rgcbProp[i][j];
  1158. if (NULL == (pbProp = (BYTE *) TestAlloc(cb)))
  1159. goto ErrorReturn;
  1160. Prop.pbData = pbProp;
  1161. Prop.cbData = cb;
  1162. for (k = 0; k < cb; k++)
  1163. pbProp[k] = (BYTE) (j + 1);
  1164. if (!CertSetCertificateContextProperty(
  1165. pCert,
  1166. CERT_FIRST_USER_PROP_ID,
  1167. 0, // dwFlags
  1168. &Prop
  1169. )) {
  1170. printf("Prop[%d] Store[%d] cb=%d ", i, j, cb);
  1171. PrintLastError("CertSetCertificateContextProperty");
  1172. goto ErrorReturn;
  1173. }
  1174. TestFree(pbProp);
  1175. pbProp = NULL;
  1176. CertFreeCertificateContext(pCert);
  1177. pCert = NULL;
  1178. CertCloseStore(hStore, 0);
  1179. hStore = NULL;
  1180. }
  1181. }
  1182. fResult = TRUE;
  1183. CommonReturn:
  1184. TestFree(pbProp);
  1185. TestFree(pbCertEncoded);
  1186. if (hStore)
  1187. CertCloseStore(hStore, 0);
  1188. if (pCert)
  1189. CertFreeCertificateContext(pCert);
  1190. return fResult;
  1191. ErrorReturn:
  1192. fResult = FALSE;
  1193. goto CommonReturn;
  1194. }
  1195. static BOOL DoDeferCloseTest()
  1196. {
  1197. BOOL fResult;
  1198. BYTE rgbSerial[] = {0x7f, 0x7e, 0x7d, 0x7c, 0x7b};
  1199. CRYPT_INTEGER_BLOB SerialNumber = {
  1200. sizeof(rgbSerial), rgbSerial
  1201. };
  1202. HCERTSTORE hStore = NULL;
  1203. PCCERT_CONTEXT pCert = NULL;
  1204. BYTE *pbCertEncoded = NULL;
  1205. DWORD cbCertEncoded;
  1206. if (!EncodeCert(&SerialNumber, &pbCertEncoded, &cbCertEncoded))
  1207. goto ErrorReturn;
  1208. // ---------------------------------------------------------------------
  1209. // Do defer close with no duplicated contexts
  1210. // ---------------------------------------------------------------------
  1211. if (NULL == (hStore = CertOpenStore(
  1212. CERT_STORE_PROV_MEMORY,
  1213. 0, // dwEncodingType
  1214. 0, // hCryptProv
  1215. CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG,
  1216. NULL))) { // pvPara
  1217. PrintLastError("CertOpenStore(MEMORY, DEFER)");
  1218. goto ErrorReturn;
  1219. }
  1220. if (!CertAddEncodedCertificateToStore(
  1221. hStore,
  1222. dwCertEncodingType,
  1223. pbCertEncoded,
  1224. cbCertEncoded,
  1225. CERT_STORE_ADD_NEW,
  1226. NULL)) { // ppCertContext
  1227. PrintLastError("CertAddEncodedCertificateToStore");
  1228. goto ErrorReturn;
  1229. }
  1230. fResult = CertCloseStore(hStore, CERT_CLOSE_STORE_CHECK_FLAG);
  1231. hStore = NULL;
  1232. if (fResult)
  1233. printf("Defer close with no duplicated contexts\n");
  1234. else
  1235. PrintLastError("CertCloseStore(DEFER, no duplicated contexts");
  1236. // ---------------------------------------------------------------------
  1237. // Do defer close with duplicated contexts
  1238. // ---------------------------------------------------------------------
  1239. if (NULL == (hStore = CertOpenStore(
  1240. CERT_STORE_PROV_MEMORY,
  1241. 0, // dwEncodingType
  1242. 0, // hCryptProv
  1243. CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG,
  1244. NULL))) { // pvPara
  1245. PrintLastError("CertOpenStore(MEMORY, DEFER)");
  1246. goto ErrorReturn;
  1247. }
  1248. if (!CertAddEncodedCertificateToStore(
  1249. hStore,
  1250. dwCertEncodingType,
  1251. pbCertEncoded,
  1252. cbCertEncoded,
  1253. CERT_STORE_ADD_NEW,
  1254. &pCert)) { // ppCertContext
  1255. PrintLastError("CertAddEncodedCertificateToStore");
  1256. goto ErrorReturn;
  1257. }
  1258. fResult = CertCloseStore(hStore, CERT_CLOSE_STORE_CHECK_FLAG);
  1259. hStore = NULL;
  1260. if (fResult)
  1261. PrintExpectedError("CertCloseStore(DEFER, with duplicated certificate)");
  1262. else
  1263. printf("Defer close with duplicated contexts\n");
  1264. CertFreeCertificateContext(pCert);
  1265. pCert = NULL;
  1266. // ---------------------------------------------------------------------
  1267. // Do context delete after a defer close
  1268. // ---------------------------------------------------------------------
  1269. if (NULL == (hStore = CertOpenStore(
  1270. CERT_STORE_PROV_MEMORY,
  1271. 0, // dwEncodingType
  1272. 0, // hCryptProv
  1273. CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG,
  1274. NULL))) { // pvPara
  1275. PrintLastError("CertOpenStore(MEMORY, DEFER)");
  1276. goto ErrorReturn;
  1277. }
  1278. if (!CertAddEncodedCertificateToStore(
  1279. hStore,
  1280. dwCertEncodingType,
  1281. pbCertEncoded,
  1282. cbCertEncoded,
  1283. CERT_STORE_ADD_NEW,
  1284. &pCert)) { // ppCertContext
  1285. PrintLastError("CertAddEncodedCertificateToStore");
  1286. goto ErrorReturn;
  1287. }
  1288. fResult = CertCloseStore(hStore, CERT_CLOSE_STORE_CHECK_FLAG);
  1289. hStore = NULL;
  1290. if (fResult)
  1291. PrintExpectedError("CertCloseStore(DEFER, with duplicated certificate)");
  1292. else
  1293. printf("Defer close with context to be deleted after\n");
  1294. CertDeleteCertificateFromStore(pCert);
  1295. pCert = NULL;
  1296. fResult = TRUE;
  1297. CommonReturn:
  1298. TestFree(pbCertEncoded);
  1299. if (hStore)
  1300. CertCloseStore(hStore, 0);
  1301. if (pCert)
  1302. CertFreeCertificateContext(pCert);
  1303. return fResult;
  1304. ErrorReturn:
  1305. fResult = FALSE;
  1306. goto CommonReturn;
  1307. }
  1308. int _cdecl main(int argc, char * argv[])
  1309. {
  1310. printf("command line: %s\n", GetCommandLine());
  1311. hCryptProv = GetCryptProv();
  1312. if (hCryptProv == 0)
  1313. return -1;
  1314. DoTest();
  1315. DoWin95Test();
  1316. DoDeferCloseTest();
  1317. CryptReleaseContext(hCryptProv, 0);
  1318. printf("Done.\n");
  1319. return 0;
  1320. }