MINOR: ssl: allow to change the signature algorithm for client authentication

This commit introduces the keyword "client-sigalgs" for the bind line,
which does the same as "sigalgs" but for the client authentication.

"ssl-default-bind-client-sigalgs" allows to set the default parameter
for all the bind lines.

This patch should fix issue #2081.
This commit is contained in:
William Lallemand 2023-05-05 00:05:46 +02:00
parent 1d3c822300
commit b6ae2aafde
6 changed files with 103 additions and 0 deletions

View File

@ -1095,6 +1095,7 @@ The following keywords are supported in the "global" section :
- setenv
- ssl-default-bind-ciphers
- ssl-default-bind-ciphersuites
- ssl-default-bind-client-sigalgs
- ssl-default-bind-curves
- ssl-default-bind-options
- ssl-default-bind-sigalgs
@ -2168,6 +2169,21 @@ ssl-default-bind-ciphersuites <ciphersuites>
"ssl-default-bind-ciphers" keyword. Please check the "bind" keyword for more
information.
ssl-default-bind-client-sigalgs <sigalgs>
This setting is only available when support for OpenSSL was built in. It sets
the default string describing the list of signature algorithms related to
client authentication for all "bind" lines which do not explicitly define
theirs. The format of the string is a colon-delimited list of signature
algorithms. Each signature algorithm can use one of two forms: TLS1.3 signature
scheme names ("rsa_pss_rsae_sha256") or the public key algorithm + digest form
("ECDSA+SHA256"). A list can contain both forms. For more information on the
format, see SSL_CTX_set1_client_sigalgs(3). A list of signature algorithms is
also available in RFC8446 section 4.2.3 and in OpenSSL in the ssl/t1_lib.c
file. This setting is not applicable to TLSv1.1 and earlier versions of the
protocol as the signature algorithms aren't separately negotiated in these
versions. It is not recommended to change this setting unless compatibility
with a middlebox is required.
ssl-default-bind-curves <curves>
This setting is only available when support for OpenSSL was built in. It sets
the default string describing the list of elliptic curves algorithms ("curve
@ -14809,6 +14825,13 @@ ciphersuites <ciphersuites>
OpenSSL man pages under the "ciphersuites" section. For cipher configuration
for TLSv1.2 and earlier, please check the "ciphers" keyword.
client-sigalgs <sigalgs>
This setting is only available when support for OpenSSL was built in. It sets
the string describing the list of signature algorithms related to client
authentication that are negotiated . The format of the string is defined in
"man 3 SSL_CTX_set1_client_sigalgs" from the OpenSSL man pages. It is not
recommended to use this setting if no specific usecase was identified.
crl-file <crlfile>
This setting is only available when support for OpenSSL was built in. It
designates a PEM file from which to load certificate revocation list used

View File

@ -144,6 +144,7 @@ struct ssl_bind_conf {
char *curves; /* curves suite to use for ECDHE */
char *ecdhe; /* named curve to use for ECDHE */
char *sigalgs; /* Signature algorithms */
char *client_sigalgs; /* Client Signature algorithms */
struct tls_version_filter ssl_methods_cfg; /* original ssl methods found in configuration */
struct tls_version_filter ssl_methods; /* actual ssl methods used at runtime */
#endif

View File

@ -281,6 +281,9 @@ struct global_ssl {
#endif
#if defined(SSL_CTX_set1_sigalgs_list)
char *listen_default_sigalgs;
#endif
#if defined(SSL_CTX_set1_sigalgs_list)
char *listen_default_client_sigalgs;
#endif
int listen_default_ssloptions;
int connect_default_ssloptions;

View File

@ -344,6 +344,33 @@ static int ssl_parse_global_sigalgs(char **args, int section_type, struct proxy
}
#endif
#if defined(SSL_CTX_set1_client_sigalgs_list)
/*
* parse the "ssl-default-bind-client-sigalgs" keyword in a global section.
* Returns <0 on alert, >0 on warning, 0 on success.
*/
static int ssl_parse_global_client_sigalgs(char **args, int section_type, struct proxy *curpx,
const struct proxy *defpx, const char *file, int line,
char **err)
{
char **target;
target = &global_ssl.listen_default_client_sigalgs;
if (too_many_args(1, args, err, NULL))
return -1;
if (*(args[1]) == 0) {
memprintf(err, "global statement '%s' expects signature algorithms as an arguments.", args[0]);
return -1;
}
free(*target);
*target = strdup(args[1]);
return 0;
}
#endif
/* parse various global tune.ssl settings consisting in positive integers.
* Returns <0 on alert, >0 on warning, 0 on success.
*/
@ -846,6 +873,26 @@ static int bind_parse_sigalgs(char **args, int cur_arg, struct proxy *px, struct
return ssl_bind_parse_sigalgs(args, cur_arg, px, &conf->ssl_conf, 0, err);
}
/* parse the "client-sigalgs" bind keyword */
static int ssl_bind_parse_client_sigalgs(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, int from_cli, char **err)
{
#if defined(SSL_CTX_set1_client_sigalgs_list)
if (!*args[cur_arg + 1]) {
memprintf(err, "'%s' : missing signature algorithm list", args[cur_arg]);
return ERR_ALERT | ERR_FATAL;
}
conf->client_sigalgs = strdup(args[cur_arg + 1]);
return 0;
#else
memprintf(err, "'%s' : library does not support setting signature algorithms", args[cur_arg]);
return ERR_ALERT | ERR_FATAL;
#endif
}
static int bind_parse_client_sigalgs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
{
return ssl_bind_parse_client_sigalgs(args, cur_arg, px, &conf->ssl_conf, 0, err);
}
/* parse the "ecdhe" bind keyword keyword */
static int ssl_bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, int from_cli, char **err)
@ -2056,6 +2103,7 @@ struct ssl_crtlist_kw ssl_crtlist_kws[] = {
#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
{ "ciphersuites", ssl_bind_parse_ciphersuites, 1 }, /* set TLS 1.3 cipher suite */
#endif
{ "client-sigalgs", ssl_bind_parse_client_sigalgs, 1 }, /* set SSL client signature algorithms */
{ "crl-file", ssl_bind_parse_crl_file, 1 }, /* set certificate revocation list file use on client cert verify */
{ "curves", ssl_bind_parse_curves, 1 }, /* set SSL curve suite */
{ "ecdhe", ssl_bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
@ -2084,6 +2132,7 @@ static struct bind_kw_list bind_kws = { "SSL", { }, {
#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
{ "ciphersuites", bind_parse_ciphersuites, 1 }, /* set TLS 1.3 cipher suite */
#endif
{ "client-sigalgs", bind_parse_client_sigalgs, 1 }, /* set SSL client signature algorithms */
{ "crl-file", bind_parse_crl_file, 1 }, /* set certificate revocation list file use on client cert verify */
{ "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
{ "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth == 0 */
@ -2210,6 +2259,9 @@ static struct cfg_kw_list cfg_kws = {ILH, {
#if defined(SSL_CTX_set1_sigalgs_list)
{ CFG_GLOBAL, "ssl-default-bind-sigalgs", ssl_parse_global_sigalgs },
#endif
#if defined(SSL_CTX_set1_client_sigalgs_list)
{ CFG_GLOBAL, "ssl-default-bind-client-sigalgs", ssl_parse_global_client_sigalgs },
#endif
#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
{ CFG_GLOBAL, "ssl-default-bind-ciphersuites", ssl_parse_global_ciphersuites },
{ CFG_GLOBAL, "ssl-default-server-ciphersuites", ssl_parse_global_ciphersuites },

View File

@ -76,6 +76,9 @@ void ssl_sock_free_ssl_conf(struct ssl_bind_conf *conf)
ha_free(&conf->ecdhe);
#if defined(SSL_CTX_set1_sigalgs_list)
ha_free(&conf->sigalgs);
#endif
#if defined(SSL_CTX_set1_client_sigalgs_list)
ha_free(&conf->client_sigalgs);
#endif
}
}
@ -160,6 +163,13 @@ struct ssl_bind_conf *crtlist_dup_ssl_conf(struct ssl_bind_conf *src)
if (!dst->sigalgs)
goto error;
}
#endif
#if defined(SSL_CTX_set1_client_sigalgs_list)
if (src->client_sigalgs) {
dst->client_sigalgs = strdup(src->client_sigalgs);
if (!dst->client_sigalgs)
goto error;
}
#endif
return dst;

View File

@ -4573,6 +4573,9 @@ static int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, struct ssl_bind_con
#if defined(SSL_CTX_set1_sigalgs_list)
const char *conf_sigalgs = NULL;
#endif
#if defined(SSL_CTX_set1_client_sigalgs_list)
const char *conf_client_sigalgs = NULL;
#endif
if (ssl_conf) {
struct tls_version_filter *conf_ssl_methods = &ssl_conf->ssl_methods;
@ -4786,6 +4789,17 @@ static int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, struct ssl_bind_con
}
#endif
#if defined(SSL_CTX_set1_client_sigalgs_list)
conf_client_sigalgs = (ssl_conf && ssl_conf->client_sigalgs) ? ssl_conf->client_sigalgs : bind_conf->ssl_conf.client_sigalgs;
if (conf_client_sigalgs) {
if (!SSL_CTX_set1_client_sigalgs_list(ctx, conf_client_sigalgs)) {
memprintf(err, "%sProxy '%s': unable to set SSL Signature Algorithm list to '%s' for bind '%s' at [%s:%d].\n",
err && *err ? *err : "", curproxy->id, conf_client_sigalgs, bind_conf->arg, bind_conf->file, bind_conf->line);
cfgerr |= ERR_ALERT | ERR_FATAL;
}
}
#endif
return cfgerr;
}