suricata
output-json-tls.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2021 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Tom DeCanio <td@npulsetech.com>
22  *
23  * Implements TLS JSON logging portion of the engine.
24  */
25 
26 #include "suricata-common.h"
27 #include "detect.h"
28 #include "pkt-var.h"
29 #include "conf.h"
30 
31 #include "threads.h"
32 #include "threadvars.h"
33 #include "tm-threads.h"
34 
35 #include "util-print.h"
36 #include "util-time.h"
37 #include "util-unittest.h"
38 
39 #include "util-debug.h"
40 #include "app-layer-parser.h"
41 #include "output.h"
42 #include "app-layer-ssl.h"
43 #include "app-layer.h"
44 #include "util-privs.h"
45 #include "util-buffer.h"
46 
47 #include "util-logopenfile.h"
48 #include "util-ja3.h"
49 #include "util-ja4.h"
50 
51 #include "output-json.h"
52 #include "output-json-tls.h"
53 
54 SC_ATOMIC_EXTERN(unsigned int, cert_id);
55 
56 #define LOG_TLS_DEFAULT 0
57 #define LOG_TLS_EXTENDED (1 << 0)
58 #define LOG_TLS_CUSTOM (1 << 1)
59 #define LOG_TLS_SESSION_RESUMPTION (1 << 2)
60 
61 #define LOG_TLS_FIELD_VERSION (1 << 0)
62 #define LOG_TLS_FIELD_SUBJECT (1 << 1)
63 #define LOG_TLS_FIELD_ISSUER (1 << 2)
64 #define LOG_TLS_FIELD_SERIAL (1 << 3)
65 #define LOG_TLS_FIELD_FINGERPRINT (1 << 4)
66 #define LOG_TLS_FIELD_NOTBEFORE (1 << 5)
67 #define LOG_TLS_FIELD_NOTAFTER (1 << 6)
68 #define LOG_TLS_FIELD_SNI (1 << 7)
69 #define LOG_TLS_FIELD_CERTIFICATE (1 << 8)
70 #define LOG_TLS_FIELD_CHAIN (1 << 9)
71 #define LOG_TLS_FIELD_SESSION_RESUMED (1 << 10)
72 #define LOG_TLS_FIELD_JA3 (1 << 11)
73 #define LOG_TLS_FIELD_JA3S (1 << 12)
74 #define LOG_TLS_FIELD_CLIENT (1 << 13) /**< client fields (issuer, subject, etc) */
75 #define LOG_TLS_FIELD_CLIENT_CERT (1 << 14)
76 #define LOG_TLS_FIELD_CLIENT_CHAIN (1 << 15)
77 #define LOG_TLS_FIELD_JA4 (1 << 16)
78 #define LOG_TLS_FIELD_SUBJECTALTNAME (1 << 17)
79 
80 typedef struct {
81  const char *name;
82  uint64_t flag;
83 } TlsFields;
84 
86  { "subject", LOG_TLS_FIELD_SUBJECT }, { "issuer", LOG_TLS_FIELD_ISSUER },
87  { "serial", LOG_TLS_FIELD_SERIAL }, { "fingerprint", LOG_TLS_FIELD_FINGERPRINT },
88  { "not_before", LOG_TLS_FIELD_NOTBEFORE }, { "not_after", LOG_TLS_FIELD_NOTAFTER },
89  { "sni", LOG_TLS_FIELD_SNI }, { "certificate", LOG_TLS_FIELD_CERTIFICATE },
90  { "chain", LOG_TLS_FIELD_CHAIN }, { "session_resumed", LOG_TLS_FIELD_SESSION_RESUMED },
91  { "ja3", LOG_TLS_FIELD_JA3 }, { "ja3s", LOG_TLS_FIELD_JA3S },
92  { "client", LOG_TLS_FIELD_CLIENT }, { "client_certificate", LOG_TLS_FIELD_CLIENT_CERT },
93  { "client_chain", LOG_TLS_FIELD_CLIENT_CHAIN }, { "ja4", LOG_TLS_FIELD_JA4 },
94  { "subjectaltname", LOG_TLS_FIELD_SUBJECTALTNAME }, { NULL, -1 } };
95 
96 typedef struct OutputTlsCtx_ {
97  uint32_t flags; /** Store mode */
98  uint64_t fields; /** Store fields */
101 
102 
103 typedef struct JsonTlsLogThread_ {
107 
108 static void JsonTlsLogSubject(JsonBuilder *js, SSLState *ssl_state)
109 {
110  if (ssl_state->server_connp.cert0_subject) {
111  jb_set_string(js, "subject",
112  ssl_state->server_connp.cert0_subject);
113  }
114 }
115 
116 static void JsonTlsLogIssuer(JsonBuilder *js, SSLState *ssl_state)
117 {
118  if (ssl_state->server_connp.cert0_issuerdn) {
119  jb_set_string(js, "issuerdn",
120  ssl_state->server_connp.cert0_issuerdn);
121  }
122 }
123 
124 static void JsonTlsLogSAN(JsonBuilder *js, SSLState *ssl_state)
125 {
126  if (ssl_state->server_connp.cert0_sans_len > 0) {
127  jb_open_array(js, "subjectaltname");
128  for (uint16_t i = 0; i < ssl_state->server_connp.cert0_sans_len; i++) {
129  jb_append_string(js, ssl_state->server_connp.cert0_sans[i]);
130  }
131  jb_close(js);
132  }
133 }
134 
135 static void JsonTlsLogSessionResumed(JsonBuilder *js, SSLState *ssl_state)
136 {
137  if (ssl_state->flags & SSL_AL_FLAG_SESSION_RESUMED) {
138  /* Only log a session as 'resumed' if a certificate has not
139  been seen, and the session is not TLSv1.3 or later. */
140  if ((ssl_state->server_connp.cert0_issuerdn == NULL &&
141  ssl_state->server_connp.cert0_subject == NULL) &&
142  (ssl_state->flags & SSL_AL_FLAG_STATE_SERVER_HELLO) &&
143  ((ssl_state->flags & SSL_AL_FLAG_LOG_WITHOUT_CERT) == 0)) {
144  jb_set_bool(js, "session_resumed", true);
145  }
146  }
147 }
148 
149 static void JsonTlsLogFingerprint(JsonBuilder *js, SSLState *ssl_state)
150 {
151  if (ssl_state->server_connp.cert0_fingerprint) {
152  jb_set_string(js, "fingerprint",
153  ssl_state->server_connp.cert0_fingerprint);
154  }
155 }
156 
157 static void JsonTlsLogSni(JsonBuilder *js, SSLState *ssl_state)
158 {
159  if (ssl_state->client_connp.sni) {
160  jb_set_string(js, "sni",
161  ssl_state->client_connp.sni);
162  }
163 }
164 
165 static void JsonTlsLogSerial(JsonBuilder *js, SSLState *ssl_state)
166 {
167  if (ssl_state->server_connp.cert0_serial) {
168  jb_set_string(js, "serial",
169  ssl_state->server_connp.cert0_serial);
170  }
171 }
172 
173 static void JsonTlsLogVersion(JsonBuilder *js, SSLState *ssl_state)
174 {
175  char ssl_version[SSL_VERSION_MAX_STRLEN];
176  SSLVersionToString(ssl_state->server_connp.version, ssl_version);
177  jb_set_string(js, "version", ssl_version);
178 }
179 
180 static void JsonTlsLogNotBefore(JsonBuilder *js, SSLState *ssl_state)
181 {
182  if (ssl_state->server_connp.cert0_not_before != 0) {
183  sc_x509_log_timestamp(js, "notbefore", ssl_state->server_connp.cert0_not_before);
184  }
185 }
186 
187 static void JsonTlsLogNotAfter(JsonBuilder *js, SSLState *ssl_state)
188 {
189  if (ssl_state->server_connp.cert0_not_after != 0) {
190  sc_x509_log_timestamp(js, "notafter", ssl_state->server_connp.cert0_not_after);
191  }
192 }
193 
194 static void JsonTlsLogJa3Hash(JsonBuilder *js, SSLState *ssl_state)
195 {
196  if (ssl_state->client_connp.ja3_hash != NULL) {
197  jb_set_string(js, "hash",
198  ssl_state->client_connp.ja3_hash);
199  }
200 }
201 
202 static void JsonTlsLogJa3String(JsonBuilder *js, SSLState *ssl_state)
203 {
204  if ((ssl_state->client_connp.ja3_str != NULL) &&
205  ssl_state->client_connp.ja3_str->data != NULL) {
206  jb_set_string(js, "string",
207  ssl_state->client_connp.ja3_str->data);
208  }
209 }
210 
211 static void JsonTlsLogJa3(JsonBuilder *js, SSLState *ssl_state)
212 {
213  if ((ssl_state->client_connp.ja3_hash != NULL) ||
214  ((ssl_state->client_connp.ja3_str != NULL) &&
215  ssl_state->client_connp.ja3_str->data != NULL)) {
216  jb_open_object(js, "ja3");
217 
218  JsonTlsLogJa3Hash(js, ssl_state);
219  JsonTlsLogJa3String(js, ssl_state);
220 
221  jb_close(js);
222  }
223 }
224 
225 static void JsonTlsLogSCJA4(JsonBuilder *js, SSLState *ssl_state)
226 {
227  if (ssl_state->client_connp.ja4 != NULL) {
228  uint8_t buffer[JA4_HEX_LEN];
229  /* JA4 hash has 36 characters */
230  SCJA4GetHash(ssl_state->client_connp.ja4, (uint8_t(*)[JA4_HEX_LEN])buffer);
231  jb_set_string_from_bytes(js, "ja4", buffer, 36);
232  }
233 }
234 
235 static void JsonTlsLogJa3SHash(JsonBuilder *js, SSLState *ssl_state)
236 {
237  if (ssl_state->server_connp.ja3_hash != NULL) {
238  jb_set_string(js, "hash",
239  ssl_state->server_connp.ja3_hash);
240  }
241 }
242 
243 static void JsonTlsLogJa3SString(JsonBuilder *js, SSLState *ssl_state)
244 {
245  if ((ssl_state->server_connp.ja3_str != NULL) &&
246  ssl_state->server_connp.ja3_str->data != NULL) {
247  jb_set_string(js, "string",
248  ssl_state->server_connp.ja3_str->data);
249  }
250 }
251 
252 static void JsonTlsLogJa3S(JsonBuilder *js, SSLState *ssl_state)
253 {
254  if ((ssl_state->server_connp.ja3_hash != NULL) ||
255  ((ssl_state->server_connp.ja3_str != NULL) &&
256  ssl_state->server_connp.ja3_str->data != NULL)) {
257  jb_open_object(js, "ja3s");
258 
259  JsonTlsLogJa3SHash(js, ssl_state);
260  JsonTlsLogJa3SString(js, ssl_state);
261 
262  jb_close(js);
263  }
264 }
265 
266 static void JsonTlsLogAlpns(JsonBuilder *js, SSLStateConnp *connp, const char *object)
267 {
268  if (TAILQ_EMPTY(&connp->alpns)) {
269  return;
270  }
271 
272  SSLAlpns *a = TAILQ_FIRST(&connp->alpns);
273  if (a == NULL) {
274  return;
275  }
276 
277  jb_open_array(js, object);
278  TAILQ_FOREACH (a, &connp->alpns, next) {
279  jb_append_string_from_bytes(js, a->alpn, a->size);
280  }
281  jb_close(js);
282 }
283 
284 static void JsonTlsLogCertificate(JsonBuilder *js, SSLStateConnp *connp)
285 {
286  if (TAILQ_EMPTY(&connp->certs)) {
287  return;
288  }
289 
290  SSLCertsChain *cert = TAILQ_FIRST(&connp->certs);
291  if (cert == NULL) {
292  return;
293  }
294 
295  jb_set_base64(js, "certificate", cert->cert_data, cert->cert_len);
296 }
297 
298 static void JsonTlsLogChain(JsonBuilder *js, SSLStateConnp *connp)
299 {
300  if (TAILQ_EMPTY(&connp->certs)) {
301  return;
302  }
303 
304  jb_open_array(js, "chain");
305 
306  SSLCertsChain *cert;
307  TAILQ_FOREACH (cert, &connp->certs, next) {
308  jb_append_base64(js, cert->cert_data, cert->cert_len);
309  }
310 
311  jb_close(js);
312 }
313 
314 static bool HasClientCert(SSLStateConnp *connp)
315 {
316  if (connp->cert0_subject || connp->cert0_issuerdn)
317  return true;
318  return false;
319 }
320 
321 static void JsonTlsLogClientCert(
322  JsonBuilder *js, SSLStateConnp *connp, const bool log_cert, const bool log_chain)
323 {
324  if (connp->cert0_subject != NULL) {
325  jb_set_string(js, "subject", connp->cert0_subject);
326  }
327  if (connp->cert0_issuerdn != NULL) {
328  jb_set_string(js, "issuerdn", connp->cert0_issuerdn);
329  }
330  if (connp->cert0_fingerprint) {
331  jb_set_string(js, "fingerprint", connp->cert0_fingerprint);
332  }
333  if (connp->cert0_serial) {
334  jb_set_string(js, "serial", connp->cert0_serial);
335  }
336  if (connp->cert0_not_before != 0) {
337  char timebuf[64];
339  CreateUtcIsoTimeString(ts, timebuf, sizeof(timebuf));
340  jb_set_string(js, "notbefore", timebuf);
341  }
342  if (connp->cert0_not_after != 0) {
343  char timebuf[64];
345  CreateUtcIsoTimeString(ts, timebuf, sizeof(timebuf));
346  jb_set_string(js, "notafter", timebuf);
347  }
348 
349  if (log_cert) {
350  JsonTlsLogCertificate(js, connp);
351  }
352  if (log_chain) {
353  JsonTlsLogChain(js, connp);
354  }
355 }
356 
357 void JsonTlsLogJSONBasic(JsonBuilder *js, SSLState *ssl_state)
358 {
359  /* tls subject */
360  JsonTlsLogSubject(js, ssl_state);
361 
362  /* tls issuerdn */
363  JsonTlsLogIssuer(js, ssl_state);
364 
365  /* tls subjectaltname */
366  JsonTlsLogSAN(js, ssl_state);
367 
368  /* tls session resumption */
369  JsonTlsLogSessionResumed(js, ssl_state);
370 }
371 
372 static void JsonTlsLogJSONCustom(OutputTlsCtx *tls_ctx, JsonBuilder *js,
373  SSLState *ssl_state)
374 {
375  /* tls subject */
376  if (tls_ctx->fields & LOG_TLS_FIELD_SUBJECT)
377  JsonTlsLogSubject(js, ssl_state);
378 
379  /* tls issuerdn */
380  if (tls_ctx->fields & LOG_TLS_FIELD_ISSUER)
381  JsonTlsLogIssuer(js, ssl_state);
382 
383  /* tls subjectaltname */
384  if (tls_ctx->fields & LOG_TLS_FIELD_SUBJECTALTNAME)
385  JsonTlsLogIssuer(js, ssl_state);
386 
387  /* tls session resumption */
388  if (tls_ctx->fields & LOG_TLS_FIELD_SESSION_RESUMED)
389  JsonTlsLogSessionResumed(js, ssl_state);
390 
391  /* tls serial */
392  if (tls_ctx->fields & LOG_TLS_FIELD_SERIAL)
393  JsonTlsLogSerial(js, ssl_state);
394 
395  /* tls fingerprint */
396  if (tls_ctx->fields & LOG_TLS_FIELD_FINGERPRINT)
397  JsonTlsLogFingerprint(js, ssl_state);
398 
399  /* tls sni */
400  if (tls_ctx->fields & LOG_TLS_FIELD_SNI)
401  JsonTlsLogSni(js, ssl_state);
402 
403  /* tls version */
404  if (tls_ctx->fields & LOG_TLS_FIELD_VERSION)
405  JsonTlsLogVersion(js, ssl_state);
406 
407  /* tls notbefore */
408  if (tls_ctx->fields & LOG_TLS_FIELD_NOTBEFORE)
409  JsonTlsLogNotBefore(js, ssl_state);
410 
411  /* tls notafter */
412  if (tls_ctx->fields & LOG_TLS_FIELD_NOTAFTER)
413  JsonTlsLogNotAfter(js, ssl_state);
414 
415  /* tls certificate */
416  if (tls_ctx->fields & LOG_TLS_FIELD_CERTIFICATE)
417  JsonTlsLogCertificate(js, &ssl_state->server_connp);
418 
419  /* tls chain */
420  if (tls_ctx->fields & LOG_TLS_FIELD_CHAIN)
421  JsonTlsLogChain(js, &ssl_state->server_connp);
422 
423  /* tls ja3_hash */
424  if (tls_ctx->fields & LOG_TLS_FIELD_JA3)
425  JsonTlsLogJa3(js, ssl_state);
426 
427  /* tls ja3s */
428  if (tls_ctx->fields & LOG_TLS_FIELD_JA3S)
429  JsonTlsLogJa3S(js, ssl_state);
430 
431  /* tls ja4 */
432  if (tls_ctx->fields & LOG_TLS_FIELD_JA4)
433  JsonTlsLogSCJA4(js, ssl_state);
434 
435  if (tls_ctx->fields & LOG_TLS_FIELD_CLIENT) {
436  const bool log_cert = (tls_ctx->fields & LOG_TLS_FIELD_CLIENT_CERT) != 0;
437  const bool log_chain = (tls_ctx->fields & LOG_TLS_FIELD_CLIENT_CHAIN) != 0;
438  if (HasClientCert(&ssl_state->client_connp)) {
439  jb_open_object(js, "client");
440  JsonTlsLogClientCert(js, &ssl_state->client_connp, log_cert, log_chain);
441  jb_close(js);
442  }
443  }
444 }
445 
446 static bool JsonTlsLogJSONExtendedAux(void *vtx, JsonBuilder *tjs)
447 {
448  SSLState *state = (SSLState *)vtx;
449  JsonTlsLogJSONBasic(tjs, state);
450 
451  /* tls serial */
452  JsonTlsLogSerial(tjs, state);
453 
454  /* tls fingerprint */
455  JsonTlsLogFingerprint(tjs, state);
456 
457  /* tls sni */
458  JsonTlsLogSni(tjs, state);
459 
460  /* tls version */
461  JsonTlsLogVersion(tjs, state);
462 
463  /* tls notbefore */
464  JsonTlsLogNotBefore(tjs, state);
465 
466  /* tls notafter */
467  JsonTlsLogNotAfter(tjs, state);
468 
469  /* tls ja3 */
470  JsonTlsLogJa3(tjs, state);
471 
472  /* tls ja3s */
473  JsonTlsLogJa3S(tjs, state);
474 
475  /* tls ja4 */
476  JsonTlsLogSCJA4(tjs, state);
477 
478  JsonTlsLogAlpns(tjs, &state->client_connp, "client_alpns");
479  JsonTlsLogAlpns(tjs, &state->server_connp, "server_alpns");
480 
481  if (HasClientCert(&state->client_connp)) {
482  jb_open_object(tjs, "client");
483  JsonTlsLogClientCert(tjs, &state->client_connp, false, false);
484  jb_close(tjs);
485  }
486  return true;
487 }
488 
489 bool JsonTlsLogJSONExtended(void *vtx, JsonBuilder *tjs)
490 {
491  jb_open_object(tjs, "tls");
492  bool r = JsonTlsLogJSONExtendedAux(vtx, tjs);
493  jb_close(tjs);
494  return r;
495 }
496 
497 static int JsonTlsLogger(ThreadVars *tv, void *thread_data, const Packet *p,
498  Flow *f, void *state, void *txptr, uint64_t tx_id)
499 {
500  JsonTlsLogThread *aft = (JsonTlsLogThread *)thread_data;
501  OutputTlsCtx *tls_ctx = aft->tlslog_ctx;
502 
503  SSLState *ssl_state = (SSLState *)state;
504  if (unlikely(ssl_state == NULL)) {
505  return 0;
506  }
507 
508  if ((ssl_state->server_connp.cert0_issuerdn == NULL ||
509  ssl_state->server_connp.cert0_subject == NULL) &&
510  ((ssl_state->flags & SSL_AL_FLAG_SESSION_RESUMED) == 0 ||
511  (tls_ctx->flags & LOG_TLS_SESSION_RESUMPTION) == 0) &&
512  ((ssl_state->flags & SSL_AL_FLAG_LOG_WITHOUT_CERT) == 0)) {
513  return 0;
514  }
515 
516  JsonBuilder *js = CreateEveHeader(p, LOG_DIR_FLOW, "tls", NULL, aft->tlslog_ctx->eve_ctx);
517  if (unlikely(js == NULL)) {
518  return 0;
519  }
520 
521  jb_open_object(js, "tls");
522 
523  /* log custom fields */
524  if (tls_ctx->flags & LOG_TLS_CUSTOM) {
525  JsonTlsLogJSONCustom(tls_ctx, js, ssl_state);
526  }
527  /* log extended */
528  else if (tls_ctx->flags & LOG_TLS_EXTENDED) {
529  JsonTlsLogJSONExtendedAux(ssl_state, js);
530  }
531  /* log basic */
532  else {
533  JsonTlsLogJSONBasic(js, ssl_state);
534  }
535 
536  /* print original application level protocol when it have been changed
537  because of STARTTLS, HTTP CONNECT, or similar. */
538  if (f->alproto_orig != ALPROTO_UNKNOWN) {
539  jb_set_string(js, "from_proto",
541  }
542 
543  /* Close the tls object. */
544  jb_close(js);
545 
546  OutputJsonBuilderBuffer(js, aft->ctx);
547  jb_free(js);
548 
549  return 0;
550 }
551 
552 static TmEcode JsonTlsLogThreadInit(ThreadVars *t, const void *initdata, void **data)
553 {
554  JsonTlsLogThread *aft = SCCalloc(1, sizeof(JsonTlsLogThread));
555  if (unlikely(aft == NULL)) {
556  return TM_ECODE_FAILED;
557  }
558 
559  if (initdata == NULL) {
560  SCLogDebug("Error getting context for eve-log tls 'initdata' argument NULL");
561  goto error_exit;
562  }
563 
564  /* use the Output Context (file pointer and mutex) */
565  aft->tlslog_ctx = ((OutputCtx *)initdata)->data;
566 
567  aft->ctx = CreateEveThreadCtx(t, aft->tlslog_ctx->eve_ctx);
568  if (!aft->ctx) {
569  goto error_exit;
570  }
571  *data = (void *)aft;
572  return TM_ECODE_OK;
573 
574 error_exit:
575  SCFree(aft);
576  return TM_ECODE_FAILED;
577 }
578 
579 static TmEcode JsonTlsLogThreadDeinit(ThreadVars *t, void *data)
580 {
581  JsonTlsLogThread *aft = (JsonTlsLogThread *)data;
582  if (aft == NULL) {
583  return TM_ECODE_OK;
584  }
585 
586  FreeEveThreadCtx(aft->ctx);
587 
588  /* clear memory */
589  memset(aft, 0, sizeof(JsonTlsLogThread));
590 
591  SCFree(aft);
592  return TM_ECODE_OK;
593 }
594 
595 static OutputTlsCtx *OutputTlsInitCtx(ConfNode *conf)
596 {
597  OutputTlsCtx *tls_ctx = SCMalloc(sizeof(OutputTlsCtx));
598  if (unlikely(tls_ctx == NULL))
599  return NULL;
600 
601  tls_ctx->flags = LOG_TLS_DEFAULT;
602  tls_ctx->fields = 0;
603 
604  if (conf == NULL)
605  return tls_ctx;
606 
607  const char *extended = ConfNodeLookupChildValue(conf, "extended");
608  if (extended) {
609  if (ConfValIsTrue(extended)) {
610  tls_ctx->flags = LOG_TLS_EXTENDED;
611  }
612  }
613 
614  ConfNode *custom = ConfNodeLookupChild(conf, "custom");
615  if (custom) {
616  tls_ctx->flags = LOG_TLS_CUSTOM;
617  ConfNode *field;
618  TAILQ_FOREACH(field, &custom->head, next)
619  {
620  bool valid = false;
621  TlsFields *valid_fields = tls_fields;
622  for ( ; valid_fields->name != NULL; valid_fields++) {
623  if (strcasecmp(field->val, valid_fields->name) == 0) {
624  tls_ctx->fields |= valid_fields->flag;
625  SCLogDebug("enabled %s", field->val);
626  valid = true;
627  break;
628  }
629  }
630  if (!valid) {
631  SCLogWarning("eve.tls: unknown 'custom' field '%s'", field->val);
632  }
633  }
634  }
635 
636  const char *session_resumption = ConfNodeLookupChildValue(conf, "session-resumption");
637  if (session_resumption == NULL || ConfValIsTrue(session_resumption)) {
638  tls_ctx->flags |= LOG_TLS_SESSION_RESUMPTION;
639  }
640 
641  if ((tls_ctx->fields & LOG_TLS_FIELD_JA3) &&
642  Ja3IsDisabled("fields")) {
643  /* JA3 is disabled, so don't log any JA3 fields */
644  tls_ctx->fields &= ~LOG_TLS_FIELD_JA3;
645  tls_ctx->fields &= ~LOG_TLS_FIELD_JA3S;
646  }
647 
648  if ((tls_ctx->fields & LOG_TLS_FIELD_CERTIFICATE) &&
649  (tls_ctx->fields & LOG_TLS_FIELD_CHAIN)) {
650  SCLogWarning("Both 'certificate' and 'chain' contains the top "
651  "certificate, so only one of them should be enabled "
652  "at a time");
653  }
654  if ((tls_ctx->fields & LOG_TLS_FIELD_CLIENT_CERT) &&
655  (tls_ctx->fields & LOG_TLS_FIELD_CLIENT_CHAIN)) {
656  SCLogWarning("Both 'client_certificate' and 'client_chain' contains the top "
657  "certificate, so only one of them should be enabled "
658  "at a time");
659  }
660 
661  if ((tls_ctx->fields & LOG_TLS_FIELD_CLIENT) == 0) {
662  if (tls_ctx->fields & LOG_TLS_FIELD_CLIENT_CERT) {
663  SCLogConfig("enabling \"client\" as a dependency of \"client_certificate\"");
664  tls_ctx->fields |= LOG_TLS_FIELD_CLIENT;
665  }
666  if (tls_ctx->fields & LOG_TLS_FIELD_CLIENT_CHAIN) {
667  SCLogConfig("enabling \"client\" as a dependency of \"client_chain\"");
668  tls_ctx->fields |= LOG_TLS_FIELD_CLIENT;
669  }
670  }
671 
672  return tls_ctx;
673 }
674 
675 static void OutputTlsLogDeinitSub(OutputCtx *output_ctx)
676 {
677  OutputTlsCtx *tls_ctx = output_ctx->data;
678  SCFree(tls_ctx);
679  SCFree(output_ctx);
680 }
681 
682 static OutputInitResult OutputTlsLogInitSub(ConfNode *conf, OutputCtx *parent_ctx)
683 {
684  OutputInitResult result = { NULL, false };
685  OutputJsonCtx *ojc = parent_ctx->data;
686 
687  OutputTlsCtx *tls_ctx = OutputTlsInitCtx(conf);
688  if (unlikely(tls_ctx == NULL))
689  return result;
690 
691  OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
692  if (unlikely(output_ctx == NULL)) {
693  SCFree(tls_ctx);
694  return result;
695  }
696 
697  tls_ctx->eve_ctx = ojc;
698 
699  if ((tls_ctx->fields & LOG_TLS_FIELD_CERTIFICATE) &&
700  (tls_ctx->fields & LOG_TLS_FIELD_CHAIN)) {
701  SCLogWarning("Both 'certificate' and 'chain' contains the top "
702  "certificate, so only one of them should be enabled "
703  "at a time");
704  }
705 
706  output_ctx->data = tls_ctx;
707  output_ctx->DeInit = OutputTlsLogDeinitSub;
708 
710 
711  result.ctx = output_ctx;
712  result.ok = true;
713  return result;
714 }
715 
717 {
718  /* register as child of eve-log */
719  OutputRegisterTxSubModuleWithProgress(LOGGER_JSON_TX, "eve-log", "JsonTlsLog", "eve-log.tls",
720  OutputTlsLogInitSub, ALPROTO_TLS, JsonTlsLogger, TLS_HANDSHAKE_DONE, TLS_HANDSHAKE_DONE,
721  JsonTlsLogThreadInit, JsonTlsLogThreadDeinit, NULL);
722 }
tm-threads.h
SSLStateConnp_::cert0_subject
char * cert0_subject
Definition: app-layer-ssl.h:255
SSLState_
SSLv[2.0|3.[0|1|2|3]] state structure.
Definition: app-layer-ssl.h:296
ts
uint64_t ts
Definition: source-erf-file.c:55
LOG_TLS_FIELD_NOTBEFORE
#define LOG_TLS_FIELD_NOTBEFORE
Definition: output-json-tls.c:66
SSLCertsChain_::cert_len
uint32_t cert_len
Definition: app-layer-ssl.h:225
JsonTlsLogJSONBasic
void JsonTlsLogJSONBasic(JsonBuilder *js, SSLState *ssl_state)
Definition: output-json-tls.c:357
LOG_TLS_DEFAULT
#define LOG_TLS_DEFAULT
Definition: output-json-tls.c:56
ConfNode_::val
char * val
Definition: conf.h:34
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
LOG_TLS_FIELD_JA3
#define LOG_TLS_FIELD_JA3
Definition: output-json-tls.c:72
SSLState_::client_connp
SSLStateConnp client_connp
Definition: app-layer-ssl.h:314
ALPROTO_TLS
@ ALPROTO_TLS
Definition: app-layer-protos.h:33
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:0
SSLState_::server_connp
SSLStateConnp server_connp
Definition: app-layer-ssl.h:315
SSLStateConnp_::cert0_not_before
int64_t cert0_not_before
Definition: app-layer-ssl.h:258
SSL_AL_FLAG_SESSION_RESUMED
#define SSL_AL_FLAG_SESSION_RESUMED
Definition: app-layer-ssl.h:116
FreeEveThreadCtx
void FreeEveThreadCtx(OutputJsonThreadCtx *ctx)
Definition: output-json-common.c:58
SSLStateConnp_
Definition: app-layer-ssl.h:235
SSLStateConnp_::ja3_hash
char * ja3_hash
Definition: app-layer-ssl.h:278
threads.h
OutputJsonCtx_
Definition: output-json.h:81
Flow_
Flow data structure.
Definition: flow.h:360
SSL_AL_FLAG_STATE_SERVER_HELLO
#define SSL_AL_FLAG_STATE_SERVER_HELLO
Definition: app-layer-ssl.h:99
TlsFields
Definition: output-json-tls.c:80
OutputJsonBuilderBuffer
int OutputJsonBuilderBuffer(JsonBuilder *js, OutputJsonThreadCtx *ctx)
Definition: output-json.c:967
SSL_VERSION_MAX_STRLEN
#define SSL_VERSION_MAX_STRLEN
Definition: app-layer-ssl.h:154
LOG_TLS_FIELD_NOTAFTER
#define LOG_TLS_FIELD_NOTAFTER
Definition: output-json-tls.c:67
TAILQ_EMPTY
#define TAILQ_EMPTY(head)
Definition: queue.h:248
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:252
Flow_::alproto_orig
AppProto alproto_orig
Definition: flow.h:465
SSLAlpns_::size
uint32_t size
Definition: app-layer-ssl.h:231
output-json-tls.h
CreateEveThreadCtx
OutputJsonThreadCtx * CreateEveThreadCtx(ThreadVars *t, OutputJsonCtx *ctx)
Definition: output-json-common.c:29
LOG_TLS_FIELD_SUBJECTALTNAME
#define LOG_TLS_FIELD_SUBJECTALTNAME
Definition: output-json-tls.c:78
JA3Buffer_::data
char * data
Definition: util-ja3.h:32
SSLAlpns_
Definition: app-layer-ssl.h:229
util-ja3.h
util-privs.h
SSLStateConnp_::sni
char * sni
Definition: app-layer-ssl.h:265
SSLStateConnp_::ja4
JA4 * ja4
Definition: app-layer-ssl.h:280
LOG_TLS_FIELD_SUBJECT
#define LOG_TLS_FIELD_SUBJECT
Definition: output-json-tls.c:62
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:83
JsonTlsLogThread
struct JsonTlsLogThread_ JsonTlsLogThread
LOG_TLS_FIELD_FINGERPRINT
#define LOG_TLS_FIELD_FINGERPRINT
Definition: output-json-tls.c:65
JsonTlsLogRegister
void JsonTlsLogRegister(void)
Definition: output-json-tls.c:716
TlsFields::flag
uint64_t flag
Definition: output-json-tls.c:82
util-unittest.h
JsonTlsLogJSONExtended
bool JsonTlsLogJSONExtended(void *vtx, JsonBuilder *tjs)
Definition: output-json-tls.c:489
JA4_HEX_LEN
#define JA4_HEX_LEN
Definition: util-ja4.h:27
SSLStateConnp_::cert0_issuerdn
char * cert0_issuerdn
Definition: app-layer-ssl.h:256
ConfValIsTrue
int ConfValIsTrue(const char *val)
Check if a value is true.
Definition: conf.c:536
JsonTlsLogThread_::ctx
OutputJsonThreadCtx * ctx
Definition: output-json-tls.c:105
OutputCtx_::data
void * data
Definition: tm-modules.h:88
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:82
OutputCtx_
Definition: tm-modules.h:85
OutputJsonThreadCtx_
Definition: output-json.h:89
SSLStateConnp_::cert0_not_after
int64_t cert0_not_after
Definition: app-layer-ssl.h:259
Ja3IsDisabled
int Ja3IsDisabled(const char *type)
Definition: util-ja3.c:325
util-ja4.h
SCTIME_FROM_SECS
#define SCTIME_FROM_SECS(s)
Definition: util-time.h:69
OutputTlsCtx_::eve_ctx
OutputJsonCtx * eve_ctx
Definition: output-json-tls.c:99
util-debug.h
TlsFields::name
const char * name
Definition: output-json-tls.c:81
TAILQ_FIRST
#define TAILQ_FIRST(head)
Definition: queue.h:250
LOG_TLS_FIELD_JA3S
#define LOG_TLS_FIELD_JA3S
Definition: output-json-tls.c:73
LOG_TLS_FIELD_JA4
#define LOG_TLS_FIELD_JA4
Definition: output-json-tls.c:77
OutputInitResult_::ctx
OutputCtx * ctx
Definition: output.h:47
output-json.h
OutputRegisterTxSubModuleWithProgress
void OutputRegisterTxSubModuleWithProgress(LoggerId id, const char *parent_name, const char *name, const char *conf_name, OutputInitSubFunc InitFunc, AppProto alproto, TxLogger TxLogFunc, int tc_log_progress, int ts_log_progress, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, ThreadExitPrintStatsFunc ThreadExitPrintStats)
Definition: output.c:374
LOG_TLS_CUSTOM
#define LOG_TLS_CUSTOM
Definition: output-json-tls.c:58
AppLayerParserRegisterLogger
void AppLayerParserRegisterLogger(uint8_t ipproto, AppProto alproto)
Definition: app-layer-parser.c:458
CreateEveHeader
JsonBuilder * CreateEveHeader(const Packet *p, enum OutputJsonLogDirection dir, const char *event_type, JsonAddrInfo *addr, OutputJsonCtx *eve_ctx)
Definition: output-json.c:816
SSLCertsChain_
Definition: app-layer-ssl.h:223
util-print.h
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
pkt-var.h
OutputTlsCtx_::flags
uint32_t flags
Definition: output-json-tls.c:97
LOG_TLS_FIELD_CLIENT_CERT
#define LOG_TLS_FIELD_CLIENT_CERT
Definition: output-json-tls.c:75
SSLVersionToString
void SSLVersionToString(uint16_t version, char *buffer)
Definition: app-layer-ssl.c:346
util-time.h
OutputInitResult_::ok
bool ok
Definition: output.h:48
SCLogWarning
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition: util-debug.h:249
app-layer-parser.h
LOG_TLS_FIELD_SERIAL
#define LOG_TLS_FIELD_SERIAL
Definition: output-json-tls.c:64
Packet_
Definition: decode.h:479
conf.h
OutputTlsCtx
struct OutputTlsCtx_ OutputTlsCtx
SCTime_t
Definition: util-time.h:40
TmEcode
TmEcode
Definition: tm-threads-common.h:81
SSLCertsChain_::cert_data
uint8_t * cert_data
Definition: app-layer-ssl.h:224
LOG_TLS_FIELD_ISSUER
#define LOG_TLS_FIELD_ISSUER
Definition: output-json-tls.c:63
ConfNodeLookupChild
ConfNode * ConfNodeLookupChild(const ConfNode *node, const char *name)
Lookup a child configuration node by name.
Definition: conf.c:781
OutputInitResult_
Definition: output.h:46
CreateUtcIsoTimeString
void CreateUtcIsoTimeString(const SCTime_t ts, char *str, size_t size)
Definition: util-time.c:230
suricata-common.h
OutputCtx_::DeInit
void(* DeInit)(struct OutputCtx_ *)
Definition: tm-modules.h:91
SSLAlpns_::alpn
uint8_t alpn[]
Definition: app-layer-ssl.h:232
tls_fields
TlsFields tls_fields[]
Definition: output-json-tls.c:85
LOG_TLS_FIELD_CERTIFICATE
#define LOG_TLS_FIELD_CERTIFICATE
Definition: output-json-tls.c:69
OutputTlsCtx_
Definition: output-json-tls.c:96
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
threadvars.h
LOG_DIR_FLOW
@ LOG_DIR_FLOW
Definition: output-json.h:38
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
SCLogConfig
struct SCLogConfig_ SCLogConfig
Holds the config state used by the logging api.
TLS_HANDSHAKE_DONE
@ TLS_HANDSHAKE_DONE
Definition: app-layer-ssl.h:79
LOGGER_JSON_TX
@ LOGGER_JSON_TX
Definition: suricata-common.h:468
SCFree
#define SCFree(p)
Definition: util-mem.h:61
ConfNode_
Definition: conf.h:32
util-logopenfile.h
util-buffer.h
AppLayerGetProtoName
const char * AppLayerGetProtoName(AppProto alproto)
Given the internal protocol id, returns a string representation of the protocol.
Definition: app-layer.c:1004
SSLStateConnp_::cert0_sans_len
uint16_t cert0_sans_len
Definition: app-layer-ssl.h:263
ALPROTO_UNKNOWN
@ ALPROTO_UNKNOWN
Definition: app-layer-protos.h:29
OutputTlsCtx_::fields
uint64_t fields
Definition: output-json-tls.c:98
LOG_TLS_FIELD_SNI
#define LOG_TLS_FIELD_SNI
Definition: output-json-tls.c:68
SSLStateConnp_::cert0_fingerprint
char * cert0_fingerprint
Definition: app-layer-ssl.h:260
LOG_TLS_EXTENDED
#define LOG_TLS_EXTENDED
Definition: output-json-tls.c:57
SSLStateConnp_::ja3_str
JA3Buffer * ja3_str
Definition: app-layer-ssl.h:277
JsonTlsLogThread_::tlslog_ctx
OutputTlsCtx * tlslog_ctx
Definition: output-json-tls.c:104
LOG_TLS_FIELD_SESSION_RESUMED
#define LOG_TLS_FIELD_SESSION_RESUMED
Definition: output-json-tls.c:71
LOG_TLS_FIELD_CLIENT_CHAIN
#define LOG_TLS_FIELD_CLIENT_CHAIN
Definition: output-json-tls.c:76
LOG_TLS_SESSION_RESUMPTION
#define LOG_TLS_SESSION_RESUMPTION
Definition: output-json-tls.c:59
LOG_TLS_FIELD_CLIENT
#define LOG_TLS_FIELD_CLIENT
Definition: output-json-tls.c:74
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
LOG_TLS_FIELD_CHAIN
#define LOG_TLS_FIELD_CHAIN
Definition: output-json-tls.c:70
SSLStateConnp_::cert0_serial
char * cert0_serial
Definition: app-layer-ssl.h:257
LOG_TLS_FIELD_VERSION
#define LOG_TLS_FIELD_VERSION
Definition: output-json-tls.c:61
JsonTlsLogThread_
Definition: output-json-tls.c:103
app-layer-ssl.h
SSL_AL_FLAG_LOG_WITHOUT_CERT
#define SSL_AL_FLAG_LOG_WITHOUT_CERT
Definition: app-layer-ssl.h:123
output.h
SC_ATOMIC_EXTERN
SC_ATOMIC_EXTERN(unsigned int, cert_id)
app-layer.h
SSLStateConnp_::cert0_sans
char ** cert0_sans
Definition: app-layer-ssl.h:262
SSLState_::flags
uint32_t flags
Definition: app-layer-ssl.h:303
SSLStateConnp_::version
uint16_t version
Definition: app-layer-ssl.h:244
ConfNodeLookupChildValue
const char * ConfNodeLookupChildValue(const ConfNode *node, const char *name)
Lookup the value of a child configuration node by name.
Definition: conf.c:809