blob: 7ebcefeb311467a99938bf1f130fb33c872b1f2e [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 PKCS#12 files. Exports the following items:
5
6 - CertBag()
7 - CrlBag()
8 - Pfx()
9 - SafeBag()
10 - SecretBag()
11
12Other type classes are defined that help compose the types listed above.
13"""
14
wbond6b66ab52015-06-21 10:26:45 -040015from __future__ import unicode_literals, division, absolute_import, print_function
wbonde91513e2015-06-03 14:52:18 -040016
17from .algos import DigestInfo
wbond5cf77ba2015-10-08 09:47:34 -040018from .cms import ContentInfo, SignedData
wbonde91513e2015-06-03 14:52:18 -040019from .core import (
20 Any,
wbondb9b75972015-06-15 09:09:17 -040021 BMPString,
wbonde91513e2015-06-03 14:52:18 -040022 Integer,
23 ObjectIdentifier,
24 OctetString,
wbonde5a1c6e2015-08-03 07:42:28 -040025 ParsableOctetString,
wbonde91513e2015-06-03 14:52:18 -040026 Sequence,
27 SequenceOf,
wbondb9b75972015-06-15 09:09:17 -040028 SetOf,
wbonde91513e2015-06-03 14:52:18 -040029)
wbonde91513e2015-06-03 14:52:18 -040030from .keys import PrivateKeyInfo, EncryptedPrivateKeyInfo
Will Bond83eab272017-02-15 06:11:22 -050031from .x509 import Certificate, KeyPurposeId
wbonde91513e2015-06-03 14:52:18 -040032
33
wbonde91513e2015-06-03 14:52:18 -040034# The structures in this file are taken from https://tools.ietf.org/html/rfc7292
35
36class MacData(Sequence):
37 _fields = [
38 ('mac', DigestInfo),
39 ('mac_salt', OctetString),
40 ('iterations', Integer, {'default': 1}),
41 ]
42
43
44class Version(Integer):
45 _map = {
46 3: 'v3'
47 }
48
49
wbondb9b75972015-06-15 09:09:17 -040050class AttributeType(ObjectIdentifier):
51 _map = {
52 # https://tools.ietf.org/html/rfc2985#page-18
53 '1.2.840.113549.1.9.20': 'friendly_name',
54 '1.2.840.113549.1.9.21': 'local_key_id',
55 # https://support.microsoft.com/en-us/kb/287547
56 '1.3.6.1.4.1.311.17.1': 'microsoft_local_machine_keyset',
Anthony Alba3fcf56b2017-02-11 09:02:15 +080057 # https://github.com/frohoff/jdk8u-dev-jdk/blob/master/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java
Anthony Alba850fd3e2017-02-11 13:01:36 +080058 # this is a set of OIDs, representing key usage, the usual value is a SET of one element OID 2.5.29.37.0
59 '2.16.840.1.113894.746875.1.1': 'trusted_key_usage',
wbondb9b75972015-06-15 09:09:17 -040060 }
61
62
wbond7b1cd4b2017-02-10 05:11:14 -050063class SetOfAny(SetOf):
64 _child_spec = Any
65
66
wbondb9b75972015-06-15 09:09:17 -040067class SetOfBMPString(SetOf):
68 _child_spec = BMPString
69
70
71class SetOfOctetString(SetOf):
72 _child_spec = OctetString
73
74
Will Bond83eab272017-02-15 06:11:22 -050075class SetOfKeyPurposeId(SetOf):
76 _child_spec = KeyPurposeId
77
78
wbondb9b75972015-06-15 09:09:17 -040079class Attribute(Sequence):
80 _fields = [
81 ('type', AttributeType),
wbond7b1cd4b2017-02-10 05:11:14 -050082 ('values', None),
wbondb9b75972015-06-15 09:09:17 -040083 ]
84
wbondb9b75972015-06-15 09:09:17 -040085 _oid_specs = {
86 'friendly_name': SetOfBMPString,
87 'local_key_id': SetOfOctetString,
88 'microsoft_csp_name': SetOfBMPString,
Will Bond83eab272017-02-15 06:11:22 -050089 'trusted_key_usage': SetOfKeyPurposeId,
wbondb9b75972015-06-15 09:09:17 -040090 }
91
wbond7b1cd4b2017-02-10 05:11:14 -050092 def _values_spec(self):
93 return self._oid_specs.get(self['type'].native, SetOfAny)
94
95 _spec_callbacks = {
96 'values': _values_spec
97 }
98
wbondb9b75972015-06-15 09:09:17 -040099
wbondaf737d92015-07-01 16:52:05 -0400100class Attributes(SetOf):
wbondb9b75972015-06-15 09:09:17 -0400101 _child_spec = Attribute
102
103
wbonde91513e2015-06-03 14:52:18 -0400104class Pfx(Sequence):
105 _fields = [
106 ('version', Version),
107 ('auth_safe', ContentInfo),
108 ('mac_data', MacData, {'optional': True})
109 ]
110
111 _authenticated_safe = None
112
113 @property
114 def authenticated_safe(self):
115 if self._authenticated_safe is None:
116 content = self['auth_safe']['content']
117 if isinstance(content, SignedData):
118 content = content['content_info']['content']
119 self._authenticated_safe = AuthenticatedSafe.load(content.native)
120 return self._authenticated_safe
121
122
123class AuthenticatedSafe(SequenceOf):
124 _child_spec = ContentInfo
125
126
127class BagId(ObjectIdentifier):
128 _map = {
129 '1.2.840.113549.1.12.10.1.1': 'key_bag',
130 '1.2.840.113549.1.12.10.1.2': 'pkcs8_shrouded_key_bag',
131 '1.2.840.113549.1.12.10.1.3': 'cert_bag',
132 '1.2.840.113549.1.12.10.1.4': 'crl_bag',
133 '1.2.840.113549.1.12.10.1.5': 'secret_bag',
134 '1.2.840.113549.1.12.10.1.6': 'safe_contents',
135 }
136
137
138class CertId(ObjectIdentifier):
139 _map = {
140 '1.2.840.113549.1.9.22.1': 'x509',
141 '1.2.840.113549.1.9.22.2': 'sdsi',
142 }
143
144
145class CertBag(Sequence):
146 _fields = [
147 ('cert_id', CertId),
wbondd62ed9a2017-09-15 07:13:52 -0400148 ('cert_value', ParsableOctetString, {'explicit': 0}),
wbonde91513e2015-06-03 14:52:18 -0400149 ]
150
151 _oid_pair = ('cert_id', 'cert_value')
152 _oid_specs = {
153 'x509': Certificate,
154 }
155
156
157class CrlBag(Sequence):
158 _fields = [
159 ('crl_id', ObjectIdentifier),
wbondd62ed9a2017-09-15 07:13:52 -0400160 ('crl_value', OctetString, {'explicit': 0}),
wbonde91513e2015-06-03 14:52:18 -0400161 ]
162
163
164class SecretBag(Sequence):
165 _fields = [
166 ('secret_type_id', ObjectIdentifier),
wbondd62ed9a2017-09-15 07:13:52 -0400167 ('secret_value', OctetString, {'explicit': 0}),
wbonde91513e2015-06-03 14:52:18 -0400168 ]
169
170
171class SafeContents(SequenceOf):
172 pass
173
174
175class SafeBag(Sequence):
176 _fields = [
177 ('bag_id', BagId),
wbondd62ed9a2017-09-15 07:13:52 -0400178 ('bag_value', Any, {'explicit': 0}),
wbonde91513e2015-06-03 14:52:18 -0400179 ('bag_attributes', Attributes, {'optional': True}),
180 ]
181
182 _oid_pair = ('bag_id', 'bag_value')
183 _oid_specs = {
184 'key_bag': PrivateKeyInfo,
185 'pkcs8_shrouded_key_bag': EncryptedPrivateKeyInfo,
186 'cert_bag': CertBag,
187 'crl_bag': CrlBag,
188 'secret_bag': SecretBag,
189 'safe_contents': SafeContents
190 }
191
192
wbonda26664f2015-10-07 11:57:35 -0400193SafeContents._child_spec = SafeBag