Coverage Report

Created: 2026-04-20 06:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ndpi/src/lib/protocols/tls.c
Line
Count
Source
1
/*
2
 * tls.c - TLS/TLS/DTLS dissector
3
 *
4
 * Copyright (C) 2016-26 - ntop.org
5
 *
6
 * nDPI is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU Lesser General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * nDPI is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public License
17
 * along with nDPI.  If not, see <http://www.gnu.org/licenses/>.
18
 *
19
 */
20
21
#include "ndpi_protocol_ids.h"
22
23
#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_TLS
24
25
#include "ndpi_api.h"
26
#include "ndpi_md5.h"
27
#include "ndpi_sha1.h"
28
#include "ndpi_sha256.h"
29
#include "ndpi_encryption.h"
30
#include "ndpi_private.h"
31
32
//#define JA4R_DECIMAL 1
33
34
static void ndpi_search_tls_wrapper(struct ndpi_detection_module_struct *ndpi_struct,
35
            struct ndpi_flow_struct *flow);
36
37
// #define DEBUG_TLS_MEMORY       1
38
// #define DEBUG_TLS              1
39
// #define DEBUG_TLS_BLOCKS       1
40
// #define DEBUG_CERTIFICATE_HASH
41
42
// #define DEBUG_HEURISTIC
43
44
// #define DEBUG_JA 1
45
46
/* #define DEBUG_FINGERPRINT      1 */
47
/* #define DEBUG_ENCRYPTED_SNI    1 */
48
49
/* **************************************** */
50
51
/*
52
  JA3
53
  https://engineering.salesforce.com/tls-fingerprinting-with-ja3-and-ja3s-247362855967
54
55
  JA4
56
  https://github.com/FoxIO-LLC/ja4/blob/main/technical_details/JA4.md
57
*/
58
59
10.2M
#define JA_STR_LEN        1024
60
61
union ndpi_ja_info {
62
  ndpi_tls_client_info client;
63
  ndpi_tls_server_info server;
64
};
65
66
/*
67
  NOTE
68
69
  How to view the certificate fingerprint
70
  1. Using wireshark save the certificate on certificate.bin file as explained
71
  in https://security.stackexchange.com/questions/123851/how-can-i-extract-the-certificate-from-this-pcap-file
72
73
  2. openssl x509 -inform der -in certificate.bin -text > certificate.der
74
  3. openssl x509 -noout -fingerprint -sha1 -inform pem -in certificate.der
75
  SHA1 Fingerprint=15:9A:76....
76
77
  $ shasum -a 1 www.grc.com.bin
78
  159a76.....
79
*/
80
81
#define NDPI_MAX_TLS_REQUEST_SIZE 10000
82
7.40k
#define TLS_THRESHOLD             34387200 /* Threshold for certificate validity                                */
83
36.8k
#define TLS_LIMIT_DATE            1598918400 /* From 01/09/2020 TLS certificates lifespan is limited to 13 months */
84
85
86
static void ndpi_int_tls_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
87
          struct ndpi_flow_struct *flow);
88
89
/* **************************************** */
90
91
1.67k
static bool str_contains_digit(char *str) {
92
1.67k
  u_int i = 0;
93
94
8.03k
  for(i=0; (str[i] != '.') && (str[i] != '\0'); i++) {
95
7.52k
    if(isdigit(str[i]))
96
1.17k
      return(true);
97
7.52k
  }
98
99
505
  return(false);
100
1.67k
}
101
102
/* **************************************** */
103
104
/* TODO: rename */
105
static int keep_extra_dissection_tcp(struct ndpi_detection_module_struct *ndpi_struct,
106
228k
                                     struct ndpi_flow_struct *flow) {
107
228k
  if(ndpi_struct->cfg.tls_max_num_blocks_to_analyze > 0)
108
0
    return(1); /* Process as much TLS blocks as the max packet number */
109
110
  /* Common path: found handshake on both directions */
111
228k
  if(
112
228k
     (flow->tls_quic.certificate_processed == 1 && flow->protos.tls_quic.client_hello_processed)
113
114
     /* Application Data on both directions: handshake already ended (did we miss it?) */
115
227k
     || (flow->l4.tcp.tls.app_data_seen[0] == 1 && flow->l4.tcp.tls.app_data_seen[1] == 1)
116
117
     /* Handshake on one direction and Application Data on the other */
118
226k
     || ((flow->protos.tls_quic.client_hello_processed && flow->l4.tcp.tls.app_data_seen[!flow->protos.tls_quic.ch_direction] == 1) ||
119
226k
   (flow->protos.tls_quic.server_hello_processed && flow->l4.tcp.tls.app_data_seen[flow->protos.tls_quic.ch_direction] == 1))
120
228k
     ) {
121
2.17k
    return 0;
122
2.17k
  }
123
124
  /* Non-warning alert */
125
226k
  if(flow->tls_quic.alert)
126
215
    return 0;
127
128
  /* Are we interested only in the (sub)-classification? */
129
130
225k
  if(/* Subclassification */
131
225k
     flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN &&
132
     /* No metadata from SH or certificate */
133
2.78k
     !ndpi_struct->cfg.tls_alpn_negotiated_enabled &&
134
2.64k
     !ndpi_struct->cfg.tls_cipher_enabled &&
135
2.64k
     !ndpi_struct->cfg.tls_sha1_fingerprint_enabled &&
136
2.64k
     !ndpi_struct->cfg.tls_cert_server_names_enabled &&
137
2.64k
     !ndpi_struct->cfg.tls_cert_validity_enabled &&
138
2.64k
     !ndpi_struct->cfg.tls_cert_issuer_enabled &&
139
2.64k
     !ndpi_struct->cfg.tls_cert_subject_enabled &&
140
2.64k
     !ndpi_struct->cfg.tls_browser_enabled &&
141
2.64k
     !ndpi_struct->cfg.tls_ja3s_fingerprint_enabled &&
142
     /* No flow risks from SH or certificate: we should have disabled all
143
        metadata needed for flow risks, so we should not need to explicitly
144
        check them */
145
     /* Ookla aggressiveness has no impact here because it is evaluated only
146
        without sub-classification */
147
     /* TLS heuristics */
148
2.64k
     (ndpi_struct->cfg.tls_heuristics == 0 || is_flow_addr_informative(flow))) {
149
2.64k
    return 0;
150
2.64k
  }
151
152
223k
  return 1;
153
225k
}
154
155
/* **************************************** */
156
157
/* Heuristic to detect proxied/obfuscated TLS flows, based on
158
   https://www.usenix.org/conference/usenixsecurity24/presentation/xue-fingerprinting.
159
   Main differences between the paper and our implementation:
160
    * only Mahalanobis Distance, no Chi-squared Test
161
    * instead of 3-grams, we use 4-grams, always starting from the Client -> Server direction
162
    * consecutive packets in the same direction always belong to the same burst/flight
163
164
   Core idea:
165
    * the packets/bytes distribution of a TLS handshake is quite unique
166
    * this fingerprint is still detectable if the handshake is
167
      encrypted/proxied/obfuscated
168
*/
169
170
struct tls_obfuscated_heuristic_set {
171
  u_int8_t stage;
172
  u_int32_t bytes[4];
173
  u_int32_t pkts[4];
174
};
175
176
struct tls_obfuscated_heuristic_state {
177
  u_int8_t num_pkts;
178
179
  /* Burst/flight: consecutive packets in the same direction.
180
   * Set: packet/bytes distribution of 4 consecutive bursts (always starting from C->S),
181
          i.e. a 4-grams (using the paper terminology)
182
   * We have up tp 2 sets contemporarily active.
183
   * At the first pkt of a new C->S flight, we close the oldest set and open a new one */
184
  struct tls_obfuscated_heuristic_set sets[2];
185
};
186
187
static int check_set(struct ndpi_detection_module_struct* ndpi_struct,
188
                     struct tls_obfuscated_heuristic_set *set)
189
35.7k
{
190
#ifdef NDPI_ENABLE_DEBUG_MESSAGES
191
  struct ndpi_packet_struct* packet = &ndpi_struct->packet;
192
#endif
193
194
  /* Model: TLS 1.2; Firefox; No session resumption/0rtt */
195
35.7k
  const float i_s_tls_12[4 * 4] = { 0.000292421113167604, 4.43677617831228E-07, -5.69966093492813E-05, -2.18124698406311E-06,
196
35.7k
                                    4.43677617831228E-07, 5.98954952745268E-07, -3.59798436724817E-07, 5.71638172955893E-07,
197
35.7k
                                    -5.69966093492813E-05, -3.59798436724817E-07, 0.00076893788148309, 2.22278496185964E-05,
198
35.7k
                                    -2.18124698406311E-06, 5.71638172955893E-07, 2.22278496185964E-05, 5.72770077086287E-05 };
199
35.7k
  const float average_tls_12[4] = { 212.883690341977, 4514.71195039459, 107.770762871101, 307.580232995115 };
200
35.7k
  const float distance_tls_12 = 3.5;
201
202
  /* Model: TLS 1.3; Firefox; No session resumption/0rtt; no PQ; ECH(-grease) enabled */
203
35.7k
  const float i_s_tls_13[4 * 4] = { 3.08030337925007E-05, 1.16179172096944E-07, 1.05356744968627E-07, 3.8862884355278E-08,
204
35.7k
                                    1.16179172096944E-07, 6.93179117519316E-07, 2.77413220880937E-08, -3.63723200682445E-09,
205
35.7k
                                    1.05356744968627E-07, 2.77413220880937E-08, 1.0260950589675E-06, -1.08769813590053E-08,
206
35.7k
                                    3.88628843552779E-08, -3.63723200682445E-09, -1.08769813590053E-08, 8.63307792288604E-08 };
207
35.7k
  const float average_tls_13[4] = { 640.657378447541, 4649.30338356554, 448.408302530566, 1094.2013079329};
208
35.7k
  const float distance_tls_13 = 3.0;
209
210
  /* Model: TLS 1.2/1.3; Chrome; No session resumption/0rtt; PQ; ECH(-grease) enabled */
211
35.7k
  const float i_s_chrome[4 * 4] = { 6.72374390966642E-06, -2.32109583941723E-08, 6.67140014394388E-08, 1.2526322628285E-08,
212
35.7k
                                    -2.32109583941723E-08, 5.64668947932086E-07, 4.58963631972597E-08, 6.41254684791958E-09,
213
35.7k
                                    6.67140014394388E-08, 4.58963631972597E-08, 6.04057768431344E-07, -9.1507432597718E-10,
214
35.7k
                                    1.2526322628285E-08, 6.41254684791958E-09, -9.1507432597718E-10, 1.01184796635481E-07 };
215
35.7k
  const float average_chrome[4] = { 1850.43045387994, 4903.07735480722, 785.25280624695, 1051.22303562714 };
216
35.7k
  const float distance_chrome = 3.0;
217
218
  /* TODO: * ECH/PQ are still under development/deployment -> re-evaluate these models
219
           * Session resumptions/0rtt
220
     * Non-web traffic */
221
222
  /* This is the only logic about pkts distributions.
223
     ClientHello shoudn't be splitted in too many fragments: usually 1; 2 with PQ */
224
35.7k
  if(set->pkts[0] > 3) {
225
3.90k
    NDPI_LOG_DBG2(ndpi_struct, "TLS-Obf-Heur: too many pkts in the first burst %d\n", set->pkts[0]);
226
3.90k
    return 0;
227
3.90k
  }
228
229
31.8k
  if(ndpi_mahalanobis_distance(set->bytes, 4, average_chrome, i_s_chrome) < distance_chrome ||
230
     /* To avoid false positives: we didn't find TLS 1.3 CH smaller than 517 */
231
30.3k
     (set->bytes[0] >= 517 && ndpi_mahalanobis_distance(set->bytes, 4, average_tls_13, i_s_tls_13) < distance_tls_13) ||
232
29.6k
     ndpi_mahalanobis_distance(set->bytes, 4, average_tls_12, i_s_tls_12) < distance_tls_12) {
233
234
3.06k
    NDPI_LOG_DBG(ndpi_struct, "TLS-Obf-Heur: md %f %f %f [%d/%d/%d/%d %d/%d/%d/%d] TCP? %d\n",
235
3.06k
                 ndpi_mahalanobis_distance(set->bytes, 4, average_tls_12, i_s_tls_12),
236
3.06k
                 ndpi_mahalanobis_distance(set->bytes, 4, average_tls_13, i_s_tls_13),
237
3.06k
                 ndpi_mahalanobis_distance(set->bytes, 4, average_chrome, i_s_chrome),
238
3.06k
                 set->pkts[0], set->pkts[1], set->pkts[2], set->pkts[3],
239
3.06k
                 set->bytes[0], set->bytes[1], set->bytes[2], set->bytes[3],
240
3.06k
                 !!packet->tcp);
241
3.06k
    return 1;
242
3.06k
  }
243
244
28.8k
  return 0;
245
31.8k
}
246
247
/* **************************************** */
248
249
static int tls_obfuscated_heur_search(struct ndpi_detection_module_struct* ndpi_struct,
250
1.97M
                                      struct ndpi_flow_struct* flow) {
251
1.97M
  struct ndpi_packet_struct* packet = &ndpi_struct->packet;
252
1.97M
  struct tls_obfuscated_heuristic_state *state = flow->tls_quic.obfuscated_heur_state;
253
1.97M
  struct tls_obfuscated_heuristic_set *set;
254
1.97M
  int i, j;
255
1.97M
  int is_tls_in_tls_heur = 0;
256
1.97M
  int byte_overhead;
257
258
  /* Stages:
259
     0: Unused/Start
260
     1: C->S : burst 1
261
     2: S->C : burst 2
262
     3: C->S : burst 3
263
     4: S->C : burst 4
264
     5: C->S : End
265
  */
266
267
1.97M
  if(!state)
268
268
    return 1; /* Exclude */
269
270
1.97M
  if(packet->payload_packet_len == 0)
271
66.6k
    return 0; /* Continue */
272
273
1.91M
  NDPI_LOG_DBG2(ndpi_struct, "TLS-Obf-Heur: num_pkts %d\n", state->num_pkts);
274
275
1.91M
  if(flow->extra_packets_func &&
276
86.1k
     (flow->detected_protocol_stack[0] == NDPI_PROTOCOL_TLS ||
277
77.2k
      flow->detected_protocol_stack[1] == NDPI_PROTOCOL_TLS)) /* TLS-in-TLS heuristic */
278
81.0k
    is_tls_in_tls_heur = 1;
279
280
  /* We try to keep into account the overhead (header/padding/mac/iv/nonce) of the
281
     external layers (i.e. above the TLS hanshake we are trying to detect) */
282
1.91M
  if(is_tls_in_tls_heur == 1) {
283
    /* According to https://datatracker.ietf.org/doc/html/draft-mattsson-uta-tls-overhead-01
284
       the average packet overhead for TLS is 29 bytes.
285
       TODO: this draft is OLD and about TLS 1.2
286
       Looking at real traffic, we found that we can have TLS packets 24 bytes long
287
    */
288
81.0k
    byte_overhead = 24;
289
1.83M
  } else {
290
    /* The paper says that the overhead is usually quite small
291
       ["typically ranging between 20 to 60 bytes"], without any citations.
292
       From the tests, it seams that we can ignore it */
293
1.83M
    byte_overhead = 0;
294
1.83M
  }
295
296
1.91M
  if(packet->payload_packet_len < byte_overhead) {
297
429
    NDPI_LOG_DBG2(ndpi_struct, "TLS-Obf-Heur: packet too small. Stop.\n");
298
429
    return 1; /* Exclude */
299
429
  }
300
301
1.91M
  if(is_tls_in_tls_heur == 1) {
302
    /* We usually stop processing TLS handshake (and switch to this extra dissection
303
       data path) after the FIRST Change-Cipher message. However, for this
304
       heuristic, we need to ignore all packets before a Change-Cipher is sent in the
305
       same direction */
306
80.6k
    if(current_pkt_from_client_to_server(ndpi_struct, flow) &&
307
32.7k
       flow->tls_quic.change_cipher_from_client == 0) {
308
431
      if(packet->payload[0] == 0x14) {
309
29
        NDPI_LOG_DBG2(ndpi_struct, "TLS-Obf-Heur: Change-Cipher from client\n");
310
29
        flow->tls_quic.change_cipher_from_client = 1;
311
29
      }
312
431
      NDPI_LOG_DBG2(ndpi_struct, "TLS-Obf-Heur: skip\n");
313
431
      return 0; /* Continue */
314
431
    }
315
80.2k
    if(current_pkt_from_server_to_client(ndpi_struct, flow) &&
316
47.8k
       flow->tls_quic.change_cipher_from_server == 0) {
317
10.5k
      if(packet->payload[0] == 0x14) {
318
2.32k
        flow->tls_quic.change_cipher_from_server = 1;
319
2.32k
        NDPI_LOG_DBG2(ndpi_struct, "TLS-Obf-Heur: Change-Cipher from server\n");
320
2.32k
      }
321
10.5k
      NDPI_LOG_DBG2(ndpi_struct, "TLS-Obf-Heur: skip\n");
322
10.5k
      return 0; /* Continue */
323
10.5k
    }
324
80.2k
  }
325
326
1.89M
  if(state->num_pkts++ > ndpi_struct->cfg.tls_heuristics_max_packets) {
327
1.44k
    NDPI_LOG_DBG2(ndpi_struct, "TLS-Obf-Heur: too many pkts. Stop\n");
328
1.44k
    return 1; /* Exclude */
329
1.44k
  }
330
331
  /* Update active sets */
332
5.55M
  for(i = 0; i < 2; i ++) {
333
3.72M
    set = &state->sets[i];
334
3.72M
    switch(set->stage) {
335
2.59M
    case 0:
336
      /* This happen only at the beginning of the heuristic: after the first pkt
337
         of the third (absolute) burst, we always have both sets used */
338
2.59M
      if(i == 0 || state->sets[0].stage == 3) {
339
1.02M
        if(current_pkt_from_client_to_server(ndpi_struct, flow)) {
340
952k
          NDPI_LOG_DBG2(ndpi_struct, "TLS-Obf-Heur: open set %d\n", i);
341
952k
          set->stage = 1;
342
952k
          break;
343
952k
  } else {
344
          /* First packet should be always from client.
345
       This shortcut makes detection harder if, before the obfuscated TLS hanshake
346
       there is random traffic */
347
67.6k
          return 1; /* Exclude */
348
67.6k
  }
349
1.02M
      }
350
1.57M
      continue;
351
1.57M
    case 1:
352
711k
      if(current_pkt_from_server_to_client(ndpi_struct, flow))
353
193k
        set->stage = 2;
354
711k
      break;
355
220k
    case 2:
356
220k
      if(current_pkt_from_client_to_server(ndpi_struct, flow))
357
89.4k
        set->stage = 3;
358
220k
      break;
359
120k
    case 3:
360
120k
      if(current_pkt_from_server_to_client(ndpi_struct, flow))
361
53.0k
        set->stage = 4;
362
120k
      break;
363
83.8k
    case 4:
364
83.8k
      if(current_pkt_from_client_to_server(ndpi_struct, flow))
365
35.7k
        set->stage = 5;
366
83.8k
      break;
367
    /* We cant have 5 here */
368
3.72M
    }
369
370
2.08M
    if(set->stage != 5) {
371
2.05M
      set->bytes[set->stage - 1] += (packet->payload_packet_len - byte_overhead);
372
2.05M
      set->pkts[set->stage - 1] += 1;
373
2.05M
    }
374
375
2.08M
    NDPI_LOG_DBG2(ndpi_struct, "TLS-Obf-Heur: set %d stage %d bytes %d/%d/%d/%d pkts %d/%d/%d/%d\n",
376
2.08M
                  i, set->stage,
377
2.08M
                  set->bytes[0], set->bytes[1], set->bytes[2], set->bytes[3],
378
2.08M
                  set->pkts[0], set->pkts[1], set->pkts[2], set->pkts[3]);
379
380
    /* Check completed set */
381
2.08M
    if(set->stage == 5) {
382
35.7k
      NDPI_LOG_DBG2(ndpi_struct, "TLS-Obf-Heur: set %d completed\n", i);
383
35.7k
      if(check_set(ndpi_struct, set)) {
384
        /* Heuristic match */
385
386
3.06k
        return 2; /* Found */
387
32.7k
      } else {
388
        /* Close this set and open a new one... */
389
32.7k
        set->stage = 1;
390
32.7k
        set->bytes[0] = packet->payload_packet_len - byte_overhead;
391
32.7k
        set->pkts[0] = 1;
392
130k
  for(j = 1; j < 4; j++) {
393
98.1k
          set->bytes[j] = 0;
394
98.1k
          set->pkts[j] = 0;
395
98.1k
        }
396
32.7k
        NDPI_LOG_DBG2(ndpi_struct, "TLS-Obf-Heur: set %d closed and reused\n", i);
397
32.7k
      }
398
35.7k
    }
399
2.08M
  }
400
401
1.82M
  return 0; /* Continue */
402
1.89M
}
403
404
/* **************************************** */
405
406
static int tls_obfuscated_heur_search_again(struct ndpi_detection_module_struct* ndpi_struct,
407
1.97M
              struct ndpi_flow_struct* flow) {
408
1.97M
  int rc;
409
410
1.97M
  NDPI_LOG_DBG2(ndpi_struct, "TLS-Obf-Heur: extra dissection\n");
411
412
1.97M
  rc = tls_obfuscated_heur_search(ndpi_struct, flow);
413
1.97M
  if(rc == 0)
414
1.90M
    return 1; /* Keep working */
415
72.8k
  if(rc == 2) {
416
3.06k
    NDPI_LOG_DBG(ndpi_struct, "TLS-Obf-Heur: found!\n");
417
418
    /* Right now, if an heuritic matches, we set the classification/risk.
419
       TODO: avoid false positives!
420
       Some ideas:
421
        * try to identify the servers: we wait for multiple sessions to the same server,
422
          before to start marking the flows to that address
423
        * consider the number of burst after TLS handshake (see Fig 8 paper) */
424
425
3.06k
    if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) {
426
2.34k
      ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TLS, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI_AGGRESSIVE);
427
2.34k
      ndpi_set_risk(ndpi_struct, flow, NDPI_OBFUSCATED_TRAFFIC, "Obfuscated TLS traffic");
428
2.34k
    } else {
429
723
      flow->confidence = NDPI_CONFIDENCE_DPI_AGGRESSIVE; /* Update the value */
430
723
      if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_TLS ||
431
664
         flow->detected_protocol_stack[1] == NDPI_PROTOCOL_TLS)
432
713
        ndpi_set_risk(ndpi_struct, flow, NDPI_OBFUSCATED_TRAFFIC, "Obfuscated TLS-in-TLS traffic");
433
10
      else
434
10
        ndpi_set_risk(ndpi_struct, flow, NDPI_OBFUSCATED_TRAFFIC, "Obfuscated TLS-in-HTTP-WebSocket traffic");
435
723
    }
436
437
3.06k
    ndpi_master_app_protocol proto;
438
3.06k
    proto.master_protocol = ndpi_get_master_proto(ndpi_struct, flow);
439
3.06k
    proto.app_protocol = NDPI_PROTOCOL_UNKNOWN;
440
3.06k
    flow->category = get_proto_category(ndpi_struct, proto);
441
3.06k
    flow->breed = get_proto_breed(ndpi_struct, proto);
442
3.06k
  }
443
72.8k
  NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); /* Not necessary in extra-dissection data path,
444
                                                but we need it with the plain heuristic */
445
72.8k
  return 0; /* Stop */
446
1.97M
}
447
448
/* **************************************** */
449
450
void switch_extra_dissection_to_tls_obfuscated_heur(struct ndpi_detection_module_struct* ndpi_struct,
451
                                                    struct ndpi_flow_struct* flow)
