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.

930 lines
24 KiB

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

Powered by TurnKey Linux.