blob: d49be2607d3c9cd7386d657579c725fa3b425bb8 [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 various algorithms using in various aspects of public
5key cryptography. Exports the following items:
6
7 - AlgorithmIdentifier()
wbondc3d85052017-11-22 11:10:48 -05008 - AnyAlgorithmIdentifier()
wbondea25fc22015-06-19 15:07:04 -04009 - DigestAlgorithm()
10 - DigestInfo()
wbondfb1f98d2017-01-23 12:18:18 -050011 - DSASignature()
wbondea25fc22015-06-19 15:07:04 -040012 - EncryptionAlgorithm()
13 - HmacAlgorithm()
14 - KdfAlgorithm()
15 - Pkcs5MacAlgorithm()
16 - SignedDigestAlgorithm()
17
18Other type classes are defined that help compose the types listed above.
19"""
20
wbond6b66ab52015-06-21 10:26:45 -040021from __future__ import unicode_literals, division, absolute_import, print_function
wbonde91513e2015-06-03 14:52:18 -040022
wbonda26664f2015-10-07 11:57:35 -040023from ._errors import unwrap
wbondfb1f98d2017-01-23 12:18:18 -050024from ._int import fill_width
25from .util import int_from_bytes, int_to_bytes
wbond5cf77ba2015-10-08 09:47:34 -040026from .core import (
27 Any,
28 Choice,
29 Integer,
wbondbfbb4102016-07-21 15:53:40 -040030 Null,
wbond5cf77ba2015-10-08 09:47:34 -040031 ObjectIdentifier,
32 OctetString,
33 Sequence,
wbondbfbb4102016-07-21 15:53:40 -040034 Void,
wbond5cf77ba2015-10-08 09:47:34 -040035)
wbonde91513e2015-06-03 14:52:18 -040036
37
wbond59af99d2015-06-15 16:19:04 -040038# Structures and OIDs in this file are pulled from
39# https://tools.ietf.org/html/rfc3279, https://tools.ietf.org/html/rfc4055,
40# https://tools.ietf.org/html/rfc5758, https://tools.ietf.org/html/rfc7292,
41# http://www.emc.com/collateral/white-papers/h11302-pkcs5v2-1-password-based-cryptography-standard-wp.pdf
wbonde91513e2015-06-03 14:52:18 -040042
43class AlgorithmIdentifier(Sequence):
44 _fields = [
45 ('algorithm', ObjectIdentifier),
46 ('parameters', Any, {'optional': True}),
47 ]
48
49
wbond381a4da2016-08-30 11:39:54 -040050class _ForceNullParameters(object):
51 """
52 Various structures based on AlgorithmIdentifier require that the parameters
53 field be core.Null() for certain OIDs. This mixin ensures that happens.
54 """
55
56 # The following attribute, plus the parameters spec callback and custom
57 # __setitem__ are all to handle a situation where parameters should not be
58 # optional and must be Null for certain OIDs. More info at
wbond09398332016-11-23 06:20:53 -050059 # https://tools.ietf.org/html/rfc4055#page-15 and
60 # https://tools.ietf.org/html/rfc4055#section-2.1
wbond381a4da2016-08-30 11:39:54 -040061 _null_algos = set([
wbond36e6bec2016-11-23 09:33:53 -050062 '1.2.840.113549.1.1.1', # rsassa_pkcs1v15 / rsaes_pkcs1v15 / rsa
63 '1.2.840.113549.1.1.11', # sha256_rsa
64 '1.2.840.113549.1.1.12', # sha384_rsa
65 '1.2.840.113549.1.1.13', # sha512_rsa
66 '1.2.840.113549.1.1.14', # sha224_rsa
67 '1.3.14.3.2.26', # sha1
68 '2.16.840.1.101.3.4.2.4', # sha224
69 '2.16.840.1.101.3.4.2.1', # sha256
70 '2.16.840.1.101.3.4.2.2', # sha384
71 '2.16.840.1.101.3.4.2.3', # sha512
wbond381a4da2016-08-30 11:39:54 -040072 ])
73
74 def _parameters_spec(self):
75 if self._oid_pair == ('algorithm', 'parameters'):
76 algo = self['algorithm'].native
77 if algo in self._oid_specs:
78 return self._oid_specs[algo]
79
80 if self['algorithm'].dotted in self._null_algos:
81 return Null
82
83 return None
84
85 _spec_callbacks = {
86 'parameters': _parameters_spec
87 }
88
89 # We have to override this since the spec callback uses the value of
90 # algorithm to determine the parameter spec, however default values are
91 # assigned before setting a field, so a default value can't be based on
92 # another field value (unless it is a default also). Thus we have to
93 # manually check to see if the algorithm was set and parameters is unset,
94 # and then fix the value as appropriate.
95 def __setitem__(self, key, value):
96 res = super(_ForceNullParameters, self).__setitem__(key, value)
97 if key != 'algorithm':
98 return res
99 if self['algorithm'].dotted not in self._null_algos:
100 return res
101 if self['parameters'].__class__ != Void:
102 return res
103 self['parameters'] = Null()
104 return res
105
106
wbonde91513e2015-06-03 14:52:18 -0400107class HmacAlgorithmId(ObjectIdentifier):
108 _map = {
109 '1.3.14.3.2.10': 'des_mac',
110 '1.2.840.113549.2.7': 'sha1',
111 '1.2.840.113549.2.8': 'sha224',
112 '1.2.840.113549.2.9': 'sha256',
113 '1.2.840.113549.2.10': 'sha384',
114 '1.2.840.113549.2.11': 'sha512',
115 '1.2.840.113549.2.12': 'sha512_224',
116 '1.2.840.113549.2.13': 'sha512_256',
Wim Lewisaa5b3062018-09-21 22:39:24 -0700117 '2.16.840.1.101.3.4.2.13': 'sha3_224',
118 '2.16.840.1.101.3.4.2.14': 'sha3_256',
119 '2.16.840.1.101.3.4.2.15': 'sha3_384',
120 '2.16.840.1.101.3.4.2.16': 'sha3_512',
wbonde91513e2015-06-03 14:52:18 -0400121 }
122
123
124class HmacAlgorithm(Sequence):
125 _fields = [
wbond225418c2015-06-16 00:08:37 -0400126 ('algorithm', HmacAlgorithmId),
wbonde91513e2015-06-03 14:52:18 -0400127 ('parameters', Any, {'optional': True}),
128 ]
129
130
131class DigestAlgorithmId(ObjectIdentifier):
132 _map = {
133 '1.2.840.113549.2.2': 'md2',
134 '1.2.840.113549.2.5': 'md5',
135 '1.3.14.3.2.26': 'sha1',
136 '2.16.840.1.101.3.4.2.4': 'sha224',
137 '2.16.840.1.101.3.4.2.1': 'sha256',
138 '2.16.840.1.101.3.4.2.2': 'sha384',
139 '2.16.840.1.101.3.4.2.3': 'sha512',
wbondb9b75972015-06-15 09:09:17 -0400140 '2.16.840.1.101.3.4.2.5': 'sha512_224',
141 '2.16.840.1.101.3.4.2.6': 'sha512_256',
Wim Lewisaa5b3062018-09-21 22:39:24 -0700142 '2.16.840.1.101.3.4.2.7': 'sha3_224',
143 '2.16.840.1.101.3.4.2.8': 'sha3_256',
144 '2.16.840.1.101.3.4.2.9': 'sha3_384',
145 '2.16.840.1.101.3.4.2.10': 'sha3_512',
146 '2.16.840.1.101.3.4.2.11': 'shake128',
147 '2.16.840.1.101.3.4.2.12': 'shake256',
148 '2.16.840.1.101.3.4.2.17': 'shake128_len',
149 '2.16.840.1.101.3.4.2.18': 'shake256_len',
wbonde91513e2015-06-03 14:52:18 -0400150 }
151
152
wbond09398332016-11-23 06:20:53 -0500153class DigestAlgorithm(_ForceNullParameters, Sequence):
wbonde91513e2015-06-03 14:52:18 -0400154 _fields = [
155 ('algorithm', DigestAlgorithmId),
156 ('parameters', Any, {'optional': True}),
157 ]
158
159
160# This structure is what is signed with a SignedDigestAlgorithm
161class DigestInfo(Sequence):
162 _fields = [
163 ('digest_algorithm', DigestAlgorithm),
164 ('digest', OctetString),
165 ]
166
167
wbond2592ed92015-07-07 23:31:10 -0400168class MaskGenAlgorithmId(ObjectIdentifier):
169 _map = {
170 '1.2.840.113549.1.1.8': 'mgf1',
171 }
172
173
174class MaskGenAlgorithm(Sequence):
175 _fields = [
176 ('algorithm', MaskGenAlgorithmId),
177 ('parameters', Any, {'optional': True}),
178 ]
179
180 _oid_pair = ('algorithm', 'parameters')
181 _oid_specs = {
182 'mgf1': DigestAlgorithm
183 }
184
185
186class TrailerField(Integer):
187 _map = {
188 1: 'trailer_field_bc',
189 }
190
191
192class RSASSAPSSParams(Sequence):
193 _fields = [
194 (
195 'hash_algorithm',
196 DigestAlgorithm,
197 {
wbondd62ed9a2017-09-15 07:13:52 -0400198 'explicit': 0,
wbond2592ed92015-07-07 23:31:10 -0400199 'default': {'algorithm': 'sha1'},
200 }
201 ),
202 (
203 'mask_gen_algorithm',
204 MaskGenAlgorithm,
205 {
wbondd62ed9a2017-09-15 07:13:52 -0400206 'explicit': 1,
wbond2592ed92015-07-07 23:31:10 -0400207 'default': {
208 'algorithm': 'mgf1',
209 'parameters': {'algorithm': 'sha1'},
210 },
211 }
212 ),
213 (
214 'salt_length',
215 Integer,
216 {
wbondd62ed9a2017-09-15 07:13:52 -0400217 'explicit': 2,
wbond2592ed92015-07-07 23:31:10 -0400218 'default': 20,
219 }
220 ),
221 (
222 'trailer_field',
223 TrailerField,
224 {
wbondd62ed9a2017-09-15 07:13:52 -0400225 'explicit': 3,
wbond2592ed92015-07-07 23:31:10 -0400226 'default': 'trailer_field_bc',
227 }
228 ),
229 ]
230
231
wbonde91513e2015-06-03 14:52:18 -0400232class SignedDigestAlgorithmId(ObjectIdentifier):
233 _map = {
234 '1.3.14.3.2.3': 'md5_rsa',
235 '1.3.14.3.2.29': 'sha1_rsa',
236 '1.3.14.7.2.3.1': 'md2_rsa',
237 '1.2.840.113549.1.1.2': 'md2_rsa',
238 '1.2.840.113549.1.1.4': 'md5_rsa',
239 '1.2.840.113549.1.1.5': 'sha1_rsa',
240 '1.2.840.113549.1.1.14': 'sha224_rsa',
241 '1.2.840.113549.1.1.11': 'sha256_rsa',
242 '1.2.840.113549.1.1.12': 'sha384_rsa',
243 '1.2.840.113549.1.1.13': 'sha512_rsa',
wbond2592ed92015-07-07 23:31:10 -0400244 '1.2.840.113549.1.1.10': 'rsassa_pss',
wbonde91513e2015-06-03 14:52:18 -0400245 '1.2.840.10040.4.3': 'sha1_dsa',
246 '1.3.14.3.2.13': 'sha1_dsa',
247 '1.3.14.3.2.27': 'sha1_dsa',
248 '2.16.840.1.101.3.4.3.1': 'sha224_dsa',
249 '2.16.840.1.101.3.4.3.2': 'sha256_dsa',
250 '1.2.840.10045.4.1': 'sha1_ecdsa',
251 '1.2.840.10045.4.3.1': 'sha224_ecdsa',
252 '1.2.840.10045.4.3.2': 'sha256_ecdsa',
253 '1.2.840.10045.4.3.3': 'sha384_ecdsa',
254 '1.2.840.10045.4.3.4': 'sha512_ecdsa',
Wim Lewisaa5b3062018-09-21 22:39:24 -0700255 '2.16.840.1.101.3.4.3.9': 'sha3_224_ecdsa',
256 '2.16.840.1.101.3.4.3.10': 'sha3_256_ecdsa',
257 '2.16.840.1.101.3.4.3.11': 'sha3_384_ecdsa',
258 '2.16.840.1.101.3.4.3.12': 'sha3_512_ecdsa',
wbonde91513e2015-06-03 14:52:18 -0400259 # For when the digest is specified elsewhere in a Sequence
wbond2592ed92015-07-07 23:31:10 -0400260 '1.2.840.113549.1.1.1': 'rsassa_pkcs1v15',
wbonde91513e2015-06-03 14:52:18 -0400261 '1.2.840.10040.4.1': 'dsa',
262 '1.2.840.10045.4': 'ecdsa',
263 }
264
wbondc7b710f2015-11-30 16:50:53 -0500265 _reverse_map = {
266 'dsa': '1.2.840.10040.4.1',
267 'ecdsa': '1.2.840.10045.4',
268 'md2_rsa': '1.2.840.113549.1.1.2',
269 'md5_rsa': '1.2.840.113549.1.1.4',
270 'rsassa_pkcs1v15': '1.2.840.113549.1.1.1',
271 'rsassa_pss': '1.2.840.113549.1.1.10',
272 'sha1_dsa': '1.2.840.10040.4.3',
273 'sha1_ecdsa': '1.2.840.10045.4.1',
274 'sha1_rsa': '1.2.840.113549.1.1.5',
275 'sha224_dsa': '2.16.840.1.101.3.4.3.1',
276 'sha224_ecdsa': '1.2.840.10045.4.3.1',
277 'sha224_rsa': '1.2.840.113549.1.1.14',
278 'sha256_dsa': '2.16.840.1.101.3.4.3.2',
279 'sha256_ecdsa': '1.2.840.10045.4.3.2',
280 'sha256_rsa': '1.2.840.113549.1.1.11',
281 'sha384_ecdsa': '1.2.840.10045.4.3.3',
282 'sha384_rsa': '1.2.840.113549.1.1.12',
283 'sha512_ecdsa': '1.2.840.10045.4.3.4',
284 'sha512_rsa': '1.2.840.113549.1.1.13',
Wim Lewisaa5b3062018-09-21 22:39:24 -0700285 'sha3_224_ecdsa': '2.16.840.1.101.3.4.3.9',
286 'sha3_256_ecdsa': '2.16.840.1.101.3.4.3.10',
287 'sha3_384_ecdsa': '2.16.840.1.101.3.4.3.11',
288 'sha3_512_ecdsa': '2.16.840.1.101.3.4.3.12',
wbondc7b710f2015-11-30 16:50:53 -0500289 }
290
wbonde91513e2015-06-03 14:52:18 -0400291
wbond381a4da2016-08-30 11:39:54 -0400292class SignedDigestAlgorithm(_ForceNullParameters, Sequence):
wbonde91513e2015-06-03 14:52:18 -0400293 _fields = [
294 ('algorithm', SignedDigestAlgorithmId),
295 ('parameters', Any, {'optional': True}),
296 ]
297
wbond381a4da2016-08-30 11:39:54 -0400298 _oid_pair = ('algorithm', 'parameters')
299 _oid_specs = {
300 'rsassa_pss': RSASSAPSSParams,
wbond2592ed92015-07-07 23:31:10 -0400301 }
302
wbond1cfca232015-07-20 08:51:58 -0400303 @property
304 def signature_algo(self):
305 """
306 :return:
307 A unicode string of "rsassa_pkcs1v15", "rsassa_pss", "dsa" or
308 "ecdsa"
309 """
310
311 algorithm = self['algorithm'].native
312
313 algo_map = {
314 'md2_rsa': 'rsassa_pkcs1v15',
315 'md5_rsa': 'rsassa_pkcs1v15',
316 'sha1_rsa': 'rsassa_pkcs1v15',
317 'sha224_rsa': 'rsassa_pkcs1v15',
318 'sha256_rsa': 'rsassa_pkcs1v15',
319 'sha384_rsa': 'rsassa_pkcs1v15',
320 'sha512_rsa': 'rsassa_pkcs1v15',
321 'rsassa_pkcs1v15': 'rsassa_pkcs1v15',
322 'rsassa_pss': 'rsassa_pss',
323 'sha1_dsa': 'dsa',
324 'sha224_dsa': 'dsa',
325 'sha256_dsa': 'dsa',
326 'dsa': 'dsa',
327 'sha1_ecdsa': 'ecdsa',
328 'sha224_ecdsa': 'ecdsa',
329 'sha256_ecdsa': 'ecdsa',
330 'sha384_ecdsa': 'ecdsa',
331 'sha512_ecdsa': 'ecdsa',
Wim Lewisaa5b3062018-09-21 22:39:24 -0700332 'sha3_224_ecdsa': 'ecdsa',
333 'sha3_256_ecdsa': 'ecdsa',
334 'sha3_384_ecdsa': 'ecdsa',
335 'sha3_512_ecdsa': 'ecdsa',
wbond1cfca232015-07-20 08:51:58 -0400336 'ecdsa': 'ecdsa',
337 }
338 if algorithm in algo_map:
339 return algo_map[algorithm]
340
wbonda26664f2015-10-07 11:57:35 -0400341 raise ValueError(unwrap(
342 '''
343 Signature algorithm not known for %s
344 ''',
345 algorithm
346 ))
wbond1cfca232015-07-20 08:51:58 -0400347
348 @property
349 def hash_algo(self):
350 """
351 :return:
352 A unicode string of "md2", "md5", "sha1", "sha224", "sha256",
353 "sha384", "sha512", "sha512_224", "sha512_256"
354 """
355
356 algorithm = self['algorithm'].native
357
358 algo_map = {
359 'md2_rsa': 'md2',
360 'md5_rsa': 'md5',
361 'sha1_rsa': 'sha1',
362 'sha224_rsa': 'sha224',
363 'sha256_rsa': 'sha256',
364 'sha384_rsa': 'sha384',
365 'sha512_rsa': 'sha512',
366 'sha1_dsa': 'sha1',
367 'sha224_dsa': 'sha224',
368 'sha256_dsa': 'sha256',
369 'sha1_ecdsa': 'sha1',
370 'sha224_ecdsa': 'sha224',
371 'sha256_ecdsa': 'sha256',
372 'sha384_ecdsa': 'sha384',
373 'sha512_ecdsa': 'sha512',
374 }
375 if algorithm in algo_map:
376 return algo_map[algorithm]
377
378 if algorithm == 'rsassa_pss':
379 return self['parameters']['hash_algorithm']['algorithm'].native
380
wbonda26664f2015-10-07 11:57:35 -0400381 raise ValueError(unwrap(
382 '''
383 Hash algorithm not known for %s
384 ''',
385 algorithm
386 ))
wbond1cfca232015-07-20 08:51:58 -0400387
wbonde91513e2015-06-03 14:52:18 -0400388
wbond59af99d2015-06-15 16:19:04 -0400389class Pbkdf2Salt(Choice):
wbond225418c2015-06-16 00:08:37 -0400390 _alternatives = [
wbond59af99d2015-06-15 16:19:04 -0400391 ('specified', OctetString),
392 ('other_source', AlgorithmIdentifier),
393 ]
394
395
396class Pbkdf2Params(Sequence):
397 _fields = [
398 ('salt', Pbkdf2Salt),
399 ('iteration_count', Integer),
400 ('key_length', Integer, {'optional': True}),
wbond225418c2015-06-16 00:08:37 -0400401 ('prf', HmacAlgorithm, {'default': {'algorithm': 'sha1'}}),
wbond59af99d2015-06-15 16:19:04 -0400402 ]
403
404
405class KdfAlgorithmId(ObjectIdentifier):
406 _map = {
407 '1.2.840.113549.1.5.12': 'pbkdf2'
408 }
409
410
411class KdfAlgorithm(Sequence):
412 _fields = [
413 ('algorithm', KdfAlgorithmId),
414 ('parameters', Any, {'optional': True}),
415 ]
416 _oid_pair = ('algorithm', 'parameters')
417 _oid_specs = {
418 'pbkdf2': Pbkdf2Params
419 }
420
421
wbond88ba5ee2016-03-17 11:39:22 -0400422class DHParameters(Sequence):
423 """
424 Original Name: DHParameter
425 Source: ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-3.asc section 9
426 """
427
428 _fields = [
429 ('p', Integer),
430 ('g', Integer),
431 ('private_value_length', Integer, {'optional': True}),
432 ]
433
434
435class KeyExchangeAlgorithmId(ObjectIdentifier):
436 _map = {
437 '1.2.840.113549.1.3.1': 'dh',
438 }
439
440
441class KeyExchangeAlgorithm(Sequence):
442 _fields = [
443 ('algorithm', KeyExchangeAlgorithmId),
444 ('parameters', Any, {'optional': True}),
445 ]
446 _oid_pair = ('algorithm', 'parameters')
447 _oid_specs = {
448 'dh': DHParameters,
449 }
450
451
wbonde91513e2015-06-03 14:52:18 -0400452class Rc2Params(Sequence):
453 _fields = [
454 ('rc2_parameter_version', Integer, {'optional': True}),
455 ('iv', OctetString),
456 ]
457
458
459class Rc5ParamVersion(Integer):
460 _map = {
461 16: 'v1-0'
462 }
463
464
465class Rc5Params(Sequence):
466 _fields = [
467 ('version', Rc5ParamVersion),
468 ('rounds', Integer),
469 ('block_size_in_bits', Integer),
470 ('iv', OctetString, {'optional': True}),
471 ]
472
473
wbond59af99d2015-06-15 16:19:04 -0400474class Pbes1Params(Sequence):
475 _fields = [
476 ('salt', OctetString),
477 ('iterations', Integer),
478 ]
479
480
Anthony Albabfa0d5a2018-01-19 08:07:11 +0800481class CcmParams(Sequence):
482 # https://tools.ietf.org/html/rfc5084
483 # aes_ICVlen: 4 | 6 | 8 | 10 | 12 | 14 | 16
484 _fields = [
485 ('aes_nonce', OctetString),
Anthony Albaa022f692018-01-28 09:42:32 +0800486 ('aes_icvlen', Integer),
Anthony Albabfa0d5a2018-01-19 08:07:11 +0800487 ]
488
489
wbond2592ed92015-07-07 23:31:10 -0400490class PSourceAlgorithmId(ObjectIdentifier):
491 _map = {
492 '1.2.840.113549.1.1.9': 'p_specified',
493 }
494
495
496class PSourceAlgorithm(Sequence):
497 _fields = [
498 ('algorithm', PSourceAlgorithmId),
499 ('parameters', Any, {'optional': True}),
500 ]
501
502 _oid_pair = ('algorithm', 'parameters')
503 _oid_specs = {
504 'p_specified': OctetString
505 }
506
507
508class RSAESOAEPParams(Sequence):
509 _fields = [
510 (
511 'hash_algorithm',
512 DigestAlgorithm,
513 {
wbondd62ed9a2017-09-15 07:13:52 -0400514 'explicit': 0,
wbond2592ed92015-07-07 23:31:10 -0400515 'default': {'algorithm': 'sha1'}
516 }
517 ),
518 (
519 'mask_gen_algorithm',
520 MaskGenAlgorithm,
521 {
wbondd62ed9a2017-09-15 07:13:52 -0400522 'explicit': 1,
wbond2592ed92015-07-07 23:31:10 -0400523 'default': {
524 'algorithm': 'mgf1',
525 'parameters': {'algorithm': 'sha1'}
526 }
527 }
528 ),
529 (
530 'p_source_algorithm',
531 PSourceAlgorithm,
532 {
wbondd62ed9a2017-09-15 07:13:52 -0400533 'explicit': 2,
wbond2592ed92015-07-07 23:31:10 -0400534 'default': {
535 'algorithm': 'p_specified',
536 'parameters': b''
537 }
538 }
539 ),
540 ]
541
542
wbondfb1f98d2017-01-23 12:18:18 -0500543class DSASignature(Sequence):
544 """
545 An ASN.1 class for translating between the OS crypto library's
546 representation of an (EC)DSA signature and the ASN.1 structure that is part
547 of various RFCs.
548
549 Original Name: DSS-Sig-Value
550 Source: https://tools.ietf.org/html/rfc3279#section-2.2.2
551 """
552
553 _fields = [
554 ('r', Integer),
555 ('s', Integer),
556 ]
557
558 @classmethod
559 def from_p1363(cls, data):
560 """
561 Reads a signature from a byte string encoding accordint to IEEE P1363,
562 which is used by Microsoft's BCryptSignHash() function.
563
564 :param data:
565 A byte string from BCryptSignHash()
566
567 :return:
568 A DSASignature object
569 """
570
571 r = int_from_bytes(data[0:len(data) // 2])
572 s = int_from_bytes(data[len(data) // 2:])
573 return cls({'r': r, 's': s})
574
575 def to_p1363(self):
576 """
577 Dumps a signature to a byte string compatible with Microsoft's
578 BCryptVerifySignature() function.
579
580 :return:
581 A byte string compatible with BCryptVerifySignature()
582 """
583
584 r_bytes = int_to_bytes(self['r'].native)
585 s_bytes = int_to_bytes(self['s'].native)
586
587 int_byte_length = max(len(r_bytes), len(s_bytes))
588 r_bytes = fill_width(r_bytes, int_byte_length)
589 s_bytes = fill_width(s_bytes, int_byte_length)
590
591 return r_bytes + s_bytes
592
593
wbonde91513e2015-06-03 14:52:18 -0400594class EncryptionAlgorithmId(ObjectIdentifier):
595 _map = {
596 '1.3.14.3.2.7': 'des',
597 '1.2.840.113549.3.7': 'tripledes_3key',
598 '1.2.840.113549.3.2': 'rc2',
wbond6a7dba82019-08-01 22:00:53 -0400599 '1.2.840.113549.3.4': 'rc4',
wbonde91513e2015-06-03 14:52:18 -0400600 '1.2.840.113549.3.9': 'rc5',
eukaryotea7bbfc92015-11-02 10:19:01 -0800601 # From http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html#AES
602 '2.16.840.1.101.3.4.1.1': 'aes128_ecb',
603 '2.16.840.1.101.3.4.1.2': 'aes128_cbc',
604 '2.16.840.1.101.3.4.1.3': 'aes128_ofb',
605 '2.16.840.1.101.3.4.1.4': 'aes128_cfb',
606 '2.16.840.1.101.3.4.1.5': 'aes128_wrap',
607 '2.16.840.1.101.3.4.1.6': 'aes128_gcm',
608 '2.16.840.1.101.3.4.1.7': 'aes128_ccm',
609 '2.16.840.1.101.3.4.1.8': 'aes128_wrap_pad',
610 '2.16.840.1.101.3.4.1.21': 'aes192_ecb',
611 '2.16.840.1.101.3.4.1.22': 'aes192_cbc',
612 '2.16.840.1.101.3.4.1.23': 'aes192_ofb',
613 '2.16.840.1.101.3.4.1.24': 'aes192_cfb',
614 '2.16.840.1.101.3.4.1.25': 'aes192_wrap',
615 '2.16.840.1.101.3.4.1.26': 'aes192_gcm',
616 '2.16.840.1.101.3.4.1.27': 'aes192_ccm',
617 '2.16.840.1.101.3.4.1.28': 'aes192_wrap_pad',
618 '2.16.840.1.101.3.4.1.41': 'aes256_ecb',
619 '2.16.840.1.101.3.4.1.42': 'aes256_cbc',
620 '2.16.840.1.101.3.4.1.43': 'aes256_ofb',
621 '2.16.840.1.101.3.4.1.44': 'aes256_cfb',
622 '2.16.840.1.101.3.4.1.45': 'aes256_wrap',
623 '2.16.840.1.101.3.4.1.46': 'aes256_gcm',
624 '2.16.840.1.101.3.4.1.47': 'aes256_ccm',
625 '2.16.840.1.101.3.4.1.48': 'aes256_wrap_pad',
wbond59af99d2015-06-15 16:19:04 -0400626 # From PKCS#5
627 '1.2.840.113549.1.5.13': 'pbes2',
628 '1.2.840.113549.1.5.1': 'pbes1_md2_des',
629 '1.2.840.113549.1.5.3': 'pbes1_md5_des',
630 '1.2.840.113549.1.5.4': 'pbes1_md2_rc2',
631 '1.2.840.113549.1.5.6': 'pbes1_md5_rc2',
632 '1.2.840.113549.1.5.10': 'pbes1_sha1_des',
633 '1.2.840.113549.1.5.11': 'pbes1_sha1_rc2',
634 # From PKCS#12
635 '1.2.840.113549.1.12.1.1': 'pkcs12_sha1_rc4_128',
636 '1.2.840.113549.1.12.1.2': 'pkcs12_sha1_rc4_40',
637 '1.2.840.113549.1.12.1.3': 'pkcs12_sha1_tripledes_3key',
638 '1.2.840.113549.1.12.1.4': 'pkcs12_sha1_tripledes_2key',
639 '1.2.840.113549.1.12.1.5': 'pkcs12_sha1_rc2_128',
640 '1.2.840.113549.1.12.1.6': 'pkcs12_sha1_rc2_40',
wbond2592ed92015-07-07 23:31:10 -0400641 # PKCS#1 v2.2
642 '1.2.840.113549.1.1.1': 'rsaes_pkcs1v15',
643 '1.2.840.113549.1.1.7': 'rsaes_oaep',
wbonde91513e2015-06-03 14:52:18 -0400644 }
645
646
wbond381a4da2016-08-30 11:39:54 -0400647class EncryptionAlgorithm(_ForceNullParameters, Sequence):
wbonde91513e2015-06-03 14:52:18 -0400648 _fields = [
649 ('algorithm', EncryptionAlgorithmId),
650 ('parameters', Any, {'optional': True}),
651 ]
652
653 _oid_pair = ('algorithm', 'parameters')
654 _oid_specs = {
655 'des': OctetString,
656 'tripledes_3key': OctetString,
657 'rc2': Rc2Params,
658 'rc5': Rc5Params,
wbond277d76d2015-11-02 17:16:46 -0500659 'aes128_cbc': OctetString,
660 'aes192_cbc': OctetString,
661 'aes256_cbc': OctetString,
662 'aes128_ofb': OctetString,
663 'aes192_ofb': OctetString,
664 'aes256_ofb': OctetString,
Anthony Albabfa0d5a2018-01-19 08:07:11 +0800665 # From RFC5084
666 'aes128_ccm': CcmParams,
667 'aes192_ccm': CcmParams,
668 'aes256_ccm': CcmParams,
wbond59af99d2015-06-15 16:19:04 -0400669 # From PKCS#5
670 'pbes1_md2_des': Pbes1Params,
671 'pbes1_md5_des': Pbes1Params,
672 'pbes1_md2_rc2': Pbes1Params,
673 'pbes1_md5_rc2': Pbes1Params,
674 'pbes1_sha1_des': Pbes1Params,
675 'pbes1_sha1_rc2': Pbes1Params,
676 # From PKCS#12
677 'pkcs12_sha1_rc4_128': Pbes1Params,
678 'pkcs12_sha1_rc4_40': Pbes1Params,
679 'pkcs12_sha1_tripledes_3key': Pbes1Params,
680 'pkcs12_sha1_tripledes_2key': Pbes1Params,
681 'pkcs12_sha1_rc2_128': Pbes1Params,
682 'pkcs12_sha1_rc2_40': Pbes1Params,
wbond2592ed92015-07-07 23:31:10 -0400683 # PKCS#1 v2.2
684 'rsaes_oaep': RSAESOAEPParams,
wbonde91513e2015-06-03 14:52:18 -0400685 }
wbondb5354a42015-06-15 15:21:59 -0400686
687 @property
wbond59af99d2015-06-15 16:19:04 -0400688 def kdf(self):
689 """
690 Returns the name of the key derivation function to use.
691
692 :return:
wbonda26664f2015-10-07 11:57:35 -0400693 A unicode from of one of the following: "pbkdf1", "pbkdf2",
694 "pkcs12_kdf"
wbond59af99d2015-06-15 16:19:04 -0400695 """
696
697 encryption_algo = self['algorithm'].native
698
699 if encryption_algo == 'pbes2':
wbond225418c2015-06-16 00:08:37 -0400700 return self['parameters']['key_derivation_func']['algorithm'].native
wbond59af99d2015-06-15 16:19:04 -0400701
702 if encryption_algo.find('.') == -1:
703 if encryption_algo.find('_') != -1:
704 encryption_algo, _ = encryption_algo.split('_', 1)
705
706 if encryption_algo == 'pbes1':
707 return 'pbkdf1'
708
709 if encryption_algo == 'pkcs12':
710 return 'pkcs12_kdf'
711
wbonda26664f2015-10-07 11:57:35 -0400712 raise ValueError(unwrap(
713 '''
714 Encryption algorithm "%s" does not have a registered key
715 derivation function
716 ''',
717 encryption_algo
718 ))
wbond59af99d2015-06-15 16:19:04 -0400719
wbonda26664f2015-10-07 11:57:35 -0400720 raise ValueError(unwrap(
721 '''
722 Unrecognized encryption algorithm "%s", can not determine key
723 derivation function
724 ''',
725 encryption_algo
726 ))
wbond59af99d2015-06-15 16:19:04 -0400727
728 @property
729 def kdf_hmac(self):
730 """
731 Returns the HMAC algorithm to use with the KDF.
732
733 :return:
wbonda26664f2015-10-07 11:57:35 -0400734 A unicode string of one of the following: "md2", "md5", "sha1",
735 "sha224", "sha256", "sha384", "sha512"
wbond59af99d2015-06-15 16:19:04 -0400736 """
737
738 encryption_algo = self['algorithm'].native
739
740 if encryption_algo == 'pbes2':
wbond225418c2015-06-16 00:08:37 -0400741 return self['parameters']['key_derivation_func']['parameters']['prf']['algorithm'].native
wbond59af99d2015-06-15 16:19:04 -0400742
743 if encryption_algo.find('.') == -1:
744 if encryption_algo.find('_') != -1:
745 _, hmac_algo, _ = encryption_algo.split('_', 2)
746 return hmac_algo
747
wbonda26664f2015-10-07 11:57:35 -0400748 raise ValueError(unwrap(
749 '''
750 Encryption algorithm "%s" does not have a registered key
751 derivation function
752 ''',
753 encryption_algo
754 ))
wbond59af99d2015-06-15 16:19:04 -0400755
wbonda26664f2015-10-07 11:57:35 -0400756 raise ValueError(unwrap(
757 '''
758 Unrecognized encryption algorithm "%s", can not determine key
759 derivation hmac algorithm
760 ''',
761 encryption_algo
762 ))
wbond59af99d2015-06-15 16:19:04 -0400763
764 @property
765 def kdf_salt(self):
766 """
767 Returns the byte string to use as the salt for the KDF.
768
769 :return:
770 A byte string
771 """
772
773 encryption_algo = self['algorithm'].native
774
775 if encryption_algo == 'pbes2':
wbond225418c2015-06-16 00:08:37 -0400776 salt = self['parameters']['key_derivation_func']['parameters']['salt']
wbond59af99d2015-06-15 16:19:04 -0400777
778 if salt.name == 'other_source':
wbonda26664f2015-10-07 11:57:35 -0400779 raise ValueError(unwrap(
780 '''
781 Can not determine key derivation salt - the
782 reserved-for-future-use other source salt choice was
783 specified in the PBKDF2 params structure
784 '''
785 ))
wbond59af99d2015-06-15 16:19:04 -0400786
787 return salt.native
788
789 if encryption_algo.find('.') == -1:
790 if encryption_algo.find('_') != -1:
791 return self['parameters']['salt'].native
792
wbonda26664f2015-10-07 11:57:35 -0400793 raise ValueError(unwrap(
794 '''
795 Encryption algorithm "%s" does not have a registered key
796 derivation function
797 ''',
798 encryption_algo
799 ))
wbond59af99d2015-06-15 16:19:04 -0400800
wbonda26664f2015-10-07 11:57:35 -0400801 raise ValueError(unwrap(
802 '''
803 Unrecognized encryption algorithm "%s", can not determine key
804 derivation salt
805 ''',
806 encryption_algo
807 ))
wbond59af99d2015-06-15 16:19:04 -0400808
809 @property
810 def kdf_iterations(self):
811 """
812 Returns the number of iterations that should be run via the KDF.
813
814 :return:
815 An integer
816 """
817
818 encryption_algo = self['algorithm'].native
819
820 if encryption_algo == 'pbes2':
wbond225418c2015-06-16 00:08:37 -0400821 return self['parameters']['key_derivation_func']['parameters']['iteration_count'].native
wbond59af99d2015-06-15 16:19:04 -0400822
823 if encryption_algo.find('.') == -1:
824 if encryption_algo.find('_') != -1:
825 return self['parameters']['iterations'].native
826
wbonda26664f2015-10-07 11:57:35 -0400827 raise ValueError(unwrap(
828 '''
829 Encryption algorithm "%s" does not have a registered key
830 derivation function
831 ''',
832 encryption_algo
833 ))
wbond59af99d2015-06-15 16:19:04 -0400834
wbonda26664f2015-10-07 11:57:35 -0400835 raise ValueError(unwrap(
836 '''
837 Unrecognized encryption algorithm "%s", can not determine key
838 derivation iterations
839 ''',
840 encryption_algo
841 ))
wbond59af99d2015-06-15 16:19:04 -0400842
843 @property
wbondb5354a42015-06-15 15:21:59 -0400844 def key_length(self):
845 """
wbond59af99d2015-06-15 16:19:04 -0400846 Returns the key length to pass to the cipher/kdf. The PKCS#5 spec does
wbondb5354a42015-06-15 15:21:59 -0400847 not specify a way to store the RC5 key length, however this tends not
848 to be a problem since OpenSSL does not support RC5 in PKCS#8 and OS X
849 does not provide an RC5 cipher for use in the Security Transforms
850 library.
851
852 :raises:
853 ValueError - when the key length can not be determined
854
855 :return:
856 An integer representing the length in bytes
857 """
858
wbond59af99d2015-06-15 16:19:04 -0400859 encryption_algo = self['algorithm'].native
wbondb5354a42015-06-15 15:21:59 -0400860
wbond277d76d2015-11-02 17:16:46 -0500861 if encryption_algo[0:3] == 'aes':
862 return {
863 'aes128_': 16,
864 'aes192_': 24,
865 'aes256_': 32,
866 }[encryption_algo[0:7]]
867
wbondb5354a42015-06-15 15:21:59 -0400868 cipher_lengths = {
869 'des': 8,
870 'tripledes_3key': 24,
wbondb5354a42015-06-15 15:21:59 -0400871 }
872
wbond59af99d2015-06-15 16:19:04 -0400873 if encryption_algo in cipher_lengths:
874 return cipher_lengths[encryption_algo]
wbondb5354a42015-06-15 15:21:59 -0400875
wbond59af99d2015-06-15 16:19:04 -0400876 if encryption_algo == 'rc2':
wbondb5354a42015-06-15 15:21:59 -0400877 rc2_params = self['parameters'].parsed['encryption_scheme']['parameters'].parsed
878 rc2_parameter_version = rc2_params['rc2_parameter_version'].native
879
wbonda26664f2015-10-07 11:57:35 -0400880 # See page 24 of
881 # http://www.emc.com/collateral/white-papers/h11302-pkcs5v2-1-password-based-cryptography-standard-wp.pdf
wbondb5354a42015-06-15 15:21:59 -0400882 encoded_key_bits_map = {
883 160: 5, # 40-bit
884 120: 8, # 64-bit
wbonda26664f2015-10-07 11:57:35 -0400885 58: 16, # 128-bit
wbondb5354a42015-06-15 15:21:59 -0400886 }
887
888 if rc2_parameter_version in encoded_key_bits_map:
889 return encoded_key_bits_map[rc2_parameter_version]
890
891 if rc2_parameter_version >= 256:
892 return rc2_parameter_version
893
894 if rc2_parameter_version is None:
895 return 4 # 32-bit default
896
wbonda26664f2015-10-07 11:57:35 -0400897 raise ValueError(unwrap(
898 '''
899 Invalid RC2 parameter version found in EncryptionAlgorithm
900 parameters
901 '''
902 ))
wbondb5354a42015-06-15 15:21:59 -0400903
wbond59af99d2015-06-15 16:19:04 -0400904 if encryption_algo == 'pbes2':
wbond225418c2015-06-16 00:08:37 -0400905 key_length = self['parameters']['key_derivation_func']['parameters']['key_length'].native
wbond59af99d2015-06-15 16:19:04 -0400906 if key_length is not None:
907 return key_length
908
909 # If the KDF params don't specify the key size, we can infer it from
910 # the encryption scheme for all schemes except for RC5. However, in
911 # practical terms, neither OpenSSL or OS X support RC5 for PKCS#8
912 # so it is unlikely to be an issue that is run into.
913
914 return self['parameters']['encryption_scheme'].key_length
915
916 if encryption_algo.find('.') == -1:
917 return {
918 'pbes1_md2_des': 8,
919 'pbes1_md5_des': 8,
920 'pbes1_md2_rc2': 8,
921 'pbes1_md5_rc2': 8,
922 'pbes1_sha1_des': 8,
923 'pbes1_sha1_rc2': 8,
924 'pkcs12_sha1_rc4_128': 16,
925 'pkcs12_sha1_rc4_40': 5,
926 'pkcs12_sha1_tripledes_3key': 24,
927 'pkcs12_sha1_tripledes_2key': 16,
928 'pkcs12_sha1_rc2_128': 16,
929 'pkcs12_sha1_rc2_40': 5,
930 }[encryption_algo]
931
wbonda26664f2015-10-07 11:57:35 -0400932 raise ValueError(unwrap(
933 '''
934 Unrecognized encryption algorithm "%s"
935 ''',
936 encryption_algo
937 ))
wbondb5354a42015-06-15 15:21:59 -0400938
939 @property
wbond277d76d2015-11-02 17:16:46 -0500940 def encryption_mode(self):
941 """
942 Returns the name of the encryption mode to use.
943
944 :return:
945 A unicode string from one of the following: "cbc", "ecb", "ofb",
946 "cfb", "wrap", "gcm", "ccm", "wrap_pad"
947 """
948
949 encryption_algo = self['algorithm'].native
950
951 if encryption_algo[0:7] in set(['aes128_', 'aes192_', 'aes256_']):
952 return encryption_algo[7:]
953
954 if encryption_algo[0:6] == 'pbes1_':
955 return 'cbc'
956
957 if encryption_algo[0:7] == 'pkcs12_':
958 return 'cbc'
959
960 if encryption_algo in set(['des', 'tripledes_3key', 'rc2', 'rc5']):
961 return 'cbc'
962
963 if encryption_algo == 'pbes2':
964 return self['parameters']['encryption_scheme'].encryption_mode
965
966 raise ValueError(unwrap(
967 '''
968 Unrecognized encryption algorithm "%s"
969 ''',
970 encryption_algo
971 ))
972
973 @property
wbondb5354a42015-06-15 15:21:59 -0400974 def encryption_cipher(self):
975 """
976 Returns the name of the symmetric encryption cipher to use. The key
977 length can be retrieved via the .key_length property to disabiguate
978 between different variations of TripleDES, AES, and the RC* ciphers.
979
980 :return:
wbonda26664f2015-10-07 11:57:35 -0400981 A unicode string from one of the following: "rc2", "rc5", "des",
982 "tripledes", "aes"
wbondb5354a42015-06-15 15:21:59 -0400983 """
984
wbond59af99d2015-06-15 16:19:04 -0400985 encryption_algo = self['algorithm'].native
wbondb5354a42015-06-15 15:21:59 -0400986
wbond277d76d2015-11-02 17:16:46 -0500987 if encryption_algo[0:7] in set(['aes128_', 'aes192_', 'aes256_']):
988 return 'aes'
989
990 if encryption_algo in set(['des', 'rc2', 'rc5']):
991 return encryption_algo
992
993 if encryption_algo == 'tripledes_3key':
994 return 'tripledes'
wbondb5354a42015-06-15 15:21:59 -0400995
wbond59af99d2015-06-15 16:19:04 -0400996 if encryption_algo == 'pbes2':
997 return self['parameters']['encryption_scheme'].encryption_cipher
998
999 if encryption_algo.find('.') == -1:
1000 return {
1001 'pbes1_md2_des': 'des',
1002 'pbes1_md5_des': 'des',
1003 'pbes1_md2_rc2': 'rc2',
1004 'pbes1_md5_rc2': 'rc2',
1005 'pbes1_sha1_des': 'des',
1006 'pbes1_sha1_rc2': 'rc2',
1007 'pkcs12_sha1_rc4_128': 'rc4',
1008 'pkcs12_sha1_rc4_40': 'rc4',
1009 'pkcs12_sha1_tripledes_3key': 'tripledes',
1010 'pkcs12_sha1_tripledes_2key': 'tripledes',
1011 'pkcs12_sha1_rc2_128': 'rc2',
1012 'pkcs12_sha1_rc2_40': 'rc2',
1013 }[encryption_algo]
1014
wbonda26664f2015-10-07 11:57:35 -04001015 raise ValueError(unwrap(
1016 '''
1017 Unrecognized encryption algorithm "%s"
1018 ''',
1019 encryption_algo
1020 ))
wbondb5354a42015-06-15 15:21:59 -04001021
1022 @property
1023 def encryption_block_size(self):
1024 """
1025 Returns the block size of the encryption cipher, in bytes.
1026
1027 :return:
1028 An integer that is the block size in bytes
1029 """
1030
wbond59af99d2015-06-15 16:19:04 -04001031 encryption_algo = self['algorithm'].native
wbondb5354a42015-06-15 15:21:59 -04001032
wbond277d76d2015-11-02 17:16:46 -05001033 if encryption_algo[0:7] in set(['aes128_', 'aes192_', 'aes256_']):
1034 return 16
1035
wbondb5354a42015-06-15 15:21:59 -04001036 cipher_map = {
1037 'des': 8,
1038 'tripledes_3key': 8,
wbondb5354a42015-06-15 15:21:59 -04001039 'rc2': 8,
1040 }
wbond59af99d2015-06-15 16:19:04 -04001041 if encryption_algo in cipher_map:
1042 return cipher_map[encryption_algo]
wbondb5354a42015-06-15 15:21:59 -04001043
wbond59af99d2015-06-15 16:19:04 -04001044 if encryption_algo == 'rc5':
wbondb5354a42015-06-15 15:21:59 -04001045 return self['parameters'].parsed['block_size_in_bits'].native / 8
1046
wbond59af99d2015-06-15 16:19:04 -04001047 if encryption_algo == 'pbes2':
1048 return self['parameters']['encryption_scheme'].encryption_block_size
1049
1050 if encryption_algo.find('.') == -1:
1051 return {
1052 'pbes1_md2_des': 8,
1053 'pbes1_md5_des': 8,
1054 'pbes1_md2_rc2': 8,
1055 'pbes1_md5_rc2': 8,
1056 'pbes1_sha1_des': 8,
1057 'pbes1_sha1_rc2': 8,
1058 'pkcs12_sha1_rc4_128': 0,
1059 'pkcs12_sha1_rc4_40': 0,
1060 'pkcs12_sha1_tripledes_3key': 8,
1061 'pkcs12_sha1_tripledes_2key': 8,
1062 'pkcs12_sha1_rc2_128': 8,
1063 'pkcs12_sha1_rc2_40': 8,
1064 }[encryption_algo]
1065
wbonda26664f2015-10-07 11:57:35 -04001066 raise ValueError(unwrap(
1067 '''
1068 Unrecognized encryption algorithm "%s"
1069 ''',
1070 encryption_algo
1071 ))
wbondb5354a42015-06-15 15:21:59 -04001072
1073 @property
1074 def encryption_iv(self):
1075 """
1076 Returns the byte string of the initialization vector for the encryption
1077 scheme. Only the PBES2 stores the IV in the params. For PBES1, the IV
1078 is derived from the KDF and this property will return None.
1079
1080 :return:
1081 A byte string or None
1082 """
1083
wbond59af99d2015-06-15 16:19:04 -04001084 encryption_algo = self['algorithm'].native
wbondb5354a42015-06-15 15:21:59 -04001085
wbond277d76d2015-11-02 17:16:46 -05001086 if encryption_algo in set(['rc2', 'rc5']):
wbondb5354a42015-06-15 15:21:59 -04001087 return self['parameters'].parsed['iv'].native
1088
1089 # For DES/Triple DES and AES the IV is the entirety of the parameters
wbond277d76d2015-11-02 17:16:46 -05001090 octet_string_iv_oids = set([
1091 'des',
1092 'tripledes_3key',
1093 'aes128_cbc',
1094 'aes192_cbc',
1095 'aes256_cbc',
1096 'aes128_ofb',
1097 'aes192_ofb',
1098 'aes256_ofb',
1099 ])
1100 if encryption_algo in octet_string_iv_oids:
wbondb5354a42015-06-15 15:21:59 -04001101 return self['parameters'].native
1102
wbond59af99d2015-06-15 16:19:04 -04001103 if encryption_algo == 'pbes2':
1104 return self['parameters']['encryption_scheme'].encryption_iv
1105
1106 # All of the PBES1 algos use their KDF to create the IV. For the pbkdf1,
1107 # the KDF is told to generate a key that is an extra 8 bytes long, and
1108 # that is used for the IV. For the PKCS#12 KDF, it is called with an id
1109 # of 2 to generate the IV. In either case, we can't return the IV
1110 # without knowing the user's password.
1111 if encryption_algo.find('.') == -1:
1112 return None
1113
wbonda26664f2015-10-07 11:57:35 -04001114 raise ValueError(unwrap(
1115 '''
1116 Unrecognized encryption algorithm "%s"
1117 ''',
1118 encryption_algo
1119 ))
wbond59af99d2015-06-15 16:19:04 -04001120
1121
1122class Pbes2Params(Sequence):
1123 _fields = [
1124 ('key_derivation_func', KdfAlgorithm),
1125 ('encryption_scheme', EncryptionAlgorithm),
1126 ]
1127
1128
1129class Pbmac1Params(Sequence):
1130 _fields = [
1131 ('key_derivation_func', KdfAlgorithm),
1132 ('message_auth_scheme', HmacAlgorithm),
1133 ]
1134
1135
1136class Pkcs5MacId(ObjectIdentifier):
1137 _map = {
1138 '1.2.840.113549.1.5.14': 'pbmac1',
1139 }
1140
1141
1142class Pkcs5MacAlgorithm(Sequence):
1143 _fields = [
1144 ('algorithm', Pkcs5MacId),
1145 ('parameters', Any),
1146 ]
1147
1148 _oid_pair = ('algorithm', 'parameters')
1149 _oid_specs = {
1150 'pbmac1': Pbmac1Params,
1151 }
1152
1153
wbonda26664f2015-10-07 11:57:35 -04001154EncryptionAlgorithm._oid_specs['pbes2'] = Pbes2Params
wbondc3d85052017-11-22 11:10:48 -05001155
1156
1157class AnyAlgorithmId(ObjectIdentifier):
1158 _map = {}
1159
1160 def _setup(self):
1161 _map = self.__class__._map
1162 for other_cls in (EncryptionAlgorithmId, SignedDigestAlgorithmId, DigestAlgorithmId):
1163 for oid, name in other_cls._map.items():
1164 _map[oid] = name
1165
1166
1167class AnyAlgorithmIdentifier(_ForceNullParameters, Sequence):
1168 _fields = [
1169 ('algorithm', AnyAlgorithmId),
1170 ('parameters', Any, {'optional': True}),
1171 ]
1172
1173 _oid_pair = ('algorithm', 'parameters')
1174 _oid_specs = {}
1175
1176 def _setup(self):
1177 Sequence._setup(self)
1178 specs = self.__class__._oid_specs
1179 for other_cls in (EncryptionAlgorithm, SignedDigestAlgorithm):
1180 for oid, spec in other_cls._oid_specs.items():
1181 specs[oid] = spec