|
|
|
|
@ -46,6 +46,7 @@
|
|
|
|
|
|
|
|
|
|
#include "util-logopenfile.h"
|
|
|
|
|
#include "util-crypt.h"
|
|
|
|
|
#include "util-ja3.h"
|
|
|
|
|
|
|
|
|
|
#include "output-json.h"
|
|
|
|
|
#include "output-json-tls.h"
|
|
|
|
|
@ -77,6 +78,7 @@ SC_ATOMIC_DECLARE(unsigned int, cert_id);
|
|
|
|
|
#define LOG_TLS_FIELD_CERTIFICATE (1 << 8)
|
|
|
|
|
#define LOG_TLS_FIELD_CHAIN (1 << 9)
|
|
|
|
|
#define LOG_TLS_FIELD_SESSION_RESUMED (1 << 10)
|
|
|
|
|
#define LOG_TLS_FIELD_JA3 (1 << 11)
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
const char *name;
|
|
|
|
|
@ -95,6 +97,7 @@ TlsFields tls_fields[] = {
|
|
|
|
|
{ "certificate", LOG_TLS_FIELD_CERTIFICATE },
|
|
|
|
|
{ "chain", LOG_TLS_FIELD_CHAIN },
|
|
|
|
|
{ "session_resumed", LOG_TLS_FIELD_SESSION_RESUMED },
|
|
|
|
|
{ "ja3", LOG_TLS_FIELD_JA3 },
|
|
|
|
|
{ NULL, -1 }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@ -211,6 +214,34 @@ static void JsonTlsLogNotAfter(json_t *js, SSLState *ssl_state)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void JsonTlsLogJa3Hash(json_t *js, SSLState *ssl_state)
|
|
|
|
|
{
|
|
|
|
|
if (ssl_state->ja3_hash != NULL) {
|
|
|
|
|
json_object_set_new(js, "hash", json_string(ssl_state->ja3_hash));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void JsonTlsLogJa3String(json_t *js, SSLState *ssl_state)
|
|
|
|
|
{
|
|
|
|
|
if ((ssl_state->ja3_str != NULL) &&
|
|
|
|
|
ssl_state->ja3_str->data != NULL) {
|
|
|
|
|
json_object_set_new(js, "string",
|
|
|
|
|
json_string(ssl_state->ja3_str->data));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void JsonTlsLogJa3(json_t *js, SSLState *ssl_state)
|
|
|
|
|
{
|
|
|
|
|
json_t *tjs = json_object();
|
|
|
|
|
if (unlikely(tjs == NULL))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
JsonTlsLogJa3Hash(tjs, ssl_state);
|
|
|
|
|
JsonTlsLogJa3String(tjs, ssl_state);
|
|
|
|
|
|
|
|
|
|
json_object_set_new(js, "ja3", tjs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void JsonTlsLogCertificate(json_t *js, SSLState *ssl_state)
|
|
|
|
|
{
|
|
|
|
|
if ((ssl_state->server_connp.cert_input == NULL) ||
|
|
|
|
|
@ -314,6 +345,10 @@ static void JsonTlsLogJSONCustom(OutputTlsCtx *tls_ctx, json_t *js,
|
|
|
|
|
/* tls chain */
|
|
|
|
|
if (tls_ctx->fields & LOG_TLS_FIELD_CHAIN)
|
|
|
|
|
JsonTlsLogChain(js, ssl_state);
|
|
|
|
|
|
|
|
|
|
/* tls ja3_hash */
|
|
|
|
|
if (tls_ctx->fields & LOG_TLS_FIELD_JA3)
|
|
|
|
|
JsonTlsLogJa3(js, ssl_state);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JsonTlsLogJSONExtended(json_t *tjs, SSLState * state)
|
|
|
|
|
@ -337,6 +372,9 @@ void JsonTlsLogJSONExtended(json_t *tjs, SSLState * state)
|
|
|
|
|
|
|
|
|
|
/* tls notafter */
|
|
|
|
|
JsonTlsLogNotAfter(tjs, state);
|
|
|
|
|
|
|
|
|
|
/* tls ja3 */
|
|
|
|
|
JsonTlsLogJa3(tjs, state);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int JsonTlsLogger(ThreadVars *tv, void *thread_data, const Packet *p,
|
|
|
|
|
@ -497,6 +535,12 @@ static OutputTlsCtx *OutputTlsInitCtx(ConfNode *conf)
|
|
|
|
|
tls_ctx->flags |= LOG_TLS_SESSION_RESUMPTION;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((tls_ctx->fields & LOG_TLS_FIELD_JA3) &&
|
|
|
|
|
Ja3IsDisabled("fields")) {
|
|
|
|
|
/* JA3 is disabled, so don't log any JA3 fields */
|
|
|
|
|
tls_ctx->fields &= ~LOG_TLS_FIELD_JA3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((tls_ctx->fields & LOG_TLS_FIELD_CERTIFICATE) &&
|
|
|
|
|
(tls_ctx->fields & LOG_TLS_FIELD_CHAIN)) {
|
|
|
|
|
SCLogWarning(SC_WARN_DUPLICATE_OUTPUT,
|
|
|
|
|
|