Implement record checking API

This commit implements the record checking API

   mbedtls_ssl_check_record()

on top of the restructured incoming record stack.

Specifically, it makes use of the fact that the core processing routines

  ssl_parse_record_header()
  mbedtls_ssl_decrypt_buf()

now operate on instances of the SSL record structure mbedtls_record
instead of the previous mbedtls_ssl_context::in_xxx fields.
This commit is contained in:
Hanno Becker 2019-07-12 14:40:00 +01:00 committed by Manuel Pégourié-Gonnard
parent 21fc61c7a7
commit 03e2db6f35

View File

@ -123,14 +123,69 @@ static void ssl_update_out_pointers( mbedtls_ssl_context *ssl,
static void ssl_update_in_pointers( mbedtls_ssl_context *ssl );
#if defined(MBEDTLS_SSL_RECORD_CHECKING)
static int ssl_parse_record_header( mbedtls_ssl_context const *ssl,
unsigned char *buf,
size_t len,
mbedtls_record *rec );
int mbedtls_ssl_check_record( mbedtls_ssl_context const *ssl,
unsigned char *buf,
size_t buflen )
{
((void) ssl);
((void) buf);
((void) buflen);
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
int ret = 0;
mbedtls_record rec;
MBEDTLS_SSL_DEBUG_MSG( 1, ( "=> mbedtls_ssl_check_record" ) );
MBEDTLS_SSL_DEBUG_BUF( 3, "record buffer", buf, buflen );
/* We don't support record checking in TLS because
* (a) there doesn't seem to be a usecase for it, and
* (b) In SSLv3 and TLS 1.0, CBC record decryption has state
* and we'd need to backup the transform here.
*/
#if defined(MBEDTLS_SSL_PROTO_TLS)
if( MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport ) )
{
ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
goto exit;
}
MBEDTLS_SSL_TRANSPORT_ELSE
#endif /* MBEDTLS_SSL_PROTO_TLS */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
{
ret = ssl_parse_record_header( ssl, buf, buflen, &rec );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 3, "ssl_parse_record_header", ret );
goto exit;
}
if( ssl->transform_in != NULL )
{
ret = mbedtls_ssl_decrypt_buf( ssl, ssl->transform_in, &rec );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 3, "mbedtls_ssl_decrypt_buf", ret );
goto exit;
}
}
}
#endif /* MBEDTLS_SSL_PROTO_DTLS */
exit:
/* On success, we have decrypted the buffer in-place, so make
* sure we don't leak any plaintext data. */
mbedtls_platform_zeroize( buf, buflen );
/* For the purpose of this API, treat messages with unexpected CID
* as well as such from future epochs as unexpected. */
if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID ||
ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE )
{
ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
}
MBEDTLS_SSL_DEBUG_MSG( 1, ( "<= mbedtls_ssl_check_record" ) );
return( ret );
}
#endif /* MBEDTLS_SSL_RECORD_CHECKING */
@ -4826,7 +4881,8 @@ static int ssl_parse_record_header( mbedtls_ssl_context const *ssl,
{
if( ssl_check_record_type( rec->type ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type" ) );
MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type %u",
(unsigned) rec->type ) );
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
}
}