1# This file is being contributed to pyasn1-modules software.
2#
3# Created by Russ Housley with assistance from the asn1ate tool.
4#
5# Copyright (c) 2019, Vigil Security, LLC
6# License: http://snmplabs.com/pyasn1/license.html
7#
8# PKCS #12: Personal Information Exchange Syntax v1.1
9#
10# ASN.1 source from:
11# https://www.rfc-editor.org/rfc/rfc7292.txt
12# https://www.rfc-editor.org/errata_search.php?rfc=7292
13
14from pyasn1.type import char
15from pyasn1.type import constraint
16from pyasn1.type import namedtype
17from pyasn1.type import namedval
18from pyasn1.type import opentype
19from pyasn1.type import tag
20from pyasn1.type import univ
21
22from pyasn1_modules import rfc2315
23from pyasn1_modules import rfc5652
24from pyasn1_modules import rfc5280
25from pyasn1_modules import rfc5958
26
27
28def _OID(*components):
29    output = []
30    for x in tuple(components):
31        if isinstance(x, univ.ObjectIdentifier):
32            output.extend(list(x))
33        else:
34            output.append(int(x))
35
36    return univ.ObjectIdentifier(output)
37
38
39# Initialize the maps used in PKCS#12
40
41pkcs12BagTypeMap = { }
42
43pkcs12CertBagMap = { }
44
45pkcs12CRLBagMap = { }
46
47pkcs12SecretBagMap = { }
48
49
50# Imports from RFC 2315, RFC 5652, and RFC 5958
51
52DigestInfo = rfc2315.DigestInfo
53
54
55ContentInfo = rfc5652.ContentInfo
56
57PKCS12Attribute = rfc5652.Attribute
58
59
60EncryptedPrivateKeyInfo = rfc5958.EncryptedPrivateKeyInfo
61
62PrivateKeyInfo = rfc5958.PrivateKeyInfo
63
64
65# CMSSingleAttribute is the same as Attribute in RFC 5652 except the attrValues
66# SET must have one and only one member
67
68class AttributeType(univ.ObjectIdentifier):
69    pass
70
71
72class AttributeValue(univ.Any):
73    pass
74
75
76class AttributeValues(univ.SetOf):
77    pass
78
79AttributeValues.componentType = AttributeValue()
80
81
82class CMSSingleAttribute(univ.Sequence):
83    pass
84
85CMSSingleAttribute.componentType = namedtype.NamedTypes(
86    namedtype.NamedType('attrType', AttributeType()),
87    namedtype.NamedType('attrValues',
88        AttributeValues().subtype(sizeSpec=constraint.ValueSizeConstraint(1, 1)),
89        openType=opentype.OpenType('attrType', rfc5652.cmsAttributesMap)
90    )
91)
92
93
94# Object identifier arcs
95
96rsadsi = _OID(1, 2, 840, 113549)
97
98pkcs = _OID(rsadsi, 1)
99
100pkcs_9 = _OID(pkcs, 9)
101
102certTypes = _OID(pkcs_9, 22)
103
104crlTypes = _OID(pkcs_9, 23)
105
106pkcs_12 = _OID(pkcs, 12)
107
108
109# PBE Algorithm Identifiers and Parameters Structure
110
111pkcs_12PbeIds = _OID(pkcs_12, 1)
112
113pbeWithSHAAnd128BitRC4 = _OID(pkcs_12PbeIds, 1)
114
115pbeWithSHAAnd40BitRC4 = _OID(pkcs_12PbeIds, 2)
116
117pbeWithSHAAnd3_KeyTripleDES_CBC = _OID(pkcs_12PbeIds, 3)
118
119pbeWithSHAAnd2_KeyTripleDES_CBC = _OID(pkcs_12PbeIds, 4)
120
121pbeWithSHAAnd128BitRC2_CBC = _OID(pkcs_12PbeIds, 5)
122
123pbeWithSHAAnd40BitRC2_CBC = _OID(pkcs_12PbeIds, 6)
124
125
126class Pkcs_12PbeParams(univ.Sequence):
127    pass
128
129Pkcs_12PbeParams.componentType = namedtype.NamedTypes(
130    namedtype.NamedType('salt', univ.OctetString()),
131    namedtype.NamedType('iterations', univ.Integer())
132)
133
134
135# Bag types
136
137bagtypes = _OID(pkcs_12, 10, 1)
138
139class BAG_TYPE(univ.Sequence):
140    pass
141
142BAG_TYPE.componentType = namedtype.NamedTypes(
143    namedtype.NamedType('id', univ.ObjectIdentifier()),
144    namedtype.NamedType('unnamed1', univ.Any(),
145        openType=opentype.OpenType('attrType', pkcs12BagTypeMap)
146    )
147)
148
149
150id_keyBag = _OID(bagtypes, 1)
151
152class KeyBag(PrivateKeyInfo):
153    pass
154
155
156id_pkcs8ShroudedKeyBag = _OID(bagtypes, 2)
157
158class PKCS8ShroudedKeyBag(EncryptedPrivateKeyInfo):
159    pass
160
161
162id_certBag = _OID(bagtypes, 3)
163
164class CertBag(univ.Sequence):
165    pass
166
167CertBag.componentType = namedtype.NamedTypes(
168    namedtype.NamedType('certId', univ.ObjectIdentifier()),
169    namedtype.NamedType('certValue',
170        univ.Any().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)),
171        openType=opentype.OpenType('certId', pkcs12CertBagMap)
172    )
173)
174
175
176x509Certificate = CertBag()
177x509Certificate['certId'] = _OID(certTypes, 1)
178x509Certificate['certValue'] = univ.OctetString()
179# DER-encoded X.509 certificate stored in OCTET STRING
180
181
182sdsiCertificate = CertBag()
183sdsiCertificate['certId'] = _OID(certTypes, 2)
184sdsiCertificate['certValue'] = char.IA5String()
185# Base64-encoded SDSI certificate stored in IA5String
186
187
188id_CRLBag = _OID(bagtypes, 4)
189
190class CRLBag(univ.Sequence):
191    pass
192
193CRLBag.componentType = namedtype.NamedTypes(
194    namedtype.NamedType('crlId', univ.ObjectIdentifier()),
195    namedtype.NamedType('crlValue',
196        univ.Any().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)),
197                openType=opentype.OpenType('crlId', pkcs12CRLBagMap)
198    )
199)
200
201
202x509CRL = CRLBag()
203x509CRL['crlId'] = _OID(crlTypes, 1)
204x509CRL['crlValue'] = univ.OctetString()
205# DER-encoded X.509 CRL stored in OCTET STRING
206
207
208id_secretBag = _OID(bagtypes, 5)
209
210class SecretBag(univ.Sequence):
211    pass
212
213SecretBag.componentType = namedtype.NamedTypes(
214    namedtype.NamedType('secretTypeId', univ.ObjectIdentifier()),
215    namedtype.NamedType('secretValue',
216        univ.Any().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)),
217        openType=opentype.OpenType('secretTypeId', pkcs12SecretBagMap)
218    )
219)
220
221
222id_safeContentsBag = _OID(bagtypes, 6)
223
224class SafeBag(univ.Sequence):
225    pass
226
227SafeBag.componentType = namedtype.NamedTypes(
228    namedtype.NamedType('bagId', univ.ObjectIdentifier()),
229    namedtype.NamedType('bagValue',
230        univ.Any().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)),
231        openType=opentype.OpenType('bagId', pkcs12BagTypeMap)
232    ),
233    namedtype.OptionalNamedType('bagAttributes',
234        univ.SetOf(componentType=PKCS12Attribute())
235    )
236)
237
238
239class SafeContents(univ.SequenceOf):
240    pass
241
242SafeContents.componentType = SafeBag()
243
244
245# The PFX PDU
246
247class AuthenticatedSafe(univ.SequenceOf):
248    pass
249
250AuthenticatedSafe.componentType = ContentInfo()
251# Data if unencrypted
252# EncryptedData if password-encrypted
253# EnvelopedData if public key-encrypted
254
255
256class MacData(univ.Sequence):
257    pass
258
259MacData.componentType = namedtype.NamedTypes(
260    namedtype.NamedType('mac', DigestInfo()),
261    namedtype.NamedType('macSalt', univ.OctetString()),
262    namedtype.DefaultedNamedType('iterations', univ.Integer().subtype(value=1))
263    # Note: The default is for historical reasons and its use is deprecated
264)
265
266
267class PFX(univ.Sequence):
268    pass
269
270PFX.componentType = namedtype.NamedTypes(
271    namedtype.NamedType('version',
272        univ.Integer(namedValues=namedval.NamedValues(('v3', 3)))
273    ),
274    namedtype.NamedType('authSafe', ContentInfo()),
275    namedtype.OptionalNamedType('macData', MacData())
276)
277
278
279# Local key identifier (also defined as certificateAttribute in rfc2985.py)
280
281pkcs_9_at_localKeyId = _OID(pkcs_9, 21)
282
283localKeyId = CMSSingleAttribute()
284localKeyId['attrType'] = pkcs_9_at_localKeyId
285localKeyId['attrValues'][0] = univ.OctetString()
286
287
288# Friendly name (also defined as certificateAttribute in rfc2985.py)
289
290pkcs_9_ub_pkcs9String = univ.Integer(255)
291
292pkcs_9_ub_friendlyName = univ.Integer(pkcs_9_ub_pkcs9String)
293
294pkcs_9_at_friendlyName = _OID(pkcs_9, 20)
295
296class FriendlyName(char.BMPString):
297    pass
298
299FriendlyName.subtypeSpec = constraint.ValueSizeConstraint(1, pkcs_9_ub_friendlyName)
300
301
302friendlyName = CMSSingleAttribute()
303friendlyName['attrType'] = pkcs_9_at_friendlyName
304friendlyName['attrValues'][0] = FriendlyName()
305
306
307# Update the PKCS#12 maps
308
309_pkcs12BagTypeMap = {
310    id_keyBag: KeyBag(),
311    id_pkcs8ShroudedKeyBag: PKCS8ShroudedKeyBag(),
312    id_certBag: CertBag(),
313    id_CRLBag: CRLBag(),
314    id_secretBag: SecretBag(),
315    id_safeContentsBag: SafeBag(),
316}
317
318pkcs12BagTypeMap.update(_pkcs12BagTypeMap)
319
320
321_pkcs12CertBagMap = {
322    _OID(certTypes, 1): univ.OctetString(),
323    _OID(certTypes, 2): char.IA5String(),
324}
325
326pkcs12CertBagMap.update(_pkcs12CertBagMap)
327
328
329_pkcs12CRLBagMap = {
330    _OID(crlTypes, 1): univ.OctetString(),
331}
332
333pkcs12CRLBagMap.update(_pkcs12CRLBagMap)
334
335
336# Update the Algorithm Identifier map
337
338_algorithmIdentifierMapUpdate = {
339    pbeWithSHAAnd128BitRC4: Pkcs_12PbeParams(),
340    pbeWithSHAAnd40BitRC4: Pkcs_12PbeParams(),
341    pbeWithSHAAnd3_KeyTripleDES_CBC: Pkcs_12PbeParams(),
342    pbeWithSHAAnd2_KeyTripleDES_CBC: Pkcs_12PbeParams(),
343    pbeWithSHAAnd128BitRC2_CBC: Pkcs_12PbeParams(),
344    pbeWithSHAAnd40BitRC2_CBC: Pkcs_12PbeParams(),
345}
346
347rfc5280.algorithmIdentifierMap.update(_algorithmIdentifierMapUpdate)
348
349
350# Update the CMS Attribute map
351
352_cmsAttributesMapUpdate = {
353    pkcs_9_at_friendlyName: FriendlyName(),
354    pkcs_9_at_localKeyId: univ.OctetString(),
355}
356
357rfc5652.cmsAttributesMap.update(_cmsAttributesMapUpdate)
358