prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Include OpenSSL in our Windows wheels
  Installing OpenSSL isn't super easy, even with the binaries for it. Maybe we should bundle it?
  
  
  </issue>
  <code>
  [start of cryptography/hazmat/bindings/openssl/binding.py]
  1 # Licensed under the Apache License, Version 2.0 (the "License");
  2 # you may not use this file except in compliance with the License.
  3 # You may obtain a copy of the License at
  4 #
  5 #    http://www.apache.org/licenses/LICENSE-2.0
  6 #
  7 # Unless required by applicable law or agreed to in writing, software
  8 # distributed under the License is distributed on an "AS IS" BASIS,
  9 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
  10 # implied.
  11 # See the License for the specific language governing permissions and
  12 # limitations under the License.
  13 
  14 from __future__ import absolute_import, division, print_function
  15 
  16 import sys
  17 import threading
  18 
  19 from cryptography.hazmat.bindings.utils import build_ffi
  20 
  21 
  22 _OSX_PRE_INCLUDE = """
  23 #ifdef __APPLE__
  24 #include <AvailabilityMacros.h>
  25 #define __ORIG_DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER \
  26     DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
  27 #undef DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
  28 #define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
  29 #endif
  30 """
  31 
  32 _OSX_POST_INCLUDE = """
  33 #ifdef __APPLE__
  34 #undef DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
  35 #define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER \
  36     __ORIG_DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
  37 #endif
  38 """
  39 
  40 
  41 class Binding(object):
  42     """
  43     OpenSSL API wrapper.
  44     """
  45     _module_prefix = "cryptography.hazmat.bindings.openssl."
  46     _modules = [
  47         "aes",
  48         "asn1",
  49         "bignum",
  50         "bio",
  51         "cmac",
  52         "cms",
  53         "conf",
  54         "crypto",
  55         "dh",
  56         "dsa",
  57         "ec",
  58         "ecdh",
  59         "ecdsa",
  60         "engine",
  61         "err",
  62         "evp",
  63         "hmac",
  64         "nid",
  65         "objects",
  66         "opensslv",
  67         "osrandom_engine",
  68         "pem",
  69         "pkcs7",
  70         "pkcs12",
  71         "rand",
  72         "rsa",
  73         "ssl",
  74         "x509",
  75         "x509name",
  76         "x509v3",
  77         "x509_vfy"
  78     ]
  79 
  80     _locks = None
  81     _lock_cb_handle = None
  82     _lock_init_lock = threading.Lock()
  83 
  84     ffi = None
  85     lib = None
  86 
  87     def __init__(self):
  88         self._ensure_ffi_initialized()
  89 
  90     @classmethod
  91     def _ensure_ffi_initialized(cls):
  92         if cls.ffi is not None and cls.lib is not None:
  93             return
  94 
  95         # OpenSSL goes by a different library name on different operating
  96         # systems.
  97         if sys.platform != "win32":
  98             libraries = ["crypto", "ssl"]
  99         else:  # pragma: no cover
  100             libraries = ["libeay32", "ssleay32", "advapi32"]
  101 
  102         cls.ffi, cls.lib = build_ffi(
  103             module_prefix=cls._module_prefix,
  104             modules=cls._modules,
  105             pre_include=_OSX_PRE_INCLUDE,
  106             post_include=_OSX_POST_INCLUDE,
  107             libraries=libraries,
  108         )
  109         res = cls.lib.Cryptography_add_osrandom_engine()
  110         assert res != 0
  111 
  112     @classmethod
  113     def is_available(cls):
  114         # For now, OpenSSL is considered our "default" binding, so we treat it
  115         # as always available.
  116         return True
  117 
  118     @classmethod
  119     def init_static_locks(cls):
  120         with cls._lock_init_lock:
  121             cls._ensure_ffi_initialized()
  122 
  123             if not cls._lock_cb_handle:
  124                 cls._lock_cb_handle = cls.ffi.callback(
  125                     "void(int, int, const char *, int)",
  126                     cls._lock_cb
  127                 )
  128 
  129             # Use Python's implementation if available, importing _ssl triggers
  130             # the setup for this.
  131             __import__("_ssl")
  132 
  133             if cls.lib.CRYPTO_get_locking_callback() != cls.ffi.NULL:
  134                 return
  135 
  136             # If nothing else has setup a locking callback already, we set up
  137             # our own
  138             num_locks = cls.lib.CRYPTO_num_locks()
  139             cls._locks = [threading.Lock() for n in range(num_locks)]
  140 
  141             cls.lib.CRYPTO_set_locking_callback(cls._lock_cb_handle)
  142 
  143     @classmethod
  144     def _lock_cb(cls, mode, n, file, line):
  145         lock = cls._locks[n]
  146 
  147         if mode & cls.lib.CRYPTO_LOCK:
  148             lock.acquire()
  149         elif mode & cls.lib.CRYPTO_UNLOCK:
  150             lock.release()
  151         else:
  152             raise RuntimeError(
  153                 "Unknown lock mode {0}: lock={1}, file={2}, line={3}.".format(
  154                     mode, n, file, line
  155                 )
  156             )
  157
  [end of cryptography/hazmat/bindings/openssl/binding.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/cryptography/hazmat/bindings/openssl/binding.py b/cryptography/hazmat/bindings/openssl/binding.py
  --- a/cryptography/hazmat/bindings/openssl/binding.py
  +++ b/cryptography/hazmat/bindings/openssl/binding.py
  @@ -13,6 +13,7 @@
   
   from __future__ import absolute_import, division, print_function
   
  +import os
   import sys
   import threading
   
  @@ -97,7 +98,8 @@
           if sys.platform != "win32":
               libraries = ["crypto", "ssl"]
           else:  # pragma: no cover
  -            libraries = ["libeay32", "ssleay32", "advapi32"]
  +            link_type = os.environ.get("PYCA_WINDOWS_LINK_TYPE", "static")
  +            libraries = _get_windows_libraries(link_type)
   
           cls.ffi, cls.lib = build_ffi(
               module_prefix=cls._module_prefix,
  @@ -154,3 +156,15 @@
                       mode, n, file, line
                   )
               )
  +
  +
  +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'"
  +        )
  
