summaryrefslogtreecommitdiff
path: root/src/cryptography/hazmat/bindings/openssl/binding.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/cryptography/hazmat/bindings/openssl/binding.py')
-rw-r--r--src/cryptography/hazmat/bindings/openssl/binding.py108
1 files changed, 53 insertions, 55 deletions
diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py
index 0824ea88c..7a84a340e 100644
--- a/src/cryptography/hazmat/bindings/openssl/binding.py
+++ b/src/cryptography/hazmat/bindings/openssl/binding.py
@@ -7,8 +7,8 @@ from __future__ import absolute_import, division, print_function
import collections
import threading
import types
-import warnings
+import cryptography
from cryptography import utils
from cryptography.exceptions import InternalError
from cryptography.hazmat.bindings._openssl import ffi, lib
@@ -51,20 +51,31 @@ def _consume_errors(lib):
return errors
-def _openssl_assert(lib, ok):
- if not ok:
- errors = _consume_errors(lib)
- errors_with_text = []
- for err in errors:
- buf = ffi.new("char[]", 256)
- lib.ERR_error_string_n(err.code, buf, len(buf))
- err_text_reason = ffi.string(buf)
-
- errors_with_text.append(
- _OpenSSLErrorWithText(
- err.code, err.lib, err.func, err.reason, err_text_reason
- )
+def _errors_with_text(errors):
+ errors_with_text = []
+ for err in errors:
+ buf = ffi.new("char[]", 256)
+ lib.ERR_error_string_n(err.code, buf, len(buf))
+ err_text_reason = ffi.string(buf)
+
+ errors_with_text.append(
+ _OpenSSLErrorWithText(
+ err.code, err.lib, err.func, err.reason, err_text_reason
)
+ )
+
+ return errors_with_text
+
+
+def _consume_errors_with_text(lib):
+ return _errors_with_text(_consume_errors(lib))
+
+
+def _openssl_assert(lib, ok, errors=None):
+ if not ok:
+ if errors is None:
+ errors = _consume_errors(lib)
+ errors_with_text = _errors_with_text(errors)
raise InternalError(
"Unknown OpenSSL error. This error is commonly encountered when "
@@ -74,7 +85,7 @@ def _openssl_assert(lib, ok):
"please file an issue at https://github.com/pyca/cryptography/"
"issues with information on how to reproduce "
"this. ({0!r})".format(errors_with_text),
- errors_with_text
+ errors_with_text,
)
@@ -97,11 +108,11 @@ class Binding(object):
"""
OpenSSL API wrapper.
"""
+
lib = None
ffi = ffi
_lib_loaded = False
_init_lock = threading.Lock()
- _lock_init_lock = threading.Lock()
def __init__(self):
self._ensure_ffi_initialized()
@@ -114,10 +125,9 @@ class Binding(object):
# reliably clear the error queue. Once we clear it here we will
# error on any subsequent unexpected item in the stack.
cls.lib.ERR_clear_error()
- cls._osrandom_engine_id = cls.lib.Cryptography_osrandom_engine_id
- cls._osrandom_engine_name = cls.lib.Cryptography_osrandom_engine_name
- result = cls.lib.Cryptography_add_osrandom_engine()
- _openssl_assert(cls.lib, result in (1, 2))
+ if cls.lib.CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE:
+ result = cls.lib.Cryptography_add_osrandom_engine()
+ _openssl_assert(cls.lib, result in (1, 2))
@classmethod
def _ensure_ffi_initialized(cls):
@@ -129,46 +139,34 @@ class Binding(object):
cls.lib.SSL_library_init()
# adds all ciphers/digests for EVP
cls.lib.OpenSSL_add_all_algorithms()
- # loads error strings for libcrypto and libssl functions
- cls.lib.SSL_load_error_strings()
cls._register_osrandom_engine()
@classmethod
def init_static_locks(cls):
- with cls._lock_init_lock:
- cls._ensure_ffi_initialized()
- # Use Python's implementation if available, importing _ssl triggers
- # the setup for this.
- __import__("_ssl")
-
- if (not cls.lib.Cryptography_HAS_LOCKING_CALLBACKS or
- cls.lib.CRYPTO_get_locking_callback() != cls.ffi.NULL):
- return
-
- # If nothing else has setup a locking callback already, we set up
- # our own
- res = lib.Cryptography_setup_ssl_threads()
- _openssl_assert(cls.lib, res == 1)
-
-
-def _verify_openssl_version(lib):
- if (
- lib.CRYPTOGRAPHY_OPENSSL_LESS_THAN_102 and
- not lib.CRYPTOGRAPHY_IS_LIBRESSL
- ):
- warnings.warn(
- "OpenSSL version 1.0.1 is no longer supported by the OpenSSL "
- "project, please upgrade. A future version of cryptography will "
- "drop support for it.",
- utils.CryptographyDeprecationWarning
+ cls._ensure_ffi_initialized()
+
+
+def _verify_package_version(version):
+ # Occasionally we run into situations where the version of the Python
+ # package does not match the version of the shared object that is loaded.
+ # This may occur in environments where multiple versions of cryptography
+ # are installed and available in the python path. To avoid errors cropping
+ # up later this code checks that the currently imported package and the
+ # shared object that were loaded have the same version and raise an
+ # ImportError if they do not
+ so_package_version = ffi.string(lib.CRYPTOGRAPHY_PACKAGE_VERSION)
+ if version.encode("ascii") != so_package_version:
+ raise ImportError(
+ "The version of cryptography does not match the loaded "
+ "shared object. This can happen if you have multiple copies of "
+ "cryptography installed in your Python path. Please try creating "
+ "a new virtual environment to resolve this issue. "
+ "Loaded python version: {}, shared object version: {}".format(
+ version, so_package_version
+ )
)
-# OpenSSL is not thread safe until the locks are initialized. We call this
-# method in module scope so that it executes with the import lock. On
-# Pythons < 3.4 this import lock is a global lock, which can prevent a race
-# condition registering the OpenSSL locks. On Python 3.4+ the import lock
-# is per module so this approach will not work.
-Binding.init_static_locks()
+_verify_package_version(cryptography.__version__)
-_verify_openssl_version(Binding.lib)
+Binding.init_static_locks()