From mdounin at mdounin.ru Tue Apr 8 15:50:13 2025 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 8 Apr 2025 18:50:13 +0300 Subject: freenginx-1.27.5 Message-ID: Changes with freenginx 1.27.5 08 Apr 2025 *) Feature: the "multipath" parameter of the "listen" directive. Thanks to Maxime Dourov and Anthony Doeraene. *) Change: SSL session reuse is no longer allowed between servers with different certificates set by the "ssl_trusted_certificate" directive if client SSL certificate verification is enabled. *) Workaround: when using TLSv1.3 with OpenSSL 1.1.1e or newer, it was possible to reuse an SSL session in a different virtual server context, notably with different certificates set by the "ssl_client_certificate" directive. *) Workaround: "gzip filter failed to use preallocated memory" alerts appeared in logs when using zlib-ng. -- Maxim Dounin http://freenginx.org/ From sca at andreasschulze.de Wed Apr 9 19:56:17 2025 From: sca at andreasschulze.de (A. Schulze) Date: Wed, 9 Apr 2025 21:56:17 +0200 Subject: freenginx-1.27.5 In-Reply-To: References: Message-ID: Am 08.04.25 um 17:50 schrieb Maxim Dounin: > Changes with freenginx 1.27.5 08 Apr 2025 > ... Hello, I've build freenginx with the just releases openssl-3.5.0. The new PQ key exchange is enabled in openssl-3.5 and freenginx use it without special configuration. (the defaults for ssl_ecdh_curve are fine) But in the log, the variable 'ssl_curve' [1] still say only the numeric number 0x11ec Firefox could name that key-exchange as "mlkem768x25519" Andreas [1] https://freenginx.org/en/docs/http/ngx_http_ssl_module.html#var_ssl_curve From mdounin at mdounin.ru Thu Apr 10 05:09:53 2025 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 10 Apr 2025 08:09:53 +0300 Subject: freenginx-1.27.5 In-Reply-To: References: Message-ID: Hello! On Wed, Apr 09, 2025 at 09:56:17PM +0200, A. Schulze via nginx wrote: > Am 08.04.25 um 17:50 schrieb Maxim Dounin: > > Changes with freenginx 1.27.5 08 Apr 2025 > > ... > > Hello, > > I've build freenginx with the just releases openssl-3.5.0. > The new PQ key exchange is enabled in openssl-3.5 and freenginx use it without special configuration. > (the defaults for ssl_ecdh_curve are fine) > > But in the log, the variable 'ssl_curve' [1] still say only the numeric number 0x11ec > Firefox could name that key-exchange as "mlkem768x25519" The $ssl_curve variable uses SSL_get_negotiated_group() and then uses OBJ_nid2sn() as long as the group is known to OpenSSL. It looks like OpenSSL for some reason decided not to add NIDs for these groups - not sure why. Either it is just an omission which is going to be fixed, or the intention is to force users to move away from using NIDs to newer interfaces, such as SSL_get0_group_name() and SSL_group_to_name(). I suspect this is just an omission and it will be eventually fixed in OpenSSL. (Just for the record, with BoringSSL the code just works and provides correct $ssl_curves name for X25519MLKEM768.) OTOH, you may try the following patch which tries to use SSL_get0_group_name() and SSL_group_to_name() if available. Note thought that it slightly changes names as seen in the $ssl_curve and $ssl_curves variables. In particular, with OpenSSL 3.5 both on the server and as a client, variables are changed from: $ssl_curve: 0x11ec $ssl_curves: 0x11ec:X25519:prime256v1:X448:secp384r1:secp521r1:ffdhe2048:ffdhe3072 to the following: $ssl_curve: X25519MLKEM768 $ssl_curves: X25519MLKEM768:x25519:secp256r1:x448:secp384r1:secp521r1:ffdhe2048:ffdhe3072 Note "X25519" changed to "x25519", and "prime256v1" to "secp256r1". Please let me know what do you think. # HG changeset patch # User Maxim Dounin # Date 1744258053 -10800 # Thu Apr 10 07:07:33 2025 +0300 # Node ID 0c82db8ddbed7ae4104a5c00d442b4cf0d3434e1 # Parent 8e674d7e1a1ad3648498d0cba2c9b2a9da5d3777 SSL: improved handling of $ssl_curve and $ssl_curves variables. Now $ssl_curve uses SSL_get0_group_name() if available, and $ssl_curves uses SSL_get0_iana_groups(). Notably, this makes it possible to see the names of the X25519MLKEM768 group as supported by OpenSSL 3.5.0. diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -5256,7 +5256,31 @@ ngx_ssl_get_ciphers(ngx_connection_t *c, ngx_int_t ngx_ssl_get_curve(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) { -#ifdef SSL_get_negotiated_group +#ifdef SSL_get0_iana_groups + + u_char *name; + + /* + * Both SSL_get0_group_name() and SSL_get0_iana_groups() + * appeared in OpenSSL 3.2.0. + */ + + name = (u_char *) SSL_get0_group_name(c->ssl->connection); + + if (name) { + s->len = ngx_strlen(name); + + s->data = ngx_pnalloc(pool, s->len); + if (s->data == NULL) { + return NGX_ERROR; + } + + ngx_memcpy(s->data, name, s->len); + + return NGX_OK; + } + +#elif defined SSL_get_negotiated_group int nid; @@ -5292,7 +5316,64 @@ ngx_ssl_get_curve(ngx_connection_t *c, n ngx_int_t ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) { -#ifdef SSL_CTRL_GET_CURVES +#ifdef SSL_get0_iana_groups + + int n, i, nid; + u_char *p, *name; + size_t len; + uint16_t *groups; + + n = SSL_get0_iana_groups(c->ssl->connection, &groups); + + if (n <= 0) { + s->len = 0; + return NGX_OK; + } + + len = 0; + + for (i = 0; i < n; i++) { + nid = groups[i] | TLSEXT_nid_unknown; + + name = (u_char *) SSL_group_to_name(c->ssl->connection, nid); + + if (name) { + len += ngx_strlen(name); + + } else { + len += sizeof("0x0000") - 1; + } + + len += sizeof(":") - 1; + } + + s->data = ngx_pnalloc(pool, len); + if (s->data == NULL) { + return NGX_ERROR; + } + + p = s->data; + + for (i = 0; i < n; i++) { + nid = groups[i] | TLSEXT_nid_unknown; + + name = (u_char *) SSL_group_to_name(c->ssl->connection, nid); + + if (name) { + p = ngx_sprintf(p, "%s", name); + + } else { + p = ngx_sprintf(p, "0x%04xd", nid & 0xffff); + } + + *p++ = ':'; + } + + p--; + + s->len = p - s->data; + +#elif defined SSL_get1_curves int *curves, n, i, nid; u_char *p; -- Maxim Dounin http://mdounin.ru/ From mdounin at mdounin.ru Thu Apr 10 13:34:25 2025 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 10 Apr 2025 16:34:25 +0300 Subject: freenginx-1.27.5 In-Reply-To: References: Message-ID: Hello! On Thu, Apr 10, 2025 at 08:09:53AM +0300, Maxim Dounin wrote: > On Wed, Apr 09, 2025 at 09:56:17PM +0200, A. Schulze via nginx wrote: > > > Am 08.04.25 um 17:50 schrieb Maxim Dounin: > > > Changes with freenginx 1.27.5 08 Apr 2025 > > > ... > > > > Hello, > > > > I've build freenginx with the just releases openssl-3.5.0. > > The new PQ key exchange is enabled in openssl-3.5 and freenginx use it without special configuration. > > (the defaults for ssl_ecdh_curve are fine) > > > > But in the log, the variable 'ssl_curve' [1] still say only the numeric number 0x11ec > > Firefox could name that key-exchange as "mlkem768x25519" > > The $ssl_curve variable uses SSL_get_negotiated_group() and then > uses OBJ_nid2sn() as long as the group is known to OpenSSL. > > It looks like OpenSSL for some reason decided not to add NIDs for > these groups - not sure why. Either it is just an omission which > is going to be fixed, or the intention is to force users to move > away from using NIDs to newer interfaces, such as > SSL_get0_group_name() and SSL_group_to_name(). > > I suspect this is just an omission and it will be eventually fixed > in OpenSSL. (Just for the record, with BoringSSL the code just > works and provides correct $ssl_curves name for X25519MLKEM768.) For the record, here is the relevant OpenSSL issue: https://github.com/openssl/openssl/issues/27137 It appears that the omission was indeed unintentional, but the suggested solution is to switch to new interfaces. [...] -- Maxim Dounin http://mdounin.ru/ From sca at andreasschulze.de Thu Apr 10 20:15:06 2025 From: sca at andreasschulze.de (A. Schulze) Date: Thu, 10 Apr 2025 22:15:06 +0200 Subject: freenginx-1.27.5 In-Reply-To: References: Message-ID: Am 10.04.25 um 07:09 schrieb Maxim Dounin: > OTOH, you may try the following patch which tries to use > SSL_get0_group_name() and SSL_group_to_name() if available. > > Note thought that it slightly changes names as seen in the > $ssl_curve and $ssl_curves variables. In particular, with OpenSSL > 3.5 both on the server and as a client, variables are changed > from: > > $ssl_curve: 0x11ec > $ssl_curves: 0x11ec:X25519:prime256v1:X448:secp384r1:secp521r1:ffdhe2048:ffdhe3072 > > to the following: > > $ssl_curve: X25519MLKEM768 > $ssl_curves: X25519MLKEM768:x25519:secp256r1:x448:secp384r1:secp521r1:ffdhe2048:ffdhe3072 > > Note "X25519" changed to "x25519", and "prime256v1" to > "secp256r1". > > Please let me know what do you think. Hello Maxim, the patch let freenginx use the expected names I personally prefer over hex numbers. I don't care if I read X25519 or x25519. I also do not know a scenario, where these names matter. But this doesn't mean, they do not exist. If the would exist, an operator may with to decide/configure, which names nginx should use. Andreas From mdounin at mdounin.ru Sun Apr 13 16:16:10 2025 From: mdounin at mdounin.ru (Maxim Dounin) Date: Sun, 13 Apr 2025 19:16:10 +0300 Subject: freenginx-1.27.5 In-Reply-To: References: Message-ID: Hello! On Thu, Apr 10, 2025 at 10:15:06PM +0200, A. Schulze via nginx wrote: > Am 10.04.25 um 07:09 schrieb Maxim Dounin: > > OTOH, you may try the following patch which tries to use > > SSL_get0_group_name() and SSL_group_to_name() if available. > > > > Note thought that it slightly changes names as seen in the > > $ssl_curve and $ssl_curves variables. In particular, with OpenSSL > > 3.5 both on the server and as a client, variables are changed > > from: > > > > $ssl_curve: 0x11ec > > $ssl_curves: 0x11ec:X25519:prime256v1:X448:secp384r1:secp521r1:ffdhe2048:ffdhe3072 > > > > to the following: > > > > $ssl_curve: X25519MLKEM768 > > $ssl_curves: X25519MLKEM768:x25519:secp256r1:x448:secp384r1:secp521r1:ffdhe2048:ffdhe3072 > > > > Note "X25519" changed to "x25519", and "prime256v1" to > > "secp256r1". > > > > Please let me know what do you think. > > Hello Maxim, > > the patch let freenginx use the expected names I personally prefer over hex numbers. > I don't care if I read X25519 or x25519. I also do not know a scenario, where these names matter. > But this doesn't mean, they do not exist. If the would exist, an operator may with to > decide/configure, which names nginx should use. Thanks for the feedback. Here is an updated path, which instead uses NIDs as before to preserve existing names, and SSL_group_to_name() only if NID is not found. Main benefit of this approach is that names are consistent across various SSL libraries, such as different versions of OpenSSL and BoringSSL. # HG changeset patch # User Maxim Dounin # Date 1744560375 -10800 # Sun Apr 13 19:06:15 2025 +0300 # Node ID e6805fbe81004faafe47d69fb267e4a6b4b0cfbf # Parent 0a8083b7093e88a56b6b06d534b52c367728d005 SSL: improved handling of $ssl_curve and $ssl_curves variables. Now both $ssl_curve and $ssl_curves try to use SSL_group_to_name() if available and no NID is found. Notably, this makes it possible to see the name of the X25519MLKEM768 group as supported by OpenSSL 3.5.0. diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -5270,6 +5270,26 @@ ngx_ssl_get_curve(ngx_connection_t *c, n return NGX_OK; } +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + { + u_char *name; + + name = (u_char *) SSL_group_to_name(c->ssl->connection, nid); + + if (name) { + s->len = ngx_strlen(name); + + s->data = ngx_pnalloc(pool, s->len); + if (s->data == NULL) { + return NGX_ERROR; + } + + ngx_memcpy(s->data, name, s->len); + return NGX_OK; + } + } +#endif + s->len = sizeof("0x0000") - 1; s->data = ngx_pnalloc(pool, s->len); @@ -5292,10 +5312,13 @@ ngx_ssl_get_curve(ngx_connection_t *c, n ngx_int_t ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) { -#ifdef SSL_CTRL_GET_CURVES +#ifdef SSL_get1_curves int *curves, n, i, nid; u_char *p; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + u_char *name; +#endif size_t len; n = SSL_get1_curves(c->ssl->connection, NULL); @@ -5316,12 +5339,25 @@ ngx_ssl_get_curves(ngx_connection_t *c, for (i = 0; i < n; i++) { nid = curves[i]; - if (nid & TLSEXT_nid_unknown) { - len += sizeof("0x0000") - 1; - - } else { + if ((nid & TLSEXT_nid_unknown) == 0) { len += ngx_strlen(OBJ_nid2sn(nid)); - } + goto next_length; + } + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + + name = (u_char *) SSL_group_to_name(c->ssl->connection, nid); + + if (name) { + len += ngx_strlen(name); + goto next_length; + } + +#endif + + len += sizeof("0x0000") - 1; + + next_length: len += sizeof(":") - 1; } @@ -5336,12 +5372,26 @@ ngx_ssl_get_curves(ngx_connection_t *c, for (i = 0; i < n; i++) { nid = curves[i]; - if (nid & TLSEXT_nid_unknown) { - p = ngx_sprintf(p, "0x%04xd", nid & 0xffff); - - } else { + if ((nid & TLSEXT_nid_unknown) == 0) { p = ngx_sprintf(p, "%s", OBJ_nid2sn(nid)); - } + goto next_value; + + } + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + + name = (u_char *) SSL_group_to_name(c->ssl->connection, nid); + + if (name) { + p = ngx_sprintf(p, "%s", name); + goto next_value; + } + +#endif + + p = ngx_sprintf(p, "0x%04xd", nid & 0xffff); + + next_value: *p++ = ':'; } -- Maxim Dounin http://mdounin.ru/ From mdounin at mdounin.ru Tue Apr 15 18:13:37 2025 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 15 Apr 2025 21:13:37 +0300 Subject: freenginx-1.27.6 Message-ID: Changes with freenginx 1.27.6 15 Apr 2025 *) Workaround: the X25519MLKEM768 group name was not shown in the $ssl_curve and $ssl_curves variables when using OpenSSL 3.5. *) Bugfix: a segmentation fault might occur in a worker process if the "proxy_ssl_password_file" directive was used along with variables in the "proxy_ssl_certificate" or "proxy_ssl_certificate_key" directives; the bug had appeared in 1.23.1. -- Maxim Dounin http://freenginx.org/ From mdounin at mdounin.ru Tue Apr 22 09:02:01 2025 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 22 Apr 2025 12:02:01 +0300 Subject: freenginx-1.28.0 Message-ID: Changes with freenginx 1.28.0 22 Apr 2025 *) 1.28.x stable branch. -- Maxim Dounin http://freenginx.org/