aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--example/ndpiReader.c21
-rw-r--r--src/include/ndpi_api.h1
-rw-r--r--src/lib/ndpi_main.c112
-rw-r--r--src/lib/ndpi_utils.c28
-rw-r--r--src/lib/protocols/quic.c4
-rw-r--r--src/lib/protocols/ssl.c78
-rw-r--r--src/lib/protocols/stun.c4
7 files changed, 155 insertions, 93 deletions
diff --git a/example/ndpiReader.c b/example/ndpiReader.c
index 75f3c4f6d..73dfdf051 100644
--- a/example/ndpiReader.c
+++ b/example/ndpiReader.c
@@ -764,23 +764,6 @@ static char* print_cipher(ndpi_cipher_weakness c) {
/* ********************************** */
-static char* ssl_version2str(u_int16_t version) {
- static char v[8];
-
- switch(version) {
- case 0x300: return("SSLv3");
- case 0x301: return("TLSv1");
- case 0x302: return("TLSv1.1");
- case 0x303: return("TLSv1.2");
- case 0x304: return("TLSv1.3");
- }
-
- snprintf(v, sizeof(v), "%04X", version);
- return(v);
-}
-
-/* ********************************** */
-
/**
* @brief Print the flow
*/
@@ -835,7 +818,7 @@ static void printFlow(u_int16_t id, struct ndpi_flow_info *flow, u_int16_t threa
if(flow->info[0] != '\0') fprintf(out, "[%s]", flow->info);
- if(flow->ssh_ssl.ssl_version != 0) fprintf(out, "[%s]", ssl_version2str(flow->ssh_ssl.ssl_version));
+ if(flow->ssh_ssl.ssl_version != 0) fprintf(out, "[%s]", ndpi_ssl_version2str(flow->ssh_ssl.ssl_version));
if(flow->ssh_ssl.ja3_client[0] != '\0') fprintf(out, "[JA3C: %s%s]", flow->ssh_ssl.ja3_client,
print_cipher(flow->ssh_ssl.client_unsafe_cipher));
if(flow->ssh_ssl.server_info[0] != '\0') fprintf(out, "[server: %s]", flow->ssh_ssl.server_info);
@@ -2742,6 +2725,8 @@ void test_lib() {
}
}
+/* *********************************************** */
+
void automataUnitTest() {
void *automa;
diff --git a/src/include/ndpi_api.h b/src/include/ndpi_api.h
index 7297f0038..466d51b48 100644
--- a/src/include/ndpi_api.h
+++ b/src/include/ndpi_api.h
@@ -813,6 +813,7 @@ extern "C" {
struct ndpi_flow_struct *flow);
int ndpi_has_human_readeable_string(struct ndpi_detection_module_struct *ndpi_struct,
char *buffer, u_int buffer_size);
+ char* ndpi_ssl_version2str(u_int16_t version);
#ifdef __cplusplus
}
#endif
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index 85366358b..325123476 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -53,7 +53,7 @@
static int _ndpi_debug_callbacks = 0;
-// #define MATCH_DEBUG 1
+/* #define MATCH_DEBUG 1 */
/* ****************************************** */
@@ -1750,7 +1750,7 @@ static int ac_match_handler(AC_MATCH_t *m, AC_TEXT_t *txt, AC_REP_t *match) {
has to match
*/
if(whatfound && (whatfound != buf)
- && (m->patterns->astring[0] != '.') /* The searched patter does not start with . */
+ && (m->patterns->astring[0] != '.') /* The searched pattern does not start with . */
&& strchr(m->patterns->astring, '.') /* The matched pattern has a . (e.g. numeric or sym IPs) */
&& (whatfound[-1] != '.')
)
@@ -1768,12 +1768,18 @@ static int ac_match_handler(AC_MATCH_t *m, AC_TEXT_t *txt, AC_REP_t *match) {
|| (strncmp(buf, m->patterns->astring, min_len) == 0) /* begins with */
) {
#ifdef MATCH_DEBUG
- printf("Found match [%s][%s] [len: %u][proto_id: %u]\n",
- buf, m->patterns->astring, min_len , *matching_protocol_id);
+ printf("Found match [%s][%s] [len: %u]"
+ // "[proto_id: %u]"
+ "\n",
+ buf, m->patterns->astring, min_len /* , *matching_protocol_id */);
#endif
return(1); /* If the pattern found matches the string at the beginning we stop here */
- } else
+ } else {
+#ifdef MATCH_DEBUG
+ printf("NO match found: continue\n");
+#endif
return 0; /* 0 to continue searching, !0 to stop */
+ }
}
/* ******************************************************************** */
@@ -2155,6 +2161,7 @@ int ndpi_match_string(void *_automa, char *string_to_match) {
AC_REP_t match = { NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED, NDPI_PROTOCOL_UNRATED };
AC_TEXT_t ac_input_text;
AC_AUTOMATA_t *automa = (AC_AUTOMATA_t*)_automa;
+ int rc;
if((automa == NULL)
|| (string_to_match == NULL)
@@ -2162,10 +2169,10 @@ int ndpi_match_string(void *_automa, char *string_to_match) {
return(-2);
ac_input_text.astring = string_to_match, ac_input_text.length = strlen(string_to_match);
- ac_automata_search(automa, &ac_input_text, &match);
+ rc = ac_automata_search(automa, &ac_input_text, &match);
ac_automata_reset(automa);
- return(match.number > 0 ? 0 : -1);
+ return(rc ? match.number : 0);
}
/* ****************************************************** */
@@ -2174,6 +2181,7 @@ int ndpi_match_string_id(void *_automa, char *string_to_match, unsigned long *id
AC_TEXT_t ac_input_text;
AC_AUTOMATA_t *automa = (AC_AUTOMATA_t*)_automa;
AC_REP_t match = { NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED, NDPI_PROTOCOL_UNRATED };
+ int rc;
*id = -1;
if((automa == NULL)
@@ -2182,10 +2190,10 @@ int ndpi_match_string_id(void *_automa, char *string_to_match, unsigned long *id
return(-2);
ac_input_text.astring = string_to_match, ac_input_text.length = strlen(string_to_match);
- ac_automata_search(automa, &ac_input_text, &match);
+ rc = ac_automata_search(automa, &ac_input_text, &match);
ac_automata_reset(automa);
- *id = match.number;
+ *id = rc ? match.number : NDPI_PROTOCOL_UNKNOWN;
return(*id != NDPI_PROTOCOL_UNKNOWN ? 0 : -1);
}
@@ -4491,7 +4499,7 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct
else sport = dport = 0;
/* guess protocol */
- flow->guessed_protocol_id = (int16_t) ndpi_guess_protocol_id(ndpi_struct, flow, protocol, sport, dport, &user_defined_proto);
+ flow->guessed_protocol_id = (int16_t)ndpi_guess_protocol_id(ndpi_struct, flow, protocol, sport, dport, &user_defined_proto);
flow->guessed_host_protocol_id = ndpi_guess_host_protocol_id(ndpi_struct, flow);
if(ndpi_struct->custom_categories.categories_loaded && flow->packet.iph) {
@@ -4534,15 +4542,24 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct
/* This is a custom protocol and it has priority over everything else */
ret.master_protocol = NDPI_PROTOCOL_UNKNOWN, ret.app_protocol = flow->guessed_host_protocol_id;
- if(flow->packet.tcp) {
+ if(flow->packet.tcp && (ret.master_protocol == NDPI_PROTOCOL_UNKNOWN)) {
/* Minimal guess for HTTP/SSL-based protocols */
- switch(ntohs(flow->packet.tcp->dest)) {
- case 80:
- ret.master_protocol = NDPI_PROTOCOL_HTTP;
- break;
- case 443:
- ret.master_protocol = NDPI_PROTOCOL_SSL; /* QUIC could also match */
- break;
+ int i;
+
+ for(i=0; i<2; i++) {
+ u_int16_t port = (i == 0) ? ntohs(flow->packet.tcp->dest) : ntohs(flow->packet.tcp->source);
+
+ switch(port) {
+ case 80:
+ ret.master_protocol = NDPI_PROTOCOL_HTTP;
+ break;
+ case 443:
+ ret.master_protocol = NDPI_PROTOCOL_SSL; /* QUIC could also match */
+ break;
+ }
+
+ if(ret.master_protocol != NDPI_PROTOCOL_UNKNOWN)
+ break;
}
}
@@ -5498,7 +5515,7 @@ ndpi_protocol ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct
u_int8_t user_defined_proto;
if((proto == IPPROTO_TCP) || (proto == IPPROTO_UDP)) {
- rc = ndpi_search_tcp_or_udp_raw(ndpi_struct, NULL, proto, shost, dhost, sport, dport);
+ rc = ndpi_search_tcp_or_udp_raw(ndpi_struct, flow, proto, shost, dhost, sport, dport);
if(rc != NDPI_PROTOCOL_UNKNOWN) {
if(flow && (proto == IPPROTO_UDP)
@@ -5507,7 +5524,7 @@ ndpi_protocol ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct
;
else {
ret.app_protocol = rc,
- ret.master_protocol = ndpi_guess_protocol_id(ndpi_struct, NULL, proto, sport,
+ ret.master_protocol = ndpi_guess_protocol_id(ndpi_struct, flow, proto, sport,
dport, &user_defined_proto);
if(ret.app_protocol == ret.master_protocol)
@@ -5518,7 +5535,7 @@ ndpi_protocol ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct
}
}
- rc = ndpi_guess_protocol_id(ndpi_struct, NULL, proto, sport, dport, &user_defined_proto);
+ rc = ndpi_guess_protocol_id(ndpi_struct, flow, proto, sport, dport, &user_defined_proto);
if(rc != NDPI_PROTOCOL_UNKNOWN) {
if(flow && (proto == IPPROTO_UDP)
&& NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, rc)
@@ -5546,7 +5563,7 @@ ndpi_protocol ndpi_guess_undetected_protocol(struct ndpi_detection_module_struct
ret.app_protocol = NDPI_PROTOCOL_SKYPE;
}
} else
- ret.app_protocol = ndpi_guess_protocol_id(ndpi_struct, NULL, proto, sport,
+ ret.app_protocol = ndpi_guess_protocol_id(ndpi_struct, flow, proto, sport,
dport, &user_defined_proto);
ret.category = ndpi_get_proto_category(ndpi_struct, ret);
@@ -5645,8 +5662,15 @@ void ndpi_category_set_name(struct ndpi_detection_module_struct *ndpi_mod,
const char* ndpi_category_get_name(struct ndpi_detection_module_struct *ndpi_mod,
ndpi_protocol_category_t category) {
- if((!ndpi_mod) || (category >= NDPI_PROTOCOL_NUM_CATEGORIES))
- return(NULL);
+ if((!ndpi_mod) || (category >= NDPI_PROTOCOL_NUM_CATEGORIES)) {
+ static char b[24];
+
+ if(!ndpi_mod)
+ snprintf(b, sizeof(b), "NULL nDPI");
+ else
+ snprintf(b, sizeof(b), "Invalid category %d", (int)category);
+ return(b);
+ }
if((category >= NDPI_PROTOCOL_CATEGORY_CUSTOM_1) && (category <= NDPI_PROTOCOL_CATEGORY_CUSTOM_5)) {
switch(category) {
@@ -5687,7 +5711,7 @@ ndpi_protocol_category_t ndpi_get_proto_category(struct ndpi_detection_module_st
char* ndpi_get_proto_name(struct ndpi_detection_module_struct *ndpi_mod, u_int16_t proto_id) {
if((proto_id >= ndpi_mod->ndpi_num_supported_protocols)
- || (proto_id < (NDPI_MAX_SUPPORTED_PROTOCOLS+NDPI_MAX_NUM_CUSTOM_PROTOCOLS))
+ || (proto_id >= (NDPI_MAX_SUPPORTED_PROTOCOLS+NDPI_MAX_NUM_CUSTOM_PROTOCOLS))
|| (ndpi_mod->proto_defaults[proto_id].protoName == NULL))
proto_id = NDPI_PROTOCOL_UNKNOWN;
@@ -5699,7 +5723,7 @@ char* ndpi_get_proto_name(struct ndpi_detection_module_struct *ndpi_mod, u_int16
ndpi_protocol_breed_t ndpi_get_proto_breed(struct ndpi_detection_module_struct *ndpi_mod,
u_int16_t proto_id) {
if((proto_id >= ndpi_mod->ndpi_num_supported_protocols)
- || (proto_id < (NDPI_MAX_SUPPORTED_PROTOCOLS+NDPI_MAX_NUM_CUSTOM_PROTOCOLS))
+ || (proto_id >= (NDPI_MAX_SUPPORTED_PROTOCOLS+NDPI_MAX_NUM_CUSTOM_PROTOCOLS))
|| (ndpi_mod->proto_defaults[proto_id].protoName == NULL))
proto_id = NDPI_PROTOCOL_UNKNOWN;
@@ -5822,8 +5846,7 @@ char* ndpi_strncasestr(const char *s, const char *find, size_t slen) {
/* ****************************************************** */
int ndpi_match_prefix(const u_int8_t *payload, size_t payload_len,
- const char *str, size_t str_len)
-{
+ const char *str, size_t str_len) {
int rc = str_len <= payload_len ? memcmp(payload, str, str_len) == 0 : 0;
return rc;
@@ -5836,9 +5859,9 @@ int ndpi_match_string_subprotocol(struct ndpi_detection_module_struct *ndpi_stru
ndpi_protocol_match_result *ret_match,
u_int8_t is_host_match) {
AC_TEXT_t ac_input_text;
- ndpi_automa *automa = is_host_match ? &ndpi_struct->host_automa :
- &ndpi_struct->content_automa;
+ ndpi_automa *automa = is_host_match ? &ndpi_struct->host_automa : &ndpi_struct->content_automa;
AC_REP_t match = { NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED, NDPI_PROTOCOL_UNRATED };
+ int rc;
if((automa->ac_automa == NULL) || (string_to_match_len == 0))
return(NDPI_PROTOCOL_UNKNOWN);
@@ -5849,14 +5872,22 @@ int ndpi_match_string_subprotocol(struct ndpi_detection_module_struct *ndpi_stru
}
ac_input_text.astring = string_to_match, ac_input_text.length = string_to_match_len;
- ac_automata_search(((AC_AUTOMATA_t*)automa->ac_automa), &ac_input_text, &match);
+ rc = ac_automata_search(((AC_AUTOMATA_t*)automa->ac_automa), &ac_input_text, &match);
ac_automata_reset(((AC_AUTOMATA_t*)automa->ac_automa));
- ret_match->protocol_id = match.number,
- ret_match->protocol_category = match.category,
- ret_match->protocol_breed = match.breed;
-
- return(match.number);
+ /* We need to take into account also rc==0 that is used for partial matches */
+#if 0
+ if(rc) {
+#endif
+ ret_match->protocol_id = match.number,
+ ret_match->protocol_category = match.category,
+ ret_match->protocol_breed = match.breed;
+
+ return(match.number);
+#if 0
+ } else
+ return(NDPI_PROTOCOL_UNKNOWN);
+#endif
}
#ifdef HAVE_HYPERSCAN
@@ -5950,6 +5981,10 @@ static int ndpi_automa_match_string_subprotocol(struct ndpi_detection_module_str
NDPI_LOG_DBG2(ndpi_struct, "[NTOP] Unable to find a match for '%s'\n", string_to_match);
#endif
+ ret_match->protocol_id = NDPI_PROTOCOL_UNKNOWN,
+ ret_match->protocol_category = NDPI_PROTOCOL_CATEGORY_UNSPECIFIED,
+ ret_match->protocol_breed = NDPI_PROTOCOL_UNRATED;
+
return(NDPI_PROTOCOL_UNKNOWN);
}
@@ -5983,6 +6018,7 @@ int ndpi_match_bigram(struct ndpi_detection_module_struct *ndpi_struct,
ndpi_automa *automa, char *bigram_to_match) {
AC_TEXT_t ac_input_text;
AC_REP_t match = { NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED, NDPI_PROTOCOL_UNRATED };
+ int rc;
if((automa->ac_automa == NULL) || (bigram_to_match == NULL))
return(-1);
@@ -5993,10 +6029,10 @@ int ndpi_match_bigram(struct ndpi_detection_module_struct *ndpi_struct,
}
ac_input_text.astring = bigram_to_match, ac_input_text.length = 2;
- ac_automata_search(((AC_AUTOMATA_t*)automa->ac_automa), &ac_input_text, &match);
+ rc = ac_automata_search(((AC_AUTOMATA_t*)automa->ac_automa), &ac_input_text, &match);
ac_automata_reset(((AC_AUTOMATA_t*)automa->ac_automa));
- return(match.number);
+ return(rc ? match.number : 0);
}
/* ****************************************************** */
diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c
index 480f4ff18..933d5634c 100644
--- a/src/lib/ndpi_utils.c
+++ b/src/lib/ndpi_utils.c
@@ -590,7 +590,12 @@ const char* ndpi_cipher2str(u_int32_t cipher) {
case 0x060040: return("SSL2_DES_64_CBC_WITH_MD5");
case 0x0700c0: return("SSL2_DES_192_EDE3_CBC_WITH_MD5");
case 0x080080: return("SSL2_RC4_64_WITH_MD5");
- case 0x001301: return("TLS_AES_128_GMC_SHA256");
+ case 0x001301: return("TLS_AES_128_GCM_SHA256");
+ case 0x001302: return("TLS_AES_256_GCM_SHA384");
+ case 0x001303: return("TLS_CHACHA20_POLY1305_SHA256");
+ case 0x001304: return("TLS_AES_128_CCM_SHA256");
+ case 0x001305: return("TLS_AES_128_CCM_8_SHA256");
+
default:
{
static char buf[8];
@@ -682,3 +687,24 @@ int ndpi_has_human_readeable_string(struct ndpi_detection_module_struct *ndpi_st
return(ret);
}
+
+/* ********************************** */
+
+char* ndpi_ssl_version2str(u_int16_t version) {
+ static char v[8];
+
+ switch(version) {
+ case 0x300: return("SSLv3");
+ case 0x301: return("TLSv1");
+ case 0x302: return("TLSv1.1");
+ case 0x303: return("TLSv1.2");
+ case 0x304: return("TLSv1.3");
+ }
+
+ if((version >= 0x7f00) && (version <= 0x7fff))
+ return("TLSv1.3 (draft)");
+
+ snprintf(v, sizeof(v), "%04X", version);
+ return(v);
+}
+
diff --git a/src/lib/protocols/quic.c b/src/lib/protocols/quic.c
index d67414fdf..9bf382217 100644
--- a/src/lib/protocols/quic.c
+++ b/src/lib/protocols/quic.c
@@ -100,8 +100,8 @@ void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct,
&& (packet->payload[i+1] == 'N')
&& (packet->payload[i+2] == 'I')
&& (packet->payload[i+3] == 0)) {
- u_int32_t offset = ntohl(*((u_int32_t*)&packet->payload[i+4]));
- u_int32_t prev_offset = ntohl(*((u_int32_t*)&packet->payload[i-4]));
+ u_int32_t offset = (*((u_int32_t*)&packet->payload[i+4]));
+ u_int32_t prev_offset = (*((u_int32_t*)&packet->payload[i-4]));
int len = offset-prev_offset;
int sni_offset = i+prev_offset+1;
diff --git a/src/lib/protocols/ssl.c b/src/lib/protocols/ssl.c
index f7009a788..29b22ac11 100644
--- a/src/lib/protocols/ssl.c
+++ b/src/lib/protocols/ssl.c
@@ -238,9 +238,10 @@ static u_int32_t ndpi_ssl_refine_master_protocol(struct ndpi_detection_module_st
{
struct ndpi_packet_struct *packet = &flow->packet;
- if(((flow->l4.tcp.ssl_seen_client_cert == 1) && (flow->protos.stun_ssl.ssl.client_certificate[0] != '\0'))
- || ((flow->l4.tcp.ssl_seen_server_cert == 1) && (flow->protos.stun_ssl.ssl.server_certificate[0] != '\0'))
- || (flow->host_server_name[0] != '\0'))
+ if(((flow->l4.tcp.ssl_seen_client_cert == 1) && (flow->protos.stun_ssl.ssl.ja3_client[0] != '\0'))
+ || ((flow->l4.tcp.ssl_seen_server_cert == 1) && (flow->protos.stun_ssl.ssl.ja3_server[0] != '\0'))
+ // || (flow->host_server_name[0] != '\0')
+ )
protocol = NDPI_PROTOCOL_SSL;
else
protocol = NDPI_PROTOCOL_SSL_NO_CERT;
@@ -373,7 +374,7 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct,
u_char md5_hash[16];
flow->protos.stun_ssl.ssl.ssl_version = ssl_version;
-
+
memset(&ja3, 0, sizeof(ja3));
#ifdef CERTIFICATE_DEBUG
@@ -409,7 +410,7 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct,
if((handshake_protocol == 0x02)
|| (handshake_protocol == 0xb) /* Server Hello and Certificate message types are interesting for us */) {
u_int num_found = 0;
- u_int16_t ssl_version = ntohs(*((u_int16_t*)&packet->payload[9]));
+ u_int16_t ssl_version = ntohs(*((u_int16_t*)&packet->payload[9]));
ja3.ssl_version = ssl_version;
@@ -417,12 +418,23 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct,
u_int16_t offset = 43, extension_len, j;
u_int8_t session_id_len = packet->payload[43];
- offset += session_id_len+1;
+#ifdef CERTIFICATE_DEBUG
+ printf("SSL Server Hello [version: 0x%04X]\n", ssl_version);
+#endif
+
+ /*
+ The server hello decides about the SSL version of this flow
+ https://networkengineering.stackexchange.com/questions/55752/why-does-wireshark-show-version-tls-1-2-here-instead-of-tls-1-3
+ */
+ flow->protos.stun_ssl.ssl.ssl_version = ssl_version;
+
+ if(ssl_version < 0x7F15 /* TLS 1.3 lacks of session id */)
+ offset += session_id_len+1;
ja3.num_cipher = 1, ja3.cipher[0] = ntohs(*((u_int16_t*)&packet->payload[offset]));
flow->protos.stun_ssl.ssl.server_unsafe_cipher = ndpi_is_safe_ssl_cipher(ja3.cipher[0]);
flow->protos.stun_ssl.ssl.server_cipher = ja3.cipher[0];
-
+
#ifdef CERTIFICATE_DEBUG
printf("SSL [server][session_id_len: %u][cipher: %04X]\n", session_id_len, ja3.cipher[0]);
#endif
@@ -468,23 +480,23 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct,
#ifdef CERTIFICATE_DEBUG
printf("SSL [server] %s\n", ja3_str);
#endif
-
+
#ifdef CERTIFICATE_DEBUG
printf("[JA3] Server: %s \n", ja3_str);
#endif
-
+
MD5Init(&ctx);
MD5Update(&ctx, (const unsigned char *)ja3_str, strlen(ja3_str));
MD5Final(md5_hash, &ctx);
-
+
for(i=0, j=0; i<16; i++)
j += snprintf(&flow->protos.stun_ssl.ssl.ja3_server[j],
sizeof(flow->protos.stun_ssl.ssl.ja3_server)-j, "%02x", md5_hash[i]);
-
+
#ifdef CERTIFICATE_DEBUG
printf("[JA3] Server: %s \n", flow->protos.stun_ssl.ssl.ja3_server);
#endif
-
+
flow->l4.tcp.ssl_seen_server_cert = 1;
} else
flow->l4.tcp.ssl_seen_certificate = 1;
@@ -561,7 +573,7 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct,
if((cipher_offset+cipher_len) <= total_len) {
for(i=0; i<cipher_len;) {
u_int16_t *id = (u_int16_t*)&packet->payload[cipher_offset+i];
-
+
#ifdef CERTIFICATE_DEBUG
printf("Client SSL [cipher suite: %u] [%u/%u]\n", ntohs(*id), i, cipher_len);
#endif
@@ -570,7 +582,7 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct,
Skip GREASE [https://tools.ietf.org/id/draft-ietf-tls-grease-01.html]
https://engineering.salesforce.com/tls-fingerprinting-with-ja3-and-ja3s-247362855967
*/
-
+
if(ja3.num_cipher < MAX_NUM_JA3)
ja3.cipher[ja3.num_cipher++] = ntohs(*id);
else {
@@ -580,16 +592,16 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct,
#endif
}
}
-
+
i += 2;
}
} else {
invalid_ja3 = 1;
#ifdef CERTIFICATE_DEBUG
printf("Client SSL Invalid len %u vs %u\n", (cipher_offset+cipher_len), total_len);
-#endif
+#endif
}
-
+
offset = base_offset + session_id_len + cipher_len + 2;
flow->l4.tcp.ssl_seen_client_cert = 1;
@@ -673,7 +685,7 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct,
if((s_offset+extension_len-2) <= total_len) {
for(i=0; i<extension_len-2;) {
u_int16_t s_group = ntohs(*((u_int16_t*)&packet->payload[s_offset+i]));
-
+
#ifdef CERTIFICATE_DEBUG
printf("Client SSL [EllipticCurve: %u]\n", s_group);
#endif
@@ -681,7 +693,7 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct,
/* Skip GREASE */
if(ja3.num_elliptic_curve < MAX_NUM_JA3)
ja3.elliptic_curve[ja3.num_elliptic_curve++] = s_group;
- else {
+ else {
invalid_ja3 = 1;
#ifdef CERTIFICATE_DEBUG
printf("Client SSL Invalid num elliptic %u\n", ja3.num_elliptic_curve);
@@ -696,7 +708,7 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct,
#ifdef CERTIFICATE_DEBUG
printf("Client SSL Invalid len %u vs %u\n", (s_offset+extension_len-1), total_len);
#endif
- }
+ }
} else if(extension_id == 11 /* ec_point_formats groups */) {
u_int16_t i, s_offset = offset+extension_offset + 1;
@@ -706,11 +718,11 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct,
if((s_offset+extension_len) < total_len) {
for(i=0; i<extension_len-1;i++) {
u_int8_t s_group = packet->payload[s_offset+i];
-
+
#ifdef CERTIFICATE_DEBUG
printf("Client SSL [EllipticCurveFormat: %u]\n", s_group);
#endif
-
+
if(ja3.num_elliptic_curve_point_format < MAX_NUM_JA3)
ja3.elliptic_curve_point_format[ja3.num_elliptic_curve_point_format++] = s_group;
else {
@@ -727,7 +739,7 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct,
#endif
}
}
-
+
extension_offset += extension_len;
#ifdef CERTIFICATE_DEBUG
@@ -737,30 +749,30 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct,
if(!invalid_ja3) {
ja3_str_len = snprintf(ja3_str, sizeof(ja3_str), "%u,", ja3.ssl_version);
-
+
for(i=0; i<ja3.num_cipher; i++) {
ja3_str_len += snprintf(&ja3_str[ja3_str_len], sizeof(ja3_str)-ja3_str_len, "%s%u",
(i > 0) ? "-" : "", ja3.cipher[i]);
}
-
+
ja3_str_len += snprintf(&ja3_str[ja3_str_len], sizeof(ja3_str)-ja3_str_len, ",");
-
+
/* ********** */
-
+
for(i=0; i<ja3.num_ssl_extension; i++)
ja3_str_len += snprintf(&ja3_str[ja3_str_len], sizeof(ja3_str)-ja3_str_len, "%s%u",
(i > 0) ? "-" : "", ja3.ssl_extension[i]);
-
+
ja3_str_len += snprintf(&ja3_str[ja3_str_len], sizeof(ja3_str)-ja3_str_len, ",");
-
+
/* ********** */
-
+
for(i=0; i<ja3.num_elliptic_curve; i++)
ja3_str_len += snprintf(&ja3_str[ja3_str_len], sizeof(ja3_str)-ja3_str_len, "%s%u",
(i > 0) ? "-" : "", ja3.elliptic_curve[i]);
-
+
ja3_str_len += snprintf(&ja3_str[ja3_str_len], sizeof(ja3_str)-ja3_str_len, ",");
-
+
for(i=0; i<ja3.num_elliptic_curve_point_format; i++)
ja3_str_len += snprintf(&ja3_str[ja3_str_len], sizeof(ja3_str)-ja3_str_len, "%s%u",
(i > 0) ? "-" : "", ja3.elliptic_curve_point_format[i]);
@@ -781,7 +793,7 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct,
printf("[JA3] Client: %s \n", flow->protos.stun_ssl.ssl.ja3_client);
#endif
}
-
+
return(2 /* Client Certificate */);
}
}
diff --git a/src/lib/protocols/stun.c b/src/lib/protocols/stun.c
index cf03ddaec..3e2e037f2 100644
--- a/src/lib/protocols/stun.c
+++ b/src/lib/protocols/stun.c
@@ -81,7 +81,9 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *
msg_type, payload_length, flow->protos.stun_ssl.stun.num_binding_requests);
*/
- if(((payload[0] == 0x80) && ((msg_len+20) <= payload_length)) /* WhatsApp Voice */) {
+ if(((payload[0] == 0x80)
+ && (payload_length < 512)
+ && ((msg_len+20) <= payload_length)) /* WhatsApp Voice */) {
*is_whatsapp = 1;
return NDPI_IS_STUN; /* This is WhatsApp Voice */
} else if((payload[0] == 0x90)