452
11.7k
{
453
11.7k
  NDPI_LOG_DBG(ndpi_struct, "Switching to TLS Obfuscated heuristic\n");
454
455
11.7k
  if(flow->tls_quic.obfuscated_heur_state == NULL)
456
11.7k
    flow->tls_quic.obfuscated_heur_state = ndpi_calloc(1, sizeof(struct tls_obfuscated_heuristic_state));
457
19
  else /* If state has been already allocated (because of NDPI_HEURISTICS_TLS_OBFUSCATED_PLAIN) reset it */
458
19
    memset(flow->tls_quic.obfuscated_heur_state, '\0', sizeof(struct tls_obfuscated_heuristic_state));
459
460
  /* "* 2" to take into account ACKs. The "real" check is performend against
461
     "tls_heuristics_max_packets" in tls_obfuscated_heur_search, as expected */
462
11.7k
  flow->max_extra_packets_to_check = ndpi_struct->cfg.tls_heuristics_max_packets * 2;
463
11.7k
  flow->extra_packets_func = tls_obfuscated_heur_search_again;
464
11.7k
}
465
466
/* **************************************** */
467
468
static int ndpi_search_tls_memory(const u_int8_t *payload,
469
          u_int16_t payload_len,
470
          u_int32_t seq,
471
4.30M
          message_t *message) {
472
4.30M
  u_int avail_bytes;
473
474
#ifdef DEBUG_TLS_MEMORY
475
  printf("[TLS Mem] Handling TLS flow [payload_len: %u][buffer_len: %u]\n",
476
   payload_len,
477
   message->buffer_len);
478
#endif
479
480
4.30M
  if(message->buffer == NULL) {
481
    /* Allocate buffer */
482
3.85M
    message->buffer_len = 2048, message->buffer_used = 0;
483
3.85M
    message->buffer = (u_int8_t*)ndpi_malloc(message->buffer_len);
484
485
3.85M
    if(message->buffer == NULL)
486
18.0k
      return -1;
487
488
#ifdef DEBUG_TLS_MEMORY
489
    printf("[TLS Mem] Allocating %u buffer\n", message->buffer_len);
490
#endif
491
3.85M
  }
492
493
4.28M
  avail_bytes = message->buffer_len - message->buffer_used;
494
495
4.28M
  if(avail_bytes < payload_len) {
496
41.0k
    u_int new_len = message->buffer_len + payload_len - avail_bytes + 1;
497
41.0k
    void *newbuf  = ndpi_realloc(message->buffer, new_len);
498
41.0k
    if(!newbuf) return -1;
499
500
#ifdef DEBUG_TLS_MEMORY
501
    printf("[TLS Mem] Enlarging %u -> %u buffer\n", message->buffer_len, new_len);
502
#endif
503
504
40.3k
    message->buffer = (u_int8_t*)newbuf;
505
40.3k
    message->buffer_len = new_len;
506
40.3k
    avail_bytes = message->buffer_len - message->buffer_used;
507
40.3k
  }
508
509
4.28M
  if(payload_len > 0 && avail_bytes >= payload_len) {
510
4.28M
    u_int8_t ok = 0;
511
512
4.28M
    if(message->next_seq != 0) {
513
451k
      if(seq == message->next_seq)
514
84.3k
  ok = 1;
515
451k
    } else
516
3.83M
      ok = 1;
517
518
4.28M
    if(ok) {
519
3.91M
      memcpy(&message->buffer[message->buffer_used],
520
3.91M
       payload, payload_len);
521
522
3.91M
      message->buffer_used += payload_len;
523
#ifdef DEBUG_TLS_MEMORY
524
      printf("[TLS Mem] Copied data to buffer [%u/%u bytes][tcp_seq: %u][next: %u]\n",
525
       message->buffer_used, message->buffer_len,
526
       seq,
527
       seq + payload_len);
528
#endif
529
530
3.91M
      message->next_seq = seq + payload_len;
531
3.91M
    } else {
532
#ifdef DEBUG_TLS_MEMORY
533
      printf("[TLS Mem] Skipping packet [%u bytes][tcp_seq: %u][expected next: %u]\n",
534
       message->buffer_len,
535
       seq,
536
       message->next_seq);
537
#endif
538
366k
    }
539
4.28M
  }
540
4.28M
  return 0;
541
4.28M
}
542
543
/* **************************************** */
544
545
139k
static void cleanupServerName(char *buffer, u_int buffer_len) {
546
139k
  u_int i;
547
548
  /* Now all lowecase */
549
2.56M
  for(i=0; i<buffer_len; i++)
550
2.42M
    buffer[i] = tolower(buffer[i]);
551
139k
}
552
553
/* **************************************** */
554
555
/*
556
  Return code
557
  -1: error (buffer too short)
558
  0: OK but buffer is not human readeable (so something went wrong)
559
  1: OK
560
*/
561
static int extractRDNSequence(struct ndpi_packet_struct *packet,
562
            u_int offset, char *buffer, u_int buffer_len,
563
            char *rdnSeqBuf, u_int *rdnSeqBuf_offset,
564
            u_int rdnSeqBuf_len,
565
265k
            const char *label) {
566
265k
  u_int8_t str_len, is_printable = 1;
567
265k
  char *str;
568
265k
  u_int len;
569
570
265k
  if(*rdnSeqBuf_offset >= rdnSeqBuf_len) {
571
#ifdef DEBUG_TLS
572
    printf("[TLS] %s() [buffer capacity reached][%u]\n",
573
           __FUNCTION__, rdnSeqBuf_len);
574
#endif
575
0
    return -1;
576
0
  }
577
265k
  if((offset+4) >= packet->payload_packet_len)
578
134
    return(-1);
579
580
265k
  str_len = packet->payload[offset+4];
581
582
  // packet is truncated... further inspection is not needed
583
265k
  if((offset+4+str_len) >= packet->payload_packet_len)
584
2.52k
    return(-1);
585
586
262k
  str = (char*)&packet->payload[offset+5];
587
588
262k
  len = (u_int)ndpi_min(str_len, buffer_len-1);
589
262k
  strncpy(buffer, str, len);
590
262k
  buffer[len] = '\0';
591
592
  // check string is printable
593
262k
  is_printable = ndpi_normalize_printable_string(buffer, len);
594
595
262k
  if(is_printable) {
596
199k
    int rc = ndpi_snprintf(&rdnSeqBuf[*rdnSeqBuf_offset],
597
199k
         rdnSeqBuf_len-(*rdnSeqBuf_offset),
598
199k
         "%s%s=%s", (*rdnSeqBuf_offset > 0) ? ", " : "",
599
199k
         label, buffer);
600
601
199k
    if(rc > 0 && ((u_int)rc > rdnSeqBuf_len-(*rdnSeqBuf_offset)))
602
0
      return -1; /* Truncated; not enough buffer */
603
199k
    if(rc > 0)
604
195k
      (*rdnSeqBuf_offset) += rc;
605
199k
  }
606
607
262k
  return(is_printable);
608
262k
}
609
610
/* **************************************** */
611
612
static u_int64_t make_tls_cert_key(struct ndpi_packet_struct *packet, int is_from_client)
613
160k
{
614
160k
  u_int64_t key;
615
616
  /* Server ip/port */
617
160k
  if(packet->iphv6 == NULL) {
618
150k
    if(packet->tcp) {
619
87.5k
      if(is_from_client)
620
52.7k
        key = ((u_int64_t)packet->iph->daddr << 32) | packet->tcp->dest;
621
34.7k
      else
622
34.7k
        key = ((u_int64_t)packet->iph->saddr << 32) | packet->tcp->source;
623
87.5k
    } else {
624
62.6k
      if(is_from_client)
625
46.8k
        key = ((u_int64_t)packet->iph->daddr << 32) | packet->udp->dest;
626
15.7k
      else
627
15.7k
        key = ((u_int64_t)packet->iph->saddr << 32) | packet->udp->source;
628
62.6k
    }
629
150k
  } else {
630
9.88k
    if(packet->tcp) {
631
8.99k
      if(is_from_client)
632
3.50k
        key = (ndpi_quick_hash64((const char *)&packet->iphv6->ip6_dst, 16) << 16) | packet->tcp->dest;
633
5.48k
      else
634
5.48k
        key = (ndpi_quick_hash64((const char *)&packet->iphv6->ip6_src, 16) << 16) | packet->tcp->source;
635
8.99k
    } else {
636
894
      if(is_from_client)
637
644
        key = (ndpi_quick_hash64((const char *)&packet->iphv6->ip6_dst, 16) << 16) | packet->udp->dest;
638
250
      else
639
250
        key = (ndpi_quick_hash64((const char *)&packet->iphv6->ip6_src, 16) << 16) | packet->udp->source;
640
894
    }
641
9.88k
  }
642
643
160k
  return key;
644
160k
}
645
646
/* **************************************** */
647
648
static void checkTLSSubprotocol(struct ndpi_detection_module_struct *ndpi_struct,
649
        struct ndpi_flow_struct *flow,
650
247k
        int is_from_client) {
651
247k
  struct ndpi_packet_struct *packet = &ndpi_struct->packet;
652
653
247k
  if(ndpi_struct->cfg.tls_subclassification_enabled &&
654
247k
     flow->detected_protocol_stack[1] == NDPI_PROTOCOL_UNKNOWN) {
655
    /* Subprotocol not yet set */
656
657
159k
    if(ndpi_struct->tls_cert_cache) {
658
159k
      u_int16_t cached_proto;
659
159k
      u_int64_t key;
660
661
159k
      key = make_tls_cert_key(packet, is_from_client);
662
663
159k
      if(ndpi_lru_find_cache(ndpi_struct->tls_cert_cache, key,
664
159k
           &cached_proto, 0 /* Don't remove it as it can be used for other connections */,
665
159k
           ndpi_get_current_time(flow))) {
666
1.76k
        ndpi_master_app_protocol proto;
667
668
1.76k
  ndpi_set_detected_protocol(ndpi_struct, flow, cached_proto, ndpi_get_master_proto(ndpi_struct, flow), NDPI_CONFIDENCE_DPI_CACHE);
669
1.76k
  proto.master_protocol = ndpi_get_master_proto(ndpi_struct, flow);
670
1.76k
  proto.app_protocol = cached_proto;
671
1.76k
  flow->category = get_proto_category(ndpi_struct, proto);
672
1.76k
  flow->breed = get_proto_breed(ndpi_struct, proto);
673
1.76k
  ndpi_check_subprotocol_risk(ndpi_struct, flow, cached_proto);
674
1.76k
  ndpi_unset_risk(ndpi_struct, flow, NDPI_NUMERIC_IP_HOST);
675
1.76k
      }
676
159k
    }
677
159k
  }
678
247k
}
679
680
/* **************************************** */
681
682
/* See https://blog.catchpoint.com/2017/05/12/dissecting-tls-using-wireshark/ */
683
void processCertificateElements(struct ndpi_detection_module_struct *ndpi_struct,
684
        struct ndpi_flow_struct *flow,
685
23.1k
        u_int16_t p_offset, u_int16_t certificate_len) {
686
23.1k
  struct ndpi_packet_struct *packet = &ndpi_struct->packet;
687
23.1k
  u_int16_t num_found = 0;
688
23.1k
  int32_t i;
689
23.1k
  char buffer[64] = { '\0' }, rdnSeqBuf[2048];
690
23.1k
  u_int rdn_len = 0;
691
692
23.1k
  rdnSeqBuf[0] = '\0';
693
694
#ifdef DEBUG_TLS
695
  printf("[TLS] %s() [offset: %u][certificate_len: %u]\n", __FUNCTION__, p_offset, certificate_len);
696
#endif
697
698
  /* Check after handshake protocol header (5 bytes) and message header (4 bytes) */
699
23.0M
  for(i = p_offset; i < certificate_len - 2; i++) {
700
    /*
701
      See https://www.ibm.com/support/knowledgecenter/SSFKSJ_7.5.0/com.ibm.mq.sec.doc/q009860_.htm
702
      for X.509 certificate labels
703
    */
704
23.0M
    if((packet->payload[i] == 0x55) && (packet->payload[i+1] == 0x04) && (packet->payload[i+2] == 0x03)) {
705
      /* Common Name */
706
47.8k
      int rc = extractRDNSequence(packet, i, buffer, sizeof(buffer), rdnSeqBuf, &rdn_len, sizeof(rdnSeqBuf), "CN");
707
47.8k
      if(rc == -1) break;
708
709
#ifdef DEBUG_TLS
710
      printf("[TLS] %s() [%s][%s: %s]\n", __FUNCTION__, (num_found == 0) ? "Subject" : "Issuer", "Common Name", buffer);
711
#endif
712
23.0M
    } else if((packet->payload[i] == 0x55) && (packet->payload[i+1] == 0x04) && (packet->payload[i+2] == 0x06)) {
713
      /* Country */
714
42.2k
      int rc = extractRDNSequence(packet, i, buffer, sizeof(buffer), rdnSeqBuf, &rdn_len, sizeof(rdnSeqBuf), "C");
715
42.2k
      if(rc == -1) break;
716
717
#ifdef DEBUG_TLS
718
      printf("[TLS] %s() [%s][%s: %s]\n", __FUNCTION__, (num_found == 0) ? "Subject" : "Issuer", "Country", buffer);
719
#endif
720
22.9M
    } else if((packet->payload[i] == 0x55) && (packet->payload[i+1] == 0x04) && (packet->payload[i+2] == 0x07)) {
721
      /* Locality */
722
40.6k
      int rc = extractRDNSequence(packet, i, buffer, sizeof(buffer), rdnSeqBuf, &rdn_len, sizeof(rdnSeqBuf), "L");
723
40.6k
      if(rc == -1) break;
724
725
#ifdef DEBUG_TLS
726
      printf("[TLS] %s() [%s][%s: %s]\n", __FUNCTION__, (num_found == 0) ? "Subject" : "Issuer", "Locality", buffer);
727
#endif
728
22.9M
    } else if((packet->payload[i] == 0x55) && (packet->payload[i+1] == 0x04) && (packet->payload[i+2] == 0x08)) {
729
      /* State or Province */
730
70.5k
      int rc = extractRDNSequence(packet, i, buffer, sizeof(buffer), rdnSeqBuf, &rdn_len, sizeof(rdnSeqBuf), "ST");
731
70.5k
      if(rc == -1) break;
732
733
#ifdef DEBUG_TLS
734
      printf("[TLS] %s() [%s][%s: %s]\n", __FUNCTION__, (num_found == 0) ? "Subject" : "Issuer", "State or Province", buffer);
735
#endif
736
22.8M
    } else if((packet->payload[i] == 0x55) && (packet->payload[i+1] == 0x04) && (packet->payload[i+2] == 0x0a)) {
737
      /* Organization Name */
738
39.7k
      int rc = extractRDNSequence(packet, i, buffer, sizeof(buffer), rdnSeqBuf, &rdn_len, sizeof(rdnSeqBuf), "O");
739
39.7k
      if(rc == -1) break;
740
741
#ifdef DEBUG_TLS
742
      printf("[TLS] %s() [%s][%s: %s]\n", __FUNCTION__, (num_found == 0) ? "Subject" : "Issuer", "Organization Name", buffer);
743
#endif
744
745
22.8M
    } else if((packet->payload[i] == 0x55) && (packet->payload[i+1] == 0x04) && (packet->payload[i+2] == 0x0b)) {
746
      /* Organization Unit */
747
24.1k
      int rc = extractRDNSequence(packet, i, buffer, sizeof(buffer), rdnSeqBuf, &rdn_len, sizeof(rdnSeqBuf), "OU");
748
24.1k
      if(rc == -1) break;
749
750
#ifdef DEBUG_TLS
751
      printf("[TLS] %s() [%s][%s: %s]\n", __FUNCTION__, (num_found == 0) ? "Subject" : "Issuer", "Organization Unit", buffer);
752
#endif
753
22.7M
    } else if((packet->payload[i] == 0x30) && (packet->payload[i+1] == 0x1e) && (packet->payload[i+2] == 0x17)) {
754
      /* Certificate Validity */
755
71.5k
      u_int offset = i+4;
756
757
71.5k
      if(num_found == 0) {
758
16.4k
  num_found++;
759
760
#ifdef DEBUG_TLS
761
  printf("[TLS] %s() IssuerDN [%s]\n", __FUNCTION__, rdnSeqBuf);
762
#endif
763
764
16.4k
  if(rdn_len && (flow->protos.tls_quic.issuerDN == NULL) &&
765
13.7k
     ndpi_struct->cfg.tls_cert_issuer_enabled) {
766
13.3k
    flow->protos.tls_quic.issuerDN = ndpi_strdup(rdnSeqBuf);
767
13.3k
    if(ndpi_normalize_printable_string(rdnSeqBuf, rdn_len) == 0) {
768
0
      if(is_flowrisk_info_enabled(ndpi_struct, NDPI_INVALID_CHARACTERS)) {
769
0
        char str[64];
770
0
        snprintf(str, sizeof(str), "Invalid issuerDN %s", flow->protos.tls_quic.issuerDN);
771
0
        ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, str);
772
0
      } else {
773
0
        ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, NULL);
774
0
      }
775
0
    }
776
13.3k
  }
777
778
16.4k
  rdn_len = 0; /* Reset buffer */
779
16.4k
      }
780
781
71.5k
      if(i + 3 < certificate_len &&
782
71.3k
   (offset+packet->payload[i+3]) < packet->payload_packet_len &&
783
69.4k
   ndpi_struct->cfg.tls_cert_validity_enabled) {
784
38.5k
  char utcDate[32];
785
38.5k
        u_int8_t len = packet->payload[i+3];
786
787
#ifdef DEBUG_TLS
788
  u_int j;
789
790
  printf("[CERTIFICATE] notBefore [len: %u][", len);
791
  for(j=0; j<len; j++) printf("%c", packet->payload[i+4+j]);
792
  printf("]\n");
793
#endif
794
795
38.5k
  if(len < (sizeof(utcDate)-1)) {
796
24.3k
    struct tm utc;
797
24.3k
    utc.tm_isdst = -1; /* Not set by strptime */
798
799
24.3k
    strncpy(utcDate, (const char*)&packet->payload[i+4], len);
800
24.3k
    utcDate[len] = '\0';
801
802
    /* 141021000000Z */
803
24.3k
    if(strptime(utcDate, "%y%m%d%H%M%SZ", &utc) != NULL) {
804
15.3k
      flow->protos.tls_quic.notBefore = timegm(&utc);
805
#ifdef DEBUG_TLS
806
      printf("[CERTIFICATE] notBefore %u [%s]\n",
807
       flow->protos.tls_quic.notBefore, utcDate);
808
#endif
809
15.3k
    }
810
24.3k
  }
811
812
38.5k
  offset += len;
813
814
38.5k
  if((offset+1) < packet->payload_packet_len) {
815
38.3k
    len = packet->payload[offset+1];
816
817
38.3k
    offset += 2;
818
819
38.3k
    if((offset+len) < packet->payload_packet_len) {
820
36.8k
      u_int32_t time_sec = packet->current_time_ms / 1000;
821
#ifdef DEBUG_TLS
822
      u_int j;
823
824
      printf("[CERTIFICATE] notAfter [len: %u][", len);
825
      for(j=0; j<len; j++) printf("%c", packet->payload[offset+j]);
826
      printf("]\n");
827
#endif
828
829
36.8k
      if(len < (sizeof(utcDate)-1)) {
830
25.5k
        struct tm utc;
831
25.5k
        utc.tm_isdst = -1; /* Not set by strptime */
832
833
25.5k
        strncpy(utcDate, (const char*)&packet->payload[offset], len);
834
25.5k
        utcDate[len] = '\0';
835
836
        /* 141021000000Z */
837
25.5k
        if(strptime(utcDate, "%y%m%d%H%M%SZ", &utc) != NULL) {
838
15.7k
    flow->protos.tls_quic.notAfter = timegm(&utc);
839
#ifdef DEBUG_TLS
840
    printf("[CERTIFICATE] notAfter %u [%s]\n",
841
           flow->protos.tls_quic.notAfter, utcDate);
842
#endif
843
15.7k
        }
844
25.5k
      }
845
846
36.8k
      if(flow->protos.tls_quic.notBefore > TLS_LIMIT_DATE)
847
7.40k
        if((flow->protos.tls_quic.notAfter-flow->protos.tls_quic.notBefore) > TLS_THRESHOLD) {
848
3.56k
          if(is_flowrisk_info_enabled(ndpi_struct, NDPI_TLS_CERT_VALIDITY_TOO_LONG)) {
849
3.28k
            char str[64];
850
851
3.28k
      snprintf(str, sizeof(str), "TLS Cert lasts %u days",
852
3.28k
         (flow->protos.tls_quic.notAfter-flow->protos.tls_quic.notBefore) / 86400);
853
854
3.28k
      ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERT_VALIDITY_TOO_LONG, str); /* Certificate validity longer than 13 months */
855
3.28k
          } else {
856
279
            ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERT_VALIDITY_TOO_LONG, NULL);
857
279
          }
858
3.56k
        }
859
860
36.8k
      if((time_sec < flow->protos.tls_quic.notBefore) || (time_sec > flow->protos.tls_quic.notAfter)) {
861
30.4k
        if(is_flowrisk_info_enabled(ndpi_struct, NDPI_TLS_CERTIFICATE_EXPIRED)) {
862
28.4k
          char str[96], b[32], e[32];
863
28.4k
          struct tm result;
864
28.4k
          time_t theTime;
865
866
28.4k
          theTime = flow->protos.tls_quic.notBefore;
867
28.4k
          strftime(b, sizeof(b), "%d/%b/%Y %H:%M:%S", ndpi_gmtime_r(&theTime, &result));
868
869
28.4k
          theTime = flow->protos.tls_quic.notAfter;
870
28.4k
          strftime(e, sizeof(e), "%d/%b/%Y %H:%M:%S", ndpi_gmtime_r(&theTime, &result));
871
872
28.4k
          snprintf(str, sizeof(str), "%s - %s", b, e);
873
28.4k
          ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_EXPIRED, str); /* Certificate expired */
874
28.4k
        } else {
875
2.03k
          ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_EXPIRED, NULL);
876
2.03k
        }
877
30.4k
      } else if((time_sec > flow->protos.tls_quic.notBefore)
878
6.41k
          && (time_sec > (flow->protos.tls_quic.notAfter - (ndpi_struct->cfg.tls_certificate_expire_in_x_days * 86400)))) {
879
649
        if(is_flowrisk_info_enabled(ndpi_struct, NDPI_TLS_CERTIFICATE_ABOUT_TO_EXPIRE)) {
880
556
          char str[96], b[32], e[32];
881
556
          struct tm result;
882
556
          time_t theTime;
883
884
556
          theTime = flow->protos.tls_quic.notBefore;
885
556
          strftime(b, sizeof(b), "%d/%b/%Y %H:%M:%S", ndpi_gmtime_r(&theTime, &result));
886
887
556
          theTime = flow->protos.tls_quic.notAfter;
888
556
          strftime(e, sizeof(e), "%d/%b/%Y %H:%M:%S", ndpi_gmtime_r(&theTime, &result));
889
890
556
          snprintf(str, sizeof(str), "%s - %s", b, e);
891
556
          ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_ABOUT_TO_EXPIRE, str); /* Certificate almost expired */
892
556
        } else {
893
93
          ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_ABOUT_TO_EXPIRE, NULL);
894
93
        }
895
649
      }
896
36.8k
    }
897
38.3k
  }
898
38.5k
      }
