From ab9dd8e2cfe7d62efe5ff8925fbef1de756a2fc2 Mon Sep 17 00:00:00 2001 From: Stefan Eissing Date: Thu, 20 Nov 2025 13:00:23 +0000 Subject: [PATCH] Merged /httpd/httpd/trunk:r1929514,1929883 Update mod_md to v2.6.6 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1929884 13f79535-47bb-0310-9956-ffa450edef68 --- STATUS | 8 -------- changes-entries/md_v2.6.5.txt | 9 +++++++++ changes-entries/md_v2.6.6.txt | 3 +++ docs/manual/mod/mod_md.xml | 17 +++++++++++++++++ modules/md/md_crypt.c | 10 +++++++--- modules/md/md_curl.c | 14 ++++++++------ modules/md/md_ocsp.c | 3 ++- modules/md/md_version.h | 4 ++-- modules/md/mod_md_config.c | 21 +++++++++++++++++++++ modules/md/mod_md_config.h | 1 + modules/md/mod_md_drive.c | 2 +- 11 files changed, 71 insertions(+), 21 deletions(-) create mode 100644 changes-entries/md_v2.6.5.txt create mode 100644 changes-entries/md_v2.6.6.txt Index: httpd-2.4.63/changes-entries/md_v2.6.5.txt =================================================================== --- /dev/null +++ httpd-2.4.63/changes-entries/md_v2.6.5.txt @@ -0,0 +1,9 @@ + *) mod_md: update to version 2.6.5 + - New directive `MDInitialDelay`, controlling how longer to wait after + a server restart before checking certificates for renewal. + [Michael Kaufmann] + - Hardening: when build with OpenSSL older than 1.0.2 or old libressl + versions, the parsing of ASN.1 time strings did not do a length check. + - Hardening: when reading back OCSP responses stored in the local JSON + store, missing 'valid' key led to uninitialized values, resulting in + wrong refresh behaviour. Index: httpd-2.4.63/changes-entries/md_v2.6.6.txt =================================================================== --- /dev/null +++ httpd-2.4.63/changes-entries/md_v2.6.6.txt @@ -0,0 +1,3 @@ + *) mod_md: update to version 2.6.6 + - Fix a small memory leak when using OpenSSL's BIGNUMs. [Theo Buehler] + - Fix reuse of curl easy handles by resetting them. [Michael Kaufmann] Index: httpd-2.4.63/modules/md/md_crypt.c =================================================================== --- httpd-2.4.63.orig/modules/md/md_crypt.c +++ httpd-2.4.63/modules/md/md_crypt.c @@ -198,7 +198,7 @@ static int pem_passwd(char *buf, int siz /* Get the apr time (micro seconds, since 1970) from an ASN1 time, as stored in X509 * certificates. OpenSSL now has a utility function, but other *SSL derivatives have - * not caughts up yet or chose to ignore. An alternative is implemented, we prefer + * not caught up yet or chose to ignore. An alternative is implemented, we prefer * however the *SSL to maintain such things. */ static apr_time_t md_asn1_time_get(const ASN1_TIME* time) @@ -212,6 +212,10 @@ static apr_time_t md_asn1_time_get(const const char* str = (const char*) time->data; apr_size_t i = 0; + if ((time->length < 12) || ( + (time->type == V_ASN1_GENERALIZEDTIME) && time->length < 16)) + return 0; + memset(&t, 0, sizeof(t)); if (time->type == V_ASN1_UTCTIME) {/* two digit year */ @@ -1188,7 +1192,7 @@ const char *md_cert_get_serial_number(co serial = BN_bn2hex(bn); s = apr_pstrdup(p, serial); OPENSSL_free((void*)serial); - OPENSSL_free((void*)bn); + BN_free(bn); } return s; } Index: httpd-2.4.63/modules/md/md_curl.c =================================================================== --- httpd-2.4.63.orig/modules/md/md_curl.c +++ httpd-2.4.63/modules/md/md_curl.c @@ -253,17 +253,19 @@ static apr_status_t internals_setup(md_h rv = APR_EGENERAL; goto leave; } - curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_cb); - curl_easy_setopt(curl, CURLOPT_HEADERDATA, NULL); - curl_easy_setopt(curl, CURLOPT_READFUNCTION, req_data_cb); - curl_easy_setopt(curl, CURLOPT_READDATA, NULL); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, resp_data_cb); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, NULL); } else { md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, req->pool, "reusing curl instance from http"); + curl_easy_reset(curl); } + curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_cb); + curl_easy_setopt(curl, CURLOPT_HEADERDATA, NULL); + curl_easy_setopt(curl, CURLOPT_READFUNCTION, req_data_cb); + curl_easy_setopt(curl, CURLOPT_READDATA, NULL); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, resp_data_cb); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, NULL); + internals = apr_pcalloc(req->pool, sizeof(*internals)); internals->curl = curl; Index: httpd-2.4.63/modules/md/md_ocsp.c =================================================================== --- httpd-2.4.63.orig/modules/md/md_ocsp.c +++ httpd-2.4.63/modules/md/md_ocsp.c @@ -190,6 +190,7 @@ static apr_status_t ostat_from_json(md_o md_timeperiod_t valid; apr_status_t rv = APR_ENOENT; + memset(&valid, 0, sizeof(valid)); memset(resp_der, 0, sizeof(*resp_der)); memset(resp_valid, 0, sizeof(*resp_valid)); s = md_json_dups(p, json, MD_KEY_VALID, MD_KEY_FROM, NULL); @@ -531,7 +532,7 @@ static const char *certid_summary(const bn = ASN1_INTEGER_to_BN(aserial, NULL); s = BN_bn2hex(bn); serial = apr_pstrdup(p, s); - OPENSSL_free((void*)bn); + BN_free(bn); OPENSSL_free((void*)s); } return apr_psprintf(p, "certid[der=%s, issuer=%s, key=%s, serial=%s]", Index: httpd-2.4.63/modules/md/mod_md_config.c =================================================================== --- httpd-2.4.63.orig/modules/md/mod_md_config.c +++ httpd-2.4.63/modules/md/mod_md_config.c @@ -84,6 +84,7 @@ static md_mod_conf_t defmc = { "crt.sh", /* default cert checker site name */ "https://crt.sh?q=", /* default cert checker site url */ NULL, /* CA cert file to use */ + APR_TIME_C(0), /* initial cert check delay */ apr_time_from_sec(MD_SECS_PER_DAY/2), /* default time between cert checks */ apr_time_from_sec(5), /* minimum delay for retries */ 13, /* retry_failover after 14 errors, with 5s delay ~ half a day */ @@ -625,6 +626,24 @@ static const char *md_config_set_base_se return set_on_off(&config->mc->manage_base_server, value, cmd->pool); } +static const char *md_config_set_initial_delay(cmd_parms *cmd, void *dc, const char *value) +{ + md_srv_conf_t *config = md_config_get(cmd->server); + const char *err = md_conf_check_location(cmd, MD_LOC_NOT_MD); + apr_time_t delay; + + (void)dc; + if (err) return err; + if (md_duration_parse(&delay, value, "s") != APR_SUCCESS) { + return "unrecognized duration format"; + } + if (delay < 0) { + return "initial delay must not be negative"; + } + config->mc->initial_delay = delay; + return NULL; +} + static const char *md_config_set_check_interval(cmd_parms *cmd, void *dc, const char *value) { md_srv_conf_t *config = md_config_get(cmd->server); @@ -1323,6 +1342,8 @@ const command_rec md_cmds[] = { "Configure locking of store for updates."), AP_INIT_TAKE1("MDMatchNames", md_config_set_match_mode, NULL, RSRC_CONF, "Determines how DNS names are matched to vhosts."), + AP_INIT_TAKE1("MDInitialDelay", md_config_set_initial_delay, NULL, RSRC_CONF, + "How long to delay the first certificate check."), AP_INIT_TAKE1("MDCheckInterval", md_config_set_check_interval, NULL, RSRC_CONF, "Time between certificate checks."), AP_INIT_TAKE1(NULL, NULL, NULL, RSRC_CONF, NULL) Index: httpd-2.4.63/modules/md/mod_md_config.h =================================================================== --- httpd-2.4.63.orig/modules/md/mod_md_config.h +++ httpd-2.4.63/modules/md/mod_md_config.h @@ -75,6 +75,7 @@ struct md_mod_conf_t { const char *cert_check_name; /* name of the linked certificate check site */ const char *cert_check_url; /* url "template for" checking a certificate */ const char *ca_certs; /* root certificates to use for connections */ + apr_time_t initial_delay; /* how long to delay the first cert renewal check */ apr_time_t check_interval; /* duration between cert renewal checks */ apr_time_t min_delay; /* minimum delay for retries */ int retry_failover; /* number of errors to trigger CA failover */ Index: httpd-2.4.63/modules/md/mod_md_drive.c =================================================================== --- httpd-2.4.63.orig/modules/md/mod_md_drive.c +++ httpd-2.4.63/modules/md/mod_md_drive.c @@ -346,7 +346,7 @@ apr_status_t md_renew_start_watching(md_ "create md renew watchdog(%s)", MD_RENEW_WATCHDOG_NAME); return rv; } - rv = wd_register_callback(dctx->watchdog, 0, dctx, run_watchdog); + rv = wd_register_callback(dctx->watchdog, mc->initial_delay, dctx, run_watchdog); ap_log_error(APLOG_MARK, rv? APLOG_CRIT : APLOG_DEBUG, rv, s, APLOGNO(10067) "register md renew watchdog(%s)", MD_RENEW_WATCHDOG_NAME); return rv;