aboutsummaryrefslogtreecommitdiffstats
path: root/cryptography/hazmat
diff options
context:
space:
mode:
Diffstat (limited to 'cryptography/hazmat')
-rw-r--r--cryptography/hazmat/bindings/utils.py38
1 files changed, 30 insertions, 8 deletions
diff --git a/cryptography/hazmat/bindings/utils.py b/cryptography/hazmat/bindings/utils.py
index b8253483..318b82bb 100644
--- a/cryptography/hazmat/bindings/utils.py
+++ b/cryptography/hazmat/bindings/utils.py
@@ -13,6 +13,8 @@
from __future__ import absolute_import, division, print_function
+import binascii
+
import sys
import cffi
@@ -50,7 +52,8 @@ def build_ffi(module_prefix, modules, pre_include, post_include, libraries):
includes.append(module.INCLUDES)
customizations.append(module.CUSTOMIZATIONS)
- ffi.cdef("\n".join(types + functions + macros))
+ cdef_sources = types + functions + macros
+ ffi.cdef("\n".join(cdef_sources))
# We include functions here so that if we got any of their definitions
# wrong, the underlying C compiler will explode. In C you are allowed
@@ -60,14 +63,16 @@ def build_ffi(module_prefix, modules, pre_include, post_include, libraries):
# is legal, but the following will fail to compile:
# int foo(int);
# int foo(short);
+ source = "\n".join(
+ [pre_include] +
+ includes +
+ [post_include] +
+ functions +
+ customizations
+ )
lib = ffi.verify(
- source="\n".join(
- [pre_include] +
- includes +
- [post_include] +
- functions +
- customizations
- ),
+ source=source,
+ modulename=_create_modulename(cdef_sources, source, sys.version),
libraries=libraries,
ext_package="cryptography",
)
@@ -81,3 +86,20 @@ def build_ffi(module_prefix, modules, pre_include, post_include, libraries):
delattr(lib, name)
return ffi, lib
+
+
+def _create_modulename(cdef_sources, source, sys_version):
+ """
+ cffi creates a modulename internally that incorporates the cffi version.
+ This will cause cryptography's wheels to break when the version of cffi
+ the user has does not match what was used when building the wheel. To
+ resolve this we build our own modulename that uses most of the same code
+ from cffi but elides the version key.
+ """
+ key = '\x00'.join([sys_version[:3], source] + cdef_sources)
+ key = key.encode('utf-8')
+ k1 = hex(binascii.crc32(key[0::2]) & 0xffffffff)
+ k1 = k1.lstrip('0x').rstrip('L')
+ k2 = hex(binascii.crc32(key[1::2]) & 0xffffffff)
+ k2 = k2.lstrip('0').rstrip('L')
+ return '_Cryptography_cffi_{0}{1}'.format(k1, k2)