1
0
mirror of synced 2025-11-03 19:53:13 +03:00
This commit is contained in:
yhirose
2025-10-25 21:36:53 -04:00
parent 08133b593b
commit afa88dbe70
2 changed files with 257 additions and 2 deletions

View File

@@ -1954,14 +1954,17 @@ public:
void update_certs(X509 *cert, EVP_PKEY *private_key,
X509_STORE *client_ca_cert_store = nullptr);
int ssl_last_error() const { return last_ssl_error_; }
private:
bool process_and_close_socket(socket_t sock) override;
STACK_OF(X509_NAME) * extract_ca_names_from_x509_store(X509_STORE *store);
SSL_CTX *ctx_;
std::mutex ctx_mutex_;
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
int last_ssl_error_ = 0;
#endif
};
class SSLClient final : public ClientImpl {
@@ -10716,6 +10719,19 @@ inline SSLServer::SSLServer(const char *cert_path, const char *private_key_path,
SSL_CTX_load_verify_locations(ctx_, client_ca_cert_file_path,
client_ca_cert_dir_path);
// Set client CA list to be sent to clients during TLS handshake
if (client_ca_cert_file_path) {
auto ca_list = SSL_load_client_CA_file(client_ca_cert_file_path);
if (ca_list != nullptr) {
SSL_CTX_set_client_CA_list(ctx_, ca_list);
} else {
// Failed to load client CA list, but we continue since
// SSL_CTX_load_verify_locations already succeeded and
// certificate verification will still work
last_ssl_error_ = static_cast<int>(ERR_get_error());
}
}
SSL_CTX_set_verify(
ctx_, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
}
@@ -10740,6 +10756,15 @@ inline SSLServer::SSLServer(X509 *cert, EVP_PKEY *private_key,
} else if (client_ca_cert_store) {
SSL_CTX_set_cert_store(ctx_, client_ca_cert_store);
// Extract CA names from the store and set them as the client CA list
auto ca_list = extract_ca_names_from_x509_store(client_ca_cert_store);
if (ca_list) {
SSL_CTX_set_client_CA_list(ctx_, ca_list);
} else {
// Failed to extract CA names, record the error
last_ssl_error_ = static_cast<int>(ERR_get_error());
}
SSL_CTX_set_verify(
ctx_, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
}
@@ -10820,6 +10845,44 @@ inline bool SSLServer::process_and_close_socket(socket_t sock) {
return ret;
}
inline STACK_OF(X509_NAME) * SSLServer::extract_ca_names_from_x509_store(
X509_STORE *store) {
if (!store) { return nullptr; }
auto ca_list = sk_X509_NAME_new_null();
if (!ca_list) { return nullptr; }
// Get all objects from the store
auto objs = X509_STORE_get0_objects(store);
if (!objs) {
sk_X509_NAME_free(ca_list);
return nullptr;
}
// Iterate through objects and extract certificate subject names
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 no names were extracted, free the list and return nullptr
if (sk_X509_NAME_num(ca_list) == 0) {
sk_X509_NAME_free(ca_list);
return nullptr;
}
return ca_list;
}
// SSL HTTP client implementation
inline SSLClient::SSLClient(const std::string &host)
: SSLClient(host, 443, std::string(), std::string()) {}