aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Kandaurov <pluknet@nginx.com>2025-04-03 15:29:31 +0400
committerpluknet <pluknet@nginx.com>2025-04-10 18:51:10 +0400
commitb6e7eb0f5792d7a52d2675ee3906e502d63c48e3 (patch)
tree145e5dd9adc9c5c6b9a4eced0cce88286a648f10
parent6c3a9d561271ec451f479a84fbe54c81a63dad2e (diff)
downloadnginx-b6e7eb0f5792d7a52d2675ee3906e502d63c48e3.tar.gz
nginx-b6e7eb0f5792d7a52d2675ee3906e502d63c48e3.zip
SSL: external groups support in $ssl_curve and $ssl_curves.
Starting with OpenSSL 3.0, groups may be added externally with pluggable KEM providers. Using SSL_get_negotiated_group(), which makes lookup in a static table with known groups, doesn't allow to list such groups by names leaving them in hex. Adding X25519MLKEM768 to the default group list in OpenSSL 3.5 made this problem more visible. SSL_get0_group_name() and, apparently, SSL_group_to_name() allow to resolve such provider-implemented groups, which is also "generally preferred" over SSL_get_negotiated_group() as documented in OpenSSL git commit 93d4f6133f. This change makes external groups listing by name using SSL_group_to_name() available since OpenSSL 3.0. To preserve "prime256v1" naming for the group 0x0017, and to avoid breaking BoringSSL and older OpenSSL versions support, it is used supplementary for a group that appears to be unknown. See https://github.com/openssl/openssl/issues/27137 for related discussion.
-rw-r--r--src/event/ngx_event_openssl.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index 865c78540..6992cc4a4 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -5040,7 +5040,8 @@ ngx_ssl_get_curve(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
{
#ifdef SSL_get_negotiated_group
- int nid;
+ int nid;
+ const char *name;
nid = SSL_get_negotiated_group(c->ssl->connection);
@@ -5052,14 +5053,24 @@ ngx_ssl_get_curve(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
return NGX_OK;
}
- s->len = sizeof("0x0000") - 1;
+#if (OPENSSL_VERSION_NUMBER >= 0x3000000fL)
+ name = SSL_group_to_name(c->ssl->connection, nid);
+#else
+ name = NULL;
+#endif
+ s->len = name ? ngx_strlen(name) : sizeof("0x0000") - 1;
s->data = ngx_pnalloc(pool, s->len);
if (s->data == NULL) {
return NGX_ERROR;
}
- ngx_sprintf(s->data, "0x%04xd", nid & 0xffff);
+ if (name) {
+ ngx_memcpy(s->data, name, s->len);
+
+ } else {
+ ngx_sprintf(s->data, "0x%04xd", nid & 0xffff);
+ }
return NGX_OK;
}
@@ -5079,6 +5090,7 @@ ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
int *curves, n, i, nid;
u_char *p;
size_t len;
+ const char *name;
n = SSL_get1_curves(c->ssl->connection, NULL);
@@ -5099,7 +5111,13 @@ ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
nid = curves[i];
if (nid & TLSEXT_nid_unknown) {
- len += sizeof("0x0000") - 1;
+#if (OPENSSL_VERSION_NUMBER >= 0x3000000fL)
+ name = SSL_group_to_name(c->ssl->connection, nid);
+#else
+ name = NULL;
+#endif
+
+ len += name ? ngx_strlen(name) : sizeof("0x0000") - 1;
} else {
len += ngx_strlen(OBJ_nid2sn(nid));
@@ -5119,7 +5137,14 @@ ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
nid = curves[i];
if (nid & TLSEXT_nid_unknown) {
- p = ngx_sprintf(p, "0x%04xd", nid & 0xffff);
+#if (OPENSSL_VERSION_NUMBER >= 0x3000000fL)
+ name = SSL_group_to_name(c->ssl->connection, nid);
+#else
+ name = NULL;
+#endif
+
+ p = name ? ngx_cpymem(p, name, ngx_strlen(name))
+ : ngx_sprintf(p, "0x%04xd", nid & 0xffff);
} else {
p = ngx_sprintf(p, "%s", OBJ_nid2sn(nid));