Skip to content

Make X509_VERIFY_PARAM exception-safe in verify()#38

Open
achamayou wants to merge 1 commit into
mainfrom
fix_verify_param_raii
Open

Make X509_VERIFY_PARAM exception-safe in verify()#38
achamayou wants to merge 1 commit into
mainfrom
fix_verify_param_raii

Conversation

@achamayou

Copy link
Copy Markdown
Member

Summary

In UqSTACK_OF_X509::verify() the verification parameters were held in a raw X509_VERIFY_PARAM*:

X509_VERIFY_PARAM* param = X509_VERIFY_PARAM_new();
...
CHECK1(X509_VERIFY_PARAM_set_flags(param, ...));   // can throw
...
X509_STORE_CTX_set0_param(store_ctx, param);       // ownership transfer

Two issues:

  • X509_VERIFY_PARAM_new() is not null-checked.
  • The CHECK1(...) calls between allocation and X509_STORE_CTX_set0_param can throw, and on that path param is leaked (ownership hasn't transferred yet).

In practice X509_VERIFY_PARAM_set_flags always returns 1, so this is latent rather than currently-triggerable, but the raw ownership is fragile.

Fix

  • Hold param in a std::unique_ptr with the X509_VERIFY_PARAM_free deleter so it is released on any throw.
  • CHECKNULL the allocation.
  • release() it into X509_STORE_CTX_set0_param once that call takes ownership.

No behavioral change.

Testing

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

Found during a security review of the codebase.

The verification parameters were held in a raw X509_VERIFY_PARAM* with two
problems: X509_VERIFY_PARAM_new() was not null-checked, and the CHECK1 calls
that follow can throw before ownership is transferred to the store context via
X509_STORE_CTX_set0_param, leaking the param.

Hold it in a unique_ptr (freed with X509_VERIFY_PARAM_free), CHECKNULL the
allocation, and release() it into set0_param once it takes ownership.
@achamayou achamayou requested a review from a team as a code owner June 12, 2026 22:31
@achamayou achamayou requested a review from Copilot June 13, 2026 06:38

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 makes UqSTACK_OF_X509::verify() exception-safe with respect to X509_VERIFY_PARAM lifetime management, ensuring the OpenSSL verification parameter object is always freed on error paths until ownership is explicitly transferred to the X509_STORE_CTX.

Changes:

  • Wrap X509_VERIFY_PARAM* in a std::unique_ptr with X509_VERIFY_PARAM_free deleter to prevent leaks on exceptions.
  • Add a CHECKNULL after allocation to guard against X509_VERIFY_PARAM_new() returning nullptr.
  • Transfer ownership safely via param_holder.release() when calling X509_STORE_CTX_set0_param.

💡 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