Example #1
0
def _openssl_assert(lib, ok):
    if not ok:
        errors = _consume_errors(lib)
        errors_with_text = []
        for err in errors:
            buf = ffi.new("char[]", 256)
            lib.ERR_error_string_n(err.code, buf, len(buf))
            err_text_reason = ffi.string(buf)

            errors_with_text.append(
                _OpenSSLErrorWithText(
                    err.code, err.lib, err.func, err.reason, err_text_reason
                )
            )

        raise InternalError(
            "Unknown OpenSSL error. This error is commonly encountered when "
            "another library is not cleaning up the OpenSSL error stack. If "
            "you are using cryptography with another library that uses "
            "OpenSSL try disabling it before reporting a bug. Otherwise "
            "please file an issue at https://github.com/pyca/cryptography/"
            "issues with information on how to reproduce "
            "this. ({0!r})".format(errors_with_text),
            errors_with_text
        )
Example #2
0
def _openssl_assert(lib, ok):
    if not ok:
        errors = _consume_errors(lib)
        errors_with_text = []
        for err in errors:
            buf = ffi.new("char[]", 256)
            lib.ERR_error_string_n(err.code, buf, len(buf))
            err_text_reason = ffi.string(buf)

            errors_with_text.append(
                _OpenSSLErrorWithText(
                    err.code, err.lib, err.func, err.reason, err_text_reason
                )
            )

        raise InternalError(
            "Unknown OpenSSL error. This error is commonly encountered when "
            "another library is not cleaning up the OpenSSL error stack. If "
            "you are using cryptography with another library that uses "
            "OpenSSL try disabling it before reporting a bug. Otherwise "
            "please file an issue at https://github.com/pyca/cryptography/"
            "issues with information on how to reproduce "
            "this. ({0!r})".format(errors_with_text),
            errors_with_text
        )
Example #3
0
def _errors_with_text(errors):
    errors_with_text = []
    for err in errors:
        buf = ffi.new("char[]", 256)
        lib.ERR_error_string_n(err.code, buf, len(buf))
        err_text_reason = ffi.string(buf)

        errors_with_text.append(
            _OpenSSLErrorWithText(err.code, err.lib, err.func, err.reason,
                                  err_text_reason))

    return errors_with_text
Example #4
0
def _errors_with_text(
    errors: typing.List[_OpenSSLError],
) -> typing.List[_OpenSSLErrorWithText]:
    errors_with_text = []
    for err in errors:
        buf = ffi.new("char[]", 256)
        lib.ERR_error_string_n(err.code, buf, len(buf))
        err_text_reason: bytes = ffi.string(buf)

        errors_with_text.append(
            _OpenSSLErrorWithText(err.code, err.lib, err.reason,
                                  err_text_reason))

    return errors_with_text
Example #5
0
def _consume_errors(lib):
    if not ok:
        errors = _consume_errors(lib)
        errors_with_text = []
        for err in errors:
            buf = ffi.new("char[]", 256)
            lib.ERR_error_string_n(err.code, buf, len(buf))
            err_text_reason = ffi.string(buf)
            err_text_reason = ffi.string(buf)

            errors_with_text.append(
                _OpenSSLErrorWithText(err.code, err.lib, err.func, err.reason,
                                      err_text_reason))

        raise InternalError(
            "xxx"
            "xxx"
            "this. ({0!r})".format(errors_with_text), errors_with_text)
