Fix mbedtls_ssl_check_record usage with ext buf

Record checking fails if mbedtls_ssl_check_record() is called with
external buffer. Received record sequence number is available in the
incoming record but it is not available in the ssl contexts `in_ctr`-
variable that is used when decoding the sequence number.

To fix the problem, temporarily update ssl context `in_ctr` to
point to the received record header and restore value later.
This commit is contained in:
Arto Kinnunen 2019-10-29 11:13:33 +02:00
parent e2bf54d3d1
commit 8a8488c1cf

View File

@ -4918,6 +4918,25 @@ static inline uint64_t ssl_load_six_bytes( unsigned char *buf )
( (uint64_t) buf[5] ) ); ( (uint64_t) buf[5] ) );
} }
static int mbedtls_ssl_dtls_record_replay_check( mbedtls_ssl_context *ssl, uint8_t *record_in_ctr )
{
int ret;
unsigned char *original_in_ctr;
// save original in_ctr
original_in_ctr = ssl->in_ctr;
// use counter from record
ssl->in_ctr = record_in_ctr;
ret = mbedtls_ssl_dtls_replay_check( (mbedtls_ssl_context const *) ssl );
// restore the counter
ssl->in_ctr = original_in_ctr;
return ret;
}
/* /*
* Return 0 if sequence number is acceptable, -1 otherwise * Return 0 if sequence number is acceptable, -1 otherwise
*/ */
@ -5433,7 +5452,8 @@ static int ssl_parse_record_header( mbedtls_ssl_context const *ssl,
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
/* For records from the correct epoch, check whether their /* For records from the correct epoch, check whether their
* sequence number has been seen before. */ * sequence number has been seen before. */
else if( mbedtls_ssl_dtls_replay_check( ssl ) != 0 ) else if( mbedtls_ssl_dtls_record_replay_check( (mbedtls_ssl_context *) ssl,
&rec->ctr[0] ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record" ) );
return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );