diff options
-rw-r--r-- | cryptography/hazmat/backends/openssl/backend.py | 32 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/urand_engine.py | 11 | ||||
-rw-r--r-- | tests/hazmat/backends/test_openssl.py | 58 |
3 files changed, 81 insertions, 20 deletions
diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index 0f134e52..a61e7b05 100644 --- a/cryptography/hazmat/backends/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -181,10 +181,11 @@ class Backend(object): if e != self.ffi.NULL: name = self.lib.ENGINE_get_name(e) assert name != self.ffi.NULL - if self.ffi.string(name) == "urandom_engine": + if name == self.lib.Cryptography_urandom_engine_name: self.lib.ENGINE_unregister_RAND(e) res = self.lib.ENGINE_free(e) assert res == 1 + # this resets the RNG to use the new engine self.lib.RAND_cleanup() def register_urandom_engine(self): @@ -192,22 +193,23 @@ class Backend(object): if current_rand != self.ffi.NULL: name = self.lib.ENGINE_get_name(current_rand) assert name != self.ffi.NULL - if self.ffi.string(name) == "urandom_engine": + if name == self.lib.Cryptography_urandom_engine_name: + # urand is already the current default RAND res = self.lib.ENGINE_finish(current_rand) assert res == 1 - return - - e = self.lib.ENGINE_by_id("urandom") - assert e != self.ffi.NULL - res = self.lib.ENGINE_init(e) - assert res == 1 - res = self.lib.ENGINE_set_default_RAND(e) - assert res == 1 - res = self.lib.ENGINE_finish(e) - assert res == 1 - res = self.lib.ENGINE_free(e) - assert res == 1 - self.lib.RAND_cleanup() + else: + e = self.lib.ENGINE_by_id(self.lib.Cryptography_urandom_engine_id) + assert e != self.ffi.NULL + res = self.lib.ENGINE_init(e) + assert res == 1 + res = self.lib.ENGINE_set_default_RAND(e) + assert res == 1 + res = self.lib.ENGINE_finish(e) + assert res == 1 + res = self.lib.ENGINE_free(e) + assert res == 1 + # this resets the RNG to use the new engine + self.lib.RAND_cleanup() def openssl_version_text(self): """ diff --git a/cryptography/hazmat/backends/openssl/urand_engine.py b/cryptography/hazmat/backends/openssl/urand_engine.py index 0a86af3e..67ebe272 100644 --- a/cryptography/hazmat/backends/openssl/urand_engine.py +++ b/cryptography/hazmat/backends/openssl/urand_engine.py @@ -21,6 +21,8 @@ INCLUDES = """ """ TYPES = """ +static const char *const Cryptography_urandom_engine_name; +static const char *const Cryptography_urandom_engine_id; """ FUNCTIONS = """ @@ -31,8 +33,8 @@ MACROS = """ """ CUSTOMIZATIONS = """ -static const char *urandom_engine_id= "urandom"; -static const char *urandom_engine_name = "urandom_engine"; +static const char *Cryptography_urandom_engine_id= "urandom"; +static const char *Cryptography_urandom_engine_name = "urandom_engine"; #ifndef _WIN32 static int urandom_fd; @@ -86,7 +88,6 @@ static int urandom_finish(ENGINE *e) { static HCRYPTPROV hCryptProv = 0; static int urandom_init(ENGINE *e) { - /* Acquire context */ if (CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { return 1; @@ -133,8 +134,8 @@ static RAND_METHOD urandom_rand = { int Cryptography_add_urandom_engine(void) { ENGINE *e = ENGINE_new(); - if(!ENGINE_set_id(e, urandom_engine_id) || - !ENGINE_set_name(e, urandom_engine_name) || + if(!ENGINE_set_id(e, Cryptography_urandom_engine_id) || + !ENGINE_set_name(e, Cryptography_urandom_engine_name) || !ENGINE_set_RAND(e, &urandom_rand) || !ENGINE_set_init_function(e, urandom_init) || !ENGINE_set_finish_function(e, urandom_finish)) { diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py index 543a05fe..4dd74c35 100644 --- a/tests/hazmat/backends/test_openssl.py +++ b/tests/hazmat/backends/test_openssl.py @@ -97,3 +97,61 @@ class TestOpenSSL(object): backend.lib.EVP_F_EVP_DECRYPTFINAL_EX, 0 ) + + # This test is not in the next class because to check if it's really + # default we don't want to run the setup_method before it + def test_urandom_engine_is_default(self): + e = backend.lib.ENGINE_get_default_RAND() + name = backend.lib.ENGINE_get_name(e) + assert name == backend.lib.Cryptography_urandom_engine_name + res = backend.lib.ENGINE_free(e) + assert res == 1 + + +class TestOpenSSLRandomEngine(object): + def setup_method(self, method): + # we need to reset state to being default. backend is a shared global + # for all these tests. + backend.register_urandom_engine() + pass + + def test_register_urandom_already_default(self): + e = backend.lib.ENGINE_get_default_RAND() + name = backend.lib.ENGINE_get_name(e) + assert name == backend.lib.Cryptography_urandom_engine_name + res = backend.lib.ENGINE_free(e) + assert res == 1 + backend.register_urandom_engine() + e = backend.lib.ENGINE_get_default_RAND() + name = backend.lib.ENGINE_get_name(e) + assert name == backend.lib.Cryptography_urandom_engine_name + res = backend.lib.ENGINE_free(e) + assert res == 1 + + def test_unregister_urandom_engine_already_unregistered(self): + backend.unregister_urandom_engine() + e = backend.lib.ENGINE_get_default_RAND() + assert e == backend.ffi.NULL + backend.unregister_urandom_engine() + e = backend.lib.ENGINE_get_default_RAND() + assert e == backend.ffi.NULL + + def test_unregister_urandom_engine(self): + e = backend.lib.ENGINE_get_default_RAND() + assert e != backend.ffi.NULL + name = backend.lib.ENGINE_get_name(e) + assert name == backend.lib.Cryptography_urandom_engine_name + backend.unregister_urandom_engine() + e = backend.lib.ENGINE_get_default_RAND() + assert e == backend.ffi.NULL + + def test_register_urandom_not_default(self): + backend.unregister_urandom_engine() + e = backend.lib.ENGINE_get_default_RAND() + assert e == backend.ffi.NULL + backend.register_urandom_engine() + e = backend.lib.ENGINE_get_default_RAND() + name = backend.lib.ENGINE_get_name(e) + assert name == backend.lib.Cryptography_urandom_engine_name + res = backend.lib.ENGINE_free(e) + assert res == 1 |