blob: 054877dcf74a520e4168de7516b2e738d620c640 [file] [log] [blame]
wbonde91513e2015-06-03 14:52:18 -04001# coding: utf-8
wbondea25fc22015-06-19 15:07:04 -04002
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()
Jörn Heisslerfb9c1362016-07-29 03:59:02 +020011 - DigestedData()
wbondea25fc22015-06-19 15:07:04 -040012 - EncryptedData()
13 - EnvelopedData()
wbondea25fc22015-06-19 15:07:04 -040014 - SignedAndEnvelopedData()
15 - SignedData()
16
17Other type classes are defined that help compose the types listed above.
Jörn Heissler63fa2f52017-11-14 20:11:12 +010018
19Most CMS structures in the wild are formatted as ContentInfo encapsulating one of the other types.
wbondea25fc22015-06-19 15:07:04 -040020"""
21
wbond6b66ab52015-06-21 10:26:45 -040022from __future__ import unicode_literals, division, absolute_import, print_function
wbonde91513e2015-06-03 14:52:18 -040023
24try:
25 import zlib
26except (ImportError):
27 zlib = None
28
29from .algos import (
wbond381a4da2016-08-30 11:39:54 -040030 _ForceNullParameters,
wbonde91513e2015-06-03 14:52:18 -040031 DigestAlgorithm,
wbond59af99d2015-06-15 16:19:04 -040032 EncryptionAlgorithm,
wbonde91513e2015-06-03 14:52:18 -040033 HmacAlgorithm,
wbond59af99d2015-06-15 16:19:04 -040034 KdfAlgorithm,
35 SignedDigestAlgorithm,
wbonde91513e2015-06-03 14:52:18 -040036)
37from .core import (
38 Any,
wbond6a8cf2a2016-07-14 07:17:44 -040039 BitString,
wbonde91513e2015-06-03 14:52:18 -040040 Choice,
41 Enumerated,
42 GeneralizedTime,
43 Integer,
44 ObjectIdentifier,
45 OctetBitString,
46 OctetString,
wbonde5a1c6e2015-08-03 07:42:28 -040047 ParsableOctetString,
wbonde91513e2015-06-03 14:52:18 -040048 Sequence,
49 SequenceOf,
50 SetOf,
51 UTCTime,
wbond6a8cf2a2016-07-14 07:17:44 -040052 UTF8String,
wbonde91513e2015-06-03 14:52:18 -040053)
54from .crl import CertificateList
55from .keys import PublicKeyInfo
56from .ocsp import OCSPResponse
wbond6a8cf2a2016-07-14 07:17:44 -040057from .x509 import Attributes, Certificate, Extensions, GeneralName, GeneralNames, Name
wbonde91513e2015-06-03 14:52:18 -040058
59
wbonde91513e2015-06-03 14:52:18 -040060# These structures are taken from
61# ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-6.asc
62
63class ExtendedCertificateInfo(Sequence):
64 _fields = [
65 ('version', Integer),
66 ('certificate', Certificate),
67 ('attributes', Attributes),
68 ]
69
wbonda26664f2015-10-07 11:57:35 -040070
wbonde91513e2015-06-03 14:52:18 -040071class ExtendedCertificate(Sequence):
72 _fields = [
73 ('extended_certificate_info', ExtendedCertificateInfo),
74 ('signature_algorithm', SignedDigestAlgorithm),
75 ('signature', OctetBitString),
76 ]
77
78
79# These structures are taken from https://tools.ietf.org/html/rfc5652,
80# https://tools.ietf.org/html/rfc5083, http://tools.ietf.org/html/rfc2315,
81# https://tools.ietf.org/html/rfc5940, https://tools.ietf.org/html/rfc3274,
82# https://tools.ietf.org/html/rfc3281
83
84
85class CMSVersion(Integer):
86 _map = {
87 0: 'v0',
88 1: 'v1',
89 2: 'v2',
90 3: 'v3',
91 4: 'v4',
92 5: 'v5',
93 }
94
95
96class CMSAttributeType(ObjectIdentifier):
97 _map = {
98 '1.2.840.113549.1.9.3': 'content_type',
99 '1.2.840.113549.1.9.4': 'message_digest',
100 '1.2.840.113549.1.9.5': 'signing_time',
101 '1.2.840.113549.1.9.6': 'counter_signature',
wbondc57878c2016-07-14 06:02:01 -0400102 # https://tools.ietf.org/html/rfc3161#page-20
103 '1.2.840.113549.1.9.16.2.14': 'signature_time_stamp_token',
Anthony Albaad0e19e2017-05-16 22:21:18 +0800104 # https://tools.ietf.org/html/rfc6211#page-5
105 '1.2.840.113549.1.9.52': 'cms_algorithm_protection',
wbonde91513e2015-06-03 14:52:18 -0400106 }
107
108
109class Time(Choice):
110 _alternatives = [
111 ('utc_time', UTCTime),
112 ('generalized_time', GeneralizedTime),
113 ]
114
115
116class ContentType(ObjectIdentifier):
117 _map = {
118 '1.2.840.113549.1.7.1': 'data',
119 '1.2.840.113549.1.7.2': 'signed_data',
120 '1.2.840.113549.1.7.3': 'enveloped_data',
121 '1.2.840.113549.1.7.4': 'signed_and_enveloped_data',
122 '1.2.840.113549.1.7.5': 'digested_data',
123 '1.2.840.113549.1.7.6': 'encrypted_data',
124 '1.2.840.113549.1.9.16.1.2': 'authenticated_data',
125 '1.2.840.113549.1.9.16.1.9': 'compressed_data',
126 '1.2.840.113549.1.9.16.1.23': 'authenticated_enveloped_data',
127 }
128
129
Anthony Albaad0e19e2017-05-16 22:21:18 +0800130class CMSAlgorithmProtection(Sequence):
131 _fields = [
132 ('digest_algorithm', DigestAlgorithm),
wbondd62ed9a2017-09-15 07:13:52 -0400133 ('signature_algorithm', SignedDigestAlgorithm, {'implicit': 1, 'optional': True}),
134 ('mac_algorithm', HmacAlgorithm, {'implicit': 2, 'optional': True}),
Anthony Albaad0e19e2017-05-16 22:21:18 +0800135 ]
136
137
wbonde91513e2015-06-03 14:52:18 -0400138class SetOfContentType(SetOf):
139 _child_spec = ContentType
140
141
142class SetOfOctetString(SetOf):
143 _child_spec = OctetString
144
145
146class SetOfTime(SetOf):
147 _child_spec = Time
148
149
wbonda07a51a2015-12-03 01:09:07 -0500150class SetOfAny(SetOf):
151 _child_spec = Any
152
153
Anthony Albaad0e19e2017-05-16 22:21:18 +0800154class SetOfCMSAlgorithmProtection(SetOf):
155 _child_spec = CMSAlgorithmProtection
156
157
wbonde91513e2015-06-03 14:52:18 -0400158class CMSAttribute(Sequence):
159 _fields = [
160 ('type', CMSAttributeType),
wbonda07a51a2015-12-03 01:09:07 -0500161 ('values', None),
wbonde91513e2015-06-03 14:52:18 -0400162 ]
163
wbonde91513e2015-06-03 14:52:18 -0400164 _oid_specs = {}
165
wbonda07a51a2015-12-03 01:09:07 -0500166 def _values_spec(self):
167 return self._oid_specs.get(self['type'].native, SetOfAny)
168
169 _spec_callbacks = {
170 'values': _values_spec
171 }
172
wbonde91513e2015-06-03 14:52:18 -0400173
wbondf87d4852015-12-03 00:02:35 -0500174class CMSAttributes(SetOf):
wbonde91513e2015-06-03 14:52:18 -0400175 _child_spec = CMSAttribute
176
177
178class IssuerSerial(Sequence):
179 _fields = [
180 ('issuer', GeneralNames),
181 ('serial', Integer),
182 ('issuer_uid', OctetBitString, {'optional': True}),
183 ]
184
185
186class AttCertVersion(Integer):
187 _map = {
188 0: 'v1',
189 1: 'v2',
190 }
191
192
193class AttCertSubject(Choice):
194 _alternatives = [
wbondd62ed9a2017-09-15 07:13:52 -0400195 ('base_certificate_id', IssuerSerial, {'explicit': 0}),
196 ('subject_name', GeneralNames, {'explicit': 1}),
wbonde91513e2015-06-03 14:52:18 -0400197 ]
198
199
200class AttCertValidityPeriod(Sequence):
201 _fields = [
202 ('not_before_time', GeneralizedTime),
203 ('not_after_time', GeneralizedTime),
204 ]
205
206
207class AttributeCertificateInfoV1(Sequence):
208 _fields = [
wbondb8dafce2015-08-24 09:28:01 -0400209 ('version', AttCertVersion, {'default': 'v1'}),
wbonde91513e2015-06-03 14:52:18 -0400210 ('subject', AttCertSubject),
211 ('issuer', GeneralNames),
212 ('signature', SignedDigestAlgorithm),
213 ('serial_number', Integer),
214 ('att_cert_validity_period', AttCertValidityPeriod),
215 ('attributes', Attributes),
216 ('issuer_unique_id', OctetBitString, {'optional': True}),
217 ('extensions', Extensions, {'optional': True}),
218 ]
219
220
221class AttributeCertificateV1(Sequence):
222 _fields = [
223 ('ac_info', AttributeCertificateInfoV1),
224 ('signature_algorithm', SignedDigestAlgorithm),
225 ('signature', OctetBitString),
226 ]
227
228
229class DigestedObjectType(Enumerated):
230 _map = {
231 0: 'public_key',
232 1: 'public_key_cert',
233 2: 'other_objy_types',
234 }
235
236
237class ObjectDigestInfo(Sequence):
238 _fields = [
239 ('digested_object_type', DigestedObjectType),
240 ('other_object_type_id', ObjectIdentifier, {'optional': True}),
241 ('digest_algorithm', DigestAlgorithm),
242 ('object_digest', OctetBitString),
243 ]
244
245
246class Holder(Sequence):
247 _fields = [
wbondd62ed9a2017-09-15 07:13:52 -0400248 ('base_certificate_id', IssuerSerial, {'implicit': 0, 'optional': True}),
249 ('entity_name', GeneralNames, {'implicit': 1, 'optional': True}),
250 ('object_digest_info', ObjectDigestInfo, {'implicit': 2, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400251 ]
252
253
254class V2Form(Sequence):
255 _fields = [
256 ('issuer_name', GeneralNames, {'optional': True}),
wbondd62ed9a2017-09-15 07:13:52 -0400257 ('base_certificate_id', IssuerSerial, {'explicit': 0, 'optional': True}),
258 ('object_digest_info', ObjectDigestInfo, {'explicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400259 ]
260
261
262class AttCertIssuer(Choice):
263 _alternatives = [
264 ('v1_form', GeneralNames),
wbondd62ed9a2017-09-15 07:13:52 -0400265 ('v2_form', V2Form, {'explicit': 0}),
wbonde91513e2015-06-03 14:52:18 -0400266 ]
267
268
wbond6a8cf2a2016-07-14 07:17:44 -0400269class IetfAttrValue(Choice):
270 _alternatives = [
271 ('octets', OctetString),
272 ('oid', ObjectIdentifier),
273 ('string', UTF8String),
274 ]
275
276
277class IetfAttrValues(SequenceOf):
278 _child_spec = IetfAttrValue
279
280
281class IetfAttrSyntax(Sequence):
282 _fields = [
wbondd62ed9a2017-09-15 07:13:52 -0400283 ('policy_authority', GeneralNames, {'implicit': 0, 'optional': True}),
wbond6a8cf2a2016-07-14 07:17:44 -0400284 ('values', IetfAttrValues),
285 ]
286
287
288class SetOfIetfAttrSyntax(SetOf):
289 _child_spec = IetfAttrSyntax
290
291
292class SvceAuthInfo(Sequence):
293 _fields = [
294 ('service', GeneralName),
295 ('ident', GeneralName),
296 ('auth_info', OctetString, {'optional': True}),
297 ]
298
299
300class SetOfSvceAuthInfo(SetOf):
301 _child_spec = SvceAuthInfo
302
303
304class RoleSyntax(Sequence):
305 _fields = [
wbondd62ed9a2017-09-15 07:13:52 -0400306 ('role_authority', GeneralNames, {'implicit': 0, 'optional': True}),
307 ('role_name', GeneralName, {'implicit': 1}),
wbond6a8cf2a2016-07-14 07:17:44 -0400308 ]
309
310
311class SetOfRoleSyntax(SetOf):
312 _child_spec = RoleSyntax
313
314
315class ClassList(BitString):
316 _map = {
317 0: 'unmarked',
318 1: 'unclassified',
319 2: 'restricted',
320 3: 'confidential',
321 4: 'secret',
322 5: 'top_secret',
323 }
324
325
326class SecurityCategory(Sequence):
327 _fields = [
wbondd62ed9a2017-09-15 07:13:52 -0400328 ('type', ObjectIdentifier, {'implicit': 0}),
329 ('value', Any, {'implicit': 1}),
wbond6a8cf2a2016-07-14 07:17:44 -0400330 ]
331
332
333class SetOfSecurityCategory(SetOf):
334 _child_spec = SecurityCategory
335
336
337class Clearance(Sequence):
338 _fields = [
wbondd62ed9a2017-09-15 07:13:52 -0400339 ('policy_id', ObjectIdentifier, {'implicit': 0}),
340 ('class_list', ClassList, {'implicit': 1, 'default': 'unclassified'}),
341 ('security_categories', SetOfSecurityCategory, {'implicit': 2, 'optional': True}),
wbond6a8cf2a2016-07-14 07:17:44 -0400342 ]
343
344
345class SetOfClearance(SetOf):
346 _child_spec = Clearance
347
348
349class BigTime(Sequence):
350 _fields = [
351 ('major', Integer),
352 ('fractional_seconds', Integer),
353 ('sign', Integer, {'optional': True}),
354 ]
355
356
357class LeapData(Sequence):
358 _fields = [
359 ('leap_time', BigTime),
360 ('action', Integer),
361 ]
362
363
364class SetOfLeapData(SetOf):
365 _child_spec = LeapData
366
367
368class TimingMetrics(Sequence):
369 _fields = [
370 ('ntp_time', BigTime),
371 ('offset', BigTime),
372 ('delay', BigTime),
373 ('expiration', BigTime),
374 ('leap_event', SetOfLeapData, {'optional': True}),
375 ]
376
377
378class SetOfTimingMetrics(SetOf):
379 _child_spec = TimingMetrics
380
381
382class TimingPolicy(Sequence):
383 _fields = [
384 ('policy_id', SequenceOf, {'spec': ObjectIdentifier}),
wbondd62ed9a2017-09-15 07:13:52 -0400385 ('max_offset', BigTime, {'explicit': 0, 'optional': True}),
386 ('max_delay', BigTime, {'explicit': 1, 'optional': True}),
wbond6a8cf2a2016-07-14 07:17:44 -0400387 ]
388
389
390class SetOfTimingPolicy(SetOf):
391 _child_spec = TimingPolicy
392
393
394class AttCertAttributeType(ObjectIdentifier):
395 _map = {
396 '1.3.6.1.5.5.7.10.1': 'authentication_info',
397 '1.3.6.1.5.5.7.10.2': 'access_identity',
398 '1.3.6.1.5.5.7.10.3': 'charging_identity',
399 '1.3.6.1.5.5.7.10.4': 'group',
400 '2.5.4.72': 'role',
401 '2.5.4.55': 'clearance',
402 '1.3.6.1.4.1.601.10.4.1': 'timing_metrics',
403 '1.3.6.1.4.1.601.10.4.2': 'timing_policy',
404 }
405
406
407class AttCertAttribute(Sequence):
408 _fields = [
409 ('type', AttCertAttributeType),
410 ('values', None),
411 ]
412
413 _oid_specs = {
414 'authentication_info': SetOfSvceAuthInfo,
415 'access_identity': SetOfSvceAuthInfo,
416 'charging_identity': SetOfIetfAttrSyntax,
417 'group': SetOfIetfAttrSyntax,
418 'role': SetOfRoleSyntax,
419 'clearance': SetOfClearance,
420 'timing_metrics': SetOfTimingMetrics,
421 'timing_policy': SetOfTimingPolicy,
422 }
423
424 def _values_spec(self):
wbond7b1cd4b2017-02-10 05:11:14 -0500425 return self._oid_specs.get(self['type'].native, SetOfAny)
wbond6a8cf2a2016-07-14 07:17:44 -0400426
427 _spec_callbacks = {
428 'values': _values_spec
429 }
430
431
432class AttCertAttributes(SequenceOf):
433 _child_spec = AttCertAttribute
434
435
wbonde91513e2015-06-03 14:52:18 -0400436class AttributeCertificateInfoV2(Sequence):
437 _fields = [
438 ('version', AttCertVersion),
439 ('holder', Holder),
440 ('issuer', AttCertIssuer),
441 ('signature', SignedDigestAlgorithm),
442 ('serial_number', Integer),
443 ('att_cert_validity_period', AttCertValidityPeriod),
wbond6a8cf2a2016-07-14 07:17:44 -0400444 ('attributes', AttCertAttributes),
wbonde91513e2015-06-03 14:52:18 -0400445 ('issuer_unique_id', OctetBitString, {'optional': True}),
446 ('extensions', Extensions, {'optional': True}),
447 ]
448
449
450class AttributeCertificateV2(Sequence):
wbond97cdd2f2016-07-14 11:58:41 -0400451 # Handle the situation where a V2 cert is encoded as V1
452 _bad_tag = 1
453
wbonde91513e2015-06-03 14:52:18 -0400454 _fields = [
455 ('ac_info', AttributeCertificateInfoV2),
456 ('signature_algorithm', SignedDigestAlgorithm),
457 ('signature', OctetBitString),
458 ]
459
460
461class OtherCertificateFormat(Sequence):
462 _fields = [
463 ('other_cert_format', ObjectIdentifier),
464 ('other_cert', Any),
465 ]
466
467
468class CertificateChoices(Choice):
469 _alternatives = [
470 ('certificate', Certificate),
wbondd62ed9a2017-09-15 07:13:52 -0400471 ('extended_certificate', ExtendedCertificate, {'implicit': 0}),
472 ('v1_attr_cert', AttributeCertificateV1, {'implicit': 1}),
473 ('v2_attr_cert', AttributeCertificateV2, {'implicit': 2}),
474 ('other', OtherCertificateFormat, {'implicit': 3}),
wbonde91513e2015-06-03 14:52:18 -0400475 ]
476
wbond97cdd2f2016-07-14 11:58:41 -0400477 def validate(self, class_, tag, contents):
478 """
479 Ensures that the class and tag specified exist as an alternative. This
480 custom version fixes parsing broken encodings there a V2 attribute
481 # certificate is encoded as a V1
482
483 :param class_:
484 The integer class_ from the encoded value header
485
486 :param tag:
487 The integer tag from the encoded value header
488
489 :param contents:
490 A byte string of the contents of the value - used when the object
491 is explicitly tagged
492
493 :raises:
494 ValueError - when value is not a valid alternative
495 """
496
497 super(CertificateChoices, self).validate(class_, tag, contents)
498 if self._choice == 2:
499 if AttCertVersion.load(Sequence.load(contents)[0].dump()).native == 'v2':
500 self._choice = 3
501
wbonde91513e2015-06-03 14:52:18 -0400502
503class CertificateSet(SetOf):
504 _child_spec = CertificateChoices
505
506
507class ContentInfo(Sequence):
508 _fields = [
509 ('content_type', ContentType),
wbondd62ed9a2017-09-15 07:13:52 -0400510 ('content', Any, {'explicit': 0, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400511 ]
512
513 _oid_pair = ('content_type', 'content')
514 _oid_specs = {}
515
516
wbondc57878c2016-07-14 06:02:01 -0400517class SetOfContentInfo(SetOf):
518 _child_spec = ContentInfo
519
520
wbonde91513e2015-06-03 14:52:18 -0400521class EncapsulatedContentInfo(Sequence):
522 _fields = [
523 ('content_type', ContentType),
wbondd62ed9a2017-09-15 07:13:52 -0400524 ('content', ParsableOctetString, {'explicit': 0, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400525 ]
526
527 _oid_pair = ('content_type', 'content')
528 _oid_specs = {}
529
530
531class IssuerAndSerialNumber(Sequence):
532 _fields = [
533 ('issuer', Name),
534 ('serial_number', Integer),
535 ]
536
537
538class SignerIdentifier(Choice):
539 _alternatives = [
540 ('issuer_and_serial_number', IssuerAndSerialNumber),
wbondd62ed9a2017-09-15 07:13:52 -0400541 ('subject_key_identifier', OctetString, {'implicit': 0}),
wbonde91513e2015-06-03 14:52:18 -0400542 ]
543
544
545class DigestAlgorithms(SetOf):
546 _child_spec = DigestAlgorithm
547
548
549class CertificateRevocationLists(SetOf):
550 _child_spec = CertificateList
551
552
553class SCVPReqRes(Sequence):
554 _fields = [
wbondd62ed9a2017-09-15 07:13:52 -0400555 ('request', ContentInfo, {'explicit': 0, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400556 ('response', ContentInfo),
557 ]
558
559
560class OtherRevInfoFormatId(ObjectIdentifier):
561 _map = {
562 '1.3.6.1.5.5.7.16.2': 'ocsp_response',
563 '1.3.6.1.5.5.7.16.4': 'scvp',
564 }
565
566
567class OtherRevocationInfoFormat(Sequence):
568 _fields = [
569 ('other_rev_info_format', OtherRevInfoFormatId),
570 ('other_rev_info', Any),
571 ]
572
573 _oid_pair = ('other_rev_info_format', 'other_rev_info')
574 _oid_specs = {
575 'ocsp_response': OCSPResponse,
576 'scvp': SCVPReqRes,
577 }
578
579
580class RevocationInfoChoice(Choice):
581 _alternatives = [
582 ('crl', CertificateList),
wbondd62ed9a2017-09-15 07:13:52 -0400583 ('other', OtherRevocationInfoFormat, {'implicit': 1}),
wbonde91513e2015-06-03 14:52:18 -0400584 ]
585
586
587class RevocationInfoChoices(SetOf):
588 _child_spec = RevocationInfoChoice
589
590
591class SignerInfo(Sequence):
592 _fields = [
593 ('version', CMSVersion),
594 ('sid', SignerIdentifier),
595 ('digest_algorithm', DigestAlgorithm),
wbondd62ed9a2017-09-15 07:13:52 -0400596 ('signed_attrs', CMSAttributes, {'implicit': 0, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400597 ('signature_algorithm', SignedDigestAlgorithm),
598 ('signature', OctetString),
wbondd62ed9a2017-09-15 07:13:52 -0400599 ('unsigned_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400600 ]
601
602
603class SignerInfos(SetOf):
604 _child_spec = SignerInfo
605
606
607class SignedData(Sequence):
608 _fields = [
609 ('version', CMSVersion),
610 ('digest_algorithms', DigestAlgorithms),
611 ('encap_content_info', None),
wbondd62ed9a2017-09-15 07:13:52 -0400612 ('certificates', CertificateSet, {'implicit': 0, 'optional': True}),
613 ('crls', RevocationInfoChoices, {'implicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400614 ('signer_infos', SignerInfos),
615 ]
616
617 def _encap_content_info_spec(self):
618 # If the encap_content_info is version v1, then this could be a PKCS#7
619 # structure, or a CMS structure. CMS wraps the encoded value in an
620 # Octet String tag.
621
622 # If the version is greater than 1, it is definite CMS
623 if self['version'].native != 'v1':
624 return EncapsulatedContentInfo
625
626 # Otherwise, the ContentInfo spec from PKCS#7 will be compatible with
627 # CMS v1 (which only allows Data, an Octet String) and PKCS#7, which
628 # allows Any
629 return ContentInfo
630
631 _spec_callbacks = {
632 'encap_content_info': _encap_content_info_spec
633 }
634
635
636class OriginatorInfo(Sequence):
637 _fields = [
wbondd62ed9a2017-09-15 07:13:52 -0400638 ('certs', CertificateSet, {'implicit': 0, 'optional': True}),
639 ('crls', RevocationInfoChoices, {'implicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400640 ]
641
642
643class RecipientIdentifier(Choice):
644 _alternatives = [
645 ('issuer_and_serial_number', IssuerAndSerialNumber),
wbondd62ed9a2017-09-15 07:13:52 -0400646 ('subject_key_identifier', OctetString, {'implicit': 0}),
wbonde91513e2015-06-03 14:52:18 -0400647 ]
648
649
650class KeyEncryptionAlgorithmId(ObjectIdentifier):
651 _map = {
eukaryotefda656d2015-11-02 10:04:37 -0800652 '1.2.840.113549.1.1.1': 'rsa',
Ludovic Watteauxb2c16e92018-06-30 14:11:22 +0200653 '1.2.840.113549.1.1.7': 'rsaes_oaep',
eukaryotefda656d2015-11-02 10:04:37 -0800654 '2.16.840.1.101.3.4.1.5': 'aes128_wrap',
655 '2.16.840.1.101.3.4.1.8': 'aes128_wrap_pad',
656 '2.16.840.1.101.3.4.1.25': 'aes192_wrap',
657 '2.16.840.1.101.3.4.1.28': 'aes192_wrap_pad',
658 '2.16.840.1.101.3.4.1.45': 'aes256_wrap',
659 '2.16.840.1.101.3.4.1.48': 'aes256_wrap_pad',
wbonde91513e2015-06-03 14:52:18 -0400660 }
661
662
wbond381a4da2016-08-30 11:39:54 -0400663class KeyEncryptionAlgorithm(_ForceNullParameters, Sequence):
wbonde91513e2015-06-03 14:52:18 -0400664 _fields = [
665 ('algorithm', KeyEncryptionAlgorithmId),
666 ('parameters', Any, {'optional': True}),
667 ]
668
669
670class KeyTransRecipientInfo(Sequence):
671 _fields = [
672 ('version', CMSVersion),
673 ('rid', RecipientIdentifier),
674 ('key_encryption_algorithm', KeyEncryptionAlgorithm),
675 ('encrypted_key', OctetString),
676 ]
677
678
679class OriginatorIdentifierOrKey(Choice):
680 _alternatives = [
681 ('issuer_and_serial_number', IssuerAndSerialNumber),
wbondd62ed9a2017-09-15 07:13:52 -0400682 ('subject_key_identifier', OctetString, {'implicit': 0}),
683 ('originator_key', PublicKeyInfo, {'implicit': 1}),
wbonde91513e2015-06-03 14:52:18 -0400684 ]
685
686
687class OtherKeyAttribute(Sequence):
688 _fields = [
689 ('key_attr_id', ObjectIdentifier),
690 ('key_attr', Any),
691 ]
692
693
694class RecipientKeyIdentifier(Sequence):
695 _fields = [
696 ('subject_key_identifier', OctetString),
697 ('date', GeneralizedTime, {'optional': True}),
698 ('other', OtherKeyAttribute, {'optional': True}),
699 ]
700
701
702class KeyAgreementRecipientIdentifier(Choice):
703 _alternatives = [
704 ('issuer_and_serial_number', IssuerAndSerialNumber),
wbondd62ed9a2017-09-15 07:13:52 -0400705 ('r_key_id', RecipientKeyIdentifier, {'implicit': 0}),
wbonde91513e2015-06-03 14:52:18 -0400706 ]
707
708
709class RecipientEncryptedKey(Sequence):
710 _fields = [
711 ('rid', KeyAgreementRecipientIdentifier),
712 ('encrypted_key', OctetString),
713 ]
714
715
716class RecipientEncryptedKeys(SequenceOf):
717 _child_spec = RecipientEncryptedKey
718
719
720class KeyAgreeRecipientInfo(Sequence):
721 _fields = [
722 ('version', CMSVersion),
wbondd62ed9a2017-09-15 07:13:52 -0400723 ('originator', OriginatorIdentifierOrKey, {'explicit': 0}),
724 ('ukm', OctetString, {'explicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400725 ('key_encryption_algorithm', KeyEncryptionAlgorithm),
726 ('recipient_encrypted_keys', RecipientEncryptedKeys),
727 ]
728
729
730class KEKIdentifier(Sequence):
731 _fields = [
732 ('key_identifier', OctetString),
733 ('date', GeneralizedTime, {'optional': True}),
734 ('other', OtherKeyAttribute, {'optional': True}),
735 ]
736
737
738class KEKRecipientInfo(Sequence):
739 _fields = [
740 ('version', CMSVersion),
741 ('kekid', KEKIdentifier),
742 ('key_encryption_algorithm', KeyEncryptionAlgorithm),
743 ('encrypted_key', OctetString),
744 ]
745
746
747class PasswordRecipientInfo(Sequence):
748 _fields = [
749 ('version', CMSVersion),
wbondd62ed9a2017-09-15 07:13:52 -0400750 ('key_derivation_algorithm', KdfAlgorithm, {'implicit': 0, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400751 ('key_encryption_algorithm', KeyEncryptionAlgorithm),
752 ('encrypted_key', OctetString),
753 ]
754
755
756class OtherRecipientInfo(Sequence):
757 _fields = [
758 ('ori_type', ObjectIdentifier),
759 ('ori_value', Any),
760 ]
761
762
763class RecipientInfo(Choice):
764 _alternatives = [
765 ('ktri', KeyTransRecipientInfo),
wbondd62ed9a2017-09-15 07:13:52 -0400766 ('kari', KeyAgreeRecipientInfo, {'implicit': 1}),
767 ('kekri', KEKRecipientInfo, {'implicit': 2}),
768 ('pwri', PasswordRecipientInfo, {'implicit': 3}),
769 ('ori', OtherRecipientInfo, {'implicit': 4}),
wbonde91513e2015-06-03 14:52:18 -0400770 ]
771
772
773class RecipientInfos(SetOf):
774 _child_spec = RecipientInfo
775
776
777class EncryptedContentInfo(Sequence):
778 _fields = [
779 ('content_type', ContentType),
wbond59af99d2015-06-15 16:19:04 -0400780 ('content_encryption_algorithm', EncryptionAlgorithm),
wbondd62ed9a2017-09-15 07:13:52 -0400781 ('encrypted_content', OctetString, {'implicit': 0, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400782 ]
783
784
785class EnvelopedData(Sequence):
786 _fields = [
787 ('version', CMSVersion),
wbondd62ed9a2017-09-15 07:13:52 -0400788 ('originator_info', OriginatorInfo, {'implicit': 0, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400789 ('recipient_infos', RecipientInfos),
790 ('encrypted_content_info', EncryptedContentInfo),
wbondd62ed9a2017-09-15 07:13:52 -0400791 ('unprotected_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400792 ]
793
794
795class SignedAndEnvelopedData(Sequence):
796 _fields = [
797 ('version', CMSVersion),
798 ('recipient_infos', RecipientInfos),
799 ('digest_algorithms', DigestAlgorithms),
800 ('encrypted_content_info', EncryptedContentInfo),
wbondd62ed9a2017-09-15 07:13:52 -0400801 ('certificates', CertificateSet, {'implicit': 0, 'optional': True}),
802 ('crls', CertificateRevocationLists, {'implicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400803 ('signer_infos', SignerInfos),
804 ]
805
806
807class DigestedData(Sequence):
808 _fields = [
809 ('version', CMSVersion),
810 ('digest_algorithm', DigestAlgorithm),
811 ('encap_content_info', None),
812 ('digest', OctetString),
813 ]
814
815 def _encap_content_info_spec(self):
816 # If the encap_content_info is version v1, then this could be a PKCS#7
817 # structure, or a CMS structure. CMS wraps the encoded value in an
818 # Octet String tag.
819
820 # If the version is greater than 1, it is definite CMS
821 if self['version'].native != 'v1':
822 return EncapsulatedContentInfo
823
824 # Otherwise, the ContentInfo spec from PKCS#7 will be compatible with
825 # CMS v1 (which only allows Data, an Octet String) and PKCS#7, which
826 # allows Any
827 return ContentInfo
828
829 _spec_callbacks = {
830 'encap_content_info': _encap_content_info_spec
831 }
832
833
834class EncryptedData(Sequence):
835 _fields = [
836 ('version', CMSVersion),
837 ('encrypted_content_info', EncryptedContentInfo),
wbondd62ed9a2017-09-15 07:13:52 -0400838 ('unprotected_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400839 ]
840
841
842class AuthenticatedData(Sequence):
843 _fields = [
844 ('version', CMSVersion),
wbondd62ed9a2017-09-15 07:13:52 -0400845 ('originator_info', OriginatorInfo, {'implicit': 0, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400846 ('recipient_infos', RecipientInfos),
847 ('mac_algorithm', HmacAlgorithm),
wbondd62ed9a2017-09-15 07:13:52 -0400848 ('digest_algorithm', DigestAlgorithm, {'implicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400849 # This does not require the _spec_callbacks approach of SignedData and
850 # DigestedData since AuthenticatedData was not part of PKCS#7
851 ('encap_content_info', EncapsulatedContentInfo),
wbondd62ed9a2017-09-15 07:13:52 -0400852 ('auth_attrs', CMSAttributes, {'implicit': 2, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400853 ('mac', OctetString),
wbondd62ed9a2017-09-15 07:13:52 -0400854 ('unauth_attrs', CMSAttributes, {'implicit': 3, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400855 ]
856
857
858class AuthEnvelopedData(Sequence):
859 _fields = [
860 ('version', CMSVersion),
wbondd62ed9a2017-09-15 07:13:52 -0400861 ('originator_info', OriginatorInfo, {'implicit': 0, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400862 ('recipient_infos', RecipientInfos),
863 ('auth_encrypted_content_info', EncryptedContentInfo),
wbondd62ed9a2017-09-15 07:13:52 -0400864 ('auth_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400865 ('mac', OctetString),
wbondd62ed9a2017-09-15 07:13:52 -0400866 ('unauth_attrs', CMSAttributes, {'implicit': 2, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400867 ]
868
869
870class CompressionAlgorithmId(ObjectIdentifier):
871 _map = {
872 '1.2.840.113549.1.9.16.3.8': 'zlib',
873 }
874
875
876class CompressionAlgorithm(Sequence):
877 _fields = [
878 ('algorithm', CompressionAlgorithmId),
wbond40a32f02015-06-17 22:29:56 -0400879 ('parameters', Any, {'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400880 ]
881
882
883class CompressedData(Sequence):
884 _fields = [
885 ('version', CMSVersion),
886 ('compression_algorithm', CompressionAlgorithm),
887 ('encap_content_info', EncapsulatedContentInfo),
888 ]
889
890 _decompressed = None
891
892 @property
893 def decompressed(self):
894 if self._decompressed is None:
895 if zlib is None:
896 raise SystemError('The zlib module is not available')
897 self._decompressed = zlib.decompress(self['encap_content_info']['content'].native)
898 return self._decompressed
899
900
wbonda26664f2015-10-07 11:57:35 -0400901ContentInfo._oid_specs = {
wbonde91513e2015-06-03 14:52:18 -0400902 'data': OctetString,
903 'signed_data': SignedData,
904 'enveloped_data': EnvelopedData,
905 'signed_and_enveloped_data': SignedAndEnvelopedData,
906 'digested_data': DigestedData,
907 'encrypted_data': EncryptedData,
908 'authenticated_data': AuthenticatedData,
909 'compressed_data': CompressedData,
910 'authenticated_enveloped_data': AuthEnvelopedData,
911}
912
913
wbonda26664f2015-10-07 11:57:35 -0400914EncapsulatedContentInfo._oid_specs = {
wbonde91513e2015-06-03 14:52:18 -0400915 'signed_data': SignedData,
916 'enveloped_data': EnvelopedData,
917 'signed_and_enveloped_data': SignedAndEnvelopedData,
918 'digested_data': DigestedData,
919 'encrypted_data': EncryptedData,
920 'authenticated_data': AuthenticatedData,
921 'compressed_data': CompressedData,
922 'authenticated_enveloped_data': AuthEnvelopedData,
923}
924
925
wbonda26664f2015-10-07 11:57:35 -0400926CMSAttribute._oid_specs = {
wbonde91513e2015-06-03 14:52:18 -0400927 'content_type': SetOfContentType,
928 'message_digest': SetOfOctetString,
929 'signing_time': SetOfTime,
930 'counter_signature': SignerInfos,
wbondc57878c2016-07-14 06:02:01 -0400931 'signature_time_stamp_token': SetOfContentInfo,
Anthony Albaad0e19e2017-05-16 22:21:18 +0800932 'cms_algorithm_protection': SetOfCMSAlgorithmProtection,
wbonde91513e2015-06-03 14:52:18 -0400933}