您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

962 行
26 KiB

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