Skip to content

Commit e820482

Browse files
authored
Support CA-specific connection root certificates (#424)
Allow the MDCACertificateFile setting to be set per MDomain. The global MDCACertificateFile setting is used by default.
1 parent 79f7108 commit e820482

9 files changed

Lines changed: 42 additions & 19 deletions

File tree

src/md.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ struct md_t {
101101
struct apr_array_header_t *acme_tls_1_domains; /* domains supporting "acme-tls/1" protocol */
102102
const char *dns01_cmd; /* DNS challenge command, override global command */
103103
const char *proxy_url; /* Proxy URL, override global command */
104-
104+
const char *ca_certs; /* root certificates to use for connections,
105+
override global command */
105106
const struct md_srv_conf_t *sc; /* server config where it was defined or NULL */
106107
const char *defn_name; /* config file this MD was defined */
107108
unsigned defn_line_number; /* line number of definition */
@@ -126,6 +127,7 @@ struct md_t {
126127
#define MD_KEY_AUTHORIZATIONS "authorizations"
127128
#define MD_KEY_BITS "bits"
128129
#define MD_KEY_CA "ca"
130+
#define MD_KEY_CA_CERTS "ca-certs"
129131
#define MD_KEY_CA_URL "ca-url"
130132
#define MD_KEY_CERT "cert"
131133
#define MD_KEY_CERT_FILES "cert-files"

src/md_acme.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ apr_status_t md_acme_init(apr_pool_t *pool, const char *base_version, int init_s
151151
* @param p pool to used
152152
* @param url url of the server, optional if known at path
153153
* @param proxy_url optional url of a HTTP(S) proxy to use
154+
* @param ca_file optional CA trust anchor file to use
154155
*/
155156
apr_status_t md_acme_create(md_acme_t **pacme, apr_pool_t *p, const char *url,
156157
const char *proxy_url, const char *ca_file);

src/md_acme_drive.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,7 @@ static apr_status_t acme_renew(md_proto_driver_t *d, md_result_t *result)
772772
d->md->name, ca_effective);
773773
if (APR_SUCCESS != (rv = md_acme_create(&ad->acme, d->p, ca_effective,
774774
ad->md->proxy_url ? ad->md->proxy_url : d->proxy_url,
775-
d->ca_file))) {
775+
ad->md->ca_certs ? ad->md->ca_certs : d->ca_certs))) {
776776
md_result_printf(result, rv, "setup ACME communications");
777777
md_result_log(result, MD_LOG_ERR);
778778
goto out;
@@ -1035,7 +1035,7 @@ static apr_status_t acme_preload(md_proto_driver_t *d, md_store_group_t load_gro
10351035

10361036
if (APR_SUCCESS != (rv = md_acme_create(&acme, d->p, md->ca_effective,
10371037
d->md->proxy_url ? d->md->proxy_url : d->proxy_url,
1038-
d->ca_file))) {
1038+
d->md->ca_certs ? d->md->ca_certs : d->ca_certs))) {
10391039
md_result_set(result, rv, "error setting up acme");
10401040
goto leave;
10411041
}
@@ -1145,7 +1145,7 @@ static apr_status_t acme_get_ari(md_proto_driver_t *d,
11451145

11461146
if (APR_SUCCESS != (rv = md_acme_create(&ad->acme, d->p, ca_effective,
11471147
d->md->proxy_url ? d->md->proxy_url : d->proxy_url,
1148-
d->ca_file))) {
1148+
d->md->ca_certs ? d->md->ca_certs : d->ca_certs))) {
11491149
md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, d->p,
11501150
"create ACME communications");
11511151
goto out;

