aboutsummaryrefslogtreecommitdiffstats
path: root/src/cryptography
diff options
context:
space:
mode:
Diffstat (limited to 'src/cryptography')
-rw-r--r--src/cryptography/hazmat/backends/openssl/backend.py2
-rw-r--r--src/cryptography/hazmat/bindings/openssl/binding.py49
2 files changed, 48 insertions, 3 deletions
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index 88a17de0..91bc304f 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -200,7 +200,7 @@ class Backend(object):
self.activate_builtin_random()
# Fetches an engine by id and returns it. This creates a structural
# reference.
- e = self._lib.ENGINE_by_id(self._lib.Cryptography_osrandom_engine_id)
+ e = self._lib.ENGINE_by_id(self._binding._osrandom_engine_id)
assert e != self._ffi.NULL
# Initialize the engine for use. This adds a functional reference.
res = self._lib.ENGINE_init(e)
diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py
index e0a83972..b7178bb2 100644
--- a/src/cryptography/hazmat/bindings/openssl/binding.py
+++ b/src/cryptography/hazmat/bindings/openssl/binding.py
@@ -4,11 +4,25 @@
from __future__ import absolute_import, division, print_function
+import os
import threading
from cryptography.hazmat.bindings._openssl import ffi, lib
+@ffi.callback("int (*)(unsigned char *, int)", error=-1)
+def _osrandom_rand_bytes(buf, size):
+ signed = ffi.cast("char *", buf)
+ result = os.urandom(size)
+ signed[0:size] = result
+ return 1
+
+
+@ffi.callback("int (*)(void)")
+def _osrandom_rand_status():
+ return 1
+
+
class Binding(object):
"""
OpenSSL API wrapper.
@@ -21,10 +35,42 @@ class Binding(object):
_init_lock = threading.Lock()
_lock_init_lock = threading.Lock()
+ _osrandom_engine_id = ffi.new("const char[]", b"osrandom")
+ _osrandom_engine_name = ffi.new("const char[]", b"osrandom_engine")
+ _osrandom_method = ffi.new(
+ "RAND_METHOD *",
+ dict(bytes=_osrandom_rand_bytes, pseudorand=_osrandom_rand_bytes,
+ status=_osrandom_rand_status)
+ )
+
def __init__(self):
self._ensure_ffi_initialized()
@classmethod
+ def _register_osrandom_engine(cls):
+ assert 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()
+ assert engine != cls.ffi.NULL
+ try:
+ result = cls.lib.ENGINE_set_id(engine, cls._osrandom_engine_id)
+ assert result == 1
+ result = cls.lib.ENGINE_set_name(engine, cls._osrandom_engine_name)
+ assert result == 1
+ result = cls.lib.ENGINE_set_RAND(engine, cls._osrandom_method)
+ assert result == 1
+ result = cls.lib.ENGINE_add(engine)
+ assert result == 1
+ finally:
+ result = cls.lib.ENGINE_free(engine)
+ assert result == 1
+
+ @classmethod
def _ensure_ffi_initialized(cls):
if cls._lib_loaded:
return
@@ -32,8 +78,7 @@ class Binding(object):
with cls._init_lock:
if not cls._lib_loaded:
cls._lib_loaded = True
- res = cls.lib.Cryptography_add_osrandom_engine()
- assert res != 0
+ cls._register_osrandom_engine()
@classmethod
def init_static_locks(cls):