diff options
Diffstat (limited to 'src/lib/protocols/ssl.c')
-rw-r--r-- | src/lib/protocols/ssl.c | 228 |
1 files changed, 115 insertions, 113 deletions
diff --git a/src/lib/protocols/ssl.c b/src/lib/protocols/ssl.c index f55b86ca1..5632741e5 100644 --- a/src/lib/protocols/ssl.c +++ b/src/lib/protocols/ssl.c @@ -35,7 +35,7 @@ extern u_int8_t is_skype_flow(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); static u_int32_t ndpi_ssl_refine_master_protocol(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow, u_int32_t protocol) + struct ndpi_flow_struct *flow, u_int32_t protocol) { struct ndpi_packet_struct *packet = &flow->packet; @@ -48,30 +48,32 @@ static u_int32_t ndpi_ssl_refine_master_protocol(struct ndpi_detection_module_st if(packet->tcp != NULL) { switch(protocol) { + case NDPI_PROTOCOL_SSL: case NDPI_PROTOCOL_SSL_NO_CERT: -{ - /* - In case of SSL there are probably sub-protocols - such as IMAPS that can be otherwise detected - */ - u_int16_t sport = ntohs(packet->tcp->source); - u_int16_t dport = ntohs(packet->tcp->dest); - - if((sport == 465) || (dport == 465)) protocol = NDPI_PROTOCOL_MAIL_SMTPS; - else if((sport == 993) || (dport == 993) + { + /* + In case of SSL there are probably sub-protocols + such as IMAPS that can be otherwise detected + */ + u_int16_t sport = ntohs(packet->tcp->source); + u_int16_t dport = ntohs(packet->tcp->dest); + + if((sport == 465) || (dport == 465)) + protocol = NDPI_PROTOCOL_MAIL_SMTPS; + else if((sport == 993) || (dport == 993) #ifdef NDPI_PROTOCOL_MAIL_IMAP - || (flow->l4.tcp.mail_imap_starttls) + || (flow->l4.tcp.mail_imap_starttls) #endif - ) protocol = NDPI_PROTOCOL_MAIL_IMAPS; - else if((sport == 995) || (dport == 995)) protocol = NDPI_PROTOCOL_MAIL_POPS; -} -break; + ) protocol = NDPI_PROTOCOL_MAIL_IMAPS; + else if((sport == 995) || (dport == 995)) protocol = NDPI_PROTOCOL_MAIL_POPS; + } + break; } - + if((protocol == NDPI_PROTOCOL_SSL_NO_CERT) - && is_skype_flow(ndpi_struct, flow)) { -protocol = NDPI_PROTOCOL_SKYPE; + && is_skype_flow(ndpi_struct, flow)) { + protocol = NDPI_PROTOCOL_SKYPE; } } @@ -96,20 +98,20 @@ static void ndpi_int_ssl_add_connection(struct ndpi_detection_module_struct *ndp #define ndpi_isdigit(ch) ((ch) >= '0' && (ch) <= '9') #define ndpi_isspace(ch) (((ch) >= '\t' && (ch) <= '\r') || ((ch) == ' ')) #define ndpi_isprint(ch) ((ch) >= 0x20 && (ch) <= 0x7e) -#define ndpi_ispunct(ch) (((ch) >= '!' && (ch) <= '/') || \ - ((ch) >= ':' && (ch) <= '@') || \ - ((ch) >= '[' && (ch) <= '`') || \ - ((ch) >= '{' && (ch) <= '~')) +#define ndpi_ispunct(ch) (((ch) >= '!' && (ch) <= '/') || \ + ((ch) >= ':' && (ch) <= '@') || \ + ((ch) >= '[' && (ch) <= '`') || \ + ((ch) >= '{' && (ch) <= '~')) static void stripCertificateTrailer(char *buffer, int buffer_len) { - + int i, is_puny; - + // printf("->%s<-\n", buffer); - + for(i = 0; i < buffer_len; i++) { // printf("%c [%d]\n", buffer[i], buffer[i]); - + if((buffer[i] != '.') && (buffer[i] != '-') && (buffer[i] != '*') @@ -163,7 +165,7 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct, /* Nothing matched so far: let's decode the certificate with some heuristics Patches courtesy of Denys Fedoryshchenko <nuclearcat@nuclearcat.com> - */ + */ if(packet->payload[0] == 0x16 /* Handshake */) { u_int16_t total_len = (packet->payload[3] << 8) + packet->payload[4] + 5 /* SSL Header */; u_int8_t handshake_protocol = packet->payload[5]; /* handshake protocol a bit misleading, it is message type according TLS specs */ @@ -172,7 +174,7 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct, /* Truncate total len, search at least in incomplete packet */ if(total_len > packet->payload_packet_len) - total_len = packet->payload_packet_len; + total_len = packet->payload_packet_len; /* At least "magic" 3 bytes, null for string end, otherwise no need to waste cpu cycles */ if(total_len > 4) { @@ -234,73 +236,73 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct, } else if(handshake_protocol == 0x01 /* Client Hello */) { u_int offset, base_offset = 43; if (base_offset + 2 <= packet->payload_packet_len) - { - u_int16_t session_id_len = packet->payload[base_offset]; + { + u_int16_t session_id_len = packet->payload[base_offset]; - if((session_id_len+base_offset+2) <= total_len) { - u_int16_t cypher_len = packet->payload[session_id_len+base_offset+2] + (packet->payload[session_id_len+base_offset+1] << 8); - offset = base_offset + session_id_len + cypher_len + 2; + if((session_id_len+base_offset+2) <= total_len) { + u_int16_t cypher_len = packet->payload[session_id_len+base_offset+2] + (packet->payload[session_id_len+base_offset+1] << 8); + offset = base_offset + session_id_len + cypher_len + 2; - flow->l4.tcp.ssl_seen_client_cert = 1; + flow->l4.tcp.ssl_seen_client_cert = 1; - if(offset < total_len) { - u_int16_t compression_len; - u_int16_t extensions_len; + if(offset < total_len) { + u_int16_t compression_len; + u_int16_t extensions_len; - compression_len = packet->payload[offset+1]; - offset += compression_len + 3; + compression_len = packet->payload[offset+1]; + offset += compression_len + 3; - if(offset < total_len) { - extensions_len = packet->payload[offset]; + if(offset < total_len) { + extensions_len = packet->payload[offset]; - if((extensions_len+offset) < total_len) { - /* Move to the first extension - Type is u_int to avoid possible overflow on extension_len addition */ - u_int extension_offset = 1; + if((extensions_len+offset) < total_len) { + /* Move to the first extension + Type is u_int to avoid possible overflow on extension_len addition */ + u_int extension_offset = 1; - while(extension_offset < extensions_len) { - u_int16_t extension_id, extension_len; + while(extension_offset < extensions_len) { + u_int16_t extension_id, extension_len; - memcpy(&extension_id, &packet->payload[offset+extension_offset], 2); - extension_offset += 2; + memcpy(&extension_id, &packet->payload[offset+extension_offset], 2); + extension_offset += 2; - memcpy(&extension_len, &packet->payload[offset+extension_offset], 2); - extension_offset += 2; + memcpy(&extension_len, &packet->payload[offset+extension_offset], 2); + extension_offset += 2; - extension_id = ntohs(extension_id), extension_len = ntohs(extension_len); + extension_id = ntohs(extension_id), extension_len = ntohs(extension_len); - if(extension_id == 0) { - u_int begin = 0,len; - char *server_name = (char*)&packet->payload[offset+extension_offset]; + if(extension_id == 0) { + u_int begin = 0,len; + char *server_name = (char*)&packet->payload[offset+extension_offset]; - while(begin < extension_len) { - if((!ndpi_isprint(server_name[begin])) - || ndpi_ispunct(server_name[begin]) - || ndpi_isspace(server_name[begin])) - begin++; - else - break; - } + while(begin < extension_len) { + if((!ndpi_isprint(server_name[begin])) + || ndpi_ispunct(server_name[begin]) + || ndpi_isspace(server_name[begin])) + begin++; + else + break; + } - len = (u_int)ndpi_min(extension_len-begin, buffer_len-1); - strncpy(buffer, &server_name[begin], len); - buffer[len] = '\0'; - stripCertificateTrailer(buffer, buffer_len); + len = (u_int)ndpi_min(extension_len-begin, buffer_len-1); + strncpy(buffer, &server_name[begin], len); + buffer[len] = '\0'; + stripCertificateTrailer(buffer, buffer_len); - snprintf(flow->protos.ssl.client_certificate, - sizeof(flow->protos.ssl.client_certificate), "%s", buffer); + snprintf(flow->protos.ssl.client_certificate, + sizeof(flow->protos.ssl.client_certificate), "%s", buffer); - /* We're happy now */ - return(2 /* Client Certificate */); - } + /* We're happy now */ + return(2 /* Client Certificate */); + } - extension_offset += extension_len; + extension_offset += extension_len; + } } } } } } - } } } } @@ -327,14 +329,14 @@ int sslDetectProtocolFromCertificate(struct ndpi_detection_module_struct *ndpi_s #ifdef CERTIFICATE_DEBUG printf("***** [SSL] %s\n", certificate); #endif - u_int32_t subproto = ndpi_match_host_subprotocol(ndpi_struct, flow, certificate, - strlen(certificate), NDPI_PROTOCOL_SSL); + u_int32_t subproto = ndpi_match_host_subprotocol(ndpi_struct, flow, certificate, + strlen(certificate), NDPI_PROTOCOL_SSL); if(subproto != NDPI_PROTOCOL_UNKNOWN) { - ndpi_set_detected_protocol(ndpi_struct, flow, subproto, - ndpi_ssl_refine_master_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SSL)); + ndpi_set_detected_protocol(ndpi_struct, flow, subproto, + ndpi_ssl_refine_master_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SSL)); return(rc); /* Fix courtesy of Gianluca Costa <g.costa@xplico.org> */ - } + } #ifdef NDPI_PROTOCOL_TOR if(ndpi_is_ssl_tor(ndpi_struct, flow, certificate) != 0) @@ -384,7 +386,7 @@ static void ssl_mark_and_payload_search_for_other_protocols(struct if(memcmp(&packet->payload[a], "talk.google.com", 15) == 0) { NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "ssl jabber packet match\n"); if(NDPI_COMPARE_PROTOCOL_TO_BITMASK - (ndpi_struct->detection_bitmask, NDPI_PROTOCOL_UNENCRYPED_JABBER) != 0) { + (ndpi_struct->detection_bitmask, NDPI_PROTOCOL_UNENCRYPED_JABBER) != 0) { ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_UNENCRYPED_JABBER); return; } @@ -393,18 +395,18 @@ static void ssl_mark_and_payload_search_for_other_protocols(struct #endif #ifdef NDPI_PROTOCOL_OSCAR if(packet->payload[a] == 'A' || packet->payload[a] == 'k' || packet->payload[a] == 'c' - || packet->payload[a] == 'h') { + || packet->payload[a] == 'h') { if(((a + 19) < packet->payload_packet_len && memcmp(&packet->payload[a], "America Online Inc.", 19) == 0) - // || (end - c > 3 memcmp (&packet->payload[c],"AOL", 3) == 0 ) - // || (end - c > 7 && memcmp (&packet->payload[c], "AOL LLC", 7) == 0) - || ((a + 15) < packet->payload_packet_len && memcmp(&packet->payload[a], "kdc.uas.aol.com", 15) == 0) - || ((a + 14) < packet->payload_packet_len && memcmp(&packet->payload[a], "corehc@aol.net", 14) == 0) - || ((a + 41) < packet->payload_packet_len - && memcmp(&packet->payload[a], "http://crl.aol.com/AOLMSPKI/aolServerCert", 41) == 0) - || ((a + 28) < packet->payload_packet_len - && memcmp(&packet->payload[a], "http://ocsp.web.aol.com/ocsp", 28) == 0) - || ((a + 32) < packet->payload_packet_len - && memcmp(&packet->payload[a], "http://pki-info.aol.com/AOLMSPKI", 32) == 0)) { + // || (end - c > 3 memcmp (&packet->payload[c],"AOL", 3) == 0 ) + // || (end - c > 7 && memcmp (&packet->payload[c], "AOL LLC", 7) == 0) + || ((a + 15) < packet->payload_packet_len && memcmp(&packet->payload[a], "kdc.uas.aol.com", 15) == 0) + || ((a + 14) < packet->payload_packet_len && memcmp(&packet->payload[a], "corehc@aol.net", 14) == 0) + || ((a + 41) < packet->payload_packet_len + && memcmp(&packet->payload[a], "http://crl.aol.com/AOLMSPKI/aolServerCert", 41) == 0) + || ((a + 28) < packet->payload_packet_len + && memcmp(&packet->payload[a], "http://ocsp.web.aol.com/ocsp", 28) == 0) + || ((a + 32) < packet->payload_packet_len + && memcmp(&packet->payload[a], "http://pki-info.aol.com/AOLMSPKI", 32) == 0)) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR SERVER SSL DETECTED\n"); if(flow->dst != NULL && packet->payload_packet_len > 75) { @@ -420,8 +422,8 @@ static void ssl_mark_and_payload_search_for_other_protocols(struct if(packet->payload[a] == 'm' || packet->payload[a] == 's') { if((a + 21) < packet->payload_packet_len && - (memcmp(&packet->payload[a], "my.screenname.aol.com", 21) == 0 - || memcmp(&packet->payload[a], "sns-static.aolcdn.com", 21) == 0)) { + (memcmp(&packet->payload[a], "my.screenname.aol.com", 21) == 0 + || memcmp(&packet->payload[a], "sns-static.aolcdn.com", 21) == 0)) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR SERVER SSL DETECTED\n"); ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_OSCAR); return; @@ -456,13 +458,13 @@ static u_int8_t ndpi_search_sslv3_direction1(struct ndpi_detection_module_struct if((packet->payload_packet_len >= 5) - && (packet->payload[0] == 0x16) - && (packet->payload[1] == 0x03) - && ((packet->payload[2] == 0x00) - || (packet->payload[2] == 0x01) - || (packet->payload[2] == 0x02) - || (packet->payload[2] == 0x03) - )) { + && (packet->payload[0] == 0x16) + && (packet->payload[1] == 0x03) + && ((packet->payload[2] == 0x00) + || (packet->payload[2] == 0x01) + || (packet->payload[2] == 0x02) + || (packet->payload[2] == 0x03) + )) { u_int32_t temp; NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "search sslv3\n"); // SSLv3 Record @@ -472,7 +474,7 @@ static u_int8_t ndpi_search_sslv3_direction1(struct ndpi_detection_module_struct temp = ntohs(get_u_int16_t(packet->payload, 3)) + 5; NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "temp = %u.\n", temp); if(packet->payload_packet_len == temp - || (temp < packet->payload_packet_len && packet->payload_packet_len > 500)) { + || (temp < packet->payload_packet_len && packet->payload_packet_len > 500)) { return 1; } @@ -517,7 +519,7 @@ static u_int8_t ndpi_search_sslv3_direction1(struct ndpi_detection_module_struct if(packet->payload_packet_len >= temp + 5 && (packet->payload[temp] == 0x14 || packet->payload[temp] == 0x16) - && packet->payload[temp + 1] == 0x03) { + && packet->payload[temp + 1] == 0x03) { u_int32_t temp2 = ntohs(get_u_int16_t(packet->payload, temp + 3)) + 5; if(temp + temp2 > NDPI_MAX_SSL_REQUEST_SIZE) { return 1; @@ -528,7 +530,7 @@ static u_int8_t ndpi_search_sslv3_direction1(struct ndpi_detection_module_struct return 1; } if(packet->payload_packet_len >= temp + 5 && - packet->payload[temp] == 0x16 && packet->payload[temp + 1] == 0x03) { + packet->payload[temp] == 0x16 && packet->payload[temp + 1] == 0x03) { temp2 = ntohs(get_u_int16_t(packet->payload, temp + 3)) + 5; if(temp + temp2 > NDPI_MAX_SSL_REQUEST_SIZE) { return 1; @@ -539,7 +541,7 @@ static u_int8_t ndpi_search_sslv3_direction1(struct ndpi_detection_module_struct return 1; } if(packet->payload_packet_len >= temp + 5 && - packet->payload[temp] == 0x16 && packet->payload[temp + 1] == 0x03) { + packet->payload[temp] == 0x16 && packet->payload[temp + 1] == 0x03) { temp2 = ntohs(get_u_int16_t(packet->payload, temp + 3)) + 5; if(temp + temp2 > NDPI_MAX_SSL_REQUEST_SIZE) { return 1; @@ -608,16 +610,16 @@ void ndpi_search_ssl_tcp(struct ndpi_detection_module_struct *ndpi_struct, struc NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "first ssl packet\n"); // SSLv2 Record if(packet->payload[2] == 0x01 && packet->payload[3] == 0x03 - && (packet->payload[4] == 0x00 || packet->payload[4] == 0x01 || packet->payload[4] == 0x02) - && (packet->payload_packet_len - packet->payload[1] == 2)) { + && (packet->payload[4] == 0x00 || packet->payload[4] == 0x01 || packet->payload[4] == 0x02) + && (packet->payload_packet_len - packet->payload[1] == 2)) { NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv2 len match\n"); flow->l4.tcp.ssl_stage = 1 + packet->packet_direction; return; } if(packet->payload[0] == 0x16 && packet->payload[1] == 0x03 - && (packet->payload[2] == 0x00 || packet->payload[2] == 0x01 || packet->payload[2] == 0x02) - && (packet->payload_packet_len - ntohs(get_u_int16_t(packet->payload, 3)) == 5)) { + && (packet->payload[2] == 0x00 || packet->payload[2] == 0x01 || packet->payload[2] == 0x02) + && (packet->payload_packet_len - ntohs(get_u_int16_t(packet->payload, 3)) == 5)) { // SSLv3 Record NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv3 len match\n"); flow->l4.tcp.ssl_stage = 1 + packet->packet_direction; @@ -626,8 +628,8 @@ void ndpi_search_ssl_tcp(struct ndpi_detection_module_struct *ndpi_struct, struc } if(packet->payload_packet_len > 40 && - flow->l4.tcp.ssl_stage == 1 + packet->packet_direction - && flow->packet_direction_counter[packet->packet_direction] < 5) { + flow->l4.tcp.ssl_stage == 1 + packet->packet_direction + && flow->packet_direction_counter[packet->packet_direction] < 5) { return; } @@ -635,8 +637,8 @@ void ndpi_search_ssl_tcp(struct ndpi_detection_module_struct *ndpi_struct, struc NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "second ssl packet\n"); // SSLv2 Record if(packet->payload[2] == 0x01 && packet->payload[3] == 0x03 - && (packet->payload[4] == 0x00 || packet->payload[4] == 0x01 || packet->payload[4] == 0x02) - && (packet->payload_packet_len - 2) >= packet->payload[1]) { + && (packet->payload[4] == 0x00 || packet->payload[4] == 0x01 || packet->payload[4] == 0x02) + && (packet->payload_packet_len - 2) >= packet->payload[1]) { NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv2 server len match\n"); ssl_mark_and_payload_search_for_other_protocols(ndpi_struct, flow); return; |