src/md_core.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ md_t *md_clone(apr_pool_t *p, const md_t *src)
259259
md->stapling = src->stapling;
260260
if (src->dns01_cmd) md->dns01_cmd = apr_pstrdup(p, src->dns01_cmd);
261261
if (src->proxy_url) md->proxy_url = apr_pstrdup(p, src->proxy_url);
262+
if (src->ca_certs) md->ca_certs = apr_pstrdup(p, src->ca_certs);
262263
if (src->cert_files) md->cert_files = md_array_str_clone(p, src->cert_files);
263264
if (src->pkey_files) md->pkey_files = md_array_str_clone(p, src->pkey_files);
264265
}
@@ -317,6 +318,7 @@ md_json_t *md_to_json(const md_t *md, apr_pool_t *p)
317318
md_json_setb(md->stapling > 0, json, MD_KEY_STAPLING, NULL);
318319
if (md->dns01_cmd) md_json_sets(md->dns01_cmd, json, MD_KEY_CMD_DNS01, NULL);
319320
if (md->proxy_url) md_json_sets(md->proxy_url, json, MD_KEY_PROXY_URL, NULL);
321+
if (md->ca_certs) md_json_sets(md->ca_certs, json, MD_KEY_CA_CERTS, NULL);
320322
if (md->ca_eab_kid && strcmp("none", md->ca_eab_kid)) {
321323
md_json_sets(md->ca_eab_kid, json, MD_KEY_EAB, MD_KEY_KID, NULL);
322324
if (md->ca_eab_hmac) md_json_sets(md->ca_eab_hmac, json, MD_KEY_EAB, MD_KEY_HMAC, NULL);
@@ -387,6 +389,7 @@ md_t *md_from_json(md_json_t *json, apr_pool_t *p)
387389
md->stapling = (int)md_json_getb(json, MD_KEY_STAPLING, NULL);
388390
md->dns01_cmd = md_json_dups(p, json, MD_KEY_CMD_DNS01, NULL);
389391
md->proxy_url = md_json_dups(p, json, MD_KEY_PROXY_URL, NULL);
392+
md->ca_certs = md_json_dups(p, json, MD_KEY_CA_CERTS, NULL);
390393
if (md_json_has_key(json, MD_KEY_EAB, NULL)) {
391394
md->ca_eab_kid = md_json_dups(p, json, MD_KEY_EAB, MD_KEY_KID, NULL);
392395
md->ca_eab_hmac = md_json_dups(p, json, MD_KEY_EAB, MD_KEY_HMAC, NULL);

src/md_reg.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ struct md_reg_t {
4747
int can_http;
4848
int can_https;
4949
const char *proxy_url;
50-
const char *ca_file;
50+
const char *ca_certs;
5151
int domains_frozen;
5252
md_timeslice_t *renew_window;
5353
md_timeslice_t *warn_window;
@@ -96,7 +96,7 @@ static apr_status_t load_props(md_reg_t *reg, apr_pool_t *p)
9696
}
9797

9898
apr_status_t md_reg_create(md_reg_t **preg, apr_pool_t *p, struct md_store_t *store,
99-
const char *proxy_url, const char *ca_file,
99+
const char *proxy_url, const char *ca_certs,
100100
apr_time_t min_delay, int retry_failover,
101101
int use_store_locks, apr_time_t lock_wait_timeout)
102102
{
@@ -111,8 +111,8 @@ apr_status_t md_reg_create(md_reg_t **preg, apr_pool_t *p, struct md_store_t *st
111111
reg->can_http = 1;
112112
reg->can_https = 1;
113113
reg->proxy_url = apr_pstrdup(p, proxy_url);
114-
reg->ca_file = (ca_file && apr_cstr_casecmp("none", ca_file))?
115-
apr_pstrdup(p, ca_file) : NULL;
114+
reg->ca_certs = (ca_certs && apr_cstr_casecmp("none", ca_certs))?
115+
apr_pstrdup(p, ca_certs) : NULL;
116116
reg->min_delay = min_delay;
117117
reg->retry_failover = retry_failover;
118118
reg->use_store_locks = use_store_locks;
@@ -1109,7 +1109,7 @@ static apr_status_t run_init(void *baton, apr_pool_t *p, ...)
11091109
driver->reg = reg;
11101110
driver->store = md_reg_store_get(reg);
11111111
driver->proxy_url = reg->proxy_url;
1112-
driver->ca_file = reg->ca_file;
1112+
driver->ca_certs = reg->ca_certs;
11131113
driver->md = md;
11141114
driver->can_http = reg->can_http;
11151115
driver->can_https = reg->can_https;

src/md_reg.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,12 @@ typedef struct md_reg_t md_reg_t;
3939
* @param pm memory pool to use for creation
4040
* @param store the store to base on
4141
* @param proxy_url optional URL of a proxy to use for requests
42-
* @param ca_file optioinal CA trust anchor file to use
42+
* @param ca_certs optional CA trust anchor file to use
4343
* @param min_delay minimum delay between renewal attempts for a domain
44-
* @param retry_failover numer of failed renewals attempt to fail over to alternate ACME ca
44+
* @param retry_failover number of failed renewals attempt to fail over to alternate ACME ca
4545
*/
4646
apr_status_t md_reg_create(md_reg_t **preg, apr_pool_t *pm, md_store_t *store,
47-
const char *proxy_url, const char *ca_file,
47+
const char *proxy_url, const char *ca_certs,
4848
apr_time_t min_delay, int retry_failover,
4949
int use_store_locks, apr_time_t lock_wait_timeout);
5050

@@ -224,7 +224,7 @@ struct md_proto_driver_t {
224224
md_reg_t *reg;
225225
md_store_t *store;
226226
const char *proxy_url;
227-
const char *ca_file;
227+
const char *ca_certs;
228228
const md_t *md;
229229

230230
int can_http;

src/mod_md.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,7 @@ static apr_status_t md_post_config_before_ssl(apr_pool_t *p, apr_pool_t *plog,
856856
int dry_run = 0, log_level = APLOG_DEBUG;
857857
md_store_t *store;
858858
const char *proxy_url;
859+
const char *ca_certs;
859860

860861
apr_pool_userdata_get(&data, mod_md_init_key, s->process->pool);
861862
if (data == NULL) {
@@ -895,8 +896,9 @@ static apr_status_t md_post_config_before_ssl(apr_pool_t *p, apr_pool_t *plog,
895896
if (APR_SUCCESS != rv) goto leave;
896897

897898
proxy_url = apr_table_get(mc->env, MD_KEY_PROXY_URL);
899+
ca_certs = apr_table_get(mc->env, MD_KEY_CA_CERTS);
898900

899-
rv = md_reg_create(&mc->reg, p, store, proxy_url, mc->ca_certs,
901+
rv = md_reg_create(&mc->reg, p, store, proxy_url, ca_certs,
900902
mc->min_delay, mc->retry_failover,
901903
mc->use_store_locks, mc->lock_wait_timeout);
902904
if (APR_SUCCESS != rv) {

src/mod_md_config.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ static md_mod_conf_t defmc = {
8282
&def_ocsp_renew_window, /* default time to renew ocsp responses */
8383
"crt.sh", /* default cert checker site name */
8484
"https://crt.sh?q=", /* default cert checker site url */
85-
NULL, /* CA cert file to use */
8685
APR_TIME_C(0), /* initial cert check delay */
8786
apr_time_from_sec(MD_SECS_PER_DAY/2), /* default time between cert checks */
8887
apr_time_from_sec(30), /* minimum delay for retries */
@@ -127,6 +126,7 @@ static md_srv_conf_t defconf = {
127126
1, /* ACME ARI renewals */
128127
NULL, /* dns01_cmd */
129128
NULL, /* proxy URL */
129+
NULL, /* CA cert file to use */
130130
NULL, /* currently defined md */
131131
NULL, /* assigned md, post config */
132132
0, /* is_ssl, set during mod_ssl post_config */
@@ -186,6 +186,7 @@ static void srv_conf_props_clear(md_srv_conf_t *sc)
186186
sc->ari_renewals = DEF_VAL;
187187
sc->dns01_cmd = NULL;
188188
sc->proxy_url = NULL;
189+
sc->ca_certs = NULL;
189190
}
190191

191192
static void srv_conf_props_copy(md_srv_conf_t *to, const md_srv_conf_t *from)
@@ -211,6 +212,7 @@ static void srv_conf_props_copy(md_srv_conf_t *to, const md_srv_conf_t *from)
211212
to->ari_renewals = from->ari_renewals;
212213
to->dns01_cmd = from->dns01_cmd;
213214
to->proxy_url = from->proxy_url;
215+
to->ca_certs = from->ca_certs;
214216
}
215217

216218
static void srv_conf_props_apply(md_t *md, const md_srv_conf_t *from, apr_pool_t *p)
@@ -239,6 +241,7 @@ static void srv_conf_props_apply(md_t *md, const md_srv_conf_t *from, apr_pool_t
239241
if (from->stapling != DEF_VAL) md->stapling = from->stapling;
240242
if (from->dns01_cmd) md->dns01_cmd = from->dns01_cmd;
241243
if (from->proxy_url) md->proxy_url = from->proxy_url;
244+
if (from->ca_certs) md->ca_certs = from->ca_certs;
242245
}
243246

244247
void *md_config_create_svr(apr_pool_t *pool, server_rec *s)
@@ -289,6 +292,7 @@ static void *md_config_merge(apr_pool_t *pool, void *basev, void *addv)
289292
nsc->ari_renewals = (add->ari_renewals != DEF_VAL)? add->ari_renewals : base->ari_renewals;
290293
nsc->dns01_cmd = (add->dns01_cmd)? add->dns01_cmd : base->dns01_cmd;
291294
nsc->proxy_url = (add->proxy_url)? add->proxy_url : base->proxy_url;
295+
nsc->ca_certs = (add->ca_certs)? add->ca_certs : base->ca_certs;
292296
nsc->current = NULL;
293297

294298
return nsc;
@@ -1250,12 +1254,22 @@ static const char *md_config_set_activation_delay(cmd_parms *cmd, void *mconfig,
12501254
return NULL;
12511255
}
12521256

1253-
static const char *md_config_set_ca_certs(cmd_parms *cmd, void *dc, const char *path)
1257+
static const char *md_config_set_ca_certs(cmd_parms *cmd, void *arg, const char *value)
12541258
{
12551259
md_srv_conf_t *sc = md_config_get(cmd->server);
1260+
const char *err;
12561261

1257-
(void)dc;
1258-
sc->mc->ca_certs = path;
1262+
if ((err = md_conf_check_location(cmd, MD_LOC_ALL))) {
1263+
return err;
1264+
}
1265+
1266+
if (inside_md_section(cmd)) {
1267+
sc->ca_certs = value;
1268+
} else {
1269+
apr_table_set(sc->mc->env, MD_KEY_CA_CERTS, value);
1270+
}
1271+
1272+
(void)arg;
12591273
return NULL;
12601274
}
12611275

src/mod_md_config.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ struct md_mod_conf_t {
7575
md_timeslice_t *ocsp_renew_window; /* time before exp. that we start renewing ocsp resp. */
7676
const char *cert_check_name; /* name of the linked certificate check site */
7777
const char *cert_check_url; /* url "template for" checking a certificate */
78-
const char *ca_certs; /* root certificates to use for connections */
7978
apr_time_t initial_delay; /* how long to delay the first cert renewal check */
8079
apr_time_t check_interval; /* duration between cert renewal checks */
8180
apr_time_t min_delay; /* minimum delay for retries */
@@ -114,6 +113,8 @@ typedef struct md_srv_conf_t {
114113

115114
const char *dns01_cmd; /* DNS challenge command, override global command */
116115
const char *proxy_url; /* Proxy URL, override global command */
116+
const char *ca_certs; /* root certificates to use for connections,
117+
override global command */
117118

118119
md_t *current; /* md currently defined in <MDomainSet xxx> section */
119120
struct apr_array_header_t *assigned; /* post_config: MDs that apply to this server */

0 commit comments

Comments
 (0)