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.

539 lines
18 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1995 - 1996
  6. //
  7. // File: tcopycer.cpp
  8. //
  9. // Contents: Cert Store Copy Cert/CRL/CTL context API Tests
  10. //
  11. // See Usage() for list of test options.
  12. //
  13. //
  14. // Functions: main
  15. //
  16. // History: 11-Apr-96 philh created
  17. // 07-Jun-96 HelleS Added printing the command line
  18. // and Failed or Passed at the end.
  19. // 20-Aug-96 jeffspel name changes
  20. //
  21. //--------------------------------------------------------------------------
  22. #include <windows.h>
  23. #include <assert.h>
  24. #include "wincrypt.h"
  25. #include "certtest.h"
  26. #include <stdlib.h>
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <memory.h>
  30. #include <time.h>
  31. static void Usage(void)
  32. {
  33. printf("Usage: tcopycer [options] <Src StoreName> <Dst StoreName>\n");
  34. printf("Options are:\n");
  35. printf(" -h - This message\n");
  36. printf(" -s - Dst \"StoreName\" System store\n");
  37. printf(" -7 - PKCS# 7 save for Dst if filename\n");
  38. printf(" -S - Src \"StoreName\" System store\n");
  39. printf(" -R - Replace certs that exist\n");
  40. printf(" -I - Replace certs with property inheritance\n");
  41. printf(" -A - Always add a new cert\n");
  42. printf(" -b<number> - Add Base CRL having specified number\n");
  43. printf(" -f<number> - Add Freshest CRL having specified number\n");
  44. printf(" -a[<ValueString>] - Only certs matching name attribute value\n");
  45. printf("\n");
  46. printf("-b and/or -f only copy the CRL having the specified number\n");
  47. printf("-b and/or -f delete all CRLs unless -A is also specified\n");
  48. printf("\n");
  49. }
  50. static void DisplayFindAttr(DWORD cRDNAttr, CERT_RDN_ATTR rgRDNAttr[])
  51. {
  52. DWORD i;
  53. for (i = 0; i < cRDNAttr; i++) {
  54. LPSTR pszObjId = rgRDNAttr[i].pszObjId;
  55. LPSTR pszValue = (LPSTR) rgRDNAttr[i].Value.pbData;
  56. printf(" [%d] ", i);
  57. if (pszObjId)
  58. printf("%s ", pszObjId);
  59. if (rgRDNAttr[i].dwValueType)
  60. printf("ValueType: %d ", rgRDNAttr[i].dwValueType);
  61. if (pszValue == NULL)
  62. pszValue = "<NONE>";
  63. printf("Value: %s\n", pszValue);
  64. }
  65. }
  66. int _cdecl main(int argc, char * argv[])
  67. {
  68. int ReturnStatus = 0;
  69. BOOL fSrcSystemStore = FALSE;
  70. BOOL fDstSystemStore = FALSE;
  71. LPSTR pszSrcStoreFilename = NULL;
  72. LPSTR pszDstStoreFilename = NULL;
  73. BOOL fPKCS7Save = FALSE;
  74. DWORD dwAddDisposition = CERT_STORE_ADD_USE_EXISTING;
  75. HANDLE hSrcStore = NULL;
  76. HANDLE hDstStore = NULL;
  77. #define MAX_RDN_ATTR 20
  78. DWORD cRDNAttr = 0;
  79. CERT_RDN_ATTR rgRDNAttr[MAX_RDN_ATTR + 1];
  80. memset (rgRDNAttr, 0, sizeof(rgRDNAttr));
  81. CERT_RDN NameRDN;
  82. BOOL fBaseOrFreshestCrl = FALSE;
  83. int iBaseCrl = -1;
  84. int iFreshestCrl = -1;
  85. while (--argc>0)
  86. {
  87. if (**++argv == '-')
  88. {
  89. switch(argv[0][1])
  90. {
  91. case 's':
  92. fDstSystemStore = TRUE;
  93. break;
  94. case '7':
  95. fPKCS7Save = TRUE;
  96. break;
  97. case 'S':
  98. fSrcSystemStore = TRUE;
  99. break;
  100. case 'R':
  101. dwAddDisposition = CERT_STORE_ADD_REPLACE_EXISTING;
  102. break;
  103. case 'A':
  104. dwAddDisposition = CERT_STORE_ADD_ALWAYS;
  105. break;
  106. case 'I':
  107. dwAddDisposition =
  108. CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES;
  109. break;
  110. case 'a':
  111. if (cRDNAttr >= MAX_RDN_ATTR) {
  112. printf("Maximum number of attributes: %d\n", MAX_RDN_ATTR);
  113. Usage();
  114. return -1;
  115. }
  116. rgRDNAttr[cRDNAttr].Value.cbData = strlen(argv[0] + 2);
  117. if (rgRDNAttr[cRDNAttr].Value.cbData == 0)
  118. rgRDNAttr[cRDNAttr].Value.pbData = NULL;
  119. else
  120. rgRDNAttr[cRDNAttr].Value.pbData = (BYTE *) (argv[0] + 2);
  121. cRDNAttr++;
  122. break;
  123. case 'b':
  124. iBaseCrl = atoi(argv[0]+2);
  125. fBaseOrFreshestCrl = TRUE;
  126. break;
  127. case 'f':
  128. iFreshestCrl = atoi(argv[0]+2);
  129. fBaseOrFreshestCrl = TRUE;
  130. break;
  131. case 'h':
  132. default:
  133. goto BadUsage;
  134. }
  135. } else {
  136. if (pszSrcStoreFilename == NULL)
  137. pszSrcStoreFilename = argv[0];
  138. else if (pszDstStoreFilename == NULL)
  139. pszDstStoreFilename = argv[0];
  140. else {
  141. printf("too many store filenames\n");
  142. goto BadUsage;
  143. }
  144. }
  145. }
  146. if (pszDstStoreFilename == NULL) {
  147. printf("missing store filename\n");
  148. goto BadUsage;
  149. }
  150. printf("command line: %s\n", GetCommandLine());
  151. // Attempt to open the source and destination stores
  152. hSrcStore = OpenStore(fSrcSystemStore, pszSrcStoreFilename);
  153. if (hSrcStore == NULL)
  154. goto ErrorReturn;
  155. hDstStore = OpenStore(fDstSystemStore, pszDstStoreFilename);
  156. if (hDstStore == NULL) {
  157. if (!CertCloseStore(hSrcStore, 0))
  158. PrintLastError("CertCloseStore");
  159. goto ErrorReturn;
  160. }
  161. if (cRDNAttr) {
  162. printf("Copy certs matching attribute values::\n");
  163. DisplayFindAttr(cRDNAttr, rgRDNAttr);
  164. NameRDN.cRDNAttr = cRDNAttr;
  165. NameRDN.rgRDNAttr = rgRDNAttr;
  166. }
  167. if (!fBaseOrFreshestCrl)
  168. {
  169. DWORD dwCopyCnt = 0;
  170. PCCERT_CONTEXT pCert = NULL;
  171. int i = 0;
  172. while (TRUE) {
  173. BOOL fResult;
  174. if (cRDNAttr) {
  175. pCert = CertFindCertificateInStore(
  176. hSrcStore,
  177. dwCertEncodingType,
  178. 0, // dwFindFlags,
  179. CERT_FIND_SUBJECT_ATTR,
  180. &NameRDN,
  181. pCert
  182. );
  183. if (pCert) {
  184. printf("===== Copy Cert %d =====\n", i++);
  185. DisplayCert(pCert, DISPLAY_BRIEF_FLAG);
  186. }
  187. } else
  188. pCert = CertEnumCertificatesInStore(
  189. hSrcStore,
  190. pCert
  191. );
  192. if (pCert == NULL)
  193. break;
  194. if (!(fResult = CertAddCertificateContextToStore(
  195. hDstStore,
  196. pCert,
  197. CERT_STORE_ADD_NEW,
  198. NULL))) {
  199. if (GetLastError() == CRYPT_E_EXISTS) {
  200. printf("Cert %d already exists in store\n", dwCopyCnt);
  201. DWORD dwNewer;
  202. if (dwAddDisposition == CERT_STORE_ADD_REPLACE_EXISTING)
  203. dwNewer = CERT_STORE_ADD_NEWER;
  204. else if (dwAddDisposition ==
  205. CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES)
  206. dwNewer = CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES;
  207. else
  208. dwNewer = 0;
  209. fResult = FALSE;
  210. if (dwNewer) {
  211. fResult = CertAddCertificateContextToStore(
  212. hDstStore,
  213. pCert,
  214. dwNewer,
  215. NULL);
  216. if (fResult)
  217. printf("Added newer cert\n");
  218. else {
  219. DWORD dwErr = GetLastError();
  220. if (dwErr == CRYPT_E_EXISTS)
  221. printf("Didn't add older cert\n");
  222. else
  223. PrintLastError("Cert: CERT_ADD_NEWER");
  224. }
  225. }
  226. if (!fResult)
  227. fResult = CertAddCertificateContextToStore(
  228. hDstStore,
  229. pCert,
  230. dwAddDisposition,
  231. NULL);
  232. }
  233. }
  234. if (!fResult) {
  235. PrintLastError("CertAddCertificateContextToStore");
  236. ReturnStatus = -1;
  237. CertFreeCertificateContext(pCert);
  238. break;
  239. } else {
  240. dwCopyCnt++;
  241. }
  242. }
  243. printf("Copied %d certificates\n", dwCopyCnt);
  244. }
  245. if (fBaseOrFreshestCrl) {
  246. DWORD fCopyCrl = FALSE;
  247. PCCRL_CONTEXT pCrl;
  248. if (dwAddDisposition != CERT_STORE_ADD_ALWAYS) {
  249. // Delete all existing CRLs from the destination store
  250. pCrl = NULL;
  251. while (pCrl = CertEnumCRLsInStore(hDstStore, pCrl)) {
  252. PCCRL_CONTEXT pDeleteCrl = CertDuplicateCRLContext(pCrl);
  253. if (!CertDeleteCRLFromStore(pDeleteCrl))
  254. PrintLastError("CertDeleteCRLFromStore");
  255. }
  256. }
  257. pCrl = NULL;
  258. while (pCrl = CertEnumCRLsInStore(hSrcStore, pCrl)) {
  259. PCERT_EXTENSION pDeltaExt;
  260. PCERT_EXTENSION pBaseExt;
  261. DWORD cbInt;
  262. int iNum;
  263. pDeltaExt = CertFindExtension(
  264. szOID_DELTA_CRL_INDICATOR,
  265. pCrl->pCrlInfo->cExtension,
  266. pCrl->pCrlInfo->rgExtension
  267. );
  268. pBaseExt = CertFindExtension(
  269. szOID_CRL_NUMBER,
  270. pCrl->pCrlInfo->cExtension,
  271. pCrl->pCrlInfo->rgExtension
  272. );
  273. if (pDeltaExt) {
  274. // Freshest, delta CRL
  275. if (0 <= iFreshestCrl) {
  276. cbInt = sizeof(iNum);
  277. if (!CryptDecodeObject(
  278. pCrl->dwCertEncodingType,
  279. X509_INTEGER,
  280. pDeltaExt->Value.pbData,
  281. pDeltaExt->Value.cbData,
  282. 0, // dwFlags
  283. &iNum,
  284. &cbInt
  285. ))
  286. PrintLastError("CryptDecodeObject(DeltaCrlNumber)");
  287. else if (iFreshestCrl == iNum) {
  288. if (CertAddCRLContextToStore(
  289. hDstStore,
  290. pCrl,
  291. CERT_STORE_ADD_ALWAYS,
  292. NULL
  293. )) {
  294. printf("Added freshest CRL %d\n", iNum);
  295. fCopyCrl = TRUE;
  296. } else
  297. PrintLastError("CertAddCRLContextToStore(Freshest)");
  298. }
  299. }
  300. } else if (pBaseExt) {
  301. // Base CRL
  302. if (0 <= iBaseCrl) {
  303. cbInt = sizeof(iNum);
  304. if (!CryptDecodeObject(
  305. pCrl->dwCertEncodingType,
  306. X509_INTEGER,
  307. pBaseExt->Value.pbData,
  308. pBaseExt->Value.cbData,
  309. 0, // dwFlags
  310. &iNum,
  311. &cbInt
  312. ))
  313. PrintLastError("CryptDecodeObject(BaseCrlNumber)");
  314. else if (iBaseCrl == iNum) {
  315. if (CertAddCRLContextToStore(
  316. hDstStore,
  317. pCrl,
  318. CERT_STORE_ADD_ALWAYS,
  319. NULL
  320. )) {
  321. printf("Added base CRL %d\n", iNum);
  322. fCopyCrl = TRUE;
  323. } else
  324. PrintLastError("CertAddCRLContextToStore(Base)");
  325. }
  326. }
  327. }
  328. }
  329. if (!fCopyCrl)
  330. printf("failed => no base or freshest, delta CRLs copied\n");
  331. } else if (cRDNAttr == 0) {
  332. DWORD dwCopyCnt;
  333. PCCRL_CONTEXT pCrl = NULL;
  334. PCCTL_CONTEXT pCtl = NULL;
  335. DWORD dwFlags;
  336. dwCopyCnt = 0;
  337. while (TRUE) {
  338. BOOL fResult;
  339. dwFlags = 0;
  340. pCrl = CertGetCRLFromStore(
  341. hSrcStore,
  342. NULL, // pIssuerContext
  343. pCrl,
  344. &dwFlags);
  345. if (pCrl == NULL)
  346. break;
  347. if (!(fResult = CertAddCRLContextToStore(
  348. hDstStore,
  349. pCrl,
  350. CERT_STORE_ADD_NEW,
  351. NULL))) {
  352. if (GetLastError() == CRYPT_E_EXISTS) {
  353. printf("CRL %d already exists in store\n", dwCopyCnt);
  354. DWORD dwNewer;
  355. if (dwAddDisposition == CERT_STORE_ADD_REPLACE_EXISTING)
  356. dwNewer = CERT_STORE_ADD_NEWER;
  357. else if (dwAddDisposition ==
  358. CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES)
  359. dwNewer = CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES;
  360. else
  361. dwNewer = 0;
  362. fResult = FALSE;
  363. if (dwNewer) {
  364. fResult = CertAddCRLContextToStore(
  365. hDstStore,
  366. pCrl,
  367. dwNewer,
  368. NULL);
  369. if (fResult)
  370. printf("Added newer CRL\n");
  371. else {
  372. DWORD dwErr = GetLastError();
  373. if (dwErr == CRYPT_E_EXISTS)
  374. printf("Didn't add older CRL\n");
  375. else
  376. PrintLastError("CRL: CERT_ADD_NEWER");
  377. }
  378. }
  379. if (!fResult)
  380. fResult = CertAddCRLContextToStore(
  381. hDstStore,
  382. pCrl,
  383. dwAddDisposition,
  384. NULL);
  385. }
  386. }
  387. if (!fResult) {
  388. PrintLastError("CertAddCRLContextToStore");
  389. ReturnStatus = -1;
  390. CertFreeCRLContext(pCrl);
  391. break;
  392. } else
  393. dwCopyCnt++;
  394. }
  395. printf("Copied %d CRLs\n", dwCopyCnt);
  396. dwCopyCnt = 0;
  397. while (TRUE) {
  398. BOOL fResult;
  399. dwFlags = 0;
  400. pCtl = CertEnumCTLsInStore(
  401. hSrcStore,
  402. pCtl
  403. );
  404. if (pCtl == NULL)
  405. break;
  406. if (!(fResult = CertAddCTLContextToStore(
  407. hDstStore,
  408. pCtl,
  409. CERT_STORE_ADD_NEW,
  410. NULL))) {
  411. if (GetLastError() == CRYPT_E_EXISTS) {
  412. printf("CTL %d already exists in store\n", dwCopyCnt);
  413. DWORD dwNewer;
  414. if (dwAddDisposition == CERT_STORE_ADD_REPLACE_EXISTING)
  415. dwNewer = CERT_STORE_ADD_NEWER;
  416. else if (dwAddDisposition ==
  417. CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES)
  418. dwNewer = CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES;
  419. else
  420. dwNewer = 0;
  421. fResult = FALSE;
  422. if (dwNewer) {
  423. fResult = CertAddCTLContextToStore(
  424. hDstStore,
  425. pCtl,
  426. dwNewer,
  427. NULL);
  428. if (fResult)
  429. printf("Added newer CTL\n");
  430. else {
  431. DWORD dwErr = GetLastError();
  432. if (dwErr == CRYPT_E_EXISTS)
  433. printf("Didn't add older CTL\n");
  434. else
  435. PrintLastError("CTL: CERT_ADD_NEWER");
  436. }
  437. }
  438. if (!fResult)
  439. fResult = CertAddCTLContextToStore(
  440. hDstStore,
  441. pCtl,
  442. dwAddDisposition,
  443. NULL);
  444. }
  445. }
  446. if (!fResult) {
  447. PrintLastError("CertAddCTLContextToStore");
  448. ReturnStatus = -1;
  449. CertFreeCTLContext(pCtl);
  450. break;
  451. } else
  452. dwCopyCnt++;
  453. }
  454. printf("Copied %d CTLs\n", dwCopyCnt);
  455. }
  456. if (!fDstSystemStore)
  457. SaveStoreEx(hDstStore, fPKCS7Save, pszDstStoreFilename);
  458. if (!CertCloseStore(hSrcStore, 0))
  459. {
  460. PrintLastError("CertCloseStore(hSrcStore)");
  461. ReturnStatus = -1;
  462. }
  463. if (!CertCloseStore(hDstStore, 0))
  464. {
  465. PrintLastError("CertCloseStore(hDstStore)");
  466. ReturnStatus = -1;
  467. }
  468. if (-1 == ReturnStatus)
  469. goto ErrorReturn;
  470. ReturnStatus = 0;
  471. goto CommonReturn;
  472. BadUsage:
  473. Usage();
  474. ErrorReturn:
  475. ReturnStatus = -1;
  476. CommonReturn:
  477. if (!ReturnStatus)
  478. printf("Passed\n");
  479. else
  480. printf("Failed\n");
  481. return ReturnStatus;
  482. }