Keep a verify callback alive while a handshake runs it

Replacing a verify callback, as set_server_certificate_verifier() does,
deleted the one that a handshake on another thread could be running, on
OpenSSL and wolfSSL. Handshakes now share the callback and take their
reference under a lock, and SSLClient replaces it under the lock that
guards creating a session from its context.
This commit is contained in:
yhirose committed 2026-10-16 23:52:15 -04:00
1 parent c52881cb1f
commit 567e099361
2 files changed
+100 -12

No files matched your search

+48
View File
@@ -16884,6 +16884,54 @@ TEST(VerifyCallbackTest, VerifierStaysWithItsClient) {
EXPECT_GT(accepting_calls, 0);
}
// A verifier replaced while a handshake runs it lives until it returns.
TEST(VerifyCallbackTest, VerifierReplacedDuringHandshake) {
using namespace httplib::tls;
SSLServer svr(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE);
ASSERT_TRUE(svr.is_valid());
svr.Get("/test", [](const Request &, Response &res) {
res.set_content("ok", "text/plain");
});
auto port = svr.bind_to_any_port(HOST);
thread t([&]() { svr.listen_after_bind(); });
auto se = detail::scope_exit([&] {
svr.stop();
t.join();
});
svr.wait_until_ready();
SSLClient cli(HOST, port);
cli.enable_server_certificate_verification(false);
std::promise<void> entered;
std::promise<void> replaced;
auto replaced_future = replaced.get_future();
auto first_call = true;
// Long enough to live on the heap
std::string expected(64, 'v');
cli.set_server_certificate_verifier([&, expected](const VerifyContext &) {
if (first_call) {
first_call = false;
entered.set_value();
replaced_future.wait();
}
return expected == std::string(64, 'v');
});
thread request([&]() {
auto res = cli.Get("/test");
EXPECT_TRUE(res) << "Error: " << to_string(res.error());
});
entered.get_future().wait();
cli.set_server_certificate_verifier(
[](const VerifyContext &) { return true; });
replaced.set_value();
request.join();
}
// VerifyContext::session is the same handle the other tls:: functions take.
TEST(VerifyCallbackTest, SessionMatchesSessionVerifier) {
using namespace httplib::tls;