aboutsummaryrefslogtreecommitdiff
path: root/src/lib/protocols
diff options
context:
space:
mode:
authorIvan Nardi <12729895+IvanNardi@users.noreply.github.com>2022-12-10 18:32:25 +0100
committerGitHub <noreply@github.com>2022-12-10 18:32:25 +0100
commit8c7071e040865b3b70b98ff8d8ad18c41f3fb74c (patch)
treeb52a3e84e4997d53049226611584e820767bb5b6 /src/lib/protocols
parent79931b2ec7dffc88df4cdd6855d7b1ec95cca20f (diff)
DTLS: handle (certificate) fragments (#1811)
Keep using the existing function to handle reassembling buffer: rename it from `ndpi_search_tls_tcp_memory` to `ndpi_search_tls_memory` and make it "transport" agnostic
Diffstat (limited to 'src/lib/protocols')
-rw-r--r--src/lib/protocols/tls.c137
1 files changed, 96 insertions, 41 deletions
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);
}