Skip to content

Remove carry over of old buffers/sizes in EVP and X509 ext functions. - #11021

Open
kareem-wolfssl wants to merge 3 commits into
wolfSSL:masterfrom
kareem-wolfssl:zd22223
Open

Remove carry over of old buffers/sizes in EVP and X509 ext functions.#11021
kareem-wolfssl wants to merge 3 commits into
wolfSSL:masterfrom
kareem-wolfssl:zd22223

Conversation

@kareem-wolfssl

Copy link
Copy Markdown
Contributor

Description

Fixes zd#22223

Testing

Built in tests, added tests, provided reproducer

Checklist

  • added tests
  • updated/added doxygen
  • updated appropriate READMEs
  • Updated manual and documentation

@kareem-wolfssl kareem-wolfssl self-assigned this Jul 30, 2026
Copilot AI review requested due to automatic review settings July 30, 2026 22:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes issues where cached buffers/lengths from prior operations could be carried over in EVP_PKEY DER caching and X509 extension OID handling, potentially leading to incorrect sizing/overreads. It also adds targeted regression tests and a new certificate fixture to cover the reported edge cases (zd#22223).

Changes:

  • EVP: stop carrying forward prior cached DER data/length when repopulating RSA/ECC EVP_PKEY DER buffers.
  • X509 ext: stop carrying forward the canonical OID buffer when the extension’s OID in the certificate is shorter than the mapped NID’s canonical OID.
  • Add regression tests plus a new cert-ext-oid-collide.der fixture and catalog entry.

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
wolfcrypt/src/evp.c Clears/stops reusing stale cached DER buffers/sizes when repopulating EVP_PKEY DER for RSA/ECC.
src/x509.c Avoids copying/reusing old ASN1_OBJECT OID buffers when rebuilding extension OIDs from the certificate.
tests/api/test_ossl_x509_ext.h Registers new X509 extension regression test.
tests/api/test_ossl_x509_ext.c Adds regression test ensuring returned extension OIDs reflect the certificate’s OID encoding/size.
tests/api/test_evp_pkey.h Registers new EVP_PKEY DER “shrink” regression test.
tests/api/test_evp_pkey.c Adds regression coverage for DER cache resizing across RSA/PKCS#8/ECC public-only scenarios.
certs/test/include.am Distributes the new DER fixture in test artifacts.
certs/test/catalog.txt Documents the new fixture and its purpose.
Comments suppressed due to low confidence (1)

wolfcrypt/src/evp.c:9859

  • XFREE(pkey->pkey.ptr, ...) is unconditionally called here, unlike other branches in ECC_populate_EVP_PKEY which guard the free with a NULL check. Adding the guard improves portability in case the underlying allocator does not accept NULL frees.
                else {
                    XFREE(pkey->pkey.ptr, pkey->heap, DYNAMIC_TYPE_OPENSSL);
                    pkey->pkey.ptr = (char*)derBuf;
                }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/x509.c
Comment thread wolfcrypt/src/evp.c Outdated
Thanks to Kushal Khemka & Mayank Jangid (OpenSec Intelligence) for the report.

@dgarske dgarske left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Skoll Code Review

Scan type: reviewOverall recommendation: COMMENT
Findings: 7 total — 2 posted, 5 skipped
2 finding(s) posted as inline comments (see file-level comments below)

Posted findings

  • [Medium] ECC_populate_EVP_PKEY now keeps the previous key's cached DER on the serialization error pathwolfcrypt/src/evp.c:9848-9868
  • [Low] New test certificate has no generation recipe alongside the other cert-ext- certs* — certs/test/catalog.txt:15-20

Skipped findings

  • [Medium] New EC test arm is gated on the wrong curve macros (P-256 arm guarded by ECC_MIN_KEY_SZ = 521 / HAVE_ECC256)
  • [Medium] X509 OID-collision test asserts a value that also holds when the collision does not occur
  • [Low] Unused pem.h include added to tests/api/test_evp.c
  • [Low] Inconsistent NULL-check-before-XFREE across the three sites touched by this PR
  • [Info] Macro continuation formatting in TEST_OSSL_X509_EXT_DECLS

Review generated by Skoll

Comment thread wolfcrypt/src/evp.c
@@ -9840,25 +9847,17 @@ static int ECC_populate_EVP_PKEY(WOLFSSL_EVP_PKEY* pkey, WOLFSSL_EC_KEY *key)
}
else if (ecc->type == ECC_PUBLICKEY) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

🟠 [Medium] ECC_populate_EVP_PKEY now keeps the previous key's cached DER on the serialization error path

The rewritten ECC_PUBLICKEY branch changes the error-path semantics. Previously, when wc_EccPublicKeyToDer() failed the code did pkey->pkey.ptr = NULL; pkey->pkey_sz = 0;, so the EVP_PKEY was left with no cached DER. After this change, on that same failure only the newly allocated derBuf is freed and the old buffer/size are left in place. wolfSSL_EVP_PKEY_set1_EC_KEY() calls clearEVPPkeyKeys() (which does not touch pkey->pkey.ptr) and installs pkey->ecc = key before calling this function, so on failure the EVP_PKEY ends up with the NEW EC key but the OLD key's DER still cached in pkey->pkey.ptr/pkey->pkey_sz. Any caller that ignores the WOLFSSL_FAILURE return (or that later reads the cached DER via wolfSSL_EVP_PKEY_get_der(), i2d_*, EVP_PKEY_cmp(), wolfSSL_CTX_use_PrivateKey()) then silently operates on a different key rather than getting an error. It is not a memory-safety issue (size still matches the retained buffer), but it is exactly the stale-carry-over class of state this PR sets out to eliminate. Note also that this block does not reset pkey->pkcs8HeaderSz (pre-existing), so a PKCS#8-wrapped key followed by a public-only EC key leaves a stale non-zero header size next to a DER that has no PKCS#8 wrapper - worth handling while the block is being rewritten.

Fix: Free and NULL pkey->pkey.ptr (and zero pkey->pkey_sz) before/when the serialization fails so a failed EVP_PKEY_set1_EC_KEY() cannot leave a DER that decodes to the previously installed key. Mirrors the pkey->pkey_sz = 0; that was added to PopulateRSAEvpPkeyDer() in this same PR.

Comment thread certs/test/catalog.txt
set.
cert-ext-joi.pem:
Simple certificate that includes OIDs for JurisdictionOfIncorporation
cert-ext-oid-collide.der:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

🔵 [Low] New test certificate has no generation recipe alongside the other cert-ext- certs*

Every other certs/test/cert-ext-* artifact is produced by certs/test/gen-ext-certs.sh from a committed .cfg. cert-ext-oid-collide.der is committed as an opaque blob with no recipe; catalog.txt documents what it is (a 4-byte OID that hashes to the prime256v1 NID, invalid signature, parse-only) but not how to rebuild it. If wc_oid_sum() ever changes, no one can regenerate a colliding OID without redoing the analysis. (The certificate itself is fine for the test: wolfSSL_X509_load_certificate_file() parses with NO_VERIFY, so neither the bogus signature nor the 2029 notAfter matters.)

Fix: Add a generation recipe or document how the colliding OID was derived so the artifact is reproducible.

@dgarske dgarske left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.

4 participants