Browse Source

[Fix] ca_cert_path/ce_cert_store lose (#1004)

When redirect from http to https, user setting for ca_cert will lose

issue: #1003
xxrl 4 years ago
parent
commit
52f5eb5980
2 changed files with 72 additions and 15 deletions
  1. 38 15
      httplib.h
  2. 34 0
      test/test.cc

+ 38 - 15
httplib.h

@@ -1036,6 +1036,12 @@ public:
   void set_proxy_digest_auth(const char *username, const char *password);
   void set_proxy_digest_auth(const char *username, const char *password);
 #endif
 #endif
 
 
+#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
+  void set_ca_cert_path(const char *ca_cert_file_path,
+                        const char *ca_cert_dir_path = nullptr);
+  void set_ca_cert_store(X509_STORE *ca_cert_store);
+#endif
+
 #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
 #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
   void enable_server_certificate_verification(bool enabled);
   void enable_server_certificate_verification(bool enabled);
 #endif
 #endif
@@ -1137,6 +1143,13 @@ protected:
   std::string proxy_digest_auth_password_;
   std::string proxy_digest_auth_password_;
 #endif
 #endif
 
 
+#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
+  std::string ca_cert_file_path_;
+  std::string ca_cert_dir_path_;
+
+  X509_STORE *ca_cert_store_ = nullptr;
+#endif
+
 #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
 #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
   bool server_certificate_verification_ = true;
   bool server_certificate_verification_ = true;
 #endif
 #endif
@@ -1415,9 +1428,6 @@ public:
 
 
   bool is_valid() const override;
   bool is_valid() const override;
 
 
-  void set_ca_cert_path(const char *ca_cert_file_path,
-                        const char *ca_cert_dir_path = nullptr);
-
   void set_ca_cert_store(X509_STORE *ca_cert_store);
   void set_ca_cert_store(X509_STORE *ca_cert_store);
 
 
   long get_openssl_verify_result() const;
   long get_openssl_verify_result() const;
@@ -1450,8 +1460,6 @@ private:
 
 
   std::vector<std::string> host_components_;
   std::vector<std::string> host_components_;
 
 
-  std::string ca_cert_file_path_;
-  std::string ca_cert_dir_path_;
   long verify_result_ = 0;
   long verify_result_ = 0;
 
 
   friend class ClientImpl;
   friend class ClientImpl;
@@ -5309,6 +5317,11 @@ inline void ClientImpl::copy_settings(const ClientImpl &rhs) {
   proxy_digest_auth_username_ = rhs.proxy_digest_auth_username_;
   proxy_digest_auth_username_ = rhs.proxy_digest_auth_username_;
   proxy_digest_auth_password_ = rhs.proxy_digest_auth_password_;
   proxy_digest_auth_password_ = rhs.proxy_digest_auth_password_;
 #endif
 #endif
+#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
+  ca_cert_file_path_ = rhs.ca_cert_file_path_;
+  ca_cert_dir_path_ = rhs.ca_cert_dir_path_;
+  ca_cert_store_ = rhs.ca_cert_store_;
+#endif
 #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
 #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
   server_certificate_verification_ = rhs.server_certificate_verification_;
   server_certificate_verification_ = rhs.server_certificate_verification_;
 #endif
 #endif
@@ -5604,6 +5617,9 @@ inline bool ClientImpl::redirect(Request &req, Response &res, Error &error) {
 #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
 #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
       SSLClient cli(next_host.c_str(), next_port);
       SSLClient cli(next_host.c_str(), next_port);
       cli.copy_settings(*this);
       cli.copy_settings(*this);
+      if (ca_cert_store_) {
+        cli.set_ca_cert_store(ca_cert_store_);
+      }
       return detail::redirect(cli, req, res, next_path, location, error);
       return detail::redirect(cli, req, res, next_path, location, error);
 #else
 #else
       return false;
       return false;
@@ -6511,6 +6527,20 @@ inline void ClientImpl::set_proxy_digest_auth(const char *username,
 }
 }
 #endif
 #endif
 
 
+#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
+inline void ClientImpl::set_ca_cert_path(const char *ca_cert_file_path,
+                                        const char *ca_cert_dir_path) {
+  if (ca_cert_file_path) { ca_cert_file_path_ = ca_cert_file_path; }
+  if (ca_cert_dir_path) { ca_cert_dir_path_ = ca_cert_dir_path; }
+}
+
+inline void ClientImpl::set_ca_cert_store(X509_STORE *ca_cert_store) {
+  if (ca_cert_store && ca_cert_store != ca_cert_store_) {
+    ca_cert_store_ = ca_cert_store;
+  }
+}
+#endif
+
 #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
 #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
 inline void ClientImpl::enable_server_certificate_verification(bool enabled) {
 inline void ClientImpl::enable_server_certificate_verification(bool enabled) {
   server_certificate_verification_ = enabled;
   server_certificate_verification_ = enabled;
@@ -6901,12 +6931,6 @@ inline SSLClient::~SSLClient() {
 
 
 inline bool SSLClient::is_valid() const { return ctx_; }
 inline bool SSLClient::is_valid() const { return ctx_; }
 
 
-inline void SSLClient::set_ca_cert_path(const char *ca_cert_file_path,
-                                        const char *ca_cert_dir_path) {
-  if (ca_cert_file_path) { ca_cert_file_path_ = ca_cert_file_path; }
-  if (ca_cert_dir_path) { ca_cert_dir_path_ = ca_cert_dir_path; }
-}
-
 inline void SSLClient::set_ca_cert_store(X509_STORE *ca_cert_store) {
 inline void SSLClient::set_ca_cert_store(X509_STORE *ca_cert_store) {
   if (ca_cert_store) {
   if (ca_cert_store) {
     if (ctx_) {
     if (ctx_) {
@@ -7649,15 +7673,14 @@ inline void Client::set_logger(Logger logger) { cli_->set_logger(logger); }
 #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
 #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
 inline void Client::set_ca_cert_path(const char *ca_cert_file_path,
 inline void Client::set_ca_cert_path(const char *ca_cert_file_path,
                                      const char *ca_cert_dir_path) {
                                      const char *ca_cert_dir_path) {
-  if (is_ssl_) {
-    static_cast<SSLClient &>(*cli_).set_ca_cert_path(ca_cert_file_path,
-                                                     ca_cert_dir_path);
-  }
+  cli_->set_ca_cert_path(ca_cert_file_path, ca_cert_dir_path);
 }
 }
 
 
 inline void Client::set_ca_cert_store(X509_STORE *ca_cert_store) {
 inline void Client::set_ca_cert_store(X509_STORE *ca_cert_store) {
   if (is_ssl_) {
   if (is_ssl_) {
     static_cast<SSLClient &>(*cli_).set_ca_cert_store(ca_cert_store);
     static_cast<SSLClient &>(*cli_).set_ca_cert_store(ca_cert_store);
+  } else {
+    cli_->set_ca_cert_store(ca_cert_store);
   }
   }
 }
 }
 
 

+ 34 - 0
test/test.cc

@@ -4456,4 +4456,38 @@ TEST(HttpsToHttpRedirectTest3, SimpleInterface) {
   ASSERT_TRUE(res);
   ASSERT_TRUE(res);
   EXPECT_EQ(200, res->status);
   EXPECT_EQ(200, res->status);
 }
 }
+
+TEST(HttpToHttpsRedirectTest, CertFile) {
+  Server svr;
+  ASSERT_TRUE(svr.is_valid());
+  svr.Get("/index", [&](const Request &, Response &res) {
+    res.set_redirect("https://127.0.0.1:1235/index");
+    svr.stop();
+  });
+
+  SSLServer ssl_svr(SERVER_CERT2_FILE, SERVER_PRIVATE_KEY_FILE);
+  ASSERT_TRUE(ssl_svr.is_valid());
+  ssl_svr.Get("/index", [&](const Request &, Response &res) {
+    res.set_content("test", "text/plain");
+    ssl_svr.stop();
+  });
+
+
+  thread t = thread([&]() { ASSERT_TRUE(svr.listen("127.0.0.1", PORT)); });
+  thread t2 = thread([&]() { ASSERT_TRUE(ssl_svr.listen("127.0.0.1", 1235)); });
+  std::this_thread::sleep_for(std::chrono::milliseconds(1));
+
+  Client cli("127.0.0.1", PORT);
+  cli.set_ca_cert_path(SERVER_CERT2_FILE);
+  cli.enable_server_certificate_verification(true);
+  cli.set_follow_location(true);
+  cli.set_connection_timeout(30);
+
+  auto res = cli.Get("/index");
+  ASSERT_TRUE(res);
+  ASSERT_EQ(200, res->status);
+
+  t.join();
+  t2.join();
+}
 #endif
 #endif