Skip to content

fix(tls): wire up trust store and verify callback (#297)#309

Merged
mvandeberg merged 1 commit into
cppalliance:develop-2from
mvandeberg:pr/297-tls-trust-store
Jul 8, 2026
Merged

fix(tls): wire up trust store and verify callback (#297)#309
mvandeberg merged 1 commit into
cppalliance:develop-2from
mvandeberg:pr/297-tls-trust-store

Conversation

@mvandeberg

Copy link
Copy Markdown
Contributor

Corosio's TLS was disclosed as "not safe against the public internet": set_default_verify_paths() left an empty trust store and set_verify_callback() failed to link. This wires both up on the OpenSSL and WolfSSL backends and makes the verify callback genuinely usable and honest across backends.

Trust store:

  • Consume use_default_verify_paths and verify_paths in both backends (SSL_CTX_set_default_verify_paths / SSL_CTX_load_verify_locations; wolfSSL_CTX_load_system_CA_certs guarded by WOLFSSL_SYS_CA_CERTS, plus wolfSSL_CTX_load_verify_locations for directories).

Verify callback:

  • Define the previously declared-but-undefined set_verify_callback template (fixes the link error) and add the private impl setter.
  • verify_context gains certificate(), returning the DER of the cert under verification, populated natively in each backend (OpenSSL i2d_X509; WolfSSL store->certs[error_depth], no OPENSSL_EXTRA required). This is the portable primitive for certificate pinning.
  • OpenSSL invokes the callback per-cert including on success, so it can both relax and tighten verification. WolfSSL only invokes it on success when built with WOLFSSL_ALWAYS_VERIFY_CB (implied by --enable-opensslextra); on a minimal build a tightening callback would silently fail open, so a context carrying a callback instead fails the handshake with std::errc::function_not_supported rather than mislead.

Tests:

  • Shared testVerifyCallback covers the portable contract (override-accept, decline, DER inspection) with a callback_supported=false path asserting the fail-closed behavior.
  • testVerifyCallbackOnSuccess (on-success invocation, reject-valid-cert, content-based pinning) runs on OpenSSL and on capable WolfSSL builds.
  • OpenSSL add_verify_path (hashed dir) / set_default_verify_paths (SSL_CERT_FILE); WolfSSL add_verify_path (plain dir).

CI:

  • All vcpkg lanes already build a capable WolfSSL (the port hardcodes OPENSSL_EXTRA), so the full-parity path is exercised. A new "wolfssl-minimal" Linux lane uses a vcpkg overlay port with OPENSSL_EXTRA disabled to exercise the fail-closed path.

Docs:

  • Rewrite the set_verify_callback docstring and the TLS guide/tutorial pages to state the portable contract and the WolfSSL build requirement; fix the rotted tls_context_examples.cpp to compile against the real std::error_code API and demonstrate DER-based pinning.

@cppalliance-bot

cppalliance-bot commented Jul 7, 2026

Copy link
Copy Markdown

An automated preview of the documentation is available at https://309.corosio.prtest3.cppalliance.org/index.html

If more commits are pushed to the pull request, the docs will rebuild at the same URL.

2026-07-08 17:23:59 UTC

@mvandeberg mvandeberg force-pushed the pr/297-tls-trust-store branch 3 times, most recently from 26ca83e to c58c40d Compare July 8, 2026 16:19
Corosio's TLS was disclosed as "not safe against the public internet":
set_default_verify_paths() left an empty trust store and
set_verify_callback() failed to link. This wires both up on the OpenSSL
and WolfSSL backends and makes the verify callback genuinely usable and
honest across backends.

Trust store:
- Consume use_default_verify_paths and verify_paths in both backends
  (SSL_CTX_set_default_verify_paths / SSL_CTX_load_verify_locations;
  wolfSSL_CTX_load_system_CA_certs guarded by WOLFSSL_SYS_CA_CERTS, plus
  wolfSSL_CTX_load_verify_locations for directories).

Verify callback:
- Define the previously declared-but-undefined set_verify_callback
  template (fixes the link error) and add the private impl setter.
- verify_context gains certificate(), returning the DER of the cert under
  verification, populated natively in each backend (OpenSSL i2d_X509;
  WolfSSL store->certs[error_depth], no OPENSSL_EXTRA required). This is
  the portable primitive for certificate pinning.
- OpenSSL invokes the callback per-cert including on success, so it can
  both relax and tighten verification. WolfSSL only invokes it on success
  when built with WOLFSSL_ALWAYS_VERIFY_CB (implied by --enable-opensslextra);
  on a minimal build a tightening callback would silently fail open, so a
  context carrying a callback instead fails the handshake with
  std::errc::function_not_supported rather than mislead.

Tests:
- Shared testVerifyCallback covers the portable contract (override-accept,
  decline, DER inspection) with a callback_supported=false path asserting
  the fail-closed behavior.
- testVerifyCallbackOnSuccess (on-success invocation, reject-valid-cert,
  content-based pinning) runs on OpenSSL and on capable WolfSSL builds.
- OpenSSL add_verify_path (hashed dir) / set_default_verify_paths
  (SSL_CERT_FILE); WolfSSL add_verify_path (plain dir).

CI:
- All vcpkg lanes already build a capable WolfSSL (the port hardcodes
  OPENSSL_EXTRA), so the full-parity path is exercised. A new
  "wolfssl-minimal" Linux lane uses a vcpkg overlay port with
  OPENSSL_EXTRA disabled to exercise the fail-closed path.

Docs:
- Rewrite the set_verify_callback docstring and the TLS guide/tutorial
  pages to state the portable contract and the WolfSSL build requirement;
  fix the rotted tls_context_examples.cpp to compile against the real
  std::error_code API and demonstrate DER-based pinning.
@mvandeberg mvandeberg force-pushed the pr/297-tls-trust-store branch from c58c40d to d270715 Compare July 8, 2026 17:19
@mvandeberg mvandeberg marked this pull request as ready for review July 8, 2026 17:42
@mvandeberg mvandeberg merged commit 19d76f3 into cppalliance:develop-2 Jul 8, 2026
40 checks passed
@github-project-automation github-project-automation Bot moved this from Backlog to Done in Beast2 Jul 8, 2026
@codecov

codecov Bot commented Jul 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 77.89%. Comparing base (3dc32e8) to head (d270715).
⚠️ Report is 3 commits behind head on develop-2.

Additional details and impacted files

Impacted file tree graph

@@              Coverage Diff              @@
##           develop-2     #309      +/-   ##
=============================================
- Coverage      77.89%   77.89%   -0.01%     
=============================================
  Files             96       96              
  Lines           7140     7139       -1     
  Branches        1745     1744       -1     
=============================================
- Hits            5562     5561       -1     
  Misses          1076     1076              
  Partials         502      502              
Files with missing lines Coverage Δ
include/boost/corosio/tls_context.hpp 100.00% <ø> (ø)
include/boost/corosio/wolfssl_stream.hpp 55.55% <ø> (ø)
src/corosio/src/tls/context.cpp 46.90% <ø> (ø)
src/corosio/src/tls/detail/context_impl.hpp 100.00% <ø> (ø)
src/openssl/src/openssl_stream.cpp 57.66% <ø> (-0.10%) ⬇️
src/wolfssl/src/wolfssl_stream.cpp 62.83% <ø> (ø)

Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3dc32e8...d270715. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants