The very first try to submit the early development of this patch here, got this response:
http://mailman.nginx.org/pipermail/nginx-devel/2017-August/010426.html <http://mailman.nginx.org/pipermail/nginx-devel/2017-August/010426.html> Thanx > On 24 Apr 2020, at 17:25, Garret Reece <gar...@trailofbits.com> wrote: > > More or less, yes--we had a request from a customer to take just the > extensions and the elliptic curve format points data from your patch > and make them available in the main package > > On Fri, Apr 24, 2020 at 11:17 AM Paulo Pacheco <fooi...@gmail.com> wrote: >> >> Hello, this looks very similar with what I've done here. >> >> https://github.com/fooinha/nginx-ssl-ja3/blob/master/patches/nginx.1.17.1.ssl.extensions.patch >> >> Is this the same code? >> >> >> Thanx. >> >> >> >> >> >> >> On 24 Apr 2020, at 16:17, Garret Reece <gar...@trailofbits.com> wrote: >> >> # HG changeset patch >> # User Garret Reece <gar...@trailofbits.com> >> # Date 1587691836 18000 >> # Thu Apr 23 20:30:36 2020 -0500 >> # Node ID 86d2f46807f597249fa59072b920a389f8c082ee >> # Parent 716eddd74bc2831537f5b3f7ecd16ad3e516d043 >> Expose additional SSL variables. >> >> Expose the ssl extensions and elliptic curve point formats provided by >> client. >> This enables ja3 fingerprinting of TLS connections. >> >> diff -r 716eddd74bc2 -r 86d2f46807f5 src/event/ngx_event_openssl.c >> --- a/src/event/ngx_event_openssl.c Thu Apr 23 15:10:26 2020 +0300 >> +++ b/src/event/ngx_event_openssl.c Thu Apr 23 20:30:36 2020 -0500 >> @@ -1588,6 +1588,100 @@ >> return NGX_OK; >> } >> >> +#if OPENSSL_VERSION_NUMBER >= 0x10101000L >> + >> +void >> +ngx_SSL_client_features(ngx_connection_t *c) >> +{ >> + unsigned short *ciphers_out = NULL; >> + int *curves_out = NULL; >> + int *point_formats_out = NULL; >> + size_t len = 0; >> + SSL *s = NULL; >> + >> + if (c == NULL) { >> + return; >> + } >> + s = c->ssl->connection; >> + >> + /* Cipher suites */ >> + c->ssl->ciphers = NULL; >> + c->ssl->ciphers_sz = SSL_get0_raw_cipherlist(s, &ciphers_out); >> + c->ssl->ciphers_sz /= 2; >> + >> + if (c->ssl->ciphers_sz && ciphers_out) { >> + len = c->ssl->ciphers_sz * sizeof(unsigned short); >> + c->ssl->ciphers = ngx_pnalloc(c->pool, len); >> + ngx_memcpy(c->ssl->ciphers, ciphers_out, len); >> + } >> + >> + /* Elliptic curve points */ >> + c->ssl->curves_sz = SSL_get1_curves(s, NULL); >> + if (c->ssl->curves_sz) { >> + curves_out = OPENSSL_malloc(c->ssl->curves_sz * sizeof(int)); >> + if (curves_out != NULL) { >> + SSL_get1_curves(s, curves_out); >> + len = c->ssl->curves_sz * sizeof(unsigned short); >> + c->ssl->curves = ngx_pnalloc(c->pool, len); >> + if (c->ssl->curves != NULL) { >> + for (size_t i = 0; i < c->ssl->curves_sz; i++) { >> + c->ssl->curves[i] = curves_out[i]; >> + } >> + } >> + OPENSSL_free(curves_out); >> + } >> + } >> + >> + /* Elliptic curve point formats */ >> + c->ssl->point_formats_sz = SSL_get0_ec_point_formats(s, >> + &point_formats_out); >> + if (c->ssl->point_formats_sz && point_formats_out != NULL) { >> + len = c->ssl->point_formats_sz * sizeof(unsigned char); >> + c->ssl->point_formats = ngx_pnalloc(c->pool, len); >> + if (c->ssl->point_formats != NULL) { >> + ngx_memcpy(c->ssl->point_formats, point_formats_out, len); >> + } >> + } >> +} >> + >> +int >> +ngx_SSL_early_cb_fn(SSL *s, int *al, void *arg) >> +{ >> + int got_extensions; >> + int *ext_out; >> + size_t ext_len; >> + ngx_connection_t *c; >> + >> + c = arg; >> + >> + if (c == NULL) { >> + return 1; >> + } >> + >> + if (c->ssl == NULL) { >> + return 1; >> + } >> + >> + c->ssl->extensions_size = 0; >> + c->ssl->extensions = NULL; >> + got_extensions = SSL_client_hello_get1_extensions_present(s, >> + &ext_out, >> + &ext_len); >> + if (got_extensions) { >> + if (ext_out && ext_len) { >> + c->ssl->extensions = >> + ngx_palloc(c->pool, sizeof(int) * ext_len); >> + if (c->ssl->extensions != NULL) { >> + c->ssl->extensions_size = ext_len; >> + ngx_memcpy(c->ssl->extensions, ext_out, sizeof(int) * >> ext_len); >> + OPENSSL_free(ext_out); >> + } >> + } >> + } >> + >> + return 1; >> +} >> +#endif >> >> ngx_int_t >> ngx_ssl_handshake(ngx_connection_t *c) >> @@ -1603,6 +1697,10 @@ >> >> ngx_ssl_clear_error(c->log); >> >> +#if OPENSSL_VERSION_NUMBER >= 0x10101000L >> + SSL_CTX_set_client_hello_cb(c->ssl->session_ctx, ngx_SSL_early_cb_fn, >> c); >> +#endif >> + >> n = SSL_do_handshake(c->ssl->connection); >> >> ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n); >> @@ -1623,6 +1721,10 @@ >> >> c->ssl->handshaked = 1; >> >> +#if OPENSSL_VERSION_NUMBER >= 0x10101000L >> + ngx_SSL_client_features(c); >> +#endif >> + >> c->recv = ngx_ssl_recv; >> c->send = ngx_ssl_write; >> c->recv_chain = ngx_ssl_recv_chain; >> @@ -5044,6 +5146,86 @@ >> return NGX_OK; >> } >> >> +#if OPENSSL_VERSION_NUMBER >= 0x10101000L >> + >> +ngx_int_t >> +ngx_ssl_get_extensions(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) >> +{ >> + size_t len; >> + u_char *p; >> + >> + len = 0; >> + s->len = 0; >> + >> + if (c->ssl->extensions_size && c->ssl->extensions) { >> + for (int n = c->ssl->extensions[0]; n > 9; n /= 10) { >> + len += 1; >> + } >> + len += 1; >> + for (size_t i = 1; i < c->ssl->extensions_size; ++i) { >> + len += 1; /* for the '-' separator */ >> + for (int n = c->ssl->extensions[i]; n > 9; n /= 10) { >> + len += 1; >> + } >> + len += 1; >> + } >> + >> + s->data = ngx_pnalloc(pool, len+1); >> + if (s->data == NULL) { >> + return NGX_ERROR; >> + } >> + s->len = len; >> + >> + p = ngx_sprintf(s->data, "%d", c->ssl->extensions[0]); >> + for (size_t i = 1; i < c->ssl->extensions_size; ++i) { >> + p = ngx_sprintf(p, "-%d", c->ssl->extensions[i]); >> + } >> + >> + } >> + return NGX_OK; >> +} >> + >> + >> +ngx_int_t >> +ngx_ssl_get_ec_point_formats(ngx_connection_t *c, ngx_pool_t *pool, >> + ngx_str_t *s) >> +{ >> + size_t len; >> + u_char *p; >> + >> + len = 0; >> + s->len = 0; >> + >> + if (c->ssl->point_formats_sz && c->ssl->point_formats) { >> + for (unsigned char n = c->ssl->point_formats[0]; n > 9; n /= 10) { >> + len += 1; >> + } >> + len += 1; >> + for (size_t i = 1; i < c->ssl->point_formats_sz; ++i) { >> + len += 1; /* for the '-' separator */ >> + for (unsigned char n = c->ssl->point_formats[i]; n > 9; n /= >> 10) { >> + len += 1; >> + } >> + len += 1; >> + } >> + >> + s->data = ngx_pnalloc(pool, len+1); >> + if (s->data == NULL) { >> + return NGX_ERROR; >> + } >> + s->len = len; >> + >> + p = ngx_sprintf(s->data, "%d", c->ssl->point_formats[0]); >> + for (size_t i = 1; i < c->ssl->point_formats_sz; ++i) { >> + p = ngx_sprintf(p, "-%d", c->ssl->point_formats[i]); >> + } >> + } >> + >> + return NGX_OK; >> +} >> + >> +#endif >> + >> >> static time_t >> ngx_ssl_parse_time( >> diff -r 716eddd74bc2 -r 86d2f46807f5 src/event/ngx_event_openssl.h >> --- a/src/event/ngx_event_openssl.h Thu Apr 23 15:10:26 2020 +0300 >> +++ b/src/event/ngx_event_openssl.h Thu Apr 23 20:30:36 2020 -0500 >> @@ -99,6 +99,21 @@ >> unsigned in_early:1; >> unsigned early_preread:1; >> unsigned write_blocked:1; >> + >> +#if OPENSSL_VERSION_NUMBER >= 0x10101000L >> + >> + size_t ciphers_sz; >> + unsigned short *ciphers; >> + >> + size_t extensions_size; >> + int *extensions; >> + >> + size_t curves_sz; >> + unsigned short *curves; >> + >> + size_t point_formats_sz; >> + unsigned char *point_formats; >> +#endif >> }; >> >> >> @@ -263,6 +278,14 @@ >> ngx_int_t ngx_ssl_get_client_v_remain(ngx_connection_t *c, ngx_pool_t *pool, >> ngx_str_t *s); >> >> +#if OPENSSL_VERSION_NUMBER >= 0x10101000L >> + >> +ngx_int_t ngx_ssl_get_extensions(ngx_connection_t *c, ngx_pool_t *pool, >> + ngx_str_t *s); >> +ngx_int_t ngx_ssl_get_ec_point_formats(ngx_connection_t *c, ngx_pool_t >> *pool, >> + ngx_str_t *s); >> + >> +#endif >> >> ngx_int_t ngx_ssl_handshake(ngx_connection_t *c); >> ssize_t ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size); >> diff -r 716eddd74bc2 -r 86d2f46807f5 src/http/modules/ngx_http_ssl_module.c >> --- a/src/http/modules/ngx_http_ssl_module.c Thu Apr 23 15:10:26 2020 +0300 >> +++ b/src/http/modules/ngx_http_ssl_module.c Thu Apr 23 20:30:36 2020 -0500 >> @@ -352,6 +352,17 @@ >> { ngx_string("ssl_client_v_remain"), NULL, ngx_http_ssl_variable, >> (uintptr_t) ngx_ssl_get_client_v_remain, NGX_HTTP_VAR_CHANGEABLE, 0 }, >> >> +#if OPENSSL_VERSION_NUMBER >= 0x10101000L >> + >> + { ngx_string("ssl_extensions"), NULL, ngx_http_ssl_variable, >> + (uintptr_t) ngx_ssl_get_extensions, NGX_HTTP_VAR_CHANGEABLE, 0 }, >> + >> + { ngx_string("ssl_elliptic_curve_point_formats"), NULL, >> + ngx_http_ssl_variable, (uintptr_t) ngx_ssl_get_ec_point_formats, >> + NGX_HTTP_VAR_CHANGEABLE, 0 }, >> + >> +#endif >> + >> ngx_http_null_variable >> }; >> _______________________________________________ >> nginx-devel mailing list >> nginx-devel@nginx.org >> http://mailman.nginx.org/mailman/listinfo/nginx-devel >> >>
_______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel