aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/Makefile.am1
-rw-r--r--src/include/ndpi_typedefs.h4
-rw-r--r--src/lib/ndpi_main.c6
-rw-r--r--src/lib/ndpi_utils.c13
-rw-r--r--src/lib/protocols/tls.c100
5 files changed, 106 insertions, 18 deletions
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
index 47fcbd224..db4e40f35 100644
--- a/src/include/Makefile.am
+++ b/src/include/Makefile.am
@@ -1,3 +1,4 @@
+p
plibrary_includedir=$(includedir)/libndpi-@VERSION@/libndpi
library_include_HEADERS = ndpi_api.h \
diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h
index b7bff5b85..ca1da4ff2 100644
--- a/src/include/ndpi_typedefs.h
+++ b/src/include/ndpi_typedefs.h
@@ -1196,8 +1196,8 @@ struct ndpi_flow_struct {
struct {
struct {
u_int16_t ssl_version, server_names_len;
- char client_requested_server_name[64], *server_names, server_organization[64],
- *alpn, *tls_supported_versions;
+ char client_requested_server_name[64], *server_names,
+ *alpn, *tls_supported_versions, *issuerDN, *subjectDN;
u_int32_t notBefore, notAfter;
char ja3_client[33], ja3_server[33];
u_int16_t server_cipher;
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index ed2d5995b..db5e14778 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -5976,6 +5976,12 @@ void ndpi_free_flow(struct ndpi_flow_struct *flow) {
if(flow->protos.stun_ssl.ssl.tls_supported_versions)
ndpi_free(flow->protos.stun_ssl.ssl.tls_supported_versions);
+ if(flow->protos.stun_ssl.ssl.issuerDN)
+ ndpi_free(flow->protos.stun_ssl.ssl.issuerDN);
+
+ if(flow->protos.stun_ssl.ssl.subjectDN)
+ ndpi_free(flow->protos.stun_ssl.ssl.subjectDN);
+
if(flow->l4.tcp.tls.srv_cert_fingerprint_ctx)
ndpi_free(flow->l4.tcp.tls.srv_cert_fingerprint_ctx);
}
diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c
index 7f6d6f9f6..db5394eb0 100644
--- a/src/lib/ndpi_utils.c
+++ b/src/lib/ndpi_utils.c
@@ -1099,7 +1099,6 @@ int ndpi_flow2json(struct ndpi_detection_module_struct *ndpi_struct,
flow->protos.stun_ssl.ssl.client_requested_server_name);
if(flow->protos.stun_ssl.ssl.server_names)
ndpi_serialize_string_string(serializer, "server_names", flow->protos.stun_ssl.ssl.server_names);
- ndpi_serialize_string_string(serializer, "issuer", flow->protos.stun_ssl.ssl.server_organization);
if(before) {
strftime(notBefore, sizeof(notBefore), "%F %T", before);
@@ -1115,6 +1114,18 @@ int ndpi_flow2json(struct ndpi_detection_module_struct *ndpi_struct,
ndpi_serialize_string_uint32(serializer, "unsafe_cipher", flow->protos.stun_ssl.ssl.server_unsafe_cipher);
ndpi_serialize_string_string(serializer, "cipher", ndpi_cipher2str(flow->protos.stun_ssl.ssl.server_cipher));
+ if(flow->protos.stun_ssl.ssl.issuerDN)
+ ndpi_serialize_string_string(serializer, "issuerDN", flow->protos.stun_ssl.ssl.issuerDN);
+
+ if(flow->protos.stun_ssl.ssl.subjectDN)
+ ndpi_serialize_string_string(serializer, "issuerDN", flow->protos.stun_ssl.ssl.subjectDN);
+
+ if(flow->protos.stun_ssl.ssl.alpn)
+ ndpi_serialize_string_string(serializer, "alpn", flow->protos.stun_ssl.ssl.alpn);
+
+ if(flow->protos.stun_ssl.ssl.tls_supported_versions)
+ ndpi_serialize_string_string(serializer, "tls_supported_versions", flow->protos.stun_ssl.ssl.tls_supported_versions);
+
if(flow->l4.tcp.tls.sha1_certificate_fingerprint[0] != '\0') {
for(i=0, off=0; i<20; i++) {
int rc = snprintf(&buf[off], sizeof(buf)-off,"%s%02X", (i > 0) ? ":" : "",
diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c
index 184f64e65..171d7c489 100644
--- a/src/lib/protocols/tls.c
+++ b/src/lib/protocols/tls.c
@@ -188,17 +188,20 @@ static void cleanupServerName(char *buffer, int buffer_len) {
1: OK
*/
static int extractRDNSequence(struct ndpi_packet_struct *packet,
- u_int offset, char *buffer, u_int buffer_len) {
+ u_int offset, char *buffer, u_int buffer_len,
+ char *rdnSeqBuf, u_int *rdnSeqBuf_offset,
+ u_int rdnSeqBuf_len,
+ const char *label) {
u_int8_t str_len = packet->payload[offset+4], is_printable = 1;
char *str;
u_int len, j;
-
+
// packet is truncated... further inspection is not needed
if((offset+4+str_len) >= packet->payload_packet_len)
return(-1);
str = (char*)&packet->payload[offset+5];
-
+
len = (u_int)ndpi_min(str_len, buffer_len-1);
strncpy(buffer, str, len);
buffer[len] = '\0';
@@ -211,6 +214,16 @@ static int extractRDNSequence(struct ndpi_packet_struct *packet,
}
}
+ if(is_printable) {
+ int rc = snprintf(&rdnSeqBuf[*rdnSeqBuf_offset],
+ rdnSeqBuf_len-(*rdnSeqBuf_offset),
+ "%s%s=%s", (*rdnSeqBuf_offset > 0) ? ", " : "",
+ label, buffer);
+
+ if(rc > 0)
+ (*rdnSeqBuf_offset) += rc;
+ }
+
return(is_printable);
}
@@ -222,7 +235,8 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi
u_int16_t p_offset, u_int16_t certificate_len) {
struct ndpi_packet_struct *packet = &flow->packet;
u_int num_found = 0, i;
- char buffer[64] = { '\0' };
+ char buffer[64] = { '\0' }, rdnSeqBuf[1024] = { '\0' };
+ u_int rdn_len = 0;
#ifdef DEBUG_TLS
printf("[TLS] %s() [offset: %u][certificate_len: %u]\n", __FUNCTION__, p_offset, certificate_len);
@@ -230,32 +244,81 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi
/* Check after handshake protocol header (5 bytes) and message header (4 bytes) */
for(i = p_offset; i < certificate_len; i++) {
- /* Organization OID: 2.5.4.10 */
- if((packet->payload[i] == 0x55) && (packet->payload[i+1] == 0x04) && (packet->payload[i+2] == 0x0a)) {
- int rc = extractRDNSequence(packet, i, buffer, sizeof(buffer));
+ /*
+ See https://www.ibm.com/support/knowledgecenter/SSFKSJ_7.5.0/com.ibm.mq.sec.doc/q009860_.htm
+ for X.509 certificate labels
+ */
+ if((packet->payload[i] == 0x55) && (packet->payload[i+1] == 0x04) && (packet->payload[i+2] == 0x03)) {
+ /* Common Name */
+ int rc = extractRDNSequence(packet, i, buffer, sizeof(buffer), rdnSeqBuf, &rdn_len, sizeof(rdnSeqBuf), "CN");
+ if(rc == -1) break;
+
+#ifdef DEBUG_TLS
+ printf("[TLS] %s() [%s][%s: %s]\n", __FUNCTION__, (num_found == 0) ? "Subject" : "Issuer", "Common Name", buffer);
+#endif
+ } else if((packet->payload[i] == 0x55) && (packet->payload[i+1] == 0x04) && (packet->payload[i+2] == 0x06)) {
+ /* Country */
+ int rc = extractRDNSequence(packet, i, buffer, sizeof(buffer), rdnSeqBuf, &rdn_len, sizeof(rdnSeqBuf), "C");
+ if(rc == -1) break;
+
+#ifdef DEBUG_TLS
+ printf("[TLS] %s() [%s][%s: %s]\n", __FUNCTION__, (num_found == 0) ? "Subject" : "Issuer", "Country", buffer);
+#endif
+ } else if((packet->payload[i] == 0x55) && (packet->payload[i+1] == 0x04) && (packet->payload[i+2] == 0x07)) {
+ /* Locality */
+ int rc = extractRDNSequence(packet, i, buffer, sizeof(buffer), rdnSeqBuf, &rdn_len, sizeof(rdnSeqBuf), "L");
+ if(rc == -1) break;
+#ifdef DEBUG_TLS
+ printf("[TLS] %s() [%s][%s: %s]\n", __FUNCTION__, (num_found == 0) ? "Subject" : "Issuer", "Locality", buffer);
+#endif
+ } else if((packet->payload[i] == 0x55) && (packet->payload[i+1] == 0x04) && (packet->payload[i+2] == 0x08)) {
+ /* State or Province */
+ int rc = extractRDNSequence(packet, i, buffer, sizeof(buffer), rdnSeqBuf, &rdn_len, sizeof(rdnSeqBuf), "ST");
if(rc == -1) break;
- num_found++;
- /* what we want is subject certificate, so we bypass the issuer certificate */
- if(num_found != 2) continue;
+#ifdef DEBUG_TLS
+ printf("[TLS] %s() [%s][%s: %s]\n", __FUNCTION__, (num_found == 0) ? "Subject" : "Issuer", "State or Province", buffer);
+#endif
+ } else if((packet->payload[i] == 0x55) && (packet->payload[i+1] == 0x04) && (packet->payload[i+2] == 0x0a)) {
+ /* Organization Name */
+ int rc = extractRDNSequence(packet, i, buffer, sizeof(buffer), rdnSeqBuf, &rdn_len, sizeof(rdnSeqBuf), "O");
+ if(rc == -1) break;
- if(rc == 1) {
- snprintf(flow->protos.stun_ssl.ssl.server_organization,
- sizeof(flow->protos.stun_ssl.ssl.server_organization), "%s", buffer);
#ifdef DEBUG_TLS
- printf("Certificate organization: %s\n", flow->protos.stun_ssl.ssl.server_organization);
+ printf("[TLS] %s() [%s][%s: %s]\n", __FUNCTION__, (num_found == 0) ? "Subject" : "Issuer", "Organization Name", buffer);
+#endif
+
+ } else if((packet->payload[i] == 0x55) && (packet->payload[i+1] == 0x04) && (packet->payload[i+2] == 0x0b)) {
+ /* Organization Unit */
+ int rc = extractRDNSequence(packet, i, buffer, sizeof(buffer), rdnSeqBuf, &rdn_len, sizeof(rdnSeqBuf), "OU");
+ if(rc == -1) break;
+
+#ifdef DEBUG_TLS
+ printf("[TLS] %s() [%s][%s: %s]\n", __FUNCTION__, (num_found == 0) ? "Subject" : "Issuer", "Organization Unit", buffer);
#endif
- }
} else if((packet->payload[i] == 0x30) && (packet->payload[i+1] == 0x1e) && (packet->payload[i+2] == 0x17)) {
/* Certificate Validity */
u_int8_t len = packet->payload[i+3];
u_int offset = i+4;
+ if(num_found == 0) {
+ num_found++;
+
+#ifdef DEBUG_TLS
+ printf("[TLS] %s() IssuerDN [%s]\n", __FUNCTION__, rdnSeqBuf);
+#endif
+
+ if(rdn_len) flow->protos.stun_ssl.ssl.issuerDN = strdup(rdnSeqBuf);
+ rdn_len = 0; /* Reset buffer */
+ }
+
if((offset+len) < packet->payload_packet_len) {
char utcDate[32];
#ifdef DEBUG_TLS
+ u_int j;
+
printf("[CERTIFICATE] notBefore [len: %u][", len);
for(j=0; j<len; j++) printf("%c", packet->payload[i+4+j]);
printf("]\n");
@@ -287,6 +350,8 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi
if((offset+len) < packet->payload_packet_len) {
#ifdef DEBUG_TLS
+ u_int j;
+
printf("[CERTIFICATE] notAfter [len: %u][", len);
for(j=0; j<len; j++) printf("%c", packet->payload[offset+j]);
printf("]\n");
@@ -383,6 +448,11 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi
} /* while */
}
}
+
+ if(rdn_len) flow->protos.stun_ssl.ssl.subjectDN = strdup(rdnSeqBuf);
+#if DEBUG_TLS
+ printf("[TLS] %s() SubjectDN [%s]\n", __FUNCTION__, rdnSeqBuf);
+#endif
}
/* **************************************** */