From: Victor Julien Date: Fri, 5 Aug 2022 20:27:22 +0000 (+0200) Subject: tls: support handshake fragmentation X-Git-Tag: suricata-7.0.0-beta1~203 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4bab6e24e5e2cef29c9a5a6bee3263e4a3d47e76;p=thirdparty%2Fsuricata.git tls: support handshake fragmentation Implement TLS record defrag for handshake messages. Ticket: #5183. --- diff --git a/src/app-layer-ssl.c b/src/app-layer-ssl.c index 4154612870..af380b5aa0 100644 --- a/src/app-layer-ssl.c +++ b/src/app-layer-ssl.c @@ -262,9 +262,7 @@ static inline int SafeMemcpy(void *dst, size_t dst_offset, size_t dst_size, #define SSLParserHSReset(connp) \ do { \ (connp)->handshake_type = 0; \ - (connp)->hs_bytes_processed = 0; \ (connp)->message_length = 0; \ - (connp)->message_start = 0; \ } while (0) #define SSLParserReset(state) \ @@ -1390,17 +1388,9 @@ static int TLSDecodeHandshakeHello(SSLState *ssl_state, } end: - ssl_state->curr_connp->hs_bytes_processed = 0; return 0; } -static inline bool -HaveEntireRecord(const SSLStateConnp *curr_connp, const uint32_t input_len) -{ - return (curr_connp->bytes_processed + input_len) >= - (curr_connp->record_length + SSLV3_RECORD_HDR_LEN); -} - #ifdef DEBUG_VALIDATION static inline bool RecordAlreadyProcessed(const SSLStateConnp *curr_connp) @@ -1424,10 +1414,33 @@ static inline int SSLv3ParseHandshakeTypeCertificate(SSLState *ssl_state, SSLParserHSReset(ssl_state->curr_connp); /* fall through to still consume the cert bytes */ } - ssl_state->curr_connp->bytes_processed += input_len; return input_len; } +static int SupportedHandshakeType(const uint8_t type) +{ + switch (type) { + case SSLV3_HS_CLIENT_HELLO: + case SSLV3_HS_SERVER_HELLO: + case SSLV3_HS_SERVER_KEY_EXCHANGE: + case SSLV3_HS_CLIENT_KEY_EXCHANGE: + case SSLV3_HS_CERTIFICATE: + case SSLV3_HS_HELLO_REQUEST: + case SSLV3_HS_CERTIFICATE_REQUEST: + case SSLV3_HS_CERTIFICATE_VERIFY: + case SSLV3_HS_FINISHED: + case SSLV3_HS_CERTIFICATE_URL: + case SSLV3_HS_CERTIFICATE_STATUS: + case SSLV3_HS_NEW_SESSION_TICKET: + return true; + break; + + default: + return false; + break; + } +} + /** * \retval parsed number of consumed bytes * \retval < 0 error @@ -1447,28 +1460,17 @@ static int SSLv3ParseHandshakeType(SSLState *ssl_state, const uint8_t *input, case SSLV3_HS_CLIENT_HELLO: ssl_state->current_flags = SSL_AL_FLAG_STATE_CLIENT_HELLO; - /* Only parse the message if it is complete */ - if (input_len >= ssl_state->curr_connp->message_length && - input_len >= 40) { - rc = TLSDecodeHandshakeHello(ssl_state, input, input_len); - if (rc < 0) - return rc; - } - + rc = TLSDecodeHandshakeHello(ssl_state, input, input_len); + if (rc < 0) + return rc; break; case SSLV3_HS_SERVER_HELLO: ssl_state->current_flags = SSL_AL_FLAG_STATE_SERVER_HELLO; - /* Only parse the message if it is complete */ - if (input_len >= ssl_state->curr_connp->message_length && - input_len >= 40) { - rc = TLSDecodeHandshakeHello(ssl_state, input, - ssl_state->curr_connp->message_length); - if (rc < 0) - return rc; - } - + rc = TLSDecodeHandshakeHello(ssl_state, input, ssl_state->curr_connp->message_length); + if (rc < 0) + return rc; break; case SSLV3_HS_SERVER_KEY_EXCHANGE: @@ -1486,9 +1488,11 @@ static int SSLv3ParseHandshakeType(SSLState *ssl_state, const uint8_t *input, "direction!"); break; } + rc = SSLv3ParseHandshakeTypeCertificate(ssl_state, initial_input, input_len); - return rc; + if (rc < 0) + return rc; break; case SSLV3_HS_HELLO_REQUEST: @@ -1508,29 +1512,10 @@ static int SSLv3ParseHandshakeType(SSLState *ssl_state, const uint8_t *input, ssl_state->flags |= ssl_state->current_flags; - SCLogDebug("message: start %u length %u", ssl_state->curr_connp->message_start, ssl_state->curr_connp->message_length); + SCLogDebug("message: length %u", ssl_state->curr_connp->message_length); SCLogDebug("input_len %u ssl_state->curr_connp->bytes_processed %u", input_len, ssl_state->curr_connp->bytes_processed); - uint32_t write_len = 0; - if (ssl_state->curr_connp->message_start + ssl_state->curr_connp->message_length < - ssl_state->curr_connp->bytes_processed + input_len) { - SCLogDebug("msg done"); - - // Safety check against integer underflow - DEBUG_VALIDATE_BUG_ON( - ssl_state->curr_connp->message_start + ssl_state->curr_connp->message_length < - ssl_state->curr_connp->bytes_processed); - write_len = (ssl_state->curr_connp->message_start + ssl_state->curr_connp->message_length) - - ssl_state->curr_connp->bytes_processed; - DEBUG_VALIDATE_BUG_ON(write_len > input_len); - ssl_state->curr_connp->bytes_processed += write_len; - SSLParserHSReset(ssl_state->curr_connp); - SCLogDebug("write_len %u", write_len); - return write_len; - } else { - ssl_state->curr_connp->bytes_processed += input_len; - return input_len; - } + return input_len; } static int SSLv3ParseHandshakeProtocol(SSLState *ssl_state, const uint8_t *input, @@ -1540,74 +1525,161 @@ static int SSLv3ParseHandshakeProtocol(SSLState *ssl_state, const uint8_t *input if (input_len == 0 || ssl_state->curr_connp->bytes_processed == (ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN)) { - return 0; + SCReturnInt(0); } while (input_len) { - SCLogDebug("bytes_processed %u", ssl_state->curr_connp->bytes_processed); - SCLogDebug("ssl_state->curr_connp->hs_bytes_processed %u input %p input_len %u", - ssl_state->curr_connp->hs_bytes_processed, input, input_len); + SCLogDebug("input_len %u", input_len); + + if (ssl_state->curr_connp->hs_buffer != NULL) { + SCLogDebug("partial handshake record in place"); + const uint32_t need = ssl_state->curr_connp->hs_buffer_message_size - + ssl_state->curr_connp->hs_buffer_offset; + const uint32_t add = MIN(need, input_len); + + /* grow buffer to next multiple of 4k that fits all data we have */ + if (ssl_state->curr_connp->hs_buffer_offset + add > + ssl_state->curr_connp->hs_buffer_size) { + const uint32_t avail = ssl_state->curr_connp->hs_buffer_offset + add; + const uint32_t new_size = avail + (4096 - (avail % 4096)); + SCLogDebug("new_size %u, avail %u", new_size, avail); + void *ptr = SCRealloc(ssl_state->curr_connp->hs_buffer, new_size); + if (ptr == NULL) + return -1; + ssl_state->curr_connp->hs_buffer = ptr; + ssl_state->curr_connp->hs_buffer_size = new_size; + } - switch (ssl_state->curr_connp->hs_bytes_processed) { - case 0: - ssl_state->curr_connp->handshake_type = *(input++); - SCLogDebug("handshake_type %u", ssl_state->curr_connp->handshake_type); - 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)) { - return (input - initial_input); - } + SCLogDebug("ssl_state->curr_connp->hs_buffer_offset %u " + "ssl_state->curr_connp->hs_buffer_size %u", + ssl_state->curr_connp->hs_buffer_offset, ssl_state->curr_connp->hs_buffer_size); + SCLogDebug("to add %u total %u", add, ssl_state->curr_connp->hs_buffer_offset + add); - /* 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)) { - return (input - initial_input); - } + if (SafeMemcpy(ssl_state->curr_connp->hs_buffer, + ssl_state->curr_connp->hs_buffer_offset, + ssl_state->curr_connp->hs_buffer_size, input, 0, add, add) != 0) { + SCLogDebug("copy failed"); + return -1; + } + ssl_state->curr_connp->hs_buffer_offset += add; - /* 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)) { - return (input - initial_input); + if (ssl_state->curr_connp->hs_buffer_message_size <= + ssl_state->curr_connp->hs_buffer_offset + input_len) { + + ssl_state->curr_connp->handshake_type = + ssl_state->curr_connp->hs_buffer_message_type; + ssl_state->curr_connp->message_length = + ssl_state->curr_connp->hs_buffer_message_size; + + SCLogDebug("got all data now: handshake_type %u message_length %u", + ssl_state->curr_connp->handshake_type, + ssl_state->curr_connp->message_length); + + int retval = SSLv3ParseHandshakeType(ssl_state, ssl_state->curr_connp->hs_buffer, + ssl_state->curr_connp->hs_buffer_offset, direction); + if (retval < 0) { + SSLParserHSReset(ssl_state->curr_connp); + return (retval); } + SCLogDebug("retval %d", retval); + + /* data processed, reset buffer */ + SCFree(ssl_state->curr_connp->hs_buffer); + ssl_state->curr_connp->hs_buffer = NULL; + ssl_state->curr_connp->hs_buffer_size = 0; + ssl_state->curr_connp->hs_buffer_message_size = 0; + ssl_state->curr_connp->hs_buffer_message_type = 0; + ssl_state->curr_connp->hs_buffer_offset = 0; + } else { + SCLogDebug("partial data"); + } - /* fall through */ - case 3: - ssl_state->curr_connp->message_length |= *(input++); - SCLogDebug("message len %u", ssl_state->curr_connp->message_length); - ssl_state->curr_connp->bytes_processed++; - ssl_state->curr_connp->hs_bytes_processed++; - --input_len; - ssl_state->curr_connp->message_start = ssl_state->curr_connp->bytes_processed; + input += add; + input_len -= add; + SCLogDebug("input_len %u", input_len); + SSLParserHSReset(ssl_state->curr_connp); + continue; + } - /* fall through */ + SCLogDebug("bytes_processed %u", ssl_state->curr_connp->bytes_processed); + SCLogDebug("input %p input_len %u", input, input_len); + + if (input_len < 4) { + SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_SSL_RECORD); + SCReturnInt(-1); } - SCLogDebug("message len %u input %p input_len %u", ssl_state->curr_connp->message_length, - input, input_len); - int retval = SSLv3ParseHandshakeType(ssl_state, input, input_len, direction); - if (retval < 0 || retval > (int)input_len) { - DEBUG_VALIDATE_BUG_ON(retval > (int)input_len); - return (retval); + ssl_state->curr_connp->handshake_type = input[0]; + ssl_state->curr_connp->message_length = input[1] << 16 | input[2] << 8 | input[3]; + SCLogDebug("handshake_type %u message len %u input %p input_len %u", + ssl_state->curr_connp->handshake_type, ssl_state->curr_connp->message_length, input, + input_len); + input += 4; + input_len -= 4; + + const uint32_t record_len = ssl_state->curr_connp->message_length; + /* see if we support this type. We check here to not use the fragment + * handling on things we don't support. */ + const bool supported_type = SupportedHandshakeType(ssl_state->curr_connp->handshake_type); + SCLogDebug("supported_type %s handshake_type %u/%02x", supported_type ? "true" : "false", + ssl_state->curr_connp->handshake_type, ssl_state->curr_connp->handshake_type); + if (!supported_type) { + uint32_t avail_record_len = MIN(input_len, record_len); + input += avail_record_len; + input_len -= avail_record_len; + + SSLParserHSReset(ssl_state->curr_connp); + SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_HANDSHAKE_MESSAGE); + SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_SSL_RECORD); + continue; } - SCLogDebug("retval %d input_len %u", retval, input_len); - input += retval; - input_len -= retval; - SSLParserHSReset(ssl_state->curr_connp); - } + /* if the message lenght exceeds our input_len, we have a tls fragment. */ + if (record_len > input_len) { + const uint32_t avail = input_len; + const uint32_t size = avail + (4096 - (avail % 4096)); + SCLogDebug("initial buffer size %u, based on input %u", size, avail); + ssl_state->curr_connp->hs_buffer = SCCalloc(1, size); + if (ssl_state->curr_connp->hs_buffer == NULL) { + return -1; + } + ssl_state->curr_connp->hs_buffer_size = size; + ssl_state->curr_connp->hs_buffer_message_size = record_len; + ssl_state->curr_connp->hs_buffer_message_type = ssl_state->curr_connp->handshake_type; + + if (input_len > 0) { + if (SafeMemcpy(ssl_state->curr_connp->hs_buffer, 0, + ssl_state->curr_connp->hs_buffer_size, input, 0, input_len, + input_len) != 0) { + return -1; + } + ssl_state->curr_connp->hs_buffer_offset = input_len; + } + SCLogDebug("opened record buffer %p size %u offset %u type %u msg_size %u", + ssl_state->curr_connp->hs_buffer, ssl_state->curr_connp->hs_buffer_size, + ssl_state->curr_connp->hs_buffer_offset, + ssl_state->curr_connp->hs_buffer_message_type, + ssl_state->curr_connp->hs_buffer_message_size); + input += input_len; + SSLParserHSReset(ssl_state->curr_connp); + return (input - initial_input); + + } else { + /* full record, parse it now */ + int retval = SSLv3ParseHandshakeType( + ssl_state, input, ssl_state->curr_connp->message_length, direction); + if (retval < 0 || retval > (int)input_len) { + DEBUG_VALIDATE_BUG_ON(retval > (int)input_len); + return (retval); + } + SCLogDebug("retval %d input_len %u", retval, input_len); + input += retval; + input_len -= retval; + SSLParserHSReset(ssl_state->curr_connp); + } + SCLogDebug("input_len left %u", input_len); + } return (input - initial_input); } @@ -1934,9 +2006,6 @@ static struct SSLDecoderResult SSLv2Decode(uint8_t direction, SSLState *ssl_stat SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_SSLV2_HEADER); return SSL_DECODER_ERROR(-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, @@ -2119,7 +2188,7 @@ static struct SSLDecoderResult SSLv3Decode(uint8_t direction, SSLState *ssl_stat 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; + 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)", record_len, input_len, parsed, ssl_state->curr_connp->record_length); @@ -2132,6 +2201,7 @@ static struct SSLDecoderResult SSLv3Decode(uint8_t direction, SSLState *ssl_stat SCLogDebug("record length %u processed %u got %u", ssl_state->curr_connp->record_length, ssl_state->curr_connp->bytes_processed, record_len); + /* if we don't have the full record, we return incomplete */ if (ssl_state->curr_connp->record_length > input_len - parsed) { /* no need to use incomplete api buffering for application * records that we'll not use anyway. */ @@ -2159,7 +2229,6 @@ static struct SSLDecoderResult SSLv3Decode(uint8_t direction, SSLState *ssl_stat ssl_state->curr_connp->record_length, direction, TLS_FRAME_DATA); switch (ssl_state->curr_connp->content_type) { - /* we don't need any data from these types */ case SSLV3_CHANGE_CIPHER_SPEC: ssl_state->flags |= SSL_AL_FLAG_CHANGE_CIPHER_SPEC; @@ -2169,7 +2238,6 @@ static struct SSLDecoderResult SSLv3Decode(uint8_t direction, SSLState *ssl_stat } else { ssl_state->flags |= SSL_AL_FLAG_CLIENT_CHANGE_CIPHER_SPEC; } - break; case SSLV3_ALERT_PROTOCOL: @@ -2207,7 +2275,6 @@ static struct SSLDecoderResult SSLv3Decode(uint8_t direction, SSLState *ssl_stat AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_BYPASS_READY); } - break; case SSLV3_HANDSHAKE_PROTOCOL: { @@ -2221,7 +2288,6 @@ static struct SSLDecoderResult SSLv3Decode(uint8_t direction, SSLState *ssl_stat /* do nothing */ } else { // if we started parsing this, we must stop - ssl_state->curr_connp->hs_bytes_processed = 0; break; } } @@ -2235,6 +2301,7 @@ static struct SSLDecoderResult SSLv3Decode(uint8_t direction, SSLState *ssl_stat int retval = SSLv3ParseHandshakeProtocol(ssl_state, input + parsed, record_len, direction); + SCLogDebug("retval %d", retval); if (retval < 0 || retval > (int)record_len) { DEBUG_VALIDATE_BUG_ON(retval > (int)record_len); SSLSetEvent(ssl_state, @@ -2244,27 +2311,8 @@ static struct SSLDecoderResult SSLv3Decode(uint8_t direction, SSLState *ssl_stat SCLogDebug("SSLv3ParseHandshakeProtocol returned %d", retval); return SSL_DECODER_ERROR(-1); } - SCLogDebug("retval %d", retval); - - parsed += retval; - record_len -= retval; - (void)record_len; /* for scan-build */ - - SCLogDebug("bytes_processed %u (record+hdr %u)", ssl_state->curr_connp->bytes_processed, - (ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN)); ValidateRecordState(ssl_state->curr_connp); - - if (ssl_state->curr_connp->bytes_processed >= - ssl_state->curr_connp->record_length + - SSLV3_RECORD_HDR_LEN) { - SCLogDebug("record ready"); - SSLParserReset(ssl_state); - } - - SCLogDebug("trigger RAW! (post HS)"); - AppLayerParserTriggerRawStreamReassembly(ssl_state->f, - direction == 0 ? STREAM_TOSERVER : STREAM_TOCLIENT); - return SSL_DECODER_OK(parsed); + break; } case SSLV3_HEARTBEAT_PROTOCOL: { AppLayerFrameNewByPointer(ssl_state->f, &stream_slice, input + parsed, @@ -2285,35 +2333,21 @@ static struct SSLDecoderResult SSLv3Decode(uint8_t direction, SSLState *ssl_stat return SSL_DECODER_ERROR(-1); } - if (HaveEntireRecord(ssl_state->curr_connp, record_len)) { - DEBUG_VALIDATE_BUG_ON(((ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN) < - ssl_state->curr_connp->bytes_processed)); - - if ((ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN) < - ssl_state->curr_connp->bytes_processed) { - /* defensive checks. Something is wrong. */ - SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_SSL_RECORD); - SCLogDebug("defensive checks. Something is wrong."); - return SSL_DECODER_ERROR(-1); - } + parsed += record_len; + ssl_state->curr_connp->bytes_processed += record_len; + if (ssl_state->curr_connp->bytes_processed >= + ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN) { SCLogDebug("record complete, trigger RAW"); - AppLayerParserTriggerRawStreamReassembly(ssl_state->f, - direction == 0 ? STREAM_TOSERVER : STREAM_TOCLIENT); - - /* 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; - parsed += diff; + AppLayerParserTriggerRawStreamReassembly( + ssl_state->f, direction == 0 ? STREAM_TOSERVER : STREAM_TOCLIENT); SSLParserReset(ssl_state); ValidateRecordState(ssl_state->curr_connp); return SSL_DECODER_OK(parsed); + } else { /* we still don't have the entire record for the one we are currently parsing */ - } else { - parsed += record_len; - ssl_state->curr_connp->bytes_processed += record_len; ValidateRecordState(ssl_state->curr_connp); return SSL_DECODER_OK(parsed); } @@ -2393,8 +2427,8 @@ static AppLayerResult SSLDecode(Flow *f, uint8_t direction, void *alstate, SCLogDebug("SSL/TLS version reset"); } } - SCLogDebug("record %u: bytes_processed %u, version %02X", counter, - ssl_state->curr_connp->bytes_processed, ssl_state->curr_connp->version); + SCLogDebug("record %u: bytes_processed %u, version %02X, input_len %u", counter, + ssl_state->curr_connp->bytes_processed, ssl_state->curr_connp->version, input_len); if (ssl_state->curr_connp->version == SSL_VERSION_2) { if (ssl_state->curr_connp->bytes_processed == 0) { @@ -2526,6 +2560,8 @@ static void SSLStateFree(void *p) SCFree(ssl_state->client_connp.sni); if (ssl_state->client_connp.session_id) SCFree(ssl_state->client_connp.session_id); + if (ssl_state->client_connp.hs_buffer) + SCFree(ssl_state->client_connp.hs_buffer); if (ssl_state->server_connp.cert0_subject) rs_cstring_free(ssl_state->server_connp.cert0_subject); @@ -2548,6 +2584,8 @@ static void SSLStateFree(void *p) Ja3BufferFree(&ssl_state->server_connp.ja3_str); if (ssl_state->server_connp.ja3_hash) SCFree(ssl_state->server_connp.ja3_hash); + if (ssl_state->server_connp.hs_buffer) + SCFree(ssl_state->server_connp.hs_buffer); AppLayerDecoderEventsFreeEvents(&ssl_state->tx_data.events); @@ -5096,7 +5134,6 @@ static int SSLParserTest25(void) FAIL_IF_NULL(ssl_state); FAIL_IF(ssl_state->client_connp.bytes_processed != 0); - FAIL_IF(ssl_state->client_connp.hs_bytes_processed != 0); r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_TLS, STREAM_TOCLIENT, server_hello_certificate_done, @@ -5104,7 +5141,6 @@ static int SSLParserTest25(void) FAIL_IF(r != 0); FAIL_IF(ssl_state->client_connp.bytes_processed != 0); - FAIL_IF(ssl_state->client_connp.hs_bytes_processed != 0); r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, client_key_exchange_cipher_enc_hs, diff --git a/src/app-layer-ssl.h b/src/app-layer-ssl.h index 2ef6944dac..70ecc24aed 100644 --- a/src/app-layer-ssl.h +++ b/src/app-layer-ssl.h @@ -199,7 +199,6 @@ typedef struct SSLStateConnp_ { uint32_t record_lengths_length; /* offset of the beginning of the current message (including header) */ - uint32_t message_start; uint32_t message_length; uint16_t version; @@ -210,8 +209,6 @@ typedef struct SSLStateConnp_ { /* the no of bytes processed in the currently parsed record */ uint32_t bytes_processed; - /* the no of bytes processed in the currently parsed handshake */ - uint16_t hs_bytes_processed; uint16_t session_id_length; @@ -235,6 +232,13 @@ typedef struct SSLStateConnp_ { JA3Buffer *ja3_str; char *ja3_hash; + /* handshake tls fragmentation buffer. Handshake messages can be fragmented over multiple + * TLS records. */ + uint8_t *hs_buffer; + uint8_t hs_buffer_message_type; + uint32_t hs_buffer_message_size; + uint32_t hs_buffer_size; /**< allocation size */ + uint32_t hs_buffer_offset; /**< write offset */ } SSLStateConnp; /**