ソースを参照

Fix set_ca_cert_store() to skip system certs like set_ca_cert_path() (#2335)

Both APIs conceptually do the same thing: "use these CA certs for
verification." However, set_ca_cert_store() falls through to the else
branch in load_certs() where system certs are added to the user's
custom store, defeating the purpose of certificate pinning.

This change makes set_ca_cert_store() behave consistently with
set_ca_cert_path() by checking ca_cert_store_ before loading system
certificates.

Added test to verify system certs are not loaded when custom store is set.

Co-authored-by: Your <you@example.com>
Sung Po-Han 1 週間 前
コミット
c3fa06112b
2 ファイル変更22 行追加1 行削除
  1. 1 1
      httplib.h
  2. 21 0
      test/test.cc

+ 1 - 1
httplib.h

@@ -13095,7 +13095,7 @@ inline bool SSLClient::load_certs() {
         last_openssl_error_ = ERR_get_error();
         ret = false;
       }
-    } else {
+    } else if (!ca_cert_store_) {
       auto loaded = false;
 #ifdef _WIN32
       loaded =

+ 21 - 0
test/test.cc

@@ -9682,6 +9682,27 @@ TEST(SSLClientRedirectTest, CertFile) {
   ASSERT_EQ(StatusCode::OK_200, res->status);
 }
 
+// Test that set_ca_cert_store() skips system certs (consistent with
+// set_ca_cert_path behavior). When a custom cert store is set, only those certs
+// should be trusted - system certs should NOT be loaded.
+TEST(SSLClientTest, SetCaCertStoreSkipsSystemCerts_Online) {
+  // Load a specific cert that is NOT a system CA cert
+  std::string cert;
+  read_file(SERVER_CERT2_FILE, cert);
+
+  SSLClient cli("google.com");
+  cli.load_ca_cert_store(cert.c_str(), cert.size());
+  cli.enable_server_certificate_verification(true);
+
+  // This should FAIL because:
+  // 1. We loaded only SERVER_CERT2 (a test cert, not a CA for google.com)
+  // 2. System certs should NOT be loaded when custom store is set
+  // If system certs WERE loaded, this would succeed
+  auto res = cli.Get("/");
+  ASSERT_FALSE(res);
+  EXPECT_EQ(Error::SSLServerVerification, res.error());
+}
+
 TEST(MultipartFormDataTest, LargeData) {
   SSLServer svr(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE);