MEDIUM: ssl: support a named crt-store section

This patch introduces named crt-store section. A named crt-store allows
to add a scope to the crt name.

For example, a crt named "foo.crt" in a crt-store named "web" will
result in a certificate called "@web/foo.crt".
This commit is contained in:
William Lallemand 2024-04-18 15:54:16 +02:00
parent 81a8a2cae1
commit ffea2e1a13
2 changed files with 58 additions and 9 deletions

View File

@ -4734,6 +4734,10 @@ section. It allows to configure certificate definitions and which files should
be loaded in it. A certificate definition must be written before it is used
elsewhere in the configuration.
The "crt-store" takes an optional name in argument. If a name is specified,
every certificate of this store must be referenced using "@<name>/<crt>" or
"@<name>/<alias>".
Files in the certificate storage can also be updated dynamically with the CLI.
See "set ssl cert" in the section 9.3 of the management guide.
@ -4780,9 +4784,16 @@ Example:
load crt "site1.crt" key "site1.key" ocsp "site1.ocsp" alias "site1"
load crt "site2.crt" key "site2.key"
frontend in
frontend in2
bind *:443 ssl crt "@/site1" crt "site2.crt"
crt-store web
load crt "site3.crt" alias "site3"
load crt "site4.crt" key "site4.key"
frontend in2
bind *:443 ssl crt "@web/site1" crt "site2.crt" crt "@web/site3" crt "@web/site4.crt"
4. Proxies
----------

View File

@ -4065,6 +4065,8 @@ int ckch_store_load_files(struct ckch_conf *f, struct ckch_store *c, char **err)
return err_code;
}
static char current_crtstore_name[PATH_MAX] = {};
static int crtstore_parse_load(char **args, int section_type, struct proxy *curpx, const struct proxy *defpx,
const char *file, int linenum, char **err)
{
@ -4098,7 +4100,7 @@ static int crtstore_parse_load(char **args, int section_type, struct proxy *curp
goto out;
}
rv = snprintf(alias_name, sizeof(alias_name), "@%s/%s", "", args[cur_arg + 1]);
rv = snprintf(alias_name, sizeof(alias_name), "@%s/%s", current_crtstore_name, args[cur_arg + 1]);
if (rv >= sizeof(alias_name)) {
memprintf(err, "parsing [%s:%d] : cannot parse '%s' value '%s', too long, max len is %ld.\n",
file, linenum, args[cur_arg], args[cur_arg + 1], sizeof(alias_name));
@ -4160,9 +4162,28 @@ static int crtstore_parse_load(char **args, int section_type, struct proxy *curp
if (!final_name) {
final_name = f.crt;
/* complete the name in the ckch_tree with 'crt-base' */
if (global_ssl.crt_base && *f.crt != '/') {
int rv = snprintf(store_path, sizeof(store_path), "%s/%s", global_ssl.crt_base, f.crt);
/* if no alias was used:
* - when a crt-store exists, use @store/crt
* - or use the absolute file (crt_base + crt)
* - or the relative file when no crt_base exists
*/
if (current_crtstore_name[0] != '\0') {
int rv;
/* add the crt-store name, avoid a double / if the crt starts by it */
rv = snprintf(alias_name, sizeof(alias_name), "@%s%s%s", current_crtstore_name, f.crt[0] != '/' ? "/" : "", f.crt);
if (rv >= sizeof(alias_name)) {
memprintf(err, "parsing [%s:%d] : cannot parse '%s' value '%s', too long, max len is %ld.\n",
file, linenum, args[cur_arg], args[cur_arg + 1], sizeof(alias_name));
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
final_name = alias_name;
} else if (global_ssl.crt_base && *f.crt != '/') {
int rv;
/* When no crt_store name, complete the name in the ckch_tree with 'crt-base' */
rv = snprintf(store_path, sizeof(store_path), "%s/%s", global_ssl.crt_base, f.crt);
if (rv >= sizeof(store_path)) {
memprintf(err, "'%s/%s' : path too long", global_ssl.crt_base, f.crt);
err_code |= ERR_ALERT | ERR_FATAL;
@ -4171,7 +4192,6 @@ static int crtstore_parse_load(char **args, int section_type, struct proxy *curp
final_name = store_path;
}
}
/* process and insert the ckch_store */
c = ckch_store_new(final_name);
if (!c)
@ -4218,8 +4238,20 @@ static int cfg_parse_crtstore(const char *file, int linenum, char **args, int kw
char *errmsg = NULL;
if (strcmp(args[0], "crt-store") == 0) { /* new crt-store section */
if (*args[1]) {
ha_alert("parsing [%s:%d] : 'crt-store' section does not support an argument.\n", file, linenum);
if (!*args[1]) {
current_crtstore_name[0] = '\0';
} else {
rc = snprintf(current_crtstore_name, sizeof(current_crtstore_name), "%s", args[1]);
if (rc >= sizeof(current_crtstore_name)) {
ha_alert("parsing [%s:%d] : 'crt-store' <name> argument is too long.\n", file, linenum);
current_crtstore_name[0] = '\0';
err_code |= ERR_ALERT | ERR_FATAL | ERR_ABORT;
goto out;
}
}
if (*args[2]) {
ha_alert("parsing [%s:%d] : 'crt-store' section only supports a <name> argument.\n", file, linenum);
err_code |= ERR_ALERT | ERR_FATAL | ERR_ABORT;
goto out;
}
@ -4269,7 +4301,13 @@ static int cfg_parse_crtstore(const char *file, int linenum, char **args, int kw
return err_code;
}
REGISTER_CONFIG_SECTION("crt-store", cfg_parse_crtstore, NULL);
static int cfg_post_parse_crtstore()
{
current_crtstore_name[0] = '\0';
return ERR_NONE;
}
REGISTER_CONFIG_SECTION("crt-store", cfg_parse_crtstore, cfg_post_parse_crtstore);
static struct cfg_kw_list cfg_kws = {ILH, {
{ CFG_CRTSTORE, "load", crtstore_parse_load },