Skip to content

Commit a7d4342

Browse files
committed
Merge modules/md/md_version.h
*) 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] git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1926084 13f79535-47bb-0310-9956-ffa450edef68
1 parent 3c28d00 commit a7d4342

File tree

5 files changed

+88
-32
lines changed

5 files changed

+88
-32
lines changed

changes-entries/md_v2.5.2.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*) mod_md: update to version 2.5.2
2+
- Fixed TLS-ALPN-01 challenges when multiple `MDPrivateKeys` are specified
3+
with EC keys before RSA ones. Fixes #377. [Stefan Eissing]
4+
- Fixed missing newlines in the status page output. [Andreas Groth]

modules/md/md_crypt.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@
6969
#define MD_HAVE_CT 0
7070
#endif
7171

72+
#if OPENSSL_VERSION_NUMBER < 0x10100000L
73+
#define MD_OPENSSL_10x
74+
#endif
75+
7276
static int initialized;
7377

7478
struct md_pkey_t {
@@ -257,9 +261,9 @@ static apr_time_t md_asn1_time_get(const ASN1_TIME* time)
257261
#endif
258262
}
259263

260-
apr_time_t md_asn1_generalized_time_get(void *ASN1_GENERALIZEDTIME)
264+
apr_time_t md_asn1_generalized_time_get(void *asn1_gtime)
261265
{
262-
return md_asn1_time_get(ASN1_GENERALIZEDTIME);
266+
return md_asn1_time_get(asn1_gtime);
263267
}
264268

