Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/oscrypto/_openssl/_libcrypto.py: 66%
67 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
4from .. import ffi
5from .._ffi import buffer_from_bytes, byte_string_from_buffer, null
6from .._types import str_cls
8if ffi() == 'cffi':
9 from ._libcrypto_cffi import (
10 libcrypto,
11 version as libcrypto_version,
12 version_info as libcrypto_version_info
13 )
14else:
15 from ._libcrypto_ctypes import (
16 libcrypto,
17 version as libcrypto_version,
18 version_info as libcrypto_version_info
19 )
22__all__ = [
23 'handle_openssl_error',
24 'libcrypto',
25 'libcrypto_legacy_support',
26 'libcrypto_version',
27 'libcrypto_version_info',
28 'LibcryptoConst',
29 'peek_openssl_error',
30]
33_encoding = 'utf-8'
34_fallback_encodings = ['utf-8', 'cp1252']
37if libcrypto_version_info < (1, 1):
38 libcrypto.ERR_load_crypto_strings()
39libcrypto.OPENSSL_config(null())
42# This enables legacy algorithms in OpenSSL 3.0, such as RC2, etc
43# which are used by various tests and some old protocols and things
44# like PKCS12
45libcrypto_legacy_support = True
46if libcrypto_version_info >= (3, ):
48 libcrypto.OSSL_PROVIDER_load(null(), "legacy".encode("ascii"))
49 libcrypto.OSSL_PROVIDER_load(null(), "default".encode("ascii"))
51 if libcrypto.OSSL_PROVIDER_available(null(), "legacy".encode("ascii")) == 0:
52 libcrypto_legacy_support = False
55def _try_decode(value):
57 try:
58 return str_cls(value, _encoding)
60 # If the "correct" encoding did not work, try some defaults, and then just
61 # obliterate characters that we can't seen to decode properly
62 except (UnicodeDecodeError):
63 for encoding in _fallback_encodings:
64 try:
65 return str_cls(value, encoding, errors='strict')
66 except (UnicodeDecodeError):
67 pass
69 return str_cls(value, errors='replace')
72def handle_openssl_error(result, exception_class=None):
73 """
74 Checks if an error occurred, and if so throws an OSError containing the
75 last OpenSSL error message
77 :param result:
78 An integer result code - 1 or greater indicates success
80 :param exception_class:
81 The exception class to use for the exception if an error occurred
83 :raises:
84 OSError - when an OpenSSL error occurs
85 """
87 if result > 0:
88 return
90 if exception_class is None:
91 exception_class = OSError
93 error_num = libcrypto.ERR_get_error()
94 buffer = buffer_from_bytes(120)
95 libcrypto.ERR_error_string(error_num, buffer)
97 # Since we are dealing with a string, it is NULL terminated
98 error_string = byte_string_from_buffer(buffer)
100 raise exception_class(_try_decode(error_string))
103def peek_openssl_error():
104 """
105 Peeks into the error stack and pulls out the lib, func and reason
107 :return:
108 A three-element tuple of integers (lib, func, reason)
109 """
111 error = libcrypto.ERR_peek_error()
112 if libcrypto_version_info < (3, 0):
113 lib = int((error >> 24) & 0xff)
114 func = int((error >> 12) & 0xfff)
115 reason = int(error & 0xfff)
116 else:
117 lib = int((error >> 23) & 0xff)
118 # OpenSSL 3.0 removed ERR_GET_FUNC()
119 func = 0
120 reason = int(error & 0x7fffff)
122 return (lib, func, reason)
125class LibcryptoConst():
126 EVP_CTRL_SET_RC2_KEY_BITS = 3
128 SSLEAY_VERSION = 0
130 RSA_PKCS1_PADDING = 1
131 RSA_NO_PADDING = 3
132 RSA_PKCS1_OAEP_PADDING = 4
134 # OpenSSL 0.9.x
135 EVP_MD_CTX_FLAG_PSS_MDLEN = -1
137 # OpenSSL 1.x.x
138 EVP_PKEY_CTRL_RSA_PADDING = 0x1001
139 RSA_PKCS1_PSS_PADDING = 6
140 EVP_PKEY_CTRL_RSA_PSS_SALTLEN = 0x1002
141 EVP_PKEY_RSA = 6
142 EVP_PKEY_OP_SIGN = 1 << 3
143 EVP_PKEY_OP_VERIFY = 1 << 4
145 NID_X9_62_prime256v1 = 415
146 NID_secp384r1 = 715
147 NID_secp521r1 = 716
149 OPENSSL_EC_NAMED_CURVE = 1
151 DH_GENERATOR_2 = 2