899
22.7M
    } else if((packet->payload[i] == 0x55) && (packet->payload[i+1] == 0x1d) && (packet->payload[i+2] == 0x11)) {
900
      /* Organization OID: 2.5.29.17 (subjectAltName) */
901
57.1k
      u_int8_t matched_name = 0;
902
903
      /* If the client hello was not observed or the requested name was missing, there is no need to trigger an alert */
904
57.1k
      if(flow->host_server_name[0] == '\0')
905
9.74k
  matched_name = 1;
906
907
#ifdef DEBUG_TLS
908
      printf("******* [TLS] Found subjectAltName\n");
909
#endif
910
911
57.1k
      i += 3 /* skip the initial patten 55 1D 11 */;
912
913
      /* skip the first type, 0x04 == BIT STRING, and jump to it's length */
914
57.1k
      if(i < packet->payload_packet_len && packet->payload[i] == 0x04) i++; else i += 4; /* 4 bytes, with the last byte set to 04 */
915
916
57.1k
      if(i < packet->payload_packet_len) {
917
57.0k
  i += (packet->payload[i] & 0x80) ? (packet->payload[i] & 0x7F) : 0; /* skip BIT STRING length */
918
57.0k
  if(i < packet->payload_packet_len) {
919
56.8k
    i += 2; /* skip the second type, 0x30 == SEQUENCE, and jump to it's length */
920
56.8k
    if(i < packet->payload_packet_len) {
921
56.7k
      i += (packet->payload[i] & 0x80) ? (packet->payload[i] & 0x7F) : 0; /* skip SEQUENCE length */
922
56.7k
      i++;
923
924
196k
      while(i < packet->payload_packet_len) {
925
196k
        u_int8_t general_name_type = packet->payload[i];
926
927
196k
        if((general_name_type == 0x81)    /* rfc822Name */
928
184k
     || (general_name_type == 0x82) /* dNSName    */
929
68.1k
     || (general_name_type == 0x87) /* ipAddress  */
930
196k
     )
931
141k
    {
932
141k
      if((i < (packet->payload_packet_len - 1))
933
141k
         && ((i + packet->payload[i + 1] + 2) < packet->payload_packet_len)) {
934
140k
        u_int8_t len = packet->payload[i + 1];
935
140k
        char dNSName[256];
936
140k
        u_int16_t dNSName_len;
937
938
140k
        i += 2;
939
940
        /* The check "len > sizeof(dNSName) - 1" will be always false. If we add it,
941
           the compiler is smart enough to detect it and throws a warning */
942
140k
        if((len == 0 /* Looks something went wrong */)
943
139k
           || ((i+len) > packet->payload_packet_len))
944
1.35k
          break;
945
946
139k
        if(general_name_type == 0x87) {
947
13.2k
          if(len == 4 /* IPv4 */) {
948
6.82k
      ndpi_snprintf(dNSName, sizeof(dNSName), "%u.%u.%u.%u",
949
6.82k
              packet->payload[i] & 0xFF,
950
6.82k
              packet->payload[i+1] & 0xFF,
951
6.82k
              packet->payload[i+2] & 0xFF,
952
6.82k
              packet->payload[i+3] & 0xFF);
953
6.82k
          } else if(len == 16 /* IPv6 */) {
954
4.43k
      struct in6_addr addr = *(struct in6_addr *)&packet->payload[i];
955
4.43k
      inet_ntop(AF_INET6, &addr, dNSName, sizeof(dNSName));
956
4.43k
          } else {
957
      /* Is that possibile? Better safe than sorry */
958
1.99k
      dNSName[0] = '\0';
959
1.99k
          }
960
126k
        } else {
961
126k
          strncpy(dNSName, (const char*)&packet->payload[i], len);
962
126k
          dNSName[len] = '\0';
963
126k
        }
964
965
139k
        dNSName_len = strlen(dNSName);
966
139k
        cleanupServerName(dNSName, dNSName_len);
967
968
#if DEBUG_TLS
969
        printf("[TLS] dNSName %s [%s][len: %u][leftover: %d]\n", dNSName,
970
         flow->host_server_name, len,
971
         packet->payload_packet_len-i-len);
972
#endif
973
974
        /*
975
          We cannot use ndpi_is_valid_hostname() as we can have wildcards
976
          here that will create false positives
977
        */
978
139k
        if(ndpi_normalize_printable_string(dNSName, dNSName_len) == 0) {
979
20.3k
          ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, dNSName);
980
981
          /* This looks like an attack */
982
20.3k
          ndpi_set_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT, "Invalid dNSName name");
983
20.3k
        }
984
985
139k
        if(matched_name == 0) {
986
#if DEBUG_TLS
987
          printf("[TLS] Trying to match '%s' with '%s'\n",
988
           flow->host_server_name, dNSName);
989
#endif
990
991
69.9k
          if(dNSName[0] == '*') {
992
18.2k
      char * label = strstr(flow->host_server_name, &dNSName[1]);
993
994
18.2k
      if(label != NULL) {
995
8.08k
        char * first_dot = strchr(flow->host_server_name, '.');
996
997
8.08k
        if((first_dot == NULL) || (first_dot <= label)) {
998
7.64k
          matched_name = 1;
999
7.64k
        }
1000
8.08k
      }
1001
51.6k
          } else if(strcmp(flow->host_server_name, dNSName) == 0) {
1002
5.95k
      matched_name = 1;
1003
5.95k
          }
1004
69.9k
        }
1005
1006
139k
        if(ndpi_struct->cfg.tls_cert_server_names_enabled) {
1007
95.6k
                      if(flow->protos.tls_quic.server_names == NULL) {
1008
10.2k
                        flow->protos.tls_quic.server_names = ndpi_strdup(dNSName);
1009
10.2k
                        flow->protos.tls_quic.server_names_len = strlen(dNSName);
1010
85.3k
                      } else if((u_int16_t)(flow->protos.tls_quic.server_names_len + dNSName_len + 1) > flow->protos.tls_quic.server_names_len) {
1011
85.3k
                        u_int16_t newstr_len = flow->protos.tls_quic.server_names_len + dNSName_len + 1;
1012
85.3k
                        char *newstr = (char*)ndpi_realloc(flow->protos.tls_quic.server_names,
1013
85.3k
                                                           newstr_len + 1);
1014
1015
85.3k
                        if(newstr) {
1016
83.7k
                          flow->protos.tls_quic.server_names = newstr;
1017
83.7k
                          flow->protos.tls_quic.server_names[flow->protos.tls_quic.server_names_len] = ',';
1018
83.7k
                          strncpy(&flow->protos.tls_quic.server_names[flow->protos.tls_quic.server_names_len+1],
1019
83.7k
                                  dNSName, dNSName_len+1);
1020
83.7k
                          flow->protos.tls_quic.server_names[newstr_len] = '\0';
1021
83.7k
                          flow->protos.tls_quic.server_names_len = newstr_len;
1022
83.7k
                        }
1023
85.3k
                      }
1024
95.6k
        }
1025
1026
139k
        if(ndpi_struct->cfg.tls_subclassification_enabled &&
1027
139k
           !flow->protos.tls_quic.subprotocol_detected &&
1028
44.7k
           !flow->tls_quic.from_rdp) { /* No (other) sub-classification; we will have TLS.RDP anyway */
1029
44.6k
          if(ndpi_match_hostname_protocol(ndpi_struct, flow, ndpi_get_master_proto(ndpi_struct, flow), dNSName, dNSName_len)) {
1030
2.17k
      flow->protos.tls_quic.subprotocol_detected = 1;
1031
2.17k
            ndpi_unset_risk(ndpi_struct, flow, NDPI_NUMERIC_IP_HOST);
1032
2.17k
          }
1033
44.6k
        }
1034
1035
139k
        i += len;
1036
139k
      } else {
1037
741
        char buf[32];
1038
1039
741
        snprintf(buf, sizeof(buf), "Unknown extension %02X", general_name_type);
1040
#if DEBUG_TLS
1041
        printf("[TLS] Leftover %u bytes", packet->payload_packet_len - i);
1042
#endif
1043
741
        ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_EXTENSION, buf);
1044
741
        break;
1045
741
      }
1046
141k
    } else {
1047
54.5k
    break;
1048
54.5k
        }
1049
196k
      } /* while */
1050
1051
56.7k
      if(!matched_name) {
1052
33.6k
        if(is_flowrisk_info_enabled(ndpi_struct, NDPI_TLS_CERTIFICATE_MISMATCH)) {
1053
33.6k
          char str[128];
1054
1055
33.6k
          snprintf(str, sizeof(str), "%s vs %s", flow->host_server_name, flow->protos.tls_quic.server_names);
1056
33.6k
          ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_MISMATCH, str); /* Certificate mismatch */
1057
33.6k
        } else {
1058
18
          ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_CERTIFICATE_MISMATCH, NULL); /* Certificate mismatch */
1059
18
        }
1060
33.6k
      }
1061
56.7k
    }
1062
56.8k
  }
1063
57.0k
      }
1064
57.1k
    }
1065
23.0M
  } /* for */
1066
1067
23.1k
  if(rdn_len && (flow->protos.tls_quic.subjectDN == NULL)) {
1068
16.3k
    if(ndpi_struct->cfg.tls_cert_subject_enabled)
1069
15.0k
      flow->protos.tls_quic.subjectDN = ndpi_strdup(rdnSeqBuf);
1070
1071
16.3k
    if(ndpi_struct->cfg.tls_subclassification_enabled &&
1072
16.3k
       flow->detected_protocol_stack[1] == NDPI_PROTOCOL_UNKNOWN) {
1073
      /* No idea what is happening behind the scenes: let's check the certificate */
1074
6.82k
      u_int32_t val;
1075
6.82k
      int rc = ndpi_match_string_value(ndpi_struct->tls_cert_subject_automa.ac_automa,
1076
6.82k
               rdnSeqBuf, strlen(rdnSeqBuf), &val);
1077
1078
6.82k
      if(rc == 0) {
1079
  /* Match found */
1080
1.03k
  u_int16_t proto_id = (u_int16_t)val;
1081
1.03k
  ndpi_master_app_protocol proto;
1082
1083
1.03k
  ndpi_set_detected_protocol(ndpi_struct, flow, proto_id, ndpi_get_master_proto(ndpi_struct, flow), NDPI_CONFIDENCE_DPI);
1084
1.03k
  proto.master_protocol = ndpi_get_master_proto(ndpi_struct, flow);
1085
1.03k
  proto.app_protocol = proto_id;
1086
1.03k
  flow->category = get_proto_category(ndpi_struct, proto);
1087
1.03k
  flow->breed = get_proto_breed(ndpi_struct, proto);
1088
1.03k
  ndpi_check_subprotocol_risk(ndpi_struct, flow, proto_id);
1089
1.03k
  ndpi_unset_risk(ndpi_struct, flow, NDPI_NUMERIC_IP_HOST);
1090
1091
1.03k
  if(ndpi_struct->tls_cert_cache) {
1092
1.03k
    u_int64_t key = make_tls_cert_key(packet, 0 /* from the server */);
1093
1094
1.03k
    ndpi_lru_add_to_cache(ndpi_struct->tls_cert_cache, key, proto_id, ndpi_get_current_time(flow));
1095
1.03k
  }
1096
1.03k
      }
1097
6.82k
    }
1098
16.3k
  }
1099
1100
23.1k
  if(flow->protos.tls_quic.subjectDN && flow->protos.tls_quic.issuerDN
1101
12.9k
     && (!strcmp(flow->protos.tls_quic.subjectDN, flow->protos.tls_quic.issuerDN))) {
1102
    /* Last resort: we check if this is a trusted issuerDN */
1103
1.21k
    if(ndpi_check_issuerdn_risk_exception(ndpi_struct, flow->protos.tls_quic.issuerDN))
1104
80
      return; /* This is a trusted DN */
1105
1106
1.13k
    if(!flow->protos.tls_quic.webrtc)
1107
941
      ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SELFSIGNED_CERTIFICATE, flow->protos.tls_quic.subjectDN);
1108
1.13k
  }
1109
1110
#if DEBUG_TLS
1111
  printf("[TLS] %s() SubjectDN [%s]\n", __FUNCTION__, rdnSeqBuf);
1112
#endif
1113
23.1k
}
1114
1115
/* **************************************** */
1116
1117
static void tls_match_ja4(struct ndpi_detection_module_struct *ndpi_struct,
1118
3.04M
        struct ndpi_flow_struct *flow) {
1119
3.04M
  if(ndpi_struct->ja4_custom_protos != NULL) {
1120
3.02M
    u_int64_t proto_id;
1121
3.02M
    ndpi_list *extra_data = NULL;
1122
1123
    /* This protocol has been defined in protos.txt-like files */
1124
3.02M
    if(ndpi_hash_find_entry_extra(ndpi_struct->ja4_custom_protos,
1125
3.02M
          flow->protos.tls_quic.ja4_client,
1126
3.02M
          NDPI_ARRAY_LENGTH(flow->protos.tls_quic.ja4_client) - 1,
1127
3.02M
          &proto_id, &extra_data) != 0)
1128
3.02M
      return; /* Not found */
1129
91
    else
1130
91
      proto_id = ndpi_compare_flow_tls_blocks(ndpi_struct, flow, extra_data, proto_id);
1131
1132
91
    if(proto_id != NDPI_PROTOCOL_UNKNOWN)
1133
91
      ndpi_set_detected_protocol(ndpi_struct, flow, proto_id,
1134
91
         ndpi_get_master_proto(ndpi_struct, flow),
1135
91
         NDPI_CONFIDENCE_CUSTOM_RULE);
1136
91
  }
1137
1138
14.9k
  if(ndpi_struct->malicious_ja4_hashmap != NULL) {
1139
496
    u_int16_t rc1 = ndpi_hash_find_entry(ndpi_struct->malicious_ja4_hashmap,
1140
496
           flow->protos.tls_quic.ja4_client,
1141
496
           NDPI_ARRAY_LENGTH(flow->protos.tls_quic.ja4_client) - 1,
1142
496
           NULL);
1143
1144
496
    if(rc1 == 0)
1145
0
      ndpi_set_risk(ndpi_struct, flow, NDPI_MALICIOUS_FINGERPRINT,
1146
0
        flow->protos.tls_quic.ja4_client);
1147
496
  }
1148
14.9k
}
1149
1150
/* **************************************** */
1151
1152
/* See https://blog.catchpoint.com/2017/05/12/dissecting-tls-using-wireshark/ */
1153
int processCertificate(struct ndpi_detection_module_struct *ndpi_struct,
1154
23.4k
           struct ndpi_flow_struct *flow) {
1155
23.4k
  struct ndpi_packet_struct *packet = &ndpi_struct->packet;
1156
23.4k
  int is_dtls = packet->udp || flow->stun.maybe_dtls; /* No certificate with QUIC */
1157
23.4k
  u_int32_t certificates_length, length = (packet->payload[1] << 16) + (packet->payload[2] << 8) + packet->payload[3];
1158
23.4k
  u_int32_t certificates_offset = 7 + (is_dtls ? 8 : 0);
1159
23.4k
  u_int8_t num_certificates_found = 0;
1160
1161
#ifdef DEBUG_TLS
1162
  printf("[TLS] %s() [payload_packet_len=%u][direction: %u][%02X %02X %02X %02X %02X %02X...]\n",
1163
   __FUNCTION__, packet->payload_packet_len,
1164
   packet->packet_direction,
1165
   packet->payload[0], packet->payload[1], packet->payload[2],
1166
   packet->payload[3], packet->payload[4], packet->payload[5]);
1167
#endif
1168
1169
23.4k
  if((packet->payload_packet_len != (length + 4 + (is_dtls ? 8 : 0))) || (packet->payload[1] != 0x0) ||
1170
23.3k
     certificates_offset >= packet->payload_packet_len) {
1171
338
    ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET, "Unvalid lenght");
1172
338
    return(-1); /* Invalid length */
1173
338
  }
1174
1175
23.1k
  certificates_length = (packet->payload[certificates_offset - 3] << 16) +
1176
23.1k
    (packet->payload[certificates_offset - 2] << 8) +
1177
23.1k
    packet->payload[certificates_offset - 1];
1178
1179
23.1k
  if((packet->payload[certificates_offset - 3] != 0x0) || ((certificates_length+3) != length)) {
1180
1.64k
    ndpi_set_risk(ndpi_struct, flow, NDPI_MALFORMED_PACKET, "Invalid certificate offset");
1181
1.64k
    return(-2); /* Invalid length */
1182
1.64k
  }
1183
1184
  /* Now let's process each individual certificates */
1185
54.4k
  while(certificates_offset < certificates_length) {
1186
35.5k
    u_int32_t certificate_len = (packet->payload[certificates_offset] << 16) + (packet->payload[certificates_offset+1] << 8) + packet->payload[certificates_offset+2];
1187
1188
    /* Invalid lenght */
1189
35.5k
    if((certificate_len == 0)
1190
34.9k
       || (packet->payload[certificates_offset] != 0x0)
1191
33.2k
       || ((certificates_offset+certificate_len) > (4+certificates_length+(is_dtls ? 8 : 0)))) {
1192
#ifdef DEBUG_TLS
1193
      printf("[TLS] Invalid length [certificate_len: %u][certificates_offset: %u][%u vs %u]\n",
1194
       certificate_len, certificates_offset,
1195
       (certificates_offset+certificate_len),
1196
       certificates_length);
1197
#endif
1198
2.60k
      break;
1199
2.60k
    }
1200
1201
32.9k
    certificates_offset += 3;
1202
#ifdef DEBUG_TLS
1203
    printf("[TLS] Processing %u bytes certificate [%02X %02X %02X]\n",
1204
     certificate_len,
1205
     packet->payload[certificates_offset],
1206
     packet->payload[certificates_offset+1],
1207
     packet->payload[certificates_offset+2]);
1208
#endif
1209
1210
32.9k
    if(num_certificates_found++ == 0) /* Dissect only the first certificate that is the one we care */ {
1211
1212
#ifdef DEBUG_CERTIFICATE_HASH
1213
      {
1214
  u_int32_t i;
1215
1216
  for(i=0;i<certificate_len;i++)
1217
    printf("%02X ", packet->payload[certificates_offset+i]);
1218
1219
  printf("\n");
1220
      }
1221
#endif
1222
1223
      /* For SHA-1 we take into account only the first certificate and not all of them */
1224
21.1k
      if(ndpi_struct->cfg.tls_sha1_fingerprint_enabled) {
1225
18.5k
        SHA1_CTX srv_cert_fingerprint_ctx ;
1226
1227
18.5k
  SHA1Init(&srv_cert_fingerprint_ctx);
1228
18.5k
  SHA1Update(&srv_cert_fingerprint_ctx,
1229
18.5k
                   &packet->payload[certificates_offset],
1230
18.5k
                   certificate_len);
1231
1232
18.5k
        SHA1Final(flow->protos.tls_quic.sha1_certificate_fingerprint, &srv_cert_fingerprint_ctx);
1233
1234
18.5k
        flow->protos.tls_quic.fingerprint_set = 1;
1235
1236
18.5k
        uint8_t * sha1 = flow->protos.tls_quic.sha1_certificate_fingerprint;
1237
18.5k
        const size_t sha1_siz = sizeof(flow->protos.tls_quic.sha1_certificate_fingerprint);
1238
18.5k
        char sha1_str[20 /* sha1_siz */ * 2 + 1];
1239
18.5k
        static const char hexalnum[] = "0123456789ABCDEF";
1240
18.5k
        size_t i;
1241
388k
        for (i = 0; i < sha1_siz; ++i) {
1242
370k
          u_int8_t lower = (sha1[i] & 0x0F);
1243
370k
          u_int8_t upper = (sha1[i] & 0xF0) >> 4;
1244
370k
          sha1_str[i*2] = hexalnum[upper];
1245
370k
          sha1_str[i*2 + 1] = hexalnum[lower];
1246
370k
        }
1247
18.5k
        sha1_str[sha1_siz * 2] = '\0';
1248
1249
#ifdef DEBUG_TLS
1250
        printf("[TLS] SHA-1: %s\n", sha1_str);
1251
#endif
1252
1253
18.5k
        if(ndpi_struct->malicious_sha1_hashmap != NULL) {
1254
17.9k
          u_int16_t rc1 = ndpi_hash_find_entry(ndpi_struct->malicious_sha1_hashmap, sha1_str, sha1_siz * 2, NULL);
1255
1256
17.9k
          if(rc1 == 0)
1257
12
            ndpi_set_risk(ndpi_struct, flow, NDPI_MALICIOUS_SHA1_CERTIFICATE, sha1_str);
1258
17.9k
        }
1259
18.5k
      }
1260
1261
21.1k
      processCertificateElements(ndpi_struct, flow, certificates_offset, certificate_len);
1262
21.1k
    }
1263
1264
32.9k
    certificates_offset += certificate_len;
1265
32.9k
  }
1266
1267
21.4k
  return(1);
