From: Vadim Zhestikov Date: Tue, 2 Jun 2026 15:02:17 +0000 (-0700) Subject: SSL: add $ssl_sigalgs variable X-Git-Tag: release-1.31.2~18 X-Git-Url: http://git.kaiwu.me/postgresql/log/contrib/postgres_fdw/static/favicon.ico?a=commitdiff_plain;h=1c387799ca8eff23aea0166e97ebd8f4435839b1;p=nginx.git SSL: add $ssl_sigalgs variable The new $ssl_sigalgs variable lists all signature algorithms advertised by the client in its ClientHello message, colon-separated, in analogy to $ssl_ciphers and $ssl_curves. On OpenSSL 4.0+, SSL_get0_sigalg() is used, which returns proper TLS scheme names (e.g. "rsa_pkcs1_sha256", "ecdsa_secp256r1_sha256") and falls back to "0xHHHH" hex for unknown schemes. On OpenSSL 1.0.2+, SSL_get_sigalgs() is used. Since OBJ_nid2sn() on the combined psignhash NID is not injective across TLS SignatureScheme codes (e.g. 0x0403 and 0x081a both yield "ecdsa-with-SHA256"), raw SignatureScheme codes are reported to avoid ambiguity and to match the hex fallback format of SSL_get0_sigalg(). With older versions, as well as BoringSSL, LibreSSL, and AWS-LC, the variable is empty. --- diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c index 1653be0c3..573894629 100644 --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -5669,6 +5669,104 @@ ngx_ssl_get_sigalg(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) } +ngx_int_t +ngx_ssl_get_sigalgs(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) +{ +#if (OPENSSL_VERSION_NUMBER >= 0x40000000L) + + int n, i; + size_t len; + u_char *p; + const char *name; + unsigned int codepoint; + + n = SSL_get0_sigalg(c->ssl->connection, -1, NULL, NULL); + + if (n <= 0) { + s->len = 0; + return NGX_OK; + } + + len = 0; + + for (i = 0; i < n; i++) { + SSL_get0_sigalg(c->ssl->connection, i, &codepoint, &name); + len += name ? ngx_strlen(name) : 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++) { + SSL_get0_sigalg(c->ssl->connection, i, &codepoint, &name); + + if (name) { + p = ngx_cpymem(p, name, ngx_strlen(name)); + + } else { + p = ngx_sprintf(p, "0x%04xd", codepoint); + } + + *p++ = ':'; + } + + p--; + + s->len = p - s->data; + +#elif defined SSL_CTRL_SET_SIGALGS + + /* + * SSL_get_sigalgs() is only available in OpenSSL 1.0.2+, + * but uses a different naming, so emit raw codes + */ + + int n, i; + size_t len; + u_char *p; + unsigned char rsig, rhash; + + n = SSL_get_sigalgs(c->ssl->connection, -1, NULL, NULL, NULL, NULL, NULL); + + if (n <= 0) { + s->len = 0; + return NGX_OK; + } + + len = n * (sizeof("0x0000") - 1 + sizeof(":") - 1); + + s->data = ngx_pnalloc(pool, len); + if (s->data == NULL) { + return NGX_ERROR; + } + + p = s->data; + + for (i = 0; i < n; i++) { + SSL_get_sigalgs(c->ssl->connection, i, NULL, NULL, NULL, &rsig, &rhash); + p = ngx_sprintf(p, "0x%04xd", rhash << 8 | rsig); + *p++ = ':'; + } + + p--; + + s->len = p - s->data; + +#else + + s->len = 0; + +#endif + + return NGX_OK; +} + + ngx_int_t ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) { diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h index 79ae39503..12ac01b3c 100644 --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -337,6 +337,8 @@ ngx_int_t ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); ngx_int_t ngx_ssl_get_sigalg(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); +ngx_int_t ngx_ssl_get_sigalgs(ngx_connection_t *c, ngx_pool_t *pool, + ngx_str_t *s); ngx_int_t ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); ngx_int_t ngx_ssl_get_session_reused(ngx_connection_t *c, ngx_pool_t *pool, diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c index 43fcafd50..0afcc9dd1 100644 --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -368,6 +368,9 @@ static ngx_http_variable_t ngx_http_ssl_vars[] = { { ngx_string("ssl_sigalg"), NULL, ngx_http_ssl_variable, (uintptr_t) ngx_ssl_get_sigalg, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_sigalgs"), NULL, ngx_http_ssl_variable, + (uintptr_t) ngx_ssl_get_sigalgs, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_session_id"), NULL, ngx_http_ssl_variable, (uintptr_t) ngx_ssl_get_session_id, NGX_HTTP_VAR_CHANGEABLE, 0 }, diff --git a/src/stream/ngx_stream_ssl_module.c b/src/stream/ngx_stream_ssl_module.c index 0e17cff4d..c68333a1c 100644 --- a/src/stream/ngx_stream_ssl_module.c +++ b/src/stream/ngx_stream_ssl_module.c @@ -367,6 +367,9 @@ static ngx_stream_variable_t ngx_stream_ssl_vars[] = { { ngx_string("ssl_sigalg"), NULL, ngx_stream_ssl_variable, (uintptr_t) ngx_ssl_get_sigalg, NGX_STREAM_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_sigalgs"), NULL, ngx_stream_ssl_variable, + (uintptr_t) ngx_ssl_get_sigalgs, NGX_STREAM_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_session_id"), NULL, ngx_stream_ssl_variable, (uintptr_t) ngx_ssl_get_session_id, NGX_STREAM_VAR_CHANGEABLE, 0 },