2 Angajamente bff54389c4 ... 2bb69e2b21

Autor SHA1 Permisiunea de a trimite mesaje. Dacă este dezactivată, utilizatorul nu va putea trimite nici un fel de mesaj Data
  yhirose 2bb69e2b21 Fix type casting for MbedTlsContext in SSLClientServerTest 2 săptămâni în urmă
  yhirose f10fa15f37 Add helper functions for client CA list management from PEM and X509_STORE 2 săptămâni în urmă
2 a modificat fișierele cu 86 adăugiri și 10 ștergeri
  1. 84 9
      httplib.h
  2. 2 1
      test/test.cc

+ 84 - 9
httplib.h

@@ -13598,6 +13598,72 @@ inline bool tls_update_server_cert(tls_ctx_t ctx, const char *cert_pem,
   return ret;
 }
 
+// Helper: Create client CA list from PEM string
+// Returns a new STACK_OF(X509_NAME)* or nullptr on failure
+// Caller takes ownership of returned list
+inline STACK_OF(X509_NAME) *
+    create_client_ca_list_from_pem(const char *ca_pem) {
+  if (!ca_pem) { return nullptr; }
+
+  auto ca_list = sk_X509_NAME_new_null();
+  if (!ca_list) { return nullptr; }
+
+  BIO *bio = BIO_new_mem_buf(ca_pem, -1);
+  if (!bio) {
+    sk_X509_NAME_pop_free(ca_list, X509_NAME_free);
+    return nullptr;
+  }
+
+  X509 *cert = nullptr;
+  while ((cert = PEM_read_bio_X509(bio, nullptr, nullptr, nullptr)) !=
+         nullptr) {
+    X509_NAME *name = X509_get_subject_name(cert);
+    if (name) { sk_X509_NAME_push(ca_list, X509_NAME_dup(name)); }
+    X509_free(cert);
+  }
+  BIO_free(bio);
+
+  return ca_list;
+}
+
+// Helper: Extract CA names from X509_STORE
+// Returns a new STACK_OF(X509_NAME)* or nullptr on failure
+// Caller takes ownership of returned list
+inline STACK_OF(X509_NAME) *
+    extract_client_ca_list_from_store(X509_STORE *store) {
+  if (!store) { return nullptr; }
+
+  auto ca_list = sk_X509_NAME_new_null();
+  if (!ca_list) { return nullptr; }
+
+  auto objs = X509_STORE_get0_objects(store);
+  if (!objs) {
+    sk_X509_NAME_free(ca_list);
+    return nullptr;
+  }
+
+  for (int i = 0; i < sk_X509_OBJECT_num(objs); i++) {
+    auto obj = sk_X509_OBJECT_value(objs, i);
+    if (X509_OBJECT_get_type(obj) == X509_LU_X509) {
+      auto cert = X509_OBJECT_get0_X509(obj);
+      if (cert) {
+        auto subject = X509_get_subject_name(cert);
+        if (subject) {
+          auto name_dup = X509_NAME_dup(subject);
+          if (name_dup) { sk_X509_NAME_push(ca_list, name_dup); }
+        }
+      }
+    }
+  }
+
+  if (sk_X509_NAME_num(ca_list) == 0) {
+    sk_X509_NAME_free(ca_list);
+    return nullptr;
+  }
+
+  return ca_list;
+}
+
 inline bool tls_update_server_client_ca(tls_ctx_t ctx, const char *ca_pem) {
   if (!ctx || !ca_pem) { return false; }
   auto ssl_ctx = static_cast<SSL_CTX *>(ctx);
@@ -13608,6 +13674,14 @@ inline bool tls_update_server_client_ca(tls_ctx_t ctx, const char *ca_pem) {
 
   // SSL_CTX_set_cert_store takes ownership
   SSL_CTX_set_cert_store(ssl_ctx, static_cast<X509_STORE *>(store));
+
+  // Set client CA list for client certificate request
+  auto ca_list = create_client_ca_list_from_pem(ca_pem);
+  if (ca_list) {
+    // SSL_CTX_set_client_CA_list takes ownership of ca_list
+    SSL_CTX_set_client_CA_list(ssl_ctx, ca_list);
+  }
+
   return true;
 }
 
@@ -13739,16 +13813,17 @@ inline tls_ctx_t create_server_context_from_x509(X509 *cert, EVP_PKEY *key,
   }
 
   if (client_ca_store) {
-    auto ca_pem = x509_store_to_pem(client_ca_store);
-    if (!ca_pem.empty()) {
-      auto ca_store = tls_create_ca_store(ca_pem.c_str(), ca_pem.size());
-      if (ca_store && tls_set_ca_store(ctx, ca_store)) {
-        tls_set_verify_client(ctx, true);
-      } else {
-        out_error = static_cast<int>(tls_get_error());
-      }
+    // Set cert store for verification (SSL_CTX_set_cert_store takes ownership)
+    SSL_CTX_set_cert_store(static_cast<SSL_CTX *>(ctx), client_ca_store);
+
+    // Extract and set client CA list directly from store (more efficient than
+    // PEM conversion)
+    auto ca_list = extract_client_ca_list_from_store(client_ca_store);
+    if (ca_list) {
+      SSL_CTX_set_client_CA_list(static_cast<SSL_CTX *>(ctx), ca_list);
     }
-    X509_STORE_free(client_ca_store);
+
+    tls_set_verify_client(ctx, true);
   }
 
   return ctx;

+ 2 - 1
test/test.cc

@@ -9246,7 +9246,8 @@ TEST(SSLClientServerTest, CustomizeServerSSLCtxMbedTLS) {
     callback_invoked = true;
 
     // Cast to MbedTlsContext* to access the ssl config
-    auto *mbedtls_ctx = static_cast<MbedTlsContext *>(ctx);
+    auto *mbedtls_ctx =
+        static_cast<httplib::detail::tls::MbedTlsContext *>(ctx);
     mbedtls_ssl_config *conf = &mbedtls_ctx->conf;
 
     // Use static variables to hold certificate data (simplified for test)