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
parent 331de3df9a
commit 5422981052

View file

@ -113,14 +113,67 @@ static void ssl_update_out_pointers( mbedtls_ssl_context *ssl,
static void ssl_update_in_pointers( mbedtls_ssl_context *ssl ); static void ssl_update_in_pointers( mbedtls_ssl_context *ssl );
#if defined(MBEDTLS_SSL_RECORD_CHECKING) #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, int mbedtls_ssl_check_record( mbedtls_ssl_context const *ssl,
unsigned char *buf, unsigned char *buf,
size_t buflen ) size_t buflen )
{ {
((void) ssl); int ret = 0;
((void) buf); mbedtls_record rec;
((void) buflen); MBEDTLS_SSL_DEBUG_MSG( 1, ( "=> mbedtls_ssl_check_record" ) );
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); 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( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM )
{
ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
goto exit;
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
else
{
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 */ #endif /* MBEDTLS_SSL_RECORD_CHECKING */
@ -4993,7 +5046,8 @@ static int ssl_parse_record_header( mbedtls_ssl_context const *ssl,
{ {
if( ssl_check_record_type( rec->type ) ) 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 ); return( MBEDTLS_ERR_SSL_INVALID_RECORD );
} }
} }