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.

932 lines
24 KiB

4 years ago
  1. # coding: utf-8
  2. """
  3. ASN.1 type classes for cryptographic message syntax (CMS). Structures are also
  4. compatible with PKCS#7. Exports the following items:
  5. - AuthenticatedData()
  6. - AuthEnvelopedData()
  7. - CompressedData()
  8. - ContentInfo()
  9. - DigestedData()
  10. - EncryptedData()
  11. - EnvelopedData()
  12. - SignedAndEnvelopedData()
  13. - SignedData()
  14. Other type classes are defined that help compose the types listed above.
  15. Most CMS structures in the wild are formatted as ContentInfo encapsulating one of the other types.
  16. """
  17. from __future__ import unicode_literals, division, absolute_import, print_function
  18. try:
  19. import zlib
  20. except (ImportError):
  21. zlib = None
  22. from .algos import (
  23. _ForceNullParameters,
  24. DigestAlgorithm,
  25. EncryptionAlgorithm,
  26. HmacAlgorithm,
  27. KdfAlgorithm,
  28. SignedDigestAlgorithm,
  29. )
  30. from .core import (
  31. Any,
  32. BitString,
  33. Choice,
  34. Enumerated,
  35. GeneralizedTime,
  36. Integer,
  37. ObjectIdentifier,
  38. OctetBitString,
  39. OctetString,
  40. ParsableOctetString,
  41. Sequence,
  42. SequenceOf,
  43. SetOf,
  44. UTCTime,
  45. UTF8String,
  46. )
  47. from .crl import CertificateList
  48. from .keys import PublicKeyInfo
  49. from .ocsp import OCSPResponse
  50. from .x509 import Attributes, Certificate, Extensions, GeneralName, GeneralNames, Name
  51. # These structures are taken from
  52. # ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-6.asc
  53. class ExtendedCertificateInfo(Sequence):
  54. _fields = [
  55. ('version', Integer),
  56. ('certificate', Certificate),
  57. ('attributes', Attributes),
  58. ]
  59. class ExtendedCertificate(Sequence):
  60. _fields = [
  61. ('extended_certificate_info', ExtendedCertificateInfo),
  62. ('signature_algorithm', SignedDigestAlgorithm),
  63. ('signature', OctetBitString),
  64. ]
  65. # These structures are taken from https://tools.ietf.org/html/rfc5652,
  66. # https://tools.ietf.org/html/rfc5083, http://tools.ietf.org/html/rfc2315,
  67. # https://tools.ietf.org/html/rfc5940, https://tools.ietf.org/html/rfc3274,
  68. # https://tools.ietf.org/html/rfc3281
  69. class CMSVersion(Integer):
  70. _map = {
  71. 0: 'v0',
  72. 1: 'v1',
  73. 2: 'v2',
  74. 3: 'v3',
  75. 4: 'v4',
  76. 5: 'v5',
  77. }
  78. class CMSAttributeType(ObjectIdentifier):
  79. _map = {
  80. '1.2.840.113549.1.9.3': 'content_type',
  81. '1.2.840.113549.1.9.4': 'message_digest',
  82. '1.2.840.113549.1.9.5': 'signing_time',
  83. '1.2.840.113549.1.9.6': 'counter_signature',
  84. # https://tools.ietf.org/html/rfc3161#page-20
  85. '1.2.840.113549.1.9.16.2.14': 'signature_time_stamp_token',
  86. # https://tools.ietf.org/html/rfc6211#page-5
  87. '1.2.840.113549.1.9.52': 'cms_algorithm_protection',
  88. }
  89. class Time(Choice):
  90. _alternatives = [
  91. ('utc_time', UTCTime),
  92. ('generalized_time', GeneralizedTime),
  93. ]
  94. class ContentType(ObjectIdentifier):
  95. _map = {
  96. '1.2.840.113549.1.7.1': 'data',
  97. '1.2.840.113549.1.7.2': 'signed_data',
  98. '1.2.840.113549.1.7.3': 'enveloped_data',
  99. '1.2.840.113549.1.7.4': 'signed_and_enveloped_data',
  100. '1.2.840.113549.1.7.5': 'digested_data',
  101. '1.2.840.113549.1.7.6': 'encrypted_data',
  102. '1.2.840.113549.1.9.16.1.2': 'authenticated_data',
  103. '1.2.840.113549.1.9.16.1.9': 'compressed_data',
  104. '1.2.840.113549.1.9.16.1.23': 'authenticated_enveloped_data',
  105. }
  106. class CMSAlgorithmProtection(Sequence):
  107. _fields = [
  108. ('digest_algorithm', DigestAlgorithm),
  109. ('signature_algorithm', SignedDigestAlgorithm, {'implicit': 1, 'optional': True}),
  110. ('mac_algorithm', HmacAlgorithm, {'implicit': 2, 'optional': True}),
  111. ]
  112. class SetOfContentType(SetOf):
  113. _child_spec = ContentType
  114. class SetOfOctetString(SetOf):
  115. _child_spec = OctetString
  116. class SetOfTime(SetOf):
  117. _child_spec = Time
  118. class SetOfAny(SetOf):
  119. _child_spec = Any
  120. class SetOfCMSAlgorithmProtection(SetOf):
  121. _child_spec = CMSAlgorithmProtection
  122. class CMSAttribute(Sequence):
  123. _fields = [
  124. ('type', CMSAttributeType),
  125. ('values', None),
  126. ]
  127. _oid_specs = {}
  128. def _values_spec(self):
  129. return self._oid_specs.get(self['type'].native, SetOfAny)
  130. _spec_callbacks = {
  131. 'values': _values_spec
  132. }
  133. class CMSAttributes(SetOf):
  134. _child_spec = CMSAttribute
  135. class IssuerSerial(Sequence):
  136. _fields = [
  137. ('issuer', GeneralNames),
  138. ('serial', Integer),
  139. ('issuer_uid', OctetBitString, {'optional': True}),
  140. ]
  141. class AttCertVersion(Integer):
  142. _map = {
  143. 0: 'v1',
  144. 1: 'v2',
  145. }
  146. class AttCertSubject(Choice):
  147. _alternatives = [
  148. ('base_certificate_id', IssuerSerial, {'explicit': 0}),
  149. ('subject_name', GeneralNames, {'explicit': 1}),
  150. ]
  151. class AttCertValidityPeriod(Sequence):
  152. _fields = [
  153. ('not_before_time', GeneralizedTime),
  154. ('not_after_time', GeneralizedTime),
  155. ]
  156. class AttributeCertificateInfoV1(Sequence):
  157. _fields = [
  158. ('version', AttCertVersion, {'default': 'v1'}),
  159. ('subject', AttCertSubject),
  160. ('issuer', GeneralNames),
  161. ('signature', SignedDigestAlgorithm),
  162. ('serial_number', Integer),
  163. ('att_cert_validity_period', AttCertValidityPeriod),
  164. ('attributes', Attributes),
  165. ('issuer_unique_id', OctetBitString, {'optional': True}),
  166. ('extensions', Extensions, {'optional': True}),
  167. ]
  168. class AttributeCertificateV1(Sequence):
  169. _fields = [
  170. ('ac_info', AttributeCertificateInfoV1),
  171. ('signature_algorithm', SignedDigestAlgorithm),
  172. ('signature', OctetBitString),
  173. ]
  174. class DigestedObjectType(Enumerated):
  175. _map = {
  176. 0: 'public_key',
  177. 1: 'public_key_cert',
  178. 2: 'other_objy_types',
  179. }
  180. class ObjectDigestInfo(Sequence):
  181. _fields = [
  182. ('digested_object_type', DigestedObjectType),
  183. ('other_object_type_id', ObjectIdentifier, {'optional': True}),
  184. ('digest_algorithm', DigestAlgorithm),
  185. ('object_digest', OctetBitString),
  186. ]
  187. class Holder(Sequence):
  188. _fields = [
  189. ('base_certificate_id', IssuerSerial, {'implicit': 0, 'optional': True}),
  190. ('entity_name', GeneralNames, {'implicit': 1, 'optional': True}),
  191. ('object_digest_info', ObjectDigestInfo, {'implicit': 2, 'optional': True}),
  192. ]
  193. class V2Form(Sequence):
  194. _fields = [
  195. ('issuer_name', GeneralNames, {'optional': True}),
  196. ('base_certificate_id', IssuerSerial, {'explicit': 0, 'optional': True}),
  197. ('object_digest_info', ObjectDigestInfo, {'explicit': 1, 'optional': True}),
  198. ]
  199. class AttCertIssuer(Choice):
  200. _alternatives = [
  201. ('v1_form', GeneralNames),
  202. ('v2_form', V2Form, {'explicit': 0}),
  203. ]
  204. class IetfAttrValue(Choice):
  205. _alternatives = [
  206. ('octets', OctetString),
  207. ('oid', ObjectIdentifier),
  208. ('string', UTF8String),
  209. ]
  210. class IetfAttrValues(SequenceOf):
  211. _child_spec = IetfAttrValue
  212. class IetfAttrSyntax(Sequence):
  213. _fields = [
  214. ('policy_authority', GeneralNames, {'implicit': 0, 'optional': True}),
  215. ('values', IetfAttrValues),
  216. ]
  217. class SetOfIetfAttrSyntax(SetOf):
  218. _child_spec = IetfAttrSyntax
  219. class SvceAuthInfo(Sequence):
  220. _fields = [
  221. ('service', GeneralName),
  222. ('ident', GeneralName),
  223. ('auth_info', OctetString, {'optional': True}),
  224. ]
  225. class SetOfSvceAuthInfo(SetOf):
  226. _child_spec = SvceAuthInfo
  227. class RoleSyntax(Sequence):
  228. _fields = [
  229. ('role_authority', GeneralNames, {'implicit': 0, 'optional': True}),
  230. ('role_name', GeneralName, {'implicit': 1}),
  231. ]
  232. class SetOfRoleSyntax(SetOf):
  233. _child_spec = RoleSyntax
  234. class ClassList(BitString):
  235. _map = {
  236. 0: 'unmarked',
  237. 1: 'unclassified',
  238. 2: 'restricted',
  239. 3: 'confidential',
  240. 4: 'secret',
  241. 5: 'top_secret',
  242. }
  243. class SecurityCategory(Sequence):
  244. _fields = [
  245. ('type', ObjectIdentifier, {'implicit': 0}),
  246. ('value', Any, {'implicit': 1}),
  247. ]
  248. class SetOfSecurityCategory(SetOf):
  249. _child_spec = SecurityCategory
  250. class Clearance(Sequence):
  251. _fields = [
  252. ('policy_id', ObjectIdentifier, {'implicit': 0}),
  253. ('class_list', ClassList, {'implicit': 1, 'default': 'unclassified'}),
  254. ('security_categories', SetOfSecurityCategory, {'implicit': 2, 'optional': True}),
  255. ]
  256. class SetOfClearance(SetOf):
  257. _child_spec = Clearance
  258. class BigTime(Sequence):
  259. _fields = [
  260. ('major', Integer),
  261. ('fractional_seconds', Integer),
  262. ('sign', Integer, {'optional': True}),
  263. ]
  264. class LeapData(Sequence):
  265. _fields = [
  266. ('leap_time', BigTime),
  267. ('action', Integer),
  268. ]
  269. class SetOfLeapData(SetOf):
  270. _child_spec = LeapData
  271. class TimingMetrics(Sequence):
  272. _fields = [
  273. ('ntp_time', BigTime),
  274. ('offset', BigTime),
  275. ('delay', BigTime),
  276. ('expiration', BigTime),
  277. ('leap_event', SetOfLeapData, {'optional': True}),
  278. ]
  279. class SetOfTimingMetrics(SetOf):
  280. _child_spec = TimingMetrics
  281. class TimingPolicy(Sequence):
  282. _fields = [
  283. ('policy_id', SequenceOf, {'spec': ObjectIdentifier}),
  284. ('max_offset', BigTime, {'explicit': 0, 'optional': True}),
  285. ('max_delay', BigTime, {'explicit': 1, 'optional': True}),
  286. ]
  287. class SetOfTimingPolicy(SetOf):
  288. _child_spec = TimingPolicy
  289. class AttCertAttributeType(ObjectIdentifier):
  290. _map = {
  291. '1.3.6.1.5.5.7.10.1': 'authentication_info',
  292. '1.3.6.1.5.5.7.10.2': 'access_identity',
  293. '1.3.6.1.5.5.7.10.3': 'charging_identity',
  294. '1.3.6.1.5.5.7.10.4': 'group',
  295. '2.5.4.72': 'role',
  296. '2.5.4.55': 'clearance',
  297. '1.3.6.1.4.1.601.10.4.1': 'timing_metrics',
  298. '1.3.6.1.4.1.601.10.4.2': 'timing_policy',
  299. }
  300. class AttCertAttribute(Sequence):
  301. _fields = [
  302. ('type', AttCertAttributeType),
  303. ('values', None),
  304. ]
  305. _oid_specs = {
  306. 'authentication_info': SetOfSvceAuthInfo,
  307. 'access_identity': SetOfSvceAuthInfo,
  308. 'charging_identity': SetOfIetfAttrSyntax,
  309. 'group': SetOfIetfAttrSyntax,
  310. 'role': SetOfRoleSyntax,
  311. 'clearance': SetOfClearance,
  312. 'timing_metrics': SetOfTimingMetrics,
  313. 'timing_policy': SetOfTimingPolicy,
  314. }
  315. def _values_spec(self):
  316. return self._oid_specs.get(self['type'].native, SetOfAny)
  317. _spec_callbacks = {
  318. 'values': _values_spec
  319. }
  320. class AttCertAttributes(SequenceOf):
  321. _child_spec = AttCertAttribute
  322. class AttributeCertificateInfoV2(Sequence):
  323. _fields = [
  324. ('version', AttCertVersion),
  325. ('holder', Holder),
  326. ('issuer', AttCertIssuer),
  327. ('signature', SignedDigestAlgorithm),
  328. ('serial_number', Integer),
  329. ('att_cert_validity_period', AttCertValidityPeriod),
  330. ('attributes', AttCertAttributes),
  331. ('issuer_unique_id', OctetBitString, {'optional': True}),
  332. ('extensions', Extensions, {'optional': True}),
  333. ]
  334. class AttributeCertificateV2(Sequence):
  335. # Handle the situation where a V2 cert is encoded as V1
  336. _bad_tag = 1
  337. _fields = [
  338. ('ac_info', AttributeCertificateInfoV2),
  339. ('signature_algorithm', SignedDigestAlgorithm),
  340. ('signature', OctetBitString),
  341. ]
  342. class OtherCertificateFormat(Sequence):
  343. _fields = [
  344. ('other_cert_format', ObjectIdentifier),
  345. ('other_cert', Any),
  346. ]
  347. class CertificateChoices(Choice):
  348. _alternatives = [
  349. ('certificate', Certificate),
  350. ('extended_certificate', ExtendedCertificate, {'implicit': 0}),
  351. ('v1_attr_cert', AttributeCertificateV1, {'implicit': 1}),
  352. ('v2_attr_cert', AttributeCertificateV2, {'implicit': 2}),
  353. ('other', OtherCertificateFormat, {'implicit': 3}),
  354. ]
  355. def validate(self, class_, tag, contents):
  356. """
  357. Ensures that the class and tag specified exist as an alternative. This
  358. custom version fixes parsing broken encodings there a V2 attribute
  359. # certificate is encoded as a V1
  360. :param class_:
  361. The integer class_ from the encoded value header
  362. :param tag:
  363. The integer tag from the encoded value header
  364. :param contents:
  365. A byte string of the contents of the value - used when the object
  366. is explicitly tagged
  367. :raises:
  368. ValueError - when value is not a valid alternative
  369. """
  370. super(CertificateChoices, self).validate(class_, tag, contents)
  371. if self._choice == 2:
  372. if AttCertVersion.load(Sequence.load(contents)[0].dump()).native == 'v2':
  373. self._choice = 3
  374. class CertificateSet(SetOf):
  375. _child_spec = CertificateChoices
  376. class ContentInfo(Sequence):
  377. _fields = [
  378. ('content_type', ContentType),
  379. ('content', Any, {'explicit': 0, 'optional': True}),
  380. ]
  381. _oid_pair = ('content_type', 'content')
  382. _oid_specs = {}
  383. class SetOfContentInfo(SetOf):
  384. _child_spec = ContentInfo
  385. class EncapsulatedContentInfo(Sequence):
  386. _fields = [
  387. ('content_type', ContentType),
  388. ('content', ParsableOctetString, {'explicit': 0, 'optional': True}),
  389. ]
  390. _oid_pair = ('content_type', 'content')
  391. _oid_specs = {}
  392. class IssuerAndSerialNumber(Sequence):
  393. _fields = [
  394. ('issuer', Name),
  395. ('serial_number', Integer),
  396. ]
  397. class SignerIdentifier(Choice):
  398. _alternatives = [
  399. ('issuer_and_serial_number', IssuerAndSerialNumber),
  400. ('subject_key_identifier', OctetString, {'implicit': 0}),
  401. ]
  402. class DigestAlgorithms(SetOf):
  403. _child_spec = DigestAlgorithm
  404. class CertificateRevocationLists(SetOf):
  405. _child_spec = CertificateList
  406. class SCVPReqRes(Sequence):
  407. _fields = [
  408. ('request', ContentInfo, {'explicit': 0, 'optional': True}),
  409. ('response', ContentInfo),
  410. ]
  411. class OtherRevInfoFormatId(ObjectIdentifier):
  412. _map = {
  413. '1.3.6.1.5.5.7.16.2': 'ocsp_response',
  414. '1.3.6.1.5.5.7.16.4': 'scvp',
  415. }
  416. class OtherRevocationInfoFormat(Sequence):
  417. _fields = [
  418. ('other_rev_info_format', OtherRevInfoFormatId),
  419. ('other_rev_info', Any),
  420. ]
  421. _oid_pair = ('other_rev_info_format', 'other_rev_info')
  422. _oid_specs = {
  423. 'ocsp_response': OCSPResponse,
  424. 'scvp': SCVPReqRes,
  425. }
  426. class RevocationInfoChoice(Choice):
  427. _alternatives = [
  428. ('crl', CertificateList),
  429. ('other', OtherRevocationInfoFormat, {'implicit': 1}),
  430. ]
  431. class RevocationInfoChoices(SetOf):
  432. _child_spec = RevocationInfoChoice
  433. class SignerInfo(Sequence):
  434. _fields = [
  435. ('version', CMSVersion),
  436. ('sid', SignerIdentifier),
  437. ('digest_algorithm', DigestAlgorithm),
  438. ('signed_attrs', CMSAttributes, {'implicit': 0, 'optional': True}),
  439. ('signature_algorithm', SignedDigestAlgorithm),
  440. ('signature', OctetString),
  441. ('unsigned_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),
  442. ]
  443. class SignerInfos(SetOf):
  444. _child_spec = SignerInfo
  445. class SignedData(Sequence):
  446. _fields = [
  447. ('version', CMSVersion),
  448. ('digest_algorithms', DigestAlgorithms),
  449. ('encap_content_info', None),
  450. ('certificates', CertificateSet, {'implicit': 0, 'optional': True}),
  451. ('crls', RevocationInfoChoices, {'implicit': 1, 'optional': True}),
  452. ('signer_infos', SignerInfos),
  453. ]
  454. def _encap_content_info_spec(self):
  455. # If the encap_content_info is version v1, then this could be a PKCS#7
  456. # structure, or a CMS structure. CMS wraps the encoded value in an
  457. # Octet String tag.
  458. # If the version is greater than 1, it is definite CMS
  459. if self['version'].native != 'v1':
  460. return EncapsulatedContentInfo
  461. # Otherwise, the ContentInfo spec from PKCS#7 will be compatible with
  462. # CMS v1 (which only allows Data, an Octet String) and PKCS#7, which
  463. # allows Any
  464. return ContentInfo
  465. _spec_callbacks = {
  466. 'encap_content_info': _encap_content_info_spec
  467. }
  468. class OriginatorInfo(Sequence):
  469. _fields = [
  470. ('certs', CertificateSet, {'implicit': 0, 'optional': True}),
  471. ('crls', RevocationInfoChoices, {'implicit': 1, 'optional': True}),
  472. ]
  473. class RecipientIdentifier(Choice):
  474. _alternatives = [
  475. ('issuer_and_serial_number', IssuerAndSerialNumber),
  476. ('subject_key_identifier', OctetString, {'implicit': 0}),
  477. ]
  478. class KeyEncryptionAlgorithmId(ObjectIdentifier):
  479. _map = {
  480. '1.2.840.113549.1.1.1': 'rsa',
  481. '2.16.840.1.101.3.4.1.5': 'aes128_wrap',
  482. '2.16.840.1.101.3.4.1.8': 'aes128_wrap_pad',
  483. '2.16.840.1.101.3.4.1.25': 'aes192_wrap',
  484. '2.16.840.1.101.3.4.1.28': 'aes192_wrap_pad',
  485. '2.16.840.1.101.3.4.1.45': 'aes256_wrap',
  486. '2.16.840.1.101.3.4.1.48': 'aes256_wrap_pad',
  487. }
  488. class KeyEncryptionAlgorithm(_ForceNullParameters, Sequence):
  489. _fields = [
  490. ('algorithm', KeyEncryptionAlgorithmId),
  491. ('parameters', Any, {'optional': True}),
  492. ]
  493. class KeyTransRecipientInfo(Sequence):
  494. _fields = [
  495. ('version', CMSVersion),
  496. ('rid', RecipientIdentifier),
  497. ('key_encryption_algorithm', KeyEncryptionAlgorithm),
  498. ('encrypted_key', OctetString),
  499. ]
  500. class OriginatorIdentifierOrKey(Choice):
  501. _alternatives = [
  502. ('issuer_and_serial_number', IssuerAndSerialNumber),
  503. ('subject_key_identifier', OctetString, {'implicit': 0}),
  504. ('originator_key', PublicKeyInfo, {'implicit': 1}),
  505. ]
  506. class OtherKeyAttribute(Sequence):
  507. _fields = [
  508. ('key_attr_id', ObjectIdentifier),
  509. ('key_attr', Any),
  510. ]
  511. class RecipientKeyIdentifier(Sequence):
  512. _fields = [
  513. ('subject_key_identifier', OctetString),
  514. ('date', GeneralizedTime, {'optional': True}),
  515. ('other', OtherKeyAttribute, {'optional': True}),
  516. ]
  517. class KeyAgreementRecipientIdentifier(Choice):
  518. _alternatives = [
  519. ('issuer_and_serial_number', IssuerAndSerialNumber),
  520. ('r_key_id', RecipientKeyIdentifier, {'implicit': 0}),
  521. ]
  522. class RecipientEncryptedKey(Sequence):
  523. _fields = [
  524. ('rid', KeyAgreementRecipientIdentifier),
  525. ('encrypted_key', OctetString),
  526. ]
  527. class RecipientEncryptedKeys(SequenceOf):
  528. _child_spec = RecipientEncryptedKey
  529. class KeyAgreeRecipientInfo(Sequence):
  530. _fields = [
  531. ('version', CMSVersion),
  532. ('originator', OriginatorIdentifierOrKey, {'explicit': 0}),
  533. ('ukm', OctetString, {'explicit': 1, 'optional': True}),
  534. ('key_encryption_algorithm', KeyEncryptionAlgorithm),
  535. ('recipient_encrypted_keys', RecipientEncryptedKeys),
  536. ]
  537. class KEKIdentifier(Sequence):
  538. _fields = [
  539. ('key_identifier', OctetString),
  540. ('date', GeneralizedTime, {'optional': True}),
  541. ('other', OtherKeyAttribute, {'optional': True}),
  542. ]
  543. class KEKRecipientInfo(Sequence):
  544. _fields = [
  545. ('version', CMSVersion),
  546. ('kekid', KEKIdentifier),
  547. ('key_encryption_algorithm', KeyEncryptionAlgorithm),
  548. ('encrypted_key', OctetString),
  549. ]
  550. class PasswordRecipientInfo(Sequence):
  551. _fields = [
  552. ('version', CMSVersion),
  553. ('key_derivation_algorithm', KdfAlgorithm, {'implicit': 0, 'optional': True}),
  554. ('key_encryption_algorithm', KeyEncryptionAlgorithm),
  555. ('encrypted_key', OctetString),
  556. ]
  557. class OtherRecipientInfo(Sequence):
  558. _fields = [
  559. ('ori_type', ObjectIdentifier),
  560. ('ori_value', Any),
  561. ]
  562. class RecipientInfo(Choice):
  563. _alternatives = [
  564. ('ktri', KeyTransRecipientInfo),
  565. ('kari', KeyAgreeRecipientInfo, {'implicit': 1}),
  566. ('kekri', KEKRecipientInfo, {'implicit': 2}),
  567. ('pwri', PasswordRecipientInfo, {'implicit': 3}),
  568. ('ori', OtherRecipientInfo, {'implicit': 4}),
  569. ]
  570. class RecipientInfos(SetOf):
  571. _child_spec = RecipientInfo
  572. class EncryptedContentInfo(Sequence):
  573. _fields = [
  574. ('content_type', ContentType),
  575. ('content_encryption_algorithm', EncryptionAlgorithm),
  576. ('encrypted_content', OctetString, {'implicit': 0, 'optional': True}),
  577. ]
  578. class EnvelopedData(Sequence):
  579. _fields = [
  580. ('version', CMSVersion),
  581. ('originator_info', OriginatorInfo, {'implicit': 0, 'optional': True}),
  582. ('recipient_infos', RecipientInfos),
  583. ('encrypted_content_info', EncryptedContentInfo),
  584. ('unprotected_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),
  585. ]
  586. class SignedAndEnvelopedData(Sequence):
  587. _fields = [
  588. ('version', CMSVersion),
  589. ('recipient_infos', RecipientInfos),
  590. ('digest_algorithms', DigestAlgorithms),
  591. ('encrypted_content_info', EncryptedContentInfo),
  592. ('certificates', CertificateSet, {'implicit': 0, 'optional': True}),
  593. ('crls', CertificateRevocationLists, {'implicit': 1, 'optional': True}),
  594. ('signer_infos', SignerInfos),
  595. ]
  596. class DigestedData(Sequence):
  597. _fields = [
  598. ('version', CMSVersion),
  599. ('digest_algorithm', DigestAlgorithm),
  600. ('encap_content_info', None),
  601. ('digest', OctetString),
  602. ]
  603. def _encap_content_info_spec(self):
  604. # If the encap_content_info is version v1, then this could be a PKCS#7
  605. # structure, or a CMS structure. CMS wraps the encoded value in an
  606. # Octet String tag.
  607. # If the version is greater than 1, it is definite CMS
  608. if self['version'].native != 'v1':
  609. return EncapsulatedContentInfo
  610. # Otherwise, the ContentInfo spec from PKCS#7 will be compatible with
  611. # CMS v1 (which only allows Data, an Octet String) and PKCS#7, which
  612. # allows Any
  613. return ContentInfo
  614. _spec_callbacks = {
  615. 'encap_content_info': _encap_content_info_spec
  616. }
  617. class EncryptedData(Sequence):
  618. _fields = [
  619. ('version', CMSVersion),
  620. ('encrypted_content_info', EncryptedContentInfo),
  621. ('unprotected_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),
  622. ]
  623. class AuthenticatedData(Sequence):
  624. _fields = [
  625. ('version', CMSVersion),
  626. ('originator_info', OriginatorInfo, {'implicit': 0, 'optional': True}),
  627. ('recipient_infos', RecipientInfos),
  628. ('mac_algorithm', HmacAlgorithm),
  629. ('digest_algorithm', DigestAlgorithm, {'implicit': 1, 'optional': True}),
  630. # This does not require the _spec_callbacks approach of SignedData and
  631. # DigestedData since AuthenticatedData was not part of PKCS#7
  632. ('encap_content_info', EncapsulatedContentInfo),
  633. ('auth_attrs', CMSAttributes, {'implicit': 2, 'optional': True}),
  634. ('mac', OctetString),
  635. ('unauth_attrs', CMSAttributes, {'implicit': 3, 'optional': True}),
  636. ]
  637. class AuthEnvelopedData(Sequence):
  638. _fields = [
  639. ('version', CMSVersion),
  640. ('originator_info', OriginatorInfo, {'implicit': 0, 'optional': True}),
  641. ('recipient_infos', RecipientInfos),
  642. ('auth_encrypted_content_info', EncryptedContentInfo),
  643. ('auth_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),
  644. ('mac', OctetString),
  645. ('unauth_attrs', CMSAttributes, {'implicit': 2, 'optional': True}),
  646. ]
  647. class CompressionAlgorithmId(ObjectIdentifier):
  648. _map = {
  649. '1.2.840.113549.1.9.16.3.8': 'zlib',
  650. }
  651. class CompressionAlgorithm(Sequence):
  652. _fields = [
  653. ('algorithm', CompressionAlgorithmId),
  654. ('parameters', Any, {'optional': True}),
  655. ]
  656. class CompressedData(Sequence):
  657. _fields = [
  658. ('version', CMSVersion),
  659. ('compression_algorithm', CompressionAlgorithm),
  660. ('encap_content_info', EncapsulatedContentInfo),
  661. ]
  662. _decompressed = None
  663. @property
  664. def decompressed(self):
  665. if self._decompressed is None:
  666. if zlib is None:
  667. raise SystemError('The zlib module is not available')
  668. self._decompressed = zlib.decompress(self['encap_content_info']['content'].native)
  669. return self._decompressed
  670. ContentInfo._oid_specs = {
  671. 'data': OctetString,
  672. 'signed_data': SignedData,
  673. 'enveloped_data': EnvelopedData,
  674. 'signed_and_enveloped_data': SignedAndEnvelopedData,
  675. 'digested_data': DigestedData,
  676. 'encrypted_data': EncryptedData,
  677. 'authenticated_data': AuthenticatedData,
  678. 'compressed_data': CompressedData,
  679. 'authenticated_enveloped_data': AuthEnvelopedData,
  680. }
  681. EncapsulatedContentInfo._oid_specs = {
  682. 'signed_data': SignedData,
  683. 'enveloped_data': EnvelopedData,
  684. 'signed_and_enveloped_data': SignedAndEnvelopedData,
  685. 'digested_data': DigestedData,
  686. 'encrypted_data': EncryptedData,
  687. 'authenticated_data': AuthenticatedData,
  688. 'compressed_data': CompressedData,
  689. 'authenticated_enveloped_data': AuthEnvelopedData,
  690. }
  691. CMSAttribute._oid_specs = {
  692. 'content_type': SetOfContentType,
  693. 'message_digest': SetOfOctetString,
  694. 'signing_time': SetOfTime,
  695. 'counter_signature': SignerInfos,
  696. 'signature_time_stamp_token': SetOfContentInfo,
  697. 'cms_algorithm_protection': SetOfCMSAlgorithmProtection,
  698. }