265269
/**************************************************************************************************/
@@ -566,7 +570,7 @@ static md_pkey_spec_t PkeySpecDef = { MD_PKEY_TYPE_DEFAULT, {{ 0 }} };
566570
md_pkey_spec_t *md_pkeys_spec_get(const md_pkeys_spec_t *pks, int index)
567571
{
568572
if (md_pkeys_spec_is_empty(pks)) {
569-
return index == 1? &PkeySpecDef : NULL;
573+
return index == 0? &PkeySpecDef : NULL;
570574
}
571575
else if (pks && index >= 0 && index < pks->specs->nelts) {
572576
return APR_ARRAY_IDX(pks->specs, index, md_pkey_spec_t*);
@@ -803,7 +807,11 @@ static apr_status_t check_EC_curve(int nid, apr_pool_t *p) {
803807
int rv = APR_ENOENT;
804808

805809
nc = EC_get_builtin_curves(NULL, 0);
810+
#ifdef MD_OPENSSL_10x
811+
if (NULL == (curves = OPENSSL_malloc((int)(sizeof(*curves) * nc))) ||
812+
#else
806813
if (NULL == (curves = OPENSSL_malloc(sizeof(*curves) * nc)) ||
814+
#endif
807815
nc != EC_get_builtin_curves(curves, nc)) {
808816
rv = APR_EGENERAL;
809817
md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p,
@@ -1515,7 +1523,11 @@ apr_status_t md_cert_read_chain(apr_array_header_t *chain, apr_pool_t *p,
15151523
md_cert_t *cert;
15161524
int added = 0;
15171525

1526+
#ifdef MD_OPENSSL_10x
1527+
if (NULL == (bf = BIO_new_mem_buf((char *)pem, (int)pem_len))) {
1528+
#else
15181529
if (NULL == (bf = BIO_new_mem_buf(pem, (int)pem_len))) {
1530+
#endif
15191531
rv = APR_ENOMEM;
15201532
goto cleanup;
15211533
}

modules/md/md_version.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@
2727
* @macro
2828
* Version number of the md module as c string
2929
*/
30-
#define MOD_MD_VERSION "2.5.1"
30+
#define MOD_MD_VERSION "2.5.2"
3131

3232
/**
3333
* @macro
3434
* Numerical representation of the version number of the md module
3535
* release. This is a 24 bit number with 8 bits for major number, 8 bits
3636
* for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
3737
*/
38-
#define MOD_MD_VERSION_NUM 0x020501
38+
#define MOD_MD_VERSION_NUM 0x020502
3939

4040
#define MD_ACME_DEF_URL "https://acme-v02.api.letsencrypt.org/directory"
4141
#define MD_TAILSCALE_DEF_URL "file://localhost/var/run/tailscale/tailscaled.sock"

modules/md/mod_md.c

Lines changed: 65 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,55 +1292,95 @@ static int md_add_fallback_cert_files(server_rec *s, apr_pool_t *p,
12921292
return DECLINED;
12931293
}
12941294

1295-
static int md_answer_challenge(conn_rec *c, const char *servername,
1296-
const char **pcert_pem, const char **pkey_pem)
1295+
static int md_get_challenge_cert(conn_rec *c, const char *servername,
1296+
md_srv_conf_t *sc,
1297+
md_pkey_type_t key_type,
1298+
const char **pcert_pem,
1299+
const char **pkey_pem)
12971300
{
1298-
const char *protocol;
1299-
int hook_rv = DECLINED;
13001301
apr_status_t rv = APR_ENOENT;
1301-
md_srv_conf_t *sc;
1302-
md_store_t *store;
1302+
int i;
13031303
char *cert_name, *pkey_name;
13041304
const char *cert_pem, *key_pem;
1305-
int i;
1305+
md_store_t *store = md_reg_store_get(sc->mc->reg);
1306+
md_pkey_spec_t *key_spec;
13061307

1307-
if (!servername
1308-
|| !(protocol = md_protocol_get(c))
1309-
|| strcmp(PROTO_ACME_TLS_1, protocol)) {
1310-
goto cleanup;
1311-
}
1312-
sc = md_config_get(c->base_server);
1313-
if (!sc || !sc->mc->reg) goto cleanup;
1314-
1315-
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
1316-
"Answer challenge[tls-alpn-01] for %s", servername);
1317-
store = md_reg_store_get(sc->mc->reg);
1308+
for (i = 0; i < md_pkeys_spec_count(sc->pks); i++) {
1309+
key_spec = md_pkeys_spec_get(sc->pks, i);
1310+
if (key_spec->type != key_type)
1311+
continue;
13181312

1319-
for (i = 0; i < md_pkeys_spec_count( sc->pks ); i++) {
1320-
tls_alpn01_fnames(c->pool, md_pkeys_spec_get(sc->pks,i),
1321-
&pkey_name, &cert_name);
1313+
tls_alpn01_fnames(c->pool, key_spec, &pkey_name, &cert_name);
13221314

13231315
rv = md_store_load(store, MD_SG_CHALLENGES, servername, cert_name, MD_SV_TEXT,
13241316
(void**)&cert_pem, c->pool);
1317+
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, rv, c,
1318+
"Load challenge: cert %s", cert_name);
13251319
if (APR_STATUS_IS_ENOENT(rv)) continue;
13261320
if (APR_SUCCESS != rv) goto cleanup;
13271321

13281322
rv = md_store_load(store, MD_SG_CHALLENGES, servername, pkey_name, MD_SV_TEXT,
13291323
(void**)&key_pem, c->pool);
1324+
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, rv, c,
1325+
"Load challenge: key %s", pkey_name);
13301326
if (APR_STATUS_IS_ENOENT(rv)) continue;
13311327
if (APR_SUCCESS != rv) goto cleanup;
13321328

13331329
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
1334-
"Found challenge cert %s, key %s for %s",
1330+
"Found challenge: cert %s, key %s for %s",
13351331
cert_name, pkey_name, servername);
13361332
*pcert_pem = cert_pem;
13371333
*pkey_pem = key_pem;
1338-
hook_rv = OK;
1339-
break;
1334+
return OK;
1335+
}
1336+
cleanup:
1337+
return DECLINED;
1338+
}
1339+
1340+
static int md_answer_challenge(conn_rec *c, const char *servername,
1341+
const char **pcert_pem, const char **pkey_pem)
1342+
{
1343+
const char *protocol;
1344+
int hook_rv = DECLINED;
1345+
md_srv_conf_t *sc;
1346+
1347+
*pcert_pem = *pkey_pem = NULL;
1348+
1349+
if (!servername
1350+
|| !(protocol = md_protocol_get(c))
1351+
|| strcmp(PROTO_ACME_TLS_1, protocol)) {
1352+
goto cleanup;
13401353
}
1354+
sc = md_config_get(c->base_server);
1355+
if (!sc || !sc->mc->reg) goto cleanup;
1356+
1357+
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
1358+
"Answer challenge[tls-alpn-01] for %s", servername);
1359+
1360+
/* A challenge for TLS-ALPN-01 used to have a single certificate,
1361+
* overriding the single fallback certificate already installed in
1362+
* the connections SSL* instance.
1363+
* Since the addition of `MDPrivateKeys`, there can be more than one,
1364+
* but the server API for a challenge cert can return only one. This
1365+
* is a short coming of the API.
1366+
* This means we cannot override all fallback certificates present, just
1367+
* a single one. If there is an RSA cert in fallback, we need to override
1368+
* that, because the ACME server has a preference for that (at least LE
1369+
* has). So we look for an RSA challenge cert first.
1370+
* The fallback is an EC cert and that works since without RSA challenges,
1371+
* there should also be no RSA fallbacks.
1372+
* Bit of a mess. */
1373+
hook_rv = md_get_challenge_cert(c, servername, sc, MD_PKEY_TYPE_DEFAULT,
1374+
pcert_pem, pkey_pem);
1375+
if (hook_rv == DECLINED)
1376+
hook_rv = md_get_challenge_cert(c, servername, sc, MD_PKEY_TYPE_RSA,
1377+
pcert_pem, pkey_pem);
1378+
if (hook_rv == DECLINED)
1379+
hook_rv = md_get_challenge_cert(c, servername, sc, MD_PKEY_TYPE_EC,
1380+
pcert_pem, pkey_pem);
13411381

13421382
if (DECLINED == hook_rv) {
1343-
ap_log_cerror(APLOG_MARK, APLOG_INFO, rv, c, APLOGNO(10080)
1383+
ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, APLOGNO(10080)
13441384
"%s: unknown tls-alpn-01 challenge host", servername);
13451385
}
13461386

modules/md/mod_md_status.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -543,15 +543,15 @@ static void si_val_activity(status_ctx *ctx, md_json_t *mdj, const status_info *
543543
apr_brigade_puts(ctx->bb, NULL, NULL, "Pending");
544544
}
545545
else {
546-
apr_brigade_printf(ctx->bb, NULL, NULL, "%s: %s", ctx->prefix, "Pending");
546+
apr_brigade_printf(ctx->bb, NULL, NULL, "%s: %s", ctx->prefix, "Pending\n");
547547
}
548548
}
549549
else if (MD_RENEW_MANUAL == md_json_getl(mdj, MD_KEY_RENEW_MODE, NULL)) {
550550
if (HTML_STATUS(ctx)) {
551551
apr_brigade_puts(ctx->bb, NULL, NULL, "Manual renew");
552552
}
553553
else {
554-
apr_brigade_printf(ctx->bb, NULL, NULL, "%s: %s", ctx->prefix, "Manual renew");
554+
apr_brigade_printf(ctx->bb, NULL, NULL, "%s: %s", ctx->prefix, "Manual renew\n");
555555
}
556556
}
557557
if (!HTML_STATUS(ctx)) {

0 commit comments

Comments
 (0)