]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: ssl: allow to change the client-sigalgs on server lines
authorWilliam Lallemand <wlallemand@haproxy.org>
Thu, 29 Jun 2023 12:11:46 +0000 (14:11 +0200)
committerWilliam Lallemand <wlallemand@haproxy.org>
Thu, 29 Jun 2023 12:11:46 +0000 (14:11 +0200)
This patch introduces the "client-sigalgs" keyword for the server line,
which allows to configure the list of server signature algorithms
negociated during the handshake. Also available as
"ssl-default-server-client-sigalgs" in the global section.

doc/configuration.txt
include/haproxy/server-t.h
include/haproxy/ssl_sock-t.h
src/cfgparse-ssl.c
src/ssl_sock.c

index d7f69514a34d4e81deb3055ae88915334f963e54..89346651d3fddd79df693412ee20c8a6c7ea5ab2 100644 (file)
@@ -1120,6 +1120,7 @@ The following keywords are supported in the "global" section :
    - ssl-default-bind-sigalgs
    - ssl-default-server-ciphers
    - ssl-default-server-ciphersuites
+   - ssl-default-server-client-sigalgs
    - ssl-default-server-options
    - ssl-default-server-sigalgs
    - ssl-dh-param-file
@@ -2275,6 +2276,21 @@ ssl-default-server-ciphersuites <ciphersuites>
   "ssl-default-server-ciphers" keyword. Please check the "server" keyword for
   more information.
 
+ssl-default-server-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 "server" 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-server-options [<option>]...
   This setting is only available when support for OpenSSL was built in. It sets
   default ssl-options to force on all "server" lines. Please check the "server"
@@ -15898,6 +15914,13 @@ ciphersuites <ciphersuites>
   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.
+
 cookie <value>
   The "cookie" parameter sets the cookie value assigned to the server to
   <value>. This value will be checked in incoming requests, and the first