1268
23.1k
}
1269
1270
/* **************************************** */
1271
1272
static void handleTLSBlockStat(struct ndpi_detection_module_struct *ndpi_struct,
1273
             struct ndpi_flow_struct *flow, bool *same_packet,
1274
             u_int8_t record_type, u_int8_t handshake_type,
1275
383k
             u_int16_t block_len) {
1276
383k
  struct ndpi_packet_struct *packet = &ndpi_struct->packet;
1277
1278
383k
  if(flow->l4_proto == IPPROTO_TCP &&
1279
383k
     ndpi_struct->cfg.tls_max_num_blocks_to_analyze != 0) {
1280
344k
    if(flow->l4.tcp.tls.tls_blocks == NULL) {
1281
139k
      u_int len = sizeof(struct ndpi_tls_block) * ndpi_struct->cfg.tls_max_num_blocks_to_analyze;
1282
1283
139k
      flow->l4.tcp.tls.tls_blocks = (struct ndpi_tls_block *)ndpi_malloc(len);
1284
139k
    }
1285
1286
344k
    if((flow->l4.tcp.tls.tls_blocks != NULL)
1287
342k
       && (flow->l4.tcp.tls.num_tls_blocks < ndpi_struct->cfg.tls_max_num_blocks_to_analyze)) {
1288
1289
322k
      int32_t blen;
1290
322k
      u_int32_t tdelta;
1291
322k
      u_int16_t enc_block_type;
1292
1293
322k
      enc_block_type = ndpi_encode_tls_block_type(record_type, handshake_type);
1294
322k
      blen = block_len;
1295
1296
322k
      if(flow->l4.tcp.tls.last_tls_block_time_ms)
1297
184k
        tdelta = ndpi_struct->packet.current_time_ms - flow->l4.tcp.tls.last_tls_block_time_ms;
1298
137k
      else
1299
137k
        tdelta = 0;
1300
1301
322k
      if(packet->packet_direction == 1 /* srv -> cli */) blen *= -1;
1302
1303
322k
      flow->l4.tcp.tls.tls_blocks[flow->l4.tcp.tls.num_tls_blocks].len = blen,
1304
322k
         flow->l4.tcp.tls.tls_blocks[flow->l4.tcp.tls.num_tls_blocks].msec_delta =
1305
322k
        (tdelta > 0xFFFF) ?  0xFFFF : (u_int16_t)tdelta,
1306
322k
        flow->l4.tcp.tls.tls_blocks[flow->l4.tcp.tls.num_tls_blocks].same_pkt = same_packet ? 1 : 0;
1307
322k
      flow->l4.tcp.tls.tls_blocks[flow->l4.tcp.tls.num_tls_blocks++].block_type = enc_block_type;
1308
1309
322k
      flow->l4.tcp.tls.last_tls_block_time_ms = ndpi_struct->packet.current_time_ms;
1310
322k
    }
1311
344k
  }
1312
383k
  if(*same_packet == false)
1313
246k
    *same_packet = true;
1314
383k
}
1315
1316
/* **************************************** */
1317
1318
static int processHandshakeTLSBlock(struct ndpi_detection_module_struct *ndpi_struct,
1319
331k
            struct ndpi_flow_struct *flow) {
1320
331k
  struct ndpi_packet_struct *packet = &ndpi_struct->packet;
1321
331k
  int ret;
1322
331k
  int is_dtls = packet->udp || flow->stun.maybe_dtls;
1323
331k
  u_int8_t handshake_type = packet->payload[0];
1324
1325
#ifdef DEBUG_TLS
1326
  printf("[TLS] Processing block %u\n", packet->payload[0]);
1327
#endif
1328
1329
331k
  switch(handshake_type) {
1330
165k
  case 0x01: /* Client Hello */
1331
165k
    if((flow->l4.tcp.three_way_handshake.syn_time != 0) /* Check only if 3WH was observed */
1332
27.9k
       && (flow->l4.tcp.three_way_handshake.ack_time != 0)
1333
165k
       ) {
1334
25.5k
      u_int64_t tdiff_ms = packet->current_time_ms - flow->l4.tcp.three_way_handshake.ack_time;
1335
1336
25.5k
      if((tdiff_ms > 3000 /* 3 sec */) && (!ndpi_isset_risk(flow, NDPI_SLOW_DOS))) {
1337
46
  char buf[64];
1338
1339
46
  snprintf(buf, sizeof(buf), "Slow TLS Request: %.1f sec", tdiff_ms/1000.);
1340
46
  ndpi_set_risk(ndpi_struct, flow, NDPI_SLOW_DOS, buf);
1341
46
      }
1342
25.5k
    }
1343
1344
165k
    flow->protos.tls_quic.client_hello_processed = 1;
1345
165k
    flow->protos.tls_quic.ch_direction = packet->packet_direction;
1346
165k
    processClientServerHello(ndpi_struct, flow, 0);
1347
165k
    ndpi_int_tls_add_connection(ndpi_struct, flow);
1348
1349
#ifdef DEBUG_TLS
1350
    printf("*** TLS [version: %02X][Client Hello]\n",
1351
     flow->protos.tls_quic.ssl_version);
1352
#endif
1353
1354
165k
    checkTLSSubprotocol(ndpi_struct, flow, packet->payload[0] == 0x01);
1355
165k
    break;
1356
1357
82.5k
  case 0x02: /* Server Hello */
1358
82.5k
    flow->protos.tls_quic.server_hello_processed = 1;
1359
82.5k
    flow->protos.tls_quic.ch_direction = !packet->packet_direction;
1360
82.5k
    processClientServerHello(ndpi_struct, flow, 0);
1361
82.5k
    ndpi_int_tls_add_connection(ndpi_struct, flow);
1362
1363
#ifdef DEBUG_TLS
1364
    printf("*** TLS [version: %02X][Server Hello]\n",
1365
     flow->protos.tls_quic.ssl_version);
1366
#endif
1367
1368
82.5k
    if(!is_dtls && flow->protos.tls_quic.ssl_version >= 0x0304 /* TLS 1.3 */)
1369
15.5k
      flow->tls_quic.certificate_processed = 1; /* No Certificate with TLS 1.3+ */
1370
1371
82.5k
    if(is_dtls && flow->protos.tls_quic.ssl_version == 0xFEFC /* DTLS 1.3 */)
1372
490
      flow->tls_quic.certificate_processed = 1; /* No Certificate with DTLS 1.3+ */
1373
1374
82.5k
    checkTLSSubprotocol(ndpi_struct, flow, packet->payload[0] == 0x01);
1375
82.5k
    break;
1376
1377
25.7k
  case 0x0b: /* Certificate */
1378
    /* Important: populate the tls union fields only after
1379
     * ndpi_int_tls_add_connection has been called */
1380
25.7k
    if(flow->protos.tls_quic.client_hello_processed ||
1381
23.8k
       flow->protos.tls_quic.server_hello_processed) {
1382
      /* Only certificates from the server */
1383
23.8k
      if(flow->protos.tls_quic.ch_direction != packet->packet_direction) {
1384
23.4k
        ret = processCertificate(ndpi_struct, flow);
1385
23.4k
        if(ret != 1) {
1386
#ifdef DEBUG_TLS
1387
          printf("[TLS] Error processing certificate: %d\n", ret);
1388
#endif
1389
1.98k
        }
1390
23.4k
      } else {
1391
#ifdef DEBUG_TLS
1392
        printf("[TLS] Certificate from client. Ignoring it\n");
1393
#endif
1394
422
      }
1395
23.8k
      flow->tls_quic.certificate_processed = 1;
1396
23.8k
    }
1397
25.7k
    break;
1398
331k
  }
1399
1400
331k
  return(0);
1401
331k
}
1402
1403
/* **************************************** */
1404
1405
static void ndpi_looks_like_tls(struct ndpi_detection_module_struct *ndpi_struct,
1406
309k
                                struct ndpi_flow_struct *flow) {
1407
309k
  if(flow->fast_callback_protocol_id == NDPI_PROTOCOL_UNKNOWN)
1408
149k
    flow->fast_callback_protocol_id = ndpi_get_master_proto(ndpi_struct, flow);
1409
309k
}
1410
1411
/* **************************************** */
1412
1413
static int check_tls_type_and_version(const u_int8_t *buf, u_int16_t buf_len)
1414
3.30M
{
1415
  /* Valid TLS Content Types:
1416
     https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-5 */
1417
3.30M
  if(buf_len >= 1 &&
1418
3.30M
     !(buf[0] >= 20 && buf[0] <= 26))
1419
2.82M
    return 0;
1420
1421
  /* Valid version in Record Layer
1422
     "Earlier versions of the TLS specification were not fully clear on what the record layer version
1423
     number (TLSPlaintext.version) should contain when sending ClientHello (i.e., before it is known
1424
     which version of the protocol will be employed). Thus, TLS servers compliant with this
1425
     specification MUST accept any value {03,XX} as the record layer version number for ClientHello."
1426
  */
1427
481k
  if(buf_len >=2 && buf[1] != 0x03)
1428
42.0k
    return 0;
1429
1430
439k
  return 1; /* ok */
1431
481k
}
1432
1433
/* **************************************** */
1434
1435
int ndpi_search_tls_tcp(struct ndpi_detection_module_struct *ndpi_struct,
1436
4.43M
                        struct ndpi_flow_struct *flow) {
1437
4.43M
  struct ndpi_packet_struct *packet = &ndpi_struct->packet;
1438
4.43M
  u_int8_t something_went_wrong = 0;
1439
4.43M
  message_t *message;
1440
4.43M
  bool same_packet = false;
1441
1442
4.43M
  if(packet->tcp == NULL)
1443
0
    return 0; /* Error -> stop (this doesn't seem to be TCP) */
1444
1445
#ifdef DEBUG_TLS_MEMORY
1446
  printf("[TLS Mem] ndpi_search_tls_tcp() Processing new packet [payload_packet_len: %u][Dir: %u]\n",
1447
   packet->payload_packet_len, packet->packet_direction);
1448
#endif
1449
1450
  /* This function is also called by "extra dissection" data path. Unfortunately,
1451
     generic "extra function" code doesn't honour protocol bitmask.
1452
     TODO: handle that in ndpi_main.c for all the protocols */
1453
4.43M
  if(packet->payload_packet_len == 0 ||
1454
4.33M
     packet->tcp_retransmission) {
1455
#ifdef DEBUG_TLS_MEMORY
1456
    printf("[TLS Mem] Ack or retransmission %d/%d. Skip\n",
1457
           packet->payload_packet_len, packet->tcp_retransmission);
1458
#endif
1459
148k
    return 1; /* Keep working */
1460
148k
  }
1461
1462
4.29M
  message = &flow->tls_quic.message[packet->packet_direction];
1463
4.29M
  if(ndpi_search_tls_memory(packet->payload,
1464
4.29M
          packet->payload_packet_len, ntohl(packet->tcp->seq),
1465
4.29M
          message) == -1)
1466
18.6k
    return 0; /* Error -> stop */
1467
1468
4.47M
  while(!something_went_wrong) {
1469
4.46M
    u_int32_t len;
1470
4.46M
    u_int16_t p_len;
1471
4.46M
    const u_int8_t *p;
1472
4.46M
    u_int8_t content_type;
1473
1474
4.46M
    if(message->buffer_used < 5)
1475
1.16M
      break;
1476
1477
3.30M
    if(!check_tls_type_and_version(message->buffer, message->buffer_used)) {
1478
#ifdef DEBUG_TLS_MEMORY
1479
      printf("[TLS Mem] Invalid record type/version");
1480
#endif
1481
2.86M
      something_went_wrong = 1;
1482
2.86M
      break;
1483
2.86M
    }
1484
1485
439k
    len = (message->buffer[3] << 8) + message->buffer[4] + 5;
1486
1487
439k
    if(len > message->buffer_used) {
1488
#ifdef DEBUG_TLS_MEMORY
1489
      printf("[TLS Mem] Not enough TLS data [%u < %u][%02X %02X %02X %02X %02X]\n",
1490
       len, message->buffer_used,
1491
       message->buffer[0],
1492
       message->buffer[1],
1493
       message->buffer[2],
1494
       message->buffer[3],
1495
       message->buffer[4]);
1496
#endif
1497
84.7k
      break;
1498
84.7k
    }
1499
1500
#ifdef DEBUG_TLS_MEMORY
1501
    printf("[TLS Mem] Processing %u bytes message\n", len);
1502
#endif
1503
1504
354k
    content_type = message->buffer[0];
1505
1506
354k
    if(content_type != 0x16)
1507
146k
      handleTLSBlockStat(ndpi_struct, flow, &same_packet, content_type, 0, len - 5);
1508
1509
    /* Overwriting packet payload */
1510
354k
    p = packet->payload;
1511
354k
    p_len = packet->payload_packet_len; /* Backup */
1512
1513
354k
    if(content_type == 0x14 /* Change Cipher Spec */) {
1514
48.5k
      if(len == 6 &&
1515
47.9k
         message->buffer[1] == 0x03 && /* TLS >= 1.0 */
1516
47.9k
         ((message->buffer[3] << 8) + (message->buffer[4])) == 1) {
1517
#ifdef DEBUG_TLS
1518
        printf("[TLS] Change Cipher Spec\n");
1519
#endif
1520
47.9k
        if(current_pkt_from_client_to_server(ndpi_struct, flow))
1521
26.5k
          flow->tls_quic.change_cipher_from_client = 1;
1522
21.3k
        else
1523
21.3k
          flow->tls_quic.change_cipher_from_server = 1;
1524
1525
47.9k
        ndpi_int_tls_add_connection(ndpi_struct, flow);
1526
47.9k
        flow->l4.tcp.tls.app_data_seen[packet->packet_direction] = 1;
1527
        /* Further data is encrypted so we are not able to parse it without
1528
           errors and without setting `something_went_wrong` variable */
1529
1530
47.9k
  if(ndpi_struct->cfg.tls_max_num_blocks_to_analyze == 0) {
1531
    /*
1532
      In case of TLS blocks analysis we want to analize all the blocks
1533
      whereas in "standard" mode we can use this shortcut and break
1534
    */
1535
4.05k
    break;
1536
4.05k
  }
1537
47.9k
      }
1538
306k
    } else if(content_type == 0x15 /* Alert */) {
1539
      /* https://techcommunity.microsoft.com/t5/iis-support-blog/ssl-tls-alert-protocol-and-the-alert-codes/ba-p/377132 */
1540
#ifdef DEBUG_TLS
1541
      printf("[TLS] *** TLS ALERT ***\n");
1542
#endif
1543
1544
3.59k
      flow->tls_quic.alert = 1;
1545
1546
      /* Basic heuristic to tell if the alert is encrypted or not */
1547
3.59k
      if(len == 7 &&
1548
971
         (message->buffer[5] == 1 ||
1549
778
          message->buffer[5] == 2)) {
1550
778
  u_int8_t alert_level = message->buffer[5];
1551
1552
778
  if(alert_level == 2 /* Warning (1), Fatal (2) */)
1553
569
    ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_FATAL_ALERT, "Found fatal TLS alert");
1554
209
  else
1555
209
    flow->tls_quic.alert = 0;
1556
778
      }
1557
1558
3.59k
      u_int16_t const alert_len = ntohs(*(u_int16_t const *)&message->buffer[3]);
1559
3.59k
      if(alert_len == (u_int32_t)message->buffer_used - 5)
1560
1.62k
  ndpi_int_tls_add_connection(ndpi_struct, flow);
1561
302k
    } else if(content_type == 0x16 /* Handshake */) {
1562
      /* Split the element in blocks */
1563
208k
      u_int32_t processed = 5;
1564
1565
208k
      if(len >= 9) {
1566
422k
        while((processed+4) <= len) {
1567
246k
          const u_int8_t *block = (const u_int8_t *)&message->buffer[processed];
1568
246k
          u_int32_t block_len   = (block[1] << 16) + (block[2] << 8) + block[3];
1569
1570
246k
          if((current_pkt_from_client_to_server(ndpi_struct, flow) &&
1571
156k
              flow->tls_quic.change_cipher_from_client == 1) ||
1572
232k
             (!current_pkt_from_client_to_server(ndpi_struct, flow) &&
1573
90.5k
              flow->tls_quic.change_cipher_from_server == 1)) {
1574
#ifdef DEBUG_TLS_MEMORY
1575
            printf("[TLS Mem] Encrypted Handshake msg. Skip\n");
1576
#endif
1577
1578
21.8k
            handleTLSBlockStat(ndpi_struct, flow, &same_packet, 0x16, 0, len - 5);
1579
1580
      /* We don't have block len, so ignore the entire record */
1581
21.8k
            processed += len - 5;
1582
21.8k
            break;
1583
21.8k
          }
1584
1585
224k
          if(/* (block_len == 0) || */ /* Note blocks can have zero lenght */
1586
224k
             (block_len > len) || ((block[1] != 0x0))) {
1587
9.09k
            something_went_wrong = 1;
1588
9.09k
            break;
1589
9.09k
          }
1590
1591
215k
          packet->payload = block;
1592
215k
          packet->payload_packet_len = ndpi_min(block_len+4, message->buffer_used);
1593
1594
215k
          if((processed+packet->payload_packet_len) > len) {
1595
439
            something_went_wrong = 1;
1596
439
            break;
1597
439
          }
1598
1599
215k
          handleTLSBlockStat(ndpi_struct, flow, &same_packet, 0x16, block[0], block_len);
1600
1601
215k
    processHandshakeTLSBlock(ndpi_struct, flow);
1602
215k
          ndpi_looks_like_tls(ndpi_struct, flow);
1603
1604
215k
          processed += packet->payload_packet_len;
1605
215k
        }
1606
207k
      }
1607
208k
    } else if(content_type == 0x17 /* Application Data */) {
1608
94.2k
      u_int32_t block_len   = (message->buffer[3] << 8) + (message->buffer[4]);
1609
1610
      /* Let's do a quick check to make sure this really looks like TLS */
1611
94.2k
      if(block_len < 16384 /* Max TLS block size */)
1612
94.1k
  ndpi_looks_like_tls(ndpi_struct, flow);
1613
1614
94.2k
      if(block_len == (u_int32_t)message->buffer_used - 5)
1615
49.5k
  ndpi_int_tls_add_connection(ndpi_struct, flow);
1616
1617
      /* If we have seen Application Data blocks in both directions, it means
1618
   we are after the handshake. Stop extra processing */
1619
94.2k
      flow->l4.tcp.tls.app_data_seen[packet->packet_direction] = 1;
1620
94.2k
      if(flow->l4.tcp.tls.app_data_seen[!packet->packet_direction] == 1)
1621
27.5k
  flow->tls_quic.certificate_processed = 1;
1622
94.2k
    }
1623
1624
350k
    packet->payload = p;
1625
350k
    packet->payload_packet_len = p_len; /* Restore */
1626
350k
    message->buffer_used -= len;
1627
1628
350k
    if(message->buffer_used > 0)
1629
201k
      memmove(message->buffer, &message->buffer[len], message->buffer_used);
1630
149k
    else
1631
149k
      break;
1632
1633
#ifdef DEBUG_TLS_MEMORY
1634
    printf("[TLS Mem] Left memory buffer %u bytes\n", message->buffer_used);
1635
#endif
1636
350k
  }
1637
1638
#ifdef DEBUG_TLS_MEMORY
1639
  printf("[TLS] Eval if keep going [%p][blocks:%d/%d][wrong:%d]\n",
1640
         flow->extra_packets_func,
1641
         flow->l4.tcp.tls.num_tls_blocks, ndpi_struct->cfg.tls_max_num_blocks_to_analyze,
1642
         something_went_wrong);
1643
#endif
1644
1645
4.27M
  if(something_went_wrong
1646
1.40M
     || ((ndpi_struct->cfg.tls_max_num_blocks_to_analyze > 0)
1647
1.17M
   && (flow->l4.tcp.tls.num_tls_blocks == ndpi_struct->cfg.tls_max_num_blocks_to_analyze))
1648
1.38M
     || ((ndpi_struct->cfg.tls_max_num_blocks_to_analyze == 0)
1649
228k
   && (!keep_extra_dissection_tcp(ndpi_struct, flow)))
1650
4.27M
     ) {
1651
#ifdef DEBUG_TLS_BLOCKS
1652
    printf("*** [TLS Block] No more blocks\n");
1653
#endif
1654
    /* An ookla flow? */
1655
2.89M
    if((ndpi_struct->cfg.ookla_aggressiveness & NDPI_AGGRESSIVENESS_OOKLA_TLS) && /* Feature enabled */
1656
2.89M
       (!something_went_wrong &&
1657
21.5k
        flow->tls_quic.certificate_processed == 1 &&
1658
17.5k
        flow->protos.tls_quic.client_hello_processed == 1 &&
1659
15.5k
        flow->protos.tls_quic.server_hello_processed == 1) && /* TLS handshake found without errors */
1660
15.3k
       flow->detected_protocol_stack[0] == NDPI_PROTOCOL_TLS && /* No IMAPS/FTPS/... */
1661
1.98k
       flow->detected_protocol_stack[1] == NDPI_PROTOCOL_UNKNOWN && /* No sub-classification */
1662
2.89M
       ntohs(flow->s_port) == 8080 && /* Ookla port */
1663
18
       ookla_search_into_cache(ndpi_struct, flow)) {
1664
11
      NDPI_LOG_INFO(ndpi_struct, "found ookla (cache over TLS)\n");
1665
      /* Even if a LRU cache is involved, NDPI_CONFIDENCE_DPI_AGGRESSIVE seems more
1666
         suited than NDPI_CONFIDENCE_DPI_CACHE */
1667
11
      ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OOKLA, NDPI_PROTOCOL_TLS, NDPI_CONFIDENCE_DPI_AGGRESSIVE);
1668
1669
11
      tls_match_ja4(ndpi_struct, flow);
1670
11
      flow->extra_packets_func = NULL;
1671
1672
11
      return(0); /* That's all */
1673
    /* Loook for TLS-in-TLS */
1674
2.89M
    } else if((ndpi_struct->cfg.tls_heuristics & NDPI_HEURISTICS_TLS_OBFUSCATED_TLS) && /* Feature enabled */
1675
2.41M
              (!something_went_wrong &&
1676
16.4k
               flow->tls_quic.certificate_processed == 1 &&
1677
16.0k
               flow->protos.tls_quic.client_hello_processed == 1 &&
1678
14.9k
               flow->protos.tls_quic.server_hello_processed == 1) && /* TLS handshake found without errors */
1679
14.7k
               flow->tls_quic.from_opportunistic_tls == 0 && /* No from plaintext Mails or FTP */
1680
14.7k
              !is_flow_addr_informative(flow) /* The proxy server is likely hosted on some cloud providers */ ) {
1681
11.4k
      switch_extra_dissection_to_tls_obfuscated_heur(ndpi_struct, flow);
1682
11.4k
      return(1);
1683
2.88M
    } else {
1684
2.88M
      tls_match_ja4(ndpi_struct, flow);
1685
1686
2.88M
      flow->extra_packets_func = NULL;
1687
2.88M
      return(0); /* That's all */
1688
2.88M
    }
1689
2.89M
  } else
1690
1.37M
    return(1);
1691
4.27M
}
1692
1693
/* **************************************** */
1694
1695
1.31M
int is_dtls(const u_int8_t *buf, u_int32_t buf_len, u_int32_t *block_len) {
1696
1.31M
  if(buf_len <= 13)
1697
6.84k
    return 0;
1698
1699
1.30M
  if((buf[0] != 0x16 && buf[0] != 0x14 && buf[0] != 0x17 && buf[0] != 0x15) || /* Handshake, change-cipher-spec, Application-Data, Alert */
1700
289k
     !((buf[1] == 0xfe && buf[2] == 0xff) || /* Versions */
1701
138k
       (buf[1] == 0xfe && buf[2] == 0xfd) ||
1702
57.2k
       (buf[1] == 0xfe && buf[2] == 0xfc) ||
1703
1.03M
       (buf[1] == 0x01 && buf[2] == 0x00))) {
1704
#ifdef DEBUG_TLS
1705
    printf("[TLS] DTLS invalid block 0x%x or old version 0x%x-0x%x-0x%x\n",
1706
           buf[0], buf[1], buf[2], buf[3]);
1707
#endif
1708
1.03M
    return 0;
1709
1.03M
  }
1710
267k
  *block_len = ntohs(*((u_int16_t*)&buf[11]));
1711
#ifdef DEBUG_TLS
1712
  printf("[TLS] DTLS block len: %d\n", *block_len);
1713
#endif
1714
267k
  if(*block_len == 0 || (*block_len + 12 >= buf_len)) { /* We might have multiple DTLS records */
1715
#ifdef DEBUG_TLS
1716
    printf("[TLS] DTLS invalid block len %d (buf_len %d)\n",
1717
           *block_len, buf_len);
1718
#endif
1719
21.7k
    return 0;
1720
21.7k
  }
1721
245k
  return 1;
1722
267k
}
1723
1724
/* **************************************** */
1725
1726
/* NOTE: this function supports both TCP and UDP */
1727
static int ndpi_search_dtls(struct ndpi_detection_module_struct *ndpi_struct,
1728
1.25M
             struct ndpi_flow_struct *flow) {
1729
1.25M
  struct ndpi_packet_struct *packet = &ndpi_struct->packet;
1730
1.25M
  u_int32_t handshake_len, handshake_frag_off, handshake_frag_len;
1731
1.25M
  u_int16_t p_len, processed;
1732
1.25M
  const u_int8_t *p;
1733
1.25M
  u_int8_t no_dtls = 0, change_cipher_found = 0;
1734
1.25M
  message_t *message = NULL;
1735
1736
#ifdef DEBUG_TLS
1737
  printf("[TLS] %s()\n", __FUNCTION__);
1738
#endif
1739
1740
  /* Overwriting packet payload */
1741
1.25M
  p = packet->payload, p_len = packet->payload_packet_len; /* Backup */
1742
1743
  /* Split the element in blocks */
1744
1.25M
  processed = 0;
1745
1.39M
  while(processed + 13 < p_len) {
1746
1.16M
    u_int32_t block_len;
1747
1.16M
    const u_int8_t *block = (const u_int8_t *)&p[processed];
1748
1749
1.16M
    if(!is_dtls(block, p_len, &block_len)) {
1750
1.01M
      no_dtls = 1;
1751
1.01M
      break;
1752
1.01M
    }
1753
1754
    /* We process only handshake msgs */
1755
148k
    if(block[0] == 0x16) {
1756
139k
      if(processed + block_len + 13 > p_len) {
1757
#ifdef DEBUG_TLS
1758
        printf("[TLS] DTLS invalid len %d %d %d\n", processed, block_len, p_len);
1759
#endif
1760
702
        no_dtls = 1;
1761
702
        break;
1762
702
      }
1763
      /* TODO: handle (certificate) fragments */
1764
138k
      if(block_len > 24) {
1765
131k
        handshake_len = (block[14] << 16) + (block[15] << 8) + block[16];
1766
131k
        handshake_frag_off = (block[19] << 16) + (block[20] << 8) + block[21];
1767
131k
        handshake_frag_len = (block[22] << 16) + (block[23] << 8) + block[24];
1768
131k
        message = &flow->tls_quic.message[packet->packet_direction];
1769
1770
1771
#ifdef DEBUG_TLS
1772
        printf("[TLS] DTLS frag off %d len %d\n", handshake_frag_off, handshake_frag_len);
1773
#endif
1774
1775
131k
  if((handshake_len + 12) == block_len) {
1776
115k
          packet->payload = &block[13];
1777
115k
          packet->payload_packet_len = block_len;
1778
115k
          processHandshakeTLSBlock(ndpi_struct, flow);
1779
115k
  } else if(handshake_len + 12 > block_len) {
1780
14.9k
    int rc;
1781
1782
#ifdef DEBUG_TLS
1783
          printf("[TLS] DTLS fragment off %d len %d\n", handshake_frag_off, handshake_frag_len);
1784
#endif
1785
14.9k
          if(handshake_frag_len + 12 > block_len) {
1786
#ifdef DEBUG_TLS
1787
            printf("[TLS] DTLS fragment invalid len %d + 12 > %d\n", handshake_frag_len, block_len);
1788
#endif
1789
3.70k
            no_dtls = 1;
1790
3.70k
            break;
1791
3.70k
    }
1792
1793
11.2k
          if(handshake_frag_off == 0) {
1794
5.29k
            rc = ndpi_search_tls_memory(&block[13],
1795
5.29k
          handshake_frag_len + 12,
1796
5.29k
          handshake_frag_off, message);
1797
5.96k
    } else {
1798
5.96k
            rc = ndpi_search_tls_memory(&block[13 + 12],
1799
5.96k
          handshake_frag_len,
1800
5.96k
          handshake_frag_off + 12, message);
1801
5.96k
    }
1802
11.2k
    if(rc == -1) {
1803
71
            no_dtls = 1;
1804
71
            break;
1805
71
    }
1806
#ifdef DEBUG_TLS
1807
          printf("[TLS] DTLS reassembled len %d vs %d\n",
1808
                 message->buffer_used, handshake_len + 12);
1809
#endif
1810
1811
11.1k
          if(handshake_len + 12 == message->buffer_used) {
1812
886
            packet->payload = message->buffer;
1813
886
            packet->payload_packet_len = message->buffer_used;
1814
886
            processHandshakeTLSBlock(ndpi_struct, flow);
1815
1816
886
            ndpi_free(message->buffer);
1817
886
            memset(message, '\0', sizeof(*message));
1818
886
            message = NULL;
1819
10.3k
          } else {
1820
            /* No break, next fragments might be in the same packet */
1821
10.3k
          }
1822
1823
11.1k
        } else {
1824
#ifdef DEBUG_TLS
1825
          printf("[TLS] DTLS invalid handshake_len %d, %d\n",
1826
                 handshake_len, block_len);
1827
#endif
1828
1.38k
          no_dtls = 1;
1829
1.38k
          break;
1830
1.38k
        }
1831
131k
      }
1832
138k
    } else if(block[0] == 0x14) {
1833
      /* Change-cipher-spec: any subsequent block might be encrypted */
1834
#ifdef DEBUG_TLS
1835
      printf("[TLS] Change-cipher-spec\n");
1836
#endif
1837
739
      change_cipher_found = 1;
1838
739
      processed += block_len + 13;
1839
739
      flow->tls_quic.certificate_processed = 1; /* Fake, to avoid extra dissection */
1840
739
      break;
1841
8.31k
    } else if(block[0] == 0x15 /* Alert */) {
1842
#ifdef DEBUG_TLS
1843
      printf("[TLS] TLS Alert\n");
1844
#endif
1845
1846
6.08k
      if(block_len == 2) {
1847
2.93k
       u_int8_t alert_level = block[13];
1848
1849
2.93k
       if(alert_level == 2 /* Warning (1), Fatal (2) */)
1850
673
         ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_FATAL_ALERT, "Found fatal TLS alert");
1851
2.93k
      }
1852
6.08k
    } else {
1853
#ifdef DEBUG_TLS
1854
      printf("[TLS] Application Data\n");
1855
#endif
1856
2.22k
      processed += block_len + 13;
1857
      /* DTLS mid session: no need to further inspect the flow */
1858
2.22k
      ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_DTLS, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
1859
1860
2.22k
      ndpi_master_app_protocol proto;
1861
2.22k
      proto.master_protocol = ndpi_get_master_proto(ndpi_struct, flow);
1862
2.22k
      proto.app_protocol = NDPI_PROTOCOL_UNKNOWN;
1863
2.22k
      flow->category = get_proto_category(ndpi_struct, proto);
1864
2.22k
      flow->breed = get_proto_breed(ndpi_struct, proto);
1865
1866
2.22k
      flow->tls_quic.certificate_processed = 1; /* Fake, to avoid extra dissection */
1867
2.22k
      break;
1868
2.22k
    }
1869
1870
139k
    processed += block_len + 13;
1871
139k
  }
1872
1873
1.25M
  if(processed != p_len && message == NULL /* No pending reassembler */) {
1874
#ifdef DEBUG_TLS
1875
    printf("[TLS] DTLS invalid processed len %d/%d (%d)\n", processed, p_len, change_cipher_found);
1876
#endif
1877
1.13M
    if(!change_cipher_found)
1878
1.13M
      no_dtls = 1;
1879
1.13M
  }
1880
1881
1.25M
  packet->payload = p;
1882
1.25M
  packet->payload_packet_len = p_len; /* Restore */
1883
1884
1.25M
  if(no_dtls || change_cipher_found || flow->tls_quic.certificate_processed) {
1885
1.16M
    return(0); /* That's all */
1886
1.16M
  } else {
1887
89.4k
    return(1); /* Keep working */
1888
89.4k
  }
1889
1.25M
}
1890
1891
/* **************************************** */
1892
1893
static void tlsInitExtraPacketProcessing(struct ndpi_detection_module_struct *ndpi_struct,
1894
156k
           struct ndpi_flow_struct *flow) {
1895
156k
  struct ndpi_packet_struct *packet = &ndpi_struct->packet;
1896
1897
  /* At most 12 packets should almost always be enough to find the server certificate if it's there.
1898
     Exception: DTLS traffic with fragments, retransmissions and STUN packets */
1899
156k
  flow->max_extra_packets_to_check = ((packet->udp != NULL) ? 20 : 12) + (ndpi_struct->cfg.tls_max_num_blocks_to_analyze*4);
1900
156k
  flow->extra_packets_func = (packet->udp != NULL) ? ndpi_search_dtls : ndpi_search_tls_tcp;
1901
156k
}
1902
1903
/* **************************************** */
1904
1905
void switch_extra_dissection_to_tls(struct ndpi_detection_module_struct *ndpi_struct,
1906
            struct ndpi_flow_struct *flow)
