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.

5959 lines
194 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1995 - 1996
  6. //
  7. // File: tstore2.cpp
  8. //
  9. // Contents: Cert Store API Tests: Create and Add a chain of certificates
  10. // and CRLs to the store.
  11. //
  12. // See Usage() for a list of test options.
  13. //
  14. //
  15. // Functions: main
  16. //
  17. // History: 07-Mar-96 philh created
  18. // 31-May-96 helles Removed check for a particular error code,
  19. // NTE_PROV_TYPE_NOT_DEF, since this can get
  20. // overwritten due to known problem with
  21. // the msvcr40d.dll on Win95.
  22. // 07-Jun-96 HelleS Added printing the command line
  23. // 20-Aug-96 jeffspel name changes
  24. //
  25. //--------------------------------------------------------------------------
  26. #define CMS_PKCS7 1
  27. #include <windows.h>
  28. #include <assert.h>
  29. #include "wincrypt.h"
  30. #include "setcert.h"
  31. #include "signcde.h"
  32. #include "softpub.h"
  33. #include <stdlib.h>
  34. #include <stdio.h>
  35. #include <string.h>
  36. #include <memory.h>
  37. #include <time.h>
  38. #include <stddef.h>
  39. //#define TEST_PROV_DSS PROV_DSS
  40. #define TEST_PROV_DSS PROV_DSS_DH
  41. // # of bytes for a hash. Such as, SHA1 (20) or MD5 (16)
  42. #define MAX_HASH_LEN 20
  43. #if 1
  44. // client authentication doesn't know about sha1
  45. #define SIGNATURE_ALG_OBJID szOID_RSA_MD5RSA
  46. #else
  47. #define SIGNATURE_ALG_OBJID szOID_OIWSEC_sha1RSASign
  48. #endif
  49. #define DSS_SIGNATURE_ALG_OBJID szOID_X957_SHA1DSA
  50. #define ENH_1024_CONTAINER_NAME_A "Regression 1024"
  51. #define ENH_1024_CONTAINER_NAME_W L"Regression 1024"
  52. #define ENH_2048_CONTAINER_NAME_A "Regression 2048"
  53. #define ENH_2048_CONTAINER_NAME_W L"Regression 2048"
  54. #define DSS_512_CONTAINER_NAME_A "Regression 512"
  55. #define DSS_512_CONTAINER_NAME_W L"Regression 512"
  56. //+-------------------------------------------------------------------------
  57. // Parameters, data used to encode the messages.
  58. //--------------------------------------------------------------------------
  59. static DWORD dwCertEncodingType = X509_ASN_ENCODING;
  60. static DWORD dwMsgEncodingType = PKCS_7_ASN_ENCODING;
  61. static DWORD dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;
  62. static SYSTEMTIME TestTime;
  63. static LPSTR pszContainer = NULL;
  64. static LPWSTR pwszContainer = NULL;
  65. static HCRYPTPROV hRSACryptProv = 0;
  66. static HCRYPTPROV hEnh1024CryptProv = 0;
  67. static HCRYPTPROV hEnh2048CryptProv = 0;
  68. static HCRYPTPROV hDSSCryptProv = 0;
  69. static HCRYPTPROV hDSS512CryptProv = 0;
  70. static BOOL fGenerate = FALSE;
  71. static BOOL fExportable = FALSE;
  72. static BOOL fUserProtected = FALSE;
  73. static BOOL fProviders = FALSE;
  74. static BOOL fMachine = FALSE;
  75. static BOOL fInheritParameters = FALSE;
  76. #define TIME_INVALID_PARA_FLAG 0x00000001
  77. #define REVOKED_PARA_FLAG 0x00000002
  78. #define PROV_PARA_FLAG 0x00000004
  79. #define XCHG_PARA_FLAG 0x00000008
  80. #define CA_PARA_FLAG 0x00000010
  81. #define NO_NAME_PARA_FLAG 0x00000020
  82. #define ALT_DIR_NAME_PARA_FLAG 0x00000040
  83. #define SET_PARA_FLAG 0x00000080
  84. #define ALL_EXT_PARA_FLAG 0x00000100
  85. #define SPC_EXT_PARA_FLAG 0x00000200
  86. #define SPC_COM_PARA_FLAG 0x00000400
  87. #define SPC_AGENCY_PARA_FLAG 0x00000800
  88. #define SPC_AGENCY_INFO_PARA_FLAG 0x00001000
  89. // "Valid" certs to give to other companies to test interoperability
  90. #define VALID_PARA_FLAG 0x00002000
  91. #define DELTA_CRL_PARA_FLAG 0x00004000
  92. #define AUX1_PARA_FLAG 0x00010000
  93. #define AUX2_PARA_FLAG 0x00020000
  94. // For duplicate, use previous cert's serial number
  95. #define DUPLICATE_PARA_FLAG 0x00040000
  96. #define NO_EXT_PARA_FLAG 0x00080000
  97. #define DUPLICATE_CRL_PARA_FLAG 0x00100000
  98. #define NO_CRL_EXT_PARA_FLAG 0x00200000
  99. #define GENERALIZED_TIME_PARA_FLAG 0x00400000
  100. #define NETSCAPE_PARA_FLAG 0x00800000
  101. #define CTL1_PARA_FLAG 0x01000000
  102. #define CTL2_PARA_FLAG 0x02000000
  103. #define USE1_PARA_FLAG 0x04000000
  104. #define USE2_PARA_FLAG 0x08000000
  105. #define HTTP_PARA_FLAG 0x10000000
  106. #define DSS_PARA_FLAG 0x80000000
  107. #define DSS_512_PARA_FLAG 0x40000000
  108. #define ENH_1024_PARA_FLAG 0x40000000
  109. #define ENH_2048_PARA_FLAG 0x20000000
  110. #define szSignManifold "Signer Manifold"
  111. #define szXchgManifold "Recipient Manifold"
  112. typedef struct _CERT_PARA {
  113. LPSTR pszName;
  114. DWORD dwIssuer;
  115. DWORD dwFlags;
  116. LPSTR pszManifold;
  117. } CERT_PARA;
  118. #define BASE_OR_DELTA_CA_ISSUER 1
  119. #define UPDATE_CTL_SIGNER 1
  120. #define POLICY_ROOT 0
  121. #define POLICY_CA 1
  122. #define CERT_CNT 76
  123. static CERT_PARA CertPara[CERT_CNT] = {
  124. "root", 0, CA_PARA_FLAG, // 0
  125. NULL,
  126. "CA", 0, CA_PARA_FLAG |
  127. DUPLICATE_CRL_PARA_FLAG, // 1
  128. NULL,
  129. "TestRoot", 2, CA_PARA_FLAG |
  130. ENH_2048_PARA_FLAG |
  131. VALID_PARA_FLAG, // 2
  132. NULL,
  133. "TestSigner", 2, PROV_PARA_FLAG | VALID_PARA_FLAG |
  134. USE1_PARA_FLAG, // 3
  135. szSignManifold,
  136. "TestRecipient",2, PROV_PARA_FLAG | XCHG_PARA_FLAG |
  137. VALID_PARA_FLAG | USE1_PARA_FLAG, // 4
  138. szXchgManifold,
  139. "me", 1, PROV_PARA_FLAG |
  140. ENH_1024_PARA_FLAG |
  141. USE2_PARA_FLAG, // 5
  142. NULL,
  143. "me", 1, PROV_PARA_FLAG |
  144. ENH_1024_PARA_FLAG |
  145. XCHG_PARA_FLAG, // 6
  146. NULL,
  147. "setrevoked", 1, REVOKED_PARA_FLAG | PROV_PARA_FLAG |
  148. SET_PARA_FLAG |
  149. ENH_2048_PARA_FLAG, // 7
  150. NULL,
  151. "setrevoked", 1, REVOKED_PARA_FLAG | XCHG_PARA_FLAG |
  152. SET_PARA_FLAG |
  153. PROV_PARA_FLAG | ENH_2048_PARA_FLAG,// 8
  154. NULL,
  155. "time invalid", 1, TIME_INVALID_PARA_FLAG, // 9
  156. NULL,
  157. "setkeith", 1, SET_PARA_FLAG, // 10
  158. NULL,
  159. "setkeith", 1, XCHG_PARA_FLAG | USE2_PARA_FLAG | // 11
  160. SET_PARA_FLAG,
  161. NULL,
  162. "kevin", 1, 0, // 12
  163. NULL,
  164. "kevin", 1, XCHG_PARA_FLAG | USE2_PARA_FLAG, // 13
  165. NULL,
  166. "all ext", 1, ALL_EXT_PARA_FLAG | AUX1_PARA_FLAG |
  167. SET_PARA_FLAG |
  168. ALT_DIR_NAME_PARA_FLAG |
  169. AUX2_PARA_FLAG |
  170. USE1_PARA_FLAG | USE2_PARA_FLAG, // 14
  171. NULL,
  172. "MSPub", 17, SPC_EXT_PARA_FLAG | SPC_COM_PARA_FLAG |
  173. PROV_PARA_FLAG | USE1_PARA_FLAG, // 15
  174. NULL,
  175. "PhilPub", 17, SPC_EXT_PARA_FLAG | PROV_PARA_FLAG |
  176. USE2_PARA_FLAG, // 16
  177. NULL,
  178. "MSAgency", 1, SPC_EXT_PARA_FLAG | SPC_AGENCY_PARA_FLAG |
  179. PROV_PARA_FLAG | CA_PARA_FLAG, // 17
  180. NULL,
  181. "AgencyInfo", 1, SPC_AGENCY_INFO_PARA_FLAG, // 18
  182. NULL,
  183. "duplicate1", 1, AUX1_PARA_FLAG | NO_EXT_PARA_FLAG |
  184. USE1_PARA_FLAG, // 19
  185. NULL,
  186. "duplicate2", 1, AUX2_PARA_FLAG | NO_EXT_PARA_FLAG |
  187. DUPLICATE_PARA_FLAG |
  188. USE2_PARA_FLAG, // 20
  189. NULL,
  190. "GeneralRoot", 21, CA_PARA_FLAG |
  191. GENERALIZED_TIME_PARA_FLAG |
  192. PROV_PARA_FLAG |
  193. DSS_PARA_FLAG, // 21
  194. NULL,
  195. "GeneralTime", 21, GENERALIZED_TIME_PARA_FLAG |
  196. PROV_PARA_FLAG |
  197. DSS_512_PARA_FLAG |
  198. DSS_PARA_FLAG, // 22
  199. NULL,
  200. "Generalrevoked", 21, REVOKED_PARA_FLAG | DSS_PARA_FLAG, // 23
  201. NULL,
  202. "NoCRLExtCA", 0, CA_PARA_FLAG | NO_CRL_EXT_PARA_FLAG, // 24
  203. NULL,
  204. "NoCRLExtrevoked", 24, REVOKED_PARA_FLAG, // 25
  205. NULL,
  206. "NetscapeCA", 0, NETSCAPE_PARA_FLAG | CA_PARA_FLAG |
  207. DSS_PARA_FLAG |
  208. REVOKED_PARA_FLAG, // 26
  209. NULL,
  210. "Netscape", 26, NETSCAPE_PARA_FLAG | REVOKED_PARA_FLAG, // 27
  211. NULL,
  212. "Ctl0", 1, CTL1_PARA_FLAG | NO_EXT_PARA_FLAG, // 28
  213. NULL,
  214. "Ctl1", 2, CTL1_PARA_FLAG, // 29
  215. NULL,
  216. "Ctl1Invalid", 2, CTL1_PARA_FLAG | TIME_INVALID_PARA_FLAG |
  217. DUPLICATE_PARA_FLAG, // 30
  218. NULL,
  219. "Ctl2", 1, CTL2_PARA_FLAG, // 31
  220. NULL,
  221. "Ctl2Invalid", 1, CTL2_PARA_FLAG | TIME_INVALID_PARA_FLAG |
  222. DUPLICATE_PARA_FLAG, // 32
  223. NULL,
  224. "Http2", 1, CTL2_PARA_FLAG | HTTP_PARA_FLAG |
  225. NO_EXT_PARA_FLAG, // 33
  226. NULL,
  227. "Http2Invalid", 1, CTL2_PARA_FLAG | TIME_INVALID_PARA_FLAG |
  228. DUPLICATE_PARA_FLAG | HTTP_PARA_FLAG |
  229. NO_EXT_PARA_FLAG, // 34
  230. NULL,
  231. "NoNameIssuer1", 0, CA_PARA_FLAG | ALT_DIR_NAME_PARA_FLAG, // 35
  232. NULL,
  233. "NoNameSubject1", 35, NO_NAME_PARA_FLAG, // 36
  234. NULL,
  235. "NoNameIssuer2", 0, CA_PARA_FLAG | ALT_DIR_NAME_PARA_FLAG, // 37
  236. NULL,
  237. "NoNameSubject2", 37, NO_NAME_PARA_FLAG |
  238. ALT_DIR_NAME_PARA_FLAG, // 38
  239. NULL,
  240. "Hellman", 21, XCHG_PARA_FLAG | NO_EXT_PARA_FLAG |
  241. PROV_PARA_FLAG |
  242. DSS_PARA_FLAG, // 39
  243. NULL,
  244. "TestSigner2", 2, PROV_PARA_FLAG | VALID_PARA_FLAG |
  245. USE1_PARA_FLAG, // 40
  246. szSignManifold,
  247. "TestRecipient2", 2, PROV_PARA_FLAG | XCHG_PARA_FLAG |
  248. VALID_PARA_FLAG | USE1_PARA_FLAG, // 41
  249. szXchgManifold,
  250. "TestSigner3", 2, PROV_PARA_FLAG | VALID_PARA_FLAG |
  251. USE1_PARA_FLAG, // 42
  252. szSignManifold,
  253. "UTF8", 2, VALID_PARA_FLAG | NO_EXT_PARA_FLAG, // 43
  254. NULL,
  255. "DssRoot", 44, CA_PARA_FLAG | VALID_PARA_FLAG |
  256. NO_EXT_PARA_FLAG |
  257. DSS_PARA_FLAG, // 44
  258. NULL,
  259. "DssCA", 44, CA_PARA_FLAG | VALID_PARA_FLAG |
  260. NO_EXT_PARA_FLAG |
  261. DSS_PARA_FLAG, // 45
  262. NULL,
  263. "DssEnd", 45, VALID_PARA_FLAG | NO_EXT_PARA_FLAG |
  264. PROV_PARA_FLAG |
  265. DSS_PARA_FLAG, // 46
  266. NULL,
  267. "ZeroNotAfter", 2, VALID_PARA_FLAG |
  268. PROV_PARA_FLAG, // 47
  269. NULL,
  270. "V1", 48, CA_PARA_FLAG | VALID_PARA_FLAG |
  271. NO_EXT_PARA_FLAG |
  272. NO_CRL_EXT_PARA_FLAG, // 48
  273. NULL,
  274. "V2", 48, VALID_PARA_FLAG | NO_EXT_PARA_FLAG, // 49
  275. NULL,
  276. "DeltaEndValid", 1, DELTA_CRL_PARA_FLAG, // 50
  277. NULL,
  278. "DeltaNoValid", 1, DELTA_CRL_PARA_FLAG | NO_EXT_PARA_FLAG, // 51
  279. NULL,
  280. "DeltaEndRevoked", 1, DELTA_CRL_PARA_FLAG | // 52
  281. REVOKED_PARA_FLAG,
  282. NULL,
  283. "DeltaCAValid", 1, DELTA_CRL_PARA_FLAG | // 53
  284. CA_PARA_FLAG,
  285. NULL,
  286. "DeltaCARevoked", 1, DELTA_CRL_PARA_FLAG | // 54
  287. CA_PARA_FLAG |
  288. REVOKED_PARA_FLAG,
  289. NULL,
  290. "NoCDPValid", 1, DELTA_CRL_PARA_FLAG, // 55
  291. NULL,
  292. "NoCDPRevoked", 1, DELTA_CRL_PARA_FLAG | // 56
  293. REVOKED_PARA_FLAG,
  294. NULL,
  295. "UnsupportedCDP", 1, DELTA_CRL_PARA_FLAG | // 57
  296. REVOKED_PARA_FLAG,
  297. NULL,
  298. "NotPermitted", 1, ALT_DIR_NAME_PARA_FLAG, // 58
  299. NULL,
  300. "Excluded", 1, ALT_DIR_NAME_PARA_FLAG, // 59
  301. NULL,
  302. "TestAIARoot", 60, CA_PARA_FLAG | NO_EXT_PARA_FLAG | // 60
  303. NO_CRL_EXT_PARA_FLAG,
  304. NULL,
  305. "TestAIARevokeRoot", 61, CA_PARA_FLAG | NO_EXT_PARA_FLAG | // 61
  306. NO_CRL_EXT_PARA_FLAG,
  307. NULL,
  308. "TestAIACA", 60, CA_PARA_FLAG | NO_EXT_PARA_FLAG | // 62
  309. NO_CRL_EXT_PARA_FLAG,
  310. NULL,
  311. "TestAIACA", 61, CA_PARA_FLAG | NO_EXT_PARA_FLAG |
  312. NO_CRL_EXT_PARA_FLAG |
  313. REVOKED_PARA_FLAG, // 63
  314. NULL,
  315. "TestAIAEnd", 63, NO_EXT_PARA_FLAG, // 64
  316. NULL,
  317. "MissingNCCA", 0, CA_PARA_FLAG, // 65
  318. NULL,
  319. "MissingNCEnd", 65, 0, // 66
  320. NULL,
  321. "TestAIAExpireRoot", 67, CA_PARA_FLAG | NO_EXT_PARA_FLAG | // 67
  322. NO_CRL_EXT_PARA_FLAG,
  323. NULL,
  324. "TestAIACA", 67, CA_PARA_FLAG | NO_EXT_PARA_FLAG |
  325. NO_CRL_EXT_PARA_FLAG |
  326. TIME_INVALID_PARA_FLAG, // 68
  327. NULL,
  328. "InvalidKeyUsageCA", 2, CA_PARA_FLAG | VALID_PARA_FLAG, // 69
  329. NULL,
  330. "InvalidKeyUsageEnd", 69, NO_EXT_PARA_FLAG, // 70
  331. NULL,
  332. "RolloverRoot", 71, CA_PARA_FLAG | VALID_PARA_FLAG | NO_EXT_PARA_FLAG |
  333. DSS_PARA_FLAG, // 71
  334. NULL,
  335. "RolloverCA", 71, CA_PARA_FLAG | VALID_PARA_FLAG | NO_EXT_PARA_FLAG |
  336. DSS_PARA_FLAG, // 72
  337. NULL,
  338. "RolloverEnd", 72, VALID_PARA_FLAG |
  339. DSS_PARA_FLAG, // 73
  340. NULL,
  341. "RolloverRoot", 2, CA_PARA_FLAG | VALID_PARA_FLAG | NO_EXT_PARA_FLAG|
  342. ENH_1024_PARA_FLAG,
  343. NULL, // 74
  344. "RolloverRoot", 74, CA_PARA_FLAG | VALID_PARA_FLAG | NO_EXT_PARA_FLAG |
  345. DSS_PARA_FLAG, // 75
  346. NULL,
  347. };
  348. #define ROLLOVER_CROSS_CERT 74
  349. #define EXPIRED_CRL_FLAG 0x00000001
  350. #define REMOVE_FROM_CRL_FLAG 0x00000002
  351. #define HOLD_CRL_FLAG 0x00000004
  352. #define FRESHEST_CRL_FLAG 0x00000010
  353. #define NO_FRESHEST_CDP_CRL_FLAG 0x00000020
  354. #define NO_IDP_CRL_FLAG 0x00000100
  355. #define ONLY_USERS_CRL_FLAG 0x00000200
  356. #define ONLY_CAS_CRL_FLAG 0x00000400
  357. #define UNSUPPORTED_IDP_OPTIONS_CRL_FLAG 0x00000800
  358. #define UNSUPPORTED_CRITICAL_EXT_CRL_FLAG 0x00001000
  359. #define NO_ENTRIES_CRL_FLAG 0x00002000
  360. typedef struct _BASE_DELTA_CRL_PARA {
  361. int iBase;
  362. DWORD dwFlags;
  363. } BASE_DELTA_CRL_PARA;
  364. static BASE_DELTA_CRL_PARA BaseDeltaCrlPara[] = {
  365. // Users Only: Base and Delta
  366. 1, ONLY_USERS_CRL_FLAG,
  367. 1, ONLY_USERS_CRL_FLAG | FRESHEST_CRL_FLAG,
  368. // CAs Only: Base and Delta
  369. 2, ONLY_CAS_CRL_FLAG,
  370. 2, ONLY_CAS_CRL_FLAG | FRESHEST_CRL_FLAG,
  371. // Base has entries, Delta has no entries
  372. 3, HOLD_CRL_FLAG,
  373. 3, NO_ENTRIES_CRL_FLAG | FRESHEST_CRL_FLAG,
  374. // Base has no entries, Delta has entries
  375. 4, NO_ENTRIES_CRL_FLAG,
  376. 4, FRESHEST_CRL_FLAG,
  377. // Base has entries, Delta has remove entries
  378. 5, HOLD_CRL_FLAG,
  379. 5, REMOVE_FROM_CRL_FLAG | FRESHEST_CRL_FLAG,
  380. // Valid base, delta has unsupported IDP options
  381. 6, HOLD_CRL_FLAG,
  382. 6, FRESHEST_CRL_FLAG | UNSUPPORTED_IDP_OPTIONS_CRL_FLAG,
  383. // Expired base, valid delta
  384. 7, EXPIRED_CRL_FLAG,
  385. 7, FRESHEST_CRL_FLAG,
  386. // Valid base, expired delta
  387. 8, 0,
  388. 8, EXPIRED_CRL_FLAG | FRESHEST_CRL_FLAG,
  389. // Expired base, without a freshest CDP extension
  390. 9, EXPIRED_CRL_FLAG | NO_FRESHEST_CDP_CRL_FLAG,
  391. 9, FRESHEST_CRL_FLAG,
  392. // Base without IDP and no freshest, delta CRL
  393. 10, NO_IDP_CRL_FLAG | NO_FRESHEST_CDP_CRL_FLAG,
  394. // Base and Delta CRL with unsupported critical ext
  395. 11, UNSUPPORTED_CRITICAL_EXT_CRL_FLAG,
  396. 11, UNSUPPORTED_CRITICAL_EXT_CRL_FLAG | FRESHEST_CRL_FLAG,
  397. // Valid base with number > above delta indicator
  398. 100, 0,
  399. };
  400. #define BASE_DELTA_CRL_CNT \
  401. (sizeof(BaseDeltaCrlPara)/sizeof(BaseDeltaCrlPara[0]))
  402. typedef struct _UPDATE_CTL_PARA {
  403. BOOL fTimeInvalid;
  404. LPSTR pszUsageObjId;
  405. LPSTR pszListIdentifier;
  406. LPWSTR pwszUrl;
  407. } UPDATE_CTL_PARA;
  408. static UPDATE_CTL_PARA UpdateCtlPara[] = {
  409. FALSE, "1.3.2000.1", "UpdateCtl1", L"file://testupdate1.ctl",
  410. TRUE, "1.3.2000.1", "UpdateCtl1", L"file://testupdate1.ctl",
  411. FALSE, "1.3.2000.2", "UpdateCtl2", L"file://testupdate2.ctl",
  412. TRUE, "1.3.2000.2", "UpdateCtl2", L"file://testupdate2.ctl",
  413. };
  414. #define UPDATE_CTL_CNT (sizeof(UpdateCtlPara)/sizeof(UpdateCtlPara[0]))
  415. #define STRING_OTHER_NAME_OID "1.2.3.4.2600.1"
  416. #define OCTET_OTHER_NAME_OID "1.2.3.4.2600.2"
  417. #define RDN_CNT 4
  418. #define ATTR_CNT 4
  419. #define ATTR_0_OBJID szOID_COMMON_NAME
  420. #define ATTR_1_OBJID "1.2.1"
  421. #define ATTR_2_OBJID "1.2.2"
  422. #define UTF8_NAME L"*** UTF8 ***"
  423. // Attr[0] - CertPara[].pszName
  424. // Attr[1] - "xchg" | "sign"
  425. // Attr[2] - "default" | pszContainer
  426. static LPSTR rgpszUsageIdentifier[] = {
  427. "1.2.3.0", // 0
  428. "1.2.3.1", // 1
  429. "1.2.3.2", // 2
  430. "1.2.3.2.1" // 3
  431. };
  432. static CTL_USAGE rgCtlUsage[] = {
  433. 1, &rgpszUsageIdentifier[0], // 0
  434. 1, &rgpszUsageIdentifier[1], // 1
  435. 2, &rgpszUsageIdentifier[2], // 2
  436. 3, &rgpszUsageIdentifier[1] // 3
  437. };
  438. static PCCERT_CONTEXT rgpCertContext[CERT_CNT];
  439. void MySystemTimeToFileTime(
  440. SYSTEMTIME *pSystemTime,
  441. FILETIME *pFileTime
  442. )
  443. {
  444. SYSTEMTIME TmpTime;
  445. if (!SystemTimeToFileTime(pSystemTime, pFileTime)) {
  446. TmpTime = *pSystemTime;
  447. // Following is a fix for Feb 29, 2000 when advancing the year forward or backward.
  448. TmpTime.wDay = 1;
  449. SystemTimeToFileTime(&TmpTime, pFileTime);
  450. }
  451. }
  452. //+-------------------------------------------------------------------------
  453. // Error output routines
  454. //--------------------------------------------------------------------------
  455. static void PrintError(LPCSTR pszMsg)
  456. {
  457. printf("%s\n", pszMsg);
  458. }
  459. static void PrintLastError(LPCSTR pszMsg)
  460. {
  461. DWORD dwErr = GetLastError();
  462. printf("%s failed => 0x%x (%d) \n", pszMsg, dwErr, dwErr);
  463. }
  464. //+-------------------------------------------------------------------------
  465. // Test allocation and free routines
  466. //--------------------------------------------------------------------------
  467. static
  468. LPVOID
  469. WINAPI
  470. TestAlloc(
  471. IN size_t cbBytes
  472. )
  473. {
  474. LPVOID pv;
  475. pv = malloc(cbBytes);
  476. if (pv == NULL) {
  477. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  478. PrintLastError("TestAlloc");
  479. }
  480. return pv;
  481. }
  482. static
  483. VOID
  484. WINAPI
  485. TestFree(
  486. IN LPVOID pv
  487. )
  488. {
  489. if (pv)
  490. free(pv);
  491. }
  492. //+-------------------------------------------------------------------------
  493. // Allocate and convert a multi-byte string to a wide string
  494. //--------------------------------------------------------------------------
  495. static LPWSTR AllocAndSzToWsz(LPCSTR psz)
  496. {
  497. size_t cb;
  498. LPWSTR pwsz = NULL;
  499. if (-1 == (cb = mbstowcs( NULL, psz, strlen(psz))))
  500. goto bad_param;
  501. cb += 1; // terminating NULL
  502. if (NULL == (pwsz = (LPWSTR)TestAlloc( cb * sizeof(WCHAR)))) {
  503. PrintLastError("AllocAndSzToWsz");
  504. goto failed;
  505. }
  506. if (-1 == mbstowcs( pwsz, psz, cb))
  507. goto bad_param;
  508. goto common_return;
  509. bad_param:
  510. PrintError("Bad AllocAndSzToWsz");
  511. failed:
  512. if (pwsz) {
  513. TestFree(pwsz);
  514. pwsz = NULL;
  515. }
  516. common_return:
  517. return pwsz;
  518. }
  519. static HCRYPTPROV GetCryptProv(
  520. DWORD dwProvType,
  521. LPCSTR pszProvider = NULL,
  522. LPCSTR pszInContainer = pszContainer,
  523. DWORD dwBitLen = 0
  524. )
  525. {
  526. HCRYPTPROV hProv = 0;
  527. BOOL fResult;
  528. DWORD dwFlags;
  529. if (fMachine)
  530. dwFlags = CRYPT_MACHINE_KEYSET;
  531. else
  532. dwFlags = 0;
  533. fResult = CryptAcquireContext(
  534. &hProv,
  535. pszInContainer,
  536. pszProvider,
  537. dwProvType,
  538. dwFlags
  539. );
  540. if (fResult) {
  541. if (fGenerate) {
  542. // Delete the existing keys
  543. CryptReleaseContext(hProv, 0);
  544. printf("Deleting existing private keys\n");
  545. // Note: for CRYPT_DELETEKEYSET, the returned hProv is undefined
  546. // and must not be released.
  547. fResult = CryptAcquireContext(
  548. &hProv,
  549. pszInContainer,
  550. pszProvider,
  551. dwProvType,
  552. dwFlags | CRYPT_DELETEKEYSET
  553. );
  554. if (!fResult) {
  555. PrintLastError("CryptAcquireContext(CRYPT_DELETEKEYSET)");
  556. return 0;
  557. }
  558. hProv = 0;
  559. }
  560. }
  561. if (0 == hProv) {
  562. printf("Creating new private keys\n");
  563. fResult = CryptAcquireContext(
  564. &hProv,
  565. pszInContainer,
  566. pszProvider,
  567. dwProvType,
  568. dwFlags | CRYPT_NEWKEYSET
  569. );
  570. if (!fResult || hProv == 0) {
  571. PrintLastError("CryptAcquireContext(CRYPT_NEWKEYSET)");
  572. return 0;
  573. }
  574. }
  575. HCRYPTKEY hKey = 0;
  576. dwFlags = dwBitLen << 16;
  577. if (fExportable)
  578. dwFlags |= CRYPT_EXPORTABLE;
  579. if (fUserProtected)
  580. dwFlags |= CRYPT_USER_PROTECTED;
  581. if (CryptGetUserKey(
  582. hProv,
  583. AT_SIGNATURE,
  584. &hKey
  585. )) {
  586. printf("Using existing SIGNATURE private key\n");
  587. CryptDestroyKey(hKey);
  588. hKey = 0;
  589. } else {
  590. printf("Generating SIGNATURE private key\n");
  591. fResult = CryptGenKey(
  592. hProv,
  593. AT_SIGNATURE,
  594. dwFlags,
  595. &hKey
  596. );
  597. if (!fResult || hKey == 0)
  598. PrintLastError("CryptGenKey(AT_SIGNATURE)");
  599. else
  600. CryptDestroyKey(hKey);
  601. }
  602. if (PROV_DSS == dwProvType)
  603. return hProv;
  604. if (CryptGetUserKey(
  605. hProv,
  606. AT_KEYEXCHANGE,
  607. &hKey
  608. )) {
  609. printf("Using existing EXCHANGE private key\n");
  610. CryptDestroyKey(hKey);
  611. hKey = 0;
  612. } else {
  613. printf("Generating EXCHANGE private key\n");
  614. hKey = 0;
  615. fResult = CryptGenKey(
  616. hProv,
  617. AT_KEYEXCHANGE,
  618. dwFlags,
  619. &hKey
  620. );
  621. if (!fResult || hKey == 0)
  622. PrintLastError("CryptGenKey(AT_KEYEXCHANGE)");
  623. else
  624. CryptDestroyKey(hKey);
  625. }
  626. return hProv;
  627. }
  628. static HCERTSTORE OpenStore(LPCSTR pszStoreFilename)
  629. {
  630. HCERTSTORE hStore;
  631. HANDLE hFile = 0;
  632. if( INVALID_HANDLE_VALUE == (hFile = CreateFile(pszStoreFilename,
  633. GENERIC_READ,
  634. FILE_SHARE_READ | FILE_SHARE_WRITE,
  635. NULL, OPEN_EXISTING, 0, NULL))) {
  636. hStore = CertOpenStore(
  637. CERT_STORE_PROV_MEMORY,
  638. dwCertEncodingType,
  639. 0, // hCryptProv
  640. 0, // dwFlags
  641. NULL // pvPara
  642. );
  643. } else {
  644. hStore = CertOpenStore(
  645. CERT_STORE_PROV_FILE,
  646. dwCertEncodingType,
  647. 0, // hCryptProv
  648. 0, // dwFlags
  649. hFile
  650. );
  651. CloseHandle(hFile);
  652. }
  653. if (hStore == NULL)
  654. PrintLastError("CertOpenStore");
  655. return hStore;
  656. }
  657. static void SaveStore(HCERTSTORE hStore, LPCSTR pszSaveFilename)
  658. {
  659. HANDLE hFile;
  660. hFile = CreateFile(pszSaveFilename,
  661. GENERIC_WRITE,
  662. 0, // fdwShareMode
  663. NULL, // lpsa
  664. CREATE_ALWAYS,
  665. 0, // fdwAttrsAndFlags
  666. 0); // TemplateFile
  667. if (INVALID_HANDLE_VALUE == hFile) {
  668. printf( "can't open %s\n", pszSaveFilename);
  669. PrintLastError("CloseStore::CreateFile");
  670. } else {
  671. if (!CertSaveStore(
  672. hStore,
  673. 0, // dwEncodingType,
  674. CERT_STORE_SAVE_AS_STORE,
  675. CERT_STORE_SAVE_TO_FILE,
  676. (void *) hFile,
  677. 0 // dwFlags
  678. ))
  679. PrintLastError("CertSaveStore");
  680. CloseHandle(hFile);
  681. }
  682. }
  683. static CRYPT_ENCODE_PARA TestEncodePara = {
  684. offsetof(CRYPT_ENCODE_PARA, pfnFree) + sizeof(TestEncodePara.pfnFree),
  685. TestAlloc,
  686. TestFree
  687. };
  688. static BOOL AllocAndEncodeObject(
  689. IN LPCSTR lpszStructType,
  690. IN const void *pvStructInfo,
  691. OUT BYTE **ppbEncoded,
  692. OUT DWORD *pcbEncoded
  693. )
  694. {
  695. BOOL fResult;
  696. fResult = CryptEncodeObjectEx(
  697. dwCertEncodingType,
  698. lpszStructType,
  699. pvStructInfo,
  700. CRYPT_ENCODE_ALLOC_FLAG,
  701. &TestEncodePara,
  702. (void *) ppbEncoded,
  703. pcbEncoded
  704. );
  705. if (!fResult) {
  706. if ((DWORD_PTR) lpszStructType <= 0xFFFF)
  707. printf("CryptEncodeObject(StructType: %d)",
  708. (DWORD)(DWORD_PTR) lpszStructType);
  709. else
  710. printf("CryptEncodeObject(StructType: %s)",
  711. lpszStructType);
  712. PrintLastError("");
  713. }
  714. return fResult;
  715. }
  716. static BOOL CreateEnhancedKeyUsage(
  717. IN DWORD dwFlags,
  718. OUT BYTE **ppbEncoded,
  719. IN OUT DWORD *pcbEncoded
  720. )
  721. {
  722. PCTL_USAGE pCtlUsage;
  723. dwFlags &= USE1_PARA_FLAG | USE2_PARA_FLAG;
  724. switch (dwFlags) {
  725. case 0:
  726. pCtlUsage = &rgCtlUsage[0];
  727. break;
  728. case USE1_PARA_FLAG:
  729. pCtlUsage = &rgCtlUsage[1];
  730. break;
  731. case USE2_PARA_FLAG:
  732. pCtlUsage = &rgCtlUsage[2];
  733. break;
  734. case USE1_PARA_FLAG | USE2_PARA_FLAG:
  735. default:
  736. pCtlUsage = &rgCtlUsage[3];
  737. break;
  738. }
  739. return AllocAndEncodeObject(
  740. X509_ENHANCED_KEY_USAGE,
  741. (const void *) pCtlUsage,
  742. ppbEncoded,
  743. pcbEncoded
  744. );
  745. }
  746. static BOOL CreateNextUpdateLocation(
  747. DWORD dwCert,
  748. BOOL fProp,
  749. OUT BYTE **ppbEncoded,
  750. IN OUT DWORD *pcbEncoded,
  751. IN OPTIONAL LPWSTR pwszUrl = NULL
  752. )
  753. {
  754. BOOL fResult;
  755. BYTE *pbEncoded = NULL;
  756. DWORD cbEncoded;
  757. CERT_ALT_NAME_INFO AltNameInfo;
  758. CERT_ALT_NAME_ENTRY rgAltNameEntry[5];
  759. rgAltNameEntry[0].dwAltNameChoice = CERT_ALT_NAME_RFC822_NAME;
  760. rgAltNameEntry[0].pwszRfc822Name = L"RFC822";
  761. rgAltNameEntry[1].dwAltNameChoice = CERT_ALT_NAME_URL;
  762. rgAltNameEntry[1].pwszURL = L"file://file1.ctl";
  763. rgAltNameEntry[2].dwAltNameChoice = CERT_ALT_NAME_URL;
  764. rgAltNameEntry[2].pwszURL = L"http://timestamp/ctltest/http1.ctl";
  765. rgAltNameEntry[3].dwAltNameChoice = CERT_ALT_NAME_URL;
  766. rgAltNameEntry[3].pwszURL = L"file://file2.ctl";
  767. rgAltNameEntry[4].dwAltNameChoice = CERT_ALT_NAME_URL;
  768. rgAltNameEntry[4].pwszURL = L"http://timestamp/ctltest/http2.ctl";
  769. if (dwCert == UPDATE_CTL_SIGNER) {
  770. rgAltNameEntry[1].pwszURL = L"file://nonexistant1.ctl";
  771. rgAltNameEntry[2].pwszURL = L"file://nonexistant2.ctl";
  772. if (pwszUrl)
  773. rgAltNameEntry[3].pwszURL = pwszUrl;
  774. else
  775. rgAltNameEntry[3].pwszURL = L"file://testupdate1.ctl";
  776. rgAltNameEntry[4].pwszURL = L"file://nonexistant3.ctl";
  777. AltNameInfo.cAltEntry = 5;
  778. AltNameInfo.rgAltEntry = &rgAltNameEntry[0];
  779. } else if (fProp) {
  780. if (CertPara[dwCert].dwFlags & HTTP_PARA_FLAG)
  781. AltNameInfo.cAltEntry = 2;
  782. else
  783. AltNameInfo.cAltEntry = 1;
  784. AltNameInfo.rgAltEntry = &rgAltNameEntry[3];
  785. } else {
  786. if (CertPara[dwCert].dwFlags & HTTP_PARA_FLAG)
  787. AltNameInfo.cAltEntry = 5;
  788. else
  789. AltNameInfo.cAltEntry = 2;
  790. AltNameInfo.rgAltEntry = &rgAltNameEntry[0];
  791. }
  792. if (!AllocAndEncodeObject(
  793. X509_ALTERNATE_NAME,
  794. &AltNameInfo,
  795. &pbEncoded,
  796. &cbEncoded))
  797. goto ErrorReturn;
  798. fResult = TRUE;
  799. goto CommonReturn;
  800. ErrorReturn:
  801. if (pbEncoded) {
  802. TestFree(pbEncoded);
  803. pbEncoded = NULL;
  804. }
  805. cbEncoded = 0;
  806. fResult = FALSE;
  807. CommonReturn:
  808. *ppbEncoded = pbEncoded;
  809. *pcbEncoded = cbEncoded;
  810. return fResult;
  811. }
  812. static BOOL AddCert(
  813. HCERTSTORE hStore,
  814. DWORD dwCert,
  815. BYTE *pbEncoded,
  816. DWORD cbEncoded)
  817. {
  818. BOOL fResult;
  819. PCCERT_CONTEXT pCert = NULL;
  820. fResult = CertAddEncodedCertificateToStore(hStore, dwCertEncodingType,
  821. pbEncoded, cbEncoded, CERT_STORE_ADD_NEW, NULL);
  822. if (!fResult) {
  823. if (GetLastError() == CRYPT_E_EXISTS) {
  824. printf("Cert already exists in store. Adding duplicate\n");
  825. fResult = CertAddEncodedCertificateToStore(hStore,
  826. dwCertEncodingType, pbEncoded, cbEncoded,
  827. CERT_STORE_ADD_ALWAYS, &pCert);
  828. }
  829. if (!fResult)
  830. PrintLastError("CertAddEncodedCertificateToStore");
  831. } else {
  832. fResult = CertAddEncodedCertificateToStore(hStore,
  833. dwCertEncodingType, pbEncoded, cbEncoded,
  834. CERT_STORE_ADD_USE_EXISTING, &pCert);
  835. if (!fResult)
  836. PrintLastError("CertAddEncodedCertificateToStore");
  837. }
  838. if (pCert) {
  839. if (CertPara[dwCert].dwFlags & PROV_PARA_FLAG) {
  840. CRYPT_KEY_PROV_INFO KeyProvInfo;
  841. memset(&KeyProvInfo, 0, sizeof(KeyProvInfo));
  842. if ((CertPara[dwCert].dwFlags & DSS_PARA_FLAG) &&
  843. (CertPara[dwCert].dwFlags & DSS_512_PARA_FLAG))
  844. KeyProvInfo.pwszContainerName = DSS_512_CONTAINER_NAME_W;
  845. else if (CertPara[dwCert].dwFlags & ENH_1024_PARA_FLAG)
  846. KeyProvInfo.pwszContainerName = ENH_1024_CONTAINER_NAME_W;
  847. else if (CertPara[dwCert].dwFlags & ENH_2048_PARA_FLAG)
  848. KeyProvInfo.pwszContainerName = ENH_2048_CONTAINER_NAME_W;
  849. else if (pwszContainer)
  850. KeyProvInfo.pwszContainerName = pwszContainer;
  851. if (CertPara[dwCert].dwFlags & DSS_PARA_FLAG)
  852. KeyProvInfo.dwProvType = TEST_PROV_DSS;
  853. else
  854. KeyProvInfo.dwProvType = PROV_RSA_FULL;
  855. if (CertPara[dwCert].dwFlags & XCHG_PARA_FLAG) {
  856. KeyProvInfo.dwFlags = CERT_SET_KEY_PROV_HANDLE_PROP_ID;
  857. KeyProvInfo.dwKeySpec = AT_KEYEXCHANGE;
  858. } else
  859. KeyProvInfo.dwKeySpec = AT_SIGNATURE;
  860. if (fMachine)
  861. KeyProvInfo.dwFlags |= CRYPT_MACHINE_KEYSET;
  862. fResult = CertSetCertificateContextProperty(
  863. pCert,
  864. CERT_KEY_PROV_INFO_PROP_ID,
  865. 0, // dwFlags
  866. &KeyProvInfo
  867. );
  868. if (!fResult)
  869. PrintLastError("CertSetCertificateContextProperty");
  870. }
  871. if (((CertPara[dwCert].dwFlags & (USE1_PARA_FLAG | USE2_PARA_FLAG)) &&
  872. (CertPara[dwCert].dwFlags &
  873. (NO_EXT_PARA_FLAG | VALID_PARA_FLAG)))
  874. ||
  875. (CertPara[dwCert].dwFlags & (USE1_PARA_FLAG | USE2_PARA_FLAG)) ==
  876. (USE1_PARA_FLAG | USE2_PARA_FLAG)) {
  877. CRYPT_DATA_BLOB Data;
  878. DWORD dwFlags = CertPara[dwCert].dwFlags;
  879. if (0 == (CertPara[dwCert].dwFlags &
  880. (NO_EXT_PARA_FLAG | VALID_PARA_FLAG)))
  881. dwFlags = 0;
  882. if (CreateEnhancedKeyUsage(
  883. dwFlags,
  884. &Data.pbData,
  885. &Data.cbData)) {
  886. if (!CertSetCertificateContextProperty(
  887. pCert,
  888. CERT_CTL_USAGE_PROP_ID,
  889. 0, // dwFlags
  890. &Data
  891. ))
  892. PrintLastError(
  893. "CertSetCertificateContextProperty(CTL_USAGE)");
  894. TestFree(Data.pbData);
  895. }
  896. }
  897. if (CertPara[dwCert].dwFlags & AUX1_PARA_FLAG) {
  898. DWORD i;
  899. CRYPT_DATA_BLOB Data[4];
  900. BYTE rgbAux0[] = {0x11, 0x0};
  901. BYTE rgbAux1[] = {0x11, 0x1};
  902. BYTE rgbAux2[] = {0x11, 0x2, 0x2};
  903. BYTE rgbAux3[] = {0x11, 0x3, 0x3, 0x3};
  904. Data[0].pbData = NULL;
  905. Data[0].cbData = 0;
  906. Data[1].pbData = rgbAux1;
  907. Data[1].cbData = sizeof(rgbAux1);
  908. Data[2].pbData = rgbAux2;
  909. Data[2].cbData = sizeof(rgbAux2);
  910. Data[3].pbData = rgbAux3;
  911. Data[3].cbData = sizeof(rgbAux3);
  912. for (i = 0; i < 4; i++) {
  913. if (!CertSetCertificateContextProperty(
  914. pCert,
  915. CERT_FIRST_USER_PROP_ID + i,
  916. 0, // dwFlags
  917. &Data[i]
  918. )) {
  919. fResult = FALSE;
  920. PrintLastError("CertSetCertificateContextProperty");
  921. break;
  922. }
  923. }
  924. }
  925. if (CertPara[dwCert].dwFlags & AUX2_PARA_FLAG) {
  926. DWORD i;
  927. CRYPT_DATA_BLOB Data[3];
  928. BYTE rgbAux0[] = {0x22, 0x2, 0x2};
  929. BYTE rgbAux1[] = {0x22, 0x3, 0x3, 0x3};
  930. BYTE rgbAux2[] = {0x22, 0x4, 0x4, 0x4, 0x4, 0x12, 0x34};
  931. Data[0].pbData = rgbAux0;
  932. Data[0].cbData = sizeof(rgbAux0);
  933. Data[1].pbData = rgbAux1;
  934. Data[1].cbData = sizeof(rgbAux1);
  935. Data[2].pbData = rgbAux2;
  936. Data[2].cbData = sizeof(rgbAux2);
  937. for (i = 0; i < 3; i++) {
  938. if (!CertSetCertificateContextProperty(
  939. pCert,
  940. CERT_FIRST_USER_PROP_ID + 2 + i,
  941. 0, // dwFlags
  942. &Data[i]
  943. )) {
  944. fResult = FALSE;
  945. PrintLastError("CertSetCertificateContextProperty");
  946. break;
  947. }
  948. }
  949. if (CertPara[dwCert].dwFlags & AUX1_PARA_FLAG) {
  950. // Delete CERT_FIRST_USER_PROP_ID + 1
  951. if (!CertSetCertificateContextProperty(
  952. pCert,
  953. CERT_FIRST_USER_PROP_ID + 1,
  954. 0, // dwFlags
  955. NULL
  956. )) {
  957. fResult = FALSE;
  958. PrintLastError("CertSetCertificateContextProperty");
  959. }
  960. }
  961. }
  962. CertFreeCertificateContext(pCert);
  963. }
  964. return fResult;
  965. }
  966. static BOOL AddCrl(
  967. HCERTSTORE hStore,
  968. DWORD dwCert,
  969. DWORD dwAuxFlags,
  970. BYTE *pbEncoded,
  971. DWORD cbEncoded,
  972. BOOL fDuplicate = FALSE
  973. )
  974. {
  975. BOOL fResult;
  976. PCCRL_CONTEXT pCrl = NULL;
  977. fResult = CertAddEncodedCRLToStore(hStore, dwCertEncodingType,
  978. pbEncoded, cbEncoded, CERT_STORE_ADD_NEW, NULL);
  979. if (!fResult) {
  980. if (GetLastError() == CRYPT_E_EXISTS) {
  981. if (fDuplicate ||
  982. 0 == strcmp("TestAIACA", CertPara[dwCert].pszName)) {
  983. printf("CRL already exists in store. Adding duplicate\n");
  984. fResult = CertAddEncodedCRLToStore(hStore,
  985. dwCertEncodingType, pbEncoded, cbEncoded,
  986. CERT_STORE_ADD_ALWAYS, &pCrl);
  987. }
  988. }
  989. if (!fResult)
  990. PrintLastError("CertAddEncodedCRLToStore");
  991. } else {
  992. if (fDuplicate)
  993. printf("AddCrl failed => ADD_NEW duplicate succeeded\n");
  994. fResult = CertAddEncodedCRLToStore(hStore,
  995. dwCertEncodingType, pbEncoded, cbEncoded,
  996. CERT_STORE_ADD_USE_EXISTING, &pCrl);
  997. if (!fResult)
  998. PrintLastError("CertAddEncodedCRLToStore");
  999. }
  1000. if (pCrl) {
  1001. if (dwAuxFlags & AUX1_PARA_FLAG) {
  1002. DWORD i;
  1003. CRYPT_DATA_BLOB Data[4];
  1004. BYTE rgbAux0[] = {0x11, 0x0};
  1005. BYTE rgbAux1[] = {0x11, 0x1};
  1006. BYTE rgbAux2[] = {0x11, 0x2, 0x2};
  1007. BYTE rgbAux3[] = {0x11, 0x3, 0x3, 0x3};
  1008. Data[0].pbData = NULL;
  1009. Data[0].cbData = 0;
  1010. Data[1].pbData = rgbAux1;
  1011. Data[1].cbData = sizeof(rgbAux1);
  1012. Data[2].pbData = rgbAux2;
  1013. Data[2].cbData = sizeof(rgbAux2);
  1014. Data[3].pbData = rgbAux3;
  1015. Data[3].cbData = sizeof(rgbAux3);
  1016. for (i = 0; i < 4; i++) {
  1017. if (!CertSetCRLContextProperty(
  1018. pCrl,
  1019. CERT_FIRST_USER_PROP_ID + i,
  1020. 0, // dwFlags
  1021. &Data[i]
  1022. )) {
  1023. fResult = FALSE;
  1024. PrintLastError("CertSetCRLContextProperty");
  1025. break;
  1026. }
  1027. }
  1028. }
  1029. if (dwAuxFlags & AUX2_PARA_FLAG) {
  1030. DWORD i;
  1031. CRYPT_DATA_BLOB Data[3];
  1032. BYTE rgbAux0[] = {0x22, 0x2, 0x2};
  1033. BYTE rgbAux1[] = {0x22, 0x3, 0x3, 0x3};
  1034. BYTE rgbAux2[] = {0x22, 0x4, 0x4, 0x4, 0x4, 0x12, 0x34};
  1035. Data[0].pbData = rgbAux0;
  1036. Data[0].cbData = sizeof(rgbAux0);
  1037. Data[1].pbData = rgbAux1;
  1038. Data[1].cbData = sizeof(rgbAux1);
  1039. Data[2].pbData = rgbAux2;
  1040. Data[2].cbData = sizeof(rgbAux2);
  1041. for (i = 0; i < 3; i++) {
  1042. if (!CertSetCRLContextProperty(
  1043. pCrl,
  1044. CERT_FIRST_USER_PROP_ID + 2 + i,
  1045. 0, // dwFlags
  1046. &Data[i]
  1047. )) {
  1048. fResult = FALSE;
  1049. PrintLastError("CertSetCRLContextProperty");
  1050. break;
  1051. }
  1052. }
  1053. }
  1054. CertFreeCRLContext(pCrl);
  1055. }
  1056. return fResult;
  1057. }
  1058. static BOOL AddCtl(
  1059. HCERTSTORE hStore,
  1060. DWORD dwCert,
  1061. BYTE *pbEncoded,
  1062. DWORD cbEncoded)
  1063. {
  1064. BOOL fResult;
  1065. PCCTL_CONTEXT pCtl = NULL;
  1066. fResult = CertAddEncodedCTLToStore(hStore, dwMsgAndCertEncodingType,
  1067. pbEncoded, cbEncoded, CERT_STORE_ADD_NEW, NULL);
  1068. if (!fResult) {
  1069. if (GetLastError() == CRYPT_E_EXISTS) {
  1070. printf("CTL already exists in store. Adding duplicate\n");
  1071. fResult = CertAddEncodedCTLToStore(hStore,
  1072. dwMsgAndCertEncodingType, pbEncoded, cbEncoded,
  1073. CERT_STORE_ADD_ALWAYS, &pCtl);
  1074. }
  1075. if (!fResult)
  1076. PrintLastError("CertAddEncodedCTLToStore");
  1077. } else {
  1078. fResult = CertAddEncodedCTLToStore(hStore,
  1079. dwMsgAndCertEncodingType, pbEncoded, cbEncoded,
  1080. CERT_STORE_ADD_USE_EXISTING, &pCtl);
  1081. if (!fResult)
  1082. PrintLastError("CertAddEncodedCTLToStore");
  1083. }
  1084. if (pCtl) {
  1085. if (0 == (CertPara[dwCert].dwFlags & NO_EXT_PARA_FLAG)) {
  1086. CRYPT_DATA_BLOB Data;
  1087. if (CreateNextUpdateLocation(
  1088. dwCert,
  1089. TRUE, // fProp
  1090. &Data.pbData,
  1091. &Data.cbData)) {
  1092. if (!CertSetCTLContextProperty(
  1093. pCtl,
  1094. CERT_NEXT_UPDATE_LOCATION_PROP_ID,
  1095. 0, // dwFlags
  1096. &Data
  1097. ))
  1098. PrintLastError(
  1099. "CertSetCertificateContextProperty(NEXT_UPDATE)");
  1100. TestFree(Data.pbData);
  1101. }
  1102. }
  1103. CertFreeCTLContext(pCtl);
  1104. }
  1105. return fResult;
  1106. }
  1107. #define AKI2_KEYID 0
  1108. #define AKI2_NONE 1
  1109. #define AKI2_FULL 2
  1110. #define AKI2_BAD_KEYID 3
  1111. #define AKI2_BAD_ISSUER 4
  1112. #define AKI2_BAD_SERIAL_NUMBER 5
  1113. #define AKI2_CNT 6
  1114. // On 02-May-01 updated to not look at the IssuerAndSerialNumber in the CRL's
  1115. // AKI
  1116. #define AKI2_BAD_CNT 1
  1117. static BOOL EncodeCert(DWORD dwCert, BYTE **ppbEncoded, DWORD *pcbEncoded);
  1118. static BOOL EncodeCrl(
  1119. DWORD dwCert,
  1120. BYTE **ppbEncoded,
  1121. DWORD *pcbEncoded,
  1122. DWORD dwAki = AKI2_KEYID
  1123. );
  1124. static BOOL EncodeBaseOrDeltaCrl(
  1125. DWORD dwIssuer,
  1126. int iBase,
  1127. DWORD dwFlags,
  1128. BYTE **ppbEncoded,
  1129. DWORD *pcbEncoded
  1130. );
  1131. static BOOL EncodeCtl(DWORD dwCert, DWORD dwEncodeFlags, BYTE **ppbEncoded,
  1132. DWORD *pcbEncoded);
  1133. static BOOL EncodeUpdateCtl(
  1134. BOOL fTimeInvalid,
  1135. LPSTR pszUsageObjId,
  1136. LPSTR pszListIdentifier,
  1137. LPWSTR pwszUrl,
  1138. BYTE **ppbEncoded,
  1139. DWORD *pcbEncoded
  1140. );
  1141. static void Usage(void)
  1142. {
  1143. printf("Usage: tstore2 [options] <StoreFilename>\n");
  1144. printf("Options are:\n");
  1145. printf(" -h - This message\n");
  1146. printf(" -c<name> - Crypto key container name\n");
  1147. printf(" -g - Generate new keys\n");
  1148. printf(" -E - Exportable private keys\n");
  1149. printf(" -U - User protected private keys\n");
  1150. printf(" -M - Store in local Machine, not current User\n");
  1151. printf(" -P - Use enhanced and DSS providers\n");
  1152. printf(" -I - Inherit DSS public key parameters\n");
  1153. printf(" -K - Keep extra Crls\n");
  1154. printf("\n");
  1155. }
  1156. int _cdecl main(int argc, char * argv[])
  1157. {
  1158. LPSTR pszStoreFilename = NULL;
  1159. HANDLE hStore = 0;
  1160. BYTE *pbEncoded = NULL;
  1161. DWORD cbEncoded;
  1162. DWORD i;
  1163. BOOL fKeepCrls = FALSE;
  1164. while (--argc>0)
  1165. {
  1166. if (**++argv == '-')
  1167. {
  1168. switch(argv[0][1])
  1169. {
  1170. case 'c':
  1171. pszContainer = argv[0]+2;
  1172. pwszContainer = AllocAndSzToWsz(pszContainer);
  1173. if (*pszContainer == '\0') {
  1174. printf("Need to specify crypto key container name\n");
  1175. Usage();
  1176. return -1;
  1177. }
  1178. break;
  1179. case 'g':
  1180. fGenerate = TRUE;
  1181. break;
  1182. case 'E':
  1183. fExportable = TRUE;
  1184. break;
  1185. case 'U':
  1186. fUserProtected = TRUE;
  1187. break;
  1188. case 'M':
  1189. fMachine = TRUE;
  1190. break;
  1191. case 'P':
  1192. fProviders = TRUE;
  1193. break;
  1194. case 'I':
  1195. fInheritParameters = TRUE;
  1196. break;
  1197. case 'K':
  1198. fKeepCrls = TRUE;
  1199. break;
  1200. case 'h':
  1201. default:
  1202. Usage();
  1203. return -1;
  1204. }
  1205. } else
  1206. pszStoreFilename = argv[0];
  1207. }
  1208. if (pszStoreFilename == NULL) {
  1209. printf("missing store filename\n");
  1210. Usage();
  1211. return -1;
  1212. }
  1213. printf("command line: %s\n", GetCommandLine());
  1214. // Get time used time stamping and serial numbers
  1215. GetSystemTime(&TestTime);
  1216. TestTime.wMilliseconds = 0;
  1217. printf("Getting RSA provider\n");
  1218. hRSACryptProv = GetCryptProv(PROV_RSA_FULL, MS_DEF_PROV_A);
  1219. if (hRSACryptProv == 0)
  1220. return -1;
  1221. printf("Getting DSS provider\n");
  1222. hDSSCryptProv = GetCryptProv(TEST_PROV_DSS);
  1223. if (fProviders) {
  1224. printf("Getting Enhanced RSA provider (1024 bit)\n");
  1225. hEnh1024CryptProv = GetCryptProv(PROV_RSA_FULL, MS_ENHANCED_PROV_A,
  1226. ENH_1024_CONTAINER_NAME_A, 1024);
  1227. if (hEnh1024CryptProv == 0)
  1228. return -1;
  1229. printf("Getting Enhanced RSA provider (2048 bit)\n");
  1230. hEnh2048CryptProv = GetCryptProv(PROV_RSA_FULL, MS_ENHANCED_PROV_A,
  1231. ENH_2048_CONTAINER_NAME_A, 2048);
  1232. if (hEnh2048CryptProv == 0)
  1233. return -1;
  1234. printf("Getting DSS provider (512 bit)\n");
  1235. hDSS512CryptProv = GetCryptProv(TEST_PROV_DSS, NULL,
  1236. DSS_512_CONTAINER_NAME_A, 512);
  1237. } else {
  1238. // Disable all enhanced provider flags
  1239. for (i = 0; i < CERT_CNT; i++)
  1240. CertPara[i].dwFlags &= ~(DSS_512_PARA_FLAG |
  1241. ENH_1024_PARA_FLAG | ENH_2048_PARA_FLAG);
  1242. }
  1243. // Attempt to open the store
  1244. hStore = OpenStore(pszStoreFilename);
  1245. if (hStore == NULL)
  1246. goto ErrorReturn;
  1247. // Encode certs and CRLs and add to the store.
  1248. for (i = 0; i < CERT_CNT; i++) {
  1249. if (EncodeCert(i, &pbEncoded, &cbEncoded)) {
  1250. rgpCertContext[i] = CertCreateCertificateContext(
  1251. dwCertEncodingType, pbEncoded, cbEncoded);
  1252. AddCert(hStore, i, pbEncoded, cbEncoded);
  1253. TestFree(pbEncoded);
  1254. pbEncoded = NULL;
  1255. }
  1256. if (CertPara[i].dwFlags & CA_PARA_FLAG) {
  1257. if (0 == strncmp(CertPara[i].pszName, "Rollover", 8)) {
  1258. // No CRL for rollover certs
  1259. ;
  1260. } else if (CertPara[i].dwFlags & DUPLICATE_CRL_PARA_FLAG) {
  1261. DWORD dwAki;
  1262. for (dwAki = 0; dwAki < AKI2_CNT; dwAki++) {
  1263. if (EncodeCrl(i, &pbEncoded, &cbEncoded, dwAki)) {
  1264. if (AKI2_BAD_SERIAL_NUMBER == dwAki)
  1265. // Modify the signature
  1266. pbEncoded[cbEncoded -1] ^= 0xFF;
  1267. AddCrl(hStore, i, AUX1_PARA_FLAG, pbEncoded, cbEncoded);
  1268. AddCrl(hStore, i, AUX2_PARA_FLAG, pbEncoded, cbEncoded,
  1269. TRUE);
  1270. TestFree(pbEncoded);
  1271. pbEncoded = NULL;
  1272. }
  1273. }
  1274. } else {
  1275. if (EncodeCrl(i, &pbEncoded, &cbEncoded)) {
  1276. AddCrl(hStore, i, 0, pbEncoded, cbEncoded);
  1277. TestFree(pbEncoded);
  1278. pbEncoded = NULL;
  1279. }
  1280. }
  1281. }
  1282. }
  1283. // Test CertFindCRLInStore(CRL_FIND_ISSUED_BY)
  1284. for (i = 0; i < CERT_CNT; i++) {
  1285. if ((CA_PARA_FLAG | DUPLICATE_CRL_PARA_FLAG) ==
  1286. ((CA_PARA_FLAG | DUPLICATE_CRL_PARA_FLAG) &
  1287. CertPara[i].dwFlags)) {
  1288. PCCERT_CONTEXT pIssuer = rgpCertContext[i];
  1289. DWORD dwCnt;
  1290. PCCRL_CONTEXT pCrl;
  1291. printf("CertFindCRLInStore(CRL_FIND_ISSUED_BY) [%d]\n", i);
  1292. dwCnt = 0;
  1293. pCrl = NULL;
  1294. while (pCrl = CertFindCRLInStore(
  1295. hStore,
  1296. dwCertEncodingType,
  1297. 0, // dwFindFlags
  1298. CRL_FIND_ISSUED_BY,
  1299. (const void *) pIssuer,
  1300. pCrl
  1301. ))
  1302. dwCnt++;
  1303. if ((AKI2_CNT * 2) != dwCnt)
  1304. printf("CRL_FIND_ISSUED_BY failed count => expected: %d actual: %d\n",
  1305. AKI2_CNT * 2, dwCnt);
  1306. dwCnt = 0;
  1307. pCrl = NULL;
  1308. while (pCrl = CertFindCRLInStore(
  1309. hStore,
  1310. dwCertEncodingType,
  1311. CRL_FIND_ISSUED_BY_AKI_FLAG,
  1312. CRL_FIND_ISSUED_BY,
  1313. (const void *) pIssuer,
  1314. pCrl
  1315. ))
  1316. dwCnt++;
  1317. if (((AKI2_CNT - AKI2_BAD_CNT) * 2) != dwCnt)
  1318. printf("CRL_FIND_ISSUED_BY(AKI_FLAG) failed count => expected: %d actual: %d\n",
  1319. (AKI2_CNT - AKI2_BAD_CNT) * 2, dwCnt);
  1320. dwCnt = 0;
  1321. pCrl = NULL;
  1322. while (pCrl = CertFindCRLInStore(
  1323. hStore,
  1324. dwCertEncodingType,
  1325. CRL_FIND_ISSUED_BY_SIGNATURE_FLAG,
  1326. CRL_FIND_ISSUED_BY,
  1327. (const void *) pIssuer,
  1328. pCrl
  1329. ))
  1330. dwCnt++;
  1331. if (((AKI2_CNT - 1) * 2) != dwCnt)
  1332. printf("CRL_FIND_ISSUED_BY(SIGNATURE_FLAG) failed count => expected: %d actual: %d\n",
  1333. (AKI2_CNT - 1) * 2, dwCnt);
  1334. if (!fKeepCrls) {
  1335. // Delete all but the last pair of duplicates
  1336. dwCnt = 0;
  1337. pCrl = NULL;
  1338. while (pCrl = CertFindCRLInStore(
  1339. hStore,
  1340. dwCertEncodingType,
  1341. 0, // dwFindFlags
  1342. CRL_FIND_ISSUED_BY,
  1343. (const void *) pIssuer,
  1344. pCrl
  1345. )) {
  1346. PCCRL_CONTEXT pDeleteCrl = CertDuplicateCRLContext(pCrl);
  1347. CertDeleteCRLFromStore(pDeleteCrl);
  1348. if (((AKI2_CNT - 1) * 2) == ++dwCnt) {
  1349. CertFreeCRLContext(pCrl);
  1350. break;
  1351. }
  1352. }
  1353. dwCnt = 0;
  1354. pCrl = NULL;
  1355. while (pCrl = CertFindCRLInStore(
  1356. hStore,
  1357. dwCertEncodingType,
  1358. CRL_FIND_ISSUED_BY_AKI_FLAG |
  1359. CRL_FIND_ISSUED_BY_SIGNATURE_FLAG,
  1360. CRL_FIND_ISSUED_BY,
  1361. (const void *) pIssuer,
  1362. pCrl
  1363. ))
  1364. dwCnt++;
  1365. if (2 != dwCnt)
  1366. printf("CRL_FIND_ISSUED_BY(After delete) failed count => expected: %d actual: %d\n",
  1367. 2, dwCnt);
  1368. }
  1369. }
  1370. }
  1371. // Encode CTLs and add to the store.
  1372. for (i = 0; i < CERT_CNT; i++) {
  1373. if (CertPara[i].dwFlags & (CTL1_PARA_FLAG | CTL2_PARA_FLAG)) {
  1374. if (EncodeCtl(i, 0, &pbEncoded, &cbEncoded)) {
  1375. AddCtl(hStore, i, pbEncoded, cbEncoded);
  1376. TestFree(pbEncoded);
  1377. pbEncoded = NULL;
  1378. }
  1379. if (EncodeCtl(
  1380. i,
  1381. #ifdef CMS_PKCS7
  1382. CMSG_CMS_ENCAPSULATED_CTL_FLAG |
  1383. #endif // CMS_PKCS7
  1384. CMSG_ENCODE_SORTED_CTL_FLAG |
  1385. ((CertPara[i].dwFlags & CTL1_PARA_FLAG) ? 0 :
  1386. CMSG_ENCODE_HASHED_SUBJECT_IDENTIFIER_FLAG),
  1387. &pbEncoded,
  1388. &cbEncoded)) {
  1389. AddCtl(hStore, i, pbEncoded, cbEncoded);
  1390. TestFree(pbEncoded);
  1391. pbEncoded = NULL;
  1392. }
  1393. }
  1394. }
  1395. for (i = 0; i < BASE_DELTA_CRL_CNT; i++) {
  1396. if (EncodeBaseOrDeltaCrl(
  1397. BASE_OR_DELTA_CA_ISSUER,
  1398. BaseDeltaCrlPara[i].iBase,
  1399. BaseDeltaCrlPara[i].dwFlags,
  1400. &pbEncoded,
  1401. &cbEncoded)) {
  1402. BOOL fResult;
  1403. fResult = CertAddEncodedCRLToStore(hStore,
  1404. dwCertEncodingType, pbEncoded, cbEncoded,
  1405. CERT_STORE_ADD_ALWAYS, NULL);
  1406. if (!fResult)
  1407. PrintLastError("CertAddEncodedCRLToStore");
  1408. TestFree(pbEncoded);
  1409. pbEncoded = NULL;
  1410. }
  1411. }
  1412. for (i = 0; i < UPDATE_CTL_CNT; i++) {
  1413. if (EncodeUpdateCtl(
  1414. UpdateCtlPara[i].fTimeInvalid,
  1415. UpdateCtlPara[i].pszUsageObjId,
  1416. UpdateCtlPara[i].pszListIdentifier,
  1417. UpdateCtlPara[i].pwszUrl,
  1418. &pbEncoded,
  1419. &cbEncoded)) {
  1420. BOOL fResult;
  1421. fResult = CertAddEncodedCTLToStore(hStore,
  1422. dwMsgAndCertEncodingType, pbEncoded, cbEncoded,
  1423. CERT_STORE_ADD_ALWAYS, NULL);
  1424. if (!fResult)
  1425. PrintLastError("CertAddEncodedCTLToStore");
  1426. TestFree(pbEncoded);
  1427. pbEncoded = NULL;
  1428. }
  1429. }
  1430. for (i = 0; i < CERT_CNT; i++)
  1431. CertFreeCertificateContext(rgpCertContext[i]);
  1432. SaveStore(hStore, pszStoreFilename);
  1433. ErrorReturn:
  1434. if (pbEncoded)
  1435. TestFree(pbEncoded);
  1436. if (hStore) {
  1437. if (!CertCloseStore(hStore, 0))
  1438. PrintLastError("CertCloseStore");
  1439. }
  1440. if (hRSACryptProv)
  1441. CryptReleaseContext(hRSACryptProv, 0);
  1442. if (hEnh1024CryptProv)
  1443. CryptReleaseContext(hEnh1024CryptProv, 0);
  1444. if (hEnh2048CryptProv)
  1445. CryptReleaseContext(hEnh2048CryptProv, 0);
  1446. if (hDSSCryptProv)
  1447. CryptReleaseContext(hDSSCryptProv, 0);
  1448. if (hDSS512CryptProv)
  1449. CryptReleaseContext(hDSS512CryptProv, 0);
  1450. if (pwszContainer)
  1451. TestFree(pwszContainer);
  1452. printf("Done.\n");
  1453. return 0;
  1454. }
  1455. static BOOL AllocAndSignToBeSigned(
  1456. DWORD dwIssuer,
  1457. BYTE *pbToBeSigned,
  1458. DWORD cbToBeSigned,
  1459. PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm,
  1460. BYTE **ppbSignature,
  1461. DWORD *pcbSignature)
  1462. {
  1463. BOOL fResult;
  1464. BYTE *pbSignature = NULL;
  1465. DWORD cbSignature;
  1466. HCRYPTPROV hProv;
  1467. if (CertPara[dwIssuer].dwFlags & DSS_PARA_FLAG) {
  1468. if (CertPara[dwIssuer].dwFlags & DSS_512_PARA_FLAG)
  1469. hProv = hDSS512CryptProv;
  1470. else
  1471. hProv = hDSSCryptProv;
  1472. } else if (CertPara[dwIssuer].dwFlags & ENH_1024_PARA_FLAG)
  1473. hProv = hEnh1024CryptProv;
  1474. else if (CertPara[dwIssuer].dwFlags & ENH_2048_PARA_FLAG)
  1475. hProv = hEnh2048CryptProv;
  1476. else
  1477. hProv = hRSACryptProv;
  1478. cbSignature = 0;
  1479. CryptSignCertificate(
  1480. hProv,
  1481. AT_SIGNATURE,
  1482. dwCertEncodingType,
  1483. pbToBeSigned,
  1484. cbToBeSigned,
  1485. pSignatureAlgorithm,
  1486. NULL, // pvHashAuxInfo
  1487. NULL, // pbSignature
  1488. &cbSignature
  1489. );
  1490. if (cbSignature == 0) {
  1491. PrintLastError("AllocAndSignToBeSigned::CryptSignCertificate(cb == 0)");
  1492. goto ErrorReturn;
  1493. }
  1494. pbSignature = (BYTE *) TestAlloc(cbSignature);
  1495. if (pbSignature == NULL) goto ErrorReturn;
  1496. if (!CryptSignCertificate(
  1497. hProv,
  1498. AT_SIGNATURE,
  1499. dwCertEncodingType,
  1500. pbToBeSigned,
  1501. cbToBeSigned,
  1502. pSignatureAlgorithm,
  1503. NULL, // pvHashAuxInfo
  1504. pbSignature,
  1505. &cbSignature
  1506. )) {
  1507. PrintLastError("AllocAndSignToBeSigned::CryptSignCertificate");
  1508. goto ErrorReturn;
  1509. }
  1510. fResult = TRUE;
  1511. goto CommonReturn;
  1512. ErrorReturn:
  1513. fResult = FALSE;
  1514. if (pbSignature) {
  1515. TestFree(pbSignature);
  1516. pbSignature = NULL;
  1517. }
  1518. cbSignature = 0;
  1519. CommonReturn:
  1520. *ppbSignature = pbSignature;
  1521. *pcbSignature = cbSignature;
  1522. return fResult;
  1523. }
  1524. static BOOL EncodeSignedContent(
  1525. DWORD dwIssuer,
  1526. BYTE *pbToBeSigned,
  1527. DWORD cbToBeSigned,
  1528. BYTE **ppbEncoded,
  1529. DWORD *pcbEncoded)
  1530. {
  1531. BOOL fResult;
  1532. BYTE *pbEncoded = NULL;
  1533. DWORD cbEncoded;
  1534. BYTE *pbSignature = NULL;
  1535. DWORD cbSignature;
  1536. CERT_SIGNED_CONTENT_INFO CertEncoding;
  1537. CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm = {
  1538. SIGNATURE_ALG_OBJID, 0, 0
  1539. };
  1540. if (CertPara[dwIssuer].dwFlags & DSS_PARA_FLAG)
  1541. SignatureAlgorithm.pszObjId = DSS_SIGNATURE_ALG_OBJID;
  1542. if (!AllocAndSignToBeSigned(dwIssuer, pbToBeSigned, cbToBeSigned,
  1543. &SignatureAlgorithm, &pbSignature, &cbSignature))
  1544. goto ErrorReturn;
  1545. memset(&CertEncoding, 0, sizeof(CertEncoding));
  1546. CertEncoding.ToBeSigned.pbData = pbToBeSigned;
  1547. CertEncoding.ToBeSigned.cbData = cbToBeSigned;
  1548. CertEncoding.SignatureAlgorithm = SignatureAlgorithm;
  1549. CertEncoding.Signature.pbData = pbSignature;
  1550. CertEncoding.Signature.cbData = cbSignature;
  1551. if (!AllocAndEncodeObject(
  1552. X509_CERT,
  1553. &CertEncoding,
  1554. &pbEncoded,
  1555. &cbEncoded
  1556. ))
  1557. goto ErrorReturn;
  1558. fResult = TRUE;
  1559. goto CommonReturn;
  1560. ErrorReturn:
  1561. if (pbEncoded) {
  1562. TestFree(pbEncoded);
  1563. pbEncoded = NULL;
  1564. }
  1565. cbEncoded = 0;
  1566. fResult = FALSE;
  1567. CommonReturn:
  1568. if (pbSignature)
  1569. TestFree(pbSignature);
  1570. *ppbEncoded = pbEncoded;
  1571. *pcbEncoded = cbEncoded;
  1572. return fResult;
  1573. }
  1574. static BOOL GetPublicKey(
  1575. DWORD dwCert,
  1576. PCERT_PUBLIC_KEY_INFO *ppPubKeyInfo)
  1577. {
  1578. BOOL fResult;
  1579. PCERT_PUBLIC_KEY_INFO pPubKeyInfo = NULL;
  1580. DWORD cbPubKeyInfo;
  1581. DWORD dwKeySpec;
  1582. HCRYPTPROV hProv;
  1583. if (CertPara[dwCert].dwFlags & XCHG_PARA_FLAG)
  1584. dwKeySpec = AT_KEYEXCHANGE;
  1585. else
  1586. dwKeySpec = AT_SIGNATURE;
  1587. if (CertPara[dwCert].dwFlags & DSS_PARA_FLAG) {
  1588. if (CertPara[dwCert].dwFlags & DSS_512_PARA_FLAG)
  1589. hProv = hDSS512CryptProv;
  1590. else
  1591. hProv = hDSSCryptProv;
  1592. } else if (CertPara[dwCert].dwFlags & ENH_1024_PARA_FLAG)
  1593. hProv = hEnh1024CryptProv;
  1594. else if (CertPara[dwCert].dwFlags & ENH_2048_PARA_FLAG)
  1595. hProv = hEnh2048CryptProv;
  1596. else
  1597. hProv = hRSACryptProv;
  1598. cbPubKeyInfo = 0;
  1599. CryptExportPublicKeyInfo(
  1600. hProv,
  1601. dwKeySpec,
  1602. dwCertEncodingType,
  1603. NULL, // pPubKeyInfo
  1604. &cbPubKeyInfo
  1605. );
  1606. if (cbPubKeyInfo == 0) {
  1607. PrintLastError("GetPublicKey::CryptExportPublicKeyInfo(cb == 0)");
  1608. goto ErrorReturn;
  1609. }
  1610. pPubKeyInfo = (PCERT_PUBLIC_KEY_INFO) TestAlloc(cbPubKeyInfo);
  1611. if (pPubKeyInfo == NULL) goto ErrorReturn;
  1612. if (!CryptExportPublicKeyInfo(
  1613. hProv,
  1614. dwKeySpec,
  1615. dwCertEncodingType,
  1616. pPubKeyInfo,
  1617. &cbPubKeyInfo
  1618. )) {
  1619. PrintLastError("GetPublicKey::CryptExportPublicKeyInfo");
  1620. goto ErrorReturn;
  1621. }
  1622. if (fInheritParameters) {
  1623. DWORD dwIssuer = CertPara[dwCert].dwIssuer;
  1624. if (dwCert != dwIssuer &&
  1625. 0 == (CertPara[dwCert].dwFlags & XCHG_PARA_FLAG) &&
  1626. 0 == (CertPara[dwCert].dwFlags & DSS_512_PARA_FLAG) &&
  1627. 0 != (CertPara[dwCert].dwFlags & DSS_PARA_FLAG) &&
  1628. 0 == (CertPara[dwIssuer].dwFlags & DSS_512_PARA_FLAG) &&
  1629. 0 != (CertPara[dwIssuer].dwFlags & DSS_PARA_FLAG)) {
  1630. pPubKeyInfo->Algorithm.Parameters.cbData = 0;
  1631. pPubKeyInfo->Algorithm.Parameters.pbData = NULL;
  1632. }
  1633. }
  1634. fResult = TRUE;
  1635. goto CommonReturn;
  1636. ErrorReturn:
  1637. fResult = FALSE;
  1638. if (pPubKeyInfo) {
  1639. TestFree(pPubKeyInfo);
  1640. pPubKeyInfo = NULL;
  1641. }
  1642. CommonReturn:
  1643. *ppPubKeyInfo = pPubKeyInfo;
  1644. return fResult;
  1645. }
  1646. #define SHA1_HASH_LEN 20
  1647. static BOOL Sha1HashPublicKey(
  1648. DWORD dwCert,
  1649. BYTE rgbHash[SHA1_HASH_LEN]
  1650. )
  1651. {
  1652. BOOL fResult;
  1653. PCERT_PUBLIC_KEY_INFO pPubKeyInfo = NULL;
  1654. DWORD cbHash;
  1655. // Get Certificates's PUBLIC KEY. SHA1 hash the encoded public key.
  1656. if (!GetPublicKey(dwCert, &pPubKeyInfo)) goto ErrorReturn;
  1657. #if 1
  1658. cbHash = SHA1_HASH_LEN;
  1659. if (!CryptHashPublicKeyInfo(
  1660. 0, // hCryptProv
  1661. CALG_SHA1,
  1662. 0,
  1663. dwCertEncodingType,
  1664. pPubKeyInfo,
  1665. rgbHash,
  1666. &cbHash)) {
  1667. PrintLastError("Sha1HashPublicKey::CryptHashPublicKeyInfo");
  1668. goto ErrorReturn;
  1669. }
  1670. #else
  1671. cbHash = SHA1_HASH_LEN;
  1672. if (!CryptHashCertificate(
  1673. 0, // hCryptProv
  1674. CALG_SHA1,
  1675. 0, // dwFlags
  1676. pPubKeyInfo->PublicKey.pbData,
  1677. pPubKeyInfo->PublicKey.cbData,
  1678. rgbHash,
  1679. &cbHash)) {
  1680. PrintLastError("Sha1HashPublicKey::CryptHashCertificate");
  1681. goto ErrorReturn;
  1682. }
  1683. #endif
  1684. fResult = TRUE;
  1685. goto CommonReturn;
  1686. ErrorReturn:
  1687. fResult = FALSE;
  1688. memset(rgbHash, 0, SHA1_HASH_LEN);
  1689. CommonReturn:
  1690. if (pPubKeyInfo)
  1691. TestFree(pPubKeyInfo);
  1692. return fResult;
  1693. }
  1694. static void CreateNameInfo(
  1695. DWORD dwCert,
  1696. PCERT_NAME_INFO pInfo,
  1697. PCERT_RDN pRDN,
  1698. CERT_RDN_ATTR rgAttr[]
  1699. )
  1700. {
  1701. LPSTR pszKey;
  1702. LPSTR pszUser;
  1703. DWORD i;
  1704. assert(RDN_CNT == ATTR_CNT);
  1705. for (i = 0; i < RDN_CNT; i++) {
  1706. pRDN[i].cRDNAttr = 1;
  1707. pRDN[i].rgRDNAttr = &rgAttr[i];
  1708. }
  1709. if (CertPara[dwCert].dwFlags & NO_NAME_PARA_FLAG) {
  1710. pInfo->cRDN = 0;
  1711. pInfo->rgRDN = NULL;
  1712. } else if (CertPara[dwCert].dwFlags & VALID_PARA_FLAG) {
  1713. pInfo->cRDN = 1;
  1714. pInfo->rgRDN = pRDN;
  1715. } else if (CertPara[dwCert].dwFlags & CA_PARA_FLAG) {
  1716. pInfo->cRDN = RDN_CNT - 1;
  1717. pInfo->rgRDN = pRDN;
  1718. } else {
  1719. pInfo->cRDN = RDN_CNT;
  1720. pInfo->rgRDN = pRDN;
  1721. }
  1722. rgAttr[0].pszObjId = ATTR_0_OBJID;
  1723. if (0 == strcmp("UTF8", CertPara[dwCert].pszName)) {
  1724. rgAttr[0].dwValueType = CERT_RDN_UTF8_STRING;
  1725. rgAttr[0].Value.pbData = (BYTE *) UTF8_NAME;
  1726. rgAttr[0].Value.cbData = wcslen(UTF8_NAME) * sizeof(WCHAR);
  1727. } else {
  1728. rgAttr[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
  1729. rgAttr[0].Value.pbData = (BYTE *) CertPara[dwCert].pszName;
  1730. rgAttr[0].Value.cbData = strlen(CertPara[dwCert].pszName);
  1731. }
  1732. rgAttr[1].pszObjId = ATTR_1_OBJID;
  1733. rgAttr[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
  1734. if (CertPara[dwCert].dwFlags & XCHG_PARA_FLAG)
  1735. pszKey = "xchg";
  1736. else
  1737. pszKey = "sign";
  1738. rgAttr[1].Value.pbData = (BYTE *) pszKey;
  1739. rgAttr[1].Value.cbData = strlen(pszKey);
  1740. rgAttr[2].pszObjId = ATTR_2_OBJID;
  1741. rgAttr[2].dwValueType = CERT_RDN_PRINTABLE_STRING;
  1742. if (pszContainer)
  1743. pszUser = pszContainer;
  1744. else
  1745. pszUser = "default";
  1746. rgAttr[2].Value.pbData = (BYTE *) pszUser;
  1747. rgAttr[2].Value.cbData = strlen(pszUser);
  1748. rgAttr[3].pszObjId = szOID_RSA_emailAddr;
  1749. rgAttr[3].dwValueType = CERT_RDN_IA5_STRING;
  1750. rgAttr[3].Value.pbData = (BYTE *) " [email protected] ";
  1751. rgAttr[3].Value.cbData = strlen(" [email protected] ");
  1752. assert(ATTR_CNT == 3+1);
  1753. }
  1754. static BOOL CreateAuthorityKeyId(
  1755. DWORD dwIssuer,
  1756. OUT BYTE **ppbEncoded,
  1757. IN OUT DWORD *pcbEncoded
  1758. )
  1759. {
  1760. BOOL fResult;
  1761. BYTE *pbEncoded = NULL;
  1762. DWORD cbEncoded;
  1763. BYTE *pbNameEncoded = NULL;
  1764. DWORD cbNameEncoded;
  1765. CERT_AUTHORITY_KEY_ID_INFO KeyIdInfo;
  1766. CERT_RDN rgRDN[RDN_CNT];
  1767. CERT_RDN_ATTR rgAttr[ATTR_CNT];
  1768. CERT_NAME_INFO Name;
  1769. FILETIME SerialNumber;
  1770. memset(&KeyIdInfo, 0, sizeof(KeyIdInfo));
  1771. // Issuer's KeyId
  1772. KeyIdInfo.KeyId.pbData = (BYTE *) &dwIssuer;
  1773. KeyIdInfo.KeyId.cbData = sizeof(dwIssuer);
  1774. // Issuer's Issuer
  1775. CreateNameInfo(CertPara[dwIssuer].dwIssuer,
  1776. &Name, rgRDN, rgAttr);
  1777. if (!AllocAndEncodeObject(
  1778. X509_NAME,
  1779. &Name,
  1780. &pbNameEncoded,
  1781. &cbNameEncoded))
  1782. goto ErrorReturn;
  1783. KeyIdInfo.CertIssuer.pbData = pbNameEncoded;
  1784. KeyIdInfo.CertIssuer.cbData = cbNameEncoded;
  1785. // Issuer's SerialNumber
  1786. {
  1787. SYSTEMTIME SystemTime = TestTime;
  1788. SystemTime.wMilliseconds += (WORD) dwIssuer;
  1789. MySystemTimeToFileTime(&SystemTime, &SerialNumber);
  1790. }
  1791. KeyIdInfo.CertSerialNumber.pbData = (BYTE *) &SerialNumber;
  1792. KeyIdInfo.CertSerialNumber.cbData = sizeof(SerialNumber);
  1793. if (!AllocAndEncodeObject(
  1794. X509_AUTHORITY_KEY_ID,
  1795. &KeyIdInfo,
  1796. &pbEncoded,
  1797. &cbEncoded))
  1798. goto ErrorReturn;
  1799. fResult = TRUE;
  1800. goto CommonReturn;
  1801. ErrorReturn:
  1802. if (pbEncoded) {
  1803. TestFree(pbEncoded);
  1804. pbEncoded = NULL;
  1805. }
  1806. cbEncoded = 0;
  1807. fResult = FALSE;
  1808. CommonReturn:
  1809. if (pbNameEncoded)
  1810. TestFree(pbNameEncoded);
  1811. *ppbEncoded = pbEncoded;
  1812. *pcbEncoded = cbEncoded;
  1813. return fResult;
  1814. }
  1815. static BOOL CreateAuthorityKeyId2(
  1816. DWORD dwCert,
  1817. DWORD dwIssuer,
  1818. OUT BYTE **ppbEncoded,
  1819. IN OUT DWORD *pcbEncoded,
  1820. IN DWORD dwAki = AKI2_KEYID
  1821. )
  1822. {
  1823. BOOL fResult;
  1824. BYTE *pbEncoded = NULL;
  1825. DWORD cbEncoded;
  1826. BYTE *pbNameEncoded = NULL;
  1827. DWORD cbNameEncoded;
  1828. CERT_AUTHORITY_KEY_ID2_INFO KeyId2Info;
  1829. CERT_ALT_NAME_ENTRY AltNameEntry;
  1830. BYTE rgbPubKeyHash[SHA1_HASH_LEN];
  1831. CERT_RDN rgRDN[RDN_CNT];
  1832. CERT_RDN_ATTR rgAttr[ATTR_CNT];
  1833. CERT_NAME_INFO Name;
  1834. FILETIME SerialNumber;
  1835. memset(&KeyId2Info, 0, sizeof(KeyId2Info));
  1836. // Issuer's KeyId
  1837. if (AKI2_BAD_KEYID == dwAki)
  1838. memset(rgbPubKeyHash, 0xba, sizeof(rgbPubKeyHash));
  1839. else
  1840. Sha1HashPublicKey(dwIssuer, rgbPubKeyHash);
  1841. KeyId2Info.KeyId.pbData = rgbPubKeyHash;
  1842. KeyId2Info.KeyId.cbData = sizeof(rgbPubKeyHash);
  1843. if (AKI2_FULL == dwAki ||
  1844. AKI2_BAD_ISSUER == dwAki ||
  1845. AKI2_BAD_SERIAL_NUMBER == dwAki ||
  1846. (CertPara[dwCert].dwFlags & ALL_EXT_PARA_FLAG)) {
  1847. if (AKI2_BAD_ISSUER == dwAki) {
  1848. Name.cRDN = 1;
  1849. Name.rgRDN = rgRDN;
  1850. rgRDN[0].cRDNAttr = 1;
  1851. rgRDN[0].rgRDNAttr = rgAttr;
  1852. rgAttr[0].pszObjId = szOID_COMMON_NAME;
  1853. rgAttr[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
  1854. rgAttr[0].Value.pbData = (BYTE *) "AKI2BadIssuer";
  1855. rgAttr[0].Value.cbData = strlen("AKI2BadIssuer");
  1856. } else
  1857. // Issuer's Issuer
  1858. CreateNameInfo(CertPara[dwIssuer].dwIssuer,
  1859. &Name, rgRDN, rgAttr);
  1860. if (!AllocAndEncodeObject(
  1861. X509_NAME,
  1862. &Name,
  1863. &pbNameEncoded,
  1864. &cbNameEncoded))
  1865. goto ErrorReturn;
  1866. AltNameEntry.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
  1867. AltNameEntry.DirectoryName.pbData = pbNameEncoded;
  1868. AltNameEntry.DirectoryName.cbData = cbNameEncoded;
  1869. KeyId2Info.AuthorityCertIssuer.cAltEntry = 1;
  1870. KeyId2Info.AuthorityCertIssuer.rgAltEntry = &AltNameEntry;
  1871. // Issuer's SerialNumber
  1872. {
  1873. SYSTEMTIME SystemTime = TestTime;
  1874. if (AKI2_BAD_SERIAL_NUMBER == dwAki)
  1875. SystemTime.wMilliseconds += CERT_CNT;
  1876. else
  1877. SystemTime.wMilliseconds += (WORD) dwIssuer;
  1878. MySystemTimeToFileTime(&SystemTime, &SerialNumber);
  1879. }
  1880. KeyId2Info.AuthorityCertSerialNumber.pbData = (BYTE *) &SerialNumber;
  1881. KeyId2Info.AuthorityCertSerialNumber.cbData = sizeof(SerialNumber);
  1882. }
  1883. if (!AllocAndEncodeObject(
  1884. X509_AUTHORITY_KEY_ID2,
  1885. &KeyId2Info,
  1886. &pbEncoded,
  1887. &cbEncoded))
  1888. goto ErrorReturn;
  1889. fResult = TRUE;
  1890. goto CommonReturn;
  1891. ErrorReturn:
  1892. if (pbEncoded) {
  1893. TestFree(pbEncoded);
  1894. pbEncoded = NULL;
  1895. }
  1896. cbEncoded = 0;
  1897. fResult = FALSE;
  1898. CommonReturn:
  1899. if (pbNameEncoded)
  1900. TestFree(pbNameEncoded);
  1901. *ppbEncoded = pbEncoded;
  1902. *pcbEncoded = cbEncoded;
  1903. return fResult;
  1904. }
  1905. static BOOL CreateAuthorityInfoAccess(
  1906. DWORD dwCert,
  1907. OUT BYTE **ppbEncoded,
  1908. IN OUT DWORD *pcbEncoded
  1909. )
  1910. {
  1911. BOOL fResult;
  1912. DWORD dwIssuer = CertPara[dwCert].dwIssuer;
  1913. BYTE *pbEncoded = NULL;
  1914. DWORD cbEncoded;
  1915. BYTE *pbNameEncoded = NULL;
  1916. DWORD cbNameEncoded;
  1917. CERT_AUTHORITY_INFO_ACCESS AuthorityInfoAccess;
  1918. #define ACCESS_DESCR_COUNT 12
  1919. CERT_ACCESS_DESCRIPTION rgAccess[ACCESS_DESCR_COUNT];
  1920. CERT_RDN rgRDN[RDN_CNT];
  1921. CERT_RDN_ATTR rgAttr[ATTR_CNT];
  1922. CERT_NAME_INFO Name;
  1923. // Issuer's Issuer
  1924. CreateNameInfo(CertPara[dwIssuer].dwIssuer, &Name, rgRDN, rgAttr);
  1925. if (!AllocAndEncodeObject(
  1926. X509_NAME,
  1927. &Name,
  1928. &pbNameEncoded,
  1929. &cbNameEncoded))
  1930. goto ErrorReturn;
  1931. rgAccess[0].pszAccessMethod = szOID_PKIX_OCSP;
  1932. rgAccess[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
  1933. rgAccess[0].AccessLocation.pwszURL = L"URL to the stars";
  1934. rgAccess[1].pszAccessMethod = szOID_PKIX_CA_ISSUERS;
  1935. rgAccess[1].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
  1936. rgAccess[1].AccessLocation.DirectoryName.pbData = pbNameEncoded;
  1937. rgAccess[1].AccessLocation.DirectoryName.cbData = cbNameEncoded;
  1938. rgAccess[2].pszAccessMethod = szOID_PKIX_CA_ISSUERS;
  1939. rgAccess[2].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_RFC822_NAME;
  1940. rgAccess[2].AccessLocation.pwszRfc822Name = L"[email protected]";
  1941. rgAccess[3].pszAccessMethod = szOID_PKIX_OCSP;
  1942. rgAccess[3].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
  1943. rgAccess[3].AccessLocation.pwszURL = L"URL to the POLICY";
  1944. rgAccess[4].pszAccessMethod = szOID_PKIX_CA_ISSUERS;
  1945. rgAccess[4].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
  1946. rgAccess[4].AccessLocation.pwszURL = L"http://URLToTheIssuerCertificate";
  1947. rgAccess[5].pszAccessMethod = szOID_PKIX_CA_ISSUERS;
  1948. rgAccess[5].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
  1949. rgAccess[5].AccessLocation.pwszURL = L"ldap://ntdev.microsoft.com/c=us??sub";
  1950. rgAccess[6].pszAccessMethod = szOID_PKIX_CA_ISSUERS;
  1951. rgAccess[6].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
  1952. rgAccess[6].AccessLocation.pwszURL = L"file://FileToTheIssuerCertificate";
  1953. rgAccess[7].pszAccessMethod = szOID_PKIX_CA_ISSUERS;
  1954. rgAccess[7].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
  1955. rgAccess[7].AccessLocation.pwszURL = L"file://FileToTheIssuerCertificate";
  1956. rgAccess[8].pszAccessMethod = szOID_PKIX_CA_ISSUERS;
  1957. rgAccess[8].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
  1958. rgAccess[8].AccessLocation.pwszURL = L"file://FileToTheIssuerCertificate";
  1959. rgAccess[9].pszAccessMethod = szOID_PKIX_CA_ISSUERS;
  1960. rgAccess[9].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
  1961. rgAccess[9].AccessLocation.pwszURL = L"file://FileToTheIssuerCertificate";
  1962. rgAccess[10].pszAccessMethod = szOID_PKIX_CA_ISSUERS;
  1963. rgAccess[10].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
  1964. rgAccess[10].AccessLocation.pwszURL = L"http://crl.verisign.com/class1.crl";
  1965. rgAccess[11].pszAccessMethod = szOID_PKIX_CA_ISSUERS;
  1966. rgAccess[11].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
  1967. rgAccess[11].AccessLocation.pwszURL = L"http://crl.microsoft.com/pki/crl/products/CodeSignPCA.crl";
  1968. memset(&AuthorityInfoAccess, 0, sizeof(AuthorityInfoAccess));
  1969. if (0 == strcmp("TestAIAEnd", CertPara[dwCert].pszName)) {
  1970. rgAccess[0].pszAccessMethod = szOID_PKIX_CA_ISSUERS;
  1971. rgAccess[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
  1972. rgAccess[0].AccessLocation.pwszURL = L"file://TestAIACA.p7b";
  1973. AuthorityInfoAccess.cAccDescr = 1;
  1974. AuthorityInfoAccess.rgAccDescr = rgAccess;
  1975. } else if (0 == strcmp("RolloverCA", CertPara[dwCert].pszName)) {
  1976. rgAccess[0].pszAccessMethod = szOID_PKIX_CA_ISSUERS;
  1977. rgAccess[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
  1978. rgAccess[0].AccessLocation.pwszURL = L"file://RolloverAIARoot.p7b";
  1979. AuthorityInfoAccess.cAccDescr = 1;
  1980. AuthorityInfoAccess.rgAccDescr = rgAccess;
  1981. } else if (0 == strcmp("kevin", CertPara[dwCert].pszName)) {
  1982. rgAccess[0].pszAccessMethod = szOID_PKIX_CA_ISSUERS;
  1983. rgAccess[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
  1984. rgAccess[0].AccessLocation.pwszURL = L"http://vbl03ca.ntdev.microsoft.com/CertEnroll/vbl03ca.ntdev.microsoft.com_Microsoft%20Windows%20VBL03CA.crt";
  1985. AuthorityInfoAccess.cAccDescr = 1;
  1986. AuthorityInfoAccess.rgAccDescr = rgAccess;
  1987. } else if (CertPara[dwCert].dwFlags & ALL_EXT_PARA_FLAG) {
  1988. AuthorityInfoAccess.cAccDescr = 11;
  1989. AuthorityInfoAccess.rgAccDescr = &rgAccess[1];
  1990. } else {
  1991. AuthorityInfoAccess.cAccDescr = 1;
  1992. AuthorityInfoAccess.rgAccDescr = rgAccess;
  1993. }
  1994. if (!AllocAndEncodeObject(
  1995. X509_AUTHORITY_INFO_ACCESS,
  1996. &AuthorityInfoAccess,
  1997. &pbEncoded,
  1998. &cbEncoded))
  1999. goto ErrorReturn;
  2000. fResult = TRUE;
  2001. goto CommonReturn;
  2002. ErrorReturn:
  2003. if (pbEncoded) {
  2004. TestFree(pbEncoded);
  2005. pbEncoded = NULL;
  2006. }
  2007. cbEncoded = 0;
  2008. fResult = FALSE;
  2009. CommonReturn:
  2010. if (pbNameEncoded)
  2011. TestFree(pbNameEncoded);
  2012. *ppbEncoded = pbEncoded;
  2013. *pcbEncoded = cbEncoded;
  2014. return fResult;
  2015. }
  2016. static BYTE CrlIPAddress[] = {1,2,3,4};
  2017. #define CRL_DNS_NAME L"CRL.DNS.NAME.COM"
  2018. #define CRL_EMAIL_NAME L"[email protected]"
  2019. #define CRL_URL_NAME1 L"file://crltest1.p7b"
  2020. #define CRL_URL_NAME2 L"file://crltest2.p7b"
  2021. #define CRL_REGISTERED_ID "1.2.3.4.5.6"
  2022. static BYTE rgbCrlOtherName[] = {0x02, 0x02, 0x11, 0x22};
  2023. static CERT_OTHER_NAME CrlOtherName = {
  2024. "1.2.33.44.55.66", sizeof(rgbCrlOtherName), rgbCrlOtherName };
  2025. #define CRL_DIST_POINTS_DELTA_FLAG 0x1
  2026. #define CRL_DIST_POINTS_UNSUPPORTED_FLAG 0x2
  2027. static BOOL CreateCrlDistPoints(
  2028. DWORD dwIssuer,
  2029. BOOL dwFlags,
  2030. OUT BYTE **ppbEncoded,
  2031. IN OUT DWORD *pcbEncoded
  2032. )
  2033. {
  2034. BOOL fResult;
  2035. BYTE *pbEncoded = NULL;
  2036. DWORD cbEncoded;
  2037. CRL_DIST_POINTS_INFO CrlDistPointsInfo;
  2038. BYTE bReasonFlags;
  2039. CERT_ALT_NAME_ENTRY rgAltNameEntry[9];
  2040. CERT_ALT_NAME_ENTRY rgIssuerAltNameEntry[1];
  2041. CRL_DIST_POINT rgDistPoint[5];
  2042. CERT_RDN rgRDN[RDN_CNT];
  2043. CERT_RDN_ATTR rgAttr[ATTR_CNT];
  2044. CERT_NAME_INFO Name;
  2045. BYTE *pbIssuerNameEncoded = NULL;
  2046. DWORD cbIssuerNameEncoded;
  2047. if (dwFlags & CRL_DIST_POINTS_DELTA_FLAG) {
  2048. // ISSUER
  2049. CreateNameInfo(dwIssuer, &Name, rgRDN, rgAttr);
  2050. if (!AllocAndEncodeObject(
  2051. X509_NAME,
  2052. &Name,
  2053. &pbIssuerNameEncoded,
  2054. &cbIssuerNameEncoded
  2055. ))
  2056. goto ErrorReturn;
  2057. rgAltNameEntry[0].dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
  2058. rgAltNameEntry[0].pwszDNSName = CRL_DNS_NAME;
  2059. rgAltNameEntry[1].dwAltNameChoice = CERT_ALT_NAME_RFC822_NAME;
  2060. rgAltNameEntry[1].pwszRfc822Name = CRL_EMAIL_NAME;
  2061. rgAltNameEntry[2].dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
  2062. rgAltNameEntry[2].IPAddress.pbData = CrlIPAddress;
  2063. rgAltNameEntry[2].IPAddress.cbData = sizeof(CrlIPAddress);
  2064. rgAltNameEntry[3].dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID;
  2065. rgAltNameEntry[3].pszRegisteredID = CRL_REGISTERED_ID;
  2066. rgAltNameEntry[4].dwAltNameChoice = CERT_ALT_NAME_URL;
  2067. rgAltNameEntry[4].pwszURL = CRL_URL_NAME2;
  2068. rgAltNameEntry[5].dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME;
  2069. rgAltNameEntry[5].pOtherName = &CrlOtherName;
  2070. rgAltNameEntry[6].dwAltNameChoice = CERT_ALT_NAME_URL;
  2071. rgAltNameEntry[6].pwszURL = CRL_URL_NAME1;
  2072. rgAltNameEntry[7].dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
  2073. rgAltNameEntry[7].DirectoryName.pbData = pbIssuerNameEncoded;
  2074. rgAltNameEntry[7].DirectoryName.cbData = cbIssuerNameEncoded;
  2075. rgAltNameEntry[8].dwAltNameChoice = CERT_ALT_NAME_URL;
  2076. rgAltNameEntry[8].pwszURL = L"file://BadUnsupportedChoice.crl";
  2077. rgIssuerAltNameEntry[0].dwAltNameChoice = CERT_ALT_NAME_URL;
  2078. rgIssuerAltNameEntry[0].pwszURL = L"CRL Issuer URL";
  2079. memset(rgDistPoint, 0, sizeof(rgDistPoint));
  2080. // [0] has unsupported ReasonFlags
  2081. rgDistPoint[0].DistPointName.dwDistPointNameChoice =
  2082. CRL_DIST_POINT_FULL_NAME;
  2083. rgDistPoint[0].DistPointName.FullName.cAltEntry = 1;
  2084. rgDistPoint[0].DistPointName.FullName.rgAltEntry = &rgAltNameEntry[8];
  2085. rgDistPoint[0].ReasonFlags.cbData = 1;
  2086. rgDistPoint[0].ReasonFlags.pbData = &bReasonFlags;
  2087. rgDistPoint[0].ReasonFlags.cUnusedBits = 1;
  2088. bReasonFlags = CRL_REASON_KEY_COMPROMISE_FLAG |
  2089. CRL_REASON_CA_COMPROMISE_FLAG;
  2090. // [1] has unsupported CRLIssuer
  2091. rgDistPoint[1].DistPointName.dwDistPointNameChoice =
  2092. CRL_DIST_POINT_FULL_NAME;
  2093. rgDistPoint[1].DistPointName.FullName.cAltEntry = 1;
  2094. rgDistPoint[1].DistPointName.FullName.rgAltEntry = &rgAltNameEntry[8];
  2095. rgDistPoint[1].CRLIssuer.cAltEntry = 1;
  2096. rgDistPoint[1].CRLIssuer.rgAltEntry = rgIssuerAltNameEntry;
  2097. // [2] is empty
  2098. rgDistPoint[3].DistPointName.dwDistPointNameChoice =
  2099. CRL_DIST_POINT_FULL_NAME;
  2100. rgDistPoint[3].DistPointName.FullName.cAltEntry = 5;
  2101. rgDistPoint[3].DistPointName.FullName.rgAltEntry = &rgAltNameEntry[0];
  2102. rgDistPoint[4].DistPointName.dwDistPointNameChoice =
  2103. CRL_DIST_POINT_FULL_NAME;
  2104. rgDistPoint[4].DistPointName.FullName.cAltEntry = 3;
  2105. rgDistPoint[4].DistPointName.FullName.rgAltEntry = &rgAltNameEntry[5];
  2106. memset(&CrlDistPointsInfo, 0, sizeof(CrlDistPointsInfo));
  2107. CrlDistPointsInfo.rgDistPoint = &rgDistPoint[0];
  2108. if (dwFlags & CRL_DIST_POINTS_UNSUPPORTED_FLAG)
  2109. CrlDistPointsInfo.cDistPoint = 1;
  2110. else
  2111. CrlDistPointsInfo.cDistPoint = 5;
  2112. } else {
  2113. rgAltNameEntry[0].dwAltNameChoice = CERT_ALT_NAME_URL;
  2114. rgAltNameEntry[0].pwszURL = L"file://test1.crl";
  2115. memset(rgDistPoint, 0, sizeof(rgDistPoint));
  2116. rgDistPoint[0].DistPointName.dwDistPointNameChoice =
  2117. CRL_DIST_POINT_FULL_NAME;
  2118. rgDistPoint[0].DistPointName.FullName.cAltEntry = 1;
  2119. rgDistPoint[0].DistPointName.FullName.rgAltEntry = &rgAltNameEntry[0];
  2120. memset(&CrlDistPointsInfo, 0, sizeof(CrlDistPointsInfo));
  2121. CrlDistPointsInfo.rgDistPoint = &rgDistPoint[0];
  2122. CrlDistPointsInfo.cDistPoint = 1;
  2123. }
  2124. if (!AllocAndEncodeObject(
  2125. X509_CRL_DIST_POINTS,
  2126. &CrlDistPointsInfo,
  2127. &pbEncoded,
  2128. &cbEncoded))
  2129. goto ErrorReturn;
  2130. fResult = TRUE;
  2131. goto CommonReturn;
  2132. ErrorReturn:
  2133. if (pbEncoded) {
  2134. TestFree(pbEncoded);
  2135. pbEncoded = NULL;
  2136. }
  2137. cbEncoded = 0;
  2138. fResult = FALSE;
  2139. CommonReturn:
  2140. if(pbIssuerNameEncoded)
  2141. TestFree(pbIssuerNameEncoded);
  2142. *ppbEncoded = pbEncoded;
  2143. *pcbEncoded = cbEncoded;
  2144. return fResult;
  2145. }
  2146. static BOOL CreateCertIssuingDistPoint(
  2147. DWORD dwCert,
  2148. OUT BYTE **ppbEncoded,
  2149. IN OUT DWORD *pcbEncoded
  2150. )
  2151. {
  2152. BOOL fResult;
  2153. BYTE *pbEncoded = NULL;
  2154. DWORD cbEncoded;
  2155. CRL_ISSUING_DIST_POINT Info;
  2156. BYTE bOnlySomeReasonFlags;
  2157. CERT_ALT_NAME_ENTRY rgAltNameEntry[2];
  2158. rgAltNameEntry[0].dwAltNameChoice = CERT_ALT_NAME_URL;
  2159. rgAltNameEntry[0].pwszURL = L"file://test1.crl";
  2160. rgAltNameEntry[1].dwAltNameChoice = CERT_ALT_NAME_URL;
  2161. rgAltNameEntry[1].pwszURL = L"file://test1.crl";
  2162. memset(&Info, 0, sizeof(Info));
  2163. Info.DistPointName.dwDistPointNameChoice =
  2164. CRL_DIST_POINT_FULL_NAME;
  2165. Info.DistPointName.FullName.cAltEntry = 2;
  2166. Info.DistPointName.FullName.rgAltEntry = &rgAltNameEntry[0];
  2167. Info.OnlySomeReasonFlags.cbData = 1;
  2168. Info.OnlySomeReasonFlags.pbData = &bOnlySomeReasonFlags;
  2169. Info.OnlySomeReasonFlags.cUnusedBits = 1;
  2170. bOnlySomeReasonFlags = CRL_REASON_KEY_COMPROMISE_FLAG |
  2171. CRL_REASON_CA_COMPROMISE_FLAG;
  2172. Info.fIndirectCRL = TRUE;
  2173. Info.fOnlyContainsUserCerts = TRUE;
  2174. Info.fOnlyContainsCACerts = TRUE;
  2175. if (!AllocAndEncodeObject(
  2176. X509_ISSUING_DIST_POINT,
  2177. &Info,
  2178. &pbEncoded,
  2179. &cbEncoded))
  2180. goto ErrorReturn;
  2181. fResult = TRUE;
  2182. goto CommonReturn;
  2183. ErrorReturn:
  2184. if (pbEncoded) {
  2185. TestFree(pbEncoded);
  2186. pbEncoded = NULL;
  2187. }
  2188. cbEncoded = 0;
  2189. fResult = FALSE;
  2190. CommonReturn:
  2191. *ppbEncoded = pbEncoded;
  2192. *pcbEncoded = cbEncoded;
  2193. return fResult;
  2194. }
  2195. static BOOL CreateCrlIssuingDistPoint(
  2196. OUT BYTE **ppbEncoded,
  2197. IN OUT DWORD *pcbEncoded
  2198. )
  2199. {
  2200. BOOL fResult;
  2201. BYTE *pbEncoded = NULL;
  2202. DWORD cbEncoded;
  2203. CRL_ISSUING_DIST_POINT Info;
  2204. CERT_ALT_NAME_ENTRY rgAltNameEntry[1];
  2205. rgAltNameEntry[0].dwAltNameChoice = CERT_ALT_NAME_URL;
  2206. rgAltNameEntry[0].pwszURL = L"file://test1.crl";
  2207. memset(&Info, 0, sizeof(Info));
  2208. Info.DistPointName.dwDistPointNameChoice =
  2209. CRL_DIST_POINT_FULL_NAME;
  2210. Info.DistPointName.FullName.cAltEntry = 1;
  2211. Info.DistPointName.FullName.rgAltEntry = &rgAltNameEntry[0];
  2212. if (!AllocAndEncodeObject(
  2213. szOID_ISSUING_DIST_POINT,
  2214. &Info,
  2215. &pbEncoded,
  2216. &cbEncoded))
  2217. goto ErrorReturn;
  2218. fResult = TRUE;
  2219. goto CommonReturn;
  2220. ErrorReturn:
  2221. if (pbEncoded) {
  2222. TestFree(pbEncoded);
  2223. pbEncoded = NULL;
  2224. }
  2225. cbEncoded = 0;
  2226. fResult = FALSE;
  2227. CommonReturn:
  2228. *ppbEncoded = pbEncoded;
  2229. *pcbEncoded = cbEncoded;
  2230. return fResult;
  2231. }
  2232. static BOOL CreateNameConstraints(
  2233. DWORD dwCert,
  2234. OUT BYTE **ppbEncoded,
  2235. IN OUT DWORD *pcbEncoded
  2236. )
  2237. {
  2238. BOOL fResult;
  2239. BYTE *pbEncoded = NULL;
  2240. DWORD cbEncoded;
  2241. PCERT_NAME_CONSTRAINTS_INFO pInfo;
  2242. CERT_NAME_CONSTRAINTS_INFO RootInfo;
  2243. CERT_GENERAL_SUBTREE rgRootPermitted[15];
  2244. CERT_GENERAL_SUBTREE rgRootExcluded[15];
  2245. CERT_NAME_CONSTRAINTS_INFO CaInfo;
  2246. CERT_GENERAL_SUBTREE rgCaPermitted[15];
  2247. CERT_NAME_CONSTRAINTS_INFO MissingInfo;
  2248. CERT_GENERAL_SUBTREE rgMissingPermitted[15];
  2249. CERT_GENERAL_SUBTREE rgMissingExcluded[15];
  2250. BYTE rgbMissing[3] = {2, 1, 1}; // INTEGER
  2251. CERT_OTHER_NAME MissingOtherName =
  2252. {"1.2.3.4.5.6", sizeof(rgbMissing), rgbMissing};
  2253. BYTE rgbEmpty[2] = {5, 0}; // NULL
  2254. CERT_OTHER_NAME AnyOctetOtherName =
  2255. {OCTET_OTHER_NAME_OID, sizeof(rgbEmpty), rgbEmpty};
  2256. CERT_OTHER_NAME AnyStringOtherName =
  2257. {STRING_OTHER_NAME_OID, sizeof(rgbEmpty), rgbEmpty};
  2258. CERT_NAME_VALUE NameValue;
  2259. CERT_OTHER_NAME PermittedUPNOtherName;
  2260. BYTE *pbPermittedUPNNameEncoded = NULL;
  2261. DWORD cbPermittedUPNNameEncoded;
  2262. CERT_OTHER_NAME ExcludedUPNOtherName;
  2263. BYTE *pbExcludedUPNNameEncoded = NULL;
  2264. DWORD cbExcludedUPNNameEncoded;
  2265. CERT_OTHER_NAME AnyUPNOtherName;
  2266. BYTE *pbAnyUPNNameEncoded = NULL;
  2267. DWORD cbAnyUPNNameEncoded;
  2268. CERT_OTHER_NAME PermittedStringOtherName;
  2269. BYTE *pbPermittedStringOtherNameEncoded = NULL;
  2270. DWORD cbPermittedStringOtherNameEncoded;
  2271. CERT_OTHER_NAME ExcludedStringOtherName;
  2272. BYTE *pbExcludedStringOtherNameEncoded = NULL;
  2273. DWORD cbExcludedStringOtherNameEncoded;
  2274. BYTE rgbDefaultIPAddress[] = {1,1,0,0, 255,255,0,0};
  2275. BYTE rgbAllExtIPAddress[] = {
  2276. 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
  2277. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0xF0};
  2278. BYTE rgbExcludedIPAddress[] = {2,2,2,2, 255,254,254,254};
  2279. CERT_RDN rgRDN[3];
  2280. CERT_RDN_ATTR rgAttr[3];
  2281. CERT_NAME_INFO NameInfo;
  2282. BYTE *pbPermittedNameEncoded = NULL;
  2283. DWORD cbPermittedNameEncoded;
  2284. BYTE *pbExcludedNameEncoded = NULL;
  2285. DWORD cbExcludedNameEncoded;
  2286. BYTE *pbAnyOUNameEncoded = NULL;
  2287. DWORD cbAnyOUNameEncoded;
  2288. BYTE *pbAnyNameEncoded = NULL;
  2289. DWORD cbAnyNameEncoded;
  2290. LPSTR pszSign = "\n sign \r";
  2291. DWORD i;
  2292. NameValue.dwValueType = CERT_RDN_BMP_STRING;
  2293. NameValue.Value.pbData = (BYTE *) L" @UPN.COM ";
  2294. NameValue.Value.cbData = 0;
  2295. if (!AllocAndEncodeObject(
  2296. X509_UNICODE_ANY_STRING,
  2297. &NameValue,
  2298. &pbPermittedUPNNameEncoded,
  2299. &cbPermittedUPNNameEncoded))
  2300. goto ErrorReturn;
  2301. PermittedUPNOtherName.pszObjId = szOID_NT_PRINCIPAL_NAME;
  2302. PermittedUPNOtherName.Value.pbData = pbPermittedUPNNameEncoded;
  2303. PermittedUPNOtherName.Value.cbData = cbPermittedUPNNameEncoded;
  2304. NameValue.dwValueType = CERT_RDN_UNIVERSAL_STRING;
  2305. NameValue.Value.pbData = (BYTE *) L" [email protected] ";
  2306. NameValue.Value.cbData = 0;
  2307. if (!AllocAndEncodeObject(
  2308. X509_UNICODE_ANY_STRING,
  2309. &NameValue,
  2310. &pbExcludedUPNNameEncoded,
  2311. &cbExcludedUPNNameEncoded))
  2312. goto ErrorReturn;
  2313. ExcludedUPNOtherName.pszObjId = szOID_NT_PRINCIPAL_NAME;
  2314. ExcludedUPNOtherName.Value.pbData = pbExcludedUPNNameEncoded;
  2315. ExcludedUPNOtherName.Value.cbData = cbExcludedUPNNameEncoded;
  2316. NameValue.dwValueType = CERT_RDN_PRINTABLE_STRING;
  2317. NameValue.Value.pbData = (BYTE *) L"";
  2318. NameValue.Value.cbData = 0;
  2319. if (!AllocAndEncodeObject(
  2320. X509_UNICODE_ANY_STRING,
  2321. &NameValue,
  2322. &pbAnyUPNNameEncoded,
  2323. &cbAnyUPNNameEncoded))
  2324. goto ErrorReturn;
  2325. AnyUPNOtherName.pszObjId = szOID_NT_PRINCIPAL_NAME;
  2326. AnyUPNOtherName.Value.pbData = pbAnyUPNNameEncoded;
  2327. AnyUPNOtherName.Value.cbData = cbAnyUPNNameEncoded;
  2328. NameValue.dwValueType = CERT_RDN_VISIBLE_STRING;
  2329. NameValue.Value.pbData = (BYTE *) L" String@OtherName ";
  2330. NameValue.Value.cbData = 0;
  2331. if (!AllocAndEncodeObject(
  2332. X509_UNICODE_ANY_STRING,
  2333. &NameValue,
  2334. &pbPermittedStringOtherNameEncoded,
  2335. &cbPermittedStringOtherNameEncoded))
  2336. goto ErrorReturn;
  2337. PermittedStringOtherName.pszObjId = STRING_OTHER_NAME_OID;
  2338. PermittedStringOtherName.Value.pbData = pbPermittedStringOtherNameEncoded;
  2339. PermittedStringOtherName.Value.cbData = cbPermittedStringOtherNameEncoded;
  2340. NameValue.dwValueType = CERT_RDN_GRAPHIC_STRING;
  2341. NameValue.Value.pbData = (BYTE *) L" excludedString@OtherName ";
  2342. NameValue.Value.cbData = 0;
  2343. if (!AllocAndEncodeObject(
  2344. X509_UNICODE_ANY_STRING,
  2345. &NameValue,
  2346. &pbExcludedStringOtherNameEncoded,
  2347. &cbExcludedStringOtherNameEncoded))
  2348. goto ErrorReturn;
  2349. ExcludedStringOtherName.pszObjId = STRING_OTHER_NAME_OID;
  2350. ExcludedStringOtherName.Value.pbData = pbExcludedStringOtherNameEncoded;
  2351. ExcludedStringOtherName.Value.cbData = cbExcludedStringOtherNameEncoded;
  2352. for (i = 0; i < 3; i++) {
  2353. rgRDN[i].cRDNAttr = 1;
  2354. rgRDN[i].rgRDNAttr = &rgAttr[i];
  2355. }
  2356. // Any
  2357. rgAttr[0].pszObjId = ATTR_0_OBJID;
  2358. rgAttr[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
  2359. rgAttr[0].Value.pbData = NULL;
  2360. rgAttr[0].Value.cbData = 0;
  2361. rgAttr[1].pszObjId = ATTR_1_OBJID;
  2362. rgAttr[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
  2363. rgAttr[1].Value.pbData = (BYTE *) pszSign;
  2364. rgAttr[1].Value.cbData = strlen(pszSign);
  2365. rgAttr[2].pszObjId = ATTR_2_OBJID;
  2366. rgAttr[2].dwValueType = CERT_RDN_PRINTABLE_STRING;
  2367. rgAttr[2].Value.pbData = (BYTE *) "default";
  2368. rgAttr[2].Value.cbData = strlen("default");
  2369. NameInfo.cRDN = 3;
  2370. NameInfo.rgRDN = rgRDN;
  2371. if (!AllocAndEncodeObject(
  2372. X509_NAME,
  2373. &NameInfo,
  2374. &pbPermittedNameEncoded,
  2375. &cbPermittedNameEncoded
  2376. ))
  2377. goto ErrorReturn;
  2378. rgAttr[0].pszObjId = ATTR_0_OBJID;
  2379. rgAttr[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
  2380. rgAttr[0].Value.pbData = (BYTE *) "excluded";
  2381. rgAttr[0].Value.cbData = strlen("excluded");
  2382. NameInfo.cRDN = 1;
  2383. NameInfo.rgRDN = rgRDN;
  2384. if (!AllocAndEncodeObject(
  2385. X509_NAME,
  2386. &NameInfo,
  2387. &pbExcludedNameEncoded,
  2388. &cbExcludedNameEncoded
  2389. ))
  2390. goto ErrorReturn;
  2391. rgAttr[0].pszObjId = szOID_ORGANIZATIONAL_UNIT_NAME;
  2392. rgAttr[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
  2393. rgAttr[0].Value.pbData = NULL;
  2394. rgAttr[0].Value.cbData = 0;
  2395. NameInfo.cRDN = 1;
  2396. NameInfo.rgRDN = rgRDN;
  2397. if (!AllocAndEncodeObject(
  2398. X509_NAME,
  2399. &NameInfo,
  2400. &pbAnyOUNameEncoded,
  2401. &cbAnyOUNameEncoded
  2402. ))
  2403. goto ErrorReturn;
  2404. NameInfo.cRDN = 0;
  2405. NameInfo.rgRDN = rgRDN;
  2406. if (!AllocAndEncodeObject(
  2407. X509_NAME,
  2408. &NameInfo,
  2409. &pbAnyNameEncoded,
  2410. &cbAnyNameEncoded
  2411. ))
  2412. goto ErrorReturn;
  2413. memset(&rgRootPermitted, 0, sizeof(rgRootPermitted));
  2414. rgRootPermitted[0].Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
  2415. rgRootPermitted[0].Base.pwszDNSName = L"dns Name ";
  2416. rgRootPermitted[1].Base.dwAltNameChoice = CERT_ALT_NAME_RFC822_NAME;
  2417. rgRootPermitted[1].Base.pwszRfc822Name = L" eMail.COM";
  2418. rgRootPermitted[2].Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
  2419. rgRootPermitted[2].Base.pwszDNSName = L" kevin ";
  2420. rgRootPermitted[3].Base.dwAltNameChoice = CERT_ALT_NAME_URL;
  2421. rgRootPermitted[3].Base.pwszURL = L".url.com";
  2422. rgRootPermitted[4].Base.dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME;
  2423. rgRootPermitted[4].Base.pOtherName = &PermittedUPNOtherName;
  2424. rgRootPermitted[5].Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
  2425. rgRootPermitted[5].Base.IPAddress.pbData = rgbDefaultIPAddress;
  2426. rgRootPermitted[5].Base.IPAddress.cbData = sizeof(rgbDefaultIPAddress);
  2427. rgRootPermitted[6].Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
  2428. rgRootPermitted[6].Base.IPAddress.pbData = rgbAllExtIPAddress;
  2429. rgRootPermitted[6].Base.IPAddress.cbData = sizeof(rgbAllExtIPAddress);
  2430. rgRootPermitted[7].Base.dwAltNameChoice = CERT_ALT_NAME_RFC822_NAME;
  2431. rgRootPermitted[7].Base.pwszRfc822Name = L" [email protected] ";
  2432. rgRootPermitted[8].Base.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
  2433. rgRootPermitted[8].Base.DirectoryName.pbData = pbPermittedNameEncoded;
  2434. rgRootPermitted[8].Base.DirectoryName.cbData = cbPermittedNameEncoded;
  2435. rgRootPermitted[9].Base.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
  2436. rgRootPermitted[9].Base.DirectoryName.pbData = pbAnyOUNameEncoded;
  2437. rgRootPermitted[9].Base.DirectoryName.cbData = cbAnyOUNameEncoded;
  2438. rgRootPermitted[10].Base.dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME;
  2439. rgRootPermitted[10].Base.pOtherName = &PermittedStringOtherName;
  2440. rgRootPermitted[11].Base.dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME;
  2441. rgRootPermitted[11].Base.pOtherName = &AnyOctetOtherName;
  2442. rgRootPermitted[12].Base.dwAltNameChoice = CERT_ALT_NAME_RFC822_NAME;
  2443. rgRootPermitted[12].Base.pwszRfc822Name = L"[email protected]";
  2444. memset(&rgRootExcluded, 0, sizeof(rgRootExcluded));
  2445. rgRootExcluded[0].Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
  2446. rgRootExcluded[0].Base.pwszDNSName = L"www.ExcLuDed.dns.com ";
  2447. rgRootExcluded[1].Base.dwAltNameChoice = CERT_ALT_NAME_RFC822_NAME;
  2448. rgRootExcluded[1].Base.pwszRfc822Name = L"[email protected]";
  2449. rgRootExcluded[2].Base.dwAltNameChoice = CERT_ALT_NAME_URL;
  2450. rgRootExcluded[2].Base.pwszURL = L"excluded.url.com";
  2451. rgRootExcluded[3].Base.dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME;
  2452. rgRootExcluded[3].Base.pOtherName = &ExcludedUPNOtherName;
  2453. rgRootExcluded[4].Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
  2454. rgRootExcluded[4].Base.IPAddress.pbData = rgbExcludedIPAddress;
  2455. rgRootExcluded[4].Base.IPAddress.cbData = sizeof(rgbExcludedIPAddress);
  2456. rgRootExcluded[5].Base.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
  2457. rgRootExcluded[5].Base.DirectoryName.pbData = pbExcludedNameEncoded;
  2458. rgRootExcluded[5].Base.DirectoryName.cbData = cbExcludedNameEncoded;
  2459. rgRootExcluded[6].Base.dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME;
  2460. rgRootExcluded[6].Base.pOtherName = &ExcludedStringOtherName;
  2461. memset(&RootInfo, 0, sizeof(RootInfo));
  2462. RootInfo.cPermittedSubtree = 13;
  2463. RootInfo.rgPermittedSubtree = rgRootPermitted;
  2464. RootInfo.cExcludedSubtree = 7;
  2465. RootInfo.rgExcludedSubtree = rgRootExcluded;
  2466. memset(&rgCaPermitted, 0, sizeof(rgCaPermitted));
  2467. rgCaPermitted[0].Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
  2468. rgCaPermitted[0].Base.pwszDNSName = L"";
  2469. rgCaPermitted[1].Base.dwAltNameChoice = CERT_ALT_NAME_RFC822_NAME;
  2470. rgCaPermitted[1].Base.pwszRfc822Name = L"";
  2471. rgCaPermitted[2].Base.dwAltNameChoice = CERT_ALT_NAME_URL;
  2472. rgCaPermitted[2].Base.pwszURL = L"";
  2473. rgCaPermitted[3].Base.dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME;
  2474. rgCaPermitted[3].Base.pOtherName = &AnyUPNOtherName;
  2475. rgCaPermitted[4].Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
  2476. rgCaPermitted[4].Base.IPAddress.pbData = NULL;
  2477. rgCaPermitted[4].Base.IPAddress.cbData = 0;
  2478. rgCaPermitted[5].Base.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
  2479. rgCaPermitted[5].Base.DirectoryName.pbData = pbAnyNameEncoded;
  2480. rgCaPermitted[5].Base.DirectoryName.cbData = cbAnyNameEncoded;
  2481. rgCaPermitted[6].Base.dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME;
  2482. rgCaPermitted[6].Base.pOtherName = &AnyOctetOtherName;
  2483. rgCaPermitted[7].Base.dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME;
  2484. rgCaPermitted[7].Base.pOtherName = &AnyStringOtherName;
  2485. memset(&CaInfo, 0, sizeof(CaInfo));
  2486. CaInfo.cPermittedSubtree = 8;
  2487. CaInfo.rgPermittedSubtree = rgCaPermitted;
  2488. CaInfo.cExcludedSubtree = 0;
  2489. CaInfo.rgExcludedSubtree = NULL;
  2490. memset(&rgMissingPermitted, 0, sizeof(rgMissingPermitted));
  2491. rgMissingPermitted[0].Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
  2492. rgMissingPermitted[0].Base.pwszDNSName = L"a super dns Name ";
  2493. rgMissingPermitted[0].dwMinimum = 1;
  2494. rgMissingPermitted[1].Base.dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME;
  2495. rgMissingPermitted[1].Base.pOtherName = &MissingOtherName;
  2496. memset(&rgMissingExcluded, 0, sizeof(rgMissingExcluded));
  2497. rgMissingExcluded[0].Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
  2498. rgMissingExcluded[0].Base.pwszDNSName = L"www.ReallyExcLuDed.dns.com ";
  2499. rgMissingExcluded[1].Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
  2500. rgMissingExcluded[1].Base.pwszDNSName = L"www.ExcLuDed.dns.com ";
  2501. rgMissingExcluded[1].fMaximum = TRUE;
  2502. rgMissingExcluded[1].dwMaximum = 2;
  2503. rgMissingExcluded[2].Base.dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME;
  2504. rgMissingExcluded[2].Base.pOtherName = &MissingOtherName;
  2505. memset(&MissingInfo, 0, sizeof(MissingInfo));
  2506. MissingInfo.cPermittedSubtree = 2;
  2507. MissingInfo.rgPermittedSubtree = rgMissingPermitted;
  2508. MissingInfo.cExcludedSubtree = 3;
  2509. MissingInfo.rgExcludedSubtree = rgMissingExcluded;
  2510. if (dwCert == POLICY_ROOT)
  2511. pInfo = &RootInfo;
  2512. else if (dwCert == POLICY_CA)
  2513. pInfo = &CaInfo;
  2514. else if (0 == strcmp(CertPara[dwCert].pszName, "MissingNCCA"))
  2515. pInfo = &MissingInfo;
  2516. else
  2517. goto ErrorReturn;
  2518. if (!AllocAndEncodeObject(
  2519. X509_NAME_CONSTRAINTS,
  2520. pInfo,
  2521. &pbEncoded,
  2522. &cbEncoded))
  2523. goto ErrorReturn;
  2524. fResult = TRUE;
  2525. goto CommonReturn;
  2526. ErrorReturn:
  2527. if (pbEncoded) {
  2528. TestFree(pbEncoded);
  2529. pbEncoded = NULL;
  2530. }
  2531. cbEncoded = 0;
  2532. fResult = FALSE;
  2533. CommonReturn:
  2534. TestFree(pbPermittedUPNNameEncoded);
  2535. TestFree(pbExcludedUPNNameEncoded);
  2536. TestFree(pbAnyUPNNameEncoded);
  2537. TestFree(pbPermittedNameEncoded);
  2538. TestFree(pbExcludedNameEncoded);
  2539. TestFree(pbPermittedStringOtherNameEncoded);
  2540. TestFree(pbExcludedStringOtherNameEncoded);
  2541. TestFree(pbAnyOUNameEncoded);
  2542. TestFree(pbAnyNameEncoded);
  2543. *ppbEncoded = pbEncoded;
  2544. *pcbEncoded = cbEncoded;
  2545. return fResult;
  2546. }
  2547. static BOOL CreatePolicyMappings(
  2548. DWORD dwCert,
  2549. OUT BYTE **ppbEncoded,
  2550. IN OUT DWORD *pcbEncoded
  2551. )
  2552. {
  2553. BOOL fResult;
  2554. BYTE *pbEncoded = NULL;
  2555. DWORD cbEncoded;
  2556. PCERT_POLICY_MAPPINGS_INFO pInfo;
  2557. CERT_POLICY_MAPPING rgRootPolicyMapping[] = {
  2558. "1.1.22", "1.2.22.1",
  2559. "1.1.22", "1.2.22.2", // multiple subjects may map to same issuer
  2560. "1.1.4444", "1.2.4444",
  2561. "1.1.4444", "1.1.4444", // multiple subjects for same issuer
  2562. "1.1.22.333", "1.2.22.1", // duplicate subject
  2563. "1.1.22", "1.2.22.3",
  2564. "1.1.333", "1.2.333.1",
  2565. "1.1.333", "1.2.333.2",
  2566. "1.1.333", "1.2.333.3",
  2567. "1.1.22", "1.2.22.3", // multiple subjects for same issuer
  2568. "1.1.22", "1.2.22.3", // duplicate subject
  2569. "1.1.22", "1.2.22.4", // multiple subjects for same issuer
  2570. };
  2571. CERT_POLICY_MAPPINGS_INFO RootInfo = {
  2572. sizeof(rgRootPolicyMapping) / sizeof(rgRootPolicyMapping[0]),
  2573. rgRootPolicyMapping
  2574. };
  2575. CERT_POLICY_MAPPING rgCaPolicyMapping[] = {
  2576. "1.1.1", "1.3.1.1",
  2577. "1.1.1", "1.3.1.2",
  2578. "1.2.22.2", "1.3.22.2.1", // -> 1.1.22
  2579. "1.2.22.2", "1.3.22.2.2", // -> 1.1.22
  2580. };
  2581. CERT_POLICY_MAPPINGS_INFO CaInfo = {
  2582. sizeof(rgCaPolicyMapping) / sizeof(rgCaPolicyMapping[0]),
  2583. rgCaPolicyMapping
  2584. };
  2585. if (dwCert == POLICY_ROOT)
  2586. pInfo = &RootInfo;
  2587. else if (dwCert == POLICY_CA)
  2588. pInfo = &CaInfo;
  2589. else
  2590. goto ErrorReturn;
  2591. if (!AllocAndEncodeObject(
  2592. X509_POLICY_MAPPINGS,
  2593. pInfo,
  2594. &pbEncoded,
  2595. &cbEncoded))
  2596. goto ErrorReturn;
  2597. fResult = TRUE;
  2598. goto CommonReturn;
  2599. ErrorReturn:
  2600. if (pbEncoded) {
  2601. TestFree(pbEncoded);
  2602. pbEncoded = NULL;
  2603. }
  2604. cbEncoded = 0;
  2605. fResult = FALSE;
  2606. CommonReturn:
  2607. *ppbEncoded = pbEncoded;
  2608. *pcbEncoded = cbEncoded;
  2609. return fResult;
  2610. }
  2611. static BOOL CreatePolicyConstraints(
  2612. DWORD dwCert,
  2613. OUT BYTE **ppbEncoded,
  2614. IN OUT DWORD *pcbEncoded
  2615. )
  2616. {
  2617. BOOL fResult;
  2618. BYTE *pbEncoded = NULL;
  2619. DWORD cbEncoded;
  2620. PCERT_POLICY_CONSTRAINTS_INFO pInfo;
  2621. CERT_POLICY_CONSTRAINTS_INFO RootInfo = {
  2622. TRUE, // fRequireExplicitPolicy
  2623. 1, // dwRequireExplicitPolicySkipCerts
  2624. TRUE, // fInhibitPolicyMapping
  2625. 1 // dwInhibitPolicyMappingSkipCerts
  2626. };
  2627. CERT_POLICY_CONSTRAINTS_INFO CaInfo = {
  2628. TRUE, // fRequireExplicitPolicy
  2629. 0, // dwRequireExplicitPolicySkipCerts
  2630. TRUE, // fInhibitPolicyMapping
  2631. 0 // dwInhibitPolicyMappingSkipCerts
  2632. };
  2633. if (dwCert == POLICY_ROOT)
  2634. pInfo = &RootInfo;
  2635. else if (dwCert == POLICY_CA)
  2636. pInfo = &CaInfo;
  2637. else if (dwCert == ROLLOVER_CROSS_CERT) {
  2638. CaInfo.dwRequireExplicitPolicySkipCerts = 2;
  2639. pInfo = &CaInfo;
  2640. } else
  2641. goto ErrorReturn;
  2642. if (!AllocAndEncodeObject(
  2643. X509_POLICY_CONSTRAINTS,
  2644. pInfo,
  2645. &pbEncoded,
  2646. &cbEncoded))
  2647. goto ErrorReturn;
  2648. fResult = TRUE;
  2649. goto CommonReturn;
  2650. ErrorReturn:
  2651. if (pbEncoded) {
  2652. TestFree(pbEncoded);
  2653. pbEncoded = NULL;
  2654. }
  2655. cbEncoded = 0;
  2656. fResult = FALSE;
  2657. CommonReturn:
  2658. *ppbEncoded = pbEncoded;
  2659. *pcbEncoded = cbEncoded;
  2660. return fResult;
  2661. }
  2662. static BOOL CreateCrossCertDistPoints(
  2663. DWORD dwCert,
  2664. OUT BYTE **ppbEncoded,
  2665. IN OUT DWORD *pcbEncoded
  2666. )
  2667. {
  2668. BOOL fResult;
  2669. BYTE *pbEncoded = NULL;
  2670. DWORD cbEncoded;
  2671. CROSS_CERT_DIST_POINTS_INFO Info;
  2672. CERT_ALT_NAME_INFO rgDistPoint[2];
  2673. CERT_ALT_NAME_ENTRY rgAltNameEntry[3];
  2674. rgAltNameEntry[0].dwAltNameChoice = CERT_ALT_NAME_URL;
  2675. rgAltNameEntry[0].pwszURL = L"file://vsgood.cer";
  2676. rgAltNameEntry[1].dwAltNameChoice = CERT_ALT_NAME_URL;
  2677. rgAltNameEntry[1].pwszURL = L"file://nt.store";
  2678. rgAltNameEntry[2].dwAltNameChoice = CERT_ALT_NAME_URL;
  2679. rgAltNameEntry[2].pwszURL = L"file://win95.store";
  2680. rgDistPoint[0].cAltEntry = 1;
  2681. rgDistPoint[0].rgAltEntry = &rgAltNameEntry[0];
  2682. rgDistPoint[1].cAltEntry = 2;
  2683. rgDistPoint[1].rgAltEntry = &rgAltNameEntry[1];
  2684. memset(&Info, 0, sizeof(Info));
  2685. Info.dwSyncDeltaTime = 60 * 60 * 8;
  2686. Info.cDistPoint = 2;
  2687. Info.rgDistPoint = rgDistPoint;
  2688. if (!AllocAndEncodeObject(
  2689. X509_CROSS_CERT_DIST_POINTS,
  2690. &Info,
  2691. &pbEncoded,
  2692. &cbEncoded))
  2693. goto ErrorReturn;
  2694. fResult = TRUE;
  2695. goto CommonReturn;
  2696. ErrorReturn:
  2697. if (pbEncoded) {
  2698. TestFree(pbEncoded);
  2699. pbEncoded = NULL;
  2700. }
  2701. cbEncoded = 0;
  2702. fResult = FALSE;
  2703. CommonReturn:
  2704. *ppbEncoded = pbEncoded;
  2705. *pcbEncoded = cbEncoded;
  2706. return fResult;
  2707. }
  2708. static BOOL CreateKeyId(
  2709. DWORD dwIssuer,
  2710. OUT BYTE **ppbEncoded,
  2711. IN OUT DWORD *pcbEncoded
  2712. )
  2713. {
  2714. BYTE rgbPubKeyHash[SHA1_HASH_LEN];
  2715. CRYPT_DATA_BLOB KeyIdentifier;
  2716. Sha1HashPublicKey(dwIssuer, rgbPubKeyHash);
  2717. KeyIdentifier.pbData = rgbPubKeyHash;
  2718. KeyIdentifier.cbData = sizeof(rgbPubKeyHash);
  2719. return AllocAndEncodeObject(
  2720. X509_OCTET_STRING,
  2721. &KeyIdentifier,
  2722. ppbEncoded,
  2723. pcbEncoded
  2724. );
  2725. }
  2726. static BOOL CreateKeyAttributes(
  2727. DWORD dwCert,
  2728. OUT BYTE **ppbEncoded,
  2729. IN OUT DWORD *pcbEncoded
  2730. )
  2731. {
  2732. BOOL fResult;
  2733. BYTE *pbEncoded = NULL;
  2734. DWORD cbEncoded;
  2735. CERT_KEY_ATTRIBUTES_INFO KeyAttrInfo;
  2736. CERT_PRIVATE_KEY_VALIDITY KeyValidity;
  2737. BYTE bIntendedKeyUsage;
  2738. memset(&KeyAttrInfo, 0, sizeof(KeyAttrInfo));
  2739. if (CertPara[dwCert].dwFlags & CA_PARA_FLAG) {
  2740. // Issuer's KeyId
  2741. KeyAttrInfo.KeyId.pbData = (BYTE *) &dwCert;
  2742. KeyAttrInfo.KeyId.cbData = sizeof(dwCert);
  2743. }
  2744. if (CertPara[dwCert].dwFlags & XCHG_PARA_FLAG)
  2745. bIntendedKeyUsage = CERT_KEY_ENCIPHERMENT_KEY_USAGE |
  2746. CERT_DATA_ENCIPHERMENT_KEY_USAGE | CERT_KEY_AGREEMENT_KEY_USAGE;
  2747. else
  2748. bIntendedKeyUsage =
  2749. CERT_DIGITAL_SIGNATURE_KEY_USAGE | CERT_NON_REPUDIATION_KEY_USAGE;
  2750. if (CertPara[dwCert].dwFlags & CA_PARA_FLAG)
  2751. bIntendedKeyUsage |= CERT_KEY_CERT_SIGN_KEY_USAGE;
  2752. KeyAttrInfo.IntendedKeyUsage.pbData = &bIntendedKeyUsage;
  2753. KeyAttrInfo.IntendedKeyUsage.cbData = 1;
  2754. KeyAttrInfo.IntendedKeyUsage.cUnusedBits = 1;
  2755. {
  2756. SYSTEMTIME SystemTime = TestTime;
  2757. SystemTime.wMilliseconds = 123;
  2758. MySystemTimeToFileTime(&SystemTime, &KeyValidity.NotBefore);
  2759. SystemTime.wYear += 2;
  2760. SystemTime.wMilliseconds = 456;
  2761. MySystemTimeToFileTime(&SystemTime, &KeyValidity.NotAfter);
  2762. }
  2763. KeyAttrInfo.pPrivateKeyUsagePeriod = &KeyValidity;
  2764. if (!AllocAndEncodeObject(
  2765. X509_KEY_ATTRIBUTES,
  2766. &KeyAttrInfo,
  2767. &pbEncoded,
  2768. &cbEncoded
  2769. ))
  2770. goto ErrorReturn;
  2771. fResult = TRUE;
  2772. goto CommonReturn;
  2773. ErrorReturn:
  2774. if (pbEncoded) {
  2775. TestFree(pbEncoded);
  2776. pbEncoded = NULL;
  2777. }
  2778. cbEncoded = 0;
  2779. fResult = FALSE;
  2780. CommonReturn:
  2781. *ppbEncoded = pbEncoded;
  2782. *pcbEncoded = cbEncoded;
  2783. return fResult;
  2784. }
  2785. static BOOL CreateKeyUsageRestriction(
  2786. DWORD dwCert,
  2787. OUT BYTE **ppbEncoded,
  2788. IN OUT DWORD *pcbEncoded
  2789. )
  2790. {
  2791. BOOL fResult;
  2792. BYTE *pbEncoded = NULL;
  2793. DWORD cbEncoded;
  2794. CERT_KEY_USAGE_RESTRICTION_INFO KeyUsageInfo;
  2795. BYTE bRestrictedKeyUsage;
  2796. LPSTR rgpszCertPolicyElementId[4] = {
  2797. "1.2.333.1",
  2798. "1.2.333.22",
  2799. "1.2.333.333",
  2800. "1.2.333.4444"
  2801. };
  2802. CERT_POLICY_ID rgCertPolicyId[3] = {
  2803. 0, NULL,
  2804. 1, rgpszCertPolicyElementId,
  2805. 4, rgpszCertPolicyElementId
  2806. };
  2807. LPSTR rgpszSpcCertPolicyElementId[2] = {
  2808. SPC_INDIVIDUAL_SP_KEY_PURPOSE_OBJID,
  2809. SPC_COMMERCIAL_SP_KEY_PURPOSE_OBJID
  2810. };
  2811. CERT_POLICY_ID rgSpcCertPolicyId[2] = {
  2812. 1, &rgpszSpcCertPolicyElementId[0],
  2813. 1, &rgpszSpcCertPolicyElementId[1]
  2814. };
  2815. memset(&KeyUsageInfo, 0, sizeof(KeyUsageInfo));
  2816. if (CertPara[dwCert].dwFlags & XCHG_PARA_FLAG)
  2817. bRestrictedKeyUsage = CERT_KEY_ENCIPHERMENT_KEY_USAGE |
  2818. CERT_DATA_ENCIPHERMENT_KEY_USAGE | CERT_KEY_AGREEMENT_KEY_USAGE;
  2819. else
  2820. bRestrictedKeyUsage =
  2821. CERT_DIGITAL_SIGNATURE_KEY_USAGE | CERT_NON_REPUDIATION_KEY_USAGE;
  2822. if (CertPara[dwCert].dwFlags & CA_PARA_FLAG)
  2823. bRestrictedKeyUsage |= CERT_KEY_CERT_SIGN_KEY_USAGE;
  2824. KeyUsageInfo.RestrictedKeyUsage.pbData = &bRestrictedKeyUsage;
  2825. KeyUsageInfo.RestrictedKeyUsage.cbData = 1;
  2826. KeyUsageInfo.RestrictedKeyUsage.cUnusedBits = 1;
  2827. if (CertPara[dwCert].dwFlags & SPC_AGENCY_PARA_FLAG) {
  2828. KeyUsageInfo.cCertPolicyId = 2;
  2829. KeyUsageInfo.rgCertPolicyId = rgSpcCertPolicyId;
  2830. } else if (CertPara[dwCert].dwFlags & SPC_COM_PARA_FLAG) {
  2831. KeyUsageInfo.cCertPolicyId = 1;
  2832. KeyUsageInfo.rgCertPolicyId = &rgSpcCertPolicyId[1];
  2833. } else if (CertPara[dwCert].dwFlags & SPC_EXT_PARA_FLAG) {
  2834. KeyUsageInfo.cCertPolicyId = 1;
  2835. KeyUsageInfo.rgCertPolicyId = &rgSpcCertPolicyId[0];
  2836. } else if (CertPara[dwCert].dwFlags & ALL_EXT_PARA_FLAG) {
  2837. KeyUsageInfo.cCertPolicyId = 3;
  2838. KeyUsageInfo.rgCertPolicyId = rgCertPolicyId;
  2839. }
  2840. if (!AllocAndEncodeObject(
  2841. X509_KEY_USAGE_RESTRICTION,
  2842. &KeyUsageInfo,
  2843. &pbEncoded,
  2844. &cbEncoded
  2845. ))
  2846. goto ErrorReturn;
  2847. fResult = TRUE;
  2848. goto CommonReturn;
  2849. ErrorReturn:
  2850. if (pbEncoded) {
  2851. TestFree(pbEncoded);
  2852. pbEncoded = NULL;
  2853. }
  2854. cbEncoded = 0;
  2855. fResult = FALSE;
  2856. CommonReturn:
  2857. *ppbEncoded = pbEncoded;
  2858. *pcbEncoded = cbEncoded;
  2859. return fResult;
  2860. }
  2861. static BOOL CreateBasicConstraints(
  2862. DWORD dwCert,
  2863. OUT BYTE **ppbEncoded,
  2864. IN OUT DWORD *pcbEncoded
  2865. )
  2866. {
  2867. BOOL fResult;
  2868. BYTE *pbEncoded = NULL;
  2869. DWORD cbEncoded;
  2870. BYTE *pbSubtreesEncoded = NULL;
  2871. DWORD cbSubtreesEncoded;
  2872. CERT_NAME_BLOB rgSubtreesConstraint[2];
  2873. CERT_BASIC_CONSTRAINTS_INFO BasicConstraintsInfo;
  2874. BYTE bSubjectType;
  2875. memset(&BasicConstraintsInfo, 0, sizeof(BasicConstraintsInfo));
  2876. if (CertPara[dwCert].dwFlags & CA_PARA_FLAG) {
  2877. bSubjectType = CERT_CA_SUBJECT_FLAG;
  2878. BasicConstraintsInfo.fPathLenConstraint = TRUE;
  2879. BasicConstraintsInfo.dwPathLenConstraint = dwCert + 1;
  2880. } else
  2881. bSubjectType = CERT_END_ENTITY_SUBJECT_FLAG;
  2882. BasicConstraintsInfo.SubjectType.pbData = &bSubjectType;
  2883. BasicConstraintsInfo.SubjectType.cbData = 1;
  2884. BasicConstraintsInfo.SubjectType.cUnusedBits = 6;
  2885. if (CertPara[dwCert].dwFlags & ALL_EXT_PARA_FLAG) {
  2886. CERT_RDN rgRDN[RDN_CNT];
  2887. CERT_RDN_ATTR rgAttr[ATTR_CNT];
  2888. CERT_NAME_INFO Name;
  2889. CreateNameInfo(dwCert, &Name, rgRDN, rgAttr);
  2890. cbSubtreesEncoded = 0;
  2891. if (!AllocAndEncodeObject(
  2892. X509_NAME,
  2893. &Name,
  2894. &pbSubtreesEncoded,
  2895. &cbSubtreesEncoded
  2896. ))
  2897. goto ErrorReturn;
  2898. BasicConstraintsInfo.cSubtreesConstraint = 2;
  2899. BasicConstraintsInfo.rgSubtreesConstraint = rgSubtreesConstraint;
  2900. rgSubtreesConstraint[0].pbData = pbSubtreesEncoded;
  2901. rgSubtreesConstraint[0].cbData = cbSubtreesEncoded;
  2902. rgSubtreesConstraint[1].pbData = pbSubtreesEncoded;
  2903. rgSubtreesConstraint[1].cbData = cbSubtreesEncoded;
  2904. }
  2905. if (!AllocAndEncodeObject(
  2906. X509_BASIC_CONSTRAINTS,
  2907. &BasicConstraintsInfo,
  2908. &pbEncoded,
  2909. &cbEncoded
  2910. ))
  2911. goto ErrorReturn;
  2912. fResult = TRUE;
  2913. goto CommonReturn;
  2914. ErrorReturn:
  2915. if (pbEncoded) {
  2916. TestFree(pbEncoded);
  2917. pbEncoded = NULL;
  2918. }
  2919. cbEncoded = 0;
  2920. fResult = FALSE;
  2921. CommonReturn:
  2922. if (pbSubtreesEncoded)
  2923. TestFree(pbSubtreesEncoded);
  2924. *ppbEncoded = pbEncoded;
  2925. *pcbEncoded = cbEncoded;
  2926. return fResult;
  2927. }
  2928. static BOOL CreateKeyUsage(
  2929. DWORD dwCert,
  2930. OUT BYTE **ppbEncoded,
  2931. IN OUT DWORD *pcbEncoded
  2932. )
  2933. {
  2934. BOOL fResult;
  2935. BYTE *pbEncoded = NULL;
  2936. DWORD cbEncoded;
  2937. CRYPT_BIT_BLOB KeyUsageInfo;
  2938. BYTE bKeyUsage;
  2939. memset(&KeyUsageInfo, 0, sizeof(KeyUsageInfo));
  2940. if (CertPara[dwCert].dwFlags & XCHG_PARA_FLAG)
  2941. bKeyUsage = CERT_KEY_ENCIPHERMENT_KEY_USAGE |
  2942. CERT_DATA_ENCIPHERMENT_KEY_USAGE | CERT_KEY_AGREEMENT_KEY_USAGE;
  2943. else
  2944. bKeyUsage =
  2945. CERT_DIGITAL_SIGNATURE_KEY_USAGE | CERT_NON_REPUDIATION_KEY_USAGE;
  2946. if (0 == strcmp(CertPara[dwCert].pszName, "InvalidKeyUsageCA"))
  2947. // No cert signing usage for this cert
  2948. ;
  2949. else if (CertPara[dwCert].dwFlags & CA_PARA_FLAG)
  2950. bKeyUsage |= CERT_KEY_CERT_SIGN_KEY_USAGE;
  2951. KeyUsageInfo.pbData = &bKeyUsage;
  2952. KeyUsageInfo.cbData = 1;
  2953. KeyUsageInfo.cUnusedBits = 1;
  2954. if (!AllocAndEncodeObject(
  2955. X509_KEY_USAGE,
  2956. &KeyUsageInfo,
  2957. &pbEncoded,
  2958. &cbEncoded
  2959. ))
  2960. goto ErrorReturn;
  2961. fResult = TRUE;
  2962. goto CommonReturn;
  2963. ErrorReturn:
  2964. if (pbEncoded) {
  2965. TestFree(pbEncoded);
  2966. pbEncoded = NULL;
  2967. }
  2968. cbEncoded = 0;
  2969. fResult = FALSE;
  2970. CommonReturn:
  2971. *ppbEncoded = pbEncoded;
  2972. *pcbEncoded = cbEncoded;
  2973. return fResult;
  2974. }
  2975. static BOOL CreateBasicConstraints2(
  2976. DWORD dwCert,
  2977. OUT BYTE **ppbEncoded,
  2978. IN OUT DWORD *pcbEncoded
  2979. )
  2980. {
  2981. BOOL fResult;
  2982. BYTE *pbEncoded = NULL;
  2983. DWORD cbEncoded;
  2984. CERT_BASIC_CONSTRAINTS2_INFO BasicConstraints2Info;
  2985. memset(&BasicConstraints2Info, 0, sizeof(BasicConstraints2Info));
  2986. if (dwCert == POLICY_ROOT || dwCert == ROLLOVER_CROSS_CERT) {
  2987. BasicConstraints2Info.fCA = TRUE;
  2988. BasicConstraints2Info.fPathLenConstraint = TRUE;
  2989. BasicConstraints2Info.dwPathLenConstraint = 1;
  2990. } else if (dwCert == POLICY_CA) {
  2991. BasicConstraints2Info.fCA = TRUE;
  2992. BasicConstraints2Info.fPathLenConstraint = TRUE;
  2993. BasicConstraints2Info.dwPathLenConstraint = 0;
  2994. } else if (CertPara[dwCert].dwFlags & CA_PARA_FLAG) {
  2995. BasicConstraints2Info.fCA = TRUE;
  2996. BasicConstraints2Info.fPathLenConstraint = TRUE;
  2997. if (0 == strcmp(CertPara[dwCert].pszName, "TestRoot"))
  2998. BasicConstraints2Info.dwPathLenConstraint = 2;
  2999. else
  3000. BasicConstraints2Info.dwPathLenConstraint = dwCert + 1;
  3001. } else
  3002. BasicConstraints2Info.fCA = FALSE;
  3003. if (!AllocAndEncodeObject(
  3004. X509_BASIC_CONSTRAINTS2,
  3005. &BasicConstraints2Info,
  3006. &pbEncoded,
  3007. &cbEncoded
  3008. ))
  3009. goto ErrorReturn;
  3010. fResult = TRUE;
  3011. goto CommonReturn;
  3012. ErrorReturn:
  3013. if (pbEncoded) {
  3014. TestFree(pbEncoded);
  3015. pbEncoded = NULL;
  3016. }
  3017. cbEncoded = 0;
  3018. fResult = FALSE;
  3019. CommonReturn:
  3020. *ppbEncoded = pbEncoded;
  3021. *pcbEncoded = cbEncoded;
  3022. return fResult;
  3023. }
  3024. static BOOL CreatePolicies(
  3025. DWORD dwCert,
  3026. OUT BYTE **ppbEncoded,
  3027. IN OUT DWORD *pcbEncoded
  3028. )
  3029. {
  3030. BYTE rgbQualifier2[] = {5, 0}; // NULL
  3031. BYTE rgbQualifier4[] = {4, 8, 1,2,3,4,5,6,7,8}; // Octet String
  3032. CERT_POLICY_QUALIFIER_INFO rgQualifierInfo[4] = {
  3033. "1.2.1", 0, NULL,
  3034. "1.2.2", sizeof(rgbQualifier2), rgbQualifier2,
  3035. "1.2.3", 0, NULL,
  3036. "1.2.4", sizeof(rgbQualifier4), rgbQualifier4
  3037. };
  3038. // Root has the following policies:
  3039. // 1.1.1
  3040. // 1.1.55555
  3041. // 1.1.22
  3042. // 1.1.333
  3043. // 1.1.4444
  3044. CERT_POLICY_INFO rgRootPolicyInfo[] = {
  3045. "1.1.1", 0, NULL,
  3046. "1.1.55555", 0, NULL,
  3047. "1.1.22", 2, rgQualifierInfo,
  3048. "1.1.333", 2, &rgQualifierInfo[2],
  3049. "1.1.333", 0, NULL, // duplicate, should be removed
  3050. "1.1.4444", 1, rgQualifierInfo,
  3051. "1.1.4444", 0, NULL, // duplicate
  3052. "1.1.1", 0, NULL, // duplicate
  3053. "1.1.1", 0, NULL, // duplicate
  3054. };
  3055. // After mapping, the CA has the following policies:
  3056. // 1.1.1
  3057. // 1.1.22
  3058. // 1.1.333
  3059. // 1.1.4444
  3060. CERT_POLICY_INFO rgCaPolicyInfo[] = {
  3061. "1.2.22.1", 0, NULL, // 1.1.22
  3062. "1.2.22.2", 0, NULL, // 1.1.22
  3063. "1.2.22.3", 0, NULL, // 1.1.22
  3064. "1.2.333.1", 0, NULL, // 1.1.333
  3065. "1.2.333.2", 0, NULL, // 1.1.333
  3066. "1.2.4444", 0, NULL, // 1.1.4444
  3067. "1.1.4444", 0, NULL, // 1.1.4444
  3068. "1.1.1", 0, NULL, // 1.1.1
  3069. "1.2.333.3", 0, NULL, // 1.1.333
  3070. "1.2.55555", 0, NULL, // no mapping
  3071. };
  3072. // After mapping, the cert has the following policies:
  3073. // 1.1.1
  3074. // 1.1.22
  3075. CERT_POLICY_INFO rgPolicyInfo[] = {
  3076. "1.1.55555", 0, NULL, // no mapping via ca
  3077. "1.3.22.2.1", 0, NULL, // 1.2.22.2 -> 1.1.22
  3078. "1.3.1.1", 0, NULL, // 1.1.1
  3079. "1.2.55555", 0, NULL, // no mapping via root
  3080. };
  3081. // After mapping, the cert has the following policies:
  3082. // 1.1.1
  3083. // 1.1.22
  3084. // 1.1.4444
  3085. CERT_POLICY_INFO rgAllExtPolicyInfo[] = {
  3086. "1.3.1.2", 0, NULL, // 1.1.1
  3087. "1.3.22.2.2", 0, NULL, // 1.2.22.2 -> 1.1.22
  3088. "1.1.55555", 0, NULL, // no mapping via ca
  3089. "1.2.55555", 0, NULL, // not mapping via root
  3090. "1.1.4444", 0, NULL, // 1.1.4444
  3091. };
  3092. CERT_POLICY_INFO rgSpcPolicyInfo[2] = {
  3093. SPC_INDIVIDUAL_SP_KEY_PURPOSE_OBJID, 0, NULL,
  3094. SPC_COMMERCIAL_SP_KEY_PURPOSE_OBJID, 0, NULL
  3095. };
  3096. CERT_POLICY_INFO rgDssCAPolicyInfo[] = {
  3097. szOID_ANY_CERT_POLICY, 0, NULL,
  3098. };
  3099. CERT_POLICY_INFO rgDssEndPolicyInfo[] = {
  3100. "1.1.4444", 0, NULL,
  3101. "1.1.55555", 0, NULL,
  3102. };
  3103. CERT_POLICIES_INFO PoliciesInfo;
  3104. memset(&PoliciesInfo, 0, sizeof(PoliciesInfo));
  3105. if (0 == strcmp(CertPara[dwCert].pszName, "DssCA")) {
  3106. PoliciesInfo.cPolicyInfo = sizeof(rgDssCAPolicyInfo) /
  3107. sizeof(rgDssCAPolicyInfo[0]);
  3108. PoliciesInfo.rgPolicyInfo = rgDssCAPolicyInfo;
  3109. } else if (0 == strcmp(CertPara[dwCert].pszName, "DssEnd")) {
  3110. PoliciesInfo.cPolicyInfo = sizeof(rgDssEndPolicyInfo) /
  3111. sizeof(rgDssEndPolicyInfo[0]);
  3112. PoliciesInfo.rgPolicyInfo = rgDssEndPolicyInfo;
  3113. } else if (POLICY_ROOT == dwCert) {
  3114. PoliciesInfo.cPolicyInfo = sizeof(rgRootPolicyInfo) /
  3115. sizeof(rgRootPolicyInfo[0]);
  3116. PoliciesInfo.rgPolicyInfo = rgRootPolicyInfo;
  3117. } else if (POLICY_CA == dwCert) {
  3118. PoliciesInfo.cPolicyInfo = sizeof(rgCaPolicyInfo) /
  3119. sizeof(rgCaPolicyInfo[0]);
  3120. PoliciesInfo.rgPolicyInfo = rgCaPolicyInfo;
  3121. } else if (CertPara[dwCert].dwFlags & SPC_AGENCY_PARA_FLAG) {
  3122. PoliciesInfo.cPolicyInfo = 2;
  3123. PoliciesInfo.rgPolicyInfo = rgSpcPolicyInfo;
  3124. } else if (CertPara[dwCert].dwFlags & SPC_COM_PARA_FLAG) {
  3125. PoliciesInfo.cPolicyInfo = 1;
  3126. PoliciesInfo.rgPolicyInfo = &rgSpcPolicyInfo[1];
  3127. } else if (CertPara[dwCert].dwFlags & SPC_EXT_PARA_FLAG) {
  3128. PoliciesInfo.cPolicyInfo = 1;
  3129. PoliciesInfo.rgPolicyInfo = &rgSpcPolicyInfo[0];
  3130. } else if (CertPara[dwCert].dwFlags & ALL_EXT_PARA_FLAG) {
  3131. PoliciesInfo.cPolicyInfo = sizeof(rgAllExtPolicyInfo) /
  3132. sizeof(rgAllExtPolicyInfo[0]);
  3133. PoliciesInfo.rgPolicyInfo = rgAllExtPolicyInfo;
  3134. } else {
  3135. PoliciesInfo.cPolicyInfo = sizeof(rgPolicyInfo) /
  3136. sizeof(rgPolicyInfo[0]);
  3137. PoliciesInfo.rgPolicyInfo = rgPolicyInfo;
  3138. }
  3139. return AllocAndEncodeObject(
  3140. X509_CERT_POLICIES,
  3141. &PoliciesInfo,
  3142. ppbEncoded,
  3143. pcbEncoded);
  3144. }
  3145. static BOOL CreateSMIMECapabilities(
  3146. DWORD dwCert,
  3147. OUT BYTE **ppbEncoded,
  3148. IN OUT DWORD *pcbEncoded
  3149. )
  3150. {
  3151. BYTE rgb128BitLen[] = {2, 2, 0, 128}; // Integer
  3152. BYTE rgb40BitLen[] = {2, 1, 40}; // Integer
  3153. CRYPT_SMIME_CAPABILITY rgCapability[4] = {
  3154. szOID_RSA_DES_EDE3_CBC, 0, NULL,
  3155. szOID_RSA_RC2CBC, sizeof(rgb128BitLen), rgb128BitLen,
  3156. szOID_RSA_RC2CBC, sizeof(rgb40BitLen), rgb40BitLen,
  3157. szOID_RSA_preferSignedData, 0, NULL
  3158. };
  3159. CRYPT_SMIME_CAPABILITIES Capabilities = {
  3160. sizeof(rgCapability)/sizeof(rgCapability[0]), rgCapability
  3161. };
  3162. return AllocAndEncodeObject(
  3163. PKCS_SMIME_CAPABILITIES,
  3164. &Capabilities,
  3165. ppbEncoded,
  3166. pcbEncoded);
  3167. }
  3168. static BOOL CreateAltName(
  3169. DWORD dwCert,
  3170. OUT BYTE **ppbEncoded,
  3171. IN OUT DWORD *pcbEncoded
  3172. )
  3173. {
  3174. BOOL fResult;
  3175. BYTE *pbEncoded = NULL;
  3176. DWORD cbEncoded;
  3177. CERT_ALT_NAME_INFO AltNameInfo;
  3178. #define ALT_NAME_ENTRY_CNT 15
  3179. CERT_ALT_NAME_ENTRY rgAltNameEntry[ALT_NAME_ENTRY_CNT];
  3180. DWORD i;
  3181. BYTE *pbNameEncoded = NULL;
  3182. DWORD cbNameEncoded;
  3183. CERT_OTHER_NAME UPNOtherName;
  3184. BYTE *pbUPNNameEncoded = NULL;
  3185. DWORD cbUPNNameEncoded;
  3186. CERT_OTHER_NAME StringOtherName;
  3187. BYTE *pbStringOtherNameEncoded = NULL;
  3188. DWORD cbStringOtherNameEncoded;
  3189. DWORD dwStringOtherNameValueType = CERT_RDN_UTF8_STRING;
  3190. LPWSTR pwszEmail = NULL;
  3191. LPWSTR pwszUrl = NULL;
  3192. LPWSTR pwszUPN = NULL;
  3193. LPWSTR pwszStringOtherName = NULL;
  3194. LPWSTR pwszDns = NULL;
  3195. BYTE rgbOctetOtherName[] = {0x04, 0x02, 0x11, 0x22};
  3196. CERT_OTHER_NAME OctetOtherName;
  3197. PCERT_OTHER_NAME pOctetOtherName = NULL;
  3198. LPSTR pszRegisteredID = NULL;
  3199. BYTE rgbDefaultIPAddress[] = {1,1,0,0};
  3200. BYTE rgbAllExtIPAddress[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,17};
  3201. BYTE rgbExcludedIPAddress[] = {2,2,3,3};
  3202. BYTE rgbNotPermittedIPAddress[] = {3,3,3,3};
  3203. BYTE *pbIPAddress = NULL;
  3204. DWORD cbIPAddress = 0;
  3205. if (CertPara[dwCert].dwFlags &
  3206. (NO_NAME_PARA_FLAG | ALT_DIR_NAME_PARA_FLAG)) {
  3207. pwszEmail = L"[email protected]";
  3208. }
  3209. if (CertPara[dwCert].dwFlags & ALL_EXT_PARA_FLAG) {
  3210. pwszEmail = L" [email protected] ";
  3211. pwszUrl = L" http://www.AllExt.url.com:388/more url stuff";
  3212. pwszDns = L"DNS name";
  3213. pwszUPN = L"[email protected]";
  3214. pwszStringOtherName = L"AllExtString@OtherName";
  3215. dwStringOtherNameValueType = CERT_RDN_TELETEX_STRING;
  3216. pbIPAddress = rgbAllExtIPAddress;
  3217. cbIPAddress = sizeof(rgbAllExtIPAddress);
  3218. } else if (0 == strcmp(CertPara[dwCert].pszName, "Excluded")) {
  3219. pwszEmail = L" [email protected] ";
  3220. pwszUrl = L" http://Excluded.url.com/more url stuff";
  3221. pwszDns = L"www.excluded.dns.com";
  3222. pwszUPN = L"[email protected]";
  3223. pwszStringOtherName = L"ExcludedString@OtherName";
  3224. dwStringOtherNameValueType = CERT_RDN_IA5_STRING;
  3225. pbIPAddress = rgbExcludedIPAddress;
  3226. cbIPAddress = sizeof(rgbExcludedIPAddress);
  3227. } else if (0 == strcmp(CertPara[dwCert].pszName, "NotPermitted")) {
  3228. pwszEmail = L"[email protected]";
  3229. pwszUrl = L"http://www.url.not/more url stuff";
  3230. pwszDns = L"www.excluded.dns.not";
  3231. pwszUPN = L"[email protected]";
  3232. pwszStringOtherName = L"String@OtherNameNot";
  3233. dwStringOtherNameValueType = CERT_RDN_GENERAL_STRING;
  3234. pbIPAddress = rgbNotPermittedIPAddress;
  3235. cbIPAddress = sizeof(rgbNotPermittedIPAddress);
  3236. OctetOtherName.pszObjId = OCTET_OTHER_NAME_OID;
  3237. OctetOtherName.Value.pbData = rgbOctetOtherName;
  3238. OctetOtherName.Value.cbData = sizeof(rgbOctetOtherName);
  3239. pOctetOtherName = &OctetOtherName;
  3240. pszRegisteredID = "1.2.3.4.5.6.7";
  3241. } else {
  3242. pwszUPN = L" [email protected] ";
  3243. pwszStringOtherName = L" DefaultString@OtherName ";
  3244. dwStringOtherNameValueType = CERT_RDN_UTF8_STRING;
  3245. pbIPAddress = rgbDefaultIPAddress;
  3246. cbIPAddress = sizeof(rgbDefaultIPAddress);
  3247. }
  3248. if (0 == strcmp(CertPara[dwCert].pszName, "MissingNCEnd")) {
  3249. OctetOtherName.pszObjId = OCTET_OTHER_NAME_OID;
  3250. OctetOtherName.Value.pbData = rgbOctetOtherName;
  3251. OctetOtherName.Value.cbData = sizeof(rgbOctetOtherName);
  3252. pOctetOtherName = &OctetOtherName;
  3253. }
  3254. i = 0;
  3255. if (pwszEmail) {
  3256. rgAltNameEntry[0].dwAltNameChoice = CERT_ALT_NAME_RFC822_NAME;
  3257. rgAltNameEntry[0].pwszRfc822Name = pwszEmail;
  3258. i++;
  3259. }
  3260. if (pwszUPN) {
  3261. CERT_NAME_VALUE UPNNameValue;
  3262. UPNNameValue.dwValueType = CERT_RDN_UTF8_STRING;
  3263. UPNNameValue.Value.pbData = (BYTE *) pwszUPN;
  3264. UPNNameValue.Value.cbData = 0;
  3265. if (!AllocAndEncodeObject(
  3266. X509_UNICODE_ANY_STRING,
  3267. &UPNNameValue,
  3268. &pbUPNNameEncoded,
  3269. &cbUPNNameEncoded))
  3270. goto ErrorReturn;
  3271. UPNOtherName.pszObjId = szOID_NT_PRINCIPAL_NAME;
  3272. UPNOtherName.Value.pbData = pbUPNNameEncoded;
  3273. UPNOtherName.Value.cbData = cbUPNNameEncoded;
  3274. rgAltNameEntry[i].dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME;
  3275. rgAltNameEntry[i].pOtherName = &UPNOtherName;
  3276. i++;
  3277. }
  3278. if (pwszStringOtherName) {
  3279. CERT_NAME_VALUE OtherNameValue;
  3280. OtherNameValue.dwValueType = dwStringOtherNameValueType;
  3281. OtherNameValue.Value.pbData = (BYTE *) pwszStringOtherName;
  3282. OtherNameValue.Value.cbData = 0;
  3283. if (!AllocAndEncodeObject(
  3284. X509_UNICODE_ANY_STRING,
  3285. &OtherNameValue,
  3286. &pbStringOtherNameEncoded,
  3287. &cbStringOtherNameEncoded))
  3288. goto ErrorReturn;
  3289. StringOtherName.pszObjId = STRING_OTHER_NAME_OID;
  3290. StringOtherName.Value.pbData = pbStringOtherNameEncoded;
  3291. StringOtherName.Value.cbData = cbStringOtherNameEncoded;
  3292. rgAltNameEntry[i].dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME;
  3293. rgAltNameEntry[i].pOtherName = &StringOtherName;
  3294. i++;
  3295. }
  3296. if (pwszUrl) {
  3297. rgAltNameEntry[i].dwAltNameChoice = CERT_ALT_NAME_URL;
  3298. rgAltNameEntry[i].pwszURL = pwszUrl;
  3299. i++;
  3300. }
  3301. if (pwszDns) {
  3302. rgAltNameEntry[i].dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
  3303. rgAltNameEntry[i].pwszDNSName = pwszDns;
  3304. i++;
  3305. }
  3306. if (pszRegisteredID) {
  3307. rgAltNameEntry[i].dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID;
  3308. rgAltNameEntry[i].pszRegisteredID = pszRegisteredID;
  3309. i++;
  3310. }
  3311. if (pbIPAddress && cbIPAddress) {
  3312. rgAltNameEntry[i].dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
  3313. rgAltNameEntry[i].IPAddress.pbData = pbIPAddress;
  3314. rgAltNameEntry[i].IPAddress.cbData = cbIPAddress;
  3315. i++;
  3316. }
  3317. if (pOctetOtherName) {
  3318. rgAltNameEntry[i].dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME;
  3319. rgAltNameEntry[i].pOtherName = pOctetOtherName;
  3320. i++;
  3321. }
  3322. if (CertPara[dwCert].dwFlags & ALT_DIR_NAME_PARA_FLAG) {
  3323. CERT_NAME_INFO NameInfo;
  3324. CERT_RDN rgRDN[1];
  3325. CERT_RDN_ATTR rgAttr[1];
  3326. NameInfo.cRDN = 1;
  3327. NameInfo.rgRDN = rgRDN;
  3328. rgRDN[0].cRDNAttr = 1;
  3329. rgRDN[0].rgRDNAttr = rgAttr;
  3330. rgAttr[0].pszObjId = szOID_ORGANIZATIONAL_UNIT_NAME;
  3331. rgAttr[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
  3332. rgAttr[0].Value.pbData = (BYTE *) CertPara[dwCert].pszName;
  3333. rgAttr[0].Value.cbData = strlen(CertPara[dwCert].pszName);
  3334. if (!AllocAndEncodeObject(
  3335. X509_NAME,
  3336. &NameInfo,
  3337. &pbNameEncoded,
  3338. &cbNameEncoded))
  3339. goto ErrorReturn;
  3340. rgAltNameEntry[i].dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
  3341. rgAltNameEntry[i].DirectoryName.pbData = pbNameEncoded;
  3342. rgAltNameEntry[i].DirectoryName.cbData = cbNameEncoded;
  3343. i++;
  3344. }
  3345. AltNameInfo.cAltEntry = i;
  3346. AltNameInfo.rgAltEntry = rgAltNameEntry;
  3347. if (!AllocAndEncodeObject(
  3348. X509_ALTERNATE_NAME,
  3349. &AltNameInfo,
  3350. &pbEncoded,
  3351. &cbEncoded))
  3352. goto ErrorReturn;
  3353. fResult = TRUE;
  3354. goto CommonReturn;
  3355. ErrorReturn:
  3356. if (pbEncoded) {
  3357. TestFree(pbEncoded);
  3358. pbEncoded = NULL;
  3359. }
  3360. cbEncoded = 0;
  3361. fResult = FALSE;
  3362. CommonReturn:
  3363. TestFree(pbNameEncoded);
  3364. TestFree(pbUPNNameEncoded);
  3365. TestFree(pbStringOtherNameEncoded);
  3366. *ppbEncoded = pbEncoded;
  3367. *pcbEncoded = cbEncoded;
  3368. return fResult;
  3369. }
  3370. static BOOL CreateSETAccountAlias(
  3371. DWORD dwCert,
  3372. OUT BYTE **ppbEncoded,
  3373. IN OUT DWORD *pcbEncoded
  3374. )
  3375. {
  3376. BOOL fResult;
  3377. BYTE *pbEncoded = NULL;
  3378. DWORD cbEncoded;
  3379. BOOL bInfo;
  3380. if (CertPara[dwCert].dwFlags & ALL_EXT_PARA_FLAG)
  3381. bInfo = TRUE;
  3382. else
  3383. bInfo = FALSE;
  3384. if (!AllocAndEncodeObject(
  3385. X509_SET_ACCOUNT_ALIAS,
  3386. &bInfo,
  3387. &pbEncoded,
  3388. &cbEncoded
  3389. ))
  3390. goto ErrorReturn;
  3391. fResult = TRUE;
  3392. goto CommonReturn;
  3393. ErrorReturn:
  3394. if (pbEncoded) {
  3395. TestFree(pbEncoded);
  3396. pbEncoded = NULL;
  3397. }
  3398. cbEncoded = 0;
  3399. fResult = FALSE;
  3400. CommonReturn:
  3401. *ppbEncoded = pbEncoded;
  3402. *pcbEncoded = cbEncoded;
  3403. return fResult;
  3404. }
  3405. static BOOL CreateSETHashedRootKey(
  3406. DWORD dwCert,
  3407. OUT BYTE **ppbEncoded,
  3408. IN OUT DWORD *pcbEncoded
  3409. )
  3410. {
  3411. BOOL fResult;
  3412. BYTE *pbEncoded = NULL;
  3413. DWORD cbEncoded;
  3414. BYTE i;
  3415. BYTE rgbInfo[SET_HASHED_ROOT_LEN];
  3416. for (i = 0; i < SET_HASHED_ROOT_LEN; i++)
  3417. rgbInfo[i] = i;
  3418. if (!AllocAndEncodeObject(
  3419. X509_SET_HASHED_ROOT_KEY,
  3420. rgbInfo,
  3421. &pbEncoded,
  3422. &cbEncoded
  3423. ))
  3424. goto ErrorReturn;
  3425. fResult = TRUE;
  3426. goto CommonReturn;
  3427. ErrorReturn:
  3428. if (pbEncoded) {
  3429. TestFree(pbEncoded);
  3430. pbEncoded = NULL;
  3431. }
  3432. cbEncoded = 0;
  3433. fResult = FALSE;
  3434. CommonReturn:
  3435. *ppbEncoded = pbEncoded;
  3436. *pcbEncoded = cbEncoded;
  3437. return fResult;
  3438. }
  3439. static BOOL CreateSETCertificateType(
  3440. DWORD dwCert,
  3441. OUT BYTE **ppbEncoded,
  3442. IN OUT DWORD *pcbEncoded
  3443. )
  3444. {
  3445. BOOL fResult;
  3446. BYTE *pbEncoded = NULL;
  3447. DWORD cbEncoded;
  3448. CRYPT_BIT_BLOB Info;
  3449. BYTE rgbType[2] = {0,0};
  3450. if (dwCert < 8)
  3451. rgbType[0] = 1 << (dwCert % 8);
  3452. else
  3453. rgbType[1] = 0x40 << (dwCert % 2);
  3454. Info.pbData = rgbType;
  3455. Info.cbData = 2;
  3456. Info.cUnusedBits = 6;
  3457. if (!AllocAndEncodeObject(
  3458. X509_SET_CERTIFICATE_TYPE,
  3459. &Info,
  3460. &pbEncoded,
  3461. &cbEncoded
  3462. ))
  3463. goto ErrorReturn;
  3464. fResult = TRUE;
  3465. goto CommonReturn;
  3466. ErrorReturn:
  3467. if (pbEncoded) {
  3468. TestFree(pbEncoded);
  3469. pbEncoded = NULL;
  3470. }
  3471. cbEncoded = 0;
  3472. fResult = FALSE;
  3473. CommonReturn:
  3474. *ppbEncoded = pbEncoded;
  3475. *pcbEncoded = cbEncoded;
  3476. return fResult;
  3477. }
  3478. static BOOL CreateSETMerchantData(
  3479. DWORD dwCert,
  3480. OUT BYTE **ppbEncoded,
  3481. IN OUT DWORD *pcbEncoded
  3482. )
  3483. {
  3484. BOOL fResult;
  3485. BYTE *pbEncoded = NULL;
  3486. DWORD cbEncoded;
  3487. SET_MERCHANT_DATA_INFO Info;
  3488. memset(&Info, 0, sizeof(Info));
  3489. if (CertPara[dwCert].dwFlags & ALL_EXT_PARA_FLAG) {
  3490. Info.pszMerID = "ID";
  3491. Info.pszMerAcquirerBIN = "0123456";
  3492. Info.pszMerTermID = "TermID";
  3493. Info.pszMerName = "Name";
  3494. Info.pszMerCity = "City";
  3495. Info.pszMerStateProvince = "StateProvince";
  3496. Info.pszMerPostalCode = "PostalCode";
  3497. Info.pszMerCountry = "Country/Region";
  3498. Info.pszMerPhone = "Phone";
  3499. Info.fMerPhoneRelease = TRUE;
  3500. Info.fMerAuthFlag = TRUE;
  3501. } else {
  3502. Info.pszMerID = "";
  3503. Info.pszMerAcquirerBIN = "";
  3504. Info.pszMerTermID = "";
  3505. Info.pszMerName = "";
  3506. Info.pszMerCity = "";
  3507. Info.pszMerStateProvince = "";
  3508. Info.pszMerPostalCode = "";
  3509. Info.pszMerCountry = "";
  3510. Info.pszMerPhone = "";
  3511. Info.fMerPhoneRelease = FALSE;
  3512. Info.fMerAuthFlag = FALSE;
  3513. }
  3514. if (!AllocAndEncodeObject(
  3515. X509_SET_MERCHANT_DATA,
  3516. &Info,
  3517. &pbEncoded,
  3518. &cbEncoded
  3519. ))
  3520. goto ErrorReturn;
  3521. fResult = TRUE;
  3522. goto CommonReturn;
  3523. ErrorReturn:
  3524. if (pbEncoded) {
  3525. TestFree(pbEncoded);
  3526. pbEncoded = NULL;
  3527. }
  3528. cbEncoded = 0;
  3529. fResult = FALSE;
  3530. CommonReturn:
  3531. *ppbEncoded = pbEncoded;
  3532. *pcbEncoded = cbEncoded;
  3533. return fResult;
  3534. }
  3535. static BOOL CreateSpcSpAgency(
  3536. DWORD dwCert,
  3537. DWORD dwLevel,
  3538. OUT BYTE **ppbEncoded,
  3539. IN OUT DWORD *pcbEncoded
  3540. )
  3541. {
  3542. BOOL fResult;
  3543. BYTE *pbEncoded = NULL;
  3544. DWORD cbEncoded;
  3545. SPC_LINK UrlLink;
  3546. SPC_LINK MonikerLink;
  3547. #define MONIKER_DATA "Moniker Serialized Data"
  3548. SPC_LINK FileLink;
  3549. SPC_IMAGE Image;
  3550. SPC_SP_AGENCY_INFO AgencyInfo;
  3551. #define BIT_MAP "Bit Map"
  3552. #define META_FILE "Metafile"
  3553. #define ENHANCED_META_FILE "Enhanced Metafile"
  3554. #define GIF_FILE "Gif File"
  3555. int i;
  3556. UrlLink.dwLinkChoice = SPC_URL_LINK_CHOICE;
  3557. UrlLink.pwszUrl = L"http://microsoft.com";
  3558. MonikerLink.dwLinkChoice = SPC_MONIKER_LINK_CHOICE;
  3559. for (i = 0; i < sizeof(MonikerLink.Moniker.ClassId); i++)
  3560. MonikerLink.Moniker.ClassId[i] = (BYTE) (i + 1);
  3561. MonikerLink.Moniker.SerializedData.cbData = strlen(MONIKER_DATA);
  3562. MonikerLink.Moniker.SerializedData.pbData = (BYTE *) MONIKER_DATA;
  3563. FileLink.dwLinkChoice = SPC_FILE_LINK_CHOICE;
  3564. FileLink.pwszFile = L"Unicode File Link";
  3565. memset(&Image, 0, sizeof(Image));
  3566. memset(&AgencyInfo, 0, sizeof(AgencyInfo));
  3567. AgencyInfo.pLogoImage = &Image;
  3568. if (dwLevel >= 1) {
  3569. AgencyInfo.pPolicyInformation = &UrlLink;
  3570. AgencyInfo.pwszPolicyDisplayText = L"MICROSOFT PRODUCTS POLICY";
  3571. AgencyInfo.pLogoImage = NULL;
  3572. }
  3573. if (dwLevel >= 2) {
  3574. AgencyInfo.pPolicyInformation = &UrlLink;
  3575. AgencyInfo.pwszPolicyDisplayText = L"Unicode String";
  3576. Image.Bitmap.cbData = strlen(BIT_MAP);
  3577. Image.Bitmap.pbData = (BYTE *) BIT_MAP;
  3578. }
  3579. if (dwLevel >= 3) {
  3580. AgencyInfo.pwszPolicyDisplayText = L"Policy Display Unicode String";
  3581. AgencyInfo.pLogoLink = &MonikerLink;
  3582. Image.pImageLink = &FileLink;
  3583. Image.Metafile.cbData = strlen(META_FILE);
  3584. Image.Metafile.pbData = (BYTE *) META_FILE;
  3585. Image.EnhancedMetafile.cbData = strlen(ENHANCED_META_FILE);
  3586. Image.EnhancedMetafile.pbData = (BYTE *) ENHANCED_META_FILE;
  3587. Image.GifFile.cbData = strlen(GIF_FILE);
  3588. Image.GifFile.pbData = (BYTE *) GIF_FILE;
  3589. }
  3590. if (!AllocAndEncodeObject(
  3591. SPC_SP_AGENCY_INFO_STRUCT,
  3592. &AgencyInfo,
  3593. &pbEncoded,
  3594. &cbEncoded
  3595. ))
  3596. goto ErrorReturn;
  3597. fResult = TRUE;
  3598. goto CommonReturn;
  3599. ErrorReturn:
  3600. if (pbEncoded) {
  3601. TestFree(pbEncoded);
  3602. pbEncoded = NULL;
  3603. }
  3604. cbEncoded = 0;
  3605. fResult = FALSE;
  3606. CommonReturn:
  3607. *ppbEncoded = pbEncoded;
  3608. *pcbEncoded = cbEncoded;
  3609. return fResult;
  3610. }
  3611. static BOOL CreateSpcCommonName(
  3612. DWORD dwCert,
  3613. OUT BYTE **ppbEncoded,
  3614. IN OUT DWORD *pcbEncoded
  3615. )
  3616. {
  3617. BOOL fResult;
  3618. BYTE *pbEncoded = NULL;
  3619. DWORD cbEncoded;
  3620. #define SPC_AGENCY_NAME L"Microsoft Code Signing Agency"
  3621. #define SPC_COM_NAME "Microsoft Software Products"
  3622. CERT_NAME_VALUE NameValue;
  3623. if (CertPara[dwCert].dwFlags & SPC_AGENCY_PARA_FLAG) {
  3624. NameValue.dwValueType = CERT_RDN_UNICODE_STRING;
  3625. NameValue.Value.pbData = (BYTE *) SPC_AGENCY_NAME;
  3626. NameValue.Value.cbData = wcslen(SPC_AGENCY_NAME) * sizeof(WCHAR);
  3627. } else if (CertPara[dwCert].dwFlags & SPC_COM_PARA_FLAG) {
  3628. NameValue.dwValueType = CERT_RDN_IA5_STRING;
  3629. NameValue.Value.pbData = (BYTE *) SPC_COM_NAME;
  3630. NameValue.Value.cbData = strlen(SPC_COM_NAME);
  3631. } else {
  3632. NameValue.dwValueType = CERT_RDN_PRINTABLE_STRING;
  3633. NameValue.Value.pbData = (BYTE *) CertPara[dwCert].pszName;
  3634. NameValue.Value.cbData = strlen(CertPara[dwCert].pszName);
  3635. }
  3636. if (!AllocAndEncodeObject(
  3637. X509_NAME_VALUE,
  3638. &NameValue,
  3639. &pbEncoded,
  3640. &cbEncoded
  3641. ))
  3642. goto ErrorReturn;
  3643. fResult = TRUE;
  3644. goto CommonReturn;
  3645. ErrorReturn:
  3646. if (pbEncoded) {
  3647. TestFree(pbEncoded);
  3648. pbEncoded = NULL;
  3649. }
  3650. cbEncoded = 0;
  3651. fResult = FALSE;
  3652. CommonReturn:
  3653. *ppbEncoded = pbEncoded;
  3654. *pcbEncoded = cbEncoded;
  3655. return fResult;
  3656. }
  3657. static BOOL CreateCRLReason(
  3658. OUT BYTE **ppbEncoded,
  3659. IN OUT DWORD *pcbEncoded
  3660. )
  3661. {
  3662. static int iReason = -1;
  3663. iReason += 1;
  3664. iReason = iReason % CRL_REASON_CERTIFICATE_HOLD;
  3665. return AllocAndEncodeObject(
  3666. X509_ENUMERATED,
  3667. (const void *) &iReason,
  3668. ppbEncoded,
  3669. pcbEncoded
  3670. );
  3671. }
  3672. static BOOL EncodeCert(DWORD dwCert, BYTE **ppbEncoded, DWORD *pcbEncoded)
  3673. {
  3674. BOOL fResult;
  3675. BYTE *pbSubjectEncoded = NULL;
  3676. DWORD cbSubjectEncoded;
  3677. BYTE *pbIssuerEncoded = NULL;
  3678. DWORD cbIssuerEncoded;
  3679. PCERT_PUBLIC_KEY_INFO pPubKeyInfo = NULL;
  3680. BYTE *pbCertEncoded = NULL;
  3681. DWORD cbCertEncoded;
  3682. BYTE *pbKeyIdEncoded = NULL;
  3683. DWORD cbKeyIdEncoded;
  3684. BYTE *pbKeyId2Encoded = NULL;
  3685. DWORD cbKeyId2Encoded;
  3686. BYTE *pbSubjectKeyIdEncoded = NULL;
  3687. DWORD cbSubjectKeyIdEncoded;
  3688. BYTE *pbAuthorityInfoAccessEncoded = NULL;
  3689. DWORD cbAuthorityInfoAccessEncoded;
  3690. BYTE *pbCrlDistPointsEncoded = NULL;
  3691. DWORD cbCrlDistPointsEncoded;
  3692. BYTE *pbKeyAttrEncoded = NULL;
  3693. DWORD cbKeyAttrEncoded;
  3694. BYTE *pbAltNameEncoded = NULL;
  3695. DWORD cbAltNameEncoded;
  3696. BYTE *pbIssuerAltNameEncoded = NULL;
  3697. DWORD cbIssuerAltNameEncoded;
  3698. BYTE *pbKeyUsageRestrictionEncoded = NULL;
  3699. DWORD cbKeyUsageRestrictionEncoded;
  3700. BYTE *pbBasicConstraintsEncoded = NULL;
  3701. DWORD cbBasicConstraintsEncoded;
  3702. BYTE *pbKeyUsageEncoded = NULL;
  3703. DWORD cbKeyUsageEncoded;
  3704. BYTE *pbBasicConstraints2Encoded = NULL;
  3705. DWORD cbBasicConstraints2Encoded;
  3706. BYTE *pbPoliciesEncoded = NULL;
  3707. DWORD cbPoliciesEncoded;
  3708. BYTE *pbSETAccountAliasEncoded = NULL;
  3709. DWORD cbSETAccountAliasEncoded;
  3710. BYTE *pbSETHashedRootKeyEncoded = NULL;
  3711. DWORD cbSETHashedRootKeyEncoded;
  3712. BYTE *pbSETCertificateTypeEncoded = NULL;
  3713. DWORD cbSETCertificateTypeEncoded;
  3714. BYTE *pbSETMerchantDataEncoded = NULL;
  3715. DWORD cbSETMerchantDataEncoded;
  3716. BYTE *pbSpcSpAgencyEncoded0 = NULL;
  3717. DWORD cbSpcSpAgencyEncoded0;
  3718. BYTE *pbSpcSpAgencyEncoded1 = NULL;
  3719. DWORD cbSpcSpAgencyEncoded1;
  3720. BYTE *pbSpcSpAgencyEncoded2 = NULL;
  3721. DWORD cbSpcSpAgencyEncoded2;
  3722. BYTE *pbSpcCommonNameEncoded = NULL;
  3723. DWORD cbSpcCommonNameEncoded;
  3724. BYTE *pbNetscapeCertType = NULL;
  3725. DWORD cbNetscapeCertType;
  3726. BYTE *pbNetscapeComment = NULL;
  3727. DWORD cbNetscapeComment;
  3728. BYTE *pbNetscapeBaseUrl = NULL;
  3729. DWORD cbNetscapeBaseUrl;
  3730. BYTE *pbNetscapeRevUrl = NULL;
  3731. DWORD cbNetscapeRevUrl;
  3732. BYTE *pbEnhancedKeyUsageEncoded = NULL;
  3733. DWORD cbEnhancedKeyUsageEncoded;
  3734. BYTE *pbSMIMECapabilitiesEncoded = NULL;
  3735. DWORD cbSMIMECapabilitiesEncoded;
  3736. BYTE *pbIDPEncoded = NULL;
  3737. DWORD cbIDPEncoded;
  3738. BYTE *pbNameConstraintsEncoded = NULL;
  3739. DWORD cbNameConstraintsEncoded;
  3740. BYTE *pbPolicyMappingsEncoded = NULL;
  3741. DWORD cbPolicyMappingsEncoded;
  3742. BYTE *pbPolicyConstraintsEncoded = NULL;
  3743. DWORD cbPolicyConstraintsEncoded;
  3744. BYTE *pbCrossCertDistPointsEncoded = NULL;
  3745. DWORD cbCrossCertDistPointsEncoded;
  3746. FILETIME SerialNumber;
  3747. CERT_RDN rgRDN[RDN_CNT];
  3748. CERT_RDN_ATTR rgAttr[ATTR_CNT];
  3749. CERT_NAME_INFO Name;
  3750. CERT_INFO Cert;
  3751. DWORD dwIssuer = CertPara[dwCert].dwIssuer;
  3752. DWORD dwCrlDistFlags;
  3753. #define CERT_EXTENSION_CNT 30
  3754. CERT_EXTENSION rgExt[CERT_EXTENSION_CNT];
  3755. // SUBJECT
  3756. CreateNameInfo(dwCert, &Name, rgRDN, rgAttr);
  3757. if (!AllocAndEncodeObject(
  3758. X509_NAME,
  3759. &Name,
  3760. &pbSubjectEncoded,
  3761. &cbSubjectEncoded
  3762. ))
  3763. goto ErrorReturn;
  3764. // ISSUER
  3765. CreateNameInfo(dwIssuer, &Name, rgRDN, rgAttr);
  3766. if (!AllocAndEncodeObject(
  3767. X509_NAME,
  3768. &Name,
  3769. &pbIssuerEncoded,
  3770. &cbIssuerEncoded
  3771. ))
  3772. goto ErrorReturn;
  3773. // PUBLIC KEY
  3774. if (!GetPublicKey(dwCert, &pPubKeyInfo)) goto ErrorReturn;
  3775. // CERT
  3776. memset(&Cert, 0, sizeof(Cert));
  3777. Cert.dwVersion = CERT_V3;
  3778. {
  3779. SYSTEMTIME SystemTime = TestTime;
  3780. if (CertPara[dwCert].dwFlags & DUPLICATE_PARA_FLAG)
  3781. // Use same serial number as previous certificate
  3782. SystemTime.wMilliseconds += (WORD) (dwCert - 1);
  3783. else
  3784. SystemTime.wMilliseconds += (WORD) dwCert;
  3785. MySystemTimeToFileTime(&SystemTime, &SerialNumber);
  3786. }
  3787. Cert.SerialNumber.pbData = (BYTE *) &SerialNumber;
  3788. Cert.SerialNumber.cbData = sizeof(SerialNumber);
  3789. if (CertPara[dwIssuer].dwFlags & DSS_PARA_FLAG)
  3790. Cert.SignatureAlgorithm.pszObjId = DSS_SIGNATURE_ALG_OBJID;
  3791. else
  3792. Cert.SignatureAlgorithm.pszObjId = SIGNATURE_ALG_OBJID;
  3793. Cert.Issuer.pbData = pbIssuerEncoded;
  3794. Cert.Issuer.cbData = cbIssuerEncoded;
  3795. {
  3796. SYSTEMTIME SystemTime = TestTime;
  3797. if (CertPara[dwCert].dwFlags & TIME_INVALID_PARA_FLAG) {
  3798. MySystemTimeToFileTime(&SystemTime, &Cert.NotAfter);
  3799. SystemTime.wYear--;
  3800. MySystemTimeToFileTime(&SystemTime, &Cert.NotBefore);
  3801. } else if (CertPara[dwCert].dwFlags & GENERALIZED_TIME_PARA_FLAG) {
  3802. SystemTime.wYear = 1920;
  3803. MySystemTimeToFileTime(&SystemTime, &Cert.NotBefore);
  3804. SystemTime.wYear = 2070;
  3805. if (CertPara[dwCert].dwFlags & CA_PARA_FLAG)
  3806. SystemTime.wHour = 1;
  3807. else
  3808. SystemTime.wHour = 0;
  3809. SystemTime.wMinute = 59 - (WORD) dwCert;
  3810. SystemTime.wSecond = 0;
  3811. MySystemTimeToFileTime(&SystemTime, &Cert.NotAfter);
  3812. } else if (0 == strcmp("ZeroNotAfter", CertPara[dwCert].pszName)) {
  3813. MySystemTimeToFileTime(&SystemTime, &Cert.NotBefore);
  3814. // NotAfter has already been zeroed
  3815. } else {
  3816. MySystemTimeToFileTime(&SystemTime, &Cert.NotBefore);
  3817. SystemTime.wYear++;
  3818. if (CertPara[dwCert].dwFlags & CA_PARA_FLAG)
  3819. SystemTime.wHour = 1;
  3820. else
  3821. SystemTime.wHour = 0;
  3822. if (dwCert < 60) {
  3823. SystemTime.wMinute = 59 - (WORD) dwCert;
  3824. SystemTime.wSecond = 0;
  3825. } else {
  3826. SystemTime.wMinute = 0;
  3827. SystemTime.wSecond = 0;
  3828. }
  3829. MySystemTimeToFileTime(&SystemTime, &Cert.NotAfter);
  3830. }
  3831. }
  3832. Cert.Subject.pbData = pbSubjectEncoded;
  3833. Cert.Subject.cbData = cbSubjectEncoded;
  3834. Cert.SubjectPublicKeyInfo = *pPubKeyInfo;
  3835. // Cert Extensions
  3836. if (!CreateAuthorityKeyId(
  3837. dwIssuer,
  3838. &pbKeyIdEncoded,
  3839. &cbKeyIdEncoded))
  3840. goto ErrorReturn;
  3841. if (!CreateAuthorityKeyId2(
  3842. dwCert,
  3843. dwIssuer,
  3844. &pbKeyId2Encoded,
  3845. &cbKeyId2Encoded))
  3846. goto ErrorReturn;
  3847. if (!CreateAuthorityInfoAccess(
  3848. dwCert,
  3849. &pbAuthorityInfoAccessEncoded,
  3850. &cbAuthorityInfoAccessEncoded))
  3851. goto ErrorReturn;
  3852. dwCrlDistFlags = 0;
  3853. if (CertPara[dwCert].dwFlags & DELTA_CRL_PARA_FLAG)
  3854. dwCrlDistFlags |= CRL_DIST_POINTS_DELTA_FLAG;
  3855. if (0 == strcmp(CertPara[dwCert].pszName, "UnsupportedCDP"))
  3856. dwCrlDistFlags |= CRL_DIST_POINTS_UNSUPPORTED_FLAG;
  3857. if (!CreateCrlDistPoints(
  3858. CertPara[dwCert].dwIssuer,
  3859. dwCrlDistFlags,
  3860. &pbCrlDistPointsEncoded,
  3861. &cbCrlDistPointsEncoded))
  3862. goto ErrorReturn;
  3863. if (!CreateKeyAttributes(
  3864. dwCert,
  3865. &pbKeyAttrEncoded,
  3866. &cbKeyAttrEncoded))
  3867. goto ErrorReturn;
  3868. if (!CreateAltName(
  3869. dwCert,
  3870. &pbAltNameEncoded,
  3871. &cbAltNameEncoded))
  3872. goto ErrorReturn;
  3873. if (!CreateKeyUsageRestriction(
  3874. dwCert,
  3875. &pbKeyUsageRestrictionEncoded,
  3876. &cbKeyUsageRestrictionEncoded))
  3877. goto ErrorReturn;
  3878. if (!CreateBasicConstraints(
  3879. dwCert,
  3880. &pbBasicConstraintsEncoded,
  3881. &cbBasicConstraintsEncoded))
  3882. goto ErrorReturn;
  3883. if (!CreateKeyUsage(
  3884. dwCert,
  3885. &pbKeyUsageEncoded,
  3886. &cbKeyUsageEncoded))
  3887. goto ErrorReturn;
  3888. if (!CreateBasicConstraints2(
  3889. dwCert,
  3890. &pbBasicConstraints2Encoded,
  3891. &cbBasicConstraints2Encoded))
  3892. goto ErrorReturn;
  3893. if (!CreatePolicies(
  3894. dwCert,
  3895. &pbPoliciesEncoded,
  3896. &cbPoliciesEncoded))
  3897. goto ErrorReturn;
  3898. if (CertPara[dwCert].dwFlags & SPC_AGENCY_INFO_PARA_FLAG) {
  3899. if (!CreateSpcSpAgency(
  3900. dwCert,
  3901. 0, // dwLevel
  3902. &pbSpcSpAgencyEncoded0,
  3903. &cbSpcSpAgencyEncoded0))
  3904. goto ErrorReturn;
  3905. if (!CreateSpcSpAgency(
  3906. dwCert,
  3907. 2, // dwLevel
  3908. &pbSpcSpAgencyEncoded1,
  3909. &cbSpcSpAgencyEncoded1))
  3910. goto ErrorReturn;
  3911. if (!CreateSpcSpAgency(
  3912. dwCert,
  3913. 3, // dwLevel
  3914. &pbSpcSpAgencyEncoded2,
  3915. &cbSpcSpAgencyEncoded2))
  3916. goto ErrorReturn;
  3917. } else if (CertPara[dwCert].dwFlags & SPC_EXT_PARA_FLAG) {
  3918. if (!CreateSpcSpAgency(
  3919. dwCert,
  3920. 1, // dwLevel
  3921. &pbSpcSpAgencyEncoded0,
  3922. &cbSpcSpAgencyEncoded0))
  3923. goto ErrorReturn;
  3924. if (!CreateSpcCommonName(
  3925. dwCert,
  3926. &pbSpcCommonNameEncoded,
  3927. &cbSpcCommonNameEncoded))
  3928. goto ErrorReturn;
  3929. } else {
  3930. if (!CreateSETAccountAlias(
  3931. dwCert,
  3932. &pbSETAccountAliasEncoded,
  3933. &cbSETAccountAliasEncoded))
  3934. goto ErrorReturn;
  3935. if (!CreateSETHashedRootKey(
  3936. dwCert,
  3937. &pbSETHashedRootKeyEncoded,
  3938. &cbSETHashedRootKeyEncoded))
  3939. goto ErrorReturn;
  3940. if (!CreateSETCertificateType(
  3941. dwCert,
  3942. &pbSETCertificateTypeEncoded,
  3943. &cbSETCertificateTypeEncoded))
  3944. goto ErrorReturn;
  3945. if (!CreateSETMerchantData(
  3946. dwCert,
  3947. &pbSETMerchantDataEncoded,
  3948. &cbSETMerchantDataEncoded))
  3949. goto ErrorReturn;
  3950. }
  3951. rgExt[0].pszObjId = szOID_AUTHORITY_KEY_IDENTIFIER;
  3952. rgExt[0].fCritical = FALSE;
  3953. rgExt[0].Value.pbData = pbKeyIdEncoded;
  3954. rgExt[0].Value.cbData = cbKeyIdEncoded;
  3955. rgExt[1].pszObjId = szOID_KEY_ATTRIBUTES;
  3956. rgExt[1].fCritical = FALSE;
  3957. rgExt[1].Value.pbData = pbKeyAttrEncoded;
  3958. rgExt[1].Value.cbData = cbKeyAttrEncoded;
  3959. rgExt[2].pszObjId = szOID_BASIC_CONSTRAINTS;
  3960. rgExt[2].fCritical = FALSE;
  3961. rgExt[2].Value.pbData = pbBasicConstraintsEncoded;
  3962. rgExt[2].Value.cbData = cbBasicConstraintsEncoded;
  3963. rgExt[3].pszObjId = szOID_KEY_USAGE_RESTRICTION;
  3964. rgExt[3].fCritical = FALSE;
  3965. rgExt[3].Value.pbData = pbKeyUsageRestrictionEncoded;
  3966. rgExt[3].Value.cbData = cbKeyUsageRestrictionEncoded;
  3967. rgExt[4].pszObjId = szOID_KEY_USAGE;
  3968. rgExt[4].fCritical = FALSE;
  3969. rgExt[4].Value.pbData = pbKeyUsageEncoded;
  3970. rgExt[4].Value.cbData = cbKeyUsageEncoded;
  3971. rgExt[5].pszObjId = szOID_BASIC_CONSTRAINTS2;
  3972. rgExt[5].fCritical = FALSE;
  3973. rgExt[5].Value.pbData = pbBasicConstraints2Encoded;
  3974. rgExt[5].Value.cbData = cbBasicConstraints2Encoded;
  3975. rgExt[6].pszObjId = szOID_CERT_POLICIES;
  3976. rgExt[6].fCritical = FALSE;
  3977. rgExt[6].Value.pbData = pbPoliciesEncoded;
  3978. rgExt[6].Value.cbData = cbPoliciesEncoded;
  3979. rgExt[7].pszObjId = szOID_SUBJECT_ALT_NAME;
  3980. rgExt[7].fCritical = FALSE;
  3981. if (0 == strcmp(CertPara[dwCert].pszName, "InvalidNCEnd_AV")) {
  3982. static BYTE rgbExt[] = {5,0};
  3983. rgExt[7].Value.pbData = rgbExt;
  3984. rgExt[7].Value.cbData = 0; // sizeof(rgbExt);
  3985. } else {
  3986. rgExt[7].Value.pbData = pbAltNameEncoded;
  3987. rgExt[7].Value.cbData = cbAltNameEncoded;
  3988. }
  3989. if (CertPara[dwCert].dwFlags & NO_EXT_PARA_FLAG)
  3990. Cert.cExtension = 0;
  3991. else if (CertPara[dwCert].dwFlags & VALID_PARA_FLAG)
  3992. Cert.cExtension = 6;
  3993. else if (CertPara[dwCert].dwFlags & SPC_AGENCY_INFO_PARA_FLAG) {
  3994. rgExt[8].pszObjId = SPC_SP_AGENCY_INFO_OBJID;
  3995. rgExt[8].fCritical = TRUE;
  3996. rgExt[8].Value.pbData = pbSpcSpAgencyEncoded2;
  3997. rgExt[8].Value.cbData = cbSpcSpAgencyEncoded2;
  3998. rgExt[9].pszObjId = SPC_SP_AGENCY_INFO_OBJID;
  3999. rgExt[9].fCritical = FALSE;
  4000. rgExt[9].Value.pbData = pbSpcSpAgencyEncoded0;
  4001. rgExt[9].Value.cbData = cbSpcSpAgencyEncoded0;
  4002. rgExt[10].pszObjId = SPC_SP_AGENCY_INFO_OBJID;
  4003. rgExt[10].fCritical = FALSE;
  4004. rgExt[10].Value.pbData = pbSpcSpAgencyEncoded1;
  4005. rgExt[10].Value.cbData = cbSpcSpAgencyEncoded1;
  4006. Cert.cExtension = 11;
  4007. } else if (CertPara[dwCert].dwFlags & SPC_EXT_PARA_FLAG) {
  4008. rgExt[8].pszObjId = SPC_SP_AGENCY_INFO_OBJID;
  4009. rgExt[8].fCritical = FALSE;
  4010. rgExt[8].Value.pbData = pbSpcSpAgencyEncoded0;
  4011. rgExt[8].Value.cbData = cbSpcSpAgencyEncoded0;
  4012. if (CertPara[dwCert].dwFlags &
  4013. (SPC_AGENCY_PARA_FLAG | SPC_COM_PARA_FLAG)) {
  4014. rgExt[9].pszObjId = SPC_COMMON_NAME_OBJID;
  4015. rgExt[9].fCritical = FALSE;
  4016. rgExt[9].Value.pbData = pbSpcCommonNameEncoded;
  4017. rgExt[9].Value.cbData = cbSpcCommonNameEncoded;
  4018. Cert.cExtension = 10;
  4019. } else
  4020. Cert.cExtension = 9;
  4021. } else if (CertPara[dwCert].dwFlags & NETSCAPE_PARA_FLAG) {
  4022. BYTE bCertType;
  4023. CRYPT_BIT_BLOB BitBlob;
  4024. CERT_NAME_VALUE Comment;
  4025. CERT_NAME_VALUE RevUrl;
  4026. CERT_NAME_VALUE BaseUrl;
  4027. BitBlob.pbData = &bCertType;
  4028. BitBlob.cbData = 1;
  4029. BitBlob.cUnusedBits = 2;
  4030. if (CertPara[dwCert].dwFlags & CA_PARA_FLAG)
  4031. bCertType = NETSCAPE_SSL_CA_CERT_TYPE;
  4032. else
  4033. bCertType = NETSCAPE_SSL_CLIENT_AUTH_CERT_TYPE;
  4034. if (!AllocAndEncodeObject(
  4035. X509_BITS,
  4036. &BitBlob,
  4037. &pbNetscapeCertType,
  4038. &cbNetscapeCertType))
  4039. goto ErrorReturn;
  4040. rgExt[8].pszObjId = szOID_NETSCAPE_CERT_TYPE;
  4041. rgExt[8].fCritical = FALSE;
  4042. rgExt[8].Value.pbData = pbNetscapeCertType;
  4043. rgExt[8].Value.cbData = cbNetscapeCertType;
  4044. memset(&Comment, 0, sizeof(Comment));
  4045. Comment.dwValueType = CERT_RDN_IA5_STRING;
  4046. Comment.Value.pbData = (BYTE *) L"This is an IA5 Netscape Comment";
  4047. if (!AllocAndEncodeObject(
  4048. X509_UNICODE_ANY_STRING,
  4049. &Comment,
  4050. &pbNetscapeComment,
  4051. &cbNetscapeComment))
  4052. goto ErrorReturn;
  4053. rgExt[9].pszObjId = szOID_NETSCAPE_COMMENT;
  4054. rgExt[9].fCritical = FALSE;
  4055. rgExt[9].Value.pbData = pbNetscapeComment;
  4056. rgExt[9].Value.cbData = cbNetscapeComment;
  4057. memset(&BaseUrl, 0, sizeof(BaseUrl));
  4058. BaseUrl.dwValueType = CERT_RDN_IA5_STRING;
  4059. #if 0
  4060. BaseUrl.Value.pbData = (BYTE *) L"http://status.verisign.com/";
  4061. #else
  4062. BaseUrl.Value.pbData = (BYTE *) L"https://www.netscape.com/";
  4063. #endif
  4064. if (!AllocAndEncodeObject(
  4065. X509_UNICODE_ANY_STRING,
  4066. &BaseUrl,
  4067. &pbNetscapeBaseUrl,
  4068. &cbNetscapeBaseUrl))
  4069. goto ErrorReturn;
  4070. rgExt[10].pszObjId = szOID_NETSCAPE_BASE_URL;
  4071. rgExt[10].fCritical = FALSE;
  4072. rgExt[10].Value.pbData = pbNetscapeBaseUrl;
  4073. rgExt[10].Value.cbData = cbNetscapeBaseUrl;
  4074. memset(&RevUrl, 0, sizeof(RevUrl));
  4075. RevUrl.dwValueType = CERT_RDN_IA5_STRING;
  4076. #if 0
  4077. RevUrl.Value.pbData = (BYTE *) L"status/check/ver/1/ID/";
  4078. #else
  4079. RevUrl.Value.pbData = (BYTE *) L"cgi-bin/check-rev.cgi?";
  4080. #endif
  4081. if (!AllocAndEncodeObject(
  4082. X509_UNICODE_ANY_STRING,
  4083. &RevUrl,
  4084. &pbNetscapeRevUrl,
  4085. &cbNetscapeRevUrl))
  4086. goto ErrorReturn;
  4087. if (CertPara[dwCert].dwFlags & CA_PARA_FLAG)
  4088. rgExt[11].pszObjId = szOID_NETSCAPE_CA_REVOCATION_URL;
  4089. else
  4090. rgExt[11].pszObjId = szOID_NETSCAPE_REVOCATION_URL;
  4091. rgExt[11].fCritical = FALSE;
  4092. rgExt[11].Value.pbData = pbNetscapeRevUrl;
  4093. rgExt[11].Value.cbData = cbNetscapeRevUrl;
  4094. Cert.cExtension = 12;
  4095. } else if (CertPara[dwCert].dwFlags & SET_PARA_FLAG) {
  4096. rgExt[8].pszObjId = szOID_SET_ACCOUNT_ALIAS;
  4097. rgExt[8].fCritical = FALSE;
  4098. rgExt[8].Value.pbData = pbSETAccountAliasEncoded;
  4099. rgExt[8].Value.cbData = cbSETAccountAliasEncoded;
  4100. rgExt[9].pszObjId = szOID_SET_HASHED_ROOT_KEY;
  4101. rgExt[9].fCritical = FALSE;
  4102. rgExt[9].Value.pbData = pbSETHashedRootKeyEncoded;
  4103. rgExt[9].Value.cbData = cbSETHashedRootKeyEncoded;
  4104. rgExt[10].pszObjId = szOID_SET_CERTIFICATE_TYPE;
  4105. rgExt[10].fCritical = FALSE;
  4106. rgExt[10].Value.pbData = pbSETCertificateTypeEncoded;
  4107. rgExt[10].Value.cbData = cbSETCertificateTypeEncoded;
  4108. rgExt[11].pszObjId = szOID_SET_MERCHANT_DATA;
  4109. rgExt[11].fCritical = FALSE;
  4110. rgExt[11].Value.pbData = pbSETMerchantDataEncoded;
  4111. rgExt[11].Value.cbData = cbSETMerchantDataEncoded;
  4112. Cert.cExtension = 12;
  4113. } else {
  4114. Cert.cExtension = 8;
  4115. }
  4116. if ((CertPara[dwCert].dwFlags & DELTA_CRL_PARA_FLAG) ||
  4117. (0 == (CertPara[dwCert].dwFlags &
  4118. (NO_EXT_PARA_FLAG | VALID_PARA_FLAG)))) {
  4119. DWORD cExt = Cert.cExtension;
  4120. if (0 == (CertPara[CertPara[dwCert].dwIssuer].dwFlags &
  4121. NO_CRL_EXT_PARA_FLAG)) {
  4122. if (0 != strncmp(CertPara[dwCert].pszName, "NoCDP", 5)) {
  4123. rgExt[cExt].pszObjId = szOID_CRL_DIST_POINTS;
  4124. rgExt[cExt].fCritical = FALSE;
  4125. rgExt[cExt].Value.pbData = pbCrlDistPointsEncoded;
  4126. rgExt[cExt].Value.cbData = cbCrlDistPointsEncoded;
  4127. cExt++;
  4128. }
  4129. }
  4130. if (0 == strcmp(CertPara[dwCert].pszName, "DeltaEndValid")) {
  4131. rgExt[cExt].pszObjId = szOID_FRESHEST_CRL;
  4132. rgExt[cExt].fCritical = FALSE;
  4133. rgExt[cExt].Value.pbData = pbCrlDistPointsEncoded;
  4134. rgExt[cExt].Value.cbData = cbCrlDistPointsEncoded;
  4135. cExt++;
  4136. }
  4137. Cert.cExtension = cExt;
  4138. }
  4139. if (0 == strcmp(CertPara[dwCert].pszName, "DssCA") ||
  4140. 0 == strcmp(CertPara[dwCert].pszName, "DssEnd")) {
  4141. DWORD cExt = Cert.cExtension;
  4142. PCTL_USAGE pCtlUsage;
  4143. rgExt[cExt].pszObjId = szOID_CERT_POLICIES;
  4144. rgExt[cExt].fCritical = FALSE;
  4145. rgExt[cExt].Value.pbData = pbPoliciesEncoded;
  4146. rgExt[cExt].Value.cbData = cbPoliciesEncoded;
  4147. cExt++;
  4148. if (0 == strcmp(CertPara[dwCert].pszName, "DssCA"))
  4149. pCtlUsage = &rgCtlUsage[0];
  4150. else
  4151. pCtlUsage = &rgCtlUsage[2];
  4152. if (!AllocAndEncodeObject(
  4153. X509_ENHANCED_KEY_USAGE,
  4154. (const void *) pCtlUsage,
  4155. &pbEnhancedKeyUsageEncoded,
  4156. &cbEnhancedKeyUsageEncoded))
  4157. goto ErrorReturn;
  4158. rgExt[cExt].pszObjId = szOID_ENHANCED_KEY_USAGE;
  4159. rgExt[cExt].fCritical = FALSE;
  4160. rgExt[cExt].Value.pbData = pbEnhancedKeyUsageEncoded;
  4161. rgExt[cExt].Value.cbData = cbEnhancedKeyUsageEncoded;
  4162. cExt++;
  4163. Cert.cExtension = cExt;
  4164. } else if (0 == strcmp("TestAIAEnd", CertPara[dwCert].pszName)) {
  4165. DWORD cExt = Cert.cExtension;
  4166. rgExt[cExt].pszObjId = szOID_AUTHORITY_INFO_ACCESS;
  4167. rgExt[cExt].fCritical = FALSE;
  4168. rgExt[cExt].Value.pbData = pbAuthorityInfoAccessEncoded;
  4169. rgExt[cExt].Value.cbData = cbAuthorityInfoAccessEncoded;
  4170. cExt++;
  4171. Cert.cExtension = cExt;
  4172. } else if (0 == strcmp(CertPara[dwCert].pszName, "RolloverRoot") ||
  4173. 0 == (CertPara[dwCert].dwFlags &
  4174. (NO_EXT_PARA_FLAG | VALID_PARA_FLAG))) {
  4175. DWORD cExt = Cert.cExtension;
  4176. rgExt[cExt].pszObjId = szOID_AUTHORITY_KEY_IDENTIFIER2;
  4177. rgExt[cExt].fCritical = FALSE;
  4178. rgExt[cExt].Value.pbData = pbKeyId2Encoded;
  4179. rgExt[cExt].Value.cbData = cbKeyId2Encoded;
  4180. cExt++;
  4181. if (0 != strcmp(CertPara[dwCert].pszName, "RolloverRoot")) {
  4182. rgExt[cExt].pszObjId = szOID_AUTHORITY_INFO_ACCESS;
  4183. rgExt[cExt].fCritical = FALSE;
  4184. rgExt[cExt].Value.pbData = pbAuthorityInfoAccessEncoded;
  4185. rgExt[cExt].Value.cbData = cbAuthorityInfoAccessEncoded;
  4186. cExt++;
  4187. }
  4188. #if 1
  4189. if (TRUE) {
  4190. #else
  4191. if (CertPara[dwCert].dwFlags & CA_PARA_FLAG) {
  4192. #endif
  4193. if (!CreateKeyId(
  4194. dwCert,
  4195. &pbSubjectKeyIdEncoded,
  4196. &cbSubjectKeyIdEncoded))
  4197. goto ErrorReturn;
  4198. rgExt[cExt].pszObjId = szOID_SUBJECT_KEY_IDENTIFIER;
  4199. rgExt[cExt].fCritical = FALSE;
  4200. rgExt[cExt].Value.pbData = pbSubjectKeyIdEncoded;
  4201. rgExt[cExt].Value.cbData = cbSubjectKeyIdEncoded;
  4202. cExt++;
  4203. }
  4204. if (CertPara[dwCert].dwFlags & (USE1_PARA_FLAG | USE2_PARA_FLAG)) {
  4205. if (!CreateEnhancedKeyUsage(
  4206. CertPara[dwCert].dwFlags,
  4207. &pbEnhancedKeyUsageEncoded,
  4208. &cbEnhancedKeyUsageEncoded))
  4209. goto ErrorReturn;
  4210. rgExt[cExt].pszObjId = szOID_ENHANCED_KEY_USAGE;
  4211. rgExt[cExt].fCritical = FALSE;
  4212. rgExt[cExt].Value.pbData = pbEnhancedKeyUsageEncoded;
  4213. rgExt[cExt].Value.cbData = cbEnhancedKeyUsageEncoded;
  4214. cExt++;
  4215. }
  4216. Cert.cExtension = cExt;
  4217. } else if (0 == strcmp(CertPara[dwCert].pszName, "RolloverCA")) {
  4218. DWORD cExt = Cert.cExtension;
  4219. rgExt[cExt].pszObjId = szOID_AUTHORITY_INFO_ACCESS;
  4220. rgExt[cExt].fCritical = FALSE;
  4221. rgExt[cExt].Value.pbData = pbAuthorityInfoAccessEncoded;
  4222. rgExt[cExt].Value.cbData = cbAuthorityInfoAccessEncoded;
  4223. cExt++;
  4224. Cert.cExtension = cExt;
  4225. }
  4226. if (dwCert == POLICY_ROOT || dwCert == POLICY_CA) {
  4227. // 0 - Root
  4228. // 1 - CA
  4229. DWORD cExt = Cert.cExtension;
  4230. if (!CreatePolicyMappings(
  4231. dwCert,
  4232. &pbPolicyMappingsEncoded,
  4233. &cbPolicyMappingsEncoded))
  4234. goto ErrorReturn;
  4235. rgExt[cExt].pszObjId = szOID_POLICY_MAPPINGS;
  4236. rgExt[cExt].fCritical = FALSE;
  4237. rgExt[cExt].Value.pbData = pbPolicyMappingsEncoded;
  4238. rgExt[cExt].Value.cbData = cbPolicyMappingsEncoded;
  4239. cExt++;
  4240. if (!CreatePolicyConstraints(
  4241. dwCert,
  4242. &pbPolicyConstraintsEncoded,
  4243. &cbPolicyConstraintsEncoded))
  4244. goto ErrorReturn;
  4245. rgExt[cExt].pszObjId = szOID_POLICY_CONSTRAINTS;
  4246. rgExt[cExt].fCritical = FALSE;
  4247. rgExt[cExt].Value.pbData = pbPolicyConstraintsEncoded;
  4248. rgExt[cExt].Value.cbData = cbPolicyConstraintsEncoded;
  4249. cExt++;
  4250. if (!CreateNameConstraints(
  4251. dwCert,
  4252. &pbNameConstraintsEncoded,
  4253. &cbNameConstraintsEncoded))
  4254. goto ErrorReturn;
  4255. rgExt[cExt].pszObjId = szOID_NAME_CONSTRAINTS;
  4256. rgExt[cExt].fCritical = FALSE;
  4257. rgExt[cExt].Value.pbData = pbNameConstraintsEncoded;
  4258. rgExt[cExt].Value.cbData = cbNameConstraintsEncoded;
  4259. cExt++;
  4260. Cert.cExtension = cExt;
  4261. } else if (dwCert == ROLLOVER_CROSS_CERT) {
  4262. DWORD cExt = Cert.cExtension;
  4263. if (!CreatePolicyConstraints(
  4264. dwCert,
  4265. &pbPolicyConstraintsEncoded,
  4266. &cbPolicyConstraintsEncoded))
  4267. goto ErrorReturn;
  4268. rgExt[cExt].pszObjId = szOID_POLICY_CONSTRAINTS;
  4269. rgExt[cExt].fCritical = FALSE;
  4270. rgExt[cExt].Value.pbData = pbPolicyConstraintsEncoded;
  4271. rgExt[cExt].Value.cbData = cbPolicyConstraintsEncoded;
  4272. cExt++;
  4273. Cert.cExtension = cExt;
  4274. } else if (0 == strcmp(CertPara[dwCert].pszName, "MissingNCCA")) {
  4275. DWORD cExt = Cert.cExtension;
  4276. if (!CreateNameConstraints(
  4277. dwCert,
  4278. &pbNameConstraintsEncoded,
  4279. &cbNameConstraintsEncoded))
  4280. goto ErrorReturn;
  4281. rgExt[cExt].pszObjId = szOID_NAME_CONSTRAINTS;
  4282. rgExt[cExt].fCritical = FALSE;
  4283. rgExt[cExt].Value.pbData = pbNameConstraintsEncoded;
  4284. rgExt[cExt].Value.cbData = cbNameConstraintsEncoded;
  4285. cExt++;
  4286. Cert.cExtension = cExt;
  4287. } else if (0 == strcmp(CertPara[dwCert].pszName, "InvalidNCCA_AV")) {
  4288. DWORD cExt = Cert.cExtension;
  4289. static BYTE rgbExt[] = {5,0};
  4290. rgExt[cExt].pszObjId = szOID_NAME_CONSTRAINTS;
  4291. rgExt[cExt].fCritical = FALSE;
  4292. rgExt[cExt].Value.pbData = rgbExt;
  4293. rgExt[cExt].Value.cbData = 0; // sizeof(rgbExt);
  4294. cExt++;
  4295. Cert.cExtension = cExt;
  4296. } else if (CertPara[dwCert].dwFlags & ALL_EXT_PARA_FLAG) {
  4297. DWORD cExt = Cert.cExtension;
  4298. if (!CreateSMIMECapabilities(
  4299. dwCert,
  4300. &pbSMIMECapabilitiesEncoded,
  4301. &cbSMIMECapabilitiesEncoded))
  4302. goto ErrorReturn;
  4303. rgExt[cExt].pszObjId = szOID_RSA_SMIMECapabilities;
  4304. rgExt[cExt].fCritical = FALSE;
  4305. rgExt[cExt].Value.pbData = pbSMIMECapabilitiesEncoded;
  4306. rgExt[cExt].Value.cbData = cbSMIMECapabilitiesEncoded;
  4307. cExt++;
  4308. if (!CreateCertIssuingDistPoint(
  4309. dwCert,
  4310. &pbIDPEncoded,
  4311. &cbIDPEncoded))
  4312. goto ErrorReturn;
  4313. rgExt[cExt].pszObjId = szOID_ISSUING_DIST_POINT;
  4314. rgExt[cExt].fCritical = FALSE;
  4315. rgExt[cExt].Value.pbData = pbIDPEncoded;
  4316. rgExt[cExt].Value.cbData = cbIDPEncoded;
  4317. cExt++;
  4318. if (!CreateCrossCertDistPoints(
  4319. dwCert,
  4320. &pbCrossCertDistPointsEncoded,
  4321. &cbCrossCertDistPointsEncoded))
  4322. goto ErrorReturn;
  4323. rgExt[cExt].pszObjId = szOID_CROSS_CERT_DIST_POINTS;
  4324. rgExt[cExt].fCritical = FALSE;
  4325. rgExt[cExt].Value.pbData = pbCrossCertDistPointsEncoded;
  4326. rgExt[cExt].Value.cbData = cbCrossCertDistPointsEncoded;
  4327. cExt++;
  4328. Cert.cExtension = cExt;
  4329. }
  4330. if (CertPara[dwCert].dwFlags & ALT_DIR_NAME_PARA_FLAG) {
  4331. DWORD cExt = Cert.cExtension;
  4332. if (!CreateAltName(
  4333. dwIssuer,
  4334. &pbIssuerAltNameEncoded,
  4335. &cbIssuerAltNameEncoded))
  4336. goto ErrorReturn;
  4337. rgExt[cExt].pszObjId = szOID_ISSUER_ALT_NAME2;
  4338. rgExt[cExt].fCritical = FALSE;
  4339. rgExt[cExt].Value.pbData = pbIssuerAltNameEncoded;
  4340. rgExt[cExt].Value.cbData = cbIssuerAltNameEncoded;
  4341. cExt++;
  4342. Cert.cExtension = cExt;
  4343. }
  4344. if (CertPara[dwCert].pszManifold) {
  4345. DWORD cExt = Cert.cExtension;
  4346. rgExt[cExt].pszObjId = szOID_CERT_MANIFOLD;
  4347. rgExt[cExt].fCritical = FALSE;
  4348. rgExt[cExt].Value.pbData = (BYTE *) CertPara[dwCert].pszManifold;
  4349. rgExt[cExt].Value.cbData = strlen(CertPara[dwCert].pszManifold);
  4350. cExt++;
  4351. Cert.cExtension = cExt;
  4352. }
  4353. if (0 == strcmp("V1", CertPara[dwCert].pszName)) {
  4354. Cert.dwVersion = CERT_V1;
  4355. Cert.cExtension = 0;
  4356. } else if (0 == strcmp("V2", CertPara[dwCert].pszName)) {
  4357. Cert.dwVersion = CERT_V2;
  4358. Cert.cExtension = 0;
  4359. #define ISSUER_UNIQUE_ID "Issuer Unique Id"
  4360. #define SUBJECT_UNIQUE_ID "Subject Unique Id"
  4361. Cert.IssuerUniqueId.pbData = (BYTE *) ISSUER_UNIQUE_ID;
  4362. Cert.IssuerUniqueId.cbData = strlen(ISSUER_UNIQUE_ID);
  4363. Cert.IssuerUniqueId.cUnusedBits = 0;
  4364. Cert.SubjectUniqueId.pbData = (BYTE *) SUBJECT_UNIQUE_ID;
  4365. Cert.SubjectUniqueId.cbData = strlen(SUBJECT_UNIQUE_ID);
  4366. Cert.SubjectUniqueId.cUnusedBits = 0;
  4367. }
  4368. Cert.rgExtension = rgExt;
  4369. if (!AllocAndEncodeObject(
  4370. X509_CERT_TO_BE_SIGNED,
  4371. &Cert,
  4372. &pbCertEncoded,
  4373. &cbCertEncoded))
  4374. goto ErrorReturn;
  4375. if (!EncodeSignedContent(
  4376. dwIssuer,
  4377. pbCertEncoded,
  4378. cbCertEncoded,
  4379. ppbEncoded,
  4380. pcbEncoded))
  4381. goto ErrorReturn;
  4382. fResult = TRUE;
  4383. goto CommonReturn;
  4384. ErrorReturn:
  4385. *ppbEncoded = NULL;
  4386. *pcbEncoded = 0;
  4387. fResult = FALSE;
  4388. CommonReturn:
  4389. if (pbKeyIdEncoded)
  4390. TestFree(pbKeyIdEncoded);
  4391. if (pbKeyId2Encoded)
  4392. TestFree(pbKeyId2Encoded);
  4393. if (pbSubjectKeyIdEncoded)
  4394. TestFree(pbSubjectKeyIdEncoded);
  4395. if (pbAuthorityInfoAccessEncoded)
  4396. TestFree(pbAuthorityInfoAccessEncoded);
  4397. if (pbCrlDistPointsEncoded)
  4398. TestFree(pbCrlDistPointsEncoded);
  4399. if (pbKeyAttrEncoded)
  4400. TestFree(pbKeyAttrEncoded);
  4401. if (pbAltNameEncoded)
  4402. TestFree(pbAltNameEncoded);
  4403. if (pbIssuerAltNameEncoded)
  4404. TestFree(pbIssuerAltNameEncoded);
  4405. if (pbKeyUsageRestrictionEncoded)
  4406. TestFree(pbKeyUsageRestrictionEncoded);
  4407. if (pbBasicConstraintsEncoded)
  4408. TestFree(pbBasicConstraintsEncoded);
  4409. if (pbKeyUsageEncoded)
  4410. TestFree(pbKeyUsageEncoded);
  4411. if (pbBasicConstraints2Encoded)
  4412. TestFree(pbBasicConstraints2Encoded);
  4413. if (pbPoliciesEncoded)
  4414. TestFree(pbPoliciesEncoded);
  4415. if (pbSETAccountAliasEncoded)
  4416. TestFree(pbSETAccountAliasEncoded);
  4417. if (pbSETHashedRootKeyEncoded)
  4418. TestFree(pbSETHashedRootKeyEncoded);
  4419. if (pbSETCertificateTypeEncoded)
  4420. TestFree(pbSETCertificateTypeEncoded);
  4421. if (pbSETMerchantDataEncoded)
  4422. TestFree(pbSETMerchantDataEncoded);
  4423. if (pbSpcSpAgencyEncoded0)
  4424. TestFree(pbSpcSpAgencyEncoded0);
  4425. if (pbSpcSpAgencyEncoded1)
  4426. TestFree(pbSpcSpAgencyEncoded1);
  4427. if (pbSpcSpAgencyEncoded2)
  4428. TestFree(pbSpcSpAgencyEncoded2);
  4429. if (pbSpcCommonNameEncoded)
  4430. TestFree(pbSpcCommonNameEncoded);
  4431. if (pbNetscapeCertType)
  4432. TestFree(pbNetscapeCertType);
  4433. if (pbNetscapeComment)
  4434. TestFree(pbNetscapeComment);
  4435. if (pbNetscapeRevUrl)
  4436. TestFree(pbNetscapeRevUrl);
  4437. if (pbNetscapeBaseUrl)
  4438. TestFree(pbNetscapeBaseUrl);
  4439. if (pbSubjectEncoded)
  4440. TestFree(pbSubjectEncoded);
  4441. if (pbIssuerEncoded)
  4442. TestFree(pbIssuerEncoded);
  4443. if (pPubKeyInfo)
  4444. TestFree(pPubKeyInfo);
  4445. if (pbCertEncoded)
  4446. TestFree(pbCertEncoded);
  4447. if (pbEnhancedKeyUsageEncoded)
  4448. TestFree(pbEnhancedKeyUsageEncoded);
  4449. if (pbSMIMECapabilitiesEncoded)
  4450. TestFree(pbSMIMECapabilitiesEncoded);
  4451. if (pbIDPEncoded)
  4452. TestFree(pbIDPEncoded);
  4453. if (pbNameConstraintsEncoded)
  4454. TestFree(pbNameConstraintsEncoded);
  4455. if (pbPolicyMappingsEncoded)
  4456. TestFree(pbPolicyMappingsEncoded);
  4457. if (pbPolicyConstraintsEncoded)
  4458. TestFree(pbPolicyConstraintsEncoded);
  4459. if (pbCrossCertDistPointsEncoded)
  4460. TestFree(pbCrossCertDistPointsEncoded);
  4461. return fResult;
  4462. }
  4463. static BOOL EncodeCrl(
  4464. DWORD dwCert,
  4465. BYTE **ppbEncoded,
  4466. DWORD *pcbEncoded,
  4467. DWORD dwAki
  4468. )
  4469. {
  4470. BOOL fResult;
  4471. BYTE *pbIssuerEncoded = NULL;
  4472. DWORD cbIssuerEncoded;
  4473. BYTE *pbCrlEncoded = NULL;
  4474. DWORD cbCrlEncoded;
  4475. BYTE *pbKeyId2Encoded = NULL;
  4476. DWORD cbKeyId2Encoded;
  4477. BYTE *pbIDPEncoded = NULL;
  4478. DWORD cbIDPEncoded;
  4479. DWORD i;
  4480. CERT_RDN rgRDN[RDN_CNT];
  4481. CERT_RDN_ATTR rgAttr[ATTR_CNT];
  4482. CERT_NAME_INFO Name;
  4483. CRL_ENTRY rgEntry[CERT_CNT];
  4484. CRL_INFO Crl;
  4485. FILETIME SerialNumber[CERT_CNT];
  4486. #define CRL_EXTENSION_CNT 2
  4487. CERT_EXTENSION rgExt[CRL_EXTENSION_CNT];
  4488. // Max of 1 extension per entry
  4489. CERT_EXTENSION rgEntryExt[CERT_CNT];
  4490. memset(rgEntryExt, 0, sizeof(rgEntryExt));
  4491. // ISSUER
  4492. CreateNameInfo(dwCert, &Name, rgRDN, rgAttr);
  4493. if (!AllocAndEncodeObject(
  4494. X509_NAME,
  4495. &Name,
  4496. &pbIssuerEncoded,
  4497. &cbIssuerEncoded
  4498. ))
  4499. goto ErrorReturn;
  4500. // CRL
  4501. memset(&Crl, 0, sizeof(Crl));
  4502. Crl.dwVersion = CRL_V2;
  4503. if (CertPara[dwCert].dwFlags & DSS_PARA_FLAG)
  4504. Crl.SignatureAlgorithm.pszObjId = DSS_SIGNATURE_ALG_OBJID;
  4505. else
  4506. Crl.SignatureAlgorithm.pszObjId = SIGNATURE_ALG_OBJID;
  4507. Crl.Issuer.pbData = pbIssuerEncoded;
  4508. Crl.Issuer.cbData = cbIssuerEncoded;
  4509. {
  4510. SYSTEMTIME SystemTime = TestTime;
  4511. if (CertPara[dwCert].dwFlags & GENERALIZED_TIME_PARA_FLAG) {
  4512. SystemTime.wYear = 1921;
  4513. MySystemTimeToFileTime(&SystemTime, &Crl.ThisUpdate);
  4514. SystemTime.wYear = 2071;
  4515. MySystemTimeToFileTime(&SystemTime, &Crl.NextUpdate);
  4516. } else {
  4517. MySystemTimeToFileTime(&SystemTime, &Crl.ThisUpdate);
  4518. if (0 == (CertPara[dwCert].dwFlags & NO_CRL_EXT_PARA_FLAG)) {
  4519. SystemTime.wYear++;
  4520. MySystemTimeToFileTime(&SystemTime, &Crl.NextUpdate);
  4521. }
  4522. }
  4523. }
  4524. Crl.cCRLEntry = 0;
  4525. Crl.rgCRLEntry = rgEntry;
  4526. for (i = 0; i < CERT_CNT; i++) {
  4527. if (CertPara[i].dwIssuer == dwCert &&
  4528. (CertPara[i].dwFlags & REVOKED_PARA_FLAG)) {
  4529. DWORD j;
  4530. SYSTEMTIME SystemTime = TestTime;
  4531. j = Crl.cCRLEntry++;
  4532. memset(&rgEntry[j], 0, sizeof(rgEntry[j]));
  4533. SystemTime.wMilliseconds += (WORD) i;
  4534. MySystemTimeToFileTime(&SystemTime, &SerialNumber[j]);
  4535. rgEntry[j].SerialNumber.pbData = (BYTE *) &SerialNumber[j];
  4536. rgEntry[j].SerialNumber.cbData = sizeof(SerialNumber[j]);
  4537. if (CertPara[dwCert].dwFlags & GENERALIZED_TIME_PARA_FLAG) {
  4538. SystemTime.wYear = 1922;
  4539. MySystemTimeToFileTime(&SystemTime, &rgEntry[j].RevocationDate);
  4540. } else
  4541. MySystemTimeToFileTime(&SystemTime, &rgEntry[j].RevocationDate);
  4542. if (0 == (CertPara[dwCert].dwFlags & NO_CRL_EXT_PARA_FLAG)) {
  4543. if (!CreateCRLReason(
  4544. &rgEntryExt[j].Value.pbData,
  4545. &rgEntryExt[j].Value.cbData))
  4546. goto ErrorReturn;
  4547. rgEntryExt[j].pszObjId = szOID_CRL_REASON_CODE;
  4548. rgEntryExt[j].fCritical = FALSE;
  4549. rgEntry[j].cExtension = 1;
  4550. rgEntry[j].rgExtension = &rgEntryExt[j];
  4551. }
  4552. }
  4553. }
  4554. if (AKI2_NONE != dwAki &&
  4555. 0 == (CertPara[dwCert].dwFlags & NO_CRL_EXT_PARA_FLAG)) {
  4556. // Crl Extensions
  4557. if (!CreateAuthorityKeyId2(
  4558. dwCert,
  4559. dwCert,
  4560. &pbKeyId2Encoded,
  4561. &cbKeyId2Encoded,
  4562. dwAki
  4563. ))
  4564. goto ErrorReturn;
  4565. rgExt[0].pszObjId = szOID_AUTHORITY_KEY_IDENTIFIER2;
  4566. rgExt[0].fCritical = FALSE;
  4567. rgExt[0].Value.pbData = pbKeyId2Encoded;
  4568. rgExt[0].Value.cbData = cbKeyId2Encoded;
  4569. if (!CreateCrlIssuingDistPoint(
  4570. &pbIDPEncoded,
  4571. &cbIDPEncoded
  4572. ))
  4573. goto ErrorReturn;
  4574. rgExt[1].pszObjId = szOID_ISSUING_DIST_POINT;
  4575. rgExt[1].fCritical = FALSE;
  4576. rgExt[1].Value.pbData = pbIDPEncoded;
  4577. rgExt[1].Value.cbData = cbIDPEncoded;
  4578. Crl.cExtension = CRL_EXTENSION_CNT;
  4579. Crl.rgExtension = rgExt;
  4580. }
  4581. if (0 == strcmp("V1", CertPara[dwCert].pszName)) {
  4582. Crl.dwVersion = CRL_V1;
  4583. Crl.cExtension = 0;
  4584. }
  4585. if (!AllocAndEncodeObject(
  4586. X509_CERT_CRL_TO_BE_SIGNED,
  4587. &Crl,
  4588. &pbCrlEncoded,
  4589. &cbCrlEncoded
  4590. ))
  4591. goto ErrorReturn;
  4592. if (!EncodeSignedContent(
  4593. dwCert,
  4594. pbCrlEncoded,
  4595. cbCrlEncoded,
  4596. ppbEncoded,
  4597. pcbEncoded))
  4598. goto ErrorReturn;
  4599. fResult = TRUE;
  4600. goto CommonReturn;
  4601. ErrorReturn:
  4602. *ppbEncoded = NULL;
  4603. *pcbEncoded = 0;
  4604. fResult = FALSE;
  4605. CommonReturn:
  4606. if (pbKeyId2Encoded)
  4607. TestFree(pbKeyId2Encoded);
  4608. if (pbIDPEncoded)
  4609. TestFree(pbIDPEncoded);
  4610. if (pbIssuerEncoded)
  4611. TestFree(pbIssuerEncoded);
  4612. if (pbCrlEncoded)
  4613. TestFree(pbCrlEncoded);
  4614. for (i = 0; i < CERT_CNT; i++) {
  4615. if (rgEntryExt[i].Value.pbData)
  4616. TestFree(rgEntryExt[i].Value.pbData);
  4617. }
  4618. return fResult;
  4619. }
  4620. static BOOL EncodeBaseOrDeltaCrl(
  4621. DWORD dwIssuer,
  4622. int iBase,
  4623. DWORD dwFlags,
  4624. BYTE **ppbEncoded,
  4625. DWORD *pcbEncoded
  4626. )
  4627. {
  4628. BOOL fResult;
  4629. DWORD i;
  4630. BYTE *pbIssuerNameEncoded = NULL;
  4631. DWORD cbIssuerNameEncoded;
  4632. BYTE *pbCDPEncoded = NULL;
  4633. DWORD cbCDPEncoded;
  4634. BYTE *pbBaseEncoded;
  4635. DWORD cbBaseEncoded;
  4636. BYTE *pbIDPEncoded = NULL;
  4637. DWORD cbIDPEncoded;
  4638. BYTE *pbCrlEncoded = NULL;
  4639. DWORD cbCrlEncoded;
  4640. CERT_RDN rgRDN[RDN_CNT];
  4641. CERT_RDN_ATTR rgAttr[ATTR_CNT];
  4642. CERT_NAME_INFO Name;
  4643. FILETIME SerialNumber[CERT_CNT];
  4644. CRL_ENTRY rgEntry[CERT_CNT];
  4645. CRL_INFO Crl;
  4646. CERT_EXTENSION rgExt[10];
  4647. DWORD cExt = 0;
  4648. // Max of 1 extension per entry
  4649. CERT_EXTENSION rgEntryExt[CERT_CNT];
  4650. memset(rgEntryExt, 0, sizeof(rgEntryExt));
  4651. // ISSUER
  4652. CreateNameInfo(dwIssuer, &Name, rgRDN, rgAttr);
  4653. if (!AllocAndEncodeObject(
  4654. X509_NAME,
  4655. &Name,
  4656. &pbIssuerNameEncoded,
  4657. &cbIssuerNameEncoded
  4658. ))
  4659. goto ErrorReturn;
  4660. // CRL
  4661. memset(&Crl, 0, sizeof(Crl));
  4662. Crl.dwVersion = CRL_V2;
  4663. if (CertPara[dwIssuer].dwFlags & DSS_PARA_FLAG)
  4664. Crl.SignatureAlgorithm.pszObjId = DSS_SIGNATURE_ALG_OBJID;
  4665. else
  4666. Crl.SignatureAlgorithm.pszObjId = SIGNATURE_ALG_OBJID;
  4667. Crl.Issuer.pbData = pbIssuerNameEncoded;
  4668. Crl.Issuer.cbData = cbIssuerNameEncoded;
  4669. {
  4670. SYSTEMTIME SystemTime = TestTime;
  4671. if (dwFlags & EXPIRED_CRL_FLAG) {
  4672. SystemTime.wYear = 1997;
  4673. MySystemTimeToFileTime(&SystemTime, &Crl.ThisUpdate);
  4674. SystemTime.wYear = 1998;
  4675. MySystemTimeToFileTime(&SystemTime, &Crl.NextUpdate);
  4676. } else if (CertPara[dwIssuer].dwFlags & GENERALIZED_TIME_PARA_FLAG) {
  4677. SystemTime.wYear = 1921;
  4678. MySystemTimeToFileTime(&SystemTime, &Crl.ThisUpdate);
  4679. SystemTime.wYear = 2071;
  4680. MySystemTimeToFileTime(&SystemTime, &Crl.NextUpdate);
  4681. } else {
  4682. MySystemTimeToFileTime(&SystemTime, &Crl.ThisUpdate);
  4683. if (0 == (CertPara[dwIssuer].dwFlags & NO_CRL_EXT_PARA_FLAG)) {
  4684. SystemTime.wYear++;
  4685. MySystemTimeToFileTime(&SystemTime, &Crl.NextUpdate);
  4686. }
  4687. }
  4688. }
  4689. Crl.cCRLEntry = 0;
  4690. Crl.rgCRLEntry = rgEntry;
  4691. if (0 == (dwFlags & NO_ENTRIES_CRL_FLAG)) {
  4692. for (i = 0; i < CERT_CNT; i++) {
  4693. if (CertPara[i].dwIssuer == dwIssuer &&
  4694. (CertPara[i].dwFlags & REVOKED_PARA_FLAG)) {
  4695. DWORD j;
  4696. SYSTEMTIME SystemTime = TestTime;
  4697. j = Crl.cCRLEntry++;
  4698. memset(&rgEntry[j], 0, sizeof(rgEntry[j]));
  4699. SystemTime.wMilliseconds += (WORD) i;
  4700. MySystemTimeToFileTime(&SystemTime, &SerialNumber[j]);
  4701. rgEntry[j].SerialNumber.pbData = (BYTE *) &SerialNumber[j];
  4702. rgEntry[j].SerialNumber.cbData = sizeof(SerialNumber[j]);
  4703. if (CertPara[dwIssuer].dwFlags & GENERALIZED_TIME_PARA_FLAG) {
  4704. SystemTime.wYear = 1922;
  4705. MySystemTimeToFileTime(&SystemTime, &rgEntry[j].RevocationDate);
  4706. } else
  4707. MySystemTimeToFileTime(&SystemTime, &rgEntry[j].RevocationDate);
  4708. if (dwFlags & REMOVE_FROM_CRL_FLAG) {
  4709. int iReason = CRL_REASON_REMOVE_FROM_CRL;
  4710. if (!AllocAndEncodeObject(
  4711. X509_ENUMERATED,
  4712. (const void *) &iReason,
  4713. &rgEntryExt[j].Value.pbData,
  4714. &rgEntryExt[j].Value.cbData))
  4715. goto ErrorReturn;
  4716. rgEntryExt[j].pszObjId = szOID_CRL_REASON_CODE;
  4717. rgEntryExt[j].fCritical = TRUE;
  4718. rgEntry[j].cExtension = 1;
  4719. rgEntry[j].rgExtension = &rgEntryExt[j];
  4720. } else if (0 == (CertPara[dwIssuer].dwFlags & NO_CRL_EXT_PARA_FLAG)) {
  4721. if (dwFlags & HOLD_CRL_FLAG) {
  4722. int iReason = CRL_REASON_CERTIFICATE_HOLD;
  4723. if (!AllocAndEncodeObject(
  4724. X509_ENUMERATED,
  4725. (const void *) &iReason,
  4726. &rgEntryExt[j].Value.pbData,
  4727. &rgEntryExt[j].Value.cbData))
  4728. goto ErrorReturn;
  4729. } else {
  4730. if (!CreateCRLReason(
  4731. &rgEntryExt[j].Value.pbData,
  4732. &rgEntryExt[j].Value.cbData))
  4733. goto ErrorReturn;
  4734. }
  4735. rgEntryExt[j].pszObjId = szOID_CRL_REASON_CODE;
  4736. rgEntryExt[j].fCritical = FALSE;
  4737. rgEntry[j].cExtension = 1;
  4738. rgEntry[j].rgExtension = &rgEntryExt[j];
  4739. }
  4740. }
  4741. }
  4742. }
  4743. // Extensions
  4744. memset(&rgExt, 0, sizeof(rgExt));
  4745. if (!AllocAndEncodeObject(
  4746. X509_INTEGER,
  4747. (const void *) &iBase,
  4748. &pbBaseEncoded,
  4749. &cbBaseEncoded))
  4750. goto ErrorReturn;
  4751. if (dwFlags & FRESHEST_CRL_FLAG) {
  4752. rgExt[0].pszObjId = szOID_DELTA_CRL_INDICATOR;
  4753. rgExt[0].fCritical = TRUE;
  4754. } else {
  4755. rgExt[0].pszObjId = szOID_CRL_NUMBER;
  4756. rgExt[0].fCritical = FALSE;
  4757. }
  4758. rgExt[0].Value.pbData = pbBaseEncoded;
  4759. rgExt[0].Value.cbData = cbBaseEncoded;
  4760. cExt = 1;
  4761. if (dwFlags & UNSUPPORTED_CRITICAL_EXT_CRL_FLAG) {
  4762. rgExt[cExt].pszObjId = "1.2.3.4.1999.2000";
  4763. rgExt[cExt].fCritical = TRUE;
  4764. rgExt[cExt].Value.pbData = pbBaseEncoded;
  4765. rgExt[cExt].Value.cbData = cbBaseEncoded;
  4766. cExt++;
  4767. }
  4768. if (0 == (dwFlags & FRESHEST_CRL_FLAG) &&
  4769. 0 == (dwFlags & NO_FRESHEST_CDP_CRL_FLAG)) {
  4770. if (!CreateCrlDistPoints(
  4771. dwIssuer,
  4772. CRL_DIST_POINTS_DELTA_FLAG,
  4773. &pbCDPEncoded,
  4774. &cbCDPEncoded))
  4775. goto ErrorReturn;
  4776. rgExt[cExt].pszObjId = szOID_FRESHEST_CRL;
  4777. rgExt[cExt].fCritical = FALSE;
  4778. rgExt[cExt].Value.pbData = pbCDPEncoded;
  4779. rgExt[cExt].Value.cbData = cbCDPEncoded;
  4780. cExt++;
  4781. }
  4782. if (0 == (dwFlags & NO_IDP_CRL_FLAG)) {
  4783. CRL_ISSUING_DIST_POINT IDP;
  4784. PCERT_ALT_NAME_INFO pIDPAltNameInfo;
  4785. CERT_ALT_NAME_ENTRY rgIDPAltNameEntry[8];
  4786. BYTE bOnlySomeReasonFlags;
  4787. memset(&IDP, 0, sizeof(IDP));
  4788. if (dwFlags & UNSUPPORTED_IDP_OPTIONS_CRL_FLAG) {
  4789. IDP.OnlySomeReasonFlags.cbData = 1;
  4790. IDP.OnlySomeReasonFlags.pbData = &bOnlySomeReasonFlags;
  4791. IDP.OnlySomeReasonFlags.cUnusedBits = 1;
  4792. bOnlySomeReasonFlags = CRL_REASON_KEY_COMPROMISE_FLAG |
  4793. CRL_REASON_CA_COMPROMISE_FLAG;
  4794. IDP.fIndirectCRL = TRUE;
  4795. }
  4796. if (dwFlags & ONLY_USERS_CRL_FLAG)
  4797. IDP.fOnlyContainsUserCerts = TRUE;
  4798. if (dwFlags & ONLY_CAS_CRL_FLAG)
  4799. IDP.fOnlyContainsCACerts = TRUE;
  4800. IDP.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
  4801. rgIDPAltNameEntry[0].dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME;
  4802. rgIDPAltNameEntry[0].pOtherName = &CrlOtherName;
  4803. rgIDPAltNameEntry[1].dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
  4804. rgIDPAltNameEntry[1].DirectoryName.pbData = pbIssuerNameEncoded;
  4805. rgIDPAltNameEntry[1].DirectoryName.cbData = cbIssuerNameEncoded;
  4806. rgIDPAltNameEntry[2].dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
  4807. rgIDPAltNameEntry[2].pwszDNSName = CRL_DNS_NAME;
  4808. rgIDPAltNameEntry[3].dwAltNameChoice = CERT_ALT_NAME_RFC822_NAME;
  4809. rgIDPAltNameEntry[3].pwszRfc822Name = CRL_EMAIL_NAME;
  4810. rgIDPAltNameEntry[4].dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID;
  4811. rgIDPAltNameEntry[4].pszRegisteredID = CRL_REGISTERED_ID;
  4812. rgIDPAltNameEntry[5].dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
  4813. rgIDPAltNameEntry[5].IPAddress.pbData = CrlIPAddress;
  4814. rgIDPAltNameEntry[5].IPAddress.cbData = sizeof(CrlIPAddress);
  4815. rgIDPAltNameEntry[6].dwAltNameChoice = CERT_ALT_NAME_URL;
  4816. rgIDPAltNameEntry[6].pwszURL = CRL_URL_NAME2;
  4817. rgIDPAltNameEntry[7].dwAltNameChoice = CERT_ALT_NAME_URL;
  4818. rgIDPAltNameEntry[7].pwszURL = CRL_URL_NAME1;
  4819. pIDPAltNameInfo = &IDP.DistPointName.FullName;
  4820. switch (iBase) {
  4821. case 1:
  4822. pIDPAltNameInfo->cAltEntry = 1;
  4823. pIDPAltNameInfo->rgAltEntry = &rgIDPAltNameEntry[0];
  4824. break;
  4825. case 2:
  4826. pIDPAltNameInfo->cAltEntry = 1;
  4827. pIDPAltNameInfo->rgAltEntry = &rgIDPAltNameEntry[1];
  4828. break;
  4829. case 3:
  4830. pIDPAltNameInfo->cAltEntry = 2;
  4831. pIDPAltNameInfo->rgAltEntry = &rgIDPAltNameEntry[2];
  4832. break;
  4833. case 4:
  4834. pIDPAltNameInfo->cAltEntry = 2;
  4835. pIDPAltNameInfo->rgAltEntry = &rgIDPAltNameEntry[4];
  4836. break;
  4837. default:
  4838. pIDPAltNameInfo->cAltEntry = 2;
  4839. pIDPAltNameInfo->rgAltEntry = &rgIDPAltNameEntry[6];
  4840. break;
  4841. }
  4842. if (!AllocAndEncodeObject(
  4843. szOID_ISSUING_DIST_POINT,
  4844. &IDP,
  4845. &pbIDPEncoded,
  4846. &cbIDPEncoded))
  4847. goto ErrorReturn;
  4848. rgExt[cExt].pszObjId = szOID_ISSUING_DIST_POINT;
  4849. rgExt[cExt].fCritical = TRUE;
  4850. rgExt[cExt].Value.pbData = pbIDPEncoded;
  4851. rgExt[cExt].Value.cbData = cbIDPEncoded;
  4852. cExt++;
  4853. }
  4854. Crl.cExtension = cExt;
  4855. Crl.rgExtension = rgExt;
  4856. if (!AllocAndEncodeObject(
  4857. X509_CERT_CRL_TO_BE_SIGNED,
  4858. &Crl,
  4859. &pbCrlEncoded,
  4860. &cbCrlEncoded
  4861. ))
  4862. goto ErrorReturn;
  4863. if (!EncodeSignedContent(
  4864. dwIssuer,
  4865. pbCrlEncoded,
  4866. cbCrlEncoded,
  4867. ppbEncoded,
  4868. pcbEncoded))
  4869. goto ErrorReturn;
  4870. fResult = TRUE;
  4871. goto CommonReturn;
  4872. ErrorReturn:
  4873. *ppbEncoded = NULL;
  4874. *pcbEncoded = 0;
  4875. fResult = FALSE;
  4876. CommonReturn:
  4877. if (pbIssuerNameEncoded)
  4878. TestFree(pbIssuerNameEncoded);
  4879. if (pbBaseEncoded)
  4880. TestFree(pbBaseEncoded);
  4881. if (pbCDPEncoded)
  4882. TestFree(pbCDPEncoded);
  4883. if (pbIDPEncoded)
  4884. TestFree(pbIDPEncoded);
  4885. if (pbCrlEncoded)
  4886. TestFree(pbCrlEncoded);
  4887. for (i = 0; i < CERT_CNT; i++) {
  4888. if (rgEntryExt[i].Value.pbData)
  4889. TestFree(rgEntryExt[i].Value.pbData);
  4890. }
  4891. return fResult;
  4892. }
  4893. static BOOL EncodeCtl(DWORD dwCert, DWORD dwEncodeFlags, BYTE **ppbEncoded,
  4894. DWORD *pcbEncoded)
  4895. {
  4896. BOOL fResult;
  4897. BYTE *pbNextUpdateLoc = NULL;
  4898. DWORD cbNextUpdateLoc;
  4899. BYTE *pbCtlEncoded = NULL;
  4900. DWORD cbCtlEncoded;
  4901. DWORD dwFlags;
  4902. DWORD dwCtlFlags;
  4903. DWORD dwUseFlag;
  4904. DWORD i;
  4905. struct {
  4906. FILETIME ft;
  4907. DWORD dwCert;
  4908. } SequenceNumber;
  4909. PCTL_USAGE pCtlUsage; // not allocated
  4910. BYTE rgbHash[CERT_CNT][MAX_HASH_LEN];
  4911. BYTE rgbZero[1] = {0};
  4912. BYTE NullDer[] = {0x05, 0x00};
  4913. BYTE IntegerDer[] = {0x02, 0x01, 0x35};
  4914. CRYPT_ATTR_BLOB rgAttrBlob[2] = {
  4915. 2, (BYTE *) NullDer,
  4916. 3, (BYTE *) IntegerDer
  4917. };
  4918. CRYPT_ATTRIBUTE rgAttr[] = {
  4919. "1.2.3.4.5.0",
  4920. 1, rgAttrBlob,
  4921. "1.2.1.1.1.1.1.1",
  4922. 2, rgAttrBlob
  4923. };
  4924. CMSG_SIGNER_ENCODE_INFO SignerInfo;
  4925. CMSG_SIGNED_ENCODE_INFO SignInfo;
  4926. CRYPT_ATTRIBUTE SignerAttr;
  4927. CRYPT_ATTR_BLOB SignerAttrBlob;
  4928. CERT_BLOB CertBlob;
  4929. CTL_ENTRY rgEntry[CERT_CNT];
  4930. #define CTL_EXTENSION_CNT 1
  4931. CERT_EXTENSION rgExt[CTL_EXTENSION_CNT];
  4932. CTL_INFO Ctl;
  4933. if (NULL == rgpCertContext[dwCert])
  4934. goto ErrorReturn;
  4935. dwFlags = CertPara[dwCert].dwFlags;
  4936. // CTL
  4937. memset(&Ctl, 0, sizeof(Ctl));
  4938. Ctl.dwVersion = CTL_V1;
  4939. dwCtlFlags = dwFlags & (CTL1_PARA_FLAG | CTL2_PARA_FLAG);
  4940. dwUseFlag = 0;
  4941. switch (dwCtlFlags) {
  4942. case CTL1_PARA_FLAG:
  4943. if (dwFlags & NO_EXT_PARA_FLAG)
  4944. pCtlUsage = &rgCtlUsage[0];
  4945. else {
  4946. pCtlUsage = &rgCtlUsage[1];
  4947. dwUseFlag = USE1_PARA_FLAG;
  4948. }
  4949. break;
  4950. case CTL2_PARA_FLAG:
  4951. pCtlUsage = &rgCtlUsage[2];
  4952. dwUseFlag = USE2_PARA_FLAG;
  4953. break;
  4954. case CTL1_PARA_FLAG | CTL2_PARA_FLAG:
  4955. default:
  4956. pCtlUsage = &rgCtlUsage[3];
  4957. break;
  4958. }
  4959. Ctl.SubjectUsage = *pCtlUsage;
  4960. if (dwFlags & CTL2_PARA_FLAG) {
  4961. DWORD dwIdx;
  4962. if (dwFlags & TIME_INVALID_PARA_FLAG) {
  4963. assert(dwFlags & DUPLICATE_PARA_FLAG);
  4964. dwIdx = dwCert - 1;
  4965. } else
  4966. dwIdx = dwCert;
  4967. Ctl.ListIdentifier.pbData = (BYTE *) CertPara[dwIdx].pszName;
  4968. Ctl.ListIdentifier.cbData = strlen(CertPara[dwIdx].pszName);
  4969. MySystemTimeToFileTime(&TestTime, &SequenceNumber.ft);
  4970. SequenceNumber.dwCert = dwCert;
  4971. Ctl.SequenceNumber.pbData = (BYTE *) &SequenceNumber;
  4972. Ctl.SequenceNumber.cbData = sizeof(SequenceNumber);
  4973. }
  4974. {
  4975. SYSTEMTIME SystemTime = TestTime;
  4976. if (dwFlags & TIME_INVALID_PARA_FLAG) {
  4977. SystemTime.wYear -=2;
  4978. MySystemTimeToFileTime(&SystemTime, &Ctl.ThisUpdate);
  4979. SystemTime.wYear++;
  4980. MySystemTimeToFileTime(&SystemTime, &Ctl.NextUpdate);
  4981. } else {
  4982. MySystemTimeToFileTime(&SystemTime, &Ctl.ThisUpdate);
  4983. if (dwUseFlag) {
  4984. SystemTime.wYear++;
  4985. MySystemTimeToFileTime(&SystemTime, &Ctl.NextUpdate);
  4986. }
  4987. }
  4988. }
  4989. Ctl.SubjectAlgorithm.pszObjId = szOID_OIWSEC_sha1;
  4990. Ctl.cCTLEntry = 0;
  4991. Ctl.rgCTLEntry = rgEntry;
  4992. for (i = 0; i < CERT_CNT; i++) {
  4993. if (CertPara[i].dwFlags & dwUseFlag) {
  4994. DWORD j;
  4995. DWORD cbHash;
  4996. if (NULL == rgpCertContext[i])
  4997. continue;
  4998. j = Ctl.cCTLEntry++;
  4999. memset(&rgEntry[j], 0, sizeof(rgEntry[j]));
  5000. cbHash = MAX_HASH_LEN;
  5001. if (CertGetCertificateContextProperty(
  5002. rgpCertContext[i],
  5003. CERT_SHA1_HASH_PROP_ID,
  5004. rgbHash[j],
  5005. &cbHash)) {
  5006. rgEntry[j].SubjectIdentifier.pbData = rgbHash[j];
  5007. rgEntry[j].SubjectIdentifier.cbData = cbHash;
  5008. } else {
  5009. PrintLastError(
  5010. "CertGetCertificateContextProperty(SHA1_HASH)");
  5011. rgEntry[j].SubjectIdentifier.pbData = rgbZero;
  5012. rgEntry[j].SubjectIdentifier.cbData = sizeof(rgbZero);
  5013. }
  5014. if (CertPara[i].dwFlags & ALL_EXT_PARA_FLAG) {
  5015. rgEntry[j].cAttribute = sizeof(rgAttr) / sizeof(rgAttr[0]);
  5016. rgEntry[j].rgAttribute = rgAttr;
  5017. }
  5018. }
  5019. }
  5020. if (!CreateNextUpdateLocation(
  5021. dwCert,
  5022. FALSE, // fProp
  5023. &pbNextUpdateLoc,
  5024. &cbNextUpdateLoc))
  5025. goto ErrorReturn;
  5026. // Ctl Extensions
  5027. rgExt[0].pszObjId = szOID_NEXT_UPDATE_LOCATION;
  5028. rgExt[0].fCritical = FALSE;
  5029. rgExt[0].Value.pbData = pbNextUpdateLoc;
  5030. rgExt[0].Value.cbData = cbNextUpdateLoc;
  5031. if (0 == (CertPara[dwCert].dwFlags & NO_EXT_PARA_FLAG)) {
  5032. Ctl.cExtension = 1;
  5033. Ctl.rgExtension = rgExt;
  5034. }
  5035. memset(&SignerInfo, 0, sizeof(SignerInfo));
  5036. SignerInfo.cbSize = sizeof(SignerInfo);
  5037. SignerInfo.pCertInfo = rgpCertContext[dwCert]->pCertInfo;
  5038. if (CertPara[dwCert].dwFlags & DSS_PARA_FLAG) {
  5039. if (CertPara[dwCert].dwFlags & DSS_512_PARA_FLAG)
  5040. SignerInfo.hCryptProv = hDSS512CryptProv;
  5041. else
  5042. SignerInfo.hCryptProv = hDSSCryptProv;
  5043. } else if (CertPara[dwCert].dwFlags & ENH_1024_PARA_FLAG)
  5044. SignerInfo.hCryptProv = hEnh1024CryptProv;
  5045. else if (CertPara[dwCert].dwFlags & ENH_2048_PARA_FLAG)
  5046. SignerInfo.hCryptProv = hEnh2048CryptProv;
  5047. else
  5048. SignerInfo.hCryptProv = hRSACryptProv;
  5049. SignerInfo.dwKeySpec = AT_SIGNATURE;
  5050. SignerInfo.HashAlgorithm.pszObjId = szOID_OIWSEC_sha1;
  5051. if (dwFlags & CTL2_PARA_FLAG) {
  5052. // Signer Attributes
  5053. memset(&SignerAttr, 0, sizeof(SignerAttr));
  5054. SignerAttr.pszObjId = szOID_NEXT_UPDATE_LOCATION;
  5055. SignerAttr.cValue = 1;
  5056. SignerAttr.rgValue = &SignerAttrBlob;
  5057. SignerAttrBlob.pbData = pbNextUpdateLoc;
  5058. SignerAttrBlob.cbData = cbNextUpdateLoc;
  5059. SignerInfo.cAuthAttr = 1;
  5060. SignerInfo.rgAuthAttr = &SignerAttr;
  5061. SignerInfo.cUnauthAttr = 1;
  5062. SignerInfo.rgUnauthAttr = &SignerAttr;
  5063. }
  5064. memset(&SignInfo, 0, sizeof(SignInfo));
  5065. SignInfo.cbSize = sizeof(SignInfo);
  5066. if (dwUseFlag) {
  5067. SignInfo.cSigners = 1;
  5068. SignInfo.rgSigners = &SignerInfo;
  5069. SignInfo.cCertEncoded = 1;
  5070. CertBlob.pbData = rgpCertContext[dwCert]->pbCertEncoded;
  5071. CertBlob.cbData = rgpCertContext[dwCert]->cbCertEncoded;
  5072. SignInfo.rgCertEncoded = &CertBlob;
  5073. }
  5074. cbCtlEncoded = 0;
  5075. if (!CryptMsgEncodeAndSignCTL(
  5076. dwMsgEncodingType,
  5077. &Ctl,
  5078. &SignInfo,
  5079. dwEncodeFlags,
  5080. NULL, // pbEncoded
  5081. &cbCtlEncoded
  5082. ) || 0 == cbCtlEncoded) {
  5083. PrintLastError("EncodeCtl::CryptMsgEncodeAndSignCTL(cbEncoded == 0)");
  5084. goto ErrorReturn;
  5085. }
  5086. pbCtlEncoded = (BYTE *) TestAlloc(cbCtlEncoded);
  5087. if (pbCtlEncoded == NULL) goto ErrorReturn;
  5088. if (!CryptMsgEncodeAndSignCTL(
  5089. dwMsgEncodingType,
  5090. &Ctl,
  5091. &SignInfo,
  5092. dwEncodeFlags,
  5093. pbCtlEncoded,
  5094. &cbCtlEncoded
  5095. )) {
  5096. PrintLastError("EncodeCtl::CryptMsgEncodeAndSignCTL");
  5097. goto ErrorReturn;
  5098. }
  5099. fResult = TRUE;
  5100. goto CommonReturn;
  5101. ErrorReturn:
  5102. if (pbCtlEncoded)
  5103. TestFree(pbCtlEncoded);
  5104. pbCtlEncoded = NULL;
  5105. cbCtlEncoded = 0;
  5106. fResult = FALSE;
  5107. CommonReturn:
  5108. if (pbNextUpdateLoc)
  5109. TestFree(pbNextUpdateLoc);
  5110. *ppbEncoded = pbCtlEncoded;
  5111. *pcbEncoded = cbCtlEncoded;
  5112. return fResult;
  5113. }
  5114. static BOOL EncodeUpdateCtl(
  5115. BOOL fTimeInvalid,
  5116. LPSTR pszUsageObjId,
  5117. LPSTR pszListIdentifier,
  5118. LPWSTR pwszUrl,
  5119. BYTE **ppbEncoded,
  5120. DWORD *pcbEncoded
  5121. )
  5122. {
  5123. BOOL fResult;
  5124. BYTE *pbNextUpdateLoc = NULL;
  5125. DWORD cbNextUpdateLoc;
  5126. BYTE *pbCtlEncoded = NULL;
  5127. DWORD cbCtlEncoded;
  5128. CERT_BLOB CertBlob;
  5129. CMSG_SIGNER_ENCODE_INFO SignerInfo;
  5130. CMSG_SIGNED_ENCODE_INFO SignInfo;
  5131. CERT_EXTENSION rgExt[1];
  5132. CTL_INFO Ctl;
  5133. if (NULL == rgpCertContext[UPDATE_CTL_SIGNER])
  5134. goto ErrorReturn;
  5135. // CTL
  5136. memset(&Ctl, 0, sizeof(Ctl));
  5137. Ctl.dwVersion = CTL_V1;
  5138. Ctl.SubjectUsage.cUsageIdentifier = 1;
  5139. Ctl.SubjectUsage.rgpszUsageIdentifier = &pszUsageObjId;
  5140. Ctl.ListIdentifier.pbData = (BYTE *) pszListIdentifier;
  5141. Ctl.ListIdentifier.cbData = strlen(pszListIdentifier);
  5142. {
  5143. SYSTEMTIME SystemTime = TestTime;
  5144. if (fTimeInvalid) {
  5145. SystemTime.wYear -=2;
  5146. MySystemTimeToFileTime(&SystemTime, &Ctl.ThisUpdate);
  5147. SystemTime.wYear++;
  5148. MySystemTimeToFileTime(&SystemTime, &Ctl.NextUpdate);
  5149. } else {
  5150. MySystemTimeToFileTime(&SystemTime, &Ctl.ThisUpdate);
  5151. SystemTime.wYear++;
  5152. MySystemTimeToFileTime(&SystemTime, &Ctl.NextUpdate);
  5153. }
  5154. }
  5155. Ctl.SubjectAlgorithm.pszObjId = szOID_OIWSEC_sha1;
  5156. if (!CreateNextUpdateLocation(
  5157. UPDATE_CTL_SIGNER, // dwCert
  5158. FALSE, // fProp
  5159. &pbNextUpdateLoc,
  5160. &cbNextUpdateLoc,
  5161. pwszUrl))
  5162. goto ErrorReturn;
  5163. // Ctl Extensions
  5164. rgExt[0].pszObjId = szOID_NEXT_UPDATE_LOCATION;
  5165. rgExt[0].fCritical = FALSE;
  5166. rgExt[0].Value.pbData = pbNextUpdateLoc;
  5167. rgExt[0].Value.cbData = cbNextUpdateLoc;
  5168. Ctl.cExtension = 1;
  5169. Ctl.rgExtension = rgExt;
  5170. memset(&SignerInfo, 0, sizeof(SignerInfo));
  5171. SignerInfo.cbSize = sizeof(SignerInfo);
  5172. SignerInfo.pCertInfo = rgpCertContext[UPDATE_CTL_SIGNER]->pCertInfo;
  5173. SignerInfo.hCryptProv = hRSACryptProv;
  5174. SignerInfo.dwKeySpec = AT_SIGNATURE;
  5175. SignerInfo.HashAlgorithm.pszObjId = szOID_OIWSEC_sha1;
  5176. memset(&SignInfo, 0, sizeof(SignInfo));
  5177. SignInfo.cbSize = sizeof(SignInfo);
  5178. SignInfo.cSigners = 1;
  5179. SignInfo.rgSigners = &SignerInfo;
  5180. SignInfo.cCertEncoded = 1;
  5181. CertBlob.pbData = rgpCertContext[UPDATE_CTL_SIGNER]->pbCertEncoded;
  5182. CertBlob.cbData = rgpCertContext[UPDATE_CTL_SIGNER]->cbCertEncoded;
  5183. SignInfo.rgCertEncoded = &CertBlob;
  5184. cbCtlEncoded = 0;
  5185. if (!CryptMsgEncodeAndSignCTL(
  5186. dwMsgEncodingType,
  5187. &Ctl,
  5188. &SignInfo,
  5189. 0, // dwEncodeFlags
  5190. NULL, // pbEncoded
  5191. &cbCtlEncoded
  5192. ) || 0 == cbCtlEncoded) {
  5193. PrintLastError("EncodeUpdateCtl::CryptMsgEncodeAndSignCTL(cbEncoded == 0)");
  5194. goto ErrorReturn;
  5195. }
  5196. pbCtlEncoded = (BYTE *) TestAlloc(cbCtlEncoded);
  5197. if (pbCtlEncoded == NULL) goto ErrorReturn;
  5198. if (!CryptMsgEncodeAndSignCTL(
  5199. dwMsgEncodingType,
  5200. &Ctl,
  5201. &SignInfo,
  5202. 0, // dwEncodeFlags
  5203. pbCtlEncoded,
  5204. &cbCtlEncoded
  5205. )) {
  5206. PrintLastError("EncodeUpdateCtl::CryptMsgEncodeAndSignCTL");
  5207. goto ErrorReturn;
  5208. }
  5209. fResult = TRUE;
  5210. goto CommonReturn;
  5211. ErrorReturn:
  5212. if (pbCtlEncoded)
  5213. TestFree(pbCtlEncoded);
  5214. pbCtlEncoded = NULL;
  5215. cbCtlEncoded = 0;
  5216. fResult = FALSE;
  5217. CommonReturn:
  5218. if (pbNextUpdateLoc)
  5219. TestFree(pbNextUpdateLoc);
  5220. *ppbEncoded = pbCtlEncoded;
  5221. *pcbEncoded = cbCtlEncoded;
  5222. return fResult;
  5223. }