From 0fba6c7bdd3731fd0f7b7637daa9adfd5a0e72d6 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 30 Apr 2022 16:17:29 -0600 Subject: [PATCH] Ressurect the PoC of OpenSSL from Rust --- .circleci/build-wheel.sh | 4 +- .github/workflows/ci.yml | 16 +- pyproject.toml | 2 +- setup.py | 3 - src/_cffi_src/build_openssl.py | 15 ++ src/_cffi_src/utils.py | 7 + .../hazmat/bindings/_rust/_openssl.pyi | 4 + .../hazmat/bindings/openssl/binding.py | 18 ++- src/rust/Cargo.lock | 63 ++++++++ src/rust/Cargo.toml | 9 ++ src/rust/build.rs | 144 ++++++++++++++++++ src/rust/src/lib.rs | 26 ++++ tests/hazmat/backends/test_openssl_memleak.py | 54 ++++--- 13 files changed, 322 insertions(+), 43 deletions(-) create mode 100644 src/cryptography/hazmat/bindings/_rust/_openssl.pyi create mode 100644 src/rust/build.rs diff --git a/.circleci/build-wheel.sh b/.circleci/build-wheel.sh index d69e8c9213fe..1cd80487992b 100755 --- a/.circleci/build-wheel.sh +++ b/.circleci/build-wheel.sh @@ -23,8 +23,8 @@ if [[ "${PYBIN}" =~ $REGEX ]]; then PY_LIMITED_API="--py-limited-api=cp3${BASH_REMATCH[1]}" fi -LDFLAGS="-L/opt/pyca/cryptography/openssl/lib" \ - CFLAGS="-I/opt/pyca/cryptography/openssl/include -Wl,--exclude-libs,ALL" \ +OPENSSL_DIR="/opt/pyca/cryptography/openssl" \ + RUSTFLAGS="-Clink-arg=-Wl,--exclude-libs,ALL" \ ../../.venv/bin/python setup.py bdist_wheel "$PY_LIMITED_API" auditwheel repair --plat "${PLATFORM}" -w wheelhouse/ dist/cryptography*.whl diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b1a058dd1f07..cd1dcb4e5327 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,7 +40,7 @@ jobs: - {VERSION: "3.10", TOXENV: "py310", OPENSSL: {TYPE: "libressl", VERSION: "3.2.7"}} - {VERSION: "3.10", TOXENV: "py310", OPENSSL: {TYPE: "libressl", VERSION: "3.3.6"}} - {VERSION: "3.10", TOXENV: "py310", OPENSSL: {TYPE: "libressl", VERSION: "3.4.3"}} - - {VERSION: "3.10", TOXENV: "py310", OPENSSL: {TYPE: "libressl", VERSION: "3.5.2"}} + # - {VERSION: "3.10", TOXENV: "py310", OPENSSL: {TYPE: "libressl", VERSION: "3.5.2"}} - {VERSION: "3.11-dev", TOXENV: "py311"} - {VERSION: "3.10", TOXENV: "py310-randomorder"} # Latest commit on the master branch, as of April 29, 2022. @@ -115,8 +115,9 @@ jobs: if: matrix.PYTHON.OPENSSL && steps.ossl-cache.outputs.cache-hit != 'true' - name: Set CFLAGS/LDFLAGS run: | - echo "CFLAGS=${CFLAGS} -Werror=implicit-function-declaration -I${OSSL_PATH}/include" >> $GITHUB_ENV - echo "LDFLAGS=${LDFLAGS} -L${OSSL_PATH}/lib -L${OSSL_PATH}/lib64 -Wl,-rpath=${OSSL_PATH}/lib -Wl,-rpath=${OSSL_PATH}/lib64" >> $GITHUB_ENV + echo "OPENSSL_DIR=${OSSL_PATH}" >> $GITHUB_ENV + echo "CFLAGS=${CFLAGS} -Werror=implicit-function-declaration" >> $GITHUB_ENV + echo "RUSTFLAGS=-Clink-arg=-Wl,-rpath=${OSSL_PATH}/lib -Clink-arg=-Wl,-rpath=${OSSL_PATH}/lib64" >> $GITHUB_ENV if: matrix.PYTHON.OPENSSL - name: Tests run: | @@ -410,9 +411,9 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Tests run: | - CRYPTOGRAPHY_SUPPRESS_LINK_FLAGS=1 \ - LDFLAGS="${HOME}/openssl-macos-x86-64/lib/libcrypto.a ${HOME}/openssl-macos-x86-64/lib/libssl.a" \ - CFLAGS="-I${HOME}/openssl-macos-x86-64/include -Werror -Wno-error=deprecated-declarations -Wno-error=incompatible-pointer-types-discards-qualifiers -Wno-error=unused-function -Wno-error=unused-command-line-argument -mmacosx-version-min=10.10 -march=core2 $EXTRA_CFLAGS" \ + OPENSSL_DIR="${HOME}/openssl-macos-x86-64" \ + OPENSSL_STATIC=1 \ + CFLAGS="-Werror -Wno-error=deprecated-declarations -Wno-error=incompatible-pointer-types-discards-qualifiers -Wno-error=unused-function -Wno-error=unused-command-line-argument -mmacosx-version-min=10.10 -march=core2 $EXTRA_CFLAGS" \ tox -vvv -r -- --color=yes --wycheproof-root=wycheproof env: TOXENV: ${{ matrix.PYTHON.TOXENV }} @@ -475,8 +476,7 @@ jobs: - name: Download OpenSSL run: | python .github/workflows/download_openssl.py windows openssl-${{ matrix.WINDOWS.WINDOWS }} - echo "INCLUDE=C:/openssl-${{ matrix.WINDOWS.WINDOWS }}/include;$INCLUDE" >> $GITHUB_ENV - echo "LIB=C:/openssl-${{ matrix.WINDOWS.WINDOWS }}/lib;$LIB" >> $GITHUB_ENV + echo "OPENSSL_DIR=C:/openssl-${{ matrix.WINDOWS.WINDOWS }}" >> $GITHUB_ENV echo "CL=${{ matrix.PYTHON.CL_FLAGS }}" >> $GITHUB_ENV env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/pyproject.toml b/pyproject.toml index 4d5812907f0a..660490e889c8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,7 @@ warn_unused_ignores = true [[tool.mypy.overrides]] module = [ - "cryptography.hazmat.bindings._openssl", + "cryptography.hazmat.bindings._rust._openssl", "pretend" ] ignore_missing_imports = true diff --git a/setup.py b/setup.py index 432dd98f0ab6..00342cea6e1d 100644 --- a/setup.py +++ b/setup.py @@ -37,9 +37,6 @@ try: # See setup.cfg for most of the config metadata. setup( - cffi_modules=[ - "src/_cffi_src/build_openssl.py:ffi", - ], rust_extensions=[ RustExtension( "_rust", diff --git a/src/_cffi_src/build_openssl.py b/src/_cffi_src/build_openssl.py index c5ab3cb3c68f..15e0b8038e3f 100644 --- a/src/_cffi_src/build_openssl.py +++ b/src/_cffi_src/build_openssl.py @@ -4,6 +4,7 @@ import os +import platform import sys from distutils import dist from distutils.ccompiler import get_default_compiler @@ -112,3 +113,17 @@ def _extra_compile_args(platform): libraries=_get_openssl_libraries(sys.platform), extra_compile_args=_extra_compile_args(sys.platform), ) + +if __name__ == "__main__": + out_dir = os.getenv("OUT_DIR") + module_name, source, source_extension, kwds = ffi._assigned_source + c_file = os.path.join(out_dir, module_name + source_extension) + # Necessary because CFFI will ignore this if there's no declarations. + if platform.python_implementation() == "PyPy": + ffi.embedding_api( + """ + extern "Python" void Cryptography_unused(void); + """ + ) + ffi.embedding_init_code("") + ffi.emit_c_code(c_file) diff --git a/src/_cffi_src/utils.py b/src/_cffi_src/utils.py index 5afc084a3834..95b548b61d8e 100644 --- a/src/_cffi_src/utils.py +++ b/src/_cffi_src/utils.py @@ -4,6 +4,7 @@ import os +import platform import sys from distutils.ccompiler import new_compiler from distutils.dist import Distribution @@ -71,6 +72,12 @@ def build_ffi( verify_source += '\n#define CRYPTOGRAPHY_PACKAGE_VERSION "{}"'.format( about["__version__"] ) + if platform.python_implementation() == "PyPy": + verify_source += r""" +int Cryptography_make_openssl_module(void) { + return cffi_start_python(); +} +""" ffi.cdef(cdef_source) ffi.set_source( module_name, diff --git a/src/cryptography/hazmat/bindings/_rust/_openssl.pyi b/src/cryptography/hazmat/bindings/_rust/_openssl.pyi new file mode 100644 index 000000000000..45a9506e12c5 --- /dev/null +++ b/src/cryptography/hazmat/bindings/_rust/_openssl.pyi @@ -0,0 +1,4 @@ +import typing + +ffi = typing.Any +lib = typing.Any diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index 2b4c574b4c34..b5f94a7d1f78 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -11,7 +11,7 @@ import cryptography from cryptography import utils from cryptography.exceptions import InternalError -from cryptography.hazmat.bindings._openssl import ffi, lib +from cryptography.hazmat.bindings._rust import _openssl from cryptography.hazmat.bindings.openssl._conditional import CONDITIONAL_NAMES _OpenSSLErrorWithText = typing.NamedTuple( @@ -62,9 +62,9 @@ def _errors_with_text( ) -> 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) + buf = _openssl.ffi.new("char[]", 256) + _openssl.lib.ERR_error_string_n(err.code, buf, len(buf)) + err_text_reason: bytes = _openssl.ffi.string(buf) errors_with_text.append( _OpenSSLErrorWithText( @@ -120,7 +120,7 @@ class Binding: """ lib: typing.ClassVar = None - ffi = ffi + ffi = _openssl.ffi _lib_loaded = False _init_lock = threading.Lock() _legacy_provider: typing.Any = None @@ -161,7 +161,9 @@ def _register_osrandom_engine(cls): def _ensure_ffi_initialized(cls): with cls._init_lock: if not cls._lib_loaded: - cls.lib = build_conditional_library(lib, CONDITIONAL_NAMES) + cls.lib = build_conditional_library( + _openssl.lib, CONDITIONAL_NAMES + ) cls._lib_loaded = True cls._register_osrandom_engine() # As of OpenSSL 3.0.0 we must register a legacy cipher provider @@ -210,7 +212,9 @@ def _verify_package_version(version): # up later this code checks that the currently imported package and the # shared object that were loaded have the same version and raise an # ImportError if they do not - so_package_version = ffi.string(lib.CRYPTOGRAPHY_PACKAGE_VERSION) + so_package_version = _openssl.ffi.string( + _openssl.lib.CRYPTOGRAPHY_PACKAGE_VERSION + ) if version.encode("ascii") != so_package_version: raise ImportError( "The version of cryptography does not match the loaded " diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 67c49dfc3738..82aecaf587ef 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -53,6 +53,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "cc" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" + [[package]] name = "cfg-if" version = "1.0.0" @@ -76,13 +82,31 @@ name = "cryptography-rust" version = "0.1.0" dependencies = [ "asn1", + "cc", "chrono", "lazy_static", + "openssl", + "openssl-sys", "ouroboros", "pem", "pyo3", ] +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "indoc" version = "0.3.6" @@ -162,6 +186,33 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" +[[package]] +name = "openssl" +version = "0.10.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-sys", +] + +[[package]] +name = "openssl-sys" +version = "0.9.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb" +dependencies = [ + "autocfg", + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "ouroboros" version = "0.15.0" @@ -239,6 +290,12 @@ dependencies = [ "base64", ] +[[package]] +name = "pkg-config" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -385,6 +442,12 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "514672a55d7380da379785a4d70ca8386c8883ff7eaae877be4d2081cebe73d8" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.4" diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 4b5c06d9b669..8f8f1d6eb50b 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -12,6 +12,11 @@ asn1 = { version = "0.9.0", default-features = false, features = ["derive"] } pem = "1.0" chrono = { version = "0.4", default-features = false, features = ["alloc", "clock"] } ouroboros = "0.15" +openssl = "0.10.38" +openssl-sys = "0.9.72" + +[build-dependencies] +cc = "1.0.72" [features] extension-module = ["pyo3/extension-module"] @@ -24,3 +29,7 @@ crate-type = ["cdylib"] [profile.release] lto = "thin" overflow-checks = true + +[patch.crates-io] +openssl-sys = { git = "https://github.com/sfackler/rust-openssl.git" } +openssl = { git = "https://github.com/sfackler/rust-openssl.git" } diff --git a/src/rust/build.rs b/src/rust/build.rs new file mode 100644 index 000000000000..df494a3e8cf1 --- /dev/null +++ b/src/rust/build.rs @@ -0,0 +1,144 @@ +use std::env; +use std::io::Write; +use std::path::{Path, MAIN_SEPARATOR}; +use std::process::{Command, Stdio}; + +fn main() { + let target = env::var("TARGET").unwrap(); + let openssl_static = env::var("OPENSSL_STATIC") + .map(|x| x == "1") + .unwrap_or(false); + if target.contains("apple") && openssl_static { + // On (older) OSX we need to link against the clang runtime, + // which is hidden in some non-default path. + // + // More details at https://github.com/alexcrichton/curl-rust/issues/279. + if let Some(path) = macos_link_search_path() { + println!("cargo:rustc-link-lib=clang_rt.osx"); + println!("cargo:rustc-link-search={}", path); + } + } + + let out_dir = env::var("OUT_DIR").unwrap(); + // FIXME: maybe pyo3-build-config should provide a way to do this? + let python = env::var("PYO3_PYTHON").unwrap_or_else(|_| "python3".to_string()); + println!("cargo:rerun-if-changed=../_cffi_src/"); + let python_path = match env::var("PYTHONPATH") { + Ok(mut val) => { + if cfg!(target_os = "windows") { + val.push(';'); + } else { + val.push(':'); + } + val.push_str(&format!("..{}", MAIN_SEPARATOR)); + val + } + Err(_) => format!("..{}", MAIN_SEPARATOR), + }; + let output = Command::new(&python) + .env("PYTHONPATH", python_path) + .env("OUT_DIR", &out_dir) + .arg("../_cffi_src/build_openssl.py") + .output() + .expect("failed to execute build_openssl.py"); + if !output.status.success() { + panic!( + "failed to run build_openssl.py, stdout: \n{}\nstderr: \n{}\n", + String::from_utf8(output.stdout).unwrap(), + String::from_utf8(output.stderr).unwrap() + ); + } + + let python_impl = run_python_script( + &python, + "import platform; print(platform.python_implementation(), end='')", + ) + .unwrap(); + println!("cargo:rustc-cfg=python_implementation=\"{}\"", python_impl); + let python_include = run_python_script( + &python, + "import sysconfig; print(sysconfig.get_path('include'), end='')", + ) + .unwrap(); + let openssl_include = + std::env::var_os("DEP_OPENSSL_INCLUDE").expect("unable to find openssl include path"); + let openssl_c = Path::new(&out_dir).join("_openssl.c"); + + let mut build = cc::Build::new(); + build + .file(openssl_c) + .include(python_include) + .include(openssl_include) + .flag_if_supported("-Wconversion") + .flag_if_supported("-Wno-error=sign-conversion"); + + // Enable abi3 mode if we're not using PyPy. + if python_impl != "PyPy" { + // cp36 + build.define("Py_LIMITED_API", "0x030600f0"); + } + + if cfg!(windows) { + build.define("WIN32_LEAN_AND_MEAN", None); + } + + build.compile("_openssl.a"); +} + +/// Run a python script using the specified interpreter binary. +fn run_python_script(interpreter: impl AsRef, script: &str) -> Result { + let interpreter = interpreter.as_ref(); + let out = Command::new(interpreter) + .env("PYTHONIOENCODING", "utf-8") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::inherit()) + .spawn() + .and_then(|mut child| { + child + .stdin + .as_mut() + .expect("piped stdin") + .write_all(script.as_bytes())?; + child.wait_with_output() + }); + + match out { + Err(err) => Err(format!( + "failed to run the Python interpreter at {}: {}", + interpreter.display(), + err + )), + Ok(ok) if !ok.status.success() => Err(format!( + "Python script failed: {}", + String::from_utf8(ok.stderr).expect("failed to parse Python script stderr as utf-8") + )), + Ok(ok) => Ok( + String::from_utf8(ok.stdout).expect("failed to parse Python script stdout as utf-8") + ), + } +} + +fn macos_link_search_path() -> Option { + let output = Command::new("clang") + .arg("--print-search-dirs") + .output() + .ok()?; + if !output.status.success() { + println!( + "failed to run 'clang --print-search-dirs', continuing without a link search path" + ); + return None; + } + + let stdout = String::from_utf8_lossy(&output.stdout); + for line in stdout.lines() { + if line.contains("libraries: =") { + let path = line.split('=').nth(1)?; + return Some(format!("{}/lib/darwin", path)); + } + } + + println!("failed to determine link search path, continuing without it"); + None +} diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs index c5ff6a69f1b4..ec336960b0f7 100644 --- a/src/rust/src/lib.rs +++ b/src/rust/src/lib.rs @@ -4,12 +4,26 @@ #![deny(rust_2018_idioms)] +// Force linking of OpenSSL since we're not using it in Rust side yet +#[allow(unused_extern_crates)] +extern crate openssl_sys; + mod asn1; pub(crate) mod oid; mod x509; +use pyo3::FromPyPointer; use std::convert::TryInto; +#[cfg(python_implementation = "PyPy")] +extern "C" { + fn Cryptography_make_openssl_module() -> std::os::raw::c_int; +} +#[cfg(not(python_implementation = "PyPy"))] +extern "C" { + fn PyInit__openssl() -> *mut pyo3::ffi::PyObject; +} + /// Returns the value of the input with the most-significant-bit copied to all /// of the bits. fn duplicate_msb_to_all(a: u8) -> u8 { @@ -93,6 +107,18 @@ fn _rust(py: pyo3::Python<'_>, m: &pyo3::types::PyModule) -> pyo3::PyResult<()> crate::x509::ocsp_resp::add_to_module(ocsp_mod)?; m.add_submodule(ocsp_mod)?; + #[cfg(python_implementation = "PyPy")] + let openssl_mod = unsafe { + Cryptography_make_openssl_module(); + pyo3::types::PyModule::import(py, "_openssl")? + }; + #[cfg(not(python_implementation = "PyPy"))] + let openssl_mod = unsafe { + let ptr = PyInit__openssl(); + pyo3::types::PyModule::from_owned_ptr(py, ptr) + }; + m.add_submodule(openssl_mod)?; + Ok(()) } diff --git a/tests/hazmat/backends/test_openssl_memleak.py b/tests/hazmat/backends/test_openssl_memleak.py index 2605566bd555..b2863ee3fd3a 100644 --- a/tests/hazmat/backends/test_openssl_memleak.py +++ b/tests/hazmat/backends/test_openssl_memleak.py @@ -24,7 +24,7 @@ def main(argv): import cffi - from cryptography.hazmat.bindings._openssl import ffi, lib + from cryptography.hazmat.bindings._rust import _openssl heap = {} @@ -49,7 +49,9 @@ def symbolize_backtrace(trace): backtrace_ffi.string(symbols[i]).decode() for i in range(length) ] - lib.Cryptography_free_wrapper(symbols, backtrace_ffi.NULL, 0) + _openssl.lib.Cryptography_free_wrapper( + symbols, backtrace_ffi.NULL, 0 + ) return stack else: def backtrace(): @@ -58,27 +60,31 @@ def backtrace(): def symbolize_backtrace(trace): return None - @ffi.callback("void *(size_t, const char *, int)") + @_openssl.ffi.callback("void *(size_t, const char *, int)") def malloc(size, path, line): - ptr = lib.Cryptography_malloc_wrapper(size, path, line) + ptr = _openssl.lib.Cryptography_malloc_wrapper(size, path, line) heap[ptr] = (size, path, line, backtrace()) return ptr - @ffi.callback("void *(void *, size_t, const char *, int)") + @_openssl.ffi.callback("void *(void *, size_t, const char *, int)") def realloc(ptr, size, path, line): - if ptr != ffi.NULL: + if ptr != _openssl.ffi.NULL: del heap[ptr] - new_ptr = lib.Cryptography_realloc_wrapper(ptr, size, path, line) + new_ptr = _openssl.lib.Cryptography_realloc_wrapper( + ptr, size, path, line + ) heap[new_ptr] = (size, path, line, backtrace()) return new_ptr - @ffi.callback("void(void *, const char *, int)") + @_openssl.ffi.callback("void(void *, const char *, int)") def free(ptr, path, line): - if ptr != ffi.NULL: + if ptr != _openssl.ffi.NULL: del heap[ptr] - lib.Cryptography_free_wrapper(ptr, path, line) + _openssl.lib.Cryptography_free_wrapper(ptr, path, line) - result = lib.Cryptography_CRYPTO_set_mem_functions(malloc, realloc, free) + result = _openssl.lib.Cryptography_CRYPTO_set_mem_functions( + malloc, realloc, free + ) assert result == 1 # Trigger a bunch of initialization stuff. @@ -96,20 +102,24 @@ def free(ptr, path, line): gc.collect() gc.collect() - if lib.CRYPTOGRAPHY_OPENSSL_300_OR_GREATER: - lib.OSSL_PROVIDER_unload(backend._binding._legacy_provider) - lib.OSSL_PROVIDER_unload(backend._binding._default_provider) + if _openssl.lib.CRYPTOGRAPHY_OPENSSL_300_OR_GREATER: + _openssl.lib.OSSL_PROVIDER_unload(backend._binding._legacy_provider) + _openssl.lib.OSSL_PROVIDER_unload(backend._binding._default_provider) - if lib.Cryptography_HAS_OPENSSL_CLEANUP: - lib.OPENSSL_cleanup() + if _openssl.lib.Cryptography_HAS_OPENSSL_CLEANUP: + _openssl.lib.OPENSSL_cleanup() # Swap back to the original functions so that if OpenSSL tries to free # something from its atexit handle it won't be going through a Python # function, which will be deallocated when this function returns - result = lib.Cryptography_CRYPTO_set_mem_functions( - ffi.addressof(lib, "Cryptography_malloc_wrapper"), - ffi.addressof(lib, "Cryptography_realloc_wrapper"), - ffi.addressof(lib, "Cryptography_free_wrapper"), + result = _openssl.lib.Cryptography_CRYPTO_set_mem_functions( + _openssl.ffi.addressof( + _openssl.lib, "Cryptography_malloc_wrapper" + ), + _openssl.ffi.addressof( + _openssl.lib, "Cryptography_realloc_wrapper" + ), + _openssl.ffi.addressof(_openssl.lib, "Cryptography_free_wrapper"), ) assert result == 1 @@ -117,9 +127,9 @@ def free(ptr, path, line): if remaining: sys.stdout.write(json.dumps(dict( - (int(ffi.cast("size_t", ptr)), { + (int(_openssl.ffi.cast("size_t", ptr)), { "size": heap[ptr][0], - "path": ffi.string(heap[ptr][1]).decode(), + "path": _openssl.ffi.string(heap[ptr][1]).decode(), "line": heap[ptr][2], "backtrace": symbolize_backtrace(heap[ptr][3]), })