Skip to content

Commit

Permalink
Ressurect the PoC of OpenSSL from Rust
Browse files Browse the repository at this point in the history
  • Loading branch information
alex committed May 3, 2022
1 parent bf559c1 commit 5b47d24
Show file tree
Hide file tree
Showing 13 changed files with 341 additions and 42 deletions.
4 changes: 2 additions & 2 deletions .circleci/build-wheel.sh
Expand Up @@ -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
Expand Down
16 changes: 8 additions & 8 deletions .github/workflows/ci.yml
Expand Up @@ -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: |
Expand Down Expand Up @@ -303,7 +304,7 @@ jobs:
repository: "google/wycheproof"
path: "wycheproof"
ref: "master"
- run: python -m pip install tox coverage
- run: python -m pip install tox coverage cffi
- name: Tests
run: |
tox -vvv -r -- --color=yes --wycheproof-root=wycheproof
Expand Down Expand Up @@ -409,9 +410,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 }}
Expand Down Expand Up @@ -474,8 +475,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 }}
Expand Down
3 changes: 0 additions & 3 deletions setup.py
Expand Up @@ -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",
Expand Down
15 changes: 15 additions & 0 deletions src/_cffi_src/build_openssl.py
Expand Up @@ -4,6 +4,7 @@


import os
import platform
import sys
from distutils import dist
from distutils.ccompiler import get_default_compiler
Expand Down Expand Up @@ -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)
if platform.python_implementation() == "PyPy":
# Necessary because CFFI will ignore this if there's no declarations.
ffi.embedding_api(
"""
extern "Python" void Cryptography_unused(void);
"""
)
ffi.embedding_init_code("")
ffi.emit_c_code(c_file)
7 changes: 7 additions & 0 deletions src/_cffi_src/utils.py
Expand Up @@ -4,6 +4,7 @@


import os
import platform
import sys
from distutils.ccompiler import new_compiler
from distutils.dist import Distribution
Expand Down Expand Up @@ -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,
Expand Down
5 changes: 5 additions & 0 deletions src/cryptography/hazmat/bindings/_rust/openssl.pyi
@@ -0,0 +1,5 @@
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.

def openssl_version() -> int: ...
23 changes: 16 additions & 7 deletions src/cryptography/hazmat/bindings/openssl/binding.py
Expand Up @@ -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, openssl
from cryptography.hazmat.bindings.openssl._conditional import CONDITIONAL_NAMES

_OpenSSLErrorWithText = typing.NamedTuple(
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 "
Expand All @@ -222,6 +226,11 @@ def _verify_package_version(version):
)
)

_openssl_assert(
_openssl.lib,
_openssl.lib.OpenSSL_version_num() == openssl.openssl_version(),
)


_verify_package_version(cryptography.__version__)

Expand Down
75 changes: 75 additions & 0 deletions src/rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/rust/Cargo.toml
Expand Up @@ -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"]
Expand Down

0 comments on commit 5b47d24

Please sign in to comment.