blob: 76143ac6d48cba7596bbec8f7676a730c2697948 [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,
wbond850c0c02019-08-01 22:27:04 -040035 RSAESOAEPParams,
wbond59af99d2015-06-15 16:19:04 -040036 SignedDigestAlgorithm,
wbonde91513e2015-06-03 14:52:18 -040037)
38from .core import (
39 Any,
wbond6a8cf2a2016-07-14 07:17:44 -040040 BitString,
wbonde91513e2015-06-03 14:52:18 -040041 Choice,
42 Enumerated,
43 GeneralizedTime,
44 Integer,
45 ObjectIdentifier,
46 OctetBitString,
47 OctetString,
wbonde5a1c6e2015-08-03 07:42:28 -040048 ParsableOctetString,
wbonde91513e2015-06-03 14:52:18 -040049 Sequence,
50 SequenceOf,
51 SetOf,
52 UTCTime,
wbond6a8cf2a2016-07-14 07:17:44 -040053 UTF8String,
wbonde91513e2015-06-03 14:52:18 -040054)
55from .crl import CertificateList
56from .keys import PublicKeyInfo
57from .ocsp import OCSPResponse
wbond6a8cf2a2016-07-14 07:17:44 -040058from .x509 import Attributes, Certificate, Extensions, GeneralName, GeneralNames, Name
wbonde91513e2015-06-03 14:52:18 -040059
60
wbonde91513e2015-06-03 14:52:18 -040061# 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
wbonda26664f2015-10-07 11:57:35 -040071
wbonde91513e2015-06-03 14:52:18 -040072class 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',
Markus Kötterf003c672019-11-19 14:47:57 +0100103 '1.2.840.113549.1.9.16.2.11': 'encrypt_key_pref',
wbondc57878c2016-07-14 06:02:01 -0400104 # https://tools.ietf.org/html/rfc3161#page-20
105 '1.2.840.113549.1.9.16.2.14': 'signature_time_stamp_token',
Anthony Albaad0e19e2017-05-16 22:21:18 +0800106 # https://tools.ietf.org/html/rfc6211#page-5
107 '1.2.840.113549.1.9.52': 'cms_algorithm_protection',
wbond74d66a92019-08-01 23:26:57 -0400108 # https://docs.microsoft.com/en-us/previous-versions/hh968145(v%3Dvs.85)
109 '1.3.6.1.4.1.311.2.4.1': 'microsoft_nested_signature',
110 # Some places refer to this as SPC_RFC3161_OBJID, others szOID_RFC3161_counterSign.
111 # https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-crypt_algorithm_identifier
112 # refers to szOID_RFC3161_counterSign as "1.2.840.113549.1.9.16.1.4",
113 # but that OID is also called szOID_TIMESTAMP_TOKEN. Because of there being
114 # no canonical source for this OID, we give it our own name
115 '1.3.6.1.4.1.311.3.3.1': 'microsoft_time_stamp_token',
wbonde91513e2015-06-03 14:52:18 -0400116 }
117
118
119class Time(Choice):
120 _alternatives = [
121 ('utc_time', UTCTime),
122 ('generalized_time', GeneralizedTime),
123 ]
124
125
126class ContentType(ObjectIdentifier):
127 _map = {
128 '1.2.840.113549.1.7.1': 'data',
129 '1.2.840.113549.1.7.2': 'signed_data',
130 '1.2.840.113549.1.7.3': 'enveloped_data',
131 '1.2.840.113549.1.7.4': 'signed_and_enveloped_data',
132 '1.2.840.113549.1.7.5': 'digested_data',
133 '1.2.840.113549.1.7.6': 'encrypted_data',
134 '1.2.840.113549.1.9.16.1.2': 'authenticated_data',
135 '1.2.840.113549.1.9.16.1.9': 'compressed_data',
136 '1.2.840.113549.1.9.16.1.23': 'authenticated_enveloped_data',
137 }
138
139
Anthony Albaad0e19e2017-05-16 22:21:18 +0800140class CMSAlgorithmProtection(Sequence):
141 _fields = [
142 ('digest_algorithm', DigestAlgorithm),
wbondd62ed9a2017-09-15 07:13:52 -0400143 ('signature_algorithm', SignedDigestAlgorithm, {'implicit': 1, 'optional': True}),
144 ('mac_algorithm', HmacAlgorithm, {'implicit': 2, 'optional': True}),
Anthony Albaad0e19e2017-05-16 22:21:18 +0800145 ]
146
147
wbonde91513e2015-06-03 14:52:18 -0400148class SetOfContentType(SetOf):
149 _child_spec = ContentType
150
151
152class SetOfOctetString(SetOf):
153 _child_spec = OctetString
154
155
156class SetOfTime(SetOf):
157 _child_spec = Time
158
159
wbonda07a51a2015-12-03 01:09:07 -0500160class SetOfAny(SetOf):
161 _child_spec = Any
162
163
Anthony Albaad0e19e2017-05-16 22:21:18 +0800164class SetOfCMSAlgorithmProtection(SetOf):
165 _child_spec = CMSAlgorithmProtection
166
167
wbonde91513e2015-06-03 14:52:18 -0400168class CMSAttribute(Sequence):
169 _fields = [
170 ('type', CMSAttributeType),
wbonda07a51a2015-12-03 01:09:07 -0500171 ('values', None),
wbonde91513e2015-06-03 14:52:18 -0400172 ]
173
wbonde91513e2015-06-03 14:52:18 -0400174 _oid_specs = {}
175
wbonda07a51a2015-12-03 01:09:07 -0500176 def _values_spec(self):
177 return self._oid_specs.get(self['type'].native, SetOfAny)
178
179 _spec_callbacks = {
180 'values': _values_spec
181 }
182
wbonde91513e2015-06-03 14:52:18 -0400183
wbondf87d4852015-12-03 00:02:35 -0500184class CMSAttributes(SetOf):
wbonde91513e2015-06-03 14:52:18 -0400185 _child_spec = CMSAttribute
186
187
188class IssuerSerial(Sequence):
189 _fields = [
190 ('issuer', GeneralNames),
191 ('serial', Integer),
192 ('issuer_uid', OctetBitString, {'optional': True}),
193 ]
194
195
196class AttCertVersion(Integer):
197 _map = {
198 0: 'v1',
199 1: 'v2',
200 }
201
202
203class AttCertSubject(Choice):
204 _alternatives = [
wbondd62ed9a2017-09-15 07:13:52 -0400205 ('base_certificate_id', IssuerSerial, {'explicit': 0}),
206 ('subject_name', GeneralNames, {'explicit': 1}),
wbonde91513e2015-06-03 14:52:18 -0400207 ]
208
209
210class AttCertValidityPeriod(Sequence):
211 _fields = [
212 ('not_before_time', GeneralizedTime),
213 ('not_after_time', GeneralizedTime),
214 ]
215
216
217class AttributeCertificateInfoV1(Sequence):
218 _fields = [
wbondb8dafce2015-08-24 09:28:01 -0400219 ('version', AttCertVersion, {'default': 'v1'}),
wbonde91513e2015-06-03 14:52:18 -0400220 ('subject', AttCertSubject),
221 ('issuer', GeneralNames),
222 ('signature', SignedDigestAlgorithm),
223 ('serial_number', Integer),
224 ('att_cert_validity_period', AttCertValidityPeriod),
225 ('attributes', Attributes),
226 ('issuer_unique_id', OctetBitString, {'optional': True}),
227 ('extensions', Extensions, {'optional': True}),
228 ]
229
230
231class AttributeCertificateV1(Sequence):
232 _fields = [
233 ('ac_info', AttributeCertificateInfoV1),
234 ('signature_algorithm', SignedDigestAlgorithm),
235 ('signature', OctetBitString),
236 ]
237
238
239class DigestedObjectType(Enumerated):
240 _map = {
241 0: 'public_key',
242 1: 'public_key_cert',
243 2: 'other_objy_types',
244 }
245
246
247class ObjectDigestInfo(Sequence):
248 _fields = [
249 ('digested_object_type', DigestedObjectType),
250 ('other_object_type_id', ObjectIdentifier, {'optional': True}),
251 ('digest_algorithm', DigestAlgorithm),
252 ('object_digest', OctetBitString),
253 ]
254
255
256class Holder(Sequence):
257 _fields = [
wbondd62ed9a2017-09-15 07:13:52 -0400258 ('base_certificate_id', IssuerSerial, {'implicit': 0, 'optional': True}),
259 ('entity_name', GeneralNames, {'implicit': 1, 'optional': True}),
260 ('object_digest_info', ObjectDigestInfo, {'implicit': 2, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400261 ]
262
263
264class V2Form(Sequence):
265 _fields = [
266 ('issuer_name', GeneralNames, {'optional': True}),
wbondd62ed9a2017-09-15 07:13:52 -0400267 ('base_certificate_id', IssuerSerial, {'explicit': 0, 'optional': True}),
268 ('object_digest_info', ObjectDigestInfo, {'explicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400269 ]
270
271
272class AttCertIssuer(Choice):
273 _alternatives = [
274 ('v1_form', GeneralNames),
wbondd62ed9a2017-09-15 07:13:52 -0400275 ('v2_form', V2Form, {'explicit': 0}),
wbonde91513e2015-06-03 14:52:18 -0400276 ]
277
278
wbond6a8cf2a2016-07-14 07:17:44 -0400279class IetfAttrValue(Choice):
280 _alternatives = [
281 ('octets', OctetString),
282 ('oid', ObjectIdentifier),
283 ('string', UTF8String),
284 ]
285
286
287class IetfAttrValues(SequenceOf):
288 _child_spec = IetfAttrValue
289
290
291class IetfAttrSyntax(Sequence):
292 _fields = [
wbondd62ed9a2017-09-15 07:13:52 -0400293 ('policy_authority', GeneralNames, {'implicit': 0, 'optional': True}),
wbond6a8cf2a2016-07-14 07:17:44 -0400294 ('values', IetfAttrValues),
295 ]
296
297
298class SetOfIetfAttrSyntax(SetOf):
299 _child_spec = IetfAttrSyntax
300
301
302class SvceAuthInfo(Sequence):
303 _fields = [
304 ('service', GeneralName),
305 ('ident', GeneralName),
306 ('auth_info', OctetString, {'optional': True}),
307 ]
308
309
310class SetOfSvceAuthInfo(SetOf):
311 _child_spec = SvceAuthInfo
312
313
314class RoleSyntax(Sequence):
315 _fields = [
wbondd62ed9a2017-09-15 07:13:52 -0400316 ('role_authority', GeneralNames, {'implicit': 0, 'optional': True}),
317 ('role_name', GeneralName, {'implicit': 1}),
wbond6a8cf2a2016-07-14 07:17:44 -0400318 ]
319
320
321class SetOfRoleSyntax(SetOf):
322 _child_spec = RoleSyntax
323
324
325class ClassList(BitString):
326 _map = {
327 0: 'unmarked',
328 1: 'unclassified',
329 2: 'restricted',
330 3: 'confidential',
331 4: 'secret',
332 5: 'top_secret',
333 }
334
335
336class SecurityCategory(Sequence):
337 _fields = [
wbondd62ed9a2017-09-15 07:13:52 -0400338 ('type', ObjectIdentifier, {'implicit': 0}),
339 ('value', Any, {'implicit': 1}),
wbond6a8cf2a2016-07-14 07:17:44 -0400340 ]
341
342
343class SetOfSecurityCategory(SetOf):
344 _child_spec = SecurityCategory
345
346
347class Clearance(Sequence):
348 _fields = [
wbondd62ed9a2017-09-15 07:13:52 -0400349 ('policy_id', ObjectIdentifier, {'implicit': 0}),
350 ('class_list', ClassList, {'implicit': 1, 'default': 'unclassified'}),
351 ('security_categories', SetOfSecurityCategory, {'implicit': 2, 'optional': True}),
wbond6a8cf2a2016-07-14 07:17:44 -0400352 ]
353
354
355class SetOfClearance(SetOf):
356 _child_spec = Clearance
357
358
359class BigTime(Sequence):
360 _fields = [
361 ('major', Integer),
362 ('fractional_seconds', Integer),
363 ('sign', Integer, {'optional': True}),
364 ]
365
366
367class LeapData(Sequence):
368 _fields = [
369 ('leap_time', BigTime),
370 ('action', Integer),
371 ]
372
373
374class SetOfLeapData(SetOf):
375 _child_spec = LeapData
376
377
378class TimingMetrics(Sequence):
379 _fields = [
380 ('ntp_time', BigTime),
381 ('offset', BigTime),
382 ('delay', BigTime),
383 ('expiration', BigTime),
384 ('leap_event', SetOfLeapData, {'optional': True}),
385 ]
386
387
388class SetOfTimingMetrics(SetOf):
389 _child_spec = TimingMetrics
390
391
392class TimingPolicy(Sequence):
393 _fields = [
394 ('policy_id', SequenceOf, {'spec': ObjectIdentifier}),
wbondd62ed9a2017-09-15 07:13:52 -0400395 ('max_offset', BigTime, {'explicit': 0, 'optional': True}),
396 ('max_delay', BigTime, {'explicit': 1, 'optional': True}),
wbond6a8cf2a2016-07-14 07:17:44 -0400397 ]
398
399
400class SetOfTimingPolicy(SetOf):
401 _child_spec = TimingPolicy
402
403
404class AttCertAttributeType(ObjectIdentifier):
405 _map = {
406 '1.3.6.1.5.5.7.10.1': 'authentication_info',
407 '1.3.6.1.5.5.7.10.2': 'access_identity',
408 '1.3.6.1.5.5.7.10.3': 'charging_identity',
409 '1.3.6.1.5.5.7.10.4': 'group',
410 '2.5.4.72': 'role',
411 '2.5.4.55': 'clearance',
412 '1.3.6.1.4.1.601.10.4.1': 'timing_metrics',
413 '1.3.6.1.4.1.601.10.4.2': 'timing_policy',
414 }
415
416
417class AttCertAttribute(Sequence):
418 _fields = [
419 ('type', AttCertAttributeType),
420 ('values', None),
421 ]
422
423 _oid_specs = {
424 'authentication_info': SetOfSvceAuthInfo,
425 'access_identity': SetOfSvceAuthInfo,
426 'charging_identity': SetOfIetfAttrSyntax,
427 'group': SetOfIetfAttrSyntax,
428 'role': SetOfRoleSyntax,
429 'clearance': SetOfClearance,
430 'timing_metrics': SetOfTimingMetrics,
431 'timing_policy': SetOfTimingPolicy,
432 }
433
434 def _values_spec(self):
wbond7b1cd4b2017-02-10 05:11:14 -0500435 return self._oid_specs.get(self['type'].native, SetOfAny)
wbond6a8cf2a2016-07-14 07:17:44 -0400436
437 _spec_callbacks = {
438 'values': _values_spec
439 }
440
441
442class AttCertAttributes(SequenceOf):
443 _child_spec = AttCertAttribute
444
445
wbonde91513e2015-06-03 14:52:18 -0400446class AttributeCertificateInfoV2(Sequence):
447 _fields = [
448 ('version', AttCertVersion),
449 ('holder', Holder),
450 ('issuer', AttCertIssuer),
451 ('signature', SignedDigestAlgorithm),
452 ('serial_number', Integer),
453 ('att_cert_validity_period', AttCertValidityPeriod),
wbond6a8cf2a2016-07-14 07:17:44 -0400454 ('attributes', AttCertAttributes),
wbonde91513e2015-06-03 14:52:18 -0400455 ('issuer_unique_id', OctetBitString, {'optional': True}),
456 ('extensions', Extensions, {'optional': True}),
457 ]
458
459
460class AttributeCertificateV2(Sequence):
wbond97cdd2f2016-07-14 11:58:41 -0400461 # Handle the situation where a V2 cert is encoded as V1
462 _bad_tag = 1
463
wbonde91513e2015-06-03 14:52:18 -0400464 _fields = [
465 ('ac_info', AttributeCertificateInfoV2),
466 ('signature_algorithm', SignedDigestAlgorithm),
467 ('signature', OctetBitString),
468 ]
469
470
471class OtherCertificateFormat(Sequence):
472 _fields = [
473 ('other_cert_format', ObjectIdentifier),
474 ('other_cert', Any),
475 ]
476
477
478class CertificateChoices(Choice):
479 _alternatives = [
480 ('certificate', Certificate),
wbondd62ed9a2017-09-15 07:13:52 -0400481 ('extended_certificate', ExtendedCertificate, {'implicit': 0}),
482 ('v1_attr_cert', AttributeCertificateV1, {'implicit': 1}),
483 ('v2_attr_cert', AttributeCertificateV2, {'implicit': 2}),
484 ('other', OtherCertificateFormat, {'implicit': 3}),
wbonde91513e2015-06-03 14:52:18 -0400485 ]
486
wbond97cdd2f2016-07-14 11:58:41 -0400487 def validate(self, class_, tag, contents):
488 """
489 Ensures that the class and tag specified exist as an alternative. This
490 custom version fixes parsing broken encodings there a V2 attribute
491 # certificate is encoded as a V1
492
493 :param class_:
494 The integer class_ from the encoded value header
495
496 :param tag:
497 The integer tag from the encoded value header
498
499 :param contents:
500 A byte string of the contents of the value - used when the object
501 is explicitly tagged
502
503 :raises:
504 ValueError - when value is not a valid alternative
505 """
506
507 super(CertificateChoices, self).validate(class_, tag, contents)
508 if self._choice == 2:
509 if AttCertVersion.load(Sequence.load(contents)[0].dump()).native == 'v2':
510 self._choice = 3
511
wbonde91513e2015-06-03 14:52:18 -0400512
513class CertificateSet(SetOf):
514 _child_spec = CertificateChoices
515
516
517class ContentInfo(Sequence):
518 _fields = [
519 ('content_type', ContentType),
wbondd62ed9a2017-09-15 07:13:52 -0400520 ('content', Any, {'explicit': 0, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400521 ]
522
523 _oid_pair = ('content_type', 'content')
524 _oid_specs = {}
525
526
wbondc57878c2016-07-14 06:02:01 -0400527class SetOfContentInfo(SetOf):
528 _child_spec = ContentInfo
529
530
wbonde91513e2015-06-03 14:52:18 -0400531class EncapsulatedContentInfo(Sequence):
532 _fields = [
533 ('content_type', ContentType),
wbondd62ed9a2017-09-15 07:13:52 -0400534 ('content', ParsableOctetString, {'explicit': 0, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400535 ]
536
537 _oid_pair = ('content_type', 'content')
538 _oid_specs = {}
539
540
541class IssuerAndSerialNumber(Sequence):
542 _fields = [
543 ('issuer', Name),
544 ('serial_number', Integer),
545 ]
546
547
548class SignerIdentifier(Choice):
549 _alternatives = [
550 ('issuer_and_serial_number', IssuerAndSerialNumber),
wbondd62ed9a2017-09-15 07:13:52 -0400551 ('subject_key_identifier', OctetString, {'implicit': 0}),
wbonde91513e2015-06-03 14:52:18 -0400552 ]
553
554
555class DigestAlgorithms(SetOf):
556 _child_spec = DigestAlgorithm
557
558
559class CertificateRevocationLists(SetOf):
560 _child_spec = CertificateList
561
562
563class SCVPReqRes(Sequence):
564 _fields = [
wbondd62ed9a2017-09-15 07:13:52 -0400565 ('request', ContentInfo, {'explicit': 0, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400566 ('response', ContentInfo),
567 ]
568
569
570class OtherRevInfoFormatId(ObjectIdentifier):
571 _map = {
572 '1.3.6.1.5.5.7.16.2': 'ocsp_response',
573 '1.3.6.1.5.5.7.16.4': 'scvp',
574 }
575
576
577class OtherRevocationInfoFormat(Sequence):
578 _fields = [
579 ('other_rev_info_format', OtherRevInfoFormatId),
580 ('other_rev_info', Any),
581 ]
582
583 _oid_pair = ('other_rev_info_format', 'other_rev_info')
584 _oid_specs = {
585 'ocsp_response': OCSPResponse,
586 'scvp': SCVPReqRes,
587 }
588
589
590class RevocationInfoChoice(Choice):
591 _alternatives = [
592 ('crl', CertificateList),
wbondd62ed9a2017-09-15 07:13:52 -0400593 ('other', OtherRevocationInfoFormat, {'implicit': 1}),
wbonde91513e2015-06-03 14:52:18 -0400594 ]
595
596
597class RevocationInfoChoices(SetOf):
598 _child_spec = RevocationInfoChoice
599
600
601class SignerInfo(Sequence):
602 _fields = [
603 ('version', CMSVersion),
604 ('sid', SignerIdentifier),
605 ('digest_algorithm', DigestAlgorithm),
wbondd62ed9a2017-09-15 07:13:52 -0400606 ('signed_attrs', CMSAttributes, {'implicit': 0, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400607 ('signature_algorithm', SignedDigestAlgorithm),
608 ('signature', OctetString),
wbondd62ed9a2017-09-15 07:13:52 -0400609 ('unsigned_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400610 ]
611
612
613class SignerInfos(SetOf):
614 _child_spec = SignerInfo
615
616
617class SignedData(Sequence):
618 _fields = [
619 ('version', CMSVersion),
620 ('digest_algorithms', DigestAlgorithms),
621 ('encap_content_info', None),
wbondd62ed9a2017-09-15 07:13:52 -0400622 ('certificates', CertificateSet, {'implicit': 0, 'optional': True}),
623 ('crls', RevocationInfoChoices, {'implicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400624 ('signer_infos', SignerInfos),
625 ]
626
627 def _encap_content_info_spec(self):
628 # If the encap_content_info is version v1, then this could be a PKCS#7
629 # structure, or a CMS structure. CMS wraps the encoded value in an
630 # Octet String tag.
631
632 # If the version is greater than 1, it is definite CMS
633 if self['version'].native != 'v1':
634 return EncapsulatedContentInfo
635
636 # Otherwise, the ContentInfo spec from PKCS#7 will be compatible with
637 # CMS v1 (which only allows Data, an Octet String) and PKCS#7, which
638 # allows Any
639 return ContentInfo
640
641 _spec_callbacks = {
642 'encap_content_info': _encap_content_info_spec
643 }
644
645
646class OriginatorInfo(Sequence):
647 _fields = [
wbondd62ed9a2017-09-15 07:13:52 -0400648 ('certs', CertificateSet, {'implicit': 0, 'optional': True}),
649 ('crls', RevocationInfoChoices, {'implicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400650 ]
651
652
653class RecipientIdentifier(Choice):
654 _alternatives = [
655 ('issuer_and_serial_number', IssuerAndSerialNumber),
wbondd62ed9a2017-09-15 07:13:52 -0400656 ('subject_key_identifier', OctetString, {'implicit': 0}),
wbonde91513e2015-06-03 14:52:18 -0400657 ]
658
659
660class KeyEncryptionAlgorithmId(ObjectIdentifier):
661 _map = {
wbond7ed8ee02019-08-01 22:14:53 -0400662 '1.2.840.113549.1.1.1': 'rsaes_pkcs1v15',
Ludovic Watteauxb2c16e92018-06-30 14:11:22 +0200663 '1.2.840.113549.1.1.7': 'rsaes_oaep',
eukaryotefda656d2015-11-02 10:04:37 -0800664 '2.16.840.1.101.3.4.1.5': 'aes128_wrap',
665 '2.16.840.1.101.3.4.1.8': 'aes128_wrap_pad',
666 '2.16.840.1.101.3.4.1.25': 'aes192_wrap',
667 '2.16.840.1.101.3.4.1.28': 'aes192_wrap_pad',
668 '2.16.840.1.101.3.4.1.45': 'aes256_wrap',
669 '2.16.840.1.101.3.4.1.48': 'aes256_wrap_pad',
wbonde91513e2015-06-03 14:52:18 -0400670 }
671
wbond7ed8ee02019-08-01 22:14:53 -0400672 _reverse_map = {
673 'rsa': '1.2.840.113549.1.1.1',
674 'rsaes_pkcs1v15': '1.2.840.113549.1.1.1',
675 'rsaes_oaep': '1.2.840.113549.1.1.7',
676 'aes128_wrap': '2.16.840.1.101.3.4.1.5',
677 'aes128_wrap_pad': '2.16.840.1.101.3.4.1.8',
678 'aes192_wrap': '2.16.840.1.101.3.4.1.25',
679 'aes192_wrap_pad': '2.16.840.1.101.3.4.1.28',
680 'aes256_wrap': '2.16.840.1.101.3.4.1.45',
681 'aes256_wrap_pad': '2.16.840.1.101.3.4.1.48',
682 }
683
wbonde91513e2015-06-03 14:52:18 -0400684
wbond381a4da2016-08-30 11:39:54 -0400685class KeyEncryptionAlgorithm(_ForceNullParameters, Sequence):
wbonde91513e2015-06-03 14:52:18 -0400686 _fields = [
687 ('algorithm', KeyEncryptionAlgorithmId),
688 ('parameters', Any, {'optional': True}),
689 ]
690
wbond850c0c02019-08-01 22:27:04 -0400691 _oid_pair = ('algorithm', 'parameters')
692 _oid_specs = {
693 'rsaes_oaep': RSAESOAEPParams,
694 }
695
wbonde91513e2015-06-03 14:52:18 -0400696
697class KeyTransRecipientInfo(Sequence):
698 _fields = [
699 ('version', CMSVersion),
700 ('rid', RecipientIdentifier),
701 ('key_encryption_algorithm', KeyEncryptionAlgorithm),
702 ('encrypted_key', OctetString),
703 ]
704
705
706class OriginatorIdentifierOrKey(Choice):
707 _alternatives = [
708 ('issuer_and_serial_number', IssuerAndSerialNumber),
wbondd62ed9a2017-09-15 07:13:52 -0400709 ('subject_key_identifier', OctetString, {'implicit': 0}),
710 ('originator_key', PublicKeyInfo, {'implicit': 1}),
wbonde91513e2015-06-03 14:52:18 -0400711 ]
712
713
714class OtherKeyAttribute(Sequence):
715 _fields = [
716 ('key_attr_id', ObjectIdentifier),
717 ('key_attr', Any),
718 ]
719
720
721class RecipientKeyIdentifier(Sequence):
722 _fields = [
723 ('subject_key_identifier', OctetString),
724 ('date', GeneralizedTime, {'optional': True}),
725 ('other', OtherKeyAttribute, {'optional': True}),
726 ]
727
728
729class KeyAgreementRecipientIdentifier(Choice):
730 _alternatives = [
731 ('issuer_and_serial_number', IssuerAndSerialNumber),
wbondd62ed9a2017-09-15 07:13:52 -0400732 ('r_key_id', RecipientKeyIdentifier, {'implicit': 0}),
wbonde91513e2015-06-03 14:52:18 -0400733 ]
734
735
736class RecipientEncryptedKey(Sequence):
737 _fields = [
738 ('rid', KeyAgreementRecipientIdentifier),
739 ('encrypted_key', OctetString),
740 ]
741
742
743class RecipientEncryptedKeys(SequenceOf):
744 _child_spec = RecipientEncryptedKey
745
746
747class KeyAgreeRecipientInfo(Sequence):
748 _fields = [
749 ('version', CMSVersion),
wbondd62ed9a2017-09-15 07:13:52 -0400750 ('originator', OriginatorIdentifierOrKey, {'explicit': 0}),
751 ('ukm', OctetString, {'explicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400752 ('key_encryption_algorithm', KeyEncryptionAlgorithm),
753 ('recipient_encrypted_keys', RecipientEncryptedKeys),
754 ]
755
756
757class KEKIdentifier(Sequence):
758 _fields = [
759 ('key_identifier', OctetString),
760 ('date', GeneralizedTime, {'optional': True}),
761 ('other', OtherKeyAttribute, {'optional': True}),
762 ]
763
764
765class KEKRecipientInfo(Sequence):
766 _fields = [
767 ('version', CMSVersion),
768 ('kekid', KEKIdentifier),
769 ('key_encryption_algorithm', KeyEncryptionAlgorithm),
770 ('encrypted_key', OctetString),
771 ]
772
773
774class PasswordRecipientInfo(Sequence):
775 _fields = [
776 ('version', CMSVersion),
wbondd62ed9a2017-09-15 07:13:52 -0400777 ('key_derivation_algorithm', KdfAlgorithm, {'implicit': 0, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400778 ('key_encryption_algorithm', KeyEncryptionAlgorithm),
779 ('encrypted_key', OctetString),
780 ]
781
782
783class OtherRecipientInfo(Sequence):
784 _fields = [
785 ('ori_type', ObjectIdentifier),
786 ('ori_value', Any),
787 ]
788
789
790class RecipientInfo(Choice):
791 _alternatives = [
792 ('ktri', KeyTransRecipientInfo),
wbondd62ed9a2017-09-15 07:13:52 -0400793 ('kari', KeyAgreeRecipientInfo, {'implicit': 1}),
794 ('kekri', KEKRecipientInfo, {'implicit': 2}),
795 ('pwri', PasswordRecipientInfo, {'implicit': 3}),
796 ('ori', OtherRecipientInfo, {'implicit': 4}),
wbonde91513e2015-06-03 14:52:18 -0400797 ]
798
799
800class RecipientInfos(SetOf):
801 _child_spec = RecipientInfo
802
803
804class EncryptedContentInfo(Sequence):
805 _fields = [
806 ('content_type', ContentType),
wbond59af99d2015-06-15 16:19:04 -0400807 ('content_encryption_algorithm', EncryptionAlgorithm),
wbondd62ed9a2017-09-15 07:13:52 -0400808 ('encrypted_content', OctetString, {'implicit': 0, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400809 ]
810
811
812class EnvelopedData(Sequence):
813 _fields = [
814 ('version', CMSVersion),
wbondd62ed9a2017-09-15 07:13:52 -0400815 ('originator_info', OriginatorInfo, {'implicit': 0, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400816 ('recipient_infos', RecipientInfos),
817 ('encrypted_content_info', EncryptedContentInfo),
wbondd62ed9a2017-09-15 07:13:52 -0400818 ('unprotected_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400819 ]
820
821
822class SignedAndEnvelopedData(Sequence):
823 _fields = [
824 ('version', CMSVersion),
825 ('recipient_infos', RecipientInfos),
826 ('digest_algorithms', DigestAlgorithms),
827 ('encrypted_content_info', EncryptedContentInfo),
wbondd62ed9a2017-09-15 07:13:52 -0400828 ('certificates', CertificateSet, {'implicit': 0, 'optional': True}),
829 ('crls', CertificateRevocationLists, {'implicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400830 ('signer_infos', SignerInfos),
831 ]
832
833
834class DigestedData(Sequence):
835 _fields = [
836 ('version', CMSVersion),
837 ('digest_algorithm', DigestAlgorithm),
838 ('encap_content_info', None),
839 ('digest', OctetString),
840 ]
841
842 def _encap_content_info_spec(self):
843 # If the encap_content_info is version v1, then this could be a PKCS#7
844 # structure, or a CMS structure. CMS wraps the encoded value in an
845 # Octet String tag.
846
847 # If the version is greater than 1, it is definite CMS
848 if self['version'].native != 'v1':
849 return EncapsulatedContentInfo
850
851 # Otherwise, the ContentInfo spec from PKCS#7 will be compatible with
852 # CMS v1 (which only allows Data, an Octet String) and PKCS#7, which
853 # allows Any
854 return ContentInfo
855
856 _spec_callbacks = {
857 'encap_content_info': _encap_content_info_spec
858 }
859
860
861class EncryptedData(Sequence):
862 _fields = [
863 ('version', CMSVersion),
864 ('encrypted_content_info', EncryptedContentInfo),
wbondd62ed9a2017-09-15 07:13:52 -0400865 ('unprotected_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400866 ]
867
868
869class AuthenticatedData(Sequence):
870 _fields = [
871 ('version', CMSVersion),
wbondd62ed9a2017-09-15 07:13:52 -0400872 ('originator_info', OriginatorInfo, {'implicit': 0, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400873 ('recipient_infos', RecipientInfos),
874 ('mac_algorithm', HmacAlgorithm),
wbondd62ed9a2017-09-15 07:13:52 -0400875 ('digest_algorithm', DigestAlgorithm, {'implicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400876 # This does not require the _spec_callbacks approach of SignedData and
877 # DigestedData since AuthenticatedData was not part of PKCS#7
878 ('encap_content_info', EncapsulatedContentInfo),
wbondd62ed9a2017-09-15 07:13:52 -0400879 ('auth_attrs', CMSAttributes, {'implicit': 2, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400880 ('mac', OctetString),
wbondd62ed9a2017-09-15 07:13:52 -0400881 ('unauth_attrs', CMSAttributes, {'implicit': 3, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400882 ]
883
884
885class AuthEnvelopedData(Sequence):
886 _fields = [
887 ('version', CMSVersion),
wbondd62ed9a2017-09-15 07:13:52 -0400888 ('originator_info', OriginatorInfo, {'implicit': 0, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400889 ('recipient_infos', RecipientInfos),
890 ('auth_encrypted_content_info', EncryptedContentInfo),
wbondd62ed9a2017-09-15 07:13:52 -0400891 ('auth_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400892 ('mac', OctetString),
wbondd62ed9a2017-09-15 07:13:52 -0400893 ('unauth_attrs', CMSAttributes, {'implicit': 2, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400894 ]
895
896
897class CompressionAlgorithmId(ObjectIdentifier):
898 _map = {
899 '1.2.840.113549.1.9.16.3.8': 'zlib',
900 }
901
902
903class CompressionAlgorithm(Sequence):
904 _fields = [
905 ('algorithm', CompressionAlgorithmId),
wbond40a32f02015-06-17 22:29:56 -0400906 ('parameters', Any, {'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400907 ]
908
909
910class CompressedData(Sequence):
911 _fields = [
912 ('version', CMSVersion),
913 ('compression_algorithm', CompressionAlgorithm),
914 ('encap_content_info', EncapsulatedContentInfo),
915 ]
916
917 _decompressed = None
918
919 @property
920 def decompressed(self):
921 if self._decompressed is None:
922 if zlib is None:
923 raise SystemError('The zlib module is not available')
924 self._decompressed = zlib.decompress(self['encap_content_info']['content'].native)
925 return self._decompressed
926
Markus Kötterdc8c2792019-11-19 14:57:02 +0100927class RecipientKeyIdentifier(Sequence):
Markus Kötterf003c672019-11-19 14:47:57 +0100928 _fields = [
Markus Kötterdc8c2792019-11-19 14:57:02 +0100929 ('subjectKeyIdentifier', OctetString),
930 ('date', GeneralizedTime, {'optional': True}),
931 ('other', OtherKeyAttribute, {'optional': True}),
Markus Kötterf003c672019-11-19 14:47:57 +0100932 ]
933
934
Markus Kötterdc8c2792019-11-19 14:57:02 +0100935class SMIMEEncryptionKeyPreference(Choice):
Markus Kötterf003c672019-11-19 14:47:57 +0100936 _alternatives = [
Markus Kötterdc8c2792019-11-19 14:57:02 +0100937 ('issuer_and_serial_number', IssuerAndSerialNumber, {'implicit':0}),
Markus Kötterf003c672019-11-19 14:47:57 +0100938 ('recipientKeyId', RecipientKeyIdentifier, {'implicit': 1}),
Markus Kötterdc8c2792019-11-19 14:57:02 +0100939 ('subjectAltKeyIdentifier', PublicKeyInfo, {'implicit': 2}),
Markus Kötterf003c672019-11-19 14:47:57 +0100940 ]
941
Markus Kötterdc8c2792019-11-19 14:57:02 +0100942class SMIMEEncryptionKeyPreferences(SetOf):
Markus Kötterf003c672019-11-19 14:47:57 +0100943 _child_spec = SMIMEEncryptionKeyPreference
944
945
wbonde91513e2015-06-03 14:52:18 -0400946
wbonda26664f2015-10-07 11:57:35 -0400947ContentInfo._oid_specs = {
wbonde91513e2015-06-03 14:52:18 -0400948 'data': OctetString,
949 'signed_data': SignedData,
950 'enveloped_data': EnvelopedData,
951 'signed_and_enveloped_data': SignedAndEnvelopedData,
952 'digested_data': DigestedData,
953 'encrypted_data': EncryptedData,
954 'authenticated_data': AuthenticatedData,
955 'compressed_data': CompressedData,
956 'authenticated_enveloped_data': AuthEnvelopedData,
957}
958
959
wbonda26664f2015-10-07 11:57:35 -0400960EncapsulatedContentInfo._oid_specs = {
wbonde91513e2015-06-03 14:52:18 -0400961 'signed_data': SignedData,
962 'enveloped_data': EnvelopedData,
963 'signed_and_enveloped_data': SignedAndEnvelopedData,
964 'digested_data': DigestedData,
965 'encrypted_data': EncryptedData,
966 'authenticated_data': AuthenticatedData,
967 'compressed_data': CompressedData,
968 'authenticated_enveloped_data': AuthEnvelopedData,
969}
970
971
wbonda26664f2015-10-07 11:57:35 -0400972CMSAttribute._oid_specs = {
wbonde91513e2015-06-03 14:52:18 -0400973 'content_type': SetOfContentType,
974 'message_digest': SetOfOctetString,
975 'signing_time': SetOfTime,
976 'counter_signature': SignerInfos,
wbondc57878c2016-07-14 06:02:01 -0400977 'signature_time_stamp_token': SetOfContentInfo,
Anthony Albaad0e19e2017-05-16 22:21:18 +0800978 'cms_algorithm_protection': SetOfCMSAlgorithmProtection,
wbond74d66a92019-08-01 23:26:57 -0400979 'microsoft_nested_signature': SetOfContentInfo,
980 'microsoft_time_stamp_token': SetOfContentInfo,
Markus Kötterf003c672019-11-19 14:47:57 +0100981 'encrypt_key_pref': SMIMEEncryptionKeyPreferences,
wbonde91513e2015-06-03 14:52:18 -0400982}