mirror of
https://github.com/yhirose/cpp-httplib
synced 2024-11-21 06:26:02 -07:00
support custom ssl ctx configuration for SSLServer (#1073)
This commit is contained in:
parent
c384be02c9
commit
b80aa7fee3
2 changed files with 83 additions and 0 deletions
14
httplib.h
14
httplib.h
|
@ -1364,6 +1364,9 @@ public:
|
|||
SSLServer(X509 *cert, EVP_PKEY *private_key,
|
||||
X509_STORE *client_ca_cert_store = nullptr);
|
||||
|
||||
SSLServer(
|
||||
const std::function<bool(SSL_CTX &ssl_ctx)> &setup_ssl_ctx_callback);
|
||||
|
||||
~SSLServer() override;
|
||||
|
||||
bool is_valid() const override;
|
||||
|
@ -7105,6 +7108,17 @@ inline SSLServer::SSLServer(X509 *cert, EVP_PKEY *private_key,
|
|||
}
|
||||
}
|
||||
|
||||
inline SSLServer::SSLServer(
|
||||
const std::function<bool(SSL_CTX &ssl_ctx)> &setup_ssl_ctx_callback) {
|
||||
ctx_ = SSL_CTX_new(TLS_method());
|
||||
if (ctx_) {
|
||||
if (!setup_ssl_ctx_callback(*ctx_)) {
|
||||
SSL_CTX_free(ctx_);
|
||||
ctx_ = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline SSLServer::~SSLServer() {
|
||||
if (ctx_) { SSL_CTX_free(ctx_); }
|
||||
}
|
||||
|
|
69
test/test.cc
69
test/test.cc
|
@ -4392,6 +4392,75 @@ TEST(SSLClientServerTest, SSLConnectTimeout) {
|
|||
svr.stop();
|
||||
t.join();
|
||||
}
|
||||
|
||||
TEST(SSLClientServerTest, CustomizeServerSSLCtx) {
|
||||
auto setup_ssl_ctx_callback = [](SSL_CTX &ssl_ctx) {
|
||||
SSL_CTX_set_options(&ssl_ctx, SSL_OP_NO_COMPRESSION);
|
||||
SSL_CTX_set_options(&ssl_ctx,
|
||||
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
|
||||
SSL_CTX_set_options(&ssl_ctx, SSL_OP_NO_SSLv2);
|
||||
SSL_CTX_set_options(&ssl_ctx, SSL_OP_NO_SSLv3);
|
||||
SSL_CTX_set_options(&ssl_ctx, SSL_OP_NO_TLSv1);
|
||||
SSL_CTX_set_options(&ssl_ctx, SSL_OP_NO_TLSv1_1);
|
||||
auto ciphers = "ECDHE-RSA-AES128-SHA256:"
|
||||
"ECDHE-DSS-AES128-SHA256:"
|
||||
"ECDHE-RSA-AES256-SHA256:"
|
||||
"ECDHE-DSS-AES256-SHA256:";
|
||||
SSL_CTX_set_cipher_list(&ssl_ctx, ciphers);
|
||||
if (SSL_CTX_use_certificate_chain_file(&ssl_ctx, SERVER_CERT_FILE) != 1 ||
|
||||
SSL_CTX_use_PrivateKey_file(&ssl_ctx, SERVER_PRIVATE_KEY_FILE,
|
||||
SSL_FILETYPE_PEM) != 1) {
|
||||
return false;
|
||||
}
|
||||
SSL_CTX_load_verify_locations(&ssl_ctx, CLIENT_CA_CERT_FILE,
|
||||
CLIENT_CA_CERT_DIR);
|
||||
SSL_CTX_set_verify(
|
||||
&ssl_ctx,
|
||||
SSL_VERIFY_PEER |
|
||||
SSL_VERIFY_FAIL_IF_NO_PEER_CERT, // SSL_VERIFY_CLIENT_ONCE,
|
||||
nullptr);
|
||||
return true;
|
||||
};
|
||||
SSLServer svr(setup_ssl_ctx_callback);
|
||||
ASSERT_TRUE(svr.is_valid());
|
||||
|
||||
svr.Get("/test", [&](const Request &req, Response &res) {
|
||||
res.set_content("test", "text/plain");
|
||||
svr.stop();
|
||||
ASSERT_TRUE(true);
|
||||
|
||||
auto peer_cert = SSL_get_peer_certificate(req.ssl);
|
||||
ASSERT_TRUE(peer_cert != nullptr);
|
||||
|
||||
auto subject_name = X509_get_subject_name(peer_cert);
|
||||
ASSERT_TRUE(subject_name != nullptr);
|
||||
|
||||
std::string common_name;
|
||||
{
|
||||
char name[BUFSIZ];
|
||||
auto name_len = X509_NAME_get_text_by_NID(subject_name, NID_commonName,
|
||||
name, sizeof(name));
|
||||
common_name.assign(name, static_cast<size_t>(name_len));
|
||||
}
|
||||
|
||||
EXPECT_EQ("Common Name", common_name);
|
||||
|
||||
X509_free(peer_cert);
|
||||
});
|
||||
|
||||
thread t = thread([&]() { ASSERT_TRUE(svr.listen(HOST, PORT)); });
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
|
||||
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);
|
||||
ASSERT_EQ(200, res->status);
|
||||
|
||||
t.join();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
|
|
Loading…
Reference in a new issue