From 294331a3158a6c7116be46f7466ceb7c262f46a5 Mon Sep 17 00:00:00 2001 From: Andres Amaya Garcia Date: Tue, 11 Jul 2017 14:39:30 +0100 Subject: [PATCH 1/3] Add ChangeLog entry for mbedtls_ssl_write() docs --- ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index be0026e2b..6764c4c07 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ mbed TLS ChangeLog (Sorted per branch, date) += mbed TLS 2.7.x released xxxx-xx-xx + +Bugfix + * Clarify documentation for mbedtls_ssl_write() to include 0 as a valid + return value. Found by @davidwu2000. #839 + = mbed TLS 2.7.4 branch released 2018-06-18 Bugfix From dbd17b75f33b38e1efb58976df8d3a0558ab532a Mon Sep 17 00:00:00 2001 From: Andres Amaya Garcia Date: Tue, 11 Jul 2017 16:15:54 +0100 Subject: [PATCH 2/3] Allow 0 as a valid ret value for mbedtls_ssl_write This patch modifies the documentation for mbedtls_ssl_write() to allow 0 as a valid return value as this is the correct number of bytes that should be returned when an empty TLS Application record is sent. --- include/mbedtls/ssl.h | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 42e0dcbc6..3937d0262 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -2504,17 +2504,19 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) * or MBEDTLS_ERR_SSL_WANT_WRITE or MBEDTLS_ERR_SSL_WANT_READ, * or another negative error code. * - * \note If this function returns something other than a positive - * value or MBEDTLS_ERR_SSL_WANT_READ/WRITE, the ssl context - * becomes unusable, and you should either free it or call - * \c mbedtls_ssl_session_reset() on it before re-using it for - * a new connection; the current connection must be closed. + * \note If this function returns something other than 0, a positive + * value or MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop + * using the SSL context for reading or writing, and either + * free it or call \c mbedtls_ssl_session_reset() on it before + * re-using it for a new connection; the current connection + * must be closed. * * \note When this function returns MBEDTLS_ERR_SSL_WANT_WRITE/READ, * it must be called later with the *same* arguments, - * until it returns a positive value. When the function returns - * MBEDTLS_ERR_SSL_WANT_WRITE there may be some partial - * data in the output buffer, however this is not yet sent. + * until it returns a value greater that or equal to 0. When + * the function returns MBEDTLS_ERR_SSL_WANT_WRITE there may be + * some partial data in the output buffer, however this is not + * yet sent. * * \note If the requested length is greater than the maximum * fragment length (either the built-in limit or the one set @@ -2523,6 +2525,9 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) * - with DTLS, MBEDTLS_ERR_SSL_BAD_INPUT_DATA is returned. * \c mbedtls_ssl_get_max_frag_len() may be used to query the * active maximum fragment length. + * + * \note Attempting to write 0 bytes will result in an empty TLS + * application record being sent. */ int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ); From 0fc4e0878e47df15f75c97ad5db716d8d704fc68 Mon Sep 17 00:00:00 2001 From: Andres Amaya Garcia Date: Thu, 28 Sep 2017 14:41:17 +0100 Subject: [PATCH 3/3] Document ssl_write_real() behaviour in detail --- library/ssl_tls.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 6d7ad331b..153d745ce 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -7137,8 +7137,16 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) } /* - * Send application data to be encrypted by the SSL layer, - * taking care of max fragment length and buffer size + * Send application data to be encrypted by the SSL layer, taking care of max + * fragment length and buffer size. + * + * According to RFC 5246 Section 6.2.1: + * + * Zero-length fragments of Application data MAY be sent as they are + * potentially useful as a traffic analysis countermeasure. + * + * Therefore, it is possible that the input message length is 0 and the + * corresponding return code is 0 on success. */ static int ssl_write_real( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ) @@ -7166,6 +7174,12 @@ static int ssl_write_real( mbedtls_ssl_context *ssl, if( ssl->out_left != 0 ) { + /* + * The user has previously tried to send the data and + * MBEDTLS_ERR_SSL_WANT_WRITE or the message was only partially + * written. In this case, we expect the high-level write function + * (e.g. mbedtls_ssl_write()) to be called with the same parameters + */ if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret ); @@ -7174,6 +7188,11 @@ static int ssl_write_real( mbedtls_ssl_context *ssl, } else { + /* + * The user is trying to send a message the first time, so we need to + * copy the data into the internal buffers and setup the data structure + * to keep track of partial writes + */ ssl->out_msglen = len; ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA; memcpy( ssl->out_msg, buf, len );