#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"
#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 },
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;
} 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;
}
}
}
-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 */
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)",
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) {
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:
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) {
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);
} 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 "
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 "
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)
{
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);