diff --git a/library/ssl_misc.h b/library/ssl_misc.h index 9ed5dfa207..6735000e63 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -1231,10 +1231,11 @@ int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl, int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ); int mbedtls_ssl_write_handshake_msg_ext( mbedtls_ssl_context *ssl, - int update_checksum ); + int update_checksum, + uint8_t force_flush ); static inline int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl ) { - return( mbedtls_ssl_write_handshake_msg_ext( ssl, 1 /* update checksum */ ) ); + return( mbedtls_ssl_write_handshake_msg_ext( ssl, 1 /* update checksum */, 1 /* force flush */ ) ); } int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush ); diff --git a/library/ssl_msg.c b/library/ssl_msg.c index 5f80ed5118..5105625cc0 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -2368,7 +2368,8 @@ void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl ) * - ssl->out_msg: the record contents (handshake headers + content) */ int mbedtls_ssl_write_handshake_msg_ext( mbedtls_ssl_context *ssl, - int update_checksum ) + int update_checksum, + uint8_t force_flush ) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; const size_t hs_len = ssl->out_msglen - 4; @@ -2495,7 +2496,7 @@ int mbedtls_ssl_write_handshake_msg_ext( mbedtls_ssl_context *ssl, else #endif { - if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 ) + if( ( ret = mbedtls_ssl_write_record( ssl, force_flush ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_record", ret ); return( ret ); diff --git a/library/ssl_tls.c b/library/ssl_tls.c index adb18ab6c2..f3e5a0af93 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -2693,6 +2693,21 @@ static int ssl_prepare_handshake_step( mbedtls_ssl_context *ssl ) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + /* + * We may have not been able to send to the peer all the handshake data + * that were written into the output buffer by the previous handshake step: + * the write to the network callback returned with the + * #MBEDTLS_ERR_SSL_WANT_WRITE error code. + * We proceed to the next handshake step only when all data from the + * previous one have been sent to the peer, thus we make sure that this is + * the case here by calling `mbedtls_ssl_flush_output()`. The function may + * return with the #MBEDTLS_ERR_SSL_WANT_WRITE error code in which case + * we have to wait before to go ahead. + * In the case of TLS 1.3, handshake step handlers do not send data to the + * peer. Data are only sent here and through + * `mbedtls_ssl_handle_pending_alert` in case an error that triggered an + * alert occured. + */ if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) return( ret ); diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c index 4fee3b0308..a54207c4f7 100644 --- a/library/ssl_tls13_generic.c +++ b/library/ssl_tls13_generic.c @@ -103,7 +103,7 @@ int mbedtls_ssl_tls13_finish_handshake_msg( mbedtls_ssl_context *ssl, /* Add reserved 4 bytes for handshake header */ msg_with_header_len = msg_len + 4; ssl->out_msglen = msg_with_header_len; - MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_write_handshake_msg_ext( ssl, 0 ) ); + MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_write_handshake_msg_ext( ssl, 0, 0 ) ); cleanup: return( ret ); @@ -1483,7 +1483,6 @@ int mbedtls_ssl_tls13_write_finished_message( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_PROC_CHK( ssl_tls13_finalize_finished_message( ssl ) ); MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_tls13_finish_handshake_msg( ssl, buf_len, msg_len ) ); - MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_flush_output( ssl ) ); cleanup: @@ -1564,8 +1563,6 @@ int mbedtls_ssl_tls13_write_change_cipher_spec( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write change cipher spec" ) ); - MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_flush_output( ssl ) ); - /* Write CCS message */ MBEDTLS_SSL_PROC_CHK( ssl_tls13_write_change_cipher_spec_body( ssl, ssl->out_msg, @@ -1578,7 +1575,7 @@ int mbedtls_ssl_tls13_write_change_cipher_spec( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_PROC_CHK( ssl_tls13_finalize_change_cipher_spec( ssl ) ); /* Dispatch message */ - MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_write_record( ssl, 1 ) ); + MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_write_record( ssl, 0 ) ); cleanup: