mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 15:47:01 +02:00
MINOR: ssl: allow to change the server signature algorithm
This patch introduces the "sigalgs" keyword for the bind line, which allows to configure the list of server signature algorithms negociated during the handshake. Also available as "ssl-default-bind-sigalgs" in the default section. This patch was originally written by Bruno Henc.
This commit is contained in:
parent
e69919d1ba
commit
1d3c822300
@ -1097,6 +1097,7 @@ The following keywords are supported in the "global" section :
|
||||
- ssl-default-bind-ciphersuites
|
||||
- ssl-default-bind-curves
|
||||
- ssl-default-bind-options
|
||||
- ssl-default-bind-sigalgs
|
||||
- ssl-default-server-ciphers
|
||||
- ssl-default-server-ciphersuites
|
||||
- ssl-default-server-options
|
||||
@ -2183,6 +2184,22 @@ ssl-default-bind-options [<option>]...
|
||||
global
|
||||
ssl-default-bind-options ssl-min-ver TLSv1.0 no-tls-tickets
|
||||
|
||||
ssl-default-bind-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 that
|
||||
are negotiated during the TLSv1.2 and TLSv1.3 handshake 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_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-server-ciphers <ciphers>
|
||||
This setting is only available when support for OpenSSL was built in. It
|
||||
sets the default string describing the list of cipher algorithms that are
|
||||
@ -15330,6 +15347,14 @@ shards <number> | by-thread | by-group
|
||||
warning will be emitted if this happens since the resulting number of
|
||||
listeners will not be the expected one.
|
||||
|
||||
sigalgs <sigalgs>
|
||||
This setting is only available when support for OpenSSL was built in. It sets
|
||||
the string describing the list of signature algorithms that are negotiated
|
||||
during the TLSv1.2 and TLSv1.3 handshake. The format of the string is defined
|
||||
in "man 3 SSL_CTX_set1_sigalgs" from the OpenSSL man pages. It is not
|
||||
recommended to use this setting unless compatibility with a middlebox is
|
||||
required.
|
||||
|
||||
ssl
|
||||
This setting is only available when support for OpenSSL was built in. It
|
||||
enables SSL deciphering on connections instantiated from this listener. A
|
||||
|
@ -143,6 +143,7 @@ struct ssl_bind_conf {
|
||||
char *ciphersuites; /* TLS 1.3 cipher suite to use if non-null */
|
||||
char *curves; /* curves suite to use for ECDHE */
|
||||
char *ecdhe; /* named curve to use for ECDHE */
|
||||
char *sigalgs; /* 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
|
||||
|
@ -520,5 +520,9 @@ static inline unsigned long ERR_peek_error_func(const char **func)
|
||||
#define SSL_CTX_set1_curves_list SSL_CTX_set1_curves_list
|
||||
#endif
|
||||
|
||||
#if !defined(SSL_CTX_set1_sigalgs_list) && defined(SSL_CTRL_SET_SIGALGS_LIST)
|
||||
#define SSL_CTX_set1_sigalgs_list SSL_CTX_set1_sigalgs_list
|
||||
#endif
|
||||
|
||||
#endif /* USE_OPENSSL */
|
||||
#endif /* _HAPROXY_OPENSSL_COMPAT_H */
|
||||
|
@ -278,6 +278,9 @@ struct global_ssl {
|
||||
#endif
|
||||
#if defined(SSL_CTX_set1_curves_list)
|
||||
char *listen_default_curves;
|
||||
#endif
|
||||
#if defined(SSL_CTX_set1_sigalgs_list)
|
||||
char *listen_default_sigalgs;
|
||||
#endif
|
||||
int listen_default_ssloptions;
|
||||
int connect_default_ssloptions;
|
||||
|
@ -316,6 +316,34 @@ static int ssl_parse_global_curves(char **args, int section_type, struct proxy *
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SSL_CTX_set1_sigalgs_list)
|
||||
/*
|
||||
* parse the "ssl-default-bind-sigalgs" keyword in a global section.
|
||||
* Returns <0 on alert, >0 on warning, 0 on success.
|
||||
*/
|
||||
static int ssl_parse_global_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_sigalgs;
|
||||
|
||||
if (too_many_args(1, args, err, NULL))
|
||||
return -1;
|
||||
|
||||
if (*(args[1]) == 0) {
|
||||
memprintf(err, "global statement '%s' expects a curves suite 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.
|
||||
*/
|
||||
@ -798,6 +826,27 @@ static int bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct
|
||||
return ssl_bind_parse_curves(args, cur_arg, px, &conf->ssl_conf, 0, err);
|
||||
}
|
||||
|
||||
/* parse the "sigalgs" bind keyword */
|
||||
static int ssl_bind_parse_sigalgs(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, int from_cli, char **err)
|
||||
{
|
||||
#if defined(SSL_CTX_set1_sigalgs_list)
|
||||
if (!*args[cur_arg + 1]) {
|
||||
memprintf(err, "'%s' : missing signature algorithm list", args[cur_arg]);
|
||||
return ERR_ALERT | ERR_FATAL;
|
||||
}
|
||||
conf->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_sigalgs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
|
||||
{
|
||||
return ssl_bind_parse_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)
|
||||
{
|
||||
@ -1153,6 +1202,10 @@ static int bind_parse_ssl(char **args, int cur_arg, struct proxy *px, struct bin
|
||||
if (global_ssl.listen_default_curves && !conf->ssl_conf.curves)
|
||||
conf->ssl_conf.curves = strdup(global_ssl.listen_default_curves);
|
||||
#endif
|
||||
#if defined(SSL_CTX_set1_sigalgs_list)
|
||||
if (global_ssl.listen_default_sigalgs && !conf->ssl_conf.sigalgs)
|
||||
conf->ssl_conf.sigalgs = strdup(global_ssl.listen_default_sigalgs);
|
||||
#endif
|
||||
#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
|
||||
if (global_ssl.listen_default_ciphersuites && !conf->ssl_conf.ciphersuites)
|
||||
conf->ssl_conf.ciphersuites = strdup(global_ssl.listen_default_ciphersuites);
|
||||
@ -2009,6 +2062,7 @@ struct ssl_crtlist_kw ssl_crtlist_kws[] = {
|
||||
{ "no-alpn", ssl_bind_parse_no_alpn, 0 }, /* disable sending ALPN */
|
||||
{ "no-ca-names", ssl_bind_parse_no_ca_names, 0 }, /* do not send ca names to clients (ca_file related) */
|
||||
{ "npn", ssl_bind_parse_npn, 1 }, /* set NPN supported protocols */
|
||||
{ "sigalgs", ssl_bind_parse_sigalgs, 1 }, /* set SSL signature algorithms */
|
||||
{ "ssl-min-ver", ssl_bind_parse_tls_method_minmax,1 }, /* minimum version */
|
||||
{ "ssl-max-ver", ssl_bind_parse_tls_method_minmax,1 }, /* maximum version */
|
||||
{ "verify", ssl_bind_parse_verify, 1 }, /* set SSL verify method */
|
||||
@ -2050,6 +2104,7 @@ static struct bind_kw_list bind_kws = { "SSL", { }, {
|
||||
{ "no-tlsv12", bind_parse_tls_method_options, 0 }, /* disable TLSv12 */
|
||||
{ "no-tlsv13", bind_parse_tls_method_options, 0 }, /* disable TLSv13 */
|
||||
{ "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
|
||||
{ "sigalgs", bind_parse_sigalgs, 1 }, /* set SSL signature algorithms */
|
||||
{ "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
|
||||
{ "ssl-min-ver", bind_parse_tls_method_minmax, 1 }, /* minimum version */
|
||||
{ "ssl-max-ver", bind_parse_tls_method_minmax, 1 }, /* maximum version */
|
||||
@ -2152,6 +2207,9 @@ static struct cfg_kw_list cfg_kws = {ILH, {
|
||||
#if defined(SSL_CTX_set1_curves_list)
|
||||
{ CFG_GLOBAL, "ssl-default-bind-curves", ssl_parse_global_curves },
|
||||
#endif
|
||||
#if defined(SSL_CTX_set1_sigalgs_list)
|
||||
{ CFG_GLOBAL, "ssl-default-bind-sigalgs", ssl_parse_global_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 },
|
||||
|
@ -74,6 +74,9 @@ void ssl_sock_free_ssl_conf(struct ssl_bind_conf *conf)
|
||||
#endif
|
||||
ha_free(&conf->curves);
|
||||
ha_free(&conf->ecdhe);
|
||||
#if defined(SSL_CTX_set1_sigalgs_list)
|
||||
ha_free(&conf->sigalgs);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -151,6 +154,13 @@ struct ssl_bind_conf *crtlist_dup_ssl_conf(struct ssl_bind_conf *src)
|
||||
dst->ssl_methods.min = src->ssl_methods.min;
|
||||
dst->ssl_methods.max = src->ssl_methods.max;
|
||||
|
||||
#if defined(SSL_CTX_set1_sigalgs_list)
|
||||
if (src->sigalgs) {
|
||||
dst->sigalgs = strdup(src->sigalgs);
|
||||
if (!dst->sigalgs)
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
return dst;
|
||||
|
||||
error:
|
||||
|
@ -4570,6 +4570,9 @@ static int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, struct ssl_bind_con
|
||||
#endif
|
||||
const char *conf_curves = NULL;
|
||||
X509_STORE *store = SSL_CTX_get_cert_store(ctx);
|
||||
#if defined(SSL_CTX_set1_sigalgs_list)
|
||||
const char *conf_sigalgs = NULL;
|
||||
#endif
|
||||
|
||||
if (ssl_conf) {
|
||||
struct tls_version_filter *conf_ssl_methods = &ssl_conf->ssl_methods;
|
||||
@ -4772,6 +4775,17 @@ static int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, struct ssl_bind_con
|
||||
#endif /* HA_OPENSSL_VERSION_NUMBER >= 0x10101000L */
|
||||
}
|
||||
|
||||
#if defined(SSL_CTX_set1_sigalgs_list)
|
||||
conf_sigalgs = (ssl_conf && ssl_conf->sigalgs) ? ssl_conf->sigalgs : bind_conf->ssl_conf.sigalgs;
|
||||
if (conf_sigalgs) {
|
||||
if (!SSL_CTX_set1_sigalgs_list(ctx, conf_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_sigalgs, bind_conf->arg, bind_conf->file, bind_conf->line);
|
||||
cfgerr |= ERR_ALERT | ERR_FATAL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return cfgerr;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user