diff --git a/httplib.h b/httplib.h index 89a6bab..1c0108d 100644 --- a/httplib.h +++ b/httplib.h @@ -1384,7 +1384,8 @@ class SSLServer : public Server { public: SSLServer(const char *cert_path, const char *private_key_path, const char *client_ca_cert_file_path = nullptr, - const char *client_ca_cert_dir_path = nullptr); + const char *client_ca_cert_dir_path = nullptr, + const char *private_key_password = nullptr); SSLServer(X509 *cert, EVP_PKEY *private_key, X509_STORE *client_ca_cert_store = nullptr); @@ -7250,7 +7251,8 @@ static SSLInit sslinit_; // SSL HTTP server implementation inline SSLServer::SSLServer(const char *cert_path, const char *private_key_path, const char *client_ca_cert_file_path, - const char *client_ca_cert_dir_path) { + const char *client_ca_cert_dir_path, + const char *private_key_password) { ctx_ = SSL_CTX_new(TLS_server_method()); if (ctx_) { @@ -7260,6 +7262,11 @@ inline SSLServer::SSLServer(const char *cert_path, const char *private_key_path, SSL_CTX_set_min_proto_version(ctx_, TLS1_1_VERSION); + // add default password callback before opening encrypted private key + if (private_key_password != nullptr && (private_key_password[0] != '\0') ) { + SSL_CTX_set_default_passwd_cb_userdata(ctx_, (char *)private_key_password); + } + if (SSL_CTX_use_certificate_chain_file(ctx_, cert_path) != 1 || SSL_CTX_use_PrivateKey_file(ctx_, private_key_path, SSL_FILETYPE_PEM) != 1) { diff --git a/test/Makefile b/test/Makefile index 3109f03..e75ab5b 100644 --- a/test/Makefile +++ b/test/Makefile @@ -65,6 +65,8 @@ cert.pem: openssl req -x509 -new -batch -config test.rootCA.conf -key rootCA.key.pem -days 1024 > rootCA.cert.pem openssl genrsa 2048 > client.key.pem openssl req -new -batch -config test.conf -key client.key.pem | openssl x509 -days 370 -req -CA rootCA.cert.pem -CAkey rootCA.key.pem -CAcreateserial > client.cert.pem + openssl genrsa -passout pass:test123! 2048 > key_encrypted.pem + openssl req -new -batch -config test.conf -key key_encrypted.pem | openssl x509 -days 3650 -req -signkey key_encrypted.pem > cert_encrypted.pem #c_rehash . clean: diff --git a/test/meson.build b/test/meson.build index 354e8c8..b53371f 100644 --- a/test/meson.build +++ b/test/meson.build @@ -33,6 +33,13 @@ cert2_pem = custom_target( command: [openssl, 'req', '-x509', '-config', test_conf, '-key', '@INPUT@', '-sha256', '-days', '3650', '-nodes', '-out', '@OUTPUT@', '-extensions', 'SAN'] ) +cert_encrypted_pem = custom_target( + 'cert_encrypted_pem', + input: key_encrypted_pem, + output: 'cert_encrypted.pem', + command: [openssl, 'req', '-x509', '-config', test_conf, '-key', '@INPUT@', '-sha256', '-days', '3650', '-nodes', '-out', '@OUTPUT@', '-extensions', 'SAN'] +) + rootca_key_pem = custom_target( 'rootca_key_pem', output: 'rootCA.key.pem', diff --git a/test/test.cc b/test/test.cc index ee4c685..e963c2d 100644 --- a/test/test.cc +++ b/test/test.cc @@ -18,6 +18,9 @@ #define CLIENT_CA_CERT_DIR "." #define CLIENT_CERT_FILE "./client.cert.pem" #define CLIENT_PRIVATE_KEY_FILE "./client.key.pem" +#define SERVER_ENCRYPTED_CERT_FILE "./cert_encrypted.pem" +#define SERVER_ENCRYPTED_PRIVATE_KEY_FILE "./key_encrypted.pem" +#define SERVER_ENCRYPTED_PRIVATE_KEY_PASS "test123!" using namespace std; using namespace httplib; @@ -1194,6 +1197,17 @@ TEST(BindServerTest, BindAndListenSeparatelySSL) { } #endif +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +TEST(BindServerTest, BindAndListenSeparatelySSLEncryptedKey) { + SSLServer svr(SERVER_ENCRYPTED_CERT_FILE, SERVER_ENCRYPTED_PRIVATE_KEY_FILE, nullptr, + nullptr, SERVER_ENCRYPTED_PRIVATE_KEY_PASS); + int port = svr.bind_to_any_port("0.0.0.0"); + ASSERT_TRUE(svr.is_valid()); + ASSERT_TRUE(port > 0); + svr.stop(); +} +#endif + TEST(ErrorHandlerTest, ContentLength) { Server svr;