mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-10-19 11:19:36 +00:00
Reject a certificate whose verify callback throws
An exception from a verify callback unwound through the TLS library, which is C: OpenSSL leaked the objects of the handshake, and a server worker thread ended the process. It also left the handshake count that update_certs_pem() waits on raised, so with a task queue that caught the exception, every later update waited forever. Take the exception as a rejection, and lower the count on every way out of the handshake.
This commit is contained in:
1 parent
567e099361
commit
645bdab90e
2 files changed
+63
-7
No files matched your search
@@ -4933,6 +4933,46 @@ TEST(SSLClientServerTest, VerifyCallbackKeepsClientCertificateRequired) {
|
||||
EXPECT_EQ("ok", res->body);
|
||||
}
|
||||
|
||||
TEST(SSLClientServerTest, ThrowingVerifyCallbackRejectsTheCertificate) {
|
||||
SSLServer svr(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE, CLIENT_CA_CERT_FILE);
|
||||
ASSERT_TRUE(svr.is_valid());
|
||||
tls::set_verify_callback(svr.tls_context(),
|
||||
[](const tls::VerifyContext &) -> bool {
|
||||
throw std::runtime_error("verify");
|
||||
});
|
||||
svr.Get("/test", [](const Request &, Response &res) {
|
||||
res.set_content("ok", "text/plain");
|
||||
});
|
||||
|
||||
thread t = thread([&]() { ASSERT_TRUE(svr.listen(HOST, PORT)); });
|
||||
auto se = detail::scope_exit([&] {
|
||||
svr.stop();
|
||||
t.join();
|
||||
ASSERT_FALSE(svr.is_running());
|
||||
});
|
||||
svr.wait_until_ready();
|
||||
|
||||
auto get = [] {
|
||||
SSLClient cli(HOST, PORT, CLIENT_CERT_FILE, CLIENT_PRIVATE_KEY_FILE);
|
||||
cli.enable_server_certificate_verification(false);
|
||||
return cli.Get("/test");
|
||||
};
|
||||
EXPECT_FALSE(get());
|
||||
|
||||
// The handshake is over, so an update does not wait for it.
|
||||
std::string cert_pem, key_pem;
|
||||
read_file(SERVER_CERT_FILE, cert_pem);
|
||||
read_file(SERVER_PRIVATE_KEY_FILE, key_pem);
|
||||
EXPECT_TRUE(svr.update_certs_pem(cert_pem.c_str(), key_pem.c_str()));
|
||||
|
||||
tls::set_verify_callback(svr.tls_context(), [](const tls::VerifyContext &v) {
|
||||
return v.preverify_ok;
|
||||
});
|
||||
auto res = get();
|
||||
ASSERT_TRUE(res) << "Error: " << to_string(res.error());
|
||||
EXPECT_EQ("ok", res->body);
|
||||
}
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
// A client that resumes its session gets through, but not once the client CA
|
||||
// has changed, as a resumed session does not show the certificate again.
|
||||
|
||||
Reference in new issue
Block a user