From cfe457921ae3f3d564ba915bfde45fa39fc7ab74 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 3 Jul 2019 16:13:00 +0100 Subject: [PATCH 01/11] Introduce configuration option and API for SSL record checking --- include/mbedtls/config.h | 13 ++++++++++ include/mbedtls/ssl.h | 48 +++++++++++++++++++++++++++++++++++++ library/ssl_tls.c | 12 ++++++++++ programs/ssl/query_config.c | 8 +++++++ 4 files changed, 81 insertions(+) diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 529c07f1f..6e841c7e6 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -1350,6 +1350,19 @@ */ #define MBEDTLS_SSL_ALL_ALERT_MESSAGES +/** + * \def MBEDTLS_SSL_RECORD_CHECKING + * + * Enable the API mbedtls_ssl_check_record() which allows to check the + * validity, freshness and authenticity of an incoming record without + * modifying the externally visible state of the SSL context. + * + * See mbedtls_ssl_check_record() for more information. + * + * Uncomment to enable support for record checking. + */ +#define MBEDTLS_SSL_RECORD_CHECKING + /** * \def MBEDTLS_SSL_DTLS_CONNECTION_ID * diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 5f9862b20..ba8d28e5b 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1756,6 +1756,54 @@ void mbedtls_ssl_set_verify( mbedtls_ssl_context *ssl, */ void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout ); +#if defined(MBEDTLS_SSL_RECORD_CHECKING) +/** + * \brief Check whether a buffer contains a valid, fresh + * and authentic application data record (DTLS only). + * + * This function does not change the user-visible state + * of the SSL context. It's sole purpose is to provide + * an indication of the legitimacy of an incoming record. + * + * This can be useful e.g. in distributed server environments + * using the DTLS Connection ID feature, in which connections + * might need to be passed between service instances on a change + * of peer address, but where such disruptive operations should + * only happen after the validity of incoming records has been + * confirmed. + * + * \param ssl The SSL context to use. + * \param buf The address of the buffer holding the record to be checked. + * This must be an R/W buffer of length \p buflen Bytes. + * \param buflen The length of \p buf in Bytes. + * + * \note This routine only checks whether the provided buffer begins + * with a valid, fresh and authentic record, but does not check + * potential data following the initial record. In particular, + * it is possible to pass DTLS datagrams containing records, + * in which case only the first record is checked. + * + * \note This function modifies the input buffer \p buf. If you need + * to preserve the original record, you have to maintain a copy. + * + * \return \c 0 if the record is valid, fresh (DTLS only) and authentic. + * \return MBEDTLS_ERR_SSL_INVALID_MAC if the check completed + * successfully but the record was found to be not authentic. + * \return MBEDTLS_ERR_SSL_INVALID_RECORD if the check completed + * successfully but the record was found to be invalid for + * a reason different from authenticity checking. + * \return MBEDTLS_ERR_SSL_UNEXPECTED_RECORD if the check completed + * successfully but the record was found to be unexpected + * in the state of the SSL context, including replayed records. + * \return Another negative error code on different kinds of failure. + * In this case, the SSL context becomes unusable and needs + * to be freed or reset before reuse. + */ +int mbedtls_ssl_check_record( mbedtls_ssl_context const *ssl, + unsigned char *buf, + size_t buflen ); +#endif /* MBEDTLS_SSL_RECORD_CHECKING */ + /** * \brief Set the timer callbacks (Mandatory for DTLS.) * diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 68a1e592e..0386ea0e8 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -112,6 +112,18 @@ static void ssl_update_out_pointers( mbedtls_ssl_context *ssl, mbedtls_ssl_transform *transform ); static void ssl_update_in_pointers( mbedtls_ssl_context *ssl ); +#if defined(MBEDTLS_SSL_RECORD_CHECKING) +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 ); +} +#endif /* MBEDTLS_SSL_RECORD_CHECKING */ + #define SSL_DONT_FORCE_FLUSH 0 #define SSL_FORCE_FLUSH 1 diff --git a/programs/ssl/query_config.c b/programs/ssl/query_config.c index 98a5df230..c6d19bf09 100644 --- a/programs/ssl/query_config.c +++ b/programs/ssl/query_config.c @@ -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 ) { From 8b1af2f89c9a3e26e748e3c856c9411425b988e1 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 3 Jul 2019 17:02:43 +0100 Subject: [PATCH 02/11] Add IO wrappers to ssl_client2 as interm's between NET and SSL layer --- programs/ssl/ssl_client2.c | 80 ++++++++++++++++++++++++++++++++++---- 1 file changed, 72 insertions(+), 8 deletions(-) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 4221159d4..6ff55e656 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -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,70 @@ 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; + +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. */ + mbedtls_printf( "[RECV] Datagram of size %u\n", (unsigned) recv_len ); + } + + 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. */ + mbedtls_printf( "[RECV] Datagram of size %u\n", (unsigned) recv_len ); + } + + 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 +939,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]; @@ -2162,12 +2228,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 ) From dcc94e61da7bf88d484c04d49b7c7b594b5cc4bf Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 3 Jul 2019 17:05:43 +0100 Subject: [PATCH 03/11] Add IO wrappers to ssl_server2 as interm's between NET and SSL layer --- programs/ssl/ssl_server2.c | 78 ++++++++++++++++++++++++++++++++++---- 1 file changed, 71 insertions(+), 7 deletions(-) diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index bbe93cb47..24c3ee9cb 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -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,70 @@ 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; + +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. */ + mbedtls_printf( "[RECV] Datagram of size %u\n", (unsigned) recv_len ); + } + + 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. */ + mbedtls_printf( "[RECV] Datagram of size %u\n", (unsigned) recv_len ); + } + + 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 */ @@ -1514,6 +1578,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) @@ -3170,11 +3235,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 ) From 4b6649e67cf20cb542b80108736993f979dcbb19 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 3 Jul 2019 17:14:41 +0100 Subject: [PATCH 04/11] Pass dgrams to mbedtls_ssl_check_record in ssl_client2/server2 --- programs/ssl/ssl_client2.c | 72 +++++++++++++++++++++++++++++++++++-- programs/ssl/ssl_server2.c | 74 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 142 insertions(+), 4 deletions(-) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 6ff55e656..51a59fef3 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -658,6 +658,68 @@ typedef struct 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 ) + { + ret = -1; + goto exit; + } + + 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. */ + } + +exit: + 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; @@ -677,7 +739,10 @@ static int recv_cb( void *ctx, unsigned char *buf, size_t len ) /* 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. */ - mbedtls_printf( "[RECV] Datagram of size %u\n", (unsigned) recv_len ); +#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 ); @@ -700,7 +765,10 @@ static int recv_timeout_cb( void *ctx, unsigned char *buf, size_t len, /* 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. */ - mbedtls_printf( "[RECV] Datagram of size %u\n", (unsigned) recv_len ); +#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 ); diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 24c3ee9cb..be448a01b 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -768,6 +768,70 @@ typedef struct 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 ) + { + ret = -1; + goto exit; + } + + 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. */ + } + +exit: + 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; @@ -787,7 +851,10 @@ static int recv_cb( void *ctx, unsigned char *buf, size_t len ) /* 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. */ - mbedtls_printf( "[RECV] Datagram of size %u\n", (unsigned) recv_len ); +#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 ); @@ -810,7 +877,10 @@ static int recv_timeout_cb( void *ctx, unsigned char *buf, size_t len, /* 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. */ - mbedtls_printf( "[RECV] Datagram of size %u\n", (unsigned) recv_len ); +#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 ); From 7132c4a6c89a6730c817eb2dccde99cc67594290 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Thu, 4 Jul 2019 17:05:10 +0100 Subject: [PATCH 05/11] Update version_features.c --- library/version_features.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/version_features.c b/library/version_features.c index 58acb5c79..e83899d0a 100644 --- a/library/version_features.c +++ b/library/version_features.c @@ -450,6 +450,9 @@ static const char * const features[] = { #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES) "MBEDTLS_SSL_ALL_ALERT_MESSAGES", #endif /* MBEDTLS_SSL_ALL_ALERT_MESSAGES */ +#if defined(MBEDTLS_SSL_RECORD_CHECKING) + "MBEDTLS_SSL_RECORD_CHECKING", +#endif /* MBEDTLS_SSL_RECORD_CHECKING */ #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) "MBEDTLS_SSL_DTLS_CONNECTION_ID", #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ From 19f1ef7a10caf02e92960d1aa07a72712779a5c5 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Thu, 18 Jul 2019 08:20:53 +0100 Subject: [PATCH 06/11] State that record checking is DTLS only and doesn't check content type --- include/mbedtls/ssl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index ba8d28e5b..8279e5fbc 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1759,7 +1759,7 @@ void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout ) #if defined(MBEDTLS_SSL_RECORD_CHECKING) /** * \brief Check whether a buffer contains a valid, fresh - * and authentic application data record (DTLS only). + * and authentic record (DTLS only). * * This function does not change the user-visible state * of the SSL context. It's sole purpose is to provide @@ -1786,7 +1786,7 @@ void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout ) * \note This function modifies the input buffer \p buf. If you need * to preserve the original record, you have to maintain a copy. * - * \return \c 0 if the record is valid, fresh (DTLS only) and authentic. + * \return \c 0 if the record is valid, fresh and authentic. * \return MBEDTLS_ERR_SSL_INVALID_MAC if the check completed * successfully but the record was found to be not authentic. * \return MBEDTLS_ERR_SSL_INVALID_RECORD if the check completed From b7d1dffcc941950570a0a72ea86b99c3796a61b6 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Thu, 18 Jul 2019 08:21:17 +0100 Subject: [PATCH 07/11] Fix minor issues in documentation of mbedtls_ssl_check_record() --- include/mbedtls/ssl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 8279e5fbc..8e128c16d 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1762,7 +1762,7 @@ void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout ) * and authentic record (DTLS only). * * This function does not change the user-visible state - * of the SSL context. It's sole purpose is to provide + * of the SSL context. Its sole purpose is to provide * an indication of the legitimacy of an incoming record. * * This can be useful e.g. in distributed server environments @@ -1780,7 +1780,7 @@ void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout ) * \note This routine only checks whether the provided buffer begins * with a valid, fresh and authentic record, but does not check * potential data following the initial record. In particular, - * it is possible to pass DTLS datagrams containing records, + * it is possible to pass DTLS datagrams containing records, * in which case only the first record is checked. * * \note This function modifies the input buffer \p buf. If you need From 91f8327e40a0ad751503f5948d832c3f9d2ece03 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 24 Jul 2019 13:59:07 +0100 Subject: [PATCH 08/11] cli/srv ex: Add dbg msg if record checking gives inconsistent result --- programs/ssl/ssl_client2.c | 4 ++-- programs/ssl/ssl_server2.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 51a59fef3..c37f4b0cf 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -681,8 +681,8 @@ static int ssl_check_record( mbedtls_ssl_context const *ssl, ret_repeated = mbedtls_ssl_check_record( ssl, tmp_buf, len ); if( ret != ret_repeated ) { - ret = -1; - goto exit; + mbedtls_printf( "mbedtls_ssl_check_record() returned inconsistent results.\n" ); + return( -1 ); } switch( ret ) diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index be448a01b..a796f5712 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -793,8 +793,8 @@ static int ssl_check_record( mbedtls_ssl_context const *ssl, ret_repeated = mbedtls_ssl_check_record( ssl, tmp_buf, len ); if( ret != ret_repeated ) { - ret = -1; - goto exit; + mbedtls_printf( "mbedtls_ssl_check_record() returned inconsistent results.\n" ); + return( -1 ); } switch( ret ) From 9548f114f399fab3d6232221b1e816f4b0ec758a Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 24 Jul 2019 14:23:16 +0100 Subject: [PATCH 09/11] Add missing word in documentation of mbedtls_ssl_check_record() --- include/mbedtls/ssl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 8e128c16d..955104af1 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1780,8 +1780,8 @@ void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout ) * \note This routine only checks whether the provided buffer begins * with a valid, fresh and authentic record, but does not check * potential data following the initial record. In particular, - * it is possible to pass DTLS datagrams containing records, - * in which case only the first record is checked. + * it is possible to pass DTLS datagrams containing multiple + * records, in which case only the first record is checked. * * \note This function modifies the input buffer \p buf. If you need * to preserve the original record, you have to maintain a copy. From 1f3fe87da3ce5a452e95f8758c064ece575eb13b Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 24 Jul 2019 16:06:23 +0100 Subject: [PATCH 10/11] Remove unused label in ssl_client2/ssl_server2 --- programs/ssl/ssl_client2.c | 1 - programs/ssl/ssl_server2.c | 1 - 2 files changed, 2 deletions(-) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index c37f4b0cf..671e54a3a 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -713,7 +713,6 @@ static int ssl_check_record( mbedtls_ssl_context const *ssl, /* Regardless of the outcome, forward the record to the stack. */ } -exit: mbedtls_free( tmp_buf ); return( 0 ); diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index a796f5712..5a7b2730c 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -825,7 +825,6 @@ static int ssl_check_record( mbedtls_ssl_context const *ssl, /* Regardless of the outcome, forward the record to the stack. */ } -exit: mbedtls_free( tmp_buf ); return( 0 ); From 31c3b14e371ed24988f0125bc473c2d9fe59f3a5 Mon Sep 17 00:00:00 2001 From: Jarno Lamsa Date: Wed, 14 Aug 2019 10:39:32 +0300 Subject: [PATCH 11/11] Documentation fixes according to review Improve grammar and replace the word 'fresh' with an explanation what is going to be verified. --- include/mbedtls/config.h | 7 ++++--- include/mbedtls/ssl.h | 18 ++++++++++-------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 6e841c7e6..87d0c6e98 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -1353,9 +1353,10 @@ /** * \def MBEDTLS_SSL_RECORD_CHECKING * - * Enable the API mbedtls_ssl_check_record() which allows to check the - * validity, freshness and authenticity of an incoming record without - * modifying the externally visible state of the SSL context. + * Enable the function mbedtls_ssl_check_record() which can be used to check + * the validity and authenticity of an incoming record, to verify that it has + * not been seen before. These checks are performed without modifying the + * externally visible state of the SSL context. * * See mbedtls_ssl_check_record() for more information. * diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 955104af1..2c7f050b5 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1758,8 +1758,8 @@ void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout ) #if defined(MBEDTLS_SSL_RECORD_CHECKING) /** - * \brief Check whether a buffer contains a valid, fresh - * and authentic record (DTLS only). + * \brief Check whether a buffer contains a valid and authentic record + * that has not been seen before. (DTLS only). * * This function does not change the user-visible state * of the SSL context. Its sole purpose is to provide @@ -1774,19 +1774,21 @@ void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout ) * * \param ssl The SSL context to use. * \param buf The address of the buffer holding the record to be checked. - * This must be an R/W buffer of length \p buflen Bytes. + * This must be a read/write buffer of length \p buflen Bytes. * \param buflen The length of \p buf in Bytes. * * \note This routine only checks whether the provided buffer begins - * with a valid, fresh and authentic record, but does not check - * potential data following the initial record. In particular, - * it is possible to pass DTLS datagrams containing multiple - * records, in which case only the first record is checked. + * with a valid and authentic record that has not been seen + * before, but does not check potential data following the + * initial record. In particular, it is possible to pass DTLS + * datagrams containing multiple records, in which case only + * the first record is checked. * * \note This function modifies the input buffer \p buf. If you need * to preserve the original record, you have to maintain a copy. * - * \return \c 0 if the record is valid, fresh and authentic. + * \return \c 0 if the record is valid and authentic and has not been + * seen before. * \return MBEDTLS_ERR_SSL_INVALID_MAC if the check completed * successfully but the record was found to be not authentic. * \return MBEDTLS_ERR_SSL_INVALID_RECORD if the check completed