diff --git a/src/app-layer-ssl.c b/src/app-layer-ssl.c index 6934586e17..44b4f57929 100644 --- a/src/app-layer-ssl.c +++ b/src/app-layer-ssl.c @@ -28,9 +28,6 @@ #include "decode.h" #include "threads.h" -#include "util-print.h" -#include "util-pool.h" - #include "stream-tcp-private.h" #include "stream-tcp-reassemble.h" #include "stream-tcp.h" @@ -40,7 +37,6 @@ #include "app-layer-protos.h" #include "app-layer-parser.h" #include "app-layer-ssl.h" - #include "app-layer-tls-handshake.h" #include "decode-events.h" @@ -49,11 +45,12 @@ #include "util-spm.h" #include "util-unittest.h" #include "util-debug.h" +#include "util-print.h" +#include "util-pool.h" +#include "util-byte.h" #include "flow-util.h" #include "flow-private.h" -#include "util-byte.h" - SCEnumCharMap tls_decoder_event_table[ ] = { /* TLS protocol messages */ { "INVALID_SSLV2_HEADER", TLS_DECODER_EVENT_INVALID_SSLV2_HEADER }, @@ -68,7 +65,7 @@ SCEnumCharMap tls_decoder_event_table[ ] = { { "MULTIPLE_SNI_EXTENSIONS", TLS_DECODER_EVENT_MULTIPLE_SNI_EXTENSIONS }, { "INVALID_SNI_TYPE", TLS_DECODER_EVENT_INVALID_SNI_TYPE }, { "INVALID_SNI_LENGTH", TLS_DECODER_EVENT_INVALID_SNI_LENGTH }, - /* Certificates decoding messages */ + /* certificate decoding messages */ { "INVALID_CERTIFICATE", TLS_DECODER_EVENT_INVALID_CERTIFICATE }, { "CERTIFICATE_MISSING_ELEMENT", TLS_DECODER_EVENT_CERTIFICATE_MISSING_ELEMENT }, { "CERTIFICATE_UNKNOWN_ELEMENT", TLS_DECODER_EVENT_CERTIFICATE_UNKNOWN_ELEMENT }, @@ -87,47 +84,47 @@ typedef struct SslConfig_ { SslConfig ssl_config; /* SSLv3 record types */ -#define SSLV3_CHANGE_CIPHER_SPEC 20 -#define SSLV3_ALERT_PROTOCOL 21 -#define SSLV3_HANDSHAKE_PROTOCOL 22 -#define SSLV3_APPLICATION_PROTOCOL 23 -#define SSLV3_HEARTBEAT_PROTOCOL 24 +#define SSLV3_CHANGE_CIPHER_SPEC 20 +#define SSLV3_ALERT_PROTOCOL 21 +#define SSLV3_HANDSHAKE_PROTOCOL 22 +#define SSLV3_APPLICATION_PROTOCOL 23 +#define SSLV3_HEARTBEAT_PROTOCOL 24 /* SSLv3 handshake protocol types */ -#define SSLV3_HS_HELLO_REQUEST 0 -#define SSLV3_HS_CLIENT_HELLO 1 -#define SSLV3_HS_SERVER_HELLO 2 -#define SSLV3_HS_NEW_SESSION_TICKET 4 -#define SSLV3_HS_CERTIFICATE 11 -#define SSLV3_HS_SERVER_KEY_EXCHANGE 12 -#define SSLV3_HS_CERTIFICATE_REQUEST 13 -#define SSLV3_HS_SERVER_HELLO_DONE 14 -#define SSLV3_HS_CERTIFICATE_VERIFY 15 -#define SSLV3_HS_CLIENT_KEY_EXCHANGE 16 -#define SSLV3_HS_FINISHED 20 -#define SSLV3_HS_CERTIFICATE_URL 21 -#define SSLV3_HS_CERTIFICATE_STATUS 22 +#define SSLV3_HS_HELLO_REQUEST 0 +#define SSLV3_HS_CLIENT_HELLO 1 +#define SSLV3_HS_SERVER_HELLO 2 +#define SSLV3_HS_NEW_SESSION_TICKET 4 +#define SSLV3_HS_CERTIFICATE 11 +#define SSLV3_HS_SERVER_KEY_EXCHANGE 12 +#define SSLV3_HS_CERTIFICATE_REQUEST 13 +#define SSLV3_HS_SERVER_HELLO_DONE 14 +#define SSLV3_HS_CERTIFICATE_VERIFY 15 +#define SSLV3_HS_CLIENT_KEY_EXCHANGE 16 +#define SSLV3_HS_FINISHED 20 +#define SSLV3_HS_CERTIFICATE_URL 21 +#define SSLV3_HS_CERTIFICATE_STATUS 22 /* SSLv2 protocol message types */ -#define SSLV2_MT_ERROR 0 -#define SSLV2_MT_CLIENT_HELLO 1 -#define SSLV2_MT_CLIENT_MASTER_KEY 2 -#define SSLV2_MT_CLIENT_FINISHED 3 -#define SSLV2_MT_SERVER_HELLO 4 -#define SSLV2_MT_SERVER_VERIFY 5 -#define SSLV2_MT_SERVER_FINISHED 6 -#define SSLV2_MT_REQUEST_CERTIFICATE 7 -#define SSLV2_MT_CLIENT_CERTIFICATE 8 - -#define SSLV3_RECORD_HDR_LEN 5 -#define SSLV3_MESSAGE_HDR_LEN 4 - -#define SSLV3_CLIENT_HELLO_VERSION_LEN 2 -#define SSLV3_CLIENT_HELLO_RANDOM_LEN 32 +#define SSLV2_MT_ERROR 0 +#define SSLV2_MT_CLIENT_HELLO 1 +#define SSLV2_MT_CLIENT_MASTER_KEY 2 +#define SSLV2_MT_CLIENT_FINISHED 3 +#define SSLV2_MT_SERVER_HELLO 4 +#define SSLV2_MT_SERVER_VERIFY 5 +#define SSLV2_MT_SERVER_FINISHED 6 +#define SSLV2_MT_REQUEST_CERTIFICATE 7 +#define SSLV2_MT_CLIENT_CERTIFICATE 8 + +#define SSLV3_RECORD_HDR_LEN 5 +#define SSLV3_MESSAGE_HDR_LEN 4 + +#define SSLV3_CLIENT_HELLO_VERSION_LEN 2 +#define SSLV3_CLIENT_HELLO_RANDOM_LEN 32 /* TLS heartbeat protocol types */ -#define TLS_HB_REQUEST 1 -#define TLS_HB_RESPONSE 2 +#define TLS_HB_REQUEST 1 +#define TLS_HB_RESPONSE 2 #define HAS_SPACE(n) ((uint32_t)((input) + (n) - (initial_input)) > (uint32_t)(input_len)) ? 0 : 1 @@ -291,16 +288,23 @@ end: case SSLV3_HS_CERTIFICATE: if (ssl_state->curr_connp->trec == NULL) { - ssl_state->curr_connp->trec_len = 2 * ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN + 1; - ssl_state->curr_connp->trec = SCMalloc( ssl_state->curr_connp->trec_len ); + ssl_state->curr_connp->trec_len = + 2 * ssl_state->curr_connp->record_length + + SSLV3_RECORD_HDR_LEN + 1; + ssl_state->curr_connp->trec = + SCMalloc(ssl_state->curr_connp->trec_len); } - if (ssl_state->curr_connp->trec_pos + input_len >= ssl_state->curr_connp->trec_len) { - ssl_state->curr_connp->trec_len = ssl_state->curr_connp->trec_len + 2 * input_len + 1; + if (ssl_state->curr_connp->trec_pos + input_len >= + ssl_state->curr_connp->trec_len) { + ssl_state->curr_connp->trec_len = + ssl_state->curr_connp->trec_len + 2 * input_len + 1; ptmp = SCRealloc(ssl_state->curr_connp->trec, - ssl_state->curr_connp->trec_len); + ssl_state->curr_connp->trec_len); + if (unlikely(ptmp == NULL)) { SCFree(ssl_state->curr_connp->trec); } + ssl_state->curr_connp->trec = ptmp; } if (unlikely(ssl_state->curr_connp->trec == NULL)) { @@ -312,30 +316,44 @@ end: } uint32_t write_len = 0; - if ((ssl_state->curr_connp->bytes_processed + input_len) > 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); + if ((ssl_state->curr_connp->bytes_processed + input_len) > + 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); return -1; } - write_len = (ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN) - ssl_state->curr_connp->bytes_processed; + write_len = (ssl_state->curr_connp->record_length + + SSLV3_RECORD_HDR_LEN) - + ssl_state->curr_connp->bytes_processed; } else { write_len = input_len; } - memcpy(ssl_state->curr_connp->trec + ssl_state->curr_connp->trec_pos, initial_input, write_len); + + memcpy(ssl_state->curr_connp->trec + + ssl_state->curr_connp->trec_pos, initial_input, write_len); ssl_state->curr_connp->trec_pos += write_len; - rc = DecodeTLSHandshakeServerCertificate(ssl_state, ssl_state->curr_connp->trec, ssl_state->curr_connp->trec_pos); + rc = DecodeTLSHandshakeServerCertificate(ssl_state, + ssl_state->curr_connp->trec, + ssl_state->curr_connp->trec_pos); + if (rc > 0) { /* do not return normally if the packet was fragmented: - * we would return the size of the *entire* message, - * while we expect only the number of bytes parsed bytes - * from the *current* fragment - */ + we would return the size of the _entire_ message, + 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, TLS_DECODER_EVENT_INVALID_SSL_RECORD); + AppLayerDecoderEventsSetEvent(ssl_state->f, + TLS_DECODER_EVENT_INVALID_SSL_RECORD); return -1; } - uint32_t diff = write_len - (ssl_state->curr_connp->trec_pos - rc); + + uint32_t diff = write_len - + (ssl_state->curr_connp->trec_pos - rc); ssl_state->curr_connp->bytes_processed += diff; ssl_state->curr_connp->trec_pos = 0; @@ -362,28 +380,40 @@ end: SCLogDebug("new session ticket"); break; default: - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD); + AppLayerDecoderEventsSetEvent(ssl_state->f, + TLS_DECODER_EVENT_INVALID_SSL_RECORD); return -1; } uint32_t write_len = 0; - if ((ssl_state->curr_connp->bytes_processed + input_len) >= 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); + if ((ssl_state->curr_connp->bytes_processed + input_len) >= + 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); return -1; } - write_len = (ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN) - ssl_state->curr_connp->bytes_processed; + write_len = (ssl_state->curr_connp->record_length + + SSLV3_RECORD_HDR_LEN) - ssl_state->curr_connp->bytes_processed; } else { write_len = input_len; } - if ((ssl_state->curr_connp->trec_pos + write_len) >= 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); + + if ((ssl_state->curr_connp->trec_pos + write_len) >= + 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); return -1; } - parsed += ssl_state->curr_connp->message_length - ssl_state->curr_connp->trec_pos; + parsed += ssl_state->curr_connp->message_length - + ssl_state->curr_connp->trec_pos; - ssl_state->curr_connp->bytes_processed += ssl_state->curr_connp->message_length - ssl_state->curr_connp->trec_pos; + ssl_state->curr_connp->bytes_processed += + ssl_state->curr_connp->message_length - + ssl_state->curr_connp->trec_pos; ssl_state->curr_connp->handshake_type = 0; ssl_state->curr_connp->hs_bytes_processed = 0; @@ -405,10 +435,8 @@ static int SSLv3ParseHandshakeProtocol(SSLState *ssl_state, uint8_t *input, uint8_t *initial_input = input; int retval; - if (input_len == 0 || - ssl_state->curr_connp->bytes_processed == - (ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN)) - { + if (input_len == 0 || ssl_state->curr_connp->bytes_processed == + (ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN)) { return 0; } @@ -417,40 +445,41 @@ static int SSLv3ParseHandshakeProtocol(SSLState *ssl_state, uint8_t *input, ssl_state->curr_connp->handshake_type = *(input++); ssl_state->curr_connp->bytes_processed++; ssl_state->curr_connp->hs_bytes_processed++; - if (--input_len == 0 || - ssl_state->curr_connp->bytes_processed == - (ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN)) - { + if (--input_len == 0 || ssl_state->curr_connp->bytes_processed == + (ssl_state->curr_connp->record_length + + SSLV3_RECORD_HDR_LEN)) { return (input - initial_input); } + /* fall through */ case 1: ssl_state->curr_connp->message_length = *(input++) << 16; ssl_state->curr_connp->bytes_processed++; ssl_state->curr_connp->hs_bytes_processed++; - if (--input_len == 0 || - ssl_state->curr_connp->bytes_processed == - (ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN)) - { + if (--input_len == 0 || ssl_state->curr_connp->bytes_processed == + (ssl_state->curr_connp->record_length + + SSLV3_RECORD_HDR_LEN)) { return (input - initial_input); } + /* fall through */ case 2: ssl_state->curr_connp->message_length |= *(input++) << 8; ssl_state->curr_connp->bytes_processed++; ssl_state->curr_connp->hs_bytes_processed++; - if (--input_len == 0 || - ssl_state->curr_connp->bytes_processed == - (ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN)) - { + if (--input_len == 0 || ssl_state->curr_connp->bytes_processed == + (ssl_state->curr_connp->record_length + + SSLV3_RECORD_HDR_LEN)) { return (input - initial_input); } + /* fall through */ case 3: ssl_state->curr_connp->message_length |= *(input++); ssl_state->curr_connp->bytes_processed++; ssl_state->curr_connp->hs_bytes_processed++; --input_len; + /* fall through */ } @@ -458,6 +487,7 @@ static int SSLv3ParseHandshakeProtocol(SSLState *ssl_state, uint8_t *input, if (retval < 0) { return retval; } + input += retval; return (input - initial_input); @@ -468,7 +498,7 @@ static int SSLv3ParseHandshakeProtocol(SSLState *ssl_state, uint8_t *input, * \brief TLS Heartbeat parser (see RFC 6520) * * \param sslstate Pointer to the SSL state. - * \param input Pointer the received input data. + * \param input Pointer to the received input data. * \param input_len Length in bytes of the received data. * \param direction 1 toclient, 0 toserver * @@ -481,10 +511,11 @@ static int SSLv3ParseHeartbeatProtocol(SSLState *ssl_state, uint8_t *input, uint16_t payload_len; uint16_t padding_len; - // expect at least 3 bytes, heartbeat type (1) + length (2) + /* expect at least 3 bytes: heartbeat type (1) + length (2) */ if (input_len < 3) { return 0; } + hb_type = *input++; if (!(ssl_state->flags & SSL_AL_FLAG_CHANGE_CIPHER_SPEC)) { @@ -499,73 +530,80 @@ static int SSLv3ParseHeartbeatProtocol(SSLState *ssl_state, uint8_t *input, ssl_state->flags |= SSL_AL_FLAG_HB_INFLIGHT; if (direction) { + SCLogDebug("HeartBeat Record type sent in the toclient direction!"); ssl_state->flags |= SSL_AL_FLAG_HB_SERVER_INIT; - SCLogDebug("HeartBeat Record type sent in the toclient " - "direction!"); } else { + SCLogDebug("HeartBeat Record type sent in the toserver direction!"); ssl_state->flags |= SSL_AL_FLAG_HB_CLIENT_INIT; - SCLogDebug("HeartBeat Record type sent in the toserver " - "direction!"); } - /* if we reach this poin then can we assume that the HB request - * is encrypted if so lets set the heartbeat record len */ + + /* if we reach this point, then we can assume that the HB request + is encrypted. If so, let's set the HB record length */ if (ssl_state->flags & SSL_AL_FLAG_CHANGE_CIPHER_SPEC) { ssl_state->hb_record_len = ssl_state->curr_connp->record_length; - SCLogDebug("Encrypted HeartBeat Request In-flight. Storing len %u", ssl_state->hb_record_len); + SCLogDebug("Encrypted HeartBeat Request In-flight. Storing len %u", + ssl_state->hb_record_len); return (ssl_state->curr_connp->record_length - 3); } payload_len = (*input++) << 8; payload_len |= (*input++); - // check that the requested payload length is really present in record (CVE-2014-0160) + /* check that the requested payload length is really present in + 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); + AppLayerDecoderEventsSetEvent(ssl_state->f, + TLS_DECODER_EVENT_OVERFLOW_HEARTBEAT); return -1; } - // check the padding length - // it must be at least 16 bytes (RFC 6520, section 4) + /* check the padding length. It must be at least 16 bytes + (RFC 6520, section 4) */ 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); + AppLayerDecoderEventsSetEvent(ssl_state->f, + TLS_DECODER_EVENT_INVALID_HEARTBEAT); return -1; } - if (input_len < payload_len+padding_len) { // we don't have the payload + /* we don't have the payload */ + if (input_len < payload_len + padding_len) { return 0; } /* OpenSSL still seems to discard multiple in-flight - * heartbeats although some tools send multiple at once */ + heartbeats although some tools send multiple at once */ } 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 Intiated HeartBeats"); - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_HEARTBEAT); + SCLogDebug("Multiple in-flight server initiated HeartBeats"); + AppLayerDecoderEventsSetEvent(ssl_state->f, + 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 Intiated HeartBeats"); - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_HEARTBEAT); + SCLogDebug("Multiple in-flight client initiated HeartBeats"); + AppLayerDecoderEventsSetEvent(ssl_state->f, + TLS_DECODER_EVENT_INVALID_HEARTBEAT); return -1; + } else { - /* we have a HB record in the opposite direction of the request - * lets reset our flags */ + /* we have a HB record in the opposite direction of the request, + let's reset our flags */ ssl_state->flags &= ~SSL_AL_FLAG_HB_INFLIGHT; ssl_state->flags &= ~SSL_AL_FLAG_HB_SERVER_INIT; ssl_state->flags &= ~SSL_AL_FLAG_HB_CLIENT_INIT; - /* if we reach this poin then can we assume that the HB request is - *encrypted if so lets set the heartbeat record len */ + /* if we reach this point, then we can assume that the HB request + is encrypted. If so, let's set the HB record length */ if (ssl_state->flags & SSL_AL_FLAG_CHANGE_CIPHER_SPEC) { /* check to see if the encrypted response is longer than the - * encrypted request */ - if (ssl_state->hb_record_len > 0 && - ssl_state->hb_record_len < ssl_state->curr_connp->record_length) - { - SCLogDebug("My Heart It's Bleeding.. OpenSSL HeartBleed Response (%u)", + encrypted request */ + if (ssl_state->hb_record_len > 0 && ssl_state->hb_record_len < + ssl_state->curr_connp->record_length) { + SCLogDebug("My heart is bleeding.. OpenSSL HeartBleed response (%u)", ssl_state->hb_record_len); AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_DATALEAK_HEARTBEAT_MISMATCH); @@ -573,11 +611,14 @@ static int SSLv3ParseHeartbeatProtocol(SSLState *ssl_state, uint8_t *input, return -1; } } - /* reset the hb record len in-case we have legit hb's followed by a bad one */ + + /* reset the HB record length in case we have a legit HB followed + by a bad one */ ssl_state->hb_record_len = 0; } - /* skip the heartbeat, 3 bytes were already parsed, e.g |18 03 02| for TLS 1.2 */ + /* skip the HeartBeat, 3 bytes were already parsed, + e.g |18 03 02| for TLS 1.2 */ return (ssl_state->curr_connp->record_length - 3); } @@ -605,28 +646,33 @@ static int SSLv3ParseRecord(uint8_t direction, SSLState *ssl_state, if (--input_len == 0) break; } + /* fall through */ case 1: ssl_state->curr_connp->version = *(input++) << 8; if (--input_len == 0) break; + /* fall through */ case 2: ssl_state->curr_connp->version |= *(input++); if (--input_len == 0) break; + /* fall through */ case 3: ssl_state->curr_connp->record_length = *(input++) << 8; if (--input_len == 0) break; + /* fall through */ case 4: ssl_state->curr_connp->record_length |= *(input++); if (--input_len == 0) break; + /* fall through */ - } /* switch (ssl_state->curr_connp->bytes_processed) */ + } ssl_state->curr_connp->bytes_processed += (input - initial_input); @@ -662,14 +708,16 @@ static int SSLv2ParseRecord(uint8_t direction, SSLState *ssl_state, ssl_state->curr_connp->record_length |= *(input++); if (--input_len == 0) break; + /* fall through */ case 2: ssl_state->curr_connp->content_type = *(input++); ssl_state->curr_connp->version = SSL_VERSION_2; if (--input_len == 0) break; + /* fall through */ - } /* switch (ssl_state->curr_connp->bytes_processed) */ + } } else { switch (ssl_state->curr_connp->bytes_processed) { @@ -685,6 +733,7 @@ static int SSLv2ParseRecord(uint8_t direction, SSLState *ssl_state, if (--input_len == 0) break; } + /* fall through */ case 1: ssl_state->curr_connp->record_length |= *(input++); @@ -704,8 +753,9 @@ static int SSLv2ParseRecord(uint8_t direction, SSLState *ssl_state, ssl_state->curr_connp->version = SSL_VERSION_2; if (--input_len == 0) break; + /* fall through */ - } /* switch (ssl_state->curr_connp->bytes_processed) */ + } } ssl_state->curr_connp->bytes_processed += (input - initial_input); @@ -728,12 +778,14 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state, } } - /* the + 1 because, we also read one extra byte inside SSLv2ParseRecord - * to read the msg_type */ - if (ssl_state->curr_connp->bytes_processed < (ssl_state->curr_connp->record_lengths_length + 1)) { + /* the +1 is because we read one extra byte inside SSLv2ParseRecord + to read the msg_type */ + if (ssl_state->curr_connp->bytes_processed < + (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); + AppLayerDecoderEventsSetEvent(ssl_state->f, + TLS_DECODER_EVENT_INVALID_SSLV2_HEADER); return -1; } else { input += retval; @@ -745,26 +797,28 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state, return (input - initial_input); } - /* record_length should never be 0 */ + /* record_length should never be zero */ if (ssl_state->curr_connp->record_length == 0) { - SCLogDebug("SSLv2 record length is 0"); - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSLV2_HEADER); + SCLogDebug("SSLv2 record length is zero"); + AppLayerDecoderEventsSetEvent(ssl_state->f, + TLS_DECODER_EVENT_INVALID_SSLV2_HEADER); return -1; } - /* record_lenghts_length should never be 0 */ + /* record_lenghts_length should never be zero */ if (ssl_state->curr_connp->record_lengths_length == 0) { - SCLogDebug("SSLv2 record lengths length is 0"); - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSLV2_HEADER); + SCLogDebug("SSLv2 record lengths length is zero"); + AppLayerDecoderEventsSetEvent(ssl_state->f, + TLS_DECODER_EVENT_INVALID_SSLV2_HEADER); return -1; } switch (ssl_state->curr_connp->content_type) { 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); + 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); break; @@ -784,6 +838,7 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state, if (ssl_state->curr_connp->session_id_length == 0) { ssl_state->flags |= SSL_AL_FLAG_SSL_NO_SESSION_ID; } + break; } else { input++; @@ -791,40 +846,45 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state, if (--input_len == 0) break; } + /* fall through */ case 5: input++; ssl_state->curr_connp->bytes_processed++; if (--input_len == 0) break; + /* fall through */ case 6: input++; ssl_state->curr_connp->bytes_processed++; if (--input_len == 0) break; + /* fall through */ case 7: input++; ssl_state->curr_connp->bytes_processed++; if (--input_len == 0) break; + /* fall through */ case 8: ssl_state->curr_connp->session_id_length = *(input++) << 8; ssl_state->curr_connp->bytes_processed++; if (--input_len == 0) break; + /* fall through */ case 9: ssl_state->curr_connp->session_id_length |= *(input++); ssl_state->curr_connp->bytes_processed++; if (--input_len == 0) break; + /* fall through */ - } /* switch (ssl_state->curr_connp->bytes_processed) */ + } - /* ssl_state->curr_connp->record_lengths_length is 3 */ } else { switch (ssl_state->curr_connp->bytes_processed) { case 3: @@ -837,6 +897,7 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state, if (ssl_state->curr_connp->session_id_length == 0) { ssl_state->flags |= SSL_AL_FLAG_SSL_NO_SESSION_ID; } + break; } else { input++; @@ -844,41 +905,47 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state, if (--input_len == 0) break; } + case 4: input++; ssl_state->curr_connp->bytes_processed++; if (--input_len == 0) break; + case 5: input++; ssl_state->curr_connp->bytes_processed++; if (--input_len == 0) break; + case 6: input++; ssl_state->curr_connp->bytes_processed++; if (--input_len == 0) break; + case 7: ssl_state->curr_connp->session_id_length = *(input++) << 8; ssl_state->curr_connp->bytes_processed++; if (--input_len == 0) break; + case 8: ssl_state->curr_connp->session_id_length |= *(input++); ssl_state->curr_connp->bytes_processed++; if (--input_len == 0) break; - } /* switch (ssl_state->curr_connp->bytes_processed) */ - } /* else - if (ssl_state->curr_connp->record_lengths_length == 3) */ + } + } break; case SSLV2_MT_CLIENT_MASTER_KEY: - if ( !(ssl_state->flags & SSL_AL_FLAG_SSL_CLIENT_HS)) { + if (!(ssl_state->flags & SSL_AL_FLAG_SSL_CLIENT_HS)) { SCLogDebug("Client hello is not seen before master key " - "message!!"); + "message!"); } + ssl_state->flags |= SSL_AL_FLAG_SSL_CLIENT_MASTER_KEY; break; @@ -890,20 +957,23 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state, } else { ssl_state->flags |= SSL_AL_FLAG_STATE_CLIENT_KEYX; } + /* fall through */ case SSLV2_MT_SERVER_VERIFY: case SSLV2_MT_SERVER_FINISHED: if (direction == 0 && - !(ssl_state->curr_connp->content_type & SSLV2_MT_CLIENT_CERTIFICATE)) { + !(ssl_state->curr_connp->content_type & + SSLV2_MT_CLIENT_CERTIFICATE)) { SCLogDebug("Incorrect SSL Record type sent in the toserver " "direction!"); } + /* fall through */ case SSLV2_MT_CLIENT_FINISHED: case SSLV2_MT_REQUEST_CERTIFICATE: - /* both ways hello seen */ + /* both client hello and server hello must be seen */ if ((ssl_state->flags & SSL_AL_FLAG_SSL_CLIENT_HS) && - (ssl_state->flags & SSL_AL_FLAG_SSL_SERVER_HS)) { + (ssl_state->flags & SSL_AL_FLAG_SSL_SERVER_HS)) { if (direction == 0) { if (ssl_state->flags & SSL_AL_FLAG_SSL_NO_SESSION_ID) { @@ -919,11 +989,12 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state, } if ((ssl_state->flags & SSL_AL_FLAG_SSL_CLIENT_SSN_ENCRYPTED) && - (ssl_state->flags & SSL_AL_FLAG_SSL_SERVER_SSN_ENCRYPTED)) { + (ssl_state->flags & SSL_AL_FLAG_SSL_SERVER_SSN_ENCRYPTED)) { AppLayerParserStateSetFlag(pstate, - APP_LAYER_PARSER_NO_INSPECTION); + APP_LAYER_PARSER_NO_INSPECTION); if (ssl_config.no_reassemble == 1) - AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_NO_REASSEMBLY); + AppLayerParserStateSetFlag(pstate, + APP_LAYER_PARSER_NO_REASSEMBLY); SCLogDebug("SSLv2 No reassembly & inspection has been set"); } } @@ -938,16 +1009,19 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state, } if (input_len + ssl_state->curr_connp->bytes_processed >= - (ssl_state->curr_connp->record_length + ssl_state->curr_connp->record_lengths_length)) { - /* looks like we have another record after this*/ + (ssl_state->curr_connp->record_length + + ssl_state->curr_connp->record_lengths_length)) { + + /* looks like we have another record after this */ uint32_t diff = ssl_state->curr_connp->record_length + - ssl_state->curr_connp->record_lengths_length + - ssl_state->curr_connp->bytes_processed; + ssl_state->curr_connp->record_lengths_length + - + ssl_state->curr_connp->bytes_processed; input += diff; SSLParserReset(ssl_state); return (input - initial_input); - /* we still don't have the entire record for the one we are - * currently parsing */ + /* we still don't have the entire record for the one we are + currently parsing */ } else { input += input_len; ssl_state->curr_connp->bytes_processed += input_len; @@ -965,7 +1039,8 @@ 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); + AppLayerDecoderEventsSetEvent(ssl_state->f, + TLS_DECODER_EVENT_INVALID_TLS_HEADER); return -1; } else { parsed += retval; @@ -979,17 +1054,18 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state, /* check record version */ if (ssl_state->curr_connp->version < SSL_VERSION_3 || - ssl_state->curr_connp->version > TLS_VERSION_12) { + ssl_state->curr_connp->version > TLS_VERSION_12) { AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_RECORD_VERSION); return -1; } - /* record_length should never be 0 */ + /* 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); + AppLayerDecoderEventsSetEvent(ssl_state->f, + TLS_DECODER_EVENT_INVALID_TLS_HEADER); return -1; } @@ -1008,15 +1084,17 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state, case SSLV3_ALERT_PROTOCOL: break; + case SSLV3_APPLICATION_PROTOCOL: if ((ssl_state->flags & SSL_AL_FLAG_CLIENT_CHANGE_CIPHER_SPEC) && - (ssl_state->flags & SSL_AL_FLAG_SERVER_CHANGE_CIPHER_SPEC)) { + (ssl_state->flags & SSL_AL_FLAG_SERVER_CHANGE_CIPHER_SPEC)) { /* AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_NO_INSPECTION); if (ssl_config.no_reassemble == 1) AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_NO_REASSEMBLY); */ - AppLayerParserStateSetFlag(pstate,APP_LAYER_PARSER_NO_INSPECTION_PAYLOAD); + AppLayerParserStateSetFlag(pstate, + APP_LAYER_PARSER_NO_INSPECTION_PAYLOAD); } break; @@ -1027,26 +1105,34 @@ 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); + AppLayerDecoderEventsSetEvent(ssl_state->f, + TLS_DECODER_EVENT_INVALID_SSL_RECORD); return -1; } retval = SSLv3ParseHandshakeProtocol(ssl_state, input + parsed, input_len); if (retval < 0) { - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_HANDSHAKE_MESSAGE); - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD); + AppLayerDecoderEventsSetEvent(ssl_state->f, + TLS_DECODER_EVENT_INVALID_HANDSHAKE_MESSAGE); + AppLayerDecoderEventsSetEvent(ssl_state->f, + TLS_DECODER_EVENT_INVALID_SSL_RECORD); return -1; } else { if ((uint32_t)retval > input_len) { - SCLogDebug("Error parsing SSLv3.x. Reseting parser " - "state. Let's get outta here"); + SCLogDebug("Error parsing SSLv3.x. Reseting parser " + "state. Let's get outta here"); SSLParserReset(ssl_state); - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD); + AppLayerDecoderEventsSetEvent(ssl_state->f, + TLS_DECODER_EVENT_INVALID_SSL_RECORD); return -1; } + parsed += retval; input_len -= retval; - if (ssl_state->curr_connp->bytes_processed == ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN) { + + if (ssl_state->curr_connp->bytes_processed == + ssl_state->curr_connp->record_length + + SSLV3_RECORD_HDR_LEN) { SSLParserReset(ssl_state); } @@ -1056,23 +1142,31 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state, } break; + case SSLV3_HEARTBEAT_PROTOCOL: - retval = SSLv3ParseHeartbeatProtocol(ssl_state, input + parsed, input_len, direction); + retval = SSLv3ParseHeartbeatProtocol(ssl_state, input + parsed, + input_len, direction); if (retval < 0) return -1; + break; 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); + AppLayerDecoderEventsSetEvent(ssl_state->f, + TLS_DECODER_EVENT_INVALID_RECORD_TYPE); + AppLayerDecoderEventsSetEvent(ssl_state->f, + TLS_DECODER_EVENT_INVALID_SSL_RECORD); return -1; } - if (input_len + ssl_state->curr_connp->bytes_processed >= 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) { - /* defensive checks. Something's wrong. */ - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD); + if (input_len + ssl_state->curr_connp->bytes_processed >= + 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) { + /* defensive checks. Something is wrong. */ + AppLayerDecoderEventsSetEvent(ssl_state->f, + TLS_DECODER_EVENT_INVALID_SSL_RECORD); return -1; } @@ -1080,13 +1174,14 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state, AppLayerParserTriggerRawStreamReassembly(ssl_state->f); /* looks like we have another record */ - uint32_t diff = ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN - ssl_state->curr_connp->bytes_processed; + uint32_t diff = ssl_state->curr_connp->record_length + + SSLV3_RECORD_HDR_LEN - ssl_state->curr_connp->bytes_processed; parsed += diff; SSLParserReset(ssl_state); return parsed; - /* we still don't have the entire record for the one we are - * currently parsing */ + /* we still don't have the entire record for the one we are + currently parsing */ } else { parsed += input_len; ssl_state->curr_connp->bytes_processed += input_len; @@ -1126,7 +1221,8 @@ static int SSLDecode(Flow *f, uint8_t direction, void *alstate, AppLayerParserSt ssl_state->f = f; - if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) { + if (input == NULL && + AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) { SCReturnInt(1); } else if (input == NULL || input_len == 0) { SCReturnInt(-1); @@ -1140,16 +1236,16 @@ static int SSLDecode(Flow *f, uint8_t direction, void *alstate, AppLayerParserSt /* if we have more than one record */ while (input_len > 0) { if (counter++ == 30) { - SCLogDebug("Looks like we have looped quite a bit. Reset state " + 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); + AppLayerDecoderEventsSetEvent(ssl_state->f, + TLS_DECODER_EVENT_INVALID_SSL_RECORD); return -1; } - /* ssl_state->bytes_processed is 0 for a - * fresh record or positive to indicate a record currently being - * parsed */ + /* ssl_state->bytes_processed is zero for a fresh record or + positive to indicate a record currently being parsed */ switch (ssl_state->curr_connp->bytes_processed) { /* fresh record */ case 0: @@ -1160,10 +1256,11 @@ static int SSLDecode(Flow *f, uint8_t direction, void *alstate, AppLayerParserSt retval = SSLv2Decode(direction, ssl_state, pstate, input, input_len); if (retval < 0) { - SCLogDebug("Error parsing SSLv2.x. Reseting parser " - "state. Let's get outta here"); + SCLogDebug("Error parsing SSLv2.x. Reseting parser " + "state. Let's get outta here"); SSLParserReset(ssl_state); - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD); + AppLayerDecoderEventsSetEvent(ssl_state->f, + TLS_DECODER_EVENT_INVALID_SSL_RECORD); return -1; } else { input_len -= retval; @@ -1172,15 +1269,16 @@ static int SSLDecode(Flow *f, uint8_t direction, void *alstate, AppLayerParserSt } else { SCLogDebug("SSLv3.x detected"); /* we will keep it this way till our record parser tells - * us what exact version it is */ + us what exact version this is */ ssl_state->curr_connp->version = TLS_VERSION_UNKNOWN; retval = SSLv3Decode(direction, ssl_state, pstate, input, input_len); if (retval < 0) { - SCLogDebug("Error parsing SSLv3.x. Reseting parser " - "state. Let's get outta here"); + SCLogDebug("Error parsing SSLv3.x. Reseting parser " + "state. Let's get outta here"); SSLParserReset(ssl_state); - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD); + AppLayerDecoderEventsSetEvent(ssl_state->f, + TLS_DECODER_EVENT_INVALID_SSL_RECORD); return -1; } else { input_len -= retval;