Skip to content

Fix BIGNUM leak on error paths in EC public_jwk()#36

Open
achamayou wants to merge 1 commit into
mainfrom
fix_ec_bignum_leak
Open

Fix BIGNUM leak on error paths in EC public_jwk()#36
achamayou wants to merge 1 commit into
mainfrom
fix_ec_bignum_leak

Conversation

@achamayou

Copy link
Copy Markdown
Member

Summary

In the EC branch of UqX509::public_jwk(), the x and y coordinate BIGNUMs were raw pointers freed only at the very end via BN_free(x); BN_free(y);. Several throws sit between their allocation and that cleanup:

  • "unsupported EC key curve" (both the OpenSSL 3 and legacy paths),
  • the CHECK1(EVP_PKEY_get_group_name(...)) calls (OpenSSL 3 path),
  • the two "EC coordinate encoding failed" checks.

On any of those error paths the BIGNUMs leaked. It is not a security vulnerability, but a service repeatedly fed malformed EC certificates would leak unboundedly.

Fix

Use the existing UqBIGNUM RAII wrapper so the coordinates are freed on every exit path, including the throws:

  • OpenSSL 3 path: reuse pk.get_bn_param(...) (consistent with the RSA branch). As a bonus, this checks the return value, which the previous raw EVP_PKEY_get_bn_param calls ignored.
  • Legacy path: default-constructed UqBIGNUMs (which BN_new + null-check) passed to EC_POINT_get_affine_coordinates.
  • Remove the now-redundant trailing BN_free calls.

No behavioral change on the success path; the JWK output is identical.

Testing

  • cmake --build build — clean.
  • ctest — all tests pass (including TestEcJwkCoordinatePadding).
  • clang-tidy ../didx509cpp.h — exit 0, no findings (mirrors the CI step).

Found during a security review of the codebase.

In the EC branch of public_jwk(), the x and y coordinate BIGNUMs were raw
pointers freed only at the very end via BN_free. Several throws sit between
their allocation and that cleanup (unsupported curve, group-name lookup,
and the two coordinate-encoding checks), so on any of those error paths the
BIGNUMs leaked. A service repeatedly fed malformed EC certificates would
leak unboundedly.

Use the existing UqBIGNUM RAII wrapper so the coordinates are freed on every
exit path. For OpenSSL 3 this reuses pk.get_bn_param() (consistent with the
RSA branch), which additionally checks the return value that the raw
EVP_PKEY_get_bn_param calls ignored. The legacy path uses default-constructed
UqBIGNUMs. The trailing manual BN_free calls are removed.
@achamayou achamayou requested a review from a team as a code owner June 12, 2026 22:20
@achamayou achamayou requested a review from Copilot June 12, 2026 22:21

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 pull request fixes a memory leak in UqX509::public_jwk() when exporting EC public keys to JWK by ensuring the x/y coordinate BIGNUMs are freed on all error/throw paths (not just on the success path).

Changes:

  • OpenSSL 3 EC path: replace raw BIGNUM* coordinate handling with UqBIGNUM via pk.get_bn_param(...) (checked return + RAII cleanup).
  • Legacy EC path: replace BN_new() raw pointers with default-constructed UqBIGNUM coordinates (RAII cleanup).
  • Remove redundant trailing BN_free(x/y) calls.

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

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