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.

856 lines
30 KiB

  1. //+-------------------------------------------------------------------------
  2. // Microsoft Windows
  3. //
  4. // Copyright (C) Microsoft Corporation, 2001 - 2001
  5. //
  6. // File: minasn1.h
  7. //
  8. // Contents: Minimal ASN.1 Utility and Parsing API Prototypes
  9. // and Definitions
  10. //
  11. // Contains functions to parse X.509 certificates, PKCS #7
  12. // Signed Data messages, Certificate Trusts Lists (CTLs),
  13. // hash catalogs, Authenticode Indirect Data and
  14. // RSA public keys.
  15. //
  16. // These APIs are implemented to be self contained and to
  17. // allow for code obfuscation. These APIs will be included
  18. // in such applications as, DRM or licensing verification.
  19. //
  20. // Additionally, since these APIs have been pared down
  21. // from their wincrypt.h and crypt32.dll counterparts they are
  22. // a good candidate for applications with minimal memory and CPU
  23. // resources.
  24. //
  25. // These parsing functions don't depend on more heavy wait
  26. // ASN.1 runtimes, such as, msoss.dll or msasn1.dll.
  27. //
  28. // These functions will only use stack memory. No heap
  29. // allocations. No calls to APIs in other DLLs.
  30. //
  31. // APIs:
  32. // MinAsn1DecodeLength
  33. // MinAsn1ExtractContent
  34. // MinAsn1ExtractValues
  35. //
  36. // MinAsn1ParseCertificate
  37. // MinAsn1ParseAlgorithmIdentifier
  38. // MinAsn1ParsePublicKeyInfo
  39. // MinAsn1ParseRSAPublicKey
  40. // MinAsn1ParseExtensions
  41. // MinAsn1ParseSignedData
  42. // MinAsn1ParseSignedDataCertificates
  43. // MinAsn1ParseAttributes
  44. // MinAsn1ParseCTL
  45. // MinAsn1ParseCTLSubject
  46. // MinAsn1ParseIndirectData
  47. //
  48. // MinAsn1FindExtension
  49. // MinAsn1FindAttribute
  50. // MinAsn1ExtractParsedCertificatesFromSignedData
  51. //
  52. //----------------------------------------------------------------------------
  53. #ifndef __MINASN1_H__
  54. #define __MINASN1_H__
  55. #if defined (_MSC_VER)
  56. #if ( _MSC_VER >= 800 )
  57. #if _MSC_VER >= 1200
  58. #pragma warning(push)
  59. #endif
  60. #pragma warning(disable:4201) /* Nameless struct/union */
  61. #endif
  62. #if (_MSC_VER > 1020)
  63. #pragma once
  64. #endif
  65. #endif
  66. #include <wincrypt.h>
  67. #ifdef __cplusplus
  68. extern "C" {
  69. #endif
  70. //+-------------------------------------------------------------------------
  71. // ASN.1 Tag Defines
  72. //--------------------------------------------------------------------------
  73. #define MINASN1_TAG_NULL 0x00
  74. #define MINASN1_TAG_BOOLEAN 0x01
  75. #define MINASN1_TAG_INTEGER 0x02
  76. #define MINASN1_TAG_BITSTRING 0x03
  77. #define MINASN1_TAG_OCTETSTRING 0x04
  78. #define MINASN1_TAG_OID 0x06
  79. #define MINASN1_TAG_UTC_TIME 0x17
  80. #define MINASN1_TAG_GENERALIZED_TIME 0x18
  81. #define MINASN1_TAG_CONSTRUCTED 0x20
  82. #define MINASN1_TAG_SEQ 0x30
  83. #define MINASN1_TAG_SET 0x31
  84. #define MINASN1_TAG_CONTEXT_0 0x80
  85. #define MINASN1_TAG_CONTEXT_1 0x81
  86. #define MINASN1_TAG_CONTEXT_2 0x82
  87. #define MINASN1_TAG_CONTEXT_3 0x83
  88. #define MINASN1_TAG_CONSTRUCTED_CONTEXT_0 \
  89. (MINASN1_TAG_CONSTRUCTED | MINASN1_TAG_CONTEXT_0)
  90. #define MINASN1_TAG_CONSTRUCTED_CONTEXT_1 \
  91. (MINASN1_TAG_CONSTRUCTED | MINASN1_TAG_CONTEXT_1)
  92. #define MINASN1_TAG_CONSTRUCTED_CONTEXT_3 \
  93. (MINASN1_TAG_CONSTRUCTED | MINASN1_TAG_CONTEXT_3)
  94. //+-------------------------------------------------------------------------
  95. // ASN.1 Length Defines for indefinite length encooding
  96. //--------------------------------------------------------------------------
  97. #define MINASN1_LENGTH_INDEFINITE 0x80
  98. #define MINASN1_LENGTH_NULL 0x00
  99. #define MINASN1_LENGTH_TOO_LARGE -1
  100. #define MINASN1_INSUFFICIENT_DATA -2
  101. #define MINASN1_UNSUPPORTED_INDEFINITE_LENGTH -3
  102. //+-------------------------------------------------------------------------
  103. // Get the number of contents octets in a definite-length BER-encoding.
  104. //
  105. // Parameters:
  106. // pcbContent - receives the number of contents octets
  107. // pbLength - points to the first length octet
  108. // cbBER - number of bytes remaining in the BER encoding
  109. //
  110. // Returns:
  111. // success - the number of bytes in the length field, > 0
  112. // failure - < 0
  113. //
  114. // One of the following failure values can be returned:
  115. // MINASN1_LENGTH_TOO_LARGE
  116. // MINASN1_INSUFFICIENT_DATA
  117. // MINASN1_UNSUPPORTED_INDEFINITE_LENGTH
  118. //--------------------------------------------------------------------------
  119. LONG
  120. WINAPI
  121. MinAsn1DecodeLength(
  122. OUT DWORD *pcbContent,
  123. IN const BYTE *pbLength,
  124. IN DWORD cbBER
  125. );
  126. //+-------------------------------------------------------------------------
  127. // Point to the content octets in a definite-length BER-encoded blob.
  128. //
  129. // Returns:
  130. // success - the number of bytes skipped, > 0
  131. // failure - < 0
  132. //
  133. // One of the following failure values can be returned:
  134. // MINASN1_LENGTH_TOO_LARGE
  135. // MINASN1_INSUFFICIENT_DATA
  136. // MINASN1_UNSUPPORTED_INDEFINITE_LENGTH
  137. //
  138. // Assumption: pbData points to a definite-length BER-encoded blob.
  139. // If *pcbContent isn't within cbBER, MINASN1_INSUFFICIENT_DATA
  140. // is returned.
  141. //--------------------------------------------------------------------------
  142. LONG
  143. WINAPI
  144. MinAsn1ExtractContent(
  145. IN const BYTE *pbBER,
  146. IN DWORD cbBER,
  147. OUT DWORD *pcbContent,
  148. OUT const BYTE **ppbContent
  149. );
  150. typedef struct _MINASN1_EXTRACT_VALUE_PARA {
  151. // See below for list of operations and optional return blobs.
  152. DWORD dwFlags;
  153. // Index into rgValueBlob of the returned value. Ignored if none of
  154. // the ASN1_PARSE_RETURN_*_BLOB_FLAG's is set in the above dwFlags.
  155. DWORD dwIndex;
  156. // The following 0 terminated array of tags is optional. If ommited, the
  157. // value may contain any tag.
  158. const BYTE *rgbTag;
  159. } MINASN1_EXTRACT_VALUE_PARA, *PMINASN1_EXTRACT_VALUE_PARA;
  160. // The lower 8 bits of dwFlags is set to one of the following operations
  161. #define MINASN1_MASK_VALUE_OP 0xFF
  162. #define MINASN1_STEP_OVER_VALUE_OP 1
  163. #define MINASN1_OPTIONAL_STEP_OVER_VALUE_OP 2
  164. #define MINASN1_STEP_INTO_VALUE_OP 3
  165. #define MINASN1_OPTIONAL_STEP_INTO_VALUE_OP 4
  166. #define MINASN1_STEP_OUT_VALUE_OP 5
  167. #define MINASN1_RETURN_VALUE_BLOB_FLAG 0x80000000
  168. #define MINASN1_RETURN_CONTENT_BLOB_FLAG 0x40000000
  169. //+-------------------------------------------------------------------------
  170. // Extract one or more tagged values from the ASN.1 encoded byte array.
  171. //
  172. // Either steps into the value's content octets (MINASN1_STEP_INTO_VALUE_OP or
  173. // MINASN1_OPTIONAL_STEP_INTO_VALUE_OP) or steps over the value's tag,
  174. // length and content octets (MINASN1_STEP_OVER_VALUE_OP or
  175. // MINASN1_OPTIONAL_STEP_OVER_VALUE_OP).
  176. //
  177. // You can step out of a stepped into sequence via MINASN1_STEP_OUT_VALUE_OP.
  178. //
  179. // For tag matching, only supports single byte tags.
  180. //
  181. // Only definite-length ASN.1 is supported.
  182. //
  183. // *pcValue is updated with the number of values successfully extracted.
  184. //
  185. // Returns:
  186. // success - >= 0 => length of all bytes consumed through the last value
  187. // extracted. For STEP_INTO, only the tag and length
  188. // octets.
  189. // failure - < 0 => negative (offset + 1) of first bad tagged value
  190. //
  191. // A non-NULL rgValueBlob[] is updated with the pointer to and length of the
  192. // tagged value or its content octets. The rgValuePara[].dwIndex is used to
  193. // index into rgValueBlob[]. For OPTIONAL_STEP_OVER or
  194. // OPTIONAL_STEP_INTO, if no more bytes in the outer SEQUENCE or if the tag
  195. // isn't found, pbData and cbData are set to 0. Additioanlly, for
  196. // OPTIONAL_STEP_INTO, all subsequent values are skipped and their
  197. // rgValueBlob[] entries zeroed until a STEP_OUT is encountered.
  198. //
  199. // If MINASN1_RETURN_VALUE_BLOB_FLAG is set, pbData points to
  200. // the tag. cbData includes the tag, length and content octets.
  201. //
  202. // If MINASN1_RETURN_CONTENT_BLOB_FLAG is set, pbData points to the content
  203. // octets. cbData includes only the content octets.
  204. //
  205. // If neither BLOB_FLAG is set, rgValueBlob[] isn't updated.
  206. //
  207. // For MINASN1_RETURN_CONTENT_BLOB_FLAG of a BITSTRING, pbData is
  208. // advanced past the first contents octet containing the number of
  209. // unused bits and cbData has been decremented by 1. If cbData > 0, then,
  210. // *(pbData - 1) will contain the number of unused bits.
  211. //--------------------------------------------------------------------------
  212. LONG
  213. WINAPI
  214. MinAsn1ExtractValues(
  215. IN const BYTE *pbEncoded,
  216. IN DWORD cbEncoded,
  217. IN OUT DWORD *pcValuePara,
  218. IN const MINASN1_EXTRACT_VALUE_PARA *rgValuePara,
  219. IN DWORD cValueBlob,
  220. OUT OPTIONAL PCRYPT_DER_BLOB rgValueBlob
  221. );
  222. //+-------------------------------------------------------------------------
  223. // Function: MinAsn1ParseCertificate
  224. //
  225. // Parses an ASN.1 encoded X.509 certificate.
  226. //
  227. // Returns:
  228. // success - > 0 => bytes skipped, length of the encoded certificate
  229. // failure - < 0 => negative (offset + 1) of first bad tagged value
  230. //
  231. // The rgCertBlob[] is updated with pointer to and length of the following
  232. // fields in the encoded X.509 certificate.
  233. //
  234. // All BITSTRING fields have been advanced past the unused count octet.
  235. //--------------------------------------------------------------------------
  236. // Encoded bytes including To Be Signed and Signature
  237. #define MINASN1_CERT_ENCODED_IDX 1
  238. // To Be Signed bytes
  239. #define MINASN1_CERT_TO_BE_SIGNED_IDX 2
  240. // Signature Algorithm value bytes (MinAsn1ParseAlgorithmIdentifier)
  241. #define MINASN1_CERT_SIGN_ALGID_IDX 3
  242. // Signature content bytes (BITSTRING)
  243. #define MINASN1_CERT_SIGNATURE_IDX 4
  244. // Version content bytes (OPTIONAL INTEGER)
  245. #define MINASN1_CERT_VERSION_IDX 5
  246. // Serial Number content bytes (INTEGER)
  247. #define MINASN1_CERT_SERIAL_NUMBER_IDX 6
  248. // Issuer Name value bytes (ANY)
  249. #define MINASN1_CERT_ISSUER_IDX 7
  250. // Not Before value bytes (UTC_TIME or GENERALIZED_TIME)
  251. #define MINASN1_CERT_NOT_BEFORE_IDX 8
  252. // Not After value bytes (UTC_TIME or GENERALIZED_TIME)
  253. #define MINASN1_CERT_NOT_AFTER_IDX 9
  254. // Subject Name value bytes (ANY)
  255. #define MINASN1_CERT_SUBJECT_IDX 10
  256. // Public Key Info value bytes (MinAsn1ParsePublicKeyInfo)
  257. #define MINASN1_CERT_PUBKEY_INFO_IDX 11
  258. // Issuer Unique Id content bytes (OPTIONAL BITSTRING)
  259. #define MINASN1_CERT_ISSUER_UNIQUE_ID_IDX 12
  260. // Subject Unique Id content bytes (OPTIONAL BITSTRING)
  261. #define MINASN1_CERT_SUBJECT_UNIQUE_ID_IDX 13
  262. // Extensions value bytes skipping "[3] EXPLICIT" tag
  263. // (OPTIONAL MinAsn1ParseExtensions)
  264. #define MINASN1_CERT_EXTS_IDX 14
  265. #define MINASN1_CERT_BLOB_CNT 15
  266. LONG
  267. WINAPI
  268. MinAsn1ParseCertificate(
  269. IN const BYTE *pbEncoded,
  270. IN DWORD cbEncoded,
  271. OUT CRYPT_DER_BLOB rgCertBlob[MINASN1_CERT_BLOB_CNT]
  272. );
  273. //+-------------------------------------------------------------------------
  274. // Function: MinAsn1ParseAlgorithmIdentifier
  275. //
  276. // Parses an ASN.1 encoded Algorithm Identifier contained in numerous
  277. // other ASN.1 structures, such as, X.509 certificate and PKCS #7 Signed Data
  278. // message.
  279. //
  280. // Returns:
  281. // success - > 0 => bytes skipped, length of the encoded algorithm
  282. // identifier
  283. // failure - < 0 => negative (offset + 1) of first bad tagged value
  284. //
  285. // The rgAlgIdBlob[] is updated with pointer to and length of the following
  286. // fields in the encoded Algorithm Identifier
  287. //--------------------------------------------------------------------------
  288. // Encoded bytes including outer SEQUENCE tag and length octets
  289. #define MINASN1_ALGID_ENCODED_IDX 1
  290. // Object Identifier content bytes (OID)
  291. #define MINASN1_ALGID_OID_IDX 2
  292. // Encoded parameters value bytes (OPTIONAL ANY)
  293. #define MINASN1_ALGID_PARA_IDX 3
  294. #define MINASN1_ALGID_BLOB_CNT 4
  295. LONG
  296. WINAPI
  297. MinAsn1ParseAlgorithmIdentifier(
  298. IN PCRYPT_DER_BLOB pAlgIdValueBlob,
  299. OUT CRYPT_DER_BLOB rgAlgIdBlob[MINASN1_ALGID_BLOB_CNT]
  300. );
  301. //+-------------------------------------------------------------------------
  302. // Function: MinAsn1ParsePublicKeyInfo
  303. //
  304. // Parses an ASN.1 encoded Public Key Info structure contained in an
  305. // X.509 certificate
  306. //
  307. // Returns:
  308. // success - > 0 => bytes skipped, length of the encoded public key
  309. // info
  310. // failure - < 0 => negative (offset + 1) of first bad tagged value
  311. //
  312. // The rgPubKeyInfoBlob[] is updated with pointer to and length of the
  313. // following fields in the encoded Public Key Info.
  314. //
  315. // All BITSTRING fields have been advanced past the unused count octet.
  316. //--------------------------------------------------------------------------
  317. // Encoded bytes including outer SEQUENCE tag and length octets
  318. #define MINASN1_PUBKEY_INFO_ENCODED_IDX 1
  319. // Algorithm Identifier value bytes (MinAsn1ParseAlgorithmIdentifier)
  320. #define MINASN1_PUBKEY_INFO_ALGID_IDX 2
  321. // Public Key content bytes (BITSTRING, MinAsn1ParseRSAPublicKey)
  322. #define MINASN1_PUBKEY_INFO_PUBKEY_IDX 3
  323. #define MINASN1_PUBKEY_INFO_BLOB_CNT 4
  324. LONG
  325. WINAPI
  326. MinAsn1ParsePublicKeyInfo(
  327. IN PCRYPT_DER_BLOB pPubKeyInfoValueBlob,
  328. CRYPT_DER_BLOB rgPubKeyInfoBlob[MINASN1_PUBKEY_INFO_BLOB_CNT]
  329. );
  330. //+-------------------------------------------------------------------------
  331. // Function: MinAsn1ParseRSAPublicKey
  332. //
  333. // Parses an ASN.1 encoded RSA PKCS #1 Public Key contained in the contents of
  334. // Public Key BITSTRING in a X.509 certificate.
  335. //
  336. // Returns:
  337. // success - > 0 => bytes skipped, length of the encoded RSA public key
  338. // failure - < 0 => negative (offset + 1) of first bad tagged value
  339. //
  340. // The rgRSAPubKeyBlob[] is updated with pointer to and length of the
  341. // following fields in the encoded RSA Public Key.
  342. //--------------------------------------------------------------------------
  343. // Encoded bytes including outer SEQUENCE tag and length octets
  344. #define MINASN1_RSA_PUBKEY_ENCODED_IDX 1
  345. // Modulus content bytes (INTEGER)
  346. #define MINASN1_RSA_PUBKEY_MODULUS_IDX 2
  347. // Exponent content bytes (INTEGER)
  348. #define MINASN1_RSA_PUBKEY_EXPONENT_IDX 3
  349. #define MINASN1_RSA_PUBKEY_BLOB_CNT 4
  350. LONG
  351. WINAPI
  352. MinAsn1ParseRSAPublicKey(
  353. IN PCRYPT_DER_BLOB pPubKeyContentBlob,
  354. CRYPT_DER_BLOB rgRSAPubKeyBlob[MINASN1_RSA_PUBKEY_BLOB_CNT]
  355. );
  356. //+-------------------------------------------------------------------------
  357. // Function: MinAsn1ParseExtensions
  358. //
  359. // Parses an ASN.1 encoded sequence of extensions contained in
  360. // other ASN.1 structures, such as, X.509 certificate and CTL.
  361. //
  362. // Upon input, *pcExt contains the maximum number of parsed extensions
  363. // that can be returned. Updated with the number of extensions processed.
  364. //
  365. // Returns:
  366. // success - >= 0 => bytes skipped, length of the encoded extensions
  367. // processed. If all extensions were processed,
  368. // bytes skipped = pExtsValueBlob->cbData.
  369. // failure - < 0 => negative (offset + 1) of first bad tagged value
  370. //
  371. // The rgrgExtBlob[][] is updated with pointer to and length of the
  372. // following fields in the encoded extension.
  373. //--------------------------------------------------------------------------
  374. // Encoded bytes including outer SEQUENCE tag and length octets
  375. #define MINASN1_EXT_ENCODED_IDX 1
  376. // Object Identifier content bytes (OID)
  377. #define MINASN1_EXT_OID_IDX 2
  378. // Critical content bytes (OPTIONAL BOOLEAN, DEFAULT FALSE)
  379. #define MINASN1_EXT_CRITICAL_IDX 3
  380. // Value content bytes (OCTETSTRING)
  381. #define MINASN1_EXT_VALUE_IDX 4
  382. #define MINASN1_EXT_BLOB_CNT 5
  383. LONG
  384. WINAPI
  385. MinAsn1ParseExtensions(
  386. IN PCRYPT_DER_BLOB pExtsValueBlob, // Extensions ::= SEQUENCE OF Extension
  387. IN OUT DWORD *pcExt,
  388. OUT CRYPT_DER_BLOB rgrgExtBlob[][MINASN1_EXT_BLOB_CNT]
  389. );
  390. //+-------------------------------------------------------------------------
  391. // Function: MinAsn1ParseSignedData
  392. //
  393. // Parses an ASN.1 encoded PKCS #7 Signed Data Message. Assumes the
  394. // PKCS #7 message is definite length encoded. Assumes PKCS #7 version
  395. // 1.5, ie, not the newer CMS version.
  396. //
  397. // Returns:
  398. // success - > 0 => bytes skipped, length of the encoded message
  399. // failure - < 0 => negative (offset + 1) of first bad tagged value
  400. //
  401. // The rgSignedDataBlob[] is updated with pointer to and length of the
  402. // following fields in the encoded PKCS #7 message.
  403. //--------------------------------------------------------------------------
  404. // Encoded bytes including outer SEQUENCE tag and length octets
  405. #define MINASN1_SIGNED_DATA_ENCODED_IDX 1
  406. // Outer Object Identfier content bytes (OID, should be "1.2.840.113549.1.7.2")
  407. #define MINASN1_SIGNED_DATA_OUTER_OID_IDX 2
  408. // Version content bytes (INTEGER)
  409. #define MINASN1_SIGNED_DATA_VERSION_IDX 3
  410. // Set of Digest Algorithms value bytes (SET OF)
  411. #define MINASN1_SIGNED_DATA_DIGEST_ALGIDS_IDX 4
  412. // Inner Object Identifier content bytes (OID)
  413. #define MINASN1_SIGNED_DATA_CONTENT_OID_IDX 5
  414. // Signed content data content bytes excluding "[0] EXPLICIT" tag
  415. // (OPTIONAL ANY, MinAsn1ParseCTL, MinAsn1ParseIndirectData)
  416. #define MINASN1_SIGNED_DATA_CONTENT_DATA_IDX 6
  417. // Certificates value bytes including "[1] IMPLICIT" tag
  418. // (OPTIONAL, MinAsn1ParseSignedDataCertificates)
  419. #define MINASN1_SIGNED_DATA_CERTS_IDX 7
  420. // CRL value bytes including "[2] IMPLICIT" tag (OPTIONAL)
  421. #define MINASN1_SIGNED_DATA_CRLS_IDX 8
  422. // Encoded bytes including outer SET tag and length octets
  423. #define MINASN1_SIGNED_DATA_SIGNER_INFOS_IDX 9
  424. // The following point to the first Signer Info fields (OPTIONAL)
  425. // Encoded bytes including outer SEQUENCE tag and length octets
  426. #define MINASN1_SIGNED_DATA_SIGNER_INFO_ENCODED_IDX 10
  427. // Version content bytes (INTEGER)
  428. #define MINASN1_SIGNED_DATA_SIGNER_INFO_VERSION_IDX 11
  429. // Issuer Name value bytes (ANY)
  430. #define MINASN1_SIGNED_DATA_SIGNER_INFO_ISSUER_IDX 12
  431. // Serial Number content bytes (INTEGER)
  432. #define MINASN1_SIGNED_DATA_SIGNER_INFO_SERIAL_NUMBER_IDX 13
  433. // Digest Algorithm value bytes (MinAsn1ParseAlgorithmIdentifier)
  434. #define MINASN1_SIGNED_DATA_SIGNER_INFO_DIGEST_ALGID_IDX 14
  435. // Authenticated attributes value bytes including "[0] IMPLICIT" tag
  436. // (OPTIONAL, MinAsn1ParseAttributes)
  437. #define MINASN1_SIGNED_DATA_SIGNER_INFO_AUTH_ATTRS_IDX 15
  438. // Encrypted Digest Algorithm value bytes (MinAsn1ParseAlgorithmIdentifier)
  439. #define MINASN1_SIGNED_DATA_SIGNER_INFO_ENCRYPT_DIGEST_ALGID_IDX 16
  440. // Encrypted digest content bytes (OCTET STRING)
  441. #define MINASN1_SIGNED_DATA_SIGNER_INFO_ENCYRPT_DIGEST_IDX 17
  442. // Unauthenticated attributes value bytes including "[1] IMPLICIT" tag
  443. // (OPTIONAL, MinAsn1ParseAttributes)
  444. #define MINASN1_SIGNED_DATA_SIGNER_INFO_UNAUTH_ATTRS_IDX 18
  445. #define MINASN1_SIGNED_DATA_BLOB_CNT 19
  446. LONG
  447. WINAPI
  448. MinAsn1ParseSignedData(
  449. IN const BYTE *pbEncoded,
  450. IN DWORD cbEncoded,
  451. OUT CRYPT_DER_BLOB rgSignedDataBlob[MINASN1_SIGNED_DATA_BLOB_CNT]
  452. );
  453. //+-------------------------------------------------------------------------
  454. // Function: MinAsn1ParseSignedDataCertificates
  455. //
  456. // Parses an ASN.1 encoded set of certificates contained in
  457. // a Signed Data message.
  458. //
  459. // Upon input, *pcCert contains the maximum number of parsed certificates
  460. // that can be returned. Updated with the number of certificates processed.
  461. //
  462. // Returns:
  463. // success - >= 0 => bytes skipped, length of the encoded certificates
  464. // processed. If all certificates were processed,
  465. // bytes skipped = pCertsValueBlob->cbData.
  466. // failure - < 0 => negative (offset + 1) of first bad tagged value
  467. //
  468. // The rgrgCertBlob[][] is updated with pointer to and length of the
  469. // fields in the encoded certificate. See MinAsn1ParseCertificate for the
  470. // field definitions.
  471. //--------------------------------------------------------------------------
  472. LONG
  473. WINAPI
  474. MinAsn1ParseSignedDataCertificates(
  475. IN PCRYPT_DER_BLOB pCertsValueBlob,
  476. IN OUT DWORD *pcCert,
  477. OUT CRYPT_DER_BLOB rgrgCertBlob[][MINASN1_CERT_BLOB_CNT]
  478. );
  479. //+-------------------------------------------------------------------------
  480. // Function: MinAsn1ParseAttributes
  481. //
  482. // Parses an ASN.1 encoded sequence of attributes contained in
  483. // other ASN.1 structures, such as, Signer Info authenticated or
  484. // unauthenticated attributes.
  485. //
  486. // The outer tag is ignored. It can be a SET, [0] IMPLICIT, or [1] IMPLICIT.
  487. //
  488. // Upon input, *pcAttr contains the maximum number of parsed attributes
  489. // that can be returned. Updated with the number of attributes processed.
  490. //
  491. // Returns:
  492. // success - >= 0 => bytes skipped, length of the encoded attributes
  493. // processed. If all attributes were processed,
  494. // bytes skipped = pAttrsValueBlob->cbData.
  495. // failure - < 0 => negative (offset + 1) of first bad tagged value
  496. //
  497. // The rgrgAttrBlob[][] is updated with pointer to and length of the
  498. // following fields in the encoded attribute.
  499. //--------------------------------------------------------------------------
  500. // Encoded bytes including outer SEQUENCE tag and length octets
  501. #define MINASN1_ATTR_ENCODED_IDX 1
  502. // Object Identifier content bytes (OID)
  503. #define MINASN1_ATTR_OID_IDX 2
  504. // Values value bytes (SET OF)
  505. #define MINASN1_ATTR_VALUES_IDX 3
  506. // First Value's value bytes (OPTIONAL ANY)
  507. #define MINASN1_ATTR_VALUE_IDX 4
  508. #define MINASN1_ATTR_BLOB_CNT 5
  509. LONG
  510. WINAPI
  511. MinAsn1ParseAttributes(
  512. IN PCRYPT_DER_BLOB pAttrsValueBlob,
  513. IN OUT DWORD *pcAttr,
  514. OUT CRYPT_DER_BLOB rgrgAttrBlob[][MINASN1_ATTR_BLOB_CNT]
  515. );
  516. //+-------------------------------------------------------------------------
  517. // Function: MinAsn1ParseCTL
  518. //
  519. // Parses an ASN.1 encoded Certificate Trust List (CTL). A CTL is always
  520. // contained as the inner content data in a PKCS #7 Signed Data. A CTL has
  521. // the following OID: "1.3.6.1.4.1.311.10.1".
  522. //
  523. // A catalog file is formatted as a PKCS #7 Signed CTL.
  524. //
  525. // Returns:
  526. // success - > 0 => bytes skipped, length of the encoded CTL
  527. // failure - < 0 => negative (offset + 1) of first bad tagged value
  528. //
  529. // The rgCTLBlob[] is updated with pointer to and length of the following
  530. // fields in the encoded CTL.
  531. //
  532. //--------------------------------------------------------------------------
  533. // Encoded bytes including outer SEQUENCE tag and length octets
  534. #define MINASN1_CTL_ENCODED_IDX 1
  535. // Version content bytes (OPTIONAL INTEGER)
  536. #define MINASN1_CTL_VERSION_IDX 2
  537. // Subject usage value bytes (SEQUENCE OF OID)
  538. #define MINASN1_CTL_SUBJECT_USAGE_IDX 3
  539. // List Identifier content bytes (OPTIONAL OCTETSTRING)
  540. #define MINASN1_CTL_LIST_ID_IDX 4
  541. // Sequence number content bytes (OPTIONAL INTEGER)
  542. #define MINASN1_CTL_SEQUENCE_NUMBER_IDX 5
  543. // This Update value bytes (UTC_TIME or GENERALIZED_TIME)
  544. #define MINASN1_CTL_THIS_UPDATE_IDX 6
  545. // Next Update value bytes (OPTIONAL UTC_TIME or GENERALIZED_TIME)
  546. #define MINASN1_CTL_NEXT_UPDATE_IDX 7
  547. // Subject Algorithm Identifier value bytes (MinAsn1ParseAlgorithmIdentifier)
  548. #define MINASN1_CTL_SUBJECT_ALGID_IDX 8
  549. // Subjects value bytes (OPTIONAL, iterative MinAsn1ParseCTLSubject)
  550. #define MINASN1_CTL_SUBJECTS_IDX 9
  551. // Extensions value bytes skipping "[0] EXPLICIT" tag
  552. // (OPTIONAL, MinAsn1ParseExtensions)
  553. #define MINASN1_CTL_EXTS_IDX 10
  554. #define MINASN1_CTL_BLOB_CNT 11
  555. LONG
  556. WINAPI
  557. MinAsn1ParseCTL(
  558. IN PCRYPT_DER_BLOB pEncodedContentBlob,
  559. OUT CRYPT_DER_BLOB rgCTLBlob[MINASN1_CTL_BLOB_CNT]
  560. );
  561. //+-------------------------------------------------------------------------
  562. // Function: MinAsn1ParseCTLSubject
  563. //
  564. // Parses an ASN.1 encoded CTL Subject contained within a CTL's SEQUENCE OF
  565. // Subjects.
  566. //
  567. // Returns:
  568. // success - > 0 => bytes skipped, length of the encoded subject.
  569. // failure - < 0 => negative (offset + 1) of first bad tagged value
  570. //
  571. // The rgCTLSubjectBlob[][] is updated with pointer to and length of the
  572. // following fields in the encoded subject.
  573. //--------------------------------------------------------------------------
  574. // Encoded bytes including outer SEQUENCE tag and length octets
  575. #define MINASN1_CTL_SUBJECT_ENCODED_IDX 1
  576. // Subject Identifier content bytes (OCTETSTRING)
  577. #define MINASN1_CTL_SUBJECT_ID_IDX 2
  578. // Attributes value bytes (OPTIONAL, MinAsn1ParseAttributes)
  579. #define MINASN1_CTL_SUBJECT_ATTRS_IDX 3
  580. #define MINASN1_CTL_SUBJECT_BLOB_CNT 4
  581. LONG
  582. WINAPI
  583. MinAsn1ParseCTLSubject(
  584. IN const BYTE *pbEncoded,
  585. IN DWORD cbEncoded,
  586. OUT CRYPT_DER_BLOB rgCTLSubjectBlob[MINASN1_CTL_SUBJECT_BLOB_CNT]
  587. );
  588. //+-------------------------------------------------------------------------
  589. // Function: MinAsn1ParseIndirectData
  590. //
  591. // Parses an ASN.1 encoded Indirect Data. Indirect Data is always
  592. // contained as the inner content data in a PKCS #7 Signed Data. It has
  593. // the following OID: "1.3.6.1.4.1.311.2.1.4"
  594. //
  595. // An Authenticode signed file contains a PKCS #7 Signed Indirect Data.
  596. //
  597. // Returns:
  598. // success - > 0 => bytes skipped, length of the encoded Indirect Data
  599. // failure - < 0 => negative (offset + 1) of first bad tagged value
  600. //
  601. // The rgIndirectDataBlob[] is updated with pointer to and length of the
  602. // following fields in the encoded Indirect Data.
  603. //
  604. //--------------------------------------------------------------------------
  605. // Encoded bytes including outer SEQUENCE tag and length octets
  606. #define MINASN1_INDIRECT_DATA_ENCODED_IDX 1
  607. // Attribute Object Identifier content bytes (OID)
  608. #define MINASN1_INDIRECT_DATA_ATTR_OID_IDX 2
  609. // Attribute value bytes (OPTIONAL ANY)
  610. #define MINASN1_INDIRECT_DATA_ATTR_VALUE_IDX 3
  611. // Digest Algorithm Identifier (MinAsn1ParseAlgorithmIdentifier)
  612. #define MINASN1_INDIRECT_DATA_DIGEST_ALGID_IDX 4
  613. // Digest content bytes (OCTETSTRING)
  614. #define MINASN1_INDIRECT_DATA_DIGEST_IDX 5
  615. #define MINASN1_INDIRECT_DATA_BLOB_CNT 6
  616. LONG
  617. WINAPI
  618. MinAsn1ParseIndirectData(
  619. IN PCRYPT_DER_BLOB pEncodedContentBlob,
  620. OUT CRYPT_DER_BLOB rgIndirectDataBlob[MINASN1_INDIRECT_DATA_BLOB_CNT]
  621. );
  622. //+-------------------------------------------------------------------------
  623. // Find an extension identified by its Encoded Object Identifier.
  624. //
  625. // Searches the list of parsed extensions returned by
  626. // MinAsn1ParseExtensions().
  627. //
  628. // If found, returns pointer to the rgExtBlob[MINASN1_EXT_BLOB_CNT].
  629. // Otherwise, returns NULL.
  630. //--------------------------------------------------------------------------
  631. PCRYPT_DER_BLOB
  632. WINAPI
  633. MinAsn1FindExtension(
  634. IN PCRYPT_DER_BLOB pEncodedOIDBlob,
  635. IN DWORD cExt,
  636. IN CRYPT_DER_BLOB rgrgExtBlob[][MINASN1_EXT_BLOB_CNT]
  637. );
  638. //+-------------------------------------------------------------------------
  639. // Find the first attribute identified by its Encoded Object Identifier.
  640. //
  641. // Searches the list of parsed attributes returned by
  642. // MinAsn1ParseAttributes().
  643. //
  644. // If found, returns pointer to the rgAttrBlob[MINASN1_ATTR_BLOB_CNT].
  645. // Otherwise, returns NULL.
  646. //--------------------------------------------------------------------------
  647. PCRYPT_DER_BLOB
  648. WINAPI
  649. MinAsn1FindAttribute(
  650. IN PCRYPT_DER_BLOB pEncodedOIDBlob,
  651. IN DWORD cAttr,
  652. IN CRYPT_DER_BLOB rgrgAttrBlob[][MINASN1_ATTR_BLOB_CNT]
  653. );
  654. //+-------------------------------------------------------------------------
  655. // Parses an ASN.1 encoded PKCS #7 Signed Data Message to extract and
  656. // parse the X.509 certificates it contains.
  657. //
  658. // Assumes the PKCS #7 message is definite length encoded.
  659. // Assumes PKCS #7 version 1.5, ie, not the newer CMS version.
  660. //
  661. // Upon input, *pcCert contains the maximum number of parsed certificates
  662. // that can be returned. Updated with the number of certificates processed.
  663. //
  664. // If the encoded message was successfully parsed, TRUE is returned
  665. // with *pcCert updated with the number of parsed certificates. Otherwise,
  666. // FALSE is returned for a parse error.
  667. // Returns:
  668. // success - >= 0 => bytes skipped, length of the encoded certificates
  669. // processed.
  670. // failure - < 0 => negative (offset + 1) of first bad tagged value
  671. // from beginning of message.
  672. //
  673. // The rgrgCertBlob[][] is updated with pointer to and length of the
  674. // fields in the encoded certificate. See MinAsn1ParseCertificate for the
  675. // field definitions.
  676. //--------------------------------------------------------------------------
  677. LONG
  678. WINAPI
  679. MinAsn1ExtractParsedCertificatesFromSignedData(
  680. IN const BYTE *pbEncoded,
  681. IN DWORD cbEncoded,
  682. IN OUT DWORD *pcCert,
  683. OUT CRYPT_DER_BLOB rgrgCertBlob[][MINASN1_CERT_BLOB_CNT]
  684. );
  685. #ifdef __cplusplus
  686. } // Balance extern "C" above
  687. #endif
  688. #if defined (_MSC_VER)
  689. #if ( _MSC_VER >= 800 )
  690. #if _MSC_VER >= 1200
  691. #pragma warning(pop)
  692. #else
  693. #pragma warning(default:4201)
  694. #endif
  695. #endif
  696. #endif
  697. #endif // __MINASN1_H__