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
Exemple #2
0
 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)
Exemple #3
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.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
Exemple #4
0
    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()
Exemple #8
0
 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
Exemple #11
0
 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
Exemple #12
0
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
Exemple #14
0
    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
Exemple #18
0
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
Exemple #19
0
 def test_add_engine_more_than_once(self):
     b = Binding()
     b._register_osrandom_engine()
     assert b.lib.ERR_get_error() == 0
Exemple #20
0
 def test_binding_loads(self):
     binding = Binding()
     assert binding
     assert binding.lib
     assert binding.ffi
Exemple #21
0
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):
Exemple #22
0
def init_dtls():
    binding = Binding()
    binding.init_static_locks()
    SSL.Context._methods[0] = getattr(binding.lib, "DTLSv1_client_method")
Exemple #23
0
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)",
    )
Exemple #24
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
Exemple #26
0
 def test_add_engine_more_than_once(self):
     b = Binding()
     res = b.lib.Cryptography_add_osrandom_engine()
     assert res == 2
Exemple #27
0
 def test_add_engine_more_than_once(self):
     b = Binding()
     with pytest.raises(RuntimeError):
         b._register_osrandom_engine()
Exemple #28
0
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.