Example #6
0
class Binding(object):
    """
    OpenSSL API wrapper.
    """
    lib = None
    ffi = ffi
    _lib_loaded = False
    _locks = None
    _lock_cb_handle = 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")
    _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):
        _openssl_assert(cls.lib, cls.lib.ERR_peek_error() == 0)

        engine = cls.lib.ENGINE_new()
        _openssl_assert(cls.lib, engine != cls.ffi.NULL)
        try:
            result = cls.lib.ENGINE_set_id(engine, cls._osrandom_engine_id)
            _openssl_assert(cls.lib, result == 1)
            result = cls.lib.ENGINE_set_name(engine, cls._osrandom_engine_name)
            _openssl_assert(cls.lib, result == 1)
            result = cls.lib.ENGINE_set_RAND(engine, cls._osrandom_method)
            _openssl_assert(cls.lib, result == 1)
            result = cls.lib.ENGINE_add(engine)
            if result != 1:
                errors = _consume_errors(cls.lib)
                _openssl_assert(
                    cls.lib,
                    errors[0].reason == cls.lib.ENGINE_R_CONFLICTING_ENGINE_ID)

        finally:
            result = cls.lib.ENGINE_free(engine)
            _openssl_assert(cls.lib, result == 1)

    @classmethod
    def _ensure_ffi_initialized(cls):
        with cls._init_lock:
            if not cls._lib_loaded:
                cls.lib = build_conditional_library(lib, CONDITIONAL_NAMES)
                cls._lib_loaded = True
                # initialize the SSL library
                cls.lib.SSL_library_init()
                # adds all ciphers/digests for EVP
                cls.lib.OpenSSL_add_all_algorithms()
                # loads error strings for libcrypto and libssl functions
                cls.lib.SSL_load_error_strings()
                cls._register_osrandom_engine()

    @classmethod
    def init_static_locks(cls):
        with cls._lock_init_lock:
            cls._ensure_ffi_initialized()

            if not cls._lock_cb_handle:
                cls._lock_cb_handle = cls.ffi.callback(
                    "void(int, int, const char *, int)", cls._lock_cb)

            # Use Python's implementation if available, importing _ssl triggers
            # the setup for this.
            __import__("_ssl")

            if cls.lib.CRYPTO_get_locking_callback() != cls.ffi.NULL:
                return

            # If nothing else has setup a locking callback already, we set up
            # our own
            num_locks = cls.lib.CRYPTO_num_locks()
            cls._locks = [threading.Lock() for n in range(num_locks)]

            cls.lib.CRYPTO_set_locking_callback(cls._lock_cb_handle)

    @classmethod
    def _lock_cb(cls, mode, n, file, line):
        lock = cls._locks[n]

        if mode & cls.lib.CRYPTO_LOCK:
            lock.acquire()
        elif mode & cls.lib.CRYPTO_UNLOCK:
            lock.release()
        else:
            raise RuntimeError(
                "Unknown lock mode {0}: lock={1}, file={2}, line={3}.".format(
                    mode, n, file, line))
Example #7
0
File: binding.py Project: DT021/wau
class Binding(object):
    """
    OpenSSL API wrapper.
    """
    lib = None
    ffi = ffi
    _lib_loaded = False
    _locks = None
    _lock_cb_handle = 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")
    _osrandom_method = ffi.new(
        "RAND_METHOD *",
        dict(bytes=_osrandom_rand_bytes,
             pseudorand=_osrandom_rand_bytes,
             status=_osrandom_rand_status))

    def __init__(self):
        self._ensure_ffi_initialized()

    @classmethod
    def _register_osrandom_engine(cls):
        assert cls.lib.ERR_peek_error() == 0
        looked_up_engine = cls.lib.ENGINE_by_id(cls._osrandom_engine_id)
        if looked_up_engine != ffi.NULL:
            raise RuntimeError("osrandom engine already registered")

        cls.lib.ERR_clear_error()

        engine = cls.lib.ENGINE_new()
        assert engine != cls.ffi.NULL
        try:
            result = cls.lib.ENGINE_set_id(engine, cls._osrandom_engine_id)
            assert result == 1
            result = cls.lib.ENGINE_set_name(engine, cls._osrandom_engine_name)
            assert result == 1
            result = cls.lib.ENGINE_set_RAND(engine, cls._osrandom_method)
            assert result == 1
            result = cls.lib.ENGINE_add(engine)
            assert result == 1
        finally:
            result = cls.lib.ENGINE_free(engine)
            assert result == 1

    @classmethod
    def _ensure_ffi_initialized(cls):
        with cls._init_lock:
            if not cls._lib_loaded:
                cls.lib = build_conditional_library(lib, CONDITIONAL_NAMES)
                cls._lib_loaded = True
                cls._register_osrandom_engine()

    @classmethod
    def init_static_locks(cls):
        with cls._lock_init_lock:
            cls._ensure_ffi_initialized()

            if not cls._lock_cb_handle:
                cls._lock_cb_handle = cls.ffi.callback(
                    "void(int, int, const char *, int)", cls._lock_cb)

            # Use Python's implementation if available, importing _ssl triggers
            # the setup for this.
            __import__("_ssl")

            if cls.lib.CRYPTO_get_locking_callback() != cls.ffi.NULL:
                return

            # If nothing else has setup a locking callback already, we set up
            # our own
            num_locks = cls.lib.CRYPTO_num_locks()
            cls._locks = [threading.Lock() for n in range(num_locks)]

            cls.lib.CRYPTO_set_locking_callback(cls._lock_cb_handle)

    @classmethod
    def _lock_cb(cls, mode, n, file, line):
        lock = cls._locks[n]

        if mode & cls.lib.CRYPTO_LOCK:
            lock.acquire()
        elif mode & cls.lib.CRYPTO_UNLOCK:
            lock.release()
        else:
            raise RuntimeError(
                "Unknown lock mode {0}: lock={1}, file={2}, line={3}.".format(
                    mode, n, file, line))
