diff options
Diffstat (limited to 'src/cryptography')
-rw-r--r-- | src/cryptography/hazmat/backends/openssl/backend.py | 2 | ||||
-rw-r--r-- | src/cryptography/hazmat/bindings/openssl/binding.py | 49 |
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): |