Fix mbedtls_ssl_read
Don't fetch a new record in mbedtls_ssl_read_record_layer as long as
an application data record is being processed.
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index c12543f..5f5beec 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -1195,6 +1195,8 @@
}
SSL_DEBUG_MSG( 1, ( "non-handshake message during renego" ) );
+
+ ssl->keep_current_message = 1;
return( POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO );
}
#endif /* POLARSSL_SSL_RENEGOTIATION */
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 08b0470..8d49be4 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -2178,47 +2178,67 @@
return( 0 );
}
- if( ssl->in_hslen != 0 &&
- ssl->in_hslen < ssl->in_msglen )
+ if( ssl->in_hslen != 0 )
{
/*
* Get next Handshake message in the current record
*/
- ssl->in_msglen -= ssl->in_hslen;
- memmove( ssl->in_msg, ssl->in_msg + ssl->in_hslen,
- ssl->in_msglen );
-
- ssl->in_hslen = 4;
- ssl->in_hslen += ( ssl->in_msg[2] << 8 ) | ssl->in_msg[3];
-
- SSL_DEBUG_MSG( 3, ( "handshake message: msglen ="
- " %d, type = %d, hslen = %d",
- ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen ) );
-
- if( ssl->in_msglen < 4 || ssl->in_msg[1] != 0 )
+ if( ssl->in_hslen < ssl->in_msglen )
{
- SSL_DEBUG_MSG( 1, ( "bad handshake length" ) );
- return( POLARSSL_ERR_SSL_INVALID_RECORD );
+ ssl->in_msglen -= ssl->in_hslen;
+ memmove( ssl->in_msg, ssl->in_msg + ssl->in_hslen,
+ ssl->in_msglen );
+
+ ssl->in_hslen = 4;
+ ssl->in_hslen += ( ssl->in_msg[2] << 8 ) | ssl->in_msg[3];
+
+ SSL_DEBUG_MSG( 3, ( "handshake message: msglen ="
+ " %d, type = %d, hslen = %d",
+ ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen ) );
+
+ if( ssl->in_msglen < 4 || ssl->in_msg[1] != 0 )
+ {
+ SSL_DEBUG_MSG( 1, ( "bad handshake length" ) );
+ return( POLARSSL_ERR_SSL_INVALID_RECORD );
+ }
+
+ if( ssl->in_msglen < ssl->in_hslen )
+ {
+ SSL_DEBUG_MSG( 1, ( "bad handshake length" ) );
+ return( POLARSSL_ERR_SSL_INVALID_RECORD );
+ }
+
+ if( ssl->state != SSL_HANDSHAKE_OVER )
+ ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen );
+
+ return( 0 );
}
- if( ssl->in_msglen < ssl->in_hslen )
- {
- SSL_DEBUG_MSG( 1, ( "bad handshake length" ) );
- return( POLARSSL_ERR_SSL_INVALID_RECORD );
- }
+ ssl->in_msglen = 0;
+ ssl->in_hslen = 0;
+ }
+ else if( ssl->in_offt != NULL )
+ {
+ return( 0 );
+ }
+ else
+ {
+ ssl->in_msglen = 0;
+ }
- if( ssl->state != SSL_HANDSHAKE_OVER )
- ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen );
+ /*
+ * Fetch and decode new record if current one is fully consumed.
+ */
+ if( ssl->in_msglen > 0 )
+ {
+ /* There's something left to be processed in the current record. */
return( 0 );
}
- ssl->in_hslen = 0;
+ /* Need to fetch a new record */
- /*
- * Read the record header and validate it
- */
read_record_header:
if( ( ret = ssl_fetch_input( ssl, 5 ) ) != 0 )
{
@@ -4651,13 +4671,15 @@
*/
int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len )
{
- int ret, record_read = 0;
+ int ret;
size_t n;
SSL_DEBUG_MSG( 2, ( "=> read" ) );
#if defined(POLARSSL_SSL_RENEGOTIATION)
- if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 )
+ ret = ssl_check_ctr_renegotiate( ssl );
+ if( ret != POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
+ ret != 0 )
{
SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
return( ret );
@@ -4667,11 +4689,8 @@
if( ssl->state != SSL_HANDSHAKE_OVER )
{
ret = ssl_handshake( ssl );
- if( ret == POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO )
- {
- record_read = 1;
- }
- else if( ret != 0 )
+ if( ret != POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
+ ret != 0 )
{
SSL_DEBUG_RET( 1, "ssl_handshake", ret );
return( ret );
@@ -4680,16 +4699,13 @@
if( ssl->in_offt == NULL )
{
- if( ! record_read )
+ if( ( ret = ssl_read_record( ssl ) ) != 0 )
{
- if( ( ret = ssl_read_record( ssl ) ) != 0 )
- {
- if( ret == POLARSSL_ERR_SSL_CONN_EOF )
- return( 0 );
+ if( ret == POLARSSL_ERR_SSL_CONN_EOF )
+ return( 0 );
- SSL_DEBUG_RET( 1, "ssl_read_record", ret );
- return( ret );
- }
+ SSL_DEBUG_RET( 1, "ssl_read_record", ret );
+ return( ret );
}
if( ssl->in_msglen == 0 &&
@@ -4763,21 +4779,15 @@
else
{
ret = ssl_start_renegotiation( ssl );
- if( ret == POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO )
- {
- record_read = 1;
- }
- else if( ret != 0 )
+ if( ret != POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
+ ret != 0 )
{
SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret );
return( ret );
}
}
- /* If a non-handshake record was read during renego, fallthrough,
- * else tell the user they should call ssl_read() again */
- if( ! record_read )
- return( POLARSSL_ERR_NET_WANT_READ );
+ return( POLARSSL_ERR_NET_WANT_READ );
}
else if( ssl->renegotiation == SSL_RENEGOTIATION_PENDING )
{