We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Deprecate OpenSSL 1.0.2 support
It's currently about 19% of our sdist installs, primarily Ubuntu 16.04 and Amazon Linux. We should start thinking about deprecating it, as it's not supported by OpenSSL upstream any longer.

I propose that our 3.1 release begin emitting a warning, with no particular timeline attached, to get this ball rolling.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/cryptography/hazmat/bindings/openssl/binding.py`
Content:
```
1 # This file is dual licensed under the terms of the Apache License, Version
2 # 2.0, and the BSD License. See the LICENSE file in the root of this repository
3 # for complete details.
4 
5 from __future__ import absolute_import, division, print_function
6 
7 import collections
8 import threading
9 import types
10 
11 import cryptography
12 from cryptography import utils
13 from cryptography.exceptions import InternalError
14 from cryptography.hazmat.bindings._openssl import ffi, lib
15 from cryptography.hazmat.bindings.openssl._conditional import CONDITIONAL_NAMES
16 
17 _OpenSSLErrorWithText = collections.namedtuple(
18     "_OpenSSLErrorWithText", ["code", "lib", "func", "reason", "reason_text"]
19 )
20 
21 
22 class _OpenSSLError(object):
23     def __init__(self, code, lib, func, reason):
24         self._code = code
25         self._lib = lib
26         self._func = func
27         self._reason = reason
28 
29     def _lib_reason_match(self, lib, reason):
30         return lib == self.lib and reason == self.reason
31 
32     code = utils.read_only_property("_code")
33     lib = utils.read_only_property("_lib")
34     func = utils.read_only_property("_func")
35     reason = utils.read_only_property("_reason")
36 
37 
38 def _consume_errors(lib):
39     errors = []
40     while True:
41         code = lib.ERR_get_error()
42         if code == 0:
43             break
44 
45         err_lib = lib.ERR_GET_LIB(code)
46         err_func = lib.ERR_GET_FUNC(code)
47         err_reason = lib.ERR_GET_REASON(code)
48 
49         errors.append(_OpenSSLError(code, err_lib, err_func, err_reason))
50 
51     return errors
52 
53 
54 def _openssl_assert(lib, ok):
55     if not ok:
56         errors = _consume_errors(lib)
57         errors_with_text = []
58         for err in errors:
59             buf = ffi.new("char[]", 256)
60             lib.ERR_error_string_n(err.code, buf, len(buf))
61             err_text_reason = ffi.string(buf)
62 
63             errors_with_text.append(
64                 _OpenSSLErrorWithText(
65                     err.code, err.lib, err.func, err.reason, err_text_reason
66                 )
67             )
68 
69         raise InternalError(
70             "Unknown OpenSSL error. This error is commonly encountered when "
71             "another library is not cleaning up the OpenSSL error stack. If "
72             "you are using cryptography with another library that uses "
73             "OpenSSL try disabling it before reporting a bug. Otherwise "
74             "please file an issue at https://github.com/pyca/cryptography/"
75             "issues with information on how to reproduce "
76             "this. ({0!r})".format(errors_with_text),
77             errors_with_text,
78         )
79 
80 
81 def build_conditional_library(lib, conditional_names):
82     conditional_lib = types.ModuleType("lib")
83     conditional_lib._original_lib = lib
84     excluded_names = set()
85     for condition, names_cb in conditional_names.items():
86         if not getattr(lib, condition):
87             excluded_names.update(names_cb())
88 
89     for attr in dir(lib):
90         if attr not in excluded_names:
91             setattr(conditional_lib, attr, getattr(lib, attr))
92 
93     return conditional_lib
94 
95 
96 class Binding(object):
97     """
98     OpenSSL API wrapper.
99     """
100 
101     lib = None
102     ffi = ffi
103     _lib_loaded = False
104     _init_lock = threading.Lock()
105     _lock_init_lock = threading.Lock()
106 
107     def __init__(self):
108         self._ensure_ffi_initialized()
109 
110     @classmethod
111     def _register_osrandom_engine(cls):
112         # Clear any errors extant in the queue before we start. In many
113         # scenarios other things may be interacting with OpenSSL in the same
114         # process space and it has proven untenable to assume that they will
115         # reliably clear the error queue. Once we clear it here we will
116         # error on any subsequent unexpected item in the stack.
117         cls.lib.ERR_clear_error()
118         if cls.lib.CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE:
119             result = cls.lib.Cryptography_add_osrandom_engine()
120             _openssl_assert(cls.lib, result in (1, 2))
121 
122     @classmethod
123     def _ensure_ffi_initialized(cls):
124         with cls._init_lock:
125             if not cls._lib_loaded:
126                 cls.lib = build_conditional_library(lib, CONDITIONAL_NAMES)
127                 cls._lib_loaded = True
128                 # initialize the SSL library
129                 cls.lib.SSL_library_init()
130                 # adds all ciphers/digests for EVP
131                 cls.lib.OpenSSL_add_all_algorithms()
132                 # loads error strings for libcrypto and libssl functions
133                 cls.lib.SSL_load_error_strings()
134                 cls._register_osrandom_engine()
135 
136     @classmethod
137     def init_static_locks(cls):
138         with cls._lock_init_lock:
139             cls._ensure_ffi_initialized()
140             # Use Python's implementation if available, importing _ssl triggers
141             # the setup for this.
142             __import__("_ssl")
143 
144             if (
145                 not cls.lib.Cryptography_HAS_LOCKING_CALLBACKS
146                 or cls.lib.CRYPTO_get_locking_callback() != cls.ffi.NULL
147             ):
148                 return
149 
150             # If nothing else has setup a locking callback already, we set up
151             # our own
152             res = lib.Cryptography_setup_ssl_threads()
153             _openssl_assert(cls.lib, res == 1)
154 
155 
156 def _verify_package_version(version):
157     # Occasionally we run into situations where the version of the Python
158     # package does not match the version of the shared object that is loaded.
159     # This may occur in environments where multiple versions of cryptography
160     # are installed and available in the python path. To avoid errors cropping
161     # up later this code checks that the currently imported package and the
162     # shared object that were loaded have the same version and raise an
163     # ImportError if they do not
164     so_package_version = ffi.string(lib.CRYPTOGRAPHY_PACKAGE_VERSION)
165     if version.encode("ascii") != so_package_version:
166         raise ImportError(
167             "The version of cryptography does not match the loaded "
168             "shared object. This can happen if you have multiple copies of "
169             "cryptography installed in your Python path. Please try creating "
170             "a new virtual environment to resolve this issue. "
171             "Loaded python version: {}, shared object version: {}".format(
172                 version, so_package_version
173             )
174         )
175 
176 
177 _verify_package_version(cryptography.__version__)
178 
179 # OpenSSL is not thread safe until the locks are initialized. We call this
180 # method in module scope so that it executes with the import lock. On
181 # Pythons < 3.4 this import lock is a global lock, which can prevent a race
182 # condition registering the OpenSSL locks. On Python 3.4+ the import lock
183 # is per module so this approach will not work.
184 Binding.init_static_locks()
185
```

Path: `src/_cffi_src/openssl/cryptography.py`
Content:
```
1 # This file is dual licensed under the terms of the Apache License, Version
2 # 2.0, and the BSD License. See the LICENSE file in the root of this repository
3 # for complete details.
4 
5 from __future__ import absolute_import, division, print_function
6 
7 INCLUDES = """
8 /* define our OpenSSL API compatibility level to 1.0.1. Any symbols older than
9    that will raise an error during compilation. We can raise this number again
10    after we drop 1.0.2 support in the distant future.  */
11 #define OPENSSL_API_COMPAT 0x10001000L
12 
13 #include <openssl/opensslv.h>
14 
15 
16 #if defined(LIBRESSL_VERSION_NUMBER)
17 #define CRYPTOGRAPHY_IS_LIBRESSL 1
18 #else
19 #define CRYPTOGRAPHY_IS_LIBRESSL 0
20 #endif
21 
22 /*
23     LibreSSL removed e_os2.h from the public headers so we'll only include it
24     if we're using vanilla OpenSSL.
25 */
26 #if !CRYPTOGRAPHY_IS_LIBRESSL
27 #include <openssl/e_os2.h>
28 #endif
29 #if defined(_WIN32)
30 #define WIN32_LEAN_AND_MEAN
31 #include <windows.h>
32 #include <Wincrypt.h>
33 #include <Winsock2.h>
34 #endif
35 
36 #define CRYPTOGRAPHY_OPENSSL_102L_OR_GREATER \
37     (OPENSSL_VERSION_NUMBER >= 0x100020cf && !CRYPTOGRAPHY_IS_LIBRESSL)
38 #define CRYPTOGRAPHY_OPENSSL_110_OR_GREATER \
39     (OPENSSL_VERSION_NUMBER >= 0x10100000 && !CRYPTOGRAPHY_IS_LIBRESSL)
40 #define CRYPTOGRAPHY_OPENSSL_110F_OR_GREATER \
41     (OPENSSL_VERSION_NUMBER >= 0x1010006f && !CRYPTOGRAPHY_IS_LIBRESSL)
42 
43 #define CRYPTOGRAPHY_OPENSSL_LESS_THAN_102I \
44     (OPENSSL_VERSION_NUMBER < 0x1000209f || CRYPTOGRAPHY_IS_LIBRESSL)
45 #define CRYPTOGRAPHY_OPENSSL_LESS_THAN_110 \
46     (OPENSSL_VERSION_NUMBER < 0x10100000 || CRYPTOGRAPHY_IS_LIBRESSL)
47 #define CRYPTOGRAPHY_OPENSSL_LESS_THAN_110J \
48     (OPENSSL_VERSION_NUMBER < 0x101000af || CRYPTOGRAPHY_IS_LIBRESSL)
49 #define CRYPTOGRAPHY_OPENSSL_LESS_THAN_111 \
50     (OPENSSL_VERSION_NUMBER < 0x10101000 || CRYPTOGRAPHY_IS_LIBRESSL)
51 #define CRYPTOGRAPHY_OPENSSL_LESS_THAN_111B \
52     (OPENSSL_VERSION_NUMBER < 0x10101020 || CRYPTOGRAPHY_IS_LIBRESSL)
53 #define CRYPTOGRAPHY_OPENSSL_LESS_THAN_111D \
54     (OPENSSL_VERSION_NUMBER < 0x10101040 || CRYPTOGRAPHY_IS_LIBRESSL)
55 #if (CRYPTOGRAPHY_OPENSSL_LESS_THAN_111D && !defined(OPENSSL_NO_ENGINE)) || \
56     defined(USE_OSRANDOM_RNG_FOR_TESTING)
57 #define CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE 1
58 #else
59 #define CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE 0
60 #endif
61 """
62 
63 TYPES = """
64 static const int CRYPTOGRAPHY_OPENSSL_102L_OR_GREATER;
65 static const int CRYPTOGRAPHY_OPENSSL_110_OR_GREATER;
66 static const int CRYPTOGRAPHY_OPENSSL_110F_OR_GREATER;
67 
68 static const int CRYPTOGRAPHY_OPENSSL_LESS_THAN_102I;
69 static const int CRYPTOGRAPHY_OPENSSL_LESS_THAN_111;
70 static const int CRYPTOGRAPHY_OPENSSL_LESS_THAN_111B;
71 static const int CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE;
72 
73 static const int CRYPTOGRAPHY_IS_LIBRESSL;
74 """
75 
76 FUNCTIONS = """
77 """
78 
79 CUSTOMIZATIONS = """
80 """
81
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/_cffi_src/openssl/cryptography.py b/src/_cffi_src/openssl/cryptography.py
--- a/src/_cffi_src/openssl/cryptography.py
+++ b/src/_cffi_src/openssl/cryptography.py
@@ -66,6 +66,7 @@
 static const int CRYPTOGRAPHY_OPENSSL_110F_OR_GREATER;
 
 static const int CRYPTOGRAPHY_OPENSSL_LESS_THAN_102I;
+static const int CRYPTOGRAPHY_OPENSSL_LESS_THAN_110;
 static const int CRYPTOGRAPHY_OPENSSL_LESS_THAN_111;
 static const int CRYPTOGRAPHY_OPENSSL_LESS_THAN_111B;
 static const int CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE;
diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py
--- a/src/cryptography/hazmat/bindings/openssl/binding.py
+++ b/src/cryptography/hazmat/bindings/openssl/binding.py
@@ -7,6 +7,7 @@
 import collections
 import threading
 import types
+import warnings
 
 import cryptography
 from cryptography import utils
@@ -153,6 +154,19 @@
             _openssl_assert(cls.lib, res == 1)
 
 
+def _verify_openssl_version(lib):
+    if (
+        lib.CRYPTOGRAPHY_OPENSSL_LESS_THAN_110
+        and not lib.CRYPTOGRAPHY_IS_LIBRESSL
+    ):
+        warnings.warn(
+            "OpenSSL version 1.0.2 is no longer supported by the OpenSSL "
+            "project, please upgrade. A future version of cryptography will "
+            "drop support for it.",
+            utils.CryptographyDeprecationWarning,
+        )
+
+
 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.
@@ -182,3 +196,5 @@
 # condition registering the OpenSSL locks. On Python 3.4+ the import lock
 # is per module so this approach will not work.
 Binding.init_static_locks()
