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

261 statements  

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}