diff options
Diffstat (limited to 'tests/hazmat/bindings/test_openssl.py')
| -rw-r--r-- | tests/hazmat/bindings/test_openssl.py | 135 |
1 files changed, 63 insertions, 72 deletions
diff --git a/tests/hazmat/bindings/test_openssl.py b/tests/hazmat/bindings/test_openssl.py index fe78b0ba..29a1c459 100644 --- a/tests/hazmat/bindings/test_openssl.py +++ b/tests/hazmat/bindings/test_openssl.py @@ -6,7 +6,10 @@ from __future__ import absolute_import, division, print_function import pytest -from cryptography.hazmat.bindings.openssl.binding import Binding +from cryptography.exceptions import InternalError +from cryptography.hazmat.bindings.openssl.binding import ( + Binding, _consume_errors, _openssl_assert, _verify_package_version +) class TestOpenSSL(object): @@ -18,85 +21,27 @@ class TestOpenSSL(object): def test_crypto_lock_init(self): b = Binding() - b.init_static_locks() - lock_cb = b.lib.CRYPTO_get_locking_callback() - assert lock_cb != b.ffi.NULL - - def _skip_if_not_fallback_lock(self, b): - # only run this test if we are using our locking cb - original_cb = b.lib.CRYPTO_get_locking_callback() - if original_cb != b._lock_cb_handle: - pytest.skip( - "Not using the fallback Python locking callback " - "implementation. Probably because import _ssl set one" - ) - - def test_fallback_crypto_lock_via_openssl_api(self): - b = Binding() - b.init_static_locks() - - self._skip_if_not_fallback_lock(b) - - # check that the lock state changes appropriately - lock = b._locks[b.lib.CRYPTO_LOCK_SSL] - - # starts out unlocked - assert lock.acquire(False) - lock.release() - - b.lib.CRYPTO_lock( - b.lib.CRYPTO_LOCK | b.lib.CRYPTO_READ, - b.lib.CRYPTO_LOCK_SSL, b.ffi.NULL, 0 - ) - - # becomes locked - assert not lock.acquire(False) - - b.lib.CRYPTO_lock( - b.lib.CRYPTO_UNLOCK | b.lib.CRYPTO_READ, - b.lib.CRYPTO_LOCK_SSL, b.ffi.NULL, 0 - ) - # then unlocked - assert lock.acquire(False) - lock.release() - - def test_fallback_crypto_lock_via_binding_api(self): - b = Binding() b.init_static_locks() - - self._skip_if_not_fallback_lock(b) - - lock = b._locks[b.lib.CRYPTO_LOCK_SSL] - - with pytest.raises(RuntimeError): - b._lock_cb(0, b.lib.CRYPTO_LOCK_SSL, "<test>", 1) - - # errors shouldn't cause locking - assert lock.acquire(False) - lock.release() - - b._lock_cb(b.lib.CRYPTO_LOCK | b.lib.CRYPTO_READ, - b.lib.CRYPTO_LOCK_SSL, "<test>", 1) - # locked - assert not lock.acquire(False) - - b._lock_cb(b.lib.CRYPTO_UNLOCK | b.lib.CRYPTO_READ, - b.lib.CRYPTO_LOCK_SSL, "<test>", 1) - # unlocked - assert lock.acquire(False) - lock.release() + lock_cb = b.lib.CRYPTO_get_locking_callback() + if b.lib.CRYPTOGRAPHY_OPENSSL_110_OR_GREATER: + assert lock_cb == b.ffi.NULL + assert b.lib.Cryptography_HAS_LOCKING_CALLBACKS == 0 + else: + assert lock_cb != b.ffi.NULL + assert b.lib.Cryptography_HAS_LOCKING_CALLBACKS == 1 def test_add_engine_more_than_once(self): b = Binding() - res = b._register_osrandom_engine() - assert res == 2 + b._register_osrandom_engine() + assert b.lib.ERR_get_error() == 0 def test_ssl_ctx_options(self): # Test that we're properly handling 32-bit unsigned on all platforms. b = Binding() assert b.lib.SSL_OP_ALL > 0 - ctx = b.lib.SSL_CTX_new(b.lib.TLSv1_method()) + ctx = b.lib.SSL_CTX_new(b.lib.SSLv23_method()) + assert ctx != b.ffi.NULL ctx = b.ffi.gc(ctx, b.lib.SSL_CTX_free) current_options = b.lib.SSL_CTX_get_options(ctx) resp = b.lib.SSL_CTX_set_options(ctx, b.lib.SSL_OP_ALL) @@ -108,7 +53,8 @@ class TestOpenSSL(object): # Test that we're properly handling 32-bit unsigned on all platforms. b = Binding() assert b.lib.SSL_OP_ALL > 0 - ctx = b.lib.SSL_CTX_new(b.lib.TLSv1_method()) + ctx = b.lib.SSL_CTX_new(b.lib.SSLv23_method()) + assert ctx != b.ffi.NULL ctx = b.ffi.gc(ctx, b.lib.SSL_CTX_free) ssl = b.lib.SSL_new(ctx) ssl = b.ffi.gc(ssl, b.lib.SSL_free) @@ -122,7 +68,8 @@ class TestOpenSSL(object): # Test that we're properly handling 32-bit unsigned on all platforms. b = Binding() assert b.lib.SSL_OP_ALL > 0 - ctx = b.lib.SSL_CTX_new(b.lib.TLSv1_method()) + ctx = b.lib.SSL_CTX_new(b.lib.SSLv23_method()) + assert ctx != b.ffi.NULL ctx = b.ffi.gc(ctx, b.lib.SSL_CTX_free) ssl = b.lib.SSL_new(ctx) ssl = b.ffi.gc(ssl, b.lib.SSL_free) @@ -131,3 +78,47 @@ class TestOpenSSL(object): expected_options = current_options | b.lib.SSL_OP_ALL assert resp == expected_options assert b.lib.SSL_get_mode(ssl) == expected_options + + def test_conditional_removal(self): + b = Binding() + + if b.lib.CRYPTOGRAPHY_OPENSSL_110_OR_GREATER: + assert b.lib.TLS_ST_OK + else: + with pytest.raises(AttributeError): + b.lib.TLS_ST_OK + + def test_openssl_assert_error_on_stack(self): + b = Binding() + b.lib.ERR_put_error( + b.lib.ERR_LIB_EVP, + b.lib.EVP_F_EVP_ENCRYPTFINAL_EX, + b.lib.EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH, + b"", + -1 + ) + with pytest.raises(InternalError) as exc_info: + _openssl_assert(b.lib, False) + + error = exc_info.value.err_code[0] + assert error.code == 101183626 + assert error.lib == b.lib.ERR_LIB_EVP + assert error.func == b.lib.EVP_F_EVP_ENCRYPTFINAL_EX + assert error.reason == b.lib.EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH + assert b"data not multiple of block length" in error.reason_text + + def test_check_startup_errors_are_allowed(self): + b = Binding() + b.lib.ERR_put_error( + b.lib.ERR_LIB_EVP, + b.lib.EVP_F_EVP_ENCRYPTFINAL_EX, + b.lib.EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH, + b"", + -1 + ) + b._register_osrandom_engine() + assert _consume_errors(b.lib) == [] + + def test_version_mismatch(self): + with pytest.raises(ImportError): + _verify_package_version("nottherightversion") |
