blob: 2115aed5a89864c2e64b0eb19657b0e0dd77a0db [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ötter317f0832019-11-20 10:24:45 +0100103 # https://tools.ietf.org/html/rfc2633#page-26
Markus Kötterf003c672019-11-19 14:47:57 +0100104 '1.2.840.113549.1.9.16.2.11': 'encrypt_key_pref',
wbondc57878c2016-07-14 06:02:01 -0400105 # https://tools.ietf.org/html/rfc3161#page-20
106 '1.2.840.113549.1.9.16.2.14': 'signature_time_stamp_token',
Anthony Albaad0e19e2017-05-16 22:21:18 +0800107 # https://tools.ietf.org/html/rfc6211#page-5
108 '1.2.840.113549.1.9.52': 'cms_algorithm_protection',
wbond74d66a92019-08-01 23:26:57 -0400109 # https://docs.microsoft.com/en-us/previous-versions/hh968145(v%3Dvs.85)
110 '1.3.6.1.4.1.311.2.4.1': 'microsoft_nested_signature',
111 # Some places refer to this as SPC_RFC3161_OBJID, others szOID_RFC3161_counterSign.
112 # https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-crypt_algorithm_identifier
113 # refers to szOID_RFC3161_counterSign as "1.2.840.113549.1.9.16.1.4",
114 # but that OID is also called szOID_TIMESTAMP_TOKEN. Because of there being
115 # no canonical source for this OID, we give it our own name
116 '1.3.6.1.4.1.311.3.3.1': 'microsoft_time_stamp_token',
wbonde91513e2015-06-03 14:52:18 -0400117 }
118
119
120class Time(Choice):
121 _alternatives = [
122 ('utc_time', UTCTime),
123 ('generalized_time', GeneralizedTime),
124 ]
125
126
127class ContentType(ObjectIdentifier):
128 _map = {
129 '1.2.840.113549.1.7.1': 'data',
130 '1.2.840.113549.1.7.2': 'signed_data',
131 '1.2.840.113549.1.7.3': 'enveloped_data',
132 '1.2.840.113549.1.7.4': 'signed_and_enveloped_data',
133 '1.2.840.113549.1.7.5': 'digested_data',
134 '1.2.840.113549.1.7.6': 'encrypted_data',
135 '1.2.840.113549.1.9.16.1.2': 'authenticated_data',
136 '1.2.840.113549.1.9.16.1.9': 'compressed_data',
137 '1.2.840.113549.1.9.16.1.23': 'authenticated_enveloped_data',
138 }
139
140
Anthony Albaad0e19e2017-05-16 22:21:18 +0800141class CMSAlgorithmProtection(Sequence):
142 _fields = [
143 ('digest_algorithm', DigestAlgorithm),
wbondd62ed9a2017-09-15 07:13:52 -0400144 ('signature_algorithm', SignedDigestAlgorithm, {'implicit': 1, 'optional': True}),
145 ('mac_algorithm', HmacAlgorithm, {'implicit': 2, 'optional': True}),
Anthony Albaad0e19e2017-05-16 22:21:18 +0800146 ]
147
148
wbonde91513e2015-06-03 14:52:18 -0400149class SetOfContentType(SetOf):
150 _child_spec = ContentType
151
152
153class SetOfOctetString(SetOf):
154 _child_spec = OctetString
155
156
157class SetOfTime(SetOf):
158 _child_spec = Time
159
160
wbonda07a51a2015-12-03 01:09:07 -0500161class SetOfAny(SetOf):
162 _child_spec = Any
163
164
Anthony Albaad0e19e2017-05-16 22:21:18 +0800165class SetOfCMSAlgorithmProtection(SetOf):
166 _child_spec = CMSAlgorithmProtection
167
168
wbonde91513e2015-06-03 14:52:18 -0400169class CMSAttribute(Sequence):
170 _fields = [
171 ('type', CMSAttributeType),
wbonda07a51a2015-12-03 01:09:07 -0500172 ('values', None),
wbonde91513e2015-06-03 14:52:18 -0400173 ]
174
wbonde91513e2015-06-03 14:52:18 -0400175 _oid_specs = {}
176
wbonda07a51a2015-12-03 01:09:07 -0500177 def _values_spec(self):
178 return self._oid_specs.get(self['type'].native, SetOfAny)
179
180 _spec_callbacks = {
181 'values': _values_spec
182 }
183
wbonde91513e2015-06-03 14:52:18 -0400184
wbondf87d4852015-12-03 00:02:35 -0500185class CMSAttributes(SetOf):
wbonde91513e2015-06-03 14:52:18 -0400186 _child_spec = CMSAttribute
187
188
189class IssuerSerial(Sequence):
190 _fields = [
191 ('issuer', GeneralNames),
192 ('serial', Integer),
193 ('issuer_uid', OctetBitString, {'optional': True}),
194 ]
195
196
197class AttCertVersion(Integer):
198 _map = {
199 0: 'v1',
200 1: 'v2',
201 }
202
203
204class AttCertSubject(Choice):
205 _alternatives = [
wbondd62ed9a2017-09-15 07:13:52 -0400206 ('base_certificate_id', IssuerSerial, {'explicit': 0}),
207 ('subject_name', GeneralNames, {'explicit': 1}),
wbonde91513e2015-06-03 14:52:18 -0400208 ]
209
210
211class AttCertValidityPeriod(Sequence):
212 _fields = [
213 ('not_before_time', GeneralizedTime),
214 ('not_after_time', GeneralizedTime),
215 ]
216
217
218class AttributeCertificateInfoV1(Sequence):
219 _fields = [
wbondb8dafce2015-08-24 09:28:01 -0400220 ('version', AttCertVersion, {'default': 'v1'}),
wbonde91513e2015-06-03 14:52:18 -0400221 ('subject', AttCertSubject),
222 ('issuer', GeneralNames),
223 ('signature', SignedDigestAlgorithm),
224 ('serial_number', Integer),
225 ('att_cert_validity_period', AttCertValidityPeriod),
226 ('attributes', Attributes),
227 ('issuer_unique_id', OctetBitString, {'optional': True}),
228 ('extensions', Extensions, {'optional': True}),
229 ]
230
231
232class AttributeCertificateV1(Sequence):
233 _fields = [
234 ('ac_info', AttributeCertificateInfoV1),
235 ('signature_algorithm', SignedDigestAlgorithm),
236 ('signature', OctetBitString),
237 ]
238
239
240class DigestedObjectType(Enumerated):
241 _map = {
242 0: 'public_key',
243 1: 'public_key_cert',
244 2: 'other_objy_types',
245 }
246
247
248class ObjectDigestInfo(Sequence):
249 _fields = [
250 ('digested_object_type', DigestedObjectType),
251 ('other_object_type_id', ObjectIdentifier, {'optional': True}),
252 ('digest_algorithm', DigestAlgorithm),
253 ('object_digest', OctetBitString),
254 ]
255
256
257class Holder(Sequence):
258 _fields = [
wbondd62ed9a2017-09-15 07:13:52 -0400259 ('base_certificate_id', IssuerSerial, {'implicit': 0, 'optional': True}),
260 ('entity_name', GeneralNames, {'implicit': 1, 'optional': True}),
261 ('object_digest_info', ObjectDigestInfo, {'implicit': 2, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400262 ]
263
264
265class V2Form(Sequence):
266 _fields = [
267 ('issuer_name', GeneralNames, {'optional': True}),
wbondd62ed9a2017-09-15 07:13:52 -0400268 ('base_certificate_id', IssuerSerial, {'explicit': 0, 'optional': True}),
269 ('object_digest_info', ObjectDigestInfo, {'explicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400270 ]
271
272
273class AttCertIssuer(Choice):
274 _alternatives = [
275 ('v1_form', GeneralNames),
wbondd62ed9a2017-09-15 07:13:52 -0400276 ('v2_form', V2Form, {'explicit': 0}),
wbonde91513e2015-06-03 14:52:18 -0400277 ]
278
279
wbond6a8cf2a2016-07-14 07:17:44 -0400280class IetfAttrValue(Choice):
281 _alternatives = [
282 ('octets', OctetString),
283 ('oid', ObjectIdentifier),
284 ('string', UTF8String),
285 ]
286
287
288class IetfAttrValues(SequenceOf):
289 _child_spec = IetfAttrValue
290
291
292class IetfAttrSyntax(Sequence):
293 _fields = [
wbondd62ed9a2017-09-15 07:13:52 -0400294 ('policy_authority', GeneralNames, {'implicit': 0, 'optional': True}),
wbond6a8cf2a2016-07-14 07:17:44 -0400295 ('values', IetfAttrValues),
296 ]
297
298
299class SetOfIetfAttrSyntax(SetOf):
300 _child_spec = IetfAttrSyntax
301
302
303class SvceAuthInfo(Sequence):
304 _fields = [
305 ('service', GeneralName),
306 ('ident', GeneralName),
307 ('auth_info', OctetString, {'optional': True}),
308 ]
309
310
311class SetOfSvceAuthInfo(SetOf):
312 _child_spec = SvceAuthInfo
313
314
315class RoleSyntax(Sequence):
316 _fields = [
wbondd62ed9a2017-09-15 07:13:52 -0400317 ('role_authority', GeneralNames, {'implicit': 0, 'optional': True}),
318 ('role_name', GeneralName, {'implicit': 1}),
wbond6a8cf2a2016-07-14 07:17:44 -0400319 ]
320
321
322class SetOfRoleSyntax(SetOf):
323 _child_spec = RoleSyntax
324
325
326class ClassList(BitString):
327 _map = {
328 0: 'unmarked',
329 1: 'unclassified',
330 2: 'restricted',
331 3: 'confidential',
332 4: 'secret',
333 5: 'top_secret',
334 }
335
336
337class SecurityCategory(Sequence):
338 _fields = [
wbondd62ed9a2017-09-15 07:13:52 -0400339 ('type', ObjectIdentifier, {'implicit': 0}),
340 ('value', Any, {'implicit': 1}),
wbond6a8cf2a2016-07-14 07:17:44 -0400341 ]
342
343
344class SetOfSecurityCategory(SetOf):
345 _child_spec = SecurityCategory
346
347
348class Clearance(Sequence):
349 _fields = [
wbondd62ed9a2017-09-15 07:13:52 -0400350 ('policy_id', ObjectIdentifier, {'implicit': 0}),
351 ('class_list', ClassList, {'implicit': 1, 'default': 'unclassified'}),
352 ('security_categories', SetOfSecurityCategory, {'implicit': 2, 'optional': True}),
wbond6a8cf2a2016-07-14 07:17:44 -0400353 ]
354
355
356class SetOfClearance(SetOf):
357 _child_spec = Clearance
358
359
360class BigTime(Sequence):
361 _fields = [
362 ('major', Integer),
363 ('fractional_seconds', Integer),
364 ('sign', Integer, {'optional': True}),
365 ]
366
367
368class LeapData(Sequence):
369 _fields = [
370 ('leap_time', BigTime),
371 ('action', Integer),
372 ]
373
374
375class SetOfLeapData(SetOf):
376 _child_spec = LeapData
377
378
379class TimingMetrics(Sequence):
380 _fields = [
381 ('ntp_time', BigTime),
382 ('offset', BigTime),
383 ('delay', BigTime),
384 ('expiration', BigTime),
385 ('leap_event', SetOfLeapData, {'optional': True}),
386 ]
387
388
389class SetOfTimingMetrics(SetOf):
390 _child_spec = TimingMetrics
391
392
393class TimingPolicy(Sequence):
394 _fields = [
395 ('policy_id', SequenceOf, {'spec': ObjectIdentifier}),
wbondd62ed9a2017-09-15 07:13:52 -0400396 ('max_offset', BigTime, {'explicit': 0, 'optional': True}),
397 ('max_delay', BigTime, {'explicit': 1, 'optional': True}),
wbond6a8cf2a2016-07-14 07:17:44 -0400398 ]
399
400
401class SetOfTimingPolicy(SetOf):
402 _child_spec = TimingPolicy
403
404
405class AttCertAttributeType(ObjectIdentifier):
406 _map = {
407 '1.3.6.1.5.5.7.10.1': 'authentication_info',
408 '1.3.6.1.5.5.7.10.2': 'access_identity',
409 '1.3.6.1.5.5.7.10.3': 'charging_identity',
410 '1.3.6.1.5.5.7.10.4': 'group',
411 '2.5.4.72': 'role',
412 '2.5.4.55': 'clearance',
413 '1.3.6.1.4.1.601.10.4.1': 'timing_metrics',
414 '1.3.6.1.4.1.601.10.4.2': 'timing_policy',
415 }
416
417
418class AttCertAttribute(Sequence):
419 _fields = [
420 ('type', AttCertAttributeType),
421 ('values', None),
422 ]
423
424 _oid_specs = {
425 'authentication_info': SetOfSvceAuthInfo,
426 'access_identity': SetOfSvceAuthInfo,
427 'charging_identity': SetOfIetfAttrSyntax,
428 'group': SetOfIetfAttrSyntax,
429 'role': SetOfRoleSyntax,
430 'clearance': SetOfClearance,
431 'timing_metrics': SetOfTimingMetrics,
432 'timing_policy': SetOfTimingPolicy,
433 }
434
435 def _values_spec(self):
wbond7b1cd4b2017-02-10 05:11:14 -0500436 return self._oid_specs.get(self['type'].native, SetOfAny)
wbond6a8cf2a2016-07-14 07:17:44 -0400437
438 _spec_callbacks = {
439 'values': _values_spec
440 }
441
442
443class AttCertAttributes(SequenceOf):
444 _child_spec = AttCertAttribute
445
446
wbonde91513e2015-06-03 14:52:18 -0400447class AttributeCertificateInfoV2(Sequence):
448 _fields = [
449 ('version', AttCertVersion),
450 ('holder', Holder),
451 ('issuer', AttCertIssuer),
452 ('signature', SignedDigestAlgorithm),
453 ('serial_number', Integer),
454 ('att_cert_validity_period', AttCertValidityPeriod),
wbond6a8cf2a2016-07-14 07:17:44 -0400455 ('attributes', AttCertAttributes),
wbonde91513e2015-06-03 14:52:18 -0400456 ('issuer_unique_id', OctetBitString, {'optional': True}),
457 ('extensions', Extensions, {'optional': True}),
458 ]
459
460
461class AttributeCertificateV2(Sequence):
wbond97cdd2f2016-07-14 11:58:41 -0400462 # Handle the situation where a V2 cert is encoded as V1
463 _bad_tag = 1
464
wbonde91513e2015-06-03 14:52:18 -0400465 _fields = [
466 ('ac_info', AttributeCertificateInfoV2),
467 ('signature_algorithm', SignedDigestAlgorithm),
468 ('signature', OctetBitString),
469 ]
470
471
472class OtherCertificateFormat(Sequence):
473 _fields = [
474 ('other_cert_format', ObjectIdentifier),
475 ('other_cert', Any),
476 ]
477
478
479class CertificateChoices(Choice):
480 _alternatives = [
481 ('certificate', Certificate),
wbondd62ed9a2017-09-15 07:13:52 -0400482 ('extended_certificate', ExtendedCertificate, {'implicit': 0}),
483 ('v1_attr_cert', AttributeCertificateV1, {'implicit': 1}),
484 ('v2_attr_cert', AttributeCertificateV2, {'implicit': 2}),
485 ('other', OtherCertificateFormat, {'implicit': 3}),
wbonde91513e2015-06-03 14:52:18 -0400486 ]
487
wbond97cdd2f2016-07-14 11:58:41 -0400488 def validate(self, class_, tag, contents):
489 """
490 Ensures that the class and tag specified exist as an alternative. This
491 custom version fixes parsing broken encodings there a V2 attribute
492 # certificate is encoded as a V1
493
494 :param class_:
495 The integer class_ from the encoded value header
496
497 :param tag:
498 The integer tag from the encoded value header
499
500 :param contents:
501 A byte string of the contents of the value - used when the object
502 is explicitly tagged
503
504 :raises:
505 ValueError - when value is not a valid alternative
506 """
507
508 super(CertificateChoices, self).validate(class_, tag, contents)
509 if self._choice == 2:
510 if AttCertVersion.load(Sequence.load(contents)[0].dump()).native == 'v2':
511 self._choice = 3
512
wbonde91513e2015-06-03 14:52:18 -0400513
514class CertificateSet(SetOf):
515 _child_spec = CertificateChoices
516
517
518class ContentInfo(Sequence):
519 _fields = [
520 ('content_type', ContentType),
wbondd62ed9a2017-09-15 07:13:52 -0400521 ('content', Any, {'explicit': 0, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400522 ]
523
524 _oid_pair = ('content_type', 'content')
525 _oid_specs = {}
526
527
wbondc57878c2016-07-14 06:02:01 -0400528class SetOfContentInfo(SetOf):
529 _child_spec = ContentInfo
530
531
wbonde91513e2015-06-03 14:52:18 -0400532class EncapsulatedContentInfo(Sequence):
533 _fields = [
534 ('content_type', ContentType),
wbondd62ed9a2017-09-15 07:13:52 -0400535 ('content', ParsableOctetString, {'explicit': 0, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400536 ]
537
538 _oid_pair = ('content_type', 'content')
539 _oid_specs = {}
540
541
542class IssuerAndSerialNumber(Sequence):
543 _fields = [
544 ('issuer', Name),
545 ('serial_number', Integer),
546 ]
547
548
549class SignerIdentifier(Choice):
550 _alternatives = [
551 ('issuer_and_serial_number', IssuerAndSerialNumber),
wbondd62ed9a2017-09-15 07:13:52 -0400552 ('subject_key_identifier', OctetString, {'implicit': 0}),
wbonde91513e2015-06-03 14:52:18 -0400553 ]
554
555
556class DigestAlgorithms(SetOf):
557 _child_spec = DigestAlgorithm
558
559
560class CertificateRevocationLists(SetOf):
561 _child_spec = CertificateList
562
563
564class SCVPReqRes(Sequence):
565 _fields = [
wbondd62ed9a2017-09-15 07:13:52 -0400566 ('request', ContentInfo, {'explicit': 0, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400567 ('response', ContentInfo),
568 ]
569
570
571class OtherRevInfoFormatId(ObjectIdentifier):
572 _map = {
573 '1.3.6.1.5.5.7.16.2': 'ocsp_response',
574 '1.3.6.1.5.5.7.16.4': 'scvp',
575 }
576
577
578class OtherRevocationInfoFormat(Sequence):
579 _fields = [
580 ('other_rev_info_format', OtherRevInfoFormatId),
581 ('other_rev_info', Any),
582 ]
583
584 _oid_pair = ('other_rev_info_format', 'other_rev_info')
585 _oid_specs = {
586 'ocsp_response': OCSPResponse,
587 'scvp': SCVPReqRes,
588 }
589
590
591class RevocationInfoChoice(Choice):
592 _alternatives = [
593 ('crl', CertificateList),
wbondd62ed9a2017-09-15 07:13:52 -0400594 ('other', OtherRevocationInfoFormat, {'implicit': 1}),
wbonde91513e2015-06-03 14:52:18 -0400595 ]
596
597
598class RevocationInfoChoices(SetOf):
599 _child_spec = RevocationInfoChoice
600
601
602class SignerInfo(Sequence):
603 _fields = [
604 ('version', CMSVersion),
605 ('sid', SignerIdentifier),
606 ('digest_algorithm', DigestAlgorithm),
wbondd62ed9a2017-09-15 07:13:52 -0400607 ('signed_attrs', CMSAttributes, {'implicit': 0, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400608 ('signature_algorithm', SignedDigestAlgorithm),
609 ('signature', OctetString),
wbondd62ed9a2017-09-15 07:13:52 -0400610 ('unsigned_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400611 ]
612
613
614class SignerInfos(SetOf):
615 _child_spec = SignerInfo
616
617
618class SignedData(Sequence):
619 _fields = [
620 ('version', CMSVersion),
621 ('digest_algorithms', DigestAlgorithms),
622 ('encap_content_info', None),
wbondd62ed9a2017-09-15 07:13:52 -0400623 ('certificates', CertificateSet, {'implicit': 0, 'optional': True}),
624 ('crls', RevocationInfoChoices, {'implicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400625 ('signer_infos', SignerInfos),
626 ]
627
628 def _encap_content_info_spec(self):
629 # If the encap_content_info is version v1, then this could be a PKCS#7
630 # structure, or a CMS structure. CMS wraps the encoded value in an
631 # Octet String tag.
632
633 # If the version is greater than 1, it is definite CMS
634 if self['version'].native != 'v1':
635 return EncapsulatedContentInfo
636
637 # Otherwise, the ContentInfo spec from PKCS#7 will be compatible with
638 # CMS v1 (which only allows Data, an Octet String) and PKCS#7, which
639 # allows Any
640 return ContentInfo
641
642 _spec_callbacks = {
643 'encap_content_info': _encap_content_info_spec
644 }
645
646
647class OriginatorInfo(Sequence):
648 _fields = [
wbondd62ed9a2017-09-15 07:13:52 -0400649 ('certs', CertificateSet, {'implicit': 0, 'optional': True}),
650 ('crls', RevocationInfoChoices, {'implicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400651 ]
652
653
654class RecipientIdentifier(Choice):
655 _alternatives = [
656 ('issuer_and_serial_number', IssuerAndSerialNumber),
wbondd62ed9a2017-09-15 07:13:52 -0400657 ('subject_key_identifier', OctetString, {'implicit': 0}),
wbonde91513e2015-06-03 14:52:18 -0400658 ]
659
660
661class KeyEncryptionAlgorithmId(ObjectIdentifier):
662 _map = {
wbond7ed8ee02019-08-01 22:14:53 -0400663 '1.2.840.113549.1.1.1': 'rsaes_pkcs1v15',
Ludovic Watteauxb2c16e92018-06-30 14:11:22 +0200664 '1.2.840.113549.1.1.7': 'rsaes_oaep',
eukaryotefda656d2015-11-02 10:04:37 -0800665 '2.16.840.1.101.3.4.1.5': 'aes128_wrap',
666 '2.16.840.1.101.3.4.1.8': 'aes128_wrap_pad',
667 '2.16.840.1.101.3.4.1.25': 'aes192_wrap',
668 '2.16.840.1.101.3.4.1.28': 'aes192_wrap_pad',
669 '2.16.840.1.101.3.4.1.45': 'aes256_wrap',
670 '2.16.840.1.101.3.4.1.48': 'aes256_wrap_pad',
wbonde91513e2015-06-03 14:52:18 -0400671 }
672
wbond7ed8ee02019-08-01 22:14:53 -0400673 _reverse_map = {
674 'rsa': '1.2.840.113549.1.1.1',
675 'rsaes_pkcs1v15': '1.2.840.113549.1.1.1',
676 'rsaes_oaep': '1.2.840.113549.1.1.7',
677 'aes128_wrap': '2.16.840.1.101.3.4.1.5',
678 'aes128_wrap_pad': '2.16.840.1.101.3.4.1.8',
679 'aes192_wrap': '2.16.840.1.101.3.4.1.25',
680 'aes192_wrap_pad': '2.16.840.1.101.3.4.1.28',
681 'aes256_wrap': '2.16.840.1.101.3.4.1.45',
682 'aes256_wrap_pad': '2.16.840.1.101.3.4.1.48',
683 }
684
wbonde91513e2015-06-03 14:52:18 -0400685
wbond381a4da2016-08-30 11:39:54 -0400686class KeyEncryptionAlgorithm(_ForceNullParameters, Sequence):
wbonde91513e2015-06-03 14:52:18 -0400687 _fields = [
688 ('algorithm', KeyEncryptionAlgorithmId),
689 ('parameters', Any, {'optional': True}),
690 ]
691
wbond850c0c02019-08-01 22:27:04 -0400692 _oid_pair = ('algorithm', 'parameters')
693 _oid_specs = {
694 'rsaes_oaep': RSAESOAEPParams,
695 }
696
wbonde91513e2015-06-03 14:52:18 -0400697
698class KeyTransRecipientInfo(Sequence):
699 _fields = [
700 ('version', CMSVersion),
701 ('rid', RecipientIdentifier),
702 ('key_encryption_algorithm', KeyEncryptionAlgorithm),
703 ('encrypted_key', OctetString),
704 ]
705
706
707class OriginatorIdentifierOrKey(Choice):
708 _alternatives = [
709 ('issuer_and_serial_number', IssuerAndSerialNumber),
wbondd62ed9a2017-09-15 07:13:52 -0400710 ('subject_key_identifier', OctetString, {'implicit': 0}),
711 ('originator_key', PublicKeyInfo, {'implicit': 1}),
wbonde91513e2015-06-03 14:52:18 -0400712 ]
713
714
715class OtherKeyAttribute(Sequence):
716 _fields = [
717 ('key_attr_id', ObjectIdentifier),
718 ('key_attr', Any),
719 ]
720
721
722class RecipientKeyIdentifier(Sequence):
723 _fields = [
724 ('subject_key_identifier', OctetString),
725 ('date', GeneralizedTime, {'optional': True}),
726 ('other', OtherKeyAttribute, {'optional': True}),
727 ]
728
729
730class KeyAgreementRecipientIdentifier(Choice):
731 _alternatives = [
732 ('issuer_and_serial_number', IssuerAndSerialNumber),
wbondd62ed9a2017-09-15 07:13:52 -0400733 ('r_key_id', RecipientKeyIdentifier, {'implicit': 0}),
wbonde91513e2015-06-03 14:52:18 -0400734 ]
735
736
737class RecipientEncryptedKey(Sequence):
738 _fields = [
739 ('rid', KeyAgreementRecipientIdentifier),
740 ('encrypted_key', OctetString),
741 ]
742
743
744class RecipientEncryptedKeys(SequenceOf):
745 _child_spec = RecipientEncryptedKey
746
747
748class KeyAgreeRecipientInfo(Sequence):
749 _fields = [
750 ('version', CMSVersion),
wbondd62ed9a2017-09-15 07:13:52 -0400751 ('originator', OriginatorIdentifierOrKey, {'explicit': 0}),
752 ('ukm', OctetString, {'explicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400753 ('key_encryption_algorithm', KeyEncryptionAlgorithm),
754 ('recipient_encrypted_keys', RecipientEncryptedKeys),
755 ]
756
757
758class KEKIdentifier(Sequence):
759 _fields = [
760 ('key_identifier', OctetString),
761 ('date', GeneralizedTime, {'optional': True}),
762 ('other', OtherKeyAttribute, {'optional': True}),
763 ]
764
765
766class KEKRecipientInfo(Sequence):
767 _fields = [
768 ('version', CMSVersion),
769 ('kekid', KEKIdentifier),
770 ('key_encryption_algorithm', KeyEncryptionAlgorithm),
771 ('encrypted_key', OctetString),
772 ]
773
774
775class PasswordRecipientInfo(Sequence):
776 _fields = [
777 ('version', CMSVersion),
wbondd62ed9a2017-09-15 07:13:52 -0400778 ('key_derivation_algorithm', KdfAlgorithm, {'implicit': 0, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400779 ('key_encryption_algorithm', KeyEncryptionAlgorithm),
780 ('encrypted_key', OctetString),
781 ]
782
783
784class OtherRecipientInfo(Sequence):
785 _fields = [
786 ('ori_type', ObjectIdentifier),
787 ('ori_value', Any),
788 ]
789
790
791class RecipientInfo(Choice):
792 _alternatives = [
793 ('ktri', KeyTransRecipientInfo),
wbondd62ed9a2017-09-15 07:13:52 -0400794 ('kari', KeyAgreeRecipientInfo, {'implicit': 1}),
795 ('kekri', KEKRecipientInfo, {'implicit': 2}),
796 ('pwri', PasswordRecipientInfo, {'implicit': 3}),
797 ('ori', OtherRecipientInfo, {'implicit': 4}),
wbonde91513e2015-06-03 14:52:18 -0400798 ]
799
800
801class RecipientInfos(SetOf):
802 _child_spec = RecipientInfo
803
804
805class EncryptedContentInfo(Sequence):
806 _fields = [
807 ('content_type', ContentType),
wbond59af99d2015-06-15 16:19:04 -0400808 ('content_encryption_algorithm', EncryptionAlgorithm),
wbondd62ed9a2017-09-15 07:13:52 -0400809 ('encrypted_content', OctetString, {'implicit': 0, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400810 ]
811
812
813class EnvelopedData(Sequence):
814 _fields = [
815 ('version', CMSVersion),
wbondd62ed9a2017-09-15 07:13:52 -0400816 ('originator_info', OriginatorInfo, {'implicit': 0, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400817 ('recipient_infos', RecipientInfos),
818 ('encrypted_content_info', EncryptedContentInfo),
wbondd62ed9a2017-09-15 07:13:52 -0400819 ('unprotected_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400820 ]
821
822
823class SignedAndEnvelopedData(Sequence):
824 _fields = [
825 ('version', CMSVersion),
826 ('recipient_infos', RecipientInfos),
827 ('digest_algorithms', DigestAlgorithms),
828 ('encrypted_content_info', EncryptedContentInfo),
wbondd62ed9a2017-09-15 07:13:52 -0400829 ('certificates', CertificateSet, {'implicit': 0, 'optional': True}),
830 ('crls', CertificateRevocationLists, {'implicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400831 ('signer_infos', SignerInfos),
832 ]
833
834
835class DigestedData(Sequence):
836 _fields = [
837 ('version', CMSVersion),
838 ('digest_algorithm', DigestAlgorithm),
839 ('encap_content_info', None),
840 ('digest', OctetString),
841 ]
842
843 def _encap_content_info_spec(self):
844 # If the encap_content_info is version v1, then this could be a PKCS#7
845 # structure, or a CMS structure. CMS wraps the encoded value in an
846 # Octet String tag.
847
848 # If the version is greater than 1, it is definite CMS
849 if self['version'].native != 'v1':
850 return EncapsulatedContentInfo
851
852 # Otherwise, the ContentInfo spec from PKCS#7 will be compatible with
853 # CMS v1 (which only allows Data, an Octet String) and PKCS#7, which
854 # allows Any
855 return ContentInfo
856
857 _spec_callbacks = {
858 'encap_content_info': _encap_content_info_spec
859 }
860
861
862class EncryptedData(Sequence):
863 _fields = [
864 ('version', CMSVersion),
865 ('encrypted_content_info', EncryptedContentInfo),
wbondd62ed9a2017-09-15 07:13:52 -0400866 ('unprotected_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400867 ]
868
869
870class AuthenticatedData(Sequence):
871 _fields = [
872 ('version', CMSVersion),
wbondd62ed9a2017-09-15 07:13:52 -0400873 ('originator_info', OriginatorInfo, {'implicit': 0, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400874 ('recipient_infos', RecipientInfos),
875 ('mac_algorithm', HmacAlgorithm),
wbondd62ed9a2017-09-15 07:13:52 -0400876 ('digest_algorithm', DigestAlgorithm, {'implicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400877 # This does not require the _spec_callbacks approach of SignedData and
878 # DigestedData since AuthenticatedData was not part of PKCS#7
879 ('encap_content_info', EncapsulatedContentInfo),
wbondd62ed9a2017-09-15 07:13:52 -0400880 ('auth_attrs', CMSAttributes, {'implicit': 2, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400881 ('mac', OctetString),
wbondd62ed9a2017-09-15 07:13:52 -0400882 ('unauth_attrs', CMSAttributes, {'implicit': 3, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400883 ]
884
885
886class AuthEnvelopedData(Sequence):
887 _fields = [
888 ('version', CMSVersion),
wbondd62ed9a2017-09-15 07:13:52 -0400889 ('originator_info', OriginatorInfo, {'implicit': 0, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400890 ('recipient_infos', RecipientInfos),
891 ('auth_encrypted_content_info', EncryptedContentInfo),
wbondd62ed9a2017-09-15 07:13:52 -0400892 ('auth_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400893 ('mac', OctetString),
wbondd62ed9a2017-09-15 07:13:52 -0400894 ('unauth_attrs', CMSAttributes, {'implicit': 2, 'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400895 ]
896
897
898class CompressionAlgorithmId(ObjectIdentifier):
899 _map = {
900 '1.2.840.113549.1.9.16.3.8': 'zlib',
901 }
902
903
904class CompressionAlgorithm(Sequence):
905 _fields = [
906 ('algorithm', CompressionAlgorithmId),
wbond40a32f02015-06-17 22:29:56 -0400907 ('parameters', Any, {'optional': True}),
wbonde91513e2015-06-03 14:52:18 -0400908 ]
909
910
911class CompressedData(Sequence):
912 _fields = [
913 ('version', CMSVersion),
914 ('compression_algorithm', CompressionAlgorithm),
915 ('encap_content_info', EncapsulatedContentInfo),
916 ]
917
918 _decompressed = None
919
920 @property
921 def decompressed(self):
922 if self._decompressed is None:
923 if zlib is None:
924 raise SystemError('The zlib module is not available')
925 self._decompressed = zlib.decompress(self['encap_content_info']['content'].native)
926 return self._decompressed
927
Markus Kötter958e8e72019-11-20 10:25:05 +0100928
Markus Kötterdc8c2792019-11-19 14:57:02 +0100929class RecipientKeyIdentifier(Sequence):
Markus Kötterf003c672019-11-19 14:47:57 +0100930 _fields = [
Markus Kötterdc8c2792019-11-19 14:57:02 +0100931 ('subjectKeyIdentifier', OctetString),
932 ('date', GeneralizedTime, {'optional': True}),
933 ('other', OtherKeyAttribute, {'optional': True}),
Markus Kötterf003c672019-11-19 14:47:57 +0100934 ]
935
936
Markus Kötterdc8c2792019-11-19 14:57:02 +0100937class SMIMEEncryptionKeyPreference(Choice):
Markus Kötterf003c672019-11-19 14:47:57 +0100938 _alternatives = [
Markus Kötter718f2902019-11-20 10:37:23 +0100939 ('issuer_and_serial_number', IssuerAndSerialNumber, {'implicit': 0}),
Markus Kötterf003c672019-11-19 14:47:57 +0100940 ('recipientKeyId', RecipientKeyIdentifier, {'implicit': 1}),
Markus Kötterdc8c2792019-11-19 14:57:02 +0100941 ('subjectAltKeyIdentifier', PublicKeyInfo, {'implicit': 2}),
Markus Kötterf003c672019-11-19 14:47:57 +0100942 ]
943
Markus Kötter958e8e72019-11-20 10:25:05 +0100944
Markus Kötterdc8c2792019-11-19 14:57:02 +0100945class SMIMEEncryptionKeyPreferences(SetOf):
Markus Kötterf003c672019-11-19 14:47:57 +0100946 _child_spec = SMIMEEncryptionKeyPreference
947
948
wbonda26664f2015-10-07 11:57:35 -0400949ContentInfo._oid_specs = {
wbonde91513e2015-06-03 14:52:18 -0400950 'data': OctetString,
951 'signed_data': SignedData,
952 'enveloped_data': EnvelopedData,
953 'signed_and_enveloped_data': SignedAndEnvelopedData,
954 'digested_data': DigestedData,
955 'encrypted_data': EncryptedData,
956 'authenticated_data': AuthenticatedData,
957 'compressed_data': CompressedData,
958 'authenticated_enveloped_data': AuthEnvelopedData,
959}
960
961
wbonda26664f2015-10-07 11:57:35 -0400962EncapsulatedContentInfo._oid_specs = {
wbonde91513e2015-06-03 14:52:18 -0400963 'signed_data': SignedData,
964 'enveloped_data': EnvelopedData,
965 'signed_and_enveloped_data': SignedAndEnvelopedData,
966 'digested_data': DigestedData,
967 'encrypted_data': EncryptedData,
968 'authenticated_data': AuthenticatedData,
969 'compressed_data': CompressedData,
970 'authenticated_enveloped_data': AuthEnvelopedData,
971}
972
973
wbonda26664f2015-10-07 11:57:35 -0400974CMSAttribute._oid_specs = {
wbonde91513e2015-06-03 14:52:18 -0400975 'content_type': SetOfContentType,
976 'message_digest': SetOfOctetString,
977 'signing_time': SetOfTime,
978 'counter_signature': SignerInfos,
wbondc57878c2016-07-14 06:02:01 -0400979 'signature_time_stamp_token': SetOfContentInfo,
Anthony Albaad0e19e2017-05-16 22:21:18 +0800980 'cms_algorithm_protection': SetOfCMSAlgorithmProtection,
wbond74d66a92019-08-01 23:26:57 -0400981 'microsoft_nested_signature': SetOfContentInfo,
982 'microsoft_time_stamp_token': SetOfContentInfo,
Markus Kötterf003c672019-11-19 14:47:57 +0100983 'encrypt_key_pref': SMIMEEncryptionKeyPreferences,
wbonde91513e2015-06-03 14:52:18 -0400984}