diff options
author | Paul Kehrer <paul.l.kehrer@gmail.com> | 2015-08-24 08:00:10 -0500 |
---|---|---|
committer | Paul Kehrer <paul.l.kehrer@gmail.com> | 2015-10-21 23:00:24 -0500 |
commit | 9837cb15b84fea92ffce3306d14160a8c11b1c65 (patch) | |
tree | 532610680f8894875ad78108bbf2d2ada1793509 | |
parent | 2d79836e9dbafd217f2febb61b964157600dc9f5 (diff) | |
download | cryptography-9837cb15b84fea92ffce3306d14160a8c11b1c65.tar.gz cryptography-9837cb15b84fea92ffce3306d14160a8c11b1c65.tar.bz2 cryptography-9837cb15b84fea92ffce3306d14160a8c11b1c65.zip |
make engine addition idempotent
Threading issues keep cropping up. ENGINE_add already
acquires a lock at the C layer via CRYPTO_w_lock (provided you
have registered the locking callbacks) so let's try to use that.
As part of this we'll try to init the openssl locks, but of course
there's potentially a race there as well. Clearly this isn't the real
fix but it might improve the situation while we try to determine what to
do.
-rw-r--r-- | src/_cffi_src/openssl/engine.py | 2 | ||||
-rw-r--r-- | src/cryptography/hazmat/bindings/openssl/binding.py | 14 | ||||
-rw-r--r-- | tests/hazmat/bindings/test_openssl.py | 4 |
3 files changed, 13 insertions, 7 deletions
diff --git a/src/_cffi_src/openssl/engine.py b/src/_cffi_src/openssl/engine.py index 011f6692..60c6f3e2 100644 --- a/src/_cffi_src/openssl/engine.py +++ b/src/_cffi_src/openssl/engine.py @@ -44,6 +44,8 @@ static const unsigned int ENGINE_METHOD_DIGESTS; static const unsigned int ENGINE_METHOD_STORE; static const unsigned int ENGINE_METHOD_ALL; static const unsigned int ENGINE_METHOD_NONE; + +static const int ENGINE_R_CONFLICTING_ENGINE_ID; """ FUNCTIONS = """ diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index 47b1d6e2..f8bf3116 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -97,10 +97,6 @@ class Binding(object): @classmethod def _register_osrandom_engine(cls): _openssl_assert(cls.lib, cls.lib.ERR_peek_error() == 0) - looked_up_engine = cls.lib.ENGINE_by_id(cls._osrandom_engine_id) - if looked_up_engine != ffi.NULL: - raise RuntimeError("osrandom engine already registered") - cls.lib.ERR_clear_error() engine = cls.lib.ENGINE_new() @@ -113,7 +109,12 @@ class Binding(object): result = cls.lib.ENGINE_set_RAND(engine, cls._osrandom_method) _openssl_assert(cls.lib, result == 1) result = cls.lib.ENGINE_add(engine) - _openssl_assert(cls.lib, result == 1) + if result != 1: + errors = _consume_errors(cls.lib) + assert ( + errors[0].reason == cls.lib.ENGINE_R_CONFLICTING_ENGINE_ID + ) + finally: result = cls.lib.ENGINE_free(engine) _openssl_assert(cls.lib, result == 1) @@ -171,3 +172,6 @@ class Binding(object): mode, n, file, line ) ) + +# init the static locks so we have a locking callback in C for engine init +Binding.init_static_locks() diff --git a/tests/hazmat/bindings/test_openssl.py b/tests/hazmat/bindings/test_openssl.py index 20171fa7..76a9218b 100644 --- a/tests/hazmat/bindings/test_openssl.py +++ b/tests/hazmat/bindings/test_openssl.py @@ -89,8 +89,8 @@ class TestOpenSSL(object): def test_add_engine_more_than_once(self): b = Binding() - with pytest.raises(RuntimeError): - b._register_osrandom_engine() + b._register_osrandom_engine() + assert b.lib.ERR_get_error() == 0 def test_ssl_ctx_options(self): # Test that we're properly handling 32-bit unsigned on all platforms. |