From 332936dffb7c8574be7340271f9cfb196f25a016 Mon Sep 17 00:00:00 2001 From: Glyph Date: Fri, 26 Jun 2015 21:59:15 -0700 Subject: deopaque a couple of things --- src/_cffi_src/openssl/engine.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/_cffi_src/openssl/engine.py b/src/_cffi_src/openssl/engine.py index 3ebfa6c1..bc5c1906 100644 --- a/src/_cffi_src/openssl/engine.py +++ b/src/_cffi_src/openssl/engine.py @@ -11,15 +11,24 @@ INCLUDES = """ TYPES = """ static const long Cryptography_HAS_ENGINE_CRYPTODEV; +struct rand_meth_st { + void (*seed)(const void *buf, int num); + int (*bytes)(unsigned char *buf, int num); + void (*cleanup)(void); + void (*add)(const void *buf, int num, double entropy); + int (*pseudorand)(unsigned char *buf, int num); + int (*status)(void); +}; + typedef ... ENGINE; typedef ... RSA_METHOD; typedef ... DSA_METHOD; typedef ... ECDH_METHOD; typedef ... ECDSA_METHOD; typedef ... DH_METHOD; -typedef ... RAND_METHOD; +typedef struct rand_meth_st RAND_METHOD; typedef ... STORE_METHOD; -typedef ... *ENGINE_GEN_INT_FUNC_PTR; +typedef int(*ENGINE_GEN_INT_FUNC_PTR)(ENGINE*); typedef ... *ENGINE_CTRL_FUNC_PTR; typedef ... *ENGINE_LOAD_KEY_PTR; typedef ... *ENGINE_CIPHERS_PTR; -- cgit v1.2.3 From e55898a7e9ec9ab6374b617140e87ef12b3fd2d5 Mon Sep 17 00:00:00 2001 From: Glyph Date: Fri, 26 Jun 2015 22:00:07 -0700 Subject: a place for a couple of new constants to live --- src/cryptography/hazmat/bindings/openssl/binding.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index e0a83972..8f741a29 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -20,6 +20,8 @@ class Binding(object): _lock_cb_handle = None _init_lock = threading.Lock() _lock_init_lock = threading.Lock() + _osrandom_engine_id = b"osrandom" + _osrandom_engine_name = b"osrandom_engine" def __init__(self): self._ensure_ffi_initialized() -- cgit v1.2.3 From eaed9510a08ee61a7f495de554e4f936985d68bd Mon Sep 17 00:00:00 2001 From: Glyph Date: Fri, 26 Jun 2015 22:00:25 -0700 Subject: compare contents and not pointers --- tests/hazmat/backends/test_openssl.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py index 34fff277..8846491a 100644 --- a/tests/hazmat/backends/test_openssl.py +++ b/tests/hazmat/backends/test_openssl.py @@ -223,8 +223,10 @@ class TestOpenSSLRandomEngine(object): # for all these tests. backend.activate_osrandom_engine() current_default = backend._lib.ENGINE_get_default_RAND() - name = backend._lib.ENGINE_get_name(current_default) - assert name == backend._lib.Cryptography_osrandom_engine_name + name = backend._ffi.string( + backend._lib.ENGINE_get_name(current_default) + ) + assert name == backend._binding._osrandom_engine_name def test_osrandom_engine_is_default(self, tmpdir): engine_printer = textwrap.dedent( @@ -277,15 +279,16 @@ class TestOpenSSLRandomEngine(object): backend.activate_osrandom_engine() e = backend._lib.ENGINE_get_default_RAND() name = backend._lib.ENGINE_get_name(e) - assert name == backend._lib.Cryptography_osrandom_engine_name + assert (backend._ffi.string(name) == + backend._binding._osrandom_engine_name) res = backend._lib.ENGINE_free(e) assert res == 1 def test_activate_builtin_random(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_osrandom_engine_name + name = backend._ffi.string(backend._lib.ENGINE_get_name(e)) + assert name == backend._binding._osrandom_engine_name res = backend._lib.ENGINE_free(e) assert res == 1 backend.activate_builtin_random() @@ -302,14 +305,14 @@ class TestOpenSSLRandomEngine(object): def test_activate_osrandom_already_default(self): e = backend._lib.ENGINE_get_default_RAND() - name = backend._lib.ENGINE_get_name(e) - assert name == backend._lib.Cryptography_osrandom_engine_name + name = backend._ffi.string(backend._lib.ENGINE_get_name(e)) + assert name == backend._binding._osrandom_engine_name res = backend._lib.ENGINE_free(e) assert res == 1 backend.activate_osrandom_engine() e = backend._lib.ENGINE_get_default_RAND() - name = backend._lib.ENGINE_get_name(e) - assert name == backend._lib.Cryptography_osrandom_engine_name + name = backend._ffi.string(backend._lib.ENGINE_get_name(e)) + assert name == backend._binding._osrandom_engine_name res = backend._lib.ENGINE_free(e) assert res == 1 -- cgit v1.2.3 From 73541ea8b61ae871fcd4470600f7012fb1aa75b3 Mon Sep 17 00:00:00 2001 From: Glyph Date: Fri, 26 Jun 2015 22:00:45 -0700 Subject: use new constant --- src/cryptography/hazmat/backends/openssl/backend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 78de79d1..85f65972 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -197,7 +197,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) -- cgit v1.2.3 From b3d37a5d485bcd295d1933d638180e9cd5d23478 Mon Sep 17 00:00:00 2001 From: Glyph Date: Fri, 26 Jun 2015 22:01:09 -0700 Subject: python implementation --- .../hazmat/bindings/openssl/binding.py | 66 +++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index 8f741a29..94751cf5 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -4,6 +4,7 @@ from __future__ import absolute_import, division, print_function +import os import threading from cryptography.hazmat.bindings._openssl import ffi, lib @@ -18,10 +19,12 @@ class Binding(object): _lib_loaded = False _locks = None _lock_cb_handle = None + _rand_method = None _init_lock = threading.Lock() _lock_init_lock = threading.Lock() _osrandom_engine_id = b"osrandom" _osrandom_engine_name = b"osrandom_engine" + _retained = [] def __init__(self): self._ensure_ffi_initialized() @@ -34,9 +37,70 @@ class Binding(object): with cls._init_lock: if not cls._lib_loaded: cls._lib_loaded = True - res = cls.lib.Cryptography_add_osrandom_engine() + res = cls._register_osrandom_engine() assert res != 0 + @classmethod + def _register_osrandom_engine(cls): + def retain(it): + cls._retained.append(it) + return it + + if cls._rand_method is not None: + raise TypeError("no") + method = cls.ffi.new("RAND_METHOD*") + retain(method) + method.seed = cls.ffi.NULL + + @retain + @cls.ffi.callback("int (*)(unsigned char *buf, int num)", error=0) + def osrandom_rand_bytes(buf, size): + signed = cls.ffi.cast("char*", buf) + result = os.urandom(size) + signed[0:size] = result + return 1 + + @retain + @cls.ffi.callback("int (*)(unsigned char *buf, int num)", error=0) + def osrandom_pseudo_rand_bytes(buf, size): + result = osrandom_rand_bytes(buf, size) + if result == 0: + return -1 + else: + return result + + @retain + @cls.ffi.callback("int (*)(void)", error=0) + def osrandom_rand_status(): + return 1 + + @retain + @cls.ffi.callback("ENGINE_GEN_INT_FUNC_PTR", error=0) + def osrandom_init(engine): + return 1 + + @retain + @cls.ffi.callback("ENGINE_GEN_INT_FUNC_PTR", error=0) + def osrandom_finish(engine): + return 1 + + method.bytes = osrandom_rand_bytes + method.cleanup = cls.ffi.NULL + method.add = cls.ffi.NULL + method.pseudorand = osrandom_pseudo_rand_bytes + method.status = osrandom_rand_status + + e = cls.lib.ENGINE_new() + result = (cls.lib.ENGINE_set_id(e, cls._osrandom_engine_id) + and cls.lib.ENGINE_set_name(e, cls._osrandom_engine_name) + and cls.lib.ENGINE_set_RAND(e, method) + and cls.lib.ENGINE_set_init_function(e, osrandom_init) + and cls.lib.ENGINE_set_finish_function(e, osrandom_finish) + and cls.lib.ENGINE_add(e)) + if not cls.lib.ENGINE_free(e): + return 0 + return result + @classmethod def init_static_locks(cls): with cls._lock_init_lock: -- cgit v1.2.3 From b51d246eb6ccaed7920ba6dd6a816f74d1158c16 Mon Sep 17 00:00:00 2001 From: Glyph Date: Fri, 26 Jun 2015 22:08:44 -0700 Subject: remove remaining vestiges, make adding twice work --- src/_cffi_src/build_openssl.py | 1 - src/_cffi_src/openssl/osrandom_engine.py | 31 ---- src/_cffi_src/openssl/src/osrandom_engine.c | 167 --------------------- src/_cffi_src/openssl/src/osrandom_engine.h | 6 - .../hazmat/bindings/openssl/binding.py | 5 +- tests/hazmat/backends/test_openssl.py | 4 +- tests/hazmat/bindings/test_openssl.py | 2 +- 7 files changed, 4 insertions(+), 212 deletions(-) delete mode 100644 src/_cffi_src/openssl/osrandom_engine.py delete mode 100644 src/_cffi_src/openssl/src/osrandom_engine.c delete mode 100644 src/_cffi_src/openssl/src/osrandom_engine.h diff --git a/src/_cffi_src/build_openssl.py b/src/_cffi_src/build_openssl.py index 1ebadccb..dac3e4d8 100644 --- a/src/_cffi_src/build_openssl.py +++ b/src/_cffi_src/build_openssl.py @@ -78,7 +78,6 @@ ffi = build_ffi_for_binding( "nid", "objects", "opensslv", - "osrandom_engine", "pem", "pkcs7", "pkcs12", diff --git a/src/_cffi_src/openssl/osrandom_engine.py b/src/_cffi_src/openssl/osrandom_engine.py deleted file mode 100644 index a8479b07..00000000 --- a/src/_cffi_src/openssl/osrandom_engine.py +++ /dev/null @@ -1,31 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. - -from __future__ import absolute_import, division, print_function - -import os - -with open(os.path.join( - os.path.dirname(__file__), "src/osrandom_engine.h" -)) as f: - INCLUDES = f.read() - -TYPES = """ -static const char *const Cryptography_osrandom_engine_name; -static const char *const Cryptography_osrandom_engine_id; -""" - -FUNCTIONS = """ -int Cryptography_add_osrandom_engine(void); -""" - -MACROS = """ -""" - -with open(os.path.join( - os.path.dirname(__file__), "src/osrandom_engine.c" -)) as f: - CUSTOMIZATIONS = f.read() - -CONDITIONAL_NAMES = {} diff --git a/src/_cffi_src/openssl/src/osrandom_engine.c b/src/_cffi_src/openssl/src/osrandom_engine.c deleted file mode 100644 index 27894712..00000000 --- a/src/_cffi_src/openssl/src/osrandom_engine.c +++ /dev/null @@ -1,167 +0,0 @@ -static const char *Cryptography_osrandom_engine_id = "osrandom"; -static const char *Cryptography_osrandom_engine_name = "osrandom_engine"; - -#if defined(_WIN32) -static HCRYPTPROV hCryptProv = 0; - -static int osrandom_init(ENGINE *e) { - if (hCryptProv > 0) { - return 1; - } - if (CryptAcquireContext(&hCryptProv, NULL, NULL, - PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { - return 1; - } else { - return 0; - } -} - -static int osrandom_rand_bytes(unsigned char *buffer, int size) { - if (hCryptProv == 0) { - return 0; - } - - if (!CryptGenRandom(hCryptProv, (DWORD)size, buffer)) { - ERR_put_error( - ERR_LIB_RAND, 0, ERR_R_RAND_LIB, "osrandom_engine.py", 0 - ); - return 0; - } - return 1; -} - -static int osrandom_finish(ENGINE *e) { - if (CryptReleaseContext(hCryptProv, 0)) { - hCryptProv = 0; - return 1; - } else { - return 0; - } -} - -static int osrandom_rand_status(void) { - if (hCryptProv == 0) { - return 0; - } else { - return 1; - } -} -#else -static int urandom_fd = -1; - -static int osrandom_finish(ENGINE *e); - -static int osrandom_init(ENGINE *e) { - if (urandom_fd > -1) { - return 1; - } - urandom_fd = open("/dev/urandom", O_RDONLY); - if (urandom_fd > -1) { - int flags = fcntl(urandom_fd, F_GETFD); - if (flags == -1) { - osrandom_finish(e); - return 0; - } else if (fcntl(urandom_fd, F_SETFD, flags | FD_CLOEXEC) == -1) { - osrandom_finish(e); - return 0; - } - return 1; - } else { - return 0; - } -} - -static int osrandom_rand_bytes(unsigned char *buffer, int size) { - ssize_t n; - while (size > 0) { - do { - n = read(urandom_fd, buffer, (size_t)size); - } while (n < 0 && errno == EINTR); - if (n <= 0) { - ERR_put_error( - ERR_LIB_RAND, 0, ERR_R_RAND_LIB, "osrandom_engine.py", 0 - ); - return 0; - } - buffer += n; - size -= n; - } - return 1; -} - -static int osrandom_finish(ENGINE *e) { - int n; - do { - n = close(urandom_fd); - } while (n < 0 && errno == EINTR); - urandom_fd = -1; - if (n < 0) { - return 0; - } else { - return 1; - } -} - -static int osrandom_rand_status(void) { - if (urandom_fd == -1) { - return 0; - } else { - return 1; - } -} -#endif - -/* This replicates the behavior of the OpenSSL FIPS RNG, which returns a - -1 in the event that there is an error when calling RAND_pseudo_bytes. */ -static int osrandom_pseudo_rand_bytes(unsigned char *buffer, int size) { - int res = osrandom_rand_bytes(buffer, size); - if (res == 0) { - return -1; - } else { - return res; - } -} - -static RAND_METHOD osrandom_rand = { - NULL, - osrandom_rand_bytes, - NULL, - NULL, - osrandom_pseudo_rand_bytes, - osrandom_rand_status, -}; - -/* Returns 1 if successfully added, 2 if engine has previously been added, - and 0 for error. */ -int Cryptography_add_osrandom_engine(void) { - ENGINE *e; - e = ENGINE_by_id(Cryptography_osrandom_engine_id); - if (e != NULL) { - ENGINE_free(e); - return 2; - } else { - ERR_clear_error(); - } - - e = ENGINE_new(); - if (e == NULL) { - return 0; - } - if(!ENGINE_set_id(e, Cryptography_osrandom_engine_id) || - !ENGINE_set_name(e, Cryptography_osrandom_engine_name) || - !ENGINE_set_RAND(e, &osrandom_rand) || - !ENGINE_set_init_function(e, osrandom_init) || - !ENGINE_set_finish_function(e, osrandom_finish)) { - ENGINE_free(e); - return 0; - } - if (!ENGINE_add(e)) { - ENGINE_free(e); - return 0; - } - if (!ENGINE_free(e)) { - return 0; - } - - return 1; -} diff --git a/src/_cffi_src/openssl/src/osrandom_engine.h b/src/_cffi_src/openssl/src/osrandom_engine.h deleted file mode 100644 index 11a3159e..00000000 --- a/src/_cffi_src/openssl/src/osrandom_engine.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifdef _WIN32 -#include -#else -#include -#include -#endif diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index 94751cf5..8e80aa60 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -42,12 +42,11 @@ class Binding(object): @classmethod def _register_osrandom_engine(cls): + if cls._retained: + return 2 def retain(it): cls._retained.append(it) return it - - if cls._rand_method is not None: - raise TypeError("no") method = cls.ffi.new("RAND_METHOD*") retain(method) method.seed = cls.ffi.NULL diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py index 8846491a..b24f03a8 100644 --- a/tests/hazmat/backends/test_openssl.py +++ b/tests/hazmat/backends/test_openssl.py @@ -259,9 +259,7 @@ class TestOpenSSLRandomEngine(object): stdout=out ) - osrandom_engine_name = backend._ffi.string( - backend._lib.Cryptography_osrandom_engine_name - ) + osrandom_engine_name = backend._binding._osrandom_engine_name assert engine_name.read().encode('ascii') == osrandom_engine_name diff --git a/tests/hazmat/bindings/test_openssl.py b/tests/hazmat/bindings/test_openssl.py index e6d6fc45..fe78b0ba 100644 --- a/tests/hazmat/bindings/test_openssl.py +++ b/tests/hazmat/bindings/test_openssl.py @@ -89,7 +89,7 @@ class TestOpenSSL(object): def test_add_engine_more_than_once(self): b = Binding() - res = b.lib.Cryptography_add_osrandom_engine() + res = b._register_osrandom_engine() assert res == 2 def test_ssl_ctx_options(self): -- cgit v1.2.3 From d70c98d28effdc410d5ac773e0e461fb548a40e0 Mon Sep 17 00:00:00 2001 From: Glyph Date: Fri, 26 Jun 2015 23:09:46 -0700 Subject: pointer shenanigans apparently (?) ENGINE_by_id treats its ID as an opaque *pointer* key and not actually as a string, and while CPython's CFFI support seems to manage to preserve the pointer identity when using the same Python string, PyPy doesn't. Fix things to use a cffi-wrapped pointer again and tests pass on PyPy. --- src/cryptography/hazmat/bindings/openssl/binding.py | 5 +++-- tests/hazmat/backends/test_openssl.py | 17 ++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index 8e80aa60..eda23959 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -22,8 +22,8 @@ class Binding(object): _rand_method = None _init_lock = threading.Lock() _lock_init_lock = threading.Lock() - _osrandom_engine_id = b"osrandom" - _osrandom_engine_name = b"osrandom_engine" + _osrandom_engine_id = ffi.new("const char[]", b"osrandom") + _osrandom_engine_name = ffi.new("const char[]", b"osrandom_engine") _retained = [] def __init__(self): @@ -98,6 +98,7 @@ class Binding(object): and cls.lib.ENGINE_add(e)) if not cls.lib.ENGINE_free(e): return 0 + assert cls.lib.ENGINE_by_id(cls._osrandom_engine_id) != cls.ffi.NULL return result @classmethod diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py index b24f03a8..6a2e8a77 100644 --- a/tests/hazmat/backends/test_openssl.py +++ b/tests/hazmat/backends/test_openssl.py @@ -223,9 +223,7 @@ class TestOpenSSLRandomEngine(object): # for all these tests. backend.activate_osrandom_engine() current_default = backend._lib.ENGINE_get_default_RAND() - name = backend._ffi.string( - backend._lib.ENGINE_get_name(current_default) - ) + name = backend._lib.ENGINE_get_name(current_default) assert name == backend._binding._osrandom_engine_name def test_osrandom_engine_is_default(self, tmpdir): @@ -259,7 +257,9 @@ class TestOpenSSLRandomEngine(object): stdout=out ) - osrandom_engine_name = backend._binding._osrandom_engine_name + osrandom_engine_name = backend._ffi.string( + backend._binding._osrandom_engine_name + ) assert engine_name.read().encode('ascii') == osrandom_engine_name @@ -277,15 +277,14 @@ class TestOpenSSLRandomEngine(object): backend.activate_osrandom_engine() e = backend._lib.ENGINE_get_default_RAND() name = backend._lib.ENGINE_get_name(e) - assert (backend._ffi.string(name) == - backend._binding._osrandom_engine_name) + assert name == backend._binding._osrandom_engine_name res = backend._lib.ENGINE_free(e) assert res == 1 def test_activate_builtin_random(self): e = backend._lib.ENGINE_get_default_RAND() assert e != backend._ffi.NULL - name = backend._ffi.string(backend._lib.ENGINE_get_name(e)) + name = backend._lib.ENGINE_get_name(e) assert name == backend._binding._osrandom_engine_name res = backend._lib.ENGINE_free(e) assert res == 1 @@ -303,13 +302,13 @@ class TestOpenSSLRandomEngine(object): def test_activate_osrandom_already_default(self): e = backend._lib.ENGINE_get_default_RAND() - name = backend._ffi.string(backend._lib.ENGINE_get_name(e)) + name = backend._lib.ENGINE_get_name(e) assert name == backend._binding._osrandom_engine_name res = backend._lib.ENGINE_free(e) assert res == 1 backend.activate_osrandom_engine() e = backend._lib.ENGINE_get_default_RAND() - name = backend._ffi.string(backend._lib.ENGINE_get_name(e)) + name = backend._lib.ENGINE_get_name(e) assert name == backend._binding._osrandom_engine_name res = backend._lib.ENGINE_free(e) assert res == 1 -- cgit v1.2.3 From 79b291dcf6a263698d921b534d34bf63b5febfcf Mon Sep 17 00:00:00 2001 From: Glyph Date: Fri, 26 Jun 2015 23:12:09 -0700 Subject: lint --- src/cryptography/hazmat/bindings/openssl/binding.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index eda23959..35ea4979 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -44,6 +44,7 @@ class Binding(object): def _register_osrandom_engine(cls): if cls._retained: return 2 + def retain(it): cls._retained.append(it) return it -- cgit v1.2.3 From add79c02c102f2874974bdec727c9733a48685cc Mon Sep 17 00:00:00 2001 From: Glyph Date: Fri, 26 Jun 2015 23:17:06 -0700 Subject: comply with C coding standard, for which there is no linter --- src/_cffi_src/openssl/engine.py | 14 +++++++------- src/cryptography/hazmat/bindings/openssl/binding.py | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/_cffi_src/openssl/engine.py b/src/_cffi_src/openssl/engine.py index bc5c1906..821c9235 100644 --- a/src/_cffi_src/openssl/engine.py +++ b/src/_cffi_src/openssl/engine.py @@ -12,12 +12,12 @@ TYPES = """ static const long Cryptography_HAS_ENGINE_CRYPTODEV; struct rand_meth_st { - void (*seed)(const void *buf, int num); - int (*bytes)(unsigned char *buf, int num); - void (*cleanup)(void); - void (*add)(const void *buf, int num, double entropy); - int (*pseudorand)(unsigned char *buf, int num); - int (*status)(void); + void (*seed)(const void *, int); + int (*bytes)(unsigned char *, int); + void (*cleanup)(); + void (*add)(const void *, int, double); + int (*pseudorand)(unsigned char *, int); + int (*status)(); }; typedef ... ENGINE; @@ -28,7 +28,7 @@ typedef ... ECDSA_METHOD; typedef ... DH_METHOD; typedef struct rand_meth_st RAND_METHOD; typedef ... STORE_METHOD; -typedef int(*ENGINE_GEN_INT_FUNC_PTR)(ENGINE*); +typedef int (*ENGINE_GEN_INT_FUNC_PTR)(ENGINE *); typedef ... *ENGINE_CTRL_FUNC_PTR; typedef ... *ENGINE_LOAD_KEY_PTR; typedef ... *ENGINE_CIPHERS_PTR; diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index 35ea4979..f85429d8 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -53,7 +53,7 @@ class Binding(object): method.seed = cls.ffi.NULL @retain - @cls.ffi.callback("int (*)(unsigned char *buf, int num)", error=0) + @cls.ffi.callback("int (*)(unsigned char *, int)", error=0) def osrandom_rand_bytes(buf, size): signed = cls.ffi.cast("char*", buf) result = os.urandom(size) @@ -61,7 +61,7 @@ class Binding(object): return 1 @retain - @cls.ffi.callback("int (*)(unsigned char *buf, int num)", error=0) + @cls.ffi.callback("int (*)(unsigned char *, int)", error=0) def osrandom_pseudo_rand_bytes(buf, size): result = osrandom_rand_bytes(buf, size) if result == 0: -- cgit v1.2.3 From 28e7d80faff025e2fa90ea69813fc73332387c25 Mon Sep 17 00:00:00 2001 From: Glyph Date: Sat, 27 Jun 2015 15:13:12 -0700 Subject: don't need the intermediary 'struct' declaration. --- src/_cffi_src/openssl/engine.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/_cffi_src/openssl/engine.py b/src/_cffi_src/openssl/engine.py index 821c9235..5079fd69 100644 --- a/src/_cffi_src/openssl/engine.py +++ b/src/_cffi_src/openssl/engine.py @@ -11,22 +11,20 @@ INCLUDES = """ TYPES = """ static const long Cryptography_HAS_ENGINE_CRYPTODEV; -struct rand_meth_st { - void (*seed)(const void *, int); - int (*bytes)(unsigned char *, int); - void (*cleanup)(); - void (*add)(const void *, int, double); - int (*pseudorand)(unsigned char *, int); - int (*status)(); -}; - typedef ... ENGINE; typedef ... RSA_METHOD; typedef ... DSA_METHOD; typedef ... ECDH_METHOD; typedef ... ECDSA_METHOD; typedef ... DH_METHOD; -typedef struct rand_meth_st RAND_METHOD; +typedef struct { + void (*seed)(const void *, int); + int (*bytes)(unsigned char *, int); + void (*cleanup)(); + void (*add)(const void *, int, double); + int (*pseudorand)(unsigned char *, int); + int (*status)(); +} RAND_METHOD; typedef ... STORE_METHOD; typedef int (*ENGINE_GEN_INT_FUNC_PTR)(ENGINE *); typedef ... *ENGINE_CTRL_FUNC_PTR; -- cgit v1.2.3 From e03e9aaf17d70f7a891920d91ac8b79a30c64282 Mon Sep 17 00:00:00 2001 From: Glyph Date: Sat, 27 Jun 2015 15:13:43 -0700 Subject: move everything to module scope; much simpler that way --- .../hazmat/bindings/openssl/binding.py | 125 ++++++++++----------- 1 file changed, 58 insertions(+), 67 deletions(-) diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index f85429d8..17dad4c1 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -9,6 +9,58 @@ import threading from cryptography.hazmat.bindings._openssl import ffi, lib +_osrandom_engine_id = ffi.new("const char[]", b"osrandom") +_osrandom_engine_name = ffi.new("const char[]", b"osrandom_engine") + +@ffi.callback("int (*)(unsigned char *, int)", error=0) +def osrandom_rand_bytes(buf, size): + signed = ffi.cast("char*", buf) + result = os.urandom(size) + signed[0:size] = result + return 1 + + +@ffi.callback("int (*)(unsigned char *, int)", error=0) +def osrandom_pseudo_rand_bytes(buf, size): + result = osrandom_rand_bytes(buf, size) + if result == 0: + return -1 + else: + return result + + +@ffi.callback("int (*)(void)") +def osrandom_rand_status(): + return 1 + + +def _register_osrandom_engine(): + looked_up_engine = lib.ENGINE_by_id(_osrandom_engine_id) + if looked_up_engine != ffi.NULL: + return 2 + + method = ffi.new( + "RAND_METHOD*", dict(bytes=osrandom_rand_bytes, + pseudorand=osrandom_pseudo_rand_bytes, + status=osrandom_rand_status) + ) + engine = lib.ENGINE_new() + try: + result = lib.ENGINE_set_id(engine, _osrandom_engine_id) + assert result == 1 + result = lib.ENGINE_set_name(engine, _osrandom_engine_name) + assert result == 1 + result = lib.ENGINE_set_RAND(engine, method) + assert result == 1 + result = lib.ENGINE_add(engine) + assert result == 1 + finally: + result = lib.ENGINE_free(engine) + assert result == 1 + looked_up_engine = lib.ENGINE_by_id(_osrandom_engine_id) + assert looked_up_engine != ffi.NULL + return 1 + class Binding(object): """ @@ -22,9 +74,11 @@ class Binding(object): _rand_method = None _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") - _retained = [] + + # aliases for the convenience of tests. + _osrandom_engine_id = _osrandom_engine_id + _osrandom_engine_name = _osrandom_engine_name + _register_osrandom_engine = staticmethod(_register_osrandom_engine) def __init__(self): self._ensure_ffi_initialized() @@ -37,70 +91,7 @@ class Binding(object): with cls._init_lock: if not cls._lib_loaded: cls._lib_loaded = True - res = cls._register_osrandom_engine() - assert res != 0 - - @classmethod - def _register_osrandom_engine(cls): - if cls._retained: - return 2 - - def retain(it): - cls._retained.append(it) - return it - method = cls.ffi.new("RAND_METHOD*") - retain(method) - method.seed = cls.ffi.NULL - - @retain - @cls.ffi.callback("int (*)(unsigned char *, int)", error=0) - def osrandom_rand_bytes(buf, size): - signed = cls.ffi.cast("char*", buf) - result = os.urandom(size) - signed[0:size] = result - return 1 - - @retain - @cls.ffi.callback("int (*)(unsigned char *, int)", error=0) - def osrandom_pseudo_rand_bytes(buf, size): - result = osrandom_rand_bytes(buf, size) - if result == 0: - return -1 - else: - return result - - @retain - @cls.ffi.callback("int (*)(void)", error=0) - def osrandom_rand_status(): - return 1 - - @retain - @cls.ffi.callback("ENGINE_GEN_INT_FUNC_PTR", error=0) - def osrandom_init(engine): - return 1 - - @retain - @cls.ffi.callback("ENGINE_GEN_INT_FUNC_PTR", error=0) - def osrandom_finish(engine): - return 1 - - method.bytes = osrandom_rand_bytes - method.cleanup = cls.ffi.NULL - method.add = cls.ffi.NULL - method.pseudorand = osrandom_pseudo_rand_bytes - method.status = osrandom_rand_status - - e = cls.lib.ENGINE_new() - result = (cls.lib.ENGINE_set_id(e, cls._osrandom_engine_id) - and cls.lib.ENGINE_set_name(e, cls._osrandom_engine_name) - and cls.lib.ENGINE_set_RAND(e, method) - and cls.lib.ENGINE_set_init_function(e, osrandom_init) - and cls.lib.ENGINE_set_finish_function(e, osrandom_finish) - and cls.lib.ENGINE_add(e)) - if not cls.lib.ENGINE_free(e): - return 0 - assert cls.lib.ENGINE_by_id(cls._osrandom_engine_id) != cls.ffi.NULL - return result + _register_osrandom_engine() @classmethod def init_static_locks(cls): -- cgit v1.2.3 From dd53a5b216ac45620e7eee0c5a70e9dbfa33d08d Mon Sep 17 00:00:00 2001 From: Glyph Date: Sat, 27 Jun 2015 15:16:25 -0700 Subject: also retain method with a global reference --- src/cryptography/hazmat/bindings/openssl/binding.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index 17dad4c1..d3999959 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -34,16 +34,18 @@ def osrandom_rand_status(): return 1 +method = ffi.new( + "RAND_METHOD*", dict(bytes=osrandom_rand_bytes, + pseudorand=osrandom_pseudo_rand_bytes, + status=osrandom_rand_status) +) + + def _register_osrandom_engine(): looked_up_engine = lib.ENGINE_by_id(_osrandom_engine_id) if looked_up_engine != ffi.NULL: return 2 - method = ffi.new( - "RAND_METHOD*", dict(bytes=osrandom_rand_bytes, - pseudorand=osrandom_pseudo_rand_bytes, - status=osrandom_rand_status) - ) engine = lib.ENGINE_new() try: result = lib.ENGINE_set_id(engine, _osrandom_engine_id) -- cgit v1.2.3 From 885d688aae732042034fed4c7cab5dd6a70c6c26 Mon Sep 17 00:00:00 2001 From: Glyph Date: Sat, 27 Jun 2015 15:40:52 -0700 Subject: bind ERR_clear_error --- src/_cffi_src/openssl/err.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/_cffi_src/openssl/err.py b/src/_cffi_src/openssl/err.py index 0ee19c9e..eebf19ba 100644 --- a/src/_cffi_src/openssl/err.py +++ b/src/_cffi_src/openssl/err.py @@ -251,6 +251,7 @@ unsigned long ERR_peek_error_line(const char **, int *); unsigned long ERR_peek_last_error_line(const char **, int *); unsigned long ERR_get_error_line_data(const char **, int *, const char **, int *); +void ERR_clear_error(void); unsigned long ERR_peek_error_line_data(const char **, int *, const char **, int *); unsigned long ERR_peek_last_error_line_data(const char **, -- cgit v1.2.3 From c1d04467fdc58e4f97e7768f77706ac4c8099c42 Mon Sep 17 00:00:00 2001 From: Glyph Date: Sat, 27 Jun 2015 15:41:08 -0700 Subject: clear the error queue make sure we're not in an error state when we start, because then all bets are off and we might consume an error we didn't cause. then clear the error queue, which restores the behavior of the way the C module was previously checking for existence of its engine. --- src/cryptography/hazmat/bindings/openssl/binding.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index d3999959..1fb7478d 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -42,10 +42,14 @@ method = ffi.new( def _register_osrandom_engine(): + assert lib.ERR_peek_error() == 0 looked_up_engine = lib.ENGINE_by_id(_osrandom_engine_id) if looked_up_engine != ffi.NULL: + assert lib.ERR_peek_error() == 0 return 2 + lib.ERR_clear_error() + engine = lib.ENGINE_new() try: result = lib.ENGINE_set_id(engine, _osrandom_engine_id) -- cgit v1.2.3 From 4e9b7d852e79769c2d51396ed747f63b85cefb29 Mon Sep 17 00:00:00 2001 From: Glyph Date: Sat, 27 Jun 2015 18:33:27 -0700 Subject: coding standard --- src/cryptography/hazmat/bindings/openssl/binding.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index 1fb7478d..27c70745 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -12,9 +12,10 @@ from cryptography.hazmat.bindings._openssl import ffi, lib _osrandom_engine_id = ffi.new("const char[]", b"osrandom") _osrandom_engine_name = ffi.new("const char[]", b"osrandom_engine") + @ffi.callback("int (*)(unsigned char *, int)", error=0) def osrandom_rand_bytes(buf, size): - signed = ffi.cast("char*", buf) + signed = ffi.cast("char *", buf) result = os.urandom(size) signed[0:size] = result return 1 -- cgit v1.2.3 From eb8059d7bd4abc11a14bdf149812057d505a2685 Mon Sep 17 00:00:00 2001 From: Glyph Date: Sat, 27 Jun 2015 18:38:02 -0700 Subject: unnecessary belt-and-suspenders error checking --- src/cryptography/hazmat/bindings/openssl/binding.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index 27c70745..727522a3 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -64,8 +64,6 @@ def _register_osrandom_engine(): finally: result = lib.ENGINE_free(engine) assert result == 1 - looked_up_engine = lib.ENGINE_by_id(_osrandom_engine_id) - assert looked_up_engine != ffi.NULL return 1 -- cgit v1.2.3 From 1e3ffe10719ef8eeeda0df79aa3e708400f7028a Mon Sep 17 00:00:00 2001 From: Glyph Date: Sat, 27 Jun 2015 18:41:16 -0700 Subject: handle previous registration by raising RuntimeError --- src/cryptography/hazmat/bindings/openssl/binding.py | 4 +--- tests/hazmat/bindings/test_openssl.py | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index 727522a3..be9904a2 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -46,8 +46,7 @@ def _register_osrandom_engine(): assert lib.ERR_peek_error() == 0 looked_up_engine = lib.ENGINE_by_id(_osrandom_engine_id) if looked_up_engine != ffi.NULL: - assert lib.ERR_peek_error() == 0 - return 2 + raise RuntimeError("osrandom engine already registered") lib.ERR_clear_error() @@ -64,7 +63,6 @@ def _register_osrandom_engine(): finally: result = lib.ENGINE_free(engine) assert result == 1 - return 1 class Binding(object): diff --git a/tests/hazmat/bindings/test_openssl.py b/tests/hazmat/bindings/test_openssl.py index fe78b0ba..75a8e3f1 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() - res = b._register_osrandom_engine() - assert res == 2 + with pytest.raises(RuntimeError): + b._register_osrandom_engine() def test_ssl_ctx_options(self): # Test that we're properly handling 32-bit unsigned on all platforms. -- cgit v1.2.3 From 3abff3a85ce23577e914b2132795ae1b0ff0a684 Mon Sep 17 00:00:00 2001 From: Glyph Date: Sat, 27 Jun 2015 18:43:45 -0700 Subject: nothing pseudo about it --- src/cryptography/hazmat/bindings/openssl/binding.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index be9904a2..dd26fe1b 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -13,7 +13,7 @@ _osrandom_engine_id = ffi.new("const char[]", b"osrandom") _osrandom_engine_name = ffi.new("const char[]", b"osrandom_engine") -@ffi.callback("int (*)(unsigned char *, int)", error=0) +@ffi.callback("int (*)(unsigned char *, int)", error=-1) def osrandom_rand_bytes(buf, size): signed = ffi.cast("char *", buf) result = os.urandom(size) @@ -21,15 +21,6 @@ def osrandom_rand_bytes(buf, size): return 1 -@ffi.callback("int (*)(unsigned char *, int)", error=0) -def osrandom_pseudo_rand_bytes(buf, size): - result = osrandom_rand_bytes(buf, size) - if result == 0: - return -1 - else: - return result - - @ffi.callback("int (*)(void)") def osrandom_rand_status(): return 1 @@ -37,7 +28,7 @@ def osrandom_rand_status(): method = ffi.new( "RAND_METHOD*", dict(bytes=osrandom_rand_bytes, - pseudorand=osrandom_pseudo_rand_bytes, + pseudorand=osrandom_rand_bytes, status=osrandom_rand_status) ) -- cgit v1.2.3 From 3c7164a9528b0058721d139adc4da89c2efe2936 Mon Sep 17 00:00:00 2001 From: Glyph Date: Sat, 27 Jun 2015 18:48:51 -0700 Subject: space before star --- src/cryptography/hazmat/bindings/openssl/binding.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index dd26fe1b..9ceabf48 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -27,9 +27,9 @@ def osrandom_rand_status(): method = ffi.new( - "RAND_METHOD*", dict(bytes=osrandom_rand_bytes, - pseudorand=osrandom_rand_bytes, - status=osrandom_rand_status) + "RAND_METHOD *", + dict(bytes=osrandom_rand_bytes, pseudorand=osrandom_rand_bytes, + status=osrandom_rand_status) ) -- cgit v1.2.3 From 678e5e336efa0acc4c69854439c804b9c7a6fcdc Mon Sep 17 00:00:00 2001 From: Glyph Date: Sat, 27 Jun 2015 18:50:34 -0700 Subject: consistency about underscores and prefixes --- src/cryptography/hazmat/bindings/openssl/binding.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index 9ceabf48..b885017a 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -14,7 +14,7 @@ _osrandom_engine_name = ffi.new("const char[]", b"osrandom_engine") @ffi.callback("int (*)(unsigned char *, int)", error=-1) -def osrandom_rand_bytes(buf, size): +def _osrandom_rand_bytes(buf, size): signed = ffi.cast("char *", buf) result = os.urandom(size) signed[0:size] = result @@ -22,14 +22,14 @@ def osrandom_rand_bytes(buf, size): @ffi.callback("int (*)(void)") -def osrandom_rand_status(): +def _osrandom_rand_status(): return 1 -method = ffi.new( +_osrandom_method = ffi.new( "RAND_METHOD *", - dict(bytes=osrandom_rand_bytes, pseudorand=osrandom_rand_bytes, - status=osrandom_rand_status) + dict(bytes=_osrandom_rand_bytes, pseudorand=_osrandom_rand_bytes, + status=_osrandom_rand_status) ) @@ -47,7 +47,7 @@ def _register_osrandom_engine(): assert result == 1 result = lib.ENGINE_set_name(engine, _osrandom_engine_name) assert result == 1 - result = lib.ENGINE_set_RAND(engine, method) + result = lib.ENGINE_set_RAND(engine, _osrandom_method) assert result == 1 result = lib.ENGINE_add(engine) assert result == 1 -- cgit v1.2.3 From 3af7e26efa2903c6c194a1cc30aafa521c2c5ac7 Mon Sep 17 00:00:00 2001 From: Glyph Date: Sat, 27 Jun 2015 18:53:44 -0700 Subject: dead code --- src/cryptography/hazmat/bindings/openssl/binding.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index b885017a..3df423dd 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -65,7 +65,6 @@ class Binding(object): _lib_loaded = False _locks = None _lock_cb_handle = None - _rand_method = None _init_lock = threading.Lock() _lock_init_lock = threading.Lock() -- cgit v1.2.3 From 9ad8a9443323c6702bc3e7a4d0afe0c4d400ab84 Mon Sep 17 00:00:00 2001 From: Glyph Date: Sat, 27 Jun 2015 19:03:34 -0700 Subject: shuffle everything back onto the class --- .../hazmat/bindings/openssl/binding.py | 95 ++++++++++------------ 1 file changed, 45 insertions(+), 50 deletions(-) diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index 3df423dd..aa072b4c 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -9,52 +9,6 @@ import threading from cryptography.hazmat.bindings._openssl import ffi, lib -_osrandom_engine_id = ffi.new("const char[]", b"osrandom") -_osrandom_engine_name = ffi.new("const char[]", b"osrandom_engine") - - -@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 - - -_osrandom_method = ffi.new( - "RAND_METHOD *", - dict(bytes=_osrandom_rand_bytes, pseudorand=_osrandom_rand_bytes, - status=_osrandom_rand_status) -) - - -def _register_osrandom_engine(): - assert lib.ERR_peek_error() == 0 - looked_up_engine = lib.ENGINE_by_id(_osrandom_engine_id) - if looked_up_engine != ffi.NULL: - raise RuntimeError("osrandom engine already registered") - - lib.ERR_clear_error() - - engine = lib.ENGINE_new() - try: - result = lib.ENGINE_set_id(engine, _osrandom_engine_id) - assert result == 1 - result = lib.ENGINE_set_name(engine, _osrandom_engine_name) - assert result == 1 - result = lib.ENGINE_set_RAND(engine, _osrandom_method) - assert result == 1 - result = lib.ENGINE_add(engine) - assert result == 1 - finally: - result = lib.ENGINE_free(engine) - assert result == 1 - class Binding(object): """ @@ -69,13 +23,54 @@ class Binding(object): _lock_init_lock = threading.Lock() # aliases for the convenience of tests. - _osrandom_engine_id = _osrandom_engine_id - _osrandom_engine_name = _osrandom_engine_name - _register_osrandom_engine = staticmethod(_register_osrandom_engine) + _osrandom_engine_id = ffi.new("const char[]", b"osrandom") + _osrandom_engine_name = ffi.new("const char[]", b"osrandom_engine") def __init__(self): self._ensure_ffi_initialized() + @ffi.callback("int (*)(unsigned char *, int)", error=-1) + @staticmethod + 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)") + @staticmethod + def _osrandom_rand_status(): + return 1 + + _osrandom_method = ffi.new( + "RAND_METHOD *", + dict(bytes=_osrandom_rand_bytes, pseudorand=_osrandom_rand_bytes, + status=_osrandom_rand_status) + ) + + @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() + 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: @@ -84,7 +79,7 @@ class Binding(object): with cls._init_lock: if not cls._lib_loaded: cls._lib_loaded = True - _register_osrandom_engine() + cls._register_osrandom_engine() @classmethod def init_static_locks(cls): -- cgit v1.2.3 From 9f6d7b53470f19410aaf9cbeca773cc2f582a546 Mon Sep 17 00:00:00 2001 From: Glyph Date: Sat, 27 Jun 2015 19:06:17 -0700 Subject: do the hokey pokey you put the functions in, you take the functions out, you make the linter work, and you shake it all about --- .../hazmat/bindings/openssl/binding.py | 26 +++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index aa072b4c..7943962f 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -10,6 +10,19 @@ 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. @@ -29,19 +42,6 @@ class Binding(object): def __init__(self): self._ensure_ffi_initialized() - @ffi.callback("int (*)(unsigned char *, int)", error=-1) - @staticmethod - 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)") - @staticmethod - def _osrandom_rand_status(): - return 1 - _osrandom_method = ffi.new( "RAND_METHOD *", dict(bytes=_osrandom_rand_bytes, pseudorand=_osrandom_rand_bytes, -- cgit v1.2.3 From 60b6b884ce0c1c7ad90de65bc7539459bda332a4 Mon Sep 17 00:00:00 2001 From: Glyph Date: Sat, 27 Jun 2015 19:10:39 -0700 Subject: comment on longer correct - not aliases any more also group all the class-level variables together for style points --- src/cryptography/hazmat/bindings/openssl/binding.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index 7943962f..5aa731e4 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -35,19 +35,17 @@ class Binding(object): _init_lock = threading.Lock() _lock_init_lock = threading.Lock() - # aliases for the convenience of tests. _osrandom_engine_id = ffi.new("const char[]", b"osrandom") _osrandom_engine_name = ffi.new("const char[]", b"osrandom_engine") - - def __init__(self): - self._ensure_ffi_initialized() - _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 -- cgit v1.2.3 From b7c6aafe2eb8c9684e5ffd69380e0f831c430fd9 Mon Sep 17 00:00:00 2001 From: Glyph Date: Sat, 27 Jun 2015 20:36:35 -0700 Subject: the assertier the merrier --- src/cryptography/hazmat/bindings/openssl/binding.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index 5aa731e4..b7178bb2 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -56,6 +56,7 @@ class Binding(object): 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 -- cgit v1.2.3 From 32c261c8a834bdcafe60bd1b5e4e886b8f9c4fb1 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Wed, 8 Oct 2014 00:12:38 -0400 Subject: Switch to codecov.io from coveralls --- .travis.yml | 2 +- .travis/install.sh | 2 +- README.rst | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 76decf62..10883cb9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -120,7 +120,7 @@ script: - ./.travis/run.sh after_success: - - source ~/.venv/bin/activate && coveralls + - source ~/.venv/bin/activate && codecov --env TRAVIS_OS_NAME TOXENV OPENSSL notifications: irc: diff --git a/.travis/install.sh b/.travis/install.sh index a046a5d8..17aee435 100755 --- a/.travis/install.sh +++ b/.travis/install.sh @@ -65,4 +65,4 @@ fi python -m virtualenv ~/.venv source ~/.venv/bin/activate -pip install tox coveralls +pip install tox codecov diff --git a/README.rst b/README.rst index 98e8d17e..949826e6 100644 --- a/README.rst +++ b/README.rst @@ -12,8 +12,8 @@ Cryptography .. image:: https://travis-ci.org/pyca/cryptography.svg?branch=master :target: https://travis-ci.org/pyca/cryptography -.. image:: https://img.shields.io/coveralls/pyca/cryptography/master.svg - :target: https://coveralls.io/r/pyca/cryptography?branch=master +.. image:: https://codecov.io/github/pyca/cryptography/coverage.svg?branch=master + :target: https://codecov.io/github/pyca/cryptography?branch=master ``cryptography`` is a package which provides cryptographic recipes and -- cgit v1.2.3 From d8f302f636f214e4397db74e9bf43f8ad0cb8da4 Mon Sep 17 00:00:00 2001 From: Steve Peak Date: Fri, 26 Jun 2015 20:25:59 -0400 Subject: Testing codecov/support#43 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 10883cb9..3ce73cbd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -120,7 +120,7 @@ script: - ./.travis/run.sh after_success: - - source ~/.venv/bin/activate && codecov --env TRAVIS_OS_NAME TOXENV OPENSSL + - source ~/.venv/bin/activate && bash <(curl -s https://raw.githubusercontent.com/codecov/codecov-bash/coveragepy/codecov) -e TRAVIS_OS_NAME,TOXENV,OPENSSL notifications: irc: -- cgit v1.2.3 From 7155c984e66580b12acc9fbeb9775406c6eccb11 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 29 Jun 2015 07:53:54 -0500 Subject: add more basic name constraints vector --- docs/development/test-vectors.rst | 10 +++++++++- .../x509/custom/nc_permitted_2.pem | 18 ++++++++++++++++++ .../x509/custom/nc_permitted_excluded_2.pem | 18 ++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 vectors/cryptography_vectors/x509/custom/nc_permitted_2.pem create mode 100644 vectors/cryptography_vectors/x509/custom/nc_permitted_excluded_2.pem diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst index ac667bb7..ca07547c 100644 --- a/docs/development/test-vectors.rst +++ b/docs/development/test-vectors.rst @@ -199,9 +199,17 @@ Custom X.509 Vectors set. * ``nc_permitted_excluded.pem`` - An RSA 2048 bit self-signed certificate containing a name constraints extension with both permitted and excluded - elements. + elements. Contains ``IPv4`` and ``IPv6`` addresses with network mask as well + as ``dNSName`` with a leading period. +* ``nc_permitted_excluded_2.pem`` - An RSA 2048 bit self-signed certificate + containing a name constraints extension with both permitted and excluded + elements. Unlike ``nc_permitted_excluded.pem``, the general names do not + contain any name constraints specific values. * ``nc_permitted.pem`` - An RSA 2048 bit self-signed certificate containing a name constraints extension with permitted elements. +* ``nc_permitted_2.pem`` - An RSA 2048 bit self-signed certificate containing a + name constraints extension with permitted elements that do not contain any + name constraints specific values. * ``nc_excluded.pem`` - An RSA 2048 bit self-signed certificate containing a name constraints extension with excluded elements. * ``nc_invalid_ip_netmask.pem`` - An RSA 2048 bit self-signed certificate diff --git a/vectors/cryptography_vectors/x509/custom/nc_permitted_2.pem b/vectors/cryptography_vectors/x509/custom/nc_permitted_2.pem new file mode 100644 index 00000000..05a904f5 --- /dev/null +++ b/vectors/cryptography_vectors/x509/custom/nc_permitted_2.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3DCCAcSgAwIBAgITBm/6kAXHpw8f3guDBcRXNLfl5DANBgkqhkiG9w0BAQsF +ADAXMRUwEwYDVQQDDAxjcnlwdG9ncmFwaHkwHhcNMTUwNjI5MDkzMjQ5WhcNMTYw +NjI4MDkzMjQ5WjAXMRUwEwYDVQQDDAxjcnlwdG9ncmFwaHkwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCylTa0WkLvIXB4sWoPdv5iL3idlVHKR+ncODKL +nwQ2Jtd990MfakOFRLrJFF1tfPL4qyRbbyMyrgCOoKBCAuIdBZfBDH3JWFjxGy8J +Yls8yVeAVKreV18HmLvAsBL3bnr7Gk3vpznrfoG5rn5T/fL0cqqTXFV8zQhjHiEo +zftSaoq0LOxsSgFdxXS8e8K6RMvLCZPcMpI4fo1Kq2QBT2J1x1/Hq/VnK132cs0g +TOyiTyyJfvRmlqdXowh7Jf8LQB4mM6gc023fEdQ+HH6JYX1vDQVxaiTM6KMYJNv/ +l4gchP3jknOfZffwGGdXQrtUMhQmltnSqV5nY/G2OGm/Z0pdAgMBAAGjITAfMB0G +A1UdHgEB/wQTMBGgDzANggt6b21iby5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEA +WcDkqLUsvIBfTzKncOSiy08lcwu+kq/8rybh4HoHEimcy47M+XLPnXqwA7jedz8M +Znog64O9wZ1olWs+GGrGcJAth2BqdNtRvb6/o2Hq29vNbCQeYRlOTdNzGnb5v6fB +HEPvuB7UNKyaJ2tF50oxqhg8ojgauX3fuanCtR9Obx/2U8e8zfBIauX13XfpoCyt +efeL97kYz+XIQwG8TvXpNdHO0QjmA/ToR7E5BbSo2e4cicKEomtLhKI7EXa+Ofwg +HoyVC8wl97nm7mwI7iFYK5f8YoqwILxKEP6O9+pZEOveqdKfx4+WAgeGyDvBwAjf +Ej8vkawtdgV/96ajsIqzDQ== +-----END CERTIFICATE----- diff --git a/vectors/cryptography_vectors/x509/custom/nc_permitted_excluded_2.pem b/vectors/cryptography_vectors/x509/custom/nc_permitted_excluded_2.pem new file mode 100644 index 00000000..2cdf1d68 --- /dev/null +++ b/vectors/cryptography_vectors/x509/custom/nc_permitted_excluded_2.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC9DCCAdygAwIBAgITBm/3q66sET2C+Ko/TLr1EHnvdTANBgkqhkiG9w0BAQsF +ADAXMRUwEwYDVQQDDAxjcnlwdG9ncmFwaHkwHhcNMTUwNjI5MDY0ODQ4WhcNMTYw +NjI4MDY0ODQ4WjAXMRUwEwYDVQQDDAxjcnlwdG9ncmFwaHkwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCylTa0WkLvIXB4sWoPdv5iL3idlVHKR+ncODKL +nwQ2Jtd990MfakOFRLrJFF1tfPL4qyRbbyMyrgCOoKBCAuIdBZfBDH3JWFjxGy8J +Yls8yVeAVKreV18HmLvAsBL3bnr7Gk3vpznrfoG5rn5T/fL0cqqTXFV8zQhjHiEo +zftSaoq0LOxsSgFdxXS8e8K6RMvLCZPcMpI4fo1Kq2QBT2J1x1/Hq/VnK132cs0g +TOyiTyyJfvRmlqdXowh7Jf8LQB4mM6gc023fEdQ+HH6JYX1vDQVxaiTM6KMYJNv/ +l4gchP3jknOfZffwGGdXQrtUMhQmltnSqV5nY/G2OGm/Z0pdAgMBAAGjOTA3MDUG +A1UdHgEB/wQrMCmgDzANggt6b21iby5sb2NhbKEWMBSkEjAQMQ4wDAYDVQQDDAV6 +b21ibzANBgkqhkiG9w0BAQsFAAOCAQEAaSyuJlNVZkkwHn4V9EglOTm6DC/lzrLm +1y/qcXsY2NXgCRfpZal0lx25M7Dl2G1IOBG+Ub1/ua0NASlpd6BeZ4prmcD4OBib +oAhMJxt8QNNwkcMG5PnI6reQz5MiRwGOCEAZeX1opIijn/tO49RliEnEQCKbsvdr +d+0ieNhLdoxazW/k3UCu+Vdd1b3TOLERrhm/xGj2W9AhWAv7GIovhBGGfuD6BFmC +uHjxoG0So//NiHTfZ9eukgW3rNSbjQjtnC8BsRzUdhX/YBvw+SKkeVL2oz7+lRgD +fhba3FtwUfCIX3y/UAc0E0+x9bLFDyQXYNHAXq+q72sOkLXgAH8bfQ== +-----END CERTIFICATE----- -- cgit v1.2.3 From 0aac590759ac202d6758d6fcb319e33dcf2c6c78 Mon Sep 17 00:00:00 2001 From: Steve Peak Date: Mon, 29 Jun 2015 17:46:59 -0400 Subject: Fix is now formally available --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3ce73cbd..8ad514fd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -120,7 +120,7 @@ script: - ./.travis/run.sh after_success: - - source ~/.venv/bin/activate && bash <(curl -s https://raw.githubusercontent.com/codecov/codecov-bash/coveragepy/codecov) -e TRAVIS_OS_NAME,TOXENV,OPENSSL + - source ~/.venv/bin/activate && bash <(curl -s https://codecov.io/bash) -e TRAVIS_OS_NAME,TOXENV,OPENSSL notifications: irc: -- cgit v1.2.3 From 870d7e8986e38aba6bbd6d89a3e0f49dad25ae93 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 21 Jun 2015 22:20:44 -0500 Subject: support name constraints in the openssl backend --- src/cryptography/hazmat/backends/openssl/x509.py | 30 ++++++++++++++++ tests/test_x509_ext.py | 44 ++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index cc805755..41258483 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -537,6 +537,35 @@ def _decode_issuer_alt_name(backend, ext): ) +def _decode_name_constraints(backend, ext): + nc = backend._ffi.cast( + "NAME_CONSTRAINTS *", backend._lib.X509V3_EXT_d2i(ext) + ) + assert nc != backend._ffi.NULL + nc = backend._ffi.gc(nc, backend._lib.NAME_CONSTRAINTS_free) + permitted = _decode_general_subtrees(backend, nc.permittedSubtrees) + excluded = _decode_general_subtrees(backend, nc.excludedSubtrees) + return x509.NameConstraints( + permitted_subtrees=permitted, excluded_subtrees=excluded + ) + + +def _decode_general_subtrees(backend, stack_subtrees): + if stack_subtrees == backend._ffi.NULL: + return None + + num = backend._lib.sk_GENERAL_SUBTREE_num(stack_subtrees) + subtrees = [] + + for i in range(num): + obj = backend._lib.sk_GENERAL_SUBTREE_value(stack_subtrees, i) + assert obj != backend._ffi.NULL + name = _decode_general_name(backend, obj.base) + subtrees.append(name) + + return subtrees + + def _decode_extended_key_usage(backend, ext): sk = backend._ffi.cast( "Cryptography_STACK_OF_ASN1_OBJECT *", @@ -728,6 +757,7 @@ _CERTIFICATE_EXTENSION_PARSER = _X509ExtensionParser( x509.OID_OCSP_NO_CHECK: _decode_ocsp_no_check, x509.OID_INHIBIT_ANY_POLICY: _decode_inhibit_any_policy, x509.OID_ISSUER_ALTERNATIVE_NAME: _decode_issuer_alt_name, + x509.OID_NAME_CONSTRAINTS: _decode_name_constraints, } ) diff --git a/tests/test_x509_ext.py b/tests/test_x509_ext.py index 6d91ba41..15ee118a 100644 --- a/tests/test_x509_ext.py +++ b/tests/test_x509_ext.py @@ -2033,6 +2033,50 @@ class TestNameConstraints(object): assert nc != object() +@pytest.mark.requires_backend_interface(interface=RSABackend) +@pytest.mark.requires_backend_interface(interface=X509Backend) +class TestNameConstraintsExtension(object): + def test_permitted_excluded(self, backend): + cert = _load_cert( + os.path.join( + "x509", "custom", "nc_permitted_excluded_2.pem" + ), + x509.load_pem_x509_certificate, + backend + ) + nc = cert.extensions.get_extension_for_oid( + x509.OID_NAME_CONSTRAINTS + ).value + assert nc == x509.NameConstraints( + permitted_subtrees=[ + x509.DNSName(u"zombo.local"), + ], + excluded_subtrees=[ + x509.DirectoryName(x509.Name([ + x509.NameAttribute(x509.OID_COMMON_NAME, u"zombo") + ])) + ] + ) + + def test_permitted(self, backend): + cert = _load_cert( + os.path.join( + "x509", "custom", "nc_permitted_2.pem" + ), + x509.load_pem_x509_certificate, + backend + ) + nc = cert.extensions.get_extension_for_oid( + x509.OID_NAME_CONSTRAINTS + ).value + assert nc == x509.NameConstraints( + permitted_subtrees=[ + x509.DNSName(u"zombo.local"), + ], + excluded_subtrees=None + ) + + class TestDistributionPoint(object): def test_distribution_point_full_name_not_general_names(self): with pytest.raises(TypeError): -- cgit v1.2.3 From 7c3e7a83f06b0ff8f0c27a4486eaa6448ba6485e Mon Sep 17 00:00:00 2001 From: Glyph Date: Mon, 29 Jun 2015 17:21:02 -0700 Subject: the output of RAND_bytes is os.urandom's result --- tests/hazmat/bindings/test_openssl.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/hazmat/bindings/test_openssl.py b/tests/hazmat/bindings/test_openssl.py index 75a8e3f1..207fece9 100644 --- a/tests/hazmat/bindings/test_openssl.py +++ b/tests/hazmat/bindings/test_openssl.py @@ -4,6 +4,8 @@ from __future__ import absolute_import, division, print_function +import os + import pytest from cryptography.hazmat.bindings.openssl.binding import Binding @@ -92,6 +94,18 @@ class TestOpenSSL(object): with pytest.raises(RuntimeError): b._register_osrandom_engine() + def test_actual_osrandom_bytes(self, monkeypatch): + sample_data = (b"\x01\x02\x03\x04" * 4) + length = len(sample_data) + def notrandom(size): + assert size == length + return sample_data + monkeypatch.setattr(os, "urandom", notrandom) + b = Binding() + buf = b.ffi.new("char[]", length) + b.lib.RAND_bytes(buf, length) + assert b.ffi.buffer(buf)[0:length] == sample_data + def test_ssl_ctx_options(self): # Test that we're properly handling 32-bit unsigned on all platforms. b = Binding() -- cgit v1.2.3 From 14e67ac4241a20c25f0d7751171c8b626f014e45 Mon Sep 17 00:00:00 2001 From: Glyph Date: Tue, 30 Jun 2015 01:46:38 -0700 Subject: Detect and ignore LibreSSL. --- tests/hazmat/bindings/test_openssl.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/hazmat/bindings/test_openssl.py b/tests/hazmat/bindings/test_openssl.py index 207fece9..73952561 100644 --- a/tests/hazmat/bindings/test_openssl.py +++ b/tests/hazmat/bindings/test_openssl.py @@ -95,13 +95,15 @@ class TestOpenSSL(object): b._register_osrandom_engine() def test_actual_osrandom_bytes(self, monkeypatch): + b = Binding() + if b'LibreSSL' in b.ffi.string(b.lib.OPENSSL_VERSION_TEXT): + pytest.skip("LibreSSL hard-codes RAND_bytes to use arc4random.") sample_data = (b"\x01\x02\x03\x04" * 4) length = len(sample_data) def notrandom(size): assert size == length return sample_data monkeypatch.setattr(os, "urandom", notrandom) - b = Binding() buf = b.ffi.new("char[]", length) b.lib.RAND_bytes(buf, length) assert b.ffi.buffer(buf)[0:length] == sample_data -- cgit v1.2.3 From fa40f9f1b42b27d0f0e3f7581cf8d1997e36f0b0 Mon Sep 17 00:00:00 2001 From: Glyph Date: Tue, 30 Jun 2015 01:57:02 -0700 Subject: pep8 --- tests/hazmat/bindings/test_openssl.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/hazmat/bindings/test_openssl.py b/tests/hazmat/bindings/test_openssl.py index 73952561..ff8bcca6 100644 --- a/tests/hazmat/bindings/test_openssl.py +++ b/tests/hazmat/bindings/test_openssl.py @@ -100,6 +100,7 @@ class TestOpenSSL(object): pytest.skip("LibreSSL hard-codes RAND_bytes to use arc4random.") sample_data = (b"\x01\x02\x03\x04" * 4) length = len(sample_data) + def notrandom(size): assert size == length return sample_data -- cgit v1.2.3 From b18fc3912682d39ba5a4addfab963e50736e689c Mon Sep 17 00:00:00 2001 From: Glyph Date: Tue, 30 Jun 2015 16:46:29 -0700 Subject: test libressl when there is no libressl --- tests/hazmat/bindings/test_openssl.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/tests/hazmat/bindings/test_openssl.py b/tests/hazmat/bindings/test_openssl.py index ff8bcca6..f3f2eaf4 100644 --- a/tests/hazmat/bindings/test_openssl.py +++ b/tests/hazmat/bindings/test_openssl.py @@ -11,6 +11,20 @@ import pytest from cryptography.hazmat.bindings.openssl.binding import Binding +def skip_if_libre_ssl(openssl_version): + if b'LibreSSL' in openssl_version: + pytest.skip("LibreSSL hard-codes RAND_bytes to use arc4random.") + + +class TestLibreSkip(object): + def test_skip_no(self): + assert skip_if_libre_ssl(b"OpenSSL 0.9.8zf 19 Mar 2015") is None + + def test_skip_yes(self): + with pytest.raises(pytest.skip.Exception): + skip_if_libre_ssl(b"LibreSSL 2.1.6") + + class TestOpenSSL(object): def test_binding_loads(self): binding = Binding() @@ -96,8 +110,7 @@ class TestOpenSSL(object): def test_actual_osrandom_bytes(self, monkeypatch): b = Binding() - if b'LibreSSL' in b.ffi.string(b.lib.OPENSSL_VERSION_TEXT): - pytest.skip("LibreSSL hard-codes RAND_bytes to use arc4random.") + skip_if_libre_ssl(b.ffi.string(b.lib.OPENSSL_VERSION_TEXT)) sample_data = (b"\x01\x02\x03\x04" * 4) length = len(sample_data) -- cgit v1.2.3 From b073c8cd31f27af8002174999904556ec283ac7e Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 1 Jul 2015 19:55:07 -0500 Subject: put the AAD and encrypted byte limit checks in the parent context --- src/cryptography/hazmat/primitives/ciphers/base.py | 19 ++++++++++++++ .../hazmat/primitives/ciphers/modes.py | 2 ++ tests/hazmat/primitives/test_aes.py | 30 ++++++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/src/cryptography/hazmat/primitives/ciphers/base.py b/src/cryptography/hazmat/primitives/ciphers/base.py index 8f3028fc..dae93655 100644 --- a/src/cryptography/hazmat/primitives/ciphers/base.py +++ b/src/cryptography/hazmat/primitives/ciphers/base.py @@ -149,6 +149,8 @@ class _CipherContext(object): class _AEADCipherContext(object): def __init__(self, ctx): self._ctx = ctx + self._bytes_processed = 0 + self._aad_bytes_processed = 0 self._tag = None self._updated = False @@ -156,6 +158,14 @@ class _AEADCipherContext(object): if self._ctx is None: raise AlreadyFinalized("Context was already finalized.") self._updated = True + self._bytes_processed += len(data) + if self._bytes_processed > self._ctx._mode._MAX_ENCRYPTED_BYTES: + raise ValueError( + "{0} has a maximum encrypted byte limit of {1}".format( + self._ctx._mode.name, self._ctx._mode._MAX_ENCRYPTED_BYTES + ) + ) + return self._ctx.update(data) def finalize(self): @@ -171,6 +181,15 @@ class _AEADCipherContext(object): raise AlreadyFinalized("Context was already finalized.") if self._updated: raise AlreadyUpdated("Update has been called on this context.") + + self._aad_bytes_processed += len(data) + if self._aad_bytes_processed > self._ctx._mode._MAX_AAD_BYTES: + raise ValueError( + "{0} has a maximum AAD byte limit of {0}".format( + self._ctx._mode.name, self._ctx._mode._MAX_AAD_BYTES + ) + ) + self._ctx.authenticate_additional_data(data) diff --git a/src/cryptography/hazmat/primitives/ciphers/modes.py b/src/cryptography/hazmat/primitives/ciphers/modes.py index e31c9060..4284042d 100644 --- a/src/cryptography/hazmat/primitives/ciphers/modes.py +++ b/src/cryptography/hazmat/primitives/ciphers/modes.py @@ -139,6 +139,8 @@ class CTR(object): @utils.register_interface(ModeWithAuthenticationTag) class GCM(object): name = "GCM" + _MAX_ENCRYPTED_BYTES = (2 ** 39 - 256) // 8 + _MAX_AAD_BYTES = (2 ** 64) // 8 def __init__(self, initialization_vector, tag=None, min_tag_length=16): # len(initialization_vector) must in [1, 2 ** 64), but it's impossible diff --git a/tests/hazmat/primitives/test_aes.py b/tests/hazmat/primitives/test_aes.py index 4d48e8ad..32892678 100644 --- a/tests/hazmat/primitives/test_aes.py +++ b/tests/hazmat/primitives/test_aes.py @@ -253,3 +253,33 @@ class TestAESModeGCM(object): computed_ct = encryptor.update(pt) + encryptor.finalize() assert computed_ct == ct assert encryptor.tag == tag + + def test_gcm_ciphertext_limit(self, backend): + encryptor = base.Cipher( + algorithms.AES(b"\x00" * 16), + modes.GCM(b"\x01" * 16), + backend=backend + ).encryptor() + # 16 bytes less than the encryption limit + near_limit_bytes = (2 ** 39 - 256 - 128) // 8 + encryptor._bytes_processed = near_limit_bytes + encryptor.update(b"0" * 16) + assert ( + encryptor._bytes_processed == modes.GCM._MAX_ENCRYPTED_BYTES + ) + with pytest.raises(ValueError): + encryptor.update(b"0") + + def test_gcm_aad_limit(self, backend): + encryptor = base.Cipher( + algorithms.AES(b"\x00" * 16), + modes.GCM(b"\x01" * 16), + backend=backend + ).encryptor() + # 16 bytes less than the AAD limit + near_limit_bytes = (2 ** 64 - 128) // 8 + encryptor._aad_bytes_processed = near_limit_bytes + encryptor.authenticate_additional_data(b"0" * 16) + assert encryptor._aad_bytes_processed == modes.GCM._MAX_AAD_BYTES + with pytest.raises(ValueError): + encryptor.authenticate_additional_data(b"0") -- cgit v1.2.3 From 463de43d9cc05ae97e08b3d439b70d44c70f9f62 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 1 Jul 2015 20:05:53 -0500 Subject: add additional increment tests --- tests/hazmat/primitives/test_aes.py | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/tests/hazmat/primitives/test_aes.py b/tests/hazmat/primitives/test_aes.py index 32892678..06e8adf8 100644 --- a/tests/hazmat/primitives/test_aes.py +++ b/tests/hazmat/primitives/test_aes.py @@ -270,16 +270,26 @@ class TestAESModeGCM(object): with pytest.raises(ValueError): encryptor.update(b"0") - def test_gcm_aad_limit(self, backend): + def test_gcm_ciphertext_increments(self, backend): encryptor = base.Cipher( algorithms.AES(b"\x00" * 16), modes.GCM(b"\x01" * 16), backend=backend ).encryptor() - # 16 bytes less than the AAD limit - near_limit_bytes = (2 ** 64 - 128) // 8 - encryptor._aad_bytes_processed = near_limit_bytes - encryptor.authenticate_additional_data(b"0" * 16) - assert encryptor._aad_bytes_processed == modes.GCM._MAX_AAD_BYTES - with pytest.raises(ValueError): - encryptor.authenticate_additional_data(b"0") + encryptor.update(b"0" * 8) + assert encryptor._bytes_processed == 8 + encryptor.update(b"0" * 7) + assert encryptor._bytes_processed == 15 + encryptor.update(b"0" * 18) + assert encryptor._bytes_processed == 33 + + def test_gcm_aad_increments(self, backend): + encryptor = base.Cipher( + algorithms.AES(b"\x00" * 16), + modes.GCM(b"\x01" * 16), + backend=backend + ).encryptor() + encryptor.authenticate_additional_data(b"0" * 8) + assert encryptor._aad_bytes_processed == 8 + encryptor.authenticate_additional_data(b"0" * 18) + assert encryptor._aad_bytes_processed == 26 -- cgit v1.2.3 From 423768361e3b5ea6a39819d512ca72ce176d151d Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 1 Jul 2015 18:10:32 -0500 Subject: name constraints - support leading periods --- src/cryptography/hazmat/backends/openssl/x509.py | 10 +++++-- tests/test_x509_ext.py | 38 ++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index 41258483..c7ca2ad1 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -86,13 +86,17 @@ def _decode_general_name(backend, gn): # This is a wildcard name. We need to remove the leading wildcard, # IDNA decode, then re-add the wildcard. Wildcard characters should # always be left-most (RFC 2595 section 2.4). - data = u"*." + idna.decode(data[2:]) + decoded = u"*." + idna.decode(data[2:]) else: # Not a wildcard, decode away. If the string has a * in it anywhere # invalid this will raise an InvalidCodePoint - data = idna.decode(data) + decoded = idna.decode(data) + if data.startswith(b"."): + # idna strips leading periods. Name constraints can have that + # so we need to re-add it. Sigh. + decoded = u"." + decoded - return x509.DNSName(data) + return x509.DNSName(decoded) elif gn.type == backend._lib.GEN_URI: data = backend._ffi.buffer( gn.d.uniformResourceIdentifier.data, diff --git a/tests/test_x509_ext.py b/tests/test_x509_ext.py index 15ee118a..0ef84e79 100644 --- a/tests/test_x509_ext.py +++ b/tests/test_x509_ext.py @@ -2076,6 +2076,44 @@ class TestNameConstraintsExtension(object): excluded_subtrees=None ) + def test_permitted_with_leading_period(self, backend): + cert = _load_cert( + os.path.join( + "x509", "custom", "nc_permitted.pem" + ), + x509.load_pem_x509_certificate, + backend + ) + nc = cert.extensions.get_extension_for_oid( + x509.OID_NAME_CONSTRAINTS + ).value + assert nc == x509.NameConstraints( + permitted_subtrees=[ + x509.DNSName(u".cryptography.io"), + x509.UniformResourceIdentifier(u"ftp://cryptography.test") + ], + excluded_subtrees=None + ) + + def test_excluded_with_leading_period(self, backend): + cert = _load_cert( + os.path.join( + "x509", "custom", "nc_excluded.pem" + ), + x509.load_pem_x509_certificate, + backend + ) + nc = cert.extensions.get_extension_for_oid( + x509.OID_NAME_CONSTRAINTS + ).value + assert nc == x509.NameConstraints( + permitted_subtrees=None, + excluded_subtrees=[ + x509.DNSName(u".cryptography.io"), + x509.UniformResourceIdentifier(u"gopher://cryptography.test") + ] + ) + class TestDistributionPoint(object): def test_distribution_point_full_name_not_general_names(self): -- cgit v1.2.3 From d5119d530b4bd15cae9e758972e0407a5bcdd244 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 1 Jul 2015 20:21:33 -0500 Subject: add missing test, simplify encrypted byte near limit calculation --- tests/hazmat/primitives/test_aes.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/tests/hazmat/primitives/test_aes.py b/tests/hazmat/primitives/test_aes.py index 06e8adf8..f079ae4f 100644 --- a/tests/hazmat/primitives/test_aes.py +++ b/tests/hazmat/primitives/test_aes.py @@ -260,9 +260,7 @@ class TestAESModeGCM(object): modes.GCM(b"\x01" * 16), backend=backend ).encryptor() - # 16 bytes less than the encryption limit - near_limit_bytes = (2 ** 39 - 256 - 128) // 8 - encryptor._bytes_processed = near_limit_bytes + encryptor._bytes_processed = modes.GCM._MAX_ENCRYPTED_BYTES - 16 encryptor.update(b"0" * 16) assert ( encryptor._bytes_processed == modes.GCM._MAX_ENCRYPTED_BYTES @@ -270,6 +268,20 @@ class TestAESModeGCM(object): with pytest.raises(ValueError): encryptor.update(b"0") + def test_gcm_aad_limit(self, backend): + encryptor = base.Cipher( + algorithms.AES(b"\x00" * 16), + modes.GCM(b"\x01" * 16), + backend=backend + ).encryptor() + # 16 bytes less than the AAD limit + near_limit_bytes = (2 ** 64 - 128) // 8 + encryptor._aad_bytes_processed = near_limit_bytes + encryptor.authenticate_additional_data(b"0" * 16) + assert encryptor._aad_bytes_processed == modes.GCM._MAX_AAD_BYTES + with pytest.raises(ValueError): + encryptor.authenticate_additional_data(b"0") + def test_gcm_ciphertext_increments(self, backend): encryptor = base.Cipher( algorithms.AES(b"\x00" * 16), -- cgit v1.2.3 From 326502a8535e72fe76fdf61762cdf66198370799 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 1 Jul 2015 20:23:11 -0500 Subject: do the same simplification to the aad test --- tests/hazmat/primitives/test_aes.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/hazmat/primitives/test_aes.py b/tests/hazmat/primitives/test_aes.py index f079ae4f..2c3e5f90 100644 --- a/tests/hazmat/primitives/test_aes.py +++ b/tests/hazmat/primitives/test_aes.py @@ -274,9 +274,7 @@ class TestAESModeGCM(object): modes.GCM(b"\x01" * 16), backend=backend ).encryptor() - # 16 bytes less than the AAD limit - near_limit_bytes = (2 ** 64 - 128) // 8 - encryptor._aad_bytes_processed = near_limit_bytes + encryptor._aad_bytes_processed = modes.GCM._MAX_AAD_BYTES - 16 encryptor.authenticate_additional_data(b"0" * 16) assert encryptor._aad_bytes_processed == modes.GCM._MAX_AAD_BYTES with pytest.raises(ValueError): -- cgit v1.2.3 From 8f458ab55739634eff751b136c14d473696d5643 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 1 Jul 2015 21:17:17 -0500 Subject: add name constraints vector with /32 and /128 IP networks --- docs/development/test-vectors.rst | 3 +++ .../x509/custom/nc_single_ip_netmask.pem | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 vectors/cryptography_vectors/x509/custom/nc_single_ip_netmask.pem diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst index ca07547c..fe64fe1a 100644 --- a/docs/development/test-vectors.rst +++ b/docs/development/test-vectors.rst @@ -215,6 +215,9 @@ Custom X.509 Vectors * ``nc_invalid_ip_netmask.pem`` - An RSA 2048 bit self-signed certificate containing a name constraints extension with a permitted element that has an ``IPv6`` IP and an invalid network mask. +* ``nc_single_ip_netmask.pem`` - An RSA 2048 bit self-signed certificate + containing a name constraints extension with a permitted element that has two + IPs with ``/32`` and ``/128`` network masks. * ``cp_user_notice_with_notice_reference.pem`` - An RSA 2048 bit self-signed certificate containing a certificate policies extension with a notice reference in the user notice. diff --git a/vectors/cryptography_vectors/x509/custom/nc_single_ip_netmask.pem b/vectors/cryptography_vectors/x509/custom/nc_single_ip_netmask.pem new file mode 100644 index 00000000..2931b6b9 --- /dev/null +++ b/vectors/cryptography_vectors/x509/custom/nc_single_ip_netmask.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/TCCAeWgAwIBAgITBnA4pkis5m3OGusBaihd9qH0hzANBgkqhkiG9w0BAQsF +ADAXMRUwEwYDVQQDDAxjcnlwdG9ncmFwaHkwHhcNMTUwNzAxMjAxNDAwWhcNMTYw +NjMwMjAxNDAwWjAXMRUwEwYDVQQDDAxjcnlwdG9ncmFwaHkwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCYyaGtu90vcm+jN+SoQHXxWMQyplY1neL9KjfE ++TsKKcy8TKJEqlT8qZr6bIL3KVbTIiYO8bCW9fHSMgHWrmtr37LlFoQ3emcLfDbM +kybmOolAxA78im0L2BIW1wT2iSHh1p/ZO5QLdt+e8zP5AkZAnXCZk912RcJYyGUW +7JQzzRfEANSLE9Gmh78NsxWNI1Ipc3dhyuk3+YHwePGCzLCeXCiF4FHGNMg8Drtr +rENNHZjHJCbMLfK9irHV5Xh1FHTK8xlqEq+YecpqboUyqgWVOOvpxUxiKagfp//Z ++iFDC1+GgpuupzFUiHPSVCZGMnE3bHvIBOkoHkNu7kNK7VX3AgMBAAGjQjBAMD4G +A1UdHgEB/wQ0MDKgMDAihyAA/wAAAAAAAAAAAAAAAAAA//////////////////// +/zAKhwjAqAAB/////zANBgkqhkiG9w0BAQsFAAOCAQEAXSDmonnBpivsW/NKE85c +1ho449K98+1cFUD51VeK42oPUd0GRQCU3ETYJ5YyK7OMoQqe4LTtNDx6ZCF+6z/r +tZctfdpwRmqh2ebGn3qDs1FAckkwwSCRtkJTdgznmtO680Ls5GveNFrgYJkYfFjj +OWpzCypse/3j3uVgSakmjBRS4BOsyX4o7trN+k1MmQOrMpWEtLlmrZJpM66sgP0j +WpI95l4paIMpkFarwCCQfJCNBpl7Uol+BD4vJvf/J7f7ZwxQMEWCBPnYk3EKMnKa +aCsmqRMV1W7SzxL07dHMzWnsC/I5oJNj4HdthGcIJf1Jut9A9KFVodOJAxKOziz2 +aQ== +-----END CERTIFICATE----- -- cgit v1.2.3 From 9bbd4900bc4db86b675aaf6c22c034a071150d5a Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 1 Jul 2015 22:26:28 -0400 Subject: Fixed #1689 -- correctly handle code with multiple requires_backend_itnerface --- tests/conftest.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index c4d6b9c1..6599a643 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -18,11 +18,13 @@ def pytest_generate_tests(metafunc): if "backend" in metafunc.fixturenames: filtered_backends = [] required = metafunc.function.requires_backend_interface - required_interfaces = tuple( + required_interfaces = [ mark.kwargs["interface"] for mark in required - ) + ] for backend in selected_backends: - if isinstance(backend, required_interfaces): + if all( + isinstance(backend, iface) for iface in required_interfaces + ): filtered_backends.append(backend) # If you pass an empty list to parametrize Bad Things(tm) happen -- cgit v1.2.3 From be28a243b2ca27a569cb732003e3ebde69ed75b7 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 2 Jul 2015 00:05:49 -0400 Subject: Improved coverage for tests, handle multiple pytest.mark.supported decorators on one function --- tests/test_interfaces.py | 2 ++ tests/utils.py | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/test_interfaces.py b/tests/test_interfaces.py index 4d571ea6..329ac7db 100644 --- a/tests/test_interfaces.py +++ b/tests/test_interfaces.py @@ -36,6 +36,7 @@ class TestVerifyInterface(object): def method(self): """Method with no arguments""" + NonImplementer().method() with pytest.raises(InterfaceNotImplemented): verify_interface(SimpleInterface, NonImplementer) @@ -51,4 +52,5 @@ class TestVerifyInterface(object): def property(self): """A concrete property""" + NonImplementer().property verify_interface(SimpleInterface, NonImplementer) diff --git a/tests/utils.py b/tests/utils.py index 8be5c1fa..c810303e 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -53,7 +53,10 @@ def skip_if_empty(backend_list, required_interfaces): def check_backend_support(item): supported = item.keywords.get("supported") if supported and "backend" in item.funcargs: - if not supported.kwargs["only_if"](item.funcargs["backend"]): + if not all( + mark.kwargs["only_if"](item.funcargs["backend"]) + for mark in supported + ): pytest.skip("{0} ({1})".format( supported.kwargs["skip_message"], item.funcargs["backend"] )) -- cgit v1.2.3 From cc04d679b81bcd69370ddc79c651e5e8a656ef04 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 2 Jul 2015 00:06:18 -0400 Subject: comment --- tests/test_interfaces.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_interfaces.py b/tests/test_interfaces.py index 329ac7db..bdb4a94d 100644 --- a/tests/test_interfaces.py +++ b/tests/test_interfaces.py @@ -36,6 +36,7 @@ class TestVerifyInterface(object): def method(self): """Method with no arguments""" + # Invoke this to ensure the line is covered NonImplementer().method() with pytest.raises(InterfaceNotImplemented): verify_interface(SimpleInterface, NonImplementer) @@ -52,5 +53,6 @@ class TestVerifyInterface(object): def property(self): """A concrete property""" + # Invoke this to ensure the line is covered NonImplementer().property verify_interface(SimpleInterface, NonImplementer) -- cgit v1.2.3 From 50ebb489852b8c9dd02d08e09375aa00859999bf Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 2 Jul 2015 00:21:41 -0400 Subject: fixed tests --- tests/test_utils.py | 4 ++-- tests/utils.py | 12 +++++------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/tests/test_utils.py b/tests/test_utils.py index 8601d11d..f71264ea 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -85,7 +85,7 @@ def test_check_backend_support_skip(): supported = pretend.stub( kwargs={"only_if": lambda backend: False, "skip_message": "Nope"} ) - item = pretend.stub(keywords={"supported": supported}, + item = pretend.stub(keywords={"supported": [supported]}, funcargs={"backend": True}) with pytest.raises(pytest.skip.Exception) as exc_info: check_backend_support(item) @@ -96,7 +96,7 @@ def test_check_backend_support_no_skip(): supported = pretend.stub( kwargs={"only_if": lambda backend: True, "skip_message": "Nope"} ) - item = pretend.stub(keywords={"supported": supported}, + item = pretend.stub(keywords={"supported": [supported]}, funcargs={"backend": True}) assert check_backend_support(item) is None diff --git a/tests/utils.py b/tests/utils.py index c810303e..5083d48c 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -53,13 +53,11 @@ def skip_if_empty(backend_list, required_interfaces): def check_backend_support(item): supported = item.keywords.get("supported") if supported and "backend" in item.funcargs: - if not all( - mark.kwargs["only_if"](item.funcargs["backend"]) - for mark in supported - ): - pytest.skip("{0} ({1})".format( - supported.kwargs["skip_message"], item.funcargs["backend"] - )) + for mark in supported: + if not mark.kwargs["only_if"](item.funcargs["backend"]): + pytest.skip("{0} ({1})".format( + mark.kwargs["skip_message"], item.funcargs["backend"] + )) elif supported: raise ValueError("This mark is only available on methods that take a " "backend") -- cgit v1.2.3 From c2818e4f3291bfa80843f185fb0c7659b6204783 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 2 Jul 2015 19:07:00 -0400 Subject: Shift around the x509 code, all the extensions are going to have the same thing --- .../hazmat/backends/openssl/backend.py | 32 ++++++++-------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 91bc304f..73a58637 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -115,9 +115,7 @@ def _txt2obj(backend, name): return obj -def _encode_basic_constraints(backend, basic_constraints, critical): - obj = _txt2obj(backend, x509.OID_BASIC_CONSTRAINTS.dotted_string) - assert obj is not None +def _encode_basic_constraints(backend, basic_constraints): constraints = backend._lib.BASIC_CONSTRAINTS_new() constraints = backend._ffi.gc( constraints, backend._lib.BASIC_CONSTRAINTS_free @@ -135,18 +133,7 @@ def _encode_basic_constraints(backend, basic_constraints, critical): pp = backend._ffi.gc( pp, lambda pointer: backend._lib.OPENSSL_free(pointer[0]) ) - - # Wrap that in an X509 extension object. - extension = backend._lib.X509_EXTENSION_create_by_OBJ( - backend._ffi.NULL, - obj, - 1 if critical else 0, - _encode_asn1_str(backend, pp[0], r), - ) - assert extension != backend._ffi.NULL - - # Return the wrapped extension. - return extension + return pp, r @utils.register_interface(CipherBackend) @@ -854,14 +841,19 @@ class Backend(object): self._lib.sk_X509_EXTENSION_free, ) for extension in builder._extensions: + obj = _txt2obj(self, extension.oid.dotted_string) if isinstance(extension.value, x509.BasicConstraints): - extension = _encode_basic_constraints( - self, - extension.value, - extension.critical - ) + pp, r = _encode_basic_constraints(self, extension.value) else: raise NotImplementedError('Extension not yet supported.') + + extension = self._lib.X509_EXTENSION_create_by_OBJ( + self._ffi.NULL, + obj, + 1 if extension.critical else 0, + _encode_asn1_str(self, pp[0], r), + ) + assert extension != self._ffi.NULL res = self._lib.sk_X509_EXTENSION_push(extensions, extension) assert res == 1 res = self._lib.X509_REQ_add_extensions(x509_req, extensions) -- cgit v1.2.3