output-json-tls: log certificate and chain

Log entire certificate and certificate chain Base64 encoded.
pull/2584/head
Mats Klepsland 8 years ago
parent 0716199acb
commit 115b3138cc

@ -66,6 +66,8 @@ SC_ATOMIC_DECLARE(unsigned int, cert_id);
#define LOG_TLS_FIELD_NOTBEFORE (1 << 4)
#define LOG_TLS_FIELD_NOTAFTER (1 << 5)
#define LOG_TLS_FIELD_SNI (1 << 6)
#define LOG_TLS_FIELD_CERTIFICATE (1 << 7)
#define LOG_TLS_FIELD_CHAIN (1 << 8)
typedef struct {
char *name;
@ -80,6 +82,8 @@ TlsFields tls_fields[] = {
{ "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 },
{ NULL, -1 }
};
@ -178,6 +182,51 @@ static void JsonTlsLogNotAfter(json_t *js, SSLState *ssl_state)
}
}
static void JsonTlsLogCertificate(json_t *js, SSLState *ssl_state)
{
if ((ssl_state->server_connp.cert_input == NULL) ||
(ssl_state->server_connp.cert_input_len == 0)) {
return;
}
SSLCertsChain *cert = TAILQ_FIRST(&ssl_state->server_connp.certs);
if (cert == NULL) {
return;
}
unsigned long len = cert->cert_len * 2;
uint8_t encoded[len];
if (Base64Encode(cert->cert_data, cert->cert_len, encoded, &len) ==
SC_BASE64_OK) {
json_object_set_new(js, "certificate", json_string((char *)encoded));
}
}
static void JsonTlsLogChain(json_t *js, SSLState *ssl_state)
{
if ((ssl_state->server_connp.cert_input == NULL) ||
(ssl_state->server_connp.cert_input_len == 0)) {
return;
}
json_t *chain = json_array();
if (chain == NULL) {
return;
}
SSLCertsChain *cert;
TAILQ_FOREACH(cert, &ssl_state->server_connp.certs, next) {
unsigned long len = cert->cert_len * 2;
uint8_t encoded[len];
if (Base64Encode(cert->cert_data, cert->cert_len, encoded, &len) ==
SC_BASE64_OK) {
json_array_append_new(chain, json_string((char *)encoded));
}
}
json_object_set_new(js, "chain", chain);
}
void JsonTlsLogJSONBasic(json_t *js, SSLState *ssl_state)
{
/* tls.subject */
@ -217,6 +266,14 @@ static void JsonTlsLogJSONCustom(OutputTlsCtx *tls_ctx, json_t *js,
/* tls.notafter */
if (tls_ctx->fields & LOG_TLS_FIELD_NOTAFTER)
JsonTlsLogNotAfter(js, ssl_state);
/* tls.certificate */
if (tls_ctx->fields & LOG_TLS_FIELD_CERTIFICATE)
JsonTlsLogCertificate(js, ssl_state);
/* tls.chain */
if (tls_ctx->fields & LOG_TLS_FIELD_CHAIN)
JsonTlsLogChain(js, ssl_state);
}
void JsonTlsLogJSONExtended(json_t *tjs, SSLState * state)
@ -447,6 +504,14 @@ OutputCtx *OutputTlsLogInitSub(ConfNode *conf, OutputCtx *parent_ctx)
tls_ctx->file_ctx = ojc->file_ctx;
if ((tls_ctx->fields & LOG_TLS_FIELD_CERTIFICATE) &&
(tls_ctx->fields & LOG_TLS_FIELD_CHAIN)) {
SCLogWarning(SC_WARN_DUPLICATE_OUTPUT,
"Both 'certificate' and 'chain' contains the top "
"certificate, so only one of them should be enabled "
"at a time");
}
output_ctx->data = tls_ctx;
output_ctx->DeInit = OutputTlsLogDeinitSub;

@ -333,6 +333,7 @@ const char * SCErrorToString(SCError err)
CASE_CODE (SC_ERR_DNP3_CONFIG);
CASE_CODE (SC_ERR_DIR_OPEN);
CASE_CODE(SC_WARN_REMOVE_FILE);
CASE_CODE (SC_WARN_DUPLICATE_OUTPUT);
CASE_CODE (SC_ERR_NO_MAGIC_SUPPORT);
CASE_CODE (SC_ERR_REDIS);
CASE_CODE (SC_ERR_VAR_LIMIT);

@ -326,6 +326,7 @@ typedef enum {
SC_ERR_NO_MAGIC_SUPPORT,
SC_ERR_REDIS,
SC_ERR_VAR_LIMIT,
SC_WARN_DUPLICATE_OUTPUT,
} SCError;
const char *SCErrorToString(SCError);

@ -208,7 +208,7 @@ outputs:
extended: yes # enable this for extended logging information
# custom allows to control which tls fields that are included
# in eve-log
#custom: [subject, issuer, fingerprint, sni, version, not_before, not_after]
#custom: [subject, issuer, fingerprint, sni, version, not_before, not_after, certificate, chain]
- files:
force-magic: no # force logging magic on all logged files
# force logging of checksums, available hash functions are md5,

Loading…
Cancel
Save