verification_info: {"golden_diff": "diff --git a/cryptography/hazmat/bindings/openssl/binding.py b/cryptography/hazmat/bindings/openssl/binding.py\n--- a/cryptography/hazmat/bindings/openssl/binding.py\n+++ b/cryptography/hazmat/bindings/openssl/binding.py\n@@ -13,6 +13,7 @@\n \n from __future__ import absolute_import, division, print_function\n \n+import os\n import sys\n import threading\n \n@@ -97,7 +98,8 @@\n         if sys.platform != \"win32\":\n             libraries = [\"crypto\", \"ssl\"]\n         else:  # pragma: no cover\n-            libraries = [\"libeay32\", \"ssleay32\", \"advapi32\"]\n+            link_type = os.environ.get(\"PYCA_WINDOWS_LINK_TYPE\", \"static\")\n+            libraries = _get_windows_libraries(link_type)\n \n         cls.ffi, cls.lib = build_ffi(\n             module_prefix=cls._module_prefix,\n@@ -154,3 +156,15 @@\n                     mode, n, file, line\n                 )\n             )\n+\n+\n+def _get_windows_libraries(link_type):\n+    if link_type == \"dynamic\":\n+        return [\"libeay32\", \"ssleay32\", \"advapi32\"]\n+    elif link_type == \"static\" or link_type == \"\":\n+        return [\"libeay32mt\", \"ssleay32mt\", \"advapi32\",\n+                \"crypt32\", \"gdi32\", \"user32\", \"ws2_32\"]\n+    else:\n+        raise ValueError(\n+            \"PYCA_WINDOWS_LINK_TYPE must be 'static' or 'dynamic'\"\n+        )\n", "issue": "Include OpenSSL in our Windows wheels\nInstalling OpenSSL isn't super easy, even with the binaries for it. Maybe we should bundle it?\n\n", "before_files": [{"content": "# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#    http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n# implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom __future__ import absolute_import, division, print_function\n\nimport sys\nimport threading\n\nfrom cryptography.hazmat.bindings.utils import build_ffi\n\n\n_OSX_PRE_INCLUDE = \"\"\"\n#ifdef __APPLE__\n#include <AvailabilityMacros.h>\n#define __ORIG_DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER \\\n    DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER\n#undef DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER\n#define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER\n#endif\n\"\"\"\n\n_OSX_POST_INCLUDE = \"\"\"\n#ifdef __APPLE__\n#undef DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER\n#define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER \\\n    __ORIG_DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER\n#endif\n\"\"\"\n\n\nclass Binding(object):\n    \"\"\"\n    OpenSSL API wrapper.\n    \"\"\"\n    _module_prefix = \"cryptography.hazmat.bindings.openssl.\"\n    _modules = [\n        \"aes\",\n        \"asn1\",\n        \"bignum\",\n        \"bio\",\n        \"cmac\",\n        \"cms\",\n        \"conf\",\n        \"crypto\",\n        \"dh\",\n        \"dsa\",\n        \"ec\",\n        \"ecdh\",\n        \"ecdsa\",\n        \"engine\",\n        \"err\",\n        \"evp\",\n        \"hmac\",\n        \"nid\",\n        \"objects\",\n        \"opensslv\",\n        \"osrandom_engine\",\n        \"pem\",\n        \"pkcs7\",\n        \"pkcs12\",\n        \"rand\",\n        \"rsa\",\n        \"ssl\",\n        \"x509\",\n        \"x509name\",\n        \"x509v3\",\n        \"x509_vfy\"\n    ]\n\n    _locks = None\n    _lock_cb_handle = None\n    _lock_init_lock = threading.Lock()\n\n    ffi = None\n    lib = None\n\n    def __init__(self):\n        self._ensure_ffi_initialized()\n\n    @classmethod\n    def _ensure_ffi_initialized(cls):\n        if cls.ffi is not None and cls.lib is not None:\n            return\n\n        # OpenSSL goes by a different library name on different operating\n        # systems.\n        if sys.platform != \"win32\":\n            libraries = [\"crypto\", \"ssl\"]\n        else:  # pragma: no cover\n            libraries = [\"libeay32\", \"ssleay32\", \"advapi32\"]\n\n        cls.ffi, cls.lib = build_ffi(\n            module_prefix=cls._module_prefix,\n            modules=cls._modules,\n            pre_include=_OSX_PRE_INCLUDE,\n            post_include=_OSX_POST_INCLUDE,\n            libraries=libraries,\n        )\n        res = cls.lib.Cryptography_add_osrandom_engine()\n        assert res != 0\n\n    @classmethod\n    def is_available(cls):\n        # For now, OpenSSL is considered our \"default\" binding, so we treat it\n        # as always available.\n        return True\n\n    @classmethod\n    def init_static_locks(cls):\n        with cls._lock_init_lock:\n            cls._ensure_ffi_initialized()\n\n            if not cls._lock_cb_handle:\n                cls._lock_cb_handle = cls.ffi.callback(\n                    \"void(int, int, const char *, int)\",\n                    cls._lock_cb\n                )\n\n            # Use Python's implementation if available, importing _ssl triggers\n            # the setup for this.\n            __import__(\"_ssl\")\n\n            if cls.lib.CRYPTO_get_locking_callback() != cls.ffi.NULL:\n                return\n\n            # If nothing else has setup a locking callback already, we set up\n            # our own\n            num_locks = cls.lib.CRYPTO_num_locks()\n            cls._locks = [threading.Lock() for n in range(num_locks)]\n\n            cls.lib.CRYPTO_set_locking_callback(cls._lock_cb_handle)\n\n    @classmethod\n    def _lock_cb(cls, mode, n, file, line):\n        lock = cls._locks[n]\n\n        if mode & cls.lib.CRYPTO_LOCK:\n            lock.acquire()\n        elif mode & cls.lib.CRYPTO_UNLOCK:\n            lock.release()\n        else:\n            raise RuntimeError(\n                \"Unknown lock mode {0}: lock={1}, file={2}, line={3}.\".format(\n                    mode, n, file, line\n                )\n            )\n", "path": "cryptography/hazmat/bindings/openssl/binding.py"}]}