From ec1a688238175100a4cd1ce18d79d4d6a2b5fe8a Mon Sep 17 00:00:00 2001 From: thatcher thornberry Date: Mon, 20 May 2024 17:15:00 -0600 Subject: [PATCH] fix extensions count to include ignore extensions --- src/ngx_http_ssl_ja4_module.c | 17 ++++++++++++----- src/ngx_http_ssl_ja4_module.h | 28 +++++++++++++++++++++------- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/ngx_http_ssl_ja4_module.c b/src/ngx_http_ssl_ja4_module.c index 265357d..4de2474 100644 --- a/src/ngx_http_ssl_ja4_module.c +++ b/src/ngx_http_ssl_ja4_module.c @@ -219,6 +219,7 @@ int ngx_ssl_ja4(ngx_connection_t *c, ngx_pool_t *pool, ngx_ssl_ja4_t *ja4) /* Extensions */ ja4->extensions = NULL; ja4->extensions_sz = 0; + ja4->extensions_count = 0; if (c->ssl->extensions_sz && c->ssl->extensions) { len = c->ssl->extensions_sz * sizeof(char *); @@ -231,6 +232,12 @@ int ngx_ssl_ja4(ngx_connection_t *c, ngx_pool_t *pool, ngx_ssl_ja4_t *ja4) { if (!ngx_ssl_ja4_is_ext_greased(c->ssl->extensions[i])) { + ja4->extensions_count++; + if (ngx_ssl_ja4_is_ext_ignored(c->ssl->extensions[i])) + { + // don't consider in list of extensions, but still count it + continue; + } char *ext = c->ssl->extensions[i]; size_t ext_len = strlen(ext) + 1; // +1 for null terminator @@ -383,13 +390,13 @@ void ngx_ssl_ja4_fp(ngx_pool_t *pool, ngx_ssl_ja4_t *ja4, ngx_str_t *out) cur += 2; // 2 character count of extensions - if (ja4->extensions_sz == 0) + if (ja4->extensions_count == 0) { ngx_snprintf(out->data + cur, 3, "00"); } else { - ngx_snprintf(out->data + cur, 3, "%02zu", ja4->extensions_sz); + ngx_snprintf(out->data + cur, 3, "%02zu", ja4->extensions_count); } cur += 2; @@ -442,7 +449,7 @@ ngx_http_ssl_ja4(ngx_http_request_t *r, { return NGX_ERROR; } - + ngx_ssl_ja4_fp(r->pool, &ja4, &fp); v->data = fp.data; @@ -525,13 +532,13 @@ void ngx_ssl_ja4_fp_string(ngx_pool_t *pool, ngx_ssl_ja4_t *ja4, ngx_str_t *out) cur += 2; // 2 character count of extensions - if (ja4->extensions_sz == 0) + if (ja4->extensions_count == 0) { ngx_snprintf(out->data + cur, 3, "00"); } else { - ngx_snprintf(out->data + cur, 3, "%02zu", ja4->extensions_sz); + ngx_snprintf(out->data + cur, 3, "%02zu", ja4->extensions_count); } cur += 2; diff --git a/src/ngx_http_ssl_ja4_module.h b/src/ngx_http_ssl_ja4_module.h index 4f7c113..30b29c6 100644 --- a/src/ngx_http_ssl_ja4_module.h +++ b/src/ngx_http_ssl_ja4_module.h @@ -2,7 +2,6 @@ #include #include - // STRUCTS typedef struct ngx_ssl_ja4_s { @@ -15,8 +14,9 @@ typedef struct ngx_ssl_ja4_s size_t ciphers_sz; // Count of ciphers char **ciphers; // List of ciphers - size_t extensions_sz; // Count of extensions - char **extensions; // List of extensions + size_t extensions_count; // Count of signature algorithms + size_t extensions_sz; // Count of extensions + char **extensions; // List of extensions size_t sigalgs_sz; // Count of signature algorithms char **sigalgs; // List of signature algorithms @@ -120,7 +120,6 @@ typedef struct ngx_ssl_ja4l_s uint8_t hop_count; // a whole number - max is less than 255 } ngx_ssl_ja4l_t; - // CONSTANTS #define SSL3_VERSION_STR "SSLv3" #define TLS1_VERSION_STR "TLSv1" @@ -151,11 +150,28 @@ static const char *GREASE[] = { "dada", "eaea", "fafa", +}; + +static const char *EXT_IGNORE[] = { "0010", // ALPN IGNORE "0000", // SNI IGNORE }; // HELPERS + +static int ngx_ssl_ja4_is_ext_ignored(const char *ext) +{ + size_t i; + for (i = 0; i < (sizeof(EXT_IGNORE) / sizeof(EXT_IGNORE[0])); ++i) + { + if (strcmp(ext, EXT_IGNORE[i]) == 0) + { + return 1; + } + } + return 0; +} + static int ngx_ssl_ja4_is_ext_greased(const char *ext) { @@ -265,7 +281,7 @@ ngx_ssl_ja4_detail_print(ngx_pool_t *pool, ngx_ssl_ja4_t *ja4) /* Extensions */ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pool->log, 0, "ssl_ja4: extensions: length: %d\n", - ja4->extensions_sz); + ja4->extensions_count); for (i = 0; i < ja4->extensions_sz; ++i) { @@ -293,7 +309,6 @@ ngx_ssl_ja4_detail_print(ngx_pool_t *pool, ngx_ssl_ja4_t *ja4) } #endif - // FUNCTION PROTOTYPES // INIT static ngx_int_t ngx_http_ssl_ja4_init(ngx_conf_t *cf); @@ -338,7 +353,6 @@ static ngx_int_t ngx_http_ssl_ja4ts(ngx_http_request_t *r, ngx_http_variable_val void ngx_ssl_ja4ts_fp_string(ngx_pool_t *pool, ngx_ssl_ja4ts_t *ja4ts, ngx_str_t *out); static ngx_int_t ngx_http_ssl_ja4ts_string(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); - // JA4X int ngx_ssl_ja4x(ngx_connection_t *c, ngx_pool_t *pool, ngx_ssl_ja4x_t *ja4x); void ngx_ssl_ja4x_fp(ngx_pool_t *pool, ngx_ssl_ja4x_t *ja4x, ngx_str_t *out);