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