From: Ray Ruvinskiy Date: Thu, 24 Nov 2016 17:16:09 +0000 (-0500) Subject: tls: logging for session resumption X-Git-Tag: suricata-4.0.0-beta1~201 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F2672%2Fhead;p=thirdparty%2Fsuricata.git tls: logging for session resumption We assume session resumption has occurred if the Client Hello message included a session id, we have not seen the server certificate, but we have seen a Change Cipher Spec message from the server. Previously, these transactions were not logged at all because the server cert was never seen. Ticket: https://redmine.openinfosecfoundation.org/issues/1969 --- diff --git a/doc/userguide/configuration/suricata-yaml.rst b/doc/userguide/configuration/suricata-yaml.rst index 7505b9e9dc..e45517124b 100644 --- a/doc/userguide/configuration/suricata-yaml.rst +++ b/doc/userguide/configuration/suricata-yaml.rst @@ -324,6 +324,9 @@ integration with 3rd party tools like logstash. #custom: [a, aaaa, cname, mx, ns, ptr, txt] - tls: extended: yes # enable this for extended logging information + # output TLS transaction where the session is resumed using a + # session id + #session-resumption: no - files: force-magic: no # force logging magic on all logged files # force logging of checksums, available hash functions are md5, diff --git a/doc/userguide/output/eve/eve-json-format.rst b/doc/userguide/output/eve/eve-json-format.rst index 7020f705c5..2d2a5632a2 100644 --- a/doc/userguide/output/eve/eve-json-format.rst +++ b/doc/userguide/output/eve/eve-json-format.rst @@ -205,6 +205,7 @@ Fields * "subject": The subject field from the TLS certificate * "issuer": The issuer field from the TLS certificate +* "session_resumed": This field has the value of "true" if the TLS session was resumed via a session id. If this field appears, "subject" and "issuer" do not appear, since a TLS certificate is not seen. If extended logging is enabled the following fields are also included: @@ -232,6 +233,14 @@ Example of regular TLS logging: "issuerdn": "C=US, O=Google Inc, CN=Google Internet Authority G2" } +Example of regular TLS logging for resumed sessions: + +:: + + "tls": { + "session_resumed": true + } + Example of extended TLS logging: :: diff --git a/src/app-layer-ssl.c b/src/app-layer-ssl.c index f6839adc5f..2397739819 100644 --- a/src/app-layer-ssl.c +++ b/src/app-layer-ssl.c @@ -265,6 +265,9 @@ static int TLSDecodeHandshakeHello(SSLState *ssl_state, uint8_t *input, /* skip session id */ uint8_t session_id_length = *(input++); + if (session_id_length != 0) { + ssl_state->flags |= SSL_AL_FLAG_SSL_CLIENT_SESSION_ID; + } input += session_id_length; @@ -1202,10 +1205,18 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state, case SSLV3_CHANGE_CIPHER_SPEC: ssl_state->flags |= SSL_AL_FLAG_CHANGE_CIPHER_SPEC; - if (direction) + if (direction) { ssl_state->flags |= SSL_AL_FLAG_SERVER_CHANGE_CIPHER_SPEC; - else + + int server_cert_seen = ssl_state->server_connp.cert0_issuerdn != NULL && \ + ssl_state->server_connp.cert0_subject != NULL; + if (!server_cert_seen && (ssl_state->flags & SSL_AL_FLAG_SSL_CLIENT_SESSION_ID) != 0) { + ssl_state->flags |= SSL_AL_FLAG_SESSION_RESUMED; + } + + } else { ssl_state->flags |= SSL_AL_FLAG_CLIENT_CHANGE_CIPHER_SPEC; + } break; @@ -4102,6 +4113,143 @@ static int SSLParserTest25(void) PASS; } +static int SSLParserTest26(void) +{ + Flow f; + uint8_t client_hello[] = { + 0x16, 0x03, 0x01, 0x02, 0x0e, 0x01, 0x00, 0x02, + 0x0a, 0x03, 0x03, 0x58, 0x36, 0x15, 0x03, 0x8e, + 0x07, 0xf9, 0xad, 0x2a, 0xb7, 0x56, 0xbf, 0xe2, + 0xa2, 0xf8, 0x21, 0xe0, 0xbb, 0x69, 0xc2, 0xd6, + 0x76, 0xe6, 0x77, 0xfe, 0x09, 0xff, 0x8e, 0xac, + 0x80, 0xb5, 0x27, 0x20, 0xb7, 0xbb, 0x90, 0x35, + 0x7a, 0xdd, 0xd9, 0x67, 0xdf, 0x79, 0xd6, 0x16, + 0x90, 0xf6, 0xd7, 0x5c, 0xd3, 0x07, 0x19, 0x20, + 0x01, 0x39, 0x76, 0x25, 0x12, 0x32, 0x71, 0xa1, + 0x84, 0x8d, 0x2d, 0xea, 0x00, 0x88, 0xc0, 0x30, + 0xc0, 0x2c, 0xc0, 0x28, 0xc0, 0x24, 0xc0, 0x14, + 0xc0, 0x0a, 0x00, 0xa3, 0x00, 0x9f, 0x00, 0x6b, + 0x00, 0x6a, 0x00, 0x39, 0x00, 0x38, 0x00, 0x88, + 0x00, 0x87, 0xc0, 0x32, 0xc0, 0x2e, 0xc0, 0x2a, + 0xc0, 0x26, 0xc0, 0x0f, 0xc0, 0x05, 0x00, 0x9d, + 0x00, 0x3d, 0x00, 0x35, 0x00, 0x84, 0xc0, 0x12, + 0xc0, 0x08, 0x00, 0x16, 0x00, 0x13, 0xc0, 0x0d, + 0xc0, 0x03, 0x00, 0x0a, 0xc0, 0x2f, 0xc0, 0x2b, + 0xc0, 0x27, 0xc0, 0x23, 0xc0, 0x13, 0xc0, 0x09, + 0x00, 0xa2, 0x00, 0x9e, 0x00, 0x67, 0x00, 0x40, + 0x00, 0x33, 0x00, 0x32, 0x00, 0x9a, 0x00, 0x99, + 0x00, 0x45, 0x00, 0x44, 0xc0, 0x31, 0xc0, 0x2d, + 0xc0, 0x29, 0xc0, 0x25, 0xc0, 0x0e, 0xc0, 0x04, + 0x00, 0x9c, 0x00, 0x3c, 0x00, 0x2f, 0x00, 0x96, + 0x00, 0x41, 0xc0, 0x11, 0xc0, 0x07, 0xc0, 0x0c, + 0xc0, 0x02, 0x00, 0x05, 0x00, 0x04, 0x00, 0x15, + 0x00, 0x12, 0x00, 0x09, 0x00, 0xff, 0x01, 0x00, + 0x01, 0x39, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, + 0x00, 0x00, 0x0f, 0x77, 0x77, 0x77, 0x2e, 0x79, + 0x6f, 0x75, 0x74, 0x75, 0x62, 0x65, 0x2e, 0x63, + 0x6f, 0x6d, 0x00, 0x0b, 0x00, 0x04, 0x03, 0x00, + 0x01, 0x02, 0x00, 0x0a, 0x00, 0x34, 0x00, 0x32, + 0x00, 0x0e, 0x00, 0x0d, 0x00, 0x19, 0x00, 0x0b, + 0x00, 0x0c, 0x00, 0x18, 0x00, 0x09, 0x00, 0x0a, + 0x00, 0x16, 0x00, 0x17, 0x00, 0x08, 0x00, 0x06, + 0x00, 0x07, 0x00, 0x14, 0x00, 0x15, 0x00, 0x04, + 0x00, 0x05, 0x00, 0x12, 0x00, 0x13, 0x00, 0x01, + 0x00, 0x02, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x10, + 0x00, 0x11, 0x00, 0x23, 0x00, 0xb4, 0x05, 0x6c, + 0xfa, 0x27, 0x6f, 0x12, 0x2f, 0x2a, 0xe5, 0x56, + 0xcb, 0x42, 0x62, 0x44, 0xf2, 0xd7, 0xd1, 0x05, + 0x87, 0xd4, 0x52, 0x02, 0x10, 0x85, 0xa4, 0xa6, + 0x82, 0x6f, 0x6d, 0x7b, 0xaf, 0x11, 0xbe, 0x21, + 0x7e, 0x7c, 0x36, 0x03, 0x20, 0x29, 0xd8, 0xf9, + 0xe5, 0x2b, 0xe2, 0x26, 0xb2, 0x27, 0xc7, 0xb9, + 0xda, 0x59, 0xd7, 0xdc, 0xfd, 0x74, 0x74, 0x76, + 0xd0, 0x5e, 0xe4, 0xfe, 0x9d, 0xb7, 0x1b, 0x13, + 0x81, 0xce, 0x63, 0x75, 0x2b, 0x2f, 0x98, 0x3a, + 0x84, 0x46, 0xd3, 0x0c, 0xb3, 0x01, 0xdb, 0x62, + 0x51, 0x97, 0x92, 0x1c, 0xa5, 0x94, 0x60, 0xef, + 0xa6, 0xd8, 0xb2, 0x2f, 0x02, 0x42, 0x5c, 0xac, + 0xb4, 0xd9, 0x10, 0x2f, 0x7e, 0x89, 0xab, 0xa5, + 0xd7, 0x56, 0x6d, 0x03, 0xd2, 0x5f, 0x20, 0x2c, + 0xb6, 0x99, 0x2b, 0x66, 0xbd, 0xd4, 0xde, 0x53, + 0x76, 0x5c, 0x78, 0xf0, 0xe9, 0x6d, 0xa5, 0xc3, + 0x1a, 0x9e, 0x61, 0xb2, 0x45, 0xb0, 0xb3, 0x61, + 0xee, 0xa1, 0x07, 0xab, 0x2f, 0x84, 0xea, 0x43, + 0x76, 0x4b, 0x3d, 0xb0, 0xbe, 0xa4, 0xb4, 0x21, + 0xe1, 0xd3, 0xfd, 0x91, 0xe2, 0xe7, 0xf3, 0x38, + 0x9c, 0x56, 0x5f, 0xa1, 0xde, 0xa8, 0x2f, 0x0a, + 0x49, 0x6d, 0x44, 0x8e, 0xb7, 0xef, 0x4a, 0x6f, + 0x79, 0xb2, 0x00, 0x0d, 0x00, 0x20, 0x00, 0x1e, + 0x06, 0x01, 0x06, 0x02, 0x06, 0x03, 0x05, 0x01, + 0x05, 0x02, 0x05, 0x03, 0x04, 0x01, 0x04, 0x02, + 0x04, 0x03, 0x03, 0x01, 0x03, 0x02, 0x03, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x02, 0x03, 0x00, 0x0f, + 0x00, 0x01, 0x01 + }; + uint32_t client_hello_len = sizeof(client_hello); + + uint8_t server_hello_change_cipher_spec[] = { + 0x16, 0x03, 0x03, 0x00, 0x57, 0x02, 0x00, 0x00, + 0x53, 0x03, 0x03, 0x58, 0x36, 0x15, 0x03, 0x9f, + 0x3b, 0xf3, 0x11, 0x96, 0x2b, 0xc3, 0xae, 0x91, + 0x8c, 0x5f, 0x8b, 0x3f, 0x90, 0xbd, 0xa9, 0x26, + 0x26, 0xb2, 0xfd, 0x12, 0xc5, 0xc5, 0x7b, 0xe4, + 0xd1, 0x3e, 0x81, 0x20, 0xb7, 0xbb, 0x90, 0x35, + 0x7a, 0xdd, 0xd9, 0x67, 0xdf, 0x79, 0xd6, 0x16, + 0x90, 0xf6, 0xd7, 0x5c, 0xd3, 0x07, 0x19, 0x20, + 0x01, 0x39, 0x76, 0x25, 0x12, 0x32, 0x71, 0xa1, + 0x84, 0x8d, 0x2d, 0xea, 0xc0, 0x2b, 0x00, 0x00, + 0x0b, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0b, + 0x00, 0x02, 0x01, 0x00, 0x14, 0x03, 0x03, 0x00, + 0x01, 0x01, 0x16, 0x03, 0x03, 0x00, 0x28, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x66, 0xfe, 0x07, 0x08, 0x33, 0x4d, 0xc2, 0x83, + 0x8e, 0x05, 0x8b, 0xf8, 0xd1, 0xb1, 0xa7, 0x16, + 0x4b, 0x42, 0x5c, 0x3a, 0xa4, 0x31, 0x0f, 0xba, + 0x84, 0x06, 0xcb, 0x9d, 0xc6, 0xc4, 0x66 + }; + uint32_t server_hello_change_cipher_spec_len = sizeof(server_hello_change_cipher_spec); + + TcpSession ssn; + AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); + + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.proto = IPPROTO_TCP; + + StreamTcpInitConfig(TRUE); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_TLS, + STREAM_TOSERVER, client_hello, + client_hello_len); + FLOWLOCK_UNLOCK(&f); + FAIL_IF(r != 0); + + SSLState *ssl_state = f.alstate; + FAIL_IF_NULL(ssl_state); + + FAIL_IF((ssl_state->flags & SSL_AL_FLAG_STATE_CLIENT_HELLO) == 0); + FAIL_IF((ssl_state->flags & SSL_AL_FLAG_SSL_CLIENT_SESSION_ID) == 0); + + FLOWLOCK_WRLOCK(&f); + r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_TLS, STREAM_TOCLIENT, + server_hello_change_cipher_spec, + server_hello_change_cipher_spec_len); + FLOWLOCK_UNLOCK(&f); + FAIL_IF(r != 0); + + FAIL_IF((ssl_state->flags & SSL_AL_FLAG_SERVER_CHANGE_CIPHER_SPEC) == 0); + FAIL_IF((ssl_state->flags & SSL_AL_FLAG_SESSION_RESUMED) == 0); + + AppLayerParserThreadCtxFree(alp_tctx); + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + + PASS; +} + #endif /* UNITTESTS */ void SSLParserRegisterTests(void) @@ -4134,6 +4282,7 @@ void SSLParserRegisterTests(void) UtRegisterTest("SSLParserTest23", SSLParserTest23); UtRegisterTest("SSLParserTest24", SSLParserTest24); UtRegisterTest("SSLParserTest25", SSLParserTest25); + UtRegisterTest("SSLParserTest26", SSLParserTest26); UtRegisterTest("SSLParserMultimsgTest01", SSLParserMultimsgTest01); UtRegisterTest("SSLParserMultimsgTest02", SSLParserMultimsgTest02); diff --git a/src/app-layer-ssl.h b/src/app-layer-ssl.h index f237578366..1748803afb 100644 --- a/src/app-layer-ssl.h +++ b/src/app-layer-ssl.h @@ -96,6 +96,12 @@ enum { /* flag to indicate that handshake is done */ #define SSL_AL_FLAG_HANDSHAKE_DONE 0x80000 +/* A session ID in the Client Hello message, indicating the client + wants to resume a session */ +#define SSL_AL_FLAG_SSL_CLIENT_SESSION_ID 0x100000 +/* Session resumed without a full handshake */ +#define SSL_AL_FLAG_SESSION_RESUMED 0x200000 + /* config flags */ #define SSL_TLS_LOG_PEM (1 << 0) diff --git a/src/log-tlslog.c b/src/log-tlslog.c index 97158b9daf..fb76d705cf 100644 --- a/src/log-tlslog.c +++ b/src/log-tlslog.c @@ -63,9 +63,10 @@ #define OUTPUT_BUFFER_SIZE 65535 #define CERT_ENC_BUFFER_SIZE 2048 -#define LOG_TLS_DEFAULT 0 -#define LOG_TLS_EXTENDED 1 -#define LOG_TLS_CUSTOM 2 +#define LOG_TLS_DEFAULT 0 +#define LOG_TLS_EXTENDED 1 +#define LOG_TLS_CUSTOM 2 +#define LOG_TLS_SESSION_RESUMPTION 4 #define LOG_TLS_CF_VERSION 'v' #define LOG_TLS_CF_DATE_NOT_BEFORE 'd' @@ -308,6 +309,11 @@ static OutputCtx *LogTlsLogInitCtx(ConfNode *conf) } } + const char *session_resumption = ConfNodeLookupChildValue(conf, "session-resumption"); + if (session_resumption == NULL || ConfValIsTrue(session_resumption)) { + tlslog_ctx->flags |= LOG_TLS_SESSION_RESUMPTION; + } + OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) goto tlslog_error; @@ -446,8 +452,10 @@ static int LogTlsLogger(ThreadVars *tv, void *thread_data, const Packet *p, return 0; } - if (ssl_state->server_connp.cert0_issuerdn == NULL || - ssl_state->server_connp.cert0_subject == NULL) { + if (((hlog->flags & LOG_TLS_SESSION_RESUMPTION) == 0 || + (ssl_state->flags & SSL_AL_FLAG_SESSION_RESUMED) == 0) && + (ssl_state->server_connp.cert0_issuerdn == NULL || + ssl_state->server_connp.cert0_subject == NULL)) { return 0; } @@ -467,10 +475,20 @@ static int LogTlsLogger(ThreadVars *tv, void *thread_data, const Packet *p, MemBufferReset(aft->buffer); CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); MemBufferWriteString(aft->buffer, - "%s %s:%d -> %s:%d TLS: Subject='%s' Issuerdn='%s'", - timebuf, srcip, sp, dstip, dp, - ssl_state->server_connp.cert0_subject, - ssl_state->server_connp.cert0_issuerdn); + "%s %s:%d -> %s:%d TLS:", + timebuf, srcip, sp, dstip, dp); + + if (ssl_state->server_connp.cert0_subject != NULL) { + MemBufferWriteString(aft->buffer, " Subject='%s'", + ssl_state->server_connp.cert0_subject); + } + if (ssl_state->server_connp.cert0_issuerdn != NULL) { + MemBufferWriteString(aft->buffer, " Issuerdn='%s'", + ssl_state->server_connp.cert0_issuerdn); + } + if (ssl_state->flags & SSL_AL_FLAG_SESSION_RESUMED) { + MemBufferWriteString(aft->buffer, " Session='resumed'"); + } if (hlog->flags & LOG_TLS_EXTENDED) { LogTlsLogExtended(aft, ssl_state); diff --git a/src/output-json-tls.c b/src/output-json-tls.c index 555c666cc4..fe7ee36843 100644 --- a/src/output-json-tls.c +++ b/src/output-json-tls.c @@ -60,20 +60,22 @@ SC_ATOMIC_DECLARE(unsigned int, cert_id); #define SSL_VERSION_LENGTH 13 -#define LOG_TLS_DEFAULT 0 -#define LOG_TLS_EXTENDED (1 << 0) -#define LOG_TLS_CUSTOM (1 << 1) - -#define LOG_TLS_FIELD_VERSION (1 << 0) -#define LOG_TLS_FIELD_SUBJECT (1 << 1) -#define LOG_TLS_FIELD_ISSUER (1 << 2) -#define LOG_TLS_FIELD_SERIAL (1 << 3) -#define LOG_TLS_FIELD_FINGERPRINT (1 << 4) -#define LOG_TLS_FIELD_NOTBEFORE (1 << 5) -#define LOG_TLS_FIELD_NOTAFTER (1 << 6) -#define LOG_TLS_FIELD_SNI (1 << 7) -#define LOG_TLS_FIELD_CERTIFICATE (1 << 8) -#define LOG_TLS_FIELD_CHAIN (1 << 9) +#define LOG_TLS_DEFAULT 0 +#define LOG_TLS_EXTENDED (1 << 0) +#define LOG_TLS_CUSTOM (1 << 1) +#define LOG_TLS_SESSION_RESUMPTION (1 << 2) + +#define LOG_TLS_FIELD_VERSION (1 << 0) +#define LOG_TLS_FIELD_SUBJECT (1 << 1) +#define LOG_TLS_FIELD_ISSUER (1 << 2) +#define LOG_TLS_FIELD_SERIAL (1 << 3) +#define LOG_TLS_FIELD_FINGERPRINT (1 << 4) +#define LOG_TLS_FIELD_NOTBEFORE (1 << 5) +#define LOG_TLS_FIELD_NOTAFTER (1 << 6) +#define LOG_TLS_FIELD_SNI (1 << 7) +#define LOG_TLS_FIELD_CERTIFICATE (1 << 8) +#define LOG_TLS_FIELD_CHAIN (1 << 9) +#define LOG_TLS_FIELD_SESSION_RESUMED (1 << 10) typedef struct { char *name; @@ -81,17 +83,18 @@ typedef struct { } 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 }, - { NULL, -1 } + { "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 }, + { NULL, -1 } }; typedef struct OutputTlsCtx_ { @@ -108,14 +111,25 @@ typedef struct JsonTlsLogThread_ { static void JsonTlsLogSubject(json_t *js, SSLState *ssl_state) { - json_object_set_new(js, "subject", - json_string(ssl_state->server_connp.cert0_subject)); + if (ssl_state->server_connp.cert0_subject) { + json_object_set_new(js, "subject", + json_string(ssl_state->server_connp.cert0_subject)); + } } static void JsonTlsLogIssuer(json_t *js, SSLState *ssl_state) { - json_object_set_new(js, "issuerdn", - json_string(ssl_state->server_connp.cert0_issuerdn)); + if (ssl_state->server_connp.cert0_issuerdn) { + json_object_set_new(js, "issuerdn", + json_string(ssl_state->server_connp.cert0_issuerdn)); + } +} + +static void JsonTlsLogSessionResumed(json_t *js, SSLState *ssl_state) +{ + if (ssl_state->flags & SSL_AL_FLAG_SESSION_RESUMED) { + json_object_set_new(js, "session_resumed", json_boolean(true)); + } } static void JsonTlsLogFingerprint(json_t *js, SSLState *ssl_state) @@ -247,6 +261,9 @@ void JsonTlsLogJSONBasic(json_t *js, SSLState *ssl_state) /* tls issuerdn */ JsonTlsLogIssuer(js, ssl_state); + + /* tls session resumption */ + JsonTlsLogSessionResumed(js, ssl_state); } static void JsonTlsLogJSONCustom(OutputTlsCtx *tls_ctx, json_t *js, @@ -260,6 +277,10 @@ static void JsonTlsLogJSONCustom(OutputTlsCtx *tls_ctx, json_t *js, if (tls_ctx->fields & LOG_TLS_FIELD_ISSUER) JsonTlsLogIssuer(js, ssl_state); + /* tls session resumption */ + if (tls_ctx->fields & LOG_TLS_FIELD_SESSION_RESUMED) + JsonTlsLogSessionResumed(js, ssl_state); + /* tls serial */ if (tls_ctx->fields & LOG_TLS_FIELD_SERIAL) JsonTlsLogSerial(js, ssl_state); @@ -327,8 +348,10 @@ static int JsonTlsLogger(ThreadVars *tv, void *thread_data, const Packet *p, return 0; } - if (ssl_state->server_connp.cert0_issuerdn == NULL || - ssl_state->server_connp.cert0_subject == NULL) { + if ((ssl_state->server_connp.cert0_issuerdn == NULL || + ssl_state->server_connp.cert0_subject == NULL) && + ((ssl_state->flags & SSL_AL_FLAG_SESSION_RESUMED) == 0 || + (tls_ctx->flags & LOG_TLS_SESSION_RESUMPTION) == 0)) { return 0; } @@ -456,6 +479,11 @@ static OutputTlsCtx *OutputTlsInitCtx(ConfNode *conf) } } + const char *session_resumption = ConfNodeLookupChildValue(conf, "session-resumption"); + if (session_resumption == NULL || ConfValIsTrue(session_resumption)) { + tls_ctx->flags |= LOG_TLS_SESSION_RESUMPTION; + } + if ((tls_ctx->fields & LOG_TLS_FIELD_CERTIFICATE) && (tls_ctx->fields & LOG_TLS_FIELD_CHAIN)) { SCLogWarning(SC_WARN_DUPLICATE_OUTPUT, diff --git a/suricata.yaml.in b/suricata.yaml.in index 8e5ae74136..7e94640e02 100644 --- a/suricata.yaml.in +++ b/suricata.yaml.in @@ -207,9 +207,12 @@ outputs: #custom: [a, aaaa, cname, mx, ns, ptr, txt] - tls: extended: yes # enable this for extended logging information + # output TLS transaction where the session is resumed using a + # session id + #session-resumption: no # custom allows to control which tls fields that are included # in eve-log - #custom: [subject, issuer, serial, fingerprint, sni, version, not_before, not_after, certificate, chain] + #custom: [subject, issuer, session_resumed, serial, 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, @@ -306,6 +309,9 @@ outputs: #custom: yes # enabled the custom logging format (defined by customformat) #customformat: "%{%D-%H:%M:%S}t.%z %a:%p -> %A:%P %v %n %d %D" #filetype: regular # 'regular', 'unix_stream' or 'unix_dgram' + # output TLS transaction where the session is resumed using a + # session id + #session-resumption: no # output module to store certificates chain to disk - tls-store: