ssl: implement frames for SSLv3 and TLS

pull/6809/head
Victor Julien 3 years ago
parent 3cdefd5f8b
commit af797b5926

@ -37,6 +37,7 @@
#include "app-layer.h"
#include "app-layer-protos.h"
#include "app-layer-parser.h"
#include "app-layer-frames.h"
#include "app-layer-ssl.h"
#include "decode-events.h"
@ -53,6 +54,38 @@
#include "flow-private.h"
#include "util-validate.h"
SCEnumCharMap tls_frame_table[] = {
{
"pdu",
TLS_FRAME_PDU,
},
{
"hdr",
TLS_FRAME_HDR,
},
{
"data",
TLS_FRAME_DATA,
},
{
"alert",
TLS_FRAME_ALERT_DATA,
},
{
"heartbeat",
TLS_FRAME_HB_DATA,
},
{
"ssl2.hdr",
TLS_FRAME_SSLV2_HDR,
},
{
"ssl2.pdu",
TLS_FRAME_SSLV2_PDU,
},
{ NULL, -1 },
};
SCEnumCharMap tls_decoder_event_table[ ] = {
/* TLS protocol messages */
{ "INVALID_SSLV2_HEADER", TLS_DECODER_EVENT_INVALID_SSLV2_HEADER },
@ -1980,9 +2013,8 @@ static int SSLv2ParseRecord(uint8_t direction, SSLState *ssl_state,
return (input - initial_input);
}
static int SSLv2Decode(uint8_t direction, SSLState *ssl_state,
AppLayerParserState *pstate, const uint8_t *input,
uint32_t input_len)
static int SSLv2Decode(uint8_t direction, SSLState *ssl_state, AppLayerParserState *pstate,
const uint8_t *input, uint32_t input_len, const StreamSlice stream_slice)
{
int retval = 0;
const uint8_t *initial_input = input;
@ -1993,18 +2025,37 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state,
} else {
ssl_state->curr_connp->record_lengths_length = 3;
}
SCLogDebug("record start: ssl2.hdr frame");
AppLayerFrameNewByPointer(ssl_state->f, &stream_slice, input,
ssl_state->curr_connp->record_lengths_length + 1, direction, TLS_FRAME_SSLV2_HDR);
}
SCLogDebug("direction %u ssl_state->curr_connp->record_lengths_length + 1 %u, "
"ssl_state->curr_connp->bytes_processed %u",
direction, ssl_state->curr_connp->record_lengths_length + 1,
ssl_state->curr_connp->bytes_processed);
/* 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);
SCLogDebug("retval %d ssl_state->curr_connp->record_length %u", retval,
ssl_state->curr_connp->record_length);
if (retval < 0 || retval > (int)input_len) {
DEBUG_VALIDATE_BUG_ON(retval > (int)input_len);
SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_SSLV2_HEADER);
return -1;
}
// TODO review
// BUG_ON(ssl_state->curr_connp->record_lengths_length + 1 !=
// ssl_state->curr_connp->bytes_processed);
AppLayerFrameNewByPointer(ssl_state->f, &stream_slice, input,
ssl_state->curr_connp->record_lengths_length + ssl_state->curr_connp->record_length,
direction, TLS_FRAME_SSLV2_PDU);
SCLogDebug("record start: ssl2.pdu frame");
input += retval;
input_len -= retval;
}
@ -2249,9 +2300,8 @@ static int SSLv2Decode(uint8_t direction, SSLState *ssl_state,
}
}
static int SSLv3Decode(uint8_t direction, SSLState *ssl_state,
AppLayerParserState *pstate, const uint8_t *input,
const uint32_t input_len)
static int SSLv3Decode(uint8_t direction, SSLState *ssl_state, AppLayerParserState *pstate,
const uint8_t *input, const uint32_t input_len, const StreamSlice stream_slice)
{
uint32_t parsed = 0;
uint32_t record_len; /* slice of input_len for the current record */
@ -2264,6 +2314,12 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state,
SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_TLS_HEADER);
return -1;
}
SCLogDebug("%s input %p record_length %u", (direction == 0) ? "toserver" : "toclient",
input, ssl_state->curr_connp->record_length);
AppLayerFrameNewByPointer(ssl_state->f, &stream_slice, input,
ssl_state->curr_connp->record_length + retval, direction, TLS_FRAME_PDU);
AppLayerFrameNewByPointer(
ssl_state->f, &stream_slice, input, SSLV3_RECORD_HDR_LEN, direction, TLS_FRAME_HDR);
parsed += retval;
record_len = MIN(input_len - parsed, ssl_state->curr_connp->record_length);
SCLogDebug("record_len %u (input_len %u, parsed %u, ssl_state->curr_connp->record_length %u)",
@ -2287,6 +2343,8 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state,
SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_TLS_HEADER);
return -1;
}
AppLayerFrameNewByPointer(ssl_state->f, &stream_slice, input + parsed,
ssl_state->curr_connp->record_length, direction, TLS_FRAME_DATA);
switch (ssl_state->curr_connp->content_type) {
@ -2303,6 +2361,8 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state,
break;
case SSLV3_ALERT_PROTOCOL:
AppLayerFrameNewByPointer(ssl_state->f, &stream_slice, input + parsed,
ssl_state->curr_connp->record_length, direction, TLS_FRAME_ALERT_DATA);
break;
case SSLV3_APPLICATION_PROTOCOL:
@ -2395,6 +2455,8 @@ static int SSLv3Decode(uint8_t direction, SSLState *ssl_state,
return parsed;
}
case SSLV3_HEARTBEAT_PROTOCOL: {
AppLayerFrameNewByPointer(ssl_state->f, &stream_slice, input + parsed,
ssl_state->curr_connp->record_length, direction, TLS_FRAME_HB_DATA);
int retval = SSLv3ParseHeartbeatProtocol(ssl_state, input + parsed,
record_len, direction);
if (retval < 0) {
@ -2474,7 +2536,8 @@ static AppLayerResult SSLDecode(Flow *f, uint8_t direction, void *alstate,
if (input == NULL &&
((direction == 0 && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TS)) ||
(direction == 1 && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TC)))) {
(direction == 1 &&
AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF_TC)))) {
/* flag session as finished if APP_LAYER_PARSER_EOF is set */
ssl_state->flags |= SSL_AL_FLAG_STATE_FINISHED;
SCReturnStruct(APP_LAYER_OK);
@ -2526,8 +2589,7 @@ static AppLayerResult SSLDecode(Flow *f, uint8_t direction, void *alstate,
} else {
SCLogDebug("Continuing parsing SSLv2 record");
}
int retval = SSLv2Decode(direction, ssl_state, pstate, input,
input_len);
int retval = SSLv2Decode(direction, ssl_state, pstate, input, input_len, stream_slice);
if (retval < 0 || retval > input_len) {
DEBUG_VALIDATE_BUG_ON(retval > input_len);
SCLogDebug("Error parsing SSLv2. Reseting parser "
@ -2548,8 +2610,7 @@ static AppLayerResult SSLDecode(Flow *f, uint8_t direction, void *alstate,
SCLogDebug("Continuing parsing TLS record: record_length %u, bytes_processed %u",
ssl_state->curr_connp->record_length, ssl_state->curr_connp->bytes_processed);
}
int retval = SSLv3Decode(direction, ssl_state, pstate, input,
input_len);
int retval = SSLv3Decode(direction, ssl_state, pstate, input, input_len, stream_slice);
if (retval < 0 || retval > input_len) {
DEBUG_VALIDATE_BUG_ON(retval > input_len);
SCLogDebug("Error parsing TLS. Reseting parser "
@ -2704,6 +2765,22 @@ static AppProto SSLProbingParser(Flow *f, uint8_t direction,
return ALPROTO_FAILED;
}
static int SSLStateGetFrameIdByName(const char *frame_name)
{
int id = SCMapEnumNameToValue(frame_name, tls_frame_table);
if (id < 0) {
SCLogError(SC_ERR_INVALID_ENUM_MAP, "unknown frame type \"%s\"", frame_name);
return -1;
}
return id;
}
static const char *SSLStateGetFrameNameById(const uint8_t frame_id)
{
const char *name = SCMapEnumValueToName(frame_id, tls_frame_table);
return name;
}
static int SSLStateGetEventInfo(const char *event_name,
int *event_id, AppLayerEventType *event_type)
{
@ -2931,6 +3008,8 @@ void RegisterSSLParsers(void)
AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_TLS, STREAM_TOCLIENT,
SSLParseServerRecord);
AppLayerParserRegisterGetFrameFuncs(
IPPROTO_TCP, ALPROTO_TLS, SSLStateGetFrameIdByName, SSLStateGetFrameNameById);
AppLayerParserRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_TLS, SSLStateGetEventInfo);
AppLayerParserRegisterGetEventInfoById(IPPROTO_TCP, ALPROTO_TLS, SSLStateGetEventInfoById);

@ -32,6 +32,16 @@
#include "util-ja3.h"
#include "queue.h"
enum TlsFrameTypes {
TLS_FRAME_PDU = 0, /**< whole PDU, so header + data */
TLS_FRAME_HDR, /**< only header portion */
TLS_FRAME_DATA, /**< only data portion */
TLS_FRAME_ALERT_DATA,
TLS_FRAME_HB_DATA,
TLS_FRAME_SSLV2_HDR,
TLS_FRAME_SSLV2_PDU,
};
enum {
/* TLS protocol messages */
TLS_DECODER_EVENT_INVALID_SSLV2_HEADER,

Loading…
Cancel
Save