]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Merged /httpd/httpd/trunk:r1929514,1929883
authorStefan Eissing <icing@apache.org>
Thu, 20 Nov 2025 13:00:23 +0000 (13:00 +0000)
committerStefan Eissing <icing@apache.org>
Thu, 20 Nov 2025 13:00:23 +0000 (13:00 +0000)
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
changes-entries/md_v2.6.5.txt [new file with mode: 0644]
changes-entries/md_v2.6.6.txt [new file with mode: 0644]
docs/manual/mod/mod_md.xml
modules/md/md_crypt.c
modules/md/md_curl.c
modules/md/md_ocsp.c
modules/md/md_version.h
modules/md/mod_md_config.c
modules/md/mod_md_config.h
modules/md/mod_md_drive.c

diff --git a/STATUS b/STATUS
index 2235e387fa4b87b65e6ba17c622526c58625db61..f3b65d598c2d9e429890282e33c33e70e6d5dd61 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -183,14 +183,6 @@ PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
       svn merge -c 1924267 ^/httpd/httpd/trunk .
      +1: rpluem, jorton, covener 
 
-  *) mod_md: update to v2.6.5
-     Trunk version of patch:
-        https://svn.apache.org/r1929514
-     Backport version for 2.4.x of patch:
-      Trunk version of patch works
-      svn merge -c 1929514 ^/httpd/httpd/trunk .
-     +1: icing, covener, rpluem
-
   *) mod_http2: use nghttp2 supplied lengths when checking trailers.
      Trunk version of patch:
         https://svn.apache.org/r1929517
diff --git a/changes-entries/md_v2.6.5.txt b/changes-entries/md_v2.6.5.txt
new file mode 100644 (file)
index 0000000..796bb0e
--- /dev/null
@@ -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.
diff --git a/changes-entries/md_v2.6.6.txt b/changes-entries/md_v2.6.6.txt
new file mode 100644 (file)
index 0000000..700e0fb
--- /dev/null
@@ -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 db694c30498dbba156c5c1ac9c862201ca02586f..d35d32c5ca409988ef3a8026ef4968883511119e 100644 (file)
@@ -1582,4 +1582,21 @@ MDMessageCmd /etc/apache/md-message
             </p>
         </usage>
     </directivesynopsis>
+
+    <directivesynopsis>
+        <name>MDInitialDelay</name>
+        <description>How long to delay the first certificate check.</description>
+        <syntax>MDInitialDelay <var>duration</var></syntax>
+        <default>MDInitialDelay 0s</default>
+        <contextlist>
+            <context>server config</context>
+        </contextlist>
+        <compatibility>Available in version 2.4.66 and later</compatibility>
+        <usage>
+            <p>
+                The amount of time to wait after the server start to check
+                renewals of certificates. By default this occurs right away.
+            </p>
+        </usage>
+    </directivesynopsis>
 </modulesynopsis>
index 23a6fd118865b0186d7340c34ec7f463d01a0413..eef1268353921499d0fbc079e17441e0de97068d 100644 (file)
@@ -206,7 +206,7 @@ static int pem_passwd(char *buf, int size, int rwflag, void *baton)
 
 /* 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)
@@ -220,6 +220,10 @@ static apr_time_t md_asn1_time_get(const ASN1_TIME* time)
     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 */
@@ -1240,7 +1244,7 @@ const char *md_cert_get_serial_number(const md_cert_t *cert, apr_pool_t *p)
         serial = BN_bn2hex(bn);
         s = apr_pstrdup(p, serial);
         OPENSSL_free((void*)serial);
-        OPENSSL_free((void*)bn);
+        BN_free(bn);
     }
     return s;
 }
@@ -2250,7 +2254,7 @@ apr_status_t md_cert_get_ari_cert_id(const char **pari_cert_id,
     memset(&ser_buf, 0, sizeof(ser_buf));
     bn = ASN1_INTEGER_to_BN(serial, NULL);
     sder_len = BN_bn2bin(bn, sbuf);
-    OPENSSL_free((void*)bn);
+    BN_free(bn);
     if (sder_len < 1)
         return APR_EINVAL;
     ser_buf.len = (apr_size_t)sder_len;
index e6a37176e980e99c66a77c10cf3e1734c98ed54a..fac2ab8ec911f57ba74bc11e10be2c0a0f3ae5c2 100644 (file)
@@ -255,17 +255,19 @@ static apr_status_t internals_setup(md_http_request_t *req)
             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 af2dd15293686a234a7af65434adb8b80468901e..d2dfd73b68bc0f06ee792f1565f80255b26fd2e4 100644 (file)
@@ -190,6 +190,7 @@ static apr_status_t ostat_from_json(md_ocsp_cert_stat_t *pstat,
     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 OCSP_CERTID *certid, apr_pool_t *p)
         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 46a154432bb441bec092b326edee8569b199cc68..f977263dab14fbb9281b34d08e98b25b1c47da66 100644 (file)
@@ -27,7 +27,7 @@
  * @macro
  * Version number of the md module as c string
  */
-#define MOD_MD_VERSION "2.6.2"
+#define MOD_MD_VERSION "2.6.6"
 
 /**
  * @macro
@@ -35,7 +35,7 @@
  * release. This is a 24 bit number with 8 bits for major number, 8 bits
  * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
  */
-#define MOD_MD_VERSION_NUM 0x020602
+#define MOD_MD_VERSION_NUM 0x020606
 
 #define MD_ACME_DEF_URL         "https://acme-v02.api.letsencrypt.org/directory"
 
index 73292ef94f46bf06e4c6fd539525825e2485d2d1..d6807c9caf6b928e8060a5c6c0d3f30030870ac2 100644 (file)
@@ -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(30),     /* minimum delay for retries */
     13,                        /* retry_failover after 14 errors, with 5s delay ~ half a day */
@@ -676,6 +677,24 @@ static const char *md_config_set_base_server(cmd_parms *cmd, void *dc, const cha
     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);
@@ -1377,6 +1396,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("MDProfile", md_config_set_profile, NULL, RSRC_CONF,
index a2354354cc440da4752c8431edd6b760b1d002a4..3159ec651f7186d53862ad161592af08d6dcc5da 100644 (file)
@@ -78,6 +78,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 9dfa93a290caad8af9c78018c5c6311769c8b756..c5d710817c98c85d9e822c63eb8b785e02e01aad 100644 (file)
@@ -403,7 +403,7 @@ apr_status_t md_renew_start_watching(md_mod_conf_t *mc, server_rec *s, apr_pool_
                      "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;