Skip to content

Commit d440316

Browse files
RainerSchielkeCEU\schielke
and
CEU\schielke
authored
New function SSLServer::update_certs. Allows to update certificates while server is running (yhirose#1827)
* New function SSLServer::update_certs. Allows to update certificates while server is running * New function SSLServer::update_certs. Added unit test --------- Co-authored-by: CEU\schielke <[email protected]>
1 parent 98cc1ec commit d440316

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

httplib.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1819,6 +1819,9 @@ class SSLServer : public Server {
18191819
bool is_valid() const override;
18201820

18211821
SSL_CTX *ssl_context() const;
1822+
1823+
void update_certs (X509 *cert, EVP_PKEY *private_key,
1824+
X509_STORE *client_ca_cert_store = nullptr);
18221825

18231826
private:
18241827
bool process_and_close_socket(socket_t sock) override;
@@ -8753,6 +8756,19 @@ inline bool SSLServer::is_valid() const { return ctx_; }
87538756

87548757
inline SSL_CTX *SSLServer::ssl_context() const { return ctx_; }
87558758

8759+
inline void SSLServer::update_certs (X509 *cert, EVP_PKEY *private_key,
8760+
X509_STORE *client_ca_cert_store) {
8761+
8762+
std::lock_guard<std::mutex> guard(ctx_mutex_);
8763+
8764+
SSL_CTX_use_certificate (ctx_, cert);
8765+
SSL_CTX_use_PrivateKey (ctx_, private_key);
8766+
8767+
if (client_ca_cert_store != nullptr) {
8768+
SSL_CTX_set_cert_store (ctx_, client_ca_cert_store);
8769+
}
8770+
}
8771+
87568772
inline bool SSLServer::process_and_close_socket(socket_t sock) {
87578773
auto ssl = detail::ssl_new(
87588774
sock, ctx_, ctx_mutex_,

test/test.cc

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1747,6 +1747,64 @@ TEST(BindServerTest, BindAndListenSeparatelySSLEncryptedKey) {
17471747
}
17481748
#endif
17491749

1750+
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
1751+
X509* readCertificate (const std::string& strFileName) {
1752+
std::ifstream inStream (strFileName);
1753+
std::string strCertPEM ((std::istreambuf_iterator<char>(inStream)), std::istreambuf_iterator<char>());
1754+
1755+
if (strCertPEM.empty ()) return (nullptr);
1756+
1757+
BIO* pbCert = BIO_new (BIO_s_mem ());
1758+
BIO_write (pbCert, strCertPEM.c_str (), (int)strCertPEM.size ());
1759+
X509* pCert = PEM_read_bio_X509 (pbCert, NULL, 0, NULL);
1760+
BIO_free (pbCert);
1761+
1762+
return (pCert);
1763+
}
1764+
1765+
EVP_PKEY* readPrivateKey (const std::string& strFileName) {
1766+
std::ifstream inStream (strFileName);
1767+
std::string strPrivateKeyPEM ((std::istreambuf_iterator<char>(inStream)), std::istreambuf_iterator<char>());
1768+
1769+
if (strPrivateKeyPEM.empty ()) return (nullptr);
1770+
1771+
BIO* pbPrivKey = BIO_new (BIO_s_mem ());
1772+
BIO_write (pbPrivKey, strPrivateKeyPEM.c_str (), (int) strPrivateKeyPEM.size ());
1773+
EVP_PKEY* pPrivateKey = PEM_read_bio_PrivateKey (pbPrivKey, NULL, NULL, NULL);
1774+
BIO_free (pbPrivKey);
1775+
1776+
return (pPrivateKey);
1777+
}
1778+
1779+
TEST(BindServerTest, UpdateCerts) {
1780+
SSLServer svr(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE, CLIENT_CA_CERT_FILE);
1781+
int port = svr.bind_to_any_port("0.0.0.0");
1782+
ASSERT_TRUE(svr.is_valid());
1783+
ASSERT_TRUE(port > 0);
1784+
1785+
X509* cert = readCertificate (SERVER_CERT_FILE);
1786+
X509* ca_cert = readCertificate (CLIENT_CA_CERT_FILE);
1787+
EVP_PKEY* key = readPrivateKey (SERVER_PRIVATE_KEY_FILE);
1788+
1789+
ASSERT_TRUE(cert != nullptr);
1790+
ASSERT_TRUE(ca_cert != nullptr);
1791+
ASSERT_TRUE(key != nullptr);
1792+
1793+
X509_STORE* cert_store = X509_STORE_new ();
1794+
1795+
X509_STORE_add_cert (cert_store, ca_cert);
1796+
1797+
svr.update_certs (cert, key, cert_store);
1798+
1799+
ASSERT_TRUE(svr.is_valid());
1800+
svr.stop();
1801+
1802+
X509_free (cert);
1803+
X509_free (ca_cert);
1804+
EVP_PKEY_free (key);
1805+
}
1806+
#endif
1807+
17501808
TEST(ErrorHandlerTest, ContentLength) {
17511809
Server svr;
17521810

0 commit comments

Comments
 (0)