aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Gaynor <alex.gaynor@gmail.com>2014-01-04 11:16:58 -0800
committerAlex Gaynor <alex.gaynor@gmail.com>2014-01-04 11:16:58 -0800
commitd68fd37ec18c5adfa580d989730f7988d72d2bea (patch)
tree96fa1716ed1273dcd7f5b79c5939bc8f653c10ea
parent7c8e9ceb38855be9beda306bd281aaa9a09d1f02 (diff)
parent3366d8bab493386c2d10fdc6c7eca5f82ea5b515 (diff)
downloadcryptography-d68fd37ec18c5adfa580d989730f7988d72d2bea.tar.gz
cryptography-d68fd37ec18c5adfa580d989730f7988d72d2bea.tar.bz2
cryptography-d68fd37ec18c5adfa580d989730f7988d72d2bea.zip
Merge pull request #403 from reaperhulk/bindings-refactor
Refactor bindings to reduce code duplication with multiple backends
-rw-r--r--cryptography/hazmat/bindings/openssl/binding.py76
-rw-r--r--cryptography/hazmat/bindings/utils.py88
2 files changed, 92 insertions, 72 deletions
diff --git a/cryptography/hazmat/bindings/openssl/binding.py b/cryptography/hazmat/bindings/openssl/binding.py
index 8b5e3449..4f6b99ae 100644
--- a/cryptography/hazmat/bindings/openssl/binding.py
+++ b/cryptography/hazmat/bindings/openssl/binding.py
@@ -13,9 +13,7 @@
from __future__ import absolute_import, division, print_function
-import sys
-
-import cffi
+from cryptography.hazmat.bindings.utils import build_ffi
_OSX_PRE_INCLUDE = """
#ifdef __APPLE__
@@ -39,20 +37,6 @@ _OSX_POST_INCLUDE = """
class Binding(object):
"""
OpenSSL API wrapper.
-
- Modules listed in the ``_modules`` listed should have the following
- attributes:
-
- * ``INCLUDES``: A string containg C includes.
- * ``TYPES``: A string containing C declarations for types.
- * ``FUNCTIONS``: A string containing C declarations for functions.
- * ``MACROS``: A string containing C declarations for any macros.
- * ``CUSTOMIZATIONS``: A string containing arbitrary top-level C code, this
- can be used to do things like test for a define and provide an
- alternate implementation based on that.
- * ``CONDITIONAL_NAMES``: A dict mapping strings of condition names from the
- library to a list of names which will not be present without the
- condition.
"""
_module_prefix = "cryptography.hazmat.bindings.openssl."
_modules = [
@@ -92,58 +76,6 @@ class Binding(object):
if cls.ffi is not None and cls.lib is not None:
return
- ffi = cffi.FFI()
- includes = []
- functions = []
- macros = []
- customizations = []
- for name in cls._modules:
- module_name = cls._module_prefix + name
- __import__(module_name)
- module = sys.modules[module_name]
-
- ffi.cdef(module.TYPES)
-
- macros.append(module.MACROS)
- functions.append(module.FUNCTIONS)
- includes.append(module.INCLUDES)
- customizations.append(module.CUSTOMIZATIONS)
-
- # loop over the functions & macros after declaring all the types
- # so we can set interdependent types in different files and still
- # have them all defined before we parse the funcs & macros
- for func in functions:
- ffi.cdef(func)
- for macro in macros:
- ffi.cdef(macro)
-
- # 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
- # to re-declare a function if it has the same signature. That is:
- # int foo(int);
- # int foo(int);
- # is legal, but the following will fail to compile:
- # int foo(int);
- # int foo(short);
-
- lib = ffi.verify(
- source="\n".join(
- [_OSX_PRE_INCLUDE] +
- includes +
- [_OSX_POST_INCLUDE] +
- functions +
- customizations
- ),
- libraries=["crypto", "ssl"],
- )
-
- for name in cls._modules:
- module_name = cls._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)
-
- cls.ffi = ffi
- cls.lib = lib
+ cls.ffi, cls.lib = build_ffi(cls._module_prefix, cls._modules,
+ _OSX_PRE_INCLUDE, _OSX_POST_INCLUDE,
+ ["crypto", "ssl"])
diff --git a/cryptography/hazmat/bindings/utils.py b/cryptography/hazmat/bindings/utils.py
new file mode 100644
index 00000000..9e1d3937
--- /dev/null
+++ b/cryptography/hazmat/bindings/utils.py
@@ -0,0 +1,88 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from __future__ import absolute_import, division, print_function
+
+import sys
+
+import cffi
+
+
+def build_ffi(module_prefix, modules, pre_include, post_include, libraries):
+ """
+ Modules listed in ``modules`` should have the following attributes:
+
+ * ``INCLUDES``: A string containing C includes.
+ * ``TYPES``: A string containing C declarations for types.
+ * ``FUNCTIONS``: A string containing C declarations for functions.
+ * ``MACROS``: A string containing C declarations for any macros.
+ * ``CUSTOMIZATIONS``: A string containing arbitrary top-level C code, this
+ can be used to do things like test for a define and provide an
+ alternate implementation based on that.
+ * ``CONDITIONAL_NAMES``: A dict mapping strings of condition names from the
+ library to a list of names which will not be present without the
+ condition.
+ """
+ ffi = cffi.FFI()
+ includes = []
+ functions = []
+ macros = []
+ customizations = []
+ for name in modules:
+ module_name = module_prefix + name
+ __import__(module_name)
+ module = sys.modules[module_name]
+
+ ffi.cdef(module.TYPES)
+
+ macros.append(module.MACROS)
+ functions.append(module.FUNCTIONS)
+ includes.append(module.INCLUDES)
+ customizations.append(module.CUSTOMIZATIONS)
+
+ # loop over the functions & macros after declaring all the types
+ # so we can set interdependent types in different files and still
+ # have them all defined before we parse the funcs & macros
+ for func in functions:
+ ffi.cdef(func)
+ for macro in macros:
+ ffi.cdef(macro)
+
+ # 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
+ # to re-declare a function if it has the same signature. That is:
+ # int foo(int);
+ # int foo(int);
+ # is legal, but the following will fail to compile:
+ # int foo(int);
+ # int foo(short);
+ lib = ffi.verify(
+ source="\n".join(
+ [pre_include] +
+ includes +
+ [post_include] +
+ functions +
+ customizations
+ ),
+ libraries=libraries
+ )
+
+ 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