Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/oscrypto/_openssl/asymmetric.py: 18%
652 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 06:25 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 06:25 +0000
1# coding: utf-8
2from __future__ import unicode_literals, division, absolute_import, print_function
4import hashlib
6from .._asn1 import (
7 Certificate as Asn1Certificate,
8 DHParameters,
9 ECDomainParameters,
10 PrivateKeyInfo,
11 PublicKeyAlgorithm,
12 PublicKeyInfo,
13)
14from .._asymmetric import (
15 _CertificateBase,
16 _fingerprint,
17 _parse_pkcs12,
18 _PrivateKeyBase,
19 _PublicKeyBase,
20 _unwrap_private_key_info,
21 parse_certificate,
22 parse_private,
23 parse_public,
24)
25from .._errors import pretty_message
26from .._ffi import (
27 buffer_from_bytes,
28 buffer_pointer,
29 bytes_from_buffer,
30 deref,
31 is_null,
32 new,
33 null,
34 unwrap,
35 write_to_buffer,
36)
37from ._libcrypto import libcrypto, LibcryptoConst, libcrypto_version_info, handle_openssl_error
38from ..errors import AsymmetricKeyError, IncompleteAsymmetricKeyError, SignatureError
39from .._types import type_name, str_cls, byte_cls, int_types
40from ..util import constant_compare
43__all__ = [
44 'Certificate',
45 'dsa_sign',
46 'dsa_verify',
47 'ecdsa_sign',
48 'ecdsa_verify',
49 'generate_pair',
50 'load_certificate',
51 'load_pkcs12',
52 'load_private_key',
53 'load_public_key',
54 'parse_pkcs12',
55 'PrivateKey',
56 'PublicKey',
57 'rsa_oaep_decrypt',
58 'rsa_oaep_encrypt',
59 'rsa_pkcs1v15_decrypt',
60 'rsa_pkcs1v15_encrypt',
61 'rsa_pkcs1v15_sign',
62 'rsa_pkcs1v15_verify',
63 'rsa_pss_sign',
64 'rsa_pss_verify',
65]
68class PrivateKey(_PrivateKeyBase):
69 """
70 Container for the OpenSSL representation of a private key
71 """
73 evp_pkey = None
74 _public_key = None
76 # A reference to the library used in the destructor to make sure it hasn't
77 # been garbage collected by the time this object is garbage collected
78 _lib = None
80 def __init__(self, evp_pkey, asn1):
81 """
82 :param evp_pkey:
83 An OpenSSL EVP_PKEY value from loading/importing the key
85 :param asn1:
86 An asn1crypto.keys.PrivateKeyInfo object
87 """
89 self.evp_pkey = evp_pkey
90 self.asn1 = asn1
91 self._lib = libcrypto
93 @property
94 def public_key(self):
95 """
96 :return:
97 A PublicKey object corresponding to this private key.
98 """
100 if self._public_key is None:
101 buffer_size = libcrypto.i2d_PUBKEY(self.evp_pkey, null())
102 pubkey_buffer = buffer_from_bytes(buffer_size)
103 pubkey_pointer = buffer_pointer(pubkey_buffer)
104 pubkey_length = libcrypto.i2d_PUBKEY(self.evp_pkey, pubkey_pointer)
105 handle_openssl_error(pubkey_length)
106 pubkey_data = bytes_from_buffer(pubkey_buffer, pubkey_length)
108 asn1 = PublicKeyInfo.load(pubkey_data)
110 # OpenSSL 1.x suffers from issues trying to use RSASSA-PSS keys, so we
111 # masquerade it as a normal RSA key so the OID checks work
112 if libcrypto_version_info < (3,) and asn1.algorithm == 'rsassa_pss':
113 temp_asn1 = asn1.copy()
114 temp_asn1['algorithm']['algorithm'] = 'rsa'
115 temp_data = temp_asn1.dump()
116 write_to_buffer(pubkey_buffer, temp_data)
117 pubkey_length = len(temp_data)
119 pub_evp_pkey = libcrypto.d2i_PUBKEY(null(), buffer_pointer(pubkey_buffer), pubkey_length)
120 if is_null(pub_evp_pkey):
121 handle_openssl_error(0)
123 self._public_key = PublicKey(pub_evp_pkey, asn1)
125 return self._public_key
127 @property
128 def fingerprint(self):
129 """
130 Creates a fingerprint that can be compared with a public key to see if
131 the two form a pair.
133 This fingerprint is not compatible with fingerprints generated by any
134 other software.
136 :return:
137 A byte string that is a sha256 hash of selected components (based
138 on the key type)
139 """
141 if self._fingerprint is None:
142 self._fingerprint = _fingerprint(self.asn1, load_private_key)
143 return self._fingerprint
145 def __del__(self):
146 if self.evp_pkey:
147 self._lib.EVP_PKEY_free(self.evp_pkey)
148 self._lib = None
149 self.evp_pkey = None
152class PublicKey(_PublicKeyBase):
153 """
154 Container for the OpenSSL representation of a public key
155 """
157 evp_pkey = None
159 # A reference to the library used in the destructor to make sure it hasn't
160 # been garbage collected by the time this object is garbage collected
161 _lib = None
163 def __init__(self, evp_pkey, asn1):
164 """
165 :param evp_pkey:
166 An OpenSSL EVP_PKEY value from loading/importing the key
168 :param asn1:
169 An asn1crypto.keys.PublicKeyInfo object
170 """
172 self.evp_pkey = evp_pkey
173 self.asn1 = asn1
174 self._lib = libcrypto
176 def __del__(self):
177 if self.evp_pkey:
178 self._lib.EVP_PKEY_free(self.evp_pkey)
179 self._lib = None
180 self.evp_pkey = None
183class Certificate(_CertificateBase):
184 """
185 Container for the OpenSSL representation of a certificate
186 """
188 x509 = None
189 _public_key = None
190 _self_signed = None
192 # A reference to the library used in the destructor to make sure it hasn't
193 # been garbage collected by the time this object is garbage collected
194 _lib = None
196 def __init__(self, x509, asn1):
197 """
198 :param x509:
199 An OpenSSL X509 value from loading/importing the certificate
201 :param asn1:
202 An asn1crypto.x509.Certificate object
203 """
205 self.x509 = x509
206 self.asn1 = asn1
207 self._lib = libcrypto
209 @property
210 def evp_pkey(self):
211 """
212 :return:
213 The EVP_PKEY of the public key this certificate contains
214 """
216 return self.public_key.evp_pkey
218 @property
219 def public_key(self):
220 """
221 :return:
222 The PublicKey object for the public key this certificate contains
223 """
225 if not self._public_key and self.x509:
226 # OpenSSL 1.x suffers from issues trying to use RSASSA-PSS keys, so we
227 # masquerade it as a normal RSA key so the OID checks work
228 if libcrypto_version_info < (3,) and self.asn1.public_key.algorithm == 'rsassa_pss':
229 self._public_key = load_public_key(self.asn1.public_key)
230 else:
231 evp_pkey = libcrypto.X509_get_pubkey(self.x509)
232 self._public_key = PublicKey(evp_pkey, self.asn1.public_key)
234 return self._public_key
236 @property
237 def self_signed(self):
238 """
239 :return:
240 A boolean - if the certificate is self-signed
241 """
243 if self._self_signed is None:
244 self._self_signed = False
245 if self.asn1.self_signed in set(['yes', 'maybe']):
247 signature_algo = self.asn1['signature_algorithm'].signature_algo
248 hash_algo = self.asn1['signature_algorithm'].hash_algo
250 if signature_algo == 'rsassa_pkcs1v15':
251 verify_func = rsa_pkcs1v15_verify
252 elif signature_algo == 'rsassa_pss':
253 verify_func = rsa_pss_verify
254 elif signature_algo == 'dsa':
255 verify_func = dsa_verify
256 elif signature_algo == 'ecdsa':
257 verify_func = ecdsa_verify
258 else:
259 raise OSError(pretty_message(
260 '''
261 Unable to verify the signature of the certificate since
262 it uses the unsupported algorithm %s
263 ''',
264 signature_algo
265 ))
267 try:
268 verify_func(
269 self.public_key,
270 self.asn1['signature_value'].native,
271 self.asn1['tbs_certificate'].dump(),
272 hash_algo
273 )
274 self._self_signed = True
275 except (SignatureError):
276 pass
278 return self._self_signed
280 def __del__(self):
281 if self._public_key:
282 self._public_key.__del__()
283 self._public_key = None
285 if self.x509:
286 self._lib.X509_free(self.x509)
287 self._lib = None
288 self.x509 = None
291def generate_pair(algorithm, bit_size=None, curve=None):
292 """
293 Generates a public/private key pair
295 :param algorithm:
296 The key algorithm - "rsa", "dsa" or "ec"
298 :param bit_size:
299 An integer - used for "rsa" and "dsa". For "rsa" the value maye be 1024,
300 2048, 3072 or 4096. For "dsa" the value may be 1024, plus 2048 or 3072
301 if OpenSSL 1.0.0 or newer is available.
303 :param curve:
304 A unicode string - used for "ec" keys. Valid values include "secp256r1",
305 "secp384r1" and "secp521r1".
307 :raises:
308 ValueError - when any of the parameters contain an invalid value
309 TypeError - when any of the parameters are of the wrong type
310 OSError - when an error is returned by the OS crypto library
312 :return:
313 A 2-element tuple of (PublicKey, PrivateKey). The contents of each key
314 may be saved by calling .asn1.dump().
315 """
317 if algorithm not in set(['rsa', 'dsa', 'ec']):
318 raise ValueError(pretty_message(
319 '''
320 algorithm must be one of "rsa", "dsa", "ec", not %s
321 ''',
322 repr(algorithm)
323 ))
325 if algorithm == 'rsa':
326 if bit_size not in set([1024, 2048, 3072, 4096]):
327 raise ValueError(pretty_message(
328 '''
329 bit_size must be one of 1024, 2048, 3072, 4096, not %s
330 ''',
331 repr(bit_size)
332 ))
334 elif algorithm == 'dsa':
335 if libcrypto_version_info < (1,):
336 if bit_size != 1024:
337 raise ValueError(pretty_message(
338 '''
339 bit_size must be 1024, not %s
340 ''',
341 repr(bit_size)
342 ))
343 else:
344 if bit_size not in set([1024, 2048, 3072]):
345 raise ValueError(pretty_message(
346 '''
347 bit_size must be one of 1024, 2048, 3072, not %s
348 ''',
349 repr(bit_size)
350 ))
352 elif algorithm == 'ec':
353 if curve not in set(['secp256r1', 'secp384r1', 'secp521r1']):
354 raise ValueError(pretty_message(
355 '''
356 curve must be one of "secp256r1", "secp384r1", "secp521r1",
357 not %s
358 ''',
359 repr(curve)
360 ))
362 if algorithm == 'rsa':
363 rsa = None
364 exponent = None
366 try:
367 rsa = libcrypto.RSA_new()
368 if is_null(rsa):
369 handle_openssl_error(0)
371 exponent_pointer = new(libcrypto, 'BIGNUM **')
372 result = libcrypto.BN_dec2bn(exponent_pointer, b'65537')
373 handle_openssl_error(result)
374 exponent = unwrap(exponent_pointer)
376 result = libcrypto.RSA_generate_key_ex(rsa, bit_size, exponent, null())
377 handle_openssl_error(result)
379 buffer_length = libcrypto.i2d_RSAPublicKey(rsa, null())
380 if buffer_length < 0:
381 handle_openssl_error(buffer_length)
382 buffer = buffer_from_bytes(buffer_length)
383 result = libcrypto.i2d_RSAPublicKey(rsa, buffer_pointer(buffer))
384 if result < 0:
385 handle_openssl_error(result)
386 public_key_bytes = bytes_from_buffer(buffer, buffer_length)
388 buffer_length = libcrypto.i2d_RSAPrivateKey(rsa, null())
389 if buffer_length < 0:
390 handle_openssl_error(buffer_length)
391 buffer = buffer_from_bytes(buffer_length)
392 result = libcrypto.i2d_RSAPrivateKey(rsa, buffer_pointer(buffer))
393 if result < 0:
394 handle_openssl_error(result)
395 private_key_bytes = bytes_from_buffer(buffer, buffer_length)
397 finally:
398 if rsa:
399 libcrypto.RSA_free(rsa)
400 if exponent:
401 libcrypto.BN_free(exponent)
403 elif algorithm == 'dsa':
404 dsa = None
406 try:
407 dsa = libcrypto.DSA_new()
408 if is_null(dsa):
409 handle_openssl_error(0)
411 result = libcrypto.DSA_generate_parameters_ex(dsa, bit_size, null(), 0, null(), null(), null())
412 handle_openssl_error(result)
414 result = libcrypto.DSA_generate_key(dsa)
415 handle_openssl_error(result)
417 buffer_length = libcrypto.i2d_DSA_PUBKEY(dsa, null())
418 if buffer_length < 0:
419 handle_openssl_error(buffer_length)
420 buffer = buffer_from_bytes(buffer_length)
421 result = libcrypto.i2d_DSA_PUBKEY(dsa, buffer_pointer(buffer))
422 if result < 0:
423 handle_openssl_error(result)
424 public_key_bytes = bytes_from_buffer(buffer, buffer_length)
426 buffer_length = libcrypto.i2d_DSAPrivateKey(dsa, null())
427 if buffer_length < 0:
428 handle_openssl_error(buffer_length)
429 buffer = buffer_from_bytes(buffer_length)
430 result = libcrypto.i2d_DSAPrivateKey(dsa, buffer_pointer(buffer))
431 if result < 0:
432 handle_openssl_error(result)
433 private_key_bytes = bytes_from_buffer(buffer, buffer_length)
435 finally:
436 if dsa:
437 libcrypto.DSA_free(dsa)
439 elif algorithm == 'ec':
440 ec_key = None
442 try:
443 curve_id = {
444 'secp256r1': LibcryptoConst.NID_X9_62_prime256v1,
445 'secp384r1': LibcryptoConst.NID_secp384r1,
446 'secp521r1': LibcryptoConst.NID_secp521r1,
447 }[curve]
449 ec_key = libcrypto.EC_KEY_new_by_curve_name(curve_id)
450 if is_null(ec_key):
451 handle_openssl_error(0)
453 result = libcrypto.EC_KEY_generate_key(ec_key)
454 handle_openssl_error(result)
456 libcrypto.EC_KEY_set_asn1_flag(ec_key, LibcryptoConst.OPENSSL_EC_NAMED_CURVE)
458 buffer_length = libcrypto.i2o_ECPublicKey(ec_key, null())
459 if buffer_length < 0:
460 handle_openssl_error(buffer_length)
461 buffer = buffer_from_bytes(buffer_length)
462 result = libcrypto.i2o_ECPublicKey(ec_key, buffer_pointer(buffer))
463 if result < 0:
464 handle_openssl_error(result)
465 public_key_point_bytes = bytes_from_buffer(buffer, buffer_length)
467 # i2o_ECPublicKey only returns the ECPoint bytes, so we have to
468 # manually wrap it in a PublicKeyInfo structure to get it to parse
469 public_key = PublicKeyInfo({
470 'algorithm': PublicKeyAlgorithm({
471 'algorithm': 'ec',
472 'parameters': ECDomainParameters(
473 name='named',
474 value=curve
475 )
476 }),
477 'public_key': public_key_point_bytes
478 })
479 public_key_bytes = public_key.dump()
481 buffer_length = libcrypto.i2d_ECPrivateKey(ec_key, null())
482 if buffer_length < 0:
483 handle_openssl_error(buffer_length)
484 buffer = buffer_from_bytes(buffer_length)
485 result = libcrypto.i2d_ECPrivateKey(ec_key, buffer_pointer(buffer))
486 if result < 0:
487 handle_openssl_error(result)
488 private_key_bytes = bytes_from_buffer(buffer, buffer_length)
490 finally:
491 if ec_key:
492 libcrypto.EC_KEY_free(ec_key)
494 return (load_public_key(public_key_bytes), load_private_key(private_key_bytes))
497def generate_dh_parameters(bit_size):
498 """
499 Generates DH parameters for use with Diffie-Hellman key exchange. Returns
500 a structure in the format of DHParameter defined in PKCS#3, which is also
501 used by the OpenSSL dhparam tool.
503 THIS CAN BE VERY TIME CONSUMING!
505 :param bit_size:
506 The integer bit size of the parameters to generate. Must be between 512
507 and 4096, and divisible by 64. Recommended secure value as of early 2016
508 is 2048, with an absolute minimum of 1024.
510 :raises:
511 ValueError - when any of the parameters contain an invalid value
512 TypeError - when any of the parameters are of the wrong type
513 OSError - when an error is returned by the OS crypto library
515 :return:
516 An asn1crypto.algos.DHParameters object. Use
517 oscrypto.asymmetric.dump_dh_parameters() to save to disk for usage with
518 web servers.
519 """
521 if not isinstance(bit_size, int_types):
522 raise TypeError(pretty_message(
523 '''
524 bit_size must be an integer, not %s
525 ''',
526 type_name(bit_size)
527 ))
529 if bit_size < 512:
530 raise ValueError('bit_size must be greater than or equal to 512')
532 if bit_size > 4096:
533 raise ValueError('bit_size must be less than or equal to 4096')
535 if bit_size % 64 != 0:
536 raise ValueError('bit_size must be a multiple of 64')
538 dh = None
540 try:
541 dh = libcrypto.DH_new()
542 if is_null(dh):
543 handle_openssl_error(0)
545 result = libcrypto.DH_generate_parameters_ex(dh, bit_size, LibcryptoConst.DH_GENERATOR_2, null())
546 handle_openssl_error(result)
548 buffer_length = libcrypto.i2d_DHparams(dh, null())
549 if buffer_length < 0:
550 handle_openssl_error(buffer_length)
551 buffer = buffer_from_bytes(buffer_length)
552 result = libcrypto.i2d_DHparams(dh, buffer_pointer(buffer))
553 if result < 0:
554 handle_openssl_error(result)
555 dh_params_bytes = bytes_from_buffer(buffer, buffer_length)
557 return DHParameters.load(dh_params_bytes)
559 finally:
560 if dh:
561 libcrypto.DH_free(dh)
564def load_certificate(source):
565 """
566 Loads an x509 certificate into a Certificate object
568 :param source:
569 A byte string of file contents, a unicode string filename or an
570 asn1crypto.x509.Certificate object
572 :raises:
573 ValueError - when any of the parameters contain an invalid value
574 TypeError - when any of the parameters are of the wrong type
575 OSError - when an error is returned by the OS crypto library
577 :return:
578 A Certificate object
579 """
581 if isinstance(source, Asn1Certificate):
582 certificate = source
584 elif isinstance(source, byte_cls):
585 certificate = parse_certificate(source)
587 elif isinstance(source, str_cls):
588 with open(source, 'rb') as f:
589 certificate = parse_certificate(f.read())
591 else:
592 raise TypeError(pretty_message(
593 '''
594 source must be a byte string, unicode string or
595 asn1crypto.x509.Certificate object, not %s
596 ''',
597 type_name(source)
598 ))
600 return _load_x509(certificate)
603def _load_x509(certificate):
604 """
605 Loads an ASN.1 object of an x509 certificate into a Certificate object
607 :param certificate:
608 An asn1crypto.x509.Certificate object
610 :return:
611 A Certificate object
612 """
614 source = certificate.dump()
616 buffer = buffer_from_bytes(source)
617 evp_pkey = libcrypto.d2i_X509(null(), buffer_pointer(buffer), len(source))
618 if is_null(evp_pkey):
619 handle_openssl_error(0)
620 return Certificate(evp_pkey, certificate)
623def load_private_key(source, password=None):
624 """
625 Loads a private key into a PrivateKey object
627 :param source:
628 A byte string of file contents, a unicode string filename or an
629 asn1crypto.keys.PrivateKeyInfo object
631 :param password:
632 A byte or unicode string to decrypt the private key file. Unicode
633 strings will be encoded using UTF-8. Not used is the source is a
634 PrivateKeyInfo object.
636 :raises:
637 ValueError - when any of the parameters contain an invalid value
638 TypeError - when any of the parameters are of the wrong type
639 oscrypto.errors.AsymmetricKeyError - when the private key is incompatible with the OS crypto library
640 OSError - when an error is returned by the OS crypto library
642 :return:
643 A PrivateKey object
644 """
646 if isinstance(source, PrivateKeyInfo):
647 private_object = source
649 else:
650 if password is not None:
651 if isinstance(password, str_cls):
652 password = password.encode('utf-8')
653 if not isinstance(password, byte_cls):
654 raise TypeError(pretty_message(
655 '''
656 password must be a byte string, not %s
657 ''',
658 type_name(password)
659 ))
661 if isinstance(source, str_cls):
662 with open(source, 'rb') as f:
663 source = f.read()
665 elif not isinstance(source, byte_cls):
666 raise TypeError(pretty_message(
667 '''
668 source must be a byte string, unicode string or
669 asn1crypto.keys.PrivateKeyInfo object, not %s
670 ''',
671 type_name(source)
672 ))
674 private_object = parse_private(source, password)
676 return _load_key(private_object)
679def load_public_key(source):
680 """
681 Loads a public key into a PublicKey object
683 :param source:
684 A byte string of file contents, a unicode string filename or an
685 asn1crypto.keys.PublicKeyInfo object
687 :raises:
688 ValueError - when any of the parameters contain an invalid value
689 TypeError - when any of the parameters are of the wrong type
690 oscrypto.errors.AsymmetricKeyError - when the public key is incompatible with the OS crypto library
691 OSError - when an error is returned by the OS crypto library
693 :return:
694 A PublicKey object
695 """
697 if isinstance(source, PublicKeyInfo):
698 public_key = source
700 elif isinstance(source, byte_cls):
701 public_key = parse_public(source)
703 elif isinstance(source, str_cls):
704 with open(source, 'rb') as f:
705 public_key = parse_public(f.read())
707 else:
708 raise TypeError(pretty_message(
709 '''
710 source must be a byte string, unicode string or
711 asn1crypto.keys.PublicKeyInfo object, not %s
712 ''',
713 type_name(source)
714 ))
716 if public_key.algorithm == 'dsa':
717 if libcrypto_version_info < (1,) and public_key.hash_algo == 'sha2':
718 raise AsymmetricKeyError(pretty_message(
719 '''
720 OpenSSL 0.9.8 only supports DSA keys based on SHA1 (2048 bits or
721 less) - this key is based on SHA2 and is %s bits
722 ''',
723 public_key.bit_size
724 ))
725 elif public_key.hash_algo is None:
726 raise IncompleteAsymmetricKeyError(pretty_message(
727 '''
728 The DSA key does not contain the necessary p, q and g
729 parameters and can not be used
730 '''
731 ))
733 # OpenSSL 1.x suffers from issues trying to use RSASSA-PSS keys, so we
734 # masquerade it as a normal RSA key so the OID checks work
735 if libcrypto_version_info < (3,) and public_key.algorithm == 'rsassa_pss':
736 temp_key = public_key.copy()
737 temp_key['algorithm']['algorithm'] = 'rsa'
738 data = temp_key.dump()
739 else:
740 data = public_key.dump()
742 buffer = buffer_from_bytes(data)
743 evp_pkey = libcrypto.d2i_PUBKEY(null(), buffer_pointer(buffer), len(data))
744 if is_null(evp_pkey):
745 handle_openssl_error(0)
746 return PublicKey(evp_pkey, public_key)
749def _load_key(private_object):
750 """
751 Loads a private key into a PrivateKey object
753 :param private_object:
754 An asn1crypto.keys.PrivateKeyInfo object
756 :return:
757 A PrivateKey object
758 """
760 if libcrypto_version_info < (1,) and private_object.algorithm == 'dsa' and private_object.hash_algo == 'sha2':
761 raise AsymmetricKeyError(pretty_message(
762 '''
763 OpenSSL 0.9.8 only supports DSA keys based on SHA1 (2048 bits or
764 less) - this key is based on SHA2 and is %s bits
765 ''',
766 private_object.bit_size
767 ))
769 source = _unwrap_private_key_info(private_object).dump()
771 buffer = buffer_from_bytes(source)
772 evp_pkey = libcrypto.d2i_AutoPrivateKey(null(), buffer_pointer(buffer), len(source))
773 if is_null(evp_pkey):
774 handle_openssl_error(0)
775 return PrivateKey(evp_pkey, private_object)
778def parse_pkcs12(data, password=None):
779 """
780 Parses a PKCS#12 ANS.1 DER-encoded structure and extracts certs and keys
782 :param data:
783 A byte string of a DER-encoded PKCS#12 file
785 :param password:
786 A byte string of the password to any encrypted data
788 :raises:
789 ValueError - when any of the parameters are of the wrong type or value
790 OSError - when an error is returned by one of the OS decryption functions
792 :return:
793 A three-element tuple of:
794 1. An asn1crypto.keys.PrivateKeyInfo object
795 2. An asn1crypto.x509.Certificate object
796 3. A list of zero or more asn1crypto.x509.Certificate objects that are
797 "extra" certificates, possibly intermediates from the cert chain
798 """
800 return _parse_pkcs12(data, password, load_private_key)
803def load_pkcs12(source, password=None):
804 """
805 Loads a .p12 or .pfx file into a PrivateKey object and one or more
806 Certificates objects
808 :param source:
809 A byte string of file contents or a unicode string filename
811 :param password:
812 A byte or unicode string to decrypt the PKCS12 file. Unicode strings
813 will be encoded using UTF-8.
815 :raises:
816 ValueError - when any of the parameters contain an invalid value
817 TypeError - when any of the parameters are of the wrong type
818 oscrypto.errors.AsymmetricKeyError - when a contained key is incompatible with the OS crypto library
819 OSError - when an error is returned by the OS crypto library
821 :return:
822 A three-element tuple containing (PrivateKey, Certificate, [Certificate, ...])
823 """
825 if password is not None:
826 if isinstance(password, str_cls):
827 password = password.encode('utf-8')
828 if not isinstance(password, byte_cls):
829 raise TypeError(pretty_message(
830 '''
831 password must be a byte string, not %s
832 ''',
833 type_name(password)
834 ))
836 if isinstance(source, str_cls):
837 with open(source, 'rb') as f:
838 source = f.read()
840 elif not isinstance(source, byte_cls):
841 raise TypeError(pretty_message(
842 '''
843 source must be a byte string or a unicode string, not %s
844 ''',
845 type_name(source)
846 ))
848 key_info, cert_info, extra_certs_info = parse_pkcs12(source, password)
850 key = None
851 cert = None
853 if key_info:
854 key = _load_key(key_info)
856 if cert_info:
857 cert = _load_x509(cert_info)
859 extra_certs = [_load_x509(info) for info in extra_certs_info]
861 return (key, cert, extra_certs)
864def rsa_pkcs1v15_encrypt(certificate_or_public_key, data):
865 """
866 Encrypts a byte string using an RSA public key or certificate. Uses PKCS#1
867 v1.5 padding.
869 :param certificate_or_public_key:
870 A PublicKey or Certificate object
872 :param data:
873 A byte string, with a maximum length 11 bytes less than the key length
874 (in bytes)
876 :raises:
877 ValueError - when any of the parameters contain an invalid value
878 TypeError - when any of the parameters are of the wrong type
879 OSError - when an error is returned by the OS crypto library
881 :return:
882 A byte string of the encrypted data
883 """
885 return _encrypt(certificate_or_public_key, data, LibcryptoConst.RSA_PKCS1_PADDING)
888def rsa_pkcs1v15_decrypt(private_key, ciphertext):
889 """
890 Decrypts a byte string using an RSA private key. Uses PKCS#1 v1.5 padding.
892 :param private_key:
893 A PrivateKey object
895 :param ciphertext:
896 A byte string of the encrypted data
898 :raises:
899 ValueError - when any of the parameters contain an invalid value
900 TypeError - when any of the parameters are of the wrong type
901 OSError - when an error is returned by the OS crypto library
903 :return:
904 A byte string of the original plaintext
905 """
907 return _decrypt(private_key, ciphertext, LibcryptoConst.RSA_PKCS1_PADDING)
910def rsa_oaep_encrypt(certificate_or_public_key, data):
911 """
912 Encrypts a byte string using an RSA public key or certificate. Uses PKCS#1
913 OAEP padding with SHA1.
915 :param certificate_or_public_key:
916 A PublicKey or Certificate object
918 :param data:
919 A byte string, with a maximum length 41 bytes (or more) less than the
920 key length (in bytes)
922 :raises:
923 ValueError - when any of the parameters contain an invalid value
924 TypeError - when any of the parameters are of the wrong type
925 OSError - when an error is returned by the OS crypto library
927 :return:
928 A byte string of the encrypted data
929 """
931 return _encrypt(certificate_or_public_key, data, LibcryptoConst.RSA_PKCS1_OAEP_PADDING)
934def rsa_oaep_decrypt(private_key, ciphertext):
935 """
936 Decrypts a byte string using an RSA private key. Uses PKCS#1 OAEP padding
937 with SHA1.
939 :param private_key:
940 A PrivateKey object
942 :param ciphertext:
943 A byte string of the encrypted data
945 :raises:
946 ValueError - when any of the parameters contain an invalid value
947 TypeError - when any of the parameters are of the wrong type
948 OSError - when an error is returned by the OS crypto library
950 :return:
951 A byte string of the original plaintext
952 """
954 return _decrypt(private_key, ciphertext, LibcryptoConst.RSA_PKCS1_OAEP_PADDING)
957def _evp_pkey_get_size(evp_pkey):
958 """
959 Handles the function name change from OpenSSL 1.1 -> 3.0
961 :param evp_pkey:
962 The EVP_PKEY of the Certificte or PublicKey to get the size of
964 :return:
965 An int of the number of bytes necessary for the key
966 """
968 if libcrypto_version_info < (3, ):
969 return libcrypto.EVP_PKEY_size(evp_pkey)
970 return libcrypto.EVP_PKEY_get_size(evp_pkey)
973def _encrypt(certificate_or_public_key, data, padding):
974 """
975 Encrypts plaintext using an RSA public key or certificate
977 :param certificate_or_public_key:
978 A PublicKey, Certificate or PrivateKey object
980 :param data:
981 The byte string to encrypt
983 :param padding:
984 The padding mode to use
986 :raises:
987 ValueError - when any of the parameters contain an invalid value
988 TypeError - when any of the parameters are of the wrong type
989 OSError - when an error is returned by the OS crypto library
991 :return:
992 A byte string of the encrypted data
993 """
995 if not isinstance(certificate_or_public_key, (Certificate, PublicKey)):
996 raise TypeError(pretty_message(
997 '''
998 certificate_or_public_key must be an instance of the Certificate or
999 PublicKey class, not %s
1000 ''',
1001 type_name(certificate_or_public_key)
1002 ))
1004 if not isinstance(data, byte_cls):
1005 raise TypeError(pretty_message(
1006 '''
1007 data must be a byte string, not %s
1008 ''',
1009 type_name(data)
1010 ))
1012 rsa = None
1014 try:
1015 buffer_size = _evp_pkey_get_size(certificate_or_public_key.evp_pkey)
1016 buffer = buffer_from_bytes(buffer_size)
1018 rsa = libcrypto.EVP_PKEY_get1_RSA(certificate_or_public_key.evp_pkey)
1019 res = libcrypto.RSA_public_encrypt(len(data), data, buffer, rsa, padding)
1020 handle_openssl_error(res)
1022 return bytes_from_buffer(buffer, res)
1024 finally:
1025 if rsa:
1026 libcrypto.RSA_free(rsa)
1029def _decrypt(private_key, ciphertext, padding):
1030 """
1031 Decrypts RSA ciphertext using a private key
1033 :param private_key:
1034 A PrivateKey object
1036 :param ciphertext:
1037 The ciphertext - a byte string
1039 :param padding:
1040 The padding mode to use
1042 :raises:
1043 ValueError - when any of the parameters contain an invalid value
1044 TypeError - when any of the parameters are of the wrong type
1045 OSError - when an error is returned by the OS crypto library
1047 :return:
1048 A byte string of the plaintext
1049 """
1051 if not isinstance(private_key, PrivateKey):
1052 raise TypeError(pretty_message(
1053 '''
1054 private_key must be an instance of the PrivateKey class, not %s
1055 ''',
1056 type_name(private_key)
1057 ))
1059 if not isinstance(ciphertext, byte_cls):
1060 raise TypeError(pretty_message(
1061 '''
1062 ciphertext must be a byte string, not %s
1063 ''',
1064 type_name(ciphertext)
1065 ))
1067 rsa = None
1069 try:
1070 buffer_size = _evp_pkey_get_size(private_key.evp_pkey)
1071 buffer = buffer_from_bytes(buffer_size)
1073 rsa = libcrypto.EVP_PKEY_get1_RSA(private_key.evp_pkey)
1074 res = libcrypto.RSA_private_decrypt(len(ciphertext), ciphertext, buffer, rsa, padding)
1075 handle_openssl_error(res)
1077 return bytes_from_buffer(buffer, res)
1079 finally:
1080 if rsa:
1081 libcrypto.RSA_free(rsa)
1084def rsa_pkcs1v15_verify(certificate_or_public_key, signature, data, hash_algorithm):
1085 """
1086 Verifies an RSASSA-PKCS-v1.5 signature.
1088 When the hash_algorithm is "raw", the operation is identical to RSA
1089 public key decryption. That is: the data is not hashed and no ASN.1
1090 structure with an algorithm identifier of the hash algorithm is placed in
1091 the encrypted byte string.
1093 :param certificate_or_public_key:
1094 A Certificate or PublicKey instance to verify the signature with
1096 :param signature:
1097 A byte string of the signature to verify
1099 :param data:
1100 A byte string of the data the signature is for
1102 :param hash_algorithm:
1103 A unicode string of "md5", "sha1", "sha224", "sha256", "sha384",
1104 "sha512" or "raw"
1106 :raises:
1107 oscrypto.errors.SignatureError - when the signature is determined to be invalid
1108 ValueError - when any of the parameters contain an invalid value
1109 TypeError - when any of the parameters are of the wrong type
1110 OSError - when an error is returned by the OS crypto library
1111 """
1113 if certificate_or_public_key.algorithm != 'rsa':
1114 raise ValueError(pretty_message(
1115 '''
1116 The key specified is not an RSA public key, but %s
1117 ''',
1118 certificate_or_public_key.algorithm.upper()
1119 ))
1121 return _verify(certificate_or_public_key, signature, data, hash_algorithm)
1124def rsa_pss_verify(certificate_or_public_key, signature, data, hash_algorithm):
1125 """
1126 Verifies an RSASSA-PSS signature. For the PSS padding the mask gen algorithm
1127 will be mgf1 using the same hash algorithm as the signature. The salt length
1128 with be the length of the hash algorithm, and the trailer field with be the
1129 standard 0xBC byte.
1131 :param certificate_or_public_key:
1132 A Certificate or PublicKey instance to verify the signature with
1134 :param signature:
1135 A byte string of the signature to verify
1137 :param data:
1138 A byte string of the data the signature is for
1140 :param hash_algorithm:
1141 A unicode string of "md5", "sha1", "sha224", "sha256", "sha384" or "sha512"
1143 :raises:
1144 oscrypto.errors.SignatureError - when the signature is determined to be invalid
1145 ValueError - when any of the parameters contain an invalid value
1146 TypeError - when any of the parameters are of the wrong type
1147 OSError - when an error is returned by the OS crypto library
1148 """
1150 cp_alg = certificate_or_public_key.algorithm
1152 if cp_alg != 'rsa' and cp_alg != 'rsassa_pss':
1153 raise ValueError(pretty_message(
1154 '''
1155 The key specified is not an RSA public key, but %s
1156 ''',
1157 certificate_or_public_key.algorithm.upper()
1158 ))
1160 return _verify(certificate_or_public_key, signature, data, hash_algorithm, rsa_pss_padding=True)
1163def dsa_verify(certificate_or_public_key, signature, data, hash_algorithm):
1164 """
1165 Verifies a DSA signature
1167 :param certificate_or_public_key:
1168 A Certificate or PublicKey instance to verify the signature with
1170 :param signature:
1171 A byte string of the signature to verify
1173 :param data:
1174 A byte string of the data the signature is for
1176 :param hash_algorithm:
1177 A unicode string of "md5", "sha1", "sha224", "sha256", "sha384" or "sha512"
1179 :raises:
1180 oscrypto.errors.SignatureError - when the signature is determined to be invalid
1181 ValueError - when any of the parameters contain an invalid value
1182 TypeError - when any of the parameters are of the wrong type
1183 OSError - when an error is returned by the OS crypto library
1184 """
1186 if certificate_or_public_key.algorithm != 'dsa':
1187 raise ValueError(pretty_message(
1188 '''
1189 The key specified is not a DSA public key, but %s
1190 ''',
1191 certificate_or_public_key.algorithm.upper()
1192 ))
1194 return _verify(certificate_or_public_key, signature, data, hash_algorithm)
1197def ecdsa_verify(certificate_or_public_key, signature, data, hash_algorithm):
1198 """
1199 Verifies an ECDSA signature
1201 :param certificate_or_public_key:
1202 A Certificate or PublicKey instance to verify the signature with
1204 :param signature:
1205 A byte string of the signature to verify
1207 :param data:
1208 A byte string of the data the signature is for
1210 :param hash_algorithm:
1211 A unicode string of "md5", "sha1", "sha224", "sha256", "sha384" or "sha512"
1213 :raises:
1214 oscrypto.errors.SignatureError - when the signature is determined to be invalid
1215 ValueError - when any of the parameters contain an invalid value
1216 TypeError - when any of the parameters are of the wrong type
1217 OSError - when an error is returned by the OS crypto library
1218 """
1220 if certificate_or_public_key.algorithm != 'ec':
1221 raise ValueError(pretty_message(
1222 '''
1223 The key specified is not an EC public key, but %s
1224 ''',
1225 certificate_or_public_key.algorithm.upper()
1226 ))
1228 return _verify(certificate_or_public_key, signature, data, hash_algorithm)
1231def _verify(certificate_or_public_key, signature, data, hash_algorithm, rsa_pss_padding=False):
1232 """
1233 Verifies an RSA, DSA or ECDSA signature
1235 :param certificate_or_public_key:
1236 A Certificate or PublicKey instance to verify the signature with
1238 :param signature:
1239 A byte string of the signature to verify
1241 :param data:
1242 A byte string of the data the signature is for
1244 :param hash_algorithm:
1245 A unicode string of "md5", "sha1", "sha224", "sha256", "sha384" or "sha512"
1247 :param rsa_pss_padding:
1248 If the certificate_or_public_key is an RSA key, this enables PSS padding
1250 :raises:
1251 oscrypto.errors.SignatureError - when the signature is determined to be invalid
1252 ValueError - when any of the parameters contain an invalid value
1253 TypeError - when any of the parameters are of the wrong type
1254 OSError - when an error is returned by the OS crypto library
1255 """
1257 if not isinstance(certificate_or_public_key, (Certificate, PublicKey)):
1258 raise TypeError(pretty_message(
1259 '''
1260 certificate_or_public_key must be an instance of the Certificate or
1261 PublicKey class, not %s
1262 ''',
1263 type_name(certificate_or_public_key)
1264 ))
1266 if not isinstance(signature, byte_cls):
1267 raise TypeError(pretty_message(
1268 '''
1269 signature must be a byte string, not %s
1270 ''',
1271 type_name(signature)
1272 ))
1274 if not isinstance(data, byte_cls):
1275 raise TypeError(pretty_message(
1276 '''
1277 data must be a byte string, not %s
1278 ''',
1279 type_name(data)
1280 ))
1282 cp_alg = certificate_or_public_key.algorithm
1283 cp_is_rsa = cp_alg == 'rsa' or cp_alg == 'rsassa_pss'
1285 valid_hash_algorithms = set(['md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512'])
1286 if cp_is_rsa and not rsa_pss_padding:
1287 valid_hash_algorithms |= set(['raw'])
1289 if hash_algorithm not in valid_hash_algorithms:
1290 valid_hash_algorithms_error = '"md5", "sha1", "sha224", "sha256", "sha384", "sha512"'
1291 if cp_is_rsa and not rsa_pss_padding:
1292 valid_hash_algorithms_error += ', "raw"'
1293 raise ValueError(pretty_message(
1294 '''
1295 hash_algorithm must be one of %s, not %s
1296 ''',
1297 valid_hash_algorithms_error,
1298 repr(hash_algorithm)
1299 ))
1301 if not cp_is_rsa and rsa_pss_padding:
1302 raise ValueError(pretty_message(
1303 '''
1304 PSS padding can only be used with RSA keys - the key provided is a
1305 %s key
1306 ''',
1307 cp_alg.upper()
1308 ))
1310 if cp_is_rsa and hash_algorithm == 'raw':
1311 if len(data) > certificate_or_public_key.byte_size - 11:
1312 raise ValueError(pretty_message(
1313 '''
1314 data must be 11 bytes shorter than the key size when
1315 hash_algorithm is "raw" - key size is %s bytes, but data is
1316 %s bytes long
1317 ''',
1318 certificate_or_public_key.byte_size,
1319 len(data)
1320 ))
1322 rsa = None
1324 try:
1325 rsa = libcrypto.EVP_PKEY_get1_RSA(certificate_or_public_key.evp_pkey)
1326 if is_null(rsa):
1327 handle_openssl_error(0)
1329 buffer_size = _evp_pkey_get_size(certificate_or_public_key.evp_pkey)
1330 decrypted_buffer = buffer_from_bytes(buffer_size)
1331 decrypted_length = libcrypto.RSA_public_decrypt(
1332 len(signature),
1333 signature,
1334 decrypted_buffer,
1335 rsa,
1336 LibcryptoConst.RSA_PKCS1_PADDING
1337 )
1338 handle_openssl_error(decrypted_length)
1340 decrypted_bytes = bytes_from_buffer(decrypted_buffer, decrypted_length)
1342 if not constant_compare(data, decrypted_bytes):
1343 raise SignatureError('Signature is invalid')
1344 return
1346 finally:
1347 if rsa:
1348 libcrypto.RSA_free(rsa)
1350 evp_md_ctx = None
1351 rsa = None
1352 dsa = None
1353 dsa_sig = None
1354 ec_key = None
1355 ecdsa_sig = None
1357 try:
1358 if libcrypto_version_info < (1, 1):
1359 evp_md_ctx = libcrypto.EVP_MD_CTX_create()
1360 else:
1361 evp_md_ctx = libcrypto.EVP_MD_CTX_new()
1363 evp_md = {
1364 'md5': libcrypto.EVP_md5,
1365 'sha1': libcrypto.EVP_sha1,
1366 'sha224': libcrypto.EVP_sha224,
1367 'sha256': libcrypto.EVP_sha256,
1368 'sha384': libcrypto.EVP_sha384,
1369 'sha512': libcrypto.EVP_sha512
1370 }[hash_algorithm]()
1372 if libcrypto_version_info < (1,):
1373 if cp_is_rsa and rsa_pss_padding:
1374 digest = getattr(hashlib, hash_algorithm)(data).digest()
1376 rsa = libcrypto.EVP_PKEY_get1_RSA(certificate_or_public_key.evp_pkey)
1377 if is_null(rsa):
1378 handle_openssl_error(0)
1380 buffer_size = _evp_pkey_get_size(certificate_or_public_key.evp_pkey)
1381 decoded_buffer = buffer_from_bytes(buffer_size)
1382 decoded_length = libcrypto.RSA_public_decrypt(
1383 len(signature),
1384 signature,
1385 decoded_buffer,
1386 rsa,
1387 LibcryptoConst.RSA_NO_PADDING
1388 )
1389 handle_openssl_error(decoded_length)
1391 res = libcrypto.RSA_verify_PKCS1_PSS(
1392 rsa,
1393 digest,
1394 evp_md,
1395 decoded_buffer,
1396 LibcryptoConst.EVP_MD_CTX_FLAG_PSS_MDLEN
1397 )
1399 elif cp_is_rsa:
1400 res = libcrypto.EVP_DigestInit_ex(evp_md_ctx, evp_md, null())
1401 handle_openssl_error(res)
1403 res = libcrypto.EVP_DigestUpdate(evp_md_ctx, data, len(data))
1404 handle_openssl_error(res)
1406 res = libcrypto.EVP_VerifyFinal(
1407 evp_md_ctx,
1408 signature,
1409 len(signature),
1410 certificate_or_public_key.evp_pkey
1411 )
1413 elif cp_alg == 'dsa':
1414 digest = getattr(hashlib, hash_algorithm)(data).digest()
1416 signature_buffer = buffer_from_bytes(signature)
1417 signature_pointer = buffer_pointer(signature_buffer)
1418 dsa_sig = libcrypto.d2i_DSA_SIG(null(), signature_pointer, len(signature))
1419 if is_null(dsa_sig):
1420 raise SignatureError('Signature is invalid')
1422 dsa = libcrypto.EVP_PKEY_get1_DSA(certificate_or_public_key.evp_pkey)
1423 if is_null(dsa):
1424 handle_openssl_error(0)
1426 res = libcrypto.DSA_do_verify(digest, len(digest), dsa_sig, dsa)
1428 elif cp_alg == 'ec':
1429 digest = getattr(hashlib, hash_algorithm)(data).digest()
1431 signature_buffer = buffer_from_bytes(signature)
1432 signature_pointer = buffer_pointer(signature_buffer)
1433 ecdsa_sig = libcrypto.d2i_ECDSA_SIG(null(), signature_pointer, len(signature))
1434 if is_null(ecdsa_sig):
1435 raise SignatureError('Signature is invalid')
1437 ec_key = libcrypto.EVP_PKEY_get1_EC_KEY(certificate_or_public_key.evp_pkey)
1438 if is_null(ec_key):
1439 handle_openssl_error(0)
1441 res = libcrypto.ECDSA_do_verify(digest, len(digest), ecdsa_sig, ec_key)
1443 else:
1444 evp_pkey_ctx_pointer_pointer = new(libcrypto, 'EVP_PKEY_CTX **')
1445 res = libcrypto.EVP_DigestVerifyInit(
1446 evp_md_ctx,
1447 evp_pkey_ctx_pointer_pointer,
1448 evp_md,
1449 null(),
1450 certificate_or_public_key.evp_pkey
1451 )
1452 handle_openssl_error(res)
1453 evp_pkey_ctx_pointer = unwrap(evp_pkey_ctx_pointer_pointer)
1455 if rsa_pss_padding:
1456 # Enable PSS padding
1457 res = libcrypto.EVP_PKEY_CTX_ctrl(
1458 evp_pkey_ctx_pointer,
1459 LibcryptoConst.EVP_PKEY_RSA,
1460 -1, # All operations
1461 LibcryptoConst.EVP_PKEY_CTRL_RSA_PADDING,
1462 LibcryptoConst.RSA_PKCS1_PSS_PADDING,
1463 null()
1464 )
1465 handle_openssl_error(res)
1467 # Use the hash algorithm output length as the salt length
1468 if libcrypto_version_info < (3, 0):
1469 res = libcrypto.EVP_PKEY_CTX_ctrl(
1470 evp_pkey_ctx_pointer,
1471 LibcryptoConst.EVP_PKEY_RSA,
1472 LibcryptoConst.EVP_PKEY_OP_SIGN | LibcryptoConst.EVP_PKEY_OP_VERIFY,
1473 LibcryptoConst.EVP_PKEY_CTRL_RSA_PSS_SALTLEN,
1474 -1,
1475 null()
1476 )
1477 handle_openssl_error(res)
1479 res = libcrypto.EVP_DigestUpdate(evp_md_ctx, data, len(data))
1480 handle_openssl_error(res)
1482 res = libcrypto.EVP_DigestVerifyFinal(evp_md_ctx, signature, len(signature))
1484 if res < 1:
1485 raise SignatureError('Signature is invalid')
1486 handle_openssl_error(res)
1488 finally:
1489 if evp_md_ctx:
1490 if libcrypto_version_info < (1, 1):
1491 libcrypto.EVP_MD_CTX_destroy(evp_md_ctx)
1492 else:
1493 libcrypto.EVP_MD_CTX_free(evp_md_ctx)
1494 if rsa:
1495 libcrypto.RSA_free(rsa)
1496 if dsa:
1497 libcrypto.DSA_free(dsa)
1498 if dsa_sig:
1499 libcrypto.DSA_SIG_free(dsa_sig)
1500 if ec_key:
1501 libcrypto.EC_KEY_free(ec_key)
1502 if ecdsa_sig:
1503 libcrypto.ECDSA_SIG_free(ecdsa_sig)
1506def rsa_pkcs1v15_sign(private_key, data, hash_algorithm):
1507 """
1508 Generates an RSASSA-PKCS-v1.5 signature.
1510 When the hash_algorithm is "raw", the operation is identical to RSA
1511 private key encryption. That is: the data is not hashed and no ASN.1
1512 structure with an algorithm identifier of the hash algorithm is placed in
1513 the encrypted byte string.
1515 :param private_key:
1516 The PrivateKey to generate the signature with
1518 :param data:
1519 A byte string of the data the signature is for
1521 :param hash_algorithm:
1522 A unicode string of "md5", "sha1", "sha224", "sha256", "sha384",
1523 "sha512" or "raw"
1525 :raises:
1526 ValueError - when any of the parameters contain an invalid value
1527 TypeError - when any of the parameters are of the wrong type
1528 OSError - when an error is returned by the OS crypto library
1530 :return:
1531 A byte string of the signature
1532 """
1534 if private_key.algorithm != 'rsa':
1535 raise ValueError(pretty_message(
1536 '''
1537 The key specified is not an RSA private key, but %s
1538 ''',
1539 private_key.algorithm.upper()
1540 ))
1542 return _sign(private_key, data, hash_algorithm)
1545def rsa_pss_sign(private_key, data, hash_algorithm):
1546 """
1547 Generates an RSASSA-PSS signature. For the PSS padding the mask gen
1548 algorithm will be mgf1 using the same hash algorithm as the signature. The
1549 salt length with be the length of the hash algorithm, and the trailer field
1550 with be the standard 0xBC byte.
1552 :param private_key:
1553 The PrivateKey to generate the signature with
1555 :param data:
1556 A byte string of the data the signature is for
1558 :param hash_algorithm:
1559 A unicode string of "md5", "sha1", "sha224", "sha256", "sha384" or "sha512"
1561 :raises:
1562 ValueError - when any of the parameters contain an invalid value
1563 TypeError - when any of the parameters are of the wrong type
1564 OSError - when an error is returned by the OS crypto library
1566 :return:
1567 A byte string of the signature
1568 """
1570 pkey_alg = private_key.algorithm
1572 if pkey_alg != 'rsa' and pkey_alg != 'rsassa_pss':
1573 raise ValueError(pretty_message(
1574 '''
1575 The key specified is not an RSA private key, but %s
1576 ''',
1577 pkey_alg.upper()
1578 ))
1580 return _sign(private_key, data, hash_algorithm, rsa_pss_padding=True)
1583def dsa_sign(private_key, data, hash_algorithm):
1584 """
1585 Generates a DSA signature
1587 :param private_key:
1588 The PrivateKey to generate the signature with
1590 :param data:
1591 A byte string of the data the signature is for
1593 :param hash_algorithm:
1594 A unicode string of "md5", "sha1", "sha224", "sha256", "sha384" or "sha512"
1596 :raises:
1597 ValueError - when any of the parameters contain an invalid value
1598 TypeError - when any of the parameters are of the wrong type
1599 OSError - when an error is returned by the OS crypto library
1601 :return:
1602 A byte string of the signature
1603 """
1605 if private_key.algorithm != 'dsa':
1606 raise ValueError(pretty_message(
1607 '''
1608 The key specified is not a DSA private key, but %s
1609 ''',
1610 private_key.algorithm.upper()
1611 ))
1613 return _sign(private_key, data, hash_algorithm)
1616def ecdsa_sign(private_key, data, hash_algorithm):
1617 """
1618 Generates an ECDSA signature
1620 :param private_key:
1621 The PrivateKey to generate the signature with
1623 :param data:
1624 A byte string of the data the signature is for
1626 :param hash_algorithm:
1627 A unicode string of "md5", "sha1", "sha224", "sha256", "sha384" or "sha512"
1629 :raises:
1630 ValueError - when any of the parameters contain an invalid value
1631 TypeError - when any of the parameters are of the wrong type
1632 OSError - when an error is returned by the OS crypto library
1634 :return:
1635 A byte string of the signature
1636 """
1638 if private_key.algorithm != 'ec':
1639 raise ValueError(pretty_message(
1640 '''
1641 The key specified is not an EC private key, but %s
1642 ''',
1643 private_key.algorithm.upper()
1644 ))
1646 return _sign(private_key, data, hash_algorithm)
1649def _sign(private_key, data, hash_algorithm, rsa_pss_padding=False):
1650 """
1651 Generates an RSA, DSA or ECDSA signature
1653 :param private_key:
1654 The PrivateKey to generate the signature with
1656 :param data:
1657 A byte string of the data the signature is for
1659 :param hash_algorithm:
1660 A unicode string of "md5", "sha1", "sha224", "sha256", "sha384" or "sha512"
1662 :param rsa_pss_padding:
1663 If the private_key is an RSA key, this enables PSS padding
1665 :raises:
1666 ValueError - when any of the parameters contain an invalid value
1667 TypeError - when any of the parameters are of the wrong type
1668 OSError - when an error is returned by the OS crypto library
1670 :return:
1671 A byte string of the signature
1672 """
1674 if not isinstance(private_key, PrivateKey):
1675 raise TypeError(pretty_message(
1676 '''
1677 private_key must be an instance of PrivateKey, not %s
1678 ''',
1679 type_name(private_key)
1680 ))
1682 if not isinstance(data, byte_cls):
1683 raise TypeError(pretty_message(
1684 '''
1685 data must be a byte string, not %s
1686 ''',
1687 type_name(data)
1688 ))
1690 pkey_alg = private_key.algorithm
1691 pkey_is_rsa = pkey_alg == 'rsa' or pkey_alg == 'rsassa_pss'
1693 valid_hash_algorithms = set(['md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512'])
1694 if pkey_alg == 'rsa' and not rsa_pss_padding:
1695 valid_hash_algorithms |= set(['raw'])
1697 if hash_algorithm not in valid_hash_algorithms:
1698 valid_hash_algorithms_error = '"md5", "sha1", "sha224", "sha256", "sha384", "sha512"'
1699 if pkey_is_rsa and not rsa_pss_padding:
1700 valid_hash_algorithms_error += ', "raw"'
1701 raise ValueError(pretty_message(
1702 '''
1703 hash_algorithm must be one of %s, not %s
1704 ''',
1705 valid_hash_algorithms_error,
1706 repr(hash_algorithm)
1707 ))
1709 if not pkey_is_rsa and rsa_pss_padding:
1710 raise ValueError(pretty_message(
1711 '''
1712 PSS padding can only be used with RSA keys - the key provided is a
1713 %s key
1714 ''',
1715 pkey_alg.upper()
1716 ))
1718 if pkey_is_rsa and hash_algorithm == 'raw':
1719 if len(data) > private_key.byte_size - 11:
1720 raise ValueError(pretty_message(
1721 '''
1722 data must be 11 bytes shorter than the key size when
1723 hash_algorithm is "raw" - key size is %s bytes, but data is
1724 %s bytes long
1725 ''',
1726 private_key.byte_size,
1727 len(data)
1728 ))
1730 rsa = None
1732 try:
1733 rsa = libcrypto.EVP_PKEY_get1_RSA(private_key.evp_pkey)
1734 if is_null(rsa):
1735 handle_openssl_error(0)
1737 buffer_size = _evp_pkey_get_size(private_key.evp_pkey)
1739 signature_buffer = buffer_from_bytes(buffer_size)
1740 signature_length = libcrypto.RSA_private_encrypt(
1741 len(data),
1742 data,
1743 signature_buffer,
1744 rsa,
1745 LibcryptoConst.RSA_PKCS1_PADDING
1746 )
1747 handle_openssl_error(signature_length)
1749 return bytes_from_buffer(signature_buffer, signature_length)
1751 finally:
1752 if rsa:
1753 libcrypto.RSA_free(rsa)
1755 evp_md_ctx = None
1756 rsa = None
1757 dsa = None
1758 dsa_sig = None
1759 ec_key = None
1760 ecdsa_sig = None
1762 try:
1763 if libcrypto_version_info < (1, 1):
1764 evp_md_ctx = libcrypto.EVP_MD_CTX_create()
1765 else:
1766 evp_md_ctx = libcrypto.EVP_MD_CTX_new()
1768 evp_md = {
1769 'md5': libcrypto.EVP_md5,
1770 'sha1': libcrypto.EVP_sha1,
1771 'sha224': libcrypto.EVP_sha224,
1772 'sha256': libcrypto.EVP_sha256,
1773 'sha384': libcrypto.EVP_sha384,
1774 'sha512': libcrypto.EVP_sha512
1775 }[hash_algorithm]()
1777 if libcrypto_version_info < (1,):
1778 if pkey_is_rsa and rsa_pss_padding:
1779 digest = getattr(hashlib, hash_algorithm)(data).digest()
1781 rsa = libcrypto.EVP_PKEY_get1_RSA(private_key.evp_pkey)
1782 if is_null(rsa):
1783 handle_openssl_error(0)
1785 buffer_size = _evp_pkey_get_size(private_key.evp_pkey)
1786 em_buffer = buffer_from_bytes(buffer_size)
1787 res = libcrypto.RSA_padding_add_PKCS1_PSS(
1788 rsa,
1789 em_buffer,
1790 digest,
1791 evp_md,
1792 LibcryptoConst.EVP_MD_CTX_FLAG_PSS_MDLEN
1793 )
1794 handle_openssl_error(res)
1796 signature_buffer = buffer_from_bytes(buffer_size)
1797 signature_length = libcrypto.RSA_private_encrypt(
1798 buffer_size,
1799 em_buffer,
1800 signature_buffer,
1801 rsa,
1802 LibcryptoConst.RSA_NO_PADDING
1803 )
1804 handle_openssl_error(signature_length)
1806 elif pkey_is_rsa:
1807 buffer_size = _evp_pkey_get_size(private_key.evp_pkey)
1808 signature_buffer = buffer_from_bytes(buffer_size)
1809 signature_length = new(libcrypto, 'unsigned int *')
1811 res = libcrypto.EVP_DigestInit_ex(evp_md_ctx, evp_md, null())
1812 handle_openssl_error(res)
1814 res = libcrypto.EVP_DigestUpdate(evp_md_ctx, data, len(data))
1815 handle_openssl_error(res)
1817 res = libcrypto.EVP_SignFinal(
1818 evp_md_ctx,
1819 signature_buffer,
1820 signature_length,
1821 private_key.evp_pkey
1822 )
1823 handle_openssl_error(res)
1825 signature_length = deref(signature_length)
1827 elif pkey_alg == 'dsa':
1828 digest = getattr(hashlib, hash_algorithm)(data).digest()
1830 dsa = libcrypto.EVP_PKEY_get1_DSA(private_key.evp_pkey)
1831 if is_null(dsa):
1832 handle_openssl_error(0)
1834 dsa_sig = libcrypto.DSA_do_sign(digest, len(digest), dsa)
1835 if is_null(dsa_sig):
1836 handle_openssl_error(0)
1838 buffer_size = libcrypto.i2d_DSA_SIG(dsa_sig, null())
1839 signature_buffer = buffer_from_bytes(buffer_size)
1840 signature_pointer = buffer_pointer(signature_buffer)
1841 signature_length = libcrypto.i2d_DSA_SIG(dsa_sig, signature_pointer)
1842 handle_openssl_error(signature_length)
1844 elif pkey_alg == 'ec':
1845 digest = getattr(hashlib, hash_algorithm)(data).digest()
1847 ec_key = libcrypto.EVP_PKEY_get1_EC_KEY(private_key.evp_pkey)
1848 if is_null(ec_key):
1849 handle_openssl_error(0)
1851 ecdsa_sig = libcrypto.ECDSA_do_sign(digest, len(digest), ec_key)
1852 if is_null(ecdsa_sig):
1853 handle_openssl_error(0)
1855 buffer_size = libcrypto.i2d_ECDSA_SIG(ecdsa_sig, null())
1856 signature_buffer = buffer_from_bytes(buffer_size)
1857 signature_pointer = buffer_pointer(signature_buffer)
1858 signature_length = libcrypto.i2d_ECDSA_SIG(ecdsa_sig, signature_pointer)
1859 handle_openssl_error(signature_length)
1861 else:
1862 buffer_size = _evp_pkey_get_size(private_key.evp_pkey)
1863 signature_buffer = buffer_from_bytes(buffer_size)
1864 signature_length = new(libcrypto, 'size_t *', buffer_size)
1866 evp_pkey_ctx_pointer_pointer = new(libcrypto, 'EVP_PKEY_CTX **')
1867 res = libcrypto.EVP_DigestSignInit(
1868 evp_md_ctx,
1869 evp_pkey_ctx_pointer_pointer,
1870 evp_md,
1871 null(),
1872 private_key.evp_pkey
1873 )
1874 handle_openssl_error(res)
1875 evp_pkey_ctx_pointer = unwrap(evp_pkey_ctx_pointer_pointer)
1877 if rsa_pss_padding:
1878 # Enable PSS padding
1879 res = libcrypto.EVP_PKEY_CTX_ctrl(
1880 evp_pkey_ctx_pointer,
1881 LibcryptoConst.EVP_PKEY_RSA,
1882 -1, # All operations
1883 LibcryptoConst.EVP_PKEY_CTRL_RSA_PADDING,
1884 LibcryptoConst.RSA_PKCS1_PSS_PADDING,
1885 null()
1886 )
1887 handle_openssl_error(res)
1889 # Use the hash algorithm output length as the salt length
1890 if libcrypto_version_info < (3, 0):
1891 res = libcrypto.EVP_PKEY_CTX_ctrl(
1892 evp_pkey_ctx_pointer,
1893 LibcryptoConst.EVP_PKEY_RSA,
1894 LibcryptoConst.EVP_PKEY_OP_SIGN | LibcryptoConst.EVP_PKEY_OP_VERIFY,
1895 LibcryptoConst.EVP_PKEY_CTRL_RSA_PSS_SALTLEN,
1896 -1,
1897 null()
1898 )
1899 handle_openssl_error(res)
1901 res = libcrypto.EVP_DigestUpdate(evp_md_ctx, data, len(data))
1902 handle_openssl_error(res)
1904 res = libcrypto.EVP_DigestSignFinal(evp_md_ctx, signature_buffer, signature_length)
1905 handle_openssl_error(res)
1907 signature_length = deref(signature_length)
1909 return bytes_from_buffer(signature_buffer, signature_length)
1911 finally:
1912 if evp_md_ctx:
1913 if libcrypto_version_info < (1, 1):
1914 libcrypto.EVP_MD_CTX_destroy(evp_md_ctx)
1915 else:
1916 libcrypto.EVP_MD_CTX_free(evp_md_ctx)
1917 if rsa:
1918 libcrypto.RSA_free(rsa)
1919 if dsa:
1920 libcrypto.DSA_free(dsa)
1921 if dsa_sig:
1922 libcrypto.DSA_SIG_free(dsa_sig)
1923 if ec_key:
1924 libcrypto.EC_KEY_free(ec_key)
1925 if ecdsa_sig:
1926 libcrypto.ECDSA_SIG_free(ecdsa_sig)