diff options
author | Nardi Ivan <nardi.ivan@gmail.com> | 2020-08-21 15:10:22 +0200 |
---|---|---|
committer | Nardi Ivan <nardi.ivan@gmail.com> | 2020-08-21 22:04:55 +0200 |
commit | 7a1147d733dc2a43c375207747e8c4587af83388 (patch) | |
tree | 215e820f395ae18d308cbb2f216b51aad4eeaeba /src | |
parent | d62ae567d1274328cfbb5e767011cdbe821060c9 (diff) |
Update TLS dissector to handle QUIC flows
Latest QUIC versions use TLS for the encryption layer: reuse existing code
to allow Client Hello parsing and sub-classification based on SNI value.
Side effect: we might have J3AC, TLS negotiated version, SNI value and
supported cipher list for QUIC, too.
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/ndpi_main.c | 3 | ||||
-rw-r--r-- | src/lib/protocols/tls.c | 32 |
2 files changed, 22 insertions, 13 deletions
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 4ce2527ee..4c9d5d37c 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -6233,7 +6233,8 @@ void ndpi_free_flow(struct ndpi_flow_struct *flow) { if(flow->kerberos_buf.pktbuf) ndpi_free(flow->kerberos_buf.pktbuf); - if(flow_is_proto(flow, NDPI_PROTOCOL_TLS)) { + if(flow_is_proto(flow, NDPI_PROTOCOL_TLS) || + flow_is_proto(flow, NDPI_PROTOCOL_QUIC)) { if(flow->protos.stun_ssl.ssl.server_names) ndpi_free(flow->protos.stun_ssl.ssl.server_names); diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c index 883de7666..aa3836442 100644 --- a/src/lib/protocols/tls.c +++ b/src/lib/protocols/tls.c @@ -31,7 +31,7 @@ extern char *strptime(const char *s, const char *format, struct tm *tm); extern int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow); + struct ndpi_flow_struct *flow, int is_quic); // #define DEBUG_TLS_MEMORY 1 // #define DEBUG_TLS 1 @@ -616,7 +616,7 @@ static int processTLSBlock(struct ndpi_detection_module_struct *ndpi_struct, switch(packet->payload[0] /* block type */) { case 0x01: /* Client Hello */ case 0x02: /* Server Hello */ - processClientServerHello(ndpi_struct, flow); + processClientServerHello(ndpi_struct, flow, 0); flow->l4.tcp.tls.hello_processed = 1; ndpi_int_tls_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TLS); break; @@ -864,7 +864,7 @@ struct ja3_info { /* **************************************** */ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow) { + struct ndpi_flow_struct *flow, int is_quic) { struct ndpi_packet_struct *packet = &flow->packet; struct ja3_info ja3; u_int8_t invalid_ja3 = 0; @@ -876,6 +876,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, u_int16_t total_len; u_int8_t handshake_type; char buffer[64] = { '\0' }; + int is_dtls = packet->udp && (!is_quic); #ifdef DEBUG_TLS printf("SSL %s() called\n", __FUNCTION__); @@ -893,9 +894,9 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, /* At least "magic" 3 bytes, null for string end, otherwise no need to waste cpu cycles */ if(total_len > 4) { - u_int16_t base_offset = packet->tcp ? 38 : 46; - u_int16_t version_offset = packet->tcp ? 4 : 12; - u_int16_t offset = packet->tcp ? 38 : 46, extension_len, j; + u_int16_t base_offset = (!is_dtls) ? 38 : 46; + u_int16_t version_offset = (!is_dtls) ? 4 : 12; + u_int16_t offset = (!is_dtls) ? 38 : 46, extension_len, j; u_int8_t session_id_len = 0; if (base_offset < total_len) session_id_len = packet->payload[base_offset]; @@ -1029,7 +1030,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, if((session_id_len+base_offset+3) > packet->payload_packet_len) return(0); /* Not found */ - if(packet->tcp) { + if(!is_dtls) { cipher_len = packet->payload[session_id_len+base_offset+2] + (packet->payload[session_id_len+base_offset+1] << 8); cipher_offset = base_offset + session_id_len + 3; } else { @@ -1079,7 +1080,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, u_int16_t compression_len; u_int16_t extensions_len; - offset += packet->tcp ? 1 : 2; + offset += (!is_dtls) ? 1 : 2; compression_len = packet->payload[offset]; offset++; @@ -1149,9 +1150,16 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, snprintf(flow->protos.stun_ssl.ssl.client_requested_server_name, sizeof(flow->protos.stun_ssl.ssl.client_requested_server_name), "%s", buffer); - - if(ndpi_match_hostname_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TLS, buffer, strlen(buffer))) - flow->l4.tcp.tls.subprotocol_detected = 1; +#ifdef DEBUG_TLS + printf("[TLS] SNI: [%s]\n", buffer); +#endif + if(!is_quic) { + if(ndpi_match_hostname_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TLS, buffer, strlen(buffer))) + flow->l4.tcp.tls.subprotocol_detected = 1; + } else { + if(ndpi_match_hostname_protocol(ndpi_struct, flow, NDPI_PROTOCOL_QUIC, buffer, strlen(buffer))) + flow->l4.tcp.tls.subprotocol_detected = 1; + } ndpi_check_dga_name(ndpi_struct, flow, flow->protos.stun_ssl.ssl.client_requested_server_name); } else { @@ -1289,7 +1297,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, #ifdef DEBUG_TLS printf("Client SSL [TLS version: %s/0x%04X]\n", - ndpi_ssl_version2str(NULL, tls_version, &unknown_tls_version), tls_version); + ndpi_ssl_version2str(flow, tls_version, &unknown_tls_version), tls_version); #endif if((version_str_len+8) < sizeof(version_str)) { |