<pre style='margin:0'>
Joshua Root (jmroot) pushed a commit to branch master
in repository macports-ports.

</pre>
<p><a href="https://github.com/macports/macports-ports/commit/b455c2926d1a450e8175a618742fada2bea58c35">https://github.com/macports/macports-ports/commit/b455c2926d1a450e8175a618742fada2bea58c35</a></p>
<pre style="white-space: pre; background: #F8F8F8">The following commit(s) were added to refs/heads/master by this push:
<span style='display:block; white-space:pre;color:#404040;'>     new b455c29  python34: support OpenSSL 1.1
</span>b455c29 is described below

<span style='display:block; white-space:pre;color:#808000;'>commit b455c2926d1a450e8175a618742fada2bea58c35
</span>Author: Chih-Hsuan Yen <yan12125@macports.org>
AuthorDate: Tue Apr 2 00:32:27 2019 +0800

<span style='display:block; white-space:pre;color:#404040;'>    python34: support OpenSSL 1.1
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    The patch is from https://github.com/python/cpython/pull/12211. It's not
</span><span style='display:block; white-space:pre;color:#404040;'>    merged into official CPython 3.4 for timing reasons.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    TLS functionality tested with the following script:
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>        try:
</span><span style='display:block; white-space:pre;color:#404040;'>            import urllib.request as urllib_request
</span><span style='display:block; white-space:pre;color:#404040;'>        except ImportError:
</span><span style='display:block; white-space:pre;color:#404040;'>            import urllib2 as urllib_request
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>        h = urllib_request.urlopen('https://httpbin.org/ip')
</span><span style='display:block; white-space:pre;color:#404040;'>        print(h.read().decode('utf-8'))
</span>---
 lang/python34/Portfile                   |   2 +
 lang/python34/files/patch-openssl11.diff | 764 +++++++++++++++++++++++++++++++
 2 files changed, 766 insertions(+)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/lang/python34/Portfile b/lang/python34/Portfile
</span><span style='display:block; white-space:pre;color:#808080;'>index 4b25f1b..c3da800 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/lang/python34/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/lang/python34/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -8,6 +8,7 @@ name                python34
</span> epoch               20170810
 # Remember to keep py34-tkinter and py34-gdbm's versions sync'd with this
 version             3.4.10
<span style='display:block; white-space:pre;background:#e0ffe0;'>+revision            1
</span> 
 set major           [lindex [split $version .] 0]
 set branch          [join [lrange [split ${version} .] 0 1] .]
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -34,6 +35,7 @@ patchfiles          patch-setup.py.diff \
</span>                     patch-configure.diff \
                     patch-Lib-ctypes-macholib-dyld.py.diff \
                     patch-libedit.diff \
<span style='display:block; white-space:pre;background:#e0ffe0;'>+                    patch-openssl11.diff \
</span>                     omit-local-site-packages.patch \
                     patch-Include-pyport.h.diff \
                     uuid-64bit.patch
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/lang/python34/files/patch-openssl11.diff b/lang/python34/files/patch-openssl11.diff
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..981f823
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/lang/python34/files/patch-openssl11.diff
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,764 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+From 55ffb704cc17d41ddf8f34aac3de5f218cd43dee Mon Sep 17 00:00:00 2001
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+From: Christian Heimes <christian@python.org>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Date: Mon, 5 Sep 2016 23:19:05 +0200
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Subject: [PATCH] bpo-26470: Port ssl and hashlib module to OpenSSL 1.1.0.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Backport notes
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+* Don't add PROTOCOL_TLS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+* Ignore documentation changes
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+(cherry picked from commit 598894ff48e9c1171cb2ec1c798235826a75c7e0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+---
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ Lib/test/test_ssl.py                          |  24 +--
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ .../2019-03-07-15-39-52.bpo-26470.QGu_wo.rst  |   1 +
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ Modules/_hashopenssl.c                        | 167 +++++++++++-------
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ Modules/_ssl.c                                | 162 +++++++++++++----
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 4 files changed, 246 insertions(+), 108 deletions(-)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ create mode 100644 Misc/NEWS.d/next/Library/2019-03-07-15-39-52.bpo-26470.QGu_wo.rst
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git Lib/test/test_ssl.py Lib/test/test_ssl.py
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index e36a309bfae4..e6d9a3912a5f 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- Lib/test/test_ssl.py
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ Lib/test/test_ssl.py
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -23,6 +23,9 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ PROTOCOLS = sorted(ssl._PROTOCOL_NAMES)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ HOST = support.HOST
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++IS_LIBRESSL = ssl.OPENSSL_VERSION.startswith('LibreSSL')
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++IS_OPENSSL_1_1 = not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (1, 1, 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ def data_file(*name):
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return os.path.join(os.path.dirname(__file__), *name)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -318,9 +321,9 @@ def test_openssl_version(self):
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         self.assertGreaterEqual(status, 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         self.assertLessEqual(status, 15)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         # Version string as returned by {Open,Libre}SSL, the format might change
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if "LibreSSL" in s:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            self.assertTrue(s.startswith("LibreSSL {:d}.{:d}".format(major, minor)),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                            (s, t))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if IS_LIBRESSL:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            self.assertTrue(s.startswith("LibreSSL {:d}".format(major)),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                            (s, t, hex(n)))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         else:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                             (s, t))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -698,15 +701,15 @@ def test_ciphers(self):
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     def test_options(self):
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         # OP_ALL | OP_NO_SSLv2 | OP_NO_SSLv3 is the default value
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                         ctx.options)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        default = (ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (1, 1, 0):
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            default |= ssl.OP_NO_COMPRESSION
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        self.assertEqual(default, ctx.options)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         ctx.options |= ssl.OP_NO_TLSv1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 | ssl.OP_NO_TLSv1,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                         ctx.options)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        self.assertEqual(default | ssl.OP_NO_TLSv1, ctx.options)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         if can_clear_options():
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            ctx.options = (ctx.options & ~ssl.OP_NO_SSLv2) | ssl.OP_NO_TLSv1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            self.assertEqual(ssl.OP_ALL | ssl.OP_NO_TLSv1 | ssl.OP_NO_SSLv3,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                             ctx.options)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            ctx.options = (ctx.options & ~ssl.OP_NO_TLSv1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            self.assertEqual(default, ctx.options)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             ctx.options = 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             # Ubuntu has OP_NO_SSLv3 forced on by default
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             self.assertEqual(0, ctx.options & ~ssl.OP_NO_SSLv3)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1042,6 +1045,7 @@ def test_load_default_certs(self):
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         self.assertRaises(TypeError, ctx.load_default_certs, 'SERVER_AUTH')
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     @unittest.skipIf(sys.platform == "win32", "not-Windows specific")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    @unittest.skipIf(IS_LIBRESSL, "LibreSSL doesn't support env vars")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     def test_load_default_certs_env(self):
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         with support.EnvironmentVarGuard() as env:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git Misc/NEWS.d/next/Library/2019-03-07-15-39-52.bpo-26470.QGu_wo.rst Misc/NEWS.d/next/Library/2019-03-07-15-39-52.bpo-26470.QGu_wo.rst
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+new file mode 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 000000000000..6369b4d7522e
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ Misc/NEWS.d/next/Library/2019-03-07-15-39-52.bpo-26470.QGu_wo.rst
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Port ssl and hashlib module to OpenSSL 1.1.0.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git Modules/_hashopenssl.c Modules/_hashopenssl.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 5b0a7be12b07..86a8950588ef 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- Modules/_hashopenssl.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ Modules/_hashopenssl.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -20,7 +20,6 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* EVP is the preferred interface to hashing in OpenSSL */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <openssl/evp.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#include <openssl/hmac.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* We use the object interface to discover what hashes OpenSSL supports. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <openssl/objects.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "openssl/err.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -31,15 +30,22 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #define HASH_OBJ_CONSTRUCTOR 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-/* Minimum OpenSSL version needed to support sha224 and higher. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#if defined(OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x00908000)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#define _OPENSSL_SUPPORTS_SHA2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* OpenSSL < 1.1.0 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define EVP_MD_CTX_new EVP_MD_CTX_create
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define EVP_MD_CTX_free EVP_MD_CTX_destroy
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define HAS_FAST_PKCS5_PBKDF2_HMAC 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <openssl/hmac.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* OpenSSL >= 1.1.0 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define HAS_FAST_PKCS5_PBKDF2_HMAC 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ typedef struct {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     PyObject_HEAD
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     PyObject            *name;  /* name of this hash algorithm */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    EVP_MD_CTX           ctx;   /* OpenSSL message digest context */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    EVP_MD_CTX          *ctx;   /* OpenSSL message digest context */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef WITH_THREAD
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     PyThread_type_lock   lock;  /* OpenSSL context lock */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -51,7 +57,6 @@ static PyTypeObject EVPtype;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #define DEFINE_CONSTS_FOR_NEW(Name)  \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     static PyObject *CONST_ ## Name ## _name_obj = NULL; \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    static EVP_MD_CTX CONST_new_ ## Name ## _ctx; \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     static EVP_MD_CTX *CONST_new_ ## Name ## _ctx_p = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ DEFINE_CONSTS_FOR_NEW(md5)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -64,19 +69,57 @@ DEFINE_CONSTS_FOR_NEW(sha512)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* LCOV_EXCL_START */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static PyObject *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++_setException(PyObject *exc)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    unsigned long errcode;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    const char *lib, *func, *reason;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    errcode = ERR_peek_last_error();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (!errcode) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        PyErr_SetString(exc, "unknown reasons");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        return NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    ERR_clear_error();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    lib = ERR_lib_error_string(errcode);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    func = ERR_func_error_string(errcode);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    reason = ERR_reason_error_string(errcode);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (lib && func) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        PyErr_Format(exc, "[%s: %s] %s", lib, func, reason);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    else if (lib) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        PyErr_Format(exc, "[%s] %s", lib, reason);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        PyErr_SetString(exc, reason);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* LCOV_EXCL_STOP */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static EVPobject *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ newEVPobject(PyObject *name)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     EVPobject *retval = (EVPobject *)PyObject_New(EVPobject, &EVPtype);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (retval == NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        return NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    retval->ctx = EVP_MD_CTX_new();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (retval->ctx == NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        PyErr_NoMemory();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        return NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     /* save the name for .name to return */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    if (retval != NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        Py_INCREF(name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        retval->name = name;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    Py_INCREF(name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    retval->name = name;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef WITH_THREAD
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        retval->lock = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    retval->lock = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return retval;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -91,7 +134,7 @@ EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             process = MUNCH_SIZE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             process = Py_SAFE_DOWNCAST(len, Py_ssize_t, unsigned int);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        EVP_DigestUpdate(&self->ctx, (const void*)cp, process);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        EVP_DigestUpdate(self->ctx, (const void*)cp, process);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         len -= process;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         cp += process;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -106,16 +149,19 @@ EVP_dealloc(EVPobject *self)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (self->lock != NULL)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         PyThread_free_lock(self->lock);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    EVP_MD_CTX_cleanup(&self->ctx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    EVP_MD_CTX_free(self->ctx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     Py_XDECREF(self->name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     PyObject_Del(self);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-static void locked_EVP_MD_CTX_copy(EVP_MD_CTX *new_ctx_p, EVPobject *self)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++locked_EVP_MD_CTX_copy(EVP_MD_CTX *new_ctx_p, EVPobject *self)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    int result;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     ENTER_HASHLIB(self);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    EVP_MD_CTX_copy(new_ctx_p, &self->ctx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    result = EVP_MD_CTX_copy(new_ctx_p, self->ctx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     LEAVE_HASHLIB(self);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return result;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* External methods for a hash object */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -131,7 +177,9 @@ EVP_copy(EVPobject *self, PyObject *unused)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if ( (newobj = newEVPobject(self->name))==NULL)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         return NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    locked_EVP_MD_CTX_copy(&newobj->ctx, self);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (!locked_EVP_MD_CTX_copy(newobj->ctx, self)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        return _setException(PyExc_ValueError);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return (PyObject *)newobj;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -142,16 +190,24 @@ static PyObject *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ EVP_digest(EVPobject *self, PyObject *unused)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     unsigned char digest[EVP_MAX_MD_SIZE];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    EVP_MD_CTX temp_ctx;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    EVP_MD_CTX *temp_ctx;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     PyObject *retval;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     unsigned int digest_size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    locked_EVP_MD_CTX_copy(&temp_ctx, self);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    digest_size = EVP_MD_CTX_size(&temp_ctx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    EVP_DigestFinal(&temp_ctx, digest, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    temp_ctx = EVP_MD_CTX_new();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (temp_ctx == NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        PyErr_NoMemory();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        return NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        return _setException(PyExc_ValueError);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    digest_size = EVP_MD_CTX_size(temp_ctx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    EVP_DigestFinal(temp_ctx, digest, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     retval = PyBytes_FromStringAndSize((const char *)digest, digest_size);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    EVP_MD_CTX_cleanup(&temp_ctx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    EVP_MD_CTX_free(temp_ctx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return retval;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -162,17 +218,25 @@ static PyObject *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ EVP_hexdigest(EVPobject *self, PyObject *unused)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     unsigned char digest[EVP_MAX_MD_SIZE];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    EVP_MD_CTX temp_ctx;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    EVP_MD_CTX *temp_ctx;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     PyObject *retval;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     char *hex_digest;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     unsigned int i, j, digest_size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    temp_ctx = EVP_MD_CTX_new();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (temp_ctx == NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        PyErr_NoMemory();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        return NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     /* Get the raw (binary) digest value */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    locked_EVP_MD_CTX_copy(&temp_ctx, self);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    digest_size = EVP_MD_CTX_size(&temp_ctx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    EVP_DigestFinal(&temp_ctx, digest, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        return _setException(PyExc_ValueError);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    digest_size = EVP_MD_CTX_size(temp_ctx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    EVP_DigestFinal(temp_ctx, digest, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    EVP_MD_CTX_cleanup(&temp_ctx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    EVP_MD_CTX_free(temp_ctx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     /* Allocate a new buffer */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     hex_digest = PyMem_Malloc(digest_size * 2 + 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -241,7 +305,7 @@ static PyObject *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ EVP_get_block_size(EVPobject *self, void *closure)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     long block_size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    block_size = EVP_MD_CTX_block_size(&self->ctx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    block_size = EVP_MD_CTX_block_size(self->ctx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return PyLong_FromLong(block_size);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -249,7 +313,7 @@ static PyObject *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ EVP_get_digest_size(EVPobject *self, void *closure)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     long size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    size = EVP_MD_CTX_size(&self->ctx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    size = EVP_MD_CTX_size(self->ctx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return PyLong_FromLong(size);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -310,7 +374,7 @@ EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             PyBuffer_Release(&view);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         return -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    EVP_DigestInit(&self->ctx, digest);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    EVP_DigestInit(self->ctx, digest);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     self->name = name_obj;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     Py_INCREF(self->name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -407,9 +471,9 @@ EVPnew(PyObject *name_obj,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         return NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (initial_ctx) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        EVP_MD_CTX_copy(&self->ctx, initial_ctx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        EVP_MD_CTX_copy(self->ctx, initial_ctx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        EVP_DigestInit(&self->ctx, digest);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        EVP_DigestInit(self->ctx, digest);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (cp && len) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -475,6 +539,7 @@ EVP_new(PyObject *self, PyObject *args, PyObject *kwdict)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #define PY_PBKDF2_HMAC 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#if !HAS_FAST_PKCS5_PBKDF2_HMAC
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Improved implementation of PKCS5_PBKDF2_HMAC()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  * PKCS5_PBKDF2_HMAC_fast() hashes the password exactly one time instead of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -556,37 +621,8 @@ PKCS5_PBKDF2_HMAC_fast(const char *pass, int passlen,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     HMAC_CTX_cleanup(&hctx_tpl);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-/* LCOV_EXCL_START */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-static PyObject *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-_setException(PyObject *exc)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    unsigned long errcode;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    const char *lib, *func, *reason;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    errcode = ERR_peek_last_error();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    if (!errcode) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        PyErr_SetString(exc, "unknown reasons");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        return NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    ERR_clear_error();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    lib = ERR_lib_error_string(errcode);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    func = ERR_func_error_string(errcode);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    reason = ERR_reason_error_string(errcode);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    if (lib && func) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        PyErr_Format(exc, "[%s: %s] %s", lib, func, reason);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    else if (lib) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        PyErr_Format(exc, "[%s] %s", lib, reason);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        PyErr_SetString(exc, reason);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    return NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-/* LCOV_EXCL_STOP */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ PyDoc_STRVAR(pbkdf2_hmac__doc__,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ "pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None) -> key\n\
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -668,10 +704,17 @@ pbkdf2_hmac(PyObject *self, PyObject *args, PyObject *kwdict)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     key = PyBytes_AS_STRING(key_obj);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     Py_BEGIN_ALLOW_THREADS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#if HAS_FAST_PKCS5_PBKDF2_HMAC
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    retval = PKCS5_PBKDF2_HMAC((char*)password.buf, (int)password.len,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                               (unsigned char *)salt.buf, (int)salt.len,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                               iterations, digest, dklen,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                               (unsigned char *)key);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     retval = PKCS5_PBKDF2_HMAC_fast((char*)password.buf, (int)password.len,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                     (unsigned char *)salt.buf, (int)salt.len,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                     iterations, digest, dklen,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                     (unsigned char *)key);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     Py_END_ALLOW_THREADS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (!retval) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -790,7 +833,7 @@ generate_hash_name_list(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (CONST_ ## NAME ## _name_obj == NULL) { \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         CONST_ ## NAME ## _name_obj = PyUnicode_FromString(#NAME); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         if (EVP_get_digestbyname(#NAME)) { \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            CONST_new_ ## NAME ## _ctx_p = &CONST_new_ ## NAME ## _ctx; \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            CONST_new_ ## NAME ## _ctx_p = EVP_MD_CTX_new(); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             EVP_DigestInit(CONST_new_ ## NAME ## _ctx_p, EVP_get_digestbyname(#NAME)); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         } \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     } \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git Modules/_ssl.c Modules/_ssl.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 0ff9d553e2a0..c94cdc3e7e71 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- Modules/_ssl.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ Modules/_ssl.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -55,6 +55,14 @@ static PySocketModule_APIObject PySocketModule;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <sys/poll.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* Don't warn about deprecated functions */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef __GNUC__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef __clang__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#pragma clang diagnostic ignored "-Wdeprecated-declarations"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Include OpenSSL header files */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "openssl/rsa.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "openssl/crypto.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -90,6 +98,10 @@ struct py_ssl_library_code {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Include generated data (error codes) */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "_ssl_data.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#  define OPENSSL_VERSION_1_1 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Openssl comes with TLSv1.1 and TLSv1.2 between 1.0.0h and 1.0.1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     http://www.openssl.org/news/changelog.html
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -108,6 +120,72 @@ struct py_ssl_library_code {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # define HAVE_SNI 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# define HAVE_ALPN
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifndef INVALID_SOCKET /* MS defines this */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define INVALID_SOCKET (-1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef OPENSSL_VERSION_1_1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* OpenSSL 1.1.0+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifndef OPENSSL_NO_SSL2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define OPENSSL_NO_SSL2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#else /* OpenSSL < 1.1.0 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#if defined(WITH_THREAD)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define HAVE_OPENSSL_CRYPTO_LOCK
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return ne->set;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifndef OPENSSL_NO_COMP
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static int COMP_get_type(const COMP_METHOD *meth)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return meth->type;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static const char *COMP_get_name(const COMP_METHOD *meth)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return meth->name;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static pem_password_cb *SSL_CTX_get_default_passwd_cb(SSL_CTX *ctx)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return ctx->default_passwd_callback;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static void *SSL_CTX_get_default_passwd_cb_userdata(SSL_CTX *ctx)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return ctx->default_passwd_callback_userdata;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static int X509_OBJECT_get_type(X509_OBJECT *x)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return x->type;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static X509 *X509_OBJECT_get0_X509(X509_OBJECT *x)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return x->data.x509;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *store) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return store->objs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *store)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return store->param;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif /* OpenSSL < 1.1.0 or LibreSSL */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ enum py_ssl_error {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     /* these mirror ssl.h */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     PY_SSL_ERROR_NONE,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -691,7 +769,7 @@ _create_tuple_for_X509_NAME (X509_NAME *xname)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         /* check to see if we've gotten to a new RDN */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         if (rdn_level >= 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            if (rdn_level != entry->set) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            if (rdn_level != X509_NAME_ENTRY_set(entry)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                 /* yes, new RDN */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                 /* add old RDN to DN */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                 rdnt = PyList_AsTuple(rdn);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -708,7 +786,7 @@ _create_tuple_for_X509_NAME (X509_NAME *xname)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                     goto fail0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        rdn_level = entry->set;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        rdn_level = X509_NAME_ENTRY_set(entry);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         /* now add this attribute to the current RDN */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         name = X509_NAME_ENTRY_get_object(entry);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -811,18 +889,18 @@ _get_peer_alt_names (X509 *certificate) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             goto fail;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        p = ext->value->data;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        p = X509_EXTENSION_get_data(ext)->data;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         if (method->it)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             names = (GENERAL_NAMES*)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+               (ASN1_item_d2i(NULL,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                              &p,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                             ext->value->length,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                             X509_EXTENSION_get_data(ext)->length,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                              ASN1_ITEM_ptr(method->it)));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             names = (GENERAL_NAMES*)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+               (method->d2i(NULL,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            &p,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                           ext->value->length));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                           X509_EXTENSION_get_data(ext)->length));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         for(j = 0; j < sk_GENERAL_NAME_num(names); j++) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             /* get a rendering of each name in the set of names */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1033,13 +1111,11 @@ _get_crl_dp(X509 *certificate) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     int i, j;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     PyObject *lst, *res = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#if OPENSSL_VERSION_NUMBER < 0x10001000L
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    dps = X509_get_ext_d2i(certificate, NID_crl_distribution_points, NULL, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#if OPENSSL_VERSION_NUMBER >= 0x10001000L
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     /* Calls x509v3_cache_extensions and sets up crldp */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     X509_check_ca(certificate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    dps = certificate->crldp;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    dps = X509_get_ext_d2i(certificate, NID_crl_distribution_points, NULL, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (dps == NULL)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         return Py_None;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1431,9 +1507,9 @@ static PyObject *PySSL_compression(PySSLSocket *self) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (self->ssl == NULL)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         Py_RETURN_NONE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     comp_method = SSL_get_current_compression(self->ssl);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    if (comp_method == NULL || comp_method->type == NID_undef)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (comp_method == NULL || COMP_get_type(comp_method) == NID_undef)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         Py_RETURN_NONE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    short_name = OBJ_nid2sn(comp_method->type);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    short_name = COMP_get_name(comp_method);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (short_name == NULL)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         Py_RETURN_NONE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return PyUnicode_DecodeFSDefault(short_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -2051,8 +2127,9 @@ context_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifndef OPENSSL_NO_ECDH
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     /* Allow automatic ECDH curve selection (on OpenSSL 1.0.2+), or use
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        prime256v1 by default.  This is Apache mod_ssl's initialization
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-       policy, so we should be safe. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#if defined(SSL_CTX_set_ecdh_auto)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++       policy, so we should be safe. OpenSSL 1.1 has it enabled by default.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++     */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#if defined(SSL_CTX_set_ecdh_auto) && !defined(OPENSSL_VERSION_1_1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     SSL_CTX_set_ecdh_auto(self->ctx, 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -2263,10 +2340,12 @@ static PyObject *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ get_verify_flags(PySSLContext *self, void *c)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     X509_STORE *store;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    X509_VERIFY_PARAM *param;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     unsigned long flags;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     store = SSL_CTX_get_cert_store(self->ctx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    flags = X509_VERIFY_PARAM_get_flags(store->param);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    param = X509_STORE_get0_param(store);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    flags = X509_VERIFY_PARAM_get_flags(param);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return PyLong_FromUnsignedLong(flags);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -2274,22 +2353,24 @@ static int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set_verify_flags(PySSLContext *self, PyObject *arg, void *c)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     X509_STORE *store;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    X509_VERIFY_PARAM *param;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     unsigned long new_flags, flags, set, clear;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (!PyArg_Parse(arg, "k", &new_flags))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         return -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     store = SSL_CTX_get_cert_store(self->ctx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    flags = X509_VERIFY_PARAM_get_flags(store->param);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    param = X509_STORE_get0_param(store);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    flags = X509_VERIFY_PARAM_get_flags(param);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     clear = flags & ~new_flags;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     set = ~flags & new_flags;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (clear) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if (!X509_VERIFY_PARAM_clear_flags(store->param, clear)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (!X509_VERIFY_PARAM_clear_flags(param, clear)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             _setSSLError(NULL, 0, __FILE__, __LINE__);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             return -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (set) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if (!X509_VERIFY_PARAM_set_flags(store->param, set)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (!X509_VERIFY_PARAM_set_flags(param, set)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             _setSSLError(NULL, 0, __FILE__, __LINE__);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             return -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -2459,8 +2540,8 @@ load_cert_chain(PySSLContext *self, PyObject *args, PyObject *kwds)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     char *kwlist[] = {"certfile", "keyfile", "password", NULL};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     PyObject *certfile, *keyfile = NULL, *password = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     PyObject *certfile_bytes = NULL, *keyfile_bytes = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    pem_password_cb *orig_passwd_cb = self->ctx->default_passwd_callback;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    void *orig_passwd_userdata = self->ctx->default_passwd_callback_userdata;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    pem_password_cb *orig_passwd_cb = SSL_CTX_get_default_passwd_cb(self->ctx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    void *orig_passwd_userdata = SSL_CTX_get_default_passwd_cb_userdata(self->ctx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     _PySSLPasswordInfo pw_info = { NULL, NULL, NULL, 0, 0 };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     int r;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -2591,8 +2672,9 @@ _add_ca_certs(PySSLContext *self, void *data, Py_ssize_t len,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             cert = d2i_X509_bio(biobuf, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             cert = PEM_read_bio_X509(biobuf, NULL,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                     self->ctx->default_passwd_callback,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                                     self->ctx->default_passwd_callback_userdata);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                     SSL_CTX_get_default_passwd_cb(self->ctx),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                     SSL_CTX_get_default_passwd_cb_userdata(self->ctx)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                    );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         if (cert == NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -3040,25 +3122,24 @@ static PyObject *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ cert_store_stats(PySSLContext *self)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     X509_STORE *store;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    STACK_OF(X509_OBJECT) *objs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     X509_OBJECT *obj;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    int x509 = 0, crl = 0, pkey = 0, ca = 0, i;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    int x509 = 0, crl = 0, ca = 0, i;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     store = SSL_CTX_get_cert_store(self->ctx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    for (i = 0; i < sk_X509_OBJECT_num(store->objs); i++) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        obj = sk_X509_OBJECT_value(store->objs, i);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        switch (obj->type) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    objs = X509_STORE_get0_objects(store);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    for (i = 0; i < sk_X509_OBJECT_num(objs); i++) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        obj = sk_X509_OBJECT_value(objs, i);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        switch (X509_OBJECT_get_type(obj)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             case X509_LU_X509:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                 x509++;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                if (X509_check_ca(obj->data.x509)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                if (X509_check_ca(X509_OBJECT_get0_X509(obj))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                     ca++;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                 }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                 break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             case X509_LU_CRL:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                 crl++;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                 break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            case X509_LU_PKEY:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                pkey++;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             default:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                 /* Ignore X509_LU_FAIL, X509_LU_RETRY, X509_LU_PKEY.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                  * As far as I can tell they are internal states and never
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -3083,6 +3164,7 @@ get_ca_certs(PySSLContext *self, PyObject *args, PyObject *kwds)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     char *kwlist[] = {"binary_form", NULL};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     X509_STORE *store;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    STACK_OF(X509_OBJECT) *objs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     PyObject *ci = NULL, *rlist = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     int i;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     int binary_mode = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -3097,17 +3179,18 @@ get_ca_certs(PySSLContext *self, PyObject *args, PyObject *kwds)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     store = SSL_CTX_get_cert_store(self->ctx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    for (i = 0; i < sk_X509_OBJECT_num(store->objs); i++) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    objs = X509_STORE_get0_objects(store);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    for (i = 0; i < sk_X509_OBJECT_num(objs); i++) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         X509_OBJECT *obj;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         X509 *cert;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        obj = sk_X509_OBJECT_value(store->objs, i);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        if (obj->type != X509_LU_X509) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        obj = sk_X509_OBJECT_value(objs, i);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (X509_OBJECT_get_type(obj) != X509_LU_X509) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             /* not a x509 cert */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         /* CA for any purpose */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        cert = obj->data.x509;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        cert = X509_OBJECT_get0_X509(obj);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         if (!X509_check_ca(cert)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -3780,10 +3863,12 @@ static PyMethodDef PySSL_methods[] = {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#ifdef WITH_THREAD
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef HAVE_OPENSSL_CRYPTO_LOCK
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* an implementation of OpenSSL threading operations in terms
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-   of the Python C thread library */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * of the Python C thread library
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Only used up to 1.0.2. OpenSSL 1.1.0+ has its own locking code.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static PyThread_type_lock *_ssl_locks = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -3864,7 +3949,7 @@ static int _setup_ssl_threads(void) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     return 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#endif  /* def HAVE_THREAD */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif  /* HAVE_OPENSSL_CRYPTO_LOCK for WITH_THREAD && OpenSSL < 1.1.0 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ PyDoc_STRVAR(module_doc,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ "Implementation module for SSL socket operations.  See the socket module\n\
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -3931,11 +4016,16 @@ PyInit__ssl(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     SSL_load_error_strings();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     SSL_library_init();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef WITH_THREAD
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef HAVE_OPENSSL_CRYPTO_LOCK
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     /* note that this will start threading if not already started */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (!_setup_ssl_threads()) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         return NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#elif OPENSSL_VERSION_1_1 && defined(OPENSSL_THREADS)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    /* OpenSSL 1.1.0 builtin thread support is enabled */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    _ssl_locks_count++;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif  /* WITH_THREAD */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     OpenSSL_add_all_algorithms();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     /* Add symbols to module dict */
</span></pre><pre style='margin:0'>

</pre>