]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: ssl: add support for 'curves' keyword on server lines
authorWilliam Lallemand <wlallemand@haproxy.org>
Thu, 7 Sep 2023 21:13:15 +0000 (23:13 +0200)
committerWilliam Lallemand <wlallemand@haproxy.org>
Thu, 7 Sep 2023 21:29:10 +0000 (23:29 +0200)
This patch implements the 'curves' keyword on server lines as well as
the 'ssl-default-server-curves' keyword in the global section.

It also add the keyword on the server line in the ssl_curves reg-test.

These keywords allow the configuration of the curves list for a server.

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

index bbec0aa8929191b21dd1f1839e6e43844cb22f69..48d8054ad1f43442b8c3655b6c414f37c5401441 100644 (file)
@@ -1123,6 +1123,7 @@ The following keywords are supported in the "global" section :
    - ssl-default-server-ciphers
    - ssl-default-server-ciphersuites
    - ssl-default-server-client-sigalgs
+   - ssl-default-server-curves
    - ssl-default-server-options
    - ssl-default-server-sigalgs
    - ssl-dh-param-file
@@ -2336,6 +2337,13 @@ ssl-default-server-client-sigalgs <sigalgs>
   versions. It is not recommended to change this setting unless compatibility
   with a middlebox is required.
 
+ssl-default-server-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
+  suite") that are negotiated during the SSL/TLS handshake with ECDHE. The format
+  of the string is a colon-delimited list of curve name.
+  Please check the "server" keyword for more information.
+
 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"
@@ -16060,6 +16068,13 @@ crt <cert>
   at the same path suffixed by a ".key" (provided the "ssl-load-extra-files"
   option is set accordingly).
 
+curves <curves>
+  This setting is only available when support for OpenSSL was built in. It sets
+  the string describing the list of elliptic curves algorithms ("curve suite")
+  that are negotiated during the SSL/TLS handshake with ECDHE. The format of the
+  string is a colon-delimited list of curve name.
+  Example: "X25519:P-256" (without quote)
+
 disabled
   The "disabled" keyword starts the server in the "disabled" state. That means
   that it is marked down in maintenance mode, and no connection other than the
index 03f6899a9bf1ea222822b4efad8b62fd1a7bd6aa..1175a470e201d81e67faa1292c988758b761ce0c 100644 (file)
@@ -397,6 +397,7 @@ struct server {
 
                char *ciphers;                  /* cipher suite to use if non-null */
                char *ciphersuites;                     /* TLS 1.3 cipher suite to use if non-null */
+               char *curves;                    /* TLS curves list */
                int options;                    /* ssl options */
                int verify;                     /* verify method (set of SSL_VERIFY_* flags) */
                struct tls_version_filter methods;      /* ssl methods */
index 3805585117cace522a590e3a3895adfa78c493d6..fdf41a7a96c8df0b7848c69f5f688558150dcade 100644 (file)
@@ -278,6 +278,7 @@ struct global_ssl {
 #endif
 #if defined(SSL_CTX_set1_curves_list)
        char *listen_default_curves;
+       char *connect_default_curves;
 #endif
 #if defined(SSL_CTX_set1_sigalgs_list)
        char *listen_default_sigalgs;
index 5cc70df1449069d96d8a3806fb8ebb2b1b0ba74d..6a8b1b690d6d69ffbf8f3b70b717fffdc7d7b72e 100644 (file)
@@ -60,10 +60,10 @@ haproxy h1 -conf {
         default_backend ssl-be
 
     backend ssl-be
-        server s1 "${tmpdir}/ssl1.sock" ssl verify none crt ${testdir}/client.ecdsa.pem force-tlsv12
+        server s1 "${tmpdir}/ssl1.sock" ssl verify none crt ${testdir}/client.ecdsa.pem force-tlsv12 curves P-256:P-384
 
     backend ssl-curves-be
-        server s1 "${tmpdir}/ssl2.sock" ssl verify none crt ${testdir}/client.ecdsa.pem force-tlsv12
+        server s1 "${tmpdir}/ssl2.sock" ssl verify none crt ${testdir}/client.ecdsa.pem force-tlsv12 curves P-384
 
     backend ssl-ecdhe-256-be
         server s1 "${tmpdir}/ssl-ecdhe-256.sock" ssl verify none crt ${testdir}/client.ecdsa.pem force-tlsv12
index 08fcd1cd4ec265fe022f199bb32616d0d690bf48..1baad8f65c6d46c3e9a561cf2cceb760872f6349 100644 (file)
@@ -301,7 +301,7 @@ static int ssl_parse_global_curves(char **args, int section_type, struct proxy *
                                   char **err)
 {
        char **target;
-       target = &global_ssl.listen_default_curves;
+       target = (args[0][12] == 'b') ? &global_ssl.listen_default_curves : &global_ssl.connect_default_curves;
 
        if (too_many_args(1, args, err, NULL))
                return -1;
@@ -1669,6 +1669,14 @@ static int ssl_sock_init_srv(struct server *s)
        }
 #endif
 
+#if defined(SSL_CTX_set1_curves_list)
+       if (global_ssl.connect_default_curves && !s->ssl_ctx.curves) {
+               s->ssl_ctx.curves = strdup(global_ssl.connect_default_curves);
+               if (!s->ssl_ctx.curves)
+                       return 1;
+       }
+#endif
+
        return 0;
 }
 
@@ -1775,6 +1783,29 @@ static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struc
 #endif
 }
 
+/* parse the "curves" server keyword */
+static int srv_parse_curves(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
+{
+#ifndef SSL_CTX_set1_curves_list
+       memprintf(err, "'%s' : library does not support setting curves list", args[*cur_arg]);
+       return ERR_ALERT | ERR_FATAL;
+#else
+       char *arg;
+
+       arg = args[*cur_arg + 1];
+       if (!*arg) {
+               memprintf(err, "'%s' : missing curves list", args[*cur_arg]);
+               return ERR_ALERT | ERR_FATAL;
+       }
+       newsrv->ssl_ctx.curves = strdup(arg);
+       if (!newsrv->ssl_ctx.curves) {
+               memprintf(err, "out of memory");
+               return ERR_ALERT | ERR_FATAL;
+       }
+       return 0;
+#endif
+}
+
 /* parse the "crt" server keyword */
 static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
 {
@@ -2250,6 +2281,7 @@ static struct srv_kw_list srv_kws = { "SSL", { }, {
 #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 */
+       { "curves",                  srv_parse_curves,             1, 1, 1 }, /* set TLS curves list */
        { "crt",                     srv_parse_crt,                1, 1, 1 }, /* set client certificate */
        { "force-sslv3",             srv_parse_tls_method_options, 0, 1, 1 }, /* force SSLv3 */
        { "force-tlsv10",            srv_parse_tls_method_options, 0, 1, 1 }, /* force TLSv10 */
@@ -2320,6 +2352,7 @@ static struct cfg_kw_list cfg_kws = {ILH, {
        { CFG_GLOBAL, "ssl-default-server-ciphers", ssl_parse_global_ciphers },
 #if defined(SSL_CTX_set1_curves_list)
        { CFG_GLOBAL, "ssl-default-bind-curves", ssl_parse_global_curves },
+       { CFG_GLOBAL, "ssl-default-server-curves", ssl_parse_global_curves },
 #endif
 #if defined(SSL_CTX_set1_sigalgs_list)
        { CFG_GLOBAL, "ssl-default-bind-sigalgs", ssl_parse_global_sigalgs },
index aaa25008a4f064edb83b2ff9a0affcbe621cc43b..24d11bf1a2e61de632341084016e17cb6a755364 100644 (file)
@@ -5105,6 +5105,9 @@ static int ssl_sock_prepare_srv_ssl_ctx(const struct server *srv, SSL_CTX *ctx)
 #if defined(SSL_CTX_set1_client_sigalgs_list)
        const char *conf_client_sigalgs = NULL;
 #endif
+#if defined(SSL_CTX_set1_curves_list)
+       const char *conf_curves = 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. "
@@ -5264,6 +5267,17 @@ static int ssl_sock_prepare_srv_ssl_ctx(const struct server *srv, SSL_CTX *ctx)
        }
 #endif
 
+#if defined(SSL_CTX_set1_curves_list)
+       conf_curves =  srv->ssl_ctx.curves;
+       if (conf_curves) {
+               if (!SSL_CTX_set1_curves_list(ctx, conf_curves)) {
+                       ha_alert("Proxy '%s': unable to set SSL curves list to '%s' for server '%s'.\n",
+                                curproxy->id, conf_curves, srv->id);
+                       cfgerr++;
+               }
+       }
+#endif /* defined(SSL_CTX_set1_curves_list) */
+
        return cfgerr;
 }