MEDIUM: ssl: support aliases in crt-store

The crt-store load line now allows to put an alias. This alias is used
as the key in the ckch_tree instead of the certificate. This way an
alias can be referenced in the configuration with the '@/' prefix.

This can only be define with a crt-store.
This commit is contained in:
William Lallemand 2024-04-17 17:03:58 +02:00
parent e6662bf706
commit bdee8ace81
4 changed files with 46 additions and 19 deletions

View File

@ -4744,6 +4744,11 @@ load [crt <filename>] [param*]
Arguments:
alias <string> Optional argument. Allow to name the certificate with an
alias, so it can be referenced with it in the
configuration. An alias must be prefixed with '@/' when
called elsewhere in the configuration.
crt <filename> This argument is mandatory, it loads a PEM which must
contain the public certificate but could also contain
the intermediate certificates and the private key.
@ -4772,11 +4777,11 @@ load [crt <filename>] [param*]
Example:
crt-store
load crt "site1.crt" key "site1.key" ocsp "site1.ocsp"
load crt "site1.crt" key "site1.key" ocsp "site1.ocsp" alias "site1"
load crt "site2.crt" key "site2.key"
frontend in
bind *:443 ssl crt "site1.crt" crt "site2.crt"
bind *:443 ssl crt "@/site1" crt "site2.crt"
4. Proxies
----------

View File

@ -784,7 +784,7 @@ static int bind_parse_crt(char **args, int cur_arg, struct proxy *px, struct bin
return ERR_ALERT | ERR_FATAL;
}
if ((*args[cur_arg + 1] != '/' ) && global_ssl.crt_base) {
if ((*args[cur_arg + 1] != '@') && (*args[cur_arg + 1] != '/' ) && global_ssl.crt_base) {
if ((strlen(global_ssl.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > sizeof(path) ||
snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, args[cur_arg + 1]) > sizeof(path)) {
memprintf(err, "'%s' : path too long", args[cur_arg]);
@ -1828,7 +1828,7 @@ static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct ser
return ERR_ALERT | ERR_FATAL;
}
if ((*args[*cur_arg + 1] != '/') && global_ssl.crt_base)
if ((*args[*cur_arg + 1] != '@') && (*args[*cur_arg + 1] != '/') && global_ssl.crt_base)
memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global_ssl.crt_base, args[*cur_arg + 1]);
else
memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);

View File

@ -3997,6 +3997,7 @@ static struct cli_kw_list cli_kws = {{ },{
INITCALL1(STG_REGISTER, cli_register_kw, &cli_kws);
struct ckch_conf_kws ckch_conf_kws[] = {
{ "alias", -1, 0, NULL, NULL },
{ "crt", offsetof(struct ckch_conf, crt), PARSE_TYPE_STR, ssl_sock_load_pem_into_ckch, &global_ssl.crt_base },
{ "key", offsetof(struct ckch_conf, key), PARSE_TYPE_STR, ssl_sock_load_key_into_ckch, &global_ssl.key_base },
{ "ocsp", offsetof(struct ckch_conf, ocsp), PARSE_TYPE_STR, ssl_sock_load_ocsp_response_from_file, &global_ssl.crt_base },
@ -4067,8 +4068,9 @@ static int crtstore_parse_load(char **args, int section_type, struct proxy *curp
int cur_arg = 0;
struct ckch_conf f = {};
struct ckch_store *c = NULL;
char store_path[PATH_MAX];
char *store_name;
char store_path[PATH_MAX]; /* complete path with crt_base */
char alias_name[PATH_MAX]; /* complete alias name with the store prefix '@/' */
char *final_name = NULL; /* name used as a key in the ckch_store */
cur_arg++; /* skip "load" */
@ -4081,7 +4083,25 @@ static int crtstore_parse_load(char **args, int section_type, struct proxy *curp
found = 1;
target = (char **)((intptr_t)&f + (ptrdiff_t)ckch_conf_kws[i].offset);
if (ckch_conf_kws[i].type == PARSE_TYPE_STR) {
if (strcmp("alias", args[cur_arg]) == 0) {
int rv;
if (*args[cur_arg] == '/') {
memprintf(err, "parsing [%s:%d] : cannot parse '%s' value '%s', '/' is forbidden as the first character.\n",
file, linenum, args[cur_arg], args[cur_arg + 1]);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
rv = snprintf(alias_name, sizeof(alias_name), "@%s/%s", "", 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));
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
final_name = alias_name;
} else if (ckch_conf_kws[i].type == PARSE_TYPE_STR) {
char **t = target;
*t = strdup(args[cur_arg + 1]);
@ -4132,21 +4152,23 @@ static int crtstore_parse_load(char **args, int section_type, struct proxy *curp
goto out;
}
store_name = f.crt;
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 (rv >= sizeof(store_path)) {
memprintf(err, "'%s/%s' : path too long", global_ssl.crt_base, f.crt);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
/* 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 (rv >= sizeof(store_path)) {
memprintf(err, "'%s/%s' : path too long", global_ssl.crt_base, f.crt);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
final_name = store_path;
}
store_name = store_path;
}
/* process and insert the ckch_store */
c = ckch_store_new(store_name);
c = ckch_store_new(final_name);
if (!c)
goto alloc_error;

View File

@ -575,7 +575,7 @@ int crtlist_parse_file(char *file, struct bind_conf *bind_conf, struct proxy *cu
continue;
}
if (*crt_path != '/' && global_ssl.crt_base) {
if (*crt_path != '@' && *crt_path != '/' && global_ssl.crt_base) {
if ((strlen(global_ssl.crt_base) + 1 + strlen(crt_path)) > sizeof(path) ||
snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, crt_path) > sizeof(path)) {
memprintf(err, "parsing [%s:%d]: '%s' : path too long",
@ -1338,7 +1338,7 @@ static int cli_parse_add_crtlist(char **args, char *payload, struct appctx *appc
*slash = '/';
}
if (*cert_path != '/' && global_ssl.crt_base) {
if (*cert_path != '@' && *cert_path != '/' && global_ssl.crt_base) {
if ((strlen(global_ssl.crt_base) + 1 + strlen(cert_path)) > sizeof(path) ||
snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, cert_path) > sizeof(path)) {
memprintf(&err, "'%s' : path too long", cert_path);