Example #8
0
class Binding(object):
    """
    OpenSSL API wrapper.
    """
    lib = None
    ffi = ffi
    _lib_loaded = False
    _init_lock = threading.Lock()
    _lock_init_lock = threading.Lock()

    _osrandom_engine_id = ffi.new("const char[]", b"osrandom")
    _osrandom_engine_name = ffi.new("const char[]", b"osrandom_engine")
    _osrandom_method = ffi.new(
        "RAND_METHOD *",
        dict(bytes=_osrandom_rand_bytes,
             pseudorand=_osrandom_rand_bytes,
             status=_osrandom_rand_status))

    def __init__(self):
        self._ensure_ffi_initialized()

    @classmethod
    def _register_osrandom_engine(cls):
        _openssl_assert(cls.lib, cls.lib.ERR_peek_error() == 0)

        engine = cls.lib.ENGINE_new()
        _openssl_assert(cls.lib, engine != cls.ffi.NULL)
        try:
            result = cls.lib.ENGINE_set_id(engine, cls._osrandom_engine_id)
            _openssl_assert(cls.lib, result == 1)
            result = cls.lib.ENGINE_set_name(engine, cls._osrandom_engine_name)
            _openssl_assert(cls.lib, result == 1)
            result = cls.lib.ENGINE_set_RAND(engine, cls._osrandom_method)
            _openssl_assert(cls.lib, result == 1)
            result = cls.lib.ENGINE_add(engine)
            if result != 1:
                errors = _consume_errors(cls.lib)
                _openssl_assert(
                    cls.lib,
                    errors[0].reason == cls.lib.ENGINE_R_CONFLICTING_ENGINE_ID)

        finally:
            result = cls.lib.ENGINE_free(engine)
            _openssl_assert(cls.lib, result == 1)

    @classmethod
    def _ensure_ffi_initialized(cls):
        with cls._init_lock:
            if not cls._lib_loaded:
                cls.lib = build_conditional_library(lib, CONDITIONAL_NAMES)
                cls._lib_loaded = True
                # initialize the SSL library
                cls.lib.SSL_library_init()
                # adds all ciphers/digests for EVP
                cls.lib.OpenSSL_add_all_algorithms()
                # loads error strings for libcrypto and libssl functions
                cls.lib.SSL_load_error_strings()
                cls._register_osrandom_engine()

    @classmethod
    def init_static_locks(cls):
        with cls._lock_init_lock:
            cls._ensure_ffi_initialized()
            # Use Python's implementation if available, importing _ssl triggers
            # the setup for this.
            __import__("_ssl")

            if cls.lib.CRYPTO_get_locking_callback() != cls.ffi.NULL:
                return

            # If nothing else has setup a locking callback already, we set up
            # our own
            res = lib._setup_ssl_threads()
            _openssl_assert(cls.lib, res == 1)