|
|
|
@ -73,28 +73,24 @@ SC_ATOMIC_EXTERN(unsigned int, cert_id);
|
|
|
|
|
#define LOG_TLS_FIELD_SESSION_RESUMED (1 << 10)
|
|
|
|
|
#define LOG_TLS_FIELD_JA3 (1 << 11)
|
|
|
|
|
#define LOG_TLS_FIELD_JA3S (1 << 12)
|
|
|
|
|
#define LOG_TLS_FIELD_CLIENT (1 << 13) /**< client fields (issuer, subject, etc) */
|
|
|
|
|
#define LOG_TLS_FIELD_CLIENT_CERT (1 << 14)
|
|
|
|
|
#define LOG_TLS_FIELD_CLIENT_CHAIN (1 << 15)
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
const char *name;
|
|
|
|
|
uint64_t flag;
|
|
|
|
|
} TlsFields;
|
|
|
|
|
|
|
|
|
|
TlsFields tls_fields[] = {
|
|
|
|
|
{ "version", LOG_TLS_FIELD_VERSION },
|
|
|
|
|
{ "subject", LOG_TLS_FIELD_SUBJECT },
|
|
|
|
|
{ "issuer", LOG_TLS_FIELD_ISSUER },
|
|
|
|
|
{ "serial", LOG_TLS_FIELD_SERIAL },
|
|
|
|
|
{ "fingerprint", LOG_TLS_FIELD_FINGERPRINT },
|
|
|
|
|
{ "not_before", LOG_TLS_FIELD_NOTBEFORE },
|
|
|
|
|
{ "not_after", LOG_TLS_FIELD_NOTAFTER },
|
|
|
|
|
{ "sni", LOG_TLS_FIELD_SNI },
|
|
|
|
|
{ "certificate", LOG_TLS_FIELD_CERTIFICATE },
|
|
|
|
|
{ "chain", LOG_TLS_FIELD_CHAIN },
|
|
|
|
|
{ "session_resumed", LOG_TLS_FIELD_SESSION_RESUMED },
|
|
|
|
|
{ "ja3", LOG_TLS_FIELD_JA3 },
|
|
|
|
|
{ "ja3s", LOG_TLS_FIELD_JA3S },
|
|
|
|
|
{ NULL, -1 }
|
|
|
|
|
};
|
|
|
|
|
TlsFields tls_fields[] = { { "version", LOG_TLS_FIELD_VERSION },
|
|
|
|
|
{ "subject", LOG_TLS_FIELD_SUBJECT }, { "issuer", LOG_TLS_FIELD_ISSUER },
|
|
|
|
|
{ "serial", LOG_TLS_FIELD_SERIAL }, { "fingerprint", LOG_TLS_FIELD_FINGERPRINT },
|
|
|
|
|
{ "not_before", LOG_TLS_FIELD_NOTBEFORE }, { "not_after", LOG_TLS_FIELD_NOTAFTER },
|
|
|
|
|
{ "sni", LOG_TLS_FIELD_SNI }, { "certificate", LOG_TLS_FIELD_CERTIFICATE },
|
|
|
|
|
{ "chain", LOG_TLS_FIELD_CHAIN }, { "session_resumed", LOG_TLS_FIELD_SESSION_RESUMED },
|
|
|
|
|
{ "ja3", LOG_TLS_FIELD_JA3 }, { "ja3s", LOG_TLS_FIELD_JA3S },
|
|
|
|
|
{ "client", LOG_TLS_FIELD_CLIENT }, { "client_certificate", LOG_TLS_FIELD_CLIENT_CERT },
|
|
|
|
|
{ "client_chain", LOG_TLS_FIELD_CLIENT_CHAIN }, { NULL, -1 } };
|
|
|
|
|
|
|
|
|
|
typedef struct OutputTlsCtx_ {
|
|
|
|
|
uint32_t flags; /** Store mode */
|
|
|
|
@ -285,6 +281,53 @@ static void JsonTlsLogChain(JsonBuilder *js, SSLStateConnp *connp)
|
|
|
|
|
jb_close(js);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool HasClientCert(SSLStateConnp *connp)
|
|
|
|
|
{
|
|
|
|
|
if (connp->cert0_subject || connp->cert0_issuerdn)
|
|
|
|
|
return true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void JsonTlsLogClientCert(
|
|
|
|
|
JsonBuilder *js, SSLStateConnp *connp, const bool log_cert, const bool log_chain)
|
|
|
|
|
{
|
|
|
|
|
if (connp->cert0_subject != NULL) {
|
|
|
|
|
jb_set_string(js, "subject", connp->cert0_subject);
|
|
|
|
|
}
|
|
|
|
|
if (connp->cert0_issuerdn != NULL) {
|
|
|
|
|
jb_set_string(js, "issuerdn", connp->cert0_issuerdn);
|
|
|
|
|
}
|
|
|
|
|
if (connp->cert0_fingerprint) {
|
|
|
|
|
jb_set_string(js, "fingerprint", connp->cert0_fingerprint);
|
|
|
|
|
}
|
|
|
|
|
if (connp->cert0_serial) {
|
|
|
|
|
jb_set_string(js, "serial", connp->cert0_serial);
|
|
|
|
|
}
|
|
|
|
|
if (connp->cert0_not_before != 0) {
|
|
|
|
|
char timebuf[64];
|
|
|
|
|
struct timeval tv;
|
|
|
|
|
tv.tv_sec = connp->cert0_not_before;
|
|
|
|
|
tv.tv_usec = 0;
|
|
|
|
|
CreateUtcIsoTimeString(&tv, timebuf, sizeof(timebuf));
|
|
|
|
|
jb_set_string(js, "notbefore", timebuf);
|
|
|
|
|
}
|
|
|
|
|
if (connp->cert0_not_after != 0) {
|
|
|
|
|
char timebuf[64];
|
|
|
|
|
struct timeval tv;
|
|
|
|
|
tv.tv_sec = connp->cert0_not_after;
|
|
|
|
|
tv.tv_usec = 0;
|
|
|
|
|
CreateUtcIsoTimeString(&tv, timebuf, sizeof(timebuf));
|
|
|
|
|
jb_set_string(js, "notafter", timebuf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (log_cert) {
|
|
|
|
|
JsonTlsLogCertificate(js, connp);
|
|
|
|
|
}
|
|
|
|
|
if (log_chain) {
|
|
|
|
|
JsonTlsLogChain(js, connp);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JsonTlsLogJSONBasic(JsonBuilder *js, SSLState *ssl_state)
|
|
|
|
|
{
|
|
|
|
|
/* tls subject */
|
|
|
|
@ -351,6 +394,16 @@ static void JsonTlsLogJSONCustom(OutputTlsCtx *tls_ctx, JsonBuilder *js,
|
|
|
|
|
/* tls ja3s */
|
|
|
|
|
if (tls_ctx->fields & LOG_TLS_FIELD_JA3S)
|
|
|
|
|
JsonTlsLogJa3S(js, ssl_state);
|
|
|
|
|
|
|
|
|
|
if (tls_ctx->fields & LOG_TLS_FIELD_CLIENT) {
|
|
|
|
|
const bool log_cert = (tls_ctx->fields & LOG_TLS_FIELD_CLIENT_CERT) != 0;
|
|
|
|
|
const bool log_chain = (tls_ctx->fields & LOG_TLS_FIELD_CLIENT_CHAIN) != 0;
|
|
|
|
|
if (HasClientCert(&ssl_state->client_connp)) {
|
|
|
|
|
jb_open_object(js, "client");
|
|
|
|
|
JsonTlsLogClientCert(js, &ssl_state->client_connp, log_cert, log_chain);
|
|
|
|
|
jb_close(js);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void JsonTlsLogJSONExtended(JsonBuilder *tjs, SSLState * state)
|
|
|
|
@ -380,6 +433,12 @@ void JsonTlsLogJSONExtended(JsonBuilder *tjs, SSLState * state)
|
|
|
|
|
|
|
|
|
|
/* tls ja3s */
|
|
|
|
|
JsonTlsLogJa3S(tjs, state);
|
|
|
|
|
|
|
|
|
|
if (HasClientCert(&state->client_connp)) {
|
|
|
|
|
jb_open_object(tjs, "client");
|
|
|
|
|
JsonTlsLogClientCert(tjs, &state->client_connp, false, false);
|
|
|
|
|
jb_close(tjs);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int JsonTlsLogger(ThreadVars *tv, void *thread_data, const Packet *p,
|
|
|
|
@ -540,6 +599,24 @@ static OutputTlsCtx *OutputTlsInitCtx(ConfNode *conf)
|
|
|
|
|
"certificate, so only one of them should be enabled "
|
|
|
|
|
"at a time");
|
|
|
|
|
}
|
|
|
|
|
if ((tls_ctx->fields & LOG_TLS_FIELD_CLIENT_CERT) &&
|
|
|
|
|
(tls_ctx->fields & LOG_TLS_FIELD_CLIENT_CHAIN)) {
|
|
|
|
|
SCLogWarning(SC_WARN_DUPLICATE_OUTPUT,
|
|
|
|
|
"Both 'client_certificate' and 'client_chain' contains the top "
|
|
|
|
|
"certificate, so only one of them should be enabled "
|
|
|
|
|
"at a time");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((tls_ctx->fields & LOG_TLS_FIELD_CLIENT) == 0) {
|
|
|
|
|
if (tls_ctx->fields & LOG_TLS_FIELD_CLIENT_CERT) {
|
|
|
|
|
SCLogConfig("enabling \"client\" as a dependency of \"client_certificate\"");
|
|
|
|
|
tls_ctx->fields |= LOG_TLS_FIELD_CLIENT;
|
|
|
|
|
}
|
|
|
|
|
if (tls_ctx->fields & LOG_TLS_FIELD_CLIENT_CHAIN) {
|
|
|
|
|
SCLogConfig("enabling \"client\" as a dependency of \"client_chain\"");
|
|
|
|
|
tls_ctx->fields |= LOG_TLS_FIELD_CLIENT;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return tls_ctx;
|
|
|
|
|
}
|
|
|
|
|