1#
2# This file is part of pyasn1-modules software.
3#
4# Created by Russ Housley with assistance from asn1ate v.0.6.0.
5# Modified by Russ Housley to add a map for use with opentypes.
6#
7# Copyright (c) 2019, Vigil Security, LLC
8# License: http://snmplabs.com/pyasn1/license.html
9#
10# Enhanced Security Services for S/MIME
11#
12# ASN.1 source from:
13# https://www.rfc-editor.org/rfc/rfc2634.txt
14#
15
16from pyasn1.type import char
17from pyasn1.type import constraint
18from pyasn1.type import namedval
19from pyasn1.type import namedtype
20from pyasn1.type import tag
21from pyasn1.type import univ
22from pyasn1.type import useful
23
24from pyasn1_modules import rfc5652
25from pyasn1_modules import rfc5280
26
27MAX = float('inf')
28
29ContentType = rfc5652.ContentType
30
31IssuerAndSerialNumber = rfc5652.IssuerAndSerialNumber
32
33SubjectKeyIdentifier = rfc5652.SubjectKeyIdentifier
34
35PolicyInformation = rfc5280.PolicyInformation
36
37GeneralNames = rfc5280.GeneralNames
38
39CertificateSerialNumber = rfc5280.CertificateSerialNumber
40
41
42# Signing Certificate Attribute
43# Warning: It is better to use SigningCertificateV2 from RFC 5035
44
45id_aa_signingCertificate = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.12')
46
47class Hash(univ.OctetString):
48    pass  # SHA-1 hash of entire certificate; RFC 5035 supports other hash algorithms
49
50
51class IssuerSerial(univ.Sequence):
52    pass
53
54IssuerSerial.componentType = namedtype.NamedTypes(
55    namedtype.NamedType('issuer', GeneralNames()),
56    namedtype.NamedType('serialNumber', CertificateSerialNumber())
57)
58
59
60class ESSCertID(univ.Sequence):
61    pass
62
63ESSCertID.componentType = namedtype.NamedTypes(
64    namedtype.NamedType('certHash', Hash()),
65    namedtype.OptionalNamedType('issuerSerial', IssuerSerial())
66)
67
68
69class SigningCertificate(univ.Sequence):
70    pass
71
72SigningCertificate.componentType = namedtype.NamedTypes(
73    namedtype.NamedType('certs', univ.SequenceOf(
74        componentType=ESSCertID())),
75    namedtype.OptionalNamedType('policies', univ.SequenceOf(
76        componentType=PolicyInformation()))
77)
78
79
80# Mail List Expansion History Attribute
81
82id_aa_mlExpandHistory = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.3')
83
84ub_ml_expansion_history = univ.Integer(64)
85
86
87class EntityIdentifier(univ.Choice):
88    pass
89
90EntityIdentifier.componentType = namedtype.NamedTypes(
91    namedtype.NamedType('issuerAndSerialNumber', IssuerAndSerialNumber()),
92    namedtype.NamedType('subjectKeyIdentifier', SubjectKeyIdentifier())
93)
94
95
96class MLReceiptPolicy(univ.Choice):
97    pass
98
99MLReceiptPolicy.componentType = namedtype.NamedTypes(
100    namedtype.NamedType('none', univ.Null().subtype(implicitTag=tag.Tag(
101        tag.tagClassContext, tag.tagFormatSimple, 0))),
102    namedtype.NamedType('insteadOf', univ.SequenceOf(
103        componentType=GeneralNames()).subtype(
104        sizeSpec=constraint.ValueSizeConstraint(1, MAX)).subtype(
105        implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))),
106    namedtype.NamedType('inAdditionTo', univ.SequenceOf(
107        componentType=GeneralNames()).subtype(
108        sizeSpec=constraint.ValueSizeConstraint(1, MAX)).subtype(
109        implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2)))
110)
111
112
113class MLData(univ.Sequence):
114    pass
115
116MLData.componentType = namedtype.NamedTypes(
117    namedtype.NamedType('mailListIdentifier', EntityIdentifier()),
118    namedtype.NamedType('expansionTime', useful.GeneralizedTime()),
119    namedtype.OptionalNamedType('mlReceiptPolicy', MLReceiptPolicy())
120)
121
122class MLExpansionHistory(univ.SequenceOf):
123    pass
124
125MLExpansionHistory.componentType = MLData()
126MLExpansionHistory.sizeSpec = constraint.ValueSizeConstraint(1, ub_ml_expansion_history)
127
128
129# ESS Security Label Attribute
130
131id_aa_securityLabel = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.2')
132
133ub_privacy_mark_length = univ.Integer(128)
134
135ub_security_categories = univ.Integer(64)
136
137ub_integer_options = univ.Integer(256)
138
139
140class ESSPrivacyMark(univ.Choice):
141    pass
142
143ESSPrivacyMark.componentType = namedtype.NamedTypes(
144    namedtype.NamedType('pString', char.PrintableString().subtype(
145        subtypeSpec=constraint.ValueSizeConstraint(1, ub_privacy_mark_length))),
146    namedtype.NamedType('utf8String', char.UTF8String().subtype(
147        subtypeSpec=constraint.ValueSizeConstraint(1, MAX)))
148)
149
150
151class SecurityClassification(univ.Integer):
152    pass
153
154SecurityClassification.subtypeSpec=constraint.ValueRangeConstraint(0, ub_integer_options)
155
156SecurityClassification.namedValues = namedval.NamedValues(
157    ('unmarked', 0),
158    ('unclassified', 1),
159    ('restricted', 2),
160    ('confidential', 3),
161    ('secret', 4),
162    ('top-secret', 5)
163)
164
165
166class SecurityPolicyIdentifier(univ.ObjectIdentifier):
167    pass
168
169
170class SecurityCategory(univ.Sequence):
171    pass
172
173SecurityCategory.componentType = namedtype.NamedTypes(
174    namedtype.NamedType('type', univ.ObjectIdentifier().subtype(
175        implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))),
176    namedtype.NamedType('value', univ.Any().subtype(implicitTag=tag.Tag(
177        tag.tagClassContext, tag.tagFormatSimple, 1)))
178)
179
180
181class SecurityCategories(univ.SetOf):
182    pass
183
184SecurityCategories.componentType = SecurityCategory()
185SecurityCategories.sizeSpec = constraint.ValueSizeConstraint(1, ub_security_categories)
186
187
188class ESSSecurityLabel(univ.Set):
189    pass
190
191ESSSecurityLabel.componentType = namedtype.NamedTypes(
192    namedtype.NamedType('security-policy-identifier', SecurityPolicyIdentifier()),
193    namedtype.OptionalNamedType('security-classification', SecurityClassification()),
194    namedtype.OptionalNamedType('privacy-mark', ESSPrivacyMark()),
195    namedtype.OptionalNamedType('security-categories', SecurityCategories())
196)
197
198
199# Equivalent Labels Attribute
200
201id_aa_equivalentLabels = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.9')
202
203class EquivalentLabels(univ.SequenceOf):
204    pass
205
206EquivalentLabels.componentType = ESSSecurityLabel()
207
208
209# Content Identifier Attribute
210
211id_aa_contentIdentifier = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.7')
212
213class ContentIdentifier(univ.OctetString):
214    pass
215
216
217# Content Reference Attribute
218
219id_aa_contentReference = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.10')
220
221class ContentReference(univ.Sequence):
222    pass
223
224ContentReference.componentType = namedtype.NamedTypes(
225    namedtype.NamedType('contentType', ContentType()),
226    namedtype.NamedType('signedContentIdentifier', ContentIdentifier()),
227    namedtype.NamedType('originatorSignatureValue', univ.OctetString())
228)
229
230
231# Message Signature Digest Attribute
232
233id_aa_msgSigDigest = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.5')
234
235class MsgSigDigest(univ.OctetString):
236    pass
237
238
239# Content Hints Attribute
240
241id_aa_contentHint = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.4')
242
243class ContentHints(univ.Sequence):
244    pass
245
246ContentHints.componentType = namedtype.NamedTypes(
247    namedtype.OptionalNamedType('contentDescription', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),
248    namedtype.NamedType('contentType', ContentType())
249)
250
251
252# Receipt Request Attribute
253
254class AllOrFirstTier(univ.Integer):
255    pass
256
257AllOrFirstTier.namedValues = namedval.NamedValues(
258    ('allReceipts', 0),
259    ('firstTierRecipients', 1)
260)
261
262
263class ReceiptsFrom(univ.Choice):
264    pass
265
266ReceiptsFrom.componentType = namedtype.NamedTypes(
267    namedtype.NamedType('allOrFirstTier', AllOrFirstTier().subtype(
268        implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))),
269    namedtype.NamedType('receiptList', univ.SequenceOf(
270        componentType=GeneralNames()).subtype(implicitTag=tag.Tag(
271        tag.tagClassContext, tag.tagFormatSimple, 1)))
272)
273
274
275id_aa_receiptRequest = univ.ObjectIdentifier('1.2.840.113549.1.9.16.2.1')
276
277ub_receiptsTo = univ.Integer(16)
278
279class ReceiptRequest(univ.Sequence):
280    pass
281
282ReceiptRequest.componentType = namedtype.NamedTypes(
283    namedtype.NamedType('signedContentIdentifier', ContentIdentifier()),
284    namedtype.NamedType('receiptsFrom', ReceiptsFrom()),
285    namedtype.NamedType('receiptsTo', univ.SequenceOf(componentType=GeneralNames()).subtype(sizeSpec=constraint.ValueSizeConstraint(1, ub_receiptsTo)))
286)
287
288# Receipt Content Type
289
290class ESSVersion(univ.Integer):
291    pass
292
293ESSVersion.namedValues = namedval.NamedValues(
294    ('v1', 1)
295)
296
297
298id_ct_receipt = univ.ObjectIdentifier('1.2.840.113549.1.9.16.1.1')
299
300class Receipt(univ.Sequence):
301    pass
302
303Receipt.componentType = namedtype.NamedTypes(
304    namedtype.NamedType('version', ESSVersion()),
305    namedtype.NamedType('contentType', ContentType()),
306    namedtype.NamedType('signedContentIdentifier', ContentIdentifier()),
307    namedtype.NamedType('originatorSignatureValue', univ.OctetString())
308)
309
310
311# Map of Attribute Type to the Attribute structure is added to the
312# ones that are in rfc5652.py
313
314_cmsAttributesMapUpdate = {
315    id_aa_signingCertificate: SigningCertificate(),
316    id_aa_mlExpandHistory: MLExpansionHistory(),
317    id_aa_securityLabel: ESSSecurityLabel(),
318    id_aa_equivalentLabels: EquivalentLabels(),
319    id_aa_contentIdentifier: ContentIdentifier(),
320    id_aa_contentReference: ContentReference(),
321    id_aa_msgSigDigest: MsgSigDigest(),
322    id_aa_contentHint: ContentHints(),
323    id_aa_receiptRequest: ReceiptRequest(),
324}
325
326rfc5652.cmsAttributesMap.update(_cmsAttributesMapUpdate)
327
328
329# Map of Content Type OIDs to Content Types is added to the
330# ones that are in rfc5652.py
331
332_cmsContentTypesMapUpdate = {
333    id_ct_receipt: Receipt(),
334}
335
336rfc5652.cmsContentTypesMap.update(_cmsContentTypesMapUpdate)
337