aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cryptography/hazmat/backends/openssl/backend.py32
-rw-r--r--cryptography/hazmat/backends/openssl/urand_engine.py11
-rw-r--r--tests/hazmat/backends/test_openssl.py58
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