mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-07-30 22:43:08 +03:00
Merge remote-tracking branch 'origin/development' into development-restricted
* origin/development: (51 commits) Fix possibly-lossy conversion warning from MSVC Reintroduce length 0 check for records Don't use memcpy() for 2-byte copy operation Remove integer parsing macro Fix alignment in record header parsing routine Don't disallow 'record from another epoch' log msg in proxy ref test Make sure 'record from another epoch' is displayed for next epoch Implement record checking API Mark ssl_parse_record_header() as `const` in SSL context Make mbedtls_ssl_in_hdr_len() CID-unaware Remove duplicate setting of ssl->in_msgtype and ssl->in_msglen Move update of in_xxx fields in ssl_get_next_record() Move update of in_xxx fields outside of ssl_prepare_record_content() Reduce dependency of ssl_prepare_record_content() on in_xxx fields Move ssl_update_in_pointers() to after record hdr parsing Mark DTLS replay check as `const` on the SSL context Move updating the internal rec ptrs to outside of rec hdr parsing Mark ssl_decrypt_buf() as `const in the input SSL context Adapt ssl_prepare_record_content() to use SSL record structure Use record length from record structure when fetching content in TLS ...
This commit is contained in:
@ -1242,6 +1242,14 @@ int query_config( const char *config )
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_ALL_ALERT_MESSAGES */
|
||||
|
||||
#if defined(MBEDTLS_SSL_RECORD_CHECKING)
|
||||
if( strcmp( "MBEDTLS_SSL_RECORD_CHECKING", config ) == 0 )
|
||||
{
|
||||
MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_RECORD_CHECKING );
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_RECORD_CHECKING */
|
||||
|
||||
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
|
||||
if( strcmp( "MBEDTLS_SSL_DTLS_CONNECTION_ID", config ) == 0 )
|
||||
{
|
||||
|
@ -617,7 +617,8 @@ exit:
|
||||
* Test recv/send functions that make sure each try returns
|
||||
* WANT_READ/WANT_WRITE at least once before sucesseding
|
||||
*/
|
||||
static int my_recv( void *ctx, unsigned char *buf, size_t len )
|
||||
|
||||
static int delayed_recv( void *ctx, unsigned char *buf, size_t len )
|
||||
{
|
||||
static int first_try = 1;
|
||||
int ret;
|
||||
@ -634,7 +635,7 @@ static int my_recv( void *ctx, unsigned char *buf, size_t len )
|
||||
return( ret );
|
||||
}
|
||||
|
||||
static int my_send( void *ctx, const unsigned char *buf, size_t len )
|
||||
static int delayed_send( void *ctx, const unsigned char *buf, size_t len )
|
||||
{
|
||||
static int first_try = 1;
|
||||
int ret;
|
||||
@ -651,6 +652,137 @@ static int my_send( void *ctx, const unsigned char *buf, size_t len )
|
||||
return( ret );
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
mbedtls_ssl_context *ssl;
|
||||
mbedtls_net_context *net;
|
||||
} io_ctx_t;
|
||||
|
||||
#if defined(MBEDTLS_SSL_RECORD_CHECKING)
|
||||
static int ssl_check_record( mbedtls_ssl_context const *ssl,
|
||||
unsigned char const *buf, size_t len )
|
||||
{
|
||||
int ret;
|
||||
unsigned char *tmp_buf;
|
||||
|
||||
tmp_buf = mbedtls_calloc( 1, len );
|
||||
if( tmp_buf == NULL )
|
||||
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
|
||||
memcpy( tmp_buf, buf, len );
|
||||
|
||||
ret = mbedtls_ssl_check_record( ssl, tmp_buf, len );
|
||||
if( ret != MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE )
|
||||
{
|
||||
int ret_repeated;
|
||||
|
||||
/* Test-only: Make sure that mbedtls_ssl_check_record()
|
||||
* doesn't alter state. */
|
||||
memcpy( tmp_buf, buf, len ); /* Restore buffer */
|
||||
ret_repeated = mbedtls_ssl_check_record( ssl, tmp_buf, len );
|
||||
if( ret != ret_repeated )
|
||||
{
|
||||
mbedtls_printf( "mbedtls_ssl_check_record() returned inconsistent results.\n" );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
switch( ret )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case MBEDTLS_ERR_SSL_INVALID_RECORD:
|
||||
if( opt.debug_level > 1 )
|
||||
mbedtls_printf( "mbedtls_ssl_check_record() detected invalid record.\n" );
|
||||
break;
|
||||
|
||||
case MBEDTLS_ERR_SSL_INVALID_MAC:
|
||||
if( opt.debug_level > 1 )
|
||||
mbedtls_printf( "mbedtls_ssl_check_record() detected unauthentic record.\n" );
|
||||
break;
|
||||
|
||||
case MBEDTLS_ERR_SSL_UNEXPECTED_RECORD:
|
||||
if( opt.debug_level > 1 )
|
||||
mbedtls_printf( "mbedtls_ssl_check_record() detected unexpected record.\n" );
|
||||
break;
|
||||
|
||||
default:
|
||||
mbedtls_printf( "mbedtls_ssl_check_record() failed fatally with -%#04x.\n", -ret );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* Regardless of the outcome, forward the record to the stack. */
|
||||
}
|
||||
|
||||
mbedtls_free( tmp_buf );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_RECORD_CHECKING */
|
||||
|
||||
static int recv_cb( void *ctx, unsigned char *buf, size_t len )
|
||||
{
|
||||
io_ctx_t *io_ctx = (io_ctx_t*) ctx;
|
||||
size_t recv_len;
|
||||
int ret;
|
||||
|
||||
if( opt.nbio == 2 )
|
||||
ret = delayed_recv( io_ctx->net, buf, len );
|
||||
else
|
||||
ret = mbedtls_net_recv( io_ctx->net, buf, len );
|
||||
if( ret < 0 )
|
||||
return( ret );
|
||||
recv_len = (size_t) ret;
|
||||
|
||||
if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
|
||||
{
|
||||
/* Here's the place to do any datagram/record checking
|
||||
* in between receiving the packet from the underlying
|
||||
* transport and passing it on to the TLS stack. */
|
||||
#if defined(MBEDTLS_SSL_RECORD_CHECKING)
|
||||
if( ssl_check_record( io_ctx->ssl, buf, recv_len ) != 0 )
|
||||
return( -1 );
|
||||
#endif /* MBEDTLS_SSL_RECORD_CHECKING */
|
||||
}
|
||||
|
||||
return( (int) recv_len );
|
||||
}
|
||||
|
||||
static int recv_timeout_cb( void *ctx, unsigned char *buf, size_t len,
|
||||
uint32_t timeout )
|
||||
{
|
||||
io_ctx_t *io_ctx = (io_ctx_t*) ctx;
|
||||
int ret;
|
||||
size_t recv_len;
|
||||
|
||||
ret = mbedtls_net_recv_timeout( io_ctx->net, buf, len, timeout );
|
||||
if( ret < 0 )
|
||||
return( ret );
|
||||
recv_len = (size_t) ret;
|
||||
|
||||
if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
|
||||
{
|
||||
/* Here's the place to do any datagram/record checking
|
||||
* in between receiving the packet from the underlying
|
||||
* transport and passing it on to the TLS stack. */
|
||||
#if defined(MBEDTLS_SSL_RECORD_CHECKING)
|
||||
if( ssl_check_record( io_ctx->ssl, buf, recv_len ) != 0 )
|
||||
return( -1 );
|
||||
#endif /* MBEDTLS_SSL_RECORD_CHECKING */
|
||||
}
|
||||
|
||||
return( (int) recv_len );
|
||||
}
|
||||
|
||||
static int send_cb( void *ctx, unsigned char const *buf, size_t len )
|
||||
{
|
||||
io_ctx_t *io_ctx = (io_ctx_t*) ctx;
|
||||
|
||||
if( opt.nbio == 2 )
|
||||
return( delayed_send( io_ctx->net, buf, len ) );
|
||||
|
||||
return( mbedtls_net_send( io_ctx->net, buf, len ) );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
static unsigned char peer_crt_info[1024];
|
||||
|
||||
@ -874,6 +1006,7 @@ int main( int argc, char *argv[] )
|
||||
{
|
||||
int ret = 0, len, tail_len, i, written, frags, retry_left;
|
||||
mbedtls_net_context server_fd;
|
||||
io_ctx_t io_ctx;
|
||||
|
||||
unsigned char buf[MAX_REQUEST_SIZE + 1];
|
||||
|
||||
@ -2149,12 +2282,10 @@ int main( int argc, char *argv[] )
|
||||
mbedtls_ssl_set_verify( &ssl, my_verify, NULL );
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||
|
||||
if( opt.nbio == 2 )
|
||||
mbedtls_ssl_set_bio( &ssl, &server_fd, my_send, my_recv, NULL );
|
||||
else
|
||||
mbedtls_ssl_set_bio( &ssl, &server_fd,
|
||||
mbedtls_net_send, mbedtls_net_recv,
|
||||
opt.nbio == 0 ? mbedtls_net_recv_timeout : NULL );
|
||||
io_ctx.ssl = &ssl;
|
||||
io_ctx.net = &server_fd;
|
||||
mbedtls_ssl_set_bio( &ssl, &io_ctx, send_cb, recv_cb,
|
||||
opt.nbio == 0 ? recv_timeout_cb : NULL );
|
||||
|
||||
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
|
||||
if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
|
||||
|
@ -728,7 +728,7 @@ exit:
|
||||
* Test recv/send functions that make sure each try returns
|
||||
* WANT_READ/WANT_WRITE at least once before sucesseding
|
||||
*/
|
||||
static int my_recv( void *ctx, unsigned char *buf, size_t len )
|
||||
static int delayed_recv( void *ctx, unsigned char *buf, size_t len )
|
||||
{
|
||||
static int first_try = 1;
|
||||
int ret;
|
||||
@ -745,7 +745,7 @@ static int my_recv( void *ctx, unsigned char *buf, size_t len )
|
||||
return( ret );
|
||||
}
|
||||
|
||||
static int my_send( void *ctx, const unsigned char *buf, size_t len )
|
||||
static int delayed_send( void *ctx, const unsigned char *buf, size_t len )
|
||||
{
|
||||
static int first_try = 1;
|
||||
int ret;
|
||||
@ -762,6 +762,139 @@ static int my_send( void *ctx, const unsigned char *buf, size_t len )
|
||||
return( ret );
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
mbedtls_ssl_context *ssl;
|
||||
mbedtls_net_context *net;
|
||||
} io_ctx_t;
|
||||
|
||||
#if defined(MBEDTLS_SSL_RECORD_CHECKING)
|
||||
static int ssl_check_record( mbedtls_ssl_context const *ssl,
|
||||
unsigned char const *buf, size_t len )
|
||||
{
|
||||
int ret;
|
||||
unsigned char *tmp_buf;
|
||||
|
||||
/* Record checking may modify the input buffer,
|
||||
* so make a copy. */
|
||||
tmp_buf = mbedtls_calloc( 1, len );
|
||||
if( tmp_buf == NULL )
|
||||
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
|
||||
memcpy( tmp_buf, buf, len );
|
||||
|
||||
ret = mbedtls_ssl_check_record( ssl, tmp_buf, len );
|
||||
if( ret != MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE )
|
||||
{
|
||||
int ret_repeated;
|
||||
|
||||
/* Test-only: Make sure that mbedtls_ssl_check_record()
|
||||
* doesn't alter state. */
|
||||
memcpy( tmp_buf, buf, len ); /* Restore buffer */
|
||||
ret_repeated = mbedtls_ssl_check_record( ssl, tmp_buf, len );
|
||||
if( ret != ret_repeated )
|
||||
{
|
||||
mbedtls_printf( "mbedtls_ssl_check_record() returned inconsistent results.\n" );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
switch( ret )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case MBEDTLS_ERR_SSL_INVALID_RECORD:
|
||||
if( opt.debug_level > 1 )
|
||||
mbedtls_printf( "mbedtls_ssl_check_record() detected invalid record.\n" );
|
||||
break;
|
||||
|
||||
case MBEDTLS_ERR_SSL_INVALID_MAC:
|
||||
if( opt.debug_level > 1 )
|
||||
mbedtls_printf( "mbedtls_ssl_check_record() detected unauthentic record.\n" );
|
||||
break;
|
||||
|
||||
case MBEDTLS_ERR_SSL_UNEXPECTED_RECORD:
|
||||
if( opt.debug_level > 1 )
|
||||
mbedtls_printf( "mbedtls_ssl_check_record() detected unexpected record.\n" );
|
||||
break;
|
||||
|
||||
default:
|
||||
mbedtls_printf( "mbedtls_ssl_check_record() failed fatally with -%#04x.\n", -ret );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* Regardless of the outcome, forward the record to the stack. */
|
||||
}
|
||||
|
||||
mbedtls_free( tmp_buf );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_RECORD_CHECKING */
|
||||
|
||||
static int recv_cb( void *ctx, unsigned char *buf, size_t len )
|
||||
{
|
||||
io_ctx_t *io_ctx = (io_ctx_t*) ctx;
|
||||
size_t recv_len;
|
||||
int ret;
|
||||
|
||||
if( opt.nbio == 2 )
|
||||
ret = delayed_recv( io_ctx->net, buf, len );
|
||||
else
|
||||
ret = mbedtls_net_recv( io_ctx->net, buf, len );
|
||||
if( ret < 0 )
|
||||
return( ret );
|
||||
recv_len = (size_t) ret;
|
||||
|
||||
if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
|
||||
{
|
||||
/* Here's the place to do any datagram/record checking
|
||||
* in between receiving the packet from the underlying
|
||||
* transport and passing it on to the TLS stack. */
|
||||
#if defined(MBEDTLS_SSL_RECORD_CHECKING)
|
||||
if( ssl_check_record( io_ctx->ssl, buf, recv_len ) != 0 )
|
||||
return( -1 );
|
||||
#endif /* MBEDTLS_SSL_RECORD_CHECKING */
|
||||
}
|
||||
|
||||
return( (int) recv_len );
|
||||
}
|
||||
|
||||
static int recv_timeout_cb( void *ctx, unsigned char *buf, size_t len,
|
||||
uint32_t timeout )
|
||||
{
|
||||
io_ctx_t *io_ctx = (io_ctx_t*) ctx;
|
||||
int ret;
|
||||
size_t recv_len;
|
||||
|
||||
ret = mbedtls_net_recv_timeout( io_ctx->net, buf, len, timeout );
|
||||
if( ret < 0 )
|
||||
return( ret );
|
||||
recv_len = (size_t) ret;
|
||||
|
||||
if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
|
||||
{
|
||||
/* Here's the place to do any datagram/record checking
|
||||
* in between receiving the packet from the underlying
|
||||
* transport and passing it on to the TLS stack. */
|
||||
#if defined(MBEDTLS_SSL_RECORD_CHECKING)
|
||||
if( ssl_check_record( io_ctx->ssl, buf, recv_len ) != 0 )
|
||||
return( -1 );
|
||||
#endif /* MBEDTLS_SSL_RECORD_CHECKING */
|
||||
}
|
||||
|
||||
return( (int) recv_len );
|
||||
}
|
||||
|
||||
static int send_cb( void *ctx, unsigned char const *buf, size_t len )
|
||||
{
|
||||
io_ctx_t *io_ctx = (io_ctx_t*) ctx;
|
||||
|
||||
if( opt.nbio == 2 )
|
||||
return( delayed_send( io_ctx->net, buf, len ) );
|
||||
|
||||
return( mbedtls_net_send( io_ctx->net, buf, len ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Return authmode from string, or -1 on error
|
||||
*/
|
||||
@ -1509,6 +1642,7 @@ int main( int argc, char *argv[] )
|
||||
{
|
||||
int ret = 0, len, written, frags, exchanges_left;
|
||||
int version_suites[4][2];
|
||||
io_ctx_t io_ctx;
|
||||
unsigned char* buf = 0;
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
@ -3151,11 +3285,10 @@ int main( int argc, char *argv[] )
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if( opt.nbio == 2 )
|
||||
mbedtls_ssl_set_bio( &ssl, &client_fd, my_send, my_recv, NULL );
|
||||
else
|
||||
mbedtls_ssl_set_bio( &ssl, &client_fd, mbedtls_net_send, mbedtls_net_recv,
|
||||
opt.nbio == 0 ? mbedtls_net_recv_timeout : NULL );
|
||||
io_ctx.ssl = &ssl;
|
||||
io_ctx.net = &client_fd;
|
||||
mbedtls_ssl_set_bio( &ssl, &io_ctx, send_cb, recv_cb,
|
||||
opt.nbio == 0 ? recv_timeout_cb : NULL );
|
||||
|
||||
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
|
||||
if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
|
||||
|
Reference in New Issue
Block a user