1# coding: utf-8 2 3""" 4ASN.1 type classes for cryptographic message syntax (CMS). Structures are also 5compatible with PKCS#7. Exports the following items: 6 7 - AuthenticatedData() 8 - AuthEnvelopedData() 9 - CompressedData() 10 - ContentInfo() 11 - DigestedData() 12 - EncryptedData() 13 - EnvelopedData() 14 - SignedAndEnvelopedData() 15 - SignedData() 16 17Other type classes are defined that help compose the types listed above. 18 19Most CMS structures in the wild are formatted as ContentInfo encapsulating one of the other types. 20""" 21 22from __future__ import unicode_literals, division, absolute_import, print_function 23 24try: 25 import zlib 26except (ImportError): 27 zlib = None 28 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 60 61 62# These structures are taken from 63# ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-6.asc 64 65class ExtendedCertificateInfo(Sequence): 66 _fields = [ 67 ('version', Integer), 68 ('certificate', Certificate), 69 ('attributes', Attributes), 70 ] 71 72 73class ExtendedCertificate(Sequence): 74 _fields = [ 75 ('extended_certificate_info', ExtendedCertificateInfo), 76 ('signature_algorithm', SignedDigestAlgorithm), 77 ('signature', OctetBitString), 78 ] 79 80 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 85 86 87class CMSVersion(Integer): 88 _map = { 89 0: 'v0', 90 1: 'v1', 91 2: 'v2', 92 3: 'v3', 93 4: 'v4', 94 5: 'v5', 95 } 96 97 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 } 121 122 123class Time(Choice): 124 _alternatives = [ 125 ('utc_time', UTCTime), 126 ('generalized_time', GeneralizedTime), 127 ] 128 129 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 } 142 143 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 ] 150 151 152class SetOfContentType(SetOf): 153 _child_spec = ContentType 154 155 156class SetOfOctetString(SetOf): 157 _child_spec = OctetString 158 159 160class SetOfTime(SetOf): 161 _child_spec = Time 162 163 164class SetOfAny(SetOf): 165 _child_spec = Any 166 167 168class SetOfCMSAlgorithmProtection(SetOf): 169 _child_spec = CMSAlgorithmProtection 170 171 172class CMSAttribute(Sequence): 173 _fields = [ 174 ('type', CMSAttributeType), 175 ('values', None), 176 ] 177 178 _oid_specs = {} 179 180 def _values_spec(self): 181 return self._oid_specs.get(self['type'].native, SetOfAny) 182 183 _spec_callbacks = { 184 'values': _values_spec 185 } 186 187 188class CMSAttributes(SetOf): 189 _child_spec = CMSAttribute 190 191 192class IssuerSerial(Sequence): 193 _fields = [ 194 ('issuer', GeneralNames), 195 ('serial', Integer), 196 ('issuer_uid', OctetBitString, {'optional': True}), 197 ] 198 199 200class AttCertVersion(Integer): 201 _map = { 202 0: 'v1', 203 1: 'v2', 204 } 205 206 207class AttCertSubject(Choice): 208 _alternatives = [ 209 ('base_certificate_id', IssuerSerial, {'explicit': 0}), 210 ('subject_name', GeneralNames, {'explicit': 1}), 211 ] 212 213 214class AttCertValidityPeriod(Sequence): 215 _fields = [ 216 ('not_before_time', GeneralizedTime), 217 ('not_after_time', GeneralizedTime), 218 ] 219 220 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 ] 233 234 235class AttributeCertificateV1(Sequence): 236 _fields = [ 237 ('ac_info', AttributeCertificateInfoV1), 238 ('signature_algorithm', SignedDigestAlgorithm), 239 ('signature', OctetBitString), 240 ] 241 242 243class DigestedObjectType(Enumerated): 244 _map = { 245 0: 'public_key', 246 1: 'public_key_cert', 247 2: 'other_objy_types', 248 } 249 250 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 ] 258 259 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 ] 266 267 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 ] 274 275 276class AttCertIssuer(Choice): 277 _alternatives = [ 278 ('v1_form', GeneralNames), 279 ('v2_form', V2Form, {'implicit': 0}), 280 ] 281 282 283class IetfAttrValue(Choice): 284 _alternatives = [ 285 ('octets', OctetString), 286 ('oid', ObjectIdentifier), 287 ('string', UTF8String), 288 ] 289 290 291class IetfAttrValues(SequenceOf): 292 _child_spec = IetfAttrValue 293 294 295class IetfAttrSyntax(Sequence): 296 _fields = [ 297 ('policy_authority', GeneralNames, {'implicit': 0, 'optional': True}), 298 ('values', IetfAttrValues), 299 ] 300 301 302class SetOfIetfAttrSyntax(SetOf): 303 _child_spec = IetfAttrSyntax 304 305 306class SvceAuthInfo(Sequence): 307 _fields = [ 308 ('service', GeneralName), 309 ('ident', GeneralName), 310 ('auth_info', OctetString, {'optional': True}), 311 ] 312 313 314class SetOfSvceAuthInfo(SetOf): 315 _child_spec = SvceAuthInfo 316 317 318class RoleSyntax(Sequence): 319 _fields = [ 320 ('role_authority', GeneralNames, {'implicit': 0, 'optional': True}), 321 ('role_name', GeneralName, {'explicit': 1}), 322 ] 323 324 325class SetOfRoleSyntax(SetOf): 326 _child_spec = RoleSyntax 327 328 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 } 338 339 340class SecurityCategory(Sequence): 341 _fields = [ 342 ('type', ObjectIdentifier, {'implicit': 0}), 343 ('value', Any, {'explicit': 1}), 344 ] 345 346 347class SetOfSecurityCategory(SetOf): 348 _child_spec = SecurityCategory 349 350 351class Clearance(Sequence): 352 _fields = [ 353 ('policy_id', ObjectIdentifier), 354 ('class_list', ClassList, {'default': set(['unclassified'])}), 355 ('security_categories', SetOfSecurityCategory, {'optional': True}), 356 ] 357 358 359class SetOfClearance(SetOf): 360 _child_spec = Clearance 361 362 363class BigTime(Sequence): 364 _fields = [ 365 ('major', Integer), 366 ('fractional_seconds', Integer), 367 ('sign', Integer, {'optional': True}), 368 ] 369 370 371class LeapData(Sequence): 372 _fields = [ 373 ('leap_time', BigTime), 374 ('action', Integer), 375 ] 376 377 378class SetOfLeapData(SetOf): 379 _child_spec = LeapData 380 381 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 ] 390 391 392class SetOfTimingMetrics(SetOf): 393 _child_spec = TimingMetrics 394 395 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 ] 402 403 404class SetOfTimingPolicy(SetOf): 405 _child_spec = TimingPolicy 406 407 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 } 419 420 421class AttCertAttribute(Sequence): 422 _fields = [ 423 ('type', AttCertAttributeType), 424 ('values', None), 425 ] 426 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 } 437 438 def _values_spec(self): 439 return self._oid_specs.get(self['type'].native, SetOfAny) 440 441 _spec_callbacks = { 442 'values': _values_spec 443 } 444 445 446class AttCertAttributes(SequenceOf): 447 _child_spec = AttCertAttribute 448 449 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 ] 462 463 464class AttributeCertificateV2(Sequence): 465 # Handle the situation where a V2 cert is encoded as V1 466 _bad_tag = 1 467 468 _fields = [ 469 ('ac_info', AttributeCertificateInfoV2), 470 ('signature_algorithm', SignedDigestAlgorithm), 471 ('signature', OctetBitString), 472 ] 473 474 475class OtherCertificateFormat(Sequence): 476 _fields = [ 477 ('other_cert_format', ObjectIdentifier), 478 ('other_cert', Any), 479 ] 480 481 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 ] 490 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 496 497 :param class_: 498 The integer class_ from the encoded value header 499 500 :param tag: 501 The integer tag from the encoded value header 502 503 :param contents: 504 A byte string of the contents of the value - used when the object 505 is explicitly tagged 506 507 :raises: 508 ValueError - when value is not a valid alternative 509 """ 510 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 515 516 517class CertificateSet(SetOf): 518 _child_spec = CertificateChoices 519 520 521class ContentInfo(Sequence): 522 _fields = [ 523 ('content_type', ContentType), 524 ('content', Any, {'explicit': 0, 'optional': True}), 525 ] 526 527 _oid_pair = ('content_type', 'content') 528 _oid_specs = {} 529 530 531class SetOfContentInfo(SetOf): 532 _child_spec = ContentInfo 533 534 535class EncapsulatedContentInfo(Sequence): 536 _fields = [ 537 ('content_type', ContentType), 538 ('content', ParsableOctetString, {'explicit': 0, 'optional': True}), 539 ] 540 541 _oid_pair = ('content_type', 'content') 542 _oid_specs = {} 543 544 545class IssuerAndSerialNumber(Sequence): 546 _fields = [ 547 ('issuer', Name), 548 ('serial_number', Integer), 549 ] 550 551 552class SignerIdentifier(Choice): 553 _alternatives = [ 554 ('issuer_and_serial_number', IssuerAndSerialNumber), 555 ('subject_key_identifier', OctetString, {'implicit': 0}), 556 ] 557 558 559class DigestAlgorithms(SetOf): 560 _child_spec = DigestAlgorithm 561 562 563class CertificateRevocationLists(SetOf): 564 _child_spec = CertificateList 565 566 567class SCVPReqRes(Sequence): 568 _fields = [ 569 ('request', ContentInfo, {'explicit': 0, 'optional': True}), 570 ('response', ContentInfo), 571 ] 572 573 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 } 579 580 581class OtherRevocationInfoFormat(Sequence): 582 _fields = [ 583 ('other_rev_info_format', OtherRevInfoFormatId), 584 ('other_rev_info', Any), 585 ] 586 587 _oid_pair = ('other_rev_info_format', 'other_rev_info') 588 _oid_specs = { 589 'ocsp_response': OCSPResponse, 590 'scvp': SCVPReqRes, 591 } 592 593 594class RevocationInfoChoice(Choice): 595 _alternatives = [ 596 ('crl', CertificateList), 597 ('other', OtherRevocationInfoFormat, {'implicit': 1}), 598 ] 599 600 601class RevocationInfoChoices(SetOf): 602 _child_spec = RevocationInfoChoice 603 604 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 ] 615 616 617class SignerInfos(SetOf): 618 _child_spec = SignerInfo 619 620 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 ] 630 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. 635 636 # If the version is greater than 1, it is definite CMS 637 if self['version'].native != 'v1': 638 return EncapsulatedContentInfo 639 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 644 645 _spec_callbacks = { 646 'encap_content_info': _encap_content_info_spec 647 } 648 649 650class OriginatorInfo(Sequence): 651 _fields = [ 652 ('certs', CertificateSet, {'implicit': 0, 'optional': True}), 653 ('crls', RevocationInfoChoices, {'implicit': 1, 'optional': True}), 654 ] 655 656 657class RecipientIdentifier(Choice): 658 _alternatives = [ 659 ('issuer_and_serial_number', IssuerAndSerialNumber), 660 ('subject_key_identifier', OctetString, {'implicit': 0}), 661 ] 662 663 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 } 675 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 } 687 688 689class KeyEncryptionAlgorithm(_ForceNullParameters, Sequence): 690 _fields = [ 691 ('algorithm', KeyEncryptionAlgorithmId), 692 ('parameters', Any, {'optional': True}), 693 ] 694 695 _oid_pair = ('algorithm', 'parameters') 696 _oid_specs = { 697 'rsaes_oaep': RSAESOAEPParams, 698 } 699 700 701class KeyTransRecipientInfo(Sequence): 702 _fields = [ 703 ('version', CMSVersion), 704 ('rid', RecipientIdentifier), 705 ('key_encryption_algorithm', KeyEncryptionAlgorithm), 706 ('encrypted_key', OctetString), 707 ] 708 709 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 ] 716 717 718class OtherKeyAttribute(Sequence): 719 _fields = [ 720 ('key_attr_id', ObjectIdentifier), 721 ('key_attr', Any), 722 ] 723 724 725class RecipientKeyIdentifier(Sequence): 726 _fields = [ 727 ('subject_key_identifier', OctetString), 728 ('date', GeneralizedTime, {'optional': True}), 729 ('other', OtherKeyAttribute, {'optional': True}), 730 ] 731 732 733class KeyAgreementRecipientIdentifier(Choice): 734 _alternatives = [ 735 ('issuer_and_serial_number', IssuerAndSerialNumber), 736 ('r_key_id', RecipientKeyIdentifier, {'implicit': 0}), 737 ] 738 739 740class RecipientEncryptedKey(Sequence): 741 _fields = [ 742 ('rid', KeyAgreementRecipientIdentifier), 743 ('encrypted_key', OctetString), 744 ] 745 746 747class RecipientEncryptedKeys(SequenceOf): 748 _child_spec = RecipientEncryptedKey 749 750 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 ] 759 760 761class KEKIdentifier(Sequence): 762 _fields = [ 763 ('key_identifier', OctetString), 764 ('date', GeneralizedTime, {'optional': True}), 765 ('other', OtherKeyAttribute, {'optional': True}), 766 ] 767 768 769class KEKRecipientInfo(Sequence): 770 _fields = [ 771 ('version', CMSVersion), 772 ('kekid', KEKIdentifier), 773 ('key_encryption_algorithm', KeyEncryptionAlgorithm), 774 ('encrypted_key', OctetString), 775 ] 776 777 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 ] 785 786 787class OtherRecipientInfo(Sequence): 788 _fields = [ 789 ('ori_type', ObjectIdentifier), 790 ('ori_value', Any), 791 ] 792 793 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 ] 802 803 804class RecipientInfos(SetOf): 805 _child_spec = RecipientInfo 806 807 808class EncryptedContentInfo(Sequence): 809 _fields = [ 810 ('content_type', ContentType), 811 ('content_encryption_algorithm', EncryptionAlgorithm), 812 ('encrypted_content', OctetString, {'implicit': 0, 'optional': True}), 813 ] 814 815 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 ] 824 825 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 ] 836 837 838class DigestedData(Sequence): 839 _fields = [ 840 ('version', CMSVersion), 841 ('digest_algorithm', DigestAlgorithm), 842 ('encap_content_info', None), 843 ('digest', OctetString), 844 ] 845 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. 850 851 # If the version is greater than 1, it is definite CMS 852 if self['version'].native != 'v1': 853 return EncapsulatedContentInfo 854 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 859 860 _spec_callbacks = { 861 'encap_content_info': _encap_content_info_spec 862 } 863 864 865class EncryptedData(Sequence): 866 _fields = [ 867 ('version', CMSVersion), 868 ('encrypted_content_info', EncryptedContentInfo), 869 ('unprotected_attrs', CMSAttributes, {'implicit': 1, 'optional': True}), 870 ] 871 872 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 ] 887 888 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 ] 899 900 901class CompressionAlgorithmId(ObjectIdentifier): 902 _map = { 903 '1.2.840.113549.1.9.16.3.8': 'zlib', 904 } 905 906 907class CompressionAlgorithm(Sequence): 908 _fields = [ 909 ('algorithm', CompressionAlgorithmId), 910 ('parameters', Any, {'optional': True}), 911 ] 912 913 914class CompressedData(Sequence): 915 _fields = [ 916 ('version', CMSVersion), 917 ('compression_algorithm', CompressionAlgorithm), 918 ('encap_content_info', EncapsulatedContentInfo), 919 ] 920 921 _decompressed = None 922 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 930 931 932class RecipientKeyIdentifier(Sequence): 933 _fields = [ 934 ('subjectKeyIdentifier', OctetString), 935 ('date', GeneralizedTime, {'optional': True}), 936 ('other', OtherKeyAttribute, {'optional': True}), 937 ] 938 939 940class SMIMEEncryptionKeyPreference(Choice): 941 _alternatives = [ 942 ('issuer_and_serial_number', IssuerAndSerialNumber, {'implicit': 0}), 943 ('recipientKeyId', RecipientKeyIdentifier, {'implicit': 1}), 944 ('subjectAltKeyIdentifier', PublicKeyInfo, {'implicit': 2}), 945 ] 946 947 948class SMIMEEncryptionKeyPreferences(SetOf): 949 _child_spec = SMIMEEncryptionKeyPreference 950 951 952class SMIMECapabilityIdentifier(Sequence): 953 _fields = [ 954 ('capability_id', EncryptionAlgorithmId), 955 ('parameters', Any, {'optional': True}), 956 ] 957 958 959class SMIMECapabilites(SequenceOf): 960 _child_spec = SMIMECapabilityIdentifier 961 962 963class SetOfSMIMECapabilites(SetOf): 964 _child_spec = SMIMECapabilites 965 966 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} 978 979 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} 990 991 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} 1004