diff --git a/httplib.h b/httplib.h index 157a4b40..eeba6d51 100644 --- a/httplib.h +++ b/httplib.h @@ -21699,6 +21699,14 @@ inline int context_ex_data_index() { return index; } +// Each WOLFSSL points back to its WolfSSLSession, the session_t that every +// other tls:: function takes. +inline int session_ex_data_index() { + static const auto index = + wolfSSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr); + return index; +} + // wolfSSL verify callback wrapper inline int wolfssl_verify_callback(int preverify_ok, WOLFSSL_X509_STORE_CTX *x509_ctx) { @@ -21716,7 +21724,7 @@ inline int wolfssl_verify_callback(int preverify_ok, int err = wolfSSL_X509_STORE_CTX_get_error(x509_ctx); VerifyContext verify_ctx; - verify_ctx.session = static_cast(ssl); + verify_ctx.session = wolfSSL_get_ex_data(ssl, session_ex_data_index()); verify_ctx.cert = static_cast(cert); verify_ctx.depth = depth; verify_ctx.preverify_ok = (preverify_ok != 0); @@ -21997,6 +22005,12 @@ inline session_t create_session(ctx_t ctx, socket_t sock) { return nullptr; } + if (wolfSSL_set_ex_data(session->ssl, impl::session_ex_data_index(), + session) != WOLFSSL_SUCCESS) { + delete session; + return nullptr; + } + wolfSSL_set_fd(session->ssl, static_cast(sock)); return static_cast(session); diff --git a/test/test.cc b/test/test.cc index 695310f4..749f73c3 100644 --- a/test/test.cc +++ b/test/test.cc @@ -15706,6 +15706,46 @@ TEST(VerifyCallbackTest, VerifierStaysWithItsClient) { EXPECT_GT(accepting_calls, 0); } +// VerifyContext::session is the same handle the other tls:: functions take. +TEST(VerifyCallbackTest, SessionMatchesSessionVerifier) { + 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); + + session_t verifier_session = nullptr; + cli.set_server_certificate_verifier([&](const VerifyContext &ctx) { + verifier_session = ctx.session; + return true; + }); + + session_t session_verifier_session = nullptr; + cli.set_session_verifier([&](session_t session) { + session_verifier_session = session; + return SSLVerifierResponse::NoDecisionMade; + }); + + auto res = cli.Get("/test"); + ASSERT_TRUE(res) << "Error: " << to_string(res.error()); + EXPECT_NE(nullptr, verifier_session); + EXPECT_EQ(session_verifier_session, verifier_session); +} + TEST(TlsVerifyErrorTest, GetVerifyErrorString) { using httplib::tls::TlsError;