1907
187
{
1908
#ifdef DEBUG_TLS
1909
  printf("Switching to TLS extra dissection\n");
1910
#endif
1911
1912
  /* Reset reassemblers */
1913
187
  if(flow->tls_quic.message[0].buffer)
1914
67
    ndpi_free(flow->tls_quic.message[0].buffer);
1915
187
  memset(&flow->tls_quic.message[0], '\0', sizeof(flow->tls_quic.message[0]));
1916
187
  if(flow->tls_quic.message[1].buffer)
1917
97
    ndpi_free(flow->tls_quic.message[1].buffer);
1918
187
  memset(&flow->tls_quic.message[1], '\0', sizeof(flow->tls_quic.message[1]));
1919
1920
187
  flow->tls_quic.from_opportunistic_tls = 1;
1921
1922
187
  tlsInitExtraPacketProcessing(ndpi_struct, flow);
1923
187
}
1924
1925
/* **************************************** */
1926
1927
void switch_to_tls(struct ndpi_detection_module_struct *ndpi_struct,
1928
       struct ndpi_flow_struct *flow, int first_time)
1929
79.7k
{
1930
#ifdef DEBUG_TLS
1931
  printf("Switching to TLS\n");
1932
#endif
1933
1934
79.7k
  if(first_time) {
1935
    /* Reset reassemblers */
1936
26.8k
    if(flow->tls_quic.message[0].buffer)
1937
2.90k
      ndpi_free(flow->tls_quic.message[0].buffer);
1938
26.8k
    memset(&flow->tls_quic.message[0], '\0', sizeof(flow->tls_quic.message[0]));
1939
26.8k
    if(flow->tls_quic.message[1].buffer)
1940
2.80k
      ndpi_free(flow->tls_quic.message[1].buffer);
1941
26.8k
    memset(&flow->tls_quic.message[1], '\0', sizeof(flow->tls_quic.message[1]));
1942
1943
    /* We will not check obfuscated heuristic (anymore) because we have been
1944
       called from the STUN code, but we need to clear the previous state
1945
       (if any) to trigger "standard" TLS/DTLS code */
1946
26.8k
    if(flow->tls_quic.obfuscated_heur_state) {
1947
1.63k
      ndpi_free(flow->tls_quic.obfuscated_heur_state);
1948
1.63k
      flow->tls_quic.obfuscated_heur_state = NULL;
1949
1.63k
    }
1950
26.8k
  }
1951
1952
79.7k
  ndpi_search_tls_wrapper(ndpi_struct, flow);
1953
79.7k
}
1954
1955
/* **************************************** */
1956
1957
static void tls_subclassify_by_alpn(struct ndpi_detection_module_struct *ndpi_struct,
1958
13.8k
            struct ndpi_flow_struct *flow) {
1959
  /* Right now we have only one rule so we can keep it trivial */
1960
1961
13.8k
  if(strlen(flow->protos.tls_quic.advertised_alpns) > NDPI_STATICSTRING_LEN("anydesk/") &&
1962
8.87k
     strncmp(flow->protos.tls_quic.advertised_alpns, "anydesk/", NDPI_STATICSTRING_LEN("anydesk/")) == 0) {
1963
#ifdef DEBUG_TLS
1964
    printf("Matching ANYDESK via alpn\n");
1965
#endif
1966
221
    ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_ANYDESK,
1967
221
             ndpi_get_master_proto(ndpi_struct, flow), NDPI_CONFIDENCE_DPI);
1968
221
    flow->protos.tls_quic.subprotocol_detected = 1;
1969
221
  }
1970
13.8k
}
1971
1972
/* **************************************** */
1973
1974
static void tlsCheckUncommonALPN(struct ndpi_detection_module_struct *ndpi_struct,
1975
         struct ndpi_flow_struct *flow,
1976
66.0k
         char *alpn_start) {
1977
66.0k
  char * comma_or_nul = alpn_start;
1978
1979
104k
  do {
1980
104k
    size_t alpn_len;
1981
1982
104k
    comma_or_nul = strchr(comma_or_nul, ',');
1983
1984
104k
    if(comma_or_nul == NULL)
1985
62.3k
      comma_or_nul = alpn_start + strlen(alpn_start);
1986
1987
104k
    alpn_len = comma_or_nul - alpn_start;
1988
1989
104k
    if(!is_a_common_alpn(ndpi_struct, alpn_start, alpn_len)) {
1990
11.2k
      if(is_flowrisk_info_enabled(ndpi_struct, NDPI_TLS_UNCOMMON_ALPN)) {
1991
10.5k
        char str[64];
1992
10.5k
        size_t str_len;
1993
1994
#ifdef DEBUG_TLS
1995
        printf("TLS uncommon ALPN found: %.*s\n", (int)alpn_len, alpn_start);
1996
#endif
1997
1998
10.5k
        str[0] = '\0';
1999
10.5k
        str_len = ndpi_min(alpn_len, sizeof(str));
2000
10.5k
        if(str_len > 0) {
2001
6.50k
          strncpy(str, alpn_start, str_len);
2002
6.50k
          str[str_len - 1] = '\0';
2003
6.50k
        }
2004
2005
10.5k
        ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_UNCOMMON_ALPN, str);
2006
10.5k
      } else {
2007
670
        ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_UNCOMMON_ALPN, NULL);
2008
670
      }
2009
11.2k
      break;
2010
11.2k
    }
2011
2012
93.5k
    alpn_start = comma_or_nul + 1;
2013
93.5k
  } while (*(comma_or_nul++) != '\0');
2014
66.0k
}
2015
2016
/* **************************************** */
2017
2018
static void ndpi_int_tls_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
2019
347k
          struct ndpi_flow_struct *flow) {
2020
347k
  u_int32_t protocol;
2021
2022
#if DEBUG_TLS
2023
  printf("[TLS] %s()\n", __FUNCTION__);
2024
#endif
2025
2026
347k
  if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_RDP) {
2027
    /* RDP over TLS */
2028
377
    ndpi_set_detected_protocol(ndpi_struct, flow,
2029
377
             NDPI_PROTOCOL_RDP, NDPI_PROTOCOL_TLS, NDPI_CONFIDENCE_DPI);
2030
377
    return;
2031
377
  }
2032
2033
346k
  if((flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) ||
2034
227k
     (flow->detected_protocol_stack[1] != NDPI_PROTOCOL_UNKNOWN)) {
2035
227k
    if(!flow->extra_packets_func)
2036
39.5k
      tlsInitExtraPacketProcessing(ndpi_struct, flow);
2037
2038
227k
    return;
2039
227k
  }
2040
2041
119k
  protocol = ndpi_get_master_proto(ndpi_struct, flow);
2042
2043
119k
  ndpi_set_detected_protocol(ndpi_struct, flow, protocol, protocol, NDPI_CONFIDENCE_DPI);
2044
  /* We don't want to ovewrite STUN extra dissection, if enabled */
2045
119k
  if(!flow->extra_packets_func)
2046
116k
    tlsInitExtraPacketProcessing(ndpi_struct, flow);
2047
119k
}
2048
2049
/* **************************************** */
2050
2051
static void checkExtensions(struct ndpi_detection_module_struct *ndpi_struct,
2052
          struct ndpi_flow_struct * const flow, int is_dtls,
2053
                            u_int16_t extension_id, u_int16_t extension_len,
2054
1.78M
          u_int16_t extension_payload_offset) {
2055
1.78M
  struct ndpi_packet_struct const * const packet = &ndpi_struct->packet;
2056
2057
1.78M
  if((extension_payload_offset + extension_len) > packet->payload_packet_len) {
2058
#ifdef DEBUG_TLS
2059
      printf("[TLS] extension length exceeds remaining packet length: %u > %u.\n",
2060
       extension_len, packet->payload_packet_len - extension_payload_offset);
2061
#endif
2062
65.8k
      ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_EXTENSION, "Invalid extension len");
2063
65.8k
      return;
2064
65.8k
    }
2065
2066
  /* see: https://www.wireshark.org/docs/wsar_html/packet-tls-utils_8h_source.html */
2067
1.71M
  static u_int16_t const allowed_non_iana_extensions[] = {
2068
1.71M
      /* 65486 ESNI is suspicious nowadays */ 13172 /* NPN - Next Proto Neg */,
2069
1.71M
      30032 /* Channel ID */, 65445 /* QUIC transport params */,
2070
      /* GREASE extensions */
2071
1.71M
      2570, 6682, 10794, 14906, 19018, 23130, 27242,
2072
1.71M
      31354, 35466, 39578, 43690, 47802, 51914, 56026,
2073
1.71M
      60138, 64250,
2074
      /* Groups */
2075
1.71M
      1035, 10794, 16696, 23130, 31354, 35466, 51914,
2076
      /* Ciphers */
2077
1.71M
      102, 129, 52243, 52244, 57363, 65279, 65413,
2078
      /* ALPS */
2079
1.71M
      17513, 17613
2080
1.71M
  };
2081
1.71M
  size_t const allowed_non_iana_extensions_size = sizeof(allowed_non_iana_extensions) /
2082
1.71M
    sizeof(allowed_non_iana_extensions[0]);
2083
2084
  /* see: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml */
2085
  /* 65281 renegotiation_info, 65037 ECH */
2086
1.71M
  if(extension_id > 59 && extension_id != 65281 && extension_id != 65037)
2087
281k
    {
2088
281k
      u_int8_t extension_found = 0;
2089
281k
      size_t i;
2090
2091
7.97M
      for (i = 0; i < allowed_non_iana_extensions_size; ++i) {
2092
7.79M
  if(allowed_non_iana_extensions[i] == extension_id) {
2093
100k
    extension_found = 1;
2094
100k
    break;
2095
100k
  }
2096
7.79M
      }
2097
2098
281k
      if(extension_found == 0) {
2099
#ifdef DEBUG_TLS
2100
        printf("[TLS] suspicious extension id: %u\n", extension_id);
2101
#endif
2102
2103
180k
        if(is_flowrisk_info_enabled(ndpi_struct, NDPI_TLS_SUSPICIOUS_EXTENSION)) {
2104
176k
    char str[64];
2105
2106
176k
    snprintf(str, sizeof(str), "Extn id %u", extension_id);
2107
176k
    ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_EXTENSION, str);
2108
176k
        } else {
2109
4.02k
          ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_EXTENSION, NULL);
2110
4.02k
        }
2111
180k
  return;
2112
180k
      }
2113
281k
    }
2114
2115
  /* Check for DTLS-only extensions. */
2116
1.53M
  if(is_dtls == 0)
2117
1.12M
    {
2118
1.12M
      if(extension_id == 53 || extension_id == 54)
2119
1.25k
  {
2120
#ifdef DEBUG_TLS
2121
          printf("[TLS] suspicious DTLS-only extension id: %u\n", extension_id);
2122
#endif
2123
2124
1.25k
          if(is_flowrisk_info_enabled(ndpi_struct, NDPI_TLS_SUSPICIOUS_EXTENSION)) {
2125
1.22k
      char str[64];
2126
2127
1.22k
      snprintf(str, sizeof(str), "Extn id %u", extension_id);
2128
1.22k
      ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_EXTENSION, str);
2129
1.22k
          } else {
2130
38
            ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_SUSPICIOUS_EXTENSION, NULL);
2131
38
          }
2132
1.25k
    return;
2133
1.25k
  }
2134
1.12M
    }
