Coverage Report

Created: 2025-06-13 06:05

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