mirror of
https://github.com/nginx/nginx.git
synced 2026-06-11 01:41:00 -04:00
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 schemes without a registered name. On older OpenSSL (1.0.2+, not BoringSSL, not LibreSSL), 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(). Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d44205284f
commit
a3ef7dea8a
4 changed files with 111 additions and 0 deletions
|
|
@ -5669,6 +5669,109 @@ 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 (OPENSSL_VERSION_NUMBER >= 0x10002000L \
|
||||
&& !defined OPENSSL_IS_BORINGSSL \
|
||||
&& !defined LIBRESSL_VERSION_NUMBER)
|
||||
|
||||
/*
|
||||
* SSL_get_sigalgs() suits TLS 1.2; OBJ_nid2sn() on the combined
|
||||
* psignhash NID is not injective across TLS SignatureScheme codes
|
||||
* (e.g. 0x0403 and 0x081a both yield "ecdsa-with-SHA256"), so raw
|
||||
* SignatureScheme codes are used to avoid ambiguity and to match
|
||||
* the hex fallback format of SSL_get0_sigalg() above.
|
||||
*/
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 },
|
||||
|
||||
|
|
|
|||
|
|
@ -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 },
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue