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.

1033 lines
29 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1995 - 1998
  6. //
  7. // File: tkeyid.cpp
  8. //
  9. // Contents: Key Identifier Property Tests
  10. //
  11. // See Usage() for a list of test options.
  12. //
  13. //
  14. // Functions: main
  15. //
  16. // History: 15-Mar-98 philh created
  17. //--------------------------------------------------------------------------
  18. #include <windows.h>
  19. #include <assert.h>
  20. #include "wincrypt.h"
  21. #include "certtest.h"
  22. #include "unicode.h"
  23. #include <stdlib.h>
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <memory.h>
  27. #include <time.h>
  28. static BOOL fVerify = FALSE;
  29. static void Usage(void)
  30. {
  31. printf("Usage: tkeyid [options] <TestName>\n");
  32. printf("\n");
  33. printf("Options are:\n");
  34. printf(" -c<Cert Filename> - Key Identifier obtained from cert\n");
  35. printf(" -k<Hash> - Key Identifier Hash\n");
  36. printf(" -s<SystemStore> - Get cert properties from system store\n");
  37. printf(" -S<FileSystemStore> - Get cert properties from file store\n");
  38. printf(" -p<Number> - Property Id\n");
  39. printf(" -M[<ComputerName>] - LocalMachine Key Identifiers\n");
  40. printf(" -f<Number> - Flags\n");
  41. printf(" -V - Verify KeyProvInfo property\n");
  42. printf(" -h - This message\n");
  43. printf(" -b - Brief\n");
  44. printf(" -v - Verbose\n");
  45. printf("\n");
  46. printf("TestNames (case insensitive):\n");
  47. printf(" Set\n");
  48. printf(" Get\n");
  49. printf(" Delete\n");
  50. printf(" DeleteAll\n");
  51. printf(" DeleteWithoutCert\n");
  52. printf(" Enum\n");
  53. printf("\n");
  54. }
  55. static PCCERT_CONTEXT ReadCert(
  56. IN LPSTR pszCert
  57. )
  58. {
  59. BOOL fResult;
  60. BYTE *pbEncoded;
  61. DWORD cbEncoded;
  62. PCCERT_CONTEXT pCert;
  63. if (!ReadDERFromFile(pszCert, &pbEncoded, &cbEncoded)) {
  64. PrintLastError("ReadCert");
  65. return NULL;
  66. }
  67. pCert = CertCreateCertificateContext(
  68. dwCertEncodingType,
  69. pbEncoded,
  70. cbEncoded
  71. );
  72. if (pCert == NULL)
  73. PrintLastError("CertCreateCertificateContext");
  74. TestFree(pbEncoded);
  75. return pCert;
  76. }
  77. static BOOL TestSet(
  78. IN const CRYPT_HASH_BLOB *pKeyIdentifier,
  79. IN PCCERT_CONTEXT pCert,
  80. IN DWORD dwPropId,
  81. IN DWORD dwFlags,
  82. IN OPTIONAL LPCWSTR pwszComputerName
  83. )
  84. {
  85. BOOL fResult = TRUE;
  86. if (0 == dwPropId) {
  87. BOOL fProp = FALSE;
  88. // Copy all the certificate properties to the KeyIdentifier
  89. while (dwPropId = CertEnumCertificateContextProperties(
  90. pCert, dwPropId)) {
  91. fProp = TRUE;
  92. fResult &= TestSet(
  93. pKeyIdentifier,
  94. pCert,
  95. dwPropId,
  96. dwFlags,
  97. pwszComputerName
  98. );
  99. }
  100. if (!fProp)
  101. printf("Certificate doesn't have any properties\n");
  102. } else {
  103. // Attempt to get and copy the specified certificate property
  104. // to the KeyIdentifier.
  105. void *pvData = NULL;
  106. DWORD cbData;
  107. CRYPT_DATA_BLOB DataBlob;
  108. void *pvSetData;
  109. printf("Setting PropId %d (0x%x)\n", dwPropId, dwPropId);
  110. if (!CertGetCertificateContextProperty(
  111. pCert,
  112. dwPropId,
  113. NULL, // pvData
  114. &cbData
  115. )) {
  116. PrintLastError("CertGetCertificateContextProperty");
  117. goto ErrorReturn;
  118. }
  119. if (cbData) {
  120. if (NULL == (pvData = TestAlloc(cbData)))
  121. goto ErrorReturn;
  122. if (!CertGetCertificateContextProperty(
  123. pCert,
  124. dwPropId,
  125. pvData,
  126. &cbData
  127. )) {
  128. PrintLastError("CertGetCertificateContextProperty");
  129. TestFree(pvData);
  130. goto ErrorReturn;
  131. }
  132. }
  133. if (CERT_KEY_PROV_INFO_PROP_ID != dwPropId) {
  134. DataBlob.pbData = (BYTE *) pvData;
  135. DataBlob.cbData = cbData;
  136. pvSetData = &DataBlob;
  137. } else
  138. pvSetData = pvData;
  139. fResult = CryptSetKeyIdentifierProperty(
  140. pKeyIdentifier,
  141. dwPropId,
  142. dwFlags,
  143. pwszComputerName,
  144. NULL, // pvReserved
  145. pvSetData
  146. );
  147. TestFree(pvData);
  148. if (!fResult)
  149. PrintLastError("CryptSetKeyIdentifierProperty");
  150. }
  151. CommonReturn:
  152. return fResult;
  153. ErrorReturn:
  154. fResult = FALSE;
  155. goto CommonReturn;
  156. }
  157. static BOOL TestDelete(
  158. IN const CRYPT_HASH_BLOB *pKeyIdentifier,
  159. IN DWORD dwPropId,
  160. IN DWORD dwFlags,
  161. IN OPTIONAL LPCWSTR pwszComputerName
  162. )
  163. {
  164. BOOL fResult;
  165. if (0 == dwPropId) {
  166. printf("Deleting KeyIdentifier and all its properties\n");
  167. dwFlags |= CRYPT_KEYID_DELETE_FLAG;
  168. } else
  169. printf("Deleting PropId %d (0x%x)\n", dwPropId, dwPropId);
  170. fResult = CryptSetKeyIdentifierProperty(
  171. pKeyIdentifier,
  172. dwPropId,
  173. dwFlags,
  174. pwszComputerName,
  175. NULL, // pvReserved
  176. NULL // pvData
  177. );
  178. if (!fResult) {
  179. DWORD dwErr = GetLastError();
  180. if (ERROR_FILE_NOT_FOUND == dwErr)
  181. fResult = TRUE;
  182. if (!fResult)
  183. PrintLastError("CryptSetKeyIdentifierProperty");
  184. }
  185. return fResult;
  186. }
  187. static void VerifyKeyProvInfo(
  188. IN const CRYPT_HASH_BLOB *pKeyIdentifier,
  189. IN PCRYPT_KEY_PROV_INFO pKeyProvInfo
  190. )
  191. {
  192. BOOL fResult;
  193. DWORD dwErr;
  194. DWORD dwAcquireFlags;
  195. HCRYPTPROV hCryptProv = 0;
  196. HCRYPTKEY hPubKey = 0;
  197. PUBLICKEYSTRUC *pPubKeyStruc = NULL;
  198. DWORD cbPubKeyStruc;
  199. BYTE rgbHash[MAX_HASH_LEN];
  200. DWORD cbHash;
  201. dwAcquireFlags = pKeyProvInfo->dwFlags & ~CERT_SET_KEY_CONTEXT_PROP_ID;
  202. fResult = CryptAcquireContextU(
  203. &hCryptProv,
  204. pKeyProvInfo->pwszContainerName,
  205. pKeyProvInfo->pwszProvName,
  206. pKeyProvInfo->dwProvType,
  207. dwAcquireFlags
  208. );
  209. if (!fResult && PROV_RSA_FULL == pKeyProvInfo->dwProvType &&
  210. (NULL == pKeyProvInfo->pwszProvName ||
  211. L'\0' == *pKeyProvInfo->pwszProvName)) {
  212. dwErr = GetLastError();
  213. fResult = CryptAcquireContextU(
  214. &hCryptProv,
  215. pKeyProvInfo->pwszContainerName,
  216. MS_ENHANCED_PROV_W,
  217. PROV_RSA_FULL,
  218. dwAcquireFlags
  219. );
  220. if (!fResult)
  221. SetLastError(dwErr);
  222. }
  223. if (!fResult) {
  224. PrintLastError("CryptAcquireContext");
  225. return;
  226. }
  227. if (!CryptGetUserKey(
  228. hCryptProv,
  229. pKeyProvInfo->dwKeySpec,
  230. &hPubKey
  231. )) {
  232. hPubKey = 0;
  233. PrintLastError("CryptGetUserKey");
  234. goto ErrorReturn;
  235. }
  236. cbPubKeyStruc = 0;
  237. if (!CryptExportKey(
  238. hPubKey,
  239. 0, // hPubKey
  240. PUBLICKEYBLOB,
  241. 0, // dwFlags
  242. NULL, // pbData
  243. &cbPubKeyStruc
  244. ) || (cbPubKeyStruc == 0)) {
  245. PrintLastError("CryptExportKey");
  246. goto ErrorReturn;
  247. }
  248. if (NULL == (pPubKeyStruc = (PUBLICKEYSTRUC *) TestAlloc(
  249. cbPubKeyStruc)))
  250. goto ErrorReturn;
  251. if (!CryptExportKey(
  252. hPubKey,
  253. 0, // hPubKey
  254. PUBLICKEYBLOB,
  255. 0, // dwFlags
  256. (BYTE *) pPubKeyStruc,
  257. &cbPubKeyStruc
  258. )) {
  259. PrintLastError("CryptExportKey");
  260. goto ErrorReturn;
  261. }
  262. cbHash = sizeof(rgbHash);
  263. if (!CryptCreateKeyIdentifierFromCSP(
  264. dwCertEncodingType,
  265. NULL, // pszPubKeyOID
  266. pPubKeyStruc,
  267. cbPubKeyStruc,
  268. 0, // dwFlags
  269. NULL, // pvReserved
  270. rgbHash,
  271. &cbHash
  272. )) {
  273. PrintLastError("CryptCreateKeyIdentifierFromCSP");
  274. goto ErrorReturn;
  275. }
  276. if (pKeyIdentifier->cbData == cbHash &&
  277. 0 == memcmp(pKeyIdentifier->pbData, rgbHash, cbHash))
  278. printf(" Verified KeyIdentifier with CSP\n");
  279. else {
  280. printf(" KeyIdentifier mismatch with CSP provider hash::\n");
  281. PrintBytes(" ", rgbHash, cbHash);
  282. }
  283. ErrorReturn:
  284. TestFree(pPubKeyStruc);
  285. if (hPubKey)
  286. CryptDestroyKey(hPubKey);
  287. if (hCryptProv)
  288. CryptReleaseContext(hCryptProv, 0);
  289. }
  290. static void DisplayProperty(
  291. IN const CRYPT_HASH_BLOB *pKeyIdentifier,
  292. IN DWORD dwPropId,
  293. IN const void *pvData,
  294. IN DWORD cbData
  295. )
  296. {
  297. if (CERT_KEY_PROV_INFO_PROP_ID == dwPropId) {
  298. PCRYPT_KEY_PROV_INFO pInfo = (PCRYPT_KEY_PROV_INFO) pvData;
  299. printf(" Key Provider:: Type: %d", pInfo->dwProvType);
  300. if (pInfo->pwszProvName)
  301. printf(" Name: %S", pInfo->pwszProvName);
  302. if (pInfo->dwFlags) {
  303. printf(" Flags: 0x%x", pInfo->dwFlags);
  304. if (pInfo->dwFlags & CRYPT_MACHINE_KEYSET)
  305. printf(" (MACHINE_KEYSET)");
  306. if (pInfo->dwFlags & CERT_SET_KEY_CONTEXT_PROP_ID)
  307. printf(" (SET_KEY_CONTEXT_PROP)");
  308. printf(" ");
  309. }
  310. if (pInfo->pwszContainerName)
  311. printf(" Container: %S", pInfo->pwszContainerName);
  312. if (pInfo->cProvParam)
  313. printf(" Params: %d", pInfo->cProvParam);
  314. if (pInfo->dwKeySpec)
  315. printf(" KeySpec: %d", pInfo->dwKeySpec);
  316. printf("\n");
  317. if (fVerify) {
  318. VerifyKeyProvInfo(pKeyIdentifier, pInfo);
  319. }
  320. } else {
  321. printf(" PropId %d (0x%x) ::\n", dwPropId, dwPropId);
  322. PrintBytes(" ", (BYTE *) pvData, cbData);
  323. }
  324. }
  325. static void DisplayKeyIdentifier(
  326. IN const CRYPT_HASH_BLOB *pKeyIdentifier
  327. )
  328. {
  329. DWORD cbKeyId = pKeyIdentifier->cbData;
  330. BYTE *pbKeyId = pKeyIdentifier->pbData;
  331. printf("KeyIdentifier:: ");
  332. if (cbKeyId == 0)
  333. printf("???");
  334. else {
  335. ULONG cb;
  336. while (cbKeyId > 0) {
  337. cb = min(4, cbKeyId);
  338. cbKeyId -= cb;
  339. for (; cb > 0; cb--, pbKeyId++)
  340. printf("%02X", *pbKeyId);
  341. printf(" ");
  342. }
  343. }
  344. printf("\n");
  345. }
  346. static void DisplayKeyIdentifierCerts(
  347. IN const CRYPT_HASH_BLOB *pKeyIdentifier,
  348. IN HCERTSTORE hStore
  349. )
  350. {
  351. if (NULL == hStore)
  352. return;
  353. PCCERT_CONTEXT pCert = NULL;
  354. DWORD i = 0;
  355. while (pCert = CertFindCertificateInStore(
  356. hStore,
  357. 0, // dwCertEncodingType
  358. 0, // dwFindFlags
  359. CERT_FIND_KEY_IDENTIFIER,
  360. pKeyIdentifier,
  361. pCert
  362. )) {
  363. DWORD cbData = 0;
  364. printf("\n");
  365. if (CertGetCertificateContextProperty(
  366. pCert,
  367. CERT_ARCHIVED_PROP_ID,
  368. NULL, // pvData
  369. &cbData
  370. ))
  371. printf("---------- ARCHIVED Cert [%d] ----------\n", i);
  372. else
  373. printf("---------- Cert [%d] ----------\n", i);
  374. i++;
  375. DisplayCert(pCert, 0);
  376. }
  377. if (0 == i)
  378. printf(">>>> No Key Identifier Certificates <<<<\n");
  379. }
  380. typedef struct _TEST_ENUM_ARG {
  381. HCERTSTORE hStore;
  382. DWORD dwDisplayFlags;
  383. } TEST_ENUM_ARG, *PTEST_ENUM_ARG;
  384. static BOOL WINAPI TestEnumCallback(
  385. IN const CRYPT_HASH_BLOB *pKeyIdentifier,
  386. IN DWORD dwFlags,
  387. IN void *pvReserved,
  388. IN void *pvArg,
  389. IN DWORD cProp,
  390. IN DWORD *rgdwPropId,
  391. IN void **rgpvData,
  392. IN DWORD *rgcbData
  393. )
  394. {
  395. PTEST_ENUM_ARG pArg = (PTEST_ENUM_ARG) pvArg;
  396. if (pArg->dwDisplayFlags & DISPLAY_VERBOSE_FLAG) {
  397. printf("\n");
  398. printf(
  399. "=========================================================================\n");
  400. }
  401. DisplayKeyIdentifier(pKeyIdentifier);
  402. if (pArg->dwDisplayFlags & DISPLAY_BRIEF_FLAG)
  403. return TRUE;
  404. if (0 == cProp)
  405. printf("No Properties\n");
  406. else {
  407. DWORD i;
  408. for (i = 0; i < cProp; i++) {
  409. DWORD dwPropId = rgdwPropId[i];
  410. DisplayProperty(pKeyIdentifier, dwPropId, rgpvData[i], rgcbData[i]);
  411. }
  412. }
  413. if (pArg->dwDisplayFlags & DISPLAY_VERBOSE_FLAG) {
  414. DisplayKeyIdentifierCerts(pKeyIdentifier, pArg->hStore);
  415. }
  416. return TRUE;
  417. }
  418. static HCERTSTORE OpenMyStore(
  419. IN DWORD dwFlags,
  420. IN OPTIONAL LPCWSTR pwszComputerName
  421. )
  422. {
  423. DWORD dwOpenFlags;
  424. LPWSTR pwszAllocStore = NULL;
  425. LPWSTR pwszStore;
  426. HCERTSTORE hStore = NULL;
  427. pwszStore = L"My";
  428. if (dwFlags & CRYPT_KEYID_MACHINE_FLAG) {
  429. if (pwszComputerName) {
  430. DWORD cchStore;
  431. cchStore = wcslen(pwszComputerName) + 1 + wcslen(pwszStore) + 1;
  432. if (pwszAllocStore = (LPWSTR) TestAlloc(
  433. cchStore * sizeof(WCHAR))) {
  434. wcscpy(pwszAllocStore, pwszComputerName);
  435. wcscat(pwszAllocStore, L"\\");
  436. wcscat(pwszAllocStore, pwszStore);
  437. pwszStore = pwszAllocStore;
  438. }
  439. }
  440. dwOpenFlags = CERT_SYSTEM_STORE_LOCAL_MACHINE;
  441. } else
  442. dwOpenFlags = CERT_SYSTEM_STORE_CURRENT_USER;
  443. dwOpenFlags |= CERT_STORE_READONLY_FLAG | CERT_STORE_ENUM_ARCHIVED_FLAG;
  444. hStore = CertOpenStore(
  445. CERT_STORE_PROV_SYSTEM_W,
  446. 0, // dwCertEncodingType
  447. 0, // hCryptProv
  448. dwOpenFlags,
  449. (const void *) pwszStore
  450. );
  451. if (NULL == hStore) {
  452. if (dwFlags & CRYPT_KEYID_MACHINE_FLAG)
  453. printf("Unable to open LocalMachine store: %S\n", pwszStore);
  454. else
  455. printf("Unable to open CurrentUser store: %S\n", pwszStore);
  456. PrintLastError("CertOpenStore");
  457. }
  458. TestFree(pwszAllocStore);
  459. return hStore;
  460. }
  461. static BOOL TestEnum(
  462. IN const CRYPT_HASH_BLOB *pKeyIdentifier,
  463. IN DWORD dwPropId,
  464. IN DWORD dwFlags,
  465. IN OPTIONAL LPCWSTR pwszComputerName,
  466. IN DWORD dwDisplayFlags
  467. )
  468. {
  469. BOOL fResult;
  470. TEST_ENUM_ARG TestArg;
  471. HCERTSTORE hStore;
  472. hStore = OpenMyStore(dwFlags, pwszComputerName);
  473. TestArg.hStore = hStore;
  474. TestArg.dwDisplayFlags = dwDisplayFlags;
  475. fResult = CryptEnumKeyIdentifierProperties(
  476. pKeyIdentifier,
  477. dwPropId,
  478. dwFlags,
  479. pwszComputerName,
  480. NULL, // pvReserved
  481. &TestArg,
  482. TestEnumCallback
  483. );
  484. if (!fResult)
  485. PrintLastError("CryptEnumKeyIdentifierProperty");
  486. if (hStore)
  487. CertCloseStore(hStore, 0);
  488. return fResult;
  489. }
  490. typedef struct _TEST_DELETE_ENUM_ARG {
  491. HCERTSTORE hStore;
  492. LPCSTR pszTestName;
  493. DWORD cKeyIdentifier;
  494. PCRYPT_HASH_BLOB rgKeyIdentifier;
  495. } TEST_DELETE_ENUM_ARG, *PTEST_DELETE_ENUM_ARG;
  496. static BOOL WINAPI TestDeleteEnumCallback(
  497. IN const CRYPT_HASH_BLOB *pKeyIdentifier,
  498. IN DWORD dwFlags,
  499. IN void *pvReserved,
  500. IN void *pvArg,
  501. IN DWORD cProp,
  502. IN DWORD *rgdwPropId,
  503. IN void **rgpvData,
  504. IN DWORD *rgcbData
  505. )
  506. {
  507. PTEST_DELETE_ENUM_ARG pArg = (PTEST_DELETE_ENUM_ARG) pvArg;
  508. BYTE *pbCopy = NULL;
  509. PCRYPT_HASH_BLOB pNewKeyIdentifier;
  510. DWORD cKeyIdentifier;
  511. if (0 == _stricmp("DeleteWithoutCert", pArg->pszTestName)) {
  512. PCCERT_CONTEXT pCert = NULL;
  513. if (pCert = CertFindCertificateInStore(
  514. pArg->hStore,
  515. 0, // dwCertEncodingType
  516. 0, // dwFindFlags
  517. CERT_FIND_KEY_IDENTIFIER,
  518. pKeyIdentifier,
  519. NULL // pPrevCert
  520. )) {
  521. CertFreeCertificateContext(pCert);
  522. return TRUE;
  523. }
  524. }
  525. if (NULL == (pbCopy = (BYTE *) TestAlloc(pKeyIdentifier->cbData)))
  526. return TRUE;
  527. memcpy(pbCopy, pKeyIdentifier->pbData, pKeyIdentifier->cbData);
  528. cKeyIdentifier = pArg->cKeyIdentifier;
  529. if (NULL == (pNewKeyIdentifier = (PCRYPT_HASH_BLOB) TestRealloc(
  530. pArg->rgKeyIdentifier,sizeof(CRYPT_HASH_BLOB) *
  531. (cKeyIdentifier + 1)))) {
  532. TestFree(pbCopy);
  533. return TRUE;
  534. }
  535. pNewKeyIdentifier[cKeyIdentifier].pbData = pbCopy;
  536. pNewKeyIdentifier[cKeyIdentifier].cbData = pKeyIdentifier->cbData;
  537. pArg->cKeyIdentifier = cKeyIdentifier + 1;
  538. pArg->rgKeyIdentifier = pNewKeyIdentifier;
  539. return TRUE;
  540. }
  541. static BOOL TestDeleteEnum(
  542. IN DWORD dwFlags,
  543. IN OPTIONAL LPCWSTR pwszComputerName,
  544. IN LPCSTR pszTestName
  545. )
  546. {
  547. BOOL fResult;
  548. TEST_DELETE_ENUM_ARG TestArg;
  549. HCERTSTORE hStore = NULL;
  550. DWORD cKeyIdentifier;
  551. PCRYPT_HASH_BLOB pKeyIdentifier;
  552. memset(&TestArg, 0, sizeof(TestArg));
  553. TestArg.pszTestName = pszTestName;
  554. if (0 == _stricmp("DeleteWithoutCert", pszTestName)) {
  555. hStore = OpenMyStore(dwFlags, pwszComputerName);
  556. if (NULL == hStore)
  557. return FALSE;
  558. TestArg.hStore = hStore;
  559. }
  560. fResult = CryptEnumKeyIdentifierProperties(
  561. NULL, // pKeyIdentifier
  562. 0, // dwPropId
  563. dwFlags,
  564. pwszComputerName,
  565. NULL, // pvReserved
  566. &TestArg,
  567. TestDeleteEnumCallback
  568. );
  569. if (!fResult)
  570. PrintLastError("CryptEnumKeyIdentifierProperty");
  571. cKeyIdentifier = TestArg.cKeyIdentifier;
  572. pKeyIdentifier = TestArg.rgKeyIdentifier;
  573. printf("Deleting %d Key Identifiers\n", cKeyIdentifier);
  574. for ( ; cKeyIdentifier > 0; cKeyIdentifier--, pKeyIdentifier++) {
  575. if (!CryptSetKeyIdentifierProperty(
  576. pKeyIdentifier,
  577. 0, // dwPropId
  578. dwFlags | CRYPT_KEYID_DELETE_FLAG,
  579. pwszComputerName,
  580. NULL, // pvReserved
  581. NULL // pvData
  582. ))
  583. PrintLastError("CryptSetKeyIdentifierProperty(Delete)");
  584. TestFree(pKeyIdentifier->pbData);
  585. }
  586. TestFree(TestArg.rgKeyIdentifier);
  587. if (hStore)
  588. CertCloseStore(hStore, 0);
  589. return fResult;
  590. }
  591. static BOOL TestGet(
  592. IN const CRYPT_HASH_BLOB *pKeyIdentifier,
  593. IN DWORD dwPropId,
  594. IN DWORD dwFlags,
  595. IN OPTIONAL LPCWSTR pwszComputerName,
  596. IN DWORD dwDisplayFlags
  597. )
  598. {
  599. BOOL fResult;
  600. void *pvData = NULL;
  601. DWORD cbData;
  602. if (0 == dwPropId)
  603. return TestEnum(
  604. pKeyIdentifier,
  605. dwPropId,
  606. dwFlags,
  607. pwszComputerName,
  608. dwDisplayFlags
  609. );
  610. dwFlags |= CRYPT_KEYID_ALLOC_FLAG;
  611. fResult = CryptGetKeyIdentifierProperty(
  612. pKeyIdentifier,
  613. dwPropId,
  614. dwFlags,
  615. pwszComputerName,
  616. NULL, // pvReserved,
  617. &pvData,
  618. &cbData
  619. );
  620. if (!fResult)
  621. PrintLastError("CryptGetKeyIdentifierProperty");
  622. else {
  623. DisplayProperty(pKeyIdentifier, dwPropId, pvData, cbData);
  624. }
  625. if (pvData && cbData) {
  626. BOOL fResult2;
  627. DWORD cbData2;
  628. dwFlags &= ~CRYPT_KEYID_ALLOC_FLAG;
  629. cbData2 = cbData;
  630. fResult2 = CryptGetKeyIdentifierProperty(
  631. pKeyIdentifier,
  632. dwPropId,
  633. dwFlags,
  634. pwszComputerName,
  635. NULL, // pvReserved,
  636. NULL, // pvData
  637. &cbData2
  638. );
  639. if (!fResult2)
  640. PrintLastError("CryptGetKeyIdentifierProperty");
  641. else if (cbData2 != cbData)
  642. printf("failed => wrong cbData for nonAlloc\n");
  643. cbData2 = cbData - 1;
  644. fResult2 = CryptGetKeyIdentifierProperty(
  645. pKeyIdentifier,
  646. dwPropId,
  647. dwFlags,
  648. pwszComputerName,
  649. NULL, // pvReserved,
  650. pvData,
  651. &cbData2
  652. );
  653. if (fResult2)
  654. printf("failed => returned success for too small buffer\n");
  655. else {
  656. DWORD dwErr = GetLastError();
  657. if (ERROR_MORE_DATA != dwErr)
  658. printf("failed => returned: %d 0x%x instead of ERROR_MORE_DATA\n", dwErr, dwErr);
  659. }
  660. if (cbData2 != cbData)
  661. printf("failed => wrong size returned for small buffer\n");
  662. }
  663. if (pvData)
  664. LocalFree((HLOCAL) pvData);
  665. return fResult;
  666. }
  667. #define SHA1_HASH_LEN 20
  668. #define MAX_KEY_ID_LEN SHA1_HASH_LEN
  669. #define SHA1_CHAR_LEN (SHA1_HASH_LEN * 2)
  670. //+-------------------------------------------------------------------------
  671. // Converts the ASCII HEX to an array of bytes
  672. //--------------------------------------------------------------------------
  673. static void StrToBytes(
  674. IN LPCSTR psz,
  675. OUT BYTE rgb[MAX_KEY_ID_LEN],
  676. OUT DWORD *pcb
  677. )
  678. {
  679. BOOL fUpperNibble = TRUE;
  680. DWORD cb = 0;
  681. char ch;
  682. while (cb < MAX_KEY_ID_LEN && (ch = *psz++)) {
  683. BYTE b;
  684. // only convert ascii hex characters 0..9, a..f, A..F
  685. // silently ignore all others
  686. if (ch >= '0' && ch <= '9')
  687. b = ch - '0';
  688. else if (ch >= 'a' && ch <= 'f')
  689. b = 10 + ch - 'a';
  690. else if (ch >= 'A' && ch <= 'F')
  691. b = 10 + ch - 'A';
  692. else
  693. continue;
  694. if (fUpperNibble) {
  695. rgb[cb] = b << 4;
  696. fUpperNibble = FALSE;
  697. } else {
  698. rgb[cb] = rgb[cb] | b;
  699. cb++;
  700. fUpperNibble = TRUE;
  701. }
  702. }
  703. *pcb = cb;
  704. }
  705. int _cdecl main(int argc, char * argv[])
  706. {
  707. BOOL fResult;
  708. int status;
  709. LONG lStatus;
  710. LPSTR pszTestName = NULL;
  711. LPSTR pszCertFilename = NULL;
  712. BOOL fPropSystemStore = FALSE;
  713. LPSTR pszPropStore = NULL;
  714. PCCERT_CONTEXT pCert = NULL;
  715. BOOL fMachine = FALSE;
  716. LPWSTR pwszComputerName = NULL;
  717. DWORD dwDisplayFlags = 0;
  718. DWORD dwPropId = 0;
  719. DWORD dwFlags = 0;
  720. DWORD i;
  721. HCERTSTORE hPropStore = NULL;
  722. BYTE rgbKeyIdentifier[SHA1_HASH_LEN];
  723. DWORD cbKeyIdentifier;
  724. CRYPT_HASH_BLOB KeyIdentifier = { 0, NULL };
  725. while (--argc>0) {
  726. if (**++argv == '-')
  727. {
  728. {
  729. switch(argv[0][1])
  730. {
  731. case 'c':
  732. pszCertFilename = argv[0]+2;
  733. break;
  734. case 's':
  735. pszPropStore = argv[0]+2;
  736. fPropSystemStore = TRUE;
  737. break;
  738. case 'S':
  739. pszPropStore = argv[0]+2;
  740. fPropSystemStore = FALSE;
  741. break;
  742. case 'b':
  743. dwDisplayFlags |= DISPLAY_BRIEF_FLAG;
  744. break;
  745. case 'v':
  746. dwDisplayFlags |= DISPLAY_VERBOSE_FLAG;
  747. break;
  748. case 'p':
  749. dwPropId = (DWORD) strtoul(argv[0]+2, NULL, 0);
  750. break;
  751. case 'f':
  752. dwFlags = (DWORD) strtoul(argv[0]+2, NULL, 0);
  753. break;
  754. case 'V':
  755. fVerify = TRUE;
  756. break;
  757. case 'M':
  758. fMachine = TRUE;
  759. if (argv[0][2])
  760. pwszComputerName = AllocAndSzToWsz(argv[0]+2);
  761. break;
  762. case 'k':
  763. StrToBytes(
  764. argv[0]+2,
  765. rgbKeyIdentifier,
  766. &cbKeyIdentifier
  767. );
  768. if (0 == cbKeyIdentifier) {
  769. printf("No Hash digits\n");
  770. goto BadUsage;
  771. }
  772. KeyIdentifier.pbData = rgbKeyIdentifier;
  773. KeyIdentifier.cbData = cbKeyIdentifier;
  774. break;
  775. case 'h':
  776. default:
  777. goto BadUsage;
  778. }
  779. }
  780. } else {
  781. if (pszTestName) {
  782. printf("Multiple TestNames:: %s %s\n", pszTestName, argv[0]);
  783. goto BadUsage;
  784. }
  785. pszTestName = argv[0];
  786. }
  787. }
  788. if (pszTestName == NULL) {
  789. printf("Missing TestName\n");
  790. goto BadUsage;
  791. }
  792. printf("command line: %s\n", GetCommandLine());
  793. if (pszPropStore) {
  794. if (NULL == (hPropStore = OpenSystemStoreOrFile(
  795. fPropSystemStore,
  796. pszPropStore,
  797. 0 // dwFlags
  798. )))
  799. goto BadUsage;
  800. }
  801. if (pszCertFilename) {
  802. if (KeyIdentifier.cbData) {
  803. printf("-c option invalid with -k option\n");
  804. goto BadUsage;
  805. }
  806. if (NULL == (pCert = ReadCert(pszCertFilename)))
  807. goto ErrorReturn;
  808. if (hPropStore) {
  809. PCCERT_CONTEXT pPropCert = NULL;
  810. // Try to find the certificate in the specified store
  811. pPropCert = CertFindCertificateInStore(
  812. hPropStore,
  813. 0, // dwCertEncodingType
  814. 0, // dwFindFlags
  815. CERT_FIND_EXISTING,
  816. pCert,
  817. NULL // pPrevCertContext
  818. );
  819. if (NULL == pPropCert) {
  820. printf("Failed, unable to find certificate in store\n");
  821. goto BadUsage;
  822. }
  823. CertFreeCertificateContext(pCert);
  824. pCert = pPropCert;
  825. }
  826. cbKeyIdentifier = MAX_KEY_ID_LEN;
  827. if (CertGetCertificateContextProperty(
  828. pCert,
  829. CERT_KEY_IDENTIFIER_PROP_ID,
  830. rgbKeyIdentifier,
  831. &cbKeyIdentifier
  832. )) {
  833. KeyIdentifier.pbData = rgbKeyIdentifier;
  834. KeyIdentifier.cbData = cbKeyIdentifier;
  835. } else {
  836. PrintLastError(
  837. "CertGetCertificateContextProperty(KEY_IDENTIFIER)");
  838. goto ErrorReturn;
  839. }
  840. }
  841. if (fMachine)
  842. dwFlags |= CRYPT_KEYID_MACHINE_FLAG;
  843. if (0 == _stricmp("Set", pszTestName)) {
  844. if (NULL == pCert) {
  845. printf("Set: requires -c option\n");
  846. goto BadUsage;
  847. }
  848. if (!TestSet(
  849. &KeyIdentifier,
  850. pCert,
  851. dwPropId,
  852. dwFlags,
  853. pwszComputerName
  854. ))
  855. goto ErrorReturn;
  856. } else if (0 == _stricmp("Get", pszTestName)) {
  857. if (0 == KeyIdentifier.cbData) {
  858. printf("Get: requires -c or -k option\n");
  859. goto BadUsage;
  860. }
  861. if (!TestGet(
  862. &KeyIdentifier,
  863. dwPropId,
  864. dwFlags,
  865. pwszComputerName,
  866. dwDisplayFlags
  867. ))
  868. goto ErrorReturn;
  869. } else if (0 == _stricmp("Delete", pszTestName)) {
  870. if (0 == KeyIdentifier.cbData) {
  871. printf("Delete: requires -c or -k option\n");
  872. goto BadUsage;
  873. }
  874. if (!TestDelete(
  875. &KeyIdentifier,
  876. dwPropId,
  877. dwFlags,
  878. pwszComputerName
  879. ))
  880. goto ErrorReturn;
  881. } else if (0 == _stricmp("Enum", pszTestName)) {
  882. if (!TestEnum(
  883. (0 == KeyIdentifier.cbData) ? NULL : &KeyIdentifier,
  884. dwPropId,
  885. dwFlags,
  886. pwszComputerName,
  887. dwDisplayFlags
  888. ))
  889. goto ErrorReturn;
  890. } else if (0 == _stricmp("DeleteAll", pszTestName) ||
  891. 0 == _stricmp("DeleteWithoutCert", pszTestName)) {
  892. if (!TestDeleteEnum(
  893. dwFlags,
  894. pwszComputerName,
  895. pszTestName
  896. ))
  897. goto ErrorReturn;
  898. } else {
  899. printf("Invalid TestName: %s\n", pszTestName);
  900. goto BadUsage;
  901. }
  902. printf("Passed\n");
  903. status = 0;
  904. CommonReturn:
  905. CertCloseStore(hPropStore, 0);
  906. CertFreeCertificateContext(pCert);
  907. TestFree(pwszComputerName);
  908. return status;
  909. ErrorReturn:
  910. status = -1;
  911. printf("Failed\n");
  912. goto CommonReturn;
  913. BadUsage:
  914. Usage();
  915. goto ErrorReturn;
  916. }