@@ -2962,13 +2962,17 @@ static uint32_t ssl_get_hs_total_len(mbedtls_ssl_context const *ssl)
29622962
29632963int mbedtls_ssl_prepare_handshake_record (mbedtls_ssl_context * ssl )
29642964{
2965- if (ssl -> in_msglen < mbedtls_ssl_hs_hdr_len (ssl )) {
2965+ /* First handshake fragment must at least include the header. */
2966+ if (ssl -> in_msglen < mbedtls_ssl_hs_hdr_len (ssl ) && ssl -> in_hslen == 0 ) {
29662967 MBEDTLS_SSL_DEBUG_MSG (1 , ("handshake message too short: %" MBEDTLS_PRINTF_SIZET ,
29672968 ssl -> in_msglen ));
29682969 return MBEDTLS_ERR_SSL_INVALID_RECORD ;
29692970 }
29702971
2971- ssl -> in_hslen = mbedtls_ssl_hs_hdr_len (ssl ) + ssl_get_hs_total_len (ssl );
2972+ if (ssl -> in_hslen == 0 ) {
2973+ ssl -> in_hslen = mbedtls_ssl_hs_hdr_len (ssl ) + ssl_get_hs_total_len (ssl );
2974+ ssl -> in_hsfraglen = 0 ;
2975+ }
29722976
29732977 MBEDTLS_SSL_DEBUG_MSG (3 , ("handshake message: msglen ="
29742978 " %" MBEDTLS_PRINTF_SIZET ", type = %u, hslen = %"
@@ -3034,10 +3038,60 @@ int mbedtls_ssl_prepare_handshake_record(mbedtls_ssl_context *ssl)
30343038 }
30353039 } else
30363040#endif /* MBEDTLS_SSL_PROTO_DTLS */
3037- /* With TLS we don't handle fragmentation (for now) */
3038- if (ssl -> in_msglen < ssl -> in_hslen ) {
3039- MBEDTLS_SSL_DEBUG_MSG (1 , ("TLS handshake fragmentation not supported" ));
3040- return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ;
3041+ if (ssl -> in_hsfraglen <= ssl -> in_hslen ) {
3042+ int ret ;
3043+ const size_t hs_remain = ssl -> in_hslen - ssl -> in_hsfraglen ;
3044+ MBEDTLS_SSL_DEBUG_MSG (3 ,
3045+ ("handshake fragment: %" MBEDTLS_PRINTF_SIZET " .. %"
3046+ MBEDTLS_PRINTF_SIZET " of %"
3047+ MBEDTLS_PRINTF_SIZET " msglen %" MBEDTLS_PRINTF_SIZET ,
3048+ ssl -> in_hsfraglen ,
3049+ ssl -> in_hsfraglen +
3050+ (hs_remain <= ssl -> in_msglen ? hs_remain : ssl -> in_msglen ),
3051+ ssl -> in_hslen , ssl -> in_msglen ));
3052+ if (ssl -> in_msglen < hs_remain ) {
3053+ ssl -> in_hsfraglen += ssl -> in_msglen ;
3054+ ssl -> in_hdr = ssl -> in_msg + ssl -> in_msglen ;
3055+ ssl -> in_msglen = 0 ;
3056+ mbedtls_ssl_update_in_pointers (ssl );
3057+ return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING ;
3058+ }
3059+ if (ssl -> in_hsfraglen > 0 ) {
3060+ /*
3061+ * At in_first_hdr we have a sequence of records that cover the next handshake
3062+ * record, each with its own record header that we need to remove.
3063+ * Note that the reassembled record size may not equal the size of the message,
3064+ * there may be more messages after it, complete or partial.
3065+ */
3066+ unsigned char * in_first_hdr = ssl -> in_buf + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN ;
3067+ unsigned char * p = in_first_hdr , * q = NULL ;
3068+ size_t merged_rec_len = 0 ;
3069+ do {
3070+ mbedtls_record rec ;
3071+ ret = ssl_parse_record_header (ssl , p , mbedtls_ssl_in_hdr_len (ssl ), & rec );
3072+ if (ret != 0 ) {
3073+ return ret ;
3074+ }
3075+ merged_rec_len += rec .data_len ;
3076+ p = rec .buf + rec .buf_len ;
3077+ if (q != NULL ) {
3078+ memmove (q , rec .buf + rec .data_offset , rec .data_len );
3079+ q += rec .data_len ;
3080+ } else {
3081+ q = p ;
3082+ }
3083+ } while (merged_rec_len < ssl -> in_hslen );
3084+ ssl -> in_hdr = in_first_hdr ;
3085+ mbedtls_ssl_update_in_pointers (ssl );
3086+ ssl -> in_msglen = merged_rec_len ;
3087+ /* Adjust message length. */
3088+ MBEDTLS_PUT_UINT16_BE (merged_rec_len , ssl -> in_len , 0 );
3089+ ssl -> in_hsfraglen = 0 ;
3090+ MBEDTLS_SSL_DEBUG_BUF (4 , "reassembled record" ,
3091+ ssl -> in_hdr , mbedtls_ssl_in_hdr_len (ssl ) + merged_rec_len );
3092+ }
3093+ } else {
3094+ return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED ;
30413095 }
30423096
30433097 return 0 ;
@@ -4382,6 +4436,16 @@ static int ssl_consume_current_message(mbedtls_ssl_context *ssl)
43824436 return MBEDTLS_ERR_SSL_INTERNAL_ERROR ;
43834437 }
43844438
4439+ if (ssl -> in_hsfraglen != 0 ) {
4440+ /* Not all handshake fragments have arrived, do not consume. */
4441+ MBEDTLS_SSL_DEBUG_MSG (3 ,
4442+ ("waiting for more fragments (%" MBEDTLS_PRINTF_SIZET " of %"
4443+ MBEDTLS_PRINTF_SIZET ", %" MBEDTLS_PRINTF_SIZET " left)" ,
4444+ ssl -> in_hsfraglen , ssl -> in_hslen ,
4445+ ssl -> in_hslen - ssl -> in_hsfraglen ));
4446+ return 0 ;
4447+ }
4448+
43854449 /*
43864450 * Get next Handshake message in the current record
43874451 */
@@ -4407,6 +4471,7 @@ static int ssl_consume_current_message(mbedtls_ssl_context *ssl)
44074471 ssl -> in_msglen -= ssl -> in_hslen ;
44084472 memmove (ssl -> in_msg , ssl -> in_msg + ssl -> in_hslen ,
44094473 ssl -> in_msglen );
4474+ MBEDTLS_PUT_UINT16_BE (ssl -> in_msglen , ssl -> in_len , 0 );
44104475
44114476 MBEDTLS_SSL_DEBUG_BUF (4 , "remaining content in record" ,
44124477 ssl -> in_msg , ssl -> in_msglen );
@@ -5081,7 +5146,7 @@ void mbedtls_ssl_update_in_pointers(mbedtls_ssl_context *ssl)
50815146 } else
50825147#endif
50835148 {
5084- ssl -> in_ctr = ssl -> in_hdr - MBEDTLS_SSL_SEQUENCE_NUMBER_LEN ;
5149+ ssl -> in_ctr = ssl -> in_buf ;
50855150 ssl -> in_len = ssl -> in_hdr + 3 ;
50865151#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID )
50875152 ssl -> in_cid = ssl -> in_len ;
@@ -5097,24 +5162,35 @@ void mbedtls_ssl_update_in_pointers(mbedtls_ssl_context *ssl)
50975162 * Setup an SSL context
50985163 */
50995164
5100- void mbedtls_ssl_reset_in_out_pointers (mbedtls_ssl_context * ssl )
5165+ void mbedtls_ssl_reset_in_pointers (mbedtls_ssl_context * ssl )
5166+ {
5167+ #if defined(MBEDTLS_SSL_PROTO_DTLS )
5168+ if (ssl -> conf -> transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) {
5169+ ssl -> in_hdr = ssl -> in_buf ;
5170+ } else
5171+ #endif /* MBEDTLS_SSL_PROTO_DTLS */
5172+ {
5173+ ssl -> in_hdr = ssl -> in_buf + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN ;
5174+ }
5175+
5176+ /* Derive other internal pointers. */
5177+ mbedtls_ssl_update_in_pointers (ssl );
5178+ }
5179+
5180+ void mbedtls_ssl_reset_out_pointers (mbedtls_ssl_context * ssl )
51015181{
51025182 /* Set the incoming and outgoing record pointers. */
51035183#if defined(MBEDTLS_SSL_PROTO_DTLS )
51045184 if (ssl -> conf -> transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) {
51055185 ssl -> out_hdr = ssl -> out_buf ;
5106- ssl -> in_hdr = ssl -> in_buf ;
51075186 } else
51085187#endif /* MBEDTLS_SSL_PROTO_DTLS */
51095188 {
51105189 ssl -> out_ctr = ssl -> out_buf ;
5111- ssl -> out_hdr = ssl -> out_buf + 8 ;
5112- ssl -> in_hdr = ssl -> in_buf + 8 ;
5190+ ssl -> out_hdr = ssl -> out_buf + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN ;
51135191 }
5114-
51155192 /* Derive other internal pointers. */
51165193 mbedtls_ssl_update_out_pointers (ssl , NULL /* no transform enabled */ );
5117- mbedtls_ssl_update_in_pointers (ssl );
51185194}
51195195
51205196/*
0 commit comments