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 <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 <[email protected]> wrote: > > # HG changeset patch > # User Garret Reece <[email protected]> > # 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 > [email protected] > http://mailman.nginx.org/mailman/listinfo/nginx-devel
_______________________________________________ nginx-devel mailing list [email protected] http://mailman.nginx.org/mailman/listinfo/nginx-devel
