From 80108a4485115a6abea10b57e8e8a8e3e9835c84 Mon Sep 17 00:00:00 2001 From: Alex Stapleton Date: Mon, 30 Dec 2013 23:10:23 +0000 Subject: [PATCH] Only init our locking function if Python didnt Adds quite a bit of complexity, might be better to set ours unconditionally but still import _ssl so that it doesn't overwrite ours at some point later. --- .../hazmat/backends/openssl/backend.py | 11 ++++++++-- .../hazmat/backends/openssl/threads.py | 5 +++++ tests/hazmat/backends/test_openssl.py | 20 +++++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index 3fbebaaa9666..52dbdee6660f 100644 --- a/cryptography/hazmat/backends/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -168,8 +168,15 @@ def _ensure_ffi_initialized(cls): cls.ffi = ffi cls.lib = lib - res = cls.lib.Cryptography_setup_locking() - assert res == 0 + try: + __import__("_ssl") + raise ImportError + except ImportError: + pass + + if cls.lib.CRYPTO_get_locking_callback() == cls.ffi.NULL: + res = cls.lib.Cryptography_setup_locking() + assert res == 0 cls.lib.OpenSSL_add_all_algorithms() cls.lib.SSL_load_error_strings() diff --git a/cryptography/hazmat/backends/openssl/threads.py b/cryptography/hazmat/backends/openssl/threads.py index e348d2ba98fb..b7e25f6be45f 100644 --- a/cryptography/hazmat/backends/openssl/threads.py +++ b/cryptography/hazmat/backends/openssl/threads.py @@ -19,7 +19,10 @@ """ FUNCTIONS = """ +void (*CRYPTO_get_locking_callback(void))(int, int, const char *, int); +void CRYPTO_set_locking_callback(void (*func)(int, int, const char *, int)); static int Cryptography_setup_locking(); +static void (*Cryptography_locking_function_ptr)(int, int, const char *, int); """ MACROS = """ @@ -200,6 +203,8 @@ } } +static void (*Cryptography_locking_function_ptr) + (int, int, const char *, int) = Cryptography_locking_function; static int Cryptography_setup_locking() { unsigned int i; diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py index 967d69c79707..e2c6f4382d21 100644 --- a/tests/hazmat/backends/test_openssl.py +++ b/tests/hazmat/backends/test_openssl.py @@ -100,6 +100,26 @@ def test_handle_unknown_error(self): 0 ) + def test_locking_callback_set(self): + b = Backend() + + locking_cb = b.lib.CRYPTO_get_locking_callback() + assert locking_cb != b.ffi.NULL + + # emulate import _ssl not setting this for some reason + b.lib.CRYPTO_set_locking_callback(b.ffi.NULL) + + # force cffi to reinit + Backend.ffi = None + Backend.lib = None + + # now it should get set to our one + b = Backend() + locking_cb = b.lib.CRYPTO_get_locking_callback() + + assert locking_cb != b.ffi.NULL + assert locking_cb == b.lib.Cryptography_locking_function_ptr + def test_threads(self): b = Backend()