mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-10-19 11:19:36 +00:00
Derive the TLS verify mode from one place per backend
set_verify_client() and set_verify_callback() each set the verify mode on their own, and set_verify_callback() ignored whether the peer's certificate was required. A server that required client certificates therefore stopped requiring them as soon as a verify callback was set on its context (OpenSSL, Mbed TLS, wolfSSL) or set and then cleared again (OpenSSL, Mbed TLS). Compute the mode from "peer certificate required" and "callback set" in one helper per backend and call it from set_verify_client(), set_verify_callback() and the context constructors. The context now records that a client verifies the server by default, so clearing a callback on a client context restores that default. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WGAYpQgXt95LdDQcJYgjB8
This commit is contained in:
2 files changed
+109
-54
No files matched your search
@@ -14571,6 +14571,59 @@ TEST(SSLClientServerTest, ClientEncryptedCertPresent) {
|
||||
CLIENT_ENCRYPTED_PRIVATE_KEY_PASS);
|
||||
}
|
||||
|
||||
// A server that requires client certificates must keep requiring them after a
|
||||
// verify callback is set on its context, or set and then cleared again.
|
||||
void ClientCertStillRequired(bool clear_callback) {
|
||||
using namespace httplib::tls;
|
||||
|
||||
SSLServer svr(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE, CLIENT_CA_CERT_FILE,
|
||||
CLIENT_CA_CERT_DIR);
|
||||
ASSERT_TRUE(svr.is_valid());
|
||||
svr.Get("/test", [](const Request &, Response &res) {
|
||||
res.set_content("test", "text/plain");
|
||||
});
|
||||
|
||||
ASSERT_TRUE(set_verify_callback(svr.tls_context(),
|
||||
[](const VerifyContext &) { return true; }));
|
||||
if (clear_callback) {
|
||||
ASSERT_TRUE(set_verify_callback(svr.tls_context(), nullptr));
|
||||
}
|
||||
|
||||
auto port = svr.bind_to_any_port(HOST);
|
||||
ASSERT_LT(0, port);
|
||||
thread t = thread([&]() { svr.listen_after_bind(); });
|
||||
auto se = detail::scope_exit([&] {
|
||||
svr.stop();
|
||||
t.join();
|
||||
ASSERT_FALSE(svr.is_running());
|
||||
});
|
||||
svr.wait_until_ready();
|
||||
|
||||
{
|
||||
SSLClient cli(HOST, port);
|
||||
cli.enable_server_certificate_verification(false);
|
||||
cli.set_connection_timeout(30);
|
||||
EXPECT_FALSE(cli.Get("/test"));
|
||||
}
|
||||
|
||||
{
|
||||
SSLClient cli(HOST, port, CLIENT_CERT_FILE, CLIENT_PRIVATE_KEY_FILE);
|
||||
cli.enable_server_certificate_verification(false);
|
||||
cli.set_connection_timeout(30);
|
||||
auto res = cli.Get("/test");
|
||||
ASSERT_TRUE(res) << "Error: " << to_string(res.error());
|
||||
EXPECT_EQ(StatusCode::OK_200, res->status);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(SSLClientServerTest, ClientCertStillRequiredAfterVerifyCallbackSet) {
|
||||
ClientCertStillRequired(false);
|
||||
}
|
||||
|
||||
TEST(SSLClientServerTest, ClientCertStillRequiredAfterVerifyCallbackCleared) {
|
||||
ClientCertStillRequired(true);
|
||||
}
|
||||
|
||||
// PEM memory-based constructor tests (works with all TLS backends)
|
||||
void PemMemoryClientCertPresent(
|
||||
const std::string &client_cert_file,
|
||||
|
||||
Reference in new issue
Block a user