You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ic...@apache.org on 2025/05/30 12:45:59 UTC
svn commit: r1925979 - in /httpd/httpd/trunk: changes-entries/md_v2.5.2.txt modules/md/md_crypt.c modules/md/md_version.h modules/md/mod_md.c modules/md/mod_md_status.c
Author: icing
Date: Fri May 30 12:45:59 2025
New Revision: 1925979
URL: http://svn.apache.org/viewvc?rev=1925979&view=rev
Log:
*) mod_md: update to version 2.5.2
- Fixed TLS-ALPN-01 challenges when multiple `MDPrivateKeys` are specified
with EC keys before RSA ones. Fixes #377. [Stefan Eissing]
- Fixed missing newlines in the status page output. [Andreas Groth]
Added:
httpd/httpd/trunk/changes-entries/md_v2.5.2.txt
Modified:
httpd/httpd/trunk/modules/md/md_crypt.c
httpd/httpd/trunk/modules/md/md_version.h
httpd/httpd/trunk/modules/md/mod_md.c
httpd/httpd/trunk/modules/md/mod_md_status.c
Added: httpd/httpd/trunk/changes-entries/md_v2.5.2.txt
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/changes-entries/md_v2.5.2.txt?rev=1925979&view=auto
==============================================================================
--- httpd/httpd/trunk/changes-entries/md_v2.5.2.txt (added)
+++ httpd/httpd/trunk/changes-entries/md_v2.5.2.txt Fri May 30 12:45:59 2025
@@ -0,0 +1,4 @@
+ *) mod_md: update to version 2.5.2
+ - Fixed TLS-ALPN-01 challenges when multiple `MDPrivateKeys` are specified
+ with EC keys before RSA ones. Fixes #377. [Stefan Eissing]
+ - Fixed missing newlines in the status page output. [Andreas Groth]
Modified: httpd/httpd/trunk/modules/md/md_crypt.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/md_crypt.c?rev=1925979&r1=1925978&r2=1925979&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/md_crypt.c (original)
+++ httpd/httpd/trunk/modules/md/md_crypt.c Fri May 30 12:45:59 2025
@@ -69,6 +69,10 @@
#define MD_HAVE_CT 0
#endif
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#define MD_OPENSSL_10x
+#endif
+
static int initialized;
struct md_pkey_t {
@@ -257,9 +261,9 @@ static apr_time_t md_asn1_time_get(const
#endif
}
-apr_time_t md_asn1_generalized_time_get(void *ASN1_GENERALIZEDTIME)
+apr_time_t md_asn1_generalized_time_get(void *asn1_gtime)
{
- return md_asn1_time_get(ASN1_GENERALIZEDTIME);
+ return md_asn1_time_get(asn1_gtime);
}
/**************************************************************************************************/
@@ -566,7 +570,7 @@ static md_pkey_spec_t PkeySpecDef = { MD
md_pkey_spec_t *md_pkeys_spec_get(const md_pkeys_spec_t *pks, int index)
{
if (md_pkeys_spec_is_empty(pks)) {
- return index == 1? &PkeySpecDef : NULL;
+ return index == 0? &PkeySpecDef : NULL;
}
else if (pks && index >= 0 && index < pks->specs->nelts) {
return APR_ARRAY_IDX(pks->specs, index, md_pkey_spec_t*);
@@ -803,7 +807,11 @@ static apr_status_t check_EC_curve(int n
int rv = APR_ENOENT;
nc = EC_get_builtin_curves(NULL, 0);
+#ifdef MD_OPENSSL_10x
+ if (NULL == (curves = OPENSSL_malloc((int)(sizeof(*curves) * nc))) ||
+#else
if (NULL == (curves = OPENSSL_malloc(sizeof(*curves) * nc)) ||
+#endif
nc != EC_get_builtin_curves(curves, nc)) {
rv = APR_EGENERAL;
md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p,
@@ -1515,7 +1523,11 @@ apr_status_t md_cert_read_chain(apr_arra
md_cert_t *cert;
int added = 0;
+#ifdef MD_OPENSSL_10x
+ if (NULL == (bf = BIO_new_mem_buf((char *)pem, (int)pem_len))) {
+#else
if (NULL == (bf = BIO_new_mem_buf(pem, (int)pem_len))) {
+#endif
rv = APR_ENOMEM;
goto cleanup;
}
Modified: httpd/httpd/trunk/modules/md/md_version.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/md_version.h?rev=1925979&r1=1925978&r2=1925979&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/md_version.h (original)
+++ httpd/httpd/trunk/modules/md/md_version.h Fri May 30 12:45:59 2025
@@ -27,7 +27,7 @@
* @macro
* Version number of the md module as c string
*/
-#define MOD_MD_VERSION "2.5.1"
+#define MOD_MD_VERSION "2.5.2"
/**
* @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 0x020501
+#define MOD_MD_VERSION_NUM 0x020502
#define MD_ACME_DEF_URL "https://acme-v02.api.letsencrypt.org/directory"
#define MD_TAILSCALE_DEF_URL "file://localhost/var/run/tailscale/tailscaled.sock"
Modified: httpd/httpd/trunk/modules/md/mod_md.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/mod_md.c?rev=1925979&r1=1925978&r2=1925979&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/mod_md.c (original)
+++ httpd/httpd/trunk/modules/md/mod_md.c Fri May 30 12:45:59 2025
@@ -1292,55 +1292,95 @@ static int md_add_fallback_cert_files(se
return DECLINED;
}
-static int md_answer_challenge(conn_rec *c, const char *servername,
- const char **pcert_pem, const char **pkey_pem)
+static int md_get_challenge_cert(conn_rec *c, const char *servername,
+ md_srv_conf_t *sc,
+ md_pkey_type_t key_type,
+ const char **pcert_pem,
+ const char **pkey_pem)
{
- const char *protocol;
- int hook_rv = DECLINED;
apr_status_t rv = APR_ENOENT;
- md_srv_conf_t *sc;
- md_store_t *store;
+ int i;
char *cert_name, *pkey_name;
const char *cert_pem, *key_pem;
- int i;
-
- if (!servername
- || !(protocol = md_protocol_get(c))
- || strcmp(PROTO_ACME_TLS_1, protocol)) {
- goto cleanup;
- }
- sc = md_config_get(c->base_server);
- if (!sc || !sc->mc->reg) goto cleanup;
+ md_store_t *store = md_reg_store_get(sc->mc->reg);
+ md_pkey_spec_t *key_spec;
- ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
- "Answer challenge[tls-alpn-01] for %s", servername);
- store = md_reg_store_get(sc->mc->reg);
+ for (i = 0; i < md_pkeys_spec_count(sc->pks); i++) {
+ key_spec = md_pkeys_spec_get(sc->pks, i);
+ if (key_spec->type != key_type)
+ continue;
- for (i = 0; i < md_pkeys_spec_count( sc->pks ); i++) {
- tls_alpn01_fnames(c->pool, md_pkeys_spec_get(sc->pks,i),
- &pkey_name, &cert_name);
+ tls_alpn01_fnames(c->pool, key_spec, &pkey_name, &cert_name);
rv = md_store_load(store, MD_SG_CHALLENGES, servername, cert_name, MD_SV_TEXT,
(void**)&cert_pem, c->pool);
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, rv, c,
+ "Load challenge: cert %s", cert_name);
if (APR_STATUS_IS_ENOENT(rv)) continue;
if (APR_SUCCESS != rv) goto cleanup;
rv = md_store_load(store, MD_SG_CHALLENGES, servername, pkey_name, MD_SV_TEXT,
(void**)&key_pem, c->pool);
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, rv, c,
+ "Load challenge: key %s", pkey_name);
if (APR_STATUS_IS_ENOENT(rv)) continue;
if (APR_SUCCESS != rv) goto cleanup;
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
- "Found challenge cert %s, key %s for %s",
+ "Found challenge: cert %s, key %s for %s",
cert_name, pkey_name, servername);
*pcert_pem = cert_pem;
*pkey_pem = key_pem;
- hook_rv = OK;
- break;
+ return OK;
}
+cleanup:
+ return DECLINED;
+}
+
+static int md_answer_challenge(conn_rec *c, const char *servername,
+ const char **pcert_pem, const char **pkey_pem)
+{
+ const char *protocol;
+ int hook_rv = DECLINED;
+ md_srv_conf_t *sc;
+
+ *pcert_pem = *pkey_pem = NULL;
+
+ if (!servername
+ || !(protocol = md_protocol_get(c))
+ || strcmp(PROTO_ACME_TLS_1, protocol)) {
+ goto cleanup;
+ }
+ sc = md_config_get(c->base_server);
+ if (!sc || !sc->mc->reg) goto cleanup;
+
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
+ "Answer challenge[tls-alpn-01] for %s", servername);
+
+ /* A challenge for TLS-ALPN-01 used to have a single certificate,
+ * overriding the single fallback certificate already installed in
+ * the connections SSL* instance.
+ * Since the addition of `MDPrivateKeys`, there can be more than one,
+ * but the server API for a challenge cert can return only one. This
+ * is a short coming of the API.
+ * This means we cannot override all fallback certificates present, just
+ * a single one. If there is an RSA cert in fallback, we need to override
+ * that, because the ACME server has a preference for that (at least LE
+ * has). So we look for an RSA challenge cert first.
+ * The fallback is an EC cert and that works since without RSA challenges,
+ * there should also be no RSA fallbacks.
+ * Bit of a mess. */
+ hook_rv = md_get_challenge_cert(c, servername, sc, MD_PKEY_TYPE_DEFAULT,
+ pcert_pem, pkey_pem);
+ if (hook_rv == DECLINED)
+ hook_rv = md_get_challenge_cert(c, servername, sc, MD_PKEY_TYPE_RSA,
+ pcert_pem, pkey_pem);
+ if (hook_rv == DECLINED)
+ hook_rv = md_get_challenge_cert(c, servername, sc, MD_PKEY_TYPE_EC,
+ pcert_pem, pkey_pem);
if (DECLINED == hook_rv) {
- ap_log_cerror(APLOG_MARK, APLOG_INFO, rv, c, APLOGNO(10080)
+ ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, APLOGNO(10080)
"%s: unknown tls-alpn-01 challenge host", servername);
}
Modified: httpd/httpd/trunk/modules/md/mod_md_status.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/mod_md_status.c?rev=1925979&r1=1925978&r2=1925979&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/mod_md_status.c (original)
+++ httpd/httpd/trunk/modules/md/mod_md_status.c Fri May 30 12:45:59 2025
@@ -543,7 +543,7 @@ static void si_val_activity(status_ctx *
apr_brigade_puts(ctx->bb, NULL, NULL, "Pending");
}
else {
- apr_brigade_printf(ctx->bb, NULL, NULL, "%s: %s", ctx->prefix, "Pending");
+ apr_brigade_printf(ctx->bb, NULL, NULL, "%s: %s", ctx->prefix, "Pending\n");
}
}
else if (MD_RENEW_MANUAL == md_json_getl(mdj, MD_KEY_RENEW_MODE, NULL)) {
@@ -551,7 +551,7 @@ static void si_val_activity(status_ctx *
apr_brigade_puts(ctx->bb, NULL, NULL, "Manual renew");
}
else {
- apr_brigade_printf(ctx->bb, NULL, NULL, "%s: %s", ctx->prefix, "Manual renew");
+ apr_brigade_printf(ctx->bb, NULL, NULL, "%s: %s", ctx->prefix, "Manual renew\n");
}
}
if (!HTML_STATUS(ctx)) {