index 732098d4d99fa9406cbf0ee3963e9c0fee86e444..f22d1fa49e24dc17c29e636193f14ae21ae954e6 100644 (file)
@@ -393,6 +393,7 @@ struct server {
                char *crl_file;                 /* CRLfile to use on verify */
                char *client_crt;               /* client certificate to send */
                char *sigalgs;                  /* Signature algorithms */
+               char *client_sigalgs;           /* Client Signature algorithms */
                struct sample_expr *sni;        /* sample expression for SNI */
                char *npn_str;                  /* NPN protocol string */
                int npn_len;                    /* NPN protocol string length */
index 3c87d844bf4ca7bedef836f369e84dd69fc68193..3805585117cace522a590e3a3895adfa78c493d6 100644 (file)
@@ -285,6 +285,7 @@ struct global_ssl {
 #endif
 #if defined(SSL_CTX_set1_sigalgs_list)
        char *listen_default_client_sigalgs;
+       char *connect_default_client_sigalgs;
 #endif
        int listen_default_ssloptions;
        int connect_default_ssloptions;
index 8ed958eaae4dcace8cc4e7c8ca389e6e2ca970e9..08fcd1cd4ec265fe022f199bb32616d0d690bf48 100644 (file)
@@ -355,7 +355,7 @@ static int ssl_parse_global_client_sigalgs(char **args, int section_type, struct
 {
        char **target;
 
-       target = &global_ssl.listen_default_client_sigalgs;
+       target = (args[0][12] == 'b') ? &global_ssl.listen_default_client_sigalgs : &global_ssl.connect_default_client_sigalgs;
 
        if (too_many_args(1, args, err, NULL))
                return -1;
@@ -1661,6 +1661,14 @@ static int ssl_sock_init_srv(struct server *s)
        }
 #endif
 
+#if defined(SSL_CTX_set1_client_sigalgs_list)
+       if (global_ssl.connect_default_client_sigalgs && !s->ssl_ctx.client_sigalgs) {
+               s->ssl_ctx.client_sigalgs = strdup(global_ssl.connect_default_client_sigalgs);
+               if (!s->ssl_ctx.client_sigalgs)
+                       return 1;
+       }
+#endif
+
        return 0;
 }
 
@@ -1716,6 +1724,30 @@ static int srv_parse_ciphersuites(char **args, int *cur_arg, struct proxy *px, s
 }
 #endif
 
+/* parse the "client-sigalgs" server keyword */
+static int srv_parse_client_sigalgs(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
+{
+#ifndef SSL_CTX_set1_client_sigalgs_list
+       memprintf(err, "'%s' : library does not support setting signature algorithms", args[*cur_arg]);
+       return ERR_ALERT | ERR_FATAL;
+#else
+       char *arg;
+
+       arg = args[*cur_arg + 1];
+       if (!*arg) {
+               memprintf(err, "'%s' : missing signature algorithm list", args[*cur_arg]);
+               return ERR_ALERT | ERR_FATAL;
+       }
+       newsrv->ssl_ctx.client_sigalgs = strdup(arg);
+       if (!newsrv->ssl_ctx.client_sigalgs) {
+               memprintf(err, "out of memory");
+               return ERR_ALERT | ERR_FATAL;
+       }
+       return 0;
+#endif
+}
+
+
 /* parse the "crl-file" server keyword */
 static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
 {
@@ -2216,6 +2248,7 @@ static struct srv_kw_list srv_kws = { "SSL", { }, {
 #ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
        { "ciphersuites",            srv_parse_ciphersuites,       1, 1, 1 }, /* select the cipher suite */
 #endif
+       { "client-sigalgs",          srv_parse_client_sigalgs,     1, 1, 1 }, /* signature algorithms */
        { "crl-file",                srv_parse_crl_file,           1, 1, 1 }, /* set certificate revocation list file use on server cert verify */
        { "crt",                     srv_parse_crt,                1, 1, 1 }, /* set client certificate */
        { "force-sslv3",             srv_parse_tls_method_options, 0, 1, 1 }, /* force SSLv3 */
@@ -2294,6 +2327,7 @@ static struct cfg_kw_list cfg_kws = {ILH, {
 #endif
 #if defined(SSL_CTX_set1_client_sigalgs_list)
        { CFG_GLOBAL, "ssl-default-bind-client-sigalgs", ssl_parse_global_client_sigalgs },
+       { CFG_GLOBAL, "ssl-default-server-client-sigalgs", ssl_parse_global_client_sigalgs },
 #endif
 #ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
        { CFG_GLOBAL, "ssl-default-bind-ciphersuites", ssl_parse_global_ciphersuites },
index 61e988b60351eab376069993729d8ae478f4df50..9f48483d9a0589fc180bf5c676602a3fb4d3e76b 100644 (file)
@@ -5050,7 +5050,9 @@ static int ssl_sock_prepare_srv_ssl_ctx(const struct server *srv, SSL_CTX *ctx)
 #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 (conf_ssl_methods->flags && (conf_ssl_methods->min || conf_ssl_methods->max))
                ha_warning("no-sslv3/no-tlsv1x are ignored for this server. "
@@ -5199,6 +5201,16 @@ static int ssl_sock_prepare_srv_ssl_ctx(const struct server *srv, SSL_CTX *ctx)
                }
        }
 #endif
+#if defined(SSL_CTX_set1_client_sigalgs_list)
+       conf_client_sigalgs = srv->ssl_ctx.client_sigalgs;
+       if (conf_client_sigalgs) {
+               if (!SSL_CTX_set1_client_sigalgs_list(ctx, conf_client_sigalgs)) {
+                       ha_alert("Proxy '%s': unable to set SSL Client Signature Algorithm list to '%s' for server '%s'.\n",
+                                curproxy->id, conf_client_sigalgs, srv->id);
+                       cfgerr++;
+               }
+       }
+#endif
 
        return cfgerr;
 }