+
+_verify_openssl_version(Binding.lib)

{"golden_diff": "diff --git a/src/_cffi_src/openssl/cryptography.py b/src/_cffi_src/openssl/cryptography.py\n--- a/src/_cffi_src/openssl/cryptography.py\n+++ b/src/_cffi_src/openssl/cryptography.py\n@@ -66,6 +66,7 @@\n static const int CRYPTOGRAPHY_OPENSSL_110F_OR_GREATER;\n \n static const int CRYPTOGRAPHY_OPENSSL_LESS_THAN_102I;\n+static const int CRYPTOGRAPHY_OPENSSL_LESS_THAN_110;\n static const int CRYPTOGRAPHY_OPENSSL_LESS_THAN_111;\n static const int CRYPTOGRAPHY_OPENSSL_LESS_THAN_111B;\n static const int CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE;\ndiff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py\n--- a/src/cryptography/hazmat/bindings/openssl/binding.py\n+++ b/src/cryptography/hazmat/bindings/openssl/binding.py\n@@ -7,6 +7,7 @@\n import collections\n import threading\n import types\n+import warnings\n \n import cryptography\n from cryptography import utils\n@@ -153,6 +154,19 @@\n             _openssl_assert(cls.lib, res == 1)\n \n \n+def _verify_openssl_version(lib):\n+    if (\n+        lib.CRYPTOGRAPHY_OPENSSL_LESS_THAN_110\n+        and not lib.CRYPTOGRAPHY_IS_LIBRESSL\n+    ):\n+        warnings.warn(\n+            \"OpenSSL version 1.0.2 is no longer supported by the OpenSSL \"\n+            \"project, please upgrade. A future version of cryptography will \"\n+            \"drop support for it.\",\n+            utils.CryptographyDeprecationWarning,\n+        )\n+\n+\n def _verify_package_version(version):\n     # Occasionally we run into situations where the version of the Python\n     # package does not match the version of the shared object that is loaded.\n@@ -182,3 +196,5 @@\n # condition registering the OpenSSL locks. On Python 3.4+ the import lock\n # is per module so this approach will not work.\n Binding.init_static_locks()\n+\n+_verify_openssl_version(Binding.lib)\n", "issue": "Deprecate OpenSSL 1.0.2 support\nIt's currently about 19% of our sdist installs, primarily Ubuntu 16.04 and Amazon Linux. We should start thinking about deprecating it, as it's not supported by OpenSSL upstream any longer.\r\n\r\nI propose that our 3.1 release begin emitting a warning, with no particular timeline attached, to get this ball rolling.\n", "before_files": [{"content": "# This file is dual licensed under the terms of the Apache License, Version\n# 2.0, and the BSD License. See the LICENSE file in the root of this repository\n# for complete details.\n\nfrom __future__ import absolute_import, division, print_function\n\nimport collections\nimport threading\nimport types\n\nimport cryptography\nfrom cryptography import utils\nfrom cryptography.exceptions import InternalError\nfrom cryptography.hazmat.bindings._openssl import ffi, lib\nfrom cryptography.hazmat.bindings.openssl._conditional import CONDITIONAL_NAMES\n\n_OpenSSLErrorWithText = collections.namedtuple(\n    \"_OpenSSLErrorWithText\", [\"code\", \"lib\", \"func\", \"reason\", \"reason_text\"]\n)\n\n\nclass _OpenSSLError(object):\n    def __init__(self, code, lib, func, reason):\n        self._code = code\n        self._lib = lib\n        self._func = func\n        self._reason = reason\n\n    def _lib_reason_match(self, lib, reason):\n        return lib == self.lib and reason == self.reason\n\n    code = utils.read_only_property(\"_code\")\n    lib = utils.read_only_property(\"_lib\")\n    func = utils.read_only_property(\"_func\")\n    reason = utils.read_only_property(\"_reason\")\n\n\ndef _consume_errors(lib):\n    errors = []\n    while True:\n        code = lib.ERR_get_error()\n        if code == 0:\n            break\n\n        err_lib = lib.ERR_GET_LIB(code)\n        err_func = lib.ERR_GET_FUNC(code)\n        err_reason = lib.ERR_GET_REASON(code)\n\n        errors.append(_OpenSSLError(code, err_lib, err_func, err_reason))\n\n    return errors\n\n\ndef _openssl_assert(lib, ok):\n    if not ok:\n        errors = _consume_errors(lib)\n        errors_with_text = []\n        for err in errors:\n            buf = ffi.new(\"char[]\", 256)\n            lib.ERR_error_string_n(err.code, buf, len(buf))\n            err_text_reason = ffi.string(buf)\n\n            errors_with_text.append(\n                _OpenSSLErrorWithText(\n                    err.code, err.lib, err.func, err.reason, err_text_reason\n                )\n            )\n\n        raise InternalError(\n            \"Unknown OpenSSL error. This error is commonly encountered when \"\n            \"another library is not cleaning up the OpenSSL error stack. If \"\n            \"you are using cryptography with another library that uses \"\n            \"OpenSSL try disabling it before reporting a bug. Otherwise \"\n            \"please file an issue at https://github.com/pyca/cryptography/\"\n            \"issues with information on how to reproduce \"\n            \"this. ({0!r})\".format(errors_with_text),\n            errors_with_text,\n        )\n\n\ndef build_conditional_library(lib, conditional_names):\n    conditional_lib = types.ModuleType(\"lib\")\n    conditional_lib._original_lib = lib\n    excluded_names = set()\n    for condition, names_cb in conditional_names.items():\n        if not getattr(lib, condition):\n            excluded_names.update(names_cb())\n\n    for attr in dir(lib):\n        if attr not in excluded_names:\n            setattr(conditional_lib, attr, getattr(lib, attr))\n\n    return conditional_lib\n\n\nclass Binding(object):\n    \"\"\"\n    OpenSSL API wrapper.\n    \"\"\"\n\n    lib = None\n    ffi = ffi\n    _lib_loaded = False\n    _init_lock = threading.Lock()\n    _lock_init_lock = threading.Lock()\n\n    def __init__(self):\n        self._ensure_ffi_initialized()\n\n    @classmethod\n    def _register_osrandom_engine(cls):\n        # Clear any errors extant in the queue before we start. In many\n        # scenarios other things may be interacting with OpenSSL in the same\n        # process space and it has proven untenable to assume that they will\n        # reliably clear the error queue. Once we clear it here we will\n        # error on any subsequent unexpected item in the stack.\n        cls.lib.ERR_clear_error()\n        if cls.lib.CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE:\n            result = cls.lib.Cryptography_add_osrandom_engine()\n            _openssl_assert(cls.lib, result in (1, 2))\n\n    @classmethod\n    def _ensure_ffi_initialized(cls):\n        with cls._init_lock:\n            if not cls._lib_loaded:\n                cls.lib = build_conditional_library(lib, CONDITIONAL_NAMES)\n                cls._lib_loaded = True\n                # initialize the SSL library\n                cls.lib.SSL_library_init()\n                # adds all ciphers/digests for EVP\n                cls.lib.OpenSSL_add_all_algorithms()\n                # loads error strings for libcrypto and libssl functions\n                cls.lib.SSL_load_error_strings()\n                cls._register_osrandom_engine()\n\n    @classmethod\n    def init_static_locks(cls):\n        with cls._lock_init_lock:\n            cls._ensure_ffi_initialized()\n            # Use Python's implementation if available, importing _ssl triggers\n            # the setup for this.\n            __import__(\"_ssl\")\n\n            if (\n                not cls.lib.Cryptography_HAS_LOCKING_CALLBACKS\n                or cls.lib.CRYPTO_get_locking_callback() != cls.ffi.NULL\n            ):\n                return\n\n            # If nothing else has setup a locking callback already, we set up\n            # our own\n            res = lib.Cryptography_setup_ssl_threads()\n            _openssl_assert(cls.lib, res == 1)\n\n\ndef _verify_package_version(version):\n    # Occasionally we run into situations where the version of the Python\n    # package does not match the version of the shared object that is loaded.\n    # This may occur in environments where multiple versions of cryptography\n    # are installed and available in the python path. To avoid errors cropping\n    # up later this code checks that the currently imported package and the\n    # shared object that were loaded have the same version and raise an\n    # ImportError if they do not\n    so_package_version = ffi.string(lib.CRYPTOGRAPHY_PACKAGE_VERSION)\n    if version.encode(\"ascii\") != so_package_version:\n        raise ImportError(\n            \"The version of cryptography does not match the loaded \"\n            \"shared object. This can happen if you have multiple copies of \"\n            \"cryptography installed in your Python path. Please try creating \"\n            \"a new virtual environment to resolve this issue. \"\n            \"Loaded python version: {}, shared object version: {}\".format(\n                version, so_package_version\n            )\n        )\n\n\n_verify_package_version(cryptography.__version__)\n\n# OpenSSL is not thread safe until the locks are initialized. We call this\n# method in module scope so that it executes with the import lock. On\n# Pythons < 3.4 this import lock is a global lock, which can prevent a race\n# condition registering the OpenSSL locks. On Python 3.4+ the import lock\n# is per module so this approach will not work.\nBinding.init_static_locks()\n", "path": "src/cryptography/hazmat/bindings/openssl/binding.py"}, {"content": "# This file is dual licensed under the terms of the Apache License, Version\n# 2.0, and the BSD License. See the LICENSE file in the root of this repository\n# for complete details.\n\nfrom __future__ import absolute_import, division, print_function\n\nINCLUDES = \"\"\"\n/* define our OpenSSL API compatibility level to 1.0.1. Any symbols older than\n   that will raise an error during compilation. We can raise this number again\n   after we drop 1.0.2 support in the distant future.  */\n#define OPENSSL_API_COMPAT 0x10001000L\n\n#include <openssl/opensslv.h>\n\n\n#if defined(LIBRESSL_VERSION_NUMBER)\n#define CRYPTOGRAPHY_IS_LIBRESSL 1\n#else\n#define CRYPTOGRAPHY_IS_LIBRESSL 0\n#endif\n\n/*\n    LibreSSL removed e_os2.h from the public headers so we'll only include it\n    if we're using vanilla OpenSSL.\n*/\n#if !CRYPTOGRAPHY_IS_LIBRESSL\n#include <openssl/e_os2.h>\n#endif\n#if defined(_WIN32)\n#define WIN32_LEAN_AND_MEAN\n#include <windows.h>\n#include <Wincrypt.h>\n#include <Winsock2.h>\n#endif\n\n#define CRYPTOGRAPHY_OPENSSL_102L_OR_GREATER \\\n    (OPENSSL_VERSION_NUMBER >= 0x100020cf && !CRYPTOGRAPHY_IS_LIBRESSL)\n#define CRYPTOGRAPHY_OPENSSL_110_OR_GREATER \\\n    (OPENSSL_VERSION_NUMBER >= 0x10100000 && !CRYPTOGRAPHY_IS_LIBRESSL)\n#define CRYPTOGRAPHY_OPENSSL_110F_OR_GREATER \\\n    (OPENSSL_VERSION_NUMBER >= 0x1010006f && !CRYPTOGRAPHY_IS_LIBRESSL)\n\n#define CRYPTOGRAPHY_OPENSSL_LESS_THAN_102I \\\n    (OPENSSL_VERSION_NUMBER < 0x1000209f || CRYPTOGRAPHY_IS_LIBRESSL)\n#define CRYPTOGRAPHY_OPENSSL_LESS_THAN_110 \\\n    (OPENSSL_VERSION_NUMBER < 0x10100000 || CRYPTOGRAPHY_IS_LIBRESSL)\n#define CRYPTOGRAPHY_OPENSSL_LESS_THAN_110J \\\n    (OPENSSL_VERSION_NUMBER < 0x101000af || CRYPTOGRAPHY_IS_LIBRESSL)\n#define CRYPTOGRAPHY_OPENSSL_LESS_THAN_111 \\\n    (OPENSSL_VERSION_NUMBER < 0x10101000 || CRYPTOGRAPHY_IS_LIBRESSL)\n#define CRYPTOGRAPHY_OPENSSL_LESS_THAN_111B \\\n    (OPENSSL_VERSION_NUMBER < 0x10101020 || CRYPTOGRAPHY_IS_LIBRESSL)\n#define CRYPTOGRAPHY_OPENSSL_LESS_THAN_111D \\\n    (OPENSSL_VERSION_NUMBER < 0x10101040 || CRYPTOGRAPHY_IS_LIBRESSL)\n#if (CRYPTOGRAPHY_OPENSSL_LESS_THAN_111D && !defined(OPENSSL_NO_ENGINE)) || \\\n    defined(USE_OSRANDOM_RNG_FOR_TESTING)\n#define CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE 1\n#else\n#define CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE 0\n#endif\n\"\"\"\n\nTYPES = \"\"\"\nstatic const int CRYPTOGRAPHY_OPENSSL_102L_OR_GREATER;\nstatic const int CRYPTOGRAPHY_OPENSSL_110_OR_GREATER;\nstatic const int CRYPTOGRAPHY_OPENSSL_110F_OR_GREATER;\n\nstatic const int CRYPTOGRAPHY_OPENSSL_LESS_THAN_102I;\nstatic const int CRYPTOGRAPHY_OPENSSL_LESS_THAN_111;\nstatic const int CRYPTOGRAPHY_OPENSSL_LESS_THAN_111B;\nstatic const int CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE;\n\nstatic const int CRYPTOGRAPHY_IS_LIBRESSL;\n\"\"\"\n\nFUNCTIONS = \"\"\"\n\"\"\"\n\nCUSTOMIZATIONS = \"\"\"\n\"\"\"\n", "path": "src/_cffi_src/openssl/cryptography.py"}], "after_files": [{"content": "# This file is dual licensed under the terms of the Apache License, Version\n# 2.0, and the BSD License. See the LICENSE file in the root of this repository\n# for complete details.\n\nfrom __future__ import absolute_import, division, print_function\n\nimport collections\nimport threading\nimport types\nimport warnings\n\nimport cryptography\nfrom cryptography import utils\nfrom cryptography.exceptions import InternalError\nfrom cryptography.hazmat.bindings._openssl import ffi, lib\nfrom cryptography.hazmat.bindings.openssl._conditional import CONDITIONAL_NAMES\n\n_OpenSSLErrorWithText = collections.namedtuple(\n    \"_OpenSSLErrorWithText\", [\"code\", \"lib\", \"func\", \"reason\", \"reason_text\"]\n)\n\n\nclass _OpenSSLError(object):\n    def __init__(self, code, lib, func, reason):\n        self._code = code\n        self._lib = lib\n        self._func = func\n        self._reason = reason\n\n    def _lib_reason_match(self, lib, reason):\n        return lib == self.lib and reason == self.reason\n\n    code = utils.read_only_property(\"_code\")\n    lib = utils.read_only_property(\"_lib\")\n    func = utils.read_only_property(\"_func\")\n    reason = utils.read_only_property(\"_reason\")\n\n\ndef _consume_errors(lib):\n    errors = []\n    while True:\n        code = lib.ERR_get_error()\n        if code == 0:\n            break\n\n        err_lib = lib.ERR_GET_LIB(code)\n        err_func = lib.ERR_GET_FUNC(code)\n        err_reason = lib.ERR_GET_REASON(code)\n\n        errors.append(_OpenSSLError(code, err_lib, err_func, err_reason))\n\n    return errors\n\n\ndef _openssl_assert(lib, ok):\n    if not ok:\n        errors = _consume_errors(lib)\n        errors_with_text = []\n        for err in errors:\n            buf = ffi.new(\"char[]\", 256)\n            lib.ERR_error_string_n(err.code, buf, len(buf))\n            err_text_reason = ffi.string(buf)\n\n            errors_with_text.append(\n                _OpenSSLErrorWithText(\n                    err.code, err.lib, err.func, err.reason, err_text_reason\n                )\n            )\n\n        raise InternalError(\n            \"Unknown OpenSSL error. This error is commonly encountered when \"\n            \"another library is not cleaning up the OpenSSL error stack. If \"\n            \"you are using cryptography with another library that uses \"\n            \"OpenSSL try disabling it before reporting a bug. Otherwise \"\n            \"please file an issue at https://github.com/pyca/cryptography/\"\n            \"issues with information on how to reproduce \"\n            \"this. ({0!r})\".format(errors_with_text),\n            errors_with_text,\n        )\n\n\ndef build_conditional_library(lib, conditional_names):\n    conditional_lib = types.ModuleType(\"lib\")\n    conditional_lib._original_lib = lib\n    excluded_names = set()\n    for condition, names_cb in conditional_names.items():\n        if not getattr(lib, condition):\n            excluded_names.update(names_cb())\n\n    for attr in dir(lib):\n        if attr not in excluded_names:\n            setattr(conditional_lib, attr, getattr(lib, attr))\n\n    return conditional_lib\n\n\nclass Binding(object):\n    \"\"\"\n    OpenSSL API wrapper.\n    \"\"\"\n\n    lib = None\n    ffi = ffi\n    _lib_loaded = False\n    _init_lock = threading.Lock()\n    _lock_init_lock = threading.Lock()\n\n    def __init__(self):\n        self._ensure_ffi_initialized()\n\n    @classmethod\n    def _register_osrandom_engine(cls):\n        # Clear any errors extant in the queue before we start. In many\n        # scenarios other things may be interacting with OpenSSL in the same\n        # process space and it has proven untenable to assume that they will\n        # reliably clear the error queue. Once we clear it here we will\n        # error on any subsequent unexpected item in the stack.\n        cls.lib.ERR_clear_error()\n        if cls.lib.CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE:\n            result = cls.lib.Cryptography_add_osrandom_engine()\n            _openssl_assert(cls.lib, result in (1, 2))\n\n    @classmethod\n    def _ensure_ffi_initialized(cls):\n        with cls._init_lock:\n            if not cls._lib_loaded:\n                cls.lib = build_conditional_library(lib, CONDITIONAL_NAMES)\n                cls._lib_loaded = True\n                # initialize the SSL library\n                cls.lib.SSL_library_init()\n                # adds all ciphers/digests for EVP\n                cls.lib.OpenSSL_add_all_algorithms()\n                # loads error strings for libcrypto and libssl functions\n                cls.lib.SSL_load_error_strings()\n                cls._register_osrandom_engine()\n\n    @classmethod\n    def init_static_locks(cls):\n        with cls._lock_init_lock:\n            cls._ensure_ffi_initialized()\n            # Use Python's implementation if available, importing _ssl triggers\n            # the setup for this.\n            __import__(\"_ssl\")\n\n            if (\n                not cls.lib.Cryptography_HAS_LOCKING_CALLBACKS\n                or cls.lib.CRYPTO_get_locking_callback() != cls.ffi.NULL\n            ):\n                return\n\n            # If nothing else has setup a locking callback already, we set up\n            # our own\n            res = lib.Cryptography_setup_ssl_threads()\n            _openssl_assert(cls.lib, res == 1)\n\n\ndef _verify_openssl_version(lib):\n    if (\n        lib.CRYPTOGRAPHY_OPENSSL_LESS_THAN_110\n        and not lib.CRYPTOGRAPHY_IS_LIBRESSL\n    ):\n        warnings.warn(\n            \"OpenSSL version 1.0.2 is no longer supported by the OpenSSL \"\n            \"project, please upgrade. A future version of cryptography will \"\n            \"drop support for it.\",\n            utils.CryptographyDeprecationWarning,\n        )\n\n\ndef _verify_package_version(version):\n    # Occasionally we run into situations where the version of the Python\n    # package does not match the version of the shared object that is loaded.\n    # This may occur in environments where multiple versions of cryptography\n    # are installed and available in the python path. To avoid errors cropping\n    # up later this code checks that the currently imported package and the\n    # shared object that were loaded have the same version and raise an\n    # ImportError if they do not\n    so_package_version = ffi.string(lib.CRYPTOGRAPHY_PACKAGE_VERSION)\n    if version.encode(\"ascii\") != so_package_version:\n        raise ImportError(\n            \"The version of cryptography does not match the loaded \"\n            \"shared object. This can happen if you have multiple copies of \"\n            \"cryptography installed in your Python path. Please try creating \"\n            \"a new virtual environment to resolve this issue. \"\n            \"Loaded python version: {}, shared object version: {}\".format(\n                version, so_package_version\n            )\n        )\n\n\n_verify_package_version(cryptography.__version__)\n\n# OpenSSL is not thread safe until the locks are initialized. We call this\n# method in module scope so that it executes with the import lock. On\n# Pythons < 3.4 this import lock is a global lock, which can prevent a race\n# condition registering the OpenSSL locks. On Python 3.4+ the import lock\n# is per module so this approach will not work.\nBinding.init_static_locks()\n\n_verify_openssl_version(Binding.lib)\n", "path": "src/cryptography/hazmat/bindings/openssl/binding.py"}, {"content": "# This file is dual licensed under the terms of the Apache License, Version\n# 2.0, and the BSD License. See the LICENSE file in the root of this repository\n# for complete details.\n\nfrom __future__ import absolute_import, division, print_function\n\nINCLUDES = \"\"\"\n/* define our OpenSSL API compatibility level to 1.0.1. Any symbols older than\n   that will raise an error during compilation. We can raise this number again\n   after we drop 1.0.2 support in the distant future.  */\n#define OPENSSL_API_COMPAT 0x10001000L\n\n#include <openssl/opensslv.h>\n\n\n#if defined(LIBRESSL_VERSION_NUMBER)\n#define CRYPTOGRAPHY_IS_LIBRESSL 1\n#else\n#define CRYPTOGRAPHY_IS_LIBRESSL 0\n#endif\n\n/*\n    LibreSSL removed e_os2.h from the public headers so we'll only include it\n    if we're using vanilla OpenSSL.\n*/\n#if !CRYPTOGRAPHY_IS_LIBRESSL\n#include <openssl/e_os2.h>\n#endif\n#if defined(_WIN32)\n#define WIN32_LEAN_AND_MEAN\n#include <windows.h>\n#include <Wincrypt.h>\n#include <Winsock2.h>\n#endif\n\n#define CRYPTOGRAPHY_OPENSSL_102L_OR_GREATER \\\n    (OPENSSL_VERSION_NUMBER >= 0x100020cf && !CRYPTOGRAPHY_IS_LIBRESSL)\n#define CRYPTOGRAPHY_OPENSSL_110_OR_GREATER \\\n    (OPENSSL_VERSION_NUMBER >= 0x10100000 && !CRYPTOGRAPHY_IS_LIBRESSL)\n#define CRYPTOGRAPHY_OPENSSL_110F_OR_GREATER \\\n    (OPENSSL_VERSION_NUMBER >= 0x1010006f && !CRYPTOGRAPHY_IS_LIBRESSL)\n\n#define CRYPTOGRAPHY_OPENSSL_LESS_THAN_102I \\\n    (OPENSSL_VERSION_NUMBER < 0x1000209f || CRYPTOGRAPHY_IS_LIBRESSL)\n#define CRYPTOGRAPHY_OPENSSL_LESS_THAN_110 \\\n    (OPENSSL_VERSION_NUMBER < 0x10100000 || CRYPTOGRAPHY_IS_LIBRESSL)\n#define CRYPTOGRAPHY_OPENSSL_LESS_THAN_110J \\\n    (OPENSSL_VERSION_NUMBER < 0x101000af || CRYPTOGRAPHY_IS_LIBRESSL)\n#define CRYPTOGRAPHY_OPENSSL_LESS_THAN_111 \\\n    (OPENSSL_VERSION_NUMBER < 0x10101000 || CRYPTOGRAPHY_IS_LIBRESSL)\n#define CRYPTOGRAPHY_OPENSSL_LESS_THAN_111B \\\n    (OPENSSL_VERSION_NUMBER < 0x10101020 || CRYPTOGRAPHY_IS_LIBRESSL)\n#define CRYPTOGRAPHY_OPENSSL_LESS_THAN_111D \\\n    (OPENSSL_VERSION_NUMBER < 0x10101040 || CRYPTOGRAPHY_IS_LIBRESSL)\n#if (CRYPTOGRAPHY_OPENSSL_LESS_THAN_111D && !defined(OPENSSL_NO_ENGINE)) || \\\n    defined(USE_OSRANDOM_RNG_FOR_TESTING)\n#define CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE 1\n#else\n#define CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE 0\n#endif\n\"\"\"\n\nTYPES = \"\"\"\nstatic const int CRYPTOGRAPHY_OPENSSL_102L_OR_GREATER;\nstatic const int CRYPTOGRAPHY_OPENSSL_110_OR_GREATER;\nstatic const int CRYPTOGRAPHY_OPENSSL_110F_OR_GREATER;\n\nstatic const int CRYPTOGRAPHY_OPENSSL_LESS_THAN_102I;\nstatic const int CRYPTOGRAPHY_OPENSSL_LESS_THAN_110;\nstatic const int CRYPTOGRAPHY_OPENSSL_LESS_THAN_111;\nstatic const int CRYPTOGRAPHY_OPENSSL_LESS_THAN_111B;\nstatic const int CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE;\n\nstatic const int CRYPTOGRAPHY_IS_LIBRESSL;\n\"\"\"\n\nFUNCTIONS = \"\"\"\n\"\"\"\n\nCUSTOMIZATIONS = \"\"\"\n\"\"\"\n", "path": "src/_cffi_src/openssl/cryptography.py"}]}