commit 686505608efc054236ee1c335da4a657548d5f33
parent 85865674789f115f29d0d47c09e01af7d4c8e37e
Author: Florian Dold <dold@taler.net>
Date: Sun, 9 Aug 2026 21:45:42 +0200
http: restore HTTPS trust-store discovery
Diffstat:
1 file changed, 65 insertions(+), 0 deletions(-)
diff --git a/quickjs/quickjs-http.c b/quickjs/quickjs-http.c
@@ -22,6 +22,7 @@
#include <strings.h>
#include <string.h>
#include <assert.h>
+#include <unistd.h>
#include "curl/multi.h"
#include "cutils.h"
@@ -75,6 +76,67 @@ static void init_curl_global_state(void)
curl_global_status = curl_global_init(CURL_GLOBAL_DEFAULT);
}
+static const char *
+find_system_ca_bundle(void)
+{
+ static const char * const candidates[] = {
+ "/etc/ssl/certs/ca-certificates.crt",
+ "/etc/pki/tls/certs/ca-bundle.crt",
+ "/usr/share/ssl/certs/ca-bundle.crt",
+ "/usr/local/share/certs/ca-root-nss.crt",
+ "/etc/ssl/cert.pem",
+ "/var/lib/ca-certificates/ca-bundle.pem",
+ NULL,
+ };
+
+ for (const char * const *candidate = candidates;
+ NULL != *candidate;
+ candidate++) {
+ if (0 == access(*candidate, R_OK)) {
+ return *candidate;
+ }
+ }
+ return NULL;
+}
+
+/**
+ * libcurl itself does not read the curl command-line tool's CA environment
+ * variables. Our minimal Meson curl build also has no configured default CA
+ * location, so reproduce curl's environment handling and then fall back to
+ * its standard Unix bundle search order.
+ */
+static CURLcode
+configure_ca_locations(CURL *curl)
+{
+ const char *ca_bundle = getenv("CURL_CA_BUNDLE");
+ const char *ca_path = NULL;
+
+ if (NULL == ca_bundle || '\0' == ca_bundle[0]) {
+ ca_bundle = getenv("SSL_CERT_FILE");
+ ca_path = getenv("SSL_CERT_DIR");
+ if (NULL != ca_bundle && '\0' == ca_bundle[0]) {
+ ca_bundle = NULL;
+ }
+ if (NULL != ca_path && '\0' == ca_path[0]) {
+ ca_path = NULL;
+ }
+ }
+ if (NULL == ca_bundle && NULL == ca_path) {
+ ca_bundle = find_system_ca_bundle();
+ }
+ if (NULL != ca_bundle) {
+ CURLcode result = curl_easy_setopt(curl, CURLOPT_CAINFO, ca_bundle);
+
+ if (CURLE_OK != result) {
+ return result;
+ }
+ }
+ if (NULL != ca_path) {
+ return curl_easy_setopt(curl, CURLOPT_CAPATH, ca_path);
+ }
+ return CURLE_OK;
+}
+
// Must only be called with locked client mutex
static void destroy_curl_request_state(struct CurlRequestState *crs)
{
@@ -281,6 +343,9 @@ create_impl(void *cls, struct JSHttpRequestInfo *req_info)
curl_easy_setopt(curl, CURLOPT_PROTOCOLS_STR, "http,https");
curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS_STR, "http,https");
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 10L);
+ if (CURLE_OK != configure_ca_locations(curl)) {
+ goto error;
+ }
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, curl_header_callback);
curl_easy_setopt(curl, CURLOPT_HEADERDATA, crs);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_cb);