diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/include/ndpi_typedefs.h | 3 | ||||
-rw-r--r-- | src/lib/ndpi_main.c | 10 | ||||
-rw-r--r-- | src/lib/protocols/tls.c | 137 |
3 files changed, 101 insertions, 49 deletions
diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index ad33eb5e6..1e75e5ee4 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -709,8 +709,6 @@ struct ndpi_flow_tcp_struct { u_int32_t telnet_stage:2; // 0 - 2 struct { - message_t message[2]; /* Directions */ - /* NDPI_PROTOCOL_TLS */ u_int8_t app_data_seen[2]; u_int8_t num_tls_blocks; @@ -1384,6 +1382,7 @@ struct ndpi_flow_struct { } stun; struct { + message_t message[2]; /* Directions */ u_int8_t certificate_processed:1, _pad:7; } tls_quic; /* Used also by DTLS and POPS/IMAPS/SMTPS/FTPS */ diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 7880aeae3..a3c017930 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -5092,12 +5092,10 @@ void ndpi_free_flow_data(struct ndpi_flow_struct* flow) { ndpi_free(flow->protos.tls_quic.encrypted_sni.esni); } - if(flow->l4_proto == IPPROTO_TCP) { - if(flow->l4.tcp.tls.message[0].buffer) - ndpi_free(flow->l4.tcp.tls.message[0].buffer); - if(flow->l4.tcp.tls.message[1].buffer) - ndpi_free(flow->l4.tcp.tls.message[1].buffer); - } + if(flow->tls_quic.message[0].buffer) + ndpi_free(flow->tls_quic.message[0].buffer); + if(flow->tls_quic.message[1].buffer) + ndpi_free(flow->tls_quic.message[1].buffer); if(flow->l4_proto == IPPROTO_UDP) { if(flow->l4.udp.quic_reasm_buf) diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c index 05b03d98c..6bc6bf059 100644 --- a/src/lib/protocols/tls.c +++ b/src/lib/protocols/tls.c @@ -146,18 +146,18 @@ static u_int32_t __get_master(struct ndpi_detection_module_struct *ndpi_struct, /* **************************************** */ -int ndpi_search_tls_tcp_memory(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow) { - struct ndpi_packet_struct *packet = &ndpi_struct->packet; - message_t *message = &flow->l4.tcp.tls.message[packet->packet_direction]; +static int ndpi_search_tls_memory(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + const u_int8_t *payload, + u_int16_t payload_len, + u_int32_t seq, + message_t *message) { u_int avail_bytes; - /* TCP */ #ifdef DEBUG_TLS_MEMORY - printf("[TLS Mem] Handling TCP/TLS flow [payload_len: %u][buffer_len: %u][direction: %u]\n", - packet->payload_packet_len, - message->buffer_len, - packet->packet_direction); + printf("[TLS Mem] Handling TLS flow [payload_len: %u][buffer_len: %u]\n", + payload_len, + message->buffer_len); #endif if(message->buffer == NULL) { @@ -175,8 +175,8 @@ int ndpi_search_tls_tcp_memory(struct ndpi_detection_module_struct *ndpi_struct, avail_bytes = message->buffer_len - message->buffer_used; - if(avail_bytes < packet->payload_packet_len) { - u_int new_len = message->buffer_len + packet->payload_packet_len - avail_bytes + 1; + if(avail_bytes < payload_len) { + u_int new_len = message->buffer_len + payload_len - avail_bytes + 1; void *newbuf = ndpi_realloc(message->buffer, message->buffer_len, new_len); if(!newbuf) return -1; @@ -190,35 +190,33 @@ int ndpi_search_tls_tcp_memory(struct ndpi_detection_module_struct *ndpi_struct, avail_bytes = message->buffer_len - message->buffer_used; } - if(packet->payload_packet_len > 0 && avail_bytes >= packet->payload_packet_len) { + if(payload_len > 0 && avail_bytes >= payload_len) { u_int8_t ok = 0; if(message->next_seq != 0) { - if(ntohl(packet->tcp->seq) == message->next_seq) + if(seq == message->next_seq) ok = 1; } else ok = 1; if(ok) { memcpy(&message->buffer[message->buffer_used], - packet->payload, packet->payload_packet_len); + payload, payload_len); - message->buffer_used += packet->payload_packet_len; + message->buffer_used += payload_len; #ifdef DEBUG_TLS_MEMORY - printf("[TLS Mem] Copied data to buffer [%u/%u bytes][direction: %u][tcp_seq: %u][next: %u]\n", + printf("[TLS Mem] Copied data to buffer [%u/%u bytes][tcp_seq: %u][next: %u]\n", message->buffer_used, message->buffer_len, - packet->packet_direction, - ntohl(packet->tcp->seq), - ntohl(packet->tcp->seq)+packet->payload_packet_len); + seq, + seq + payload_len); #endif - message->next_seq = ntohl(packet->tcp->seq)+packet->payload_packet_len; + message->next_seq = seq + payload_len; } else { #ifdef DEBUG_TLS_MEMORY - printf("[TLS Mem] Skipping packet [%u bytes][direction: %u][tcp_seq: %u][expected next: %u]\n", + printf("[TLS Mem] Skipping packet [%u bytes][tcp_seq: %u][expected next: %u]\n", message->buffer_len, - packet->packet_direction, - ntohl(packet->tcp->seq), + seq, message->next_seq); #endif } @@ -958,8 +956,8 @@ static int ndpi_search_tls_tcp(struct ndpi_detection_module_struct *ndpi_struct, message_t *message; #ifdef DEBUG_TLS_MEMORY - printf("[TLS Mem] ndpi_search_tls_tcp() Processing new packet [payload_packet_len: %u]\n", - packet->payload_packet_len); + printf("[TLS Mem] ndpi_search_tls_tcp() Processing new packet [payload_packet_len: %u][Dir: %u]\n", + packet->payload_packet_len, packet->packet_direction); #endif /* This function is also called by "extra dissection" data path. Unfortunately, @@ -974,9 +972,11 @@ static int ndpi_search_tls_tcp(struct ndpi_detection_module_struct *ndpi_struct, return 1; /* Keep working */ } - if(ndpi_search_tls_tcp_memory(ndpi_struct, flow) == -1) + message = &flow->tls_quic.message[packet->packet_direction]; + if(ndpi_search_tls_memory(ndpi_struct, flow, packet->payload, + packet->payload_packet_len, ntohl(packet->tcp->seq), + message) == -1) return 0; /* Error -> stop */ - message = &flow->l4.tcp.tls.message[packet->packet_direction]; /* Valid TLS Content Types: https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-5 */ @@ -1153,10 +1153,11 @@ static int ndpi_search_tls_tcp(struct ndpi_detection_module_struct *ndpi_struct, static int ndpi_search_tls_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &ndpi_struct->packet; - u_int32_t handshake_len; + u_int32_t handshake_len, handshake_frag_off, handshake_frag_len; u_int16_t p_len, processed; const u_int8_t *p; u_int8_t no_dtls = 0, change_cipher_found = 0; + message_t *message = NULL; #ifdef DEBUG_TLS printf("[TLS] %s()\n", __FUNCTION__); @@ -1204,19 +1205,73 @@ static int ndpi_search_tls_udp(struct ndpi_detection_module_struct *ndpi_struct, break; } /* TODO: handle (certificate) fragments */ - if(block_len > 16) { + if(block_len > 24) { handshake_len = (block[14] << 16) + (block[15] << 8) + block[16]; - if((handshake_len + 12) != block_len) { + handshake_frag_off = (block[19] << 16) + (block[20] << 8) + block[21]; + handshake_frag_len = (block[22] << 16) + (block[23] << 8) + block[24]; + message = &flow->tls_quic.message[packet->packet_direction]; + + +#ifdef DEBUG_TLS + printf("[TLS] DTLS frag off %d len %d\n", handshake_frag_off, handshake_frag_len); +#endif + + if((handshake_len + 12) == block_len) { + packet->payload = &block[13]; + packet->payload_packet_len = block_len; + processTLSBlock(ndpi_struct, flow); + } else if(handshake_len + 12 > block_len) { + int rc; + +#ifdef DEBUG_TLS + printf("[TLS] DTLS fragment off %d len %d\n", handshake_frag_off, handshake_frag_len); +#endif + if(handshake_frag_len + 12 > block_len) { +#ifdef DEBUG_TLS + printf("[TLS] DTLS fragment invalid len %d + 12 > %d\n", handshake_frag_len, block_len); +#endif + no_dtls = 1; + break; + } + + if(handshake_frag_off == 0) { + rc = ndpi_search_tls_memory(ndpi_struct, flow, &block[13], + handshake_frag_len + 12, + handshake_frag_off, message); + } else { + rc = ndpi_search_tls_memory(ndpi_struct, flow, &block[13 + 12], + handshake_frag_len, + handshake_frag_off + 12, message); + } + if(rc == -1) { + no_dtls = 1; + break; + } +#ifdef DEBUG_TLS + printf("[TLS] DTLS reassembled len %d vs %d\n", + message->buffer_used, handshake_len + 12); +#endif + + if(handshake_len + 12 == message->buffer_used) { + packet->payload = message->buffer; + packet->payload_packet_len = message->buffer_used; + processTLSBlock(ndpi_struct, flow); + + ndpi_free(message->buffer); + memset(message, '\0', sizeof(*message)); + message = NULL; + } else { + /* No break, next fragments might be in the same packet */ + } + + } else { #ifdef DEBUG_TLS - printf("[TLS] DTLS invalid handshake_len %d, %d)\n", + printf("[TLS] DTLS invalid handshake_len %d, %d\n", handshake_len, block_len); #endif no_dtls = 1; break; } - packet->payload = &block[13]; - packet->payload_packet_len = block_len; - processTLSBlock(ndpi_struct, flow); } } else if(block[0] == 0x14) { /* Change-cipher-spec: any subsequent block might be encrypted */ @@ -1239,7 +1294,7 @@ static int ndpi_search_tls_udp(struct ndpi_detection_module_struct *ndpi_struct, processed += block_len + 13; } - if(processed != p_len) { + if(processed != p_len && message == NULL /* No pending reassembler */) { #ifdef DEBUG_TLS printf("[TLS] DTLS invalid processed len %d/%d (%d)\n", processed, p_len, change_cipher_found); #endif @@ -1280,12 +1335,12 @@ void switch_extra_dissection_to_tls(struct ndpi_detection_module_struct *ndpi_st #endif /* Reset reassemblers */ - if(flow->l4.tcp.tls.message[0].buffer) - ndpi_free(flow->l4.tcp.tls.message[0].buffer); - memset(&flow->l4.tcp.tls.message[0], '\0', sizeof(flow->l4.tcp.tls.message[0])); - if(flow->l4.tcp.tls.message[1].buffer) - ndpi_free(flow->l4.tcp.tls.message[1].buffer); - memset(&flow->l4.tcp.tls.message[1], '\0', sizeof(flow->l4.tcp.tls.message[1])); + if(flow->tls_quic.message[0].buffer) + ndpi_free(flow->tls_quic.message[0].buffer); + memset(&flow->tls_quic.message[0], '\0', sizeof(flow->tls_quic.message[0])); + if(flow->tls_quic.message[1].buffer) + ndpi_free(flow->tls_quic.message[1].buffer); + memset(&flow->tls_quic.message[1], '\0', sizeof(flow->tls_quic.message[1])); tlsInitExtraPacketProcessing(ndpi_struct, flow); } |