aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/_cffi_src/utils.py13
-rw-r--r--src/cryptography/hazmat/bindings/openssl/binding.py24
-rw-r--r--tests/hazmat/bindings/test_openssl.py6
3 files changed, 42 insertions, 1 deletions
diff --git a/src/_cffi_src/utils.py b/src/_cffi_src/utils.py
index d3dd18a4..eecd6ea1 100644
--- a/src/_cffi_src/utils.py
+++ b/src/_cffi_src/utils.py
@@ -4,6 +4,7 @@
from __future__ import absolute_import, division, print_function
+import os
import sys
from distutils.ccompiler import new_compiler
from distutils.dist import Distribution
@@ -11,6 +12,13 @@ from distutils.dist import Distribution
from cffi import FFI
+# Load the cryptography __about__ to get the current package version
+base_src = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+about = {}
+with open(os.path.join(base_src, "cryptography", "__about__.py")) as f:
+ exec(f.read(), about)
+
+
def build_ffi_for_binding(module_name, module_prefix, modules, libraries=[],
extra_compile_args=[], extra_link_args=[]):
"""
@@ -55,6 +63,11 @@ def build_ffi_for_binding(module_name, module_prefix, modules, libraries=[],
def build_ffi(module_name, cdef_source, verify_source, libraries=[],
extra_compile_args=[], extra_link_args=[]):
ffi = FFI()
+ # Always add the CRYPTOGRAPHY_PACKAGE_VERSION to the shared object
+ cdef_source += "\nstatic const char *const CRYPTOGRAPHY_PACKAGE_VERSION;"
+ verify_source += '\n#define CRYPTOGRAPHY_PACKAGE_VERSION "{}"'.format(
+ about["__version__"]
+ )
ffi.cdef(cdef_source)
ffi.set_source(
module_name,
diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py
index 0824ea88..1115acbf 100644
--- a/src/cryptography/hazmat/bindings/openssl/binding.py
+++ b/src/cryptography/hazmat/bindings/openssl/binding.py
@@ -9,6 +9,7 @@ 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
@@ -164,6 +165,29 @@ def _verify_openssl_version(lib):
)
+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
+ )
+ )
+
+
+_verify_package_version(cryptography.__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
diff --git a/tests/hazmat/bindings/test_openssl.py b/tests/hazmat/bindings/test_openssl.py
index fb1e62fa..29a1c459 100644
--- a/tests/hazmat/bindings/test_openssl.py
+++ b/tests/hazmat/bindings/test_openssl.py
@@ -8,7 +8,7 @@ import pytest
from cryptography.exceptions import InternalError
from cryptography.hazmat.bindings.openssl.binding import (
- Binding, _consume_errors, _openssl_assert
+ Binding, _consume_errors, _openssl_assert, _verify_package_version
)
@@ -118,3 +118,7 @@ class TestOpenSSL(object):
)
b._register_osrandom_engine()
assert _consume_errors(b.lib) == []
+
+ def test_version_mismatch(self):
+ with pytest.raises(ImportError):
+ _verify_package_version("nottherightversion")