aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLuca Deri <deri@ntop.org>2020-05-31 08:28:02 +0200
committerLuca Deri <deri@ntop.org>2020-05-31 08:28:02 +0200
commitc793e16050df1de377e400eec6e2b34ccff6ca85 (patch)
treeeae00620f08c260404999b7382470430a9178ec9 /src
parentb6eef17e54999586b6aef8f545c87de4d3ec0ab3 (diff)
Added extra TLS memory boundary checks
Diffstat (limited to 'src')
-rw-r--r--src/lib/protocols/tls.c124
1 files changed, 65 insertions, 59 deletions
diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c
index 816a08adc..e2d1a572e 100644
--- a/src/lib/protocols/tls.c
+++ b/src/lib/protocols/tls.c
@@ -390,77 +390,83 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi
i += 3 /* skip the initial patten 55 1D 11 */;
i++; /* skip the first type, 0x04 == BIT STRING, and jump to it's length */
- i += (packet->payload[i] & 0x80) ? (packet->payload[i] & 0x7F) : 0; /* skip BIT STRING length */
- i += 2; /* skip the second type, 0x30 == SEQUENCE, and jump to it's length */
- i += (packet->payload[i] & 0x80) ? (packet->payload[i] & 0x7F) : 0; /* skip SEQUENCE length */
- i++;
-
- while(i < packet->payload_packet_len) {
- if(packet->payload[i] == 0x82) {
- if((i < (packet->payload_packet_len - 1))
- && ((i + packet->payload[i + 1] + 2) < packet->payload_packet_len)) {
- u_int8_t len = packet->payload[i + 1];
- char dNSName[256];
-
- i += 2;
-
- /* The check "len > sizeof(dNSName) - 1" will be always false. If we add it,
- the compiler is smart enough to detect it and throws a warning */
- if(len == 0 /* Looks something went wrong */)
- break;
+ if(i < packet->payload_packet_len) {
+ i += (packet->payload[i] & 0x80) ? (packet->payload[i] & 0x7F) : 0; /* skip BIT STRING length */
+ if(i < packet->payload_packet_len) {
+ i += 2; /* skip the second type, 0x30 == SEQUENCE, and jump to it's length */
+ if(i < packet->payload_packet_len) {
+ i += (packet->payload[i] & 0x80) ? (packet->payload[i] & 0x7F) : 0; /* skip SEQUENCE length */
+ i++;
+
+ while(i < packet->payload_packet_len) {
+ if(packet->payload[i] == 0x82) {
+ if((i < (packet->payload_packet_len - 1))
+ && ((i + packet->payload[i + 1] + 2) < packet->payload_packet_len)) {
+ u_int8_t len = packet->payload[i + 1];
+ char dNSName[256];
+
+ i += 2;
+
+ /* The check "len > sizeof(dNSName) - 1" will be always false. If we add it,
+ the compiler is smart enough to detect it and throws a warning */
+ if(len == 0 /* Looks something went wrong */)
+ break;
- strncpy(dNSName, (const char*)&packet->payload[i], len);
- dNSName[len] = '\0';
+ strncpy(dNSName, (const char*)&packet->payload[i], len);
+ dNSName[len] = '\0';
- cleanupServerName(dNSName, len);
+ cleanupServerName(dNSName, len);
#if DEBUG_TLS
- printf("[TLS] dNSName %s [%s]\n", dNSName, flow->protos.stun_ssl.ssl.client_requested_server_name);
+ printf("[TLS] dNSName %s [%s]\n", dNSName, flow->protos.stun_ssl.ssl.client_requested_server_name);
#endif
- if(matched_name == 0) {
- if((dNSName[0] == '*') && strstr(flow->protos.stun_ssl.ssl.client_requested_server_name, &dNSName[1]))
- matched_name = 1;
- else if(strcmp(flow->protos.stun_ssl.ssl.client_requested_server_name, dNSName) == 0)
- matched_name = 1;
- }
+ if(matched_name == 0) {
+ if((dNSName[0] == '*') && strstr(flow->protos.stun_ssl.ssl.client_requested_server_name, &dNSName[1]))
+ matched_name = 1;
+ else if(strcmp(flow->protos.stun_ssl.ssl.client_requested_server_name, dNSName) == 0)
+ matched_name = 1;
+ }
- if(flow->protos.stun_ssl.ssl.server_names == NULL)
- flow->protos.stun_ssl.ssl.server_names = ndpi_strdup(dNSName),
- flow->protos.stun_ssl.ssl.server_names_len = strlen(dNSName);
- else {
- u_int16_t dNSName_len = strlen(dNSName);
- u_int16_t newstr_len = flow->protos.stun_ssl.ssl.server_names_len + dNSName_len + 1;
- char *newstr = (char*)ndpi_realloc(flow->protos.stun_ssl.ssl.server_names,
- flow->protos.stun_ssl.ssl.server_names_len+1, newstr_len+1);
-
- if(newstr) {
- flow->protos.stun_ssl.ssl.server_names = newstr;
- flow->protos.stun_ssl.ssl.server_names[flow->protos.stun_ssl.ssl.server_names_len] = ',';
- strncpy(&flow->protos.stun_ssl.ssl.server_names[flow->protos.stun_ssl.ssl.server_names_len+1],
- dNSName, dNSName_len+1);
- flow->protos.stun_ssl.ssl.server_names[newstr_len] = '\0';
- flow->protos.stun_ssl.ssl.server_names_len = newstr_len;
- }
- }
+ if(flow->protos.stun_ssl.ssl.server_names == NULL)
+ flow->protos.stun_ssl.ssl.server_names = ndpi_strdup(dNSName),
+ flow->protos.stun_ssl.ssl.server_names_len = strlen(dNSName);
+ else {
+ u_int16_t dNSName_len = strlen(dNSName);
+ u_int16_t newstr_len = flow->protos.stun_ssl.ssl.server_names_len + dNSName_len + 1;
+ char *newstr = (char*)ndpi_realloc(flow->protos.stun_ssl.ssl.server_names,
+ flow->protos.stun_ssl.ssl.server_names_len+1, newstr_len+1);
+
+ if(newstr) {
+ flow->protos.stun_ssl.ssl.server_names = newstr;
+ flow->protos.stun_ssl.ssl.server_names[flow->protos.stun_ssl.ssl.server_names_len] = ',';
+ strncpy(&flow->protos.stun_ssl.ssl.server_names[flow->protos.stun_ssl.ssl.server_names_len+1],
+ dNSName, dNSName_len+1);
+ flow->protos.stun_ssl.ssl.server_names[newstr_len] = '\0';
+ flow->protos.stun_ssl.ssl.server_names_len = newstr_len;
+ }
+ }
- if(!flow->l4.tcp.tls.subprotocol_detected)
- if(ndpi_match_hostname_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TLS, dNSName, len))
- flow->l4.tcp.tls.subprotocol_detected = 1;
+ if(!flow->l4.tcp.tls.subprotocol_detected)
+ if(ndpi_match_hostname_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TLS, dNSName, len))
+ flow->l4.tcp.tls.subprotocol_detected = 1;
- i += len;
- } else {
+ i += len;
+ } else {
#if DEBUG_TLS
- printf("[TLS] Leftover %u bytes", packet->payload_packet_len - i);
+ printf("[TLS] Leftover %u bytes", packet->payload_packet_len - i);
#endif
- break;
+ break;
+ }
+ } else {
+ break;
+ }
+ } /* while */
+
+ if(!matched_name)
+ NDPI_SET_BIT(flow->risk, NDPI_TLS_CERTIFICATE_MISMATCH); /* Certificate mismatch */
}
- } else {
- break;
}
- } /* while */
-
- if(!matched_name)
- NDPI_SET_BIT(flow->risk, NDPI_TLS_CERTIFICATE_MISMATCH); /* Certificate mismatch */
+ }
}
}