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