Skip to content

Fix local wolfSSL build compatibility and renew test certs - #73

Open
julek-wolfssl wants to merge 9 commits into
wolfSSL:masterfrom
julek-wolfssl:fenrir/20260924
Open

julek-wolfssl wants to merge 9 commits into
wolfSSL:masterfrom
julek-wolfssl:fenrir/20260924

Conversation

@julek-wolfssl

Copy link
Copy Markdown
Member
  • Reject or gracefully degrade against local wolfSSL builds missing features the extension assumed were present:
    • Require OPENSSL_ALL and match options.h macro names exactly instead of substring matching (F-13426)
    • Reject builds with NO_KEEP_PEER_CERT (F-11777)
    • Reject builds with NO_FILESYSTEM (F-12664)
    • Make CRL support optional, detecting HAVE_CRL and raising NotImplementedError from enable_crl()/load_crl_file() when absent (F-12663)
    • Free WOLFSSL_METHOD via a small XFREE helper instead of wolfSSL_Free, which isn't binary-compatible with WOLFSSL_STATIC_MEMORY/WOLFSSL_DEBUG_MEMORY builds (F-12662)
  • Tie the SSLSocket session lifetime to its Python object via ffi.gc, so close()/shutdown()/unwrap() no longer free the session while another thread is using it (F-11784)
  • Build bundled wolfSSL with -fPIC (not -fpic) on every Linux platform so linking the static lib into the shared extension works on non-x86 architectures like aarch64; add arm64 Linux to CI (F-10706)
  • Update expired test certificates (ca-cert.pem, server-cert.pem, client-cert.pem, crl.pem) from wolfSSL

ca-cert.pem, server-cert.pem and client-cert.pem expired on 2026-09-08.
Copy the renewed files from wolfSSL (92e76d46). The keys are unchanged
but the subject email is now facts@wolfssl.com, so crl.pem is replaced
with certs/crl/crl.pem from the same commit, which the new CA signs.
The static library is linked into the shared CFFI extension. Only x86
Linux got a PIC flag, so linking failed on other architectures such as
aarch64. Use -fPIC rather than -fpic, which has GOT size limits on some
architectures.

Run CI on arm64 Linux too. Use the checkout and setup-python versions
wolfcrypt-py already runs; the v3 actions predate the arm64 runners.
wolfSSL_ctrl(), SSL_set_mode() and SSL_OP_NO_TICKET are always bound
but only exist when wolfSSL is built with OPENSSL_ALL. Local builds
without it passed detection and then failed to compile. Detection also
used substring matching, so OPENSSL_EXTRA_X509_SMALL was taken for
OPENSSL_EXTRA. Match options.h macro names exactly and require
--enable-opensslall.
wolfSSL_get_peer_certificate() and wolfSSL_X509_get_subjectCN() are
always bound but only exist with KEEP_PEER_CERT. settings.h defines it
for OPENSSL_EXTRA builds unless NO_KEEP_PEER_CERT is set, so such local
builds passed detection and then failed to import. Reject them unless
KEEP_PEER_CERT is also defined.
The file based cert/key loading APIs (wolfSSL_CTX_use_PrivateKey_file(),
wolfSSL_CTX_load_verify_locations(),
wolfSSL_CTX_use_certificate_chain_file() and their OpenSSL names) are
always bound but only exist without NO_FILESYSTEM. Such local builds
passed detection and then failed to import. The Python API loads
certificates and keys only from files, so reject these builds.
wolfSSL_EnableCRL() and wolfSSL_LoadCRLFile() were always bound but only
exist with HAVE_CRL, which wolfSSL leaves off by default. Local builds
without it passed detection and then failed to import. Detect HAVE_CRL,
bind the CRL functions only when it is set, and make
SSLSocket.enable_crl() and load_crl_file() raise NotImplementedError
otherwise. The bundled build keeps --enable-crl. The client example test
passes -C when CRL support is absent.
wolfSSL_Free() takes extra arguments when wolfSSL is built with
WOLFSSL_STATIC_MEMORY or WOLFSSL_DEBUG_MEMORY, so the extension did not
compile against such a local build. A small C helper now frees the
method with XFREE, which follows the configured allocator. The private
wolfssl._ffi.lib.wolfSSL_Free binding is removed.
close(), shutdown() and unwrap() no longer free the WOLFSSL session
while another thread is inside a native call on it. The session is
wrapped with ffi.gc and freed when its last reference goes. Closing
drops the socket's reference, and each method keeps a local reference
for all its native calls, so a call running in another thread keeps the
session alive.
Copilot AI lite review requested due to automatic review settings September 28, 2026 16:51
@julek-wolfssl julek-wolfssl self-assigned this Sep 28, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

A critical closed-socket handling issue remains, and the regression test does not reject NULL session calls.

Review effort: Lite
Findings: 1 High severity · 1 Medium severity

Open (2)
What changed in this PR

Improves wolfSSL build compatibility, session lifetime safety, ARM64 portability, CI coverage, and test certificates.

Changes:

  • Adds feature detection, optional CRL support, and allocator-safe cleanup.
  • Uses ffi.gc for safer session lifetime management.
  • Adds -fPIC, ARM64 CI coverage, regression tests, and renewed certificates.
File Summary
wolfssl/​_methods.py Updates method deallocation.
wolfssl/​_build_ffi.py Adds feature checks, CRL handling, cleanup, and PIC builds.
wolfssl/​__init__.py Updates session ownership and closed-socket handling.
tests/​test_methods.py Tests method cleanup.
tests/​test_crl_support.py Tests optional CRL support.
tests/​test_close_race.py Tests concurrent session closing.
tests/​test_client_example.py Handles builds without CRL support.
tests/​test_build_ffi.py Tests build compatibility.
certs/​server-cert.pem Renews the server certificate.
certs/​crl.pem Renews the CRL.
certs/​client-cert.pem Renews the client certificate.
certs/​ca-cert.pem Renews the CA certificate.
.github/​workflows/​python-app.yml Adds ARM64 CI coverage.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread wolfssl/__init__.py
Comment thread tests/test_close_race.py Outdated
use_sni(), enable_crl(), load_crl_file() and add_peer() now go through
_check_closed() and raise ValueError instead of passing a NULL session
to wolfSSL. The close-race test now fails on any session call after
close, including ones with a NULL pointer.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Guard native_object access in SSLSocket.__del__() when initialization fails.

Review effort: Lite
Findings: None

Resolved since last review (2)
Previously missed (1)

In code that hasn't changed since last review

Medium severity Guard native_object access in __del__ after failed initialization

wolfssl/​__init__.py:522

__del__() can run after SSLSocket.__init__() raises before native_object is assigned (for example during context setup or getpeername()). This unconditional attribute access then raises AttributeError during finalization, producing an ignored destructor exception instead of safely doing nothing; retain a getattr guard here.

@julek-wolfssl

Copy link
Copy Markdown
Member Author

retest this please

1 similar comment
@julek-wolfssl

Copy link
Copy Markdown
Member Author

retest this please

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants