diff --git a/library/ssl_msg.c b/library/ssl_msg.c index 681e431e6..5aa098ec5 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -3156,7 +3156,7 @@ int mbedtls_ssl_check_dtls_clihlo_cookie( const unsigned char *in, size_t in_len, unsigned char *obuf, size_t buf_len, size_t *olen ) { - size_t sid_len, cookie_len; + size_t sid_len, cookie_len, epoch, fragment_offset; unsigned char *p; /* @@ -3193,15 +3193,17 @@ int mbedtls_ssl_check_dtls_clihlo_cookie( MBEDTLS_SSL_DEBUG_MSG( 4, ( "check cookie: record too short" ) ); return( MBEDTLS_ERR_SSL_DECODE_ERROR ); } - if( in[0] != MBEDTLS_SSL_MSG_HANDSHAKE || - in[3] != 0 || in[4] != 0 || - in[19] != 0 || in[20] != 0 || in[21] != 0 ) + + epoch = MBEDTLS_GET_UINT16_BE( in, 3 ); + fragment_offset = MBEDTLS_GET_UINT24_BE( in, 19 ); + + if( in[0] != MBEDTLS_SSL_MSG_HANDSHAKE || epoch != 0 || + fragment_offset != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 4, ( "check cookie: not a good ClientHello" ) ); MBEDTLS_SSL_DEBUG_MSG( 4, ( " type=%u epoch=%u fragment_offset=%u", - in[0], - (unsigned) in[3] << 8 | in[4], - (unsigned) in[19] << 16 | in[20] << 8 | in[21] ) ); + in[0], (unsigned) epoch, + (unsigned) fragment_offset ) ); return( MBEDTLS_ERR_SSL_DECODE_ERROR ); } diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c index 4e0756988..7f8047beb 100644 --- a/library/ssl_tls12_server.c +++ b/library/ssl_tls12_server.c @@ -1278,24 +1278,29 @@ read_record_header: MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } - - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, handshake len.: %d", - ( buf[1] << 16 ) | ( buf[2] << 8 ) | buf[3] ) ); - - if( buf[1] != 0 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message: %u != 0", - (unsigned) buf[1] ) ); - return( MBEDTLS_ERR_SSL_DECODE_ERROR ); - } - /* We don't support fragmentation of ClientHello (yet?) */ - if( msg_len != mbedtls_ssl_hs_hdr_len( ssl ) + ( ( buf[2] << 8 ) | buf[3] ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message: %u != %u + %u", + size_t handshake_len = MBEDTLS_GET_UINT24_BE( buf, 1 ); + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, handshake len.: %d", + ( unsigned ) handshake_len ) ); + + /* The record layer has a record size limit of 2^14 - 1 and + * fragmentation is not supported, so buf[1] should be zero. */ + if( buf[1] != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message: %u != 0", + (unsigned) buf[1] ) ); + return( MBEDTLS_ERR_SSL_DECODE_ERROR ); + } + + /* We don't support fragmentation of ClientHello (yet?) */ + if( msg_len != mbedtls_ssl_hs_hdr_len( ssl ) + handshake_len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message: %u != %u + %u", (unsigned) msg_len, (unsigned) mbedtls_ssl_hs_hdr_len( ssl ), - (unsigned) ( buf[2] << 8 ) | buf[3] ) ); - return( MBEDTLS_ERR_SSL_DECODE_ERROR ); + (unsigned) handshake_len ) ); + return( MBEDTLS_ERR_SSL_DECODE_ERROR ); + } } #if defined(MBEDTLS_SSL_PROTO_DTLS) @@ -1330,21 +1335,24 @@ read_record_header: ssl->handshake->out_msg_seq = cli_msg_seq; ssl->handshake->in_msg_seq = cli_msg_seq + 1; } - - /* - * For now we don't support fragmentation, so make sure - * fragment_offset == 0 and fragment_length == length - */ - MBEDTLS_SSL_DEBUG_MSG( - 4, ( "fragment_offset=%u fragment_length=%u length=%u", - (unsigned) ( ssl->in_msg[6] << 16 | ssl->in_msg[7] << 8 | ssl->in_msg[8] ), - (unsigned) ( ssl->in_msg[9] << 16 | ssl->in_msg[10] << 8 | ssl->in_msg[11] ), - (unsigned) ( ssl->in_msg[1] << 16 | ssl->in_msg[2] << 8 | ssl->in_msg[3] ) ) ); - if( ssl->in_msg[6] != 0 || ssl->in_msg[7] != 0 || ssl->in_msg[8] != 0 || - memcmp( ssl->in_msg + 1, ssl->in_msg + 9, 3 ) != 0 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "ClientHello fragmentation not supported" ) ); - return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); + /* + * For now we don't support fragmentation, so make sure + * fragment_offset == 0 and fragment_length == length + */ + size_t fragment_offset, fragment_length, length; + fragment_offset = MBEDTLS_GET_UINT24_BE( ssl->in_msg, 6 ); + fragment_length = MBEDTLS_GET_UINT24_BE( ssl->in_msg, 9 ); + length = MBEDTLS_GET_UINT24_BE( ssl->in_msg, 1 ); + MBEDTLS_SSL_DEBUG_MSG( + 4, ( "fragment_offset=%u fragment_length=%u length=%u", + (unsigned) fragment_offset, (unsigned) fragment_length, + (unsigned) length ) ); + if( fragment_offset != 0 || length != fragment_length ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "ClientHello fragmentation not supported" ) ); + return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); + } } } #endif /* MBEDTLS_SSL_PROTO_DTLS */