From e25e3b7d960a11c2509698be61a0e4319aabf068 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Thu, 16 Aug 2018 09:30:53 +0100 Subject: [PATCH] Add function to check is HS msg is a proper fragment This commit introduces a static function ssl_hs_is_proper_fragment() to check if the current incoming handshake message is a proper fragment. It is used within mbedtls_ssl_prepare_handshake_record() to decide whether handshake reassembly through ssl_reassemble_dtls_handshake() is needed. The commit changes the behavior of the library in the (unnatural) situation where proper fragments for a handshake message are followed by a non-fragmented version of the same message. In this case, the previous code invoked the handshake reassembly routine ssl_reassemble_dtls_handshake(), while with this commit, the full handshake message is directly forwarded to the user, no altering the handshake reassembly state -- in particular, not freeing it. As a remedy, freeing of a potential handshake reassembly structure is now done as part of the handshake update function mbedtls_ssl_update_handshake_status(). --- library/ssl_tls.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index a9f84d497..c2daeb36e 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3409,6 +3409,17 @@ int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush ) } #if defined(MBEDTLS_SSL_PROTO_DTLS) + +static int ssl_hs_is_proper_fragment( mbedtls_ssl_context *ssl ) +{ + if( ssl->in_msglen < ssl->in_hslen || + memcmp( ssl->in_msg + 6, "\0\0\0", 3 ) != 0 || + memcmp( ssl->in_msg + 9, ssl->in_msg + 1, 3 ) != 0 ) + { + return( 1 ); + } + return( 0 ); +} /* * Mark bits in bitmask (used for DTLS HS reassembly) */ @@ -3636,9 +3647,6 @@ static int ssl_reassemble_dtls_handshake( mbedtls_ssl_context *ssl ) memcpy( ssl->in_msg, ssl->handshake->hs_msg, ssl->in_hslen ); - mbedtls_free( ssl->handshake->hs_msg ); - ssl->handshake->hs_msg = NULL; - MBEDTLS_SSL_DEBUG_BUF( 3, "reassembled handshake message", ssl->in_msg, ssl->in_hslen ); @@ -3646,6 +3654,7 @@ static int ssl_reassemble_dtls_handshake( mbedtls_ssl_context *ssl ) } #endif /* MBEDTLS_SSL_PROTO_DTLS */ + int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl ) { if( ssl->in_msglen < mbedtls_ssl_hs_hdr_len( ssl ) ) @@ -3713,12 +3722,7 @@ int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl ) } /* Wait until message completion to increment in_msg_seq */ - /* Reassemble if current message is fragmented or reassembly is - * already in progress */ - if( ssl->in_msglen < ssl->in_hslen || - memcmp( ssl->in_msg + 6, "\0\0\0", 3 ) != 0 || - memcmp( ssl->in_msg + 9, ssl->in_msg + 1, 3 ) != 0 || - ( ssl->handshake != NULL && ssl->handshake->hs_msg != NULL ) ) + if( ssl_hs_is_proper_fragment( ssl ) == 1 ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "found fragmented DTLS handshake message" ) ); @@ -3756,6 +3760,13 @@ void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl ) ssl->handshake != NULL ) { ssl->handshake->in_msg_seq++; + + /* Clear up handshake reassembly structure, if any. */ + if( ssl->handshake->hs_msg != NULL ) + { + mbedtls_free( ssl->handshake->hs_msg ); + ssl->handshake->hs_msg = NULL; + } } #endif }