Browse Source

Add optional private key password to SSLServer ctor (#1205)

Sebastien Blanchet 3 years ago
parent
commit
8191fd8e6c
4 changed files with 32 additions and 2 deletions
  1. 9 2
      httplib.h
  2. 2 0
      test/Makefile
  3. 7 0
      test/meson.build
  4. 14 0
      test/test.cc

+ 9 - 2
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) {

+ 2 - 0
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:

+ 7 - 0
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',

+ 14 - 0
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;