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