88 * \author Jiri Havranek <[email protected] > 99 * \author Karel Hynek <[email protected] > 1010 * \author Andrej Lukacovic [email protected] 11+ * \author Jonas Mücke <[email protected] > 1112 * \date 2022
1213 */
1314
2930#include < ipfixprobe/process.hpp>
3031#include < ipfixprobe/flowifc.hpp>
3132#include < ipfixprobe/packet.hpp>
33+ #include < ipfixprobe/ipfix-basiclist.hpp>
3234#include < ipfixprobe/ipfix-elements.hpp>
3335#include < ipfixprobe/utils.hpp>
3436#include < process/tls_parser.hpp>
3739#define BUFF_SIZE 255
3840
3941namespace ipxp {
40- #define TLS_UNIREC_TEMPLATE " TLS_SNI,TLS_JA3,TLS_ALPN,TLS_VERSION"
42+ #define TLS_UNIREC_TEMPLATE " TLS_SNI,TLS_JA3,TLS_ALPN,TLS_VERSION,TLS_EXT_TYPE,TLS_EXT_LEN "
4143
4244UR_FIELDS (
4345 string TLS_SNI,
4446 string TLS_ALPN,
4547 uint16 TLS_VERSION,
46- bytes TLS_JA3
48+ bytes TLS_JA3,
49+ uint16* TLS_EXT_TYPE,
50+ uint16* TLS_EXT_LEN
4751)
4852
4953/* *
5054 * \brief Flow record extension header for storing parsed HTTPS packets.
5155 */
56+ // TODO fix IEs
57+ #define TLS_EXT_TYPE_FIELD_ID 802
58+ #define TLS_EXT_LEN_FIELD_ID 803
5259struct RecordExtTLS : public RecordExt {
5360 static int REGISTERED_ID;
5461
@@ -60,6 +67,14 @@ struct RecordExtTLS : public RecordExt {
6067 std::string ja3;
6168 bool server_hello_parsed;
6269
70+ uint16_t tls_ext_type[MAX_TLS_EXT_LEN];
71+ uint16_t tls_ext_type_len;
72+ bool tls_ext_type_set;
73+
74+ uint16_t tls_ext_len[MAX_TLS_EXT_LEN];
75+ uint8_t tls_ext_len_len;
76+ bool tls_ext_len_set;
77+
6378 /* *
6479 * \brief Constructor.
6580 */
@@ -69,6 +84,14 @@ struct RecordExtTLS : public RecordExt {
6984 sni[0 ] = 0 ;
7085 ja3_hash[0 ] = 0 ;
7186 server_hello_parsed = false ;
87+
88+ memset (tls_ext_type, 0 , sizeof (tls_ext_type));
89+ tls_ext_type_len = 0 ;
90+ tls_ext_type_set = false ;
91+
92+ memset (tls_ext_len, 0 , sizeof (tls_ext_len));
93+ tls_ext_len_len = 0 ;
94+ tls_ext_len_set = false ;
7295 }
7396
7497 #ifdef WITH_NEMEA
@@ -78,6 +101,14 @@ struct RecordExtTLS : public RecordExt {
78101 ur_set_string (tmplt, record, F_TLS_SNI, sni);
79102 ur_set_string (tmplt, record, F_TLS_ALPN, alpn);
80103 ur_set_var (tmplt, record, F_TLS_JA3, ja3_hash_bin, 16 );
104+ ur_array_allocate (tmplt, record, F_QUIC_TLS_EXT_TYPE, tls_ext_type_len);
105+ for (int i = 0 ; i < tls_ext_type_len; i++) {
106+ ur_array_set (tmplt, record, F_TLS_EXT_TYPE, i, tls_ext_type[i]);
107+ }
108+ ur_array_allocate (tmplt, record, F_TLS_EXT_LEN, tls_ext_len_len);
109+ for (int i = 0 ; i < tls_ext_len_len; i++) {
110+ ur_array_set (tmplt, record, F_TLS_EXT_LEN, i, tls_ext_len[i]);
111+ }
81112 }
82113
83114 const char *get_unirec_tmplt () const
@@ -89,11 +120,18 @@ struct RecordExtTLS : public RecordExt {
89120
90121 virtual int fill_ipfix (uint8_t *buffer, int size)
91122 {
123+ IpfixBasicList basiclist;
124+ basiclist.hdrEnterpriseNum = IpfixBasicList::CesnetPEM;
125+
92126 uint16_t sni_len = strlen (sni);
93127 uint16_t alpn_len = strlen (alpn);
94128
95129 uint32_t pos = 0 ;
96- uint32_t req_buff_len = (sni_len + 3 ) + (alpn_len + 3 ) + (2 ) + (16 + 3 ); // (SNI) + (ALPN) + (VERSION) + (JA3)
130+
131+ uint16_t len_tls_ext_type = sizeof (tls_ext_type[0 ]) * (tls_ext_type_len) + basiclist.HeaderSize ();
132+ uint16_t len_tls_len = sizeof (tls_ext_len[0 ]) * (tls_ext_len_len) + basiclist.HeaderSize ();
133+
134+ uint32_t req_buff_len = (sni_len + 3 ) + (alpn_len + 3 ) + (2 ) + (16 + 3 ) + len_tls_ext_type + len_tls_len; // (SNI) + (ALPN) + (VERSION) + (JA3)
97135
98136 if (req_buff_len > (uint32_t ) size) {
99137 return -1 ;
@@ -108,7 +146,16 @@ struct RecordExtTLS : public RecordExt {
108146 buffer[pos++] = 16 ;
109147 memcpy (buffer + pos, ja3_hash_bin, 16 );
110148 pos += 16 ;
111-
149+ pos += basiclist.FillBuffer (
150+ buffer + pos,
151+ tls_ext_type,
152+ (uint16_t ) tls_ext_type_len,
153+ (uint16_t ) TLS_EXT_TYPE_FIELD_ID);
154+ pos += basiclist.FillBuffer (
155+ buffer + pos,
156+ tls_ext_len,
157+ (uint16_t ) tls_ext_len_len,
158+ (uint16_t ) TLS_EXT_LEN_FIELD_ID);
112159 return pos;
113160 }
114161
@@ -133,6 +180,22 @@ struct RecordExtTLS : public RecordExt {
133180 for (int i = 0 ; i < 16 ; i++) {
134181 out << std::hex << std::setw (2 ) << std::setfill (' 0' ) << (unsigned ) ja3_hash_bin[i];
135182 }
183+ out << " ,tlsexttype=(" ;
184+ for (int i = 0 ; i < tls_ext_type_len; i++) {
185+ out << std::dec << (uint16_t ) tls_ext_type[i];
186+ if (i != tls_ext_type_len - 1 ) {
187+ out << " ," ;
188+ }
189+ }
190+ out << " ),tlsextlen=(" ;
191+ for (int i = 0 ; i < tls_ext_len_len; i++) {
192+ out << std::dec << (uint16_t ) tls_ext_len[i];
193+ if (i != tls_ext_len_len - 1 ) {
194+ out << " ," ;
195+ }
196+ }
197+ out << " )" ;
198+
136199 return out.str ();
137200 }
138201};
0 commit comments