2135
1.53M
}
2136
2137
/* **************************************** */
2138
2139
11.8M
static int u_int16_t_cmpfunc(const void * a, const void * b) { return(*(u_int16_t*)a - *(u_int16_t*)b); }
2140
2141
247k
static bool is_grease_version(u_int16_t version) {
2142
247k
  switch(version) {
2143
3.03k
  case 0x0a0a:
2144
10.6k
  case 0x1a1a:
2145
13.2k
  case 0x2a2a:
2146
15.9k
  case 0x3a3a:
2147
18.1k
  case 0x4a4a:
2148
19.6k
  case 0x5a5a:
2149
22.2k
  case 0x6a6a:
2150
24.7k
  case 0x7a7a:
2151
26.9k
  case 0x8a8a:
2152
29.9k
  case 0x9a9a:
2153
32.4k
  case 0xaaaa:
2154
35.1k
  case 0xbaba:
2155
38.5k
  case 0xcaca:
2156
40.8k
  case 0xdada:
2157
57.3k
  case 0xeaea:
2158
62.6k
  case 0xfafa:
2159
62.6k
    return(true);
2160
2161
184k
  default:
2162
184k
    return(false);
2163
247k
  }
2164
247k
}
2165
2166
/* **************************************** */
2167
2168
bool skipTLSextension(struct ndpi_detection_module_struct *ndpi_struct,
2169
2.30M
          u_int16_t extension_id)  {
2170
2.30M
  if((extension_id == 0x0 /* SNI */) && ndpi_struct->cfg.tls_ndpifp_ignore_sni_extension)
2171
285k
    return(true);
2172
2173
2.02M
  if(ndpi_struct->cfg.tls_ja_ignore_ephemeral_extensions) {
2174
1.53M
    switch(extension_id) {
2175
80.6k
    case 0x23: /* session ticket - RFC 9149 */
2176
91.9k
    case 0x29: /* pre-shared key - RFC 8446 */
2177
126k
    case 0x15: /* padding        - RFC 7685 */
2178
      /* Noisy extensions */
2179
218k
    case 0x2b: /* Supported TLS versions    */
2180
363k
    case 0x0a: /* Supported groups          */
2181
363k
      return(true);
2182
1.53M
    }
2183
1.53M
  }
2184
2185
1.65M
  return(false);
2186
2.02M
}
2187
2188
/* **************************************** */
2189
2190
static void ndpi_fill_version_str(char *ja_str,
2191
219k
          u_int16_t tls_handshake_version) {
2192
219k
  switch(tls_handshake_version) {
2193
42.7k
  case 0x0304: /* TLS 1.3 = “13” */
2194
42.7k
    ja_str[1] = '1';
2195
42.7k
    ja_str[2] = '3';
2196
42.7k
    break;
2197
2198
78.1k
  case 0x0303: /* TLS 1.2 = “12” */
2199
78.1k
    ja_str[1] = '1';
2200
78.1k
    ja_str[2] = '2';
2201
78.1k
    break;
2202
2203
2.04k
  case 0x0302: /* TLS 1.1 = “11” */
2204
2.04k
    ja_str[1] = '1';
2205
2.04k
    ja_str[2] = '1';
2206
2.04k
    break;
2207
2208
15.2k
  case 0x0301: /* TLS 1.0 = “10” */
2209
15.2k
    ja_str[1] = '1';
2210
15.2k
    ja_str[2] = '0';
2211
15.2k
    break;
2212
3.72k
  case 0x0300: /* SSL 3.0 = “s3” */
2213
3.72k
    ja_str[1] = 's';
2214
3.72k
    ja_str[2] = '3';
2215
3.72k
    break;
2216
2217
858
  case 0x0002: /* SSL 2.0 = “s2” */
2218
858
    ja_str[1] = 's';
2219
858
    ja_str[2] = '2';
2220
858
    break;
2221
2222
3.62k
  case 0xFEFF: /* DTLS 1.0 = “d1” */
2223
3.62k
    ja_str[1] = 'd';
2224
3.62k
    ja_str[2] = '1';
2225
3.62k
    break;
2226
2227
23.3k
  case 0xFEFD: /* DTLS 1.2 = “d2” */
2228
23.3k
    ja_str[1] = 'd';
2229
23.3k
    ja_str[2] = '2';
2230
23.3k
    break;
2231
1.69k
  case 0xFEFC: /* DTLS 1.3 = “d3” */
2232
1.69k
    ja_str[1] = 'd';
2233
1.69k
    ja_str[2] = '3';
2234
1.69k
    break;
2235
2236
47.4k
  default:
2237
47.4k
    ja_str[1] = '0';
2238
47.4k
    ja_str[2] = '0';
2239
47.4k
    break;
2240
219k
  }
2241
219k
}
2242
2243
/* **************************************** */
2244
2245
static void ndpi_compute_ja4(struct ndpi_detection_module_struct *ndpi_struct,
2246
           struct ndpi_flow_struct *flow,
2247
           u_int32_t quic_version,
2248
161k
           union ndpi_ja_info *ja) {
2249
161k
  u_int8_t tmp_str[JA_STR_LEN], tmp_ndpi_str[512];
2250
161k
  u_int tmp_str_len, tmp_ndpi_str_len = 0, num_extn, num_ndpi_extn;
2251
161k
  u_int8_t sha_hash[NDPI_SHA256_BLOCK_SIZE];
2252
161k
  u_int16_t ja_str_len, i, ja_offset;
2253
161k
  int rc;
2254
161k
  u_int16_t tls_handshake_version = ja->client.tls_handshake_version;
2255
161k
  char * const ja_str = &flow->protos.tls_quic.ja4_client[0];
2256
161k
  char * const ja_ndpi_str = &flow->protos.tls_quic.ja4_ndpi_client[0];
2257
161k
  const u_int16_t ja_max_len = sizeof(flow->protos.tls_quic.ja4_client);
2258
161k
  bool is_dtls = ((flow->l4_proto == IPPROTO_UDP) && (quic_version == 0)) || flow->stun.maybe_dtls;
2259
161k
  int ja4_r_len = 0;
2260
161k
  char ja4_r[1024];
2261
2262
  /*
2263
    Compute JA4 TLS/QUIC client
2264
2265
    https://github.com/FoxIO-LLC/ja4/blob/main/technical_details/JA4.md
2266
2267
    (QUIC=”q”, DTLS="d" or TCP=”t”)
2268
    (2 character TLS version)
2269
    (SNI=”d” or no SNI=”i”)
2270
    (2 character count of ciphers)
2271
    (2 character count of extensions)
2272
    (first and last characters of first ALPN extension value)
2273
    _
2274
    (sha256 hash of the list of cipher hex codes sorted in hex order, truncated to 12 characters)
2275
    _
2276
    (sha256 hash of (the list of extension hex codes sorted in hex order)
2277
    _
2278
    (the list of signature algorithms), truncated to 12 characters)
2279
  */
2280
161k
  ja_str[0] = is_dtls ? 'd' : ((quic_version != 0) ? 'q' : 't');
2281
2282
409k
  for(i=0; i<ja->client.num_supported_versions; i++) {
2283
247k
    if((!is_grease_version(ja->client.supported_version[i]))
2284
184k
       && (tls_handshake_version < ja->client.supported_version[i]))
2285
56.9k
      tls_handshake_version = ja->client.supported_version[i];
2286
247k
  }
2287
2288
161k
  ndpi_fill_version_str(ja_str, tls_handshake_version);
2289
2290
  /* Check if SNI extension exists at all */
2291
161k
  if(flow->host_server_name[0] == '\0') {
2292
63.6k
    ja_str[3] = 'i';  /* No SNI extension */
2293
98.3k
  } else if(ndpi_isset_risk(flow, NDPI_NUMERIC_IP_HOST)) {
2294
694
    ja_str[3] = 'i';  /* SNI contains IP address */
2295
97.6k
  } else {
2296
97.6k
    ja_str[3] = 'd';  /* SNI contains domain name */
2297
97.6k
  }
2298
161k
  ja_str_len = 4;
2299
2300
  /* JA4_a */
2301
  /* first + last character of the ALPN string (or '0' if missing) */
2302
161k
  char alpn_first = (ja->client.alpn[0] != '\0') ? ja->client.alpn[0] : '0';
2303
161k
  char alpn_last  = ja->client.alpn_original_last;  /* Use original last character before null terminator */
2304
2305
#ifdef DEBUG_JA
2306
  size_t alpn_len = strlen(ja->client.alpn);
2307
  printf("[JA4 DEBUG] ALPN string: '%s' (len=%zu)\n", ja->client.alpn, alpn_len);
2308
  printf("[JA4 DEBUG] First='%c', Last='%c'\n", alpn_first, alpn_last);
2309
#endif
2310
2311
161k
  rc = ndpi_snprintf(&ja_str[ja_str_len], ja_max_len - ja_str_len,
2312
161k
         "%02u%02u%c%c_",
2313
161k
         ndpi_min(99, ja->client.num_ciphers),
2314
161k
         ndpi_min(99, ja->client.num_tls_extensions),
2315
161k
         alpn_first, alpn_last);
2316
161k
  if((rc > 0) && (ja_str_len + rc < JA_STR_LEN)) ja_str_len += rc;
2317
2318
  /* Sort ciphers and extensions */
2319
161k
  qsort(&ja->client.cipher, ja->client.num_ciphers, sizeof(u_int16_t), u_int16_t_cmpfunc);
2320
161k
  qsort(&ja->client.tls_extension, ja->client.num_tls_extensions, sizeof(u_int16_t), u_int16_t_cmpfunc);
2321
2322
161k
  tmp_str_len = 0;
2323
2.63M
  for(i=0; i<ja->client.num_ciphers; i++) {
2324
#ifdef JA4R_DECIMAL
2325
    rc = snprintf(&ja4_r[ja4_r_len], sizeof(ja4_r)-ja4_r_len, "%s%u", (i > 0) ? "," : "", ja->client.cipher[i]);
2326
    if(rc > 0) ja4_r_len += rc;
2327
#endif
2328
2.47M
    rc = ndpi_snprintf((char *)&tmp_str[tmp_str_len], JA_STR_LEN-tmp_str_len, "%s%04x",
2329
2.47M
           (i > 0) ? "," : "", ja->client.cipher[i]);
2330
2.47M
    if((rc > 0) && (tmp_str_len + rc < JA_STR_LEN)) tmp_str_len += rc; else break;
2331
2.47M
  }
2332
2333
161k
#ifndef JA4R_DECIMAL
2334
161k
  ja_str[ja_str_len] = 0;
2335
161k
  i = snprintf(&ja4_r[ja4_r_len], sizeof(ja4_r)-ja4_r_len, "%s", ja_str); if(i > 0) ja4_r_len += i;
2336
2337
161k
  tmp_str[tmp_str_len] = 0;
2338
161k
  i = snprintf(&ja4_r[ja4_r_len], sizeof(ja4_r)-ja4_r_len, "%s_", tmp_str); if(i > 0) ja4_r_len += i;
2339
161k
#endif
2340
2341
161k
  if(ja->client.num_ciphers > 0) {
2342
127k
    ndpi_sha256(tmp_str, tmp_str_len, sha_hash);
2343
127k
  } else {
2344
34.8k
    memset(sha_hash, '\0', 6);
2345
34.8k
  }
2346
2347
161k
  rc = ndpi_snprintf(&ja_str[ja_str_len], ja_max_len - ja_str_len,
2348
161k
         "%02x%02x%02x%02x%02x%02x_",
2349
161k
         sha_hash[0], sha_hash[1], sha_hash[2],
2350
161k
         sha_hash[3], sha_hash[4], sha_hash[5]);
2351
161k
  if((rc > 0) && (ja_str_len + rc < JA_STR_LEN)) ja_str_len += rc;
2352
2353
#ifdef DEBUG_JA
2354
  printf("[CIPHER] %s [len: %u]\n", tmp_str, tmp_str_len);
2355
#endif
2356
2357
#ifdef JA4R_DECIMAL
2358
  rc = snprintf(&ja4_r[ja4_r_len], sizeof(ja4_r)-ja4_r_len, "_");
2359
  if(rc > 0) ja4_r_len += rc;
2360
#endif
2361
2362
161k
  tmp_str_len = 0;
2363
1.48M
  for(i=0, num_extn = num_ndpi_extn = 0; i<ja->client.num_tls_extensions; i++) {
2364
1.32M
    if((ja->client.tls_extension[i] > 0) && (ja->client.tls_extension[i] != 0x10 /* ALPN extension */)) {
2365
#ifdef JA4R_DECIMAL
2366
      rc = snprintf(&ja4_r[ja4_r_len], sizeof(ja4_r)-ja4_r_len, "%s%u", (num_extn > 0) ? "," : "", ja->client.tls_extension[i]);
2367
      if((rc > 0) && (ja4_r_len + rc < JA_STR_LEN)) ja4_r_len += rc; else break;
2368
#endif
2369
2370
893k
      rc = ndpi_snprintf((char *)&tmp_str[tmp_str_len], JA_STR_LEN-tmp_str_len, "%s%04x",
2371
893k
       (num_extn > 0) ? "," : "", ja->client.tls_extension[i]);
2372
893k
      if((rc > 0) && (tmp_str_len + rc < JA_STR_LEN)) tmp_str_len += rc; else break;
2373
893k
      num_extn++;
2374
2375
893k
      if(!skipTLSextension(ndpi_struct, ja->client.tls_extension[i])) {
2376
713k
  rc = ndpi_snprintf((char *)&tmp_ndpi_str[tmp_ndpi_str_len], sizeof(tmp_ndpi_str)-tmp_ndpi_str_len, "%s%04x",
2377
713k
         (num_ndpi_extn > 0) ? "," : "", ja->client.tls_extension[i]);
2378
713k
  if((rc > 0) && (tmp_ndpi_str_len + rc < sizeof(tmp_ndpi_str))) tmp_ndpi_str_len += rc; else break;
2379
713k
  num_ndpi_extn++;
2380
713k
      }
2381
893k
    }
2382
1.32M
  }
2383
2384
1.24M
  for(i=0; i<ja->client.num_signature_algorithms; i++) {
2385
1.08M
    rc = ndpi_snprintf((char *)&tmp_str[tmp_str_len], JA_STR_LEN-tmp_str_len, "%s%04x",
2386
1.08M
           (i > 0) ? "," : "_", ja->client.signature_algorithm[i]);
2387
1.08M
    if((rc > 0) && (tmp_str_len + rc < JA_STR_LEN)) tmp_str_len += rc; else break;
2388
2389
1.08M
    rc = ndpi_snprintf((char *)&tmp_ndpi_str[tmp_ndpi_str_len], sizeof(tmp_ndpi_str)-tmp_ndpi_str_len, "%s%04x",
2390
1.08M
           (i > 0) ? "," : "_", ja->client.signature_algorithm[i]);
2391
1.08M
    if((rc > 0) && (tmp_ndpi_str_len + rc < sizeof(tmp_ndpi_str))) tmp_ndpi_str_len += rc; else break;
2392
1.08M
  }
2393
2394
#ifdef DEBUG_JA
2395
  printf("[EXTN] %s [len: %u]\n", tmp_str, tmp_str_len);
2396
#endif
2397
2398
#ifdef DEBUG_NDPIFP
2399
  printf("[EXTN] %s [len: %u]\n", tmp_ndpi_str, tmp_ndpi_str_len);
2400
#endif
2401
2402
161k
  tmp_str[tmp_str_len] = 0;
2403
2404
161k
#ifndef JA4R_DECIMAL
2405
161k
  i = snprintf(&ja4_r[ja4_r_len], sizeof(ja4_r)-ja4_r_len, "%s", tmp_str);
2406
161k
  if(i > 0) ja4_r_len += i;
2407
161k
#endif
2408
2409
161k
  if(ndpi_struct->cfg.tls_ja4r_fingerprint_enabled) {
2410
114k
    if(flow->protos.tls_quic.ja4_client_raw == NULL)
2411
90.1k
      flow->protos.tls_quic.ja4_client_raw = ndpi_strdup(ja4_r);
2412
#ifdef DEBUG_JA
2413
    printf("[JA4_r] %s [len: %u]\n", ja4_r, ja4_r_len);
2414
#endif
2415
114k
  }
2416
2417
161k
  if(ja->client.num_tls_extensions > 0)
2418
146k
    ndpi_sha256(tmp_str, tmp_str_len, sha_hash);
2419
14.9k
  else
2420
14.9k
    memset(sha_hash, '\0', 6);
2421
2422
161k
  ja_offset = ja_str_len;
2423
161k
  rc = ndpi_snprintf(&ja_str[ja_str_len], ja_max_len - ja_str_len,
2424
161k
         "%02x%02x%02x%02x%02x%02x",
2425
161k
         sha_hash[0], sha_hash[1], sha_hash[2],
2426
161k
         sha_hash[3], sha_hash[4], sha_hash[5]);
2427
161k
  if((rc > 0) && (ja_str_len + rc < JA_STR_LEN)) ja_str_len += rc;
2428
161k
  ja_str[36] = 0;
2429
2430
  /* nDPI */
2431
161k
  if(ja->client.num_tls_extensions > 0)
2432
146k
    ndpi_sha256(tmp_ndpi_str, tmp_ndpi_str_len, sha_hash);
2433
14.9k
  else
2434
14.9k
    memset(sha_hash, '\0', 6);
2435
2436
161k
  ja_str_len = ja_offset;
2437
161k
  strncpy(ja_ndpi_str, ja_str, ja_str_len);
2438
2439
  /* Overwrite the extensions number */
2440
161k
  ndpi_snprintf(&ja_ndpi_str[6], 2, "%02u", num_ndpi_extn);
2441
2442
161k
  rc = ndpi_snprintf(&ja_ndpi_str[ja_str_len], ja_max_len - ja_str_len,
2443
161k
         "%02x%02x%02x%02x%02x%02x",
2444
161k
         sha_hash[0], sha_hash[1], sha_hash[2],
2445
161k
         sha_hash[3], sha_hash[4], sha_hash[5]);
2446
161k
  if((rc > 0) && (ja_str_len + rc < JA_STR_LEN)) ja_str_len += rc;
2447
161k
  ja_ndpi_str[36] = 0;
2448
2449
#ifdef DEBUG_JA
2450
  printf("[JA4] %s [len: %lu]\n", ja_str, strlen(ja_str));
2451
#endif
2452
2453
#ifdef DEBUG_NDPIFP
2454
  printf("[EXTN] %s\n", ja_ndpi_str);
2455
#endif
2456
161k
}
2457
2458
/* **************************************** */
2459
2460
static void ndpi_compute_tls_server_fingerprint(struct ndpi_flow_struct *flow,
2461
                                                bool is_dtls,
2462
                                                u_int32_t quic_version,
2463
57.0k
                                                ndpi_tls_server_info *s) {
2464
57.0k
  char tls_s[128], fp_buf[13];
2465
57.0k
  u_int tls_s_len, i;
2466
57.0k
  u_int8_t sha_hash[NDPI_SHA256_BLOCK_SIZE];
2467
2468
57.0k
  tls_s[0] = is_dtls ? 'd' : ((quic_version != 0) ? 'q' : 't');
2469
57.0k
  ndpi_fill_version_str(tls_s, s->tls_handshake_version);
2470
57.0k
  tls_s_len = 3;
2471
2472
57.0k
  if(sizeof(tls_s) > tls_s_len) {
2473
57.0k
    int b_diff = sizeof(tls_s)-tls_s_len-1;
2474
2475
57.0k
    if(b_diff > 0) {
2476
57.0k
      int rc = ndpi_snprintf(&tls_s[tls_s_len], b_diff, "%02u_%s_%04x",
2477
57.0k
           s->num_tls_extensions,
2478
57.0k
           (s->alpn[0] == '\0') ? "00" : s->alpn,
2479
57.0k
           (s->num_ciphers > 0) ? s->cipher[0] : 0);
2480
2481
57.0k
      if(rc > 0)
2482
57.0k
  tls_s_len += rc;
2483
57.0k
    }
2484
57.0k
  }
2485
2486
57.0k
  if(sizeof(tls_s) > tls_s_len)
2487
57.0k
    tls_s[tls_s_len++] = '_';
2488
2489
183k
  for(i=0; i<s->num_tls_extensions; i++) {
2490
127k
    int b_diff = sizeof(tls_s)-tls_s_len-1;
2491
2492
127k
    if(b_diff > 0) {
2493
127k
      int rc = ndpi_snprintf(&tls_s[tls_s_len], b_diff, "%04x",
2494
127k
           s->tls_extension[i]);
2495
2496
127k
      if(rc <= 0)
2497
166
  break;
2498
126k
      else
2499
126k
  tls_s_len += rc;
2500
127k
    } else
2501
102
      break;
2502
127k
  }
2503
2504
57.0k
  if(sizeof(tls_s) > tls_s_len)
2505
57.0k
    tls_s[tls_s_len++] = '_';
2506
2507
57.0k
  if(s->num_elliptic_curve_point_format > 0) {
2508
67.9k
    for(i=0; i<s->num_elliptic_curve_point_format; i++) {
2509
53.4k
      int b_diff = sizeof(tls_s)-tls_s_len-1;
2510
2511
53.4k
      if(b_diff > 0) {
2512
53.3k
  int rc = ndpi_snprintf(&tls_s[tls_s_len], b_diff, "%04x",
2513
53.3k
             s->elliptic_curve_point_format[i]);
2514
2515
53.3k
  if(rc <= 0)
2516
589
    break;
2517
52.8k
  else
2518
52.8k
    tls_s_len += rc;
2519
53.3k
      } else
2520
98
  break;
2521
53.4k
    }
2522
41.8k
  } else {
2523
41.8k
    int b_diff = sizeof(tls_s)-tls_s_len-1;
2524
2525
41.8k
    if(b_diff > 0) {
2526
41.6k
      int rc = ndpi_snprintf(&tls_s[tls_s_len], b_diff, "%04x", 0);
2527
2528
41.6k
      if(rc > 0)
2529
41.6k
  tls_s_len += rc;
2530
41.6k
    }
2531
41.8k
  }
2532
2533
57.0k
  ndpi_sha256((const u_char *)tls_s, tls_s_len, sha_hash);
2534
2535
57.0k
  ndpi_snprintf(fp_buf, sizeof(fp_buf),
2536
57.0k
    "%02x%02x%02x%02x%02x%02x",
2537
57.0k
    sha_hash[0], sha_hash[1], sha_hash[2],
2538
57.0k
    sha_hash[3], sha_hash[4], sha_hash[5]);
2539
2540
57.0k
  flow->ndpi.server_fingerprint = ndpi_strdup((char*)fp_buf);
2541
57.0k
}
2542
2543
/* **************************************** */
2544
2545
int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
2546
270k
           struct ndpi_flow_struct *flow, u_int32_t quic_version) {
2547
270k
  struct ndpi_packet_struct *packet = &ndpi_struct->packet;
2548
270k
  union ndpi_ja_info ja;
2549
270k
  ndpi_tls_server_info *s = &ja.server;
2550
270k
  u_int8_t invalid_ja = 0;
2551
270k
  u_int16_t tls_version;
2552
270k
  u_int32_t i, j;
2553
270k
  u_int16_t total_len;
2554
270k
  u_int8_t handshake_type;
2555
270k
  bool is_quic = (quic_version != 0);
2556
270k
  bool is_dtls = (packet->udp && !is_quic) || flow->stun.maybe_dtls;
2557
2558
#ifdef DEBUG_TLS
2559
  printf("TLS %s() called\n", __FUNCTION__);
2560
#endif
2561
2562
270k
  handshake_type = packet->payload[0];
2563
270k
  total_len = (packet->payload[1] << 16) +  (packet->payload[2] << 8) + packet->payload[3];
2564
2565
270k
  if((total_len > packet->payload_packet_len) || (packet->payload[1] != 0x0))
2566
159
    return(0); /* Not found */
2567
2568
270k
  total_len = packet->payload_packet_len;
2569
2570
  /* At least "magic" 3 bytes, null for string end, otherwise no need to waste cpu cycles */
2571
270k
  if(total_len > 4) {
2572
269k
    u_int16_t base_offset    = (!is_dtls) ? 38 : 46;
2573
269k
    u_int16_t version_offset = (!is_dtls) ? 4 : 12;
2574
269k
    u_int16_t offset = (!is_dtls) ? 38 : 46;
2575
269k
    u_int32_t tot_extension_len;
2576
269k
    u_int8_t  session_id_len =  0;
2577
2578
269k
    if((base_offset >= total_len) ||
2579
268k
       (version_offset + 1) >= total_len)
2580
1.39k
      return 0; /* Not found */
2581
2582
268k
    session_id_len = packet->payload[base_offset];
2583
2584
#ifdef DEBUG_TLS
2585
    printf("TLS [len: %u][handshake_type: %02X]\n", packet->payload_packet_len, handshake_type);
2586
#endif
2587
2588
268k
    tls_version = ntohs(*((u_int16_t*)&packet->payload[version_offset]));
2589
2590
268k
    if(handshake_type == 0x02 /* Server Hello */) {
2591
80.9k
      int rc;
2592
2593
80.9k
      memset(&ja.server, 0, sizeof(ja.server));
2594
2595
80.9k
      ja.server.tls_handshake_version = tls_version;
2596
2597
#ifdef DEBUG_TLS
2598
      printf("TLS Server Hello [version: 0x%04X]\n", tls_version);
2599
#endif
2600
2601
      /*
2602
  The server hello decides about the TLS version of this flow
2603
  https://networkengineering.stackexchange.com/questions/55752/why-does-wireshark-show-version-tls-1-2-here-instead-of-tls-1-3
2604
      */
2605
80.9k
      if(packet->udp)
2606
18.1k
  offset += session_id_len + 1;
2607
62.8k
      else {
2608
62.8k
  if(tls_version < 0x7F15 /* TLS 1.3 lacks of session id */)
2609
55.6k
    offset += session_id_len+1;
2610
62.8k
      }
2611
2612
80.9k
      if((offset+3) > packet->payload_packet_len)
2613
3.89k
  return(0); /* Not found */
2614
2615
77.0k
      ja.server.num_ciphers = 1, ja.server.cipher[0] = ntohs(*((u_int16_t*)&packet->payload[offset]));
2616
2617
77.0k
      if(ndpi_struct->cfg.tls_cipher_enabled) {
2618
69.2k
        if((flow->protos.tls_quic.server_unsafe_cipher = ndpi_is_safe_ssl_cipher(ja.server.cipher[0])) != NDPI_CIPHER_SAFE) {
2619
15.9k
          if(is_flowrisk_info_enabled(ndpi_struct, NDPI_TLS_WEAK_CIPHER)) {
2620
14.9k
            char str[64];
2621
14.9k
            char unknown_cipher[8];
2622
2623
14.9k
            snprintf(str, sizeof(str), "Cipher %s", ndpi_cipher2str(ja.server.cipher[0], unknown_cipher));
2624
14.9k
            ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_WEAK_CIPHER, str);
2625
14.9k
          } else {
2626
994
            ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_WEAK_CIPHER, NULL);
2627
994
          }
2628
15.9k
        }
2629
2630
69.2k
        flow->protos.tls_quic.server_cipher = ja.server.cipher[0];
2631
69.2k
      }
2632
2633
#ifdef DEBUG_TLS
2634
      printf("TLS [server][session_id_len: %u][cipher: %04X]\n", session_id_len, ja.server.cipher[0]);
2635
#endif
2636
2637
77.0k
      offset += 2 + 1;
2638
2639
77.0k
      if((offset + 1) < packet->payload_packet_len) /* +1 because we are goint to read 2 bytes */
2640
71.0k
  tot_extension_len = ntohs(*((u_int16_t*)&packet->payload[offset]));
2641
6.01k
      else
2642
6.01k
  tot_extension_len = 0;
2643
2644
#ifdef DEBUG_TLS
2645
      printf("TLS [server][tot_extension_len: %u]\n", tot_extension_len);
2646
#endif
2647
77.0k
      offset += 2;
2648
2649
301k
      for(i=0; i<tot_extension_len; ) {
2650
269k
        u_int16_t extension_id;
2651
269k
        u_int32_t extension_len;
2652
2653
269k
  if((offset+4) > packet->payload_packet_len) break;
2654
2655
248k
  extension_id  = ntohs(*((u_int16_t*)&packet->payload[offset]));
2656
248k
  extension_len = ntohs(*((u_int16_t*)&packet->payload[offset+2]));
2657
248k
  if(offset+4+extension_len > packet->payload_packet_len) {
2658
22.9k
    break;
2659
22.9k
  }
2660
2661
225k
  if(ja.server.num_tls_extensions < MAX_NUM_JA)
2662
217k
    ja.server.tls_extension[ja.server.num_tls_extensions++] = extension_id;
2663
2664
#ifdef DEBUG_TLS
2665
  printf("TLS [server][extension_id: %u/0x%04X][len: %u]\n",
2666
         extension_id, extension_id, extension_len);
2667
#endif
2668
225k
  checkExtensions(ndpi_struct, flow, is_dtls, extension_id, extension_len, offset + 4);
2669
2670
225k
  if(extension_id == 43 /* supported versions */) {
2671
14.8k
    if(extension_len >= 2) {
2672
13.5k
      u_int16_t tls_version = ntohs(*((u_int16_t*)&packet->payload[offset+4]));
2673
2674
#ifdef DEBUG_TLS
2675
      printf("TLS [server] [TLS version: 0x%04X]\n", tls_version);
2676
#endif
2677
2678
13.5k
      flow->protos.tls_quic.ssl_version = ja.server.tls_supported_version = tls_version;
2679
13.5k
    }
2680
210k
  } else if(extension_id == 16 /* application_layer_protocol_negotiation (ALPN) */ &&
2681
23.1k
            offset + 6 < packet->payload_packet_len) {
2682
22.9k
    u_int16_t s_offset = offset+4;
2683
22.9k
    u_int16_t tot_alpn_len = ntohs(*((u_int16_t*)&packet->payload[s_offset]));
2684
22.9k
    char alpn_str[256];
2685
22.9k
    u_int16_t alpn_str_len = 0, i;
2686
2687
#ifdef DEBUG_TLS
2688
    printf("Server TLS [ALPN: block_len=%u/len=%u]\n", extension_len, tot_alpn_len);
2689
#endif
2690
22.9k
    s_offset += 2;
2691
22.9k
    tot_alpn_len += s_offset;
2692
2693
22.9k
    if(tot_alpn_len > packet->payload_packet_len)
2694
967
      return 0;
2695
2696
124k
    while(s_offset < tot_alpn_len && s_offset < total_len) {
2697
111k
      u_int8_t alpn_i, alpn_len = packet->payload[s_offset++];
2698
2699
111k
      if((s_offset + alpn_len) <= tot_alpn_len) {
2700
#ifdef DEBUG_TLS
2701
        printf("Server TLS [ALPN: %u]\n", alpn_len);
2702
#endif
2703
2704
102k
        if(((uint32_t)alpn_str_len+alpn_len+1) < (sizeof(alpn_str)-1)) {
2705
102k
          if(alpn_str_len > 0) {
2706
56.9k
            alpn_str[alpn_str_len] = ',';
2707
56.9k
            alpn_str_len++;
2708
56.9k
          }
2709
2710
342k
          for(alpn_i=0; alpn_i<alpn_len; alpn_i++) {
2711
240k
        alpn_str[alpn_str_len+alpn_i] = packet->payload[s_offset+alpn_i];
2712
240k
      }
2713
2714
102k
          s_offset += alpn_len, alpn_str_len += alpn_len;;
2715
102k
        } else {
2716
363
          alpn_str[alpn_str_len] = '\0';
2717
363
          ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_UNCOMMON_ALPN, alpn_str);
2718
363
          break;
2719
363
        }
2720
102k
      } else {
2721
8.34k
        alpn_str[alpn_str_len] = '\0';
2722
8.34k
        ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_UNCOMMON_ALPN, alpn_str);
2723
8.34k
        break;
2724
8.34k
      }
2725
111k
    } /* while */
2726
2727
21.9k
    alpn_str[alpn_str_len] = '\0';
2728
2729
#ifdef DEBUG_TLS
2730
    printf("Server TLS [ALPN: %s][len: %u]\n", alpn_str, alpn_str_len);
2731
#endif
2732
21.9k
    if(ndpi_normalize_printable_string(alpn_str, alpn_str_len) == 0)
2733
5.41k
      ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, alpn_str);
2734
2735
21.9k
    if(flow->protos.tls_quic.negotiated_alpn == NULL &&
2736
19.4k
       ndpi_struct->cfg.tls_alpn_negotiated_enabled)
2737
9.23k
      flow->protos.tls_quic.negotiated_alpn = ndpi_strdup(alpn_str);
2738
2739
    /* Check ALPN only if not already checked (client-side) */
2740
21.9k
    if(flow->protos.tls_quic.negotiated_alpn != NULL &&
2741
11.5k
       flow->protos.tls_quic.advertised_alpns == NULL)
2742
6.36k
      tlsCheckUncommonALPN(ndpi_struct, flow, flow->protos.tls_quic.negotiated_alpn);
2743
2744
21.9k
    alpn_str_len = ndpi_min(sizeof(ja.server.alpn), (size_t)alpn_str_len);
2745
21.9k
    memcpy(ja.server.alpn, alpn_str, alpn_str_len);
2746
21.9k
    if(alpn_str_len > 0)
2747
14.4k
      ja.server.alpn[alpn_str_len] = '\0';
2748
2749
    /* Replace , with - as in JA3 */
2750
498k
    for(i=0; ja.server.alpn[i] != '\0'; i++)
2751
476k
      if(ja.server.alpn[i] == ',') ja.server.alpn[i] = '-';
2752
187k
  } else if(extension_id == 11 /* ec_point_formats groups */) {
2753
21.2k
    u_int16_t s_offset = offset+4 + 1;
2754
2755
#ifdef DEBUG_TLS
2756
    printf("Server TLS [EllipticCurveFormat: len=%u]\n", extension_len);
2757
#endif
2758
21.2k
    if((s_offset+extension_len-1) <= total_len) {
2759
606k
      for(i=0; i<extension_len-1 && s_offset+i<packet->payload_packet_len; i++) {
2760
585k
        u_int8_t s_group = packet->payload[s_offset+i];
2761
2762
#ifdef DEBUG_TLS
2763
        printf("Server TLS [EllipticCurveFormat: %u]\n", s_group);
2764
#endif
2765
2766
585k
        if(ja.server.num_elliptic_curve_point_format < MAX_NUM_JA)
2767
202k
    ja.server.elliptic_curve_point_format[ja.server.num_elliptic_curve_point_format++] = s_group;
2768
382k
        else {
2769
382k
    invalid_ja = 1;
2770
#ifdef DEBUG_TLS
2771
    printf("Server TLS Invalid num elliptic %u\n", ja.server.num_elliptic_curve_point_format);
2772
#endif
2773
382k
        }
2774
585k
      }
2775
21.2k
    } else {
2776
0
      invalid_ja = 1;
2777
#ifdef DEBUG_TLS
2778
      printf("Server TLS Invalid len %u vs %u\n", s_offset+extension_len, total_len);
2779
#endif
2780
0
    }
2781
21.2k
  }
2782
2783
224k
  i += 4 + extension_len, offset += 4 + extension_len;
2784
224k
      } /* for */
2785
2786
      /* If the CH is not available and if "supported_versions" extension is not present in the SH
2787
         (i.e. (D)TLS <= 1.2), use the version field present in the record layer */
2788
76.1k
      if(flow->protos.tls_quic.ssl_version == 0)
2789
32.6k
        flow->protos.tls_quic.ssl_version = tls_version;
2790
2791
76.1k
      if(ndpi_struct->cfg.ndpi_server_fingerprint_enabled
2792
68.7k
   && (flow->ndpi.server_fingerprint == NULL))
2793
57.0k
  ndpi_compute_tls_server_fingerprint(flow, is_dtls, quic_version, s);
2794
2795
76.1k
      if(ndpi_struct->cfg.tls_ja3s_fingerprint_enabled) {
2796
68.7k
         u_int16_t ja_str_len;
2797
68.7k
         char ja_str[JA_STR_LEN];
2798
68.7k
         ndpi_MD5_CTX ctx;
2799
68.7k
         u_char md5_hash[16];
2800
2801
68.7k
        ja_str_len = ndpi_snprintf(ja_str, JA_STR_LEN, "%u,", ja.server.tls_handshake_version);
2802
2803
137k
        for(i=0; (i<ja.server.num_ciphers) && (JA_STR_LEN > ja_str_len); i++) {
2804
68.7k
    rc = ndpi_snprintf(&ja_str[ja_str_len], JA_STR_LEN-ja_str_len, "%s%u", (i > 0) ? "-" : "", ja.server.cipher[i]);
2805
2806
68.7k
    if(rc <= 0) break; else ja_str_len += rc;
2807
68.7k
        }
2808
2809
68.7k
        if(JA_STR_LEN > ja_str_len) {
2810
68.7k
    rc = ndpi_snprintf(&ja_str[ja_str_len], JA_STR_LEN-ja_str_len, ",");
2811
68.7k
    if(rc > 0 && ja_str_len + rc < JA_STR_LEN) ja_str_len += rc;
2812
68.7k
        }
2813
2814
        /* ********** */
2815
2816
235k
        for(i=0; (i<ja.server.num_tls_extensions) && (JA_STR_LEN > ja_str_len); i++) {
2817
167k
    int rc = ndpi_snprintf(&ja_str[ja_str_len], JA_STR_LEN-ja_str_len, "%s%u", (i > 0) ? "-" : "", ja.server.tls_extension[i]);
2818
2819
167k
    if(rc <= 0) break; else ja_str_len += rc;
2820
167k
        }
2821
2822
#ifdef DEBUG_TLS
2823
        printf("[JA3] Server: %s \n", ja_str);
2824
#endif
2825
2826
68.7k
        ndpi_MD5Init(&ctx);
2827
68.7k
        ndpi_MD5Update(&ctx, (const unsigned char *)ja_str, strlen(ja_str));
2828
68.7k
        ndpi_MD5Final(md5_hash, &ctx);
2829
2830
1.16M
        for(i=0, j=0; i<16; i++) {
2831
1.09M
    int rc = ndpi_snprintf(&flow->protos.tls_quic.ja3_server[j],
2832
1.09M
               sizeof(flow->protos.tls_quic.ja3_server)-j, "%02x", md5_hash[i]);
2833
1.09M
    if(rc <= 0) break; else j += rc;
2834
1.09M
        }
2835
2836
#ifdef DEBUG_TLS
2837
        printf("[JA3] Server: %s \n", flow->protos.tls_quic.ja3_server);
2838
#endif
2839
2840
68.7k
  if(ndpi_struct->cfg.tls_ja_data_enabled) {
2841
67.4k
    if(flow->protos.tls_quic.ja_server == NULL) {
2842
55.8k
      flow->protos.tls_quic.ja_server = ndpi_malloc(sizeof(ndpi_tls_server_info));
2843
2844
55.8k
      if(flow->protos.tls_quic.ja_server != NULL)
2845
54.9k
        memcpy(flow->protos.tls_quic.ja_server, &ja.server, sizeof(ndpi_tls_server_info));
2846
55.8k
    }
2847
67.4k
  }
2848
68.7k
      }
2849
187k
    } else if(handshake_type == 0x01 /* Client Hello */) {
2850
187k
      u_int16_t cipher_len, cipher_offset;
2851
187k
      u_int8_t cookie_len = 0;
2852
2853
187k
      memset(&ja.client, 0, sizeof(ja.client));
2854
187k
      ja.client.alpn_original_last = '0'; /* Initialize to '0' if no ALPN */
2855
2856
187k
      flow->protos.tls_quic.ssl_version = ja.client.tls_handshake_version = tls_version;
2857
187k
      if(flow->protos.tls_quic.ssl_version < 0x0303) /* < TLSv1.2 */ {
2858
25.4k
        if(is_flowrisk_info_enabled(ndpi_struct, NDPI_TLS_OBSOLETE_VERSION)) {
2859
24.6k
          char str[32], buf[32];
2860
24.6k
    u_int8_t unknown_tls_version;
2861
2862
24.6k
    snprintf(str, sizeof(str), "%s", ndpi_ssl_version2str(buf, sizeof(buf),
2863
24.6k
                      flow->protos.tls_quic.ssl_version,
2864
24.6k
                     &unknown_tls_version));
2865
24.6k
    ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_OBSOLETE_VERSION, str);
2866
24.6k
        } else {
2867
829
          ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_OBSOLETE_VERSION, NULL);
2868
829
        }
