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