def test_crypto_lock_init(self): b = Binding() if ( b.lib.CRYPTOGRAPHY_OPENSSL_110_OR_GREATER and not b.lib.CRYPTOGRAPHY_IS_LIBRESSL ): pytest.skip("Requires an older OpenSSL. Must be < 1.1.0") b.init_static_locks() lock_cb = b.lib.CRYPTO_get_locking_callback() assert lock_cb != b.ffi.NULL
def test_ssl_mode(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.ffi.gc(ctx, b.lib.SSL_CTX_free) ssl = b.lib.SSL_new(ctx) ssl = b.ffi.gc(ssl, b.lib.SSL_free) resp = b.lib.SSL_set_mode(ssl, b.lib.SSL_OP_ALL) assert resp == b.lib.SSL_OP_ALL assert b.lib.SSL_OP_ALL == b.lib.SSL_get_mode(ssl)
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.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) expected_options = current_options | b.lib.SSL_OP_ALL assert resp == expected_options assert b.lib.SSL_CTX_get_options(ctx) == expected_options
def __init__(self, sleeper=None): ctx = SSL.Context(SSL.SSLv23_METHOD) # TLS 1.3 removes renegotiation support. Which is great for them, but # we still have to support versions before that, and that means we # need to test renegotiation support, which means we need to force this # to use a lower version where this test server can trigger # renegotiations. Of course TLS 1.3 support isn't released yet, but # I'm told that this will work once it is. (And once it is we can # remove the pragma: no cover too.) Alternatively, we could switch to # using TLSv1_2_METHOD. # # Discussion: https://github.com/pyca/pyopenssl/issues/624 # This is the right way, but we can't use it until this PR is in a # released: # https://github.com/pyca/pyopenssl/pull/861 # # if hasattr(SSL, "OP_NO_TLSv1_3"): # ctx.set_options(SSL.OP_NO_TLSv1_3) # # Fortunately pyopenssl uses cryptography under the hood, so we can be # confident that they're using the same version of openssl from cryptography.hazmat.bindings.openssl.binding import Binding b = Binding() if hasattr(b.lib, "SSL_OP_NO_TLSv1_3"): ctx.set_options(b.lib.SSL_OP_NO_TLSv1_3) # Unfortunately there's currently no way to say "use 1.3 or worse", we # can only disable specific versions. And if the two sides start # negotiating 1.4 at some point in the future, it *might* mean that # our tests silently stop working properly. So the next line is a # tripwire to remind us we need to revisit this stuff in 5 years or # whatever when the next TLS version is released: assert not hasattr(SSL, "OP_NO_TLSv1_4") TRIO_TEST_1_CERT.configure_cert(ctx) self._conn = SSL.Connection(ctx, None) self._conn.set_accept_state() self._lot = _core.ParkingLot() self._pending_cleartext = bytearray() self._send_all_conflict_detector = ConflictDetector( "simultaneous calls to PyOpenSSLEchoStream.send_all") self._receive_some_conflict_detector = ConflictDetector( "simultaneous calls to PyOpenSSLEchoStream.receive_some") if sleeper is None: async def no_op_sleeper(_): return self.sleeper = no_op_sleeper else: self.sleeper = sleeper
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_crypto_lock_init(self): b = Binding() b.init_static_locks() 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 __init__(self, host: str, port: int): self.host = host self.port = port self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) binding = Binding() binding.init_static_locks() # Binding the DTLSv1 method to SSL context methods 1st entry # Required as this is UDP OpenSSL.SSL.Context._methods[0] = getattr(binding.lib, "DTLSv1_client_method") ctx = OpenSSL.SSL.Context(0) self.socket = OpenSSL.SSL.Connection(ctx, self.s) self.connect()
def test_ssl_ctx_options(self): # Test that we're properly handling 32-bit unsigned on all platforms. b = Binding() # SSL_OP_ALL is 0 on BoringSSL if not b.lib.CRYPTOGRAPHY_IS_BORINGSSL: assert b.lib.SSL_OP_ALL > 0 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) expected_options = current_options | b.lib.SSL_OP_ALL assert resp == expected_options assert b.lib.SSL_CTX_get_options(ctx) == expected_options
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_actual_osrandom_bytes(self, monkeypatch): b = Binding() skip_if_libre_ssl(b.ffi.string(b.lib.OPENSSL_VERSION_TEXT)) 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) buf = b.ffi.new("char[]", length) b.lib.RAND_bytes(buf, length) assert b.ffi.buffer(buf)[0:length] == sample_data
def test_ssl_mode(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.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) current_options = b.lib.SSL_get_mode(ssl) resp = b.lib.SSL_set_mode(ssl, b.lib.SSL_OP_ALL) expected_options = current_options | b.lib.SSL_OP_ALL assert resp == expected_options assert b.lib.SSL_get_mode(ssl) == expected_options
def _openssl_get_supported_curves(): if hasattr(_openssl_get_supported_curves, '_curves'): return _openssl_get_supported_curves._curves # use cryptography's cffi bindings to get an array of curve names b = Binding() cn = b.lib.EC_get_builtin_curves(b.ffi.NULL, 0) cs = b.ffi.new('EC_builtin_curve[]', cn) b.lib.EC_get_builtin_curves(cs, cn) # store the result so we don't have to do all of this every time curves = { b.ffi.string(b.lib.OBJ_nid2sn(c.nid)).decode('utf-8') for c in cs } _openssl_get_supported_curves._curves = curves return curves
def test_conditional_removal(self): b = Binding() if b.lib.OPENSSL_VERSION_NUMBER >= 0x10000000: assert b.lib.X509_V_ERR_DIFFERENT_CRL_SCOPE assert b.lib.X509_V_ERR_CRL_PATH_VALIDATION_ERROR else: with pytest.raises(AttributeError): b.lib.X509_V_ERR_DIFFERENT_CRL_SCOPE with pytest.raises(AttributeError): b.lib.X509_V_ERR_CRL_PATH_VALIDATION_ERROR if b.lib.OPENSSL_VERSION_NUMBER >= 0x10001000: assert b.lib.CMAC_Init else: with pytest.raises(AttributeError): b.lib.CMAC_Init
def __init__(self): self._binding = Binding() self._ffi = self._binding.ffi self._lib = self._binding.lib self._binding.init_static_locks() # adds all ciphers/digests for EVP self._lib.OpenSSL_add_all_algorithms() # registers available SSL/TLS ciphers and digests self._lib.SSL_library_init() # loads error strings for libcrypto and libssl functions self._lib.SSL_load_error_strings() self._cipher_registry = {} self._register_default_ciphers() self.activate_osrandom_engine()
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) assert exc_info.value.err_code == [ _OpenSSLErrorWithText( code=101183626, lib=b.lib.ERR_LIB_EVP, func=b.lib.EVP_F_EVP_ENCRYPTFINAL_EX, reason=b.lib.EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH, reason_text= (b'error:0607F08A:digital envelope routines:EVP_EncryptFinal_' b'ex:data not multiple of block length')) ]
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] # As of 3.0.0 OpenSSL no longer sets func codes (which we now also # ignore), so the combined code is a different value assert error.code in (101183626, 50331786) assert error.lib == b.lib.ERR_LIB_EVP 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 get_random_bytes(num_bytes): """ Get random bytes Currently, Cryptography returns OS random bytes. If you want OpenSSL generated random bytes, you'll have to switch the RAND engine after initializing the OpenSSL backend Args: num_bytes (int): Number of random bytes to generate and return Returns: bytes: Random bytes """ global _binding if _binding is None: _binding = Binding() buf = _binding.ffi.new("char[]", num_bytes) _binding.lib.RAND_bytes(buf, num_bytes) rand_bytes = _binding.ffi.buffer(buf, num_bytes)[:] return rand_bytes
def _openssl_get_supported_curves(): if hasattr(_openssl_get_supported_curves, '_curves'): return _openssl_get_supported_curves._curves # use cryptography's cffi bindings to get an array of curve names b = Binding() cn = b.lib.EC_get_builtin_curves(b.ffi.NULL, 0) cs = b.ffi.new('EC_builtin_curve[]', cn) b.lib.EC_get_builtin_curves(cs, cn) # store the result so we don't have to do all of this every time curves = { b.ffi.string(b.lib.OBJ_nid2sn(c.nid)).decode('utf-8') for c in cs } # Ed25519 and X25519 are always present in cryptography>=2.6 # The python cryptography lib provides a different interface for these curves, # so they are handled differently in the ECDHPriv/Pub and EdDSAPriv/Pub classes curves |= {'X25519', 'ed25519'} _openssl_get_supported_curves._curves = curves return curves
def test_add_engine_more_than_once(self): b = Binding() b._register_osrandom_engine() assert b.lib.ERR_get_error() == 0
def test_binding_loads(self): binding = Binding() assert binding assert binding.lib assert binding.ffi
import attr import pylibsrtp from cryptography.hazmat.backends import default_backend from cryptography.hazmat.bindings.openssl.binding import Binding from cryptography.hazmat.primitives.asymmetric import ec from cryptography.hazmat.primitives.serialization import (Encoding, NoEncryption, PrivateFormat) from OpenSSL import crypto from pyee import EventEmitter from pylibsrtp import Policy, Session from .rtp import RtcpPacket, RtpPacket, get_header_extensions, is_rtcp from .utils import first_completed binding = Binding() binding.init_static_locks() ffi = binding.ffi lib = binding.lib SRTP_KEY_LEN = 16 SRTP_SALT_LEN = 14 logger = logging.getLogger('dtls') class DtlsError(Exception): pass def _openssl_assert(ok):
def init_dtls(): binding = Binding() binding.init_static_locks() SSL.Context._methods[0] = getattr(binding.lib, "DTLSv1_client_method")
def skip_if_memtesting_not_supported(): return pytest.mark.skipif( not Binding().lib.Cryptography_HAS_MEM_FUNCTIONS, reason="Requires OpenSSL memory functions (>=1.1.0)", )
from cryptography.hazmat.bindings.openssl.binding import Binding from cryptography.hazmat.primitives.serialization import (load_der_private_key, load_der_public_key) from cryptography.hazmat.backends import default_backend from .cffi import ffi, lib __all__ = [ 'InvalidPKeyError', 'PKey', 'ImportedPKey', 'ExportedPKey', ] crypto = Binding() # cryptography provides no common base class for keys CryptoKey = Any class InvalidPKeyError(ValueError): """Invalid key""" class PKey: """An EVP_PKEY wrapper""" _key: CryptoKey _pkey: ffi.CType
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 test_add_engine_more_than_once(self): b = Binding() res = b.lib.Cryptography_add_osrandom_engine() assert res == 2
def test_add_engine_more_than_once(self): b = Binding() with pytest.raises(RuntimeError): b._register_osrandom_engine()
from treq.testing import StubTreq from OpenSSL import SSL from cryptography.hazmat.bindings.openssl.binding import Binding from .http_common import ( swissnum_auth_header, Secrets, get_content_type, CBOR_MIME_TYPE, get_spki_hash, ) from .common import si_b2a from ..util.hashutil import timing_safe_compare from ..util.deferredutil import async_to_deferred _OPENSSL = Binding().lib def _encode_si(si): # type: (bytes) -> str """Encode the storage index into Unicode string.""" return str(si_b2a(si), "ascii") class ClientException(Exception): """An unexpected response code from the server.""" def __init__(self, code, *additional_args): Exception.__init__(self, code, *additional_args) self.code = code # Schemas for server responses.