app-layer-ssl: code cleanup

pull/1997/head
Mats Klepsland 10 years ago committed by Victor Julien
parent 550823455e
commit e117461d4b

@ -28,9 +28,6 @@
#include "decode.h" #include "decode.h"
#include "threads.h" #include "threads.h"
#include "util-print.h"
#include "util-pool.h"
#include "stream-tcp-private.h" #include "stream-tcp-private.h"
#include "stream-tcp-reassemble.h" #include "stream-tcp-reassemble.h"
#include "stream-tcp.h" #include "stream-tcp.h"
@ -40,7 +37,6 @@
#include "app-layer-protos.h" #include "app-layer-protos.h"
#include "app-layer-parser.h" #include "app-layer-parser.h"
#include "app-layer-ssl.h" #include "app-layer-ssl.h"
#include "app-layer-tls-handshake.h" #include "app-layer-tls-handshake.h"
#include "decode-events.h" #include "decode-events.h"
@ -49,11 +45,12 @@
#include "util-spm.h" #include "util-spm.h"
#include "util-unittest.h" #include "util-unittest.h"
#include "util-debug.h" #include "util-debug.h"
#include "util-print.h"
#include "util-pool.h"
#include "util-byte.h"
#include "flow-util.h" #include "flow-util.h"
#include "flow-private.h" #include "flow-private.h"
#include "util-byte.h"
SCEnumCharMap tls_decoder_event_table[ ] = { SCEnumCharMap tls_decoder_event_table[ ] = {
/* TLS protocol messages */ /* TLS protocol messages */
{ "INVALID_SSLV2_HEADER", TLS_DECODER_EVENT_INVALID_SSLV2_HEADER }, { "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 }, { "MULTIPLE_SNI_EXTENSIONS", TLS_DECODER_EVENT_MULTIPLE_SNI_EXTENSIONS },
{ "INVALID_SNI_TYPE", TLS_DECODER_EVENT_INVALID_SNI_TYPE }, { "INVALID_SNI_TYPE", TLS_DECODER_EVENT_INVALID_SNI_TYPE },
{ "INVALID_SNI_LENGTH", TLS_DECODER_EVENT_INVALID_SNI_LENGTH }, { "INVALID_SNI_LENGTH", TLS_DECODER_EVENT_INVALID_SNI_LENGTH },
/* Certificates decoding messages */ /* certificate decoding messages */
{ "INVALID_CERTIFICATE", TLS_DECODER_EVENT_INVALID_CERTIFICATE }, { "INVALID_CERTIFICATE", TLS_DECODER_EVENT_INVALID_CERTIFICATE },
{ "CERTIFICATE_MISSING_ELEMENT", TLS_DECODER_EVENT_CERTIFICATE_MISSING_ELEMENT }, { "CERTIFICATE_MISSING_ELEMENT", TLS_DECODER_EVENT_CERTIFICATE_MISSING_ELEMENT },
{ "CERTIFICATE_UNKNOWN_ELEMENT", TLS_DECODER_EVENT_CERTIFICATE_UNKNOWN_ELEMENT }, { "CERTIFICATE_UNKNOWN_ELEMENT", TLS_DECODER_EVENT_CERTIFICATE_UNKNOWN_ELEMENT },
@ -87,47 +84,47 @@ typedef struct SslConfig_ {
SslConfig ssl_config; SslConfig ssl_config;
/* SSLv3 record types */ /* SSLv3 record types */
#define SSLV3_CHANGE_CIPHER_SPEC 20 #define SSLV3_CHANGE_CIPHER_SPEC 20
#define SSLV3_ALERT_PROTOCOL 21 #define SSLV3_ALERT_PROTOCOL 21
#define SSLV3_HANDSHAKE_PROTOCOL 22 #define SSLV3_HANDSHAKE_PROTOCOL 22
#define SSLV3_APPLICATION_PROTOCOL 23 #define SSLV3_APPLICATION_PROTOCOL 23
#define SSLV3_HEARTBEAT_PROTOCOL 24 #define SSLV3_HEARTBEAT_PROTOCOL 24
/* SSLv3 handshake protocol types */ /* SSLv3 handshake protocol types */
#define SSLV3_HS_HELLO_REQUEST 0 #define SSLV3_HS_HELLO_REQUEST 0
#define SSLV3_HS_CLIENT_HELLO 1 #define SSLV3_HS_CLIENT_HELLO 1
#define SSLV3_HS_SERVER_HELLO 2 #define SSLV3_HS_SERVER_HELLO 2
#define SSLV3_HS_NEW_SESSION_TICKET 4 #define SSLV3_HS_NEW_SESSION_TICKET 4
#define SSLV3_HS_CERTIFICATE 11 #define SSLV3_HS_CERTIFICATE 11
#define SSLV3_HS_SERVER_KEY_EXCHANGE 12 #define SSLV3_HS_SERVER_KEY_EXCHANGE 12
#define SSLV3_HS_CERTIFICATE_REQUEST 13 #define SSLV3_HS_CERTIFICATE_REQUEST 13
#define SSLV3_HS_SERVER_HELLO_DONE 14 #define SSLV3_HS_SERVER_HELLO_DONE 14
#define SSLV3_HS_CERTIFICATE_VERIFY 15 #define SSLV3_HS_CERTIFICATE_VERIFY 15
#define SSLV3_HS_CLIENT_KEY_EXCHANGE 16 #define SSLV3_HS_CLIENT_KEY_EXCHANGE 16
#define SSLV3_HS_FINISHED 20 #define SSLV3_HS_FINISHED 20
#define SSLV3_HS_CERTIFICATE_URL 21 #define SSLV3_HS_CERTIFICATE_URL 21
#define SSLV3_HS_CERTIFICATE_STATUS 22 #define SSLV3_HS_CERTIFICATE_STATUS 22
/* SSLv2 protocol message types */ /* SSLv2 protocol message types */
#define SSLV2_MT_ERROR 0 #define SSLV2_MT_ERROR 0
#define SSLV2_MT_CLIENT_HELLO 1 #define SSLV2_MT_CLIENT_HELLO 1
#define SSLV2_MT_CLIENT_MASTER_KEY 2 #define SSLV2_MT_CLIENT_MASTER_KEY 2
#define SSLV2_MT_CLIENT_FINISHED 3 #define SSLV2_MT_CLIENT_FINISHED 3
#define SSLV2_MT_SERVER_HELLO 4 #define SSLV2_MT_SERVER_HELLO 4
#define SSLV2_MT_SERVER_VERIFY 5 #define SSLV2_MT_SERVER_VERIFY 5
#define SSLV2_MT_SERVER_FINISHED 6 #define SSLV2_MT_SERVER_FINISHED 6
#define SSLV2_MT_REQUEST_CERTIFICATE 7 #define SSLV2_MT_REQUEST_CERTIFICATE 7
#define SSLV2_MT_CLIENT_CERTIFICATE 8 #define SSLV2_MT_CLIENT_CERTIFICATE 8
#define SSLV3_RECORD_HDR_LEN 5 #define SSLV3_RECORD_HDR_LEN 5
#define SSLV3_MESSAGE_HDR_LEN 4 #define SSLV3_MESSAGE_HDR_LEN 4
#define SSLV3_CLIENT_HELLO_VERSION_LEN 2 #define SSLV3_CLIENT_HELLO_VERSION_LEN 2
#define SSLV3_CLIENT_HELLO_RANDOM_LEN 32 #define SSLV3_CLIENT_HELLO_RANDOM_LEN 32
/* TLS heartbeat protocol types */ /* TLS heartbeat protocol types */
#define TLS_HB_REQUEST 1 #define TLS_HB_REQUEST 1
#define TLS_HB_RESPONSE 2 #define TLS_HB_RESPONSE 2
#define HAS_SPACE(n) ((uint32_t)((input) + (n) - (initial_input)) > (uint32_t)(input_len)) ? 0 : 1 #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: case SSLV3_HS_CERTIFICATE:
if (ssl_state->curr_connp->trec == NULL) { 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_len =
ssl_state->curr_connp->trec = SCMalloc( 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) { if (ssl_state->curr_connp->trec_pos + input_len >=
ssl_state->curr_connp->trec_len = ssl_state->curr_connp->trec_len + 2 * input_len + 1; 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, ptmp = SCRealloc(ssl_state->curr_connp->trec,
ssl_state->curr_connp->trec_len); ssl_state->curr_connp->trec_len);
if (unlikely(ptmp == NULL)) { if (unlikely(ptmp == NULL)) {
SCFree(ssl_state->curr_connp->trec); SCFree(ssl_state->curr_connp->trec);
} }
ssl_state->curr_connp->trec = ptmp; ssl_state->curr_connp->trec = ptmp;
} }
if (unlikely(ssl_state->curr_connp->trec == NULL)) { if (unlikely(ssl_state->curr_connp->trec == NULL)) {
@ -312,30 +316,44 @@ end:
} }
uint32_t write_len = 0; 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->bytes_processed + input_len) >
if ((ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN) < ssl_state->curr_connp->bytes_processed) { ssl_state->curr_connp->record_length +
AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD); (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; 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 { } else {
write_len = input_len; 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; 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) { if (rc > 0) {
/* do not return normally if the packet was fragmented: /* do not return normally if the packet was fragmented:
* we would return the size of the *entire* message, we would return the size of the _entire_ message,
* while we expect only the number of bytes parsed bytes while we expect only the number of bytes parsed bytes
* from the *current* fragment from the _current_ fragment */
*/
if (write_len < (ssl_state->curr_connp->trec_pos - rc)) { 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; 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->bytes_processed += diff;
ssl_state->curr_connp->trec_pos = 0; ssl_state->curr_connp->trec_pos = 0;
@ -362,28 +380,40 @@ end:
SCLogDebug("new session ticket"); SCLogDebug("new session ticket");
break; break;
default: default:
AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD); AppLayerDecoderEventsSetEvent(ssl_state->f,
TLS_DECODER_EVENT_INVALID_SSL_RECORD);
return -1; return -1;
} }
uint32_t write_len = 0; 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->bytes_processed + input_len) >=
if ((ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN) < ssl_state->curr_connp->bytes_processed) { ssl_state->curr_connp->record_length + (SSLV3_RECORD_HDR_LEN)) {
AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD); 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; 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 { } else {
write_len = input_len; 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) { if ((ssl_state->curr_connp->trec_pos + write_len) >=
AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD); 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; 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->handshake_type = 0;
ssl_state->curr_connp->hs_bytes_processed = 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; uint8_t *initial_input = input;
int retval; int retval;
if (input_len == 0 || if (input_len == 0 || ssl_state->curr_connp->bytes_processed ==
ssl_state->curr_connp->bytes_processed == (ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN)) {
(ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN))
{
return 0; 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->handshake_type = *(input++);
ssl_state->curr_connp->bytes_processed++; ssl_state->curr_connp->bytes_processed++;
ssl_state->curr_connp->hs_bytes_processed++; ssl_state->curr_connp->hs_bytes_processed++;
if (--input_len == 0 || if (--input_len == 0 || ssl_state->curr_connp->bytes_processed ==
ssl_state->curr_connp->bytes_processed == (ssl_state->curr_connp->record_length +
(ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN)) SSLV3_RECORD_HDR_LEN)) {
{
return (input - initial_input); return (input - initial_input);
} }
/* fall through */ /* fall through */
case 1: case 1:
ssl_state->curr_connp->message_length = *(input++) << 16; ssl_state->curr_connp->message_length = *(input++) << 16;
ssl_state->curr_connp->bytes_processed++; ssl_state->curr_connp->bytes_processed++;
ssl_state->curr_connp->hs_bytes_processed++; ssl_state->curr_connp->hs_bytes_processed++;
if (--input_len == 0 || if (--input_len == 0 || ssl_state->curr_connp->bytes_processed ==
ssl_state->curr_connp->bytes_processed == (ssl_state->curr_connp->record_length +
(ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN)) SSLV3_RECORD_HDR_LEN)) {
{
return (input - initial_input); return (input - initial_input);
} }
/* fall through */ /* fall through */
case 2: case 2:
ssl_state->curr_connp->message_length |= *(input++) << 8; ssl_state->curr_connp->message_length |= *(input++) << 8;
ssl_state->curr_connp->bytes_processed++; ssl_state->curr_connp->bytes_processed++;
ssl_state->curr_connp->hs_bytes_processed++; ssl_state->curr_connp->hs_bytes_processed++;
if (--input_len == 0 || if (--input_len == 0 || ssl_state->curr_connp->bytes_processed ==
ssl_state->curr_connp->bytes_processed == (ssl_state->curr_connp->record_length +
(ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN)) SSLV3_RECORD_HDR_LEN)) {
{
return (input - initial_input); return (input - initial_input);
} }
/* fall through */ /* fall through */
case 3: case 3:
ssl_state->curr_connp->message_length |= *(input++); ssl_state->curr_connp->message_length |= *(input++);
ssl_state->curr_connp->bytes_processed++; ssl_state->curr_connp->bytes_processed++;
ssl_state->curr_connp->hs_bytes_processed++; ssl_state->curr_connp->hs_bytes_processed++;
--input_len; --input_len;
/* fall through */ /* fall through */
} }
@ -458,6 +487,7 @@ static int SSLv3ParseHandshakeProtocol(SSLState *ssl_state, uint8_t *input,
if (retval < 0) { if (retval < 0) {
return retval; return retval;
} }
input += retval; input += retval;
return (input - initial_input); return (input - initial_input);
@ -468,7 +498,7 @@ static int SSLv3ParseHandshakeProtocol(SSLState *ssl_state, uint8_t *input,
* \brief TLS Heartbeat parser (see RFC 6520) * \brief TLS Heartbeat parser (see RFC 6520)
* *
* \param sslstate Pointer to the SSL state. * \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 input_len Length in bytes of the received data.
* \param direction 1 toclient, 0 toserver * \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 payload_len;
uint16_t padding_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) { if (input_len < 3) {
return 0; return 0;
} }
hb_type = *input++; hb_type = *input++;
if (!(ssl_state->flags & SSL_AL_FLAG_CHANGE_CIPHER_SPEC)) { 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; ssl_state->flags |= SSL_AL_FLAG_HB_INFLIGHT;
if (direction) { if (direction) {
SCLogDebug("HeartBeat Record type sent in the toclient direction!");
ssl_state->flags |= SSL_AL_FLAG_HB_SERVER_INIT; ssl_state->flags |= SSL_AL_FLAG_HB_SERVER_INIT;
SCLogDebug("HeartBeat Record type sent in the toclient "
"direction!");
} else { } else {
SCLogDebug("HeartBeat Record type sent in the toserver direction!");
ssl_state->flags |= SSL_AL_FLAG_HB_CLIENT_INIT; 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) { if (ssl_state->flags & SSL_AL_FLAG_CHANGE_CIPHER_SPEC) {
ssl_state->hb_record_len = ssl_state->curr_connp->record_length; 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); return (ssl_state->curr_connp->record_length - 3);
} }
payload_len = (*input++) << 8; payload_len = (*input++) << 8;
payload_len |= (*input++); 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) { if ((uint32_t)(payload_len+3) > ssl_state->curr_connp->record_length) {
SCLogDebug("We have a short record in HeartBeat Request"); 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; return -1;
} }
// check the padding length /* check the padding length. It must be at least 16 bytes
// it must be at least 16 bytes (RFC 6520, section 4) (RFC 6520, section 4) */
padding_len = ssl_state->curr_connp->record_length - payload_len - 3; padding_len = ssl_state->curr_connp->record_length - payload_len - 3;
if (padding_len < 16) { if (padding_len < 16) {
SCLogDebug("We have a short record in HeartBeat Request"); 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; 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; return 0;
} }
/* OpenSSL still seems to discard multiple in-flight /* 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) && } else if (direction == 1 && (ssl_state->flags & SSL_AL_FLAG_HB_INFLIGHT) &&
(ssl_state->flags & SSL_AL_FLAG_HB_SERVER_INIT)) { (ssl_state->flags & SSL_AL_FLAG_HB_SERVER_INIT)) {
SCLogDebug("Multiple In-Flight Server Intiated HeartBeats"); SCLogDebug("Multiple in-flight server initiated HeartBeats");
AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_HEARTBEAT); AppLayerDecoderEventsSetEvent(ssl_state->f,
TLS_DECODER_EVENT_INVALID_HEARTBEAT);
return -1; return -1;
} else if (direction == 0 && (ssl_state->flags & SSL_AL_FLAG_HB_INFLIGHT) && } else if (direction == 0 && (ssl_state->flags & SSL_AL_FLAG_HB_INFLIGHT) &&
(ssl_state->flags & SSL_AL_FLAG_HB_CLIENT_INIT)) { (ssl_state->flags & SSL_AL_FLAG_HB_CLIENT_INIT)) {
SCLogDebug("Multiple In-Flight Client Intiated HeartBeats"); SCLogDebug("Multiple in-flight client initiated HeartBeats");
AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_HEARTBEAT); AppLayerDecoderEventsSetEvent(ssl_state->f,
TLS_DECODER_EVENT_INVALID_HEARTBEAT);
return -1; return -1;
} else { } else {
/* we have a HB record in the opposite direction of the request /* we have a HB record in the opposite direction of the request,
* lets reset our flags */ let's reset our flags */
ssl_state->flags &= ~SSL_AL_FLAG_HB_INFLIGHT; ssl_state->flags &= ~SSL_AL_FLAG_HB_INFLIGHT;
ssl_state->flags &= ~SSL_AL_FLAG_HB_SERVER_INIT; ssl_state->flags &= ~SSL_AL_FLAG_HB_SERVER_INIT;
ssl_state->flags &= ~SSL_AL_FLAG_HB_CLIENT_INIT; ssl_state->flags &= ~SSL_AL_FLAG_HB_CLIENT_INIT;
/* if we reach this poin then can we assume that the HB request is /* if we reach this point, then we can assume that the HB request
*encrypted if so lets set the heartbeat record len */ is encrypted. If so, let's set the HB record length */
if (ssl_state->flags & SSL_AL_FLAG_CHANGE_CIPHER_SPEC) { if (ssl_state->flags & SSL_AL_FLAG_CHANGE_CIPHER_SPEC) {
/* check to see if the encrypted response is longer than the /* check to see if the encrypted response is longer than the
* encrypted request */ encrypted request */
if (ssl_state->hb_record_len > 0 && if (ssl_state->hb_record_len > 0 && ssl_state->hb_record_len <
ssl_state->hb_record_len < ssl_state->curr_connp->record_length) ssl_state->curr_connp->record_length) {
{ SCLogDebug("My heart is bleeding.. OpenSSL HeartBleed response (%u)",
SCLogDebug("My Heart It's Bleeding.. OpenSSL HeartBleed Response (%u)",
ssl_state->hb_record_len); ssl_state->hb_record_len);
AppLayerDecoderEventsSetEvent(ssl_state->f, AppLayerDecoderEventsSetEvent(ssl_state->f,
TLS_DECODER_EVENT_DATALEAK_HEARTBEAT_MISMATCH); TLS_DECODER_EVENT_DATALEAK_HEARTBEAT_MISMATCH);
@ -573,11 +611,14 @@ static int SSLv3ParseHeartbeatProtocol(SSLState *ssl_state, uint8_t *input,
return -1; 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; 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); 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) if (--input_len == 0)
break; break;
} }
/* fall through */ /* fall through */
case 1: case 1:
ssl_state->curr_connp->version = *(input++) << 8; ssl_state->curr_connp->version = *(input++) << 8;
if (--input_len == 0) if (--input_len == 0)
break; break;
/* fall through */ /* fall through */
case 2: case 2:
ssl_state->curr_connp->version |= *(input++); ssl_state->curr_connp->version |= *(input++);
if (--input_len == 0) if (--input_len == 0)
break; break;
/* fall through */ /* fall through */
case 3: case 3:
ssl_state->curr_connp->record_length = *(input++) << 8; ssl_state->curr_connp->record_length = *(input++) << 8;
if (--input_len == 0) if (--input_len == 0)
break; break;
/* fall through */ /* fall through */
case 4: case 4:
ssl_state->curr_connp->record_length |= *(input++); ssl_state->curr_connp->record_length |= *(input++);
if (--input_len == 0) if (--input_len == 0)
break; break;
/* fall through */ /* fall through */
} /* switch (ssl_state->curr_connp->bytes_processed) */ }
ssl_state->curr_connp->bytes_processed += (input - initial_input); 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++); ssl_state->curr_connp->record_length |= *(input++);
if (--input_len == 0) if (--input_len == 0)
break; break;
/* fall through */ /* fall through */
case 2: case 2:
ssl_state->curr_connp->content_type = *(input++); ssl_state->curr_connp->content_type = *(input++);
ssl_state->curr_connp->version = SSL_VERSION_2; ssl_state->curr_connp->version = SSL_VERSION_2;
if (--input_len == 0) if (--input_len == 0)
break; break;
/* fall through */ /* fall through */
} /* switch (ssl_state->curr_connp->bytes_processed) */ }
} else { } else {
switch (ssl_state->curr_connp->bytes_processed) { switch (ssl_state->curr_connp->bytes_processed) {
@ -685,6 +733,7 @@ static int SSLv2ParseRecord(uint8_t direction, SSLState *ssl_state,
if (--input_len == 0) if (--input_len == 0)
break; break;
} }
/* fall through */ /* fall through */
case 1: case 1:
ssl_state->curr_connp->record_length |= *(input++); 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; ssl_state->curr_connp->version = SSL_VERSION_2;
if (--input_len == 0) if (--input_len == 0)
break; break;
/* fall through */ /* fall through */
} /* switch (ssl_state->curr_connp->bytes_processed) */ }
} }
ssl_state->curr_connp->bytes_processed += (input - initial_input); 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 /* the +1 is because we read one extra byte inside SSLv2ParseRecord
* to read the msg_type */ to read the msg_type */
if (ssl_state->curr_connp->bytes_processed < (ssl_state->curr_connp->record_lengths_length + 1)) { if (ssl_state->curr_connp->bytes_processed <
(ssl_state->curr_connp->record_lengths_length + 1)) {
retval = SSLv2ParseRecord(direction, ssl_state, input, input_len); retval = SSLv2ParseRecord(direction, ssl_state, input, input_len);
if (retval == -1) { 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; return -1;
} else { } else {
input += retval; input += retval;
@ -745,26 +797,28 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state,
return (input - initial_input); return (input - initial_input);
} }
/* record_length should never be 0 */ /* record_length should never be zero */
if (ssl_state->curr_connp->record_length == 0) { if (ssl_state->curr_connp->record_length == 0) {
SCLogDebug("SSLv2 record length is 0"); SCLogDebug("SSLv2 record length is zero");
AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSLV2_HEADER); AppLayerDecoderEventsSetEvent(ssl_state->f,
TLS_DECODER_EVENT_INVALID_SSLV2_HEADER);
return -1; 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) { if (ssl_state->curr_connp->record_lengths_length == 0) {
SCLogDebug("SSLv2 record lengths length is 0"); SCLogDebug("SSLv2 record lengths length is zero");
AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSLV2_HEADER); AppLayerDecoderEventsSetEvent(ssl_state->f,
TLS_DECODER_EVENT_INVALID_SSLV2_HEADER);
return -1; return -1;
} }
switch (ssl_state->curr_connp->content_type) { switch (ssl_state->curr_connp->content_type) {
case SSLV2_MT_ERROR: case SSLV2_MT_ERROR:
SCLogDebug("SSLV2_MT_ERROR msg_type received. " SCLogDebug("SSLV2_MT_ERROR msg_type received. Error encountered "
"Error encountered in establishing the sslv2 " "in establishing the sslv2 session, may be version");
"session, may be version"); AppLayerDecoderEventsSetEvent(ssl_state->f,
AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_ERROR_MSG_ENCOUNTERED); TLS_DECODER_EVENT_ERROR_MSG_ENCOUNTERED);
break; break;
@ -784,6 +838,7 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state,
if (ssl_state->curr_connp->session_id_length == 0) { if (ssl_state->curr_connp->session_id_length == 0) {
ssl_state->flags |= SSL_AL_FLAG_SSL_NO_SESSION_ID; ssl_state->flags |= SSL_AL_FLAG_SSL_NO_SESSION_ID;
} }
break; break;
} else { } else {
input++; input++;
@ -791,40 +846,45 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state,
if (--input_len == 0) if (--input_len == 0)
break; break;
} }
/* fall through */ /* fall through */
case 5: case 5:
input++; input++;
ssl_state->curr_connp->bytes_processed++; ssl_state->curr_connp->bytes_processed++;
if (--input_len == 0) if (--input_len == 0)
break; break;
/* fall through */ /* fall through */
case 6: case 6:
input++; input++;
ssl_state->curr_connp->bytes_processed++; ssl_state->curr_connp->bytes_processed++;
if (--input_len == 0) if (--input_len == 0)
break; break;
/* fall through */ /* fall through */
case 7: case 7:
input++; input++;
ssl_state->curr_connp->bytes_processed++; ssl_state->curr_connp->bytes_processed++;
if (--input_len == 0) if (--input_len == 0)
break; break;
/* fall through */ /* fall through */
case 8: case 8:
ssl_state->curr_connp->session_id_length = *(input++) << 8; ssl_state->curr_connp->session_id_length = *(input++) << 8;
ssl_state->curr_connp->bytes_processed++; ssl_state->curr_connp->bytes_processed++;
if (--input_len == 0) if (--input_len == 0)
break; break;
/* fall through */ /* fall through */
case 9: case 9:
ssl_state->curr_connp->session_id_length |= *(input++); ssl_state->curr_connp->session_id_length |= *(input++);
ssl_state->curr_connp->bytes_processed++; ssl_state->curr_connp->bytes_processed++;
if (--input_len == 0) if (--input_len == 0)
break; break;
/* fall through */ /* fall through */
} /* switch (ssl_state->curr_connp->bytes_processed) */ }
/* ssl_state->curr_connp->record_lengths_length is 3 */
} else { } else {
switch (ssl_state->curr_connp->bytes_processed) { switch (ssl_state->curr_connp->bytes_processed) {
case 3: case 3:
@ -837,6 +897,7 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state,
if (ssl_state->curr_connp->session_id_length == 0) { if (ssl_state->curr_connp->session_id_length == 0) {
ssl_state->flags |= SSL_AL_FLAG_SSL_NO_SESSION_ID; ssl_state->flags |= SSL_AL_FLAG_SSL_NO_SESSION_ID;
} }
break; break;
} else { } else {
input++; input++;
@ -844,41 +905,47 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state,
if (--input_len == 0) if (--input_len == 0)
break; break;
} }
case 4: case 4:
input++; input++;
ssl_state->curr_connp->bytes_processed++; ssl_state->curr_connp->bytes_processed++;
if (--input_len == 0) if (--input_len == 0)
break; break;
case 5: case 5:
input++; input++;
ssl_state->curr_connp->bytes_processed++; ssl_state->curr_connp->bytes_processed++;
if (--input_len == 0) if (--input_len == 0)
break; break;
case 6: case 6:
input++; input++;
ssl_state->curr_connp->bytes_processed++; ssl_state->curr_connp->bytes_processed++;
if (--input_len == 0) if (--input_len == 0)
break; break;
case 7: case 7:
ssl_state->curr_connp->session_id_length = *(input++) << 8; ssl_state->curr_connp->session_id_length = *(input++) << 8;
ssl_state->curr_connp->bytes_processed++; ssl_state->curr_connp->bytes_processed++;
if (--input_len == 0) if (--input_len == 0)
break; break;
case 8: case 8:
ssl_state->curr_connp->session_id_length |= *(input++); ssl_state->curr_connp->session_id_length |= *(input++);
ssl_state->curr_connp->bytes_processed++; ssl_state->curr_connp->bytes_processed++;
if (--input_len == 0) if (--input_len == 0)
break; break;
} /* switch (ssl_state->curr_connp->bytes_processed) */ }
} /* else - if (ssl_state->curr_connp->record_lengths_length == 3) */ }
break; break;
case SSLV2_MT_CLIENT_MASTER_KEY: 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 " SCLogDebug("Client hello is not seen before master key "
"message!!"); "message!");
} }
ssl_state->flags |= SSL_AL_FLAG_SSL_CLIENT_MASTER_KEY; ssl_state->flags |= SSL_AL_FLAG_SSL_CLIENT_MASTER_KEY;
break; break;
@ -890,20 +957,23 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state,
} else { } else {
ssl_state->flags |= SSL_AL_FLAG_STATE_CLIENT_KEYX; ssl_state->flags |= SSL_AL_FLAG_STATE_CLIENT_KEYX;
} }
/* fall through */ /* fall through */
case SSLV2_MT_SERVER_VERIFY: case SSLV2_MT_SERVER_VERIFY:
case SSLV2_MT_SERVER_FINISHED: case SSLV2_MT_SERVER_FINISHED:
if (direction == 0 && 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 " SCLogDebug("Incorrect SSL Record type sent in the toserver "
"direction!"); "direction!");
} }
/* fall through */ /* fall through */
case SSLV2_MT_CLIENT_FINISHED: case SSLV2_MT_CLIENT_FINISHED:
case SSLV2_MT_REQUEST_CERTIFICATE: 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) && 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 (direction == 0) {
if (ssl_state->flags & SSL_AL_FLAG_SSL_NO_SESSION_ID) { 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) && 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, AppLayerParserStateSetFlag(pstate,
APP_LAYER_PARSER_NO_INSPECTION); APP_LAYER_PARSER_NO_INSPECTION);
if (ssl_config.no_reassemble == 1) 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"); 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 >= if (input_len + ssl_state->curr_connp->bytes_processed >=
(ssl_state->curr_connp->record_length + ssl_state->curr_connp->record_lengths_length)) { (ssl_state->curr_connp->record_length +
/* looks like we have another record after this*/ ssl_state->curr_connp->record_lengths_length)) {
/* looks like we have another record after this */
uint32_t diff = ssl_state->curr_connp->record_length + 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; input += diff;
SSLParserReset(ssl_state); SSLParserReset(ssl_state);
return (input - initial_input); return (input - initial_input);
/* we still don't have the entire record for the one we are /* we still don't have the entire record for the one we are
* currently parsing */ currently parsing */
} else { } else {
input += input_len; input += input_len;
ssl_state->curr_connp->bytes_processed += 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) { if (ssl_state->curr_connp->bytes_processed < SSLV3_RECORD_HDR_LEN) {
retval = SSLv3ParseRecord(direction, ssl_state, input, input_len); retval = SSLv3ParseRecord(direction, ssl_state, input, input_len);
if (retval < 0) { 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; return -1;
} else { } else {
parsed += retval; parsed += retval;
@ -979,17 +1054,18 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state,
/* check record version */ /* check record version */
if (ssl_state->curr_connp->version < SSL_VERSION_3 || 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, AppLayerDecoderEventsSetEvent(ssl_state->f,
TLS_DECODER_EVENT_INVALID_RECORD_VERSION); TLS_DECODER_EVENT_INVALID_RECORD_VERSION);
return -1; return -1;
} }
/* record_length should never be 0 */ /* record_length should never be zero */
if (ssl_state->curr_connp->record_length == 0) { if (ssl_state->curr_connp->record_length == 0) {
SCLogDebug("SSLv3 Record length is 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; return -1;
} }
@ -1008,15 +1084,17 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state,
case SSLV3_ALERT_PROTOCOL: case SSLV3_ALERT_PROTOCOL:
break; break;
case SSLV3_APPLICATION_PROTOCOL: case SSLV3_APPLICATION_PROTOCOL:
if ((ssl_state->flags & SSL_AL_FLAG_CLIENT_CHANGE_CIPHER_SPEC) && 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); AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_NO_INSPECTION);
if (ssl_config.no_reassemble == 1) if (ssl_config.no_reassemble == 1)
AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_NO_REASSEMBLY); AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_NO_REASSEMBLY);
*/ */
AppLayerParserStateSetFlag(pstate,APP_LAYER_PARSER_NO_INSPECTION_PAYLOAD); AppLayerParserStateSetFlag(pstate,
APP_LAYER_PARSER_NO_INSPECTION_PAYLOAD);
} }
break; break;
@ -1027,26 +1105,34 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state,
if (ssl_state->curr_connp->record_length < 4) { if (ssl_state->curr_connp->record_length < 4) {
SSLParserReset(ssl_state); 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; return -1;
} }
retval = SSLv3ParseHandshakeProtocol(ssl_state, input + parsed, input_len); retval = SSLv3ParseHandshakeProtocol(ssl_state, input + parsed, input_len);
if (retval < 0) { if (retval < 0) {
AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_HANDSHAKE_MESSAGE); AppLayerDecoderEventsSetEvent(ssl_state->f,
AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD); TLS_DECODER_EVENT_INVALID_HANDSHAKE_MESSAGE);
AppLayerDecoderEventsSetEvent(ssl_state->f,
TLS_DECODER_EVENT_INVALID_SSL_RECORD);
return -1; return -1;
} else { } else {
if ((uint32_t)retval > input_len) { if ((uint32_t)retval > input_len) {
SCLogDebug("Error parsing SSLv3.x. Reseting parser " SCLogDebug("Error parsing SSLv3.x. Reseting parser "
"state. Let's get outta here"); "state. Let's get outta here");
SSLParserReset(ssl_state); 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; return -1;
} }
parsed += retval; parsed += retval;
input_len -= 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); SSLParserReset(ssl_state);
} }
@ -1056,23 +1142,31 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state,
} }
break; break;
case SSLV3_HEARTBEAT_PROTOCOL: 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) if (retval < 0)
return -1; return -1;
break; break;
default: default:
/* \todo fix the event from invalid rule to unknown rule */ /* \todo fix the event from invalid rule to unknown rule */
AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_RECORD_TYPE); AppLayerDecoderEventsSetEvent(ssl_state->f,
AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD); TLS_DECODER_EVENT_INVALID_RECORD_TYPE);
AppLayerDecoderEventsSetEvent(ssl_state->f,
TLS_DECODER_EVENT_INVALID_SSL_RECORD);
return -1; return -1;
} }
if (input_len + ssl_state->curr_connp->bytes_processed >= ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN) { if (input_len + ssl_state->curr_connp->bytes_processed >=
if ((ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN) < ssl_state->curr_connp->bytes_processed) { ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN) {
/* defensive checks. Something's wrong. */ if ((ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN) <
AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD); ssl_state->curr_connp->bytes_processed) {
/* defensive checks. Something is wrong. */
AppLayerDecoderEventsSetEvent(ssl_state->f,
TLS_DECODER_EVENT_INVALID_SSL_RECORD);
return -1; return -1;
} }
@ -1080,13 +1174,14 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state,
AppLayerParserTriggerRawStreamReassembly(ssl_state->f); AppLayerParserTriggerRawStreamReassembly(ssl_state->f);
/* looks like we have another record */ /* 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; parsed += diff;
SSLParserReset(ssl_state); SSLParserReset(ssl_state);
return parsed; return parsed;
/* we still don't have the entire record for the one we are /* we still don't have the entire record for the one we are
* currently parsing */ currently parsing */
} else { } else {
parsed += input_len; parsed += input_len;
ssl_state->curr_connp->bytes_processed += 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; ssl_state->f = f;
if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) { if (input == NULL &&
AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
SCReturnInt(1); SCReturnInt(1);
} else if (input == NULL || input_len == 0) { } else if (input == NULL || input_len == 0) {
SCReturnInt(-1); SCReturnInt(-1);
@ -1140,16 +1236,16 @@ static int SSLDecode(Flow *f, uint8_t direction, void *alstate, AppLayerParserSt
/* if we have more than one record */ /* if we have more than one record */
while (input_len > 0) { while (input_len > 0) {
if (counter++ == 30) { 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"); "and get out of here");
SSLParserReset(ssl_state); 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; return -1;
} }
/* ssl_state->bytes_processed is 0 for a /* ssl_state->bytes_processed is zero for a fresh record or
* fresh record or positive to indicate a record currently being positive to indicate a record currently being parsed */
* parsed */
switch (ssl_state->curr_connp->bytes_processed) { switch (ssl_state->curr_connp->bytes_processed) {
/* fresh record */ /* fresh record */
case 0: case 0:
@ -1160,10 +1256,11 @@ static int SSLDecode(Flow *f, uint8_t direction, void *alstate, AppLayerParserSt
retval = SSLv2Decode(direction, ssl_state, pstate, input, retval = SSLv2Decode(direction, ssl_state, pstate, input,
input_len); input_len);
if (retval < 0) { if (retval < 0) {
SCLogDebug("Error parsing SSLv2.x. Reseting parser " SCLogDebug("Error parsing SSLv2.x. Reseting parser "
"state. Let's get outta here"); "state. Let's get outta here");
SSLParserReset(ssl_state); 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; return -1;
} else { } else {
input_len -= retval; input_len -= retval;
@ -1172,15 +1269,16 @@ static int SSLDecode(Flow *f, uint8_t direction, void *alstate, AppLayerParserSt
} else { } else {
SCLogDebug("SSLv3.x detected"); SCLogDebug("SSLv3.x detected");
/* we will keep it this way till our record parser tells /* 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; ssl_state->curr_connp->version = TLS_VERSION_UNKNOWN;
retval = SSLv3Decode(direction, ssl_state, pstate, input, retval = SSLv3Decode(direction, ssl_state, pstate, input,
input_len); input_len);
if (retval < 0) { if (retval < 0) {
SCLogDebug("Error parsing SSLv3.x. Reseting parser " SCLogDebug("Error parsing SSLv3.x. Reseting parser "
"state. Let's get outta here"); "state. Let's get outta here");
SSLParserReset(ssl_state); 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; return -1;
} else { } else {
input_len -= retval; input_len -= retval;

Loading…
Cancel
Save