2869
25.4k
      }
2870
2871
187k
      if((session_id_len+base_offset+3) > packet->payload_packet_len)
2872
3.63k
  return(0); /* Not found */
2873
2874
183k
      if(!is_dtls) {
2875
107k
  cipher_len = packet->payload[session_id_len+base_offset+2] + (packet->payload[session_id_len+base_offset+1] << 8);
2876
107k
  cipher_offset = base_offset + session_id_len + 3;
2877
107k
      } else {
2878
76.2k
  cookie_len = packet->payload[base_offset+session_id_len+1];
2879
#ifdef DEBUG_TLS
2880
  printf("[JA3] Client: DTLS cookie len %d\n", cookie_len);
2881
#endif
2882
76.2k
  if((session_id_len+base_offset+cookie_len+4) > packet->payload_packet_len)
2883
1.62k
    return(0); /* Not found */
2884
74.6k
  cipher_len = ntohs(*((u_int16_t*)&packet->payload[base_offset+session_id_len+cookie_len+2]));
2885
74.6k
  cipher_offset = base_offset + session_id_len + cookie_len + 4;
2886
74.6k
      }
2887
2888
#ifdef DEBUG_TLS
2889
      printf("Client TLS [client cipher_len: %u][tls_version: 0x%04X]\n", cipher_len, tls_version);
2890
#endif
2891
2892
181k
      if((cipher_offset+cipher_len) <= total_len - 1) { /* -1 because variable "id" is a u_int16_t */
2893
171k
  u_int8_t safari_ciphers = 0, chrome_ciphers = 0, this_is_not_safari = 0, looks_like_safari_on_big_sur = 0;
2894
2895
2.95M
  for(i=0; i<cipher_len;) {
2896
2.77M
    u_int16_t *id = (u_int16_t*)&packet->payload[cipher_offset+i];
2897
2.77M
    u_int16_t cipher_id = ntohs(*id);
2898
2899
2.77M
    if(cipher_offset+i+1 < packet->payload_packet_len &&
2900
2.77M
       ((packet->payload[cipher_offset+i] != packet->payload[cipher_offset+i+1]) ||
2901
2.74M
        ((packet->payload[cipher_offset+i] & 0xF) != 0xA)) /* Skip GREASE */) {
2902
      /*
2903
        Skip GREASE [https://datatracker.ietf.org/doc/html/rfc8701]
2904
        https://engineering.salesforce.com/tls-fingerprinting-with-ja3-and-ja3s-247362855967
2905
      */
2906
2907
#if defined(DEBUG_TLS) || defined(DEBUG_HEURISTIC)
2908
      printf("Client TLS [non-GREASE cipher suite: %u/0x%04X] [%d/%u]\n", cipher_id, cipher_id, i, cipher_len);
2909
#endif
2910
2911
2.74M
      if(ja.client.num_ciphers < MAX_NUM_JA)
2912
2.71M
        ja.client.cipher[ja.client.num_ciphers++] = cipher_id;
2913
29.8k
      else {
2914
29.8k
        invalid_ja = 1;
2915
#ifdef DEBUG_TLS
2916
        printf("Client TLS Invalid cipher %u\n", ja.client.num_ciphers);
2917
#endif
2918
29.8k
      }
2919
2920
#if defined(DEBUG_TLS) || defined(DEBUG_HEURISTIC)
2921
      printf("Client TLS [cipher suite: %u/0x%04X] [%d/%u]\n", cipher_id, cipher_id, i, cipher_len);
2922
#endif
2923
2924
2.74M
      switch(cipher_id) {
2925
71.5k
      case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
2926
133k
      case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
2927
133k
        safari_ciphers++;
2928
133k
        break;
2929
2930
61.3k
      case TLS_AES_128_GCM_SHA256:
2931
121k
      case TLS_AES_256_GCM_SHA384:
2932
182k
      case TLS_CHACHA20_POLY1305_SHA256:
2933
182k
        chrome_ciphers++;
2934
182k
        break;
2935
2936
61.5k
      case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
2937
117k
      case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
2938
189k
      case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
2939
251k
      case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
2940
324k
      case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
2941
399k
      case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
2942
468k
      case TLS_RSA_WITH_AES_128_CBC_SHA:
2943
535k
      case TLS_RSA_WITH_AES_256_CBC_SHA:
2944
594k
      case TLS_RSA_WITH_AES_128_GCM_SHA256:
2945
644k
      case TLS_RSA_WITH_AES_256_GCM_SHA384:
2946
644k
        safari_ciphers++, chrome_ciphers++;
2947
644k
        break;
2948
2949
36.2k
      case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
2950
36.2k
        looks_like_safari_on_big_sur = 1;
2951
36.2k
        break;
2952
2.74M
      }
2953
2.74M
    } else {
2954
#if defined(DEBUG_TLS) || defined(DEBUG_HEURISTIC)
2955
      printf("Client TLS [GREASE cipher suite: %u/0x%04X] [%d/%u]\n", cipher_id, cipher_id, i, cipher_len);
2956
#endif
2957
2958
37.3k
      this_is_not_safari = 1; /* NOTE: BugSur and up have grease support */
2959
37.3k
    }
2960
2961
2.77M
    i += 2;
2962
2.77M
  } /* for */
2963
2964
171k
  if(ndpi_struct->cfg.tls_browser_enabled) {
2965
          /* NOTE:
2966
             we do not check for duplicates as with signatures because
2967
             this is time consuming and we want to avoid overhead whem possible
2968
          */
2969
124k
          if(this_is_not_safari)
2970
26.3k
            flow->protos.tls_quic.browser_heuristics.is_safari_tls = 0;
2971
97.9k
          else if((safari_ciphers == 12) || (this_is_not_safari && looks_like_safari_on_big_sur))
2972
13.4k
            flow->protos.tls_quic.browser_heuristics.is_safari_tls = 1;
2973
2974
124k
          if(chrome_ciphers == 13)
2975
23.9k
            flow->protos.tls_quic.browser_heuristics.is_chrome_tls = 1;
2976
2977
          /* Note that both Safari and Chrome can overlap */
2978
#ifdef DEBUG_HEURISTIC
2979
          printf("[CIPHERS] [is_chrome_tls: %u (%u)][is_safari_tls: %u (%u)][this_is_not_safari: %u]\n",
2980
                 flow->protos.tls_quic.browser_heuristics.is_chrome_tls,
2981
                 chrome_ciphers,
2982
                 flow->protos.tls_quic.browser_heuristics.is_safari_tls,
2983
                 safari_ciphers,
2984
                 this_is_not_safari);
2985
#endif
2986
124k
  }
2987
171k
      } else {
2988
9.92k
  invalid_ja = 1;
2989
#ifdef DEBUG_TLS
2990
  printf("Client TLS Invalid len %u vs %u\n", (cipher_offset+cipher_len), total_len);
2991
#endif
2992
9.92k
      }
2993
2994
181k
      offset = base_offset + session_id_len + cookie_len + cipher_len + 2;
2995
181k
      offset += (!is_dtls) ? 1 : 2;
