]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
tls: make TX aware
authorMats Klepsland <mats.klepsland@gmail.com>
Wed, 13 Apr 2016 06:28:16 +0000 (08:28 +0200)
committerVictor Julien <victor@inliniac.net>
Tue, 17 May 2016 10:25:25 +0000 (12:25 +0200)
src/app-layer-ssl.c
src/app-layer-ssl.h
src/app-layer-tls-handshake.c
src/detect.c

index 952663f9b0456a2a2b211b67a752bb853ebc2b5a..6869614d41becc72a999aeb492861cb29e25bcf9 100644 (file)
@@ -133,6 +133,87 @@ static void SSLParserReset(SSLState *ssl_state)
     ssl_state->curr_connp->bytes_processed = 0;
 }
 
+void SSLSetEvent(SSLState *ssl_state, uint8_t event)
+{
+    if (ssl_state == NULL) {
+        SCLogDebug("Could not set decoder event: %u", event);
+        return;
+    }
+
+    AppLayerDecoderEventsSetEventRaw(&ssl_state->decoder_events, event);
+    ssl_state->events++;
+}
+
+AppLayerDecoderEvents *SSLGetEvents(void *state, uint64_t id)
+{
+    SSLState *ssl_state = (SSLState *)state;
+    return ssl_state->decoder_events;
+}
+
+int SSLHasEvents(void *state)
+{
+    SSLState *ssl_state = (SSLState *)state;
+    return (ssl_state->events > 0);
+}
+
+int SSLStateHasTxDetectState(void *state)
+{
+    SSLState *ssl_state = (SSLState *)state;
+    if (ssl_state->de_state)
+        return 1;
+
+    return 0;
+}
+
+int SSLSetTxDetectState(void *state, void *vtx, DetectEngineState *de_state)
+{
+    SSLState *ssl_state = (SSLState *)state;
+    ssl_state->de_state = de_state;
+    return 0;
+}
+
+DetectEngineState *SSLGetTxDetectState(void *vtx)
+{
+    SSLState *ssl_state = (SSLState *)vtx;
+    return ssl_state->de_state;
+}
+
+void *SSLGetTx(void *state, uint64_t tx_id)
+{
+    SSLState *ssl_state = (SSLState *)state;
+    return ssl_state;
+}
+
+uint64_t SSLGetTxCnt(void *state)
+{
+    /* single tx */
+    return 1;
+}
+
+int SSLGetAlstateProgressCompletionStatus(uint8_t direction)
+{
+    return TLS_STATE_FINISHED;
+}
+
+int SSLGetAlstateProgress(void *tx, uint8_t direction)
+{
+    SSLState *ssl_state = (SSLState *)tx;
+
+    /* we don't care about direction, only that app-layer parser is done
+       and have sent an EOF */
+    if (ssl_state->flags & SSL_AL_FLAG_STATE_FINISHED) {
+        return TLS_STATE_FINISHED;
+    }
+
+    /* we want the logger to log when the handshake is done, even if the
+       state is not finished */
+    if (ssl_state->flags & SSL_AL_FLAG_HANDSHAKE_DONE) {
+        return TLS_HANDSHAKE_DONE;
+    }
+
+    return TLS_STATE_IN_PROGRESS;
+}
+
 static int SSLv3ParseHandshakeType(SSLState *ssl_state, uint8_t *input,
                                    uint32_t input_len)
 {
@@ -208,7 +289,7 @@ static int SSLv3ParseHandshakeType(SSLState *ssl_state, uint8_t *input,
                            type (RFC5246 section 7.4.1.4) */
                         if (ssl_state->curr_connp->sni) {
                             SCLogDebug("Multiple SNI extensions");
-                            AppLayerDecoderEventsSetEvent(ssl_state->f,
+                            SSLSetEvent(ssl_state,
                                     TLS_DECODER_EVENT_MULTIPLE_SNI_EXTENSIONS);
                             return -1;
                         }
@@ -225,7 +306,7 @@ static int SSLv3ParseHandshakeType(SSLState *ssl_state, uint8_t *input,
                            (RFC6066 section 3) */
                         if (sni_type != SSL_SNI_TYPE_HOST_NAME) {
                             SCLogDebug("Unknown SNI type");
-                            AppLayerDecoderEventsSetEvent(ssl_state->f,
+                            SSLSetEvent(ssl_state,
                                     TLS_DECODER_EVENT_INVALID_SNI_TYPE);
                             return -1;
                         }
@@ -244,7 +325,7 @@ static int SSLv3ParseHandshakeType(SSLState *ssl_state, uint8_t *input,
                            name length */
                         if (sni_len > 255) {
                             SCLogDebug("SNI length >255");
-                            AppLayerDecoderEventsSetEvent(ssl_state->f,
+                            SSLSetEvent(ssl_state,
                                     TLS_DECODER_EVENT_INVALID_SNI_LENGTH);
                             return -1;
                         }
@@ -321,7 +402,7 @@ end:
                 if ((ssl_state->curr_connp->record_length +
                         SSLV3_RECORD_HDR_LEN) <
                         ssl_state->curr_connp->bytes_processed) {
-                    AppLayerDecoderEventsSetEvent(ssl_state->f,
+                    SSLSetEvent(ssl_state,
                             TLS_DECODER_EVENT_INVALID_SSL_RECORD);
                     return -1;
                 }
@@ -346,7 +427,7 @@ end:
                    while we expect only the number of bytes parsed bytes
                    from the _current_ fragment */
                 if (write_len < (ssl_state->curr_connp->trec_pos - rc)) {
-                    AppLayerDecoderEventsSetEvent(ssl_state->f,
+                    SSLSetEvent(ssl_state,
                             TLS_DECODER_EVENT_INVALID_SSL_RECORD);
                     return -1;
                 }
@@ -379,8 +460,7 @@ end:
             SCLogDebug("new session ticket");
             break;
         default:
-            AppLayerDecoderEventsSetEvent(ssl_state->f,
-                    TLS_DECODER_EVENT_INVALID_SSL_RECORD);
+            SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_SSL_RECORD);
             return -1;
     }
 
@@ -389,8 +469,7 @@ end:
             ssl_state->curr_connp->record_length + (SSLV3_RECORD_HDR_LEN)) {
         if ((ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN) <
                 ssl_state->curr_connp->bytes_processed) {
-            AppLayerDecoderEventsSetEvent(ssl_state->f,
-                    TLS_DECODER_EVENT_INVALID_SSL_RECORD);
+            SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_SSL_RECORD);
             return -1;
         }
         write_len = (ssl_state->curr_connp->record_length +
@@ -403,8 +482,7 @@ end:
             ssl_state->curr_connp->message_length) {
         if (ssl_state->curr_connp->message_length <
                 ssl_state->curr_connp->trec_pos) {
-            AppLayerDecoderEventsSetEvent(ssl_state->f,
-                    TLS_DECODER_EVENT_INVALID_SSL_RECORD);
+            SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_SSL_RECORD);
             return -1;
         }
         parsed += ssl_state->curr_connp->message_length -
@@ -519,8 +597,7 @@ static int SSLv3ParseHeartbeatProtocol(SSLState *ssl_state, uint8_t *input,
 
     if (!(ssl_state->flags & SSL_AL_FLAG_CHANGE_CIPHER_SPEC)) {
         if (!(hb_type == TLS_HB_REQUEST || hb_type == TLS_HB_RESPONSE)) {
-            AppLayerDecoderEventsSetEvent(ssl_state->f,
-                    TLS_DECODER_EVENT_INVALID_HEARTBEAT);
+            SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_HEARTBEAT);
             return -1;
         }
     }
@@ -552,8 +629,7 @@ static int SSLv3ParseHeartbeatProtocol(SSLState *ssl_state, uint8_t *input,
            the record (CVE-2014-0160) */
         if ((uint32_t)(payload_len+3) > ssl_state->curr_connp->record_length) {
             SCLogDebug("We have a short record in HeartBeat Request");
-            AppLayerDecoderEventsSetEvent(ssl_state->f,
-                    TLS_DECODER_EVENT_OVERFLOW_HEARTBEAT);
+            SSLSetEvent(ssl_state, TLS_DECODER_EVENT_OVERFLOW_HEARTBEAT);
             return -1;
         }
 
@@ -562,8 +638,7 @@ static int SSLv3ParseHeartbeatProtocol(SSLState *ssl_state, uint8_t *input,
         padding_len = ssl_state->curr_connp->record_length - payload_len - 3;
         if (padding_len < 16) {
             SCLogDebug("We have a short record in HeartBeat Request");
-            AppLayerDecoderEventsSetEvent(ssl_state->f,
-                    TLS_DECODER_EVENT_INVALID_HEARTBEAT);
+            SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_HEARTBEAT);
             return -1;
         }
 
@@ -577,15 +652,13 @@ static int SSLv3ParseHeartbeatProtocol(SSLState *ssl_state, uint8_t *input,
     } else if (direction == 1 && (ssl_state->flags & SSL_AL_FLAG_HB_INFLIGHT) &&
             (ssl_state->flags & SSL_AL_FLAG_HB_SERVER_INIT)) {
         SCLogDebug("Multiple in-flight server initiated HeartBeats");
-        AppLayerDecoderEventsSetEvent(ssl_state->f,
-                TLS_DECODER_EVENT_INVALID_HEARTBEAT);
+        SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_HEARTBEAT);
         return -1;
 
     } else if (direction == 0 && (ssl_state->flags & SSL_AL_FLAG_HB_INFLIGHT) &&
             (ssl_state->flags & SSL_AL_FLAG_HB_CLIENT_INIT)) {
         SCLogDebug("Multiple in-flight client initiated HeartBeats");
-        AppLayerDecoderEventsSetEvent(ssl_state->f,
-                TLS_DECODER_EVENT_INVALID_HEARTBEAT);
+        SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_HEARTBEAT);
         return -1;
 
     } else {
@@ -604,7 +677,7 @@ static int SSLv3ParseHeartbeatProtocol(SSLState *ssl_state, uint8_t *input,
                     ssl_state->curr_connp->record_length) {
                 SCLogDebug("My heart is bleeding.. OpenSSL HeartBleed response (%u)",
                         ssl_state->hb_record_len);
-                AppLayerDecoderEventsSetEvent(ssl_state->f,
+                SSLSetEvent(ssl_state,
                         TLS_DECODER_EVENT_DATALEAK_HEARTBEAT_MISMATCH);
                 ssl_state->hb_record_len = 0;
                 return -1;
@@ -783,8 +856,7 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state,
             (ssl_state->curr_connp->record_lengths_length + 1)) {
         retval = SSLv2ParseRecord(direction, ssl_state, input, input_len);
         if (retval == -1) {
-            AppLayerDecoderEventsSetEvent(ssl_state->f,
-                    TLS_DECODER_EVENT_INVALID_SSLV2_HEADER);
+            SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_SSLV2_HEADER);
             return -1;
         } else {
             input += retval;
@@ -799,16 +871,14 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state,
     /* record_length should never be zero */
     if (ssl_state->curr_connp->record_length == 0) {
         SCLogDebug("SSLv2 record length is zero");
-        AppLayerDecoderEventsSetEvent(ssl_state->f,
-                TLS_DECODER_EVENT_INVALID_SSLV2_HEADER);
+        SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_SSLV2_HEADER);
         return -1;
     }
 
     /* record_lenghts_length should never be zero */
     if (ssl_state->curr_connp->record_lengths_length == 0) {
         SCLogDebug("SSLv2 record lengths length is zero");
-        AppLayerDecoderEventsSetEvent(ssl_state->f,
-                TLS_DECODER_EVENT_INVALID_SSLV2_HEADER);
+        SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_SSLV2_HEADER);
         return -1;
     }
 
@@ -816,8 +886,7 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state,
         case SSLV2_MT_ERROR:
             SCLogDebug("SSLV2_MT_ERROR msg_type received. Error encountered "
                        "in establishing the sslv2 session, may be version");
-            AppLayerDecoderEventsSetEvent(ssl_state->f,
-                    TLS_DECODER_EVENT_ERROR_MSG_ENCOUNTERED);
+            SSLSetEvent(ssl_state, TLS_DECODER_EVENT_ERROR_MSG_ENCOUNTERED);
 
             break;
 
@@ -1038,8 +1107,7 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state,
     if (ssl_state->curr_connp->bytes_processed < SSLV3_RECORD_HDR_LEN) {
         retval = SSLv3ParseRecord(direction, ssl_state, input, input_len);
         if (retval < 0) {
-            AppLayerDecoderEventsSetEvent(ssl_state->f,
-                    TLS_DECODER_EVENT_INVALID_TLS_HEADER);
+            SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_TLS_HEADER);
             return -1;
         } else {
             parsed += retval;
@@ -1055,16 +1123,14 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state,
     if (ssl_state->curr_connp->version < SSL_VERSION_3 ||
             ssl_state->curr_connp->version > TLS_VERSION_12) {
 
-        AppLayerDecoderEventsSetEvent(ssl_state->f,
-                TLS_DECODER_EVENT_INVALID_RECORD_VERSION);
+        SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_RECORD_VERSION);
         return -1;
     }
 
     /* record_length should never be zero */
     if (ssl_state->curr_connp->record_length == 0) {
         SCLogDebug("SSLv3 Record length is 0");
-        AppLayerDecoderEventsSetEvent(ssl_state->f,
-                TLS_DECODER_EVENT_INVALID_TLS_HEADER);
+        SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_TLS_HEADER);
         return -1;
     }
 
@@ -1096,6 +1162,10 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state,
                         APP_LAYER_PARSER_NO_INSPECTION_PAYLOAD);
             }
 
+            /* if we see (encrypted) aplication data, then this means the
+               handshake must be done */
+            ssl_state->flags |= SSL_AL_FLAG_HANDSHAKE_DONE;
+
             break;
 
         case SSLV3_HANDSHAKE_PROTOCOL:
@@ -1104,16 +1174,15 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state,
 
             if (ssl_state->curr_connp->record_length < 4) {
                 SSLParserReset(ssl_state);
-                AppLayerDecoderEventsSetEvent(ssl_state->f,
-                        TLS_DECODER_EVENT_INVALID_SSL_RECORD);
+                SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_SSL_RECORD);
                 return -1;
             }
 
             retval = SSLv3ParseHandshakeProtocol(ssl_state, input + parsed, input_len);
             if (retval < 0) {
-                AppLayerDecoderEventsSetEvent(ssl_state->f,
+                SSLSetEvent(ssl_state,
                         TLS_DECODER_EVENT_INVALID_HANDSHAKE_MESSAGE);
-                AppLayerDecoderEventsSetEvent(ssl_state->f,
+                SSLSetEvent(ssl_state,
                         TLS_DECODER_EVENT_INVALID_SSL_RECORD);
                 return -1;
             } else {
@@ -1121,7 +1190,7 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state,
                     SCLogDebug("Error parsing SSLv3.x. Reseting parser "
                                "state. Let's get outta here");
                     SSLParserReset(ssl_state);
-                    AppLayerDecoderEventsSetEvent(ssl_state->f,
+                    SSLSetEvent(ssl_state,
                             TLS_DECODER_EVENT_INVALID_SSL_RECORD);
                     return -1;
                 }
@@ -1152,10 +1221,8 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state,
 
         default:
             /* \todo fix the event from invalid rule to unknown rule */
-            AppLayerDecoderEventsSetEvent(ssl_state->f,
-                    TLS_DECODER_EVENT_INVALID_RECORD_TYPE);
-            AppLayerDecoderEventsSetEvent(ssl_state->f,
-                    TLS_DECODER_EVENT_INVALID_SSL_RECORD);
+            SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_RECORD_TYPE);
+            SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_SSL_RECORD);
             return -1;
     }
 
@@ -1164,8 +1231,7 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state,
         if ((ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN) <
                 ssl_state->curr_connp->bytes_processed) {
             /* defensive checks. Something is wrong. */
-            AppLayerDecoderEventsSetEvent(ssl_state->f,
-                    TLS_DECODER_EVENT_INVALID_SSL_RECORD);
+            SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_SSL_RECORD);
             return -1;
         }
 
@@ -1222,6 +1288,8 @@ static int SSLDecode(Flow *f, uint8_t direction, void *alstate, AppLayerParserSt
 
     if (input == NULL &&
             AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
+        /* flag session as finished if APP_LAYER_PARSER_EOF is set */
+        ssl_state->flags |= SSL_AL_FLAG_STATE_FINISHED;
         SCReturnInt(1);
     } else if (input == NULL || input_len == 0) {
         SCReturnInt(-1);
@@ -1238,8 +1306,7 @@ static int SSLDecode(Flow *f, uint8_t direction, void *alstate, AppLayerParserSt
             SCLogDebug("Looks like we have looped quite a bit. Reset state "
                        "and get out of here");
             SSLParserReset(ssl_state);
-            AppLayerDecoderEventsSetEvent(ssl_state->f,
-                    TLS_DECODER_EVENT_INVALID_SSL_RECORD);
+            SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_SSL_RECORD);
             return -1;
         }
 
@@ -1258,7 +1325,7 @@ static int SSLDecode(Flow *f, uint8_t direction, void *alstate, AppLayerParserSt
                         SCLogDebug("Error parsing SSLv2.x. Reseting parser "
                                    "state. Let's get outta here");
                         SSLParserReset(ssl_state);
-                        AppLayerDecoderEventsSetEvent(ssl_state->f,
+                        SSLSetEvent(ssl_state,
                                 TLS_DECODER_EVENT_INVALID_SSL_RECORD);
                         return -1;
                     } else {
@@ -1276,7 +1343,7 @@ static int SSLDecode(Flow *f, uint8_t direction, void *alstate, AppLayerParserSt
                         SCLogDebug("Error parsing SSLv3.x. Reseting parser "
                                    "state. Let's get outta here");
                         SSLParserReset(ssl_state);
-                        AppLayerDecoderEventsSetEvent(ssl_state->f,
+                        SSLSetEvent(ssl_state,
                                 TLS_DECODER_EVENT_INVALID_SSL_RECORD);
                         return -1;
                     } else {
@@ -1339,6 +1406,15 @@ static int SSLDecode(Flow *f, uint8_t direction, void *alstate, AppLayerParserSt
         } /* switch (ssl_state->curr_connp->bytes_processed) */
     } /* while (input_len) */
 
+    /* mark handshake as done if we have subject and issuer */
+    if (ssl_state->server_connp.cert0_subject &&
+            ssl_state->server_connp.cert0_issuerdn)
+        ssl_state->flags |= SSL_AL_FLAG_HANDSHAKE_DONE;
+
+    /* flag session as finished if APP_LAYER_PARSER_EOF is set */
+    if (AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF))
+        ssl_state->flags |= SSL_AL_FLAG_STATE_FINISHED;
+
     return 1;
 }
 
@@ -1404,6 +1480,12 @@ void SSLStateFree(void *p)
     if (ssl_state->server_connp.sni)
         SCFree(ssl_state->server_connp.sni);
 
+    AppLayerDecoderEventsFreeEvents(&ssl_state->decoder_events);
+
+    if (ssl_state->de_state != NULL) {
+        DetectEngineStateFree(ssl_state->de_state);
+    }
+
     /* Free certificate chain */
     while ((item = TAILQ_FIRST(&ssl_state->server_connp.certs))) {
         TAILQ_REMOVE(&ssl_state->server_connp.certs, item, next);
@@ -1416,6 +1498,11 @@ void SSLStateFree(void *p)
     return;
 }
 
+void SSLStateTransactionFree(void *state, uint64_t tx_id)
+{
+    /* do nothing */
+}
+
 static uint16_t SSLProbingParser(uint8_t *input, uint32_t ilen, uint32_t *offset)
 {
     /* probably a rst/fin sending an eof */
@@ -1442,7 +1529,7 @@ int SSLStateGetEventInfo(const char *event_name,
         return -1;
     }
 
-    *event_type = APP_LAYER_EVENT_TYPE_GENERAL;
+    *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
 
     return 0;
 }
@@ -1631,11 +1718,31 @@ void RegisterSSLParsers(void)
 
         AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_TLS, STREAM_TOCLIENT,
                                      SSLParseServerRecord);
+
         AppLayerParserRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_TLS, SSLStateGetEventInfo);
 
         AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_TLS, SSLStateAlloc, SSLStateFree);
