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.
This commit is contained in:
Hanno Becker 2017-06-08 15:56:50 +01:00
parent 10699cc96c
commit d37839e3fa
2 changed files with 63 additions and 51 deletions

View File

@ -1195,6 +1195,8 @@ static int ssl_parse_server_hello( ssl_context *ssl )
}
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 */

View File

@ -2178,14 +2178,15 @@ int ssl_read_record( ssl_context *ssl )
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;
if( ssl->in_hslen < ssl->in_msglen )
{
ssl->in_msglen -= ssl->in_hslen;
memmove( ssl->in_msg, ssl->in_msg + ssl->in_hslen,
ssl->in_msglen );
@ -2214,11 +2215,30 @@ int ssl_read_record( ssl_context *ssl )
return( 0 );
}
ssl->in_msglen = 0;
ssl->in_hslen = 0;
}
else if( ssl->in_offt != NULL )
{
return( 0 );
}
else
{
ssl->in_msglen = 0;
}
/*
* Read the record header and validate it
* 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 );
}
/* Need to fetch a new record */
read_record_header:
if( ( ret = ssl_fetch_input( ssl, 5 ) ) != 0 )
{
@ -4651,13 +4671,15 @@ static int ssl_check_ctr_renegotiate( ssl_context *ssl )
*/
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 @@ int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len )
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 );
@ -4679,8 +4698,6 @@ int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len )
}
if( ssl->in_offt == NULL )
{
if( ! record_read )
{
if( ( ret = ssl_read_record( ssl ) ) != 0 )
{
@ -4690,7 +4707,6 @@ int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len )
SSL_DEBUG_RET( 1, "ssl_read_record", ret );
return( ret );
}
}
if( ssl->in_msglen == 0 &&
ssl->in_msgtype == SSL_MSG_APPLICATION_DATA )
@ -4763,20 +4779,14 @@ int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len )
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 );
}
else if( ssl->renegotiation == SSL_RENEGOTIATION_PENDING )