2996
2997
181k
      if(offset < total_len) {
2998
174k
  u_int16_t compression_len;
2999
174k
  u_int16_t extensions_len;
3000
3001
174k
  compression_len = packet->payload[offset];
3002
174k
  offset++;
3003
3004
#ifdef DEBUG_TLS
3005
  printf("Client TLS [compression_len: %u]\n", compression_len);
3006
#endif
3007
3008
  // offset += compression_len + 3;
3009
174k
  offset += compression_len;
3010
3011
174k
  if(offset+1 < total_len) {
3012
168k
    extensions_len = ntohs(*((u_int16_t*)&packet->payload[offset]));
3013
168k
    offset += 2;
3014
3015
#ifdef DEBUG_TLS
3016
    printf("Client TLS [extensions_len: %u]\n", extensions_len);
3017
#endif
3018
3019
168k
    if((extensions_len+offset) <= total_len) {
3020
      /* Move to the first extension
3021
         Type is u_int to avoid possible overflow on extension_len addition */
3022
162k
      u_int extension_offset = 0;
3023
3024
1.66M
      while(extension_offset < extensions_len &&
3025
1.55M
      offset+extension_offset+4 <= total_len) {
3026
1.55M
        u_int16_t extension_id, extension_len, extn_off = offset+extension_offset;
3027
3028
1.55M
        extension_id = ntohs(*((u_int16_t*)&packet->payload[offset+extension_offset]));
3029
1.55M
        extension_offset += 2;
3030
3031
1.55M
        extension_len = ntohs(*((u_int16_t*)&packet->payload[offset+extension_offset]));
3032
1.55M
        extension_offset += 2;
3033
3034
#ifdef DEBUG_TLS
3035
        printf("Client TLS [extension_id: %u][extension_len: %u]\n", extension_id, extension_len);
3036
#endif
3037
1.55M
        checkExtensions(ndpi_struct, flow, is_dtls,
3038
1.55M
            extension_id, extension_len, offset + extension_offset);
3039
3040
1.55M
        if(offset + 4 + extension_len > total_len) {
3041
#ifdef DEBUG_TLS
3042
          printf("[TLS] extension length %u too long (%u, offset %u)\n",
3043
                 extension_len, total_len, offset);
3044
#endif
3045
57.8k
          break;
3046
57.8k
        }
3047
3048
1.49M
        if((extension_id == 0) || (packet->payload[extn_off] != packet->payload[extn_off+1]) ||
3049
1.45M
     ((packet->payload[extn_off] & 0xF) != 0xA)) {
3050
    /* Skip GREASE */
3051
3052
1.45M
    if(ja.client.num_tls_extensions < MAX_NUM_JA) {
3053
1.41M
      if(((extension_id == 0xFE0D /* ECHO */) || skipTLSextension(ndpi_struct, extension_id))
3054
471k
         && (flow->l4_proto == IPPROTO_TCP)
3055
264k
         && (ndpi_struct->cfg.tls_max_num_blocks_to_analyze > 0)
3056
264k
         && (flow->l4.tcp.tls.tls_blocks != NULL)
3057
251k
         && (flow->l4.tcp.tls.num_tls_blocks > 0) /* It should always be like that */) {
3058
        /*
3059
          Taking EncryptedClientHello (ECHO) lenght out of the block lenght
3060
          allows us to have a consistent measurement regardless of the SNI being used
3061
          and other information put in ECHO across requests
3062
        */
3063
251k
        if(extension_id == 0x0 /* SNI */)
3064
134k
          ; /* Nothing to do as already handled by (***) */
3065
117k
        else
3066
117k
          flow->l4.tcp.tls.tls_blocks[flow->l4.tcp.tls.num_tls_blocks-1].len -= extension_len + 4 /* id + len */;
3067
251k
      }
3068
3069
1.41M
      ja.client.tls_extension[ja.client.num_tls_extensions++] = extension_id;
3070
1.41M
    } else {
3071
40.1k
      invalid_ja = 1;
3072
#ifdef DEBUG_TLS
3073
      printf("Client TLS Invalid extensions %u\n", ja.client.num_tls_extensions);
3074
#endif
3075
40.1k
    }
3076
1.45M
        }
3077
3078
1.49M
        if(extension_id == 0 /* server name */) {
3079
418k
    u_int16_t len;
3080
418k
    bool sni_numeric = false;
3081
3082
#ifdef DEBUG_TLS
3083
    printf("[TLS] Extensions: found server name\n");
3084
#endif
3085
418k
    if((offset+extension_offset+4) < packet->payload_packet_len) {
3086
414k
      len = (packet->payload[offset+extension_offset+3] << 8) + packet->payload[offset+extension_offset+4];
3087
3088
414k
      if((offset+extension_offset+5+len) <= packet->payload_packet_len) {
3089
385k
        char *sni = ndpi_hostname_sni_set(flow, &packet->payload[offset+extension_offset+5], len, NDPI_HOSTNAME_NORM_ALL);
3090
385k
        int sni_len = strlen(sni);
3091
#ifdef DEBUG_TLS
3092
        printf("[TLS] SNI: [%s]\n", sni);
3093
#endif
3094
385k
        if(sni /* It should always be like that */
3095
385k
           && (flow->l4_proto == IPPROTO_TCP)
3096
169k
           && (ndpi_struct->cfg.tls_max_num_blocks_to_analyze > 0)
3097
146k
           && (flow->l4.tcp.tls.tls_blocks != NULL)
3098
138k
           && (flow->l4.tcp.tls.num_tls_blocks > 0) /* It should always be like that */
3099
385k
           ) {
3100
          /*
3101
      Taking SNI lenght out of the block lenght allows us to have a consistent
3102
      measurement regardless of the SNI being used
3103
          */
3104
138k
          if(ndpi_struct->cfg.tls_ndpifp_ignore_sni_extension)
3105
138k
      flow->l4.tcp.tls.tls_blocks[flow->l4.tcp.tls.num_tls_blocks-1].len -= extension_len + 4 /* id + len */;
3106
0
          else
3107
0
      flow->l4.tcp.tls.tls_blocks[flow->l4.tcp.tls.num_tls_blocks-1].len -= sni_len; /* (***) */
3108
138k
        }
3109
3110
385k
        if(ndpi_is_valid_hostname((char *)&packet->payload[offset+extension_offset+5], len) == 0) {
3111
311k
          ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, sni);
3112
3113
          /* This looks like an attack */
3114
311k
          ndpi_set_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT, "Invalid chars found in SNI: exploit or misconfiguration?");
3115
311k
        }
3116
3117
385k
        if(!is_quic) {
3118
344k
          if(ndpi_struct->cfg.tls_subclassification_enabled &&
3119
344k
             flow->protos.tls_quic.subprotocol_detected == 0 &&
3120
322k
             !flow->tls_quic.from_rdp && /* No (other) sub-classification; we will have TLS.RDP anyway */
3121
322k
             ndpi_match_hostname_protocol(ndpi_struct, flow, ndpi_get_master_proto(ndpi_struct, flow), sni, sni_len))
3122
39.1k
            flow->protos.tls_quic.subprotocol_detected = 1;
3123
344k
        } else {
3124
41.3k
          if(ndpi_struct->cfg.quic_subclassification_enabled &&
3125
41.3k
             flow->protos.tls_quic.subprotocol_detected == 0 &&
3126
40.7k
             !flow->tls_quic.from_rdp && /* No (other) sub-classification; we will have TLS.RDP anyway */
3127
40.7k
             ndpi_match_hostname_protocol(ndpi_struct, flow, NDPI_PROTOCOL_QUIC, sni, sni_len))
3128
19.5k
            flow->protos.tls_quic.subprotocol_detected = 1;
3129
41.3k
        }
3130
3131
385k
        if((flow->protos.tls_quic.subprotocol_detected == 0)
3132
304k
           && (ndpi_check_is_numeric_ip(sni) == 1)) {
3133
1.79k
          ndpi_set_risk(ndpi_struct, flow, NDPI_NUMERIC_IP_HOST, sni);
3134
1.79k
          sni_numeric = true;
3135
1.79k
        }
3136
3137
385k
        if(ndpi_str_endswith(sni, "signal.org")) {
3138
          /* printf("[SIGNAL] SNI: [%s]\n", sni); */
3139
2.22k
          signal_add_to_cache(ndpi_struct, flow);
3140
2.22k
        }
3141
3142
385k
        if(ndpi_check_dga_name(ndpi_struct, flow, sni, 1, 0, 0)) {
3143
#ifdef DEBUG_TLS
3144
          printf("[TLS] SNI: (DGA) [%s]\n", sni);
3145
#endif
3146
3147
36.3k
          if((sni_len >= 4)
3148
             /* Check if it ends in .com or .net */
3149
36.3k
             && ((strcmp(&sni[sni_len-4], ".com") == 0) || (strcmp(&sni[sni_len-4], ".net") == 0))
3150
3.10k
             && (strncmp(sni, "www.", 4) == 0)) /* Starting with www.... */
3151
585
            ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TOR, ndpi_get_master_proto(ndpi_struct, flow), NDPI_CONFIDENCE_DPI);
3152
349k
        } else {
3153
#ifdef DEBUG_TLS
3154
          printf("[TLS] SNI: (NO DGA) [%s]\n", sni);
3155
#endif
3156
349k
        }
3157
3158
385k
        if(ndpi_struct->cfg.hostname_dns_check_enabled && (!sni_numeric)) {
3159
269k
          ndpi_ip_addr_t ip_addr;
3160
3161
269k
          memset(&ip_addr, 0, sizeof(ip_addr));
3162
3163
269k
          if(packet->iph)
3164
253k
      ip_addr.ipv4 = packet->iph->daddr;
3165
15.6k
          else
3166
15.6k
      memcpy(&ip_addr.ipv6, &packet->iphv6->ip6_dst,
3167
15.6k
             sizeof(struct ndpi_in6_addr));
3168
3169
269k
          if(!ndpi_cache_find_hostname_ip(ndpi_struct, &ip_addr, sni)) {
3170
#ifdef DEBUG_TLS
3171
      printf("[TLS] Not found SNI %s\n", sni);
3172
#endif
3173
262k
      ndpi_set_risk(ndpi_struct, flow, NDPI_UNRESOLVED_HOSTNAME, sni);
3174
3175
262k
          } else {
3176
#ifdef DEBUG_TLS
3177
      printf("[TLS] Found SNI %s\n", sni);
3178
#endif
3179
6.81k
          }
3180
269k
        }
3181
385k
      } else {
3182
#ifdef DEBUG_TLS
3183
        printf("[TLS] Extensions server len too short: %u vs %u\n",
3184
         offset+extension_offset+5+len,
3185
         packet->payload_packet_len);
3186
#endif
3187
28.6k
      }
3188
414k
    }
3189
1.07M
        } else if(extension_id == 10 /* supported groups */) {
3190
87.7k
    u_int16_t s_offset = offset+extension_offset + 2;
3191
3192
#ifdef DEBUG_TLS
3193
    printf("Client TLS [EllipticCurveGroups: len=%u]\n", extension_len);
3194
#endif
3195
3196
87.7k
    if((s_offset+extension_len-2) <= total_len) {
3197
1.18M
      for(i=0; i<(u_int32_t)extension_len-2 && s_offset + i + 1 < total_len; i += 2) {
3198
1.10M
        u_int16_t s_group = ntohs(*((u_int16_t*)&packet->payload[s_offset+i]));
3199
3200
#ifdef DEBUG_TLS
3201
        printf("Client TLS [EllipticCurve: %u/0x%04X]\n", s_group, s_group);
3202
#endif
3203
3204
1.10M
        if((s_group == 0) || (packet->payload[s_offset+i] != packet->payload[s_offset+i+1])
3205
1.05M
           || ((packet->payload[s_offset+i] & 0xF) != 0xA)) {
3206
          /* Skip GREASE */
3207
1.05M
          if(ja.client.num_elliptic_curve_groups < MAX_NUM_JA)
3208
742k
      ja.client.elliptic_curve_group[ja.client.num_elliptic_curve_groups++] = s_group;
3209
311k
          else {
3210
311k
      invalid_ja = 1;
3211
#ifdef DEBUG_TLS
3212
      printf("Client TLS Invalid num elliptic group %u\n", ja.client.num_elliptic_curve_groups);
3213
#endif
3214
311k
          }
3215
1.05M
        }
3216
1.10M
      }
3217
87.0k
    } else {
3218
743
      invalid_ja = 1;
3219
#ifdef DEBUG_TLS
3220
      printf("Client TLS Invalid len %u vs %u\n", (s_offset+extension_len-1), total_len);
3221
#endif
3222
743
    }
3223
991k
        } else if(extension_id == 11 /* ec_point_formats groups */) {
3224
63.0k
    u_int16_t s_offset = offset+extension_offset + 1;
3225
3226
#ifdef DEBUG_TLS
3227
    printf("Client TLS [EllipticCurveFormat: len=%u]\n", extension_len);
3228
#endif
3229
63.0k
    if((s_offset+extension_len-1) <= total_len) {
3230
1.09M
      for(i=0; i<(u_int32_t)extension_len-1 && s_offset+i < total_len; i++) {
3231
1.03M
        u_int8_t s_group = packet->payload[s_offset+i];
3232
3233
#ifdef DEBUG_TLS
3234
        printf("Client TLS [EllipticCurveFormat: %u]\n", s_group);
3235
#endif
3236
3237
1.03M
        if(ja.client.num_elliptic_curve_point_format < MAX_NUM_JA)
3238
483k
          ja.client.elliptic_curve_point_format[ja.client.num_elliptic_curve_point_format++] = s_group;
3239
551k
        else {
3240
551k
          invalid_ja = 1;
3241
#ifdef DEBUG_TLS
3242
          printf("Client TLS Invalid num elliptic %u\n", ja.client.num_elliptic_curve_point_format);
3243
#endif
3244
551k
        }
3245
1.03M
      }
3246
62.4k
    } else {
3247
612
      invalid_ja = 1;
3248
#ifdef DEBUG_TLS
3249
      printf("Client TLS Invalid len %u vs %u\n", s_offset+extension_len, total_len);
3250
#endif
3251
612
    }
3252
928k
        } else if(extension_id == 13 /* signature algorithms */ &&
3253
95.0k
                  offset+extension_offset+1 < total_len) {
3254
93.6k
    int s_offset = offset+extension_offset, safari_signature_algorithms = 0, id;
3255
93.6k
    u_int16_t tot_signature_algorithms_len = ntohs(*((u_int16_t*)&packet->payload[s_offset]));
3256
3257
#ifdef DEBUG_TLS
3258
    printf("Client TLS [SIGNATURE_ALGORITHMS: block_len=%u/len=%u]\n", extension_len, tot_signature_algorithms_len);
3259
#endif
3260
3261
93.6k
    s_offset += 2;
3262
93.6k
    tot_signature_algorithms_len = ndpi_min((sizeof(ja.client.signature_algorithms_str) / 2) - 1, tot_signature_algorithms_len);
3263
3264
1.34M
    for(i=0, id=0; i<tot_signature_algorithms_len && s_offset+i+1<total_len; i += 2)
3265
1.24M
      ja.client.signature_algorithm[id++] = ntohs(*(u_int16_t*)&packet->payload[s_offset+i]);
3266
3267
93.6k
    ja.client.num_signature_algorithms = id;
3268
3269
2.57M
    for(i=0, id=0; i<tot_signature_algorithms_len && s_offset+i+1<total_len; i++) {
3270
2.47M
      int rc = ndpi_snprintf(&ja.client.signature_algorithms_str[i*2],
3271
2.47M
           sizeof(ja.client.signature_algorithms_str)-i*2,
3272
2.47M
           "%02X", packet->payload[s_offset+i]);
3273
2.47M
      if(rc < 0) break;
3274
2.47M
    }
3275
3276
93.6k
    if(ndpi_struct->cfg.tls_browser_enabled) {
3277
75.4k
            int chrome_signature_algorithms = 0, duplicate_found = 0, last_signature = 0;
3278
3279
1.10M
                  for(i=0; i<tot_signature_algorithms_len && s_offset + (int)i + 2 < packet->payload_packet_len; i+=2) {
3280
1.02M
                    u_int16_t signature_algo = (u_int16_t)ntohs(*((u_int16_t*)&packet->payload[s_offset+i]));
3281
3282
1.02M
                    if(last_signature == signature_algo) {
3283
                      /* Consecutive duplication */
3284
12.7k
                      duplicate_found = 1;
3285
12.7k
                      continue;
3286
1.01M
                    } else {
3287
                      /* Check for other duplications */
3288
1.01M
                      u_int all_ok = 1;
3289
3290
29.1M
                      for(j=0; j<tot_signature_algorithms_len; j+=2) {
3291
28.2M
                        if(j != i && s_offset + (int)j + 2 < packet->payload_packet_len) {
3292
22.2M
                          u_int16_t j_signature_algo = (u_int16_t)ntohs(*((u_int16_t*)&packet->payload[s_offset+j]));
3293
3294
22.2M
                          if((signature_algo == j_signature_algo)
3295
1.60M
                             && (i < j) /* Don't skip both of them */) {
3296
#ifdef DEBUG_HEURISTIC
3297
                            printf("[SIGNATURE] [TLS Signature Algorithm] Skipping duplicate 0x%04X\n", signature_algo);
3298
#endif
3299
3300
123k
                            duplicate_found = 1, all_ok = 0;
3301
123k
                            break;
3302
123k
                          }
3303
22.2M
                        }
3304
28.2M
                      }
3305
3306
1.01M
                      if(!all_ok)
3307
123k
                        continue;
3308
1.01M
                    }
3309
3310
889k
                    last_signature = signature_algo;
3311
3312
#ifdef DEBUG_HEURISTIC
3313
                    printf("[SIGNATURE] [TLS Signature Algorithm] 0x%04X\n", signature_algo);
3314
#endif
3315
889k
                    switch(signature_algo) {
3316
16.8k
                    case ECDSA_SECP521R1_SHA512:
3317
16.8k
                      flow->protos.tls_quic.browser_heuristics.is_firefox_tls = 1;
3318
16.8k
                      break;
3319
3320
62.4k
                    case ECDSA_SECP256R1_SHA256:
3321
122k
                    case ECDSA_SECP384R1_SHA384:
3322
183k
                    case RSA_PKCS1_SHA256:
3323
244k
                    case RSA_PKCS1_SHA384:
3324
304k
                    case RSA_PKCS1_SHA512:
3325
360k
                    case RSA_PSS_RSAE_SHA256:
3326
415k
                    case RSA_PSS_RSAE_SHA384:
3327
469k
                    case RSA_PSS_RSAE_SHA512:
3328
469k
                      chrome_signature_algorithms++, safari_signature_algorithms++;
3329
#ifdef DEBUG_HEURISTIC
3330
                      printf("[SIGNATURE] [Chrome/Safari] Found 0x%04X [chrome: %u][safari: %u]\n",
3331
                             signature_algo, chrome_signature_algorithms, safari_signature_algorithms);
3332
#endif
3333
3334
469k
                      break;
3335
889k
                    }
3336
889k
                  }
3337
3338
#ifdef DEBUG_HEURISTIC
3339
                  printf("[SIGNATURE] [safari_signature_algorithms: %u][chrome_signature_algorithms: %u]\n",
3340
                         safari_signature_algorithms, chrome_signature_algorithms);
3341
#endif
3342
3343
75.4k
                  if(flow->protos.tls_quic.browser_heuristics.is_firefox_tls)
3344
17.0k
                    flow->protos.tls_quic.browser_heuristics.is_safari_tls = 0,
3345
17.0k
                      flow->protos.tls_quic.browser_heuristics.is_chrome_tls = 0;
3346
3347
75.4k
                  if(safari_signature_algorithms != 8)
3348
24.4k
                    flow->protos.tls_quic.browser_heuristics.is_safari_tls = 0;
3349
3350
75.4k
                  if((chrome_signature_algorithms != 8) || duplicate_found)
3351
26.7k
                    flow->protos.tls_quic.browser_heuristics.is_chrome_tls = 0;
3352
3353
                  /* Avoid Chrome and Safari overlaps, thing that cannot happen with Firefox */
3354
75.4k
                  if(flow->protos.tls_quic.browser_heuristics.is_safari_tls)
3355
4.68k
                    flow->protos.tls_quic.browser_heuristics.is_chrome_tls = 0;
3356
3357
75.4k
                  if((flow->protos.tls_quic.browser_heuristics.is_chrome_tls == 0)
3358
64.5k
                     && duplicate_found)
3359
14.0k
                    flow->protos.tls_quic.browser_heuristics.is_safari_tls = 1; /* Safari */
3360
3361
#ifdef DEBUG_HEURISTIC
3362
                  printf("[SIGNATURE] [is_firefox_tls: %u][is_chrome_tls: %u][is_safari_tls: %u][duplicate_found: %u]\n",
3363
                         flow->protos.tls_quic.browser_heuristics.is_firefox_tls,
3364
                         flow->protos.tls_quic.browser_heuristics.is_chrome_tls,
3365
                         flow->protos.tls_quic.browser_heuristics.is_safari_tls,
3366
                         duplicate_found);
3367
#endif
3368
75.4k
    }
3369
3370
93.6k
    if(i > 0 && i >= tot_signature_algorithms_len) {
3371
74.8k
      ja.client.signature_algorithms_str[i*2 - 1] = '\0';
3372
74.8k
    } else {
3373
18.8k
      ja.client.signature_algorithms_str[i*2] = '\0';
3374
18.8k
    }
3375
3376
#ifdef DEBUG_TLS
3377
    printf("Client TLS [SIGNATURE_ALGORITHMS: %s]\n", ja.client.signature_algorithms_str);
3378
#endif
3379
835k
        } else if(extension_id == 14 /* use_srtp */) {
3380
                /* This is likely a werbrtc flow */
3381
5.98k
                if(flow->stun.maybe_dtls || flow->detected_protocol_stack[0] == NDPI_PROTOCOL_DTLS)
3382
4.89k
            flow->protos.tls_quic.webrtc = 1;
3383
#ifdef DEBUG_TLS
3384
                printf("Client TLS: use_srtp\n");
3385
#endif
3386
829k
        } else if(extension_id == 16 /* application_layer_protocol_negotiation */ &&
3387
85.9k
                  offset+extension_offset+1 < total_len) {
3388
85.4k
    u_int16_t s_offset = offset+extension_offset;
3389
85.4k
    u_int16_t tot_alpn_len = ntohs(*((u_int16_t*)&packet->payload[s_offset]));
3390
85.4k
    char alpn_str[256];
3391
85.4k
    u_int16_t alpn_str_len = 0, i;
3392
3393
#ifdef DEBUG_TLS
3394
    printf("Client TLS [ALPN: block_len=%u/len=%u]\n", extension_len, tot_alpn_len);
3395
#endif
3396
85.4k
    s_offset += 2;
3397
85.4k
    tot_alpn_len += s_offset;
3398
3399
389k
    while(s_offset < tot_alpn_len && s_offset < total_len) {
3400
326k
      u_int8_t alpn_i, alpn_len = packet->payload[s_offset++];
3401
3402
326k
      if((s_offset + alpn_len) <= tot_alpn_len &&
3403
315k
         (s_offset + alpn_len) <= total_len) {
3404
#ifdef DEBUG_TLS
3405
        printf("Client TLS [ALPN: %u]\n", alpn_len);
3406
#endif
3407
3408
305k
        if(((uint32_t)alpn_str_len+alpn_len+1) < (sizeof(alpn_str)-1)) {
3409
303k
          if(alpn_str_len > 0) {
3410
158k
      alpn_str[alpn_str_len] = ',';
3411
158k
      alpn_str_len++;
3412
158k
          }
3413
3414
1.79M
          for(alpn_i=0; alpn_i<alpn_len; alpn_i++)
3415
1.49M
      alpn_str[alpn_str_len+alpn_i] = packet->payload[s_offset+alpn_i];
3416
3417
303k
          s_offset += alpn_len, alpn_str_len += alpn_len;;
3418
303k
        } else
3419
1.80k
          break;
3420
305k
      } else
3421
20.9k
        break;
3422
326k
    } /* while */
3423
3424
85.4k
    alpn_str[alpn_str_len] = '\0';
3425
3426
#ifdef DEBUG_TLS
3427
    printf("Client TLS [ALPN: %s][len: %u]\n", alpn_str, alpn_str_len);
3428
#endif
3429
85.4k
    if(flow->protos.tls_quic.advertised_alpns == NULL) {
3430
60.5k
      flow->protos.tls_quic.advertised_alpns = ndpi_strdup(alpn_str);
3431
60.5k
      if(flow->protos.tls_quic.advertised_alpns) {
3432
59.6k
        tlsCheckUncommonALPN(ndpi_struct, flow, flow->protos.tls_quic.advertised_alpns);
3433
3434
        /* Without SNI matching we can try to sub-classify the flow via ALPN.
3435
           Note that this happens only on very rare cases, not the common ones
3436
           ("h2", "http/1.1", ...). Usefull for asymmetric traffic */
3437
59.6k
        if(!flow->protos.tls_quic.subprotocol_detected) {
3438
13.8k
          if((is_quic && ndpi_struct->cfg.quic_subclassification_enabled) ||
3439
12.8k
             (!is_quic && ndpi_struct->cfg.tls_subclassification_enabled))
3440
13.8k
                  tls_subclassify_by_alpn(ndpi_struct, flow);
3441
13.8k
        }
3442
59.6k
      }
3443
60.5k
    }
3444
3445
85.4k
                alpn_str_len = ndpi_min(sizeof(ja.client.alpn), (size_t)alpn_str_len);
3446
85.4k
    memcpy(ja.client.alpn, alpn_str, alpn_str_len);
3447
3448
    /* Store the last character of the first ALPN protocol (before any semicolon) */
3449
85.4k
    ja.client.alpn_original_last = '0';
3450
85.4k
    if(alpn_str_len > 0) {
3451
      /* Find the end of the first ALPN protocol (before semicolon or comma) */
3452
74.0k
      int first_alpn_end = 0;
3453
822k
      for(first_alpn_end = 0; first_alpn_end < alpn_str_len; first_alpn_end++) {
3454
794k
        if(ja.client.alpn[first_alpn_end] == ';' || ja.client.alpn[first_alpn_end] == ',') {
3455
46.6k
          break;
3456
46.6k
        }
3457
794k
      }
3458
74.0k
      if(first_alpn_end > 0) {
3459
73.4k
        ja.client.alpn_original_last = ja.client.alpn[first_alpn_end - 1];
3460
73.4k
      }
3461
74.0k
    }
3462
3463
85.4k
    if(alpn_str_len > 0)
3464
74.0k
      ja.client.alpn[alpn_str_len - 1] = '\0';
3465
3466
    /* Replace , with - as in JA3 */
3467
722k
    for(i=0; ja.client.alpn[i] != '\0'; i++)
3468
636k
      if(ja.client.alpn[i] == ',') ja.client.alpn[i] = '-';
3469
3470
743k
        } else if(extension_id == 43 /* supported versions */ &&
3471
57.1k
                  offset+extension_offset < total_len) {
3472
56.9k
    u_int16_t s_offset = offset+extension_offset;
3473
56.9k
    u_int8_t version_len = packet->payload[s_offset];
3474
56.9k
    char version_str[256];
3475
56.9k
    char buf_ver_tmp[16];
3476
56.9k
    size_t version_str_len = 0;
3477
56.9k
    version_str[0] = 0;
3478
#ifdef DEBUG_TLS
3479
    printf("Client TLS [TLS version len: %u]\n", version_len);
3480
#endif
3481
3482
56.9k
    if(version_len == (extension_len-1)) {
3483
54.4k
      u_int8_t j;
3484
3485
54.4k
      s_offset++;
3486
3487
      // careful not to overflow and loop forever with u_int8_t
3488
498k
      for(j=0; j+1<version_len && s_offset + j + 1 < packet->payload_packet_len; j += 2) {
3489
444k
        u_int16_t tls_version = ntohs(*((u_int16_t*)&packet->payload[s_offset+j]));
3490
444k
        u_int8_t unknown_tls_version;
3491
3492
#ifdef DEBUG_TLS
3493
        printf("Client TLS [TLS version: %s/0x%04X]\n",
3494
         ndpi_ssl_version2str(buf_ver_tmp, sizeof(buf_ver_tmp), tls_version, &unknown_tls_version), tls_version);
3495
#endif
3496
3497
444k
        if((version_str_len+8) < sizeof(version_str)) {
3498
261k
          int rc = ndpi_snprintf(&version_str[version_str_len],
3499
261k
               sizeof(version_str) - version_str_len, "%s%s",
3500
261k
               (version_str_len > 0) ? "," : "",
3501
261k
               ndpi_ssl_version2str(buf_ver_tmp, sizeof(buf_ver_tmp), tls_version, &unknown_tls_version));
3502
261k
          if(rc <= 0)
3503
0
      break;
3504
261k
          else
3505
261k
      version_str_len += rc;
3506
3507
261k
          if(ja.client.num_supported_versions < MAX_NUM_JA)
3508
254k
      ja.client.supported_version[ja.client.num_supported_versions++] = tls_version;
3509
261k
        }
3510
444k
      }
3511
3512
#ifdef DEBUG_TLS
3513
      printf("Client TLS [SUPPORTED_VERSIONS: %s]\n", version_str);
3514
#endif
3515
3516
54.4k
      if(flow->protos.tls_quic.tls_supported_versions == NULL &&
3517
50.0k
         ndpi_struct->cfg.tls_versions_supported_enabled)
3518
40.5k
        flow->protos.tls_quic.tls_supported_versions = ndpi_strdup(version_str);
3519
54.4k
    }
3520
686k
        } else if(extension_id == 65037 /* ECH: latest drafts */) {
3521
#ifdef DEBUG_TLS
3522
    printf("Client TLS: ECH version 0x%x\n", extension_id);
3523
#endif
3524
    /* Beginning with draft-08, the version is the same as the code point
3525
       for the "encrypted_client_hello" extension. */
3526
2.85k
    flow->protos.tls_quic.encrypted_ch.version = extension_id;
3527
683k
        } else if(extension_id == 65445 || /* QUIC transport parameters (drafts version) */
3528
659k
            extension_id == 57) { /* QUIC transport parameters (final version) */
3529
31.1k
    u_int16_t s_offset = offset+extension_offset;
3530
31.1k
    uint16_t final_offset;
3531
31.1k
    int using_var_int = is_version_with_var_int_transport_params(quic_version);
3532
3533
31.1k
    if(!using_var_int) {
3534
8.64k
      if(s_offset+1 >= total_len) {
3535
452
        final_offset = 0; /* Force skipping extension */
3536
8.19k
      } else {
3537
8.19k
        u_int16_t seq_len = ntohs(*((u_int16_t*)&packet->payload[s_offset]));
3538
8.19k
        s_offset += 2;
3539
8.19k
              final_offset = ndpi_min(total_len, s_offset + seq_len);
3540
8.19k
      }
3541
22.5k
    } else {
3542
22.5k
            final_offset = ndpi_min(total_len, s_offset + extension_len);
3543
22.5k
    }
3544
3545
325k
    while(s_offset < final_offset) {
3546
302k
      u_int64_t param_type, param_len;
3547
3548
302k
                  if(!using_var_int) {
3549
27.6k
        if(s_offset+3 >= final_offset)
3550
1.31k
          break;
3551
26.2k
        param_type = ntohs(*((u_int16_t*)&packet->payload[s_offset]));
3552
26.2k
        param_len = ntohs(*((u_int16_t*)&packet->payload[s_offset + 2]));
3553
26.2k
        s_offset += 4;
3554
274k
      } else {
3555
274k
        if(s_offset >= final_offset ||
3556
274k
           (s_offset + quic_len_buffer_still_required(packet->payload[s_offset])) >= final_offset)
3557
241
          break;
3558
274k
        s_offset += quic_len(&packet->payload[s_offset], &param_type);
3559
3560
274k
        if(s_offset >= final_offset ||
3561
274k
           (s_offset + quic_len_buffer_still_required(packet->payload[s_offset])) >= final_offset)
3562
675
          break;
3563
274k
        s_offset += quic_len(&packet->payload[s_offset], &param_len);
3564
274k
      }
3565
3566
#ifdef DEBUG_TLS
3567
      printf("Client TLS [QUIC TP: Param 0x%x Len %d]\n", (int)param_type, (int)param_len);
3568
#endif
3569
300k
      if(s_offset+param_len > final_offset)
3570
6.26k
        break;
3571
3572
294k
      s_offset += param_len;
3573
294k
    }
3574
652k
        } else if(extension_id == 21) { /* Padding */
3575
    /* Padding is usually some hundreds byte long. Longer padding
3576
       might be used as obfuscation technique to force unusual CH fragmentation */
3577
20.3k
    if(extension_len > 500 /* Arbitrary value */) {
3578
#ifdef DEBUG_TLS
3579
      printf("Padding length: %d\n", extension_len);
3580
#endif
3581
34
      ndpi_set_risk(ndpi_struct, flow, NDPI_OBFUSCATED_TRAFFIC, "Abnormal Client Hello/Padding length");
3582
34
    }
3583
632k
        } else if(extension_id == 22) { /* Encrypt-then-MAC */
3584
10.3k
    if(extension_len == 0) {
3585
9.23k
      char *sni = flow->host_server_name;
3586
3587
9.23k
      if(sni != NULL) {
3588
9.23k
        u_int sni_len = strlen(sni);
3589
3590
9.23k
        if((flow->protos.tls_quic.advertised_alpns == NULL) /* No ALPN */
3591
6.91k
           && (sni_len > 8)
3592
4.60k
           && ((strcmp(&sni[sni_len-4], ".com") == 0) || (strcmp(&sni[sni_len-4], ".net") == 0))
3593
2.88k
           && (strncmp(sni, "www.", 4) == 0) /* Starting with www.... */
3594
1.67k
           && str_contains_digit(&sni[4])) {
3595
1.17k
          ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TOR, ndpi_get_master_proto(ndpi_struct, flow), NDPI_CONFIDENCE_DPI);
3596
1.17k
        }
3597
9.23k
      }
3598
9.23k
    }
3599
622k
        } else if(extension_id == 51 &&  /* key_share */
3600
47.7k
                  offset + extension_offset < total_len) {
3601
47.5k
    u_int32_t extn_offset        = extn_off + 4;
3602
47.5k
    u_int16_t extn_end           = extn_offset + extension_len;
3603
3604
47.5k
    if(extn_offset + extension_len <= total_len) {
3605
#ifdef DEBUG_TLS
3606
                  u_int16_t key_share_extn_len = ntohs(*((u_int16_t*)&(packet->payload[extn_offset])));
3607
3608
                  printf("[key_share] [len=%u][key_share_extn_len: %u][%02X %02X]\n",
3609
                         extension_len, key_share_extn_len,
3610
                         (packet->payload[extn_offset] & 0xFF),
3611
                         (packet->payload[extn_offset+1] & 0xFF));
3612
#endif
3613
3614
47.2k
                  extn_offset += 2;
3615
3616
122k
                  while(extn_offset + 4 < extn_end) {
3617
75.2k
                    u_int16_t group_id     = ntohs(*((u_int16_t*)&(packet->payload[extn_offset])));
3618
75.2k
                    u_int16_t key_extn_len = ntohs(*((u_int16_t*)&(packet->payload[extn_offset + 2])));
3619
3620
  #ifdef DEBUG_TLS
3621
                    printf("\t[%02X %02X][extn_offset: %u][group_id: %u][key_extn_len: %u]\n",
3622
                           (packet->payload[extn_offset] & 0xFF),
3623
                           (packet->payload[extn_offset+1] & 0xFF),
3624
                           extn_offset,
3625
                           group_id, key_extn_len);
3626
  #endif
3627
75.2k
        if(group_id != 0x2A2A /* Skip GREASE */) {
3628
73.7k
          if(ja.client.num_key_share_groups < MAX_NUM_JA)
3629
73.2k
      ja.client.key_share_group[ja.client.num_key_share_groups++] = group_id;
3630
73.7k
        }
3631
3632
75.2k
                    extn_offset += key_extn_len + 4;
3633
75.2k
                  }
3634
47.2k
    }
3635
3636
#ifdef DEBUG_TLS
3637
    printf("[extn_offset: %u][extn_end: %u]\n", extn_offset, extn_end);
3638
#endif
3639
47.5k
        }
3640
3641
1.49M
        extension_offset += extension_len; /* Move to the next extension */
3642
3643
#ifdef DEBUG_TLS
3644
        printf("Client TLS [extension_offset/len: %u/%u]\n", extension_offset, extension_len);
3645
#endif
3646
1.49M
      } /* while */
3647
3648
162k
      if(!invalid_ja) {
3649
        /* Compute JA4 client */
3650
3651
161k
compute_ja4c:
3652
161k
        if(ndpi_struct->cfg.tls_ja4c_fingerprint_enabled) {
3653
161k
          ndpi_compute_ja4(ndpi_struct, flow, quic_version, &ja);
3654
161k
    tls_match_ja4(ndpi_struct, flow);
3655
161k
        }
3656
3657
161k
        if(ndpi_struct->cfg.tls_ja_data_enabled) {
3658
114k
    if(flow->protos.tls_quic.ja_client == NULL) {
3659
90.1k
      flow->protos.tls_quic.ja_client = ndpi_malloc(sizeof(ndpi_tls_client_info));
3660
3661
90.1k
      if(flow->protos.tls_quic.ja_client != NULL)
3662
89.1k
        memcpy(flow->protos.tls_quic.ja_client, &ja.client, sizeof(ndpi_tls_client_info));
3663
90.1k
    }
3664
114k
        }
3665
3666
        /* End JA4 */
3667
161k
      }
3668
3669
      /* Before returning to the caller we need to make a final check */
3670
166k
      if((flow->protos.tls_quic.ssl_version >= 0x0303) /* >= TLSv1.2 */
3671
144k
         && !flow->protos.tls_quic.webrtc
3672
137k
         && (flow->protos.tls_quic.advertised_alpns == NULL) /* No ALPN */) {
3673
65.8k
        ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_NOT_CARRYING_HTTPS, "No ALPN");
3674
65.8k
      }
3675
3676
      /* Add check for missing SNI */
3677
166k
      if(flow->host_server_name[0] == '\0'
3678
67.2k
         && (flow->protos.tls_quic.ssl_version >= 0x0302) /* TLSv1.1 */
3679
54.7k
         && !flow->protos.tls_quic.webrtc
3680
166k
         ) {
3681
        /* This is a bit suspicious */
3682
49.5k
        ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_MISSING_SNI, "SNI should always be present");
3683
3684
49.5k
        if(flow->protos.tls_quic.advertised_alpns != NULL) {
3685
14.9k
    char buf[256], *tmp, *item;
3686
3687
14.9k
    snprintf(buf, sizeof(buf), "%s", flow->protos.tls_quic.advertised_alpns);
3688
3689
14.9k
    item = strtok_r(buf, ",", &tmp);
3690
3691
26.6k
    while(item != NULL) {
3692
14.3k
      if(item[0] == 'h') {
3693
        /* Example 'h2' */
3694
2.67k
        ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_ALPN_SNI_MISMATCH, item);
3695
2.67k
        break;
3696
2.67k
      } else
3697
11.6k
        item = strtok_r(NULL, ",", &tmp);
3698
14.3k
    }
3699
14.9k
        }
3700
49.5k
      }
3701
3702
166k
      return(2 /* Client Certificate */);
3703
162k
    } else {
3704
#ifdef DEBUG_TLS
3705
      printf("[TLS] Client: too short [%u vs %u]\n",
3706
       (extensions_len+offset), total_len);
3707
#endif
3708
5.26k
    }
3709
168k
  } else if(offset == total_len) {
3710
    /* TLS does not have extensions etc */
3711
3.89k
    goto compute_ja4c;
3712
3.89k
  }
3713
174k
      } else {
3714
#ifdef DEBUG_TLS
3715
  printf("[JA3] Client: invalid length detected\n");
3716
#endif
3717
6.82k
      }
3718
181k
    }
3719
268k
  }
3720
3721
92.4k
  return(0); /* Not found */
3722
270k
}
3723
3724
/* **************************************** */
3725
3726
static void ndpi_search_tls_wrapper(struct ndpi_detection_module_struct *ndpi_struct,
3727
6.23M
            struct ndpi_flow_struct *flow) {
3728
6.23M
  struct ndpi_packet_struct *packet = &ndpi_struct->packet;
3729
6.23M
  int rc = 0;
3730
3731
#ifdef DEBUG_TLS
3732
  printf("==>> %s() [len: %u][version: %u]\n",
3733
   __FUNCTION__,
3734
   packet->payload_packet_len,
3735
   flow->protos.tls_quic.ssl_version);
3736
#endif
3737
3738
  /* It is not easy to handle "standard" TLS/DTLS detection and (plain) obfuscated
3739
     heuristic at the SAME time. Use a trivial logic: switch to heuristic
3740
     code only if the standard functions fail */
3741
3742
  /* We might be in extra-dissection data-path here (if we have been
3743
     called from STUN or from Mails/FTP/...), but plain obfuscated heuristic
3744
     is always checked in "standard" data-path! */
3745
3746
6.23M
  if(flow->tls_quic.obfuscated_heur_state == NULL) {
3747
5.36M
    if(packet->udp != NULL || flow->stun.maybe_dtls)
3748
1.22M
      rc = ndpi_search_dtls(ndpi_struct, flow);
3749
4.14M
    else
3750
4.14M
      rc = ndpi_search_tls_tcp(ndpi_struct, flow);
3751
3752
     /* We should check for this TLS heuristic if:
3753
      * the feature is enabled
3754
      * this flow doesn't seem a real TLS/DTLS one
3755
      * we are not here from STUN code or from opportunistic tls path (mails/ftp)
3756
      * with TCP, we got the 3WHS (so that we can process the beginning of the flow)
3757
      */
3758
5.36M
    if(rc == 0 &&
3759
4.04M
       (ndpi_struct->cfg.tls_heuristics & NDPI_HEURISTICS_TLS_OBFUSCATED_PLAIN) &&
3760
3.46M
       flow->stun.maybe_dtls == 0 &&
3761
3.44M
       flow->tls_quic.from_opportunistic_tls == 0 &&
3762
3.44M
       ((flow->l4_proto == IPPROTO_TCP && ndpi_seen_flow_beginning(flow)) ||
3763
3.42M
        flow->l4_proto == IPPROTO_UDP) &&
3764
1.05M
       !is_flow_addr_informative(flow) /* The proxy server is likely hosted on some cloud providers */ ) {
3765
963k
      flow->tls_quic.obfuscated_heur_state = ndpi_calloc(1, sizeof(struct tls_obfuscated_heuristic_state));
3766
963k
    }
3767
5.36M
  }
3768
3769
6.23M
  if(flow->tls_quic.obfuscated_heur_state) {
3770
1.82M
    tls_obfuscated_heur_search_again(ndpi_struct, flow);
3771
4.40M
  } else if(rc == 0) {
3772
3.09M
    NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow);
3773
3.09M
  }
3774
6.23M
}
3775
3776
/* **************************************** */
3777
3778
14.2k
void init_tls_dissector(struct ndpi_detection_module_struct *ndpi_struct) {
3779
14.2k
  ndpi_register_dissector("(D)TLS", ndpi_struct,
3780
14.2k
                     ndpi_search_tls_wrapper,
3781
14.2k
                     NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
3782
14.2k
                     2,
3783
14.2k
                     NDPI_PROTOCOL_TLS,
3784
14.2k
                     NDPI_PROTOCOL_DTLS);
3785
14.2k
}