+
         AppLayerParserRegisterParserAcceptableDataDirection(IPPROTO_TCP, ALPROTO_TLS, STREAM_TOSERVER);
 
+        AppLayerParserRegisterTxFreeFunc(IPPROTO_TCP, ALPROTO_TLS, SSLStateTransactionFree);
+
+        AppLayerParserRegisterGetEventsFunc(IPPROTO_TCP, ALPROTO_TLS, SSLGetEvents);
+
+        AppLayerParserRegisterHasEventsFunc(IPPROTO_TCP, ALPROTO_TLS, SSLHasEvents);
+
+        AppLayerParserRegisterDetectStateFuncs(IPPROTO_TCP, ALPROTO_TLS, SSLStateHasTxDetectState,
+                                               SSLGetTxDetectState, SSLSetTxDetectState);
+
+        AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_TLS, SSLGetTx);
+
+        AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_TLS, SSLGetTxCnt);
+
+        AppLayerParserRegisterGetStateProgressFunc(IPPROTO_TCP, ALPROTO_TLS, SSLGetAlstateProgress);
+
+        AppLayerParserRegisterGetStateProgressCompletionStatus(IPPROTO_TCP, ALPROTO_TLS,
+                                                               SSLGetAlstateProgressCompletionStatus);
+
         /* Get the value of no reassembly option from the config file */
         if (ConfGetNode("app-layer.protocols.tls.no-reassemble") == NULL) {
             if (ConfGetBool("tls.no-reassemble", &ssl_config.no_reassemble) != 1)
index b38035254ee962faff102d9a4d9c04536300015c..12f76219a8edbf65ca135ff175440b93d817eb2d 100644 (file)
@@ -26,6 +26,8 @@
 #ifndef __APP_LAYER_SSL_H__
 #define __APP_LAYER_SSL_H__
 
+#include "app-layer-protos.h"
+#include "app-layer-parser.h"
 #include "decode-events.h"
 #include "queue.h"
 
@@ -53,6 +55,12 @@ enum {
     TLS_DECODER_EVENT_INVALID_SSL_RECORD,
 };
 
+enum {
+    TLS_STATE_IN_PROGRESS = 0,
+    TLS_HANDSHAKE_DONE = 1,
+    TLS_STATE_FINISHED = 2
+};
+
 /* Flag to indicate that server will now on send encrypted msgs */
 #define SSL_AL_FLAG_SERVER_CHANGE_CIPHER_SPEC   0x0001
 /* Flag to indicate that client will now on send encrypted msgs */
@@ -76,11 +84,17 @@ enum {
 
 #define SSL_AL_FLAG_STATE_LOGGED                0x4000
 
+/* flag to indicate that session is finished */
+#define SSL_AL_FLAG_STATE_FINISHED              0x4000
+
 /* flags specific to HeartBeat state */
 #define SSL_AL_FLAG_HB_INFLIGHT                 0x8000
 #define SSL_AL_FLAG_HB_CLIENT_INIT              0x10000
 #define SSL_AL_FLAG_HB_SERVER_INIT              0x20000
 
+/* flag to indicate that handshake is done */
+#define SSL_AL_FLAG_HANDSHAKE_DONE              0x80000
+
 /* flags for file storage */
 #define SSL_AL_FLAG_STATE_STORED                0x40000
 
@@ -169,16 +183,22 @@ typedef struct SSLState_ {
     /* holds some state flags we need */
     uint32_t flags;
 
+    /* there might be a better place to store this*/
+    uint16_t hb_record_len;
+
+    uint16_t events;
+
     SSLStateConnp *curr_connp;
 
     SSLStateConnp client_connp;
     SSLStateConnp server_connp;
 
-    /* there might be a better place to store this*/
-    uint16_t hb_record_len;
+    DetectEngineState *de_state;
+    AppLayerDecoderEvents *decoder_events;
 } SSLState;
 
 void RegisterSSLParsers(void);
 void SSLParserRegisterTests(void);
+void SSLSetEvent(SSLState *ssl_state, uint8_t event);
 
 #endif /* __APP_LAYER_SSL_H__ */
index 9f034016cb46424602d251b7c003eb4ba229b60a..c95fd4373a05d27f939913439caf059d44814bff 100644 (file)
@@ -58,25 +58,24 @@ static void TLSCertificateErrCodeToWarning(SSLState *ssl_state,
     switch (errcode) {
         case ERR_DER_ELEMENT_SIZE_TOO_BIG:
         case ERR_DER_INVALID_SIZE:
-            AppLayerDecoderEventsSetEvent(ssl_state->f,
+            SSLSetEvent(ssl_state,
                     TLS_DECODER_EVENT_CERTIFICATE_INVALID_LENGTH);
             break;
         case ERR_DER_UNSUPPORTED_STRING:
-            AppLayerDecoderEventsSetEvent(ssl_state->f,
+            SSLSetEvent(ssl_state,
                     TLS_DECODER_EVENT_CERTIFICATE_INVALID_STRING);
             break;
         case ERR_DER_UNKNOWN_ELEMENT:
-            AppLayerDecoderEventsSetEvent(ssl_state->f,
+            SSLSetEvent(ssl_state,
                     TLS_DECODER_EVENT_CERTIFICATE_UNKNOWN_ELEMENT);
             break;
         case ERR_DER_MISSING_ELEMENT:
-            AppLayerDecoderEventsSetEvent(ssl_state->f,
+            SSLSetEvent(ssl_state,
                     TLS_DECODER_EVENT_CERTIFICATE_MISSING_ELEMENT);
             break;
         case ERR_DER_GENERIC:
         default:
-            AppLayerDecoderEventsSetEvent(ssl_state->f,
-                    TLS_DECODER_EVENT_INVALID_CERTIFICATE);
+            SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_CERTIFICATE);
             break;
     };
 }
@@ -108,8 +107,7 @@ int DecodeTLSHandshakeServerCertificate(SSLState *ssl_state, uint8_t *input,
     i = 0;
     while (certificates_length > 0) {
         if ((uint32_t)(input + 3 - start_data) > (uint32_t)input_len) {
-            AppLayerDecoderEventsSetEvent(ssl_state->f,
-                    TLS_DECODER_EVENT_INVALID_CERTIFICATE);
+            SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_CERTIFICATE);
             return -1;
         }
 
@@ -119,14 +117,12 @@ int DecodeTLSHandshakeServerCertificate(SSLState *ssl_state, uint8_t *input,
 
         /* current certificate length should be greater than zero */
         if (cur_cert_length == 0) {
-            AppLayerDecoderEventsSetEvent(ssl_state->f,
-                    TLS_DECODER_EVENT_INVALID_CERTIFICATE);
+            SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_CERTIFICATE);
             return -1;
         }
 
         if (input - start_data + cur_cert_length > input_len) {
-            AppLayerDecoderEventsSetEvent(ssl_state->f,
-                    TLS_DECODER_EVENT_INVALID_CERTIFICATE);
+            SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_CERTIFICATE);
             return -1;
         }
 
index 19e7571ee5f3fa3584e445dc262995227b1e27de..60ca9795f578171bb6be4021c32eb187e72d6f56 100644 (file)
@@ -2579,6 +2579,10 @@ static int SignatureCreateMask(Signature *s)
                         s->mask |= SIG_MASK_REQUIRE_DNS_STATE;
                         SCLogDebug("sig %u requires dns app state (dns event)", s->id);
                         break;
+                    case ALPROTO_TLS:
+                        s->mask |= SIG_MASK_REQUIRE_TLS_STATE;
+                        SCLogDebug("sig %u requires tls app state (tls event)", s->id);
+                        break;
                 }
                 break;
             }