diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c index 1653be0c3..bdca69768 100644 --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -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) { 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 },