Refactor raw public key handling and legacy EVP_PKEY methods - #669
Refactor raw public key handling and legacy EVP_PKEY methods#669olszomal wants to merge 8 commits into
Conversation
|
Reviewed at 55c9aaf against master (8f8f9c4). The consolidation looks good and the SoftHSM suite is green on OpenSSL 3.6.3 (48 pass / 2 skip, identical to master), but I found two blockers that only show up outside the 3.x path. 1. Global RSA
|
| Environment | Result |
|---|---|
OpenSSL 3.6.3, --enable-strict, make check |
48 pass / 2 skip — same as master |
OpenSSL 1.1.0, build + rsa-evp-sign/rsa-pss-sign/rsa-oaep/rsa-keygen |
pass on both branches |
| OpenSSL 1.1.0, lifetime reproducer above | master 0, PR SIGSEGV |
LibreSSL 3.7.3, compile p11_pkey.c |
master OK, PR fails |
OpenSSL 3.6.3, direct libp11 Ed25519 EVP_DigestSign/Verify vs SoftHSM |
pass on both (new p11_rawkey.c path) |
./testall.sh |
stops at OpenSSL 1.0.2 — pre-existing on master too (OPENSSL_zalloc, X509_SIG_getm, OPENSSL_clear_free) |
Not covered: MSVC/Windows (Makefile.mak updated but not built), valgrind, ML-DSA/SLH-DSA/Falcon raw-key paths (no SoftHSM support), and thread-safety of the new global ecx_methods[]/rsa_pkey_method state (same unlocked pattern as master).
|
I’ve pushed another version of the refactoring with the changes discussed above. Could you please take another look and review it? |
|
Maintainer review — PR head Thanks for the rework — it addresses both blockers from my review at Previous blockers — resolved ✅
Finding 1 — must fix (new): unsynchronized cache construction publishes partially-built methods
if (state->method != NULL)
return state->method;
...
state->method = EVP_PKEY_meth_new(state->type, original_flags); /* published NOW */
EVP_PKEY_meth_copy(state->method, original_meth); /* filled LATER */
... EVP_PKEY_meth_set_sign(...) ...
Reproduced (head
This is new — base's builders assign a fully-constructed local only after returning, so base's window is a harmless duplicate-build/leak, never a half-built method. Please fix: build into a local and publish once under a lock — e.g. Finding 2 — must fix (pre-existing, but this PR extends it): OpenSSL frees the cached method at ENGINE destruction → use-after-free/double-freeOpenSSL teardown, verified identical in There is no copy and no refcount: Reproduced (standalone reproducer of the exact libp11 pattern, OpenSSL 3.5.7):
Reachability: Base has the same static-cache pattern for RSA/EC/Ed25519/Ed448 (same-pointer-per-cycle behavior reproduced there too), so this is pre-existing — but this PR is exactly the refactor that consolidates this path and adds X25519/X448 to it, so let's fix it here rather than carrying it forward. Please fix: scope the cache per ENGINE via Finding 3 — recommended (pre-existing code, newly activated): XDH derive has no all-zero shared-secret check
Please consider: after a successful derive, constant-time-compare the result against all-zero and fail the operation if it matches, mirroring OpenSSL; document the assumption that tokens perform RFC 7748 checks. What I liked
Action items
Happy to share the reproducers: standalone ENGINE cache-lifetime test, 64-thread race test, 200 ms |
Pull Request Type
Related Issue
Issue number: N/A
Scope of Changes
This PR consolidates raw public key handling into a shared module and reorganizes legacy OpenSSL
EVP_PKEY_METHODwrappers.It removes duplicated EdDSA, XDH and PQC key code, centralizes RSA and ECX method registration, reuses the existing
EVP_PKEYex-data association, and updates build files and tests for OpenSSL 3.x compatibility.Testing
Additional Notes
License Declaration