From: Stefan Eissing Date: Wed, 24 Nov 2021 10:13:42 +0000 (+0000) Subject: *) mod_md: values for External Account Binding (EAB) can X-Git-Tag: 2.5.0-alpha2-ci-test-only~690 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=331504f01e6b682b00b4cae43d0fb8c94957c0ec;p=thirdparty%2Fapache%2Fhttpd.git *) mod_md: values for External Account Binding (EAB) can now also be configured to be read from a separate JSON file. This allows to keep server configuration permissions world readable without exposing secrets. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1895285 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/changes-entries/md_2.4.9.txt b/changes-entries/md_2.4.9.txt new file mode 100644 index 00000000000..27cc5c9c28e --- /dev/null +++ b/changes-entries/md_2.4.9.txt @@ -0,0 +1,6 @@ + *) mod_md: values for External Account Binding (EAB) can + now also be configured to be read from a separate JSON + file. This allows to keep server configuration permissions + world readable without exposing secrets. + [Stefan Eissing] + diff --git a/docs/manual/mod/mod_md.xml b/docs/manual/mod/mod_md.xml index 15ad758338a..15430327958 100644 --- a/docs/manual/mod/mod_md.xml +++ b/docs/manual/mod/mod_md.xml @@ -1295,7 +1295,7 @@ MDMessageCmd /etc/apache/md-message MDExternalAccountBinding - MDExternalAccountBinding key-id hmac-64 + MDExternalAccountBinding key-id hmac-64 | none | file MDExternalAccountBinding none server config @@ -1319,7 +1319,17 @@ MDMessageCmd /etc/apache/md-message e.g. root only.

- If you change these values, the new ones will be used when the next + The value can also be taken from a JSON file, to keep more open + permissions on the server configuration and restrict the ones on that + file. The JSON itself is: +

+ EAB JSON Example file + +{"kid": "kid-1", "hmac": "zWND..."} + + +

+ If you change EAB values, the new ones will be used when the next certificate renewal is due.

diff --git a/modules/md/md_version.h b/modules/md/md_version.h index 72c14983226..27a20fd25e9 100644 --- a/modules/md/md_version.h +++ b/modules/md/md_version.h @@ -27,7 +27,7 @@ * @macro * Version number of the md module as c string */ -#define MOD_MD_VERSION "2.4.8" +#define MOD_MD_VERSION "2.4.9" /** * @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 0x020408 +#define MOD_MD_VERSION_NUM 0x020409 #define MD_ACME_DEF_URL "https://acme-v02.api.letsencrypt.org/directory" diff --git a/modules/md/mod_md_config.c b/modules/md/mod_md_config.c index cda11a00267..8d3260634ec 100644 --- a/modules/md/mod_md_config.c +++ b/modules/md/mod_md_config.c @@ -28,6 +28,7 @@ #include "md.h" #include "md_crypt.h" #include "md_log.h" +#include "md_json.h" #include "md_util.h" #include "mod_md_private.h" #include "mod_md_config.h" @@ -1038,11 +1039,50 @@ static const char *md_config_set_eab(cmd_parms *cmd, void *dc, return err; } if (!hmac) { - if (apr_strnatcasecmp("None", keyid)) { - return "only 'None' or a KEYID and HMAC string are allowed."; + if (!apr_strnatcasecmp("None", keyid)) { + keyid = "none"; + } + else { + /* a JSON file keeping keyid and hmac */ + const char *fpath; + apr_status_t rv; + md_json_t *json; + + /* If only dumping the config, don't verify the file */ + if (ap_state_query(AP_SQ_RUN_MODE) == AP_SQ_RM_CONFIG_DUMP) { + goto leave; + } + + fpath = ap_server_root_relative(cmd->pool, keyid); + if (!fpath) { + return apr_pstrcat(cmd->pool, cmd->cmd->name, + ": Invalid file path ", keyid, NULL); + } + if (!md_file_exists(fpath, cmd->pool)) { + return apr_pstrcat(cmd->pool, cmd->cmd->name, + ": file not found: ", fpath, NULL); + } + + rv = md_json_readf(&json, cmd->pool, fpath); + if (APR_SUCCESS != rv) { + return apr_pstrcat(cmd->pool, cmd->cmd->name, + ": error reading JSON file ", fpath, NULL); + } + keyid = md_json_gets(json, MD_KEY_KID, NULL); + if (!keyid || !*keyid) { + return apr_pstrcat(cmd->pool, cmd->cmd->name, + ": JSON does not contain '", MD_KEY_KID, + "' element in file ", fpath, NULL); + } + hmac = md_json_gets(json, MD_KEY_HMAC, NULL); + if (!hmac || !*hmac) { + return apr_pstrcat(cmd->pool, cmd->cmd->name, + ": JSON does not contain '", MD_KEY_HMAC, + "' element in file ", fpath, NULL); + } } - keyid = "none"; } +leave: sc->ca_eab_kid = keyid; sc->ca_eab_hmac = hmac; return NULL;