suricata
output-json-tls.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2012 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 "debug.h"
28 #include "detect.h"
29 #include "pkt-var.h"
30 #include "conf.h"
31 
32 #include "threads.h"
33 #include "threadvars.h"
34 #include "tm-threads.h"
35 
36 #include "util-print.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-crypt.h"
49 #include "util-ja3.h"
50 
51 #include "output-json.h"
52 #include "output-json-tls.h"
53 
54 #ifdef HAVE_LIBJANSSON
55 
56 SC_ATOMIC_DECLARE(unsigned int, cert_id);
57 
58 #define MODULE_NAME "LogTlsLog"
59 #define DEFAULT_LOG_FILENAME "tls.json"
60 
61 #define LOG_TLS_DEFAULT 0
62 #define LOG_TLS_EXTENDED (1 << 0)
63 #define LOG_TLS_CUSTOM (1 << 1)
64 #define LOG_TLS_SESSION_RESUMPTION (1 << 2)
65 
66 #define LOG_TLS_FIELD_VERSION (1 << 0)
67 #define LOG_TLS_FIELD_SUBJECT (1 << 1)
68 #define LOG_TLS_FIELD_ISSUER (1 << 2)
69 #define LOG_TLS_FIELD_SERIAL (1 << 3)
70 #define LOG_TLS_FIELD_FINGERPRINT (1 << 4)
71 #define LOG_TLS_FIELD_NOTBEFORE (1 << 5)
72 #define LOG_TLS_FIELD_NOTAFTER (1 << 6)
73 #define LOG_TLS_FIELD_SNI (1 << 7)
74 #define LOG_TLS_FIELD_CERTIFICATE (1 << 8)
75 #define LOG_TLS_FIELD_CHAIN (1 << 9)
76 #define LOG_TLS_FIELD_SESSION_RESUMED (1 << 10)
77 #define LOG_TLS_FIELD_JA3 (1 << 11)
78 #define LOG_TLS_FIELD_JA3S (1 << 12)
79 
80 typedef struct {
81  const char *name;
82  uint64_t flag;
83 } TlsFields;
84 
85 TlsFields tls_fields[] = {
86  { "version", LOG_TLS_FIELD_VERSION },
87  { "subject", LOG_TLS_FIELD_SUBJECT },
88  { "issuer", LOG_TLS_FIELD_ISSUER },
89  { "serial", LOG_TLS_FIELD_SERIAL },
90  { "fingerprint", LOG_TLS_FIELD_FINGERPRINT },
91  { "not_before", LOG_TLS_FIELD_NOTBEFORE },
92  { "not_after", LOG_TLS_FIELD_NOTAFTER },
93  { "sni", LOG_TLS_FIELD_SNI },
94  { "certificate", LOG_TLS_FIELD_CERTIFICATE },
95  { "chain", LOG_TLS_FIELD_CHAIN },
96  { "session_resumed", LOG_TLS_FIELD_SESSION_RESUMED },
97  { "ja3", LOG_TLS_FIELD_JA3 },
98  { "ja3s", LOG_TLS_FIELD_JA3S },
99  { NULL, -1 }
100 };
101 
102 typedef struct OutputTlsCtx_ {
103  LogFileCtx *file_ctx;
104  uint32_t flags; /** Store mode */
105  uint64_t fields; /** Store fields */
106  OutputJsonCommonSettings cfg;
107 } OutputTlsCtx;
108 
109 
110 typedef struct JsonTlsLogThread_ {
111  OutputTlsCtx *tlslog_ctx;
112  MemBuffer *buffer;
113 } JsonTlsLogThread;
114 
115 static void JsonTlsLogSubject(json_t *js, SSLState *ssl_state)
116 {
117  if (ssl_state->server_connp.cert0_subject) {
118  json_object_set_new(js, "subject",
119  SCJsonString(ssl_state->server_connp.cert0_subject));
120  }
121 }
122 
123 static void JsonTlsLogIssuer(json_t *js, SSLState *ssl_state)
124 {
125  if (ssl_state->server_connp.cert0_issuerdn) {
126  json_object_set_new(js, "issuerdn",
127  SCJsonString(ssl_state->server_connp.cert0_issuerdn));
128  }
129 }
130 
131 static void JsonTlsLogSessionResumed(json_t *js, SSLState *ssl_state)
132 {
133  if (ssl_state->flags & SSL_AL_FLAG_SESSION_RESUMED) {
134  /* Only log a session as 'resumed' if a certificate has not
135  been seen, and the session is not TLSv1.3 or later. */
136  if ((ssl_state->server_connp.cert0_issuerdn == NULL &&
137  ssl_state->server_connp.cert0_subject == NULL) &&
138  (ssl_state->flags & SSL_AL_FLAG_STATE_SERVER_HELLO) &&
139  ((ssl_state->flags & SSL_AL_FLAG_LOG_WITHOUT_CERT) == 0)) {
140  json_object_set_new(js, "session_resumed", json_boolean(true));
141  }
142  }
143 }
144 
145 static void JsonTlsLogFingerprint(json_t *js, SSLState *ssl_state)
146 {
147  if (ssl_state->server_connp.cert0_fingerprint) {
148  json_object_set_new(js, "fingerprint",
149  SCJsonString(ssl_state->server_connp.cert0_fingerprint));
150  }
151 }
152 
153 static void JsonTlsLogSni(json_t *js, SSLState *ssl_state)
154 {
155  if (ssl_state->client_connp.sni) {
156  json_object_set_new(js, "sni",
157  SCJsonString(ssl_state->client_connp.sni));
158  }
159 }
160 
161 static void JsonTlsLogSerial(json_t *js, SSLState *ssl_state)
162 {
163  if (ssl_state->server_connp.cert0_serial) {
164  json_object_set_new(js, "serial",
165  SCJsonString(ssl_state->server_connp.cert0_serial));
166  }
167 }
168 
169 static void JsonTlsLogVersion(json_t *js, SSLState *ssl_state)
170 {
171  char ssl_version[SSL_VERSION_MAX_STRLEN];
172  SSLVersionToString(ssl_state->server_connp.version, ssl_version);
173  json_object_set_new(js, "version", json_string(ssl_version));
174 }
175 
176 static void JsonTlsLogNotBefore(json_t *js, SSLState *ssl_state)
177 {
178  if (ssl_state->server_connp.cert0_not_before != 0) {
179  char timebuf[64];
180  struct timeval tv;
181  tv.tv_sec = ssl_state->server_connp.cert0_not_before;
182  tv.tv_usec = 0;
183  CreateUtcIsoTimeString(&tv, timebuf, sizeof(timebuf));
184  json_object_set_new(js, "notbefore", json_string(timebuf));
185  }
186 }
187 
188 static void JsonTlsLogNotAfter(json_t *js, SSLState *ssl_state)
189 {
190  if (ssl_state->server_connp.cert0_not_after != 0) {
191  char timebuf[64];
192  struct timeval tv;
193  tv.tv_sec = ssl_state->server_connp.cert0_not_after;
194  tv.tv_usec = 0;
195  CreateUtcIsoTimeString(&tv, timebuf, sizeof(timebuf));
196  json_object_set_new(js, "notafter", json_string(timebuf));
197  }
198 }
199 
200 static void JsonTlsLogJa3Hash(json_t *js, SSLState *ssl_state)
201 {
202  if (ssl_state->client_connp.ja3_hash != NULL) {
203  json_object_set_new(js, "hash",
204  json_string(ssl_state->client_connp.ja3_hash));
205  }
206 }
207 
208 static void JsonTlsLogJa3String(json_t *js, SSLState *ssl_state)
209 {
210  if ((ssl_state->client_connp.ja3_str != NULL) &&
211  ssl_state->client_connp.ja3_str->data != NULL) {
212  json_object_set_new(js, "string",
213  json_string(ssl_state->client_connp.ja3_str->data));
214  }
215 }
216 
217 static void JsonTlsLogJa3(json_t *js, SSLState *ssl_state)
218 {
219  json_t *tjs = json_object();
220  if (unlikely(tjs == NULL))
221  return;
222 
223  JsonTlsLogJa3Hash(tjs, ssl_state);
224  JsonTlsLogJa3String(tjs, ssl_state);
225 
226  json_object_set_new(js, "ja3", tjs);
227 }
228 
229 static void JsonTlsLogJa3SHash(json_t *js, SSLState *ssl_state)
230 {
231  if (ssl_state->server_connp.ja3_hash != NULL) {
232  json_object_set_new(js, "hash",
233  json_string(ssl_state->server_connp.ja3_hash));
234  }
235 }
236 
237 static void JsonTlsLogJa3SString(json_t *js, SSLState *ssl_state)
238 {
239  if ((ssl_state->server_connp.ja3_str != NULL) &&
240  ssl_state->server_connp.ja3_str->data != NULL) {
241  json_object_set_new(js, "string",
242  json_string(ssl_state->server_connp.ja3_str->data));
243  }
244 }
245 
246 static void JsonTlsLogJa3S(json_t *js, SSLState *ssl_state)
247 {
248  json_t *tjs = json_object();
249  if (unlikely(tjs == NULL))
250  return;
251 
252  JsonTlsLogJa3SHash(tjs, ssl_state);
253  JsonTlsLogJa3SString(tjs, ssl_state);
254 
255  json_object_set_new(js, "ja3s", tjs);
256 }
257 static void JsonTlsLogCertificate(json_t *js, SSLState *ssl_state)
258 {
259  if (TAILQ_EMPTY(&ssl_state->server_connp.certs)) {
260  return;
261  }
262 
263  SSLCertsChain *cert = TAILQ_FIRST(&ssl_state->server_connp.certs);
264  if (cert == NULL) {
265  return;
266  }
267 
268  unsigned long len = cert->cert_len * 2;
269  uint8_t encoded[len];
270  if (Base64Encode(cert->cert_data, cert->cert_len, encoded, &len) ==
271  SC_BASE64_OK) {
272  json_object_set_new(js, "certificate", json_string((char *)encoded));
273  }
274 }
275 
276 static void JsonTlsLogChain(json_t *js, SSLState *ssl_state)
277 {
278  if (TAILQ_EMPTY(&ssl_state->server_connp.certs)) {
279  return;
280  }
281 
282  json_t *chain = json_array();
283  if (chain == NULL) {
284  return;
285  }
286 
287  SSLCertsChain *cert;
288  TAILQ_FOREACH(cert, &ssl_state->server_connp.certs, next) {
289  unsigned long len = cert->cert_len * 2;
290  uint8_t encoded[len];
291  if (Base64Encode(cert->cert_data, cert->cert_len, encoded, &len) ==
292  SC_BASE64_OK) {
293  json_array_append_new(chain, json_string((char *)encoded));
294  }
295  }
296 
297  json_object_set_new(js, "chain", chain);
298 }
299 
300 void JsonTlsLogJSONBasic(json_t *js, SSLState *ssl_state)
301 {
302  /* tls subject */
303  JsonTlsLogSubject(js, ssl_state);
304 
305  /* tls issuerdn */
306  JsonTlsLogIssuer(js, ssl_state);
307 
308  /* tls session resumption */
309  JsonTlsLogSessionResumed(js, ssl_state);
310 }
311 
312 static void JsonTlsLogJSONCustom(OutputTlsCtx *tls_ctx, json_t *js,
313  SSLState *ssl_state)
314 {
315  /* tls subject */
316  if (tls_ctx->fields & LOG_TLS_FIELD_SUBJECT)
317  JsonTlsLogSubject(js, ssl_state);
318 
319  /* tls issuerdn */
320  if (tls_ctx->fields & LOG_TLS_FIELD_ISSUER)
321  JsonTlsLogIssuer(js, ssl_state);
322 
323  /* tls session resumption */
324  if (tls_ctx->fields & LOG_TLS_FIELD_SESSION_RESUMED)
325  JsonTlsLogSessionResumed(js, ssl_state);
326 
327  /* tls serial */
328  if (tls_ctx->fields & LOG_TLS_FIELD_SERIAL)
329  JsonTlsLogSerial(js, ssl_state);
330 
331  /* tls fingerprint */
332  if (tls_ctx->fields & LOG_TLS_FIELD_FINGERPRINT)
333  JsonTlsLogFingerprint(js, ssl_state);
334 
335  /* tls sni */
336  if (tls_ctx->fields & LOG_TLS_FIELD_SNI)
337  JsonTlsLogSni(js, ssl_state);
338 
339  /* tls version */
340  if (tls_ctx->fields & LOG_TLS_FIELD_VERSION)
341  JsonTlsLogVersion(js, ssl_state);
342 
343  /* tls notbefore */
344  if (tls_ctx->fields & LOG_TLS_FIELD_NOTBEFORE)
345  JsonTlsLogNotBefore(js, ssl_state);
346 
347  /* tls notafter */
348  if (tls_ctx->fields & LOG_TLS_FIELD_NOTAFTER)
349  JsonTlsLogNotAfter(js, ssl_state);
350 
351  /* tls certificate */
352  if (tls_ctx->fields & LOG_TLS_FIELD_CERTIFICATE)
353  JsonTlsLogCertificate(js, ssl_state);
354 
355  /* tls chain */
356  if (tls_ctx->fields & LOG_TLS_FIELD_CHAIN)
357  JsonTlsLogChain(js, ssl_state);
358 
359  /* tls ja3_hash */
360  if (tls_ctx->fields & LOG_TLS_FIELD_JA3)
361  JsonTlsLogJa3(js, ssl_state);
362 
363  /* tls ja3s */
364  if (tls_ctx->fields & LOG_TLS_FIELD_JA3S)
365  JsonTlsLogJa3S(js, ssl_state);
366 }
367 
368 void JsonTlsLogJSONExtended(json_t *tjs, SSLState * state)
369 {
370  JsonTlsLogJSONBasic(tjs, state);
371 
372  /* tls serial */
373  JsonTlsLogSerial(tjs, state);
374 
375  /* tls fingerprint */
376  JsonTlsLogFingerprint(tjs, state);
377 
378  /* tls sni */
379  JsonTlsLogSni(tjs, state);
380 
381  /* tls version */
382  JsonTlsLogVersion(tjs, state);
383 
384  /* tls notbefore */
385  JsonTlsLogNotBefore(tjs, state);
386 
387  /* tls notafter */
388  JsonTlsLogNotAfter(tjs, state);
389 
390  /* tls ja3 */
391  JsonTlsLogJa3(tjs, state);
392 
393  /* tls ja3s */
394  JsonTlsLogJa3S(tjs, state);
395 }
396 
397 static int JsonTlsLogger(ThreadVars *tv, void *thread_data, const Packet *p,
398  Flow *f, void *state, void *txptr, uint64_t tx_id)
399 {
400  JsonTlsLogThread *aft = (JsonTlsLogThread *)thread_data;
401  OutputTlsCtx *tls_ctx = aft->tlslog_ctx;
402 
403  SSLState *ssl_state = (SSLState *)state;
404  if (unlikely(ssl_state == NULL)) {
405  return 0;
406  }
407 
408  if ((ssl_state->server_connp.cert0_issuerdn == NULL ||
409  ssl_state->server_connp.cert0_subject == NULL) &&
410  ((ssl_state->flags & SSL_AL_FLAG_SESSION_RESUMED) == 0 ||
411  (tls_ctx->flags & LOG_TLS_SESSION_RESUMPTION) == 0) &&
412  ((ssl_state->flags & SSL_AL_FLAG_LOG_WITHOUT_CERT) == 0)) {
413  return 0;
414  }
415 
416  json_t *js = CreateJSONHeader(p, LOG_DIR_FLOW, "tls");
417  if (unlikely(js == NULL)) {
418  return 0;
419  }
420 
421  JsonAddCommonOptions(&tls_ctx->cfg, p, f, js);
422 
423  json_t *tjs = json_object();
424  if (tjs == NULL) {
425  free(js);
426  return 0;
427  }
428 
429  /* reset */
430  MemBufferReset(aft->buffer);
431 
432  /* log custom fields */
433  if (tls_ctx->flags & LOG_TLS_CUSTOM) {
434  JsonTlsLogJSONCustom(tls_ctx, tjs, ssl_state);
435  }
436  /* log extended */
437  else if (tls_ctx->flags & LOG_TLS_EXTENDED) {
438  JsonTlsLogJSONExtended(tjs, ssl_state);
439  }
440  /* log basic */
441  else {
442  JsonTlsLogJSONBasic(tjs, ssl_state);
443  }
444 
445  /* print original application level protocol when it have been changed
446  because of STARTTLS, HTTP CONNECT, or similar. */
447  if (f->alproto_orig != ALPROTO_UNKNOWN) {
448  json_object_set_new(tjs, "from_proto",
449  json_string(AppLayerGetProtoName(f->alproto_orig)));
450  }
451 
452  json_object_set_new(js, "tls", tjs);
453 
454  OutputJSONBuffer(js, tls_ctx->file_ctx, &aft->buffer);
455  json_object_clear(js);
456  json_decref(js);
457 
458  return 0;
459 }
460 
461 static TmEcode JsonTlsLogThreadInit(ThreadVars *t, const void *initdata, void **data)
462 {
463  JsonTlsLogThread *aft = SCMalloc(sizeof(JsonTlsLogThread));
464  if (unlikely(aft == NULL)) {
465  return TM_ECODE_FAILED;
466  }
467 
468  memset(aft, 0, sizeof(JsonTlsLogThread));
469 
470  if (initdata == NULL) {
471  SCLogDebug("Error getting context for eve-log tls 'initdata' argument NULL");
472  SCFree(aft);
473  return TM_ECODE_FAILED;
474  }
475 
476  /* use the Output Context (file pointer and mutex) */
477  aft->tlslog_ctx = ((OutputCtx *)initdata)->data;
478 
479  aft->buffer = MemBufferCreateNew(JSON_OUTPUT_BUFFER_SIZE);
480  if (aft->buffer == NULL) {
481  SCFree(aft);
482  return TM_ECODE_FAILED;
483  }
484 
485  *data = (void *)aft;
486  return TM_ECODE_OK;
487 }
488 
489 static TmEcode JsonTlsLogThreadDeinit(ThreadVars *t, void *data)
490 {
491  JsonTlsLogThread *aft = (JsonTlsLogThread *)data;
492  if (aft == NULL) {
493  return TM_ECODE_OK;
494  }
495 
496  MemBufferFree(aft->buffer);
497 
498  /* clear memory */
499  memset(aft, 0, sizeof(JsonTlsLogThread));
500 
501  SCFree(aft);
502  return TM_ECODE_OK;
503 }
504 
505 static void OutputTlsLogDeinit(OutputCtx *output_ctx)
506 {
507  OutputTlsCtx *tls_ctx = output_ctx->data;
508  LogFileCtx *logfile_ctx = tls_ctx->file_ctx;
509  LogFileFreeCtx(logfile_ctx);
510  SCFree(tls_ctx);
511  SCFree(output_ctx);
512 }
513 
514 static OutputTlsCtx *OutputTlsInitCtx(ConfNode *conf)
515 {
516  OutputTlsCtx *tls_ctx = SCMalloc(sizeof(OutputTlsCtx));
517  if (unlikely(tls_ctx == NULL))
518  return NULL;
519 
520  tls_ctx->flags = LOG_TLS_DEFAULT;
521  tls_ctx->fields = 0;
522 
523  if (conf == NULL)
524  return tls_ctx;
525 
526  const char *extended = ConfNodeLookupChildValue(conf, "extended");
527  if (extended) {
528  if (ConfValIsTrue(extended)) {
529  tls_ctx->flags = LOG_TLS_EXTENDED;
530  }
531  }
532 
533  ConfNode *custom = ConfNodeLookupChild(conf, "custom");
534  if (custom) {
535  tls_ctx->flags = LOG_TLS_CUSTOM;
536  ConfNode *field;
537  TAILQ_FOREACH(field, &custom->head, next)
538  {
539  TlsFields *valid_fields = tls_fields;
540  for ( ; valid_fields->name != NULL; valid_fields++) {
541  if (strcasecmp(field->val, valid_fields->name) == 0) {
542  tls_ctx->fields |= valid_fields->flag;
543  break;
544  }
545  }
546  }
547  }
548 
549  const char *session_resumption = ConfNodeLookupChildValue(conf, "session-resumption");
550  if (session_resumption == NULL || ConfValIsTrue(session_resumption)) {
551  tls_ctx->flags |= LOG_TLS_SESSION_RESUMPTION;
552  }
553 
554  if ((tls_ctx->fields & LOG_TLS_FIELD_JA3) &&
555  Ja3IsDisabled("fields")) {
556  /* JA3 is disabled, so don't log any JA3 fields */
557  tls_ctx->fields &= ~LOG_TLS_FIELD_JA3;
558  tls_ctx->fields &= ~LOG_TLS_FIELD_JA3S;
559  }
560 
561  if ((tls_ctx->fields & LOG_TLS_FIELD_CERTIFICATE) &&
562  (tls_ctx->fields & LOG_TLS_FIELD_CHAIN)) {
564  "Both 'certificate' and 'chain' contains the top "
565  "certificate, so only one of them should be enabled "
566  "at a time");
567  }
568 
569  return tls_ctx;
570 }
571 
572 static OutputInitResult OutputTlsLogInit(ConfNode *conf)
573 {
574  OutputInitResult result = { NULL, false };
575  LogFileCtx *file_ctx = LogFileNewCtx();
576  if (file_ctx == NULL) {
577  SCLogError(SC_ERR_TLS_LOG_GENERIC, "couldn't create new file_ctx");
578  return result;
579  }
580 
581  if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) {
582  LogFileFreeCtx(file_ctx);
583  return result;
584  }
585 
586  OutputTlsCtx *tls_ctx = OutputTlsInitCtx(conf);
587  if (unlikely(tls_ctx == NULL)) {
588  LogFileFreeCtx(file_ctx);
589  return result;
590  }
591 
592  OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
593  if (unlikely(output_ctx == NULL)) {
594  LogFileFreeCtx(file_ctx);
595  SCFree(tls_ctx);
596  return result;
597  }
598 
599  tls_ctx->file_ctx = file_ctx;
600 
601  output_ctx->data = tls_ctx;
602  output_ctx->DeInit = OutputTlsLogDeinit;
603 
605 
606  result.ctx = output_ctx;
607  result.ok = true;
608  return result;
609 }
610 
611 static void OutputTlsLogDeinitSub(OutputCtx *output_ctx)
612 {
613  OutputTlsCtx *tls_ctx = output_ctx->data;
614  SCFree(tls_ctx);
615  SCFree(output_ctx);
616 }
617 
618 static OutputInitResult OutputTlsLogInitSub(ConfNode *conf, OutputCtx *parent_ctx)
619 {
620  OutputInitResult result = { NULL, false };
621  OutputJsonCtx *ojc = parent_ctx->data;
622 
623  OutputTlsCtx *tls_ctx = OutputTlsInitCtx(conf);
624  if (unlikely(tls_ctx == NULL))
625  return result;
626 
627  OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
628  if (unlikely(output_ctx == NULL)) {
629  SCFree(tls_ctx);
630  return result;
631  }
632 
633  tls_ctx->file_ctx = ojc->file_ctx;
634  tls_ctx->cfg = ojc->cfg;
635 
636  if ((tls_ctx->fields & LOG_TLS_FIELD_CERTIFICATE) &&
637  (tls_ctx->fields & LOG_TLS_FIELD_CHAIN)) {
639  "Both 'certificate' and 'chain' contains the top "
640  "certificate, so only one of them should be enabled "
641  "at a time");
642  }
643 
644  output_ctx->data = tls_ctx;
645  output_ctx->DeInit = OutputTlsLogDeinitSub;
646 
648 
649  result.ctx = output_ctx;
650  result.ok = true;
651  return result;
652 }
653 
654 void JsonTlsLogRegister (void)
655 {
656  /* register as separate module */
658  "tls-json-log", OutputTlsLogInit, ALPROTO_TLS, JsonTlsLogger,
659  TLS_HANDSHAKE_DONE, TLS_HANDSHAKE_DONE, JsonTlsLogThreadInit,
660  JsonTlsLogThreadDeinit, NULL);
661 
662  /* also register as child of eve-log */
664  "JsonTlsLog", "eve-log.tls", OutputTlsLogInitSub, ALPROTO_TLS,
665  JsonTlsLogger, TLS_HANDSHAKE_DONE, TLS_HANDSHAKE_DONE,
666  JsonTlsLogThreadInit, JsonTlsLogThreadDeinit, NULL);
667 }
668 
669 #else
670 
672 {
673 }
674 
675 #endif /* HAVE_LIBJANSSON */
676 
#define SSL_AL_FLAG_SESSION_RESUMED
MemBuffer * MemBufferCreateNew(uint32_t size)
Definition: util-buffer.c:32
#define SSL_AL_FLAG_STATE_SERVER_HELLO
Definition: app-layer-ssl.h:84
uint16_t flags
char * cert0_subject
#define SCLogDebug(...)
Definition: util-debug.h:335
time_t cert0_not_before
uint32_t flags
#define TAILQ_FIRST(head)
Definition: queue.h:339
#define SC_ATOMIC_DECLARE(type, name)
wrapper to declare an atomic variable including a (spin) lock to protect it.
Definition: util-atomic.h:56
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:350
struct HtpBodyChunk_ * next
#define LOG_TLS_DEFAULT
Definition: log-tlslog.c:66
#define LOG_TLS_EXTENDED
Definition: log-tlslog.c:67
uint16_t version
#define unlikely(expr)
Definition: util-optimize.h:35
void JsonTlsLogRegister(void)
char * cert0_fingerprint
#define MemBufferReset(mem_buffer)
Reset the mem buffer.
Definition: util-buffer.h:42
SSLStateConnp server_connp
char * data
Definition: util-ja3.h:30
void(* DeInit)(struct OutputCtx_ *)
Definition: tm-modules.h:84
int Ja3IsDisabled(const char *type)
Check if JA3 is disabled.
Definition: util-ja3.c:262
time_t cert0_not_after
char * val
Definition: conf.h:34
void CreateUtcIsoTimeString(const struct timeval *ts, char *str, size_t size)
Definition: util-time.c:203
ConfNode * ConfNodeLookupChild(const ConfNode *node, const char *name)
Lookup a child configuration node by name.
Definition: conf.c:815
void SSLVersionToString(uint16_t version, char *buffer)
#define SSL_VERSION_MAX_STRLEN
SSLv[2.0|3.[0|1|2|3]] state structure.
AppProto alproto_orig
Definition: flow.h:415
#define SCCalloc(nm, a)
Definition: util-mem.h:253
const char * ConfNodeLookupChildValue(const ConfNode *node, const char *name)
Lookup the value of a child configuration node by name.
Definition: conf.c:843
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
void AppLayerParserRegisterLogger(uint8_t ipproto, AppProto alproto)
void OutputRegisterTxModuleWithProgress(LoggerId id, const char *name, const char *conf_name, OutputInitFunc InitFunc, AppProto alproto, TxLogger TxLogFunc, int tc_log_progress, int ts_log_progress, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, ThreadExitPrintStatsFunc ThreadExitPrintStats)
Register a tx output module with progress.
Definition: output.c:358
LogFileCtx * LogFileNewCtx(void)
LogFileNewCtx() Get a new LogFileCtx.
int SCConfLogOpenGeneric(ConfNode *conf, LogFileCtx *log_ctx, const char *default_filename, int rotate)
open a generic output "log file", which may be a regular file or a socket
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:369
#define LOG_TLS_SESSION_RESUMPTION
Definition: log-tlslog.c:69
#define LOG_TLS_CUSTOM
Definition: log-tlslog.c:68
#define SCLogWarning(err_code,...)
Macro used to log WARNING messages.
Definition: util-debug.h:281
int ConfValIsTrue(const char *val)
Check if a value is true.
Definition: conf.c:566
Definition: conf.h:32
OutputCtx * ctx
Definition: output.h:42
#define DEFAULT_LOG_FILENAME
#define SCMalloc(a)
Definition: util-mem.h:222
int LogFileFreeCtx(LogFileCtx *lf_ctx)
LogFileFreeCtx() Destroy a LogFileCtx (Close the file and free memory)
#define SCFree(a)
Definition: util-mem.h:322
uint32_t cert_len
uint16_t tx_id
uint8_t * cert_data
void * data
Definition: tm-modules.h:81
int Base64Encode(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen)
Definition: util-crypt.c:272
const char * AppLayerGetProtoName(AppProto alproto)
Given the internal protocol id, returns a string representation of the protocol.
Definition: app-layer.c:766
#define TAILQ_EMPTY(head)
Definition: queue.h:347
uint8_t len
Per thread variable structure.
Definition: threadvars.h:57
JA3Buffer * ja3_str
#define SSL_AL_FLAG_LOG_WITHOUT_CERT
Flow data structure.
Definition: flow.h:325
SSLStateConnp client_connp
char * cert0_issuerdn
void MemBufferFree(MemBuffer *buffer)
Definition: util-buffer.c:82