aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Gaynor <alex.gaynor@gmail.com>2014-11-08 00:56:09 -0300
committerAlex Gaynor <alex.gaynor@gmail.com>2014-11-08 00:56:09 -0300
commitd3bdbdbdeedda6031cd23adee8bd530f4bcb5c7b (patch)
tree2ad3c2c0baef3573ad8053c4b23ef62a1715d0fd
parent29493c9c1029c43b24adaef69731e9668a321dc0 (diff)
parent6f21499d82d17c8655e77b8c771811d1d1d4353d (diff)
downloadcryptography-d3bdbdbdeedda6031cd23adee8bd530f4bcb5c7b.tar.gz
cryptography-d3bdbdbdeedda6031cd23adee8bd530f4bcb5c7b.tar.bz2
cryptography-d3bdbdbdeedda6031cd23adee8bd530f4bcb5c7b.zip
Merge pull request #1467 from dstufft/no-implicit-compile
Refactor to avoid the implicit compile when executing setup.py
-rw-r--r--cryptography/hazmat/bindings/commoncrypto/binding.py20
-rw-r--r--cryptography/hazmat/bindings/openssl/binding.py78
-rw-r--r--cryptography/hazmat/bindings/utils.py45
-rw-r--r--cryptography/hazmat/primitives/constant_time.py9
-rw-r--r--cryptography/hazmat/primitives/padding.py9
-rw-r--r--setup.py4
6 files changed, 97 insertions, 68 deletions
diff --git a/cryptography/hazmat/bindings/commoncrypto/binding.py b/cryptography/hazmat/bindings/commoncrypto/binding.py
index 0e6dffc0..bb950aac 100644
--- a/cryptography/hazmat/bindings/commoncrypto/binding.py
+++ b/cryptography/hazmat/bindings/commoncrypto/binding.py
@@ -13,7 +13,9 @@
from __future__ import absolute_import, division, print_function
-from cryptography.hazmat.bindings.utils import build_ffi_for_binding
+from cryptography.hazmat.bindings.utils import (
+ build_ffi_for_binding, load_library_for_binding,
+)
class Binding(object):
@@ -34,7 +36,13 @@ class Binding(object):
"sectransform",
]
- ffi = None
+ ffi = build_ffi_for_binding(
+ module_prefix=_module_prefix,
+ modules=_modules,
+ extra_link_args=[
+ "-framework", "Security", "-framework", "CoreFoundation"
+ ],
+ )
lib = None
def __init__(self):
@@ -42,13 +50,11 @@ class Binding(object):
@classmethod
def _ensure_ffi_initialized(cls):
- if cls.ffi is not None and cls.lib is not None:
+ if cls.lib is not None:
return
- cls.ffi, cls.lib = build_ffi_for_binding(
+ cls.lib = load_library_for_binding(
+ cls.ffi,
module_prefix=cls._module_prefix,
modules=cls._modules,
- extra_link_args=[
- "-framework", "Security", "-framework", "CoreFoundation"
- ]
)
diff --git a/cryptography/hazmat/bindings/openssl/binding.py b/cryptography/hazmat/bindings/openssl/binding.py
index 056785dc..ff9039cf 100644
--- a/cryptography/hazmat/bindings/openssl/binding.py
+++ b/cryptography/hazmat/bindings/openssl/binding.py
@@ -17,7 +17,9 @@ import os
import sys
import threading
-from cryptography.hazmat.bindings.utils import build_ffi_for_binding
+from cryptography.hazmat.bindings.utils import (
+ build_ffi_for_binding, load_library_for_binding,
+)
_OSX_PRE_INCLUDE = """
@@ -39,6 +41,31 @@ _OSX_POST_INCLUDE = """
"""
+def _get_libraries(platform):
+ # OpenSSL goes by a different library name on different operating systems.
+ if platform != "win32":
+ # In some circumstances, the order in which these libs are
+ # specified on the linker command-line is significant;
+ # libssl must come before libcrypto
+ # (http://marc.info/?l=openssl-users&m=135361825921871)
+ return ["ssl", "crypto"]
+ else:
+ link_type = os.environ.get("PYCA_WINDOWS_LINK_TYPE", "static")
+ return _get_windows_libraries(link_type)
+
+
+def _get_windows_libraries(link_type):
+ if link_type == "dynamic":
+ return ["libeay32", "ssleay32", "advapi32"]
+ elif link_type == "static" or link_type == "":
+ return ["libeay32mt", "ssleay32mt", "advapi32",
+ "crypt32", "gdi32", "user32", "ws2_32"]
+ else:
+ raise ValueError(
+ "PYCA_WINDOWS_LINK_TYPE must be 'static' or 'dynamic'"
+ )
+
+
class Binding(object):
"""
OpenSSL API wrapper.
@@ -82,7 +109,13 @@ class Binding(object):
_lock_cb_handle = None
_lock_init_lock = threading.Lock()
- ffi = None
+ ffi = build_ffi_for_binding(
+ module_prefix=_module_prefix,
+ modules=_modules,
+ pre_include=_OSX_PRE_INCLUDE,
+ post_include=_OSX_POST_INCLUDE,
+ libraries=_get_libraries(sys.platform)
+ )
lib = None
def __init__(self):
@@ -90,20 +123,15 @@ class Binding(object):
@classmethod
def _ensure_ffi_initialized(cls):
- if cls.ffi is not None and cls.lib is not None:
+ if cls.lib is not None:
return
- # OpenSSL goes by a different library name on different operating
- # systems.
- libraries = _get_libraries(sys.platform)
-
- cls.ffi, cls.lib = build_ffi_for_binding(
- module_prefix=cls._module_prefix,
- modules=cls._modules,
- pre_include=_OSX_PRE_INCLUDE,
- post_include=_OSX_POST_INCLUDE,
- libraries=libraries,
+ cls.lib = load_library_for_binding(
+ cls.ffi,
+ cls._module_prefix,
+ cls._modules,
)
+
res = cls.lib.Cryptography_add_osrandom_engine()
assert res != 0
@@ -146,27 +174,3 @@ class Binding(object):
mode, n, file, line
)
)
-
-
-def _get_libraries(platform):
- if platform != "win32":
- # In some circumstances, the order in which these libs are
- # specified on the linker command-line is significant;
- # libssl must come before libcrypto
- # (http://marc.info/?l=openssl-users&m=135361825921871)
- return ["ssl", "crypto"]
- else:
- link_type = os.environ.get("PYCA_WINDOWS_LINK_TYPE", "static")
- return _get_windows_libraries(link_type)
-
-
-def _get_windows_libraries(link_type):
- if link_type == "dynamic":
- return ["libeay32", "ssleay32", "advapi32"]
- elif link_type == "static" or link_type == "":
- return ["libeay32mt", "ssleay32mt", "advapi32",
- "crypt32", "gdi32", "user32", "ws2_32"]
- else:
- raise ValueError(
- "PYCA_WINDOWS_LINK_TYPE must be 'static' or 'dynamic'"
- )
diff --git a/cryptography/hazmat/bindings/utils.py b/cryptography/hazmat/bindings/utils.py
index 63334ff1..55b61292 100644
--- a/cryptography/hazmat/bindings/utils.py
+++ b/cryptography/hazmat/bindings/utils.py
@@ -14,13 +14,42 @@
from __future__ import absolute_import, division, print_function
import binascii
-
import sys
+import threading
from cffi import FFI
from cffi.verifier import Verifier
+class LazyLibrary(object):
+ def __init__(self, ffi):
+ self._ffi = ffi
+ self._lib = None
+ self._lock = threading.Lock()
+
+ def __getattr__(self, name):
+ if self._lib is None:
+ with self._lock:
+ if self._lib is None:
+ self._lib = self._ffi.verifier.load_library()
+
+ return getattr(self._lib, name)
+
+
+def load_library_for_binding(ffi, module_prefix, modules):
+ lib = ffi.verifier.load_library()
+
+ for name in modules:
+ module_name = module_prefix + name
+ module = sys.modules[module_name]
+ for condition, names in module.CONDITIONAL_NAMES.items():
+ if not getattr(lib, condition):
+ for name in names:
+ delattr(lib, name)
+
+ return lib
+
+
def build_ffi_for_binding(module_prefix, modules, pre_include="",
post_include="", libraries=[], extra_compile_args=[],
extra_link_args=[]):
@@ -69,7 +98,7 @@ def build_ffi_for_binding(module_prefix, modules, pre_include="",
functions +
customizations
)
- ffi, lib = build_ffi(
+ ffi = build_ffi(
cdef_source="\n".join(types + functions + macros),
verify_source=verify_source,
libraries=libraries,
@@ -77,15 +106,7 @@ def build_ffi_for_binding(module_prefix, modules, pre_include="",
extra_link_args=extra_link_args,
)
- for name in modules:
- module_name = module_prefix + name
- module = sys.modules[module_name]
- for condition, names in module.CONDITIONAL_NAMES.items():
- if not getattr(lib, condition):
- for name in names:
- delattr(lib, name)
-
- return ffi, lib
+ return ffi
def build_ffi(cdef_source, verify_source, libraries=[], extra_compile_args=[],
@@ -103,7 +124,7 @@ def build_ffi(cdef_source, verify_source, libraries=[], extra_compile_args=[],
extra_compile_args=extra_compile_args,
extra_link_args=extra_link_args,
)
- return ffi, ffi.verifier.load_library()
+ return ffi
def _create_modulename(cdef_sources, source, sys_version):
diff --git a/cryptography/hazmat/primitives/constant_time.py b/cryptography/hazmat/primitives/constant_time.py
index b98eb108..a14eda85 100644
--- a/cryptography/hazmat/primitives/constant_time.py
+++ b/cryptography/hazmat/primitives/constant_time.py
@@ -16,7 +16,7 @@ from __future__ import absolute_import, division, print_function
import hmac
import os
-from cryptography.hazmat.bindings.utils import build_ffi
+from cryptography.hazmat.bindings.utils import LazyLibrary, build_ffi
with open(os.path.join(os.path.dirname(__file__), "src/constant_time.h")) as f:
@@ -26,10 +26,9 @@ with open(os.path.join(os.path.dirname(__file__), "src/constant_time.c")) as f:
FUNCTIONS = f.read()
-_ffi, _lib = build_ffi(
- cdef_source=TYPES,
- verify_source=FUNCTIONS,
-)
+_ffi = build_ffi(cdef_source=TYPES, verify_source=FUNCTIONS)
+_lib = LazyLibrary(_ffi)
+
if hasattr(hmac, "compare_digest"):
def bytes_eq(a, b):
diff --git a/cryptography/hazmat/primitives/padding.py b/cryptography/hazmat/primitives/padding.py
index d799a7e1..7aeeff7c 100644
--- a/cryptography/hazmat/primitives/padding.py
+++ b/cryptography/hazmat/primitives/padding.py
@@ -17,7 +17,7 @@ import six
from cryptography import utils
from cryptography.exceptions import AlreadyFinalized
-from cryptography.hazmat.bindings.utils import build_ffi
+from cryptography.hazmat.bindings.utils import LazyLibrary, build_ffi
from cryptography.hazmat.primitives import interfaces
@@ -63,10 +63,9 @@ uint8_t Cryptography_check_pkcs7_padding(const uint8_t *data,
}
"""
-_ffi, _lib = build_ffi(
- cdef_source=TYPES,
- verify_source=FUNCTIONS,
-)
+
+_ffi = build_ffi(cdef_source=TYPES, verify_source=FUNCTIONS)
+_lib = LazyLibrary(_ffi)
class PKCS7(object):
diff --git a/setup.py b/setup.py
index bf4e864b..2a6646db 100644
--- a/setup.py
+++ b/setup.py
@@ -83,12 +83,12 @@ def get_ext_modules():
from cryptography.hazmat.primitives import constant_time, padding
ext_modules = [
- OpenSSLBinding().ffi.verifier.get_extension(),
+ OpenSSLBinding.ffi.verifier.get_extension(),
constant_time._ffi.verifier.get_extension(),
padding._ffi.verifier.get_extension()
]
if cc_is_available():
- ext_modules.append(CommonCryptoBinding().ffi.verifier.get_extension())
+ ext_modules.append(CommonCryptoBinding.ffi.verifier.get_extension())
return ext_modules