From a562c2630061c2492082710196928c74984b67c6 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 027a97174..ca4c0b1a8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ mbed TLS ChangeLog (Sorted per branch, date) += mbed TLS x.x.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.11.0 branch released 2018-06-18 Features From 7ee25d770d874c59384d31a9d5cf76e423c83e73 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 45135500f..39b7f290a 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -2907,17 +2907,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, 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 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 @@ -2926,6 +2928,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 5b92352374e50856f6faa229e9986a300fe96796 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 e5119fcda..c24a12f97 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -7231,8 +7231,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 ) @@ -7260,6 +7268,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 ); @@ -7268,6 +7282,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 );