Split OpenSSL binding
diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py
index 6231aad..b25d86d 100644
--- a/cryptography/hazmat/backends/openssl/backend.py
+++ b/cryptography/hazmat/backends/openssl/backend.py
@@ -14,9 +14,6 @@
 from __future__ import absolute_import, division, print_function
 
 import itertools
-import sys
-
-import cffi
 
 from cryptography import utils
 from cryptography.exceptions import UnsupportedAlgorithm, InvalidTag
@@ -30,24 +27,7 @@
 from cryptography.hazmat.primitives.ciphers.modes import (
     CBC, CTR, ECB, OFB, CFB, GCM,
 )
-
-_OSX_PRE_INCLUDE = """
-#ifdef __APPLE__
-#include <AvailabilityMacros.h>
-#define __ORIG_DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER \
-    DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
-#undef DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
-#define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
-#endif
-"""
-
-_OSX_POST_INCLUDE = """
-#ifdef __APPLE__
-#undef DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
-#define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER \
-    __ORIG_DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
-#endif
-"""
+from cryptography.hazmat.bindings.openssl.binding import Binding
 
 
 @utils.register_interface(CipherBackend)
@@ -55,121 +35,20 @@
 @utils.register_interface(HMACBackend)
 class Backend(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.
+    OpenSSL API binding interfaces.
     """
-    _module_prefix = "cryptography.hazmat.backends.openssl."
-    _modules = [
-        "asn1",
-        "bignum",
-        "bio",
-        "conf",
-        "crypto",
-        "dh",
-        "dsa",
-        "engine",
-        "err",
-        "evp",
-        "hmac",
-        "nid",
-        "objects",
-        "opensslv",
-        "pem",
-        "pkcs7",
-        "pkcs12",
-        "rand",
-        "rsa",
-        "ssl",
-        "x509",
-        "x509name",
-        "x509v3",
-    ]
-
-    ffi = None
-    lib = None
 
     def __init__(self):
-        self._ensure_ffi_initialized()
+        self._binding = Binding()
+        self.ffi = self._binding.ffi
+        self.lib = self._binding.lib
+
+        self.lib.OpenSSL_add_all_algorithms()
+        self.lib.SSL_load_error_strings()
 
         self._cipher_registry = {}
         self._register_default_ciphers()
 
-    @classmethod
-    def _ensure_ffi_initialized(cls):
-        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.lib.OpenSSL_add_all_algorithms()
-        cls.lib.SSL_load_error_strings()
-
     def openssl_version_text(self):
         """
         Friendly string name of linked OpenSSL.
diff --git a/cryptography/hazmat/bindings/__init__.py b/cryptography/hazmat/bindings/__init__.py
new file mode 100644
index 0000000..55c925c
--- /dev/null
+++ b/cryptography/hazmat/bindings/__init__.py
@@ -0,0 +1,12 @@
+# 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.
diff --git a/cryptography/hazmat/bindings/openssl/__init__.py b/cryptography/hazmat/bindings/openssl/__init__.py
new file mode 100644
index 0000000..55c925c
--- /dev/null
+++ b/cryptography/hazmat/bindings/openssl/__init__.py
@@ -0,0 +1,12 @@
+# 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.
diff --git a/cryptography/hazmat/backends/openssl/asn1.py b/cryptography/hazmat/bindings/openssl/asn1.py
similarity index 100%
rename from cryptography/hazmat/backends/openssl/asn1.py
rename to cryptography/hazmat/bindings/openssl/asn1.py
diff --git a/cryptography/hazmat/backends/openssl/bignum.py b/cryptography/hazmat/bindings/openssl/bignum.py
similarity index 100%
rename from cryptography/hazmat/backends/openssl/bignum.py
rename to cryptography/hazmat/bindings/openssl/bignum.py
diff --git a/cryptography/hazmat/bindings/openssl/binding.py b/cryptography/hazmat/bindings/openssl/binding.py
new file mode 100644
index 0000000..8b5e344
--- /dev/null
+++ b/cryptography/hazmat/bindings/openssl/binding.py
@@ -0,0 +1,149 @@
+# 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
+
+_OSX_PRE_INCLUDE = """
+#ifdef __APPLE__
+#include <AvailabilityMacros.h>
+#define __ORIG_DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER \
+    DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
+#undef DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
+#define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
+#endif
+"""
+
+_OSX_POST_INCLUDE = """
+#ifdef __APPLE__
+#undef DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
+#define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER \
+    __ORIG_DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
+#endif
+"""
+
+
+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 = [
+        "asn1",
+        "bignum",
+        "bio",
+        "conf",
+        "crypto",
+        "dh",
+        "dsa",
+        "engine",
+        "err",
+        "evp",
+        "hmac",
+        "nid",
+        "objects",
+        "opensslv",
+        "pem",
+        "pkcs7",
+        "pkcs12",
+        "rand",
+        "rsa",
+        "ssl",
+        "x509",
+        "x509name",
+        "x509v3",
+    ]
+
+    ffi = None
+    lib = None
+
+    def __init__(self):
+        self._ensure_ffi_initialized()
+
+    @classmethod
+    def _ensure_ffi_initialized(cls):
+        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
diff --git a/cryptography/hazmat/backends/openssl/bio.py b/cryptography/hazmat/bindings/openssl/bio.py
similarity index 100%
rename from cryptography/hazmat/backends/openssl/bio.py
rename to cryptography/hazmat/bindings/openssl/bio.py
diff --git a/cryptography/hazmat/backends/openssl/conf.py b/cryptography/hazmat/bindings/openssl/conf.py
similarity index 100%
rename from cryptography/hazmat/backends/openssl/conf.py
rename to cryptography/hazmat/bindings/openssl/conf.py
diff --git a/cryptography/hazmat/backends/openssl/crypto.py b/cryptography/hazmat/bindings/openssl/crypto.py
similarity index 100%
rename from cryptography/hazmat/backends/openssl/crypto.py
rename to cryptography/hazmat/bindings/openssl/crypto.py
diff --git a/cryptography/hazmat/backends/openssl/dh.py b/cryptography/hazmat/bindings/openssl/dh.py
similarity index 100%
rename from cryptography/hazmat/backends/openssl/dh.py
rename to cryptography/hazmat/bindings/openssl/dh.py
diff --git a/cryptography/hazmat/backends/openssl/dsa.py b/cryptography/hazmat/bindings/openssl/dsa.py
similarity index 100%
rename from cryptography/hazmat/backends/openssl/dsa.py
rename to cryptography/hazmat/bindings/openssl/dsa.py
diff --git a/cryptography/hazmat/backends/openssl/engine.py b/cryptography/hazmat/bindings/openssl/engine.py
similarity index 100%
rename from cryptography/hazmat/backends/openssl/engine.py
rename to cryptography/hazmat/bindings/openssl/engine.py
diff --git a/cryptography/hazmat/backends/openssl/err.py b/cryptography/hazmat/bindings/openssl/err.py
similarity index 100%
rename from cryptography/hazmat/backends/openssl/err.py
rename to cryptography/hazmat/bindings/openssl/err.py
diff --git a/cryptography/hazmat/backends/openssl/evp.py b/cryptography/hazmat/bindings/openssl/evp.py
similarity index 100%
rename from cryptography/hazmat/backends/openssl/evp.py
rename to cryptography/hazmat/bindings/openssl/evp.py
diff --git a/cryptography/hazmat/backends/openssl/hmac.py b/cryptography/hazmat/bindings/openssl/hmac.py
similarity index 100%
rename from cryptography/hazmat/backends/openssl/hmac.py
rename to cryptography/hazmat/bindings/openssl/hmac.py
diff --git a/cryptography/hazmat/backends/openssl/nid.py b/cryptography/hazmat/bindings/openssl/nid.py
similarity index 100%
rename from cryptography/hazmat/backends/openssl/nid.py
rename to cryptography/hazmat/bindings/openssl/nid.py
diff --git a/cryptography/hazmat/backends/openssl/objects.py b/cryptography/hazmat/bindings/openssl/objects.py
similarity index 100%
rename from cryptography/hazmat/backends/openssl/objects.py
rename to cryptography/hazmat/bindings/openssl/objects.py
diff --git a/cryptography/hazmat/backends/openssl/opensslv.py b/cryptography/hazmat/bindings/openssl/opensslv.py
similarity index 100%
rename from cryptography/hazmat/backends/openssl/opensslv.py
rename to cryptography/hazmat/bindings/openssl/opensslv.py
diff --git a/cryptography/hazmat/backends/openssl/pem.py b/cryptography/hazmat/bindings/openssl/pem.py
similarity index 100%
rename from cryptography/hazmat/backends/openssl/pem.py
rename to cryptography/hazmat/bindings/openssl/pem.py
diff --git a/cryptography/hazmat/backends/openssl/pkcs12.py b/cryptography/hazmat/bindings/openssl/pkcs12.py
similarity index 100%
rename from cryptography/hazmat/backends/openssl/pkcs12.py
rename to cryptography/hazmat/bindings/openssl/pkcs12.py
diff --git a/cryptography/hazmat/backends/openssl/pkcs7.py b/cryptography/hazmat/bindings/openssl/pkcs7.py
similarity index 100%
rename from cryptography/hazmat/backends/openssl/pkcs7.py
rename to cryptography/hazmat/bindings/openssl/pkcs7.py
diff --git a/cryptography/hazmat/backends/openssl/rand.py b/cryptography/hazmat/bindings/openssl/rand.py
similarity index 100%
rename from cryptography/hazmat/backends/openssl/rand.py
rename to cryptography/hazmat/bindings/openssl/rand.py
diff --git a/cryptography/hazmat/backends/openssl/rsa.py b/cryptography/hazmat/bindings/openssl/rsa.py
similarity index 100%
rename from cryptography/hazmat/backends/openssl/rsa.py
rename to cryptography/hazmat/bindings/openssl/rsa.py
diff --git a/cryptography/hazmat/backends/openssl/ssl.py b/cryptography/hazmat/bindings/openssl/ssl.py
similarity index 100%
rename from cryptography/hazmat/backends/openssl/ssl.py
rename to cryptography/hazmat/bindings/openssl/ssl.py
diff --git a/cryptography/hazmat/backends/openssl/x509.py b/cryptography/hazmat/bindings/openssl/x509.py
similarity index 100%
rename from cryptography/hazmat/backends/openssl/x509.py
rename to cryptography/hazmat/bindings/openssl/x509.py
diff --git a/cryptography/hazmat/backends/openssl/x509name.py b/cryptography/hazmat/bindings/openssl/x509name.py
similarity index 100%
rename from cryptography/hazmat/backends/openssl/x509name.py
rename to cryptography/hazmat/bindings/openssl/x509name.py
diff --git a/cryptography/hazmat/backends/openssl/x509v3.py b/cryptography/hazmat/bindings/openssl/x509v3.py
similarity index 100%
rename from cryptography/hazmat/backends/openssl/x509v3.py
rename to cryptography/hazmat/bindings/openssl/x509v3.py
diff --git a/docs/hazmat/backends/openssl.rst b/docs/hazmat/backends/openssl.rst
index 99b327d..404573a 100644
--- a/docs/hazmat/backends/openssl.rst
+++ b/docs/hazmat/backends/openssl.rst
@@ -3,23 +3,11 @@
 OpenSSL Backend
 ===============
 
-These are `CFFI`_ bindings to the `OpenSSL`_ C library.
+The `OpenSSL`_ C library.
 
 .. data:: cryptography.hazmat.backends.openssl.backend
 
-    This is the exposed API for the OpenSSL bindings. It has two public
-    attributes:
-
-    .. attribute:: ffi
-
-        This is a :class:`cffi.FFI` instance. It can be used to allocate and
-        otherwise manipulate OpenSSL structures.
-
-    .. attribute:: lib
-
-        This is a ``cffi`` library. It can be used to call OpenSSL functions,
-        and access constants.
-
+    This is the exposed API for the OpenSSL backend. It has no public attributes.    
 
 Using your own OpenSSL on Linux
 -------------------------------
@@ -48,5 +36,4 @@
 You should replace the version string on the first line as appropriate for your
 build.
 
-.. _`CFFI`: https://cffi.readthedocs.org/
 .. _`OpenSSL`: https://www.openssl.org/
diff --git a/docs/hazmat/bindings/index.rst b/docs/hazmat/bindings/index.rst
new file mode 100644
index 0000000..809eddf
--- /dev/null
+++ b/docs/hazmat/bindings/index.rst
@@ -0,0 +1,22 @@
+.. hazmat::
+
+Bindings
+========
+
+.. currentmodule:: cryptography.hazmat.bindings
+
+``cryptography`` aims to provide low-level CFFI based bindings to multiple
+native C libraries. These provide no automatic initialisation of the library
+and may not provide complete wrappers for its API.
+
+Using these functions directly is likely to require you to be careful in
+managing memory allocation, locking and other resources.
+
+
+Individual Bindings
+-------------------
+
+.. toctree::
+    :maxdepth: 1
+
+    openssl
diff --git a/docs/hazmat/bindings/openssl.rst b/docs/hazmat/bindings/openssl.rst
new file mode 100644
index 0000000..373fe47
--- /dev/null
+++ b/docs/hazmat/bindings/openssl.rst
@@ -0,0 +1,27 @@
+.. hazmat::
+
+OpenSSL Binding
+===============
+
+.. currentmodule:: cryptography.hazmat.bindings.openssl.binding
+
+These are `CFFI`_ bindings to the `OpenSSL`_ C library.
+
+.. class:: cryptography.hazmat.bindings.openssl.binding.Binding()
+
+    This is the exposed API for the OpenSSL bindings. It has two public
+    attributes:
+
+    .. attribute:: ffi
+
+        This is a :class:`cffi.FFI` instance. It can be used to allocate and
+        otherwise manipulate OpenSSL structures.
+
+    .. attribute:: lib
+
+        This is a ``cffi`` library. It can be used to call OpenSSL functions,
+        and access constants.
+
+
+.. _`CFFI`: https://cffi.readthedocs.org/
+.. _`OpenSSL`: https://www.openssl.org/
diff --git a/docs/index.rst b/docs/index.rst
index 9939182..5eb3de7 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -67,6 +67,7 @@
 
     hazmat/primitives/index
     hazmat/backends/index
+    hazmat/bindings/index
 
 The ``cryptography`` open source project
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/tests/hazmat/bindings/test_openssl.py b/tests/hazmat/bindings/test_openssl.py
new file mode 100644
index 0000000..31f736a
--- /dev/null
+++ b/tests/hazmat/bindings/test_openssl.py
@@ -0,0 +1,22 @@
+# 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 cryptography.hazmat.bindings.openssl.binding import Binding
+
+
+class TestOpenSSL(object):
+    def test_binding_loads(self):
+        binding = Binding()
+        assert binding
+        assert binding.lib
+        assert binding.ffi