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.

12863 lines
411 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: wincert.cpp
  8. //
  9. // Contents: Certificate, Certificate Revocation List (CRL),
  10. // Certificate Request and Certificate Name
  11. // Encode/Decode APIs
  12. //
  13. // ASN.1 implementation uses the ASN1 compiler.
  14. //
  15. // Functions: CryptEncodeObject
  16. // CryptDecodeObject
  17. // CryptEncodeObjectEx
  18. // CryptDecodeObjectEx
  19. //
  20. // History: 29-Feb-96 philh created
  21. // 20-Jan-98 philh added "Ex" version
  22. //
  23. //--------------------------------------------------------------------------
  24. #include "global.hxx"
  25. #include <dbgdef.h>
  26. #ifndef OSS_CRYPT_ASN1
  27. #define ASN1_SUPPORTS_UTF8_TAG 1
  28. #endif // OSS_CRYPT_ASN1
  29. // All the *pvInfo extra stuff needs to be aligned
  30. #define INFO_LEN_ALIGN(Len) ((Len + 7) & ~7)
  31. static const BYTE NullDer[2] = {0x05, 0x00};
  32. static const CRYPT_OBJID_BLOB NullDerBlob = {2, (BYTE *)&NullDer[0]};
  33. HCRYPTASN1MODULE hX509Asn1Module;
  34. HCRYPTOIDFUNCSET hX509EncodeFuncSet;
  35. HCRYPTOIDFUNCSET hX509DecodeFuncSet;
  36. HCRYPTOIDFUNCSET hX509EncodeExFuncSet;
  37. HCRYPTOIDFUNCSET hX509DecodeExFuncSet;
  38. //+-------------------------------------------------------------------------
  39. // Function: GetEncoder/GetDecoder
  40. //
  41. // Synopsis: Initialize thread local storage for the asn libs
  42. //
  43. // Returns: pointer to an initialized Asn1 encoder/decoder data
  44. // structures
  45. //--------------------------------------------------------------------------
  46. static inline ASN1encoding_t GetEncoder(void)
  47. {
  48. return I_CryptGetAsn1Encoder(hX509Asn1Module);
  49. }
  50. static inline ASN1decoding_t GetDecoder(void)
  51. {
  52. return I_CryptGetAsn1Decoder(hX509Asn1Module);
  53. }
  54. typedef BOOL (WINAPI *PFN_ENCODE_FUNC) (
  55. IN DWORD dwCertEncodingType,
  56. IN LPCSTR lpszStructType,
  57. IN const void *pvStructInfo,
  58. OUT OPTIONAL BYTE *pbEncoded,
  59. IN OUT DWORD *pcbEncoded
  60. );
  61. typedef BOOL (WINAPI *PFN_DECODE_FUNC) (
  62. IN DWORD dwCertEncodingType,
  63. IN LPCSTR lpszStructType,
  64. IN const BYTE *pbEncoded,
  65. IN DWORD cbEncoded,
  66. IN DWORD dwFlags,
  67. OUT OPTIONAL void *pvStructInfo,
  68. IN OUT DWORD *pcbStructInfo
  69. );
  70. typedef BOOL (WINAPI *PFN_ENCODE_EX_FUNC) (
  71. IN DWORD dwCertEncodingType,
  72. IN LPCSTR lpszStructType,
  73. IN const void *pvStructInfo,
  74. IN DWORD dwFlags,
  75. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  76. OUT OPTIONAL void *pvEncoded,
  77. IN OUT DWORD *pcbEncoded
  78. );
  79. typedef BOOL (WINAPI *PFN_DECODE_EX_FUNC) (
  80. IN DWORD dwCertEncodingType,
  81. IN LPCSTR lpszStructType,
  82. IN const BYTE *pbEncoded,
  83. IN DWORD cbEncoded,
  84. IN DWORD dwFlags,
  85. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  86. OUT OPTIONAL void *pvStructInfo,
  87. IN OUT DWORD *pcbStructInfo
  88. );
  89. //+-------------------------------------------------------------------------
  90. // ASN1 X509 v3 ASN.1 Encode / Decode functions
  91. //--------------------------------------------------------------------------
  92. BOOL WINAPI Asn1CSPProviderEncodeEx(
  93. IN DWORD dwCertEncodingType,
  94. IN LPCSTR lpszStructType,
  95. IN PCRYPT_CSP_PROVIDER pCSPProvider,
  96. IN DWORD dwFlags,
  97. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  98. OUT OPTIONAL void *pvEncoded,
  99. IN OUT DWORD *pcbEncoded
  100. );
  101. BOOL WINAPI Asn1CSPProviderDecodeEx(
  102. IN DWORD dwCertEncodingType,
  103. IN LPCSTR lpszStructType,
  104. IN const BYTE *pbEncoded,
  105. IN DWORD cbEncoded,
  106. IN DWORD dwFlags,
  107. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  108. OUT OPTIONAL void *pvStructInfo,
  109. IN OUT DWORD *pcbStructInfo
  110. );
  111. BOOL WINAPI Asn1NameValueEncodeEx(
  112. IN DWORD dwCertEncodingType,
  113. IN LPCSTR lpszStructType,
  114. IN PCRYPT_ENROLLMENT_NAME_VALUE_PAIR pNameValue,
  115. IN DWORD dwFlags,
  116. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  117. OUT OPTIONAL void *pvEncoded,
  118. IN OUT DWORD *pcbEncoded
  119. );
  120. BOOL WINAPI Asn1NameValueDecodeEx(
  121. IN DWORD dwCertEncodingType,
  122. IN LPCSTR lpszStructType,
  123. IN const BYTE *pbEncoded,
  124. IN DWORD cbEncoded,
  125. IN DWORD dwFlags,
  126. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  127. OUT OPTIONAL void *pvStructInfo,
  128. IN OUT DWORD *pcbStructInfo
  129. );
  130. BOOL WINAPI Asn1X509CertInfoEncodeEx(
  131. IN DWORD dwCertEncodingType,
  132. IN LPCSTR lpszStructType,
  133. IN PCERT_INFO pInfo,
  134. IN DWORD dwFlags,
  135. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  136. OUT OPTIONAL void *pvEncoded,
  137. IN OUT DWORD *pcbEncoded
  138. );
  139. BOOL WINAPI Asn1X509CertInfoDecodeEx(
  140. IN DWORD dwCertEncodingType,
  141. IN LPCSTR lpszStructType,
  142. IN const BYTE *pbEncoded,
  143. IN DWORD cbEncoded,
  144. IN DWORD dwFlags,
  145. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  146. OUT OPTIONAL void *pvStructInfo,
  147. IN OUT DWORD *pcbStructInfo
  148. );
  149. BOOL WINAPI Asn1X509CrlInfoEncodeEx(
  150. IN DWORD dwCertEncodingType,
  151. IN LPCSTR lpszStructType,
  152. IN PCRL_INFO pInfo,
  153. IN DWORD dwFlags,
  154. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  155. OUT OPTIONAL void *pvEncoded,
  156. IN OUT DWORD *pcbEncoded
  157. );
  158. BOOL WINAPI Asn1X509CrlInfoDecodeEx(
  159. IN DWORD dwCertEncodingType,
  160. IN LPCSTR lpszStructType,
  161. IN const BYTE *pbEncoded,
  162. IN DWORD cbEncoded,
  163. IN DWORD dwFlags,
  164. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  165. OUT OPTIONAL void *pvStructInfo,
  166. IN OUT DWORD *pcbStructInfo
  167. );
  168. BOOL WINAPI Asn1X509CertRequestInfoEncodeEx(
  169. IN DWORD dwCertEncodingType,
  170. IN LPCSTR lpszStructType,
  171. IN PCERT_REQUEST_INFO pInfo,
  172. IN DWORD dwFlags,
  173. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  174. OUT OPTIONAL void *pvEncoded,
  175. IN OUT DWORD *pcbEncoded
  176. );
  177. BOOL WINAPI Asn1X509CertRequestInfoDecodeEx(
  178. IN DWORD dwCertEncodingType,
  179. IN LPCSTR lpszStructType,
  180. IN const BYTE *pbEncoded,
  181. IN DWORD cbEncoded,
  182. IN DWORD dwFlags,
  183. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  184. OUT OPTIONAL void *pvStructInfo,
  185. IN OUT DWORD *pcbStructInfo
  186. );
  187. BOOL WINAPI Asn1X509KeygenRequestInfoEncodeEx(
  188. IN DWORD dwCertEncodingType,
  189. IN LPCSTR lpszStructType,
  190. IN PCERT_KEYGEN_REQUEST_INFO pInfo,
  191. IN DWORD dwFlags,
  192. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  193. OUT OPTIONAL void *pvEncoded,
  194. IN OUT DWORD *pcbEncoded
  195. );
  196. BOOL WINAPI Asn1X509KeygenRequestInfoDecodeEx(
  197. IN DWORD dwCertEncodingType,
  198. IN LPCSTR lpszStructType,
  199. IN const BYTE *pbEncoded,
  200. IN DWORD cbEncoded,
  201. IN DWORD dwFlags,
  202. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  203. OUT OPTIONAL void *pvStructInfo,
  204. IN OUT DWORD *pcbStructInfo
  205. );
  206. BOOL WINAPI Asn1X509SignedContentEncodeEx(
  207. IN DWORD dwCertEncodingType,
  208. IN LPCSTR lpszStructType,
  209. IN PCERT_SIGNED_CONTENT_INFO pInfo,
  210. IN DWORD dwFlags,
  211. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  212. OUT OPTIONAL void *pvEncoded,
  213. IN OUT DWORD *pcbEncoded
  214. );
  215. BOOL WINAPI Asn1X509SignedContentDecodeEx(
  216. IN DWORD dwCertEncodingType,
  217. IN LPCSTR lpszStructType,
  218. IN const BYTE *pbEncoded,
  219. IN DWORD cbEncoded,
  220. IN DWORD dwFlags,
  221. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  222. OUT OPTIONAL void *pvStructInfo,
  223. IN OUT DWORD *pcbStructInfo
  224. );
  225. BOOL WINAPI Asn1X509NameInfoEncodeEx(
  226. IN DWORD dwCertEncodingType,
  227. IN LPCSTR lpszStructType,
  228. IN PCERT_NAME_INFO pInfo,
  229. IN DWORD dwFlags,
  230. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  231. OUT OPTIONAL void *pvEncoded,
  232. IN OUT DWORD *pcbEncoded
  233. );
  234. BOOL WINAPI Asn1X509NameInfoDecodeEx(
  235. IN DWORD dwCertEncodingType,
  236. IN LPCSTR lpszStructType,
  237. IN const BYTE *pbEncoded,
  238. IN DWORD cbEncoded,
  239. IN DWORD dwFlags,
  240. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  241. OUT OPTIONAL void *pvStructInfo,
  242. IN OUT DWORD *pcbStructInfo
  243. );
  244. BOOL WINAPI Asn1X509NameValueEncodeEx(
  245. IN DWORD dwCertEncodingType,
  246. IN LPCSTR lpszStructType,
  247. IN PCERT_NAME_VALUE pInfo,
  248. IN DWORD dwFlags,
  249. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  250. OUT OPTIONAL void *pvEncoded,
  251. IN OUT DWORD *pcbEncoded
  252. );
  253. BOOL WINAPI Asn1X509NameValueDecodeEx(
  254. IN DWORD dwCertEncodingType,
  255. IN LPCSTR lpszStructType,
  256. IN const BYTE *pbEncoded,
  257. IN DWORD cbEncoded,
  258. IN DWORD dwFlags,
  259. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  260. OUT OPTIONAL void *pvStructInfo,
  261. IN OUT DWORD *pcbStructInfo
  262. );
  263. //+-------------------------------------------------------------------------
  264. // ASN1 ASN.1 X509 Certificate Extensions Encode / Decode functions
  265. //--------------------------------------------------------------------------
  266. BOOL WINAPI Asn1X509ExtensionsEncodeEx(
  267. IN DWORD dwCertEncodingType,
  268. IN LPCSTR lpszStructType,
  269. IN PCERT_EXTENSIONS pInfo,
  270. IN DWORD dwFlags,
  271. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  272. OUT OPTIONAL void *pvEncoded,
  273. IN OUT DWORD *pcbEncoded
  274. );
  275. BOOL WINAPI Asn1X509ExtensionsDecodeEx(
  276. IN DWORD dwCertEncodingType,
  277. IN LPCSTR lpszStructType,
  278. IN const BYTE *pbEncoded,
  279. IN DWORD cbEncoded,
  280. IN DWORD dwFlags,
  281. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  282. OUT OPTIONAL void *pvStructInfo,
  283. IN OUT DWORD *pcbStructInfo
  284. );
  285. //+-------------------------------------------------------------------------
  286. // ASN1 ASN.1 Public Key Info Encode / Decode functions
  287. //--------------------------------------------------------------------------
  288. BOOL WINAPI Asn1X509PublicKeyInfoEncodeEx(
  289. IN DWORD dwCertEncodingType,
  290. IN LPCSTR lpszStructType,
  291. IN PCERT_PUBLIC_KEY_INFO pInfo,
  292. IN DWORD dwFlags,
  293. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  294. OUT OPTIONAL void *pvEncoded,
  295. IN OUT DWORD *pcbEncoded
  296. );
  297. BOOL WINAPI Asn1X509PublicKeyInfoDecodeEx(
  298. IN DWORD dwCertEncodingType,
  299. IN LPCSTR lpszStructType,
  300. IN const BYTE *pbEncoded,
  301. IN DWORD cbEncoded,
  302. IN DWORD dwFlags,
  303. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  304. OUT OPTIONAL void *pvStructInfo,
  305. IN OUT DWORD *pcbStructInfo
  306. );
  307. //+-------------------------------------------------------------------------
  308. // ASN1 ASN.1 PKCS#1 RSAPublicKey Encode / Decode functions
  309. //--------------------------------------------------------------------------
  310. BOOL WINAPI Asn1RSAPublicKeyStrucEncodeEx(
  311. IN DWORD dwCertEncodingType,
  312. IN LPCSTR lpszStructType,
  313. IN PUBLICKEYSTRUC *pPubKeyStruc,
  314. IN DWORD dwFlags,
  315. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  316. OUT OPTIONAL void *pvEncoded,
  317. IN OUT DWORD *pcbEncoded
  318. );
  319. BOOL WINAPI Asn1RSAPublicKeyStrucDecodeEx(
  320. IN DWORD dwCertEncodingType,
  321. IN LPCSTR lpszStructType,
  322. IN const BYTE *pbEncoded,
  323. IN DWORD cbEncoded,
  324. IN DWORD dwFlags,
  325. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  326. OUT OPTIONAL void *pvStructInfo,
  327. IN OUT DWORD *pcbStructInfo
  328. );
  329. //+-------------------------------------------------------------------------
  330. // ASN1 X509 v3 Extension ASN.1 Encode / Decode functions
  331. //--------------------------------------------------------------------------
  332. BOOL WINAPI Asn1X509AuthorityKeyIdEncodeEx(
  333. IN DWORD dwCertEncodingType,
  334. IN LPCSTR lpszStructType,
  335. IN PCERT_AUTHORITY_KEY_ID_INFO pInfo,
  336. IN DWORD dwFlags,
  337. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  338. OUT OPTIONAL void *pvEncoded,
  339. IN OUT DWORD *pcbEncoded
  340. );
  341. BOOL WINAPI Asn1X509AuthorityKeyIdDecodeEx(
  342. IN DWORD dwCertEncodingType,
  343. IN LPCSTR lpszStructType,
  344. IN const BYTE *pbEncoded,
  345. IN DWORD cbEncoded,
  346. IN DWORD dwFlags,
  347. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  348. OUT OPTIONAL void *pvStructInfo,
  349. IN OUT DWORD *pcbStructInfo
  350. );
  351. BOOL WINAPI Asn1X509AuthorityKeyId2EncodeEx(
  352. IN DWORD dwCertEncodingType,
  353. IN LPCSTR lpszStructType,
  354. IN PCERT_AUTHORITY_KEY_ID2_INFO pInfo,
  355. IN DWORD dwFlags,
  356. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  357. OUT OPTIONAL void *pvEncoded,
  358. IN OUT DWORD *pcbEncoded
  359. );
  360. BOOL WINAPI Asn1X509AuthorityKeyId2DecodeEx(
  361. IN DWORD dwCertEncodingType,
  362. IN LPCSTR lpszStructType,
  363. IN const BYTE *pbEncoded,
  364. IN DWORD cbEncoded,
  365. IN DWORD dwFlags,
  366. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  367. OUT OPTIONAL void *pvStructInfo,
  368. IN OUT DWORD *pcbStructInfo
  369. );
  370. BOOL WINAPI Asn1X509KeyAttributesEncodeEx(
  371. IN DWORD dwCertEncodingType,
  372. IN LPCSTR lpszStructType,
  373. IN PCERT_KEY_ATTRIBUTES_INFO pInfo,
  374. IN DWORD dwFlags,
  375. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  376. OUT OPTIONAL void *pvEncoded,
  377. IN OUT DWORD *pcbEncoded
  378. );
  379. BOOL WINAPI Asn1X509KeyAttributesDecodeEx(
  380. IN DWORD dwCertEncodingType,
  381. IN LPCSTR lpszStructType,
  382. IN const BYTE *pbEncoded,
  383. IN DWORD cbEncoded,
  384. IN DWORD dwFlags,
  385. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  386. OUT OPTIONAL void *pvStructInfo,
  387. IN OUT DWORD *pcbStructInfo
  388. );
  389. BOOL WINAPI Asn1X509AltNameEncodeEx(
  390. IN DWORD dwCertEncodingType,
  391. IN LPCSTR lpszStructType,
  392. IN PCERT_ALT_NAME_INFO pInfo,
  393. IN DWORD dwFlags,
  394. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  395. OUT OPTIONAL void *pvEncoded,
  396. IN OUT DWORD *pcbEncoded
  397. );
  398. BOOL WINAPI Asn1X509AltNameDecodeEx(
  399. IN DWORD dwCertEncodingType,
  400. IN LPCSTR lpszStructType,
  401. IN const BYTE *pbEncoded,
  402. IN DWORD cbEncoded,
  403. IN DWORD dwFlags,
  404. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  405. OUT OPTIONAL void *pvStructInfo,
  406. IN OUT DWORD *pcbStructInfo
  407. );
  408. BOOL WINAPI Asn1X509KeyUsageRestrictionEncodeEx(
  409. IN DWORD dwCertEncodingType,
  410. IN LPCSTR lpszStructType,
  411. IN PCERT_KEY_USAGE_RESTRICTION_INFO pInfo,
  412. IN DWORD dwFlags,
  413. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  414. OUT OPTIONAL void *pvEncoded,
  415. IN OUT DWORD *pcbEncoded
  416. );
  417. BOOL WINAPI Asn1X509KeyUsageRestrictionDecodeEx(
  418. IN DWORD dwCertEncodingType,
  419. IN LPCSTR lpszStructType,
  420. IN const BYTE *pbEncoded,
  421. IN DWORD cbEncoded,
  422. IN DWORD dwFlags,
  423. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  424. OUT OPTIONAL void *pvStructInfo,
  425. IN OUT DWORD *pcbStructInfo
  426. );
  427. BOOL WINAPI Asn1X509BasicConstraintsEncodeEx(
  428. IN DWORD dwCertEncodingType,
  429. IN LPCSTR lpszStructType,
  430. IN PCERT_BASIC_CONSTRAINTS_INFO pInfo,
  431. IN DWORD dwFlags,
  432. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  433. OUT OPTIONAL void *pvEncoded,
  434. IN OUT DWORD *pcbEncoded
  435. );
  436. BOOL WINAPI Asn1X509BasicConstraintsDecodeEx(
  437. IN DWORD dwCertEncodingType,
  438. IN LPCSTR lpszStructType,
  439. IN const BYTE *pbEncoded,
  440. IN DWORD cbEncoded,
  441. IN DWORD dwFlags,
  442. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  443. OUT OPTIONAL void *pvStructInfo,
  444. IN OUT DWORD *pcbStructInfo
  445. );
  446. BOOL WINAPI Asn1X509BasicConstraints2EncodeEx(
  447. IN DWORD dwCertEncodingType,
  448. IN LPCSTR lpszStructType,
  449. IN PCERT_BASIC_CONSTRAINTS2_INFO pInfo,
  450. IN DWORD dwFlags,
  451. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  452. OUT OPTIONAL void *pvEncoded,
  453. IN OUT DWORD *pcbEncoded
  454. );
  455. BOOL WINAPI Asn1X509BasicConstraints2DecodeEx(
  456. IN DWORD dwCertEncodingType,
  457. IN LPCSTR lpszStructType,
  458. IN const BYTE *pbEncoded,
  459. IN DWORD cbEncoded,
  460. IN DWORD dwFlags,
  461. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  462. OUT OPTIONAL void *pvStructInfo,
  463. IN OUT DWORD *pcbStructInfo
  464. );
  465. BOOL WINAPI Asn1X509BitsEncodeEx(
  466. IN DWORD dwCertEncodingType,
  467. IN LPCSTR lpszStructType,
  468. IN PCRYPT_BIT_BLOB pInfo,
  469. IN DWORD dwFlags,
  470. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  471. OUT OPTIONAL void *pvEncoded,
  472. IN OUT DWORD *pcbEncoded
  473. );
  474. BOOL WINAPI Asn1X509BitsDecodeEx(
  475. IN DWORD dwCertEncodingType,
  476. IN LPCSTR lpszStructType,
  477. IN const BYTE *pbEncoded,
  478. IN DWORD cbEncoded,
  479. IN DWORD dwFlags,
  480. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  481. OUT OPTIONAL void *pvStructInfo,
  482. IN OUT DWORD *pcbStructInfo
  483. );
  484. BOOL WINAPI Asn1X509BitsWithoutTrailingZeroesEncodeEx(
  485. IN DWORD dwCertEncodingType,
  486. IN LPCSTR lpszStructType,
  487. IN PCRYPT_BIT_BLOB pInfo,
  488. IN DWORD dwFlags,
  489. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  490. OUT OPTIONAL void *pvEncoded,
  491. IN OUT DWORD *pcbEncoded
  492. );
  493. BOOL WINAPI Asn1X509CertPoliciesEncodeEx(
  494. IN DWORD dwCertEncodingType,
  495. IN LPCSTR lpszStructType,
  496. IN PCERT_POLICIES_INFO pInfo,
  497. IN DWORD dwFlags,
  498. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  499. OUT OPTIONAL void *pvEncoded,
  500. IN OUT DWORD *pcbEncoded
  501. );
  502. BOOL WINAPI Asn1X509CertPoliciesDecodeEx(
  503. IN DWORD dwCertEncodingType,
  504. IN LPCSTR lpszStructType,
  505. IN const BYTE *pbEncoded,
  506. IN DWORD cbEncoded,
  507. IN DWORD dwFlags,
  508. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  509. OUT OPTIONAL void *pvStructInfo,
  510. IN OUT DWORD *pcbStructInfo
  511. );
  512. BOOL WINAPI Asn1X509CertPoliciesQualifier1DecodeEx(
  513. IN DWORD dwCertEncodingType,
  514. IN LPCSTR lpszStructType,
  515. IN const BYTE *pbEncoded,
  516. IN DWORD cbEncoded,
  517. IN DWORD dwFlags,
  518. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  519. OUT OPTIONAL void *pvStructInfo,
  520. IN OUT DWORD *pcbStructInfo
  521. );
  522. BOOL WINAPI Asn1X509PKIXUserNoticeEncodeEx(
  523. IN DWORD dwCertEncodingType,
  524. IN LPCSTR lpszStructType,
  525. IN PCERT_POLICY_QUALIFIER_USER_NOTICE pInfo,
  526. IN DWORD dwFlags,
  527. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  528. OUT OPTIONAL void *pvEncoded,
  529. IN OUT DWORD *pcbEncoded
  530. );
  531. BOOL WINAPI Asn1X509PKIXUserNoticeDecodeEx(
  532. IN DWORD dwCertEncodingType,
  533. IN LPCSTR lpszStructType,
  534. IN const BYTE *pbEncoded,
  535. IN DWORD cbEncoded,
  536. IN DWORD dwFlags,
  537. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  538. OUT OPTIONAL void *pvStructInfo,
  539. IN OUT DWORD *pcbStructInfo
  540. );
  541. BOOL WINAPI Asn1X509AuthorityInfoAccessEncodeEx(
  542. IN DWORD dwCertEncodingType,
  543. IN LPCSTR lpszStructType,
  544. IN PCERT_AUTHORITY_INFO_ACCESS pInfo,
  545. IN DWORD dwFlags,
  546. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  547. OUT OPTIONAL void *pvEncoded,
  548. IN OUT DWORD *pcbEncoded
  549. );
  550. BOOL WINAPI Asn1X509AuthorityInfoAccessDecodeEx(
  551. IN DWORD dwCertEncodingType,
  552. IN LPCSTR lpszStructType,
  553. IN const BYTE *pbEncoded,
  554. IN DWORD cbEncoded,
  555. IN DWORD dwFlags,
  556. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  557. OUT OPTIONAL void *pvStructInfo,
  558. IN OUT DWORD *pcbStructInfo
  559. );
  560. BOOL WINAPI Asn1X509CrlDistPointsEncodeEx(
  561. IN DWORD dwCertEncodingType,
  562. IN LPCSTR lpszStructType,
  563. IN PCRL_DIST_POINTS_INFO pInfo,
  564. IN DWORD dwFlags,
  565. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  566. OUT OPTIONAL void *pvEncoded,
  567. IN OUT DWORD *pcbEncoded
  568. );
  569. BOOL WINAPI Asn1X509CrlDistPointsDecodeEx(
  570. IN DWORD dwCertEncodingType,
  571. IN LPCSTR lpszStructType,
  572. IN const BYTE *pbEncoded,
  573. IN DWORD cbEncoded,
  574. IN DWORD dwFlags,
  575. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  576. OUT OPTIONAL void *pvStructInfo,
  577. IN OUT DWORD *pcbStructInfo
  578. );
  579. BOOL WINAPI Asn1X509IntegerEncodeEx(
  580. IN DWORD dwCertEncodingType,
  581. IN LPCSTR lpszStructType,
  582. IN int *pInfo,
  583. IN DWORD dwFlags,
  584. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  585. OUT OPTIONAL void *pvEncoded,
  586. IN OUT DWORD *pcbEncoded
  587. );
  588. BOOL WINAPI Asn1X509IntegerDecodeEx(
  589. IN DWORD dwCertEncodingType,
  590. IN LPCSTR lpszStructType,
  591. IN const BYTE *pbEncoded,
  592. IN DWORD cbEncoded,
  593. IN DWORD dwFlags,
  594. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  595. OUT OPTIONAL void *pvStructInfo,
  596. IN OUT DWORD *pcbStructInfo
  597. );
  598. BOOL WINAPI Asn1X509MultiByteIntegerEncodeEx(
  599. IN DWORD dwCertEncodingType,
  600. IN LPCSTR lpszStructType,
  601. IN PCRYPT_INTEGER_BLOB pInfo,
  602. IN DWORD dwFlags,
  603. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  604. OUT OPTIONAL void *pvEncoded,
  605. IN OUT DWORD *pcbEncoded
  606. );
  607. BOOL WINAPI Asn1X509MultiByteIntegerDecodeEx(
  608. IN DWORD dwCertEncodingType,
  609. IN LPCSTR lpszStructType,
  610. IN const BYTE *pbEncoded,
  611. IN DWORD cbEncoded,
  612. IN DWORD dwFlags,
  613. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  614. OUT OPTIONAL void *pvStructInfo,
  615. IN OUT DWORD *pcbStructInfo
  616. );
  617. BOOL WINAPI Asn1X509EnumeratedEncodeEx(
  618. IN DWORD dwCertEncodingType,
  619. IN LPCSTR lpszStructType,
  620. IN int *pInfo,
  621. IN DWORD dwFlags,
  622. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  623. OUT OPTIONAL void *pvEncoded,
  624. IN OUT DWORD *pcbEncoded
  625. );
  626. BOOL WINAPI Asn1X509EnumeratedDecodeEx(
  627. IN DWORD dwCertEncodingType,
  628. IN LPCSTR lpszStructType,
  629. IN const BYTE *pbEncoded,
  630. IN DWORD cbEncoded,
  631. IN DWORD dwFlags,
  632. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  633. OUT OPTIONAL void *pvStructInfo,
  634. IN OUT DWORD *pcbStructInfo
  635. );
  636. BOOL WINAPI Asn1X509OctetStringEncodeEx(
  637. IN DWORD dwCertEncodingType,
  638. IN LPCSTR lpszStructType,
  639. IN PCRYPT_DATA_BLOB pInfo,
  640. IN DWORD dwFlags,
  641. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  642. OUT OPTIONAL void *pvEncoded,
  643. IN OUT DWORD *pcbEncoded
  644. );
  645. BOOL WINAPI Asn1X509OctetStringDecodeEx(
  646. IN DWORD dwCertEncodingType,
  647. IN LPCSTR lpszStructType,
  648. IN const BYTE *pbEncoded,
  649. IN DWORD cbEncoded,
  650. IN DWORD dwFlags,
  651. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  652. OUT OPTIONAL void *pvStructInfo,
  653. IN OUT DWORD *pcbStructInfo
  654. );
  655. BOOL WINAPI Asn1X509ChoiceOfTimeEncodeEx(
  656. IN DWORD dwCertEncodingType,
  657. IN LPCSTR lpszStructType,
  658. IN LPFILETIME pInfo,
  659. IN DWORD dwFlags,
  660. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  661. OUT OPTIONAL void *pvEncoded,
  662. IN OUT DWORD *pcbEncoded
  663. );
  664. BOOL WINAPI Asn1X509ChoiceOfTimeDecodeEx(
  665. IN DWORD dwCertEncodingType,
  666. IN LPCSTR lpszStructType,
  667. IN const BYTE *pbEncoded,
  668. IN DWORD cbEncoded,
  669. IN DWORD dwFlags,
  670. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  671. OUT OPTIONAL void *pvStructInfo,
  672. IN OUT DWORD *pcbStructInfo
  673. );
  674. BOOL WINAPI Asn1X509AttributeEncodeEx(
  675. IN DWORD dwCertEncodingType,
  676. IN LPCSTR lpszStructType,
  677. IN PCRYPT_ATTRIBUTE pInfo,
  678. IN DWORD dwFlags,
  679. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  680. OUT OPTIONAL void *pvEncoded,
  681. IN OUT DWORD *pcbEncoded
  682. );
  683. BOOL WINAPI Asn1X509AttributeDecodeEx(
  684. IN DWORD dwCertEncodingType,
  685. IN LPCSTR lpszStructType,
  686. IN const BYTE *pbEncoded,
  687. IN DWORD cbEncoded,
  688. IN DWORD dwFlags,
  689. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  690. OUT OPTIONAL void *pvStructInfo,
  691. IN OUT DWORD *pcbStructInfo
  692. );
  693. BOOL WINAPI Asn1X509ContentInfoSequenceOfAnyEncodeEx(
  694. IN DWORD dwCertEncodingType,
  695. IN LPCSTR lpszStructType,
  696. IN PCRYPT_CONTENT_INFO_SEQUENCE_OF_ANY pInfo,
  697. IN DWORD dwFlags,
  698. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  699. OUT OPTIONAL void *pvEncoded,
  700. IN OUT DWORD *pcbEncoded
  701. );
  702. BOOL WINAPI Asn1X509ContentInfoSequenceOfAnyDecodeEx(
  703. IN DWORD dwCertEncodingType,
  704. IN LPCSTR lpszStructType,
  705. IN const BYTE *pbEncoded,
  706. IN DWORD cbEncoded,
  707. IN DWORD dwFlags,
  708. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  709. OUT OPTIONAL void *pvStructInfo,
  710. IN OUT DWORD *pcbStructInfo
  711. );
  712. BOOL WINAPI Asn1X509ContentInfoEncodeEx(
  713. IN DWORD dwCertEncodingType,
  714. IN LPCSTR lpszStructType,
  715. IN PCRYPT_CONTENT_INFO pInfo,
  716. IN DWORD dwFlags,
  717. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  718. OUT OPTIONAL void *pvEncoded,
  719. IN OUT DWORD *pcbEncoded
  720. );
  721. BOOL WINAPI Asn1X509ContentInfoDecodeEx(
  722. IN DWORD dwCertEncodingType,
  723. IN LPCSTR lpszStructType,
  724. IN const BYTE *pbEncoded,
  725. IN DWORD cbEncoded,
  726. IN DWORD dwFlags,
  727. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  728. OUT OPTIONAL void *pvStructInfo,
  729. IN OUT DWORD *pcbStructInfo
  730. );
  731. BOOL WINAPI Asn1X509SequenceOfAnyEncodeEx(
  732. IN DWORD dwCertEncodingType,
  733. IN LPCSTR lpszStructType,
  734. IN PCRYPT_SEQUENCE_OF_ANY pInfo,
  735. IN DWORD dwFlags,
  736. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  737. OUT OPTIONAL void *pvEncoded,
  738. IN OUT DWORD *pcbEncoded
  739. );
  740. BOOL WINAPI Asn1X509SequenceOfAnyDecodeEx(
  741. IN DWORD dwCertEncodingType,
  742. IN LPCSTR lpszStructType,
  743. IN const BYTE *pbEncoded,
  744. IN DWORD cbEncoded,
  745. IN DWORD dwFlags,
  746. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  747. OUT OPTIONAL void *pvStructInfo,
  748. IN OUT DWORD *pcbStructInfo
  749. );
  750. BOOL WINAPI Asn1X509MultiByteUINTEncodeEx(
  751. IN DWORD dwCertEncodingType,
  752. IN LPCSTR lpszStructType,
  753. IN PCRYPT_UINT_BLOB pInfo,
  754. IN DWORD dwFlags,
  755. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  756. OUT OPTIONAL void *pvEncoded,
  757. IN OUT DWORD *pcbEncoded
  758. );
  759. BOOL WINAPI Asn1X509MultiByteUINTDecodeEx(
  760. IN DWORD dwCertEncodingType,
  761. IN LPCSTR lpszStructType,
  762. IN const BYTE *pbEncoded,
  763. IN DWORD cbEncoded,
  764. IN DWORD dwFlags,
  765. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  766. OUT OPTIONAL void *pvStructInfo,
  767. IN OUT DWORD *pcbStructInfo
  768. );
  769. BOOL WINAPI Asn1X509DSSParametersEncodeEx(
  770. IN DWORD dwCertEncodingType,
  771. IN LPCSTR lpszStructType,
  772. IN PCERT_DSS_PARAMETERS pInfo,
  773. IN DWORD dwFlags,
  774. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  775. OUT OPTIONAL void *pvEncoded,
  776. IN OUT DWORD *pcbEncoded
  777. );
  778. BOOL WINAPI Asn1X509DSSParametersDecodeEx(
  779. IN DWORD dwCertEncodingType,
  780. IN LPCSTR lpszStructType,
  781. IN const BYTE *pbEncoded,
  782. IN DWORD cbEncoded,
  783. IN DWORD dwFlags,
  784. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  785. OUT OPTIONAL void *pvStructInfo,
  786. IN OUT DWORD *pcbStructInfo
  787. );
  788. BOOL WINAPI Asn1X509DSSSignatureEncodeEx(
  789. IN DWORD dwCertEncodingType,
  790. IN LPCSTR lpszStructType,
  791. IN BYTE rgbSignature[CERT_DSS_SIGNATURE_LEN],
  792. IN DWORD dwFlags,
  793. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  794. OUT OPTIONAL void *pvEncoded,
  795. IN OUT DWORD *pcbEncoded
  796. );
  797. BOOL WINAPI Asn1X509DSSSignatureDecodeEx(
  798. IN DWORD dwCertEncodingType,
  799. IN LPCSTR lpszStructType,
  800. IN const BYTE *pbEncoded,
  801. IN DWORD cbEncoded,
  802. IN DWORD dwFlags,
  803. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  804. OUT OPTIONAL void *pvStructInfo,
  805. IN OUT DWORD *pcbStructInfo
  806. );
  807. BOOL WINAPI Asn1X509DHParametersEncodeEx(
  808. IN DWORD dwCertEncodingType,
  809. IN LPCSTR lpszStructType,
  810. IN PCERT_DH_PARAMETERS pInfo,
  811. IN DWORD dwFlags,
  812. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  813. OUT OPTIONAL void *pvEncoded,
  814. IN OUT DWORD *pcbEncoded
  815. );
  816. BOOL WINAPI Asn1X509DHParametersDecodeEx(
  817. IN DWORD dwCertEncodingType,
  818. IN LPCSTR lpszStructType,
  819. IN const BYTE *pbEncoded,
  820. IN DWORD cbEncoded,
  821. IN DWORD dwFlags,
  822. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  823. OUT OPTIONAL void *pvStructInfo,
  824. IN OUT DWORD *pcbStructInfo
  825. );
  826. BOOL WINAPI Asn1X942DhParametersEncodeEx(
  827. IN DWORD dwCertEncodingType,
  828. IN LPCSTR lpszStructType,
  829. IN PCERT_X942_DH_PARAMETERS pInfo,
  830. IN DWORD dwFlags,
  831. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  832. OUT OPTIONAL void *pvEncoded,
  833. IN OUT DWORD *pcbEncoded
  834. );
  835. BOOL WINAPI Asn1X942DhParametersDecodeEx(
  836. IN DWORD dwCertEncodingType,
  837. IN LPCSTR lpszStructType,
  838. IN const BYTE *pbEncoded,
  839. IN DWORD cbEncoded,
  840. IN DWORD dwFlags,
  841. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  842. OUT OPTIONAL void *pvStructInfo,
  843. IN OUT DWORD *pcbStructInfo
  844. );
  845. BOOL WINAPI Asn1X942OtherInfoEncodeEx(
  846. IN DWORD dwCertEncodingType,
  847. IN LPCSTR lpszStructType,
  848. IN PCRYPT_X942_OTHER_INFO pInfo,
  849. IN DWORD dwFlags,
  850. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  851. OUT OPTIONAL void *pvEncoded,
  852. IN OUT DWORD *pcbEncoded
  853. );
  854. BOOL WINAPI Asn1X942OtherInfoDecodeEx(
  855. IN DWORD dwCertEncodingType,
  856. IN LPCSTR lpszStructType,
  857. IN const BYTE *pbEncoded,
  858. IN DWORD cbEncoded,
  859. IN DWORD dwFlags,
  860. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  861. OUT OPTIONAL void *pvStructInfo,
  862. IN OUT DWORD *pcbStructInfo
  863. );
  864. BOOL WINAPI Asn1RC2CBCParametersEncodeEx(
  865. IN DWORD dwCertEncodingType,
  866. IN LPCSTR lpszStructType,
  867. IN PCRYPT_RC2_CBC_PARAMETERS pInfo,
  868. IN DWORD dwFlags,
  869. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  870. OUT OPTIONAL void *pvEncoded,
  871. IN OUT DWORD *pcbEncoded
  872. );
  873. BOOL WINAPI Asn1RC2CBCParametersDecodeEx(
  874. IN DWORD dwCertEncodingType,
  875. IN LPCSTR lpszStructType,
  876. IN const BYTE *pbEncoded,
  877. IN DWORD cbEncoded,
  878. IN DWORD dwFlags,
  879. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  880. OUT OPTIONAL void *pvStructInfo,
  881. IN OUT DWORD *pcbStructInfo
  882. );
  883. BOOL WINAPI Asn1SMIMECapabilitiesEncodeEx(
  884. IN DWORD dwCertEncodingType,
  885. IN LPCSTR lpszStructType,
  886. IN PCRYPT_SMIME_CAPABILITIES pInfo,
  887. IN DWORD dwFlags,
  888. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  889. OUT OPTIONAL void *pvEncoded,
  890. IN OUT DWORD *pcbEncoded
  891. );
  892. BOOL WINAPI Asn1SMIMECapabilitiesDecodeEx(
  893. IN DWORD dwCertEncodingType,
  894. IN LPCSTR lpszStructType,
  895. IN const BYTE *pbEncoded,
  896. IN DWORD cbEncoded,
  897. IN DWORD dwFlags,
  898. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  899. OUT OPTIONAL void *pvStructInfo,
  900. IN OUT DWORD *pcbStructInfo
  901. );
  902. BOOL WINAPI Asn1UtcTimeEncodeEx(
  903. IN DWORD dwCertEncodingType,
  904. IN LPCSTR lpszStructType,
  905. IN FILETIME * pFileTime,
  906. IN DWORD dwFlags,
  907. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  908. OUT OPTIONAL void *pvEncoded,
  909. IN OUT DWORD *pcbEncoded
  910. );
  911. BOOL WINAPI Asn1UtcTimeDecodeEx(
  912. IN DWORD dwCertEncodingType,
  913. IN LPCSTR lpszStructType,
  914. IN const BYTE *pbEncoded,
  915. IN DWORD cbEncoded,
  916. IN DWORD dwFlags,
  917. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  918. OUT OPTIONAL void *pvStructInfo,
  919. IN OUT DWORD *pcbStructInfo
  920. );
  921. BOOL WINAPI Asn1TimeStampRequestInfoEncodeEx(
  922. IN DWORD dwCertEncodingType,
  923. IN LPCSTR lpszStructType,
  924. IN PCRYPT_TIME_STAMP_REQUEST_INFO pInfo,
  925. IN DWORD dwFlags,
  926. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  927. OUT OPTIONAL void *pvEncoded,
  928. IN OUT DWORD *pcbEncoded
  929. );
  930. BOOL WINAPI Asn1TimeStampRequestInfoDecodeEx(
  931. IN DWORD dwCertEncodingType,
  932. IN LPCSTR lpszStructType,
  933. IN const BYTE *pbEncoded,
  934. IN DWORD cbEncoded,
  935. IN DWORD dwFlags,
  936. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  937. OUT OPTIONAL void *pvStructInfo,
  938. IN OUT DWORD *pcbStructInfo
  939. );
  940. BOOL WINAPI Asn1X509AttributesEncodeEx(
  941. IN DWORD dwCertEncodingType,
  942. IN LPCSTR lpszStructType,
  943. IN PCRYPT_ATTRIBUTES pInfo,
  944. IN DWORD dwFlags,
  945. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  946. OUT OPTIONAL void *pvEncoded,
  947. IN OUT DWORD *pcbEncoded
  948. );
  949. BOOL WINAPI Asn1X509AttributesDecodeEx(
  950. IN DWORD dwCertEncodingType,
  951. IN LPCSTR lpszStructType,
  952. IN const BYTE *pbEncoded,
  953. IN DWORD cbEncoded,
  954. IN DWORD dwFlags,
  955. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  956. OUT OPTIONAL void *pvStructInfo,
  957. IN OUT DWORD *pcbStructInfo
  958. );
  959. //+-------------------------------------------------------------------------
  960. // ASN1 X509 Certificate Trust List (CTL) ASN.1 Encode / Decode functions
  961. //--------------------------------------------------------------------------
  962. BOOL WINAPI Asn1X509CtlUsageEncodeEx(
  963. IN DWORD dwCertEncodingType,
  964. IN LPCSTR lpszStructType,
  965. IN PCTL_USAGE pInfo,
  966. IN DWORD dwFlags,
  967. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  968. OUT OPTIONAL void *pvEncoded,
  969. IN OUT DWORD *pcbEncoded
  970. );
  971. BOOL WINAPI Asn1X509CtlUsageDecodeEx(
  972. IN DWORD dwCertEncodingType,
  973. IN LPCSTR lpszStructType,
  974. IN const BYTE *pbEncoded,
  975. IN DWORD cbEncoded,
  976. IN DWORD dwFlags,
  977. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  978. OUT OPTIONAL void *pvStructInfo,
  979. IN OUT DWORD *pcbStructInfo
  980. );
  981. BOOL WINAPI Asn1X509CtlInfoEncodeEx(
  982. IN DWORD dwCertEncodingType,
  983. IN LPCSTR lpszStructType,
  984. IN PCTL_INFO pInfo,
  985. IN DWORD dwFlags,
  986. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  987. OUT OPTIONAL void *pvEncoded,
  988. IN OUT DWORD *pcbEncoded
  989. );
  990. BOOL WINAPI Asn1X509CtlInfoDecodeEx(
  991. IN DWORD dwCertEncodingType,
  992. IN LPCSTR lpszStructType,
  993. IN const BYTE *pbEncoded,
  994. IN DWORD cbEncoded,
  995. IN DWORD dwFlags,
  996. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  997. OUT OPTIONAL void *pvStructInfo,
  998. IN OUT DWORD *pcbStructInfo
  999. );
  1000. BOOL WINAPI Asn1X509CertPairEncodeEx(
  1001. IN DWORD dwCertEncodingType,
  1002. IN LPCSTR lpszStructType,
  1003. IN PCERT_PAIR pInfo,
  1004. IN DWORD dwFlags,
  1005. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  1006. OUT OPTIONAL void *pvEncoded,
  1007. IN OUT DWORD *pcbEncoded
  1008. );
  1009. BOOL WINAPI Asn1X509CertPairDecodeEx(
  1010. IN DWORD dwCertEncodingType,
  1011. IN LPCSTR lpszStructType,
  1012. IN const BYTE *pbEncoded,
  1013. IN DWORD cbEncoded,
  1014. IN DWORD dwFlags,
  1015. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  1016. OUT OPTIONAL void *pvStructInfo,
  1017. IN OUT DWORD *pcbStructInfo
  1018. );
  1019. BOOL WINAPI Asn1X509NameConstraintsEncodeEx(
  1020. IN DWORD dwCertEncodingType,
  1021. IN LPCSTR lpszStructType,
  1022. IN PCERT_NAME_CONSTRAINTS_INFO pInfo,
  1023. IN DWORD dwFlags,
  1024. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  1025. OUT OPTIONAL void *pvEncoded,
  1026. IN OUT DWORD *pcbEncoded
  1027. );
  1028. BOOL WINAPI Asn1X509NameConstraintsDecodeEx(
  1029. IN DWORD dwCertEncodingType,
  1030. IN LPCSTR lpszStructType,
  1031. IN const BYTE *pbEncoded,
  1032. IN DWORD cbEncoded,
  1033. IN DWORD dwFlags,
  1034. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  1035. OUT OPTIONAL void *pvStructInfo,
  1036. IN OUT DWORD *pcbStructInfo
  1037. );
  1038. BOOL WINAPI Asn1X509CrlIssuingDistPointEncodeEx(
  1039. IN DWORD dwCertEncodingType,
  1040. IN LPCSTR lpszStructType,
  1041. IN PCRL_ISSUING_DIST_POINT pInfo,
  1042. IN DWORD dwFlags,
  1043. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  1044. OUT OPTIONAL void *pvEncoded,
  1045. IN OUT DWORD *pcbEncoded
  1046. );
  1047. BOOL WINAPI Asn1X509CrlIssuingDistPointDecodeEx(
  1048. IN DWORD dwCertEncodingType,
  1049. IN LPCSTR lpszStructType,
  1050. IN const BYTE *pbEncoded,
  1051. IN DWORD cbEncoded,
  1052. IN DWORD dwFlags,
  1053. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  1054. OUT OPTIONAL void *pvStructInfo,
  1055. IN OUT DWORD *pcbStructInfo
  1056. );
  1057. BOOL WINAPI Asn1X509PolicyMappingsEncodeEx(
  1058. IN DWORD dwCertEncodingType,
  1059. IN LPCSTR lpszStructType,
  1060. IN PCERT_POLICY_MAPPINGS_INFO pInfo,
  1061. IN DWORD dwFlags,
  1062. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  1063. OUT OPTIONAL void *pvEncoded,
  1064. IN OUT DWORD *pcbEncoded
  1065. );
  1066. BOOL WINAPI Asn1X509PolicyMappingsDecodeEx(
  1067. IN DWORD dwCertEncodingType,
  1068. IN LPCSTR lpszStructType,
  1069. IN const BYTE *pbEncoded,
  1070. IN DWORD cbEncoded,
  1071. IN DWORD dwFlags,
  1072. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  1073. OUT OPTIONAL void *pvStructInfo,
  1074. IN OUT DWORD *pcbStructInfo
  1075. );
  1076. BOOL WINAPI Asn1X509PolicyConstraintsEncodeEx(
  1077. IN DWORD dwCertEncodingType,
  1078. IN LPCSTR lpszStructType,
  1079. IN PCERT_POLICY_CONSTRAINTS_INFO pInfo,
  1080. IN DWORD dwFlags,
  1081. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  1082. OUT OPTIONAL void *pvEncoded,
  1083. IN OUT DWORD *pcbEncoded
  1084. );
  1085. BOOL WINAPI Asn1X509PolicyConstraintsDecodeEx(
  1086. IN DWORD dwCertEncodingType,
  1087. IN LPCSTR lpszStructType,
  1088. IN const BYTE *pbEncoded,
  1089. IN DWORD cbEncoded,
  1090. IN DWORD dwFlags,
  1091. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  1092. OUT OPTIONAL void *pvStructInfo,
  1093. IN OUT DWORD *pcbStructInfo
  1094. );
  1095. BOOL WINAPI Asn1X509CrossCertDistPointsEncodeEx(
  1096. IN DWORD dwCertEncodingType,
  1097. IN LPCSTR lpszStructType,
  1098. IN PCROSS_CERT_DIST_POINTS_INFO pInfo,
  1099. IN DWORD dwFlags,
  1100. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  1101. OUT OPTIONAL void *pvEncoded,
  1102. IN OUT DWORD *pcbEncoded
  1103. );
  1104. BOOL WINAPI Asn1X509CrossCertDistPointsDecodeEx(
  1105. IN DWORD dwCertEncodingType,
  1106. IN LPCSTR lpszStructType,
  1107. IN const BYTE *pbEncoded,
  1108. IN DWORD cbEncoded,
  1109. IN DWORD dwFlags,
  1110. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  1111. OUT OPTIONAL void *pvStructInfo,
  1112. IN OUT DWORD *pcbStructInfo
  1113. );
  1114. //+=========================================================================
  1115. // Certificate Management Messages over CMS (CMC) Encode/Decode Functions
  1116. //==========================================================================
  1117. BOOL WINAPI Asn1CmcDataEncodeEx(
  1118. IN DWORD dwCertEncodingType,
  1119. IN LPCSTR lpszStructType,
  1120. IN PCMC_DATA_INFO pInfo,
  1121. IN DWORD dwFlags,
  1122. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  1123. OUT OPTIONAL void *pvEncoded,
  1124. IN OUT DWORD *pcbEncoded
  1125. );
  1126. BOOL WINAPI Asn1CmcDataDecodeEx(
  1127. IN DWORD dwCertEncodingType,
  1128. IN LPCSTR lpszStructType,
  1129. IN const BYTE *pbEncoded,
  1130. IN DWORD cbEncoded,
  1131. IN DWORD dwFlags,
  1132. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  1133. OUT OPTIONAL void *pvStructInfo,
  1134. IN OUT DWORD *pcbStructInfo
  1135. );
  1136. BOOL WINAPI Asn1CmcResponseEncodeEx(
  1137. IN DWORD dwCertEncodingType,
  1138. IN LPCSTR lpszStructType,
  1139. IN PCMC_RESPONSE_INFO pInfo,
  1140. IN DWORD dwFlags,
  1141. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  1142. OUT OPTIONAL void *pvEncoded,
  1143. IN OUT DWORD *pcbEncoded
  1144. );
  1145. BOOL WINAPI Asn1CmcResponseDecodeEx(
  1146. IN DWORD dwCertEncodingType,
  1147. IN LPCSTR lpszStructType,
  1148. IN const BYTE *pbEncoded,
  1149. IN DWORD cbEncoded,
  1150. IN DWORD dwFlags,
  1151. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  1152. OUT OPTIONAL void *pvStructInfo,
  1153. IN OUT DWORD *pcbStructInfo
  1154. );
  1155. BOOL WINAPI Asn1CmcStatusEncodeEx(
  1156. IN DWORD dwCertEncodingType,
  1157. IN LPCSTR lpszStructType,
  1158. IN PCMC_STATUS_INFO pInfo,
  1159. IN DWORD dwFlags,
  1160. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  1161. OUT OPTIONAL void *pvEncoded,
  1162. IN OUT DWORD *pcbEncoded
  1163. );
  1164. BOOL WINAPI Asn1CmcStatusDecodeEx(
  1165. IN DWORD dwCertEncodingType,
  1166. IN LPCSTR lpszStructType,
  1167. IN const BYTE *pbEncoded,
  1168. IN DWORD cbEncoded,
  1169. IN DWORD dwFlags,
  1170. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  1171. OUT OPTIONAL void *pvStructInfo,
  1172. IN OUT DWORD *pcbStructInfo
  1173. );
  1174. BOOL WINAPI Asn1CmcAddExtensionsEncodeEx(
  1175. IN DWORD dwCertEncodingType,
  1176. IN LPCSTR lpszStructType,
  1177. IN PCMC_ADD_EXTENSIONS_INFO pInfo,
  1178. IN DWORD dwFlags,
  1179. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  1180. OUT OPTIONAL void *pvEncoded,
  1181. IN OUT DWORD *pcbEncoded
  1182. );
  1183. BOOL WINAPI Asn1CmcAddExtensionsDecodeEx(
  1184. IN DWORD dwCertEncodingType,
  1185. IN LPCSTR lpszStructType,
  1186. IN const BYTE *pbEncoded,
  1187. IN DWORD cbEncoded,
  1188. IN DWORD dwFlags,
  1189. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  1190. OUT OPTIONAL void *pvStructInfo,
  1191. IN OUT DWORD *pcbStructInfo
  1192. );
  1193. BOOL WINAPI Asn1CmcAddAttributesEncodeEx(
  1194. IN DWORD dwCertEncodingType,
  1195. IN LPCSTR lpszStructType,
  1196. IN PCMC_ADD_ATTRIBUTES_INFO pInfo,
  1197. IN DWORD dwFlags,
  1198. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  1199. OUT OPTIONAL void *pvEncoded,
  1200. IN OUT DWORD *pcbEncoded
  1201. );
  1202. BOOL WINAPI Asn1CmcAddAttributesDecodeEx(
  1203. IN DWORD dwCertEncodingType,
  1204. IN LPCSTR lpszStructType,
  1205. IN const BYTE *pbEncoded,
  1206. IN DWORD cbEncoded,
  1207. IN DWORD dwFlags,
  1208. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  1209. OUT OPTIONAL void *pvStructInfo,
  1210. IN OUT DWORD *pcbStructInfo
  1211. );
  1212. //+=========================================================================
  1213. // Certificate Template Encode/Decode Functions
  1214. //==========================================================================
  1215. BOOL WINAPI Asn1X509CertTemplateEncodeEx(
  1216. IN DWORD dwCertEncodingType,
  1217. IN LPCSTR lpszStructType,
  1218. IN PCERT_TEMPLATE_EXT pInfo,
  1219. IN DWORD dwFlags,
  1220. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  1221. OUT OPTIONAL void *pvEncoded,
  1222. IN OUT DWORD *pcbEncoded
  1223. );
  1224. BOOL WINAPI Asn1X509CertTemplateDecodeEx(
  1225. IN DWORD dwCertEncodingType,
  1226. IN LPCSTR lpszStructType,
  1227. IN const BYTE *pbEncoded,
  1228. IN DWORD cbEncoded,
  1229. IN DWORD dwFlags,
  1230. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  1231. OUT OPTIONAL void *pvStructInfo,
  1232. IN OUT DWORD *pcbStructInfo
  1233. );
  1234. #ifndef OSS_CRYPT_ASN1
  1235. //+-------------------------------------------------------------------------
  1236. // Encode / Decode the "UNICODE" Name Info
  1237. //
  1238. // from certstr.cpp
  1239. //--------------------------------------------------------------------------
  1240. extern BOOL WINAPI UnicodeNameInfoEncodeEx(
  1241. IN DWORD dwCertEncodingType,
  1242. IN LPCSTR lpszStructType,
  1243. IN PCERT_NAME_INFO pInfo,
  1244. IN DWORD dwFlags,
  1245. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  1246. OUT OPTIONAL void *pvEncoded,
  1247. IN OUT DWORD *pcbEncoded
  1248. );
  1249. extern BOOL WINAPI UnicodeNameInfoDecodeEx(
  1250. IN DWORD dwCertEncodingType,
  1251. IN LPCSTR lpszStructType,
  1252. IN const BYTE *pbEncoded,
  1253. IN DWORD cbEncoded,
  1254. IN DWORD dwFlags,
  1255. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  1256. OUT OPTIONAL void *pvStructInfo,
  1257. IN OUT DWORD *pcbStructInfo
  1258. );
  1259. //+-------------------------------------------------------------------------
  1260. // Encode / Decode the "UNICODE" Name Value
  1261. //
  1262. // from certstr.cpp
  1263. //--------------------------------------------------------------------------
  1264. extern BOOL WINAPI UnicodeNameValueEncodeEx(
  1265. IN DWORD dwCertEncodingType,
  1266. IN LPCSTR lpszStructType,
  1267. IN PCERT_NAME_VALUE pInfo,
  1268. IN DWORD dwFlags,
  1269. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  1270. OUT OPTIONAL void *pvEncoded,
  1271. IN OUT DWORD *pcbEncoded
  1272. );
  1273. extern BOOL WINAPI UnicodeNameValueDecodeEx(
  1274. IN DWORD dwCertEncodingType,
  1275. IN LPCSTR lpszStructType,
  1276. IN const BYTE *pbEncoded,
  1277. IN DWORD cbEncoded,
  1278. IN DWORD dwFlags,
  1279. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  1280. OUT OPTIONAL void *pvStructInfo,
  1281. IN OUT DWORD *pcbStructInfo
  1282. );
  1283. //+-------------------------------------------------------------------------
  1284. // Encode sorted ctl info
  1285. //
  1286. // from newstor.cpp
  1287. //--------------------------------------------------------------------------
  1288. extern BOOL WINAPI SortedCtlInfoEncodeEx(
  1289. IN DWORD dwCertEncodingType,
  1290. IN LPCSTR lpszStructType,
  1291. IN PCTL_INFO pCtlInfo,
  1292. IN DWORD dwFlags,
  1293. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  1294. OUT OPTIONAL void *pvEncoded,
  1295. IN OUT DWORD *pcbEncoded
  1296. );
  1297. #endif // OSS_CRYPT_ASN1
  1298. #ifdef OSS_CRYPT_ASN1
  1299. #define ASN1_OID_OFFSET 10000 +
  1300. #define ASN1_OID_PREFIX "OssCryptAsn1."
  1301. #else
  1302. #define ASN1_OID_OFFSET
  1303. #define ASN1_OID_PREFIX
  1304. #endif // OSS_CRYPT_ASN1
  1305. #ifdef DEBUG_CRYPT_ASN1_MASTER
  1306. #define OSS_OID_OFFSET 10000
  1307. #define OSS_OID_PREFIX "OssCryptAsn1."
  1308. #endif // DEBUG_CRYPT_ASN1_MASTER
  1309. static const CRYPT_OID_FUNC_ENTRY X509EncodeExFuncTable[] = {
  1310. ASN1_OID_OFFSET X509_CERT, Asn1X509SignedContentEncodeEx,
  1311. ASN1_OID_OFFSET X509_CERT_TO_BE_SIGNED, Asn1X509CertInfoEncodeEx,
  1312. ASN1_OID_OFFSET X509_CERT_CRL_TO_BE_SIGNED, Asn1X509CrlInfoEncodeEx,
  1313. ASN1_OID_OFFSET X509_CERT_REQUEST_TO_BE_SIGNED, Asn1X509CertRequestInfoEncodeEx,
  1314. ASN1_OID_OFFSET X509_EXTENSIONS, Asn1X509ExtensionsEncodeEx,
  1315. ASN1_OID_OFFSET X509_NAME_VALUE, Asn1X509NameValueEncodeEx,
  1316. ASN1_OID_OFFSET X509_NAME, Asn1X509NameInfoEncodeEx,
  1317. ASN1_OID_OFFSET X509_PUBLIC_KEY_INFO, Asn1X509PublicKeyInfoEncodeEx,
  1318. ASN1_OID_OFFSET X509_AUTHORITY_KEY_ID, Asn1X509AuthorityKeyIdEncodeEx,
  1319. ASN1_OID_OFFSET X509_KEY_ATTRIBUTES, Asn1X509KeyAttributesEncodeEx,
  1320. ASN1_OID_OFFSET X509_KEY_USAGE_RESTRICTION, Asn1X509KeyUsageRestrictionEncodeEx,
  1321. ASN1_OID_OFFSET X509_ALTERNATE_NAME, Asn1X509AltNameEncodeEx,
  1322. ASN1_OID_OFFSET X509_BASIC_CONSTRAINTS, Asn1X509BasicConstraintsEncodeEx,
  1323. ASN1_OID_OFFSET X509_KEY_USAGE, Asn1X509BitsWithoutTrailingZeroesEncodeEx,
  1324. ASN1_OID_OFFSET X509_BASIC_CONSTRAINTS2, Asn1X509BasicConstraints2EncodeEx,
  1325. ASN1_OID_OFFSET X509_CERT_POLICIES, Asn1X509CertPoliciesEncodeEx,
  1326. ASN1_OID_OFFSET PKCS_UTC_TIME, Asn1UtcTimeEncodeEx,
  1327. ASN1_OID_OFFSET PKCS_TIME_REQUEST, Asn1TimeStampRequestInfoEncodeEx,
  1328. ASN1_OID_OFFSET RSA_CSP_PUBLICKEYBLOB, Asn1RSAPublicKeyStrucEncodeEx,
  1329. #ifndef OSS_CRYPT_ASN1
  1330. ASN1_OID_OFFSET X509_UNICODE_NAME, UnicodeNameInfoEncodeEx,
  1331. #endif // OSS_CRYPT_ASN1
  1332. ASN1_OID_OFFSET X509_KEYGEN_REQUEST_TO_BE_SIGNED, Asn1X509KeygenRequestInfoEncodeEx,
  1333. ASN1_OID_OFFSET PKCS_ATTRIBUTE, Asn1X509AttributeEncodeEx,
  1334. ASN1_OID_OFFSET PKCS_CONTENT_INFO_SEQUENCE_OF_ANY, Asn1X509ContentInfoSequenceOfAnyEncodeEx,
  1335. #ifndef OSS_CRYPT_ASN1
  1336. ASN1_OID_OFFSET X509_UNICODE_NAME_VALUE, UnicodeNameValueEncodeEx,
  1337. #endif // OSS_CRYPT_ASN1
  1338. ASN1_OID_OFFSET X509_OCTET_STRING, Asn1X509OctetStringEncodeEx,
  1339. ASN1_OID_OFFSET X509_BITS, Asn1X509BitsEncodeEx,
  1340. ASN1_OID_OFFSET X509_INTEGER, Asn1X509IntegerEncodeEx,
  1341. ASN1_OID_OFFSET X509_MULTI_BYTE_INTEGER, Asn1X509MultiByteIntegerEncodeEx,
  1342. ASN1_OID_OFFSET X509_ENUMERATED, Asn1X509EnumeratedEncodeEx,
  1343. ASN1_OID_OFFSET X509_CHOICE_OF_TIME, Asn1X509ChoiceOfTimeEncodeEx,
  1344. ASN1_OID_OFFSET X509_AUTHORITY_KEY_ID2, Asn1X509AuthorityKeyId2EncodeEx,
  1345. ASN1_OID_OFFSET X509_AUTHORITY_INFO_ACCESS, Asn1X509AuthorityInfoAccessEncodeEx,
  1346. ASN1_OID_OFFSET PKCS_CONTENT_INFO, Asn1X509ContentInfoEncodeEx,
  1347. ASN1_OID_OFFSET X509_SEQUENCE_OF_ANY, Asn1X509SequenceOfAnyEncodeEx,
  1348. ASN1_OID_OFFSET X509_CRL_DIST_POINTS, Asn1X509CrlDistPointsEncodeEx,
  1349. ASN1_OID_OFFSET X509_ENHANCED_KEY_USAGE, Asn1X509CtlUsageEncodeEx,
  1350. ASN1_OID_OFFSET PKCS_CTL, Asn1X509CtlInfoEncodeEx,
  1351. ASN1_OID_OFFSET X509_MULTI_BYTE_UINT, Asn1X509MultiByteUINTEncodeEx,
  1352. ASN1_OID_OFFSET X509_DSS_PARAMETERS, Asn1X509DSSParametersEncodeEx,
  1353. ASN1_OID_OFFSET X509_DSS_SIGNATURE, Asn1X509DSSSignatureEncodeEx,
  1354. ASN1_OID_OFFSET PKCS_RC2_CBC_PARAMETERS, Asn1RC2CBCParametersEncodeEx,
  1355. ASN1_OID_OFFSET PKCS_SMIME_CAPABILITIES, Asn1SMIMECapabilitiesEncodeEx,
  1356. ASN1_OID_PREFIX X509_PKIX_POLICY_QUALIFIER_USERNOTICE, Asn1X509PKIXUserNoticeEncodeEx,
  1357. ASN1_OID_OFFSET X509_DH_PARAMETERS, Asn1X509DHParametersEncodeEx,
  1358. ASN1_OID_OFFSET PKCS_ATTRIBUTES, Asn1X509AttributesEncodeEx,
  1359. #ifndef OSS_CRYPT_ASN1
  1360. ASN1_OID_OFFSET PKCS_SORTED_CTL, SortedCtlInfoEncodeEx,
  1361. #endif // OSS_CRYPT_ASN1
  1362. ASN1_OID_OFFSET X942_DH_PARAMETERS, Asn1X942DhParametersEncodeEx,
  1363. ASN1_OID_OFFSET X509_BITS_WITHOUT_TRAILING_ZEROES, Asn1X509BitsWithoutTrailingZeroesEncodeEx,
  1364. ASN1_OID_OFFSET X942_OTHER_INFO, Asn1X942OtherInfoEncodeEx,
  1365. ASN1_OID_OFFSET X509_CERT_PAIR, Asn1X509CertPairEncodeEx,
  1366. ASN1_OID_OFFSET X509_ISSUING_DIST_POINT, Asn1X509CrlIssuingDistPointEncodeEx,
  1367. ASN1_OID_OFFSET X509_NAME_CONSTRAINTS, Asn1X509NameConstraintsEncodeEx,
  1368. ASN1_OID_OFFSET X509_POLICY_MAPPINGS, Asn1X509PolicyMappingsEncodeEx,
  1369. ASN1_OID_OFFSET X509_POLICY_CONSTRAINTS, Asn1X509PolicyConstraintsEncodeEx,
  1370. ASN1_OID_OFFSET X509_CROSS_CERT_DIST_POINTS, Asn1X509CrossCertDistPointsEncodeEx,
  1371. ASN1_OID_OFFSET CMC_DATA, Asn1CmcDataEncodeEx,
  1372. ASN1_OID_OFFSET CMC_RESPONSE, Asn1CmcResponseEncodeEx,
  1373. ASN1_OID_OFFSET CMC_STATUS, Asn1CmcStatusEncodeEx,
  1374. ASN1_OID_OFFSET CMC_ADD_EXTENSIONS, Asn1CmcAddExtensionsEncodeEx,
  1375. ASN1_OID_OFFSET CMC_ADD_ATTRIBUTES, Asn1CmcAddAttributesEncodeEx,
  1376. ASN1_OID_OFFSET X509_CERTIFICATE_TEMPLATE, Asn1X509CertTemplateEncodeEx,
  1377. ASN1_OID_PREFIX szOID_AUTHORITY_KEY_IDENTIFIER, Asn1X509AuthorityKeyIdEncodeEx,
  1378. ASN1_OID_PREFIX szOID_KEY_ATTRIBUTES, Asn1X509KeyAttributesEncodeEx,
  1379. ASN1_OID_PREFIX szOID_KEY_USAGE_RESTRICTION, Asn1X509KeyUsageRestrictionEncodeEx,
  1380. ASN1_OID_PREFIX szOID_SUBJECT_ALT_NAME, Asn1X509AltNameEncodeEx,
  1381. ASN1_OID_PREFIX szOID_ISSUER_ALT_NAME, Asn1X509AltNameEncodeEx,
  1382. ASN1_OID_PREFIX szOID_BASIC_CONSTRAINTS, Asn1X509BasicConstraintsEncodeEx,
  1383. ASN1_OID_PREFIX szOID_KEY_USAGE, Asn1X509BitsWithoutTrailingZeroesEncodeEx,
  1384. ASN1_OID_PREFIX szOID_BASIC_CONSTRAINTS2, Asn1X509BasicConstraints2EncodeEx,
  1385. ASN1_OID_PREFIX szOID_CERT_POLICIES, Asn1X509CertPoliciesEncodeEx,
  1386. ASN1_OID_PREFIX szOID_PKIX_POLICY_QUALIFIER_USERNOTICE, Asn1X509PKIXUserNoticeEncodeEx,
  1387. ASN1_OID_PREFIX szOID_AUTHORITY_KEY_IDENTIFIER2, Asn1X509AuthorityKeyId2EncodeEx,
  1388. ASN1_OID_PREFIX szOID_SUBJECT_KEY_IDENTIFIER, Asn1X509OctetStringEncodeEx,
  1389. ASN1_OID_PREFIX szOID_SUBJECT_ALT_NAME2, Asn1X509AltNameEncodeEx,
  1390. ASN1_OID_PREFIX szOID_ISSUER_ALT_NAME2, Asn1X509AltNameEncodeEx,
  1391. ASN1_OID_PREFIX szOID_CRL_REASON_CODE, Asn1X509EnumeratedEncodeEx,
  1392. ASN1_OID_PREFIX szOID_AUTHORITY_INFO_ACCESS, Asn1X509AuthorityInfoAccessEncodeEx,
  1393. ASN1_OID_PREFIX szOID_CRL_DIST_POINTS, Asn1X509CrlDistPointsEncodeEx,
  1394. ASN1_OID_PREFIX szOID_CERT_EXTENSIONS, Asn1X509ExtensionsEncodeEx,
  1395. ASN1_OID_PREFIX szOID_RSA_certExtensions, Asn1X509ExtensionsEncodeEx,
  1396. ASN1_OID_PREFIX szOID_NEXT_UPDATE_LOCATION, Asn1X509AltNameEncodeEx,
  1397. ASN1_OID_PREFIX szOID_ENHANCED_KEY_USAGE, Asn1X509CtlUsageEncodeEx,
  1398. ASN1_OID_PREFIX szOID_CTL, Asn1X509CtlInfoEncodeEx,
  1399. ASN1_OID_PREFIX szOID_RSA_RC2CBC, Asn1RC2CBCParametersEncodeEx,
  1400. ASN1_OID_PREFIX szOID_RSA_SMIMECapabilities, Asn1SMIMECapabilitiesEncodeEx,
  1401. ASN1_OID_PREFIX szOID_RSA_signingTime, Asn1UtcTimeEncodeEx,
  1402. ASN1_OID_PREFIX szOID_ENROLLMENT_NAME_VALUE_PAIR, Asn1NameValueEncodeEx,
  1403. szOID_ENROLLMENT_CSP_PROVIDER, Asn1CSPProviderEncodeEx,
  1404. ASN1_OID_OFFSET szOID_CRL_NUMBER, Asn1X509IntegerEncodeEx,
  1405. ASN1_OID_OFFSET szOID_DELTA_CRL_INDICATOR, Asn1X509IntegerEncodeEx,
  1406. ASN1_OID_OFFSET szOID_ISSUING_DIST_POINT, Asn1X509CrlIssuingDistPointEncodeEx,
  1407. ASN1_OID_PREFIX szOID_FRESHEST_CRL, Asn1X509CrlDistPointsEncodeEx,
  1408. ASN1_OID_OFFSET szOID_NAME_CONSTRAINTS, Asn1X509NameConstraintsEncodeEx,
  1409. ASN1_OID_OFFSET szOID_POLICY_MAPPINGS, Asn1X509PolicyMappingsEncodeEx,
  1410. ASN1_OID_OFFSET szOID_LEGACY_POLICY_MAPPINGS, Asn1X509PolicyMappingsEncodeEx,
  1411. ASN1_OID_OFFSET szOID_POLICY_CONSTRAINTS, Asn1X509PolicyConstraintsEncodeEx,
  1412. ASN1_OID_OFFSET szOID_CROSS_CERT_DIST_POINTS, Asn1X509CrossCertDistPointsEncodeEx,
  1413. ASN1_OID_OFFSET szOID_CERTIFICATE_TEMPLATE, Asn1X509CertTemplateEncodeEx,
  1414. };
  1415. #define X509_ENCODE_EX_FUNC_COUNT (sizeof(X509EncodeExFuncTable) / \
  1416. sizeof(X509EncodeExFuncTable[0]))
  1417. static const CRYPT_OID_FUNC_ENTRY X509DecodeExFuncTable[] = {
  1418. ASN1_OID_OFFSET X509_CERT, Asn1X509SignedContentDecodeEx,
  1419. ASN1_OID_OFFSET X509_CERT_TO_BE_SIGNED, Asn1X509CertInfoDecodeEx,
  1420. ASN1_OID_OFFSET X509_CERT_CRL_TO_BE_SIGNED, Asn1X509CrlInfoDecodeEx,
  1421. ASN1_OID_OFFSET X509_CERT_REQUEST_TO_BE_SIGNED, Asn1X509CertRequestInfoDecodeEx,
  1422. ASN1_OID_OFFSET X509_EXTENSIONS, Asn1X509ExtensionsDecodeEx,
  1423. ASN1_OID_OFFSET X509_NAME_VALUE, Asn1X509NameValueDecodeEx,
  1424. ASN1_OID_OFFSET X509_NAME, Asn1X509NameInfoDecodeEx,
  1425. ASN1_OID_OFFSET X509_PUBLIC_KEY_INFO, Asn1X509PublicKeyInfoDecodeEx,
  1426. ASN1_OID_OFFSET X509_AUTHORITY_KEY_ID, Asn1X509AuthorityKeyIdDecodeEx,
  1427. ASN1_OID_OFFSET X509_KEY_ATTRIBUTES, Asn1X509KeyAttributesDecodeEx,
  1428. ASN1_OID_OFFSET X509_KEY_USAGE_RESTRICTION, Asn1X509KeyUsageRestrictionDecodeEx,
  1429. ASN1_OID_OFFSET X509_ALTERNATE_NAME, Asn1X509AltNameDecodeEx,
  1430. ASN1_OID_OFFSET X509_BASIC_CONSTRAINTS, Asn1X509BasicConstraintsDecodeEx,
  1431. ASN1_OID_OFFSET X509_KEY_USAGE, Asn1X509BitsDecodeEx,
  1432. ASN1_OID_OFFSET X509_BASIC_CONSTRAINTS2, Asn1X509BasicConstraints2DecodeEx,
  1433. ASN1_OID_OFFSET X509_CERT_POLICIES, Asn1X509CertPoliciesDecodeEx,
  1434. ASN1_OID_OFFSET PKCS_UTC_TIME, Asn1UtcTimeDecodeEx,
  1435. ASN1_OID_OFFSET PKCS_TIME_REQUEST, Asn1TimeStampRequestInfoDecodeEx,
  1436. ASN1_OID_OFFSET RSA_CSP_PUBLICKEYBLOB, Asn1RSAPublicKeyStrucDecodeEx,
  1437. #ifndef OSS_CRYPT_ASN1
  1438. ASN1_OID_OFFSET X509_UNICODE_NAME, UnicodeNameInfoDecodeEx,
  1439. #endif // OSS_CRYPT_ASN1
  1440. ASN1_OID_OFFSET X509_KEYGEN_REQUEST_TO_BE_SIGNED, Asn1X509KeygenRequestInfoDecodeEx,
  1441. ASN1_OID_OFFSET PKCS_ATTRIBUTE, Asn1X509AttributeDecodeEx,
  1442. ASN1_OID_OFFSET PKCS_CONTENT_INFO_SEQUENCE_OF_ANY, Asn1X509ContentInfoSequenceOfAnyDecodeEx,
  1443. #ifndef OSS_CRYPT_ASN1
  1444. ASN1_OID_OFFSET X509_UNICODE_NAME_VALUE, UnicodeNameValueDecodeEx,
  1445. #endif // OSS_CRYPT_ASN1
  1446. ASN1_OID_OFFSET X509_OCTET_STRING, Asn1X509OctetStringDecodeEx,
  1447. ASN1_OID_OFFSET X509_BITS, Asn1X509BitsDecodeEx,
  1448. ASN1_OID_OFFSET X509_INTEGER, Asn1X509IntegerDecodeEx,
  1449. ASN1_OID_OFFSET X509_MULTI_BYTE_INTEGER, Asn1X509MultiByteIntegerDecodeEx,
  1450. ASN1_OID_OFFSET X509_ENUMERATED, Asn1X509EnumeratedDecodeEx,
  1451. ASN1_OID_OFFSET X509_CHOICE_OF_TIME, Asn1X509ChoiceOfTimeDecodeEx,
  1452. ASN1_OID_OFFSET X509_AUTHORITY_KEY_ID2, Asn1X509AuthorityKeyId2DecodeEx,
  1453. ASN1_OID_OFFSET X509_AUTHORITY_INFO_ACCESS, Asn1X509AuthorityInfoAccessDecodeEx,
  1454. ASN1_OID_OFFSET PKCS_CONTENT_INFO, Asn1X509ContentInfoDecodeEx,
  1455. ASN1_OID_OFFSET X509_SEQUENCE_OF_ANY, Asn1X509SequenceOfAnyDecodeEx,
  1456. ASN1_OID_OFFSET X509_CRL_DIST_POINTS, Asn1X509CrlDistPointsDecodeEx,
  1457. ASN1_OID_OFFSET X509_ENHANCED_KEY_USAGE, Asn1X509CtlUsageDecodeEx,
  1458. ASN1_OID_OFFSET PKCS_CTL, Asn1X509CtlInfoDecodeEx,
  1459. ASN1_OID_OFFSET X509_MULTI_BYTE_UINT, Asn1X509MultiByteUINTDecodeEx,
  1460. ASN1_OID_OFFSET X509_DSS_PARAMETERS, Asn1X509DSSParametersDecodeEx,
  1461. ASN1_OID_OFFSET X509_DSS_SIGNATURE, Asn1X509DSSSignatureDecodeEx,
  1462. ASN1_OID_OFFSET PKCS_RC2_CBC_PARAMETERS, Asn1RC2CBCParametersDecodeEx,
  1463. ASN1_OID_OFFSET PKCS_SMIME_CAPABILITIES, Asn1SMIMECapabilitiesDecodeEx,
  1464. ASN1_OID_PREFIX X509_PKIX_POLICY_QUALIFIER_USERNOTICE, Asn1X509PKIXUserNoticeDecodeEx,
  1465. ASN1_OID_OFFSET X509_DH_PARAMETERS, Asn1X509DHParametersDecodeEx,
  1466. ASN1_OID_OFFSET PKCS_ATTRIBUTES, Asn1X509AttributesDecodeEx,
  1467. #ifndef OSS_CRYPT_ASN1
  1468. ASN1_OID_OFFSET PKCS_SORTED_CTL, Asn1X509CtlInfoDecodeEx,
  1469. #endif // OSS_CRYPT_ASN1
  1470. ASN1_OID_OFFSET X942_DH_PARAMETERS, Asn1X942DhParametersDecodeEx,
  1471. ASN1_OID_OFFSET X509_BITS_WITHOUT_TRAILING_ZEROES, Asn1X509BitsDecodeEx,
  1472. ASN1_OID_OFFSET X942_OTHER_INFO, Asn1X942OtherInfoDecodeEx,
  1473. ASN1_OID_OFFSET X509_CERT_PAIR, Asn1X509CertPairDecodeEx,
  1474. ASN1_OID_OFFSET X509_ISSUING_DIST_POINT, Asn1X509CrlIssuingDistPointDecodeEx,
  1475. ASN1_OID_OFFSET X509_NAME_CONSTRAINTS, Asn1X509NameConstraintsDecodeEx,
  1476. ASN1_OID_OFFSET X509_POLICY_MAPPINGS, Asn1X509PolicyMappingsDecodeEx,
  1477. ASN1_OID_OFFSET X509_POLICY_CONSTRAINTS, Asn1X509PolicyConstraintsDecodeEx,
  1478. ASN1_OID_OFFSET X509_CROSS_CERT_DIST_POINTS, Asn1X509CrossCertDistPointsDecodeEx,
  1479. ASN1_OID_OFFSET CMC_DATA, Asn1CmcDataDecodeEx,
  1480. ASN1_OID_OFFSET CMC_RESPONSE, Asn1CmcResponseDecodeEx,
  1481. ASN1_OID_OFFSET CMC_STATUS, Asn1CmcStatusDecodeEx,
  1482. ASN1_OID_OFFSET CMC_ADD_EXTENSIONS, Asn1CmcAddExtensionsDecodeEx,
  1483. ASN1_OID_OFFSET CMC_ADD_ATTRIBUTES, Asn1CmcAddAttributesDecodeEx,
  1484. ASN1_OID_OFFSET X509_CERTIFICATE_TEMPLATE, Asn1X509CertTemplateDecodeEx,
  1485. ASN1_OID_PREFIX szOID_AUTHORITY_KEY_IDENTIFIER, Asn1X509AuthorityKeyIdDecodeEx,
  1486. ASN1_OID_PREFIX szOID_KEY_ATTRIBUTES, Asn1X509KeyAttributesDecodeEx,
  1487. ASN1_OID_PREFIX szOID_KEY_USAGE_RESTRICTION, Asn1X509KeyUsageRestrictionDecodeEx,
  1488. ASN1_OID_PREFIX szOID_SUBJECT_ALT_NAME, Asn1X509AltNameDecodeEx,
  1489. ASN1_OID_PREFIX szOID_ISSUER_ALT_NAME, Asn1X509AltNameDecodeEx,
  1490. ASN1_OID_PREFIX szOID_BASIC_CONSTRAINTS, Asn1X509BasicConstraintsDecodeEx,
  1491. ASN1_OID_PREFIX szOID_KEY_USAGE, Asn1X509BitsDecodeEx,
  1492. ASN1_OID_PREFIX szOID_BASIC_CONSTRAINTS2, Asn1X509BasicConstraints2DecodeEx,
  1493. ASN1_OID_PREFIX szOID_CERT_POLICIES, Asn1X509CertPoliciesDecodeEx,
  1494. ASN1_OID_PREFIX szOID_CERT_POLICIES_95, Asn1X509CertPoliciesDecodeEx,
  1495. ASN1_OID_PREFIX szOID_CERT_POLICIES_95_QUALIFIER1, Asn1X509CertPoliciesQualifier1DecodeEx,
  1496. ASN1_OID_PREFIX szOID_PKIX_POLICY_QUALIFIER_USERNOTICE, Asn1X509PKIXUserNoticeDecodeEx,
  1497. ASN1_OID_PREFIX szOID_AUTHORITY_KEY_IDENTIFIER2, Asn1X509AuthorityKeyId2DecodeEx,
  1498. ASN1_OID_PREFIX szOID_SUBJECT_KEY_IDENTIFIER, Asn1X509OctetStringDecodeEx,
  1499. ASN1_OID_PREFIX szOID_SUBJECT_ALT_NAME2, Asn1X509AltNameDecodeEx,
  1500. ASN1_OID_PREFIX szOID_ISSUER_ALT_NAME2, Asn1X509AltNameDecodeEx,
  1501. ASN1_OID_PREFIX szOID_CRL_REASON_CODE, Asn1X509EnumeratedDecodeEx,
  1502. ASN1_OID_PREFIX szOID_AUTHORITY_INFO_ACCESS, Asn1X509AuthorityInfoAccessDecodeEx,
  1503. ASN1_OID_PREFIX szOID_CRL_DIST_POINTS, Asn1X509CrlDistPointsDecodeEx,
  1504. ASN1_OID_PREFIX szOID_CERT_EXTENSIONS, Asn1X509ExtensionsDecodeEx,
  1505. ASN1_OID_PREFIX szOID_RSA_certExtensions, Asn1X509ExtensionsDecodeEx,
  1506. ASN1_OID_PREFIX szOID_NEXT_UPDATE_LOCATION, Asn1X509AltNameDecodeEx,
  1507. ASN1_OID_PREFIX szOID_ENHANCED_KEY_USAGE, Asn1X509CtlUsageDecodeEx,
  1508. ASN1_OID_PREFIX szOID_CTL, Asn1X509CtlInfoDecodeEx,
  1509. ASN1_OID_PREFIX szOID_RSA_RC2CBC, Asn1RC2CBCParametersDecodeEx,
  1510. ASN1_OID_PREFIX szOID_RSA_SMIMECapabilities, Asn1SMIMECapabilitiesDecodeEx,
  1511. ASN1_OID_PREFIX szOID_RSA_signingTime, Asn1UtcTimeDecodeEx,
  1512. ASN1_OID_PREFIX szOID_ENROLLMENT_NAME_VALUE_PAIR, Asn1NameValueDecodeEx,
  1513. ASN1_OID_PREFIX szOID_ENROLLMENT_CSP_PROVIDER, Asn1CSPProviderDecodeEx,
  1514. ASN1_OID_OFFSET szOID_CRL_NUMBER, Asn1X509IntegerDecodeEx,
  1515. ASN1_OID_OFFSET szOID_DELTA_CRL_INDICATOR, Asn1X509IntegerDecodeEx,
  1516. ASN1_OID_OFFSET szOID_ISSUING_DIST_POINT, Asn1X509CrlIssuingDistPointDecodeEx,
  1517. ASN1_OID_PREFIX szOID_FRESHEST_CRL, Asn1X509CrlDistPointsDecodeEx,
  1518. ASN1_OID_OFFSET szOID_NAME_CONSTRAINTS, Asn1X509NameConstraintsDecodeEx,
  1519. ASN1_OID_OFFSET szOID_POLICY_MAPPINGS, Asn1X509PolicyMappingsDecodeEx,
  1520. ASN1_OID_OFFSET szOID_LEGACY_POLICY_MAPPINGS, Asn1X509PolicyMappingsDecodeEx,
  1521. ASN1_OID_OFFSET szOID_POLICY_CONSTRAINTS, Asn1X509PolicyConstraintsDecodeEx,
  1522. ASN1_OID_OFFSET szOID_CROSS_CERT_DIST_POINTS, Asn1X509CrossCertDistPointsDecodeEx,
  1523. ASN1_OID_OFFSET szOID_CERTIFICATE_TEMPLATE, Asn1X509CertTemplateDecodeEx,
  1524. };
  1525. #define X509_DECODE_EX_FUNC_COUNT (sizeof(X509DecodeExFuncTable) / \
  1526. sizeof(X509DecodeExFuncTable[0]))
  1527. #ifdef DEBUG_CRYPT_ASN1_MASTER
  1528. static HMODULE hOssCryptDll = NULL;
  1529. #endif // DEBUG_CRYPT_ASN1_MASTER
  1530. BOOL
  1531. WINAPI
  1532. CertASNDllMain(
  1533. HMODULE hInst,
  1534. ULONG ulReason,
  1535. LPVOID lpReserved)
  1536. {
  1537. BOOL fRet;
  1538. if (!I_CryptOIDConvDllMain(hInst, ulReason, lpReserved))
  1539. return FALSE;
  1540. switch (ulReason) {
  1541. case DLL_PROCESS_ATTACH:
  1542. if (NULL == (hX509EncodeFuncSet = CryptInitOIDFunctionSet(
  1543. CRYPT_OID_ENCODE_OBJECT_FUNC,
  1544. 0)))
  1545. goto CryptInitOIDFunctionSetError;
  1546. if (NULL == (hX509DecodeFuncSet = CryptInitOIDFunctionSet(
  1547. CRYPT_OID_DECODE_OBJECT_FUNC,
  1548. 0)))
  1549. goto CryptInitOIDFunctionSetError;
  1550. if (NULL == (hX509EncodeExFuncSet = CryptInitOIDFunctionSet(
  1551. CRYPT_OID_ENCODE_OBJECT_EX_FUNC,
  1552. 0)))
  1553. goto CryptInitOIDFunctionSetError;
  1554. if (NULL == (hX509DecodeExFuncSet = CryptInitOIDFunctionSet(
  1555. CRYPT_OID_DECODE_OBJECT_EX_FUNC,
  1556. 0)))
  1557. goto CryptInitOIDFunctionSetError;
  1558. if (!CryptInstallOIDFunctionAddress(
  1559. NULL, // hModule
  1560. X509_ASN_ENCODING,
  1561. CRYPT_OID_ENCODE_OBJECT_EX_FUNC,
  1562. X509_ENCODE_EX_FUNC_COUNT,
  1563. X509EncodeExFuncTable,
  1564. 0)) // dwFlags
  1565. goto CryptInstallOIDFunctionAddressError;
  1566. if (!CryptInstallOIDFunctionAddress(
  1567. NULL, // hModule
  1568. X509_ASN_ENCODING,
  1569. CRYPT_OID_DECODE_OBJECT_EX_FUNC,
  1570. X509_DECODE_EX_FUNC_COUNT,
  1571. X509DecodeExFuncTable,
  1572. 0)) // dwFlags
  1573. goto CryptInstallOIDFunctionAddressError;
  1574. #ifdef OSS_CRYPT_ASN1
  1575. if (0 == (hX509Asn1Module = I_CryptInstallAsn1Module(ossx509, 0, NULL)))
  1576. goto CryptInstallAsn1ModuleError;
  1577. #else
  1578. X509_Module_Startup();
  1579. if (0 == (hX509Asn1Module = I_CryptInstallAsn1Module(
  1580. X509_Module, 0, NULL))) {
  1581. X509_Module_Cleanup();
  1582. goto CryptInstallAsn1ModuleError;
  1583. }
  1584. #endif // OSS_CRYPT_ASN1
  1585. break;
  1586. case DLL_PROCESS_DETACH:
  1587. #ifdef DEBUG_CRYPT_ASN1_MASTER
  1588. if (hOssCryptDll) {
  1589. FreeLibrary(hOssCryptDll);
  1590. hOssCryptDll = NULL;
  1591. }
  1592. #endif // DEBUG_CRYPT_ASN1_MASTER
  1593. I_CryptUninstallAsn1Module(hX509Asn1Module);
  1594. #ifndef OSS_CRYPT_ASN1
  1595. X509_Module_Cleanup();
  1596. #endif // OSS_CRYPT_ASN1
  1597. case DLL_THREAD_DETACH:
  1598. default:
  1599. break;
  1600. }
  1601. fRet = TRUE;
  1602. CommonReturn:
  1603. return fRet;
  1604. ErrorReturn:
  1605. I_CryptOIDConvDllMain(hInst, DLL_PROCESS_DETACH, NULL);
  1606. fRet = FALSE;
  1607. goto CommonReturn;
  1608. TRACE_ERROR(CryptInstallAsn1ModuleError)
  1609. TRACE_ERROR(CryptInitOIDFunctionSetError)
  1610. TRACE_ERROR(CryptInstallOIDFunctionAddressError)
  1611. }
  1612. #ifdef DEBUG_CRYPT_ASN1_MASTER
  1613. #define DEBUG_OSS_CRYPT_ASN1_ENCODE_FLAG 0x1
  1614. #define DEBUG_OSS_CRYPT_ASN1_DECODE_FLAG 0x2
  1615. #define DEBUG_OSS_CRYPT_ASN1_COMPARE_FLAG 0x4
  1616. static BOOL fGotDebugCryptAsn1Flags = FALSE;
  1617. static int iDebugCryptAsn1Flags = 0;
  1618. int
  1619. WINAPI
  1620. GetDebugCryptAsn1Flags()
  1621. {
  1622. if (!fGotDebugCryptAsn1Flags) {
  1623. char *pszEnvVar;
  1624. char *p;
  1625. int iFlags;
  1626. if (pszEnvVar = getenv("DEBUG_CRYPT_ASN1_FLAGS"))
  1627. iFlags = strtol(pszEnvVar, &p, 16);
  1628. else
  1629. iFlags = DEBUG_OSS_CRYPT_ASN1_COMPARE_FLAG;
  1630. if (iFlags) {
  1631. if (NULL == (hOssCryptDll = LoadLibraryA("osscrypt.dll"))) {
  1632. iFlags = 0;
  1633. if (pszEnvVar)
  1634. MessageBoxA(
  1635. NULL, // hwndOwner
  1636. "LoadLibrary(osscrypt.dll) failed",
  1637. "CheckCryptEncodeDecodeAsn1",
  1638. MB_TOPMOST | MB_OK | MB_ICONWARNING |
  1639. MB_SERVICE_NOTIFICATION
  1640. );
  1641. }
  1642. }
  1643. iDebugCryptAsn1Flags = iFlags;
  1644. fGotDebugCryptAsn1Flags = TRUE;
  1645. }
  1646. return iDebugCryptAsn1Flags;
  1647. }
  1648. //+-------------------------------------------------------------------------
  1649. // Write an encoded DER blob to a file
  1650. //--------------------------------------------------------------------------
  1651. static BOOL WriteDERToFile(
  1652. LPCSTR pszFileName,
  1653. PBYTE pbDER,
  1654. DWORD cbDER
  1655. )
  1656. {
  1657. BOOL fResult;
  1658. // Write the Encoded Blob to the file
  1659. HANDLE hFile;
  1660. hFile = CreateFile(pszFileName,
  1661. GENERIC_WRITE,
  1662. 0, // fdwShareMode
  1663. NULL, // lpsa
  1664. CREATE_ALWAYS,
  1665. 0, // fdwAttrsAndFlags
  1666. 0); // TemplateFile
  1667. if (INVALID_HANDLE_VALUE == hFile) {
  1668. fResult = FALSE;
  1669. } else {
  1670. DWORD dwBytesWritten;
  1671. fResult = WriteFile(
  1672. hFile,
  1673. pbDER,
  1674. cbDER,
  1675. &dwBytesWritten,
  1676. NULL // lpOverlapped
  1677. );
  1678. CloseHandle(hFile);
  1679. }
  1680. return fResult;
  1681. }
  1682. #endif // DEBUG_CRYPT_ASN1_MASTER
  1683. //+-------------------------------------------------------------------------
  1684. // Encode the specified data structure according to the certificate
  1685. // encoding type.
  1686. //--------------------------------------------------------------------------
  1687. BOOL
  1688. WINAPI
  1689. CryptEncodeObjectEx(
  1690. IN DWORD dwCertEncodingType,
  1691. IN LPCSTR lpszStructType,
  1692. IN const void *pvStructInfo,
  1693. IN DWORD dwFlags,
  1694. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  1695. OUT void *pvEncoded,
  1696. IN OUT DWORD *pcbEncoded
  1697. )
  1698. {
  1699. BOOL fResult;
  1700. void *pvFuncAddr;
  1701. HCRYPTOIDFUNCADDR hFuncAddr = NULL;
  1702. #ifdef DEBUG_CRYPT_ASN1_MASTER
  1703. int iOssAsn1Flags;
  1704. LPSTR lpszOssAsn1StructType = NULL;
  1705. char szOssOID[128];
  1706. HCRYPTOIDFUNCADDR hOssAsn1FuncAddr = NULL;
  1707. void *pvOssAsn1FuncAddr = NULL;
  1708. iOssAsn1Flags = GetDebugCryptAsn1Flags() &
  1709. (DEBUG_OSS_CRYPT_ASN1_ENCODE_FLAG |
  1710. DEBUG_OSS_CRYPT_ASN1_COMPARE_FLAG);
  1711. if (iOssAsn1Flags) {
  1712. if (0xFFFF < (DWORD_PTR) lpszStructType) {
  1713. if ((DWORD) strlen(lpszStructType) <
  1714. (sizeof(szOssOID) - strlen(OSS_OID_PREFIX) - 1)) {
  1715. strcpy(szOssOID, OSS_OID_PREFIX);
  1716. strcat(szOssOID, lpszStructType);
  1717. lpszOssAsn1StructType = szOssOID;
  1718. }
  1719. } else
  1720. lpszOssAsn1StructType = (LPSTR) lpszStructType +
  1721. OSS_OID_OFFSET;
  1722. if (lpszOssAsn1StructType) {
  1723. if (!CryptGetOIDFunctionAddress(
  1724. hX509EncodeExFuncSet,
  1725. dwCertEncodingType,
  1726. lpszOssAsn1StructType,
  1727. 0, // dwFlags
  1728. &pvOssAsn1FuncAddr,
  1729. &hOssAsn1FuncAddr
  1730. ))
  1731. pvOssAsn1FuncAddr = NULL;
  1732. }
  1733. }
  1734. if (pvOssAsn1FuncAddr &&
  1735. 0 == (iOssAsn1Flags & DEBUG_OSS_CRYPT_ASN1_COMPARE_FLAG)) {
  1736. fResult = ((PFN_ENCODE_EX_FUNC) pvOssAsn1FuncAddr)(
  1737. dwCertEncodingType,
  1738. lpszStructType,
  1739. pvStructInfo,
  1740. dwFlags,
  1741. pEncodePara,
  1742. pvEncoded,
  1743. pcbEncoded
  1744. );
  1745. } else
  1746. #endif // DEBUG_CRYPT_ASN1_MASTER
  1747. if (CryptGetOIDFunctionAddress(
  1748. hX509EncodeExFuncSet,
  1749. dwCertEncodingType,
  1750. lpszStructType,
  1751. 0, // dwFlags
  1752. &pvFuncAddr,
  1753. &hFuncAddr)) {
  1754. __try {
  1755. fResult = ((PFN_ENCODE_EX_FUNC) pvFuncAddr)(
  1756. dwCertEncodingType,
  1757. lpszStructType,
  1758. pvStructInfo,
  1759. dwFlags,
  1760. pEncodePara,
  1761. pvEncoded,
  1762. pcbEncoded
  1763. );
  1764. } __except(EXCEPTION_EXECUTE_HANDLER) {
  1765. fResult = FALSE;
  1766. *pcbEncoded = 0;
  1767. SetLastError(GetExceptionCode());
  1768. }
  1769. #ifdef DEBUG_CRYPT_ASN1_MASTER
  1770. if (pvOssAsn1FuncAddr && fResult && pvEncoded) {
  1771. BYTE *pbEncoded;
  1772. BOOL fOssAsn1Result;
  1773. BYTE *pbOssAsn1 = NULL;
  1774. DWORD cbOssAsn1;
  1775. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  1776. pbEncoded = *((BYTE **)pvEncoded);
  1777. else
  1778. pbEncoded = (BYTE *) pvEncoded;
  1779. fOssAsn1Result = ((PFN_ENCODE_EX_FUNC) pvOssAsn1FuncAddr)(
  1780. dwCertEncodingType,
  1781. lpszStructType,
  1782. pvStructInfo,
  1783. dwFlags | CRYPT_ENCODE_ALLOC_FLAG,
  1784. &PkiEncodePara,
  1785. (void *) &pbOssAsn1,
  1786. &cbOssAsn1
  1787. );
  1788. if (!fOssAsn1Result) {
  1789. int id;
  1790. id = MessageBoxA(
  1791. NULL, // hwndOwner
  1792. "OssCryptAsn1 encode failed. Select Cancel to stop future OssCryptAsn1 encodes",
  1793. "CheckCryptEncodeDecodeAsn1",
  1794. MB_TOPMOST | MB_OKCANCEL | MB_ICONQUESTION |
  1795. MB_SERVICE_NOTIFICATION
  1796. );
  1797. if (IDCANCEL == id)
  1798. iDebugCryptAsn1Flags = 0;
  1799. } else if (*pcbEncoded != cbOssAsn1 ||
  1800. 0 != memcmp(pbEncoded, pbOssAsn1, cbOssAsn1)) {
  1801. int id;
  1802. WriteDERToFile("msasn1.der", pbEncoded, *pcbEncoded);
  1803. WriteDERToFile("ossasn1.der", pbOssAsn1, cbOssAsn1);
  1804. id = MessageBoxA(
  1805. NULL, // hwndOwner
  1806. "OssCryptAsn1 encode compare failed. Check ossasn1.der and msasn1.der. Select Cancel to stop future OssCryptAsn1 encodes",
  1807. "CheckCryptEncodeDecodeAsn1",
  1808. MB_TOPMOST | MB_OKCANCEL | MB_ICONQUESTION |
  1809. MB_SERVICE_NOTIFICATION
  1810. );
  1811. if (IDCANCEL == id)
  1812. iDebugCryptAsn1Flags = 0;
  1813. }
  1814. if (pbOssAsn1)
  1815. PkiFree(pbOssAsn1);
  1816. }
  1817. #endif // DEBUG_CRYPT_ASN1_MASTER
  1818. } else {
  1819. BYTE *pbEncoded;
  1820. #ifdef DEBUG_CRYPT_ASN1_MASTER
  1821. if (lpszOssAsn1StructType) {
  1822. if (hOssAsn1FuncAddr)
  1823. CryptFreeOIDFunctionAddress(hOssAsn1FuncAddr, 0);
  1824. if (!CryptGetOIDFunctionAddress(
  1825. hX509EncodeFuncSet,
  1826. dwCertEncodingType,
  1827. lpszOssAsn1StructType,
  1828. 0, // dwFlags
  1829. &pvOssAsn1FuncAddr,
  1830. &hOssAsn1FuncAddr
  1831. ))
  1832. pvOssAsn1FuncAddr = NULL;
  1833. }
  1834. #endif // DEBUG_CRYPT_ASN1_MASTER
  1835. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  1836. *((void **) pvEncoded) = NULL;
  1837. if (dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG)
  1838. goto InvalidFlags;
  1839. #ifdef DEBUG_CRYPT_ASN1_MASTER
  1840. if (pvOssAsn1FuncAddr &&
  1841. 0 == (iOssAsn1Flags & DEBUG_OSS_CRYPT_ASN1_COMPARE_FLAG)) {
  1842. pvFuncAddr = pvOssAsn1FuncAddr;
  1843. pvOssAsn1FuncAddr = NULL;
  1844. hFuncAddr = hOssAsn1FuncAddr;
  1845. hOssAsn1FuncAddr = NULL;
  1846. } else
  1847. #endif // DEBUG_CRYPT_ASN1_MASTER
  1848. if (!CryptGetOIDFunctionAddress(
  1849. hX509EncodeFuncSet,
  1850. dwCertEncodingType,
  1851. lpszStructType,
  1852. 0, // dwFlags
  1853. &pvFuncAddr,
  1854. &hFuncAddr))
  1855. goto NoEncodeFunction;
  1856. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG) {
  1857. PFN_CRYPT_ALLOC pfnAlloc;
  1858. *pcbEncoded = 0;
  1859. __try {
  1860. fResult = ((PFN_ENCODE_FUNC) pvFuncAddr)(
  1861. dwCertEncodingType,
  1862. lpszStructType,
  1863. pvStructInfo,
  1864. NULL,
  1865. pcbEncoded
  1866. );
  1867. } __except(EXCEPTION_EXECUTE_HANDLER) {
  1868. fResult = FALSE;
  1869. *pcbEncoded = 0;
  1870. SetLastError(GetExceptionCode());
  1871. }
  1872. if (!fResult || 0 == *pcbEncoded)
  1873. goto CommonReturn;
  1874. pfnAlloc = PkiGetEncodeAllocFunction(pEncodePara);
  1875. if (NULL == (pbEncoded = (BYTE *) pfnAlloc(*pcbEncoded)))
  1876. goto OutOfMemory;
  1877. } else
  1878. pbEncoded = (BYTE *) pvEncoded;
  1879. __try {
  1880. fResult = ((PFN_ENCODE_FUNC) pvFuncAddr)(
  1881. dwCertEncodingType,
  1882. lpszStructType,
  1883. pvStructInfo,
  1884. pbEncoded,
  1885. pcbEncoded
  1886. );
  1887. } __except(EXCEPTION_EXECUTE_HANDLER) {
  1888. fResult = FALSE;
  1889. *pcbEncoded = 0;
  1890. SetLastError(GetExceptionCode());
  1891. }
  1892. #ifdef DEBUG_CRYPT_ASN1_MASTER
  1893. if (pvOssAsn1FuncAddr && fResult && pbEncoded) {
  1894. BOOL fOssAsn1Result;
  1895. BYTE *pbOssAsn1 = NULL;
  1896. DWORD cbOssAsn1;
  1897. cbOssAsn1 = *pcbEncoded;
  1898. pbOssAsn1 = (BYTE *) PkiNonzeroAlloc(cbOssAsn1);
  1899. if (NULL == pbOssAsn1)
  1900. fOssAsn1Result = FALSE;
  1901. else
  1902. fOssAsn1Result = ((PFN_ENCODE_FUNC) pvOssAsn1FuncAddr)(
  1903. dwCertEncodingType,
  1904. lpszStructType,
  1905. pvStructInfo,
  1906. pbOssAsn1,
  1907. &cbOssAsn1
  1908. );
  1909. if (!fOssAsn1Result) {
  1910. int id;
  1911. id = MessageBoxA(
  1912. NULL, // hwndOwner
  1913. "OssCryptAsn1 encode failed. Select Cancel to stop future OssCryptAsn1 encodes",
  1914. "CheckCryptEncodeDecodeAsn1",
  1915. MB_TOPMOST | MB_OKCANCEL | MB_ICONQUESTION |
  1916. MB_SERVICE_NOTIFICATION
  1917. );
  1918. if (IDCANCEL == id)
  1919. iDebugCryptAsn1Flags = 0;
  1920. } else if (*pcbEncoded != cbOssAsn1 ||
  1921. 0 != memcmp(pbEncoded, pbOssAsn1, cbOssAsn1)) {
  1922. int id;
  1923. WriteDERToFile("msasn1.der", pbEncoded, *pcbEncoded);
  1924. WriteDERToFile("ossasn1.der", pbOssAsn1, cbOssAsn1);
  1925. id = MessageBoxA(
  1926. NULL, // hwndOwner
  1927. "OssCryptAsn1 encode compare failed. Check ossasn1.der and msasn1.der. Select Cancel to stop future OssCryptAsn1 encodes",
  1928. "CheckCryptEncodeDecodeAsn1",
  1929. MB_TOPMOST | MB_OKCANCEL | MB_ICONQUESTION |
  1930. MB_SERVICE_NOTIFICATION
  1931. );
  1932. if (IDCANCEL == id)
  1933. iDebugCryptAsn1Flags = 0;
  1934. }
  1935. PkiFree(pbOssAsn1);
  1936. }
  1937. #endif // DEBUG_CRYPT_ASN1_MASTER
  1938. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG) {
  1939. if (fResult)
  1940. *((BYTE **) pvEncoded) = pbEncoded;
  1941. else {
  1942. PFN_CRYPT_FREE pfnFree;
  1943. pfnFree = PkiGetEncodeFreeFunction(pEncodePara);
  1944. pfnFree(pbEncoded);
  1945. }
  1946. }
  1947. }
  1948. CommonReturn:
  1949. if (hFuncAddr)
  1950. CryptFreeOIDFunctionAddress(hFuncAddr, 0);
  1951. #ifdef DEBUG_CRYPT_ASN1_MASTER
  1952. if (hOssAsn1FuncAddr)
  1953. CryptFreeOIDFunctionAddress(hOssAsn1FuncAddr, 0);
  1954. #endif // DEBUG_CRYPT_ASN1_MASTER
  1955. return fResult;
  1956. ErrorReturn:
  1957. *pcbEncoded = 0;
  1958. fResult = FALSE;
  1959. goto CommonReturn;
  1960. SET_ERROR(InvalidFlags, E_INVALIDARG)
  1961. TRACE_ERROR(NoEncodeFunction)
  1962. SET_ERROR(OutOfMemory, E_OUTOFMEMORY)
  1963. }
  1964. BOOL
  1965. WINAPI
  1966. CryptEncodeObject(
  1967. IN DWORD dwCertEncodingType,
  1968. IN LPCSTR lpszStructType,
  1969. IN const void *pvStructInfo,
  1970. OUT OPTIONAL BYTE *pbEncoded,
  1971. IN OUT DWORD *pcbEncoded
  1972. )
  1973. {
  1974. return CryptEncodeObjectEx(
  1975. dwCertEncodingType,
  1976. lpszStructType,
  1977. pvStructInfo,
  1978. 0, // dwFlags
  1979. NULL, // pEncodePara
  1980. pbEncoded,
  1981. pcbEncoded
  1982. );
  1983. }
  1984. //+-------------------------------------------------------------------------
  1985. // Decode the specified data structure according to the certificate
  1986. // encoding type.
  1987. //--------------------------------------------------------------------------
  1988. BOOL
  1989. WINAPI
  1990. CryptDecodeObjectEx(
  1991. IN DWORD dwCertEncodingType,
  1992. IN LPCSTR lpszStructType,
  1993. IN const BYTE *pbEncoded,
  1994. IN DWORD cbEncoded,
  1995. IN DWORD dwFlags,
  1996. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  1997. OUT OPTIONAL void *pvStructInfo,
  1998. IN OUT DWORD *pcbStructInfo
  1999. )
  2000. {
  2001. BOOL fResult;
  2002. void *pvFuncAddr;
  2003. HCRYPTOIDFUNCADDR hFuncAddr = NULL;
  2004. #ifdef DEBUG_CRYPT_ASN1_MASTER
  2005. int iOssAsn1Flags;
  2006. LPSTR lpszOssAsn1StructType = NULL;
  2007. char szOssOID[128];
  2008. HCRYPTOIDFUNCADDR hOssAsn1FuncAddr = NULL;
  2009. void *pvOssAsn1FuncAddr = NULL;
  2010. iOssAsn1Flags = GetDebugCryptAsn1Flags() &
  2011. DEBUG_OSS_CRYPT_ASN1_DECODE_FLAG;
  2012. if (iOssAsn1Flags) {
  2013. if (0xFFFF < (DWORD_PTR) lpszStructType) {
  2014. if ((DWORD) strlen(lpszStructType) <
  2015. (sizeof(szOssOID) - strlen(OSS_OID_PREFIX) - 1)) {
  2016. strcpy(szOssOID, OSS_OID_PREFIX);
  2017. strcat(szOssOID, lpszStructType);
  2018. lpszOssAsn1StructType = szOssOID;
  2019. }
  2020. } else
  2021. lpszOssAsn1StructType = (LPSTR) lpszStructType + OSS_OID_OFFSET;
  2022. if (lpszOssAsn1StructType) {
  2023. if (!CryptGetOIDFunctionAddress(
  2024. hX509DecodeExFuncSet,
  2025. dwCertEncodingType,
  2026. lpszOssAsn1StructType,
  2027. 0, // dwFlags
  2028. &pvOssAsn1FuncAddr,
  2029. &hOssAsn1FuncAddr
  2030. ))
  2031. pvOssAsn1FuncAddr = NULL;
  2032. }
  2033. }
  2034. if (pvOssAsn1FuncAddr) {
  2035. fResult = ((PFN_DECODE_EX_FUNC) pvOssAsn1FuncAddr)(
  2036. dwCertEncodingType,
  2037. lpszStructType,
  2038. pbEncoded,
  2039. cbEncoded,
  2040. dwFlags,
  2041. pDecodePara,
  2042. pvStructInfo,
  2043. pcbStructInfo
  2044. );
  2045. } else
  2046. #endif // DEBUG_CRYPT_ASN1_MASTER
  2047. if (CryptGetOIDFunctionAddress(
  2048. hX509DecodeExFuncSet,
  2049. dwCertEncodingType,
  2050. lpszStructType,
  2051. 0, // dwFlags
  2052. &pvFuncAddr,
  2053. &hFuncAddr)) {
  2054. __try {
  2055. fResult = ((PFN_DECODE_EX_FUNC) pvFuncAddr)(
  2056. dwCertEncodingType,
  2057. lpszStructType,
  2058. pbEncoded,
  2059. cbEncoded,
  2060. dwFlags,
  2061. pDecodePara,
  2062. pvStructInfo,
  2063. pcbStructInfo
  2064. );
  2065. } __except(EXCEPTION_EXECUTE_HANDLER) {
  2066. fResult = FALSE;
  2067. *pcbStructInfo = 0;
  2068. SetLastError(GetExceptionCode());
  2069. }
  2070. } else {
  2071. void *pv;
  2072. #ifdef DEBUG_CRYPT_ASN1_MASTER
  2073. if (lpszOssAsn1StructType) {
  2074. if (!CryptGetOIDFunctionAddress(
  2075. hX509DecodeFuncSet,
  2076. dwCertEncodingType,
  2077. lpszOssAsn1StructType,
  2078. 0, // dwFlags
  2079. &pvOssAsn1FuncAddr,
  2080. &hOssAsn1FuncAddr
  2081. ))
  2082. pvOssAsn1FuncAddr = NULL;
  2083. }
  2084. #endif // DEBUG_CRYPT_ASN1_MASTER
  2085. if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
  2086. *((void **) pvStructInfo) = NULL;
  2087. #ifdef DEBUG_CRYPT_ASN1_MASTER
  2088. if (pvOssAsn1FuncAddr) {
  2089. pvFuncAddr = pvOssAsn1FuncAddr;
  2090. pvOssAsn1FuncAddr = NULL;
  2091. hFuncAddr = hOssAsn1FuncAddr;
  2092. hOssAsn1FuncAddr = NULL;
  2093. } else
  2094. #endif // DEBUG_CRYPT_ASN1_MASTER
  2095. if (!CryptGetOIDFunctionAddress(
  2096. hX509DecodeFuncSet,
  2097. dwCertEncodingType,
  2098. lpszStructType,
  2099. 0, // dwFlags
  2100. &pvFuncAddr,
  2101. &hFuncAddr))
  2102. goto NoDecodeFunction;
  2103. if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) {
  2104. PFN_CRYPT_ALLOC pfnAlloc;
  2105. *pcbStructInfo = 0;
  2106. __try {
  2107. fResult = ((PFN_DECODE_FUNC) pvFuncAddr)(
  2108. dwCertEncodingType,
  2109. lpszStructType,
  2110. pbEncoded,
  2111. cbEncoded,
  2112. dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
  2113. NULL,
  2114. pcbStructInfo
  2115. );
  2116. } __except(EXCEPTION_EXECUTE_HANDLER) {
  2117. fResult = FALSE;
  2118. *pcbStructInfo = 0;
  2119. SetLastError(GetExceptionCode());
  2120. }
  2121. if (!fResult || 0 == *pcbStructInfo)
  2122. goto CommonReturn;
  2123. pfnAlloc = PkiGetDecodeAllocFunction(pDecodePara);
  2124. if (NULL == (pv = pfnAlloc(*pcbStructInfo)))
  2125. goto OutOfMemory;
  2126. } else
  2127. pv = pvStructInfo;
  2128. __try {
  2129. fResult = ((PFN_DECODE_FUNC) pvFuncAddr)(
  2130. dwCertEncodingType,
  2131. lpszStructType,
  2132. pbEncoded,
  2133. cbEncoded,
  2134. dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
  2135. pv,
  2136. pcbStructInfo
  2137. );
  2138. } __except(EXCEPTION_EXECUTE_HANDLER) {
  2139. fResult = FALSE;
  2140. *pcbStructInfo = 0;
  2141. SetLastError(GetExceptionCode());
  2142. }
  2143. if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) {
  2144. if (fResult)
  2145. *((void **) pvStructInfo) = pv;
  2146. else {
  2147. PFN_CRYPT_FREE pfnFree;
  2148. pfnFree = PkiGetDecodeFreeFunction(pDecodePara);
  2149. pfnFree(pv);
  2150. }
  2151. }
  2152. }
  2153. CommonReturn:
  2154. if (hFuncAddr)
  2155. CryptFreeOIDFunctionAddress(hFuncAddr, 0);
  2156. #ifdef DEBUG_CRYPT_ASN1_MASTER
  2157. if (hOssAsn1FuncAddr)
  2158. CryptFreeOIDFunctionAddress(hOssAsn1FuncAddr, 0);
  2159. #endif // DEBUG_CRYPT_ASN1_MASTER
  2160. return fResult;
  2161. ErrorReturn:
  2162. *pcbStructInfo = 0;
  2163. fResult = FALSE;
  2164. goto CommonReturn;
  2165. TRACE_ERROR(NoDecodeFunction)
  2166. SET_ERROR(OutOfMemory, E_OUTOFMEMORY)
  2167. }
  2168. BOOL
  2169. WINAPI
  2170. CryptDecodeObject(
  2171. IN DWORD dwCertEncodingType,
  2172. IN LPCSTR lpszStructType,
  2173. IN const BYTE *pbEncoded,
  2174. IN DWORD cbEncoded,
  2175. IN DWORD dwFlags,
  2176. OUT OPTIONAL void *pvStructInfo,
  2177. IN OUT DWORD *pcbStructInfo
  2178. )
  2179. {
  2180. return CryptDecodeObjectEx(
  2181. dwCertEncodingType,
  2182. lpszStructType,
  2183. pbEncoded,
  2184. cbEncoded,
  2185. dwFlags,
  2186. NULL, // pDecodePara
  2187. pvStructInfo,
  2188. pcbStructInfo
  2189. );
  2190. }
  2191. //+-------------------------------------------------------------------------
  2192. // Encode an ASN1 formatted info structure
  2193. //
  2194. // Called by the Asn1X509*Encode() functions.
  2195. //--------------------------------------------------------------------------
  2196. static BOOL Asn1InfoEncodeEx(
  2197. IN int pdunum,
  2198. IN void *pvAsn1Info,
  2199. IN DWORD dwFlags,
  2200. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  2201. OUT OPTIONAL void *pvEncoded,
  2202. IN OUT DWORD *pcbEncoded
  2203. )
  2204. {
  2205. return PkiAsn1EncodeInfoEx(
  2206. GetEncoder(),
  2207. pdunum,
  2208. pvAsn1Info,
  2209. dwFlags,
  2210. pEncodePara,
  2211. pvEncoded,
  2212. pcbEncoded);
  2213. }
  2214. //+-------------------------------------------------------------------------
  2215. // Decode into an allocated, ASN1 formatted info structure
  2216. //
  2217. // Called by the Asn1X509*Decode() functions.
  2218. //--------------------------------------------------------------------------
  2219. static BOOL Asn1InfoDecodeAndAlloc(
  2220. IN int pdunum,
  2221. IN const BYTE *pbEncoded,
  2222. IN DWORD cbEncoded,
  2223. OUT void **ppvAsn1Info
  2224. )
  2225. {
  2226. return PkiAsn1DecodeAndAllocInfo(
  2227. GetDecoder(),
  2228. pdunum,
  2229. pbEncoded,
  2230. cbEncoded,
  2231. ppvAsn1Info);
  2232. }
  2233. //+-------------------------------------------------------------------------
  2234. // Free an allocated, ASN1 formatted info structure
  2235. //
  2236. // Called by the Asn1X509*Decode() functions.
  2237. //--------------------------------------------------------------------------
  2238. static void Asn1InfoFree(
  2239. IN int pdunum,
  2240. IN void *pAsn1Info
  2241. )
  2242. {
  2243. if (pAsn1Info) {
  2244. DWORD dwErr = GetLastError();
  2245. // TlsGetValue globbers LastError
  2246. PkiAsn1FreeInfo(GetDecoder(), pdunum, pAsn1Info);
  2247. SetLastError(dwErr);
  2248. }
  2249. }
  2250. //+-------------------------------------------------------------------------
  2251. // Decode into an ASN1 formatted info structure. Call the callback
  2252. // function to convert into the 'C' data structure. If
  2253. // CRYPT_DECODE_ALLOC_FLAG is set, call the callback twice. First,
  2254. // to get the length of the 'C' data structure. Then after allocating,
  2255. // call again to update the 'C' data structure.
  2256. //
  2257. // Called by the Asn1X509*Decode() functions.
  2258. //--------------------------------------------------------------------------
  2259. static BOOL Asn1InfoDecodeAndAllocEx(
  2260. IN int pdunum,
  2261. IN const BYTE *pbEncoded,
  2262. IN DWORD cbEncoded,
  2263. IN DWORD dwFlags,
  2264. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  2265. IN PFN_PKI_ASN1_DECODE_EX_CALLBACK pfnDecodeExCallback,
  2266. OUT OPTIONAL void *pvStructInfo,
  2267. IN OUT DWORD *pcbStructInfo
  2268. )
  2269. {
  2270. return PkiAsn1DecodeAndAllocInfoEx(
  2271. GetDecoder(),
  2272. pdunum,
  2273. pbEncoded,
  2274. cbEncoded,
  2275. dwFlags,
  2276. pDecodePara,
  2277. pfnDecodeExCallback,
  2278. pvStructInfo,
  2279. pcbStructInfo
  2280. );
  2281. }
  2282. //+-------------------------------------------------------------------------
  2283. // ASN1 X509 v3 ASN.1 Set / Get functions
  2284. //
  2285. // Called by the ASN1 X509 encode/decode functions.
  2286. //
  2287. // Assumption: all types are UNBOUNDED.
  2288. //
  2289. // The Get functions decrement *plRemainExtra and advance
  2290. // *ppbExtra. When *plRemainExtra becomes negative, the functions continue
  2291. // with the length calculation but stop doing any copies.
  2292. // The functions don't return an error for a negative *plRemainExtra.
  2293. //--------------------------------------------------------------------------
  2294. //+-------------------------------------------------------------------------
  2295. // Set/Get Encoded Object Identifier string
  2296. //--------------------------------------------------------------------------
  2297. #ifdef OSS_CRYPT_ASN1
  2298. #define Asn1X509SetEncodedObjId(pszObjId, pAsn1) \
  2299. I_CryptSetEncodedOID(pszObjId, (OssEncodedOID *) (pAsn1))
  2300. #define Asn1X509GetEncodedObjId(pAsn1, dwFlags, \
  2301. ppszObjId, ppbExtra, plRemainExtra) \
  2302. I_CryptGetEncodedOID((OssEncodedOID *) (pAsn1), dwFlags, \
  2303. ppszObjId, ppbExtra, plRemainExtra)
  2304. #else
  2305. #define Asn1X509SetEncodedObjId(pszObjId, pAsn1) \
  2306. I_CryptSetEncodedOID(pszObjId, pAsn1)
  2307. #define Asn1X509GetEncodedObjId(pAsn1, dwFlags, \
  2308. ppszObjId, ppbExtra, plRemainExtra) \
  2309. I_CryptGetEncodedOID(pAsn1, dwFlags, \
  2310. ppszObjId, ppbExtra, plRemainExtra)
  2311. #endif // OSS_CRYPT_ASN1
  2312. //+-------------------------------------------------------------------------
  2313. // Set/Get CRYPT_DATA_BLOB (Octet String)
  2314. //--------------------------------------------------------------------------
  2315. inline void Asn1X509SetOctetString(
  2316. IN PCRYPT_DATA_BLOB pInfo,
  2317. OUT OCTETSTRING *pAsn1
  2318. )
  2319. {
  2320. pAsn1->value = pInfo->pbData;
  2321. pAsn1->length = pInfo->cbData;
  2322. }
  2323. inline void Asn1X509GetOctetString(
  2324. IN OCTETSTRING *pAsn1,
  2325. IN DWORD dwFlags,
  2326. OUT PCRYPT_DATA_BLOB pInfo,
  2327. IN OUT BYTE **ppbExtra,
  2328. IN OUT LONG *plRemainExtra
  2329. )
  2330. {
  2331. PkiAsn1GetOctetString(pAsn1->length, pAsn1->value, dwFlags,
  2332. pInfo, ppbExtra, plRemainExtra);
  2333. }
  2334. //+-------------------------------------------------------------------------
  2335. // Set/Free/Get CRYPT_INTEGER_BLOB
  2336. //--------------------------------------------------------------------------
  2337. inline BOOL Asn1X509SetHugeInteger(
  2338. IN PCRYPT_INTEGER_BLOB pInfo,
  2339. OUT HUGEINTEGER *pAsn1
  2340. )
  2341. {
  2342. return PkiAsn1SetHugeInteger(pInfo, &pAsn1->length, &pAsn1->value);
  2343. }
  2344. inline void Asn1X509FreeHugeInteger(
  2345. IN HUGEINTEGER *pAsn1
  2346. )
  2347. {
  2348. PkiAsn1FreeHugeInteger(pAsn1->value);
  2349. pAsn1->value = NULL;
  2350. pAsn1->length = 0;
  2351. }
  2352. inline void Asn1X509GetHugeInteger(
  2353. IN HUGEINTEGER *pAsn1,
  2354. IN DWORD dwFlags,
  2355. OUT PCRYPT_INTEGER_BLOB pInfo,
  2356. IN OUT BYTE **ppbExtra,
  2357. IN OUT LONG *plRemainExtra
  2358. )
  2359. {
  2360. PkiAsn1GetHugeInteger(pAsn1->length, pAsn1->value, dwFlags,
  2361. pInfo, ppbExtra, plRemainExtra);
  2362. }
  2363. //+-------------------------------------------------------------------------
  2364. // Set/Free/Get CRYPT_UINT_BLOB
  2365. //--------------------------------------------------------------------------
  2366. inline BOOL Asn1X509SetHugeUINT(
  2367. IN PCRYPT_UINT_BLOB pInfo,
  2368. OUT HUGEINTEGER *pAsn1
  2369. )
  2370. {
  2371. return PkiAsn1SetHugeUINT(pInfo, &pAsn1->length, &pAsn1->value);
  2372. }
  2373. #define Asn1X509FreeHugeUINT Asn1X509FreeHugeInteger
  2374. inline void Asn1X509GetHugeUINT(
  2375. IN HUGEINTEGER *pAsn1,
  2376. IN DWORD dwFlags,
  2377. OUT PCRYPT_UINT_BLOB pInfo,
  2378. IN OUT BYTE **ppbExtra,
  2379. IN OUT LONG *plRemainExtra
  2380. )
  2381. {
  2382. PkiAsn1GetHugeUINT(pAsn1->length, pAsn1->value, dwFlags,
  2383. pInfo, ppbExtra, plRemainExtra);
  2384. }
  2385. //+-------------------------------------------------------------------------
  2386. // Set/Get CRYPT_BIT_BLOB
  2387. //--------------------------------------------------------------------------
  2388. inline void Asn1X509SetBit(
  2389. IN PCRYPT_BIT_BLOB pInfo,
  2390. OUT BITSTRING *pAsn1
  2391. )
  2392. {
  2393. PkiAsn1SetBitString(pInfo, &pAsn1->length, &pAsn1->value);
  2394. }
  2395. inline void Asn1X509GetBit(
  2396. IN BITSTRING *pAsn1,
  2397. IN DWORD dwFlags,
  2398. OUT PCRYPT_BIT_BLOB pInfo,
  2399. IN OUT BYTE **ppbExtra,
  2400. IN OUT LONG *plRemainExtra
  2401. )
  2402. {
  2403. PkiAsn1GetBitString(pAsn1->length, pAsn1->value, dwFlags,
  2404. pInfo, ppbExtra, plRemainExtra);
  2405. }
  2406. inline void Asn1X509SetBitWithoutTrailingZeroes(
  2407. IN PCRYPT_BIT_BLOB pInfo,
  2408. OUT BITSTRING *pAsn1
  2409. )
  2410. {
  2411. PkiAsn1SetBitStringWithoutTrailingZeroes(
  2412. pInfo, &pAsn1->length, &pAsn1->value);
  2413. }
  2414. //+-------------------------------------------------------------------------
  2415. // Set/Get LPSTR (IA5 String)
  2416. //--------------------------------------------------------------------------
  2417. inline void Asn1X509SetIA5(
  2418. IN LPSTR psz,
  2419. OUT IA5STRING *pAsn1
  2420. )
  2421. {
  2422. pAsn1->value = psz;
  2423. pAsn1->length = strlen(psz);
  2424. }
  2425. inline void Asn1X509GetIA5(
  2426. IN IA5STRING *pAsn1,
  2427. IN DWORD dwFlags,
  2428. OUT LPSTR *ppsz,
  2429. IN OUT BYTE **ppbExtra,
  2430. IN OUT LONG *plRemainExtra
  2431. )
  2432. {
  2433. PkiAsn1GetIA5String(pAsn1->length, pAsn1->value, dwFlags,
  2434. ppsz, ppbExtra, plRemainExtra);
  2435. }
  2436. //+-------------------------------------------------------------------------
  2437. // Set/Free/Get Unicode mapped to IA5 String
  2438. //--------------------------------------------------------------------------
  2439. BOOL Asn1X509SetUnicodeConvertedToIA5(
  2440. IN LPWSTR pwsz,
  2441. OUT IA5STRING *pAsn1,
  2442. IN DWORD dwIndex,
  2443. OUT DWORD *pdwErrLocation
  2444. )
  2445. {
  2446. BOOL fResult;
  2447. fResult = PkiAsn1SetUnicodeConvertedToIA5String(pwsz,
  2448. &pAsn1->length, &pAsn1->value);
  2449. if (!fResult && (DWORD) CRYPT_E_INVALID_IA5_STRING == GetLastError())
  2450. *pdwErrLocation = (dwIndex << 16) | pAsn1->length;
  2451. else
  2452. *pdwErrLocation = 0;
  2453. return fResult;
  2454. }
  2455. inline void Asn1X509FreeUnicodeConvertedToIA5(IN IA5STRING *pAsn1)
  2456. {
  2457. PkiAsn1FreeUnicodeConvertedToIA5String(pAsn1->value);
  2458. pAsn1->value = NULL;
  2459. }
  2460. inline void Asn1X509GetIA5ConvertedToUnicode(
  2461. IN IA5STRING *pAsn1,
  2462. IN DWORD dwFlags,
  2463. OUT LPWSTR *ppwsz,
  2464. IN OUT BYTE **ppbExtra,
  2465. IN OUT LONG *plRemainExtra
  2466. )
  2467. {
  2468. PkiAsn1GetIA5StringConvertedToUnicode(pAsn1->length, pAsn1->value, dwFlags,
  2469. ppwsz, ppbExtra, plRemainExtra);
  2470. }
  2471. //+-------------------------------------------------------------------------
  2472. // Set/Get LPWSTR (BMP String)
  2473. //--------------------------------------------------------------------------
  2474. inline void Asn1X509SetBMP(
  2475. IN LPWSTR pwsz,
  2476. OUT BMPSTRING *pAsn1
  2477. )
  2478. {
  2479. pAsn1->value = pwsz;
  2480. pAsn1->length = wcslen(pwsz);
  2481. }
  2482. inline void Asn1X509GetBMP(
  2483. IN BMPSTRING *pAsn1,
  2484. IN DWORD dwFlags,
  2485. OUT LPWSTR *ppwsz,
  2486. IN OUT BYTE **ppbExtra,
  2487. IN OUT LONG *plRemainExtra
  2488. )
  2489. {
  2490. PkiAsn1GetBMPString(pAsn1->length, pAsn1->value, dwFlags,
  2491. ppwsz, ppbExtra, plRemainExtra);
  2492. }
  2493. //+-------------------------------------------------------------------------
  2494. // Set/Get "Any" DER BLOB
  2495. //--------------------------------------------------------------------------
  2496. inline void Asn1X509SetAny(
  2497. IN PCRYPT_OBJID_BLOB pInfo,
  2498. OUT NOCOPYANY *pAsn1
  2499. )
  2500. {
  2501. PkiAsn1SetAny(pInfo, pAsn1);
  2502. }
  2503. inline void Asn1X509GetAny(
  2504. IN NOCOPYANY *pAsn1,
  2505. IN DWORD dwFlags,
  2506. OUT PCRYPT_OBJID_BLOB pInfo,
  2507. IN OUT BYTE **ppbExtra,
  2508. IN OUT LONG *plRemainExtra
  2509. )
  2510. {
  2511. PkiAsn1GetAny(pAsn1, dwFlags, pInfo, ppbExtra, plRemainExtra);
  2512. }
  2513. //+-------------------------------------------------------------------------
  2514. // Set/Get CRYPT_ALGORITHM_IDENTIFIER
  2515. //--------------------------------------------------------------------------
  2516. BOOL Asn1X509SetAlgorithm(
  2517. IN PCRYPT_ALGORITHM_IDENTIFIER pInfo,
  2518. OUT AlgorithmIdentifier *pAsn1,
  2519. IN DWORD dwGroupId = 0
  2520. )
  2521. {
  2522. memset(pAsn1, 0, sizeof(*pAsn1));
  2523. if (pInfo->pszObjId) {
  2524. if (!Asn1X509SetEncodedObjId(pInfo->pszObjId, &pAsn1->algorithm))
  2525. return FALSE;
  2526. if (pInfo->Parameters.cbData) {
  2527. Asn1X509SetAny(&pInfo->Parameters, &pAsn1->parameters);
  2528. pAsn1->bit_mask |= parameters_present;
  2529. } else {
  2530. if (dwGroupId) {
  2531. // For public key or signature algorithms, check if
  2532. // NO NULL parameters.
  2533. PCCRYPT_OID_INFO pOIDInfo;
  2534. DWORD dwFlags = 0;
  2535. switch (dwGroupId) {
  2536. case CRYPT_PUBKEY_ALG_OID_GROUP_ID:
  2537. if (pOIDInfo = CryptFindOIDInfo(
  2538. CRYPT_OID_INFO_OID_KEY,
  2539. pInfo->pszObjId,
  2540. CRYPT_PUBKEY_ALG_OID_GROUP_ID)) {
  2541. if (1 <= pOIDInfo->ExtraInfo.cbData /
  2542. sizeof(DWORD)) {
  2543. DWORD *pdwExtra = (DWORD *)
  2544. pOIDInfo->ExtraInfo.pbData;
  2545. dwFlags = pdwExtra[0];
  2546. }
  2547. }
  2548. break;
  2549. case CRYPT_SIGN_ALG_OID_GROUP_ID:
  2550. if (pOIDInfo = CryptFindOIDInfo(
  2551. CRYPT_OID_INFO_OID_KEY,
  2552. pInfo->pszObjId,
  2553. CRYPT_SIGN_ALG_OID_GROUP_ID)) {
  2554. if (2 <= pOIDInfo->ExtraInfo.cbData /
  2555. sizeof(DWORD)) {
  2556. DWORD *pdwExtra = (DWORD *)
  2557. pOIDInfo->ExtraInfo.pbData;
  2558. dwFlags = pdwExtra[1];
  2559. }
  2560. }
  2561. break;
  2562. default:
  2563. break;
  2564. }
  2565. if (dwFlags & CRYPT_OID_NO_NULL_ALGORITHM_PARA_FLAG)
  2566. return TRUE;
  2567. }
  2568. // Per PKCS #1: default to the ASN.1 type NULL.
  2569. Asn1X509SetAny((PCRYPT_OBJID_BLOB) &NullDerBlob, &pAsn1->parameters);
  2570. pAsn1->bit_mask |= parameters_present;
  2571. }
  2572. }
  2573. return TRUE;
  2574. }
  2575. void Asn1X509GetAlgorithm(
  2576. IN AlgorithmIdentifier *pAsn1,
  2577. IN DWORD dwFlags,
  2578. OUT PCRYPT_ALGORITHM_IDENTIFIER pInfo,
  2579. IN OUT BYTE **ppbExtra,
  2580. IN OUT LONG *plRemainExtra
  2581. )
  2582. {
  2583. if (*plRemainExtra >= 0)
  2584. memset(pInfo, 0, sizeof(*pInfo));
  2585. Asn1X509GetEncodedObjId(&pAsn1->algorithm, dwFlags, &pInfo->pszObjId,
  2586. ppbExtra, plRemainExtra);
  2587. if (pAsn1->bit_mask & parameters_present)
  2588. Asn1X509GetAny(&pAsn1->parameters, dwFlags, &pInfo->Parameters,
  2589. ppbExtra, plRemainExtra);
  2590. }
  2591. //+-------------------------------------------------------------------------
  2592. // Set/Get CERT_PUBLIC_KEY_INFO
  2593. //--------------------------------------------------------------------------
  2594. BOOL Asn1X509SetPublicKeyInfo(
  2595. IN PCERT_PUBLIC_KEY_INFO pInfo,
  2596. OUT SubjectPublicKeyInfo *pAsn1
  2597. )
  2598. {
  2599. if (!Asn1X509SetAlgorithm(&pInfo->Algorithm, &pAsn1->algorithm,
  2600. CRYPT_PUBKEY_ALG_OID_GROUP_ID))
  2601. return FALSE;
  2602. Asn1X509SetBit(&pInfo->PublicKey, &pAsn1->subjectPublicKey);
  2603. return TRUE;
  2604. }
  2605. void Asn1X509GetPublicKeyInfo(
  2606. IN SubjectPublicKeyInfo *pAsn1,
  2607. IN DWORD dwFlags,
  2608. OUT PCERT_PUBLIC_KEY_INFO pInfo,
  2609. IN OUT BYTE **ppbExtra,
  2610. IN OUT LONG *plRemainExtra
  2611. )
  2612. {
  2613. Asn1X509GetAlgorithm(&pAsn1->algorithm, dwFlags, &pInfo->Algorithm,
  2614. ppbExtra, plRemainExtra);
  2615. Asn1X509GetBit(&pAsn1->subjectPublicKey, dwFlags, &pInfo->PublicKey,
  2616. ppbExtra, plRemainExtra);
  2617. }
  2618. //+-------------------------------------------------------------------------
  2619. // Set/Free/Get Extensions
  2620. //--------------------------------------------------------------------------
  2621. BOOL Asn1X509SetExtensions(
  2622. IN DWORD cExtension,
  2623. IN PCERT_EXTENSION pExtension,
  2624. OUT Extensions *pAsn1
  2625. )
  2626. {
  2627. Extension *pAsn1Ext;
  2628. pAsn1->value = NULL;
  2629. pAsn1->count = 0;
  2630. if (cExtension == 0)
  2631. return TRUE;
  2632. pAsn1Ext = (Extension *) PkiZeroAlloc(cExtension * sizeof(Extension));
  2633. if (pAsn1Ext == NULL)
  2634. return FALSE;
  2635. pAsn1->value = pAsn1Ext;
  2636. pAsn1->count = cExtension;
  2637. for ( ; cExtension > 0; cExtension--, pExtension++, pAsn1Ext++) {
  2638. if (!Asn1X509SetEncodedObjId(pExtension->pszObjId, &pAsn1Ext->extnId))
  2639. return FALSE;
  2640. if (pExtension->fCritical) {
  2641. pAsn1Ext->critical = TRUE;
  2642. pAsn1Ext->bit_mask |= critical_present;
  2643. }
  2644. Asn1X509SetOctetString(&pExtension->Value, &pAsn1Ext->extnValue);
  2645. }
  2646. return TRUE;
  2647. }
  2648. void Asn1X509FreeExtensions(
  2649. IN Extensions *pAsn1)
  2650. {
  2651. if (pAsn1->value) {
  2652. PkiFree(pAsn1->value);
  2653. pAsn1->value = NULL;
  2654. }
  2655. pAsn1->count = 0;
  2656. }
  2657. void Asn1X509GetExtensions(
  2658. IN Extensions *pAsn1,
  2659. IN DWORD dwFlags,
  2660. OUT DWORD *pcExtension,
  2661. OUT PCERT_EXTENSION *ppExtension,
  2662. IN OUT BYTE **ppbExtra,
  2663. IN OUT LONG *plRemainExtra
  2664. )
  2665. {
  2666. LONG lRemainExtra = *plRemainExtra;
  2667. BYTE *pbExtra = *ppbExtra;
  2668. LONG lAlignExtra;
  2669. DWORD cExt;
  2670. Extension *pAsn1Ext;
  2671. PCERT_EXTENSION pGetExt;
  2672. cExt = pAsn1->count;
  2673. lAlignExtra = INFO_LEN_ALIGN(cExt * sizeof(CERT_EXTENSION));
  2674. lRemainExtra -= lAlignExtra;
  2675. if (lRemainExtra >= 0) {
  2676. *pcExtension = cExt;
  2677. pGetExt = (PCERT_EXTENSION) pbExtra;
  2678. *ppExtension = pGetExt;
  2679. pbExtra += lAlignExtra;
  2680. } else
  2681. pGetExt = NULL;
  2682. pAsn1Ext = pAsn1->value;
  2683. for ( ; cExt > 0; cExt--, pAsn1Ext++, pGetExt++) {
  2684. Asn1X509GetEncodedObjId(&pAsn1Ext->extnId, dwFlags, &pGetExt->pszObjId,
  2685. &pbExtra, &lRemainExtra);
  2686. if (lRemainExtra >= 0) {
  2687. pGetExt->fCritical = FALSE;
  2688. if (pAsn1Ext->bit_mask & critical_present)
  2689. pGetExt->fCritical = (BOOLEAN) pAsn1Ext->critical;
  2690. }
  2691. Asn1X509GetOctetString(&pAsn1Ext->extnValue, dwFlags, &pGetExt->Value,
  2692. &pbExtra, &lRemainExtra);
  2693. }
  2694. *plRemainExtra = lRemainExtra;
  2695. *ppbExtra = pbExtra;
  2696. }
  2697. //+-------------------------------------------------------------------------
  2698. // Set/Free/Get CRL Entries
  2699. //--------------------------------------------------------------------------
  2700. BOOL Asn1X509SetCrlEntries(
  2701. IN DWORD cEntry,
  2702. IN PCRL_ENTRY pEntry,
  2703. OUT RevokedCertificates *pAsn1
  2704. )
  2705. {
  2706. CRLEntry *pAsn1Entry;
  2707. pAsn1->value = NULL;
  2708. pAsn1->count = 0;
  2709. if (cEntry == 0)
  2710. return TRUE;
  2711. pAsn1Entry = (CRLEntry *) PkiZeroAlloc(cEntry * sizeof(CRLEntry));
  2712. if (pAsn1Entry == NULL)
  2713. return FALSE;
  2714. pAsn1->value = pAsn1Entry;
  2715. pAsn1->count = cEntry;
  2716. for ( ; cEntry > 0; cEntry--, pEntry++, pAsn1Entry++) {
  2717. if (!Asn1X509SetHugeInteger(&pEntry->SerialNumber,
  2718. &pAsn1Entry->userCertificate))
  2719. return FALSE;
  2720. if (!PkiAsn1ToChoiceOfTime(&pEntry->RevocationDate,
  2721. &pAsn1Entry->revocationDate.choice,
  2722. &pAsn1Entry->revocationDate.u.generalTime,
  2723. &pAsn1Entry->revocationDate.u.utcTime
  2724. )) {
  2725. SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
  2726. return FALSE;
  2727. }
  2728. if (pEntry->cExtension) {
  2729. if (!Asn1X509SetExtensions(pEntry->cExtension, pEntry->rgExtension,
  2730. &pAsn1Entry->crlEntryExtensions))
  2731. return FALSE;
  2732. pAsn1Entry->bit_mask |= crlEntryExtensions_present;
  2733. }
  2734. }
  2735. return TRUE;
  2736. }
  2737. void Asn1X509FreeCrlEntries(
  2738. IN RevokedCertificates *pAsn1)
  2739. {
  2740. if (pAsn1->value) {
  2741. CRLEntry *pAsn1Entry = pAsn1->value;
  2742. DWORD cEntry = pAsn1->count;
  2743. for ( ; cEntry > 0; cEntry--, pAsn1Entry++) {
  2744. Asn1X509FreeHugeInteger(&pAsn1Entry->userCertificate);
  2745. Asn1X509FreeExtensions(&pAsn1Entry->crlEntryExtensions);
  2746. }
  2747. PkiFree(pAsn1->value);
  2748. pAsn1->value = NULL;
  2749. }
  2750. pAsn1->count = 0;
  2751. }
  2752. BOOL Asn1X509GetCrlEntries(
  2753. IN RevokedCertificates *pAsn1,
  2754. IN DWORD dwFlags,
  2755. OUT DWORD *pcEntry,
  2756. OUT PCRL_ENTRY *ppEntry,
  2757. IN OUT BYTE **ppbExtra,
  2758. IN OUT LONG *plRemainExtra
  2759. )
  2760. {
  2761. LONG lRemainExtra = *plRemainExtra;
  2762. BYTE *pbExtra = *ppbExtra;
  2763. LONG lAlignExtra;
  2764. DWORD cEntry;
  2765. CRLEntry *pAsn1Entry;
  2766. PCRL_ENTRY pGetEntry;
  2767. cEntry = pAsn1->count;
  2768. lAlignExtra = INFO_LEN_ALIGN(cEntry * sizeof(CRL_ENTRY));
  2769. lRemainExtra -= lAlignExtra;
  2770. if (lRemainExtra >= 0) {
  2771. *pcEntry = cEntry;
  2772. pGetEntry = (PCRL_ENTRY) pbExtra;
  2773. *ppEntry = pGetEntry;
  2774. pbExtra += lAlignExtra;
  2775. } else
  2776. pGetEntry = NULL;
  2777. pAsn1Entry = pAsn1->value;
  2778. for ( ; cEntry > 0; cEntry--, pAsn1Entry++, pGetEntry++) {
  2779. Asn1X509GetHugeInteger(&pAsn1Entry->userCertificate, dwFlags,
  2780. &pGetEntry->SerialNumber, &pbExtra, &lRemainExtra);
  2781. // RevocationDate
  2782. if (lRemainExtra >= 0) {
  2783. if (!PkiAsn1FromChoiceOfTime(pAsn1Entry->revocationDate.choice,
  2784. &pAsn1Entry->revocationDate.u.generalTime,
  2785. &pAsn1Entry->revocationDate.u.utcTime,
  2786. &pGetEntry->RevocationDate)) {
  2787. SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
  2788. return FALSE;
  2789. }
  2790. }
  2791. // Extensions
  2792. if (pAsn1Entry->bit_mask & crlEntryExtensions_present)
  2793. Asn1X509GetExtensions(&pAsn1Entry->crlEntryExtensions, dwFlags,
  2794. &pGetEntry->cExtension, &pGetEntry->rgExtension,
  2795. &pbExtra, &lRemainExtra);
  2796. else if (lRemainExtra >= 0) {
  2797. pGetEntry->cExtension = 0;
  2798. pGetEntry->rgExtension = NULL;
  2799. }
  2800. }
  2801. *plRemainExtra = lRemainExtra;
  2802. *ppbExtra = pbExtra;
  2803. return TRUE;
  2804. }
  2805. #ifndef ASN1_SUPPORTS_UTF8_TAG
  2806. void inline Asn1X509ReverseCopy(
  2807. OUT BYTE *pbOut,
  2808. IN BYTE *pbInOrg,
  2809. IN DWORD cbIn
  2810. )
  2811. {
  2812. BYTE *pbIn = pbInOrg + cbIn - 1;
  2813. while (cbIn-- > 0)
  2814. *pbOut++ = *pbIn--;
  2815. }
  2816. #define MAX_LENGTH_OCTETS 5
  2817. //+-------------------------------------------------------------------------
  2818. // Copy out the encoding of the length octets for a specified content length.
  2819. //
  2820. // Returns the number of length octets
  2821. //--------------------------------------------------------------------------
  2822. DWORD Asn1X509GetLengthOctets(
  2823. IN DWORD cbContent,
  2824. OUT BYTE rgbLength[MAX_LENGTH_OCTETS]
  2825. )
  2826. {
  2827. DWORD cbLength;
  2828. if (cbContent < 0x80) {
  2829. rgbLength[0] = (BYTE) cbContent;
  2830. cbLength = 0;
  2831. } else {
  2832. if (cbContent > 0xffffff)
  2833. cbLength = 4;
  2834. else if (cbContent > 0xffff)
  2835. cbLength = 3;
  2836. else if (cbContent > 0xff)
  2837. cbLength = 2;
  2838. else
  2839. cbLength = 1;
  2840. rgbLength[0] = (BYTE) cbLength | 0x80;
  2841. Asn1X509ReverseCopy(rgbLength + 1, (BYTE *) &cbContent, cbLength);
  2842. }
  2843. return cbLength + 1;
  2844. }
  2845. // Prefix includes:
  2846. // - 1 byte for number of unused bytes in the prefix
  2847. // - 1 byte for the tag
  2848. // - up to 5 bytes for the length octets
  2849. #define MAX_ENCODED_UTF8_PREFIX (1 + 1 + MAX_LENGTH_OCTETS)
  2850. #define UTF8_ASN_TAG 0x0C
  2851. //+-------------------------------------------------------------------------
  2852. // Allocate and Encode UTF8
  2853. //
  2854. // The returned pbEncoded points to an ASN.1 encoded UTF8 string.
  2855. // pbEncoded points to the UTF8_ASN_TAG, followed by the length octets and
  2856. // then the UTF8 bytes.
  2857. //
  2858. // *(pbEncoded -1) contains the number of unused bytes preceding the encoded
  2859. // UTF8, ie, pbAllocEncoded = pbEncoded - *(pbEncoded -1).
  2860. //--------------------------------------------------------------------------
  2861. BOOL Asn1X509AllocAndEncodeUTF8(
  2862. IN PCERT_RDN_VALUE_BLOB pValue,
  2863. OUT BYTE **ppbEncoded,
  2864. OUT DWORD *pcbEncoded
  2865. )
  2866. {
  2867. BOOL fResult;
  2868. BYTE *pbAllocEncoded = NULL;
  2869. BYTE *pbEncoded;
  2870. DWORD cbEncoded;
  2871. BYTE rgbLength[MAX_LENGTH_OCTETS];
  2872. DWORD cbLength;
  2873. DWORD cbUnusedPrefix;
  2874. int cchUnicode;
  2875. int cchUTF8;
  2876. cchUnicode = pValue->cbData / sizeof(WCHAR);
  2877. // In the largest buffer case there are 3 bytes per Unicode character.
  2878. // The encoded UTF8 is preceded with a prefix consisting of a byte
  2879. // indicating the number of unused bytes in the prefix, a byte for the
  2880. // UTF8 tag and up to 5 bytes for the length octets.
  2881. if (NULL == (pbAllocEncoded = (BYTE *) PkiNonzeroAlloc(
  2882. MAX_ENCODED_UTF8_PREFIX + cchUnicode * 3)))
  2883. goto OutOfMemory;
  2884. if (0 == cchUnicode)
  2885. cchUTF8 = 0;
  2886. else {
  2887. if (0 >= (cchUTF8 = WideCharToUTF8(
  2888. (LPCWSTR) pValue->pbData,
  2889. cchUnicode,
  2890. (LPSTR) (pbAllocEncoded + MAX_ENCODED_UTF8_PREFIX),
  2891. cchUnicode * 3
  2892. )))
  2893. goto WideCharToUTF8Error;
  2894. }
  2895. cbLength = Asn1X509GetLengthOctets(cchUTF8, rgbLength);
  2896. assert(MAX_ENCODED_UTF8_PREFIX > (1 + cbLength));
  2897. cbUnusedPrefix = MAX_ENCODED_UTF8_PREFIX - (1 + cbLength);
  2898. pbEncoded = pbAllocEncoded + cbUnusedPrefix;
  2899. cbEncoded = 1 + cbLength + cchUTF8;
  2900. *(pbEncoded - 1) = (BYTE) cbUnusedPrefix;
  2901. *(pbEncoded) = UTF8_ASN_TAG;
  2902. memcpy(pbEncoded + 1, rgbLength, cbLength);
  2903. fResult = TRUE;
  2904. CommonReturn:
  2905. *ppbEncoded = pbEncoded;
  2906. *pcbEncoded = cbEncoded;
  2907. return fResult;
  2908. ErrorReturn:
  2909. PkiFree(pbAllocEncoded);
  2910. pbEncoded = NULL;
  2911. cbEncoded = 0;
  2912. fResult = FALSE;
  2913. goto CommonReturn;
  2914. TRACE_ERROR(OutOfMemory)
  2915. TRACE_ERROR(WideCharToUTF8Error)
  2916. }
  2917. //+-------------------------------------------------------------------------
  2918. // Free previously encoded UTF8
  2919. //
  2920. // *(pbEncoded -1) contains the number of unused bytes preceding the encoded
  2921. // UTF8, ie, pbAllocEncoded = pbEncoded - *(pbEncoded -1).
  2922. //--------------------------------------------------------------------------
  2923. void Asn1X509FreeEncodedUTF8(
  2924. IN BYTE *pbEncoded
  2925. )
  2926. {
  2927. if (pbEncoded) {
  2928. BYTE *pbAllocEncoded;
  2929. assert(MAX_ENCODED_UTF8_PREFIX > *(pbEncoded -1));
  2930. pbAllocEncoded = pbEncoded - *(pbEncoded - 1);
  2931. PkiFree(pbAllocEncoded);
  2932. }
  2933. }
  2934. //+-------------------------------------------------------------------------
  2935. // Get UTF8
  2936. //--------------------------------------------------------------------------
  2937. BOOL Asn1X509GetUTF8(
  2938. IN NOCOPYANY *pAsn1,
  2939. IN DWORD dwFlags,
  2940. OUT DWORD *pdwValueType,
  2941. OUT PCERT_RDN_VALUE_BLOB pValue,
  2942. IN OUT BYTE **ppbExtra,
  2943. IN OUT LONG *plRemainExtra
  2944. )
  2945. {
  2946. BOOL fResult;
  2947. const BYTE *pbEncoded = (const BYTE *) pAsn1->encoded;
  2948. DWORD cbEncoded = pAsn1->length;
  2949. const BYTE *pbContent;
  2950. DWORD cbContent;
  2951. int cchUnicode;
  2952. LPWSTR pwszUnicode = NULL;
  2953. LONG lAlignExtra;
  2954. LONG lData;
  2955. if (0 == cbEncoded || UTF8_ASN_TAG != *pbEncoded)
  2956. goto InvalidUTF8Tag;
  2957. if (0 >= Asn1UtilExtractContent(
  2958. pbEncoded,
  2959. cbEncoded,
  2960. &cbContent,
  2961. &pbContent
  2962. ))
  2963. goto InvalidUTF8Header;
  2964. if (0 == cbContent)
  2965. cchUnicode = 0;
  2966. else {
  2967. if (pbContent + cbContent > pbEncoded + cbEncoded)
  2968. goto InvalidUTF8Header;
  2969. // In the largest buffer case there is one Unicode character per
  2970. // UTF8 character
  2971. if (NULL == (pwszUnicode = (LPWSTR) PkiNonzeroAlloc(
  2972. cbContent * sizeof(WCHAR))))
  2973. goto OutOfMemory;
  2974. if (0 >= (cchUnicode = UTF8ToWideChar(
  2975. (LPCSTR) pbContent,
  2976. cbContent, // cchUTF8
  2977. pwszUnicode,
  2978. cbContent // cchUnicode
  2979. )))
  2980. goto UTF8ToWideCharError;
  2981. }
  2982. // Add + sizeof(WCHAR) for added 0 bytes. Want to ensure that the WCHAR
  2983. // string is always null terminated
  2984. lData = cchUnicode * sizeof(WCHAR);
  2985. lAlignExtra = INFO_LEN_ALIGN(lData + sizeof(WCHAR));
  2986. *plRemainExtra -= lAlignExtra;
  2987. if (*plRemainExtra >= 0) {
  2988. *pdwValueType = CERT_RDN_UTF8_STRING;
  2989. pValue->pbData = *ppbExtra;
  2990. pValue->cbData = (DWORD) lData;
  2991. if (lData > 0)
  2992. memcpy(pValue->pbData, pwszUnicode, lData);
  2993. memset(pValue->pbData + lData, 0, sizeof(WCHAR));
  2994. *ppbExtra += lAlignExtra;
  2995. }
  2996. fResult = TRUE;
  2997. CommonReturn:
  2998. PkiFree(pwszUnicode);
  2999. return fResult;
  3000. ErrorReturn:
  3001. fResult = FALSE;
  3002. goto CommonReturn;
  3003. SET_ERROR(InvalidUTF8Tag, CRYPT_E_BAD_ENCODE)
  3004. SET_ERROR(InvalidUTF8Header, CRYPT_E_BAD_ENCODE)
  3005. TRACE_ERROR(OutOfMemory)
  3006. TRACE_ERROR(UTF8ToWideCharError)
  3007. }
  3008. #endif // not defined ASN1_SUPPORTS_UTF8_TAG
  3009. //+-------------------------------------------------------------------------
  3010. // Set/Get AnyString
  3011. //--------------------------------------------------------------------------
  3012. void Asn1X509SetAnyString(
  3013. IN DWORD dwValueType,
  3014. IN PCERT_RDN_VALUE_BLOB pValue,
  3015. OUT AnyString *pAsn1
  3016. )
  3017. {
  3018. pAsn1->u.octetString.value = pValue->pbData;
  3019. pAsn1->u.octetString.length = pValue->cbData;
  3020. switch (dwValueType) {
  3021. case CERT_RDN_OCTET_STRING:
  3022. pAsn1->choice = octetString_chosen;
  3023. break;
  3024. case CERT_RDN_NUMERIC_STRING:
  3025. pAsn1->choice = numericString_chosen;
  3026. break;
  3027. case CERT_RDN_PRINTABLE_STRING:
  3028. pAsn1->choice = printableString_chosen;
  3029. break;
  3030. case CERT_RDN_TELETEX_STRING:
  3031. pAsn1->choice = teletexString_chosen;
  3032. break;
  3033. case CERT_RDN_VIDEOTEX_STRING:
  3034. pAsn1->choice = videotexString_chosen;
  3035. break;
  3036. case CERT_RDN_IA5_STRING:
  3037. pAsn1->choice = ia5String_chosen;
  3038. break;
  3039. case CERT_RDN_GRAPHIC_STRING:
  3040. pAsn1->choice = graphicString_chosen;
  3041. break;
  3042. case CERT_RDN_VISIBLE_STRING:
  3043. pAsn1->choice = visibleString_chosen;
  3044. break;
  3045. case CERT_RDN_GENERAL_STRING:
  3046. pAsn1->choice = generalString_chosen;
  3047. break;
  3048. case CERT_RDN_UNIVERSAL_STRING:
  3049. pAsn1->choice = universalString_chosen;
  3050. pAsn1->u.octetString.length = pValue->cbData / 4;
  3051. break;
  3052. case CERT_RDN_BMP_STRING:
  3053. pAsn1->choice = bmpString_chosen;
  3054. pAsn1->u.octetString.length = pValue->cbData / 2;
  3055. break;
  3056. #ifdef ASN1_SUPPORTS_UTF8_TAG
  3057. case CERT_RDN_UTF8_STRING:
  3058. pAsn1->choice = utf8String_chosen;
  3059. pAsn1->u.octetString.length = pValue->cbData / 2;
  3060. break;
  3061. #endif // ASN1_SUPPORTS_UTF8_TAG
  3062. default:
  3063. assert(dwValueType >= CERT_RDN_OCTET_STRING &&
  3064. dwValueType <= CERT_RDN_UTF8_STRING);
  3065. pAsn1->choice = 0;
  3066. }
  3067. }
  3068. void Asn1X509GetAnyString(
  3069. IN AnyString *pAsn1,
  3070. IN DWORD dwFlags,
  3071. OUT DWORD *pdwValueType,
  3072. OUT PCERT_RDN_VALUE_BLOB pValue,
  3073. IN OUT BYTE **ppbExtra,
  3074. IN OUT LONG *plRemainExtra
  3075. )
  3076. {
  3077. LONG lAlignExtra;
  3078. DWORD dwValueType;
  3079. BYTE *pbData;
  3080. LONG lData;
  3081. pbData = pAsn1->u.octetString.value;
  3082. lData = pAsn1->u.octetString.length;
  3083. switch (pAsn1->choice) {
  3084. case octetString_chosen:
  3085. dwValueType = CERT_RDN_OCTET_STRING;
  3086. break;
  3087. case numericString_chosen:
  3088. dwValueType = CERT_RDN_NUMERIC_STRING;
  3089. break;
  3090. case printableString_chosen:
  3091. dwValueType = CERT_RDN_PRINTABLE_STRING;
  3092. break;
  3093. case teletexString_chosen:
  3094. dwValueType = CERT_RDN_TELETEX_STRING;
  3095. break;
  3096. case videotexString_chosen:
  3097. dwValueType = CERT_RDN_VIDEOTEX_STRING;
  3098. break;
  3099. case ia5String_chosen:
  3100. dwValueType = CERT_RDN_IA5_STRING;
  3101. break;
  3102. case graphicString_chosen:
  3103. dwValueType = CERT_RDN_GRAPHIC_STRING;
  3104. break;
  3105. case visibleString_chosen:
  3106. dwValueType = CERT_RDN_VISIBLE_STRING;
  3107. break;
  3108. case generalString_chosen:
  3109. dwValueType = CERT_RDN_GENERAL_STRING;
  3110. break;
  3111. case universalString_chosen:
  3112. dwValueType = CERT_RDN_UNIVERSAL_STRING;
  3113. lData = pAsn1->u.universalString.length * 4;
  3114. break;
  3115. case bmpString_chosen:
  3116. dwValueType = CERT_RDN_BMP_STRING;
  3117. lData = pAsn1->u.bmpString.length * 2;
  3118. break;
  3119. #ifdef ASN1_SUPPORTS_UTF8_TAG
  3120. case utf8String_chosen:
  3121. dwValueType = CERT_RDN_UTF8_STRING;
  3122. lData = pAsn1->u.utf8String.length * 2;
  3123. break;
  3124. #endif // ASN1_SUPPORTS_UTF8_TAG
  3125. default:
  3126. assert(pAsn1->choice >= 1 && pAsn1->choice <= bmpString_chosen);
  3127. dwValueType = 0;
  3128. }
  3129. // Add + sizeof(WCHAR) for added 0 bytes. Want to ensure that a char
  3130. // or WCHAR string is always null terminated
  3131. lAlignExtra = INFO_LEN_ALIGN(lData + sizeof(WCHAR));
  3132. *plRemainExtra -= lAlignExtra;
  3133. if (*plRemainExtra >= 0) {
  3134. *pdwValueType = dwValueType;
  3135. pValue->pbData = *ppbExtra;
  3136. pValue->cbData = (DWORD) lData;
  3137. if (lData > 0)
  3138. memcpy(pValue->pbData, pbData, lData);
  3139. memset(pValue->pbData + lData, 0, sizeof(WCHAR));
  3140. *ppbExtra += lAlignExtra;
  3141. }
  3142. }
  3143. //+-------------------------------------------------------------------------
  3144. // Allocate and Encode AnyString
  3145. //--------------------------------------------------------------------------
  3146. BOOL Asn1X509AllocAndEncodeAnyString(
  3147. IN DWORD dwValueType,
  3148. IN PCERT_RDN_VALUE_BLOB pValue,
  3149. OUT BYTE **ppbEncoded,
  3150. OUT DWORD *pcbEncoded
  3151. )
  3152. {
  3153. BOOL fResult;
  3154. AnyString Asn1String;
  3155. ASN1error_e Asn1Err;
  3156. ASN1encoding_t pEnc = GetEncoder();
  3157. Asn1X509SetAnyString(dwValueType, pValue, &Asn1String);
  3158. *ppbEncoded = NULL;
  3159. *pcbEncoded = 0;
  3160. PkiAsn1SetEncodingRule(pEnc, ASN1_BER_RULE_DER);
  3161. if (ASN1_SUCCESS != (Asn1Err = PkiAsn1Encode(
  3162. pEnc,
  3163. &Asn1String,
  3164. AnyString_PDU,
  3165. ppbEncoded,
  3166. pcbEncoded
  3167. )))
  3168. goto Asn1EncodeError;
  3169. fResult = TRUE;
  3170. CommonReturn:
  3171. return fResult;
  3172. ErrorReturn:
  3173. fResult = FALSE;
  3174. goto CommonReturn;
  3175. SET_ERROR_VAR(Asn1EncodeError, PkiAsn1ErrToHr(Asn1Err))
  3176. }
  3177. //+-------------------------------------------------------------------------
  3178. // Set/Free/Get CERT_RDN attribute value
  3179. //--------------------------------------------------------------------------
  3180. BOOL Asn1X509SetRDNAttributeValue(
  3181. IN DWORD dwValueType,
  3182. IN PCERT_RDN_VALUE_BLOB pValue,
  3183. OUT NOCOPYANY *pAsn1
  3184. )
  3185. {
  3186. memset(pAsn1, 0, sizeof(*pAsn1));
  3187. if (dwValueType == CERT_RDN_ANY_TYPE) {
  3188. SetLastError((DWORD) E_INVALIDARG);
  3189. return FALSE;
  3190. }
  3191. // Determine if value is an encoded representation or is a known string
  3192. // type. Encode accordingly.
  3193. if (dwValueType == CERT_RDN_ENCODED_BLOB) {
  3194. Asn1X509SetAny(pValue, pAsn1);
  3195. #ifndef ASN1_SUPPORTS_UTF8_TAG
  3196. } else if (dwValueType == CERT_RDN_UTF8_STRING) {
  3197. CRYPT_OBJID_BLOB ObjIdBlob;
  3198. if (!Asn1X509AllocAndEncodeUTF8(
  3199. pValue,
  3200. &ObjIdBlob.pbData,
  3201. &ObjIdBlob.cbData))
  3202. return FALSE;
  3203. Asn1X509SetAny(&ObjIdBlob, pAsn1);
  3204. #endif // not defined ASN1_SUPPORTS_UTF8_TAG
  3205. } else {
  3206. CRYPT_OBJID_BLOB ObjIdBlob;
  3207. if (!Asn1X509AllocAndEncodeAnyString(
  3208. dwValueType,
  3209. pValue,
  3210. &ObjIdBlob.pbData,
  3211. &ObjIdBlob.cbData))
  3212. return FALSE;
  3213. Asn1X509SetAny(&ObjIdBlob, pAsn1);
  3214. }
  3215. return TRUE;
  3216. }
  3217. void Asn1X509FreeRDNAttributeValue(
  3218. IN DWORD dwValueType,
  3219. IN OUT NOCOPYANY *pAsn1
  3220. )
  3221. {
  3222. #ifndef ASN1_SUPPORTS_UTF8_TAG
  3223. if (dwValueType == CERT_RDN_UTF8_STRING) {
  3224. Asn1X509FreeEncodedUTF8((BYTE *) pAsn1->encoded);
  3225. pAsn1->encoded = NULL;
  3226. pAsn1->length = 0;
  3227. } else
  3228. #endif // not defined ASN1_SUPPORTS_UTF8_TAG
  3229. if (dwValueType != CERT_RDN_ENCODED_BLOB) {
  3230. if (pAsn1->encoded) {
  3231. DWORD dwErr = GetLastError();
  3232. // TlsGetValue globbers LastError
  3233. PkiAsn1FreeEncoded(GetEncoder(), pAsn1->encoded);
  3234. pAsn1->encoded = NULL;
  3235. SetLastError(dwErr);
  3236. }
  3237. pAsn1->length = 0;
  3238. }
  3239. }
  3240. BOOL Asn1X509GetRDNAttributeValue(
  3241. IN NOCOPYANY *pAsn1,
  3242. IN DWORD dwFlags,
  3243. OUT DWORD *pdwValueType,
  3244. OUT PCERT_RDN_VALUE_BLOB pValue,
  3245. IN OUT BYTE **ppbExtra,
  3246. IN OUT LONG *plRemainExtra
  3247. )
  3248. {
  3249. ASN1decoding_t pDec = GetDecoder();
  3250. AnyString *pAsn1String = NULL;
  3251. #ifndef ASN1_SUPPORTS_UTF8_TAG
  3252. if (0 < pAsn1->length && UTF8_ASN_TAG == *((BYTE *) pAsn1->encoded))
  3253. return Asn1X509GetUTF8(
  3254. pAsn1,
  3255. dwFlags,
  3256. pdwValueType,
  3257. pValue,
  3258. ppbExtra,
  3259. plRemainExtra
  3260. );
  3261. #endif // not defined ASN1_SUPPORTS_UTF8_TAG
  3262. #ifdef OSS_CRYPT_ASN1
  3263. unsigned long ulPrevDecodingFlags;
  3264. // Since its acceptable for the following decode to fail, don't output
  3265. // decode errors.
  3266. ulPrevDecodingFlags = ossGetDecodingFlags((POssGlobal) pDec);
  3267. if (ulPrevDecodingFlags & DEBUG_ERRORS)
  3268. ossSetDecodingFlags((POssGlobal) pDec,
  3269. ulPrevDecodingFlags & ~DEBUG_ERRORS);
  3270. ossSetEncodingRules((POssGlobal) pDec, OSS_BER);
  3271. #endif // OSS_CRYPT_ASN1
  3272. // Check if the value is a string type
  3273. if (ASN1_SUCCESS == PkiAsn1Decode(
  3274. pDec,
  3275. (void **) &pAsn1String,
  3276. AnyString_PDU,
  3277. (BYTE *) pAsn1->encoded,
  3278. pAsn1->length
  3279. )) {
  3280. Asn1X509GetAnyString(pAsn1String, dwFlags, pdwValueType, pValue,
  3281. ppbExtra, plRemainExtra);
  3282. } else {
  3283. // Encoded representation
  3284. if (*plRemainExtra >= 0)
  3285. *pdwValueType = CERT_RDN_ENCODED_BLOB;
  3286. Asn1X509GetAny(pAsn1, dwFlags, pValue, ppbExtra, plRemainExtra);
  3287. }
  3288. #ifdef OSS_CRYPT_ASN1
  3289. // Restore previous flags
  3290. if (ulPrevDecodingFlags & DEBUG_ERRORS)
  3291. ossSetDecodingFlags((POssGlobal) pDec, ulPrevDecodingFlags);
  3292. #endif // OSS_CRYPT_ASN1
  3293. PkiAsn1FreeDecoded(
  3294. pDec,
  3295. pAsn1String,
  3296. AnyString_PDU
  3297. );
  3298. return TRUE;
  3299. }
  3300. //+-------------------------------------------------------------------------
  3301. // Set/Free/Get CERT_RDN attribute
  3302. //--------------------------------------------------------------------------
  3303. BOOL Asn1X509SetRDNAttribute(
  3304. IN PCERT_RDN_ATTR pInfo,
  3305. OUT AttributeTypeValue *pAsn1
  3306. )
  3307. {
  3308. memset(pAsn1, 0, sizeof(*pAsn1));
  3309. if (pInfo->pszObjId) {
  3310. if (!Asn1X509SetEncodedObjId(pInfo->pszObjId, &pAsn1->type))
  3311. return FALSE;
  3312. }
  3313. return Asn1X509SetRDNAttributeValue(
  3314. pInfo->dwValueType,
  3315. &pInfo->Value,
  3316. &pAsn1->value
  3317. );
  3318. }
  3319. void Asn1X509FreeRDNAttribute(
  3320. IN PCERT_RDN_ATTR pInfo,
  3321. IN OUT AttributeTypeValue *pAsn1
  3322. )
  3323. {
  3324. Asn1X509FreeRDNAttributeValue(
  3325. pInfo->dwValueType,
  3326. &pAsn1->value
  3327. );
  3328. }
  3329. BOOL Asn1X509GetRDNAttribute(
  3330. IN AttributeTypeValue *pAsn1,
  3331. IN DWORD dwFlags,
  3332. OUT PCERT_RDN_ATTR pInfo,
  3333. IN OUT BYTE **ppbExtra,
  3334. IN OUT LONG *plRemainExtra
  3335. )
  3336. {
  3337. // Get ObjectIdentifier
  3338. Asn1X509GetEncodedObjId(&pAsn1->type, dwFlags, &pInfo->pszObjId,
  3339. ppbExtra, plRemainExtra);
  3340. // Get value
  3341. return Asn1X509GetRDNAttributeValue(&pAsn1->value, dwFlags,
  3342. &pInfo->dwValueType, &pInfo->Value, ppbExtra, plRemainExtra);
  3343. }
  3344. //+-------------------------------------------------------------------------
  3345. // Set/Free/Get SeqOfAny
  3346. //--------------------------------------------------------------------------
  3347. BOOL WINAPI Asn1X509SetSeqOfAny(
  3348. IN DWORD cValue,
  3349. IN PCRYPT_DER_BLOB pValue,
  3350. #ifdef OSS_CRYPT_ASN1
  3351. OUT unsigned int *pAsn1Count,
  3352. #else
  3353. OUT ASN1uint32_t *pAsn1Count,
  3354. #endif // OSS_CRYPT_ASN1
  3355. OUT NOCOPYANY **ppAsn1Value
  3356. )
  3357. {
  3358. *pAsn1Count = 0;
  3359. *ppAsn1Value = NULL;
  3360. if (cValue > 0) {
  3361. NOCOPYANY *pAsn1Value;
  3362. pAsn1Value = (NOCOPYANY *) PkiZeroAlloc(cValue * sizeof(NOCOPYANY));
  3363. if (pAsn1Value == NULL)
  3364. return FALSE;
  3365. *pAsn1Count = cValue;
  3366. *ppAsn1Value = pAsn1Value;
  3367. for ( ; cValue > 0; cValue--, pValue++, pAsn1Value++)
  3368. Asn1X509SetAny(pValue, pAsn1Value);
  3369. }
  3370. return TRUE;
  3371. }
  3372. void Asn1X509FreeSeqOfAny(
  3373. IN NOCOPYANY *pAsn1Value
  3374. )
  3375. {
  3376. if (pAsn1Value)
  3377. PkiFree(pAsn1Value);
  3378. }
  3379. void Asn1X509GetSeqOfAny(
  3380. IN unsigned int Asn1Count,
  3381. IN NOCOPYANY *pAsn1Value,
  3382. IN DWORD dwFlags,
  3383. OUT DWORD *pcValue,
  3384. OUT PCRYPT_DER_BLOB *ppValue,
  3385. IN OUT BYTE **ppbExtra,
  3386. IN OUT LONG *plRemainExtra
  3387. )
  3388. {
  3389. LONG lAlignExtra;
  3390. PCRYPT_ATTR_BLOB pValue;
  3391. lAlignExtra = INFO_LEN_ALIGN(Asn1Count * sizeof(CRYPT_DER_BLOB));
  3392. *plRemainExtra -= lAlignExtra;
  3393. if (*plRemainExtra >= 0) {
  3394. *pcValue = Asn1Count;
  3395. pValue = (PCRYPT_DER_BLOB) *ppbExtra;
  3396. *ppValue = pValue;
  3397. *ppbExtra += lAlignExtra;
  3398. } else
  3399. pValue = NULL;
  3400. for (; Asn1Count > 0; Asn1Count--, pAsn1Value++, pValue++)
  3401. Asn1X509GetAny(pAsn1Value, dwFlags, pValue, ppbExtra, plRemainExtra);
  3402. }
  3403. //+-------------------------------------------------------------------------
  3404. // Set/Free/Get CRYPT_ATTRIBUTE
  3405. //--------------------------------------------------------------------------
  3406. BOOL WINAPI Asn1X509SetAttribute(
  3407. IN PCRYPT_ATTRIBUTE pInfo,
  3408. OUT Attribute *pAsn1
  3409. )
  3410. {
  3411. memset(pAsn1, 0, sizeof(*pAsn1));
  3412. if (!Asn1X509SetEncodedObjId(pInfo->pszObjId, &pAsn1->type))
  3413. return FALSE;
  3414. return Asn1X509SetSeqOfAny(
  3415. pInfo->cValue,
  3416. pInfo->rgValue,
  3417. &pAsn1->values.count,
  3418. &pAsn1->values.value);
  3419. }
  3420. void Asn1X509FreeAttribute(
  3421. IN OUT Attribute *pAsn1
  3422. )
  3423. {
  3424. Asn1X509FreeSeqOfAny(pAsn1->values.value);
  3425. }
  3426. void Asn1X509GetAttribute(
  3427. IN Attribute *pAsn1,
  3428. IN DWORD dwFlags,
  3429. OUT PCRYPT_ATTRIBUTE pInfo,
  3430. IN OUT BYTE **ppbExtra,
  3431. IN OUT LONG *plRemainExtra
  3432. )
  3433. {
  3434. Asn1X509GetEncodedObjId(&pAsn1->type, dwFlags,
  3435. &pInfo->pszObjId, ppbExtra, plRemainExtra);
  3436. Asn1X509GetSeqOfAny(pAsn1->values.count, pAsn1->values.value, dwFlags,
  3437. &pInfo->cValue, &pInfo->rgValue, ppbExtra, plRemainExtra);
  3438. }
  3439. //+-------------------------------------------------------------------------
  3440. // Set/Free/Get Attributes
  3441. //--------------------------------------------------------------------------
  3442. BOOL Asn1X509SetAttributes(
  3443. IN DWORD cAttribute,
  3444. IN PCRYPT_ATTRIBUTE pAttribute,
  3445. OUT Attributes *pAsn1
  3446. )
  3447. {
  3448. Attribute *pAsn1Attr;
  3449. pAsn1->value = NULL;
  3450. pAsn1->count = 0;
  3451. if (cAttribute == 0)
  3452. return TRUE;
  3453. pAsn1Attr = (Attribute *) PkiZeroAlloc(cAttribute * sizeof(Attribute));
  3454. if (pAsn1Attr == NULL)
  3455. return FALSE;
  3456. pAsn1->value = pAsn1Attr;
  3457. pAsn1->count = cAttribute;
  3458. for ( ; cAttribute > 0; cAttribute--, pAttribute++, pAsn1Attr++) {
  3459. if (!Asn1X509SetAttribute(pAttribute, pAsn1Attr))
  3460. return FALSE;
  3461. }
  3462. return TRUE;
  3463. }
  3464. void Asn1X509FreeAttributes(
  3465. IN Attributes *pAsn1
  3466. )
  3467. {
  3468. if (pAsn1->value) {
  3469. DWORD cAttr = pAsn1->count;
  3470. Attribute *pAsn1Attr = pAsn1->value;
  3471. for ( ; cAttr > 0; cAttr--, pAsn1Attr++)
  3472. Asn1X509FreeAttribute(pAsn1Attr);
  3473. PkiFree(pAsn1->value);
  3474. pAsn1->value = NULL;
  3475. }
  3476. pAsn1->count = 0;
  3477. }
  3478. void Asn1X509GetAttributes(
  3479. IN Attributes *pAsn1,
  3480. IN DWORD dwFlags,
  3481. OUT DWORD *pcAttribute,
  3482. OUT PCRYPT_ATTRIBUTE *ppAttribute,
  3483. IN OUT BYTE **ppbExtra,
  3484. IN OUT LONG *plRemainExtra
  3485. )
  3486. {
  3487. LONG lRemainExtra = *plRemainExtra;
  3488. BYTE *pbExtra = *ppbExtra;
  3489. LONG lAlignExtra;
  3490. DWORD cAttr;
  3491. Attribute *pAsn1Attr;
  3492. PCRYPT_ATTRIBUTE pGetAttr;
  3493. cAttr = pAsn1->count;
  3494. lAlignExtra = INFO_LEN_ALIGN(cAttr * sizeof(CRYPT_ATTRIBUTE));
  3495. lRemainExtra -= lAlignExtra;
  3496. if (lRemainExtra >= 0) {
  3497. *pcAttribute = cAttr;
  3498. pGetAttr = (PCRYPT_ATTRIBUTE) pbExtra;
  3499. *ppAttribute = pGetAttr;
  3500. pbExtra += lAlignExtra;
  3501. } else
  3502. pGetAttr = NULL;
  3503. pAsn1Attr = pAsn1->value;
  3504. for ( ; cAttr > 0; cAttr--, pAsn1Attr++, pGetAttr++) {
  3505. Asn1X509GetAttribute(pAsn1Attr, dwFlags, pGetAttr,
  3506. &pbExtra, &lRemainExtra);
  3507. }
  3508. *plRemainExtra = lRemainExtra;
  3509. *ppbExtra = pbExtra;
  3510. }
  3511. //+-------------------------------------------------------------------------
  3512. // Set/Free/Get CERT_ALT_NAME_ENTRY
  3513. //--------------------------------------------------------------------------
  3514. BOOL Asn1X509SetAltNameEntry(
  3515. IN PCERT_ALT_NAME_ENTRY pInfo,
  3516. OUT GeneralName *pAsn1,
  3517. IN DWORD dwEntryIndex,
  3518. OUT DWORD *pdwErrLocation
  3519. )
  3520. {
  3521. BOOL fResult;
  3522. // Assumption: ASN1 choice == dwAltNameChoice
  3523. // Asn1X509GetAltNameEntry has asserts to verify
  3524. pAsn1->choice = (unsigned short) pInfo->dwAltNameChoice;
  3525. *pdwErrLocation = 0;
  3526. switch (pInfo->dwAltNameChoice) {
  3527. case CERT_ALT_NAME_OTHER_NAME:
  3528. if (!Asn1X509SetEncodedObjId(pInfo->pOtherName->pszObjId,
  3529. &pAsn1->u.otherName.type))
  3530. goto ErrorReturn;
  3531. Asn1X509SetAny(&pInfo->pOtherName->Value, &pAsn1->u.otherName.value);
  3532. break;
  3533. case CERT_ALT_NAME_DIRECTORY_NAME:
  3534. Asn1X509SetAny(&pInfo->DirectoryName, &pAsn1->u.directoryName);
  3535. break;
  3536. case CERT_ALT_NAME_RFC822_NAME:
  3537. case CERT_ALT_NAME_DNS_NAME:
  3538. case CERT_ALT_NAME_URL:
  3539. if (!Asn1X509SetUnicodeConvertedToIA5(pInfo->pwszRfc822Name,
  3540. &pAsn1->u.rfc822Name, dwEntryIndex, pdwErrLocation))
  3541. goto ErrorReturn;
  3542. break;
  3543. case CERT_ALT_NAME_IP_ADDRESS:
  3544. Asn1X509SetOctetString(&pInfo->IPAddress, &pAsn1->u.iPAddress);
  3545. break;
  3546. case CERT_ALT_NAME_REGISTERED_ID:
  3547. if (!Asn1X509SetEncodedObjId(pInfo->pszRegisteredID, &pAsn1->u.registeredID))
  3548. goto ErrorReturn;
  3549. break;
  3550. case CERT_ALT_NAME_X400_ADDRESS:
  3551. case CERT_ALT_NAME_EDI_PARTY_NAME:
  3552. default:
  3553. SetLastError((DWORD) E_INVALIDARG);
  3554. goto ErrorReturn;
  3555. }
  3556. fResult = TRUE;
  3557. CommonReturn:
  3558. return fResult;
  3559. ErrorReturn:
  3560. fResult = FALSE;
  3561. goto CommonReturn;
  3562. }
  3563. void Asn1X509FreeAltNameEntry(
  3564. IN GeneralName *pAsn1
  3565. )
  3566. {
  3567. switch (pAsn1->choice) {
  3568. case CERT_ALT_NAME_RFC822_NAME:
  3569. case CERT_ALT_NAME_DNS_NAME:
  3570. case CERT_ALT_NAME_URL:
  3571. Asn1X509FreeUnicodeConvertedToIA5(&pAsn1->u.rfc822Name);
  3572. break;
  3573. default:
  3574. break;
  3575. }
  3576. }
  3577. BOOL Asn1X509GetAltNameEntry(
  3578. IN GeneralName *pAsn1,
  3579. IN DWORD dwFlags,
  3580. OUT PCERT_ALT_NAME_ENTRY pInfo,
  3581. IN OUT BYTE **ppbExtra,
  3582. IN OUT LONG *plRemainExtra
  3583. )
  3584. {
  3585. DWORD dwAltNameChoice;
  3586. assert(otherName_chosen == CERT_ALT_NAME_OTHER_NAME);
  3587. assert(rfc822Name_chosen == CERT_ALT_NAME_RFC822_NAME);
  3588. assert(dNSName_chosen == CERT_ALT_NAME_DNS_NAME);
  3589. assert(x400Address_chosen == CERT_ALT_NAME_X400_ADDRESS);
  3590. assert(directoryName_chosen == CERT_ALT_NAME_DIRECTORY_NAME);
  3591. assert(ediPartyName_chosen == CERT_ALT_NAME_EDI_PARTY_NAME);
  3592. assert(uniformResourceLocator_chosen == CERT_ALT_NAME_URL);
  3593. assert(iPAddress_chosen == CERT_ALT_NAME_IP_ADDRESS);
  3594. assert(registeredID_chosen == CERT_ALT_NAME_REGISTERED_ID);
  3595. dwAltNameChoice = pAsn1->choice;
  3596. if (*plRemainExtra >= 0)
  3597. pInfo->dwAltNameChoice = dwAltNameChoice;
  3598. switch (dwAltNameChoice) {
  3599. case CERT_ALT_NAME_OTHER_NAME:
  3600. {
  3601. LONG lAlignExtra;
  3602. PCERT_OTHER_NAME pOtherName;
  3603. lAlignExtra = INFO_LEN_ALIGN(sizeof(CERT_OTHER_NAME));
  3604. *plRemainExtra -= lAlignExtra;
  3605. if (*plRemainExtra >= 0) {
  3606. pOtherName = (PCERT_OTHER_NAME) *ppbExtra;
  3607. pInfo->pOtherName = pOtherName;
  3608. *ppbExtra += lAlignExtra;
  3609. } else
  3610. pOtherName = NULL;
  3611. Asn1X509GetEncodedObjId(&pAsn1->u.otherName.type, dwFlags,
  3612. &pOtherName->pszObjId, ppbExtra, plRemainExtra);
  3613. Asn1X509GetAny(&pAsn1->u.otherName.value, dwFlags,
  3614. &pOtherName->Value, ppbExtra, plRemainExtra);
  3615. }
  3616. break;
  3617. case CERT_ALT_NAME_DIRECTORY_NAME:
  3618. Asn1X509GetAny(&pAsn1->u.directoryName, dwFlags,
  3619. &pInfo->DirectoryName, ppbExtra, plRemainExtra);
  3620. break;
  3621. case CERT_ALT_NAME_RFC822_NAME:
  3622. case CERT_ALT_NAME_DNS_NAME:
  3623. case CERT_ALT_NAME_URL:
  3624. Asn1X509GetIA5ConvertedToUnicode(&pAsn1->u.rfc822Name, dwFlags,
  3625. &pInfo->pwszRfc822Name, ppbExtra, plRemainExtra);
  3626. break;
  3627. case CERT_ALT_NAME_IP_ADDRESS:
  3628. Asn1X509GetOctetString(&pAsn1->u.iPAddress, dwFlags,
  3629. &pInfo->IPAddress, ppbExtra, plRemainExtra);
  3630. break;
  3631. case CERT_ALT_NAME_REGISTERED_ID:
  3632. Asn1X509GetEncodedObjId(&pAsn1->u.registeredID, dwFlags,
  3633. &pInfo->pszRegisteredID, ppbExtra, plRemainExtra);
  3634. break;
  3635. case CERT_ALT_NAME_X400_ADDRESS:
  3636. case CERT_ALT_NAME_EDI_PARTY_NAME:
  3637. break;
  3638. default:
  3639. SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
  3640. return FALSE;
  3641. }
  3642. return TRUE;
  3643. }
  3644. //+-------------------------------------------------------------------------
  3645. // Set/Free/Get CERT_ALT_NAME_INFO
  3646. //--------------------------------------------------------------------------
  3647. BOOL Asn1X509SetAltNames(
  3648. IN PCERT_ALT_NAME_INFO pInfo,
  3649. OUT AltNames *pAsn1,
  3650. IN DWORD dwIndex,
  3651. OUT DWORD *pdwErrLocation
  3652. )
  3653. {
  3654. BOOL fResult;
  3655. DWORD i;
  3656. DWORD cEntry;
  3657. PCERT_ALT_NAME_ENTRY pEntry;
  3658. GeneralName *pAsn1Entry = NULL;
  3659. *pdwErrLocation = 0;
  3660. cEntry = pInfo->cAltEntry;
  3661. pEntry = pInfo->rgAltEntry;
  3662. pAsn1->count = cEntry;
  3663. pAsn1->value = NULL;
  3664. if (cEntry > 0) {
  3665. pAsn1Entry =
  3666. (GeneralName *) PkiZeroAlloc(cEntry * sizeof(GeneralName));
  3667. if (pAsn1Entry == NULL)
  3668. goto ErrorReturn;
  3669. pAsn1->value = pAsn1Entry;
  3670. }
  3671. // Array of AltName entries
  3672. for (i = 0; i < cEntry; i++, pEntry++, pAsn1Entry++) {
  3673. if (!Asn1X509SetAltNameEntry(pEntry, pAsn1Entry,
  3674. (dwIndex << 8) | i, pdwErrLocation))
  3675. goto ErrorReturn;
  3676. }
  3677. fResult = TRUE;
  3678. CommonReturn:
  3679. return fResult;
  3680. ErrorReturn:
  3681. fResult = FALSE;
  3682. goto CommonReturn;
  3683. }
  3684. void Asn1X509FreeAltNames(
  3685. OUT AltNames *pAsn1
  3686. )
  3687. {
  3688. if (pAsn1->value) {
  3689. DWORD cEntry = pAsn1->count;
  3690. GeneralName *pAsn1Entry = pAsn1->value;
  3691. for ( ; cEntry > 0; cEntry--, pAsn1Entry++)
  3692. Asn1X509FreeAltNameEntry(pAsn1Entry);
  3693. PkiFree(pAsn1->value);
  3694. }
  3695. }
  3696. BOOL Asn1X509GetAltNames(
  3697. IN AltNames *pAsn1,
  3698. IN DWORD dwFlags,
  3699. OUT PCERT_ALT_NAME_INFO pInfo,
  3700. IN OUT BYTE **ppbExtra,
  3701. IN OUT LONG *plRemainExtra
  3702. )
  3703. {
  3704. LONG lAlignExtra;
  3705. DWORD cEntry;
  3706. PCERT_ALT_NAME_ENTRY pEntry;
  3707. GeneralName *pAsn1Entry;
  3708. cEntry = pAsn1->count;
  3709. lAlignExtra = INFO_LEN_ALIGN(cEntry * sizeof(CERT_ALT_NAME_ENTRY));
  3710. *plRemainExtra -= lAlignExtra;
  3711. if (*plRemainExtra >= 0) {
  3712. pInfo->cAltEntry = cEntry;
  3713. pEntry = (PCERT_ALT_NAME_ENTRY) *ppbExtra;
  3714. pInfo->rgAltEntry = pEntry;
  3715. *ppbExtra += lAlignExtra;
  3716. } else
  3717. pEntry = NULL;
  3718. // Array of AltName entries
  3719. pAsn1Entry = pAsn1->value;
  3720. for (; cEntry > 0; cEntry--, pEntry++, pAsn1Entry++) {
  3721. if (!Asn1X509GetAltNameEntry(pAsn1Entry, dwFlags,
  3722. pEntry, ppbExtra, plRemainExtra))
  3723. return FALSE;
  3724. }
  3725. return TRUE;
  3726. }
  3727. //+-------------------------------------------------------------------------
  3728. // Set/Free/Get CERT_ACCESS_DESCRIPTION
  3729. //--------------------------------------------------------------------------
  3730. BOOL Asn1X509SetAccessDescriptions(
  3731. IN DWORD cAccDescr,
  3732. IN PCERT_ACCESS_DESCRIPTION pAccDescr,
  3733. OUT AccessDescription *pAsn1,
  3734. OUT DWORD *pdwErrLocation
  3735. )
  3736. {
  3737. BOOL fResult;
  3738. DWORD i;
  3739. *pdwErrLocation = 0;
  3740. for (i = 0; i < cAccDescr; i++, pAccDescr++, pAsn1++) {
  3741. if (!Asn1X509SetEncodedObjId(pAccDescr->pszAccessMethod, &pAsn1->accessMethod))
  3742. goto ErrorReturn;
  3743. if (!Asn1X509SetAltNameEntry(&pAccDescr->AccessLocation,
  3744. &pAsn1->accessLocation,
  3745. i,
  3746. pdwErrLocation))
  3747. goto ErrorReturn;
  3748. }
  3749. fResult = TRUE;
  3750. CommonReturn:
  3751. return fResult;
  3752. ErrorReturn:
  3753. fResult = FALSE;
  3754. goto CommonReturn;
  3755. }
  3756. void Asn1X509FreeAccessDescriptions(
  3757. IN DWORD cAccDescr,
  3758. IN OUT AccessDescription *pAsn1
  3759. )
  3760. {
  3761. for ( ; cAccDescr > 0; cAccDescr--, pAsn1++)
  3762. Asn1X509FreeAltNameEntry(&pAsn1->accessLocation);
  3763. }
  3764. BOOL Asn1X509GetAccessDescriptions(
  3765. IN DWORD cAccDescr,
  3766. IN AccessDescription *pAsn1,
  3767. IN DWORD dwFlags,
  3768. IN PCERT_ACCESS_DESCRIPTION pAccDescr,
  3769. IN OUT BYTE **ppbExtra,
  3770. IN OUT LONG *plRemainExtra
  3771. )
  3772. {
  3773. // Array of AccessDescription entries
  3774. for (; cAccDescr > 0; cAccDescr--, pAccDescr++, pAsn1++) {
  3775. Asn1X509GetEncodedObjId(&pAsn1->accessMethod, dwFlags,
  3776. &pAccDescr->pszAccessMethod, ppbExtra, plRemainExtra);
  3777. if (!Asn1X509GetAltNameEntry(&pAsn1->accessLocation, dwFlags,
  3778. &pAccDescr->AccessLocation, ppbExtra, plRemainExtra))
  3779. return FALSE;
  3780. }
  3781. return TRUE;
  3782. }
  3783. //+-------------------------------------------------------------------------
  3784. // Encode the Cert Info (ASN1 X509 v3 ASN.1)
  3785. //--------------------------------------------------------------------------
  3786. BOOL WINAPI Asn1X509CertInfoEncodeEx(
  3787. IN DWORD dwCertEncodingType,
  3788. IN LPCSTR lpszStructType,
  3789. IN PCERT_INFO pInfo,
  3790. IN DWORD dwFlags,
  3791. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  3792. OUT OPTIONAL void *pvEncoded,
  3793. IN OUT DWORD *pcbEncoded
  3794. )
  3795. {
  3796. BOOL fResult;
  3797. CertificateToBeSigned Cert;
  3798. memset(&Cert, 0, sizeof(Cert));
  3799. if (pInfo->dwVersion != 0) {
  3800. #ifdef OSS_CRYPT_ASN1
  3801. Cert.CertificateToBeSigned_version = pInfo->dwVersion;
  3802. #else
  3803. Cert.version = pInfo->dwVersion;
  3804. #endif // OSS_CRYPT_ASN1
  3805. Cert.bit_mask |= CertificateToBeSigned_version_present;
  3806. }
  3807. if (!Asn1X509SetHugeInteger(&pInfo->SerialNumber, &Cert.serialNumber))
  3808. goto ErrorReturn;
  3809. if (!Asn1X509SetAlgorithm(&pInfo->SignatureAlgorithm, &Cert.signature,
  3810. CRYPT_SIGN_ALG_OID_GROUP_ID))
  3811. goto ErrorReturn;
  3812. Asn1X509SetAny(&pInfo->Issuer, &Cert.issuer);
  3813. if (!PkiAsn1ToChoiceOfTime(&pInfo->NotBefore,
  3814. &Cert.validity.notBefore.choice,
  3815. &Cert.validity.notBefore.u.generalTime,
  3816. &Cert.validity.notBefore.u.utcTime
  3817. ))
  3818. goto EncodeError;
  3819. if (!PkiAsn1ToChoiceOfTime(&pInfo->NotAfter,
  3820. &Cert.validity.notAfter.choice,
  3821. &Cert.validity.notAfter.u.generalTime,
  3822. &Cert.validity.notAfter.u.utcTime
  3823. ))
  3824. goto EncodeError;
  3825. Asn1X509SetAny(&pInfo->Subject, &Cert.subject);
  3826. if (!Asn1X509SetPublicKeyInfo(&pInfo->SubjectPublicKeyInfo,
  3827. &Cert.subjectPublicKeyInfo))
  3828. goto ErrorReturn;
  3829. if (pInfo->IssuerUniqueId.cbData) {
  3830. Asn1X509SetBit(&pInfo->IssuerUniqueId, &Cert.issuerUniqueIdentifier);
  3831. Cert.bit_mask |= issuerUniqueIdentifier_present;
  3832. }
  3833. if (pInfo->SubjectUniqueId.cbData) {
  3834. Asn1X509SetBit(&pInfo->SubjectUniqueId, &Cert.subjectUniqueIdentifier);
  3835. Cert.bit_mask |= subjectUniqueIdentifier_present;
  3836. }
  3837. if (pInfo->cExtension) {
  3838. if (!Asn1X509SetExtensions(pInfo->cExtension, pInfo->rgExtension,
  3839. &Cert.extensions))
  3840. goto ErrorReturn;
  3841. Cert.bit_mask |= extensions_present;
  3842. }
  3843. fResult = Asn1InfoEncodeEx(
  3844. CertificateToBeSigned_PDU,
  3845. &Cert,
  3846. dwFlags,
  3847. pEncodePara,
  3848. pvEncoded,
  3849. pcbEncoded
  3850. );
  3851. goto CommonReturn;
  3852. EncodeError:
  3853. SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
  3854. ErrorReturn:
  3855. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  3856. *((void **) pvEncoded) = NULL;
  3857. *pcbEncoded = 0;
  3858. fResult = FALSE;
  3859. CommonReturn:
  3860. Asn1X509FreeHugeInteger(&Cert.serialNumber);
  3861. Asn1X509FreeExtensions(&Cert.extensions);
  3862. return fResult;
  3863. }
  3864. //+-------------------------------------------------------------------------
  3865. // Decode the Cert Info (ASN1 X509 v3 ASN.1)
  3866. //--------------------------------------------------------------------------
  3867. BOOL WINAPI Asn1X509CertInfoDecodeExCallback(
  3868. IN void *pvAsn1Info,
  3869. IN DWORD dwFlags,
  3870. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  3871. OUT OPTIONAL void *pvStructInfo,
  3872. IN OUT LONG *plRemainExtra
  3873. )
  3874. {
  3875. BOOL fResult;
  3876. CertificateToBeSigned *pCert = (CertificateToBeSigned *) pvAsn1Info;
  3877. PCERT_INFO pInfo = (PCERT_INFO) pvStructInfo;
  3878. LONG lRemainExtra = *plRemainExtra;
  3879. BYTE *pbExtra;
  3880. lRemainExtra -= sizeof(CERT_INFO);
  3881. if (lRemainExtra < 0) {
  3882. pbExtra = NULL;
  3883. } else {
  3884. // Default all optional fields to zero
  3885. memset(pInfo, 0, sizeof(CERT_INFO));
  3886. // Update fields not needing extra memory after the CERT_INFO
  3887. if (pCert->bit_mask & CertificateToBeSigned_version_present)
  3888. #ifdef OSS_CRYPT_ASN1
  3889. pInfo->dwVersion = pCert->CertificateToBeSigned_version;
  3890. #else
  3891. pInfo->dwVersion = pCert->version;
  3892. #endif // OSS_CRYPT_ASN1
  3893. if (!PkiAsn1FromChoiceOfTime(pCert->validity.notBefore.choice,
  3894. &pCert->validity.notBefore.u.generalTime,
  3895. &pCert->validity.notBefore.u.utcTime,
  3896. &pInfo->NotBefore))
  3897. goto DecodeError;
  3898. if (!PkiAsn1FromChoiceOfTime(pCert->validity.notAfter.choice,
  3899. &pCert->validity.notAfter.u.generalTime,
  3900. &pCert->validity.notAfter.u.utcTime,
  3901. &pInfo->NotAfter))
  3902. goto DecodeError;
  3903. pbExtra = (BYTE *) pInfo + sizeof(CERT_INFO);
  3904. }
  3905. Asn1X509GetHugeInteger(&pCert->serialNumber, dwFlags,
  3906. &pInfo->SerialNumber, &pbExtra, &lRemainExtra);
  3907. Asn1X509GetAlgorithm(&pCert->signature, dwFlags,
  3908. &pInfo->SignatureAlgorithm, &pbExtra, &lRemainExtra);
  3909. Asn1X509GetAny(&pCert->issuer, dwFlags,
  3910. &pInfo->Issuer, &pbExtra, &lRemainExtra);
  3911. Asn1X509GetAny(&pCert->subject, dwFlags,
  3912. &pInfo->Subject, &pbExtra, &lRemainExtra);
  3913. Asn1X509GetPublicKeyInfo(&pCert->subjectPublicKeyInfo, dwFlags,
  3914. &pInfo->SubjectPublicKeyInfo, &pbExtra, &lRemainExtra);
  3915. if (pCert->bit_mask & issuerUniqueIdentifier_present)
  3916. Asn1X509GetBit(&pCert->issuerUniqueIdentifier, dwFlags,
  3917. &pInfo->IssuerUniqueId, &pbExtra, &lRemainExtra);
  3918. if (pCert->bit_mask & subjectUniqueIdentifier_present)
  3919. Asn1X509GetBit(&pCert->subjectUniqueIdentifier, dwFlags,
  3920. &pInfo->SubjectUniqueId, &pbExtra, &lRemainExtra);
  3921. if (pCert->bit_mask & extensions_present)
  3922. Asn1X509GetExtensions(&pCert->extensions, dwFlags,
  3923. &pInfo->cExtension, &pInfo->rgExtension, &pbExtra, &lRemainExtra);
  3924. fResult = TRUE;
  3925. CommonReturn:
  3926. *plRemainExtra = lRemainExtra;
  3927. return fResult;
  3928. ErrorReturn:
  3929. fResult = FALSE;
  3930. goto CommonReturn;
  3931. SET_ERROR(DecodeError, CRYPT_E_BAD_ENCODE)
  3932. }
  3933. BOOL WINAPI Asn1X509CertInfoDecodeEx(
  3934. IN DWORD dwCertEncodingType,
  3935. IN LPCSTR lpszStructType,
  3936. IN const BYTE *pbEncoded,
  3937. IN DWORD cbEncoded,
  3938. IN DWORD dwFlags,
  3939. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  3940. OUT OPTIONAL void *pvStructInfo,
  3941. IN OUT DWORD *pcbStructInfo
  3942. )
  3943. {
  3944. const BYTE *pbToBeSigned;
  3945. DWORD cbToBeSigned;
  3946. if ((dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG) ||
  3947. !Asn1UtilExtractCertificateToBeSignedContent(
  3948. pbEncoded,
  3949. cbEncoded,
  3950. &cbToBeSigned,
  3951. &pbToBeSigned
  3952. )) {
  3953. pbToBeSigned = pbEncoded;
  3954. cbToBeSigned = cbEncoded;
  3955. }
  3956. return Asn1InfoDecodeAndAllocEx(
  3957. CertificateToBeSigned_PDU,
  3958. pbToBeSigned,
  3959. cbToBeSigned,
  3960. dwFlags,
  3961. pDecodePara,
  3962. Asn1X509CertInfoDecodeExCallback,
  3963. pvStructInfo,
  3964. pcbStructInfo
  3965. );
  3966. }
  3967. //+-------------------------------------------------------------------------
  3968. // Encode the CRL Info (ASN1 X509 ASN.1)
  3969. //--------------------------------------------------------------------------
  3970. BOOL WINAPI Asn1X509CrlInfoEncodeEx(
  3971. IN DWORD dwCertEncodingType,
  3972. IN LPCSTR lpszStructType,
  3973. IN PCRL_INFO pInfo,
  3974. IN DWORD dwFlags,
  3975. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  3976. OUT OPTIONAL void *pvEncoded,
  3977. IN OUT DWORD *pcbEncoded
  3978. )
  3979. {
  3980. BOOL fResult;
  3981. CertificateRevocationListToBeSigned Crl;
  3982. memset(&Crl, 0, sizeof(Crl));
  3983. if (pInfo->dwVersion != 0) {
  3984. #ifdef OSS_CRYPT_ASN1
  3985. Crl.CertificateRevocationListToBeSigned_version = pInfo->dwVersion;
  3986. #else
  3987. Crl.version = pInfo->dwVersion;
  3988. #endif // OSS_CRYPT_ASN1
  3989. Crl.bit_mask |= CertificateRevocationListToBeSigned_version_present;
  3990. }
  3991. if (!Asn1X509SetAlgorithm(&pInfo->SignatureAlgorithm, &Crl.signature,
  3992. CRYPT_SIGN_ALG_OID_GROUP_ID))
  3993. goto ErrorReturn;
  3994. Asn1X509SetAny(&pInfo->Issuer, &Crl.issuer);
  3995. if (!PkiAsn1ToChoiceOfTime(&pInfo->ThisUpdate,
  3996. &Crl.thisUpdate.choice,
  3997. &Crl.thisUpdate.u.generalTime,
  3998. &Crl.thisUpdate.u.utcTime
  3999. ))
  4000. goto EncodeError;
  4001. if (pInfo->NextUpdate.dwLowDateTime || pInfo->NextUpdate.dwHighDateTime) {
  4002. Crl.bit_mask |= nextUpdate_present;
  4003. if (!PkiAsn1ToChoiceOfTime(&pInfo->NextUpdate,
  4004. &Crl.nextUpdate.choice,
  4005. &Crl.nextUpdate.u.generalTime,
  4006. &Crl.nextUpdate.u.utcTime
  4007. ))
  4008. goto EncodeError;
  4009. }
  4010. if (pInfo->cCRLEntry) {
  4011. if (!Asn1X509SetCrlEntries(pInfo->cCRLEntry, pInfo->rgCRLEntry,
  4012. &Crl.revokedCertificates))
  4013. goto ErrorReturn;
  4014. Crl.bit_mask |= revokedCertificates_present;
  4015. }
  4016. if (pInfo->cExtension) {
  4017. if (!Asn1X509SetExtensions(pInfo->cExtension, pInfo->rgExtension,
  4018. &Crl.crlExtensions))
  4019. goto ErrorReturn;
  4020. Crl.bit_mask |= crlExtensions_present;
  4021. }
  4022. fResult = Asn1InfoEncodeEx(
  4023. CertificateRevocationListToBeSigned_PDU,
  4024. &Crl,
  4025. dwFlags,
  4026. pEncodePara,
  4027. pvEncoded,
  4028. pcbEncoded
  4029. );
  4030. goto CommonReturn;
  4031. EncodeError:
  4032. SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
  4033. ErrorReturn:
  4034. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  4035. *((void **) pvEncoded) = NULL;
  4036. *pcbEncoded = 0;
  4037. fResult = FALSE;
  4038. CommonReturn:
  4039. Asn1X509FreeCrlEntries(&Crl.revokedCertificates);
  4040. Asn1X509FreeExtensions(&Crl.crlExtensions);
  4041. return fResult;
  4042. }
  4043. //+-------------------------------------------------------------------------
  4044. // Decode the CRL Info (ASN1 X509 ASN.1)
  4045. //--------------------------------------------------------------------------
  4046. BOOL WINAPI Asn1X509CrlInfoDecodeExCallback(
  4047. IN void *pvAsn1Info,
  4048. IN DWORD dwFlags,
  4049. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  4050. OUT OPTIONAL void *pvStructInfo,
  4051. IN OUT LONG *plRemainExtra
  4052. )
  4053. {
  4054. BOOL fResult;
  4055. CertificateRevocationListToBeSigned *pCrl =
  4056. (CertificateRevocationListToBeSigned *) pvAsn1Info;
  4057. PCRL_INFO pInfo = (PCRL_INFO) pvStructInfo;
  4058. LONG lRemainExtra = *plRemainExtra;
  4059. BYTE *pbExtra;
  4060. lRemainExtra -= sizeof(CRL_INFO);
  4061. if (lRemainExtra < 0) {
  4062. pbExtra = NULL;
  4063. } else {
  4064. // Default all optional fields to zero
  4065. memset(pInfo, 0, sizeof(CRL_INFO));
  4066. // Update fields not needing extra memory after the CRL_INFO
  4067. if (pCrl->bit_mask &
  4068. CertificateRevocationListToBeSigned_version_present)
  4069. #ifdef OSS_CRYPT_ASN1
  4070. pInfo->dwVersion =
  4071. pCrl->CertificateRevocationListToBeSigned_version;
  4072. #else
  4073. pInfo->dwVersion = pCrl->version;
  4074. #endif // OSS_CRYPT_ASN1
  4075. if (!PkiAsn1FromChoiceOfTime(pCrl->thisUpdate.choice,
  4076. &pCrl->thisUpdate.u.generalTime,
  4077. &pCrl->thisUpdate.u.utcTime,
  4078. &pInfo->ThisUpdate))
  4079. goto DecodeError;
  4080. if (pCrl->bit_mask & nextUpdate_present) {
  4081. if (!PkiAsn1FromChoiceOfTime(pCrl->nextUpdate.choice,
  4082. &pCrl->nextUpdate.u.generalTime,
  4083. &pCrl->nextUpdate.u.utcTime,
  4084. &pInfo->NextUpdate))
  4085. goto DecodeError;
  4086. }
  4087. pbExtra = (BYTE *) pInfo + sizeof(CRL_INFO);
  4088. }
  4089. Asn1X509GetAlgorithm(&pCrl->signature, dwFlags,
  4090. &pInfo->SignatureAlgorithm, &pbExtra, &lRemainExtra);
  4091. Asn1X509GetAny(&pCrl->issuer, dwFlags,
  4092. &pInfo->Issuer, &pbExtra, &lRemainExtra);
  4093. if (pCrl->bit_mask & revokedCertificates_present)
  4094. Asn1X509GetCrlEntries(&pCrl->revokedCertificates, dwFlags,
  4095. &pInfo->cCRLEntry, &pInfo->rgCRLEntry, &pbExtra, &lRemainExtra);
  4096. if (pCrl->bit_mask & crlExtensions_present)
  4097. Asn1X509GetExtensions(&pCrl->crlExtensions, dwFlags,
  4098. &pInfo->cExtension, &pInfo->rgExtension, &pbExtra, &lRemainExtra);
  4099. fResult = TRUE;
  4100. CommonReturn:
  4101. *plRemainExtra = lRemainExtra;
  4102. return fResult;
  4103. ErrorReturn:
  4104. fResult = FALSE;
  4105. goto CommonReturn;
  4106. SET_ERROR(DecodeError, CRYPT_E_BAD_ENCODE)
  4107. }
  4108. BOOL WINAPI Asn1X509CrlInfoDecodeEx(
  4109. IN DWORD dwCertEncodingType,
  4110. IN LPCSTR lpszStructType,
  4111. IN const BYTE *pbEncoded,
  4112. IN DWORD cbEncoded,
  4113. IN DWORD dwFlags,
  4114. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  4115. OUT OPTIONAL void *pvStructInfo,
  4116. IN OUT DWORD *pcbStructInfo
  4117. )
  4118. {
  4119. const BYTE *pbToBeSigned;
  4120. DWORD cbToBeSigned;
  4121. if ((dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG) ||
  4122. !Asn1UtilExtractCertificateToBeSignedContent(
  4123. pbEncoded,
  4124. cbEncoded,
  4125. &cbToBeSigned,
  4126. &pbToBeSigned
  4127. )) {
  4128. pbToBeSigned = pbEncoded;
  4129. cbToBeSigned = cbEncoded;
  4130. }
  4131. return Asn1InfoDecodeAndAllocEx(
  4132. CertificateRevocationListToBeSigned_PDU,
  4133. pbToBeSigned,
  4134. cbToBeSigned,
  4135. dwFlags,
  4136. pDecodePara,
  4137. Asn1X509CrlInfoDecodeExCallback,
  4138. pvStructInfo,
  4139. pcbStructInfo
  4140. );
  4141. }
  4142. //+-------------------------------------------------------------------------
  4143. // Encode the Cert Request Info (ASN1 X509 v3 ASN.1)
  4144. //--------------------------------------------------------------------------
  4145. BOOL WINAPI Asn1X509CertRequestInfoEncodeEx(
  4146. IN DWORD dwCertEncodingType,
  4147. IN LPCSTR lpszStructType,
  4148. IN PCERT_REQUEST_INFO pInfo,
  4149. IN DWORD dwFlags,
  4150. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  4151. OUT OPTIONAL void *pvEncoded,
  4152. IN OUT DWORD *pcbEncoded
  4153. )
  4154. {
  4155. BOOL fResult;
  4156. CertificationRequestInfo CertReq;
  4157. memset(&CertReq, 0, sizeof(CertReq));
  4158. CertReq.version = pInfo->dwVersion;
  4159. Asn1X509SetAny(&pInfo->Subject, &CertReq.subject);
  4160. if (!Asn1X509SetPublicKeyInfo(&pInfo->SubjectPublicKeyInfo,
  4161. &CertReq.subjectPublicKeyInfo))
  4162. goto ErrorReturn;
  4163. if (!Asn1X509SetAttributes(pInfo->cAttribute, pInfo->rgAttribute,
  4164. &CertReq.attributes))
  4165. goto ErrorReturn;
  4166. fResult = Asn1InfoEncodeEx(
  4167. CertificationRequestInfo_PDU,
  4168. &CertReq,
  4169. dwFlags,
  4170. pEncodePara,
  4171. pvEncoded,
  4172. pcbEncoded
  4173. );
  4174. goto CommonReturn;
  4175. ErrorReturn:
  4176. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  4177. *((void **) pvEncoded) = NULL;
  4178. *pcbEncoded = 0;
  4179. fResult = FALSE;
  4180. CommonReturn:
  4181. Asn1X509FreeAttributes(&CertReq.attributes);
  4182. return fResult;
  4183. }
  4184. //+-------------------------------------------------------------------------
  4185. // Decode the Cert Request Info (ASN1 X509 v3 ASN.1)
  4186. //--------------------------------------------------------------------------
  4187. BOOL WINAPI Asn1X509CertRequestInfoDecodeExCallback(
  4188. IN void *pvAsn1Info,
  4189. IN DWORD dwFlags,
  4190. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  4191. OUT OPTIONAL void *pvStructInfo,
  4192. IN OUT LONG *plRemainExtra
  4193. )
  4194. {
  4195. CertificationRequestInfoDecode *pCertReq =
  4196. (CertificationRequestInfoDecode *) pvAsn1Info;
  4197. PCERT_REQUEST_INFO pInfo = (PCERT_REQUEST_INFO) pvStructInfo;
  4198. BYTE *pbExtra;
  4199. LONG lRemainExtra = *plRemainExtra;
  4200. lRemainExtra -= sizeof(CERT_REQUEST_INFO);
  4201. if (lRemainExtra < 0) {
  4202. pbExtra = NULL;
  4203. } else {
  4204. // Default all optional fields to zero
  4205. memset(pInfo, 0, sizeof(CERT_REQUEST_INFO));
  4206. // Update fields not needing extra memory after the CERT_INFO
  4207. pInfo->dwVersion = pCertReq->version;
  4208. pbExtra = (BYTE *) pInfo + sizeof(CERT_REQUEST_INFO);
  4209. }
  4210. Asn1X509GetAny(&pCertReq->subject, dwFlags,
  4211. &pInfo->Subject, &pbExtra, &lRemainExtra);
  4212. Asn1X509GetPublicKeyInfo(&pCertReq->subjectPublicKeyInfo, dwFlags,
  4213. &pInfo->SubjectPublicKeyInfo,
  4214. &pbExtra, &lRemainExtra);
  4215. if (pCertReq->bit_mask & attributes_present) {
  4216. Asn1X509GetAttributes(&pCertReq->attributes, dwFlags,
  4217. &pInfo->cAttribute, &pInfo->rgAttribute, &pbExtra, &lRemainExtra);
  4218. }
  4219. *plRemainExtra = lRemainExtra;
  4220. return TRUE;
  4221. }
  4222. BOOL WINAPI Asn1X509CertRequestInfoDecodeEx(
  4223. IN DWORD dwCertEncodingType,
  4224. IN LPCSTR lpszStructType,
  4225. IN const BYTE *pbEncoded,
  4226. IN DWORD cbEncoded,
  4227. IN DWORD dwFlags,
  4228. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  4229. OUT OPTIONAL void *pvStructInfo,
  4230. IN OUT DWORD *pcbStructInfo
  4231. )
  4232. {
  4233. const BYTE *pbToBeSigned;
  4234. DWORD cbToBeSigned;
  4235. if ((dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG) ||
  4236. !Asn1UtilExtractCertificateToBeSignedContent(
  4237. pbEncoded,
  4238. cbEncoded,
  4239. &cbToBeSigned,
  4240. &pbToBeSigned
  4241. )) {
  4242. pbToBeSigned = pbEncoded;
  4243. cbToBeSigned = cbEncoded;
  4244. }
  4245. return Asn1InfoDecodeAndAllocEx(
  4246. CertificationRequestInfoDecode_PDU,
  4247. pbToBeSigned,
  4248. cbToBeSigned,
  4249. dwFlags,
  4250. pDecodePara,
  4251. Asn1X509CertRequestInfoDecodeExCallback,
  4252. pvStructInfo,
  4253. pcbStructInfo
  4254. );
  4255. }
  4256. //+-------------------------------------------------------------------------
  4257. // Encode the Keygen Request Info (ASN1 X509 v3 ASN.1)
  4258. //--------------------------------------------------------------------------
  4259. BOOL WINAPI Asn1X509KeygenRequestInfoEncodeEx(
  4260. IN DWORD dwCertEncodingType,
  4261. IN LPCSTR lpszStructType,
  4262. IN PCERT_KEYGEN_REQUEST_INFO pInfo,
  4263. IN DWORD dwFlags,
  4264. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  4265. OUT OPTIONAL void *pvEncoded,
  4266. IN OUT DWORD *pcbEncoded
  4267. )
  4268. {
  4269. BOOL fResult;
  4270. KeygenRequestInfo KeygenReq;
  4271. DWORD dwErrLocation;
  4272. memset(&KeygenReq, 0, sizeof(KeygenReq));
  4273. if (!Asn1X509SetPublicKeyInfo(&pInfo->SubjectPublicKeyInfo,
  4274. &KeygenReq.subjectPublicKeyInfo))
  4275. goto ErrorReturn;
  4276. if (!Asn1X509SetUnicodeConvertedToIA5(pInfo->pwszChallengeString,
  4277. &KeygenReq.challenge, 0, &dwErrLocation)) {
  4278. *pcbEncoded = dwErrLocation;
  4279. goto InvalidIA5;
  4280. }
  4281. fResult = Asn1InfoEncodeEx(
  4282. KeygenRequestInfo_PDU,
  4283. &KeygenReq,
  4284. dwFlags,
  4285. pEncodePara,
  4286. pvEncoded,
  4287. pcbEncoded
  4288. );
  4289. goto CommonReturn;
  4290. ErrorReturn:
  4291. *pcbEncoded = 0;
  4292. InvalidIA5:
  4293. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  4294. *((void **) pvEncoded) = NULL;
  4295. fResult = FALSE;
  4296. CommonReturn:
  4297. Asn1X509FreeUnicodeConvertedToIA5(&KeygenReq.challenge);
  4298. return fResult;
  4299. }
  4300. //+-------------------------------------------------------------------------
  4301. // Decode the Keygen Request Info (ASN1 X509 v3 ASN.1)
  4302. //--------------------------------------------------------------------------
  4303. BOOL WINAPI Asn1X509KeygenRequestInfoDecodeExCallback(
  4304. IN void *pvAsn1Info,
  4305. IN DWORD dwFlags,
  4306. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  4307. OUT OPTIONAL void *pvStructInfo,
  4308. IN OUT LONG *plRemainExtra
  4309. )
  4310. {
  4311. KeygenRequestInfo *pKeygenReq = (KeygenRequestInfo *) pvAsn1Info;
  4312. PCERT_KEYGEN_REQUEST_INFO pInfo = (PCERT_KEYGEN_REQUEST_INFO) pvStructInfo;
  4313. LONG lRemainExtra = *plRemainExtra;
  4314. BYTE *pbExtra;
  4315. lRemainExtra -= sizeof(CERT_KEYGEN_REQUEST_INFO);
  4316. if (lRemainExtra < 0) {
  4317. pbExtra = NULL;
  4318. } else {
  4319. // Default all optional fields to zero
  4320. memset(pInfo, 0, sizeof(CERT_KEYGEN_REQUEST_INFO));
  4321. pbExtra = (BYTE *) pInfo + sizeof(CERT_KEYGEN_REQUEST_INFO);
  4322. }
  4323. Asn1X509GetPublicKeyInfo(&pKeygenReq->subjectPublicKeyInfo, dwFlags,
  4324. &pInfo->SubjectPublicKeyInfo, &pbExtra, &lRemainExtra);
  4325. Asn1X509GetIA5ConvertedToUnicode(&pKeygenReq->challenge, dwFlags,
  4326. &pInfo->pwszChallengeString, &pbExtra, &lRemainExtra);
  4327. *plRemainExtra = lRemainExtra;
  4328. return TRUE;
  4329. }
  4330. BOOL WINAPI Asn1X509KeygenRequestInfoDecodeEx(
  4331. IN DWORD dwCertEncodingType,
  4332. IN LPCSTR lpszStructType,
  4333. IN const BYTE *pbEncoded,
  4334. IN DWORD cbEncoded,
  4335. IN DWORD dwFlags,
  4336. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  4337. OUT OPTIONAL void *pvStructInfo,
  4338. IN OUT DWORD *pcbStructInfo
  4339. )
  4340. {
  4341. const BYTE *pbToBeSigned;
  4342. DWORD cbToBeSigned;
  4343. if ((dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG) ||
  4344. !Asn1UtilExtractCertificateToBeSignedContent(
  4345. pbEncoded,
  4346. cbEncoded,
  4347. &cbToBeSigned,
  4348. &pbToBeSigned
  4349. )) {
  4350. pbToBeSigned = pbEncoded;
  4351. cbToBeSigned = cbEncoded;
  4352. }
  4353. return Asn1InfoDecodeAndAllocEx(
  4354. KeygenRequestInfo_PDU,
  4355. pbToBeSigned,
  4356. cbToBeSigned,
  4357. dwFlags,
  4358. pDecodePara,
  4359. Asn1X509KeygenRequestInfoDecodeExCallback,
  4360. pvStructInfo,
  4361. pcbStructInfo
  4362. );
  4363. }
  4364. //+-------------------------------------------------------------------------
  4365. // Encode the Signed Content (ASN1 X509)
  4366. //--------------------------------------------------------------------------
  4367. BOOL WINAPI Asn1X509SignedContentEncodeEx(
  4368. IN DWORD dwCertEncodingType,
  4369. IN LPCSTR lpszStructType,
  4370. IN PCERT_SIGNED_CONTENT_INFO pInfo,
  4371. IN DWORD dwFlags,
  4372. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  4373. OUT OPTIONAL void *pvEncoded,
  4374. IN OUT DWORD *pcbEncoded
  4375. )
  4376. {
  4377. BOOL fResult;
  4378. SignedContent Asn1SignedContent;
  4379. CRYPT_BIT_BLOB SignatureBlob;
  4380. BYTE *pbAllocSignature = NULL;
  4381. memset(&Asn1SignedContent, 0, sizeof(Asn1SignedContent));
  4382. Asn1X509SetAny(&pInfo->ToBeSigned, &Asn1SignedContent.toBeSigned);
  4383. if (!Asn1X509SetAlgorithm(&pInfo->SignatureAlgorithm,
  4384. &Asn1SignedContent.algorithm, CRYPT_SIGN_ALG_OID_GROUP_ID))
  4385. goto ErrorReturn;
  4386. if (dwFlags & CRYPT_ENCODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG) {
  4387. SignatureBlob.pbData = pInfo->Signature.pbData;
  4388. } else {
  4389. if (NULL == (pbAllocSignature = PkiAsn1AllocAndReverseBytes(
  4390. pInfo->Signature.pbData, pInfo->Signature.cbData)))
  4391. goto ErrorReturn;
  4392. SignatureBlob.pbData = pbAllocSignature;
  4393. }
  4394. SignatureBlob.cbData = pInfo->Signature.cbData;
  4395. SignatureBlob.cUnusedBits = 0;
  4396. Asn1X509SetBit(&SignatureBlob, &Asn1SignedContent.signature);
  4397. fResult = Asn1InfoEncodeEx(
  4398. SignedContent_PDU,
  4399. &Asn1SignedContent,
  4400. dwFlags,
  4401. pEncodePara,
  4402. pvEncoded,
  4403. pcbEncoded
  4404. );
  4405. goto CommonReturn;
  4406. ErrorReturn:
  4407. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  4408. *((void **) pvEncoded) = NULL;
  4409. *pcbEncoded = 0;
  4410. fResult = FALSE;
  4411. CommonReturn:
  4412. if (pbAllocSignature)
  4413. PkiAsn1Free(pbAllocSignature);
  4414. return fResult;
  4415. }
  4416. //+-------------------------------------------------------------------------
  4417. // Decode the Signed Content (ASN1 X509)
  4418. //--------------------------------------------------------------------------
  4419. BOOL WINAPI Asn1X509SignedContentDecodeExCallback(
  4420. IN void *pvAsn1Info,
  4421. IN DWORD dwFlags,
  4422. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  4423. OUT OPTIONAL void *pvStructInfo,
  4424. IN OUT LONG *plRemainExtra
  4425. )
  4426. {
  4427. SignedContent *pSignedContent = (SignedContent *) pvAsn1Info;
  4428. PCERT_SIGNED_CONTENT_INFO pInfo = (PCERT_SIGNED_CONTENT_INFO) pvStructInfo;
  4429. LONG lRemainExtra = *plRemainExtra;
  4430. BYTE *pbExtra;
  4431. lRemainExtra -= sizeof(CERT_SIGNED_CONTENT_INFO);
  4432. if (lRemainExtra < 0) {
  4433. pbExtra = NULL;
  4434. } else
  4435. pbExtra = (BYTE *) pInfo + sizeof(CERT_SIGNED_CONTENT_INFO);
  4436. Asn1X509GetAny(&pSignedContent->toBeSigned, dwFlags,
  4437. &pInfo->ToBeSigned, &pbExtra, &lRemainExtra);
  4438. Asn1X509GetAlgorithm(&pSignedContent->algorithm, dwFlags,
  4439. &pInfo->SignatureAlgorithm, &pbExtra, &lRemainExtra);
  4440. // Since bits will be reversed, always need to make a copy (dwFlags = 0)
  4441. Asn1X509GetBit(&pSignedContent->signature, 0,
  4442. &pInfo->Signature, &pbExtra, &lRemainExtra);
  4443. if (lRemainExtra >= 0) {
  4444. if (0 == (dwFlags & CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG))
  4445. PkiAsn1ReverseBytes(pInfo->Signature.pbData,
  4446. pInfo->Signature.cbData);
  4447. }
  4448. *plRemainExtra = lRemainExtra;
  4449. return TRUE;
  4450. }
  4451. BOOL WINAPI Asn1X509SignedContentDecodeEx(
  4452. IN DWORD dwCertEncodingType,
  4453. IN LPCSTR lpszStructType,
  4454. IN const BYTE *pbEncoded,
  4455. IN DWORD cbEncoded,
  4456. IN DWORD dwFlags,
  4457. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  4458. OUT OPTIONAL void *pvStructInfo,
  4459. IN OUT DWORD *pcbStructInfo
  4460. )
  4461. {
  4462. return Asn1InfoDecodeAndAllocEx(
  4463. SignedContent_PDU,
  4464. pbEncoded,
  4465. cbEncoded,
  4466. dwFlags,
  4467. pDecodePara,
  4468. Asn1X509SignedContentDecodeExCallback,
  4469. pvStructInfo,
  4470. pcbStructInfo
  4471. );
  4472. }
  4473. //+-------------------------------------------------------------------------
  4474. // Encode the Name Info (ASN1 X509)
  4475. //--------------------------------------------------------------------------
  4476. BOOL WINAPI Asn1X509NameInfoEncodeEx(
  4477. IN DWORD dwCertEncodingType,
  4478. IN LPCSTR lpszStructType,
  4479. IN PCERT_NAME_INFO pInfo,
  4480. IN DWORD dwFlags,
  4481. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  4482. OUT OPTIONAL void *pvEncoded,
  4483. IN OUT DWORD *pcbEncoded
  4484. )
  4485. {
  4486. BOOL fResult;
  4487. DWORD cRDN, cAttr;
  4488. PCERT_RDN pRDN;
  4489. PCERT_RDN_ATTR pAttr;
  4490. Name Asn1Name;
  4491. RelativeDistinguishedName *pAsn1RDN = NULL;
  4492. AttributeTypeValue *pAsn1Attr = NULL;
  4493. cRDN = pInfo->cRDN;
  4494. pRDN = pInfo->rgRDN;
  4495. Asn1Name.count = cRDN;
  4496. Asn1Name.value = NULL;
  4497. if (cRDN > 0) {
  4498. pAsn1RDN =
  4499. (RelativeDistinguishedName *) PkiZeroAlloc(
  4500. cRDN * sizeof(RelativeDistinguishedName));
  4501. if (pAsn1RDN == NULL)
  4502. goto ErrorReturn;
  4503. Asn1Name.value = pAsn1RDN;
  4504. }
  4505. // Array of RDNs
  4506. for ( ; cRDN > 0; cRDN--, pRDN++, pAsn1RDN++) {
  4507. cAttr = pRDN->cRDNAttr;
  4508. pAttr = pRDN->rgRDNAttr;
  4509. pAsn1RDN->count = cAttr;
  4510. if (cAttr > 0) {
  4511. pAsn1Attr =
  4512. (AttributeTypeValue *) PkiZeroAlloc(cAttr *
  4513. sizeof(AttributeTypeValue));
  4514. if (pAsn1Attr == NULL)
  4515. goto ErrorReturn;
  4516. pAsn1RDN->value = pAsn1Attr;
  4517. }
  4518. // Array of attribute/values
  4519. for ( ; cAttr > 0; cAttr--, pAttr++, pAsn1Attr++) {
  4520. // We're now ready to encode the attribute/value stuff
  4521. if (!Asn1X509SetRDNAttribute(pAttr, pAsn1Attr))
  4522. goto ErrorReturn;
  4523. }
  4524. }
  4525. fResult = Asn1InfoEncodeEx(
  4526. Name_PDU,
  4527. &Asn1Name,
  4528. dwFlags,
  4529. pEncodePara,
  4530. pvEncoded,
  4531. pcbEncoded
  4532. );
  4533. goto CommonReturn;
  4534. ErrorReturn:
  4535. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  4536. *((void **) pvEncoded) = NULL;
  4537. *pcbEncoded = 0;
  4538. fResult = FALSE;
  4539. CommonReturn:
  4540. if (Asn1Name.value) {
  4541. cRDN = Asn1Name.count;
  4542. pRDN = pInfo->rgRDN;
  4543. pAsn1RDN = Asn1Name.value;
  4544. for ( ; cRDN > 0; cRDN--, pRDN++, pAsn1RDN++) {
  4545. if (pAsn1RDN->value) {
  4546. cAttr = pAsn1RDN->count;
  4547. pAttr = pRDN->rgRDNAttr;
  4548. pAsn1Attr = pAsn1RDN->value;
  4549. for ( ; cAttr > 0; cAttr--, pAttr++, pAsn1Attr++)
  4550. Asn1X509FreeRDNAttribute(pAttr, pAsn1Attr);
  4551. PkiFree(pAsn1RDN->value);
  4552. }
  4553. }
  4554. PkiFree(Asn1Name.value);
  4555. }
  4556. return fResult;
  4557. }
  4558. //+-------------------------------------------------------------------------
  4559. // Decode the Name Info (ASN1 X509)
  4560. //--------------------------------------------------------------------------
  4561. BOOL WINAPI Asn1X509NameInfoDecodeExCallback(
  4562. IN void *pvAsn1Info,
  4563. IN DWORD dwFlags,
  4564. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  4565. OUT OPTIONAL void *pvStructInfo,
  4566. IN OUT LONG *plRemainExtra
  4567. )
  4568. {
  4569. Name *pAsn1Name = (Name *) pvAsn1Info;
  4570. PCERT_NAME_INFO pInfo = (PCERT_NAME_INFO) pvStructInfo;
  4571. LONG lRemainExtra = *plRemainExtra;
  4572. BYTE *pbExtra;
  4573. LONG lAlignExtra;
  4574. DWORD cRDN, cAttr;
  4575. PCERT_RDN pRDN;
  4576. PCERT_RDN_ATTR pAttr;
  4577. RelativeDistinguishedName *pAsn1RDN;
  4578. AttributeTypeValue *pAsn1Attr;
  4579. lRemainExtra -= sizeof(CERT_NAME_INFO);
  4580. if (lRemainExtra < 0) {
  4581. pbExtra = NULL;
  4582. } else
  4583. pbExtra = (BYTE *) pInfo + sizeof(CERT_NAME_INFO);
  4584. cRDN = pAsn1Name->count;
  4585. pAsn1RDN = pAsn1Name->value;
  4586. lAlignExtra = INFO_LEN_ALIGN(cRDN * sizeof(CERT_RDN));
  4587. lRemainExtra -= lAlignExtra;
  4588. if (lRemainExtra >= 0) {
  4589. pInfo->cRDN = cRDN;
  4590. pRDN = (PCERT_RDN) pbExtra;
  4591. pInfo->rgRDN = pRDN;
  4592. pbExtra += lAlignExtra;
  4593. } else
  4594. pRDN = NULL;
  4595. // Array of RDNs
  4596. for (; cRDN > 0; cRDN--, pRDN++, pAsn1RDN++) {
  4597. cAttr = pAsn1RDN->count;
  4598. pAsn1Attr = pAsn1RDN->value;
  4599. lAlignExtra = INFO_LEN_ALIGN(cAttr * sizeof(CERT_RDN_ATTR));
  4600. lRemainExtra -= lAlignExtra;
  4601. if (lRemainExtra >= 0) {
  4602. pRDN->cRDNAttr = cAttr;
  4603. pAttr = (PCERT_RDN_ATTR) pbExtra;
  4604. pRDN->rgRDNAttr = pAttr;
  4605. pbExtra += lAlignExtra;
  4606. } else
  4607. pAttr = NULL;
  4608. // Array of attribute/values
  4609. for (; cAttr > 0; cAttr--, pAttr++, pAsn1Attr++)
  4610. // We're now ready to decode the attribute/value stuff
  4611. if (!Asn1X509GetRDNAttribute(pAsn1Attr, dwFlags,
  4612. pAttr, &pbExtra, &lRemainExtra))
  4613. return FALSE;
  4614. }
  4615. *plRemainExtra = lRemainExtra;
  4616. return TRUE;
  4617. }
  4618. BOOL WINAPI Asn1X509NameInfoDecodeEx(
  4619. IN DWORD dwCertEncodingType,
  4620. IN LPCSTR lpszStructType,
  4621. IN const BYTE *pbEncoded,
  4622. IN DWORD cbEncoded,
  4623. IN DWORD dwFlags,
  4624. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  4625. OUT OPTIONAL void *pvStructInfo,
  4626. IN OUT DWORD *pcbStructInfo
  4627. )
  4628. {
  4629. return Asn1InfoDecodeAndAllocEx(
  4630. Name_PDU,
  4631. pbEncoded,
  4632. cbEncoded,
  4633. dwFlags,
  4634. pDecodePara,
  4635. Asn1X509NameInfoDecodeExCallback,
  4636. pvStructInfo,
  4637. pcbStructInfo
  4638. );
  4639. }
  4640. //+-------------------------------------------------------------------------
  4641. // Encode a single Name Value (ASN1 X509)
  4642. //--------------------------------------------------------------------------
  4643. BOOL WINAPI Asn1X509NameValueEncodeEx(
  4644. IN DWORD dwCertEncodingType,
  4645. IN LPCSTR lpszStructType,
  4646. IN PCERT_NAME_VALUE pInfo,
  4647. IN DWORD dwFlags,
  4648. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  4649. OUT OPTIONAL void *pvEncoded,
  4650. IN OUT DWORD *pcbEncoded
  4651. )
  4652. {
  4653. BOOL fResult;
  4654. DWORD dwValueType;
  4655. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  4656. *((void **) pvEncoded) = NULL;
  4657. dwValueType = pInfo->dwValueType;
  4658. switch (dwValueType) {
  4659. case CERT_RDN_ANY_TYPE:
  4660. SetLastError((DWORD) E_INVALIDARG);
  4661. *pcbEncoded = 0;
  4662. fResult = FALSE;
  4663. break;
  4664. #ifndef ASN1_SUPPORTS_UTF8_TAG
  4665. case CERT_RDN_UTF8_STRING:
  4666. {
  4667. CERT_NAME_VALUE EncodedBlobInfo;
  4668. fResult = Asn1X509AllocAndEncodeUTF8(
  4669. &pInfo->Value,
  4670. &EncodedBlobInfo.Value.pbData,
  4671. &EncodedBlobInfo.Value.cbData
  4672. );
  4673. if (fResult) {
  4674. EncodedBlobInfo.dwValueType = CERT_RDN_ENCODED_BLOB;
  4675. fResult = Asn1X509NameValueEncodeEx(
  4676. dwCertEncodingType,
  4677. lpszStructType,
  4678. &EncodedBlobInfo,
  4679. dwFlags,
  4680. pEncodePara,
  4681. pvEncoded,
  4682. pcbEncoded
  4683. );
  4684. Asn1X509FreeEncodedUTF8(EncodedBlobInfo.Value.pbData);
  4685. } else
  4686. *pcbEncoded = 0;
  4687. }
  4688. break;
  4689. #endif // not defined ASN1_SUPPORTS_UTF8_TAG
  4690. case CERT_RDN_ENCODED_BLOB:
  4691. {
  4692. DWORD cbEncoded = pInfo->Value.cbData;
  4693. fResult = TRUE;
  4694. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG) {
  4695. if (cbEncoded) {
  4696. BYTE *pb;
  4697. PFN_CRYPT_ALLOC pfnAlloc =
  4698. PkiGetEncodeAllocFunction(pEncodePara);
  4699. if (NULL == (pb = (BYTE *) pfnAlloc(cbEncoded))) {
  4700. fResult = FALSE;
  4701. cbEncoded = 0;
  4702. } else {
  4703. memcpy(pb, pInfo->Value.pbData, cbEncoded);
  4704. *((BYTE **) pvEncoded) = pb;
  4705. }
  4706. }
  4707. } else {
  4708. if (NULL == pvEncoded)
  4709. *pcbEncoded = 0;
  4710. if (*pcbEncoded < cbEncoded) {
  4711. if (pvEncoded) {
  4712. SetLastError((DWORD) ERROR_MORE_DATA);
  4713. fResult = FALSE;
  4714. }
  4715. } else if (cbEncoded)
  4716. memcpy((BYTE *) pvEncoded, pInfo->Value.pbData, cbEncoded);
  4717. }
  4718. *pcbEncoded = cbEncoded;
  4719. }
  4720. break;
  4721. default:
  4722. {
  4723. AnyString Asn1AnyString;
  4724. Asn1X509SetAnyString(dwValueType, &pInfo->Value, &Asn1AnyString);
  4725. fResult = Asn1InfoEncodeEx(
  4726. AnyString_PDU,
  4727. &Asn1AnyString,
  4728. dwFlags,
  4729. pEncodePara,
  4730. pvEncoded,
  4731. pcbEncoded
  4732. );
  4733. }
  4734. break;
  4735. }
  4736. return fResult;
  4737. }
  4738. //+-------------------------------------------------------------------------
  4739. // Decode a single Name Value (ASN1 X509)
  4740. //--------------------------------------------------------------------------
  4741. BOOL WINAPI Asn1X509NameValueDecodeEx(
  4742. IN DWORD dwCertEncodingType,
  4743. IN LPCSTR lpszStructType,
  4744. IN const BYTE *pbEncoded,
  4745. IN DWORD cbEncoded,
  4746. IN DWORD dwFlags,
  4747. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  4748. OUT OPTIONAL void *pvStructInfo,
  4749. IN OUT DWORD *pcbStructInfo
  4750. )
  4751. {
  4752. BOOL fResult;
  4753. PCERT_NAME_VALUE pInfo = (PCERT_NAME_VALUE) pvStructInfo;
  4754. NOCOPYANY Asn1Value;
  4755. BYTE *pbExtra;
  4756. LONG lRemainExtra;
  4757. if (pInfo == NULL || (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
  4758. *pcbStructInfo = 0;
  4759. memset(&Asn1Value, 0, sizeof(Asn1Value));
  4760. Asn1Value.encoded = (void *)pbEncoded;
  4761. Asn1Value.length = cbEncoded;
  4762. // for lRemainExtra < 0, LENGTH_ONLY calculation
  4763. lRemainExtra = (LONG) *pcbStructInfo - sizeof(CERT_NAME_VALUE);
  4764. if (lRemainExtra < 0) {
  4765. pbExtra = NULL;
  4766. } else
  4767. pbExtra = (BYTE *) pInfo + sizeof(CERT_NAME_VALUE);
  4768. if (!Asn1X509GetRDNAttributeValue(&Asn1Value, dwFlags,
  4769. &pInfo->dwValueType, &pInfo->Value, &pbExtra, &lRemainExtra))
  4770. goto GetRDNAttributeValueError;
  4771. if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) {
  4772. PCERT_NAME_VALUE pAllocInfo;
  4773. PFN_CRYPT_ALLOC pfnAlloc = PkiGetDecodeAllocFunction(pDecodePara);
  4774. assert(0 > lRemainExtra);
  4775. lRemainExtra = -lRemainExtra;
  4776. pAllocInfo = (PCERT_NAME_VALUE) pfnAlloc(lRemainExtra);
  4777. *((PCERT_NAME_VALUE *) pvStructInfo) = pAllocInfo;
  4778. if (NULL == pAllocInfo)
  4779. goto OutOfMemory;
  4780. *pcbStructInfo = lRemainExtra;
  4781. pbExtra = (BYTE *) pAllocInfo + sizeof(CERT_NAME_VALUE);
  4782. lRemainExtra -= sizeof(CERT_NAME_VALUE);
  4783. if (!Asn1X509GetRDNAttributeValue(&Asn1Value, dwFlags,
  4784. &pAllocInfo->dwValueType, &pAllocInfo->Value,
  4785. &pbExtra, &lRemainExtra))
  4786. goto GetRDNAttributeValueError;
  4787. assert(lRemainExtra >= 0);
  4788. }
  4789. if (lRemainExtra >= 0)
  4790. *pcbStructInfo = *pcbStructInfo - (DWORD) lRemainExtra;
  4791. else {
  4792. *pcbStructInfo = *pcbStructInfo + (DWORD) -lRemainExtra;
  4793. if (pInfo) goto LengthError;
  4794. }
  4795. fResult = TRUE;
  4796. goto CommonReturn;
  4797. LengthError:
  4798. SetLastError((DWORD) ERROR_MORE_DATA);
  4799. fResult = FALSE;
  4800. CommonReturn:
  4801. return fResult;
  4802. ErrorReturn:
  4803. fResult = FALSE;
  4804. *pcbStructInfo = 0;
  4805. goto CommonReturn;
  4806. TRACE_ERROR(GetRDNAttributeValueError)
  4807. TRACE_ERROR(OutOfMemory)
  4808. }
  4809. //+-------------------------------------------------------------------------
  4810. // Encode X509 certificate extensions (ASN1)
  4811. //--------------------------------------------------------------------------
  4812. BOOL WINAPI Asn1X509ExtensionsEncodeEx(
  4813. IN DWORD dwCertEncodingType,
  4814. IN LPCSTR lpszStructType,
  4815. IN PCERT_EXTENSIONS pInfo,
  4816. IN DWORD dwFlags,
  4817. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  4818. OUT OPTIONAL void *pvEncoded,
  4819. IN OUT DWORD *pcbEncoded
  4820. )
  4821. {
  4822. BOOL fResult;
  4823. Extensions Asn1Ext;
  4824. if (!Asn1X509SetExtensions(pInfo->cExtension, pInfo->rgExtension, &Asn1Ext))
  4825. goto ErrorReturn;
  4826. fResult = Asn1InfoEncodeEx(
  4827. Extensions_PDU,
  4828. &Asn1Ext,
  4829. dwFlags,
  4830. pEncodePara,
  4831. pvEncoded,
  4832. pcbEncoded
  4833. );
  4834. goto CommonReturn;
  4835. ErrorReturn:
  4836. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  4837. *((void **) pvEncoded) = NULL;
  4838. *pcbEncoded = 0;
  4839. fResult = FALSE;
  4840. CommonReturn:
  4841. Asn1X509FreeExtensions(&Asn1Ext);
  4842. return fResult;
  4843. }
  4844. //+-------------------------------------------------------------------------
  4845. // Decode X509 certificate extensions (ASN1)
  4846. //--------------------------------------------------------------------------
  4847. BOOL WINAPI Asn1X509ExtensionsDecodeExCallback(
  4848. IN void *pvAsn1Info,
  4849. IN DWORD dwFlags,
  4850. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  4851. OUT OPTIONAL void *pvStructInfo,
  4852. IN OUT LONG *plRemainExtra
  4853. )
  4854. {
  4855. Extensions *pAsn1Ext = (Extensions *) pvAsn1Info;
  4856. PCERT_EXTENSIONS pInfo = (PCERT_EXTENSIONS) pvStructInfo;
  4857. LONG lRemainExtra = *plRemainExtra;
  4858. BYTE *pbExtra;
  4859. lRemainExtra -= sizeof(CERT_EXTENSIONS);
  4860. if (lRemainExtra < 0) {
  4861. pbExtra = NULL;
  4862. } else
  4863. pbExtra = (BYTE *) pInfo + sizeof(CERT_EXTENSIONS);
  4864. Asn1X509GetExtensions(pAsn1Ext, dwFlags,
  4865. &pInfo->cExtension, &pInfo->rgExtension, &pbExtra, &lRemainExtra);
  4866. *plRemainExtra = lRemainExtra;
  4867. return TRUE;
  4868. }
  4869. #define T61_ASN_TAG 0x14
  4870. BOOL WINAPI Asn1X509ExtensionsDecodeEx(
  4871. IN DWORD dwCertEncodingType,
  4872. IN LPCSTR lpszStructType,
  4873. IN const BYTE *pbEncoded,
  4874. IN DWORD cbEncoded,
  4875. IN DWORD dwFlags,
  4876. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  4877. OUT OPTIONAL void *pvStructInfo,
  4878. IN OUT DWORD *pcbStructInfo
  4879. )
  4880. {
  4881. if (0 < cbEncoded && T61_ASN_TAG == *pbEncoded) {
  4882. // Entrust wraps X509 Extensions within a T61 string
  4883. DWORD cbContent;
  4884. const BYTE *pbContent;
  4885. // Skip past the outer T61 tag and length octets
  4886. if (0 < Asn1UtilExtractContent(
  4887. pbEncoded,
  4888. cbEncoded,
  4889. &cbContent,
  4890. &pbContent
  4891. )) {
  4892. cbEncoded = cbContent;
  4893. pbEncoded = pbContent;
  4894. }
  4895. }
  4896. return Asn1InfoDecodeAndAllocEx(
  4897. Extensions_PDU,
  4898. pbEncoded,
  4899. cbEncoded,
  4900. dwFlags,
  4901. pDecodePara,
  4902. Asn1X509ExtensionsDecodeExCallback,
  4903. pvStructInfo,
  4904. pcbStructInfo
  4905. );
  4906. }
  4907. //+-------------------------------------------------------------------------
  4908. // Public Key Info Encode (ASN1 X509)
  4909. //--------------------------------------------------------------------------
  4910. BOOL WINAPI Asn1X509PublicKeyInfoEncodeEx(
  4911. IN DWORD dwCertEncodingType,
  4912. IN LPCSTR lpszStructType,
  4913. IN PCERT_PUBLIC_KEY_INFO pInfo,
  4914. IN DWORD dwFlags,
  4915. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  4916. OUT OPTIONAL void *pvEncoded,
  4917. IN OUT DWORD *pcbEncoded
  4918. )
  4919. {
  4920. BOOL fResult;
  4921. SubjectPublicKeyInfo PublicKey;
  4922. if (!Asn1X509SetPublicKeyInfo(pInfo, &PublicKey))
  4923. goto ErrorReturn;
  4924. fResult = Asn1InfoEncodeEx(
  4925. SubjectPublicKeyInfo_PDU,
  4926. &PublicKey,
  4927. dwFlags,
  4928. pEncodePara,
  4929. pvEncoded,
  4930. pcbEncoded
  4931. );
  4932. goto CommonReturn;
  4933. ErrorReturn:
  4934. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  4935. *((void **) pvEncoded) = NULL;
  4936. *pcbEncoded = 0;
  4937. fResult = FALSE;
  4938. CommonReturn:
  4939. return fResult;
  4940. }
  4941. //+-------------------------------------------------------------------------
  4942. // Public Key Info Decode (ASN1 X509)
  4943. //--------------------------------------------------------------------------
  4944. BOOL WINAPI Asn1X509PublicKeyInfoDecodeExCallback(
  4945. IN void *pvAsn1Info,
  4946. IN DWORD dwFlags,
  4947. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  4948. OUT OPTIONAL void *pvStructInfo,
  4949. IN OUT LONG *plRemainExtra
  4950. )
  4951. {
  4952. SubjectPublicKeyInfo *pPublicKey = (SubjectPublicKeyInfo *) pvAsn1Info;
  4953. PCERT_PUBLIC_KEY_INFO pInfo = (PCERT_PUBLIC_KEY_INFO) pvStructInfo;
  4954. LONG lRemainExtra = *plRemainExtra;
  4955. BYTE *pbExtra;
  4956. lRemainExtra -= sizeof(CERT_PUBLIC_KEY_INFO);
  4957. if (lRemainExtra < 0) {
  4958. pbExtra = NULL;
  4959. } else
  4960. pbExtra = (BYTE *) pInfo + sizeof(CERT_PUBLIC_KEY_INFO);
  4961. Asn1X509GetPublicKeyInfo(pPublicKey, dwFlags,
  4962. pInfo, &pbExtra, &lRemainExtra);
  4963. *plRemainExtra = lRemainExtra;
  4964. return TRUE;
  4965. }
  4966. BOOL WINAPI Asn1X509PublicKeyInfoDecodeEx(
  4967. IN DWORD dwCertEncodingType,
  4968. IN LPCSTR lpszStructType,
  4969. IN const BYTE *pbEncoded,
  4970. IN DWORD cbEncoded,
  4971. IN DWORD dwFlags,
  4972. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  4973. OUT OPTIONAL void *pvStructInfo,
  4974. IN OUT DWORD *pcbStructInfo
  4975. )
  4976. {
  4977. return Asn1InfoDecodeAndAllocEx(
  4978. SubjectPublicKeyInfo_PDU,
  4979. pbEncoded,
  4980. cbEncoded,
  4981. dwFlags,
  4982. pDecodePara,
  4983. Asn1X509PublicKeyInfoDecodeExCallback,
  4984. pvStructInfo,
  4985. pcbStructInfo
  4986. );
  4987. }
  4988. #ifndef RSA1
  4989. #define RSA1 ((DWORD)'R'+((DWORD)'S'<<8)+((DWORD)'A'<<16)+((DWORD)'1'<<24))
  4990. #endif
  4991. //+-------------------------------------------------------------------------
  4992. // RSA Public Key Structure Encode (ASN1 X509)
  4993. //
  4994. // Converts from the CAPI public key representation to a PKCS #1 RSAPublicKey
  4995. //
  4996. // BYTE reversal::
  4997. // - this only needs to be done for little endian processors
  4998. //--------------------------------------------------------------------------
  4999. BOOL WINAPI Asn1RSAPublicKeyStrucEncodeEx(
  5000. IN DWORD dwCertEncodingType,
  5001. IN LPCSTR lpszStructType,
  5002. IN PUBLICKEYSTRUC *pPubKeyStruc,
  5003. IN DWORD dwFlags,
  5004. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  5005. OUT OPTIONAL void *pvEncoded,
  5006. IN OUT DWORD *pcbEncoded
  5007. )
  5008. {
  5009. BOOL fResult;
  5010. BYTE *pbKeyBlob;
  5011. RSAPUBKEY *pRsaPubKey;
  5012. const BYTE *pbModulus;
  5013. DWORD cbModulus;
  5014. BYTE *pbAllocModulus = NULL;
  5015. RSAPublicKey Asn1PubKey;
  5016. // The CAPI public key representation consists of the following sequence:
  5017. // - PUBLICKEYSTRUC
  5018. // - RSAPUBKEY
  5019. // - rgbModulus[]
  5020. pbKeyBlob = (BYTE *) pPubKeyStruc;
  5021. pRsaPubKey = (RSAPUBKEY *) (pbKeyBlob + sizeof(PUBLICKEYSTRUC));
  5022. pbModulus = pbKeyBlob + sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY);
  5023. cbModulus = pRsaPubKey->bitlen / 8;
  5024. assert(cbModulus > 0);
  5025. assert(pPubKeyStruc->bType == PUBLICKEYBLOB);
  5026. assert(pPubKeyStruc->bVersion == CUR_BLOB_VERSION);
  5027. assert(pPubKeyStruc->aiKeyAlg == CALG_RSA_SIGN ||
  5028. pPubKeyStruc->aiKeyAlg == CALG_RSA_KEYX);
  5029. assert(pRsaPubKey->magic == RSA1);
  5030. assert(pRsaPubKey->bitlen % 8 == 0);
  5031. if (pPubKeyStruc->bType != PUBLICKEYBLOB)
  5032. goto InvalidArg;
  5033. // PKCS #1 ASN.1 encode
  5034. //
  5035. // ASN1 isn't reversing HUGE_INTEGERs. Also, after doing the
  5036. // reversal insert a leading 0 byte to force it to always be treated
  5037. // as an unsigned integer
  5038. if (NULL == (pbAllocModulus = (BYTE *) PkiNonzeroAlloc(cbModulus + 1)))
  5039. goto ErrorReturn;
  5040. *pbAllocModulus = 0;
  5041. memcpy(pbAllocModulus + 1, pbModulus, cbModulus);
  5042. PkiAsn1ReverseBytes(pbAllocModulus + 1, cbModulus);
  5043. pbModulus = pbAllocModulus;
  5044. cbModulus++;
  5045. Asn1PubKey.publicExponent = pRsaPubKey->pubexp;
  5046. Asn1PubKey.modulus.length = cbModulus;
  5047. Asn1PubKey.modulus.value = (BYTE *) pbModulus;
  5048. fResult = Asn1InfoEncodeEx(
  5049. RSAPublicKey_PDU,
  5050. &Asn1PubKey,
  5051. dwFlags,
  5052. pEncodePara,
  5053. pvEncoded,
  5054. pcbEncoded
  5055. );
  5056. goto CommonReturn;
  5057. InvalidArg:
  5058. SetLastError((DWORD) E_INVALIDARG);
  5059. ErrorReturn:
  5060. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  5061. *((void **) pvEncoded) = NULL;
  5062. *pcbEncoded = 0;
  5063. fResult = FALSE;
  5064. CommonReturn:
  5065. if (pbAllocModulus)
  5066. PkiFree(pbAllocModulus);
  5067. return fResult;
  5068. }
  5069. //+-------------------------------------------------------------------------
  5070. // RSA Public Key Structure Decode (ASN1 X509)
  5071. //
  5072. // Converts from a PKCS #1 RSAPublicKey to a CAPI public key representation
  5073. //
  5074. // BYTE reversal::
  5075. // - this only needs to be done for little endian processors
  5076. //--------------------------------------------------------------------------
  5077. BOOL WINAPI Asn1RSAPublicKeyStrucDecodeExCallback(
  5078. IN void *pvAsn1Info,
  5079. IN DWORD dwFlags,
  5080. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  5081. OUT OPTIONAL void *pvStructInfo,
  5082. IN OUT LONG *plRemainExtra
  5083. )
  5084. {
  5085. RSAPublicKey *pAsn1PubKey = (RSAPublicKey *) pvAsn1Info;
  5086. PUBLICKEYSTRUC *pPubKeyStruc = (PUBLICKEYSTRUC *) pvStructInfo;
  5087. BYTE *pbAsn1Modulus;
  5088. DWORD cbModulus;
  5089. // Now convert the ASN1 RSA public key into CAPI's representation which
  5090. // consists of the following sequence:
  5091. // - PUBLICKEYSTRUC
  5092. // - RSAPUBKEY
  5093. // - rgbModulus[]
  5094. cbModulus = pAsn1PubKey->modulus.length;
  5095. pbAsn1Modulus = pAsn1PubKey->modulus.value;
  5096. // Strip off a leading 0 byte. Its there in the decoded ASN
  5097. // integer for an unsigned integer with the leading bit set.
  5098. if (cbModulus > 1 && *pbAsn1Modulus == 0) {
  5099. pbAsn1Modulus++;
  5100. cbModulus--;
  5101. }
  5102. *plRemainExtra -= sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY) + cbModulus;
  5103. if (0 <= *plRemainExtra) {
  5104. BYTE *pbKeyBlob = (BYTE *) pPubKeyStruc;
  5105. RSAPUBKEY *pRsaPubKey =
  5106. (RSAPUBKEY *) (pbKeyBlob + sizeof(PUBLICKEYSTRUC));
  5107. BYTE *pbModulus = pbKeyBlob + sizeof(PUBLICKEYSTRUC) +
  5108. sizeof(RSAPUBKEY);
  5109. pPubKeyStruc->bType = PUBLICKEYBLOB;
  5110. pPubKeyStruc->bVersion = CUR_BLOB_VERSION;
  5111. pPubKeyStruc->reserved = 0;
  5112. // Note: KEYX can also be used for doing a signature
  5113. pPubKeyStruc->aiKeyAlg = CALG_RSA_KEYX;
  5114. pRsaPubKey->magic = RSA1;
  5115. pRsaPubKey->bitlen = cbModulus * 8;
  5116. pRsaPubKey->pubexp = pAsn1PubKey->publicExponent;
  5117. if (cbModulus > 0) {
  5118. memcpy(pbModulus, pbAsn1Modulus, cbModulus);
  5119. // ASN1 isn't reversing HUGEINTEGERs
  5120. PkiAsn1ReverseBytes(pbModulus, cbModulus);
  5121. }
  5122. }
  5123. return TRUE;
  5124. }
  5125. BOOL WINAPI Asn1RSAPublicKeyStrucDecodeEx(
  5126. IN DWORD dwCertEncodingType,
  5127. IN LPCSTR lpszStructType,
  5128. IN const BYTE *pbEncoded,
  5129. IN DWORD cbEncoded,
  5130. IN DWORD dwFlags,
  5131. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  5132. OUT OPTIONAL void *pvStructInfo,
  5133. IN OUT DWORD *pcbStructInfo
  5134. )
  5135. {
  5136. return Asn1InfoDecodeAndAllocEx(
  5137. RSAPublicKey_PDU,
  5138. pbEncoded,
  5139. cbEncoded,
  5140. dwFlags,
  5141. pDecodePara,
  5142. Asn1RSAPublicKeyStrucDecodeExCallback,
  5143. pvStructInfo,
  5144. pcbStructInfo
  5145. );
  5146. }
  5147. //+-------------------------------------------------------------------------
  5148. // Authority Key Id Extension Encode (ASN1 X509)
  5149. //--------------------------------------------------------------------------
  5150. BOOL WINAPI Asn1X509AuthorityKeyIdEncodeEx(
  5151. IN DWORD dwCertEncodingType,
  5152. IN LPCSTR lpszStructType,
  5153. IN PCERT_AUTHORITY_KEY_ID_INFO pInfo,
  5154. IN DWORD dwFlags,
  5155. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  5156. OUT OPTIONAL void *pvEncoded,
  5157. IN OUT DWORD *pcbEncoded
  5158. )
  5159. {
  5160. BOOL fResult;
  5161. AuthorityKeyId Asn1AuthorityKeyId;
  5162. memset(&Asn1AuthorityKeyId, 0, sizeof(Asn1AuthorityKeyId));
  5163. if (pInfo->KeyId.cbData) {
  5164. Asn1X509SetOctetString(&pInfo->KeyId,
  5165. #ifdef OSS_CRYPT_ASN1
  5166. &Asn1AuthorityKeyId.AuthorityKeyId_keyIdentifier);
  5167. #else
  5168. &Asn1AuthorityKeyId.keyIdentifier);
  5169. #endif // OSS_CRYPT_ASN1
  5170. Asn1AuthorityKeyId.bit_mask |= AuthorityKeyId_keyIdentifier_present;
  5171. }
  5172. if (pInfo->CertIssuer.cbData) {
  5173. Asn1X509SetAny(&pInfo->CertIssuer, &Asn1AuthorityKeyId.certIssuer);
  5174. Asn1AuthorityKeyId.bit_mask |= certIssuer_present;
  5175. }
  5176. if (pInfo->CertSerialNumber.cbData) {
  5177. if (!Asn1X509SetHugeInteger(&pInfo->CertSerialNumber,
  5178. &Asn1AuthorityKeyId.certSerialNumber))
  5179. goto ErrorReturn;
  5180. Asn1AuthorityKeyId.bit_mask |= certSerialNumber_present;
  5181. }
  5182. fResult = Asn1InfoEncodeEx(
  5183. AuthorityKeyId_PDU,
  5184. &Asn1AuthorityKeyId,
  5185. dwFlags,
  5186. pEncodePara,
  5187. pvEncoded,
  5188. pcbEncoded
  5189. );
  5190. goto CommonReturn;
  5191. ErrorReturn:
  5192. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  5193. *((void **) pvEncoded) = NULL;
  5194. *pcbEncoded = 0;
  5195. fResult = FALSE;
  5196. CommonReturn:
  5197. Asn1X509FreeHugeInteger(&Asn1AuthorityKeyId.certSerialNumber);
  5198. return fResult;
  5199. }
  5200. //+-------------------------------------------------------------------------
  5201. // Authority Key Id Extension Decode (ASN1 X509)
  5202. //--------------------------------------------------------------------------
  5203. BOOL WINAPI Asn1X509AuthorityKeyIdDecodeExCallback(
  5204. IN void *pvAsn1Info,
  5205. IN DWORD dwFlags,
  5206. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  5207. OUT OPTIONAL void *pvStructInfo,
  5208. IN OUT LONG *plRemainExtra
  5209. )
  5210. {
  5211. AuthorityKeyId *pAuthorityKeyId = (AuthorityKeyId *) pvAsn1Info;
  5212. PCERT_AUTHORITY_KEY_ID_INFO pInfo =
  5213. (PCERT_AUTHORITY_KEY_ID_INFO) pvStructInfo;
  5214. LONG lRemainExtra = *plRemainExtra;
  5215. BYTE *pbExtra;
  5216. lRemainExtra -= sizeof(CERT_AUTHORITY_KEY_ID_INFO);
  5217. if (lRemainExtra < 0) {
  5218. pbExtra = NULL;
  5219. } else {
  5220. // Default all optional fields to zero
  5221. memset(pInfo, 0, sizeof(CERT_AUTHORITY_KEY_ID_INFO));
  5222. pbExtra = (BYTE *) pInfo + sizeof(CERT_AUTHORITY_KEY_ID_INFO);
  5223. }
  5224. if (pAuthorityKeyId->bit_mask & AuthorityKeyId_keyIdentifier_present)
  5225. #ifdef OSS_CRYPT_ASN1
  5226. Asn1X509GetOctetString(&pAuthorityKeyId->AuthorityKeyId_keyIdentifier,
  5227. #else
  5228. Asn1X509GetOctetString(&pAuthorityKeyId->keyIdentifier,
  5229. #endif // OSS_CRYPT_ASN1
  5230. dwFlags, &pInfo->KeyId, &pbExtra, &lRemainExtra);
  5231. if (pAuthorityKeyId->bit_mask & certIssuer_present)
  5232. Asn1X509GetAny(&pAuthorityKeyId->certIssuer, dwFlags,
  5233. &pInfo->CertIssuer, &pbExtra, &lRemainExtra);
  5234. if (pAuthorityKeyId->bit_mask & certSerialNumber_present)
  5235. Asn1X509GetHugeInteger(&pAuthorityKeyId->certSerialNumber, dwFlags,
  5236. &pInfo->CertSerialNumber, &pbExtra, &lRemainExtra);
  5237. *plRemainExtra = lRemainExtra;
  5238. return TRUE;
  5239. }
  5240. BOOL WINAPI Asn1X509AuthorityKeyIdDecodeEx(
  5241. IN DWORD dwCertEncodingType,
  5242. IN LPCSTR lpszStructType,
  5243. IN const BYTE *pbEncoded,
  5244. IN DWORD cbEncoded,
  5245. IN DWORD dwFlags,
  5246. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  5247. OUT OPTIONAL void *pvStructInfo,
  5248. IN OUT DWORD *pcbStructInfo
  5249. )
  5250. {
  5251. return Asn1InfoDecodeAndAllocEx(
  5252. AuthorityKeyId_PDU,
  5253. pbEncoded,
  5254. cbEncoded,
  5255. dwFlags,
  5256. pDecodePara,
  5257. Asn1X509AuthorityKeyIdDecodeExCallback,
  5258. pvStructInfo,
  5259. pcbStructInfo
  5260. );
  5261. }
  5262. //+-------------------------------------------------------------------------
  5263. // Authority Key Id2 Extension Encode (ASN1 X509)
  5264. //--------------------------------------------------------------------------
  5265. BOOL WINAPI Asn1X509AuthorityKeyId2EncodeEx(
  5266. IN DWORD dwCertEncodingType,
  5267. IN LPCSTR lpszStructType,
  5268. IN PCERT_AUTHORITY_KEY_ID2_INFO pInfo,
  5269. IN DWORD dwFlags,
  5270. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  5271. OUT OPTIONAL void *pvEncoded,
  5272. IN OUT DWORD *pcbEncoded
  5273. )
  5274. {
  5275. BOOL fResult;
  5276. DWORD dwErrLocation;
  5277. AuthorityKeyId2 Asn1AuthorityKeyId2;
  5278. memset(&Asn1AuthorityKeyId2, 0, sizeof(Asn1AuthorityKeyId2));
  5279. if (pInfo->KeyId.cbData) {
  5280. Asn1X509SetOctetString(&pInfo->KeyId,
  5281. #ifdef OSS_CRYPT_ASN1
  5282. &Asn1AuthorityKeyId2.AuthorityKeyId2_keyIdentifier);
  5283. #else
  5284. &Asn1AuthorityKeyId2.keyIdentifier);
  5285. #endif // OSS_CRYPT_ASN1
  5286. Asn1AuthorityKeyId2.bit_mask |= AuthorityKeyId2_keyIdentifier_present;
  5287. }
  5288. if (pInfo->AuthorityCertIssuer.cAltEntry) {
  5289. if (!Asn1X509SetAltNames(&pInfo->AuthorityCertIssuer,
  5290. &Asn1AuthorityKeyId2.authorityCertIssuer, 0, &dwErrLocation)) {
  5291. *pcbEncoded = dwErrLocation;
  5292. goto AltNamesError;
  5293. }
  5294. Asn1AuthorityKeyId2.bit_mask |= authorityCertIssuer_present;
  5295. }
  5296. if (pInfo->AuthorityCertSerialNumber.cbData) {
  5297. if (!Asn1X509SetHugeInteger(&pInfo->AuthorityCertSerialNumber,
  5298. &Asn1AuthorityKeyId2.authorityCertSerialNumber))
  5299. goto ErrorReturn;
  5300. Asn1AuthorityKeyId2.bit_mask |= authorityCertSerialNumber_present;
  5301. }
  5302. fResult = Asn1InfoEncodeEx(
  5303. AuthorityKeyId2_PDU,
  5304. &Asn1AuthorityKeyId2,
  5305. dwFlags,
  5306. pEncodePara,
  5307. pvEncoded,
  5308. pcbEncoded
  5309. );
  5310. goto CommonReturn;
  5311. ErrorReturn:
  5312. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  5313. *((void **) pvEncoded) = NULL;
  5314. *pcbEncoded = 0;
  5315. AltNamesError:
  5316. fResult = FALSE;
  5317. CommonReturn:
  5318. Asn1X509FreeAltNames(&Asn1AuthorityKeyId2.authorityCertIssuer);
  5319. Asn1X509FreeHugeInteger(&Asn1AuthorityKeyId2.authorityCertSerialNumber);
  5320. return fResult;
  5321. }
  5322. //+-------------------------------------------------------------------------
  5323. // Authority Key Id2 Extension Decode (ASN1 X509)
  5324. //--------------------------------------------------------------------------
  5325. BOOL WINAPI Asn1X509AuthorityKeyId2DecodeExCallback(
  5326. IN void *pvAsn1Info,
  5327. IN DWORD dwFlags,
  5328. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  5329. OUT OPTIONAL void *pvStructInfo,
  5330. IN OUT LONG *plRemainExtra
  5331. )
  5332. {
  5333. BOOL fResult;
  5334. AuthorityKeyId2 *pAuthorityKeyId2 = (AuthorityKeyId2 *) pvAsn1Info;
  5335. PCERT_AUTHORITY_KEY_ID2_INFO pInfo =
  5336. (PCERT_AUTHORITY_KEY_ID2_INFO) pvStructInfo;
  5337. LONG lRemainExtra = *plRemainExtra;
  5338. BYTE *pbExtra;
  5339. lRemainExtra -= sizeof(CERT_AUTHORITY_KEY_ID2_INFO);
  5340. if (lRemainExtra < 0) {
  5341. pbExtra = NULL;
  5342. } else {
  5343. // Default all optional fields to zero
  5344. memset(pInfo, 0, sizeof(CERT_AUTHORITY_KEY_ID2_INFO));
  5345. pbExtra = (BYTE *) pInfo + sizeof(CERT_AUTHORITY_KEY_ID2_INFO);
  5346. }
  5347. if (pAuthorityKeyId2->bit_mask & AuthorityKeyId2_keyIdentifier_present)
  5348. #ifdef OSS_CRYPT_ASN1
  5349. Asn1X509GetOctetString(&pAuthorityKeyId2->AuthorityKeyId2_keyIdentifier,
  5350. #else
  5351. Asn1X509GetOctetString(&pAuthorityKeyId2->keyIdentifier,
  5352. #endif // OSS_CRYPT_ASN1
  5353. dwFlags, &pInfo->KeyId, &pbExtra, &lRemainExtra);
  5354. if (pAuthorityKeyId2->bit_mask & authorityCertIssuer_present) {
  5355. if (!Asn1X509GetAltNames(&pAuthorityKeyId2->authorityCertIssuer, dwFlags,
  5356. &pInfo->AuthorityCertIssuer, &pbExtra, &lRemainExtra))
  5357. goto ErrorReturn;
  5358. }
  5359. if (pAuthorityKeyId2->bit_mask & authorityCertSerialNumber_present)
  5360. Asn1X509GetHugeInteger(&pAuthorityKeyId2->authorityCertSerialNumber, dwFlags,
  5361. &pInfo->AuthorityCertSerialNumber, &pbExtra, &lRemainExtra);
  5362. fResult = TRUE;
  5363. CommonReturn:
  5364. *plRemainExtra = lRemainExtra;
  5365. return fResult;
  5366. ErrorReturn:
  5367. fResult = FALSE;
  5368. goto CommonReturn;
  5369. }
  5370. BOOL WINAPI Asn1X509AuthorityKeyId2DecodeEx(
  5371. IN DWORD dwCertEncodingType,
  5372. IN LPCSTR lpszStructType,
  5373. IN const BYTE *pbEncoded,
  5374. IN DWORD cbEncoded,
  5375. IN DWORD dwFlags,
  5376. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  5377. OUT OPTIONAL void *pvStructInfo,
  5378. IN OUT DWORD *pcbStructInfo
  5379. )
  5380. {
  5381. return Asn1InfoDecodeAndAllocEx(
  5382. AuthorityKeyId2_PDU,
  5383. pbEncoded,
  5384. cbEncoded,
  5385. dwFlags,
  5386. pDecodePara,
  5387. Asn1X509AuthorityKeyId2DecodeExCallback,
  5388. pvStructInfo,
  5389. pcbStructInfo
  5390. );
  5391. }
  5392. //+-------------------------------------------------------------------------
  5393. // Key Attributes Extension Encode (ASN1 X509)
  5394. //--------------------------------------------------------------------------
  5395. BOOL WINAPI Asn1X509KeyAttributesEncodeEx(
  5396. IN DWORD dwCertEncodingType,
  5397. IN LPCSTR lpszStructType,
  5398. IN PCERT_KEY_ATTRIBUTES_INFO pInfo,
  5399. IN DWORD dwFlags,
  5400. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  5401. OUT OPTIONAL void *pvEncoded,
  5402. IN OUT DWORD *pcbEncoded
  5403. )
  5404. {
  5405. BOOL fResult;
  5406. KeyAttributes Asn1KeyAttributes;
  5407. memset(&Asn1KeyAttributes, 0, sizeof(Asn1KeyAttributes));
  5408. if (pInfo->KeyId.cbData) {
  5409. Asn1X509SetOctetString(&pInfo->KeyId,
  5410. #ifdef OSS_CRYPT_ASN1
  5411. &Asn1KeyAttributes.KeyAttributes_keyIdentifier);
  5412. #else
  5413. &Asn1KeyAttributes.keyIdentifier);
  5414. #endif // OSS_CRYPT_ASN1
  5415. Asn1KeyAttributes.bit_mask |= KeyAttributes_keyIdentifier_present;
  5416. }
  5417. if (pInfo->IntendedKeyUsage.cbData) {
  5418. Asn1X509SetBitWithoutTrailingZeroes(&pInfo->IntendedKeyUsage,
  5419. &Asn1KeyAttributes.intendedKeyUsage);
  5420. Asn1KeyAttributes.bit_mask |= intendedKeyUsage_present;
  5421. }
  5422. if (pInfo->pPrivateKeyUsagePeriod) {
  5423. if (!PkiAsn1ToGeneralizedTime(
  5424. &pInfo->pPrivateKeyUsagePeriod->NotBefore,
  5425. &Asn1KeyAttributes.privateKeyUsagePeriod.notBefore))
  5426. goto EncodeError;
  5427. if (!PkiAsn1ToGeneralizedTime(
  5428. &pInfo->pPrivateKeyUsagePeriod->NotAfter,
  5429. &Asn1KeyAttributes.privateKeyUsagePeriod.notAfter))
  5430. goto EncodeError;
  5431. Asn1KeyAttributes.privateKeyUsagePeriod.bit_mask |=
  5432. notBefore_present | notAfter_present;
  5433. Asn1KeyAttributes.bit_mask |= privateKeyUsagePeriod_present;
  5434. }
  5435. fResult = Asn1InfoEncodeEx(
  5436. KeyAttributes_PDU,
  5437. &Asn1KeyAttributes,
  5438. dwFlags,
  5439. pEncodePara,
  5440. pvEncoded,
  5441. pcbEncoded
  5442. );
  5443. goto CommonReturn;
  5444. EncodeError:
  5445. SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
  5446. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  5447. *((void **) pvEncoded) = NULL;
  5448. *pcbEncoded = 0;
  5449. fResult = FALSE;
  5450. CommonReturn:
  5451. return fResult;
  5452. }
  5453. //+-------------------------------------------------------------------------
  5454. // Key Attributes Extension Decode (ASN1 X509)
  5455. //--------------------------------------------------------------------------
  5456. BOOL WINAPI Asn1X509KeyAttributesDecodeExCallback(
  5457. IN void *pvAsn1Info,
  5458. IN DWORD dwFlags,
  5459. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  5460. OUT OPTIONAL void *pvStructInfo,
  5461. IN OUT LONG *plRemainExtra
  5462. )
  5463. {
  5464. BOOL fResult;
  5465. KeyAttributes *pKeyAttributes = (KeyAttributes *) pvAsn1Info;
  5466. PCERT_KEY_ATTRIBUTES_INFO pInfo = (PCERT_KEY_ATTRIBUTES_INFO) pvStructInfo;
  5467. LONG lRemainExtra = *plRemainExtra;
  5468. BYTE *pbExtra;
  5469. lRemainExtra -= sizeof(CERT_KEY_ATTRIBUTES_INFO);
  5470. if (lRemainExtra < 0) {
  5471. pbExtra = NULL;
  5472. } else {
  5473. // Default all optional fields to zero
  5474. memset(pInfo, 0, sizeof(CERT_KEY_ATTRIBUTES_INFO));
  5475. pbExtra = (BYTE *) pInfo + sizeof(CERT_KEY_ATTRIBUTES_INFO);
  5476. }
  5477. if (pKeyAttributes->bit_mask & KeyAttributes_keyIdentifier_present)
  5478. #ifdef OSS_CRYPT_ASN1
  5479. Asn1X509GetOctetString(&pKeyAttributes->KeyAttributes_keyIdentifier,
  5480. #else
  5481. Asn1X509GetOctetString(&pKeyAttributes->keyIdentifier,
  5482. #endif // OSS_CRYPT_ASN1
  5483. dwFlags, &pInfo->KeyId, &pbExtra, &lRemainExtra);
  5484. if (pKeyAttributes->bit_mask & intendedKeyUsage_present)
  5485. Asn1X509GetBit(&pKeyAttributes->intendedKeyUsage, dwFlags,
  5486. &pInfo->IntendedKeyUsage, &pbExtra, &lRemainExtra);
  5487. if (pKeyAttributes->bit_mask & privateKeyUsagePeriod_present) {
  5488. LONG lAlignExtra;
  5489. PrivateKeyValidity *pAsn1KeyUsage =
  5490. &pKeyAttributes->privateKeyUsagePeriod;
  5491. lAlignExtra = INFO_LEN_ALIGN(sizeof(CERT_PRIVATE_KEY_VALIDITY));
  5492. lRemainExtra -= lAlignExtra;
  5493. if (lRemainExtra >= 0) {
  5494. PCERT_PRIVATE_KEY_VALIDITY pKeyUsage =
  5495. (PCERT_PRIVATE_KEY_VALIDITY) pbExtra;
  5496. // Default all optional fields to zero
  5497. memset(pKeyUsage, 0, sizeof(CERT_PRIVATE_KEY_VALIDITY));
  5498. if (pAsn1KeyUsage->bit_mask & notBefore_present) {
  5499. if (!PkiAsn1FromGeneralizedTime(&pAsn1KeyUsage->notBefore,
  5500. &pKeyUsage->NotBefore))
  5501. goto DecodeError;
  5502. }
  5503. if (pAsn1KeyUsage->bit_mask & notAfter_present) {
  5504. if (!PkiAsn1FromGeneralizedTime(&pAsn1KeyUsage->notAfter,
  5505. &pKeyUsage->NotAfter))
  5506. goto DecodeError;
  5507. }
  5508. pInfo->pPrivateKeyUsagePeriod = pKeyUsage;
  5509. pbExtra += lAlignExtra;
  5510. }
  5511. }
  5512. fResult = TRUE;
  5513. CommonReturn:
  5514. *plRemainExtra = lRemainExtra;
  5515. return fResult;
  5516. ErrorReturn:
  5517. fResult = FALSE;
  5518. goto CommonReturn;
  5519. SET_ERROR(DecodeError, CRYPT_E_BAD_ENCODE)
  5520. }
  5521. BOOL WINAPI Asn1X509KeyAttributesDecodeEx(
  5522. IN DWORD dwCertEncodingType,
  5523. IN LPCSTR lpszStructType,
  5524. IN const BYTE *pbEncoded,
  5525. IN DWORD cbEncoded,
  5526. IN DWORD dwFlags,
  5527. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  5528. OUT OPTIONAL void *pvStructInfo,
  5529. IN OUT DWORD *pcbStructInfo
  5530. )
  5531. {
  5532. return Asn1InfoDecodeAndAllocEx(
  5533. KeyAttributes_PDU,
  5534. pbEncoded,
  5535. cbEncoded,
  5536. dwFlags,
  5537. pDecodePara,
  5538. Asn1X509KeyAttributesDecodeExCallback,
  5539. pvStructInfo,
  5540. pcbStructInfo
  5541. );
  5542. }
  5543. //+-------------------------------------------------------------------------
  5544. // AltName Extension Encode (ASN1 X509)
  5545. //--------------------------------------------------------------------------
  5546. BOOL WINAPI Asn1X509AltNameEncodeEx(
  5547. IN DWORD dwCertEncodingType,
  5548. IN LPCSTR lpszStructType,
  5549. IN PCERT_ALT_NAME_INFO pInfo,
  5550. IN DWORD dwFlags,
  5551. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  5552. OUT OPTIONAL void *pvEncoded,
  5553. IN OUT DWORD *pcbEncoded
  5554. )
  5555. {
  5556. BOOL fResult;
  5557. AltNames AltNames;
  5558. DWORD dwErrLocation;
  5559. if (!Asn1X509SetAltNames(pInfo, &AltNames, 0, &dwErrLocation)) {
  5560. *pcbEncoded = dwErrLocation;
  5561. fResult = FALSE;
  5562. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  5563. *((void **) pvEncoded) = NULL;
  5564. goto CommonReturn;
  5565. }
  5566. fResult = Asn1InfoEncodeEx(
  5567. AltNames_PDU,
  5568. &AltNames,
  5569. dwFlags,
  5570. pEncodePara,
  5571. pvEncoded,
  5572. pcbEncoded
  5573. );
  5574. CommonReturn:
  5575. Asn1X509FreeAltNames(&AltNames);
  5576. return fResult;
  5577. }
  5578. //+-------------------------------------------------------------------------
  5579. // AltName Extension Decode (ASN1 X509)
  5580. //--------------------------------------------------------------------------
  5581. BOOL WINAPI Asn1X509AltNameDecodeExCallback(
  5582. IN void *pvAsn1Info,
  5583. IN DWORD dwFlags,
  5584. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  5585. OUT OPTIONAL void *pvStructInfo,
  5586. IN OUT LONG *plRemainExtra
  5587. )
  5588. {
  5589. BOOL fResult;
  5590. AltNames *pAltNames = (AltNames *) pvAsn1Info;
  5591. PCERT_ALT_NAME_INFO pInfo = (PCERT_ALT_NAME_INFO) pvStructInfo;
  5592. LONG lRemainExtra = *plRemainExtra;
  5593. BYTE *pbExtra;
  5594. lRemainExtra -= sizeof(CERT_ALT_NAME_INFO);
  5595. if (lRemainExtra < 0) {
  5596. pbExtra = NULL;
  5597. } else
  5598. pbExtra = (BYTE *) pInfo + sizeof(CERT_ALT_NAME_INFO);
  5599. if (!Asn1X509GetAltNames(pAltNames, dwFlags,
  5600. pInfo, &pbExtra, &lRemainExtra))
  5601. goto ErrorReturn;
  5602. fResult = TRUE;
  5603. CommonReturn:
  5604. *plRemainExtra = lRemainExtra;
  5605. return fResult;
  5606. ErrorReturn:
  5607. fResult = FALSE;
  5608. goto CommonReturn;
  5609. }
  5610. BOOL WINAPI Asn1X509AltNameDecodeEx(
  5611. IN DWORD dwCertEncodingType,
  5612. IN LPCSTR lpszStructType,
  5613. IN const BYTE *pbEncoded,
  5614. IN DWORD cbEncoded,
  5615. IN DWORD dwFlags,
  5616. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  5617. OUT OPTIONAL void *pvStructInfo,
  5618. IN OUT DWORD *pcbStructInfo
  5619. )
  5620. {
  5621. return Asn1InfoDecodeAndAllocEx(
  5622. AltNames_PDU,
  5623. pbEncoded,
  5624. cbEncoded,
  5625. dwFlags,
  5626. pDecodePara,
  5627. Asn1X509AltNameDecodeExCallback,
  5628. pvStructInfo,
  5629. pcbStructInfo
  5630. );
  5631. }
  5632. //+-------------------------------------------------------------------------
  5633. // Key Usage Restriction Extension Encode (ASN1 X509)
  5634. //--------------------------------------------------------------------------
  5635. BOOL WINAPI Asn1X509KeyUsageRestrictionEncodeEx(
  5636. IN DWORD dwCertEncodingType,
  5637. IN LPCSTR lpszStructType,
  5638. IN PCERT_KEY_USAGE_RESTRICTION_INFO pInfo,
  5639. IN DWORD dwFlags,
  5640. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  5641. OUT OPTIONAL void *pvEncoded,
  5642. IN OUT DWORD *pcbEncoded
  5643. )
  5644. {
  5645. BOOL fResult;
  5646. DWORD cPolicyId;
  5647. KeyUsageRestriction Asn1KeyUsageRestriction;
  5648. memset(&Asn1KeyUsageRestriction, 0, sizeof(Asn1KeyUsageRestriction));
  5649. cPolicyId = pInfo->cCertPolicyId;
  5650. if (cPolicyId) {
  5651. PCERT_POLICY_ID pPolicyId = pInfo->rgCertPolicyId;
  5652. CertPolicyId *pAsn1PolicyId =
  5653. (CertPolicyId *) PkiZeroAlloc(cPolicyId * sizeof(CertPolicyId));
  5654. if (pAsn1PolicyId == NULL) goto ErrorReturn;
  5655. Asn1KeyUsageRestriction.certPolicySet.count = cPolicyId;
  5656. Asn1KeyUsageRestriction.certPolicySet.value = pAsn1PolicyId;
  5657. for ( ; cPolicyId > 0; cPolicyId--, pPolicyId++, pAsn1PolicyId++) {
  5658. DWORD cElement = pPolicyId->cCertPolicyElementId;
  5659. if (cElement > 0) {
  5660. LPSTR *ppszElement = pPolicyId->rgpszCertPolicyElementId;
  5661. EncodedObjectID *pAsn1Element =
  5662. (EncodedObjectID *) PkiZeroAlloc(cElement * sizeof(EncodedObjectID));
  5663. if (pAsn1Element == NULL) goto ErrorReturn;
  5664. pAsn1PolicyId->count = cElement;
  5665. pAsn1PolicyId->value = pAsn1Element;
  5666. for ( ; cElement > 0; cElement--, ppszElement++, pAsn1Element++)
  5667. if (!Asn1X509SetEncodedObjId(*ppszElement, pAsn1Element))
  5668. goto ErrorReturn;
  5669. }
  5670. }
  5671. Asn1KeyUsageRestriction.bit_mask |= certPolicySet_present;
  5672. }
  5673. if (pInfo->RestrictedKeyUsage.cbData) {
  5674. Asn1X509SetBitWithoutTrailingZeroes(&pInfo->RestrictedKeyUsage,
  5675. &Asn1KeyUsageRestriction.restrictedKeyUsage);
  5676. Asn1KeyUsageRestriction.bit_mask |= restrictedKeyUsage_present;
  5677. }
  5678. fResult = Asn1InfoEncodeEx(
  5679. KeyUsageRestriction_PDU,
  5680. &Asn1KeyUsageRestriction,
  5681. dwFlags,
  5682. pEncodePara,
  5683. pvEncoded,
  5684. pcbEncoded
  5685. );
  5686. goto CommonReturn;
  5687. ErrorReturn:
  5688. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  5689. *((void **) pvEncoded) = NULL;
  5690. *pcbEncoded = 0;
  5691. fResult = FALSE;
  5692. CommonReturn:
  5693. if (Asn1KeyUsageRestriction.certPolicySet.value) {
  5694. cPolicyId = Asn1KeyUsageRestriction.certPolicySet.count;
  5695. CertPolicyId *pAsn1PolicyId = Asn1KeyUsageRestriction.certPolicySet.value;
  5696. for ( ; cPolicyId > 0; cPolicyId--, pAsn1PolicyId++)
  5697. if (pAsn1PolicyId->value)
  5698. PkiFree(pAsn1PolicyId->value);
  5699. PkiFree(Asn1KeyUsageRestriction.certPolicySet.value);
  5700. }
  5701. return fResult;
  5702. }
  5703. //+-------------------------------------------------------------------------
  5704. // Key Usage Restriction Extension Decode (ASN1 X509)
  5705. //--------------------------------------------------------------------------
  5706. BOOL WINAPI Asn1X509KeyUsageRestrictionDecodeExCallback(
  5707. IN void *pvAsn1Info,
  5708. IN DWORD dwFlags,
  5709. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  5710. OUT OPTIONAL void *pvStructInfo,
  5711. IN OUT LONG *plRemainExtra
  5712. )
  5713. {
  5714. KeyUsageRestriction *pKeyUsageRestriction =
  5715. (KeyUsageRestriction *) pvAsn1Info;
  5716. PCERT_KEY_USAGE_RESTRICTION_INFO pInfo =
  5717. (PCERT_KEY_USAGE_RESTRICTION_INFO) pvStructInfo;
  5718. LONG lRemainExtra = *plRemainExtra;
  5719. BYTE *pbExtra;
  5720. lRemainExtra -= sizeof(CERT_KEY_USAGE_RESTRICTION_INFO);
  5721. if (lRemainExtra < 0) {
  5722. pbExtra = NULL;
  5723. } else {
  5724. // Default all optional fields to zero
  5725. memset(pInfo, 0, sizeof(CERT_KEY_USAGE_RESTRICTION_INFO));
  5726. pbExtra = (BYTE *) pInfo + sizeof(CERT_KEY_USAGE_RESTRICTION_INFO);
  5727. }
  5728. if (pKeyUsageRestriction->bit_mask & certPolicySet_present) {
  5729. LONG lAlignExtra;
  5730. DWORD cPolicyId;
  5731. PCERT_POLICY_ID pPolicyId;
  5732. CertPolicyId *pAsn1PolicyId;
  5733. cPolicyId = pKeyUsageRestriction->certPolicySet.count;
  5734. lAlignExtra = INFO_LEN_ALIGN(cPolicyId * sizeof(CERT_POLICY_ID));
  5735. lRemainExtra -= lAlignExtra;
  5736. if (lRemainExtra >= 0) {
  5737. pInfo->cCertPolicyId = cPolicyId;
  5738. pPolicyId = (PCERT_POLICY_ID) pbExtra;
  5739. pInfo->rgCertPolicyId = pPolicyId;
  5740. pbExtra += lAlignExtra;
  5741. } else
  5742. pPolicyId = NULL;
  5743. pAsn1PolicyId = pKeyUsageRestriction->certPolicySet.value;
  5744. for ( ; cPolicyId > 0; cPolicyId--, pPolicyId++, pAsn1PolicyId++) {
  5745. DWORD cElement;
  5746. LPSTR *ppszElement;
  5747. EncodedObjectID *pAsn1Element;
  5748. cElement = pAsn1PolicyId->count;
  5749. lAlignExtra = INFO_LEN_ALIGN(cElement * sizeof(LPSTR *));
  5750. lRemainExtra -= lAlignExtra;
  5751. if (lRemainExtra >= 0) {
  5752. pPolicyId->cCertPolicyElementId = cElement;
  5753. ppszElement = (LPSTR *) pbExtra;
  5754. pPolicyId->rgpszCertPolicyElementId = ppszElement;
  5755. pbExtra += lAlignExtra;
  5756. } else
  5757. ppszElement = NULL;
  5758. pAsn1Element = pAsn1PolicyId->value;
  5759. for ( ; cElement > 0; cElement--, ppszElement++, pAsn1Element++)
  5760. Asn1X509GetEncodedObjId(pAsn1Element, dwFlags,
  5761. ppszElement, &pbExtra, &lRemainExtra);
  5762. }
  5763. }
  5764. if (pKeyUsageRestriction->bit_mask & restrictedKeyUsage_present)
  5765. Asn1X509GetBit(&pKeyUsageRestriction->restrictedKeyUsage, dwFlags,
  5766. &pInfo->RestrictedKeyUsage, &pbExtra, &lRemainExtra);
  5767. *plRemainExtra = lRemainExtra;
  5768. return TRUE;
  5769. }
  5770. BOOL WINAPI Asn1X509KeyUsageRestrictionDecodeEx(
  5771. IN DWORD dwCertEncodingType,
  5772. IN LPCSTR lpszStructType,
  5773. IN const BYTE *pbEncoded,
  5774. IN DWORD cbEncoded,
  5775. IN DWORD dwFlags,
  5776. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  5777. OUT OPTIONAL void *pvStructInfo,
  5778. IN OUT DWORD *pcbStructInfo
  5779. )
  5780. {
  5781. return Asn1InfoDecodeAndAllocEx(
  5782. KeyUsageRestriction_PDU,
  5783. pbEncoded,
  5784. cbEncoded,
  5785. dwFlags,
  5786. pDecodePara,
  5787. Asn1X509KeyUsageRestrictionDecodeExCallback,
  5788. pvStructInfo,
  5789. pcbStructInfo
  5790. );
  5791. }
  5792. //+-------------------------------------------------------------------------
  5793. // Basic Constraints Extension Encode (ASN1 X509)
  5794. //--------------------------------------------------------------------------
  5795. BOOL WINAPI Asn1X509BasicConstraintsEncodeEx(
  5796. IN DWORD dwCertEncodingType,
  5797. IN LPCSTR lpszStructType,
  5798. IN PCERT_BASIC_CONSTRAINTS_INFO pInfo,
  5799. IN DWORD dwFlags,
  5800. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  5801. OUT OPTIONAL void *pvEncoded,
  5802. IN OUT DWORD *pcbEncoded
  5803. )
  5804. {
  5805. BOOL fResult;
  5806. DWORD cSubtrees;
  5807. BasicConstraints Asn1BasicConstraints;
  5808. memset(&Asn1BasicConstraints, 0, sizeof(Asn1BasicConstraints));
  5809. Asn1X509SetBitWithoutTrailingZeroes(&pInfo->SubjectType,
  5810. &Asn1BasicConstraints.subjectType);
  5811. if (pInfo->fPathLenConstraint) {
  5812. #ifdef OSS_CRYPT_ASN1
  5813. Asn1BasicConstraints.BasicConstraints_pathLenConstraint =
  5814. #else
  5815. Asn1BasicConstraints.pathLenConstraint =
  5816. #endif // OSS_CRYPT_ASN1
  5817. pInfo->dwPathLenConstraint;
  5818. Asn1BasicConstraints.bit_mask |=
  5819. BasicConstraints_pathLenConstraint_present;
  5820. }
  5821. cSubtrees = pInfo->cSubtreesConstraint;
  5822. if (cSubtrees) {
  5823. PCERT_NAME_BLOB pSubtrees = pInfo->rgSubtreesConstraint;
  5824. NOCOPYANY *pAsn1Subtrees =
  5825. (NOCOPYANY *) PkiZeroAlloc(
  5826. cSubtrees * sizeof(NOCOPYANY));
  5827. if (pAsn1Subtrees == NULL) goto ErrorReturn;
  5828. Asn1BasicConstraints.subtreesConstraint.count = cSubtrees;
  5829. Asn1BasicConstraints.subtreesConstraint.value = pAsn1Subtrees;
  5830. for ( ; cSubtrees > 0; cSubtrees--, pSubtrees++, pAsn1Subtrees++)
  5831. Asn1X509SetAny(pSubtrees, pAsn1Subtrees);
  5832. Asn1BasicConstraints.bit_mask |= subtreesConstraint_present;
  5833. }
  5834. fResult = Asn1InfoEncodeEx(
  5835. BasicConstraints_PDU,
  5836. &Asn1BasicConstraints,
  5837. dwFlags,
  5838. pEncodePara,
  5839. pvEncoded,
  5840. pcbEncoded
  5841. );
  5842. goto CommonReturn;
  5843. ErrorReturn:
  5844. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  5845. *((void **) pvEncoded) = NULL;
  5846. *pcbEncoded = 0;
  5847. fResult = FALSE;
  5848. CommonReturn:
  5849. if (Asn1BasicConstraints.subtreesConstraint.value)
  5850. PkiFree(Asn1BasicConstraints.subtreesConstraint.value);
  5851. return fResult;
  5852. }
  5853. //+-------------------------------------------------------------------------
  5854. // Basic Constraints Extension Decode (ASN1 X509)
  5855. //--------------------------------------------------------------------------
  5856. BOOL WINAPI Asn1X509BasicConstraintsDecodeExCallback(
  5857. IN void *pvAsn1Info,
  5858. IN DWORD dwFlags,
  5859. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  5860. OUT OPTIONAL void *pvStructInfo,
  5861. IN OUT LONG *plRemainExtra
  5862. )
  5863. {
  5864. BasicConstraints *pBasicConstraints = (BasicConstraints *) pvAsn1Info;
  5865. PCERT_BASIC_CONSTRAINTS_INFO pInfo =
  5866. (PCERT_BASIC_CONSTRAINTS_INFO) pvStructInfo;
  5867. LONG lRemainExtra = *plRemainExtra;
  5868. BYTE *pbExtra;
  5869. lRemainExtra -= sizeof(CERT_BASIC_CONSTRAINTS_INFO);
  5870. if (lRemainExtra < 0) {
  5871. pbExtra = NULL;
  5872. } else {
  5873. // Default all optional fields to zero
  5874. memset(pInfo, 0, sizeof(CERT_BASIC_CONSTRAINTS_INFO));
  5875. // Update fields not needing extra memory after the
  5876. // CERT_BASIC_CONSTRAINTS_INFO
  5877. if (pBasicConstraints->bit_mask &
  5878. BasicConstraints_pathLenConstraint_present) {
  5879. pInfo->fPathLenConstraint = TRUE;
  5880. pInfo->dwPathLenConstraint =
  5881. #ifdef OSS_CRYPT_ASN1
  5882. pBasicConstraints->BasicConstraints_pathLenConstraint;
  5883. #else
  5884. pBasicConstraints->pathLenConstraint;
  5885. #endif // OSS_CRYPT_ASN1
  5886. }
  5887. pbExtra = (BYTE *) pInfo + sizeof(CERT_BASIC_CONSTRAINTS_INFO);
  5888. }
  5889. Asn1X509GetBit(&pBasicConstraints->subjectType, dwFlags,
  5890. &pInfo->SubjectType, &pbExtra, &lRemainExtra);
  5891. if (pBasicConstraints->bit_mask & subtreesConstraint_present) {
  5892. LONG lAlignExtra;
  5893. DWORD cSubtrees;
  5894. PCERT_NAME_BLOB pSubtrees;
  5895. NOCOPYANY *pAsn1Subtrees;
  5896. cSubtrees = pBasicConstraints->subtreesConstraint.count;
  5897. lAlignExtra = INFO_LEN_ALIGN(cSubtrees * sizeof(CERT_NAME_BLOB));
  5898. lRemainExtra -= lAlignExtra;
  5899. if (lRemainExtra >= 0) {
  5900. pInfo->cSubtreesConstraint = cSubtrees;
  5901. pSubtrees = (PCERT_NAME_BLOB) pbExtra;
  5902. pInfo->rgSubtreesConstraint = pSubtrees;
  5903. pbExtra += lAlignExtra;
  5904. } else
  5905. pSubtrees = NULL;
  5906. pAsn1Subtrees = pBasicConstraints->subtreesConstraint.value;
  5907. for ( ; cSubtrees > 0; cSubtrees--, pSubtrees++, pAsn1Subtrees++)
  5908. Asn1X509GetAny(pAsn1Subtrees, dwFlags,
  5909. pSubtrees, &pbExtra, &lRemainExtra);
  5910. }
  5911. *plRemainExtra = lRemainExtra;
  5912. return TRUE;
  5913. }
  5914. BOOL WINAPI Asn1X509BasicConstraintsDecodeEx(
  5915. IN DWORD dwCertEncodingType,
  5916. IN LPCSTR lpszStructType,
  5917. IN const BYTE *pbEncoded,
  5918. IN DWORD cbEncoded,
  5919. IN DWORD dwFlags,
  5920. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  5921. OUT OPTIONAL void *pvStructInfo,
  5922. IN OUT DWORD *pcbStructInfo
  5923. )
  5924. {
  5925. return Asn1InfoDecodeAndAllocEx(
  5926. BasicConstraints_PDU,
  5927. pbEncoded,
  5928. cbEncoded,
  5929. dwFlags,
  5930. pDecodePara,
  5931. Asn1X509BasicConstraintsDecodeExCallback,
  5932. pvStructInfo,
  5933. pcbStructInfo
  5934. );
  5935. }
  5936. //+-------------------------------------------------------------------------
  5937. // Basic Constraints #2 Extension Encode (ASN1 X509)
  5938. //--------------------------------------------------------------------------
  5939. BOOL WINAPI Asn1X509BasicConstraints2EncodeEx(
  5940. IN DWORD dwCertEncodingType,
  5941. IN LPCSTR lpszStructType,
  5942. IN PCERT_BASIC_CONSTRAINTS2_INFO pInfo,
  5943. IN DWORD dwFlags,
  5944. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  5945. OUT OPTIONAL void *pvEncoded,
  5946. IN OUT DWORD *pcbEncoded
  5947. )
  5948. {
  5949. BasicConstraints2 Asn1Info;
  5950. memset(&Asn1Info, 0, sizeof(Asn1Info));
  5951. if (pInfo->fCA) {
  5952. Asn1Info.cA = TRUE;
  5953. Asn1Info.bit_mask |= cA_present;
  5954. }
  5955. if (pInfo->fPathLenConstraint) {
  5956. #ifdef OSS_CRYPT_ASN1
  5957. Asn1Info.BasicConstraints2_pathLenConstraint =
  5958. #else
  5959. Asn1Info.pathLenConstraint =
  5960. #endif // OSS_CRYPT_ASN1
  5961. pInfo->dwPathLenConstraint;
  5962. Asn1Info.bit_mask |= BasicConstraints2_pathLenConstraint_present;
  5963. }
  5964. return Asn1InfoEncodeEx(
  5965. BasicConstraints2_PDU,
  5966. &Asn1Info,
  5967. dwFlags,
  5968. pEncodePara,
  5969. pvEncoded,
  5970. pcbEncoded
  5971. );
  5972. }
  5973. //+-------------------------------------------------------------------------
  5974. // Basic Constraints #2 Extension Decode (ASN1 X509)
  5975. //--------------------------------------------------------------------------
  5976. BOOL WINAPI Asn1X509BasicConstraints2DecodeExCallback(
  5977. IN void *pvAsn1Info,
  5978. IN DWORD dwFlags,
  5979. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  5980. OUT OPTIONAL void *pvStructInfo,
  5981. IN OUT LONG *plRemainExtra
  5982. )
  5983. {
  5984. BasicConstraints2 *pAsn1Info = (BasicConstraints2 *) pvAsn1Info;
  5985. PCERT_BASIC_CONSTRAINTS2_INFO pInfo =
  5986. (PCERT_BASIC_CONSTRAINTS2_INFO) pvStructInfo;
  5987. *plRemainExtra -= sizeof(CERT_BASIC_CONSTRAINTS2_INFO);
  5988. if (*plRemainExtra >= 0) {
  5989. memset(pInfo, 0, sizeof(CERT_BASIC_CONSTRAINTS2_INFO));
  5990. if (pAsn1Info->bit_mask & cA_present)
  5991. pInfo->fCA = (BOOLEAN) pAsn1Info->cA;
  5992. if (pAsn1Info->bit_mask &
  5993. BasicConstraints2_pathLenConstraint_present) {
  5994. pInfo->fPathLenConstraint = TRUE;
  5995. pInfo->dwPathLenConstraint =
  5996. #ifdef OSS_CRYPT_ASN1
  5997. pAsn1Info->BasicConstraints2_pathLenConstraint;
  5998. #else
  5999. pAsn1Info->pathLenConstraint;
  6000. #endif // OSS_CRYPT_ASN1
  6001. }
  6002. }
  6003. return TRUE;
  6004. }
  6005. BOOL WINAPI Asn1X509BasicConstraints2DecodeEx(
  6006. IN DWORD dwCertEncodingType,
  6007. IN LPCSTR lpszStructType,
  6008. IN const BYTE *pbEncoded,
  6009. IN DWORD cbEncoded,
  6010. IN DWORD dwFlags,
  6011. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  6012. OUT OPTIONAL void *pvStructInfo,
  6013. IN OUT DWORD *pcbStructInfo
  6014. )
  6015. {
  6016. return Asn1InfoDecodeAndAllocEx(
  6017. BasicConstraints2_PDU,
  6018. pbEncoded,
  6019. cbEncoded,
  6020. dwFlags,
  6021. pDecodePara,
  6022. Asn1X509BasicConstraints2DecodeExCallback,
  6023. pvStructInfo,
  6024. pcbStructInfo
  6025. );
  6026. }
  6027. //+-------------------------------------------------------------------------
  6028. // Bits Extension Encode (ASN1 X509)
  6029. //--------------------------------------------------------------------------
  6030. BOOL WINAPI Asn1X509BitsEncodeEx(
  6031. IN DWORD dwCertEncodingType,
  6032. IN LPCSTR lpszStructType,
  6033. IN PCRYPT_BIT_BLOB pInfo,
  6034. IN DWORD dwFlags,
  6035. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  6036. OUT OPTIONAL void *pvEncoded,
  6037. IN OUT DWORD *pcbEncoded
  6038. )
  6039. {
  6040. BITSTRING Asn1Info;
  6041. Asn1X509SetBit(pInfo, &Asn1Info);
  6042. return Asn1InfoEncodeEx(
  6043. Bits_PDU,
  6044. &Asn1Info,
  6045. dwFlags,
  6046. pEncodePara,
  6047. pvEncoded,
  6048. pcbEncoded
  6049. );
  6050. }
  6051. //+-------------------------------------------------------------------------
  6052. // Bits Extension Decode (ASN1 X509)
  6053. //--------------------------------------------------------------------------
  6054. BOOL WINAPI Asn1X509BitsDecodeExCallback(
  6055. IN void *pvAsn1Info,
  6056. IN DWORD dwFlags,
  6057. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  6058. OUT OPTIONAL void *pvStructInfo,
  6059. IN OUT LONG *plRemainExtra
  6060. )
  6061. {
  6062. BITSTRING *pAsn1Info = (BITSTRING *) pvAsn1Info;
  6063. PCRYPT_BIT_BLOB pInfo = (PCRYPT_BIT_BLOB) pvStructInfo;
  6064. LONG lRemainExtra = *plRemainExtra;
  6065. BYTE *pbExtra;
  6066. lRemainExtra -= sizeof(CRYPT_BIT_BLOB);
  6067. if (lRemainExtra < 0) {
  6068. pbExtra = NULL;
  6069. } else
  6070. pbExtra = (BYTE *) pInfo + sizeof(CRYPT_BIT_BLOB);
  6071. Asn1X509GetBit(pAsn1Info, dwFlags, pInfo, &pbExtra, &lRemainExtra);
  6072. *plRemainExtra = lRemainExtra;
  6073. return TRUE;
  6074. }
  6075. BOOL WINAPI Asn1X509BitsDecodeEx(
  6076. IN DWORD dwCertEncodingType,
  6077. IN LPCSTR lpszStructType,
  6078. IN const BYTE *pbEncoded,
  6079. IN DWORD cbEncoded,
  6080. IN DWORD dwFlags,
  6081. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  6082. OUT OPTIONAL void *pvStructInfo,
  6083. IN OUT DWORD *pcbStructInfo
  6084. )
  6085. {
  6086. return Asn1InfoDecodeAndAllocEx(
  6087. Bits_PDU,
  6088. pbEncoded,
  6089. cbEncoded,
  6090. dwFlags,
  6091. pDecodePara,
  6092. Asn1X509BitsDecodeExCallback,
  6093. pvStructInfo,
  6094. pcbStructInfo
  6095. );
  6096. }
  6097. //+-------------------------------------------------------------------------
  6098. // Bits Without Trailing Zeroes Extension Encode (ASN1 X509)
  6099. //--------------------------------------------------------------------------
  6100. BOOL WINAPI Asn1X509BitsWithoutTrailingZeroesEncodeEx(
  6101. IN DWORD dwCertEncodingType,
  6102. IN LPCSTR lpszStructType,
  6103. IN PCRYPT_BIT_BLOB pInfo,
  6104. IN DWORD dwFlags,
  6105. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  6106. OUT OPTIONAL void *pvEncoded,
  6107. IN OUT DWORD *pcbEncoded
  6108. )
  6109. {
  6110. BITSTRING Asn1Info;
  6111. Asn1X509SetBitWithoutTrailingZeroes(pInfo, &Asn1Info);
  6112. return Asn1InfoEncodeEx(
  6113. Bits_PDU,
  6114. &Asn1Info,
  6115. dwFlags,
  6116. pEncodePara,
  6117. pvEncoded,
  6118. pcbEncoded
  6119. );
  6120. }
  6121. //+-------------------------------------------------------------------------
  6122. // Certificate Policies Extension Encode (ASN1 X509)
  6123. //--------------------------------------------------------------------------
  6124. BOOL WINAPI Asn1X509CertPoliciesEncodeEx(
  6125. IN DWORD dwCertEncodingType,
  6126. IN LPCSTR lpszStructType,
  6127. IN PCERT_POLICIES_INFO pInfo,
  6128. IN DWORD dwFlags,
  6129. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  6130. OUT OPTIONAL void *pvEncoded,
  6131. IN OUT DWORD *pcbEncoded
  6132. )
  6133. {
  6134. BOOL fResult;
  6135. DWORD cPolicyInfo;
  6136. CertificatePolicies Asn1Info;
  6137. memset(&Asn1Info, 0, sizeof(Asn1Info));
  6138. cPolicyInfo = pInfo->cPolicyInfo;
  6139. if (cPolicyInfo) {
  6140. PCERT_POLICY_INFO pPolicyInfo = pInfo->rgPolicyInfo;
  6141. PolicyInformation *pAsn1PolicyInfo =
  6142. (PolicyInformation *) PkiZeroAlloc(
  6143. cPolicyInfo * sizeof(PolicyInformation));
  6144. if (pAsn1PolicyInfo == NULL) goto ErrorReturn;
  6145. Asn1Info.count = cPolicyInfo;
  6146. Asn1Info.value = pAsn1PolicyInfo;
  6147. for ( ; cPolicyInfo > 0;
  6148. cPolicyInfo--, pPolicyInfo++, pAsn1PolicyInfo++) {
  6149. DWORD cQualifier = pPolicyInfo->cPolicyQualifier;
  6150. if (!Asn1X509SetEncodedObjId(pPolicyInfo->pszPolicyIdentifier,
  6151. &pAsn1PolicyInfo->policyIdentifier))
  6152. goto ErrorReturn;
  6153. if (cQualifier > 0) {
  6154. PCERT_POLICY_QUALIFIER_INFO pQualifier =
  6155. pPolicyInfo->rgPolicyQualifier;
  6156. PolicyQualifierInfo *pAsn1Qualifier =
  6157. (PolicyQualifierInfo *) PkiZeroAlloc(
  6158. cQualifier * sizeof(PolicyQualifierInfo));
  6159. if (pAsn1Qualifier == NULL) goto ErrorReturn;
  6160. pAsn1PolicyInfo->policyQualifiers.count = cQualifier;
  6161. pAsn1PolicyInfo->policyQualifiers.value = pAsn1Qualifier;
  6162. pAsn1PolicyInfo->bit_mask |= policyQualifiers_present;
  6163. for ( ; cQualifier > 0;
  6164. cQualifier--, pQualifier++, pAsn1Qualifier++) {
  6165. if (!Asn1X509SetEncodedObjId(pQualifier->pszPolicyQualifierId,
  6166. &pAsn1Qualifier->policyQualifierId))
  6167. goto ErrorReturn;
  6168. if (pQualifier->Qualifier.cbData) {
  6169. Asn1X509SetAny(&pQualifier->Qualifier,
  6170. &pAsn1Qualifier->qualifier);
  6171. pAsn1Qualifier->bit_mask |= qualifier_present;
  6172. }
  6173. }
  6174. }
  6175. }
  6176. }
  6177. fResult = Asn1InfoEncodeEx(
  6178. CertificatePolicies_PDU,
  6179. &Asn1Info,
  6180. dwFlags,
  6181. pEncodePara,
  6182. pvEncoded,
  6183. pcbEncoded
  6184. );
  6185. goto CommonReturn;
  6186. ErrorReturn:
  6187. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  6188. *((void **) pvEncoded) = NULL;
  6189. *pcbEncoded = 0;
  6190. fResult = FALSE;
  6191. CommonReturn:
  6192. if (Asn1Info.value) {
  6193. cPolicyInfo = Asn1Info.count;
  6194. PolicyInformation *pAsn1PolicyInfo = Asn1Info.value;
  6195. for ( ; cPolicyInfo > 0; cPolicyInfo--, pAsn1PolicyInfo++)
  6196. if (pAsn1PolicyInfo->policyQualifiers.value)
  6197. PkiFree(pAsn1PolicyInfo->policyQualifiers.value);
  6198. PkiFree(Asn1Info.value);
  6199. }
  6200. return fResult;
  6201. }
  6202. //+-------------------------------------------------------------------------
  6203. // Certificate Policies Extension Decode (ASN1 X509)
  6204. //--------------------------------------------------------------------------
  6205. BOOL WINAPI Asn1X509CertPoliciesDecodeExCallback(
  6206. IN void *pvAsn1Info,
  6207. IN DWORD dwFlags,
  6208. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  6209. OUT OPTIONAL void *pvStructInfo,
  6210. IN OUT LONG *plRemainExtra
  6211. )
  6212. {
  6213. CertificatePolicies *pAsn1Info = (CertificatePolicies *) pvAsn1Info;
  6214. PCERT_POLICIES_INFO pInfo = (PCERT_POLICIES_INFO) pvStructInfo;
  6215. LONG lRemainExtra = *plRemainExtra;
  6216. BYTE *pbExtra;
  6217. DWORD cPolicyInfo;
  6218. lRemainExtra -= sizeof(CERT_POLICIES_INFO);
  6219. if (lRemainExtra < 0) {
  6220. pbExtra = NULL;
  6221. } else {
  6222. memset(pInfo, 0, sizeof(CERT_POLICIES_INFO));
  6223. pbExtra = (BYTE *) pInfo + sizeof(CERT_POLICIES_INFO);
  6224. }
  6225. cPolicyInfo = pAsn1Info->count;
  6226. if (cPolicyInfo) {
  6227. LONG lAlignExtra;
  6228. PCERT_POLICY_INFO pPolicyInfo;
  6229. PolicyInformation *pAsn1PolicyInfo;
  6230. lAlignExtra = INFO_LEN_ALIGN(cPolicyInfo * sizeof(CERT_POLICY_INFO));
  6231. lRemainExtra -= lAlignExtra;
  6232. if (lRemainExtra >= 0) {
  6233. pInfo->cPolicyInfo = cPolicyInfo;
  6234. pPolicyInfo = (PCERT_POLICY_INFO) pbExtra;
  6235. pInfo->rgPolicyInfo = pPolicyInfo;
  6236. memset(pPolicyInfo, 0, cPolicyInfo * sizeof(CERT_POLICY_INFO));
  6237. pbExtra += lAlignExtra;
  6238. } else
  6239. pPolicyInfo = NULL;
  6240. pAsn1PolicyInfo = pAsn1Info->value;
  6241. for ( ; cPolicyInfo > 0;
  6242. cPolicyInfo--, pPolicyInfo++, pAsn1PolicyInfo++) {
  6243. DWORD cQualifier;
  6244. // check to see if there is a policy identifier
  6245. if (pAsn1PolicyInfo->policyIdentifier.length != 0) {
  6246. Asn1X509GetEncodedObjId(&pAsn1PolicyInfo->policyIdentifier, dwFlags,
  6247. &pPolicyInfo->pszPolicyIdentifier, &pbExtra, &lRemainExtra);
  6248. }
  6249. else {
  6250. lAlignExtra = INFO_LEN_ALIGN(strlen("")+1);
  6251. lRemainExtra -= lAlignExtra;
  6252. if (lRemainExtra >= 0) {
  6253. pPolicyInfo->pszPolicyIdentifier = (LPSTR) pbExtra;
  6254. strcpy(pPolicyInfo->pszPolicyIdentifier, "");
  6255. pbExtra += lAlignExtra;
  6256. }
  6257. }
  6258. cQualifier = pAsn1PolicyInfo->bit_mask & policyQualifiers_present ?
  6259. pAsn1PolicyInfo->policyQualifiers.count : 0;
  6260. if (cQualifier > 0) {
  6261. PCERT_POLICY_QUALIFIER_INFO pQualifier;
  6262. PolicyQualifierInfo *pAsn1Qualifier;
  6263. lAlignExtra = INFO_LEN_ALIGN(cQualifier *
  6264. sizeof(CERT_POLICY_QUALIFIER_INFO));
  6265. lRemainExtra -= lAlignExtra;
  6266. if (lRemainExtra >= 0) {
  6267. pPolicyInfo->cPolicyQualifier = cQualifier;
  6268. pQualifier = (PCERT_POLICY_QUALIFIER_INFO) pbExtra;
  6269. pPolicyInfo->rgPolicyQualifier = pQualifier;
  6270. memset(pQualifier, 0,
  6271. cQualifier * sizeof(CERT_POLICY_QUALIFIER_INFO));
  6272. pbExtra += lAlignExtra;
  6273. } else
  6274. pQualifier = NULL;
  6275. pAsn1Qualifier = pAsn1PolicyInfo->policyQualifiers.value;
  6276. for ( ; cQualifier > 0;
  6277. cQualifier--, pQualifier++, pAsn1Qualifier++) {
  6278. Asn1X509GetEncodedObjId(&pAsn1Qualifier->policyQualifierId, dwFlags,
  6279. &pQualifier->pszPolicyQualifierId,
  6280. &pbExtra, &lRemainExtra);
  6281. if (pAsn1Qualifier->bit_mask & qualifier_present)
  6282. Asn1X509GetAny(&pAsn1Qualifier->qualifier, dwFlags,
  6283. &pQualifier->Qualifier, &pbExtra, &lRemainExtra);
  6284. }
  6285. }
  6286. }
  6287. }
  6288. *plRemainExtra = lRemainExtra;
  6289. return TRUE;
  6290. }
  6291. BOOL WINAPI Asn1X509CertPoliciesDecodeEx(
  6292. IN DWORD dwCertEncodingType,
  6293. IN LPCSTR lpszStructType,
  6294. IN const BYTE *pbEncoded,
  6295. IN DWORD cbEncoded,
  6296. IN DWORD dwFlags,
  6297. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  6298. OUT OPTIONAL void *pvStructInfo,
  6299. IN OUT DWORD *pcbStructInfo
  6300. )
  6301. {
  6302. BOOL fResult;
  6303. CertificatePolicies *pAsn1Info = NULL;
  6304. CertificatePolicies95 *pAsn1Info95 = NULL;
  6305. PolicyInformation *pPolicyInformation = NULL;
  6306. CertificatePolicies certificatePolicies;
  6307. DWORD i;
  6308. if (!Asn1InfoDecodeAndAlloc(
  6309. CertificatePolicies_PDU,
  6310. pbEncoded,
  6311. cbEncoded,
  6312. (void **) &pAsn1Info))
  6313. {
  6314. // try to decode it as the old style
  6315. if (!Asn1InfoDecodeAndAlloc(
  6316. CertificatePolicies95_PDU,
  6317. pbEncoded,
  6318. cbEncoded,
  6319. (void **) &pAsn1Info95))
  6320. goto ErrorReturn;
  6321. // that decode worked, so alloc some memory, fix up some pointers
  6322. // and role through the rest of the routine per usual
  6323. certificatePolicies.count = pAsn1Info95->count;
  6324. if (NULL == (pPolicyInformation =
  6325. (PolicyInformation *) PkiNonzeroAlloc(pAsn1Info95->count * sizeof(PolicyInformation))))
  6326. goto ErrorReturn;
  6327. certificatePolicies.value = pPolicyInformation;
  6328. for (i=0; i<pAsn1Info95->count; i++)
  6329. {
  6330. pPolicyInformation[i].bit_mask = policyQualifiers_present;
  6331. pPolicyInformation[i].policyIdentifier.length = 0;
  6332. pPolicyInformation[i].policyIdentifier.value = NULL;
  6333. pPolicyInformation[i].policyQualifiers.count = pAsn1Info95->value[i].count;
  6334. pPolicyInformation[i].policyQualifiers.value = pAsn1Info95->value[i].value;
  6335. }
  6336. pAsn1Info = &certificatePolicies;
  6337. }
  6338. fResult = PkiAsn1AllocStructInfoEx(
  6339. pAsn1Info,
  6340. dwFlags,
  6341. pDecodePara,
  6342. Asn1X509CertPoliciesDecodeExCallback,
  6343. pvStructInfo,
  6344. pcbStructInfo
  6345. );
  6346. CommonReturn:
  6347. if (pAsn1Info95)
  6348. {
  6349. if (pPolicyInformation)
  6350. PkiFree(pPolicyInformation);
  6351. Asn1InfoFree(CertificatePolicies95_PDU, pAsn1Info95);
  6352. }
  6353. else
  6354. {
  6355. Asn1InfoFree(CertificatePolicies_PDU, pAsn1Info);
  6356. }
  6357. return fResult;
  6358. ErrorReturn:
  6359. *pcbStructInfo = 0;
  6360. fResult = FALSE;
  6361. goto CommonReturn;
  6362. }
  6363. //+-------------------------------------------------------------------------
  6364. // Policy Information 95 - Qualifier 1 decode
  6365. //--------------------------------------------------------------------------
  6366. BOOL WINAPI Asn1X509CertPoliciesQualifier1DecodeExCallback(
  6367. IN void *pvAsn1Info,
  6368. IN DWORD dwFlags,
  6369. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  6370. OUT OPTIONAL void *pvStructInfo,
  6371. IN OUT LONG *plRemainExtra
  6372. )
  6373. {
  6374. VerisignQualifier1 *pAsn1Info = (VerisignQualifier1 *) pvAsn1Info;
  6375. PCERT_POLICY95_QUALIFIER1 pInfo =
  6376. (PCERT_POLICY95_QUALIFIER1) pvStructInfo;
  6377. LONG lRemainExtra = *plRemainExtra;
  6378. BYTE *pbExtra;
  6379. LONG lAlignExtra;
  6380. DWORD i;
  6381. lRemainExtra -= sizeof(CERT_POLICY95_QUALIFIER1);
  6382. if (lRemainExtra < 0) {
  6383. pbExtra = NULL;
  6384. } else {
  6385. memset(pInfo, 0, sizeof(CERT_POLICY95_QUALIFIER1));
  6386. pbExtra = (BYTE *) pInfo + sizeof(CERT_POLICY95_QUALIFIER1);
  6387. }
  6388. if (
  6389. #ifndef OSS_CRYPT_ASN1
  6390. 0 != (pAsn1Info->bit_mask & practicesReference_present) &&
  6391. #endif // OSS_CRYPT_ASN1
  6392. pAsn1Info->practicesReference != NULL)
  6393. {
  6394. lAlignExtra = INFO_LEN_ALIGN((strlen(pAsn1Info->practicesReference)+1) * 2);
  6395. lRemainExtra -= lAlignExtra;
  6396. if (lRemainExtra >= 0) {
  6397. pInfo->pszPracticesReference = (LPWSTR) pbExtra;
  6398. MultiByteToWideChar(CP_ACP,
  6399. 0,
  6400. pAsn1Info->practicesReference,
  6401. -1,
  6402. pInfo->pszPracticesReference,
  6403. lAlignExtra / 2); // character count
  6404. pbExtra += lAlignExtra;
  6405. }
  6406. }
  6407. else if (lRemainExtra >= 0)
  6408. {
  6409. pInfo->pszPracticesReference = NULL;
  6410. }
  6411. if (pAsn1Info->bit_mask & noticeId_present)
  6412. {
  6413. Asn1X509GetEncodedObjId(&pAsn1Info->noticeId, dwFlags,
  6414. &pInfo->pszNoticeIdentifier,
  6415. &pbExtra, &lRemainExtra);
  6416. }
  6417. else if (lRemainExtra >= 0)
  6418. {
  6419. pInfo->pszNoticeIdentifier = NULL;
  6420. }
  6421. if (pAsn1Info->bit_mask & nsiNoticeId_present)
  6422. {
  6423. Asn1X509GetEncodedObjId(&pAsn1Info->nsiNoticeId, dwFlags,
  6424. &pInfo->pszNSINoticeIdentifier,
  6425. &pbExtra, &lRemainExtra);
  6426. }
  6427. else if (lRemainExtra >= 0)
  6428. {
  6429. pInfo->pszNSINoticeIdentifier = NULL;
  6430. }
  6431. if (pAsn1Info->bit_mask & cpsURLs_present)
  6432. {
  6433. lAlignExtra = INFO_LEN_ALIGN(pAsn1Info->cpsURLs.count * sizeof(CPS_URLS));
  6434. lRemainExtra -= lAlignExtra;
  6435. if (lRemainExtra >= 0) {
  6436. pInfo->rgCPSURLs = (CPS_URLS *) pbExtra;
  6437. memset(pInfo->rgCPSURLs, 0, lAlignExtra);
  6438. pInfo->cCPSURLs = pAsn1Info->cpsURLs.count;
  6439. pbExtra += lAlignExtra;
  6440. }
  6441. for (i=0; i<pAsn1Info->cpsURLs.count; i++)
  6442. {
  6443. lAlignExtra = INFO_LEN_ALIGN((strlen(pAsn1Info->cpsURLs.value[i].url)+1) * 2);
  6444. lRemainExtra -= lAlignExtra;
  6445. if (lRemainExtra >= 0)
  6446. {
  6447. pInfo->rgCPSURLs[i].pszURL = (LPWSTR) pbExtra;
  6448. MultiByteToWideChar(CP_ACP,
  6449. 0,
  6450. pAsn1Info->cpsURLs.value[i].url,
  6451. -1,
  6452. pInfo->rgCPSURLs[i].pszURL,
  6453. lAlignExtra / 2); // character count
  6454. pbExtra += lAlignExtra;
  6455. }
  6456. if (pAsn1Info->cpsURLs.value[i].bit_mask & digestAlgorithmId_present)
  6457. {
  6458. lAlignExtra = INFO_LEN_ALIGN(sizeof(CRYPT_ALGORITHM_IDENTIFIER));
  6459. lRemainExtra -= lAlignExtra;
  6460. if (lRemainExtra >= 0)
  6461. {
  6462. pInfo->rgCPSURLs[i].pAlgorithm = (CRYPT_ALGORITHM_IDENTIFIER *) pbExtra;
  6463. memset(pInfo->rgCPSURLs[i].pAlgorithm, 0, lAlignExtra);
  6464. pbExtra += lAlignExtra;
  6465. }
  6466. Asn1X509GetAlgorithm(
  6467. &(pAsn1Info->cpsURLs.value[i].digestAlgorithmId),
  6468. dwFlags,
  6469. pInfo->rgCPSURLs[i].pAlgorithm,
  6470. &pbExtra,
  6471. &lRemainExtra);
  6472. }
  6473. else if (lRemainExtra >= 0)
  6474. {
  6475. pInfo->rgCPSURLs[i].pAlgorithm = NULL;
  6476. }
  6477. if (pAsn1Info->cpsURLs.value[i].bit_mask & digest_present)
  6478. {
  6479. lAlignExtra = INFO_LEN_ALIGN(sizeof(CRYPT_DATA_BLOB));
  6480. lRemainExtra -= lAlignExtra;
  6481. if (lRemainExtra >= 0)
  6482. {
  6483. pInfo->rgCPSURLs[i].pDigest = (CRYPT_DATA_BLOB *) pbExtra;
  6484. memset(pInfo->rgCPSURLs[i].pDigest, 0, lAlignExtra);
  6485. pbExtra += lAlignExtra;
  6486. }
  6487. Asn1X509GetOctetString(
  6488. &(pAsn1Info->cpsURLs.value[i].digest),
  6489. dwFlags,
  6490. pInfo->rgCPSURLs[i].pDigest,
  6491. &pbExtra,
  6492. &lRemainExtra);
  6493. }
  6494. else if (lRemainExtra >= 0)
  6495. {
  6496. pInfo->rgCPSURLs[i].pDigest = NULL;
  6497. }
  6498. }
  6499. }
  6500. else if (lRemainExtra >= 0)
  6501. {
  6502. pInfo->rgCPSURLs = NULL;
  6503. }
  6504. *plRemainExtra = lRemainExtra;
  6505. return TRUE;
  6506. }
  6507. BOOL WINAPI Asn1X509CertPoliciesQualifier1DecodeEx(
  6508. IN DWORD dwCertEncodingType,
  6509. IN LPCSTR lpszStructType,
  6510. IN const BYTE *pbEncoded,
  6511. IN DWORD cbEncoded,
  6512. IN DWORD dwFlags,
  6513. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  6514. OUT OPTIONAL void *pvStructInfo,
  6515. IN OUT DWORD *pcbStructInfo
  6516. )
  6517. {
  6518. return Asn1InfoDecodeAndAllocEx(
  6519. VerisignQualifier1_PDU,
  6520. pbEncoded,
  6521. cbEncoded,
  6522. dwFlags,
  6523. pDecodePara,
  6524. Asn1X509CertPoliciesQualifier1DecodeExCallback,
  6525. pvStructInfo,
  6526. pcbStructInfo
  6527. );
  6528. }
  6529. //+-------------------------------------------------------------------------
  6530. // Authority Information Access Extension Encode (ASN1 X509)
  6531. //--------------------------------------------------------------------------
  6532. BOOL WINAPI Asn1X509AuthorityInfoAccessEncodeEx(
  6533. IN DWORD dwCertEncodingType,
  6534. IN LPCSTR lpszStructType,
  6535. IN PCERT_AUTHORITY_INFO_ACCESS pInfo,
  6536. IN DWORD dwFlags,
  6537. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  6538. OUT OPTIONAL void *pvEncoded,
  6539. IN OUT DWORD *pcbEncoded
  6540. )
  6541. {
  6542. BOOL fResult;
  6543. AuthorityInfoAccess Asn1Info;
  6544. DWORD cAccDescr;
  6545. AccessDescription *pAsn1AccDescr;
  6546. DWORD dwErrLocation;
  6547. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  6548. *((void **) pvEncoded) = NULL;
  6549. memset(&Asn1Info, 0, sizeof(Asn1Info));
  6550. cAccDescr = pInfo->cAccDescr;
  6551. if (cAccDescr > 0) {
  6552. pAsn1AccDescr =
  6553. (AccessDescription *) PkiZeroAlloc(cAccDescr *
  6554. sizeof(AccessDescription));
  6555. if (pAsn1AccDescr == NULL)
  6556. goto ErrorReturn;
  6557. Asn1Info.count = cAccDescr;
  6558. Asn1Info.value = pAsn1AccDescr;
  6559. if (!Asn1X509SetAccessDescriptions(
  6560. cAccDescr,
  6561. pInfo->rgAccDescr,
  6562. pAsn1AccDescr,
  6563. &dwErrLocation))
  6564. goto AccessDescriptionsError;
  6565. } else
  6566. pAsn1AccDescr = NULL;
  6567. fResult = Asn1InfoEncodeEx(
  6568. AuthorityInfoAccess_PDU,
  6569. &Asn1Info,
  6570. dwFlags,
  6571. pEncodePara,
  6572. pvEncoded,
  6573. pcbEncoded
  6574. );
  6575. goto CommonReturn;
  6576. AccessDescriptionsError:
  6577. *pcbEncoded = dwErrLocation;
  6578. fResult = FALSE;
  6579. goto CommonReturn;
  6580. ErrorReturn:
  6581. *pcbEncoded = 0;
  6582. fResult = FALSE;
  6583. CommonReturn:
  6584. if (pAsn1AccDescr) {
  6585. Asn1X509FreeAccessDescriptions(cAccDescr, pAsn1AccDescr);
  6586. PkiFree(pAsn1AccDescr);
  6587. }
  6588. return fResult;
  6589. }
  6590. //+-------------------------------------------------------------------------
  6591. // Authority Information Access Extension Decode (ASN1 X509)
  6592. //--------------------------------------------------------------------------
  6593. BOOL WINAPI Asn1X509AuthorityInfoAccessDecodeExCallback(
  6594. IN void *pvAsn1Info,
  6595. IN DWORD dwFlags,
  6596. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  6597. OUT OPTIONAL void *pvStructInfo,
  6598. IN OUT LONG *plRemainExtra
  6599. )
  6600. {
  6601. BOOL fResult;
  6602. AuthorityInfoAccess *pAsn1 = (AuthorityInfoAccess *) pvAsn1Info;
  6603. PCERT_AUTHORITY_INFO_ACCESS pInfo =
  6604. (PCERT_AUTHORITY_INFO_ACCESS) pvStructInfo;
  6605. LONG lRemainExtra = *plRemainExtra;
  6606. BYTE *pbExtra;
  6607. LONG lAlignExtra;
  6608. DWORD cAccDescr;
  6609. PCERT_ACCESS_DESCRIPTION pAccDescr;
  6610. cAccDescr = pAsn1->count;
  6611. lAlignExtra = INFO_LEN_ALIGN(cAccDescr * sizeof(CERT_ACCESS_DESCRIPTION));
  6612. lRemainExtra -= sizeof(CERT_AUTHORITY_INFO_ACCESS) + lAlignExtra;
  6613. if (lRemainExtra < 0) {
  6614. pbExtra = NULL;
  6615. pAccDescr = NULL;
  6616. } else {
  6617. pbExtra = (BYTE *) pInfo + sizeof(CERT_AUTHORITY_INFO_ACCESS);
  6618. pAccDescr = (PCERT_ACCESS_DESCRIPTION) pbExtra;
  6619. pInfo->cAccDescr = cAccDescr;
  6620. pInfo->rgAccDescr = pAccDescr;
  6621. pbExtra += lAlignExtra;
  6622. }
  6623. if (!Asn1X509GetAccessDescriptions(
  6624. cAccDescr,
  6625. pAsn1->value,
  6626. dwFlags,
  6627. pAccDescr,
  6628. &pbExtra,
  6629. &lRemainExtra
  6630. )) goto ErrorReturn;
  6631. fResult = TRUE;
  6632. CommonReturn:
  6633. *plRemainExtra = lRemainExtra;
  6634. return fResult;
  6635. ErrorReturn:
  6636. fResult = FALSE;
  6637. goto CommonReturn;
  6638. }
  6639. BOOL WINAPI Asn1X509AuthorityInfoAccessDecodeEx(
  6640. IN DWORD dwCertEncodingType,
  6641. IN LPCSTR lpszStructType,
  6642. IN const BYTE *pbEncoded,
  6643. IN DWORD cbEncoded,
  6644. IN DWORD dwFlags,
  6645. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  6646. OUT OPTIONAL void *pvStructInfo,
  6647. IN OUT DWORD *pcbStructInfo
  6648. )
  6649. {
  6650. return Asn1InfoDecodeAndAllocEx(
  6651. AuthorityInfoAccess_PDU,
  6652. pbEncoded,
  6653. cbEncoded,
  6654. dwFlags,
  6655. pDecodePara,
  6656. Asn1X509AuthorityInfoAccessDecodeExCallback,
  6657. pvStructInfo,
  6658. pcbStructInfo
  6659. );
  6660. }
  6661. //+-------------------------------------------------------------------------
  6662. // CRL Distribution Points Encode (ASN1 X509)
  6663. //--------------------------------------------------------------------------
  6664. BOOL WINAPI Asn1X509CrlDistPointsEncodeEx(
  6665. IN DWORD dwCertEncodingType,
  6666. IN LPCSTR lpszStructType,
  6667. IN PCRL_DIST_POINTS_INFO pInfo,
  6668. IN DWORD dwFlags,
  6669. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  6670. OUT OPTIONAL void *pvEncoded,
  6671. IN OUT DWORD *pcbEncoded
  6672. )
  6673. {
  6674. BOOL fResult;
  6675. CRLDistributionPoints Asn1Info;
  6676. DistributionPoint *pAsn1DistPoint;
  6677. PCRL_DIST_POINT pDistPoint;
  6678. DWORD cDistPoint;
  6679. DWORD i;
  6680. DWORD dwErrLocation;
  6681. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  6682. *((void **) pvEncoded) = NULL;
  6683. memset(&Asn1Info, 0, sizeof(Asn1Info));
  6684. if (0 == (cDistPoint = pInfo->cDistPoint))
  6685. goto InvalidArg;
  6686. if (NULL == (pAsn1DistPoint = (DistributionPoint *) PkiZeroAlloc(
  6687. cDistPoint * sizeof(DistributionPoint))))
  6688. goto ErrorReturn;
  6689. Asn1Info.count = cDistPoint;
  6690. Asn1Info.value = pAsn1DistPoint;
  6691. pDistPoint = pInfo->rgDistPoint;
  6692. for (i = 0; i < cDistPoint; i++, pDistPoint++, pAsn1DistPoint++) {
  6693. PCRL_DIST_POINT_NAME pDistPointName =
  6694. &pDistPoint->DistPointName;
  6695. if (CRL_DIST_POINT_NO_NAME !=
  6696. pDistPointName->dwDistPointNameChoice) {
  6697. DistributionPointName *pAsn1DistPointName =
  6698. &pAsn1DistPoint->distributionPoint;
  6699. pAsn1DistPoint->bit_mask |= distributionPoint_present;
  6700. pAsn1DistPointName->choice = (unsigned short)
  6701. pDistPointName->dwDistPointNameChoice;
  6702. assert(fullName_chosen == CRL_DIST_POINT_FULL_NAME);
  6703. assert(nameRelativeToCRLIssuer_chosen ==
  6704. CRL_DIST_POINT_ISSUER_RDN_NAME);
  6705. switch (pDistPointName->dwDistPointNameChoice) {
  6706. case CRL_DIST_POINT_FULL_NAME:
  6707. if (!Asn1X509SetAltNames(
  6708. &pDistPointName->FullName,
  6709. &pAsn1DistPointName->u.fullName, i, &dwErrLocation))
  6710. goto AltNamesError;
  6711. break;
  6712. case CRL_DIST_POINT_ISSUER_RDN_NAME:
  6713. default:
  6714. goto InvalidArg;
  6715. }
  6716. }
  6717. if (pDistPoint->ReasonFlags.cbData) {
  6718. pAsn1DistPoint->bit_mask |= reasons_present;
  6719. Asn1X509SetBitWithoutTrailingZeroes(&pDistPoint->ReasonFlags,
  6720. &pAsn1DistPoint->reasons);
  6721. }
  6722. if (pDistPoint->CRLIssuer.cAltEntry) {
  6723. pAsn1DistPoint->bit_mask |= cRLIssuer_present;
  6724. if (!Asn1X509SetAltNames(
  6725. &pDistPoint->CRLIssuer,
  6726. &pAsn1DistPoint->cRLIssuer,
  6727. (CRL_DIST_POINT_ERR_CRL_ISSUER_BIT >> 24) | i,
  6728. &dwErrLocation))
  6729. goto AltNamesError;
  6730. }
  6731. }
  6732. fResult = Asn1InfoEncodeEx(
  6733. CRLDistributionPoints_PDU,
  6734. &Asn1Info,
  6735. dwFlags,
  6736. pEncodePara,
  6737. pvEncoded,
  6738. pcbEncoded
  6739. );
  6740. goto CommonReturn;
  6741. AltNamesError:
  6742. *pcbEncoded = dwErrLocation;
  6743. fResult = FALSE;
  6744. goto CommonReturn;
  6745. InvalidArg:
  6746. SetLastError((DWORD) E_INVALIDARG);
  6747. ErrorReturn:
  6748. *pcbEncoded = 0;
  6749. fResult = FALSE;
  6750. CommonReturn:
  6751. pAsn1DistPoint = Asn1Info.value;
  6752. if (pAsn1DistPoint) {
  6753. cDistPoint = Asn1Info.count;
  6754. pDistPoint = pInfo->rgDistPoint;
  6755. for ( ; cDistPoint > 0; cDistPoint--, pDistPoint++, pAsn1DistPoint++) {
  6756. DistributionPointName *pAsn1DistPointName =
  6757. &pAsn1DistPoint->distributionPoint;
  6758. switch (pAsn1DistPointName->choice) {
  6759. case CRL_DIST_POINT_FULL_NAME:
  6760. Asn1X509FreeAltNames(&pAsn1DistPointName->u.fullName);
  6761. break;
  6762. case CRL_DIST_POINT_ISSUER_RDN_NAME:
  6763. default:
  6764. break;
  6765. }
  6766. Asn1X509FreeAltNames(&pAsn1DistPoint->cRLIssuer);
  6767. }
  6768. PkiFree(Asn1Info.value);
  6769. }
  6770. return fResult;
  6771. }
  6772. //+-------------------------------------------------------------------------
  6773. // CRL Distribution Points Decode (ASN1 X509)
  6774. //--------------------------------------------------------------------------
  6775. BOOL WINAPI Asn1X509CrlDistPointsDecodeExCallback(
  6776. IN void *pvAsn1Info,
  6777. IN DWORD dwFlags,
  6778. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  6779. OUT OPTIONAL void *pvStructInfo,
  6780. IN OUT LONG *plRemainExtra
  6781. )
  6782. {
  6783. BOOL fResult;
  6784. CRLDistributionPoints *pAsn1 = (CRLDistributionPoints *) pvAsn1Info;
  6785. PCRL_DIST_POINTS_INFO pInfo = (PCRL_DIST_POINTS_INFO) pvStructInfo;
  6786. LONG lRemainExtra = *plRemainExtra;
  6787. BYTE *pbExtra;
  6788. LONG lAlignExtra;
  6789. lRemainExtra -= sizeof(CRL_DIST_POINTS_INFO);
  6790. if (lRemainExtra < 0) {
  6791. pbExtra = NULL;
  6792. } else {
  6793. memset(pInfo, 0, sizeof(CRL_DIST_POINTS_INFO));
  6794. pbExtra = (BYTE *) pInfo + sizeof(CRL_DIST_POINTS_INFO);
  6795. }
  6796. if (pAsn1->count) {
  6797. DWORD cDistPoint = pAsn1->count;
  6798. DistributionPoint *pAsn1DistPoint = pAsn1->value;
  6799. PCRL_DIST_POINT pDistPoint;
  6800. lAlignExtra = INFO_LEN_ALIGN(cDistPoint * sizeof(CRL_DIST_POINT));
  6801. lRemainExtra -= lAlignExtra;
  6802. if (lRemainExtra >= 0) {
  6803. pDistPoint = (PCRL_DIST_POINT) pbExtra;
  6804. memset(pDistPoint, 0, cDistPoint * sizeof(CRL_DIST_POINT));
  6805. pInfo->cDistPoint = cDistPoint;
  6806. pInfo->rgDistPoint = pDistPoint;
  6807. pbExtra += lAlignExtra;
  6808. } else
  6809. pDistPoint = NULL;
  6810. for ( ; cDistPoint > 0; cDistPoint--, pAsn1DistPoint++, pDistPoint++) {
  6811. if (pAsn1DistPoint->bit_mask & distributionPoint_present) {
  6812. DistributionPointName *pAsn1DistPointName =
  6813. &pAsn1DistPoint->distributionPoint;
  6814. DWORD dwDistPointNameChoice = pAsn1DistPointName->choice;
  6815. PCRL_DIST_POINT_NAME pDistPointName;
  6816. if (lRemainExtra >= 0) {
  6817. pDistPointName = &pDistPoint->DistPointName;
  6818. pDistPointName->dwDistPointNameChoice =
  6819. dwDistPointNameChoice;
  6820. } else
  6821. pDistPointName = NULL;
  6822. assert(fullName_chosen == CRL_DIST_POINT_FULL_NAME);
  6823. assert(nameRelativeToCRLIssuer_chosen ==
  6824. CRL_DIST_POINT_ISSUER_RDN_NAME);
  6825. switch (dwDistPointNameChoice) {
  6826. case CRL_DIST_POINT_FULL_NAME:
  6827. if (!Asn1X509GetAltNames(&pAsn1DistPointName->u.fullName,
  6828. dwFlags, &pDistPointName->FullName,
  6829. &pbExtra, &lRemainExtra))
  6830. goto ErrorReturn;
  6831. break;
  6832. case CRL_DIST_POINT_ISSUER_RDN_NAME:
  6833. break;
  6834. default:
  6835. SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
  6836. goto ErrorReturn;
  6837. }
  6838. }
  6839. if (pAsn1DistPoint->bit_mask & reasons_present)
  6840. Asn1X509GetBit(&pAsn1DistPoint->reasons, dwFlags,
  6841. &pDistPoint->ReasonFlags, &pbExtra, &lRemainExtra);
  6842. if (pAsn1DistPoint->bit_mask & cRLIssuer_present) {
  6843. if (!Asn1X509GetAltNames(&pAsn1DistPoint->cRLIssuer, dwFlags,
  6844. &pDistPoint->CRLIssuer, &pbExtra, &lRemainExtra))
  6845. goto ErrorReturn;
  6846. }
  6847. }
  6848. }
  6849. fResult = TRUE;
  6850. CommonReturn:
  6851. *plRemainExtra = lRemainExtra;
  6852. return fResult;
  6853. ErrorReturn:
  6854. fResult = FALSE;
  6855. goto CommonReturn;
  6856. }
  6857. BOOL WINAPI Asn1X509CrlDistPointsDecodeEx(
  6858. IN DWORD dwCertEncodingType,
  6859. IN LPCSTR lpszStructType,
  6860. IN const BYTE *pbEncoded,
  6861. IN DWORD cbEncoded,
  6862. IN DWORD dwFlags,
  6863. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  6864. OUT OPTIONAL void *pvStructInfo,
  6865. IN OUT DWORD *pcbStructInfo
  6866. )
  6867. {
  6868. return Asn1InfoDecodeAndAllocEx(
  6869. CRLDistributionPoints_PDU,
  6870. pbEncoded,
  6871. cbEncoded,
  6872. dwFlags,
  6873. pDecodePara,
  6874. Asn1X509CrlDistPointsDecodeExCallback,
  6875. pvStructInfo,
  6876. pcbStructInfo
  6877. );
  6878. }
  6879. //+-------------------------------------------------------------------------
  6880. // Integer Extension Encode (ASN1 X509)
  6881. //--------------------------------------------------------------------------
  6882. BOOL WINAPI Asn1X509IntegerEncodeEx(
  6883. IN DWORD dwCertEncodingType,
  6884. IN LPCSTR lpszStructType,
  6885. IN int *pInfo,
  6886. IN DWORD dwFlags,
  6887. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  6888. OUT OPTIONAL void *pvEncoded,
  6889. IN OUT DWORD *pcbEncoded
  6890. )
  6891. {
  6892. int Asn1Info = *pInfo;
  6893. return Asn1InfoEncodeEx(
  6894. IntegerType_PDU,
  6895. &Asn1Info,
  6896. dwFlags,
  6897. pEncodePara,
  6898. pvEncoded,
  6899. pcbEncoded
  6900. );
  6901. }
  6902. //+-------------------------------------------------------------------------
  6903. // Integer Extension Decode (ASN1 X509)
  6904. //--------------------------------------------------------------------------
  6905. BOOL WINAPI Asn1X509IntegerDecodeExCallback(
  6906. IN void *pvAsn1Info,
  6907. IN DWORD dwFlags,
  6908. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  6909. OUT OPTIONAL void *pvStructInfo,
  6910. IN OUT LONG *plRemainExtra
  6911. )
  6912. {
  6913. int *pAsn1Info = (int *) pvAsn1Info;
  6914. int *pInfo = (int *) pvStructInfo;
  6915. *plRemainExtra -= sizeof(int);
  6916. if (*plRemainExtra >= 0)
  6917. *pInfo = *pAsn1Info;
  6918. return TRUE;
  6919. }
  6920. BOOL WINAPI Asn1X509IntegerDecodeEx(
  6921. IN DWORD dwCertEncodingType,
  6922. IN LPCSTR lpszStructType,
  6923. IN const BYTE *pbEncoded,
  6924. IN DWORD cbEncoded,
  6925. IN DWORD dwFlags,
  6926. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  6927. OUT OPTIONAL void *pvStructInfo,
  6928. IN OUT DWORD *pcbStructInfo
  6929. )
  6930. {
  6931. return Asn1InfoDecodeAndAllocEx(
  6932. IntegerType_PDU,
  6933. pbEncoded,
  6934. cbEncoded,
  6935. dwFlags,
  6936. pDecodePara,
  6937. Asn1X509IntegerDecodeExCallback,
  6938. pvStructInfo,
  6939. pcbStructInfo
  6940. );
  6941. }
  6942. //+-------------------------------------------------------------------------
  6943. // MultiByte Integer Extension Encode (ASN1 X509)
  6944. //--------------------------------------------------------------------------
  6945. BOOL WINAPI Asn1X509MultiByteIntegerEncodeEx(
  6946. IN DWORD dwCertEncodingType,
  6947. IN LPCSTR lpszStructType,
  6948. IN PCRYPT_INTEGER_BLOB pInfo,
  6949. IN DWORD dwFlags,
  6950. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  6951. OUT OPTIONAL void *pvEncoded,
  6952. IN OUT DWORD *pcbEncoded
  6953. )
  6954. {
  6955. BOOL fResult;
  6956. HUGEINTEGER Asn1Info;
  6957. if (!Asn1X509SetHugeInteger(pInfo, &Asn1Info)) {
  6958. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  6959. *((void **) pvEncoded) = NULL;
  6960. *pcbEncoded = 0;
  6961. return FALSE;
  6962. }
  6963. fResult = Asn1InfoEncodeEx(
  6964. HugeIntegerType_PDU,
  6965. &Asn1Info,
  6966. dwFlags,
  6967. pEncodePara,
  6968. pvEncoded,
  6969. pcbEncoded
  6970. );
  6971. Asn1X509FreeHugeInteger(&Asn1Info);
  6972. return fResult;
  6973. }
  6974. //+-------------------------------------------------------------------------
  6975. // MultiByte Integer Extension Decode (ASN1 X509)
  6976. //--------------------------------------------------------------------------
  6977. BOOL WINAPI Asn1X509MultiByteIntegerDecodeExCallback(
  6978. IN void *pvAsn1Info,
  6979. IN DWORD dwFlags,
  6980. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  6981. OUT OPTIONAL void *pvStructInfo,
  6982. IN OUT LONG *plRemainExtra
  6983. )
  6984. {
  6985. HUGEINTEGER *pAsn1Info = (HUGEINTEGER *) pvAsn1Info;
  6986. PCRYPT_INTEGER_BLOB pInfo = (PCRYPT_INTEGER_BLOB) pvStructInfo;
  6987. LONG lRemainExtra = *plRemainExtra;
  6988. BYTE *pbExtra;
  6989. lRemainExtra -= sizeof(CRYPT_INTEGER_BLOB);
  6990. if (lRemainExtra < 0) {
  6991. pbExtra = NULL;
  6992. } else
  6993. pbExtra = (BYTE *) pInfo + sizeof(CRYPT_INTEGER_BLOB);
  6994. Asn1X509GetHugeInteger(pAsn1Info, dwFlags, pInfo, &pbExtra, &lRemainExtra);
  6995. *plRemainExtra = lRemainExtra;
  6996. return TRUE;
  6997. }
  6998. BOOL WINAPI Asn1X509MultiByteIntegerDecodeEx(
  6999. IN DWORD dwCertEncodingType,
  7000. IN LPCSTR lpszStructType,
  7001. IN const BYTE *pbEncoded,
  7002. IN DWORD cbEncoded,
  7003. IN DWORD dwFlags,
  7004. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  7005. OUT OPTIONAL void *pvStructInfo,
  7006. IN OUT DWORD *pcbStructInfo
  7007. )
  7008. {
  7009. return Asn1InfoDecodeAndAllocEx(
  7010. HugeIntegerType_PDU,
  7011. pbEncoded,
  7012. cbEncoded,
  7013. dwFlags,
  7014. pDecodePara,
  7015. Asn1X509MultiByteIntegerDecodeExCallback,
  7016. pvStructInfo,
  7017. pcbStructInfo
  7018. );
  7019. }
  7020. //+-------------------------------------------------------------------------
  7021. // MultiByte UINT Extension Encode (ASN1 X509)
  7022. //--------------------------------------------------------------------------
  7023. BOOL WINAPI Asn1X509MultiByteUINTEncodeEx(
  7024. IN DWORD dwCertEncodingType,
  7025. IN LPCSTR lpszStructType,
  7026. IN PCRYPT_UINT_BLOB pInfo,
  7027. IN DWORD dwFlags,
  7028. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  7029. OUT OPTIONAL void *pvEncoded,
  7030. IN OUT DWORD *pcbEncoded
  7031. )
  7032. {
  7033. BOOL fResult;
  7034. HUGEINTEGER Asn1Info;
  7035. if (!Asn1X509SetHugeUINT(pInfo, &Asn1Info)) {
  7036. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  7037. *((void **) pvEncoded) = NULL;
  7038. *pcbEncoded = 0;
  7039. return FALSE;
  7040. }
  7041. fResult = Asn1InfoEncodeEx(
  7042. HugeIntegerType_PDU,
  7043. &Asn1Info,
  7044. dwFlags,
  7045. pEncodePara,
  7046. pvEncoded,
  7047. pcbEncoded
  7048. );
  7049. Asn1X509FreeHugeUINT(&Asn1Info);
  7050. return fResult;
  7051. }
  7052. //+-------------------------------------------------------------------------
  7053. // MultiByte UINT Extension Decode (ASN1 X509)
  7054. //--------------------------------------------------------------------------
  7055. BOOL WINAPI Asn1X509MultiByteUINTDecodeExCallback(
  7056. IN void *pvAsn1Info,
  7057. IN DWORD dwFlags,
  7058. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  7059. OUT OPTIONAL void *pvStructInfo,
  7060. IN OUT LONG *plRemainExtra
  7061. )
  7062. {
  7063. HUGEINTEGER *pAsn1Info = (HUGEINTEGER *) pvAsn1Info;
  7064. PCRYPT_UINT_BLOB pInfo = (PCRYPT_UINT_BLOB) pvStructInfo;
  7065. LONG lRemainExtra = *plRemainExtra;
  7066. BYTE *pbExtra;
  7067. lRemainExtra -= sizeof(CRYPT_UINT_BLOB);
  7068. if (lRemainExtra < 0) {
  7069. pbExtra = NULL;
  7070. } else
  7071. pbExtra = (BYTE *) pInfo + sizeof(CRYPT_UINT_BLOB);
  7072. Asn1X509GetHugeUINT(pAsn1Info, dwFlags, pInfo, &pbExtra, &lRemainExtra);
  7073. *plRemainExtra = lRemainExtra;
  7074. return TRUE;
  7075. }
  7076. BOOL WINAPI Asn1X509MultiByteUINTDecodeEx(
  7077. IN DWORD dwCertEncodingType,
  7078. IN LPCSTR lpszStructType,
  7079. IN const BYTE *pbEncoded,
  7080. IN DWORD cbEncoded,
  7081. IN DWORD dwFlags,
  7082. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  7083. OUT OPTIONAL void *pvStructInfo,
  7084. IN OUT DWORD *pcbStructInfo
  7085. )
  7086. {
  7087. return Asn1InfoDecodeAndAllocEx(
  7088. HugeIntegerType_PDU,
  7089. pbEncoded,
  7090. cbEncoded,
  7091. dwFlags,
  7092. pDecodePara,
  7093. Asn1X509MultiByteUINTDecodeExCallback,
  7094. pvStructInfo,
  7095. pcbStructInfo
  7096. );
  7097. }
  7098. //+-------------------------------------------------------------------------
  7099. // DSS Parameters Encode (ASN1 X509)
  7100. //--------------------------------------------------------------------------
  7101. BOOL WINAPI Asn1X509DSSParametersEncodeEx(
  7102. IN DWORD dwCertEncodingType,
  7103. IN LPCSTR lpszStructType,
  7104. IN PCERT_DSS_PARAMETERS pInfo,
  7105. IN DWORD dwFlags,
  7106. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  7107. OUT OPTIONAL void *pvEncoded,
  7108. IN OUT DWORD *pcbEncoded
  7109. )
  7110. {
  7111. BOOL fResult;
  7112. DSSParameters Asn1Info;
  7113. memset(&Asn1Info, 0, sizeof(Asn1Info));
  7114. if (!Asn1X509SetHugeUINT(&pInfo->p, &Asn1Info.p))
  7115. goto ErrorReturn;
  7116. if (!Asn1X509SetHugeUINT(&pInfo->q, &Asn1Info.q))
  7117. goto ErrorReturn;
  7118. if (!Asn1X509SetHugeUINT(&pInfo->g, &Asn1Info.g))
  7119. goto ErrorReturn;
  7120. fResult = Asn1InfoEncodeEx(
  7121. DSSParameters_PDU,
  7122. &Asn1Info,
  7123. dwFlags,
  7124. pEncodePara,
  7125. pvEncoded,
  7126. pcbEncoded
  7127. );
  7128. goto CommonReturn;
  7129. ErrorReturn:
  7130. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  7131. *((void **) pvEncoded) = NULL;
  7132. *pcbEncoded = 0;
  7133. fResult = FALSE;
  7134. CommonReturn:
  7135. Asn1X509FreeHugeUINT(&Asn1Info.p);
  7136. Asn1X509FreeHugeUINT(&Asn1Info.q);
  7137. Asn1X509FreeHugeUINT(&Asn1Info.g);
  7138. return fResult;
  7139. }
  7140. //+-------------------------------------------------------------------------
  7141. // DSS Parameters Decode (ASN1 X509)
  7142. //--------------------------------------------------------------------------
  7143. BOOL WINAPI Asn1X509DSSParametersDecodeExCallback(
  7144. IN void *pvAsn1Info,
  7145. IN DWORD dwFlags,
  7146. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  7147. OUT OPTIONAL void *pvStructInfo,
  7148. IN OUT LONG *plRemainExtra
  7149. )
  7150. {
  7151. DSSParameters *pAsn1Info = (DSSParameters *) pvAsn1Info;
  7152. PCERT_DSS_PARAMETERS pInfo = (PCERT_DSS_PARAMETERS) pvStructInfo;
  7153. LONG lRemainExtra = *plRemainExtra;
  7154. BYTE *pbExtra;
  7155. lRemainExtra -= sizeof(CERT_DSS_PARAMETERS);
  7156. if (lRemainExtra < 0) {
  7157. pbExtra = NULL;
  7158. } else
  7159. pbExtra = (BYTE *) pInfo + sizeof(CERT_DSS_PARAMETERS);
  7160. Asn1X509GetHugeUINT(&pAsn1Info->p, dwFlags,
  7161. &pInfo->p, &pbExtra, &lRemainExtra);
  7162. Asn1X509GetHugeUINT(&pAsn1Info->q, dwFlags,
  7163. &pInfo->q, &pbExtra, &lRemainExtra);
  7164. Asn1X509GetHugeUINT(&pAsn1Info->g, dwFlags,
  7165. &pInfo->g, &pbExtra, &lRemainExtra);
  7166. *plRemainExtra = lRemainExtra;
  7167. return TRUE;
  7168. }
  7169. BOOL WINAPI Asn1X509DSSParametersDecodeEx(
  7170. IN DWORD dwCertEncodingType,
  7171. IN LPCSTR lpszStructType,
  7172. IN const BYTE *pbEncoded,
  7173. IN DWORD cbEncoded,
  7174. IN DWORD dwFlags,
  7175. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  7176. OUT OPTIONAL void *pvStructInfo,
  7177. IN OUT DWORD *pcbStructInfo
  7178. )
  7179. {
  7180. return Asn1InfoDecodeAndAllocEx(
  7181. DSSParameters_PDU,
  7182. pbEncoded,
  7183. cbEncoded,
  7184. dwFlags,
  7185. pDecodePara,
  7186. Asn1X509DSSParametersDecodeExCallback,
  7187. pvStructInfo,
  7188. pcbStructInfo
  7189. );
  7190. }
  7191. //+-------------------------------------------------------------------------
  7192. // DSS Signature Encode (ASN1 X509)
  7193. //--------------------------------------------------------------------------
  7194. BOOL WINAPI Asn1X509DSSSignatureEncodeEx(
  7195. IN DWORD dwCertEncodingType,
  7196. IN LPCSTR lpszStructType,
  7197. IN BYTE rgbSignature[CERT_DSS_SIGNATURE_LEN],
  7198. IN DWORD dwFlags,
  7199. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  7200. OUT OPTIONAL void *pvEncoded,
  7201. IN OUT DWORD *pcbEncoded
  7202. )
  7203. {
  7204. BYTE rgbR[1 + CERT_DSS_R_LEN];
  7205. BYTE rgbS[1 + CERT_DSS_S_LEN];
  7206. DSSSignature Asn1Signature;
  7207. DWORD i;
  7208. // Treat the r and s components of the DSS signature as being unsigned.
  7209. // Also need to swap before doing the encode.
  7210. rgbR[0] = 0;
  7211. for (i = 0; i < CERT_DSS_R_LEN; i++)
  7212. rgbR[(1 + CERT_DSS_R_LEN - 1) - i] = rgbSignature[i];
  7213. Asn1Signature.r.length = sizeof(rgbR);
  7214. Asn1Signature.r.value = rgbR;
  7215. rgbS[0] = 0;
  7216. for (i = 0; i < CERT_DSS_S_LEN; i++)
  7217. rgbS[(1 + CERT_DSS_S_LEN - 1) - i] =
  7218. rgbSignature[CERT_DSS_R_LEN + i];
  7219. Asn1Signature.s.length = sizeof(rgbS);
  7220. Asn1Signature.s.value = rgbS;
  7221. return Asn1InfoEncodeEx(
  7222. DSSSignature_PDU,
  7223. &Asn1Signature,
  7224. dwFlags,
  7225. pEncodePara,
  7226. pvEncoded,
  7227. pcbEncoded
  7228. );
  7229. }
  7230. //+-------------------------------------------------------------------------
  7231. // DSS Signature Decode (ASN1 X509)
  7232. //--------------------------------------------------------------------------
  7233. BOOL WINAPI Asn1X509DSSSignatureDecodeExCallback(
  7234. IN void *pvAsn1Info,
  7235. IN DWORD dwFlags,
  7236. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  7237. OUT OPTIONAL void *pvStructInfo,
  7238. IN OUT LONG *plRemainExtra
  7239. )
  7240. {
  7241. BOOL fResult;
  7242. DSSSignature *pAsn1Signature = (DSSSignature *) pvAsn1Info;
  7243. // BYTE rgbSignature[CERT_DSS_SIGNATURE_LEN],
  7244. BYTE *rgbSignature = (BYTE *) pvStructInfo;
  7245. DWORD cb;
  7246. BYTE *pb;
  7247. DWORD i;
  7248. *plRemainExtra -= CERT_DSS_SIGNATURE_LEN;
  7249. if (*plRemainExtra >= 0) {
  7250. memset(rgbSignature, 0, CERT_DSS_SIGNATURE_LEN);
  7251. // Strip off a leading 0 byte. Byte reverse while copying
  7252. cb = pAsn1Signature->r.length;
  7253. pb = pAsn1Signature->r.value;
  7254. if (cb > 1 && *pb == 0) {
  7255. pb++;
  7256. cb--;
  7257. }
  7258. if (0 == cb || cb > CERT_DSS_R_LEN)
  7259. goto DecodeError;
  7260. for (i = 0; i < cb; i++)
  7261. rgbSignature[i] = pb[cb - 1 - i];
  7262. // Strip off a leading 0 byte. Byte reverse while copying
  7263. cb = pAsn1Signature->s.length;
  7264. pb = pAsn1Signature->s.value;
  7265. if (cb > 1 && *pb == 0) {
  7266. pb++;
  7267. cb--;
  7268. }
  7269. if (0 == cb || cb > CERT_DSS_S_LEN)
  7270. goto DecodeError;
  7271. for (i = 0; i < cb; i++)
  7272. rgbSignature[CERT_DSS_R_LEN + i] = pb[cb - 1 - i];
  7273. }
  7274. fResult = TRUE;
  7275. CommonReturn:
  7276. return fResult;
  7277. ErrorReturn:
  7278. fResult = FALSE;
  7279. goto CommonReturn;
  7280. SET_ERROR(DecodeError, CRYPT_E_BAD_ENCODE)
  7281. }
  7282. BOOL WINAPI Asn1X509DSSSignatureDecodeEx(
  7283. IN DWORD dwCertEncodingType,
  7284. IN LPCSTR lpszStructType,
  7285. IN const BYTE *pbEncoded,
  7286. IN DWORD cbEncoded,
  7287. IN DWORD dwFlags,
  7288. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  7289. OUT OPTIONAL void *pvStructInfo,
  7290. IN OUT DWORD *pcbStructInfo
  7291. )
  7292. {
  7293. return Asn1InfoDecodeAndAllocEx(
  7294. DSSSignature_PDU,
  7295. pbEncoded,
  7296. cbEncoded,
  7297. dwFlags,
  7298. pDecodePara,
  7299. Asn1X509DSSSignatureDecodeExCallback,
  7300. pvStructInfo,
  7301. pcbStructInfo
  7302. );
  7303. }
  7304. //+-------------------------------------------------------------------------
  7305. // DH Parameters Encode (ASN1 X509)
  7306. //--------------------------------------------------------------------------
  7307. BOOL WINAPI Asn1X509DHParametersEncodeEx(
  7308. IN DWORD dwCertEncodingType,
  7309. IN LPCSTR lpszStructType,
  7310. IN PCERT_DH_PARAMETERS pInfo,
  7311. IN DWORD dwFlags,
  7312. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  7313. OUT OPTIONAL void *pvEncoded,
  7314. IN OUT DWORD *pcbEncoded
  7315. )
  7316. {
  7317. BOOL fResult;
  7318. DHParameters Asn1Info;
  7319. memset(&Asn1Info, 0, sizeof(Asn1Info));
  7320. if (!Asn1X509SetHugeUINT(&pInfo->p, &Asn1Info.p))
  7321. goto ErrorReturn;
  7322. if (!Asn1X509SetHugeUINT(&pInfo->g, &Asn1Info.g))
  7323. goto ErrorReturn;
  7324. fResult = Asn1InfoEncodeEx(
  7325. DHParameters_PDU,
  7326. &Asn1Info,
  7327. dwFlags,
  7328. pEncodePara,
  7329. pvEncoded,
  7330. pcbEncoded
  7331. );
  7332. goto CommonReturn;
  7333. ErrorReturn:
  7334. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  7335. *((void **) pvEncoded) = NULL;
  7336. *pcbEncoded = 0;
  7337. fResult = FALSE;
  7338. CommonReturn:
  7339. Asn1X509FreeHugeUINT(&Asn1Info.p);
  7340. Asn1X509FreeHugeUINT(&Asn1Info.g);
  7341. return fResult;
  7342. }
  7343. //+-------------------------------------------------------------------------
  7344. // DH Parameters Decode (ASN1 X509)
  7345. //--------------------------------------------------------------------------
  7346. BOOL WINAPI Asn1X509DHParametersDecodeExCallback(
  7347. IN void *pvAsn1Info,
  7348. IN DWORD dwFlags,
  7349. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  7350. OUT OPTIONAL void *pvStructInfo,
  7351. IN OUT LONG *plRemainExtra
  7352. )
  7353. {
  7354. DHParameters *pAsn1Info = (DHParameters *) pvAsn1Info;
  7355. PCERT_DH_PARAMETERS pInfo = (PCERT_DH_PARAMETERS) pvStructInfo;
  7356. LONG lRemainExtra = *plRemainExtra;
  7357. BYTE *pbExtra;
  7358. lRemainExtra -= sizeof(CERT_DH_PARAMETERS);
  7359. if (lRemainExtra < 0) {
  7360. pbExtra = NULL;
  7361. } else
  7362. pbExtra = (BYTE *) pInfo + sizeof(CERT_DH_PARAMETERS);
  7363. Asn1X509GetHugeUINT(&pAsn1Info->p, dwFlags,
  7364. &pInfo->p, &pbExtra, &lRemainExtra);
  7365. Asn1X509GetHugeUINT(&pAsn1Info->g, dwFlags,
  7366. &pInfo->g, &pbExtra, &lRemainExtra);
  7367. *plRemainExtra = lRemainExtra;
  7368. return TRUE;
  7369. }
  7370. //+-------------------------------------------------------------------------
  7371. // DH Parameters Decode (ASN1) New Style X942
  7372. //--------------------------------------------------------------------------
  7373. BOOL WINAPI Asn1X509DHParametersX942DecodeExCallback(
  7374. IN void *pvAsn1Info,
  7375. IN DWORD dwFlags,
  7376. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  7377. OUT OPTIONAL void *pvStructInfo,
  7378. IN OUT LONG *plRemainExtra
  7379. )
  7380. {
  7381. X942DhParameters *pAsn1Info = (X942DhParameters *) pvAsn1Info;
  7382. PCERT_DH_PARAMETERS pInfo = (PCERT_DH_PARAMETERS) pvStructInfo;
  7383. LONG lRemainExtra = *plRemainExtra;
  7384. BYTE *pbExtra;
  7385. lRemainExtra -= sizeof(CERT_DH_PARAMETERS);
  7386. if (lRemainExtra < 0) {
  7387. pbExtra = NULL;
  7388. } else
  7389. pbExtra = (BYTE *) pInfo + sizeof(CERT_DH_PARAMETERS);
  7390. Asn1X509GetHugeUINT(&pAsn1Info->p, dwFlags,
  7391. &pInfo->p, &pbExtra, &lRemainExtra);
  7392. Asn1X509GetHugeUINT(&pAsn1Info->g, dwFlags,
  7393. &pInfo->g, &pbExtra, &lRemainExtra);
  7394. *plRemainExtra = lRemainExtra;
  7395. return TRUE;
  7396. }
  7397. BOOL WINAPI Asn1X509DHParametersDecodeEx(
  7398. IN DWORD dwCertEncodingType,
  7399. IN LPCSTR lpszStructType,
  7400. IN const BYTE *pbEncoded,
  7401. IN DWORD cbEncoded,
  7402. IN DWORD dwFlags,
  7403. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  7404. OUT OPTIONAL void *pvStructInfo,
  7405. IN OUT DWORD *pcbStructInfo
  7406. )
  7407. {
  7408. BOOL fResult;
  7409. DWORD cbStructInfo;
  7410. cbStructInfo = *pcbStructInfo;
  7411. fResult = Asn1InfoDecodeAndAllocEx(
  7412. DHParameters_PDU,
  7413. pbEncoded,
  7414. cbEncoded,
  7415. dwFlags,
  7416. pDecodePara,
  7417. Asn1X509DHParametersDecodeExCallback,
  7418. pvStructInfo,
  7419. &cbStructInfo
  7420. );
  7421. if (!fResult && 0 == cbStructInfo) {
  7422. // Try to decode as new style X942 parameters
  7423. DWORD dwErr = GetLastError();
  7424. cbStructInfo = *pcbStructInfo;
  7425. fResult = Asn1InfoDecodeAndAllocEx(
  7426. X942DhParameters_PDU,
  7427. pbEncoded,
  7428. cbEncoded,
  7429. dwFlags,
  7430. pDecodePara,
  7431. Asn1X509DHParametersX942DecodeExCallback,
  7432. pvStructInfo,
  7433. &cbStructInfo
  7434. );
  7435. if (!fResult && 0 == cbStructInfo)
  7436. SetLastError(dwErr);
  7437. }
  7438. *pcbStructInfo = cbStructInfo;
  7439. return fResult;
  7440. }
  7441. //+-------------------------------------------------------------------------
  7442. // X942 DH Parameters Encode (ASN1)
  7443. //--------------------------------------------------------------------------
  7444. BOOL WINAPI Asn1X942DhParametersEncodeEx(
  7445. IN DWORD dwCertEncodingType,
  7446. IN LPCSTR lpszStructType,
  7447. IN PCERT_X942_DH_PARAMETERS pInfo,
  7448. IN DWORD dwFlags,
  7449. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  7450. OUT OPTIONAL void *pvEncoded,
  7451. IN OUT DWORD *pcbEncoded
  7452. )
  7453. {
  7454. BOOL fResult;
  7455. X942DhParameters Asn1Info;
  7456. if (0 == pInfo->q.cbData) {
  7457. CERT_DH_PARAMETERS Pkcs3Info;
  7458. Pkcs3Info.p = pInfo->p;
  7459. Pkcs3Info.g = pInfo->g;
  7460. return Asn1X509DHParametersEncodeEx(
  7461. dwCertEncodingType,
  7462. lpszStructType,
  7463. &Pkcs3Info,
  7464. dwFlags,
  7465. pEncodePara,
  7466. pvEncoded,
  7467. pcbEncoded
  7468. );
  7469. }
  7470. memset(&Asn1Info, 0, sizeof(Asn1Info));
  7471. if (!Asn1X509SetHugeUINT(&pInfo->p, &Asn1Info.p))
  7472. goto ErrorReturn;
  7473. if (!Asn1X509SetHugeUINT(&pInfo->g, &Asn1Info.g))
  7474. goto ErrorReturn;
  7475. if (!Asn1X509SetHugeUINT(&pInfo->q, &Asn1Info.q))
  7476. goto ErrorReturn;
  7477. if (pInfo->j.cbData) {
  7478. if (!Asn1X509SetHugeUINT(&pInfo->j, &Asn1Info.j))
  7479. goto ErrorReturn;
  7480. Asn1Info.bit_mask |= j_present;
  7481. }
  7482. if (pInfo->pValidationParams) {
  7483. PCERT_X942_DH_VALIDATION_PARAMS pValidationParams =
  7484. pInfo->pValidationParams;
  7485. Asn1X509SetBit(&pValidationParams->seed,
  7486. &Asn1Info.validationParams.seed);
  7487. Asn1Info.validationParams.pgenCounter = pValidationParams->pgenCounter;
  7488. Asn1Info.bit_mask |= validationParams_present;
  7489. }
  7490. fResult = Asn1InfoEncodeEx(
  7491. X942DhParameters_PDU,
  7492. &Asn1Info,
  7493. dwFlags,
  7494. pEncodePara,
  7495. pvEncoded,
  7496. pcbEncoded
  7497. );
  7498. goto CommonReturn;
  7499. ErrorReturn:
  7500. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  7501. *((void **) pvEncoded) = NULL;
  7502. *pcbEncoded = 0;
  7503. fResult = FALSE;
  7504. CommonReturn:
  7505. Asn1X509FreeHugeUINT(&Asn1Info.p);
  7506. Asn1X509FreeHugeUINT(&Asn1Info.g);
  7507. Asn1X509FreeHugeUINT(&Asn1Info.q);
  7508. Asn1X509FreeHugeUINT(&Asn1Info.j);
  7509. return fResult;
  7510. }
  7511. //+-------------------------------------------------------------------------
  7512. // X942 DH Parameters Decode (ASN1)
  7513. //--------------------------------------------------------------------------
  7514. BOOL WINAPI Asn1X942DhParametersDecodeExCallback(
  7515. IN void *pvAsn1Info,
  7516. IN DWORD dwFlags,
  7517. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  7518. OUT OPTIONAL void *pvStructInfo,
  7519. IN OUT LONG *plRemainExtra
  7520. )
  7521. {
  7522. X942DhParameters *pAsn1Info = (X942DhParameters *) pvAsn1Info;
  7523. PCERT_X942_DH_PARAMETERS pInfo = (PCERT_X942_DH_PARAMETERS) pvStructInfo;
  7524. LONG lRemainExtra = *plRemainExtra;
  7525. BYTE *pbExtra;
  7526. lRemainExtra -= sizeof(CERT_X942_DH_PARAMETERS);
  7527. if (lRemainExtra < 0) {
  7528. pbExtra = NULL;
  7529. } else {
  7530. // Default all optional fields to zero
  7531. memset(pInfo, 0, sizeof(CERT_X942_DH_PARAMETERS));
  7532. pbExtra = (BYTE *) pInfo + sizeof(CERT_X942_DH_PARAMETERS);
  7533. }
  7534. Asn1X509GetHugeUINT(&pAsn1Info->p, dwFlags,
  7535. &pInfo->p, &pbExtra, &lRemainExtra);
  7536. Asn1X509GetHugeUINT(&pAsn1Info->g, dwFlags,
  7537. &pInfo->g, &pbExtra, &lRemainExtra);
  7538. Asn1X509GetHugeUINT(&pAsn1Info->q, dwFlags,
  7539. &pInfo->q, &pbExtra, &lRemainExtra);
  7540. if (pAsn1Info->bit_mask & j_present)
  7541. Asn1X509GetHugeUINT(&pAsn1Info->j, dwFlags,
  7542. &pInfo->j, &pbExtra, &lRemainExtra);
  7543. if (pAsn1Info->bit_mask & validationParams_present) {
  7544. PCERT_X942_DH_VALIDATION_PARAMS pValidationParams;
  7545. lRemainExtra -= sizeof(CERT_X942_DH_VALIDATION_PARAMS);
  7546. if (lRemainExtra < 0) {
  7547. pValidationParams = NULL;
  7548. } else {
  7549. pValidationParams = (PCERT_X942_DH_VALIDATION_PARAMS) pbExtra;
  7550. pInfo->pValidationParams = pValidationParams;
  7551. pbExtra += sizeof(CERT_X942_DH_VALIDATION_PARAMS);
  7552. pValidationParams->pgenCounter =
  7553. pAsn1Info->validationParams.pgenCounter;
  7554. }
  7555. Asn1X509GetBit(&pAsn1Info->validationParams.seed, dwFlags,
  7556. &pValidationParams->seed, &pbExtra, &lRemainExtra);
  7557. }
  7558. *plRemainExtra = lRemainExtra;
  7559. return TRUE;
  7560. }
  7561. //+-------------------------------------------------------------------------
  7562. // X942 DH Parameters Decode (ASN1) Old Style Pkcs #3
  7563. //--------------------------------------------------------------------------
  7564. BOOL WINAPI Asn1X942DhParametersPkcs3DecodeExCallback(
  7565. IN void *pvAsn1Info,
  7566. IN DWORD dwFlags,
  7567. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  7568. OUT OPTIONAL void *pvStructInfo,
  7569. IN OUT LONG *plRemainExtra
  7570. )
  7571. {
  7572. DHParameters *pAsn1Info = (DHParameters *) pvAsn1Info;
  7573. PCERT_X942_DH_PARAMETERS pInfo = (PCERT_X942_DH_PARAMETERS) pvStructInfo;
  7574. LONG lRemainExtra = *plRemainExtra;
  7575. BYTE *pbExtra;
  7576. lRemainExtra -= sizeof(CERT_X942_DH_PARAMETERS);
  7577. if (lRemainExtra < 0) {
  7578. pbExtra = NULL;
  7579. } else {
  7580. // Default all optional fields to zero
  7581. memset(pInfo, 0, sizeof(CERT_X942_DH_PARAMETERS));
  7582. pbExtra = (BYTE *) pInfo + sizeof(CERT_X942_DH_PARAMETERS);
  7583. }
  7584. Asn1X509GetHugeUINT(&pAsn1Info->p, dwFlags,
  7585. &pInfo->p, &pbExtra, &lRemainExtra);
  7586. Asn1X509GetHugeUINT(&pAsn1Info->g, dwFlags,
  7587. &pInfo->g, &pbExtra, &lRemainExtra);
  7588. *plRemainExtra = lRemainExtra;
  7589. return TRUE;
  7590. }
  7591. BOOL WINAPI Asn1X942DhParametersDecodeEx(
  7592. IN DWORD dwCertEncodingType,
  7593. IN LPCSTR lpszStructType,
  7594. IN const BYTE *pbEncoded,
  7595. IN DWORD cbEncoded,
  7596. IN DWORD dwFlags,
  7597. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  7598. OUT OPTIONAL void *pvStructInfo,
  7599. IN OUT DWORD *pcbStructInfo
  7600. )
  7601. {
  7602. BOOL fResult;
  7603. DWORD cbStructInfo;
  7604. cbStructInfo = *pcbStructInfo;
  7605. fResult = Asn1InfoDecodeAndAllocEx(
  7606. X942DhParameters_PDU,
  7607. pbEncoded,
  7608. cbEncoded,
  7609. dwFlags,
  7610. pDecodePara,
  7611. Asn1X942DhParametersDecodeExCallback,
  7612. pvStructInfo,
  7613. &cbStructInfo
  7614. );
  7615. if (!fResult && 0 == cbStructInfo) {
  7616. // Try to decode as old style PKCS #3 parameters
  7617. DWORD dwErr = GetLastError();
  7618. cbStructInfo = *pcbStructInfo;
  7619. fResult = Asn1InfoDecodeAndAllocEx(
  7620. DHParameters_PDU,
  7621. pbEncoded,
  7622. cbEncoded,
  7623. dwFlags,
  7624. pDecodePara,
  7625. Asn1X942DhParametersPkcs3DecodeExCallback,
  7626. pvStructInfo,
  7627. &cbStructInfo
  7628. );
  7629. if (!fResult && 0 == cbStructInfo)
  7630. SetLastError(dwErr);
  7631. }
  7632. *pcbStructInfo = cbStructInfo;
  7633. return fResult;
  7634. }
  7635. //+-------------------------------------------------------------------------
  7636. // X942_OTHER_INFO Encode (ASN1)
  7637. //--------------------------------------------------------------------------
  7638. BOOL WINAPI Asn1X942OtherInfoEncodeEx(
  7639. IN DWORD dwCertEncodingType,
  7640. IN LPCSTR lpszStructType,
  7641. IN PCRYPT_X942_OTHER_INFO pInfo,
  7642. IN DWORD dwFlags,
  7643. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  7644. OUT OPTIONAL void *pvEncoded,
  7645. IN OUT DWORD *pcbEncoded
  7646. )
  7647. {
  7648. BOOL fResult;
  7649. X942DhOtherInfo Asn1Info;
  7650. BYTE rgbAsn1Counter[CRYPT_X942_COUNTER_BYTE_LENGTH];
  7651. BYTE rgbAsn1KeyLength[CRYPT_X942_KEY_LENGTH_BYTE_LENGTH];
  7652. memset(&Asn1Info, 0, sizeof(Asn1Info));
  7653. if (!Asn1X509SetEncodedObjId(pInfo->pszContentEncryptionObjId,
  7654. &Asn1Info.keyInfo.algorithm))
  7655. goto ErrorReturn;
  7656. memcpy(rgbAsn1Counter, pInfo->rgbCounter, CRYPT_X942_COUNTER_BYTE_LENGTH);
  7657. PkiAsn1ReverseBytes(rgbAsn1Counter, CRYPT_X942_COUNTER_BYTE_LENGTH);
  7658. Asn1Info.keyInfo.counter.length = CRYPT_X942_COUNTER_BYTE_LENGTH;
  7659. Asn1Info.keyInfo.counter.value = rgbAsn1Counter;
  7660. memcpy(rgbAsn1KeyLength, pInfo->rgbKeyLength,
  7661. CRYPT_X942_KEY_LENGTH_BYTE_LENGTH);
  7662. PkiAsn1ReverseBytes(rgbAsn1KeyLength, CRYPT_X942_KEY_LENGTH_BYTE_LENGTH);
  7663. Asn1Info.keyLength.length = CRYPT_X942_KEY_LENGTH_BYTE_LENGTH;
  7664. Asn1Info.keyLength.value = rgbAsn1KeyLength;
  7665. if (pInfo->PubInfo.cbData) {
  7666. Asn1X509SetOctetString(&pInfo->PubInfo, &Asn1Info.pubInfo);
  7667. Asn1Info.bit_mask |= pubInfo_present;
  7668. }
  7669. fResult = Asn1InfoEncodeEx(
  7670. X942DhOtherInfo_PDU,
  7671. &Asn1Info,
  7672. dwFlags,
  7673. pEncodePara,
  7674. pvEncoded,
  7675. pcbEncoded
  7676. );
  7677. goto CommonReturn;
  7678. ErrorReturn:
  7679. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  7680. *((void **) pvEncoded) = NULL;
  7681. *pcbEncoded = 0;
  7682. fResult = FALSE;
  7683. CommonReturn:
  7684. return fResult;
  7685. }
  7686. //+-------------------------------------------------------------------------
  7687. // X942_OTHER_INFO Decode (ASN1)
  7688. //--------------------------------------------------------------------------
  7689. BOOL WINAPI Asn1X942OtherInfoDecodeExCallback(
  7690. IN void *pvAsn1Info,
  7691. IN DWORD dwFlags,
  7692. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  7693. OUT OPTIONAL void *pvStructInfo,
  7694. IN OUT LONG *plRemainExtra
  7695. )
  7696. {
  7697. X942DhOtherInfo *pAsn1Info = (X942DhOtherInfo *) pvAsn1Info;
  7698. PCRYPT_X942_OTHER_INFO pInfo = (PCRYPT_X942_OTHER_INFO) pvStructInfo;
  7699. LONG lRemainExtra = *plRemainExtra;
  7700. BYTE *pbExtra;
  7701. if (CRYPT_X942_COUNTER_BYTE_LENGTH != pAsn1Info->keyInfo.counter.length ||
  7702. CRYPT_X942_KEY_LENGTH_BYTE_LENGTH !=
  7703. pAsn1Info->keyLength.length) {
  7704. SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
  7705. return FALSE;
  7706. }
  7707. lRemainExtra -= sizeof(CRYPT_X942_OTHER_INFO);
  7708. if (lRemainExtra < 0) {
  7709. pbExtra = NULL;
  7710. } else {
  7711. // Default all optional fields to zero
  7712. memset(pInfo, 0, sizeof(CRYPT_X942_OTHER_INFO));
  7713. memcpy(pInfo->rgbCounter, pAsn1Info->keyInfo.counter.value,
  7714. CRYPT_X942_COUNTER_BYTE_LENGTH);
  7715. PkiAsn1ReverseBytes(pInfo->rgbCounter, CRYPT_X942_COUNTER_BYTE_LENGTH);
  7716. memcpy(pInfo->rgbKeyLength, pAsn1Info->keyLength.value,
  7717. CRYPT_X942_KEY_LENGTH_BYTE_LENGTH);
  7718. PkiAsn1ReverseBytes(pInfo->rgbKeyLength,
  7719. CRYPT_X942_KEY_LENGTH_BYTE_LENGTH);
  7720. pbExtra = (BYTE *) pInfo + sizeof(CRYPT_X942_OTHER_INFO);
  7721. }
  7722. Asn1X509GetEncodedObjId(&pAsn1Info->keyInfo.algorithm, dwFlags,
  7723. &pInfo->pszContentEncryptionObjId,
  7724. &pbExtra, &lRemainExtra);
  7725. if (pAsn1Info->bit_mask & pubInfo_present) {
  7726. Asn1X509GetOctetString(&pAsn1Info->pubInfo, dwFlags,
  7727. &pInfo->PubInfo, &pbExtra, &lRemainExtra);
  7728. }
  7729. *plRemainExtra = lRemainExtra;
  7730. return TRUE;
  7731. }
  7732. BOOL WINAPI Asn1X942OtherInfoDecodeEx(
  7733. IN DWORD dwCertEncodingType,
  7734. IN LPCSTR lpszStructType,
  7735. IN const BYTE *pbEncoded,
  7736. IN DWORD cbEncoded,
  7737. IN DWORD dwFlags,
  7738. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  7739. OUT OPTIONAL void *pvStructInfo,
  7740. IN OUT DWORD *pcbStructInfo
  7741. )
  7742. {
  7743. return Asn1InfoDecodeAndAllocEx(
  7744. X942DhOtherInfo_PDU,
  7745. pbEncoded,
  7746. cbEncoded,
  7747. dwFlags,
  7748. pDecodePara,
  7749. Asn1X942OtherInfoDecodeExCallback,
  7750. pvStructInfo,
  7751. pcbStructInfo
  7752. );
  7753. }
  7754. //+-------------------------------------------------------------------------
  7755. // RC2 CBC Parameters Encode (ASN1)
  7756. //--------------------------------------------------------------------------
  7757. BOOL WINAPI Asn1RC2CBCParametersEncodeEx(
  7758. IN DWORD dwCertEncodingType,
  7759. IN LPCSTR lpszStructType,
  7760. IN PCRYPT_RC2_CBC_PARAMETERS pInfo,
  7761. IN DWORD dwFlags,
  7762. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  7763. OUT OPTIONAL void *pvEncoded,
  7764. IN OUT DWORD *pcbEncoded
  7765. )
  7766. {
  7767. RC2CBCParameters Asn1Info;
  7768. memset(&Asn1Info, 0, sizeof(Asn1Info));
  7769. Asn1Info.version = pInfo->dwVersion;
  7770. if (pInfo->fIV) {
  7771. Asn1Info.bit_mask |= iv_present;
  7772. Asn1Info.iv.length = sizeof(pInfo->rgbIV);
  7773. Asn1Info.iv.value = pInfo->rgbIV;
  7774. }
  7775. return Asn1InfoEncodeEx(
  7776. RC2CBCParameters_PDU,
  7777. &Asn1Info,
  7778. dwFlags,
  7779. pEncodePara,
  7780. pvEncoded,
  7781. pcbEncoded
  7782. );
  7783. }
  7784. //+-------------------------------------------------------------------------
  7785. // RC2 CBC Parameters Decode (ASN1)
  7786. //--------------------------------------------------------------------------
  7787. BOOL WINAPI Asn1RC2CBCParametersDecodeExCallback(
  7788. IN void *pvAsn1Info,
  7789. IN DWORD dwFlags,
  7790. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  7791. OUT OPTIONAL void *pvStructInfo,
  7792. IN OUT LONG *plRemainExtra
  7793. )
  7794. {
  7795. BOOL fResult;
  7796. RC2CBCParameters *pAsn1Info = (RC2CBCParameters *) pvAsn1Info;
  7797. PCRYPT_RC2_CBC_PARAMETERS pInfo = (PCRYPT_RC2_CBC_PARAMETERS) pvStructInfo;
  7798. *plRemainExtra -= sizeof(CRYPT_RC2_CBC_PARAMETERS);
  7799. if (*plRemainExtra >= 0) {
  7800. memset(pInfo, 0, sizeof(CRYPT_RC2_CBC_PARAMETERS));
  7801. pInfo->dwVersion = pAsn1Info->version;
  7802. if (pAsn1Info->bit_mask & iv_present) {
  7803. pInfo->fIV = TRUE;
  7804. if (pAsn1Info->iv.length != sizeof(pInfo->rgbIV))
  7805. goto DecodeError;
  7806. memcpy(pInfo->rgbIV, pAsn1Info->iv.value, sizeof(pInfo->rgbIV));
  7807. }
  7808. }
  7809. fResult = TRUE;
  7810. CommonReturn:
  7811. return fResult;
  7812. ErrorReturn:
  7813. fResult = FALSE;
  7814. goto CommonReturn;
  7815. SET_ERROR(DecodeError, CRYPT_E_BAD_ENCODE)
  7816. }
  7817. BOOL WINAPI Asn1RC2CBCParametersDecodeEx(
  7818. IN DWORD dwCertEncodingType,
  7819. IN LPCSTR lpszStructType,
  7820. IN const BYTE *pbEncoded,
  7821. IN DWORD cbEncoded,
  7822. IN DWORD dwFlags,
  7823. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  7824. OUT OPTIONAL void *pvStructInfo,
  7825. IN OUT DWORD *pcbStructInfo
  7826. )
  7827. {
  7828. return Asn1InfoDecodeAndAllocEx(
  7829. RC2CBCParameters_PDU,
  7830. pbEncoded,
  7831. cbEncoded,
  7832. dwFlags,
  7833. pDecodePara,
  7834. Asn1RC2CBCParametersDecodeExCallback,
  7835. pvStructInfo,
  7836. pcbStructInfo
  7837. );
  7838. }
  7839. //+-------------------------------------------------------------------------
  7840. // SMIME Capabilities Encode (ASN1)
  7841. //--------------------------------------------------------------------------
  7842. BOOL WINAPI Asn1SMIMECapabilitiesEncodeEx(
  7843. IN DWORD dwCertEncodingType,
  7844. IN LPCSTR lpszStructType,
  7845. IN PCRYPT_SMIME_CAPABILITIES pInfo,
  7846. IN DWORD dwFlags,
  7847. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  7848. OUT OPTIONAL void *pvEncoded,
  7849. IN OUT DWORD *pcbEncoded
  7850. )
  7851. {
  7852. BOOL fResult;
  7853. SMIMECapabilities Asn1Info;
  7854. memset(&Asn1Info, 0, sizeof(Asn1Info));
  7855. if (0 != pInfo->cCapability) {
  7856. DWORD cCap = pInfo->cCapability;
  7857. PCRYPT_SMIME_CAPABILITY pCap = pInfo->rgCapability;
  7858. SMIMECapability *pAsn1Cap;
  7859. if (NULL == (pAsn1Cap = (SMIMECapability *) PkiZeroAlloc(
  7860. cCap * sizeof(SMIMECapability))))
  7861. goto ErrorReturn;
  7862. Asn1Info.count = cCap;
  7863. Asn1Info.value = pAsn1Cap;
  7864. for ( ; cCap > 0; cCap--, pCap++, pAsn1Cap++) {
  7865. if (!Asn1X509SetEncodedObjId(pCap->pszObjId, &pAsn1Cap->capabilityID))
  7866. goto ErrorReturn;
  7867. if (pCap->Parameters.cbData) {
  7868. pAsn1Cap->bit_mask |= smimeParameters_present;
  7869. Asn1X509SetAny(&pCap->Parameters,
  7870. &pAsn1Cap->smimeParameters);
  7871. }
  7872. }
  7873. }
  7874. fResult = Asn1InfoEncodeEx(
  7875. SMIMECapabilities_PDU,
  7876. &Asn1Info,
  7877. dwFlags,
  7878. pEncodePara,
  7879. pvEncoded,
  7880. pcbEncoded
  7881. );
  7882. goto CommonReturn;
  7883. ErrorReturn:
  7884. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  7885. *((void **) pvEncoded) = NULL;
  7886. *pcbEncoded = 0;
  7887. fResult = FALSE;
  7888. CommonReturn:
  7889. PkiFree(Asn1Info.value);
  7890. return fResult;
  7891. }
  7892. //+-------------------------------------------------------------------------
  7893. // SMIME Capabilities Decode (ASN1)
  7894. //--------------------------------------------------------------------------
  7895. BOOL WINAPI Asn1SMIMECapabilitiesDecodeExCallback(
  7896. IN void *pvAsn1Info,
  7897. IN DWORD dwFlags,
  7898. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  7899. OUT OPTIONAL void *pvStructInfo,
  7900. IN OUT LONG *plRemainExtra
  7901. )
  7902. {
  7903. SMIMECapabilities *pAsn1Info = (SMIMECapabilities *) pvAsn1Info;
  7904. PCRYPT_SMIME_CAPABILITIES pInfo = (PCRYPT_SMIME_CAPABILITIES) pvStructInfo;
  7905. LONG lRemainExtra = *plRemainExtra;
  7906. BYTE *pbExtra;
  7907. LONG lAlignExtra;
  7908. DWORD cCap;
  7909. SMIMECapability *pAsn1Cap;
  7910. PCRYPT_SMIME_CAPABILITY pCap;
  7911. cCap = pAsn1Info->count;
  7912. lAlignExtra = cCap * sizeof(CRYPT_SMIME_CAPABILITY);
  7913. lRemainExtra -= sizeof(CRYPT_SMIME_CAPABILITIES) + lAlignExtra;
  7914. if (lRemainExtra < 0) {
  7915. pbExtra = NULL;
  7916. pCap = NULL;
  7917. } else {
  7918. pbExtra = (BYTE *) pInfo + sizeof(CRYPT_SMIME_CAPABILITIES);
  7919. pCap = (PCRYPT_SMIME_CAPABILITY) pbExtra;
  7920. pInfo->cCapability = cCap;
  7921. pInfo->rgCapability = pCap;
  7922. if (lAlignExtra) {
  7923. memset(pbExtra, 0, lAlignExtra);
  7924. pbExtra += lAlignExtra;
  7925. }
  7926. }
  7927. pAsn1Cap = pAsn1Info->value;
  7928. for ( ; cCap > 0; cCap--, pAsn1Cap++, pCap++) {
  7929. Asn1X509GetEncodedObjId(&pAsn1Cap->capabilityID, dwFlags, &pCap->pszObjId,
  7930. &pbExtra, &lRemainExtra);
  7931. if (pAsn1Cap->bit_mask & smimeParameters_present)
  7932. Asn1X509GetAny(&pAsn1Cap->smimeParameters, dwFlags,
  7933. &pCap->Parameters, &pbExtra, &lRemainExtra);
  7934. }
  7935. *plRemainExtra = lRemainExtra;
  7936. return TRUE;
  7937. }
  7938. BOOL WINAPI Asn1SMIMECapabilitiesDecodeEx(
  7939. IN DWORD dwCertEncodingType,
  7940. IN LPCSTR lpszStructType,
  7941. IN const BYTE *pbEncoded,
  7942. IN DWORD cbEncoded,
  7943. IN DWORD dwFlags,
  7944. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  7945. OUT OPTIONAL void *pvStructInfo,
  7946. IN OUT DWORD *pcbStructInfo
  7947. )
  7948. {
  7949. return Asn1InfoDecodeAndAllocEx(
  7950. SMIMECapabilities_PDU,
  7951. pbEncoded,
  7952. cbEncoded,
  7953. dwFlags,
  7954. pDecodePara,
  7955. Asn1SMIMECapabilitiesDecodeExCallback,
  7956. pvStructInfo,
  7957. pcbStructInfo
  7958. );
  7959. }
  7960. //+-------------------------------------------------------------------------
  7961. // Enumerated Extension Encode (ASN1 X509)
  7962. //--------------------------------------------------------------------------
  7963. BOOL WINAPI Asn1X509EnumeratedEncodeEx(
  7964. IN DWORD dwCertEncodingType,
  7965. IN LPCSTR lpszStructType,
  7966. IN int *pInfo,
  7967. IN DWORD dwFlags,
  7968. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  7969. OUT OPTIONAL void *pvEncoded,
  7970. IN OUT DWORD *pcbEncoded
  7971. )
  7972. {
  7973. EnumeratedType Asn1Info = (EnumeratedType) *pInfo;
  7974. return Asn1InfoEncodeEx(
  7975. EnumeratedType_PDU,
  7976. &Asn1Info,
  7977. dwFlags,
  7978. pEncodePara,
  7979. pvEncoded,
  7980. pcbEncoded
  7981. );
  7982. }
  7983. //+-------------------------------------------------------------------------
  7984. // Enumerated Extension Decode (ASN1 X509)
  7985. //--------------------------------------------------------------------------
  7986. BOOL WINAPI Asn1X509EnumeratedDecodeExCallback(
  7987. IN void *pvAsn1Info,
  7988. IN DWORD dwFlags,
  7989. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  7990. OUT OPTIONAL void *pvStructInfo,
  7991. IN OUT LONG *plRemainExtra
  7992. )
  7993. {
  7994. EnumeratedType *pAsn1Info = (EnumeratedType *) pvAsn1Info;
  7995. int *pInfo = (int *) pvStructInfo;
  7996. *plRemainExtra -= sizeof(int);
  7997. if (*plRemainExtra >= 0)
  7998. *pInfo = *pAsn1Info;
  7999. return TRUE;
  8000. }
  8001. BOOL WINAPI Asn1X509EnumeratedDecodeEx(
  8002. IN DWORD dwCertEncodingType,
  8003. IN LPCSTR lpszStructType,
  8004. IN const BYTE *pbEncoded,
  8005. IN DWORD cbEncoded,
  8006. IN DWORD dwFlags,
  8007. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  8008. OUT OPTIONAL void *pvStructInfo,
  8009. IN OUT DWORD *pcbStructInfo
  8010. )
  8011. {
  8012. return Asn1InfoDecodeAndAllocEx(
  8013. EnumeratedType_PDU,
  8014. pbEncoded,
  8015. cbEncoded,
  8016. dwFlags,
  8017. pDecodePara,
  8018. Asn1X509EnumeratedDecodeExCallback,
  8019. pvStructInfo,
  8020. pcbStructInfo
  8021. );
  8022. }
  8023. //+-------------------------------------------------------------------------
  8024. // Octet String Extension Encode (ASN1 X509)
  8025. //--------------------------------------------------------------------------
  8026. BOOL WINAPI Asn1X509OctetStringEncodeEx(
  8027. IN DWORD dwCertEncodingType,
  8028. IN LPCSTR lpszStructType,
  8029. IN PCRYPT_DATA_BLOB pInfo,
  8030. IN DWORD dwFlags,
  8031. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  8032. OUT OPTIONAL void *pvEncoded,
  8033. IN OUT DWORD *pcbEncoded
  8034. )
  8035. {
  8036. OCTETSTRING Asn1Info;
  8037. Asn1X509SetOctetString(pInfo, &Asn1Info);
  8038. return Asn1InfoEncodeEx(
  8039. OctetStringType_PDU,
  8040. &Asn1Info,
  8041. dwFlags,
  8042. pEncodePara,
  8043. pvEncoded,
  8044. pcbEncoded
  8045. );
  8046. }
  8047. //+-------------------------------------------------------------------------
  8048. // Octet String Extension Decode (ASN1 X509)
  8049. //--------------------------------------------------------------------------
  8050. BOOL WINAPI Asn1X509OctetStringDecodeExCallback(
  8051. IN void *pvAsn1Info,
  8052. IN DWORD dwFlags,
  8053. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  8054. OUT OPTIONAL void *pvStructInfo,
  8055. IN OUT LONG *plRemainExtra
  8056. )
  8057. {
  8058. OCTETSTRING *pAsn1Info = (OCTETSTRING *) pvAsn1Info;
  8059. PCRYPT_DATA_BLOB pInfo = (PCRYPT_DATA_BLOB) pvStructInfo;
  8060. LONG lRemainExtra = *plRemainExtra;
  8061. BYTE *pbExtra;
  8062. lRemainExtra -= sizeof(CRYPT_DATA_BLOB);
  8063. if (lRemainExtra < 0) {
  8064. pbExtra = NULL;
  8065. } else
  8066. pbExtra = (BYTE *) pInfo + sizeof(CRYPT_DATA_BLOB);
  8067. Asn1X509GetOctetString(pAsn1Info, dwFlags, pInfo, &pbExtra, &lRemainExtra);
  8068. *plRemainExtra = lRemainExtra;
  8069. return TRUE;
  8070. }
  8071. BOOL WINAPI Asn1X509OctetStringDecodeEx(
  8072. IN DWORD dwCertEncodingType,
  8073. IN LPCSTR lpszStructType,
  8074. IN const BYTE *pbEncoded,
  8075. IN DWORD cbEncoded,
  8076. IN DWORD dwFlags,
  8077. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  8078. OUT OPTIONAL void *pvStructInfo,
  8079. IN OUT DWORD *pcbStructInfo
  8080. )
  8081. {
  8082. return Asn1InfoDecodeAndAllocEx(
  8083. OctetStringType_PDU,
  8084. pbEncoded,
  8085. cbEncoded,
  8086. dwFlags,
  8087. pDecodePara,
  8088. Asn1X509OctetStringDecodeExCallback,
  8089. pvStructInfo,
  8090. pcbStructInfo
  8091. );
  8092. }
  8093. //+-------------------------------------------------------------------------
  8094. // ChoiceOfTime Extension Encode (ASN1 X509)
  8095. //--------------------------------------------------------------------------
  8096. BOOL WINAPI Asn1X509ChoiceOfTimeEncodeEx(
  8097. IN DWORD dwCertEncodingType,
  8098. IN LPCSTR lpszStructType,
  8099. IN LPFILETIME pInfo,
  8100. IN DWORD dwFlags,
  8101. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  8102. OUT OPTIONAL void *pvEncoded,
  8103. IN OUT DWORD *pcbEncoded
  8104. )
  8105. {
  8106. ChoiceOfTime Asn1Info;
  8107. if (!PkiAsn1ToChoiceOfTime(pInfo,
  8108. &Asn1Info.choice,
  8109. &Asn1Info.u.generalTime ,
  8110. &Asn1Info.u.utcTime
  8111. )) {
  8112. SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
  8113. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  8114. *((void **) pvEncoded) = NULL;
  8115. *pcbEncoded = 0;
  8116. return FALSE;
  8117. }
  8118. return Asn1InfoEncodeEx(
  8119. ChoiceOfTime_PDU,
  8120. &Asn1Info,
  8121. dwFlags,
  8122. pEncodePara,
  8123. pvEncoded,
  8124. pcbEncoded
  8125. );
  8126. }
  8127. //+-------------------------------------------------------------------------
  8128. // ChoiceOfTime Extension Decode (ASN1 X509)
  8129. //--------------------------------------------------------------------------
  8130. BOOL WINAPI Asn1X509ChoiceOfTimeDecodeExCallback(
  8131. IN void *pvAsn1Info,
  8132. IN DWORD dwFlags,
  8133. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  8134. OUT OPTIONAL void *pvStructInfo,
  8135. IN OUT LONG *plRemainExtra
  8136. )
  8137. {
  8138. BOOL fResult;
  8139. ChoiceOfTime *pAsn1Info = (ChoiceOfTime *) pvAsn1Info;
  8140. LPFILETIME pInfo = (LPFILETIME) pvStructInfo;
  8141. *plRemainExtra -= sizeof(FILETIME);
  8142. if (*plRemainExtra >= 0) {
  8143. if (!PkiAsn1FromChoiceOfTime(pAsn1Info->choice,
  8144. &pAsn1Info->u.generalTime,
  8145. &pAsn1Info->u.utcTime,
  8146. pInfo))
  8147. goto DecodeError;
  8148. }
  8149. fResult = TRUE;
  8150. CommonReturn:
  8151. return fResult;
  8152. ErrorReturn:
  8153. fResult = FALSE;
  8154. goto CommonReturn;
  8155. SET_ERROR(DecodeError, CRYPT_E_BAD_ENCODE)
  8156. }
  8157. BOOL WINAPI Asn1X509ChoiceOfTimeDecodeEx(
  8158. IN DWORD dwCertEncodingType,
  8159. IN LPCSTR lpszStructType,
  8160. IN const BYTE *pbEncoded,
  8161. IN DWORD cbEncoded,
  8162. IN DWORD dwFlags,
  8163. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  8164. OUT OPTIONAL void *pvStructInfo,
  8165. IN OUT DWORD *pcbStructInfo
  8166. )
  8167. {
  8168. return Asn1InfoDecodeAndAllocEx(
  8169. ChoiceOfTime_PDU,
  8170. pbEncoded,
  8171. cbEncoded,
  8172. dwFlags,
  8173. pDecodePara,
  8174. Asn1X509ChoiceOfTimeDecodeExCallback,
  8175. pvStructInfo,
  8176. pcbStructInfo
  8177. );
  8178. }
  8179. //+-------------------------------------------------------------------------
  8180. // Attribute Encode (ASN1 X509)
  8181. //--------------------------------------------------------------------------
  8182. BOOL WINAPI Asn1X509AttributeEncodeEx(
  8183. IN DWORD dwCertEncodingType,
  8184. IN LPCSTR lpszStructType,
  8185. IN PCRYPT_ATTRIBUTE pInfo,
  8186. IN DWORD dwFlags,
  8187. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  8188. OUT OPTIONAL void *pvEncoded,
  8189. IN OUT DWORD *pcbEncoded
  8190. )
  8191. {
  8192. BOOL fResult;
  8193. Attribute Asn1Info;
  8194. if (!Asn1X509SetAttribute(pInfo, &Asn1Info)) {
  8195. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  8196. *((void **) pvEncoded) = NULL;
  8197. *pcbEncoded = 0;
  8198. return FALSE;
  8199. }
  8200. fResult = Asn1InfoEncodeEx(
  8201. Attribute_PDU,
  8202. &Asn1Info,
  8203. dwFlags,
  8204. pEncodePara,
  8205. pvEncoded,
  8206. pcbEncoded
  8207. );
  8208. Asn1X509FreeAttribute(&Asn1Info);
  8209. return fResult;
  8210. }
  8211. //+-------------------------------------------------------------------------
  8212. // Attribute Decode (ASN1 X509)
  8213. //--------------------------------------------------------------------------
  8214. BOOL WINAPI Asn1X509AttributeDecodeExCallback(
  8215. IN void *pvAsn1Info,
  8216. IN DWORD dwFlags,
  8217. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  8218. OUT OPTIONAL void *pvStructInfo,
  8219. IN OUT LONG *plRemainExtra
  8220. )
  8221. {
  8222. Attribute *pAsn1Info = (Attribute *) pvAsn1Info;
  8223. PCRYPT_ATTRIBUTE pInfo = (PCRYPT_ATTRIBUTE) pvStructInfo;
  8224. LONG lRemainExtra = *plRemainExtra;
  8225. BYTE *pbExtra;
  8226. lRemainExtra -= sizeof(CRYPT_ATTRIBUTE);
  8227. if (lRemainExtra < 0) {
  8228. pbExtra = NULL;
  8229. } else
  8230. pbExtra = (BYTE *) pInfo + sizeof(CRYPT_ATTRIBUTE);
  8231. Asn1X509GetAttribute(pAsn1Info, dwFlags, pInfo, &pbExtra, &lRemainExtra);
  8232. *plRemainExtra = lRemainExtra;
  8233. return TRUE;
  8234. }
  8235. BOOL WINAPI Asn1X509AttributeDecodeEx(
  8236. IN DWORD dwCertEncodingType,
  8237. IN LPCSTR lpszStructType,
  8238. IN const BYTE *pbEncoded,
  8239. IN DWORD cbEncoded,
  8240. IN DWORD dwFlags,
  8241. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  8242. OUT OPTIONAL void *pvStructInfo,
  8243. IN OUT DWORD *pcbStructInfo
  8244. )
  8245. {
  8246. return Asn1InfoDecodeAndAllocEx(
  8247. Attribute_PDU,
  8248. pbEncoded,
  8249. cbEncoded,
  8250. dwFlags,
  8251. pDecodePara,
  8252. Asn1X509AttributeDecodeExCallback,
  8253. pvStructInfo,
  8254. pcbStructInfo
  8255. );
  8256. }
  8257. //+-------------------------------------------------------------------------
  8258. // ContentInfo Encode (ASN1 X509)
  8259. //--------------------------------------------------------------------------
  8260. BOOL WINAPI Asn1X509ContentInfoEncodeEx(
  8261. IN DWORD dwCertEncodingType,
  8262. IN LPCSTR lpszStructType,
  8263. IN PCRYPT_CONTENT_INFO pInfo,
  8264. IN DWORD dwFlags,
  8265. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  8266. OUT OPTIONAL void *pvEncoded,
  8267. IN OUT DWORD *pcbEncoded
  8268. )
  8269. {
  8270. ContentInfo Asn1Info;
  8271. memset(&Asn1Info, 0, sizeof(Asn1Info));
  8272. if (!Asn1X509SetEncodedObjId(pInfo->pszObjId, &Asn1Info.contentType)) {
  8273. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  8274. *((void **) pvEncoded) = NULL;
  8275. *pcbEncoded = 0;
  8276. return FALSE;
  8277. }
  8278. if (pInfo->Content.cbData) {
  8279. Asn1Info.bit_mask |= content_present;
  8280. Asn1X509SetAny(&pInfo->Content, &Asn1Info.content);
  8281. }
  8282. return Asn1InfoEncodeEx(
  8283. ContentInfo_PDU,
  8284. &Asn1Info,
  8285. dwFlags,
  8286. pEncodePara,
  8287. pvEncoded,
  8288. pcbEncoded
  8289. );
  8290. }
  8291. //+-------------------------------------------------------------------------
  8292. // ContentInfo Decode (ASN1 X509)
  8293. //--------------------------------------------------------------------------
  8294. BOOL WINAPI Asn1X509ContentInfoDecodeExCallback(
  8295. IN void *pvAsn1Info,
  8296. IN DWORD dwFlags,
  8297. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  8298. OUT OPTIONAL void *pvStructInfo,
  8299. IN OUT LONG *plRemainExtra
  8300. )
  8301. {
  8302. ContentInfo *pAsn1Info = (ContentInfo *) pvAsn1Info;
  8303. PCRYPT_CONTENT_INFO pInfo = (PCRYPT_CONTENT_INFO) pvStructInfo;
  8304. LONG lRemainExtra = *plRemainExtra;
  8305. BYTE *pbExtra;
  8306. lRemainExtra -= sizeof(CRYPT_CONTENT_INFO);
  8307. if (lRemainExtra < 0) {
  8308. pbExtra = NULL;
  8309. } else {
  8310. memset(pInfo, 0, sizeof(CRYPT_CONTENT_INFO));
  8311. pbExtra = (BYTE *) pInfo + sizeof(CRYPT_CONTENT_INFO);
  8312. }
  8313. Asn1X509GetEncodedObjId(&pAsn1Info->contentType, dwFlags,
  8314. &pInfo->pszObjId, &pbExtra, &lRemainExtra);
  8315. if (pAsn1Info->bit_mask & content_present)
  8316. Asn1X509GetAny(&pAsn1Info->content, dwFlags,
  8317. &pInfo->Content, &pbExtra, &lRemainExtra);
  8318. *plRemainExtra = lRemainExtra;
  8319. return TRUE;
  8320. }
  8321. BOOL WINAPI Asn1X509ContentInfoDecodeEx(
  8322. IN DWORD dwCertEncodingType,
  8323. IN LPCSTR lpszStructType,
  8324. IN const BYTE *pbEncoded,
  8325. IN DWORD cbEncoded,
  8326. IN DWORD dwFlags,
  8327. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  8328. OUT OPTIONAL void *pvStructInfo,
  8329. IN OUT DWORD *pcbStructInfo
  8330. )
  8331. {
  8332. return Asn1InfoDecodeAndAllocEx(
  8333. ContentInfo_PDU,
  8334. pbEncoded,
  8335. cbEncoded,
  8336. dwFlags,
  8337. pDecodePara,
  8338. Asn1X509ContentInfoDecodeExCallback,
  8339. pvStructInfo,
  8340. pcbStructInfo
  8341. );
  8342. }
  8343. //+-------------------------------------------------------------------------
  8344. // ContentInfoSequenceOfAny Encode (ASN1 X509)
  8345. //--------------------------------------------------------------------------
  8346. BOOL WINAPI Asn1X509ContentInfoSequenceOfAnyEncodeEx(
  8347. IN DWORD dwCertEncodingType,
  8348. IN LPCSTR lpszStructType,
  8349. IN PCRYPT_CONTENT_INFO_SEQUENCE_OF_ANY pInfo,
  8350. IN DWORD dwFlags,
  8351. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  8352. OUT OPTIONAL void *pvEncoded,
  8353. IN OUT DWORD *pcbEncoded
  8354. )
  8355. {
  8356. BOOL fResult;
  8357. ContentInfoSeqOfAny Asn1Info;
  8358. memset(&Asn1Info, 0, sizeof(Asn1Info));
  8359. if (!Asn1X509SetEncodedObjId(pInfo->pszObjId, &Asn1Info.contentType))
  8360. goto ErrorReturn;
  8361. if (pInfo->cValue) {
  8362. Asn1Info.bit_mask |= contentSeqOfAny_present;
  8363. if (!Asn1X509SetSeqOfAny(
  8364. pInfo->cValue,
  8365. pInfo->rgValue,
  8366. &Asn1Info.contentSeqOfAny.count,
  8367. &Asn1Info.contentSeqOfAny.value))
  8368. goto ErrorReturn;
  8369. }
  8370. fResult = Asn1InfoEncodeEx(
  8371. ContentInfoSeqOfAny_PDU,
  8372. &Asn1Info,
  8373. dwFlags,
  8374. pEncodePara,
  8375. pvEncoded,
  8376. pcbEncoded
  8377. );
  8378. goto CommonReturn;
  8379. ErrorReturn:
  8380. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  8381. *((void **) pvEncoded) = NULL;
  8382. *pcbEncoded = 0;
  8383. fResult = FALSE;
  8384. CommonReturn:
  8385. Asn1X509FreeSeqOfAny(Asn1Info.contentSeqOfAny.value);
  8386. return fResult;
  8387. }
  8388. //+-------------------------------------------------------------------------
  8389. // ContentInfoSequenceOfAny Decode (ASN1 X509)
  8390. //--------------------------------------------------------------------------
  8391. BOOL WINAPI Asn1X509ContentInfoSequenceOfAnyDecodeExCallback(
  8392. IN void *pvAsn1Info,
  8393. IN DWORD dwFlags,
  8394. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  8395. OUT OPTIONAL void *pvStructInfo,
  8396. IN OUT LONG *plRemainExtra
  8397. )
  8398. {
  8399. ContentInfoSeqOfAny *pAsn1Info = (ContentInfoSeqOfAny *) pvAsn1Info;
  8400. PCRYPT_CONTENT_INFO_SEQUENCE_OF_ANY pInfo =
  8401. (PCRYPT_CONTENT_INFO_SEQUENCE_OF_ANY) pvStructInfo;
  8402. LONG lRemainExtra = *plRemainExtra;
  8403. BYTE *pbExtra;
  8404. lRemainExtra -= sizeof(CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY);
  8405. if (lRemainExtra < 0) {
  8406. pbExtra = NULL;
  8407. } else {
  8408. memset(pInfo, 0, sizeof(CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY));
  8409. pbExtra = (BYTE *) pInfo + sizeof(CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY);
  8410. }
  8411. Asn1X509GetEncodedObjId(&pAsn1Info->contentType, dwFlags,
  8412. &pInfo->pszObjId, &pbExtra, &lRemainExtra);
  8413. if (pAsn1Info->bit_mask & contentSeqOfAny_present)
  8414. Asn1X509GetSeqOfAny(pAsn1Info->contentSeqOfAny.count,
  8415. pAsn1Info->contentSeqOfAny.value, dwFlags,
  8416. &pInfo->cValue, &pInfo->rgValue, &pbExtra, &lRemainExtra);
  8417. *plRemainExtra = lRemainExtra;
  8418. return TRUE;
  8419. }
  8420. BOOL WINAPI Asn1X509ContentInfoSequenceOfAnyDecodeEx(
  8421. IN DWORD dwCertEncodingType,
  8422. IN LPCSTR lpszStructType,
  8423. IN const BYTE *pbEncoded,
  8424. IN DWORD cbEncoded,
  8425. IN DWORD dwFlags,
  8426. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  8427. OUT OPTIONAL void *pvStructInfo,
  8428. IN OUT DWORD *pcbStructInfo
  8429. )
  8430. {
  8431. return Asn1InfoDecodeAndAllocEx(
  8432. ContentInfoSeqOfAny_PDU,
  8433. pbEncoded,
  8434. cbEncoded,
  8435. dwFlags,
  8436. pDecodePara,
  8437. Asn1X509ContentInfoSequenceOfAnyDecodeExCallback,
  8438. pvStructInfo,
  8439. pcbStructInfo
  8440. );
  8441. }
  8442. //+-------------------------------------------------------------------------
  8443. // SequenceOfAny Encode (ASN1 X509)
  8444. //--------------------------------------------------------------------------
  8445. BOOL WINAPI Asn1X509SequenceOfAnyEncodeEx(
  8446. IN DWORD dwCertEncodingType,
  8447. IN LPCSTR lpszStructType,
  8448. IN PCRYPT_SEQUENCE_OF_ANY pInfo,
  8449. IN DWORD dwFlags,
  8450. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  8451. OUT OPTIONAL void *pvEncoded,
  8452. IN OUT DWORD *pcbEncoded
  8453. )
  8454. {
  8455. BOOL fResult;
  8456. SeqOfAny Asn1Info;
  8457. if (!Asn1X509SetSeqOfAny(
  8458. pInfo->cValue,
  8459. pInfo->rgValue,
  8460. &Asn1Info.count,
  8461. &Asn1Info.value))
  8462. goto ErrorReturn;
  8463. fResult = Asn1InfoEncodeEx(
  8464. SeqOfAny_PDU,
  8465. &Asn1Info,
  8466. dwFlags,
  8467. pEncodePara,
  8468. pvEncoded,
  8469. pcbEncoded
  8470. );
  8471. goto CommonReturn;
  8472. ErrorReturn:
  8473. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  8474. *((void **) pvEncoded) = NULL;
  8475. *pcbEncoded = 0;
  8476. fResult = FALSE;
  8477. CommonReturn:
  8478. Asn1X509FreeSeqOfAny(Asn1Info.value);
  8479. return fResult;
  8480. }
  8481. //+-------------------------------------------------------------------------
  8482. // SequenceOfAny Decode (ASN1 X509)
  8483. //--------------------------------------------------------------------------
  8484. BOOL WINAPI Asn1X509SequenceOfAnyDecodeExCallback(
  8485. IN void *pvAsn1Info,
  8486. IN DWORD dwFlags,
  8487. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  8488. OUT OPTIONAL void *pvStructInfo,
  8489. IN OUT LONG *plRemainExtra
  8490. )
  8491. {
  8492. SeqOfAny *pAsn1Info = (SeqOfAny *) pvAsn1Info;
  8493. PCRYPT_SEQUENCE_OF_ANY pInfo = (PCRYPT_SEQUENCE_OF_ANY) pvStructInfo;
  8494. LONG lRemainExtra = *plRemainExtra;
  8495. BYTE *pbExtra;
  8496. lRemainExtra -= sizeof(CRYPT_SEQUENCE_OF_ANY);
  8497. if (lRemainExtra < 0) {
  8498. pbExtra = NULL;
  8499. } else {
  8500. pbExtra = (BYTE *) pInfo + sizeof(CRYPT_SEQUENCE_OF_ANY);
  8501. }
  8502. Asn1X509GetSeqOfAny(pAsn1Info->count, pAsn1Info->value, dwFlags,
  8503. &pInfo->cValue, &pInfo->rgValue, &pbExtra, &lRemainExtra);
  8504. *plRemainExtra = lRemainExtra;
  8505. return TRUE;
  8506. }
  8507. BOOL WINAPI Asn1X509SequenceOfAnyDecodeEx(
  8508. IN DWORD dwCertEncodingType,
  8509. IN LPCSTR lpszStructType,
  8510. IN const BYTE *pbEncoded,
  8511. IN DWORD cbEncoded,
  8512. IN DWORD dwFlags,
  8513. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  8514. OUT OPTIONAL void *pvStructInfo,
  8515. IN OUT DWORD *pcbStructInfo
  8516. )
  8517. {
  8518. return Asn1InfoDecodeAndAllocEx(
  8519. SeqOfAny_PDU,
  8520. pbEncoded,
  8521. cbEncoded,
  8522. dwFlags,
  8523. pDecodePara,
  8524. Asn1X509SequenceOfAnyDecodeExCallback,
  8525. pvStructInfo,
  8526. pcbStructInfo
  8527. );
  8528. }
  8529. //+-------------------------------------------------------------------------
  8530. // UTC TIME Encode/Decode
  8531. //--------------------------------------------------------------------------
  8532. BOOL WINAPI Asn1UtcTimeEncodeEx(
  8533. IN DWORD dwCertEncodingType,
  8534. IN LPCSTR lpszStructType,
  8535. IN FILETIME * pFileTime,
  8536. IN DWORD dwFlags,
  8537. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  8538. OUT OPTIONAL void *pvEncoded,
  8539. IN OUT DWORD *pcbEncoded
  8540. ) {
  8541. assert(pcbEncoded != NULL);
  8542. BOOL fResult;
  8543. UtcTime utcTime;
  8544. memset(&utcTime, 0, sizeof(UtcTime));
  8545. if( !PkiAsn1ToUTCTime(pFileTime, &utcTime) )
  8546. goto PkiAsn1ToUTCTimeError;
  8547. fResult = Asn1InfoEncodeEx(
  8548. UtcTime_PDU,
  8549. &utcTime,
  8550. dwFlags,
  8551. pEncodePara,
  8552. pvEncoded,
  8553. pcbEncoded
  8554. );
  8555. CommonReturn:
  8556. return fResult;
  8557. ErrorReturn:
  8558. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  8559. *((void **) pvEncoded) = NULL;
  8560. *pcbEncoded = 0;
  8561. fResult = FALSE;
  8562. goto CommonReturn;
  8563. SET_ERROR(PkiAsn1ToUTCTimeError, CRYPT_E_BAD_ENCODE);
  8564. }
  8565. BOOL WINAPI Asn1UtcTimeDecodeExCallback(
  8566. IN void *pvAsn1Info,
  8567. IN DWORD dwFlags,
  8568. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  8569. OUT OPTIONAL void *pvStructInfo,
  8570. IN OUT LONG *plRemainExtra
  8571. )
  8572. {
  8573. BOOL fResult;
  8574. UtcTime *putcTime = (UtcTime *) pvAsn1Info;
  8575. LPFILETIME pInfo = (LPFILETIME) pvStructInfo;
  8576. *plRemainExtra -= sizeof(FILETIME);
  8577. if (*plRemainExtra >= 0) {
  8578. if(!PkiAsn1FromUTCTime(putcTime, pInfo))
  8579. goto DecodeError;
  8580. }
  8581. fResult = TRUE;
  8582. CommonReturn:
  8583. return fResult;
  8584. ErrorReturn:
  8585. fResult = FALSE;
  8586. goto CommonReturn;
  8587. SET_ERROR(DecodeError, CRYPT_E_BAD_ENCODE)
  8588. }
  8589. BOOL WINAPI Asn1UtcTimeDecodeEx(
  8590. IN DWORD dwCertEncodingType,
  8591. IN LPCSTR lpszStructType,
  8592. IN const BYTE *pbEncoded,
  8593. IN DWORD cbEncoded,
  8594. IN DWORD dwFlags,
  8595. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  8596. OUT OPTIONAL void *pvStructInfo,
  8597. IN OUT DWORD *pcbStructInfo
  8598. )
  8599. {
  8600. return Asn1InfoDecodeAndAllocEx(
  8601. UtcTime_PDU,
  8602. pbEncoded,
  8603. cbEncoded,
  8604. dwFlags,
  8605. pDecodePara,
  8606. Asn1UtcTimeDecodeExCallback,
  8607. pvStructInfo,
  8608. pcbStructInfo
  8609. );
  8610. }
  8611. BOOL WINAPI Asn1TimeStampRequestInfoEncodeEx(
  8612. IN DWORD dwCertEncodingType,
  8613. IN LPCSTR lpszStructType,
  8614. IN PCRYPT_TIME_STAMP_REQUEST_INFO pInfo,
  8615. IN DWORD dwFlags,
  8616. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  8617. OUT OPTIONAL void *pvEncoded,
  8618. IN OUT DWORD *pcbEncoded
  8619. )
  8620. {
  8621. BOOL fResult;
  8622. DWORD pdu;
  8623. union {
  8624. TimeStampRequest tsr;
  8625. TimeStampRequestOTS tsrocs;
  8626. } timeStampReq;
  8627. memset(&timeStampReq, 0, sizeof(TimeStampRequest));
  8628. if( !Asn1X509SetEncodedObjId(pInfo->pszTimeStampAlgorithm, &timeStampReq.tsr.timeStampAlgorithm) ||
  8629. !Asn1X509SetEncodedObjId(pInfo->pszContentType, &timeStampReq.tsr.content.contentType) )
  8630. goto Asn1X509SetEncodedObjIdError;
  8631. // only write content if it is present
  8632. if(pInfo->Content.cbData != 0)
  8633. timeStampReq.tsr.content.bit_mask |= content_present;
  8634. if(!strcmp(pInfo->pszContentType, szOID_RSA_data)) {
  8635. Asn1X509SetOctetString(&pInfo->Content, &timeStampReq.tsrocs.contentOTS.contentOTS);
  8636. pdu = TimeStampRequestOTS_PDU;
  8637. }
  8638. else {
  8639. Asn1X509SetAny(&pInfo->Content, &timeStampReq.tsr.content.content);
  8640. pdu = TimeStampRequest_PDU;
  8641. }
  8642. if (pInfo->cAttribute > 0) {
  8643. if (!Asn1X509SetAttributes(pInfo->cAttribute, pInfo->rgAttribute,
  8644. &timeStampReq.tsr.attributesTS))
  8645. goto ErrorReturn;
  8646. timeStampReq.tsr.bit_mask |= attributesTS_present;
  8647. }
  8648. fResult = Asn1InfoEncodeEx(
  8649. pdu,
  8650. &timeStampReq,
  8651. dwFlags,
  8652. pEncodePara,
  8653. pvEncoded,
  8654. pcbEncoded
  8655. );
  8656. goto CommonReturn;
  8657. CommonReturn:
  8658. Asn1X509FreeAttributes(&timeStampReq.tsr.attributesTS);
  8659. return fResult;
  8660. ErrorReturn:
  8661. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  8662. *((void **) pvEncoded) = NULL;
  8663. *pcbEncoded = 0;
  8664. fResult = FALSE;
  8665. goto CommonReturn;
  8666. TRACE_ERROR(Asn1X509SetEncodedObjIdError);
  8667. }
  8668. //+-------------------------------------------------------------------------
  8669. // Decode the Time Stamp Request Info (ASN1 X509 v3 ASN.1)
  8670. //--------------------------------------------------------------------------
  8671. BOOL WINAPI Asn1TimeStampRequestInfoDecodeExCallback(
  8672. IN void *pvAsn1Info,
  8673. IN DWORD dwFlags,
  8674. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  8675. OUT OPTIONAL void *pvStructInfo,
  8676. IN OUT LONG *plRemainExtra
  8677. )
  8678. {
  8679. BOOL fResult;
  8680. TimeStampRequest *pTimeStampReq = (TimeStampRequest *) pvAsn1Info;
  8681. PCRYPT_TIME_STAMP_REQUEST_INFO pInfo =
  8682. (PCRYPT_TIME_STAMP_REQUEST_INFO) pvStructInfo;
  8683. OctetStringType *pOctetStringType = NULL;
  8684. LONG lRemainExtra = *plRemainExtra;
  8685. BYTE *pbExtra;
  8686. lRemainExtra -= sizeof(CRYPT_TIME_STAMP_REQUEST_INFO);
  8687. if (lRemainExtra < 0) {
  8688. pbExtra = NULL;
  8689. } else {
  8690. // Default all optional fields to zero
  8691. memset(pInfo, 0, sizeof(CRYPT_TIME_STAMP_REQUEST_INFO));
  8692. // Update fields not needing extra memory after the CERT_INFO
  8693. pbExtra = (BYTE *) pInfo + sizeof(CRYPT_TIME_STAMP_REQUEST_INFO);
  8694. }
  8695. Asn1X509GetEncodedObjId( &pTimeStampReq->timeStampAlgorithm,
  8696. dwFlags,
  8697. &pInfo->pszTimeStampAlgorithm,
  8698. &pbExtra,
  8699. &lRemainExtra
  8700. );
  8701. Asn1X509GetEncodedObjId( &pTimeStampReq->content.contentType,
  8702. dwFlags,
  8703. &pInfo->pszContentType,
  8704. &pbExtra,
  8705. &lRemainExtra
  8706. );
  8707. if(pTimeStampReq->content.bit_mask == content_present) {
  8708. // OctetStrings will be smaller, so when doing byte counting go to
  8709. // ANY which will requre more room for decode...
  8710. if(pInfo && !strcmp(pInfo->pszContentType, szOID_RSA_data)) {
  8711. if (!Asn1InfoDecodeAndAlloc(
  8712. OctetStringType_PDU,
  8713. (const unsigned char *) pTimeStampReq->content.content.encoded,
  8714. pTimeStampReq->content.content.length,
  8715. (void **) &pOctetStringType))
  8716. goto Asn1InfoDecodeAndAllocError;
  8717. Asn1X509GetOctetString(pOctetStringType, dwFlags,
  8718. &pInfo->Content, &pbExtra, &lRemainExtra);
  8719. }
  8720. else
  8721. Asn1X509GetAny(&pTimeStampReq->content.content, dwFlags,
  8722. &pInfo->Content, &pbExtra, &lRemainExtra);
  8723. }
  8724. if (pTimeStampReq->bit_mask & attributesTS_present) {
  8725. Asn1X509GetAttributes(&pTimeStampReq->attributesTS, dwFlags,
  8726. &pInfo->cAttribute, &pInfo->rgAttribute, &pbExtra, &lRemainExtra);
  8727. }
  8728. fResult = TRUE;
  8729. CommonReturn:
  8730. Asn1InfoFree(OctetStringType_PDU, pOctetStringType);
  8731. *plRemainExtra = lRemainExtra;
  8732. return fResult;
  8733. ErrorReturn:
  8734. fResult = FALSE;
  8735. goto CommonReturn;
  8736. TRACE_ERROR(Asn1InfoDecodeAndAllocError);
  8737. }
  8738. BOOL WINAPI Asn1TimeStampRequestInfoDecodeEx(
  8739. IN DWORD dwCertEncodingType,
  8740. IN LPCSTR lpszStructType,
  8741. IN const BYTE *pbEncoded,
  8742. IN DWORD cbEncoded,
  8743. IN DWORD dwFlags,
  8744. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  8745. OUT OPTIONAL void *pvStructInfo,
  8746. IN OUT DWORD *pcbStructInfo
  8747. )
  8748. {
  8749. return Asn1InfoDecodeAndAllocEx(
  8750. TimeStampRequest_PDU,
  8751. pbEncoded,
  8752. cbEncoded,
  8753. dwFlags,
  8754. pDecodePara,
  8755. Asn1TimeStampRequestInfoDecodeExCallback,
  8756. pvStructInfo,
  8757. pcbStructInfo
  8758. );
  8759. }
  8760. //+-------------------------------------------------------------------------
  8761. // Set/Free/Get CTL Usage object identifiers
  8762. //--------------------------------------------------------------------------
  8763. BOOL Asn1X509SetCtlUsage(
  8764. IN PCTL_USAGE pUsage,
  8765. OUT EnhancedKeyUsage *pAsn1
  8766. )
  8767. {
  8768. DWORD cId;
  8769. LPSTR *ppszId;
  8770. UsageIdentifier *pAsn1Id;
  8771. pAsn1->count = 0;
  8772. pAsn1->value = NULL;
  8773. cId = pUsage->cUsageIdentifier;
  8774. if (0 == cId)
  8775. return TRUE;
  8776. pAsn1Id = (UsageIdentifier *) PkiNonzeroAlloc(cId * sizeof(UsageIdentifier));
  8777. if (pAsn1Id == NULL)
  8778. return FALSE;
  8779. pAsn1->count = cId;
  8780. pAsn1->value = pAsn1Id;
  8781. ppszId = pUsage->rgpszUsageIdentifier;
  8782. for ( ; cId > 0; cId--, ppszId++, pAsn1Id++) {
  8783. if (!Asn1X509SetEncodedObjId(*ppszId, pAsn1Id))
  8784. return FALSE;
  8785. }
  8786. return TRUE;
  8787. }
  8788. void Asn1X509FreeCtlUsage(
  8789. IN EnhancedKeyUsage *pAsn1)
  8790. {
  8791. if (pAsn1->value) {
  8792. PkiFree(pAsn1->value);
  8793. pAsn1->value = NULL;
  8794. }
  8795. }
  8796. void Asn1X509GetCtlUsage(
  8797. IN EnhancedKeyUsage *pAsn1,
  8798. IN DWORD dwFlags,
  8799. OUT PCTL_USAGE pUsage,
  8800. IN OUT BYTE **ppbExtra,
  8801. IN OUT LONG *plRemainExtra
  8802. )
  8803. {
  8804. LONG lRemainExtra = *plRemainExtra;
  8805. BYTE *pbExtra = *ppbExtra;
  8806. LONG lAlignExtra;
  8807. DWORD cId;
  8808. UsageIdentifier *pAsn1Id;
  8809. LPSTR *ppszId;
  8810. cId = pAsn1->count;
  8811. lAlignExtra = INFO_LEN_ALIGN(cId * sizeof(LPSTR));
  8812. lRemainExtra -= lAlignExtra;
  8813. if (lRemainExtra >= 0) {
  8814. pUsage->cUsageIdentifier = cId;
  8815. ppszId = (LPSTR *) pbExtra;
  8816. pUsage->rgpszUsageIdentifier = ppszId;
  8817. pbExtra += lAlignExtra;
  8818. } else
  8819. ppszId = NULL;
  8820. pAsn1Id = pAsn1->value;
  8821. for ( ; cId > 0; cId--, pAsn1Id++, ppszId++)
  8822. Asn1X509GetEncodedObjId(pAsn1Id, dwFlags, ppszId, &pbExtra, &lRemainExtra);
  8823. *plRemainExtra = lRemainExtra;
  8824. *ppbExtra = pbExtra;
  8825. }
  8826. //+-------------------------------------------------------------------------
  8827. // CTL Usage (Enhanced Key Usage) Encode (ASN1 X509)
  8828. //--------------------------------------------------------------------------
  8829. BOOL WINAPI Asn1X509CtlUsageEncodeEx(
  8830. IN DWORD dwCertEncodingType,
  8831. IN LPCSTR lpszStructType,
  8832. IN PCTL_USAGE pInfo,
  8833. IN DWORD dwFlags,
  8834. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  8835. OUT OPTIONAL void *pvEncoded,
  8836. IN OUT DWORD *pcbEncoded
  8837. )
  8838. {
  8839. BOOL fResult;
  8840. EnhancedKeyUsage Asn1Info;
  8841. if (!Asn1X509SetCtlUsage(pInfo, &Asn1Info)) {
  8842. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  8843. *((void **) pvEncoded) = NULL;
  8844. *pcbEncoded = 0;
  8845. fResult = FALSE;
  8846. } else
  8847. fResult = Asn1InfoEncodeEx(
  8848. EnhancedKeyUsage_PDU,
  8849. &Asn1Info,
  8850. dwFlags,
  8851. pEncodePara,
  8852. pvEncoded,
  8853. pcbEncoded
  8854. );
  8855. Asn1X509FreeCtlUsage(&Asn1Info);
  8856. return fResult;
  8857. }
  8858. //+-------------------------------------------------------------------------
  8859. // CTL Usage (Enhanced Key Usage) Decode (ASN1 X509)
  8860. //--------------------------------------------------------------------------
  8861. BOOL WINAPI Asn1X509CtlUsageDecodeExCallback(
  8862. IN void *pvAsn1Info,
  8863. IN DWORD dwFlags,
  8864. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  8865. OUT OPTIONAL void *pvStructInfo,
  8866. IN OUT LONG *plRemainExtra
  8867. )
  8868. {
  8869. EnhancedKeyUsage *pAsn1Info = (EnhancedKeyUsage *) pvAsn1Info;
  8870. PCTL_USAGE pInfo = (PCTL_USAGE) pvStructInfo;
  8871. LONG lRemainExtra = *plRemainExtra;
  8872. BYTE *pbExtra;
  8873. lRemainExtra -= sizeof(CTL_USAGE);
  8874. if (lRemainExtra < 0) {
  8875. pbExtra = NULL;
  8876. } else
  8877. pbExtra = (BYTE *) pInfo + sizeof(CTL_USAGE);
  8878. Asn1X509GetCtlUsage(pAsn1Info, dwFlags, pInfo, &pbExtra, &lRemainExtra);
  8879. *plRemainExtra = lRemainExtra;
  8880. return TRUE;
  8881. }
  8882. BOOL WINAPI Asn1X509CtlUsageDecodeEx(
  8883. IN DWORD dwCertEncodingType,
  8884. IN LPCSTR lpszStructType,
  8885. IN const BYTE *pbEncoded,
  8886. IN DWORD cbEncoded,
  8887. IN DWORD dwFlags,
  8888. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  8889. OUT OPTIONAL void *pvStructInfo,
  8890. IN OUT DWORD *pcbStructInfo
  8891. )
  8892. {
  8893. return Asn1InfoDecodeAndAllocEx(
  8894. EnhancedKeyUsage_PDU,
  8895. pbEncoded,
  8896. cbEncoded,
  8897. dwFlags,
  8898. pDecodePara,
  8899. Asn1X509CtlUsageDecodeExCallback,
  8900. pvStructInfo,
  8901. pcbStructInfo
  8902. );
  8903. }
  8904. //+-------------------------------------------------------------------------
  8905. // Set/Free/Get CTL Entries
  8906. //--------------------------------------------------------------------------
  8907. BOOL Asn1X509SetCtlEntries(
  8908. IN DWORD cEntry,
  8909. IN PCTL_ENTRY pEntry,
  8910. OUT TrustedSubjects *pAsn1
  8911. )
  8912. {
  8913. TrustedSubject *pAsn1Entry;
  8914. pAsn1->value = NULL;
  8915. pAsn1->count = 0;
  8916. if (cEntry == 0)
  8917. return TRUE;
  8918. pAsn1Entry = (TrustedSubject *) PkiZeroAlloc(
  8919. cEntry * sizeof(TrustedSubject));
  8920. if (pAsn1Entry == NULL)
  8921. return FALSE;
  8922. pAsn1->value = pAsn1Entry;
  8923. pAsn1->count = cEntry;
  8924. for ( ; cEntry > 0; cEntry--, pEntry++, pAsn1Entry++) {
  8925. Asn1X509SetOctetString(&pEntry->SubjectIdentifier,
  8926. &pAsn1Entry->subjectIdentifier);
  8927. if (pEntry->cAttribute > 0) {
  8928. pAsn1Entry->bit_mask |= subjectAttributes_present;
  8929. if (!Asn1X509SetAttributes(pEntry->cAttribute, pEntry->rgAttribute,
  8930. &pAsn1Entry->subjectAttributes))
  8931. return FALSE;
  8932. }
  8933. }
  8934. return TRUE;
  8935. }
  8936. void Asn1X509FreeCtlEntries(
  8937. IN TrustedSubjects *pAsn1)
  8938. {
  8939. if (pAsn1->value) {
  8940. DWORD cEntry = pAsn1->count;
  8941. TrustedSubject *pAsn1Entry = pAsn1->value;
  8942. for ( ; cEntry > 0; cEntry--, pAsn1Entry++)
  8943. Asn1X509FreeAttributes(&pAsn1Entry->subjectAttributes);
  8944. PkiFree(pAsn1->value);
  8945. pAsn1->value = NULL;
  8946. }
  8947. pAsn1->count = 0;
  8948. }
  8949. void Asn1X509GetCtlEntries(
  8950. IN TrustedSubjects *pAsn1,
  8951. IN DWORD dwFlags,
  8952. OUT DWORD *pcEntry,
  8953. OUT PCTL_ENTRY *ppEntry,
  8954. IN OUT BYTE **ppbExtra,
  8955. IN OUT LONG *plRemainExtra
  8956. )
  8957. {
  8958. LONG lRemainExtra = *plRemainExtra;
  8959. BYTE *pbExtra = *ppbExtra;
  8960. LONG lAlignExtra;
  8961. DWORD cEntry;
  8962. TrustedSubject *pAsn1Entry;
  8963. PCTL_ENTRY pEntry;
  8964. cEntry = pAsn1->count;
  8965. lAlignExtra = INFO_LEN_ALIGN(cEntry * sizeof(CTL_ENTRY));
  8966. lRemainExtra -= lAlignExtra;
  8967. if (lRemainExtra >= 0) {
  8968. *pcEntry = cEntry;
  8969. pEntry = (PCTL_ENTRY) pbExtra;
  8970. memset(pEntry, 0, cEntry * sizeof(CTL_ENTRY));
  8971. *ppEntry = pEntry;
  8972. pbExtra += lAlignExtra;
  8973. } else
  8974. pEntry = NULL;
  8975. pAsn1Entry = pAsn1->value;
  8976. for ( ; cEntry > 0; cEntry--, pAsn1Entry++, pEntry++) {
  8977. // SubjectIdentifier
  8978. Asn1X509GetOctetString(&pAsn1Entry->subjectIdentifier, dwFlags,
  8979. &pEntry->SubjectIdentifier, &pbExtra, &lRemainExtra);
  8980. // Attributes
  8981. if (pAsn1Entry->bit_mask & subjectAttributes_present) {
  8982. Asn1X509GetAttributes(&pAsn1Entry->subjectAttributes, dwFlags,
  8983. &pEntry->cAttribute, &pEntry->rgAttribute,
  8984. &pbExtra, &lRemainExtra);
  8985. }
  8986. }
  8987. *plRemainExtra = lRemainExtra;
  8988. *ppbExtra = pbExtra;
  8989. }
  8990. //+-------------------------------------------------------------------------
  8991. // Encode the CTL Info (ASN1 X509 ASN.1)
  8992. //--------------------------------------------------------------------------
  8993. BOOL WINAPI Asn1X509CtlInfoEncodeEx(
  8994. IN DWORD dwCertEncodingType,
  8995. IN LPCSTR lpszStructType,
  8996. IN PCTL_INFO pInfo,
  8997. IN DWORD dwFlags,
  8998. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  8999. OUT OPTIONAL void *pvEncoded,
  9000. IN OUT DWORD *pcbEncoded
  9001. )
  9002. {
  9003. BOOL fResult;
  9004. CertificateTrustList Ctl;
  9005. memset(&Ctl, 0, sizeof(Ctl));
  9006. if (pInfo->dwVersion != 0) {
  9007. #ifdef OSS_CRYPT_ASN1
  9008. Ctl.CertificateTrustList_version = pInfo->dwVersion;
  9009. #else
  9010. Ctl.version = pInfo->dwVersion;
  9011. #endif // OSS_CRYPT_ASN1
  9012. Ctl.bit_mask |= CertificateTrustList_version_present;
  9013. }
  9014. if (!Asn1X509SetCtlUsage(&pInfo->SubjectUsage, &Ctl.subjectUsage))
  9015. goto ErrorReturn;
  9016. if (pInfo->ListIdentifier.cbData) {
  9017. Asn1X509SetOctetString(&pInfo->ListIdentifier, &Ctl.listIdentifier);
  9018. Ctl.bit_mask |= listIdentifier_present;
  9019. }
  9020. if (pInfo->SequenceNumber.cbData) {
  9021. if (!Asn1X509SetHugeInteger(&pInfo->SequenceNumber,
  9022. &Ctl.sequenceNumber))
  9023. goto ErrorReturn;
  9024. Ctl.bit_mask |= sequenceNumber_present;
  9025. }
  9026. if (!PkiAsn1ToChoiceOfTime(&pInfo->ThisUpdate,
  9027. &Ctl.ctlThisUpdate.choice,
  9028. &Ctl.ctlThisUpdate.u.generalTime,
  9029. &Ctl.ctlThisUpdate.u.utcTime
  9030. ))
  9031. goto EncodeError;
  9032. if (pInfo->NextUpdate.dwLowDateTime || pInfo->NextUpdate.dwHighDateTime) {
  9033. Ctl.bit_mask |= ctlNextUpdate_present;
  9034. if (!PkiAsn1ToChoiceOfTime(&pInfo->NextUpdate,
  9035. &Ctl.ctlNextUpdate.choice,
  9036. &Ctl.ctlNextUpdate.u.generalTime,
  9037. &Ctl.ctlNextUpdate.u.utcTime
  9038. ))
  9039. goto EncodeError;
  9040. }
  9041. if (!Asn1X509SetAlgorithm(&pInfo->SubjectAlgorithm, &Ctl.subjectAlgorithm))
  9042. goto ErrorReturn;
  9043. if (pInfo->cCTLEntry) {
  9044. if (!Asn1X509SetCtlEntries(pInfo->cCTLEntry, pInfo->rgCTLEntry,
  9045. &Ctl.trustedSubjects))
  9046. goto ErrorReturn;
  9047. Ctl.bit_mask |= trustedSubjects_present;
  9048. }
  9049. if (pInfo->cExtension) {
  9050. if (!Asn1X509SetExtensions(pInfo->cExtension, pInfo->rgExtension,
  9051. &Ctl.ctlExtensions))
  9052. goto ErrorReturn;
  9053. Ctl.bit_mask |= ctlExtensions_present;
  9054. }
  9055. fResult = Asn1InfoEncodeEx(
  9056. CertificateTrustList_PDU,
  9057. &Ctl,
  9058. dwFlags,
  9059. pEncodePara,
  9060. pvEncoded,
  9061. pcbEncoded
  9062. );
  9063. goto CommonReturn;
  9064. EncodeError:
  9065. SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
  9066. ErrorReturn:
  9067. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  9068. *((void **) pvEncoded) = NULL;
  9069. *pcbEncoded = 0;
  9070. fResult = FALSE;
  9071. CommonReturn:
  9072. Asn1X509FreeCtlUsage(&Ctl.subjectUsage);
  9073. Asn1X509FreeHugeInteger(&Ctl.sequenceNumber);
  9074. Asn1X509FreeCtlEntries(&Ctl.trustedSubjects);
  9075. Asn1X509FreeExtensions(&Ctl.ctlExtensions);
  9076. return fResult;
  9077. }
  9078. //+-------------------------------------------------------------------------
  9079. // Decode the CTL Info (ASN1 X509 ASN.1)
  9080. //--------------------------------------------------------------------------
  9081. BOOL WINAPI Asn1X509CtlInfoDecodeExCallback(
  9082. IN void *pvAsn1Info,
  9083. IN DWORD dwFlags,
  9084. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  9085. OUT OPTIONAL void *pvStructInfo,
  9086. IN OUT LONG *plRemainExtra
  9087. )
  9088. {
  9089. BOOL fResult;
  9090. CertificateTrustList *pCtl = (CertificateTrustList *) pvAsn1Info;
  9091. PCTL_INFO pInfo = (PCTL_INFO) pvStructInfo;
  9092. LONG lRemainExtra = *plRemainExtra;
  9093. BYTE *pbExtra;
  9094. lRemainExtra -= sizeof(CTL_INFO);
  9095. if (lRemainExtra < 0) {
  9096. pbExtra = NULL;
  9097. } else {
  9098. // Default all optional fields to zero
  9099. memset(pInfo, 0, sizeof(CTL_INFO));
  9100. // Update fields not needing extra memory after the CTL_INFO
  9101. if (pCtl->bit_mask &
  9102. CertificateTrustList_version_present)
  9103. #ifdef OSS_CRYPT_ASN1
  9104. pInfo->dwVersion =
  9105. pCtl->CertificateTrustList_version;
  9106. #else
  9107. pInfo->dwVersion = pCtl->version;
  9108. #endif // OSS_CRYPT_ASN1
  9109. if (!PkiAsn1FromChoiceOfTime(pCtl->ctlThisUpdate.choice,
  9110. &pCtl->ctlThisUpdate.u.generalTime,
  9111. &pCtl->ctlThisUpdate.u.utcTime,
  9112. &pInfo->ThisUpdate))
  9113. goto DecodeError;
  9114. if (pCtl->bit_mask & ctlNextUpdate_present) {
  9115. if (!PkiAsn1FromChoiceOfTime(pCtl->ctlNextUpdate.choice,
  9116. &pCtl->ctlNextUpdate.u.generalTime,
  9117. &pCtl->ctlNextUpdate.u.utcTime,
  9118. &pInfo->NextUpdate))
  9119. goto DecodeError;
  9120. }
  9121. pbExtra = (BYTE *) pInfo + sizeof(CTL_INFO);
  9122. }
  9123. Asn1X509GetCtlUsage(&pCtl->subjectUsage, dwFlags,
  9124. &pInfo->SubjectUsage, &pbExtra, &lRemainExtra);
  9125. if (pCtl->bit_mask & listIdentifier_present)
  9126. // Always copy to force alignment
  9127. Asn1X509GetOctetString(&pCtl->listIdentifier,
  9128. dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG,
  9129. &pInfo->ListIdentifier, &pbExtra, &lRemainExtra);
  9130. if (pCtl->bit_mask & sequenceNumber_present)
  9131. Asn1X509GetHugeInteger(&pCtl->sequenceNumber, dwFlags,
  9132. &pInfo->SequenceNumber, &pbExtra, &lRemainExtra);
  9133. Asn1X509GetAlgorithm(&pCtl->subjectAlgorithm, dwFlags,
  9134. &pInfo->SubjectAlgorithm, &pbExtra, &lRemainExtra);
  9135. if (pCtl->bit_mask & trustedSubjects_present)
  9136. Asn1X509GetCtlEntries(&pCtl->trustedSubjects, dwFlags,
  9137. &pInfo->cCTLEntry, &pInfo->rgCTLEntry, &pbExtra, &lRemainExtra);
  9138. if (pCtl->bit_mask & ctlExtensions_present)
  9139. Asn1X509GetExtensions(&pCtl->ctlExtensions, dwFlags,
  9140. &pInfo->cExtension, &pInfo->rgExtension, &pbExtra, &lRemainExtra);
  9141. fResult = TRUE;
  9142. CommonReturn:
  9143. *plRemainExtra = lRemainExtra;
  9144. return fResult;
  9145. ErrorReturn:
  9146. fResult = FALSE;
  9147. goto CommonReturn;
  9148. SET_ERROR(DecodeError, CRYPT_E_BAD_ENCODE)
  9149. }
  9150. BOOL WINAPI Asn1X509CtlInfoDecodeEx(
  9151. IN DWORD dwCertEncodingType,
  9152. IN LPCSTR lpszStructType,
  9153. IN const BYTE *pbEncoded,
  9154. IN DWORD cbEncoded,
  9155. IN DWORD dwFlags,
  9156. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  9157. OUT OPTIONAL void *pvStructInfo,
  9158. IN OUT DWORD *pcbStructInfo
  9159. )
  9160. {
  9161. return Asn1InfoDecodeAndAllocEx(
  9162. CertificateTrustList_PDU,
  9163. pbEncoded,
  9164. cbEncoded,
  9165. dwFlags,
  9166. pDecodePara,
  9167. Asn1X509CtlInfoDecodeExCallback,
  9168. pvStructInfo,
  9169. pcbStructInfo
  9170. );
  9171. }
  9172. BOOL WINAPI Asn1X509PKIXUserNoticeEncodeEx(
  9173. IN DWORD dwCertEncodingType,
  9174. IN LPCSTR lpszStructType,
  9175. IN PCERT_POLICY_QUALIFIER_USER_NOTICE pInfo,
  9176. IN DWORD dwFlags,
  9177. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  9178. OUT OPTIONAL void *pvEncoded,
  9179. IN OUT DWORD *pcbEncoded
  9180. )
  9181. {
  9182. BOOL fResult;
  9183. UserNotice Asn1Info;
  9184. memset (&Asn1Info, 0, sizeof(Asn1Info));
  9185. if (pInfo->pNoticeReference != NULL)
  9186. {
  9187. Asn1Info.bit_mask |= noticeRef_present;
  9188. Asn1Info.noticeRef.organization = pInfo->pNoticeReference->pszOrganization;
  9189. Asn1Info.noticeRef.noticeNumbers.count = pInfo->pNoticeReference->cNoticeNumbers;
  9190. #ifdef OSS_CRYPT_ASN1
  9191. Asn1Info.noticeRef.noticeNumbers.value = pInfo->pNoticeReference->rgNoticeNumbers;
  9192. #else
  9193. Asn1Info.noticeRef.noticeNumbers.value = (ASN1int32_t *) pInfo->pNoticeReference->rgNoticeNumbers;
  9194. #endif // OSS_CRYPT_ASN1
  9195. }
  9196. if (pInfo->pszDisplayText)
  9197. {
  9198. Asn1Info.bit_mask |= explicitText_present;
  9199. Asn1Info.explicitText.choice = theBMPString_chosen;
  9200. Asn1Info.explicitText.u.theBMPString.length = wcslen(pInfo->pszDisplayText);
  9201. Asn1Info.explicitText.u.theBMPString.value = (unsigned short *) pInfo->pszDisplayText;
  9202. }
  9203. fResult = Asn1InfoEncodeEx(
  9204. UserNotice_PDU,
  9205. &Asn1Info,
  9206. dwFlags,
  9207. pEncodePara,
  9208. pvEncoded,
  9209. pcbEncoded
  9210. );
  9211. return fResult;
  9212. }
  9213. BOOL WINAPI Asn1X509PKIXUserNoticeDecodeExCallback(
  9214. IN void *pvAsn1Info,
  9215. IN DWORD dwFlags,
  9216. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  9217. OUT OPTIONAL void *pvStructInfo,
  9218. IN OUT LONG *plRemainExtra
  9219. )
  9220. {
  9221. UserNotice *pAsn1UserNotice = (UserNotice *) pvAsn1Info;
  9222. PCERT_POLICY_QUALIFIER_USER_NOTICE pInfo =
  9223. (PCERT_POLICY_QUALIFIER_USER_NOTICE) pvStructInfo;
  9224. LONG lRemainExtra = *plRemainExtra;
  9225. BYTE *pbExtra;
  9226. lRemainExtra -= sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE);
  9227. if (lRemainExtra < 0) {
  9228. pbExtra = NULL;
  9229. } else {
  9230. memset(pInfo, 0, sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE));
  9231. pbExtra = (BYTE *) pInfo + sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE);
  9232. }
  9233. // check to see if there is a notice reference
  9234. if (pAsn1UserNotice->bit_mask & noticeRef_present)
  9235. {
  9236. lRemainExtra -= sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE);
  9237. if (lRemainExtra >= 0)
  9238. {
  9239. pInfo->pNoticeReference = (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE) pbExtra;
  9240. memset(pInfo->pNoticeReference, 0, sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE));
  9241. pbExtra += sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE);
  9242. }
  9243. lRemainExtra -= INFO_LEN_ALIGN(strlen(pAsn1UserNotice->noticeRef.organization)+1);
  9244. if (lRemainExtra >= 0)
  9245. {
  9246. pInfo->pNoticeReference->pszOrganization = (LPSTR) pbExtra;
  9247. strcpy(pInfo->pNoticeReference->pszOrganization, pAsn1UserNotice->noticeRef.organization);
  9248. pbExtra += INFO_LEN_ALIGN(strlen(pAsn1UserNotice->noticeRef.organization)+1);
  9249. }
  9250. lRemainExtra -= pAsn1UserNotice->noticeRef.noticeNumbers.count * sizeof(int);
  9251. if (lRemainExtra >= 0)
  9252. {
  9253. pInfo->pNoticeReference->cNoticeNumbers = pAsn1UserNotice->noticeRef.noticeNumbers.count;
  9254. pInfo->pNoticeReference->rgNoticeNumbers = (int *) pbExtra;
  9255. memcpy(
  9256. pInfo->pNoticeReference->rgNoticeNumbers,
  9257. pAsn1UserNotice->noticeRef.noticeNumbers.value,
  9258. pAsn1UserNotice->noticeRef.noticeNumbers.count * sizeof(int));
  9259. pbExtra += pAsn1UserNotice->noticeRef.noticeNumbers.count * sizeof(int);
  9260. }
  9261. }
  9262. else if (lRemainExtra >= 0)
  9263. {
  9264. pInfo->pNoticeReference = NULL;
  9265. }
  9266. // check to see if there is a notice reference
  9267. if (pAsn1UserNotice->bit_mask & explicitText_present)
  9268. {
  9269. // check whether it is a visible or bmp string
  9270. if (pAsn1UserNotice->explicitText.choice & theVisibleString_chosen)
  9271. {
  9272. lRemainExtra -= (strlen(pAsn1UserNotice->explicitText.u.theVisibleString)+1) * sizeof(WCHAR);
  9273. if (lRemainExtra >= 0)
  9274. {
  9275. pInfo->pszDisplayText = (LPWSTR) pbExtra;
  9276. MultiByteToWideChar(
  9277. CP_ACP,
  9278. 0,
  9279. pAsn1UserNotice->explicitText.u.theVisibleString,
  9280. -1,
  9281. pInfo->pszDisplayText,
  9282. (strlen(pAsn1UserNotice->explicitText.u.theVisibleString)+1));
  9283. pbExtra += (strlen(pAsn1UserNotice->explicitText.u.theVisibleString)+1) * sizeof(WCHAR);
  9284. }
  9285. }
  9286. else if (pAsn1UserNotice->explicitText.choice & theBMPString_chosen)
  9287. {
  9288. lRemainExtra -= (pAsn1UserNotice->explicitText.u.theBMPString.length + 1) * sizeof(WCHAR);
  9289. if (lRemainExtra >= 0)
  9290. {
  9291. pInfo->pszDisplayText = (LPWSTR) pbExtra;
  9292. memcpy(
  9293. (void *)pInfo->pszDisplayText,
  9294. pAsn1UserNotice->explicitText.u.theBMPString.value,
  9295. pAsn1UserNotice->explicitText.u.theBMPString.length * sizeof(WCHAR));
  9296. pInfo->pszDisplayText[pAsn1UserNotice->explicitText.u.theBMPString.length] = 0;
  9297. pbExtra += (pAsn1UserNotice->explicitText.u.theBMPString.length + 1) * sizeof(WCHAR);
  9298. }
  9299. }
  9300. }
  9301. *plRemainExtra = lRemainExtra;
  9302. return TRUE;
  9303. }
  9304. BOOL WINAPI Asn1X509PKIXUserNoticeDecodeEx(
  9305. IN DWORD dwCertEncodingType,
  9306. IN LPCSTR lpszStructType,
  9307. IN const BYTE *pbEncoded,
  9308. IN DWORD cbEncoded,
  9309. IN DWORD dwFlags,
  9310. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  9311. OUT OPTIONAL void *pvStructInfo,
  9312. IN OUT DWORD *pcbStructInfo
  9313. )
  9314. {
  9315. return Asn1InfoDecodeAndAllocEx(
  9316. UserNotice_PDU,
  9317. pbEncoded,
  9318. cbEncoded,
  9319. dwFlags,
  9320. pDecodePara,
  9321. Asn1X509PKIXUserNoticeDecodeExCallback,
  9322. pvStructInfo,
  9323. pcbStructInfo
  9324. );
  9325. }
  9326. //+-------------------------------------------------------------------------
  9327. // Encode Attributes (ASN1 X509 v3 ASN.1)
  9328. //--------------------------------------------------------------------------
  9329. BOOL WINAPI Asn1X509AttributesEncodeEx(
  9330. IN DWORD dwCertEncodingType,
  9331. IN LPCSTR lpszStructType,
  9332. IN PCRYPT_ATTRIBUTES pInfo,
  9333. IN DWORD dwFlags,
  9334. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  9335. OUT OPTIONAL void *pvEncoded,
  9336. IN OUT DWORD *pcbEncoded
  9337. )
  9338. {
  9339. BOOL fResult;
  9340. Attributes Asn1Info;
  9341. if (!Asn1X509SetAttributes(pInfo->cAttr, pInfo->rgAttr,
  9342. &Asn1Info))
  9343. goto ErrorReturn;
  9344. fResult = Asn1InfoEncodeEx(
  9345. Attributes_PDU,
  9346. &Asn1Info,
  9347. dwFlags,
  9348. pEncodePara,
  9349. pvEncoded,
  9350. pcbEncoded
  9351. );
  9352. goto CommonReturn;
  9353. ErrorReturn:
  9354. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  9355. *((void **) pvEncoded) = NULL;
  9356. *pcbEncoded = 0;
  9357. fResult = FALSE;
  9358. CommonReturn:
  9359. Asn1X509FreeAttributes(&Asn1Info);
  9360. return fResult;
  9361. }
  9362. //+-------------------------------------------------------------------------
  9363. // Decode Attributes (ASN1 X509 v3 ASN.1)
  9364. //--------------------------------------------------------------------------
  9365. BOOL WINAPI Asn1X509AttributesDecodeExCallback(
  9366. IN void *pvAsn1Info,
  9367. IN DWORD dwFlags,
  9368. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  9369. OUT OPTIONAL void *pvStructInfo,
  9370. IN OUT LONG *plRemainExtra
  9371. )
  9372. {
  9373. Attributes *pAsn1Info = (Attributes *) pvAsn1Info;
  9374. PCRYPT_ATTRIBUTES pInfo = (PCRYPT_ATTRIBUTES) pvStructInfo;
  9375. BYTE *pbExtra;
  9376. LONG lRemainExtra = *plRemainExtra;
  9377. lRemainExtra -= sizeof(CRYPT_ATTRIBUTES);
  9378. if (lRemainExtra < 0) {
  9379. pbExtra = NULL;
  9380. } else {
  9381. pbExtra = (BYTE *) pInfo + sizeof(CRYPT_ATTRIBUTES);
  9382. }
  9383. Asn1X509GetAttributes(pAsn1Info, dwFlags,
  9384. &pInfo->cAttr, &pInfo->rgAttr, &pbExtra, &lRemainExtra);
  9385. *plRemainExtra = lRemainExtra;
  9386. return TRUE;
  9387. }
  9388. BOOL WINAPI Asn1X509AttributesDecodeEx(
  9389. IN DWORD dwCertEncodingType,
  9390. IN LPCSTR lpszStructType,
  9391. IN const BYTE *pbEncoded,
  9392. IN DWORD cbEncoded,
  9393. IN DWORD dwFlags,
  9394. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  9395. OUT OPTIONAL void *pvStructInfo,
  9396. IN OUT DWORD *pcbStructInfo
  9397. )
  9398. {
  9399. return Asn1InfoDecodeAndAllocEx(
  9400. Attributes_PDU,
  9401. pbEncoded,
  9402. cbEncoded,
  9403. dwFlags,
  9404. pDecodePara,
  9405. Asn1X509AttributesDecodeExCallback,
  9406. pvStructInfo,
  9407. pcbStructInfo
  9408. );
  9409. }
  9410. //+-------------------------------------------------------------------------
  9411. // Decode Enrollment Name Value Pair Authenticated Attributes in RA PKCS7s
  9412. //--------------------------------------------------------------------------
  9413. BOOL WINAPI Asn1NameValueDecodeExCallback(
  9414. IN void *pvAsn1Info,
  9415. IN DWORD dwFlags,
  9416. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  9417. OUT OPTIONAL void *pvStructInfo,
  9418. IN OUT LONG *plRemainExtra
  9419. )
  9420. {
  9421. EnrollmentNameValuePair *pAsn1Info = (EnrollmentNameValuePair *) pvAsn1Info;
  9422. PCRYPT_ENROLLMENT_NAME_VALUE_PAIR pNameValuePair = (PCRYPT_ENROLLMENT_NAME_VALUE_PAIR) pvStructInfo;
  9423. BYTE *pbExtra;
  9424. LONG lRemainExtra = *plRemainExtra;
  9425. LONG lAlignExtra;
  9426. lRemainExtra -= sizeof(CRYPT_ENROLLMENT_NAME_VALUE_PAIR);
  9427. if (lRemainExtra < 0) {
  9428. pbExtra = NULL;
  9429. } else {
  9430. pbExtra = (BYTE *) pNameValuePair + sizeof(CRYPT_ENROLLMENT_NAME_VALUE_PAIR);
  9431. }
  9432. lAlignExtra = INFO_LEN_ALIGN(sizeof(CRYPT_ENROLLMENT_NAME_VALUE_PAIR));
  9433. lRemainExtra -= lAlignExtra;
  9434. if (lRemainExtra >= 0) {
  9435. pbExtra += lAlignExtra;
  9436. }
  9437. PkiAsn1GetBMPString(
  9438. pAsn1Info->name.length,
  9439. pAsn1Info->name.value,
  9440. 0,
  9441. &pNameValuePair->pwszName,
  9442. &pbExtra,
  9443. &lRemainExtra
  9444. );
  9445. PkiAsn1GetBMPString(
  9446. pAsn1Info->value.length,
  9447. pAsn1Info->value.value,
  9448. 0,
  9449. &pNameValuePair->pwszValue,
  9450. &pbExtra,
  9451. &lRemainExtra
  9452. );
  9453. *plRemainExtra = lRemainExtra;
  9454. return TRUE;
  9455. }
  9456. BOOL WINAPI Asn1NameValueDecodeEx(
  9457. IN DWORD dwCertEncodingType,
  9458. IN LPCSTR lpszStructType,
  9459. IN const BYTE *pbEncoded,
  9460. IN DWORD cbEncoded,
  9461. IN DWORD dwFlags,
  9462. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  9463. OUT OPTIONAL void *pvStructInfo,
  9464. IN OUT DWORD *pcbStructInfo
  9465. )
  9466. {
  9467. return Asn1InfoDecodeAndAllocEx(
  9468. EnrollmentNameValuePair_PDU,
  9469. pbEncoded,
  9470. cbEncoded,
  9471. dwFlags,
  9472. pDecodePara,
  9473. Asn1NameValueDecodeExCallback,
  9474. pvStructInfo,
  9475. pcbStructInfo
  9476. );
  9477. }
  9478. //+-------------------------------------------------------------------------
  9479. // Encode Name Value Pair Authenticated Attributes in RA PKCS7s
  9480. //--------------------------------------------------------------------------
  9481. BOOL WINAPI Asn1NameValueEncodeEx(
  9482. IN DWORD dwCertEncodingType,
  9483. IN LPCSTR lpszStructType,
  9484. IN PCRYPT_ENROLLMENT_NAME_VALUE_PAIR pNameValue,
  9485. IN DWORD dwFlags,
  9486. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  9487. OUT OPTIONAL void *pvEncoded,
  9488. IN OUT DWORD *pcbEncoded
  9489. )
  9490. {
  9491. BOOL fResult;
  9492. EnrollmentNameValuePair NameValue;
  9493. NameValue.name.length = wcslen(pNameValue->pwszName);
  9494. NameValue.name.value = pNameValue->pwszName;
  9495. NameValue.value.length = wcslen(pNameValue->pwszValue);
  9496. NameValue.value.value = pNameValue->pwszValue;
  9497. fResult = Asn1InfoEncodeEx(
  9498. EnrollmentNameValuePair_PDU,
  9499. &NameValue,
  9500. dwFlags,
  9501. pEncodePara,
  9502. pvEncoded,
  9503. pcbEncoded
  9504. );
  9505. if (!fResult && (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)) {
  9506. *((void **) pvEncoded) = NULL;
  9507. *pcbEncoded = 0;
  9508. }
  9509. return fResult;
  9510. }
  9511. //+-------------------------------------------------------------------------
  9512. // Decode CSP Provider Attribute
  9513. //--------------------------------------------------------------------------
  9514. BOOL WINAPI Asn1CSPProviderDecodeExCallback(
  9515. IN void *pvAsn1Info,
  9516. IN DWORD dwFlags,
  9517. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  9518. OUT OPTIONAL void *pvStructInfo,
  9519. IN OUT LONG *plRemainExtra
  9520. )
  9521. {
  9522. CSPProvider *pAsn1Info = (CSPProvider *) pvAsn1Info;
  9523. PCRYPT_CSP_PROVIDER pCSPProvider = (PCRYPT_CSP_PROVIDER) pvStructInfo;
  9524. BYTE *pbExtra;
  9525. LONG lRemainExtra = *plRemainExtra;
  9526. LONG lAlignExtra;
  9527. lRemainExtra -= sizeof(CRYPT_CSP_PROVIDER);
  9528. if (lRemainExtra < 0) {
  9529. pbExtra = NULL;
  9530. } else {
  9531. pbExtra = (BYTE *) pCSPProvider + sizeof(CRYPT_CSP_PROVIDER);
  9532. }
  9533. lAlignExtra = INFO_LEN_ALIGN(sizeof(CRYPT_CSP_PROVIDER));
  9534. lRemainExtra -= lAlignExtra;
  9535. if (lRemainExtra >= 0) {
  9536. pbExtra += lAlignExtra;
  9537. }
  9538. pCSPProvider->dwKeySpec = (DWORD) pAsn1Info->keySpec;
  9539. PkiAsn1GetBMPString(
  9540. pAsn1Info->cspName.length,
  9541. pAsn1Info->cspName.value,
  9542. 0,
  9543. &pCSPProvider->pwszProviderName,
  9544. &pbExtra,
  9545. &lRemainExtra
  9546. );
  9547. Asn1X509GetBit(
  9548. &pAsn1Info->signature,
  9549. dwFlags,
  9550. &pCSPProvider->Signature,
  9551. &pbExtra,
  9552. &lRemainExtra
  9553. );
  9554. *plRemainExtra = lRemainExtra;
  9555. return TRUE;
  9556. }
  9557. BOOL WINAPI Asn1CSPProviderDecodeEx(
  9558. IN DWORD dwCertEncodingType,
  9559. IN LPCSTR lpszStructType,
  9560. IN const BYTE *pbEncoded,
  9561. IN DWORD cbEncoded,
  9562. IN DWORD dwFlags,
  9563. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  9564. OUT OPTIONAL void *pvStructInfo,
  9565. IN OUT DWORD *pcbStructInfo
  9566. )
  9567. {
  9568. return Asn1InfoDecodeAndAllocEx(
  9569. CSPProvider_PDU,
  9570. pbEncoded,
  9571. cbEncoded,
  9572. dwFlags,
  9573. pDecodePara,
  9574. Asn1CSPProviderDecodeExCallback,
  9575. pvStructInfo,
  9576. pcbStructInfo
  9577. );
  9578. }
  9579. //+-------------------------------------------------------------------------
  9580. // Encode CSP Provider Attribute
  9581. //--------------------------------------------------------------------------
  9582. BOOL WINAPI Asn1CSPProviderEncodeEx(
  9583. IN DWORD dwCertEncodingType,
  9584. IN LPCSTR lpszStructType,
  9585. IN PCRYPT_CSP_PROVIDER pCSPProvider,
  9586. IN DWORD dwFlags,
  9587. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  9588. OUT OPTIONAL void *pvEncoded,
  9589. IN OUT DWORD *pcbEncoded
  9590. )
  9591. {
  9592. BOOL fResult;
  9593. CSPProvider CspProvider;
  9594. CspProvider.keySpec = (int) pCSPProvider->dwKeySpec;
  9595. CspProvider.cspName.length = wcslen(pCSPProvider->pwszProviderName);
  9596. CspProvider.cspName.value = pCSPProvider->pwszProviderName;
  9597. Asn1X509SetBit(
  9598. &pCSPProvider->Signature,
  9599. &CspProvider.signature
  9600. );
  9601. fResult = Asn1InfoEncodeEx(
  9602. CSPProvider_PDU,
  9603. &CspProvider,
  9604. dwFlags,
  9605. pEncodePara,
  9606. pvEncoded,
  9607. pcbEncoded
  9608. );
  9609. if (!fResult && (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)) {
  9610. *((void **) pvEncoded) = NULL;
  9611. *pcbEncoded = 0;
  9612. }
  9613. return fResult;
  9614. }
  9615. //+-------------------------------------------------------------------------
  9616. // Certificate Pair Encode (ASN1 X509)
  9617. //--------------------------------------------------------------------------
  9618. BOOL WINAPI Asn1X509CertPairEncodeEx(
  9619. IN DWORD dwCertEncodingType,
  9620. IN LPCSTR lpszStructType,
  9621. IN PCERT_PAIR pInfo,
  9622. IN DWORD dwFlags,
  9623. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  9624. OUT OPTIONAL void *pvEncoded,
  9625. IN OUT DWORD *pcbEncoded
  9626. )
  9627. {
  9628. CertificatePair Asn1CertificatePair;
  9629. memset(&Asn1CertificatePair, 0, sizeof(Asn1CertificatePair));
  9630. if (pInfo->Forward.cbData) {
  9631. Asn1X509SetAny(&pInfo->Forward, &Asn1CertificatePair.forward);
  9632. Asn1CertificatePair.bit_mask |= forward_present;
  9633. }
  9634. if (pInfo->Reverse.cbData) {
  9635. Asn1X509SetAny(&pInfo->Reverse, &Asn1CertificatePair.reverse);
  9636. Asn1CertificatePair.bit_mask |= reverse_present;
  9637. }
  9638. return Asn1InfoEncodeEx(
  9639. CertificatePair_PDU,
  9640. &Asn1CertificatePair,
  9641. dwFlags,
  9642. pEncodePara,
  9643. pvEncoded,
  9644. pcbEncoded
  9645. );
  9646. }
  9647. //+-------------------------------------------------------------------------
  9648. // Certificate Pair Decode (ASN1 X509)
  9649. //--------------------------------------------------------------------------
  9650. BOOL WINAPI Asn1X509CertPairDecodeExCallback(
  9651. IN void *pvAsn1Info,
  9652. IN DWORD dwFlags,
  9653. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  9654. OUT OPTIONAL void *pvStructInfo,
  9655. IN OUT LONG *plRemainExtra
  9656. )
  9657. {
  9658. CertificatePair *pCertificatePair = (CertificatePair *) pvAsn1Info;
  9659. PCERT_PAIR pInfo =
  9660. (PCERT_PAIR) pvStructInfo;
  9661. LONG lRemainExtra = *plRemainExtra;
  9662. BYTE *pbExtra;
  9663. lRemainExtra -= sizeof(CERT_PAIR);
  9664. if (lRemainExtra < 0) {
  9665. pbExtra = NULL;
  9666. } else {
  9667. // Default all optional fields to zero
  9668. memset(pInfo, 0, sizeof(CERT_PAIR));
  9669. pbExtra = (BYTE *) pInfo + sizeof(CERT_PAIR);
  9670. }
  9671. if (pCertificatePair->bit_mask & forward_present)
  9672. Asn1X509GetAny(&pCertificatePair->forward, dwFlags,
  9673. &pInfo->Forward, &pbExtra, &lRemainExtra);
  9674. if (pCertificatePair->bit_mask & reverse_present)
  9675. Asn1X509GetAny(&pCertificatePair->reverse, dwFlags,
  9676. &pInfo->Reverse, &pbExtra, &lRemainExtra);
  9677. *plRemainExtra = lRemainExtra;
  9678. return TRUE;
  9679. }
  9680. BOOL WINAPI Asn1X509CertPairDecodeEx(
  9681. IN DWORD dwCertEncodingType,
  9682. IN LPCSTR lpszStructType,
  9683. IN const BYTE *pbEncoded,
  9684. IN DWORD cbEncoded,
  9685. IN DWORD dwFlags,
  9686. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  9687. OUT OPTIONAL void *pvStructInfo,
  9688. IN OUT DWORD *pcbStructInfo
  9689. )
  9690. {
  9691. return Asn1InfoDecodeAndAllocEx(
  9692. CertificatePair_PDU,
  9693. pbEncoded,
  9694. cbEncoded,
  9695. dwFlags,
  9696. pDecodePara,
  9697. Asn1X509CertPairDecodeExCallback,
  9698. pvStructInfo,
  9699. pcbStructInfo
  9700. );
  9701. }
  9702. //+-------------------------------------------------------------------------
  9703. // Set/Free/Get NameConstraints Subtree
  9704. //--------------------------------------------------------------------------
  9705. BOOL Asn1X509SetNameConstraintsSubtree(
  9706. IN DWORD cSubtree,
  9707. IN PCERT_GENERAL_SUBTREE pSubtree,
  9708. IN OUT GeneralSubtrees *pAsn1,
  9709. OUT DWORD *pdwErrLocation
  9710. )
  9711. {
  9712. BOOL fResult;
  9713. DWORD i;
  9714. GeneralSubtree *pAsn1Subtree;
  9715. *pdwErrLocation = 0;
  9716. assert(0 != cSubtree);
  9717. if (NULL == (pAsn1Subtree = (GeneralSubtree *) PkiZeroAlloc(
  9718. cSubtree * sizeof(GeneralSubtree))))
  9719. goto ErrorReturn;
  9720. pAsn1->count = cSubtree;
  9721. pAsn1->value = pAsn1Subtree;
  9722. for (i = 0; i < cSubtree; i++, pSubtree++, pAsn1Subtree++) {
  9723. if (!Asn1X509SetAltNameEntry(&pSubtree->Base,
  9724. &pAsn1Subtree->base,
  9725. i,
  9726. pdwErrLocation))
  9727. goto ErrorReturn;
  9728. if (0 < pSubtree->dwMinimum) {
  9729. pAsn1Subtree->minimum = pSubtree->dwMinimum;
  9730. pAsn1Subtree->bit_mask |= minimum_present;
  9731. }
  9732. if (pSubtree->fMaximum) {
  9733. pAsn1Subtree->maximum = pSubtree->dwMaximum;
  9734. pAsn1Subtree->bit_mask |= maximum_present;
  9735. }
  9736. }
  9737. fResult = TRUE;
  9738. CommonReturn:
  9739. return fResult;
  9740. ErrorReturn:
  9741. fResult = FALSE;
  9742. goto CommonReturn;
  9743. }
  9744. void Asn1X509FreeNameConstraintsSubtree(
  9745. IN OUT GeneralSubtrees *pAsn1
  9746. )
  9747. {
  9748. DWORD cSubtree = pAsn1->count;
  9749. GeneralSubtree *pAsn1Subtree = pAsn1->value;
  9750. for ( ; cSubtree > 0; cSubtree--, pAsn1Subtree++)
  9751. Asn1X509FreeAltNameEntry(&pAsn1Subtree->base);
  9752. PkiFree(pAsn1->value);
  9753. }
  9754. BOOL Asn1X509GetNameConstraintsSubtree(
  9755. IN GeneralSubtrees *pAsn1,
  9756. IN DWORD dwFlags,
  9757. OUT DWORD *pcSubtree,
  9758. IN OUT PCERT_GENERAL_SUBTREE *ppSubtree,
  9759. IN OUT BYTE **ppbExtra,
  9760. IN OUT LONG *plRemainExtra
  9761. )
  9762. {
  9763. BOOL fResult;
  9764. BYTE *pbExtra = *ppbExtra;
  9765. LONG lRemainExtra = *plRemainExtra;
  9766. LONG lAlignExtra;
  9767. DWORD cSubtree;
  9768. GeneralSubtree *pAsn1Subtree;
  9769. PCERT_GENERAL_SUBTREE pSubtree;
  9770. cSubtree = pAsn1->count;
  9771. if (0 == cSubtree)
  9772. goto SuccessReturn;
  9773. pAsn1Subtree = pAsn1->value;
  9774. lAlignExtra = INFO_LEN_ALIGN(cSubtree * sizeof(CERT_GENERAL_SUBTREE));
  9775. lRemainExtra -= lAlignExtra;
  9776. if (lRemainExtra < 0) {
  9777. pSubtree = NULL;
  9778. } else {
  9779. pSubtree = (PCERT_GENERAL_SUBTREE) pbExtra;
  9780. memset(pSubtree, 0, lAlignExtra);
  9781. *pcSubtree = cSubtree;
  9782. *ppSubtree = pSubtree;
  9783. pbExtra += lAlignExtra;
  9784. }
  9785. // Subtree Array entries
  9786. for (; cSubtree > 0; cSubtree--, pSubtree++, pAsn1Subtree++) {
  9787. if (!Asn1X509GetAltNameEntry(&pAsn1Subtree->base, dwFlags,
  9788. &pSubtree->Base, &pbExtra, &lRemainExtra))
  9789. goto ErrorReturn;
  9790. if (lRemainExtra >= 0) {
  9791. if (pAsn1Subtree->bit_mask & minimum_present)
  9792. pSubtree->dwMinimum = pAsn1Subtree->minimum;
  9793. if (pAsn1Subtree->bit_mask & maximum_present) {
  9794. pSubtree->fMaximum = TRUE;
  9795. pSubtree->dwMaximum = pAsn1Subtree->maximum;
  9796. }
  9797. }
  9798. }
  9799. SuccessReturn:
  9800. fResult = TRUE;
  9801. CommonReturn:
  9802. *ppbExtra = pbExtra;
  9803. *plRemainExtra = lRemainExtra;
  9804. return fResult;
  9805. ErrorReturn:
  9806. fResult = FALSE;
  9807. goto CommonReturn;
  9808. }
  9809. //+-------------------------------------------------------------------------
  9810. // Name Constraints Extension Encode (ASN1 X509)
  9811. //--------------------------------------------------------------------------
  9812. BOOL WINAPI Asn1X509NameConstraintsEncodeEx(
  9813. IN DWORD dwCertEncodingType,
  9814. IN LPCSTR lpszStructType,
  9815. IN PCERT_NAME_CONSTRAINTS_INFO pInfo,
  9816. IN DWORD dwFlags,
  9817. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  9818. OUT OPTIONAL void *pvEncoded,
  9819. IN OUT DWORD *pcbEncoded
  9820. )
  9821. {
  9822. BOOL fResult;
  9823. NameConstraints Asn1Info;
  9824. DWORD cSubtree;
  9825. DWORD dwErrLocation;
  9826. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  9827. *((void **) pvEncoded) = NULL;
  9828. memset(&Asn1Info, 0, sizeof(Asn1Info));
  9829. cSubtree = pInfo->cPermittedSubtree;
  9830. if (0 < cSubtree) {
  9831. if (!Asn1X509SetNameConstraintsSubtree(
  9832. cSubtree,
  9833. pInfo->rgPermittedSubtree,
  9834. &Asn1Info.permittedSubtrees,
  9835. &dwErrLocation))
  9836. goto SubtreeError;
  9837. Asn1Info.bit_mask |= permittedSubtrees_present;
  9838. }
  9839. cSubtree = pInfo->cExcludedSubtree;
  9840. if (0 < cSubtree) {
  9841. if (!Asn1X509SetNameConstraintsSubtree(
  9842. cSubtree,
  9843. pInfo->rgExcludedSubtree,
  9844. &Asn1Info.excludedSubtrees,
  9845. &dwErrLocation)) {
  9846. if (0 != dwErrLocation)
  9847. dwErrLocation |= CERT_EXCLUDED_SUBTREE_BIT;
  9848. goto SubtreeError;
  9849. }
  9850. Asn1Info.bit_mask |= excludedSubtrees_present;
  9851. }
  9852. fResult = Asn1InfoEncodeEx(
  9853. NameConstraints_PDU,
  9854. &Asn1Info,
  9855. dwFlags,
  9856. pEncodePara,
  9857. pvEncoded,
  9858. pcbEncoded
  9859. );
  9860. CommonReturn:
  9861. Asn1X509FreeNameConstraintsSubtree(&Asn1Info.permittedSubtrees);
  9862. Asn1X509FreeNameConstraintsSubtree(&Asn1Info.excludedSubtrees);
  9863. return fResult;
  9864. SubtreeError:
  9865. *pcbEncoded = dwErrLocation;
  9866. fResult = FALSE;
  9867. goto CommonReturn;
  9868. }
  9869. //+-------------------------------------------------------------------------
  9870. // Name Constraints Extension Decode (ASN1 X509)
  9871. //--------------------------------------------------------------------------
  9872. BOOL WINAPI Asn1X509NameConstraintsDecodeExCallback(
  9873. IN void *pvAsn1Info,
  9874. IN DWORD dwFlags,
  9875. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  9876. OUT OPTIONAL void *pvStructInfo,
  9877. IN OUT LONG *plRemainExtra
  9878. )
  9879. {
  9880. BOOL fResult;
  9881. NameConstraints *pAsn1 = (NameConstraints *) pvAsn1Info;
  9882. PCERT_NAME_CONSTRAINTS_INFO pInfo =
  9883. (PCERT_NAME_CONSTRAINTS_INFO) pvStructInfo;
  9884. LONG lRemainExtra = *plRemainExtra;
  9885. BYTE *pbExtra;
  9886. lRemainExtra -= sizeof(CERT_NAME_CONSTRAINTS_INFO);
  9887. if (lRemainExtra < 0) {
  9888. pbExtra = NULL;
  9889. } else {
  9890. memset(pInfo, 0, sizeof(CERT_NAME_CONSTRAINTS_INFO));
  9891. pbExtra = (BYTE *) pInfo + sizeof(CERT_NAME_CONSTRAINTS_INFO);
  9892. }
  9893. if (pAsn1->bit_mask & permittedSubtrees_present) {
  9894. if (!Asn1X509GetNameConstraintsSubtree(
  9895. &pAsn1->permittedSubtrees,
  9896. dwFlags,
  9897. &pInfo->cPermittedSubtree,
  9898. &pInfo->rgPermittedSubtree,
  9899. &pbExtra,
  9900. &lRemainExtra
  9901. )) goto ErrorReturn;
  9902. }
  9903. if (pAsn1->bit_mask & excludedSubtrees_present) {
  9904. if (!Asn1X509GetNameConstraintsSubtree(
  9905. &pAsn1->excludedSubtrees,
  9906. dwFlags,
  9907. &pInfo->cExcludedSubtree,
  9908. &pInfo->rgExcludedSubtree,
  9909. &pbExtra,
  9910. &lRemainExtra
  9911. )) goto ErrorReturn;
  9912. }
  9913. fResult = TRUE;
  9914. CommonReturn:
  9915. *plRemainExtra = lRemainExtra;
  9916. return fResult;
  9917. ErrorReturn:
  9918. fResult = FALSE;
  9919. goto CommonReturn;
  9920. }
  9921. BOOL WINAPI Asn1X509NameConstraintsDecodeEx(
  9922. IN DWORD dwCertEncodingType,
  9923. IN LPCSTR lpszStructType,
  9924. IN const BYTE *pbEncoded,
  9925. IN DWORD cbEncoded,
  9926. IN DWORD dwFlags,
  9927. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  9928. OUT OPTIONAL void *pvStructInfo,
  9929. IN OUT DWORD *pcbStructInfo
  9930. )
  9931. {
  9932. return Asn1InfoDecodeAndAllocEx(
  9933. NameConstraints_PDU,
  9934. pbEncoded,
  9935. cbEncoded,
  9936. dwFlags,
  9937. pDecodePara,
  9938. Asn1X509NameConstraintsDecodeExCallback,
  9939. pvStructInfo,
  9940. pcbStructInfo
  9941. );
  9942. }
  9943. //+-------------------------------------------------------------------------
  9944. // CRL Issuing Distribution Point Extension Encode (ASN1 X509)
  9945. //--------------------------------------------------------------------------
  9946. BOOL WINAPI Asn1X509CrlIssuingDistPointEncodeEx(
  9947. IN DWORD dwCertEncodingType,
  9948. IN LPCSTR lpszStructType,
  9949. IN PCRL_ISSUING_DIST_POINT pInfo,
  9950. IN DWORD dwFlags,
  9951. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  9952. OUT OPTIONAL void *pvEncoded,
  9953. IN OUT DWORD *pcbEncoded
  9954. )
  9955. {
  9956. BOOL fResult;
  9957. IssuingDistributionPoint Asn1Info;
  9958. DistributionPointName *pAsn1DistPointName;
  9959. PCRL_DIST_POINT_NAME pDistPointName;
  9960. DWORD dwErrLocation;
  9961. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  9962. *((void **) pvEncoded) = NULL;
  9963. memset(&Asn1Info, 0, sizeof(Asn1Info));
  9964. pDistPointName = &pInfo->DistPointName;
  9965. if (CRL_DIST_POINT_NO_NAME !=
  9966. pDistPointName->dwDistPointNameChoice) {
  9967. pAsn1DistPointName = &Asn1Info.issuingDistributionPoint;
  9968. Asn1Info.bit_mask |= issuingDistributionPoint_present;
  9969. pAsn1DistPointName->choice = (unsigned short)
  9970. pDistPointName->dwDistPointNameChoice;
  9971. assert(fullName_chosen == CRL_DIST_POINT_FULL_NAME);
  9972. assert(nameRelativeToCRLIssuer_chosen ==
  9973. CRL_DIST_POINT_ISSUER_RDN_NAME);
  9974. switch (pDistPointName->dwDistPointNameChoice) {
  9975. case CRL_DIST_POINT_FULL_NAME:
  9976. if (!Asn1X509SetAltNames(
  9977. &pDistPointName->FullName,
  9978. &pAsn1DistPointName->u.fullName, 0, &dwErrLocation))
  9979. goto AltNamesError;
  9980. break;
  9981. case CRL_DIST_POINT_ISSUER_RDN_NAME:
  9982. default:
  9983. goto InvalidArg;
  9984. }
  9985. }
  9986. if (pInfo->fOnlyContainsUserCerts) {
  9987. Asn1Info.bit_mask |= onlyContainsUserCerts_present;
  9988. Asn1Info.onlyContainsUserCerts = TRUE;
  9989. }
  9990. if (pInfo->fOnlyContainsCACerts) {
  9991. Asn1Info.bit_mask |= onlyContainsCACerts_present;
  9992. Asn1Info.onlyContainsCACerts = TRUE;
  9993. }
  9994. if (pInfo->fIndirectCRL) {
  9995. Asn1Info.bit_mask |= indirectCRL_present;
  9996. Asn1Info.indirectCRL = TRUE;
  9997. }
  9998. if (pInfo->OnlySomeReasonFlags.cbData) {
  9999. Asn1Info.bit_mask |= onlySomeReasons_present;
  10000. Asn1X509SetBitWithoutTrailingZeroes(&pInfo->OnlySomeReasonFlags,
  10001. &Asn1Info.onlySomeReasons);
  10002. }
  10003. fResult = Asn1InfoEncodeEx(
  10004. IssuingDistributionPoint_PDU,
  10005. &Asn1Info,
  10006. dwFlags,
  10007. pEncodePara,
  10008. pvEncoded,
  10009. pcbEncoded
  10010. );
  10011. CommonReturn:
  10012. pAsn1DistPointName = &Asn1Info.issuingDistributionPoint;
  10013. switch (pAsn1DistPointName->choice) {
  10014. case CRL_DIST_POINT_FULL_NAME:
  10015. Asn1X509FreeAltNames(&pAsn1DistPointName->u.fullName);
  10016. break;
  10017. case CRL_DIST_POINT_ISSUER_RDN_NAME:
  10018. default:
  10019. break;
  10020. }
  10021. return fResult;
  10022. AltNamesError:
  10023. *pcbEncoded = dwErrLocation;
  10024. goto ErrorReturn;
  10025. InvalidArg:
  10026. SetLastError((DWORD) E_INVALIDARG);
  10027. *pcbEncoded = 0;
  10028. ErrorReturn:
  10029. fResult = FALSE;
  10030. goto CommonReturn;
  10031. }
  10032. //+-------------------------------------------------------------------------
  10033. // CRL Issuing Distribution Point Extension Decode (ASN1 X509)
  10034. //--------------------------------------------------------------------------
  10035. BOOL WINAPI Asn1X509CrlIssuingDistPointDecodeExCallback(
  10036. IN void *pvAsn1Info,
  10037. IN DWORD dwFlags,
  10038. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  10039. OUT OPTIONAL void *pvStructInfo,
  10040. IN OUT LONG *plRemainExtra
  10041. )
  10042. {
  10043. BOOL fResult;
  10044. IssuingDistributionPoint *pAsn1 = (IssuingDistributionPoint *) pvAsn1Info;
  10045. PCRL_ISSUING_DIST_POINT pInfo = (PCRL_ISSUING_DIST_POINT) pvStructInfo;
  10046. LONG lRemainExtra = *plRemainExtra;
  10047. BYTE *pbExtra;
  10048. lRemainExtra -= sizeof(CRL_ISSUING_DIST_POINT);
  10049. if (lRemainExtra < 0) {
  10050. pbExtra = NULL;
  10051. } else {
  10052. memset(pInfo, 0, sizeof(CRL_ISSUING_DIST_POINT));
  10053. pbExtra = (BYTE *) pInfo + sizeof(CRL_ISSUING_DIST_POINT);
  10054. if (pAsn1->bit_mask & onlyContainsUserCerts_present)
  10055. pInfo->fOnlyContainsUserCerts =
  10056. (BOOL) pAsn1->onlyContainsUserCerts;
  10057. if (pAsn1->bit_mask & onlyContainsCACerts_present)
  10058. pInfo->fOnlyContainsCACerts = (BOOL) pAsn1->onlyContainsCACerts;
  10059. if (pAsn1->bit_mask & indirectCRL_present)
  10060. pInfo->fIndirectCRL = (BOOL) pAsn1->indirectCRL;
  10061. }
  10062. if (pAsn1->bit_mask & issuingDistributionPoint_present) {
  10063. DistributionPointName *pAsn1DistPointName =
  10064. &pAsn1->issuingDistributionPoint;
  10065. DWORD dwDistPointNameChoice = pAsn1DistPointName->choice;
  10066. PCRL_DIST_POINT_NAME pDistPointName;
  10067. if (lRemainExtra >= 0) {
  10068. pDistPointName = &pInfo->DistPointName;
  10069. pDistPointName->dwDistPointNameChoice =
  10070. dwDistPointNameChoice;
  10071. } else
  10072. pDistPointName = NULL;
  10073. assert(fullName_chosen == CRL_DIST_POINT_FULL_NAME);
  10074. assert(nameRelativeToCRLIssuer_chosen ==
  10075. CRL_DIST_POINT_ISSUER_RDN_NAME);
  10076. switch (dwDistPointNameChoice) {
  10077. case CRL_DIST_POINT_FULL_NAME:
  10078. if (!Asn1X509GetAltNames(&pAsn1DistPointName->u.fullName,
  10079. dwFlags, &pDistPointName->FullName,
  10080. &pbExtra, &lRemainExtra))
  10081. goto ErrorReturn;
  10082. break;
  10083. case CRL_DIST_POINT_ISSUER_RDN_NAME:
  10084. break;
  10085. default:
  10086. SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
  10087. goto ErrorReturn;
  10088. }
  10089. }
  10090. if (pAsn1->bit_mask & onlySomeReasons_present)
  10091. Asn1X509GetBit(&pAsn1->onlySomeReasons, dwFlags,
  10092. &pInfo->OnlySomeReasonFlags, &pbExtra, &lRemainExtra);
  10093. fResult = TRUE;
  10094. CommonReturn:
  10095. *plRemainExtra = lRemainExtra;
  10096. return fResult;
  10097. ErrorReturn:
  10098. fResult = FALSE;
  10099. goto CommonReturn;
  10100. }
  10101. BOOL WINAPI Asn1X509CrlIssuingDistPointDecodeEx(
  10102. IN DWORD dwCertEncodingType,
  10103. IN LPCSTR lpszStructType,
  10104. IN const BYTE *pbEncoded,
  10105. IN DWORD cbEncoded,
  10106. IN DWORD dwFlags,
  10107. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  10108. OUT OPTIONAL void *pvStructInfo,
  10109. IN OUT DWORD *pcbStructInfo
  10110. )
  10111. {
  10112. return Asn1InfoDecodeAndAllocEx(
  10113. IssuingDistributionPoint_PDU,
  10114. pbEncoded,
  10115. cbEncoded,
  10116. dwFlags,
  10117. pDecodePara,
  10118. Asn1X509CrlIssuingDistPointDecodeExCallback,
  10119. pvStructInfo,
  10120. pcbStructInfo
  10121. );
  10122. }
  10123. //+-------------------------------------------------------------------------
  10124. // Policy Mappings Extension Encode (ASN1 X509)
  10125. //--------------------------------------------------------------------------
  10126. BOOL WINAPI Asn1X509PolicyMappingsEncodeEx(
  10127. IN DWORD dwCertEncodingType,
  10128. IN LPCSTR lpszStructType,
  10129. IN PCERT_POLICY_MAPPINGS_INFO pInfo,
  10130. IN DWORD dwFlags,
  10131. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  10132. OUT OPTIONAL void *pvEncoded,
  10133. IN OUT DWORD *pcbEncoded
  10134. )
  10135. {
  10136. BOOL fResult;
  10137. PolicyMappings Asn1Info;
  10138. memset(&Asn1Info, 0, sizeof(Asn1Info));
  10139. if (0 != pInfo->cPolicyMapping) {
  10140. DWORD cMap = pInfo->cPolicyMapping;
  10141. PCERT_POLICY_MAPPING pMap = pInfo->rgPolicyMapping;
  10142. PolicyMapping *pAsn1Map;
  10143. if (NULL == (pAsn1Map = (PolicyMapping *) PkiZeroAlloc(
  10144. cMap * sizeof(PolicyMapping))))
  10145. goto ErrorReturn;
  10146. Asn1Info.count = cMap;
  10147. Asn1Info.value = pAsn1Map;
  10148. for ( ; cMap > 0; cMap--, pMap++, pAsn1Map++) {
  10149. if (!Asn1X509SetEncodedObjId(pMap->pszIssuerDomainPolicy,
  10150. &pAsn1Map->issuerDomainPolicy))
  10151. goto ErrorReturn;
  10152. if (!Asn1X509SetEncodedObjId(pMap->pszSubjectDomainPolicy,
  10153. &pAsn1Map->subjectDomainPolicy))
  10154. goto ErrorReturn;
  10155. }
  10156. }
  10157. fResult = Asn1InfoEncodeEx(
  10158. PolicyMappings_PDU,
  10159. &Asn1Info,
  10160. dwFlags,
  10161. pEncodePara,
  10162. pvEncoded,
  10163. pcbEncoded
  10164. );
  10165. goto CommonReturn;
  10166. ErrorReturn:
  10167. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  10168. *((void **) pvEncoded) = NULL;
  10169. *pcbEncoded = 0;
  10170. fResult = FALSE;
  10171. CommonReturn:
  10172. PkiFree(Asn1Info.value);
  10173. return fResult;
  10174. }
  10175. //+-------------------------------------------------------------------------
  10176. // Policy Mappings Extension Decode (ASN1 X509)
  10177. //--------------------------------------------------------------------------
  10178. BOOL WINAPI Asn1X509PolicyMappingsDecodeExCallback(
  10179. IN void *pvAsn1Info,
  10180. IN DWORD dwFlags,
  10181. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  10182. OUT OPTIONAL void *pvStructInfo,
  10183. IN OUT LONG *plRemainExtra
  10184. )
  10185. {
  10186. PolicyMappings *pAsn1Info = (PolicyMappings *) pvAsn1Info;
  10187. PCERT_POLICY_MAPPINGS_INFO pInfo =
  10188. (PCERT_POLICY_MAPPINGS_INFO) pvStructInfo;
  10189. LONG lRemainExtra = *plRemainExtra;
  10190. BYTE *pbExtra;
  10191. LONG lAlignExtra;
  10192. DWORD cMap;
  10193. PolicyMapping *pAsn1Map;
  10194. PCERT_POLICY_MAPPING pMap;
  10195. cMap = pAsn1Info->count;
  10196. lAlignExtra = cMap * sizeof(CERT_POLICY_MAPPING);
  10197. lRemainExtra -= sizeof(CERT_POLICY_MAPPINGS_INFO) + lAlignExtra;
  10198. if (lRemainExtra < 0) {
  10199. pbExtra = NULL;
  10200. pMap = NULL;
  10201. } else {
  10202. pbExtra = (BYTE *) pInfo + sizeof(CERT_POLICY_MAPPINGS_INFO);
  10203. pMap = (PCERT_POLICY_MAPPING) pbExtra;
  10204. pInfo->cPolicyMapping = cMap;
  10205. pInfo->rgPolicyMapping = pMap;
  10206. if (lAlignExtra) {
  10207. memset(pbExtra, 0, lAlignExtra);
  10208. pbExtra += lAlignExtra;
  10209. }
  10210. }
  10211. pAsn1Map = pAsn1Info->value;
  10212. for ( ; cMap > 0; cMap--, pAsn1Map++, pMap++) {
  10213. Asn1X509GetEncodedObjId(&pAsn1Map->issuerDomainPolicy, dwFlags,
  10214. &pMap->pszIssuerDomainPolicy, &pbExtra, &lRemainExtra);
  10215. Asn1X509GetEncodedObjId(&pAsn1Map->subjectDomainPolicy, dwFlags,
  10216. &pMap->pszSubjectDomainPolicy, &pbExtra, &lRemainExtra);
  10217. }
  10218. *plRemainExtra = lRemainExtra;
  10219. return TRUE;
  10220. }
  10221. BOOL WINAPI Asn1X509PolicyMappingsDecodeEx(
  10222. IN DWORD dwCertEncodingType,
  10223. IN LPCSTR lpszStructType,
  10224. IN const BYTE *pbEncoded,
  10225. IN DWORD cbEncoded,
  10226. IN DWORD dwFlags,
  10227. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  10228. OUT OPTIONAL void *pvStructInfo,
  10229. IN OUT DWORD *pcbStructInfo
  10230. )
  10231. {
  10232. return Asn1InfoDecodeAndAllocEx(
  10233. PolicyMappings_PDU,
  10234. pbEncoded,
  10235. cbEncoded,
  10236. dwFlags,
  10237. pDecodePara,
  10238. Asn1X509PolicyMappingsDecodeExCallback,
  10239. pvStructInfo,
  10240. pcbStructInfo
  10241. );
  10242. }
  10243. //+-------------------------------------------------------------------------
  10244. // Policy Constraints Extension Encode (ASN1 X509)
  10245. //--------------------------------------------------------------------------
  10246. BOOL WINAPI Asn1X509PolicyConstraintsEncodeEx(
  10247. IN DWORD dwCertEncodingType,
  10248. IN LPCSTR lpszStructType,
  10249. IN PCERT_POLICY_CONSTRAINTS_INFO pInfo,
  10250. IN DWORD dwFlags,
  10251. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  10252. OUT OPTIONAL void *pvEncoded,
  10253. IN OUT DWORD *pcbEncoded
  10254. )
  10255. {
  10256. PolicyConstraints Asn1Info;
  10257. memset(&Asn1Info, 0, sizeof(Asn1Info));
  10258. if (pInfo->fRequireExplicitPolicy) {
  10259. Asn1Info.requireExplicitPolicy =
  10260. pInfo->dwRequireExplicitPolicySkipCerts;
  10261. Asn1Info.bit_mask |= requireExplicitPolicy_present;
  10262. }
  10263. if (pInfo->fInhibitPolicyMapping) {
  10264. Asn1Info.inhibitPolicyMapping =
  10265. pInfo->dwInhibitPolicyMappingSkipCerts;
  10266. Asn1Info.bit_mask |= inhibitPolicyMapping_present;
  10267. }
  10268. return Asn1InfoEncodeEx(
  10269. PolicyConstraints_PDU,
  10270. &Asn1Info,
  10271. dwFlags,
  10272. pEncodePara,
  10273. pvEncoded,
  10274. pcbEncoded
  10275. );
  10276. }
  10277. //+-------------------------------------------------------------------------
  10278. // Policy Constraints Extension Decode (ASN1 X509)
  10279. //--------------------------------------------------------------------------
  10280. BOOL WINAPI Asn1X509PolicyConstraintsDecodeExCallback(
  10281. IN void *pvAsn1Info,
  10282. IN DWORD dwFlags,
  10283. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  10284. OUT OPTIONAL void *pvStructInfo,
  10285. IN OUT LONG *plRemainExtra
  10286. )
  10287. {
  10288. PolicyConstraints *pAsn1Info = (PolicyConstraints *) pvAsn1Info;
  10289. PCERT_POLICY_CONSTRAINTS_INFO pInfo =
  10290. (PCERT_POLICY_CONSTRAINTS_INFO) pvStructInfo;
  10291. *plRemainExtra -= sizeof(CERT_POLICY_CONSTRAINTS_INFO);
  10292. if (*plRemainExtra >= 0) {
  10293. memset(pInfo, 0, sizeof(CERT_POLICY_CONSTRAINTS_INFO));
  10294. if (pAsn1Info->bit_mask & requireExplicitPolicy_present) {
  10295. pInfo->fRequireExplicitPolicy = TRUE;
  10296. pInfo->dwRequireExplicitPolicySkipCerts =
  10297. pAsn1Info->requireExplicitPolicy;
  10298. }
  10299. if (pAsn1Info->bit_mask & inhibitPolicyMapping_present) {
  10300. pInfo->fInhibitPolicyMapping = TRUE;
  10301. pInfo->dwInhibitPolicyMappingSkipCerts =
  10302. pAsn1Info->inhibitPolicyMapping;
  10303. }
  10304. }
  10305. return TRUE;
  10306. }
  10307. BOOL WINAPI Asn1X509PolicyConstraintsDecodeEx(
  10308. IN DWORD dwCertEncodingType,
  10309. IN LPCSTR lpszStructType,
  10310. IN const BYTE *pbEncoded,
  10311. IN DWORD cbEncoded,
  10312. IN DWORD dwFlags,
  10313. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  10314. OUT OPTIONAL void *pvStructInfo,
  10315. IN OUT DWORD *pcbStructInfo
  10316. )
  10317. {
  10318. return Asn1InfoDecodeAndAllocEx(
  10319. PolicyConstraints_PDU,
  10320. pbEncoded,
  10321. cbEncoded,
  10322. dwFlags,
  10323. pDecodePara,
  10324. Asn1X509PolicyConstraintsDecodeExCallback,
  10325. pvStructInfo,
  10326. pcbStructInfo
  10327. );
  10328. }
  10329. //+-------------------------------------------------------------------------
  10330. // Cross Cert Distribution Points Encode (ASN1 X509)
  10331. //--------------------------------------------------------------------------
  10332. BOOL WINAPI Asn1X509CrossCertDistPointsEncodeEx(
  10333. IN DWORD dwCertEncodingType,
  10334. IN LPCSTR lpszStructType,
  10335. IN PCROSS_CERT_DIST_POINTS_INFO pInfo,
  10336. IN DWORD dwFlags,
  10337. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  10338. OUT OPTIONAL void *pvEncoded,
  10339. IN OUT DWORD *pcbEncoded
  10340. )
  10341. {
  10342. BOOL fResult;
  10343. CrossCertDistPoints Asn1Info;
  10344. GeneralNames *pAsn1DistPoint;
  10345. PCERT_ALT_NAME_INFO pDistPoint;
  10346. DWORD cDistPoint;
  10347. DWORD i;
  10348. DWORD dwErrLocation;
  10349. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  10350. *((void **) pvEncoded) = NULL;
  10351. memset(&Asn1Info, 0, sizeof(Asn1Info));
  10352. if (pInfo->dwSyncDeltaTime) {
  10353. Asn1Info.syncDeltaTime = pInfo->dwSyncDeltaTime;
  10354. Asn1Info.bit_mask |= syncDeltaTime_present;
  10355. }
  10356. cDistPoint = pInfo->cDistPoint;
  10357. if (0 < cDistPoint) {
  10358. if (NULL == (pAsn1DistPoint = (GeneralNames *) PkiZeroAlloc(
  10359. cDistPoint * sizeof(GeneralNames))))
  10360. goto ErrorReturn;
  10361. Asn1Info.crossCertDistPointNames.count = cDistPoint;
  10362. Asn1Info.crossCertDistPointNames.value = pAsn1DistPoint;
  10363. pDistPoint = pInfo->rgDistPoint;
  10364. for (i = 0; i < cDistPoint; i++, pDistPoint++, pAsn1DistPoint++) {
  10365. if (!Asn1X509SetAltNames(
  10366. pDistPoint,
  10367. pAsn1DistPoint,
  10368. i,
  10369. &dwErrLocation))
  10370. goto AltNamesError;
  10371. }
  10372. }
  10373. fResult = Asn1InfoEncodeEx(
  10374. CrossCertDistPoints_PDU,
  10375. &Asn1Info,
  10376. dwFlags,
  10377. pEncodePara,
  10378. pvEncoded,
  10379. pcbEncoded
  10380. );
  10381. CommonReturn:
  10382. pAsn1DistPoint = Asn1Info.crossCertDistPointNames.value;
  10383. if (pAsn1DistPoint) {
  10384. cDistPoint = Asn1Info.crossCertDistPointNames.count;
  10385. for ( ; cDistPoint > 0; cDistPoint--, pAsn1DistPoint++) {
  10386. Asn1X509FreeAltNames(pAsn1DistPoint);
  10387. }
  10388. PkiFree(Asn1Info.crossCertDistPointNames.value);
  10389. }
  10390. return fResult;
  10391. AltNamesError:
  10392. *pcbEncoded = dwErrLocation;
  10393. fResult = FALSE;
  10394. goto CommonReturn;
  10395. ErrorReturn:
  10396. *pcbEncoded = 0;
  10397. fResult = FALSE;
  10398. goto CommonReturn;
  10399. }
  10400. //+-------------------------------------------------------------------------
  10401. // Cross Cert Distribution Points Decode (ASN1 X509)
  10402. //--------------------------------------------------------------------------
  10403. BOOL WINAPI Asn1X509CrossCertDistPointsDecodeExCallback(
  10404. IN void *pvAsn1Info,
  10405. IN DWORD dwFlags,
  10406. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  10407. OUT OPTIONAL void *pvStructInfo,
  10408. IN OUT LONG *plRemainExtra
  10409. )
  10410. {
  10411. BOOL fResult;
  10412. CrossCertDistPoints *pAsn1 = (CrossCertDistPoints *) pvAsn1Info;
  10413. PCROSS_CERT_DIST_POINTS_INFO pInfo =
  10414. (PCROSS_CERT_DIST_POINTS_INFO) pvStructInfo;
  10415. LONG lRemainExtra = *plRemainExtra;
  10416. BYTE *pbExtra;
  10417. LONG lAlignExtra;
  10418. lRemainExtra -= sizeof(CROSS_CERT_DIST_POINTS_INFO);
  10419. if (lRemainExtra < 0) {
  10420. pbExtra = NULL;
  10421. } else {
  10422. memset(pInfo, 0, sizeof(CROSS_CERT_DIST_POINTS_INFO));
  10423. pbExtra = (BYTE *) pInfo + sizeof(CROSS_CERT_DIST_POINTS_INFO);
  10424. if (pAsn1->bit_mask & syncDeltaTime_present)
  10425. pInfo->dwSyncDeltaTime = pAsn1->syncDeltaTime;
  10426. }
  10427. if (pAsn1->crossCertDistPointNames.count) {
  10428. DWORD cDistPoint = pAsn1->crossCertDistPointNames.count;
  10429. GeneralNames *pAsn1DistPoint = pAsn1->crossCertDistPointNames.value;
  10430. PCERT_ALT_NAME_INFO pDistPoint;
  10431. lAlignExtra = INFO_LEN_ALIGN(cDistPoint * sizeof(CERT_ALT_NAME_INFO));
  10432. lRemainExtra -= lAlignExtra;
  10433. if (lRemainExtra >= 0) {
  10434. pDistPoint = (PCERT_ALT_NAME_INFO) pbExtra;
  10435. memset(pDistPoint, 0, cDistPoint * sizeof(CERT_ALT_NAME_INFO));
  10436. pInfo->cDistPoint = cDistPoint;
  10437. pInfo->rgDistPoint = pDistPoint;
  10438. pbExtra += lAlignExtra;
  10439. } else
  10440. pDistPoint = NULL;
  10441. for ( ; cDistPoint > 0; cDistPoint--, pAsn1DistPoint++, pDistPoint++) {
  10442. if (!Asn1X509GetAltNames(pAsn1DistPoint, dwFlags, pDistPoint,
  10443. &pbExtra, &lRemainExtra))
  10444. goto ErrorReturn;
  10445. }
  10446. }
  10447. fResult = TRUE;
  10448. CommonReturn:
  10449. *plRemainExtra = lRemainExtra;
  10450. return fResult;
  10451. ErrorReturn:
  10452. fResult = FALSE;
  10453. goto CommonReturn;
  10454. }
  10455. BOOL WINAPI Asn1X509CrossCertDistPointsDecodeEx(
  10456. IN DWORD dwCertEncodingType,
  10457. IN LPCSTR lpszStructType,
  10458. IN const BYTE *pbEncoded,
  10459. IN DWORD cbEncoded,
  10460. IN DWORD dwFlags,
  10461. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  10462. OUT OPTIONAL void *pvStructInfo,
  10463. IN OUT DWORD *pcbStructInfo
  10464. )
  10465. {
  10466. return Asn1InfoDecodeAndAllocEx(
  10467. CrossCertDistPoints_PDU,
  10468. pbEncoded,
  10469. cbEncoded,
  10470. dwFlags,
  10471. pDecodePara,
  10472. Asn1X509CrossCertDistPointsDecodeExCallback,
  10473. pvStructInfo,
  10474. pcbStructInfo
  10475. );
  10476. }
  10477. //+=========================================================================
  10478. // Certificate Management Messages over CMS (CMC) Encode/Decode Functions
  10479. //==========================================================================
  10480. //+-------------------------------------------------------------------------
  10481. // Set/Free/Get CMC Tagged Attributes
  10482. //--------------------------------------------------------------------------
  10483. BOOL Asn1CmcSetTaggedAttributes(
  10484. IN DWORD cTaggedAttr,
  10485. IN PCMC_TAGGED_ATTRIBUTE pTaggedAttr,
  10486. OUT ControlSequence *pAsn1
  10487. )
  10488. {
  10489. TaggedAttribute *pAsn1Attr;
  10490. pAsn1->value = NULL;
  10491. pAsn1->count = 0;
  10492. if (cTaggedAttr == 0)
  10493. return TRUE;
  10494. pAsn1Attr = (TaggedAttribute *) PkiZeroAlloc(
  10495. cTaggedAttr * sizeof(TaggedAttribute));
  10496. if (pAsn1Attr == NULL)
  10497. return FALSE;
  10498. pAsn1->value = pAsn1Attr;
  10499. pAsn1->count = cTaggedAttr;
  10500. for ( ; cTaggedAttr > 0; cTaggedAttr--, pTaggedAttr++, pAsn1Attr++) {
  10501. pAsn1Attr->bodyPartID = pTaggedAttr->dwBodyPartID;
  10502. if (!Asn1X509SetEncodedObjId(pTaggedAttr->Attribute.pszObjId,
  10503. &pAsn1Attr->type))
  10504. return FALSE;
  10505. if (!Asn1X509SetSeqOfAny(
  10506. pTaggedAttr->Attribute.cValue,
  10507. pTaggedAttr->Attribute.rgValue,
  10508. &pAsn1Attr->values.count,
  10509. &pAsn1Attr->values.value))
  10510. return FALSE;
  10511. }
  10512. return TRUE;
  10513. }
  10514. void Asn1CmcFreeTaggedAttributes(
  10515. IN OUT ControlSequence *pAsn1
  10516. )
  10517. {
  10518. if (pAsn1->value) {
  10519. TaggedAttribute *pAsn1Attr = pAsn1->value;
  10520. DWORD cTaggedAttr = pAsn1->count;
  10521. for ( ; cTaggedAttr > 0; cTaggedAttr--, pAsn1Attr++) {
  10522. Asn1X509FreeSeqOfAny(pAsn1Attr->values.value);
  10523. }
  10524. PkiFree(pAsn1->value);
  10525. pAsn1->value = NULL;
  10526. }
  10527. pAsn1->count = 0;
  10528. }
  10529. void Asn1CmcGetTaggedAttributes(
  10530. IN ControlSequence *pAsn1,
  10531. IN DWORD dwFlags,
  10532. OUT DWORD *pcTaggedAttr,
  10533. OUT PCMC_TAGGED_ATTRIBUTE *ppTaggedAttr,
  10534. IN OUT BYTE **ppbExtra,
  10535. IN OUT LONG *plRemainExtra
  10536. )
  10537. {
  10538. LONG lRemainExtra = *plRemainExtra;
  10539. BYTE *pbExtra = *ppbExtra;
  10540. LONG lAlignExtra;
  10541. DWORD cTaggedAttr;
  10542. TaggedAttribute *pAsn1Attr;
  10543. PCMC_TAGGED_ATTRIBUTE pTaggedAttr;
  10544. cTaggedAttr = pAsn1->count;
  10545. lAlignExtra = INFO_LEN_ALIGN(cTaggedAttr * sizeof(CMC_TAGGED_ATTRIBUTE));
  10546. lRemainExtra -= lAlignExtra;
  10547. if (lRemainExtra >= 0) {
  10548. *pcTaggedAttr = cTaggedAttr;
  10549. pTaggedAttr = (PCMC_TAGGED_ATTRIBUTE) pbExtra;
  10550. *ppTaggedAttr = pTaggedAttr;
  10551. pbExtra += lAlignExtra;
  10552. } else
  10553. pTaggedAttr = NULL;
  10554. pAsn1Attr = pAsn1->value;
  10555. for ( ; cTaggedAttr > 0; cTaggedAttr--, pAsn1Attr++, pTaggedAttr++) {
  10556. if (lRemainExtra >= 0) {
  10557. pTaggedAttr->dwBodyPartID = pAsn1Attr->bodyPartID;
  10558. }
  10559. Asn1X509GetEncodedObjId(&pAsn1Attr->type, dwFlags,
  10560. &pTaggedAttr->Attribute.pszObjId, &pbExtra, &lRemainExtra);
  10561. Asn1X509GetSeqOfAny(
  10562. pAsn1Attr->values.count, pAsn1Attr->values.value, dwFlags,
  10563. &pTaggedAttr->Attribute.cValue, &pTaggedAttr->Attribute.rgValue,
  10564. &pbExtra, &lRemainExtra);
  10565. }
  10566. *plRemainExtra = lRemainExtra;
  10567. *ppbExtra = pbExtra;
  10568. }
  10569. //+-------------------------------------------------------------------------
  10570. // Set/Free/Get CMC Tagged Requests
  10571. //--------------------------------------------------------------------------
  10572. BOOL Asn1CmcSetTaggedRequests(
  10573. IN DWORD cTaggedReq,
  10574. IN PCMC_TAGGED_REQUEST pTaggedReq,
  10575. OUT ReqSequence *pAsn1
  10576. )
  10577. {
  10578. TaggedRequest *pAsn1Req;
  10579. pAsn1->value = NULL;
  10580. pAsn1->count = 0;
  10581. if (cTaggedReq == 0)
  10582. return TRUE;
  10583. pAsn1Req = (TaggedRequest *) PkiZeroAlloc(
  10584. cTaggedReq * sizeof(TaggedRequest));
  10585. if (pAsn1Req == NULL)
  10586. return FALSE;
  10587. pAsn1->value = pAsn1Req;
  10588. pAsn1->count = cTaggedReq;
  10589. for ( ; cTaggedReq > 0; cTaggedReq--, pTaggedReq++, pAsn1Req++) {
  10590. PCMC_TAGGED_CERT_REQUEST pTaggedCertReq;
  10591. TaggedCertificationRequest *ptcr;
  10592. if (CMC_TAGGED_CERT_REQUEST_CHOICE !=
  10593. pTaggedReq->dwTaggedRequestChoice) {
  10594. SetLastError((DWORD) E_INVALIDARG);
  10595. return FALSE;
  10596. }
  10597. pAsn1Req->choice = tcr_chosen;
  10598. ptcr = &pAsn1Req->u.tcr;
  10599. pTaggedCertReq = pTaggedReq->pTaggedCertRequest;
  10600. ptcr->bodyPartID = pTaggedCertReq->dwBodyPartID;
  10601. Asn1X509SetAny(&pTaggedCertReq->SignedCertRequest,
  10602. &ptcr->certificationRequest);
  10603. }
  10604. return TRUE;
  10605. }
  10606. void Asn1CmcFreeTaggedRequests(
  10607. IN OUT ReqSequence *pAsn1
  10608. )
  10609. {
  10610. if (pAsn1->value) {
  10611. PkiFree(pAsn1->value);
  10612. pAsn1->value = NULL;
  10613. }
  10614. pAsn1->count = 0;
  10615. }
  10616. BOOL Asn1CmcGetTaggedRequests(
  10617. IN ReqSequence *pAsn1,
  10618. IN DWORD dwFlags,
  10619. OUT DWORD *pcTaggedReq,
  10620. OUT PCMC_TAGGED_REQUEST *ppTaggedReq,
  10621. IN OUT BYTE **ppbExtra,
  10622. IN OUT LONG *plRemainExtra
  10623. )
  10624. {
  10625. BOOL fResult;
  10626. LONG lRemainExtra = *plRemainExtra;
  10627. BYTE *pbExtra = *ppbExtra;
  10628. LONG lAlignExtra;
  10629. DWORD cTaggedReq;
  10630. TaggedRequest *pAsn1Req;
  10631. PCMC_TAGGED_REQUEST pTaggedReq;
  10632. cTaggedReq = pAsn1->count;
  10633. lAlignExtra = INFO_LEN_ALIGN(cTaggedReq * sizeof(CMC_TAGGED_REQUEST));
  10634. lRemainExtra -= lAlignExtra;
  10635. if (lRemainExtra >= 0) {
  10636. *pcTaggedReq = cTaggedReq;
  10637. pTaggedReq = (PCMC_TAGGED_REQUEST) pbExtra;
  10638. *ppTaggedReq = pTaggedReq;
  10639. pbExtra += lAlignExtra;
  10640. } else
  10641. pTaggedReq = NULL;
  10642. pAsn1Req = pAsn1->value;
  10643. for ( ; cTaggedReq > 0; cTaggedReq--, pAsn1Req++, pTaggedReq++) {
  10644. PCMC_TAGGED_CERT_REQUEST pTaggedCertReq;
  10645. TaggedCertificationRequest *ptcr;
  10646. if (tcr_chosen != pAsn1Req->choice) {
  10647. SetLastError((DWORD) CRYPT_E_BAD_ENCODE);
  10648. goto ErrorReturn;
  10649. }
  10650. ptcr = &pAsn1Req->u.tcr;
  10651. lAlignExtra = INFO_LEN_ALIGN(sizeof(CMC_TAGGED_CERT_REQUEST));
  10652. lRemainExtra -= lAlignExtra;
  10653. if (lRemainExtra >= 0) {
  10654. pTaggedReq->dwTaggedRequestChoice =
  10655. CMC_TAGGED_CERT_REQUEST_CHOICE;
  10656. pTaggedCertReq = (PCMC_TAGGED_CERT_REQUEST) pbExtra;
  10657. pbExtra += lAlignExtra;
  10658. pTaggedReq->pTaggedCertRequest = pTaggedCertReq;
  10659. pTaggedCertReq->dwBodyPartID = ptcr->bodyPartID;
  10660. } else
  10661. pTaggedCertReq = NULL;
  10662. Asn1X509GetAny(&ptcr->certificationRequest, dwFlags,
  10663. &pTaggedCertReq->SignedCertRequest, &pbExtra, &lRemainExtra);
  10664. }
  10665. *plRemainExtra = lRemainExtra;
  10666. *ppbExtra = pbExtra;
  10667. fResult = TRUE;
  10668. CommonReturn:
  10669. return fResult;
  10670. ErrorReturn:
  10671. fResult = FALSE;
  10672. goto CommonReturn;
  10673. }
  10674. //+-------------------------------------------------------------------------
  10675. // Set/Free/Get CMC Tagged ContentInfo
  10676. //--------------------------------------------------------------------------
  10677. BOOL Asn1CmcSetTaggedContentInfos(
  10678. IN DWORD cTaggedCI,
  10679. IN PCMC_TAGGED_CONTENT_INFO pTaggedCI,
  10680. OUT CmsSequence *pAsn1
  10681. )
  10682. {
  10683. TaggedContentInfo *pAsn1CI;
  10684. pAsn1->value = NULL;
  10685. pAsn1->count = 0;
  10686. if (cTaggedCI == 0)
  10687. return TRUE;
  10688. pAsn1CI = (TaggedContentInfo *) PkiZeroAlloc(
  10689. cTaggedCI * sizeof(TaggedContentInfo));
  10690. if (pAsn1CI == NULL)
  10691. return FALSE;
  10692. pAsn1->value = pAsn1CI;
  10693. pAsn1->count = cTaggedCI;
  10694. for ( ; cTaggedCI > 0; cTaggedCI--, pTaggedCI++, pAsn1CI++) {
  10695. pAsn1CI->bodyPartID = pTaggedCI->dwBodyPartID;
  10696. Asn1X509SetAny(&pTaggedCI->EncodedContentInfo, &pAsn1CI->contentInfo);
  10697. }
  10698. return TRUE;
  10699. }
  10700. void Asn1CmcFreeTaggedContentInfos(
  10701. IN OUT CmsSequence *pAsn1
  10702. )
  10703. {
  10704. if (pAsn1->value) {
  10705. PkiFree(pAsn1->value);
  10706. pAsn1->value = NULL;
  10707. }
  10708. pAsn1->count = 0;
  10709. }
  10710. void Asn1CmcGetTaggedContentInfos(
  10711. IN CmsSequence *pAsn1,
  10712. IN DWORD dwFlags,
  10713. OUT DWORD *pcTaggedCI,
  10714. OUT PCMC_TAGGED_CONTENT_INFO *ppTaggedCI,
  10715. IN OUT BYTE **ppbExtra,
  10716. IN OUT LONG *plRemainExtra
  10717. )
  10718. {
  10719. LONG lRemainExtra = *plRemainExtra;
  10720. BYTE *pbExtra = *ppbExtra;
  10721. LONG lAlignExtra;
  10722. DWORD cTaggedCI;
  10723. TaggedContentInfo *pAsn1CI;
  10724. PCMC_TAGGED_CONTENT_INFO pTaggedCI;
  10725. cTaggedCI = pAsn1->count;
  10726. lAlignExtra = INFO_LEN_ALIGN(cTaggedCI * sizeof(CMC_TAGGED_CONTENT_INFO));
  10727. lRemainExtra -= lAlignExtra;
  10728. if (lRemainExtra >= 0) {
  10729. *pcTaggedCI = cTaggedCI;
  10730. pTaggedCI = (PCMC_TAGGED_CONTENT_INFO) pbExtra;
  10731. *ppTaggedCI = pTaggedCI;
  10732. pbExtra += lAlignExtra;
  10733. } else
  10734. pTaggedCI = NULL;
  10735. pAsn1CI = pAsn1->value;
  10736. for ( ; cTaggedCI > 0; cTaggedCI--, pAsn1CI++, pTaggedCI++) {
  10737. if (lRemainExtra >= 0) {
  10738. pTaggedCI->dwBodyPartID = pAsn1CI->bodyPartID;
  10739. }
  10740. Asn1X509GetAny(&pAsn1CI->contentInfo, dwFlags,
  10741. &pTaggedCI->EncodedContentInfo, &pbExtra, &lRemainExtra);
  10742. }
  10743. *plRemainExtra = lRemainExtra;
  10744. *ppbExtra = pbExtra;
  10745. }
  10746. //+-------------------------------------------------------------------------
  10747. // Set/Free/Get CMC Tagged OtherMsg
  10748. //--------------------------------------------------------------------------
  10749. BOOL Asn1CmcSetTaggedOtherMsgs(
  10750. IN DWORD cTaggedOM,
  10751. IN PCMC_TAGGED_OTHER_MSG pTaggedOM,
  10752. OUT OtherMsgSequence *pAsn1
  10753. )
  10754. {
  10755. TaggedOtherMsg *pAsn1OM;
  10756. pAsn1->value = NULL;
  10757. pAsn1->count = 0;
  10758. if (cTaggedOM == 0)
  10759. return TRUE;
  10760. pAsn1OM = (TaggedOtherMsg *) PkiZeroAlloc(
  10761. cTaggedOM * sizeof(TaggedOtherMsg));
  10762. if (pAsn1OM == NULL)
  10763. return FALSE;
  10764. pAsn1->value = pAsn1OM;
  10765. pAsn1->count = cTaggedOM;
  10766. for ( ; cTaggedOM > 0; cTaggedOM--, pTaggedOM++, pAsn1OM++) {
  10767. pAsn1OM->bodyPartID = pTaggedOM->dwBodyPartID;
  10768. if (!Asn1X509SetEncodedObjId(pTaggedOM->pszObjId,
  10769. &pAsn1OM->otherMsgType))
  10770. return FALSE;
  10771. Asn1X509SetAny(&pTaggedOM->Value, &pAsn1OM->otherMsgValue);
  10772. }
  10773. return TRUE;
  10774. }
  10775. void Asn1CmcFreeTaggedOtherMsgs(
  10776. IN OUT OtherMsgSequence *pAsn1
  10777. )
  10778. {
  10779. if (pAsn1->value) {
  10780. PkiFree(pAsn1->value);
  10781. pAsn1->value = NULL;
  10782. }
  10783. pAsn1->count = 0;
  10784. }
  10785. void Asn1CmcGetTaggedOtherMsgs(
  10786. IN OtherMsgSequence *pAsn1,
  10787. IN DWORD dwFlags,
  10788. OUT DWORD *pcTaggedOM,
  10789. OUT PCMC_TAGGED_OTHER_MSG *ppTaggedOM,
  10790. IN OUT BYTE **ppbExtra,
  10791. IN OUT LONG *plRemainExtra
  10792. )
  10793. {
  10794. LONG lRemainExtra = *plRemainExtra;
  10795. BYTE *pbExtra = *ppbExtra;
  10796. LONG lAlignExtra;
  10797. DWORD cTaggedOM;
  10798. TaggedOtherMsg *pAsn1OM;
  10799. PCMC_TAGGED_OTHER_MSG pTaggedOM;
  10800. cTaggedOM = pAsn1->count;
  10801. lAlignExtra = INFO_LEN_ALIGN(cTaggedOM * sizeof(CMC_TAGGED_OTHER_MSG));
  10802. lRemainExtra -= lAlignExtra;
  10803. if (lRemainExtra >= 0) {
  10804. *pcTaggedOM = cTaggedOM;
  10805. pTaggedOM = (PCMC_TAGGED_OTHER_MSG) pbExtra;
  10806. *ppTaggedOM = pTaggedOM;
  10807. pbExtra += lAlignExtra;
  10808. } else
  10809. pTaggedOM = NULL;
  10810. pAsn1OM = pAsn1->value;
  10811. for ( ; cTaggedOM > 0; cTaggedOM--, pAsn1OM++, pTaggedOM++) {
  10812. if (lRemainExtra >= 0) {
  10813. pTaggedOM->dwBodyPartID = pAsn1OM->bodyPartID;
  10814. }
  10815. Asn1X509GetEncodedObjId(&pAsn1OM->otherMsgType, dwFlags,
  10816. &pTaggedOM->pszObjId, &pbExtra, &lRemainExtra);
  10817. Asn1X509GetAny(&pAsn1OM->otherMsgValue, dwFlags,
  10818. &pTaggedOM->Value, &pbExtra, &lRemainExtra);
  10819. }
  10820. *plRemainExtra = lRemainExtra;
  10821. *ppbExtra = pbExtra;
  10822. }
  10823. //+-------------------------------------------------------------------------
  10824. // CMC Data Encode (ASN1)
  10825. //--------------------------------------------------------------------------
  10826. BOOL WINAPI Asn1CmcDataEncodeEx(
  10827. IN DWORD dwCertEncodingType,
  10828. IN LPCSTR lpszStructType,
  10829. IN PCMC_DATA_INFO pInfo,
  10830. IN DWORD dwFlags,
  10831. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  10832. OUT OPTIONAL void *pvEncoded,
  10833. IN OUT DWORD *pcbEncoded
  10834. )
  10835. {
  10836. BOOL fResult;
  10837. CmcData Asn1Info;
  10838. memset(&Asn1Info, 0, sizeof(Asn1Info));
  10839. if (!Asn1CmcSetTaggedAttributes(pInfo->cTaggedAttribute,
  10840. pInfo->rgTaggedAttribute, &Asn1Info.controlSequence))
  10841. goto ErrorReturn;
  10842. if (!Asn1CmcSetTaggedRequests(pInfo->cTaggedRequest,
  10843. pInfo->rgTaggedRequest, &Asn1Info.reqSequence))
  10844. goto ErrorReturn;
  10845. if (!Asn1CmcSetTaggedContentInfos(pInfo->cTaggedContentInfo,
  10846. pInfo->rgTaggedContentInfo, &Asn1Info.cmsSequence))
  10847. goto ErrorReturn;
  10848. if (!Asn1CmcSetTaggedOtherMsgs(pInfo->cTaggedOtherMsg,
  10849. pInfo->rgTaggedOtherMsg, &Asn1Info.otherMsgSequence))
  10850. goto ErrorReturn;
  10851. fResult = Asn1InfoEncodeEx(
  10852. CmcData_PDU,
  10853. &Asn1Info,
  10854. dwFlags,
  10855. pEncodePara,
  10856. pvEncoded,
  10857. pcbEncoded
  10858. );
  10859. CommonReturn:
  10860. Asn1CmcFreeTaggedAttributes(&Asn1Info.controlSequence);
  10861. Asn1CmcFreeTaggedRequests(&Asn1Info.reqSequence);
  10862. Asn1CmcFreeTaggedContentInfos(&Asn1Info.cmsSequence);
  10863. Asn1CmcFreeTaggedOtherMsgs(&Asn1Info.otherMsgSequence);
  10864. return fResult;
  10865. ErrorReturn:
  10866. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  10867. *((void **) pvEncoded) = NULL;
  10868. *pcbEncoded = 0;
  10869. fResult = FALSE;
  10870. goto CommonReturn;
  10871. }
  10872. //+-------------------------------------------------------------------------
  10873. // CMC Data Decode (ASN1)
  10874. //--------------------------------------------------------------------------
  10875. BOOL WINAPI Asn1CmcDataDecodeExCallback(
  10876. IN void *pvAsn1Info,
  10877. IN DWORD dwFlags,
  10878. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  10879. OUT OPTIONAL void *pvStructInfo,
  10880. IN OUT LONG *plRemainExtra
  10881. )
  10882. {
  10883. BOOL fResult;
  10884. CmcData *pAsn1 = (CmcData *) pvAsn1Info;
  10885. PCMC_DATA_INFO pInfo = (PCMC_DATA_INFO) pvStructInfo;
  10886. LONG lRemainExtra = *plRemainExtra;
  10887. BYTE *pbExtra;
  10888. lRemainExtra -= sizeof(CMC_DATA_INFO);
  10889. if (lRemainExtra < 0) {
  10890. pbExtra = NULL;
  10891. } else {
  10892. memset(pInfo, 0, sizeof(CMC_DATA_INFO));
  10893. pbExtra = (BYTE *) pInfo + sizeof(CMC_DATA_INFO);
  10894. }
  10895. Asn1CmcGetTaggedAttributes(&pAsn1->controlSequence,
  10896. dwFlags,
  10897. &pInfo->cTaggedAttribute,
  10898. &pInfo->rgTaggedAttribute,
  10899. &pbExtra,
  10900. &lRemainExtra
  10901. );
  10902. if (!Asn1CmcGetTaggedRequests(&pAsn1->reqSequence,
  10903. dwFlags,
  10904. &pInfo->cTaggedRequest,
  10905. &pInfo->rgTaggedRequest,
  10906. &pbExtra,
  10907. &lRemainExtra
  10908. ))
  10909. goto ErrorReturn;
  10910. Asn1CmcGetTaggedContentInfos(&pAsn1->cmsSequence,
  10911. dwFlags,
  10912. &pInfo->cTaggedContentInfo,
  10913. &pInfo->rgTaggedContentInfo,
  10914. &pbExtra,
  10915. &lRemainExtra
  10916. );
  10917. Asn1CmcGetTaggedOtherMsgs(&pAsn1->otherMsgSequence,
  10918. dwFlags,
  10919. &pInfo->cTaggedOtherMsg,
  10920. &pInfo->rgTaggedOtherMsg,
  10921. &pbExtra,
  10922. &lRemainExtra
  10923. );
  10924. fResult = TRUE;
  10925. CommonReturn:
  10926. *plRemainExtra = lRemainExtra;
  10927. return fResult;
  10928. ErrorReturn:
  10929. fResult = FALSE;
  10930. goto CommonReturn;
  10931. }
  10932. BOOL WINAPI Asn1CmcDataDecodeEx(
  10933. IN DWORD dwCertEncodingType,
  10934. IN LPCSTR lpszStructType,
  10935. IN const BYTE *pbEncoded,
  10936. IN DWORD cbEncoded,
  10937. IN DWORD dwFlags,
  10938. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  10939. OUT OPTIONAL void *pvStructInfo,
  10940. IN OUT DWORD *pcbStructInfo
  10941. )
  10942. {
  10943. return Asn1InfoDecodeAndAllocEx(
  10944. CmcData_PDU,
  10945. pbEncoded,
  10946. cbEncoded,
  10947. dwFlags,
  10948. pDecodePara,
  10949. Asn1CmcDataDecodeExCallback,
  10950. pvStructInfo,
  10951. pcbStructInfo
  10952. );
  10953. }
  10954. //+-------------------------------------------------------------------------
  10955. // CMC Response Encode (ASN1)
  10956. //--------------------------------------------------------------------------
  10957. BOOL WINAPI Asn1CmcResponseEncodeEx(
  10958. IN DWORD dwCertEncodingType,
  10959. IN LPCSTR lpszStructType,
  10960. IN PCMC_RESPONSE_INFO pInfo,
  10961. IN DWORD dwFlags,
  10962. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  10963. OUT OPTIONAL void *pvEncoded,
  10964. IN OUT DWORD *pcbEncoded
  10965. )
  10966. {
  10967. BOOL fResult;
  10968. CmcResponseBody Asn1Info;
  10969. memset(&Asn1Info, 0, sizeof(Asn1Info));
  10970. if (!Asn1CmcSetTaggedAttributes(pInfo->cTaggedAttribute,
  10971. pInfo->rgTaggedAttribute, &Asn1Info.controlSequence))
  10972. goto ErrorReturn;
  10973. if (!Asn1CmcSetTaggedContentInfos(pInfo->cTaggedContentInfo,
  10974. pInfo->rgTaggedContentInfo, &Asn1Info.cmsSequence))
  10975. goto ErrorReturn;
  10976. if (!Asn1CmcSetTaggedOtherMsgs(pInfo->cTaggedOtherMsg,
  10977. pInfo->rgTaggedOtherMsg, &Asn1Info.otherMsgSequence))
  10978. goto ErrorReturn;
  10979. fResult = Asn1InfoEncodeEx(
  10980. CmcResponseBody_PDU,
  10981. &Asn1Info,
  10982. dwFlags,
  10983. pEncodePara,
  10984. pvEncoded,
  10985. pcbEncoded
  10986. );
  10987. CommonReturn:
  10988. Asn1CmcFreeTaggedAttributes(&Asn1Info.controlSequence);
  10989. Asn1CmcFreeTaggedContentInfos(&Asn1Info.cmsSequence);
  10990. Asn1CmcFreeTaggedOtherMsgs(&Asn1Info.otherMsgSequence);
  10991. return fResult;
  10992. ErrorReturn:
  10993. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  10994. *((void **) pvEncoded) = NULL;
  10995. *pcbEncoded = 0;
  10996. fResult = FALSE;
  10997. goto CommonReturn;
  10998. }
  10999. //+-------------------------------------------------------------------------
  11000. // CMC Response Decode (ASN1)
  11001. //--------------------------------------------------------------------------
  11002. BOOL WINAPI Asn1CmcResponseDecodeExCallback(
  11003. IN void *pvAsn1Info,
  11004. IN DWORD dwFlags,
  11005. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  11006. OUT OPTIONAL void *pvStructInfo,
  11007. IN OUT LONG *plRemainExtra
  11008. )
  11009. {
  11010. BOOL fResult;
  11011. CmcResponseBody *pAsn1 = (CmcResponseBody *) pvAsn1Info;
  11012. PCMC_RESPONSE_INFO pInfo = (PCMC_RESPONSE_INFO) pvStructInfo;
  11013. LONG lRemainExtra = *plRemainExtra;
  11014. BYTE *pbExtra;
  11015. lRemainExtra -= sizeof(CMC_RESPONSE_INFO);
  11016. if (lRemainExtra < 0) {
  11017. pbExtra = NULL;
  11018. } else {
  11019. memset(pInfo, 0, sizeof(CMC_RESPONSE_INFO));
  11020. pbExtra = (BYTE *) pInfo + sizeof(CMC_RESPONSE_INFO);
  11021. }
  11022. Asn1CmcGetTaggedAttributes(&pAsn1->controlSequence,
  11023. dwFlags,
  11024. &pInfo->cTaggedAttribute,
  11025. &pInfo->rgTaggedAttribute,
  11026. &pbExtra,
  11027. &lRemainExtra
  11028. );
  11029. Asn1CmcGetTaggedContentInfos(&pAsn1->cmsSequence,
  11030. dwFlags,
  11031. &pInfo->cTaggedContentInfo,
  11032. &pInfo->rgTaggedContentInfo,
  11033. &pbExtra,
  11034. &lRemainExtra
  11035. );
  11036. Asn1CmcGetTaggedOtherMsgs(&pAsn1->otherMsgSequence,
  11037. dwFlags,
  11038. &pInfo->cTaggedOtherMsg,
  11039. &pInfo->rgTaggedOtherMsg,
  11040. &pbExtra,
  11041. &lRemainExtra
  11042. );
  11043. fResult = TRUE;
  11044. *plRemainExtra = lRemainExtra;
  11045. return fResult;
  11046. }
  11047. BOOL WINAPI Asn1CmcResponseDecodeEx(
  11048. IN DWORD dwCertEncodingType,
  11049. IN LPCSTR lpszStructType,
  11050. IN const BYTE *pbEncoded,
  11051. IN DWORD cbEncoded,
  11052. IN DWORD dwFlags,
  11053. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  11054. OUT OPTIONAL void *pvStructInfo,
  11055. IN OUT DWORD *pcbStructInfo
  11056. )
  11057. {
  11058. return Asn1InfoDecodeAndAllocEx(
  11059. CmcResponseBody_PDU,
  11060. pbEncoded,
  11061. cbEncoded,
  11062. dwFlags,
  11063. pDecodePara,
  11064. Asn1CmcResponseDecodeExCallback,
  11065. pvStructInfo,
  11066. pcbStructInfo
  11067. );
  11068. }
  11069. //+-------------------------------------------------------------------------
  11070. // CMC Status Encode (ASN1)
  11071. //--------------------------------------------------------------------------
  11072. BOOL WINAPI Asn1CmcStatusEncodeEx(
  11073. IN DWORD dwCertEncodingType,
  11074. IN LPCSTR lpszStructType,
  11075. IN PCMC_STATUS_INFO pInfo,
  11076. IN DWORD dwFlags,
  11077. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  11078. OUT OPTIONAL void *pvEncoded,
  11079. IN OUT DWORD *pcbEncoded
  11080. )
  11081. {
  11082. BOOL fResult;
  11083. CmcStatusInfo Asn1Info;
  11084. memset(&Asn1Info, 0, sizeof(Asn1Info));
  11085. Asn1Info.cmcStatus = pInfo->dwStatus;
  11086. if (pInfo->cBodyList) {
  11087. Asn1Info.bodyList.count = pInfo->cBodyList;
  11088. Asn1Info.bodyList.value = pInfo->rgdwBodyList;
  11089. }
  11090. if (pInfo->pwszStatusString && L'\0' != *pInfo->pwszStatusString) {
  11091. Asn1Info.bit_mask |= statusString_present;
  11092. Asn1Info.statusString.length = wcslen(pInfo->pwszStatusString);
  11093. Asn1Info.statusString.value = pInfo->pwszStatusString;
  11094. }
  11095. if (CMC_OTHER_INFO_NO_CHOICE != pInfo->dwOtherInfoChoice) {
  11096. Asn1Info.bit_mask |= otherInfo_present;
  11097. switch (pInfo->dwOtherInfoChoice) {
  11098. case CMC_OTHER_INFO_FAIL_CHOICE:
  11099. Asn1Info.otherInfo.choice = failInfo_chosen;
  11100. Asn1Info.otherInfo.u.failInfo = pInfo->dwFailInfo;
  11101. break;
  11102. case CMC_OTHER_INFO_PEND_CHOICE:
  11103. Asn1Info.otherInfo.choice = pendInfo_chosen;
  11104. Asn1X509SetOctetString(&pInfo->pPendInfo->PendToken,
  11105. &Asn1Info.otherInfo.u.pendInfo.pendToken);
  11106. if (!PkiAsn1ToGeneralizedTime(
  11107. &pInfo->pPendInfo->PendTime,
  11108. &Asn1Info.otherInfo.u.pendInfo.pendTime))
  11109. goto GeneralizedTimeError;
  11110. break;
  11111. default:
  11112. goto InvalidOtherInfoChoiceError;
  11113. }
  11114. }
  11115. fResult = Asn1InfoEncodeEx(
  11116. CmcStatusInfo_PDU,
  11117. &Asn1Info,
  11118. dwFlags,
  11119. pEncodePara,
  11120. pvEncoded,
  11121. pcbEncoded
  11122. );
  11123. CommonReturn:
  11124. return fResult;
  11125. ErrorReturn:
  11126. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  11127. *((void **) pvEncoded) = NULL;
  11128. *pcbEncoded = 0;
  11129. fResult = FALSE;
  11130. goto CommonReturn;
  11131. SET_ERROR(InvalidOtherInfoChoiceError, E_INVALIDARG)
  11132. SET_ERROR(GeneralizedTimeError, CRYPT_E_BAD_ENCODE)
  11133. }
  11134. //+-------------------------------------------------------------------------
  11135. // CMC Status Decode (ASN1)
  11136. //--------------------------------------------------------------------------
  11137. BOOL WINAPI Asn1CmcStatusDecodeExCallback(
  11138. IN void *pvAsn1Info,
  11139. IN DWORD dwFlags,
  11140. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  11141. OUT OPTIONAL void *pvStructInfo,
  11142. IN OUT LONG *plRemainExtra
  11143. )
  11144. {
  11145. BOOL fResult;
  11146. CmcStatusInfo *pAsn1 = (CmcStatusInfo *) pvAsn1Info;
  11147. PCMC_STATUS_INFO pInfo = (PCMC_STATUS_INFO) pvStructInfo;
  11148. LONG lRemainExtra = *plRemainExtra;
  11149. LONG lAlignExtra;
  11150. BYTE *pbExtra;
  11151. lRemainExtra -= sizeof(CMC_STATUS_INFO);
  11152. if (lRemainExtra < 0) {
  11153. pbExtra = NULL;
  11154. } else {
  11155. memset(pInfo, 0, sizeof(CMC_STATUS_INFO));
  11156. pbExtra = (BYTE *) pInfo + sizeof(CMC_STATUS_INFO);
  11157. pInfo->dwStatus = pAsn1->cmcStatus;
  11158. }
  11159. if (pAsn1->bodyList.count > 0) {
  11160. ASN1uint32_t count = pAsn1->bodyList.count;
  11161. lAlignExtra = INFO_LEN_ALIGN(count * sizeof(DWORD));
  11162. lRemainExtra -= lAlignExtra;
  11163. if (lRemainExtra >= 0) {
  11164. BodyPartID *value;
  11165. DWORD *pdwBodyList;
  11166. value = pAsn1->bodyList.value;
  11167. pdwBodyList = (DWORD *) pbExtra;
  11168. pbExtra += lAlignExtra;
  11169. pInfo->cBodyList = count;
  11170. pInfo->rgdwBodyList = pdwBodyList;
  11171. for ( ; count > 0; count--, value++, pdwBodyList++)
  11172. *pdwBodyList = *value;
  11173. }
  11174. }
  11175. if (pAsn1->bit_mask & statusString_present) {
  11176. ASN1uint32_t length = pAsn1->statusString.length;
  11177. lAlignExtra = INFO_LEN_ALIGN((length + 1) * sizeof(WCHAR));
  11178. lRemainExtra -= lAlignExtra;
  11179. if (lRemainExtra >= 0) {
  11180. memcpy(pbExtra, pAsn1->statusString.value, length * sizeof(WCHAR));
  11181. memset(pbExtra + (length * sizeof(WCHAR)), 0, sizeof(WCHAR));
  11182. pInfo->pwszStatusString = (LPWSTR) pbExtra;
  11183. pbExtra += lAlignExtra;
  11184. }
  11185. }
  11186. if (pAsn1->bit_mask & otherInfo_present) {
  11187. switch (pAsn1->otherInfo.choice) {
  11188. case failInfo_chosen:
  11189. if (lRemainExtra >= 0) {
  11190. pInfo->dwOtherInfoChoice = CMC_OTHER_INFO_FAIL_CHOICE;
  11191. pInfo->dwFailInfo = pAsn1->otherInfo.u.failInfo;
  11192. }
  11193. break;
  11194. case pendInfo_chosen:
  11195. {
  11196. PCMC_PEND_INFO pPendInfo;
  11197. lAlignExtra = INFO_LEN_ALIGN(sizeof(CMC_PEND_INFO));
  11198. lRemainExtra -= lAlignExtra;
  11199. if (lRemainExtra >= 0) {
  11200. pInfo->dwOtherInfoChoice = CMC_OTHER_INFO_PEND_CHOICE;
  11201. pPendInfo = (PCMC_PEND_INFO) pbExtra;
  11202. pInfo->pPendInfo = pPendInfo;
  11203. pbExtra += lAlignExtra;
  11204. if (!PkiAsn1FromGeneralizedTime(
  11205. &pAsn1->otherInfo.u.pendInfo.pendTime,
  11206. &pPendInfo->PendTime))
  11207. goto GeneralizedTimeDecodeError;
  11208. } else
  11209. pPendInfo = NULL;
  11210. Asn1X509GetOctetString(
  11211. &pAsn1->otherInfo.u.pendInfo.pendToken, dwFlags,
  11212. &pPendInfo->PendToken, &pbExtra, &lRemainExtra);
  11213. }
  11214. break;
  11215. default:
  11216. goto InvalidOtherInfoChoiceError;
  11217. }
  11218. }
  11219. fResult = TRUE;
  11220. CommonReturn:
  11221. *plRemainExtra = lRemainExtra;
  11222. return fResult;
  11223. ErrorReturn:
  11224. fResult = FALSE;
  11225. goto CommonReturn;
  11226. SET_ERROR(InvalidOtherInfoChoiceError, CRYPT_E_BAD_ENCODE)
  11227. SET_ERROR(GeneralizedTimeDecodeError, CRYPT_E_BAD_ENCODE)
  11228. }
  11229. BOOL WINAPI Asn1CmcStatusDecodeEx(
  11230. IN DWORD dwCertEncodingType,
  11231. IN LPCSTR lpszStructType,
  11232. IN const BYTE *pbEncoded,
  11233. IN DWORD cbEncoded,
  11234. IN DWORD dwFlags,
  11235. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  11236. OUT OPTIONAL void *pvStructInfo,
  11237. IN OUT DWORD *pcbStructInfo
  11238. )
  11239. {
  11240. return Asn1InfoDecodeAndAllocEx(
  11241. CmcStatusInfo_PDU,
  11242. pbEncoded,
  11243. cbEncoded,
  11244. dwFlags,
  11245. pDecodePara,
  11246. Asn1CmcStatusDecodeExCallback,
  11247. pvStructInfo,
  11248. pcbStructInfo
  11249. );
  11250. }
  11251. //+-------------------------------------------------------------------------
  11252. // CMC Add Extensions Encode (ASN1)
  11253. //--------------------------------------------------------------------------
  11254. BOOL WINAPI Asn1CmcAddExtensionsEncodeEx(
  11255. IN DWORD dwCertEncodingType,
  11256. IN LPCSTR lpszStructType,
  11257. IN PCMC_ADD_EXTENSIONS_INFO pInfo,
  11258. IN DWORD dwFlags,
  11259. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  11260. OUT OPTIONAL void *pvEncoded,
  11261. IN OUT DWORD *pcbEncoded
  11262. )
  11263. {
  11264. BOOL fResult;
  11265. CmcAddExtensions Asn1Info;
  11266. memset(&Asn1Info, 0, sizeof(Asn1Info));
  11267. Asn1Info.pkiDataReference = pInfo->dwCmcDataReference;
  11268. if (pInfo->cCertReference) {
  11269. Asn1Info.certReferences.count = pInfo->cCertReference;
  11270. Asn1Info.certReferences.value = pInfo->rgdwCertReference;
  11271. }
  11272. if (!Asn1X509SetExtensions(pInfo->cExtension, pInfo->rgExtension,
  11273. &Asn1Info.extensions))
  11274. goto ErrorReturn;
  11275. fResult = Asn1InfoEncodeEx(
  11276. CmcAddExtensions_PDU,
  11277. &Asn1Info,
  11278. dwFlags,
  11279. pEncodePara,
  11280. pvEncoded,
  11281. pcbEncoded
  11282. );
  11283. CommonReturn:
  11284. Asn1X509FreeExtensions(&Asn1Info.extensions);
  11285. return fResult;
  11286. ErrorReturn:
  11287. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  11288. *((void **) pvEncoded) = NULL;
  11289. *pcbEncoded = 0;
  11290. fResult = FALSE;
  11291. goto CommonReturn;
  11292. }
  11293. //+-------------------------------------------------------------------------
  11294. // CMC Add Extensions Decode (ASN1)
  11295. //--------------------------------------------------------------------------
  11296. BOOL WINAPI Asn1CmcAddExtensionsDecodeExCallback(
  11297. IN void *pvAsn1Info,
  11298. IN DWORD dwFlags,
  11299. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  11300. OUT OPTIONAL void *pvStructInfo,
  11301. IN OUT LONG *plRemainExtra
  11302. )
  11303. {
  11304. BOOL fResult;
  11305. CmcAddExtensions *pAsn1 = (CmcAddExtensions *) pvAsn1Info;
  11306. PCMC_ADD_EXTENSIONS_INFO pInfo = (PCMC_ADD_EXTENSIONS_INFO) pvStructInfo;
  11307. LONG lRemainExtra = *plRemainExtra;
  11308. LONG lAlignExtra;
  11309. BYTE *pbExtra;
  11310. lRemainExtra -= sizeof(CMC_ADD_EXTENSIONS_INFO);
  11311. if (lRemainExtra < 0) {
  11312. pbExtra = NULL;
  11313. } else {
  11314. memset(pInfo, 0, sizeof(CMC_ADD_EXTENSIONS_INFO));
  11315. pbExtra = (BYTE *) pInfo + sizeof(CMC_ADD_EXTENSIONS_INFO);
  11316. pInfo->dwCmcDataReference = pAsn1->pkiDataReference;
  11317. }
  11318. if (pAsn1->certReferences.count > 0) {
  11319. ASN1uint32_t count = pAsn1->certReferences.count;
  11320. lAlignExtra = INFO_LEN_ALIGN(count * sizeof(DWORD));
  11321. lRemainExtra -= lAlignExtra;
  11322. if (lRemainExtra >= 0) {
  11323. BodyPartID *value;
  11324. DWORD *pdwCertReference;
  11325. value = pAsn1->certReferences.value;
  11326. pdwCertReference = (DWORD *) pbExtra;
  11327. pbExtra += lAlignExtra;
  11328. pInfo->cCertReference = count;
  11329. pInfo->rgdwCertReference = pdwCertReference;
  11330. for ( ; count > 0; count--, value++, pdwCertReference++)
  11331. *pdwCertReference = *value;
  11332. }
  11333. }
  11334. Asn1X509GetExtensions(&pAsn1->extensions, dwFlags,
  11335. &pInfo->cExtension, &pInfo->rgExtension, &pbExtra, &lRemainExtra);
  11336. fResult = TRUE;
  11337. *plRemainExtra = lRemainExtra;
  11338. return fResult;
  11339. }
  11340. BOOL WINAPI Asn1CmcAddExtensionsDecodeEx(
  11341. IN DWORD dwCertEncodingType,
  11342. IN LPCSTR lpszStructType,
  11343. IN const BYTE *pbEncoded,
  11344. IN DWORD cbEncoded,
  11345. IN DWORD dwFlags,
  11346. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  11347. OUT OPTIONAL void *pvStructInfo,
  11348. IN OUT DWORD *pcbStructInfo
  11349. )
  11350. {
  11351. return Asn1InfoDecodeAndAllocEx(
  11352. CmcAddExtensions_PDU,
  11353. pbEncoded,
  11354. cbEncoded,
  11355. dwFlags,
  11356. pDecodePara,
  11357. Asn1CmcAddExtensionsDecodeExCallback,
  11358. pvStructInfo,
  11359. pcbStructInfo
  11360. );
  11361. }
  11362. //+-------------------------------------------------------------------------
  11363. // CMC Add Attributes Encode (ASN1)
  11364. //--------------------------------------------------------------------------
  11365. BOOL WINAPI Asn1CmcAddAttributesEncodeEx(
  11366. IN DWORD dwCertEncodingType,
  11367. IN LPCSTR lpszStructType,
  11368. IN PCMC_ADD_ATTRIBUTES_INFO pInfo,
  11369. IN DWORD dwFlags,
  11370. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  11371. OUT OPTIONAL void *pvEncoded,
  11372. IN OUT DWORD *pcbEncoded
  11373. )
  11374. {
  11375. BOOL fResult;
  11376. CmcAddAttributes Asn1Info;
  11377. memset(&Asn1Info, 0, sizeof(Asn1Info));
  11378. Asn1Info.pkiDataReference = pInfo->dwCmcDataReference;
  11379. if (pInfo->cCertReference) {
  11380. Asn1Info.certReferences.count = pInfo->cCertReference;
  11381. Asn1Info.certReferences.value = pInfo->rgdwCertReference;
  11382. }
  11383. if (!Asn1X509SetAttributes(pInfo->cAttribute, pInfo->rgAttribute,
  11384. &Asn1Info.attributes))
  11385. goto ErrorReturn;
  11386. fResult = Asn1InfoEncodeEx(
  11387. CmcAddAttributes_PDU,
  11388. &Asn1Info,
  11389. dwFlags,
  11390. pEncodePara,
  11391. pvEncoded,
  11392. pcbEncoded
  11393. );
  11394. CommonReturn:
  11395. Asn1X509FreeAttributes(&Asn1Info.attributes);
  11396. return fResult;
  11397. ErrorReturn:
  11398. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  11399. *((void **) pvEncoded) = NULL;
  11400. *pcbEncoded = 0;
  11401. fResult = FALSE;
  11402. goto CommonReturn;
  11403. }
  11404. //+-------------------------------------------------------------------------
  11405. // CMC Add Attributes Decode (ASN1)
  11406. //--------------------------------------------------------------------------
  11407. BOOL WINAPI Asn1CmcAddAttributesDecodeExCallback(
  11408. IN void *pvAsn1Info,
  11409. IN DWORD dwFlags,
  11410. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  11411. OUT OPTIONAL void *pvStructInfo,
  11412. IN OUT LONG *plRemainExtra
  11413. )
  11414. {
  11415. BOOL fResult;
  11416. CmcAddAttributes *pAsn1 = (CmcAddAttributes *) pvAsn1Info;
  11417. PCMC_ADD_ATTRIBUTES_INFO pInfo = (PCMC_ADD_ATTRIBUTES_INFO) pvStructInfo;
  11418. LONG lRemainExtra = *plRemainExtra;
  11419. LONG lAlignExtra;
  11420. BYTE *pbExtra;
  11421. lRemainExtra -= sizeof(CMC_ADD_ATTRIBUTES_INFO);
  11422. if (lRemainExtra < 0) {
  11423. pbExtra = NULL;
  11424. } else {
  11425. memset(pInfo, 0, sizeof(CMC_ADD_ATTRIBUTES_INFO));
  11426. pbExtra = (BYTE *) pInfo + sizeof(CMC_ADD_ATTRIBUTES_INFO);
  11427. pInfo->dwCmcDataReference = pAsn1->pkiDataReference;
  11428. }
  11429. if (pAsn1->certReferences.count > 0) {
  11430. ASN1uint32_t count = pAsn1->certReferences.count;
  11431. lAlignExtra = INFO_LEN_ALIGN(count * sizeof(DWORD));
  11432. lRemainExtra -= lAlignExtra;
  11433. if (lRemainExtra >= 0) {
  11434. BodyPartID *value;
  11435. DWORD *pdwCertReference;
  11436. value = pAsn1->certReferences.value;
  11437. pdwCertReference = (DWORD *) pbExtra;
  11438. pbExtra += lAlignExtra;
  11439. pInfo->cCertReference = count;
  11440. pInfo->rgdwCertReference = pdwCertReference;
  11441. for ( ; count > 0; count--, value++, pdwCertReference++)
  11442. *pdwCertReference = *value;
  11443. }
  11444. }
  11445. Asn1X509GetAttributes(&pAsn1->attributes, dwFlags,
  11446. &pInfo->cAttribute, &pInfo->rgAttribute, &pbExtra, &lRemainExtra);
  11447. fResult = TRUE;
  11448. *plRemainExtra = lRemainExtra;
  11449. return fResult;
  11450. }
  11451. BOOL WINAPI Asn1CmcAddAttributesDecodeEx(
  11452. IN DWORD dwCertEncodingType,
  11453. IN LPCSTR lpszStructType,
  11454. IN const BYTE *pbEncoded,
  11455. IN DWORD cbEncoded,
  11456. IN DWORD dwFlags,
  11457. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  11458. OUT OPTIONAL void *pvStructInfo,
  11459. IN OUT DWORD *pcbStructInfo
  11460. )
  11461. {
  11462. return Asn1InfoDecodeAndAllocEx(
  11463. CmcAddAttributes_PDU,
  11464. pbEncoded,
  11465. cbEncoded,
  11466. dwFlags,
  11467. pDecodePara,
  11468. Asn1CmcAddAttributesDecodeExCallback,
  11469. pvStructInfo,
  11470. pcbStructInfo
  11471. );
  11472. }
  11473. //+=========================================================================
  11474. // Certificate Template Encode/Decode Functions
  11475. //==========================================================================
  11476. BOOL WINAPI Asn1X509CertTemplateEncodeEx(
  11477. IN DWORD dwCertEncodingType,
  11478. IN LPCSTR lpszStructType,
  11479. IN PCERT_TEMPLATE_EXT pInfo,
  11480. IN DWORD dwFlags,
  11481. IN OPTIONAL PCRYPT_ENCODE_PARA pEncodePara,
  11482. OUT OPTIONAL void *pvEncoded,
  11483. IN OUT DWORD *pcbEncoded
  11484. )
  11485. {
  11486. BOOL fResult;
  11487. CertificateTemplate Asn1Info;
  11488. memset(&Asn1Info, 0, sizeof(Asn1Info));
  11489. if (!Asn1X509SetEncodedObjId(pInfo->pszObjId, &Asn1Info.templateID))
  11490. goto ErrorReturn;
  11491. Asn1Info.templateMajorVersion = pInfo->dwMajorVersion;
  11492. if (pInfo->fMinorVersion) {
  11493. Asn1Info.bit_mask |= templateMinorVersion_present;
  11494. Asn1Info.templateMinorVersion = pInfo->dwMinorVersion;
  11495. }
  11496. fResult = Asn1InfoEncodeEx(
  11497. CertificateTemplate_PDU,
  11498. &Asn1Info,
  11499. dwFlags,
  11500. pEncodePara,
  11501. pvEncoded,
  11502. pcbEncoded
  11503. );
  11504. goto CommonReturn;
  11505. ErrorReturn:
  11506. if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
  11507. *((void **) pvEncoded) = NULL;
  11508. *pcbEncoded = 0;
  11509. fResult = FALSE;
  11510. CommonReturn:
  11511. return fResult;
  11512. }
  11513. BOOL WINAPI Asn1X509CertTemplateDecodeExCallback(
  11514. IN void *pvAsn1Info,
  11515. IN DWORD dwFlags,
  11516. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  11517. OUT OPTIONAL void *pvStructInfo,
  11518. IN OUT LONG *plRemainExtra
  11519. )
  11520. {
  11521. CertificateTemplate *pAsn1Info = (CertificateTemplate *) pvAsn1Info;
  11522. PCERT_TEMPLATE_EXT pInfo =
  11523. (PCERT_TEMPLATE_EXT) pvStructInfo;
  11524. LONG lRemainExtra = *plRemainExtra;
  11525. BYTE *pbExtra;
  11526. lRemainExtra -= sizeof(CERT_TEMPLATE_EXT);
  11527. if (lRemainExtra < 0) {
  11528. pbExtra = NULL;
  11529. } else {
  11530. memset(pInfo, 0, sizeof(CERT_TEMPLATE_EXT));
  11531. pbExtra = (BYTE *) pInfo + sizeof(CERT_TEMPLATE_EXT);
  11532. pInfo->dwMajorVersion = pAsn1Info->templateMajorVersion;
  11533. if (pAsn1Info->bit_mask & templateMinorVersion_present) {
  11534. pInfo->fMinorVersion = TRUE;
  11535. pInfo->dwMinorVersion = pAsn1Info->templateMinorVersion;
  11536. }
  11537. }
  11538. Asn1X509GetEncodedObjId(&pAsn1Info->templateID, dwFlags,
  11539. &pInfo->pszObjId, &pbExtra, &lRemainExtra);
  11540. *plRemainExtra = lRemainExtra;
  11541. return TRUE;
  11542. }
  11543. BOOL WINAPI Asn1X509CertTemplateDecodeEx(
  11544. IN DWORD dwCertEncodingType,
  11545. IN LPCSTR lpszStructType,
  11546. IN const BYTE *pbEncoded,
  11547. IN DWORD cbEncoded,
  11548. IN DWORD dwFlags,
  11549. IN OPTIONAL PCRYPT_DECODE_PARA pDecodePara,
  11550. OUT OPTIONAL void *pvStructInfo,
  11551. IN OUT DWORD *pcbStructInfo
  11552. )
  11553. {
  11554. return Asn1InfoDecodeAndAllocEx(
  11555. CertificateTemplate_PDU,
  11556. pbEncoded,
  11557. cbEncoded,
  11558. dwFlags,
  11559. pDecodePara,
  11560. Asn1X509CertTemplateDecodeExCallback,
  11561. pvStructInfo,
  11562. pcbStructInfo
  11563. );
  11564. }