Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/asn1crypto/cms.py: 92%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# coding: utf-8
3"""
4ASN.1 type classes for cryptographic message syntax (CMS). Structures are also
5compatible with PKCS#7. Exports the following items:
7 - AuthenticatedData()
8 - AuthEnvelopedData()
9 - CompressedData()
10 - ContentInfo()
11 - DigestedData()
12 - EncryptedData()
13 - EnvelopedData()
14 - SignedAndEnvelopedData()
15 - SignedData()
17Other type classes are defined that help compose the types listed above.
19Most CMS structures in the wild are formatted as ContentInfo encapsulating one of the other types.
20"""
22from __future__ import unicode_literals, division, absolute_import, print_function
24try:
25 import zlib
26except (ImportError):
27 zlib = None
29from .algos import (
30 _ForceNullParameters,
31 DigestAlgorithm,
32 EncryptionAlgorithm,
33 EncryptionAlgorithmId,
34 HmacAlgorithm,
35 KdfAlgorithm,
36 RSAESOAEPParams,
37 SignedDigestAlgorithm,
38)
39from .core import (
40 Any,
41 BitString,
42 Choice,
43 Enumerated,
44 GeneralizedTime,
45 Integer,
46 ObjectIdentifier,
47 OctetBitString,
48 OctetString,
49 ParsableOctetString,
50 Sequence,
51 SequenceOf,
52 SetOf,
53 UTCTime,
54 UTF8String,
55)
56from .crl import CertificateList
57from .keys import PublicKeyInfo
58from .ocsp import OCSPResponse
59from .x509 import Attributes, Certificate, Extensions, GeneralName, GeneralNames, Name
62# These structures are taken from
63# ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-6.asc
65class ExtendedCertificateInfo(Sequence):
66 _fields = [
67 ('version', Integer),
68 ('certificate', Certificate),
69 ('attributes', Attributes),
70 ]
73class ExtendedCertificate(Sequence):
74 _fields = [
75 ('extended_certificate_info', ExtendedCertificateInfo),
76 ('signature_algorithm', SignedDigestAlgorithm),
77 ('signature', OctetBitString),
78 ]
81# These structures are taken from https://tools.ietf.org/html/rfc5652,
82# https://tools.ietf.org/html/rfc5083, http://tools.ietf.org/html/rfc2315,
83# https://tools.ietf.org/html/rfc5940, https://tools.ietf.org/html/rfc3274,
84# https://tools.ietf.org/html/rfc3281
87class CMSVersion(Integer):
88 _map = {
89 0: 'v0',
90 1: 'v1',
91 2: 'v2',
92 3: 'v3',
93 4: 'v4',
94 5: 'v5',
95 }
98class CMSAttributeType(ObjectIdentifier):
99 _map = {
100 '1.2.840.113549.1.9.3': 'content_type',
101 '1.2.840.113549.1.9.4': 'message_digest',
102 '1.2.840.113549.1.9.5': 'signing_time',
103 '1.2.840.113549.1.9.6': 'counter_signature',
104 # https://datatracker.ietf.org/doc/html/rfc2633#section-2.5.2
105 '1.2.840.113549.1.9.15': 'smime_capabilities',
106 # https://tools.ietf.org/html/rfc2633#page-26
107 '1.2.840.113549.1.9.16.2.11': 'encrypt_key_pref',
108 # https://tools.ietf.org/html/rfc3161#page-20
109 '1.2.840.113549.1.9.16.2.14': 'signature_time_stamp_token',
110 # https://tools.ietf.org/html/rfc6211#page-5
111 '1.2.840.113549.1.9.52': 'cms_algorithm_protection',
112 # https://docs.microsoft.com/en-us/previous-versions/hh968145(v%3Dvs.85)
113 '1.3.6.1.4.1.311.2.4.1': 'microsoft_nested_signature',
114 # Some places refer to this as SPC_RFC3161_OBJID, others szOID_RFC3161_counterSign.
115 # https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-crypt_algorithm_identifier
116 # refers to szOID_RFC3161_counterSign as "1.2.840.113549.1.9.16.1.4",
117 # but that OID is also called szOID_TIMESTAMP_TOKEN. Because of there being
118 # no canonical source for this OID, we give it our own name
119 '1.3.6.1.4.1.311.3.3.1': 'microsoft_time_stamp_token',
120 }
123class Time(Choice):
124 _alternatives = [
125 ('utc_time', UTCTime),
126 ('generalized_time', GeneralizedTime),
127 ]
130class ContentType(ObjectIdentifier):
131 _map = {
132 '1.2.840.113549.1.7.1': 'data',
133 '1.2.840.113549.1.7.2': 'signed_data',
134 '1.2.840.113549.1.7.3': 'enveloped_data',
135 '1.2.840.113549.1.7.4': 'signed_and_enveloped_data',
136 '1.2.840.113549.1.7.5': 'digested_data',
137 '1.2.840.113549.1.7.6': 'encrypted_data',
138 '1.2.840.113549.1.9.16.1.2': 'authenticated_data',
139 '1.2.840.113549.1.9.16.1.9': 'compressed_data',
140 '1.2.840.113549.1.9.16.1.23': 'authenticated_enveloped_data',
141 }
144class CMSAlgorithmProtection(Sequence):
145 _fields = [
146 ('digest_algorithm', DigestAlgorithm),
147 ('signature_algorithm', SignedDigestAlgorithm, {'implicit': 1, 'optional': True}),
148 ('mac_algorithm', HmacAlgorithm, {'implicit': 2, 'optional': True}),
149 ]
152class SetOfContentType(SetOf):
153 _child_spec = ContentType
156class SetOfOctetString(SetOf):
157 _child_spec = OctetString
160class SetOfTime(SetOf):
161 _child_spec = Time
164class SetOfAny(SetOf):
165 _child_spec = Any
168class SetOfCMSAlgorithmProtection(SetOf):
169 _child_spec = CMSAlgorithmProtection
172class CMSAttribute(Sequence):
173 _fields = [
174 ('type', CMSAttributeType),
175 ('values', None),
176 ]
178 _oid_specs = {}
180 def _values_spec(self):
181 return self._oid_specs.get(self['type'].native, SetOfAny)
183 _spec_callbacks = {
184 'values': _values_spec
185 }
188class CMSAttributes(SetOf):
189 _child_spec = CMSAttribute
192class IssuerSerial(Sequence):
193 _fields = [
194 ('issuer', GeneralNames),
195 ('serial', Integer),
196 ('issuer_uid', OctetBitString, {'optional': True}),
197 ]
200class AttCertVersion(Integer):
201 _map = {
202 0: 'v1',
203 1: 'v2',
204 }
207class AttCertSubject(Choice):
208 _alternatives = [
209 ('base_certificate_id', IssuerSerial, {'explicit': 0}),
210 ('subject_name', GeneralNames, {'explicit': 1}),
211 ]
214class AttCertValidityPeriod(Sequence):
215 _fields = [
216 ('not_before_time', GeneralizedTime),
217 ('not_after_time', GeneralizedTime),
218 ]
221class AttributeCertificateInfoV1(Sequence):
222 _fields = [
223 ('version', AttCertVersion, {'default': 'v1'}),
224 ('subject', AttCertSubject),
225 ('issuer', GeneralNames),
226 ('signature', SignedDigestAlgorithm),
227 ('serial_number', Integer),
228 ('att_cert_validity_period', AttCertValidityPeriod),
229 ('attributes', Attributes),
230 ('issuer_unique_id', OctetBitString, {'optional': True}),
231 ('extensions', Extensions, {'optional': True}),
232 ]
235class AttributeCertificateV1(Sequence):
236 _fields = [
237 ('ac_info', AttributeCertificateInfoV1),
238 ('signature_algorithm', SignedDigestAlgorithm),
239 ('signature', OctetBitString),
240 ]
243class DigestedObjectType(Enumerated):
244 _map = {
245 0: 'public_key',
246 1: 'public_key_cert',
247 2: 'other_objy_types',
248 }
251class ObjectDigestInfo(Sequence):
252 _fields = [
253 ('digested_object_type', DigestedObjectType),
254 ('other_object_type_id', ObjectIdentifier, {'optional': True}),
255 ('digest_algorithm', DigestAlgorithm),
256 ('object_digest', OctetBitString),
257 ]
260class Holder(Sequence):
261 _fields = [
262 ('base_certificate_id', IssuerSerial, {'implicit': 0, 'optional': True}),
263 ('entity_name', GeneralNames, {'implicit': 1, 'optional': True}),
264 ('object_digest_info', ObjectDigestInfo, {'implicit': 2, 'optional': True}),
265 ]
268class V2Form(Sequence):
269 _fields = [
270 ('issuer_name', GeneralNames, {'optional': True}),
271 ('base_certificate_id', IssuerSerial, {'explicit': 0, 'optional': True}),
272 ('object_digest_info', ObjectDigestInfo, {'explicit': 1, 'optional': True}),
273 ]
276class AttCertIssuer(Choice):
277 _alternatives = [
278 ('v1_form', GeneralNames),
279 ('v2_form', V2Form, {'implicit': 0}),
280 ]
283class IetfAttrValue(Choice):
284 _alternatives = [
285 ('octets', OctetString),
286 ('oid', ObjectIdentifier),
287 ('string', UTF8String),
288 ]
291class IetfAttrValues(SequenceOf):
292 _child_spec = IetfAttrValue
295class IetfAttrSyntax(Sequence):
296 _fields = [
297 ('policy_authority', GeneralNames, {'implicit': 0, 'optional': True}),
298 ('values', IetfAttrValues),
299 ]
302class SetOfIetfAttrSyntax(SetOf):
303 _child_spec = IetfAttrSyntax
306class SvceAuthInfo(Sequence):
307 _fields = [
308 ('service', GeneralName),
309 ('ident', GeneralName),
310 ('auth_info', OctetString, {'optional': True}),
311 ]
314class SetOfSvceAuthInfo(SetOf):
315 _child_spec = SvceAuthInfo
318class RoleSyntax(Sequence):
319 _fields = [
320 ('role_authority', GeneralNames, {'implicit': 0, 'optional': True}),
321 ('role_name', GeneralName, {'explicit': 1}),
322 ]
325class SetOfRoleSyntax(SetOf):
326 _child_spec = RoleSyntax
329class ClassList(BitString):
330 _map = {
331 0: 'unmarked',
332 1: 'unclassified',
333 2: 'restricted',
334 3: 'confidential',
335 4: 'secret',
336 5: 'top_secret',
337 }
340class SecurityCategory(Sequence):
341 _fields = [
342 ('type', ObjectIdentifier, {'implicit': 0}),
343 ('value', Any, {'explicit': 1}),
344 ]
347class SetOfSecurityCategory(SetOf):
348 _child_spec = SecurityCategory
351class Clearance(Sequence):
352 _fields = [
353 ('policy_id', ObjectIdentifier),
354 ('class_list', ClassList, {'default': set(['unclassified'])}),
355 ('security_categories', SetOfSecurityCategory, {'optional': True}),
356 ]
359class SetOfClearance(SetOf):
360 _child_spec = Clearance
363class BigTime(Sequence):
364 _fields = [
365 ('major', Integer),
366 ('fractional_seconds', Integer),
367 ('sign', Integer, {'optional': True}),
368 ]
371class LeapData(Sequence):
372 _fields = [
373 ('leap_time', BigTime),
374 ('action', Integer),
375 ]
378class SetOfLeapData(SetOf):
379 _child_spec = LeapData
382class TimingMetrics(Sequence):
383 _fields = [
384 ('ntp_time', BigTime),
385 ('offset', BigTime),
386 ('delay', BigTime),
387 ('expiration', BigTime),
388 ('leap_event', SetOfLeapData, {'optional': True}),
389 ]
392class SetOfTimingMetrics(SetOf):
393 _child_spec = TimingMetrics
396class TimingPolicy(Sequence):
397 _fields = [
398 ('policy_id', SequenceOf, {'spec': ObjectIdentifier}),
399 ('max_offset', BigTime, {'explicit': 0, 'optional': True}),
400 ('max_delay', BigTime, {'explicit': 1, 'optional': True}),
401 ]
404class SetOfTimingPolicy(SetOf):
405 _child_spec = TimingPolicy
408class AttCertAttributeType(ObjectIdentifier):
409 _map = {
410 '1.3.6.1.5.5.7.10.1': 'authentication_info',
411 '1.3.6.1.5.5.7.10.2': 'access_identity',
412 '1.3.6.1.5.5.7.10.3': 'charging_identity',
413 '1.3.6.1.5.5.7.10.4': 'group',
414 '2.5.4.72': 'role',
415 '2.5.4.55': 'clearance',
416 '1.3.6.1.4.1.601.10.4.1': 'timing_metrics',
417 '1.3.6.1.4.1.601.10.4.2': 'timing_policy',
418 }
421class AttCertAttribute(Sequence):
422 _fields = [
423 ('type', AttCertAttributeType),
424 ('values', None),
425 ]
427 _oid_specs = {
428 'authentication_info': SetOfSvceAuthInfo,
429 'access_identity': SetOfSvceAuthInfo,
430 'charging_identity': SetOfIetfAttrSyntax,
431 'group': SetOfIetfAttrSyntax,
432 'role': SetOfRoleSyntax,
433 'clearance': SetOfClearance,
434 'timing_metrics': SetOfTimingMetrics,
435 'timing_policy': SetOfTimingPolicy,
436 }
438 def _values_spec(self):
439 return self._oid_specs.get(self['type'].native, SetOfAny)
441 _spec_callbacks = {
442 'values': _values_spec
443 }
446class AttCertAttributes(SequenceOf):
447 _child_spec = AttCertAttribute
450class AttributeCertificateInfoV2(Sequence):
451 _fields = [
452 ('version', AttCertVersion),
453 ('holder', Holder),
454 ('issuer', AttCertIssuer),
455 ('signature', SignedDigestAlgorithm),
456 ('serial_number', Integer),
457 ('att_cert_validity_period', AttCertValidityPeriod),
458 ('attributes', AttCertAttributes),
459 ('issuer_unique_id', OctetBitString, {'optional': True}),
460 ('extensions', Extensions, {'optional': True}),
461 ]
464class AttributeCertificateV2(Sequence):
465 # Handle the situation where a V2 cert is encoded as V1
466 _bad_tag = 1
468 _fields = [
469 ('ac_info', AttributeCertificateInfoV2),
470 ('signature_algorithm', SignedDigestAlgorithm),
471 ('signature', OctetBitString),
472 ]
475class OtherCertificateFormat(Sequence):
476 _fields = [
477 ('other_cert_format', ObjectIdentifier),
478 ('other_cert', Any),
479 ]
482class CertificateChoices(Choice):
483 _alternatives = [
484 ('certificate', Certificate),
485 ('extended_certificate', ExtendedCertificate, {'implicit': 0}),
486 ('v1_attr_cert', AttributeCertificateV1, {'implicit': 1}),
487 ('v2_attr_cert', AttributeCertificateV2, {'implicit': 2}),
488 ('other', OtherCertificateFormat, {'implicit': 3}),
489 ]
491 def validate(self, class_, tag, contents):
492 """
493 Ensures that the class and tag specified exist as an alternative. This
494 custom version fixes parsing broken encodings there a V2 attribute
495 # certificate is encoded as a V1
497 :param class_:
498 The integer class_ from the encoded value header
500 :param tag:
501 The integer tag from the encoded value header
503 :param contents:
504 A byte string of the contents of the value - used when the object
505 is explicitly tagged
507 :raises:
508 ValueError - when value is not a valid alternative
509 """
511 super(CertificateChoices, self).validate(class_, tag, contents)
512 if self._choice == 2:
513 if AttCertVersion.load(Sequence.load(contents)[0].dump()).native == 'v2':
514 self._choice = 3
517class CertificateSet(SetOf):
518 _child_spec = CertificateChoices
521class ContentInfo(Sequence):
522 _fields = [
523 ('content_type', ContentType),
524 ('content', Any, {'explicit': 0, 'optional': True}),
525 ]
527 _oid_pair = ('content_type', 'content')
528 _oid_specs = {}
531class SetOfContentInfo(SetOf):
532 _child_spec = ContentInfo
535class EncapsulatedContentInfo(Sequence):
536 _fields = [
537 ('content_type', ContentType),
538 ('content', ParsableOctetString, {'explicit': 0, 'optional': True}),
539 ]
541 _oid_pair = ('content_type', 'content')
542 _oid_specs = {}
545class IssuerAndSerialNumber(Sequence):
546 _fields = [
547 ('issuer', Name),
548 ('serial_number', Integer),
549 ]
552class SignerIdentifier(Choice):
553 _alternatives = [
554 ('issuer_and_serial_number', IssuerAndSerialNumber),
555 ('subject_key_identifier', OctetString, {'implicit': 0}),
556 ]
559class DigestAlgorithms(SetOf):
560 _child_spec = DigestAlgorithm
563class CertificateRevocationLists(SetOf):
564 _child_spec = CertificateList
567class SCVPReqRes(Sequence):
568 _fields = [
569 ('request', ContentInfo, {'explicit': 0, 'optional': True}),
570 ('response', ContentInfo),
571 ]
574class OtherRevInfoFormatId(ObjectIdentifier):
575 _map = {
576 '1.3.6.1.5.5.7.16.2': 'ocsp_response',
577 '1.3.6.1.5.5.7.16.4': 'scvp',
578 }
581class OtherRevocationInfoFormat(Sequence):
582 _fields = [
583 ('other_rev_info_format', OtherRevInfoFormatId),
584 ('other_rev_info', Any),
585 ]
587 _oid_pair = ('other_rev_info_format', 'other_rev_info')
588 _oid_specs = {
589 'ocsp_response': OCSPResponse,
590 'scvp': SCVPReqRes,
591 }
594class RevocationInfoChoice(Choice):
595 _alternatives = [
596 ('crl', CertificateList),
597 ('other', OtherRevocationInfoFormat, {'implicit': 1}),
598 ]
601class RevocationInfoChoices(SetOf):
602 _child_spec = RevocationInfoChoice
605class SignerInfo(Sequence):
606 _fields = [
607 ('version', CMSVersion),
608 ('sid', SignerIdentifier),
609 ('digest_algorithm', DigestAlgorithm),
610 ('signed_attrs', CMSAttributes, {'implicit': 0, 'optional': True}),
611 ('signature_algorithm', SignedDigestAlgorithm),
612 ('signature', OctetString),
613 ('unsigned_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),
614 ]
617class SignerInfos(SetOf):
618 _child_spec = SignerInfo
621class SignedData(Sequence):
622 _fields = [
623 ('version', CMSVersion),
624 ('digest_algorithms', DigestAlgorithms),
625 ('encap_content_info', None),
626 ('certificates', CertificateSet, {'implicit': 0, 'optional': True}),
627 ('crls', RevocationInfoChoices, {'implicit': 1, 'optional': True}),
628 ('signer_infos', SignerInfos),
629 ]
631 def _encap_content_info_spec(self):
632 # If the encap_content_info is version v1, then this could be a PKCS#7
633 # structure, or a CMS structure. CMS wraps the encoded value in an
634 # Octet String tag.
636 # If the version is greater than 1, it is definite CMS
637 if self['version'].native != 'v1':
638 return EncapsulatedContentInfo
640 # Otherwise, the ContentInfo spec from PKCS#7 will be compatible with
641 # CMS v1 (which only allows Data, an Octet String) and PKCS#7, which
642 # allows Any
643 return ContentInfo
645 _spec_callbacks = {
646 'encap_content_info': _encap_content_info_spec
647 }
650class OriginatorInfo(Sequence):
651 _fields = [
652 ('certs', CertificateSet, {'implicit': 0, 'optional': True}),
653 ('crls', RevocationInfoChoices, {'implicit': 1, 'optional': True}),
654 ]
657class RecipientIdentifier(Choice):
658 _alternatives = [
659 ('issuer_and_serial_number', IssuerAndSerialNumber),
660 ('subject_key_identifier', OctetString, {'implicit': 0}),
661 ]
664class KeyEncryptionAlgorithmId(ObjectIdentifier):
665 _map = {
666 '1.2.840.113549.1.1.1': 'rsaes_pkcs1v15',
667 '1.2.840.113549.1.1.7': 'rsaes_oaep',
668 '2.16.840.1.101.3.4.1.5': 'aes128_wrap',
669 '2.16.840.1.101.3.4.1.8': 'aes128_wrap_pad',
670 '2.16.840.1.101.3.4.1.25': 'aes192_wrap',
671 '2.16.840.1.101.3.4.1.28': 'aes192_wrap_pad',
672 '2.16.840.1.101.3.4.1.45': 'aes256_wrap',
673 '2.16.840.1.101.3.4.1.48': 'aes256_wrap_pad',
674 }
676 _reverse_map = {
677 'rsa': '1.2.840.113549.1.1.1',
678 'rsaes_pkcs1v15': '1.2.840.113549.1.1.1',
679 'rsaes_oaep': '1.2.840.113549.1.1.7',
680 'aes128_wrap': '2.16.840.1.101.3.4.1.5',
681 'aes128_wrap_pad': '2.16.840.1.101.3.4.1.8',
682 'aes192_wrap': '2.16.840.1.101.3.4.1.25',
683 'aes192_wrap_pad': '2.16.840.1.101.3.4.1.28',
684 'aes256_wrap': '2.16.840.1.101.3.4.1.45',
685 'aes256_wrap_pad': '2.16.840.1.101.3.4.1.48',
686 }
689class KeyEncryptionAlgorithm(_ForceNullParameters, Sequence):
690 _fields = [
691 ('algorithm', KeyEncryptionAlgorithmId),
692 ('parameters', Any, {'optional': True}),
693 ]
695 _oid_pair = ('algorithm', 'parameters')
696 _oid_specs = {
697 'rsaes_oaep': RSAESOAEPParams,
698 }
701class KeyTransRecipientInfo(Sequence):
702 _fields = [
703 ('version', CMSVersion),
704 ('rid', RecipientIdentifier),
705 ('key_encryption_algorithm', KeyEncryptionAlgorithm),
706 ('encrypted_key', OctetString),
707 ]
710class OriginatorIdentifierOrKey(Choice):
711 _alternatives = [
712 ('issuer_and_serial_number', IssuerAndSerialNumber),
713 ('subject_key_identifier', OctetString, {'implicit': 0}),
714 ('originator_key', PublicKeyInfo, {'implicit': 1}),
715 ]
718class OtherKeyAttribute(Sequence):
719 _fields = [
720 ('key_attr_id', ObjectIdentifier),
721 ('key_attr', Any),
722 ]
725class RecipientKeyIdentifier(Sequence):
726 _fields = [
727 ('subject_key_identifier', OctetString),
728 ('date', GeneralizedTime, {'optional': True}),
729 ('other', OtherKeyAttribute, {'optional': True}),
730 ]
733class KeyAgreementRecipientIdentifier(Choice):
734 _alternatives = [
735 ('issuer_and_serial_number', IssuerAndSerialNumber),
736 ('r_key_id', RecipientKeyIdentifier, {'implicit': 0}),
737 ]
740class RecipientEncryptedKey(Sequence):
741 _fields = [
742 ('rid', KeyAgreementRecipientIdentifier),
743 ('encrypted_key', OctetString),
744 ]
747class RecipientEncryptedKeys(SequenceOf):
748 _child_spec = RecipientEncryptedKey
751class KeyAgreeRecipientInfo(Sequence):
752 _fields = [
753 ('version', CMSVersion),
754 ('originator', OriginatorIdentifierOrKey, {'explicit': 0}),
755 ('ukm', OctetString, {'explicit': 1, 'optional': True}),
756 ('key_encryption_algorithm', KeyEncryptionAlgorithm),
757 ('recipient_encrypted_keys', RecipientEncryptedKeys),
758 ]
761class KEKIdentifier(Sequence):
762 _fields = [
763 ('key_identifier', OctetString),
764 ('date', GeneralizedTime, {'optional': True}),
765 ('other', OtherKeyAttribute, {'optional': True}),
766 ]
769class KEKRecipientInfo(Sequence):
770 _fields = [
771 ('version', CMSVersion),
772 ('kekid', KEKIdentifier),
773 ('key_encryption_algorithm', KeyEncryptionAlgorithm),
774 ('encrypted_key', OctetString),
775 ]
778class PasswordRecipientInfo(Sequence):
779 _fields = [
780 ('version', CMSVersion),
781 ('key_derivation_algorithm', KdfAlgorithm, {'implicit': 0, 'optional': True}),
782 ('key_encryption_algorithm', KeyEncryptionAlgorithm),
783 ('encrypted_key', OctetString),
784 ]
787class OtherRecipientInfo(Sequence):
788 _fields = [
789 ('ori_type', ObjectIdentifier),
790 ('ori_value', Any),
791 ]
794class RecipientInfo(Choice):
795 _alternatives = [
796 ('ktri', KeyTransRecipientInfo),
797 ('kari', KeyAgreeRecipientInfo, {'implicit': 1}),
798 ('kekri', KEKRecipientInfo, {'implicit': 2}),
799 ('pwri', PasswordRecipientInfo, {'implicit': 3}),
800 ('ori', OtherRecipientInfo, {'implicit': 4}),
801 ]
804class RecipientInfos(SetOf):
805 _child_spec = RecipientInfo
808class EncryptedContentInfo(Sequence):
809 _fields = [
810 ('content_type', ContentType),
811 ('content_encryption_algorithm', EncryptionAlgorithm),
812 ('encrypted_content', OctetString, {'implicit': 0, 'optional': True}),
813 ]
816class EnvelopedData(Sequence):
817 _fields = [
818 ('version', CMSVersion),
819 ('originator_info', OriginatorInfo, {'implicit': 0, 'optional': True}),
820 ('recipient_infos', RecipientInfos),
821 ('encrypted_content_info', EncryptedContentInfo),
822 ('unprotected_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),
823 ]
826class SignedAndEnvelopedData(Sequence):
827 _fields = [
828 ('version', CMSVersion),
829 ('recipient_infos', RecipientInfos),
830 ('digest_algorithms', DigestAlgorithms),
831 ('encrypted_content_info', EncryptedContentInfo),
832 ('certificates', CertificateSet, {'implicit': 0, 'optional': True}),
833 ('crls', CertificateRevocationLists, {'implicit': 1, 'optional': True}),
834 ('signer_infos', SignerInfos),
835 ]
838class DigestedData(Sequence):
839 _fields = [
840 ('version', CMSVersion),
841 ('digest_algorithm', DigestAlgorithm),
842 ('encap_content_info', None),
843 ('digest', OctetString),
844 ]
846 def _encap_content_info_spec(self):
847 # If the encap_content_info is version v1, then this could be a PKCS#7
848 # structure, or a CMS structure. CMS wraps the encoded value in an
849 # Octet String tag.
851 # If the version is greater than 1, it is definite CMS
852 if self['version'].native != 'v1':
853 return EncapsulatedContentInfo
855 # Otherwise, the ContentInfo spec from PKCS#7 will be compatible with
856 # CMS v1 (which only allows Data, an Octet String) and PKCS#7, which
857 # allows Any
858 return ContentInfo
860 _spec_callbacks = {
861 'encap_content_info': _encap_content_info_spec
862 }
865class EncryptedData(Sequence):
866 _fields = [
867 ('version', CMSVersion),
868 ('encrypted_content_info', EncryptedContentInfo),
869 ('unprotected_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),
870 ]
873class AuthenticatedData(Sequence):
874 _fields = [
875 ('version', CMSVersion),
876 ('originator_info', OriginatorInfo, {'implicit': 0, 'optional': True}),
877 ('recipient_infos', RecipientInfos),
878 ('mac_algorithm', HmacAlgorithm),
879 ('digest_algorithm', DigestAlgorithm, {'implicit': 1, 'optional': True}),
880 # This does not require the _spec_callbacks approach of SignedData and
881 # DigestedData since AuthenticatedData was not part of PKCS#7
882 ('encap_content_info', EncapsulatedContentInfo),
883 ('auth_attrs', CMSAttributes, {'implicit': 2, 'optional': True}),
884 ('mac', OctetString),
885 ('unauth_attrs', CMSAttributes, {'implicit': 3, 'optional': True}),
886 ]
889class AuthEnvelopedData(Sequence):
890 _fields = [
891 ('version', CMSVersion),
892 ('originator_info', OriginatorInfo, {'implicit': 0, 'optional': True}),
893 ('recipient_infos', RecipientInfos),
894 ('auth_encrypted_content_info', EncryptedContentInfo),
895 ('auth_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),
896 ('mac', OctetString),
897 ('unauth_attrs', CMSAttributes, {'implicit': 2, 'optional': True}),
898 ]
901class CompressionAlgorithmId(ObjectIdentifier):
902 _map = {
903 '1.2.840.113549.1.9.16.3.8': 'zlib',
904 }
907class CompressionAlgorithm(Sequence):
908 _fields = [
909 ('algorithm', CompressionAlgorithmId),
910 ('parameters', Any, {'optional': True}),
911 ]
914class CompressedData(Sequence):
915 _fields = [
916 ('version', CMSVersion),
917 ('compression_algorithm', CompressionAlgorithm),
918 ('encap_content_info', EncapsulatedContentInfo),
919 ]
921 _decompressed = None
923 @property
924 def decompressed(self):
925 if self._decompressed is None:
926 if zlib is None:
927 raise SystemError('The zlib module is not available')
928 self._decompressed = zlib.decompress(self['encap_content_info']['content'].native)
929 return self._decompressed
932class RecipientKeyIdentifier(Sequence):
933 _fields = [
934 ('subjectKeyIdentifier', OctetString),
935 ('date', GeneralizedTime, {'optional': True}),
936 ('other', OtherKeyAttribute, {'optional': True}),
937 ]
940class SMIMEEncryptionKeyPreference(Choice):
941 _alternatives = [
942 ('issuer_and_serial_number', IssuerAndSerialNumber, {'implicit': 0}),
943 ('recipientKeyId', RecipientKeyIdentifier, {'implicit': 1}),
944 ('subjectAltKeyIdentifier', PublicKeyInfo, {'implicit': 2}),
945 ]
948class SMIMEEncryptionKeyPreferences(SetOf):
949 _child_spec = SMIMEEncryptionKeyPreference
952class SMIMECapabilityIdentifier(Sequence):
953 _fields = [
954 ('capability_id', EncryptionAlgorithmId),
955 ('parameters', Any, {'optional': True}),
956 ]
959class SMIMECapabilites(SequenceOf):
960 _child_spec = SMIMECapabilityIdentifier
963class SetOfSMIMECapabilites(SetOf):
964 _child_spec = SMIMECapabilites
967ContentInfo._oid_specs = {
968 'data': OctetString,
969 'signed_data': SignedData,
970 'enveloped_data': EnvelopedData,
971 'signed_and_enveloped_data': SignedAndEnvelopedData,
972 'digested_data': DigestedData,
973 'encrypted_data': EncryptedData,
974 'authenticated_data': AuthenticatedData,
975 'compressed_data': CompressedData,
976 'authenticated_enveloped_data': AuthEnvelopedData,
977}
980EncapsulatedContentInfo._oid_specs = {
981 'signed_data': SignedData,
982 'enveloped_data': EnvelopedData,
983 'signed_and_enveloped_data': SignedAndEnvelopedData,
984 'digested_data': DigestedData,
985 'encrypted_data': EncryptedData,
986 'authenticated_data': AuthenticatedData,
987 'compressed_data': CompressedData,
988 'authenticated_enveloped_data': AuthEnvelopedData,
989}
992CMSAttribute._oid_specs = {
993 'content_type': SetOfContentType,
994 'message_digest': SetOfOctetString,
995 'signing_time': SetOfTime,
996 'counter_signature': SignerInfos,
997 'signature_time_stamp_token': SetOfContentInfo,
998 'cms_algorithm_protection': SetOfCMSAlgorithmProtection,
999 'microsoft_nested_signature': SetOfContentInfo,
1000 'microsoft_time_stamp_token': SetOfContentInfo,
1001 'encrypt_key_pref': SMIMEEncryptionKeyPreferences,
1002 'smime_capabilities': SetOfSMIMECapabilites,
1003}