From 6a7f01c237612960f35a052e65aaabd607565aca Mon Sep 17 00:00:00 2001 From: Piotr Nowicki Date: Wed, 12 Feb 2020 13:53:36 +0100 Subject: [PATCH] Add test with sending application data via DTLS Signed-off-by: Piotr Nowicki --- tests/suites/test_suite_ssl.data | 58 ++++- tests/suites/test_suite_ssl.function | 370 ++++++++++++++++++++------- 2 files changed, 327 insertions(+), 101 deletions(-) diff --git a/tests/suites/test_suite_ssl.data b/tests/suites/test_suite_ssl.data index 722d7fec6..3113bd483 100644 --- a/tests/suites/test_suite_ssl.data +++ b/tests/suites/test_suite_ssl.data @@ -275,44 +275,82 @@ DTLS Handshake with serialization, tls1_2 depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_SSL_PROTO_DTLS handshake:"":MBEDTLS_SSL_MINOR_VERSION_3:MBEDTLS_PK_RSA:"":1:1 -Test sending app data MFL=512 without fragmentation +Sending app data via TLS, MFL=512 without fragmentation depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH send_application_data:MBEDTLS_SSL_MAX_FRAG_LEN_512:400:512:1:1 -Test sending app data MFL=512 with fragmentation +Sending app data via TLS, MFL=512 with fragmentation depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH send_application_data:MBEDTLS_SSL_MAX_FRAG_LEN_512:513:1536:2:3 -Test sending app data MFL=1024 without fragmentation +Sending app data via TLS, MFL=1024 without fragmentation depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH send_application_data:MBEDTLS_SSL_MAX_FRAG_LEN_1024:1000:1024:1:1 -Test sending app data MFL=1024 with fragmentation +Sending app data via TLS, MFL=1024 with fragmentation depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH send_application_data:MBEDTLS_SSL_MAX_FRAG_LEN_1024:1025:5120:2:5 -Test sending app data MFL=2048 without fragmentation +Sending app data via TLS, MFL=2048 without fragmentation depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH send_application_data:MBEDTLS_SSL_MAX_FRAG_LEN_2048:2000:2048:1:1 -Test sending app data MFL=2048 with fragmentation +Sending app data via TLS, MFL=2048 with fragmentation depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH send_application_data:MBEDTLS_SSL_MAX_FRAG_LEN_2048:2049:8192:2:4 -Test sending app data MFL=4096 without fragmentation +Sending app data via TLS, MFL=4096 without fragmentation depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH send_application_data:MBEDTLS_SSL_MAX_FRAG_LEN_4096:4000:4096:1:1 -Test sending app data MFL=4096 with fragmentation +Sending app data via TLS, MFL=4096 with fragmentation depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH send_application_data:MBEDTLS_SSL_MAX_FRAG_LEN_4096:4097:12288:2:3 -Test sending app data without MFL and without fragmentation +Sending app data via TLS without MFL and without fragmentation send_application_data:MBEDTLS_SSL_MAX_FRAG_LEN_NONE:16001:16384:1:1 -Test sending app data without MFL and with fragmentation +Sending app data via TLS without MFL and with fragmentation send_application_data:MBEDTLS_SSL_MAX_FRAG_LEN_NONE:16385:100000:2:7 +Sending app data via DTLS, MFL=512 without fragmentation +depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH +send_application_data_dtls:MBEDTLS_SSL_MAX_FRAG_LEN_512:400:512:1:1 + +Sending app data via DTLS, MFL=512 with fragmentation +depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH +send_application_data_dtls:MBEDTLS_SSL_MAX_FRAG_LEN_512:513:1536:0:0 + +Sending app data via DTLS, MFL=1024 without fragmentation +depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH +send_application_data_dtls:MBEDTLS_SSL_MAX_FRAG_LEN_1024:1000:1024:1:1 + +Sending app data via DTLS, MFL=1024 with fragmentation +depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH +send_application_data_dtls:MBEDTLS_SSL_MAX_FRAG_LEN_1024:1025:5120:0:0 + +Sending app data via DTLS, MFL=2048 without fragmentation +depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH +send_application_data_dtls:MBEDTLS_SSL_MAX_FRAG_LEN_2048:2000:2048:1:1 + +Sending app data via DTLS, MFL=2048 with fragmentation +depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH +send_application_data_dtls:MBEDTLS_SSL_MAX_FRAG_LEN_2048:2049:8192:0:0 + +Sending app data via DTLS, MFL=4096 without fragmentation +depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH +send_application_data_dtls:MBEDTLS_SSL_MAX_FRAG_LEN_4096:4000:4096:1:1 + +Sending app data via DTLS, MFL=4096 with fragmentation +depends_on:MBEDTLS_SSL_MAX_FRAGMENT_LENGTH +send_application_data_dtls:MBEDTLS_SSL_MAX_FRAG_LEN_4096:4097:12288:0:0 + +Sending app data via DTLS, without MFL and without fragmentation +send_application_data_dtls:MBEDTLS_SSL_MAX_FRAG_LEN_NONE:16001:16384:1:1 + +Sending app data via DTLS, without MFL and with fragmentation +send_application_data_dtls:MBEDTLS_SSL_MAX_FRAG_LEN_NONE:16385:100000:0:0 + SSL DTLS replay: initial state, seqnum 0 ssl_dtls_replay:"":"000000000000":0 diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index f25ad65da..88e405bf7 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -928,31 +928,87 @@ int mbedtls_move_handshake_to_state( mbedtls_ssl_context *ssl, #endif /* MBEDTLS_X509_CRT_PARSE_C */ /* - * Write application data. Then increase write and fragments counter + * Write application data. Increase write counter and fragments counter if + * necessary. */ int mbedtls_ssl_write_fragment( mbedtls_ssl_context *ssl, unsigned char *buf, - int ln, int *writen, int *fragments ) + int buf_len, int *written, + int *fragments, const int expected_fragments ) { - int ret = mbedtls_ssl_write( ssl, buf + *writen, ln - *writen ); - if( ret >= 0 ) + int ret = mbedtls_ssl_write( ssl, buf + *written, buf_len - *written ); + if( ret > 0 ) { (*fragments)++; - *writen += ret; + *written += ret; } - return ret; + + if( expected_fragments == 0 ) + { + /* Used for DTLS and the message size larger than MFL. In that case + * the message can not be fragmented and the library should return + * MBEDTLS_ERR_SSL_BAD_INPUT_DATA error. This error must be returned + * to prevent a dead loop inside mbedtls_exchange_data(). */ + return ret; + } + else if( expected_fragments == 1 ) + { + /* Used for TLS/DTLS and the message size lower than MFL */ + TEST_ASSERT( ret == buf_len || + ret == MBEDTLS_ERR_SSL_WANT_READ || + ret == MBEDTLS_ERR_SSL_WANT_WRITE ); + } + else + { + /* Used for TLS and the message size larger than MFL */ + TEST_ASSERT( expected_fragments > 1 ); + TEST_ASSERT( ( ret >= 0 && ret <= buf_len ) || + ret == MBEDTLS_ERR_SSL_WANT_READ || + ret == MBEDTLS_ERR_SSL_WANT_WRITE ); + } + + return 0; + +exit: + /* Some of the tests failed */ + return -1; } /* - * Read application data and increase read counter + * Read application data and increase read counter if necessary. */ -int mbedtls_ssl_read_fragment( mbedtls_ssl_context *ssl, unsigned char *buf, int ln, int *read ) +int mbedtls_ssl_read_fragment( mbedtls_ssl_context *ssl, unsigned char *buf, + int buf_len, int *read, + const int expected_fragments ) { - int ret = mbedtls_ssl_read( ssl, buf + *read, ln - *read ); - if( ret >= 0 ) + int ret = mbedtls_ssl_read( ssl, buf + *read, buf_len - *read ); + if( ret > 0 ) { *read += ret; } - return ret; + + if( expected_fragments == 0 ) + { + TEST_ASSERT( ret == 0 ); + } + else if( expected_fragments == 1 ) + { + TEST_ASSERT( ret == buf_len || + ret == MBEDTLS_ERR_SSL_WANT_READ || + ret == MBEDTLS_ERR_SSL_WANT_WRITE ); + } + else + { + TEST_ASSERT( expected_fragments > 1 ); + TEST_ASSERT( ( ret >= 0 && ret <= buf_len ) || + ret == MBEDTLS_ERR_SSL_WANT_READ || + ret == MBEDTLS_ERR_SSL_WANT_WRITE ); + } + + return 0; + +exit: + /* Some of the tests failed */ + return -1; } /* @@ -1347,6 +1403,146 @@ static int ssl_populate_session( mbedtls_ssl_session *session, return( 0 ); } +/* + * Perform data exchanging between \p ssl_1 and \p ssl_2 and check if the + * message was sent in the correct number of fragments. + * + * /p ssl_1 and /p ssl_2 Endpoints represented by mbedtls_ssl_context. Both + * of them must be initialized and connected beforehand. + * /p msg_len_1 and /p msg_len_2 specify the size of the message to send. + * /p expected_fragments_1 and /p expected_fragments_2 determine in how many + * fragments the message should be sent. + * expected_fragments is 0: can be used for DTLS testing while the message + * size is larger than MFL. In that case the message + * cannot be fragmented and sent to the second endpoint. + * This value can be used for negative tests. + * expected_fragments is 1: can be used for TLS/DTLS testing while the + * message size is below MFL + * expected_fragments > 1: can be used for TLS testing while the message + * size is larger than MFL + * + * \retval 0 on success, otherwise error code. + */ +int mbedtls_exchange_data( mbedtls_ssl_context *ssl_1, + int msg_len_1, const int expected_fragments_1, + mbedtls_ssl_context *ssl_2, + int msg_len_2, const int expected_fragments_2 ) +{ + unsigned char *msg_buf_1 = malloc( msg_len_1 ); + unsigned char *msg_buf_2 = malloc( msg_len_2 ); + unsigned char *in_buf_1 = malloc( msg_len_2 ); + unsigned char *in_buf_2 = malloc( msg_len_1 ); + int msg_type, ret = -1; + + /* Perform this test with two message types. At first use a message + * consisting of only 0x00 for the client and only 0xFF for the server. + * At the second time use message with generated data */ + for( msg_type = 0; msg_type < 2; msg_type++ ) + { + int written_1 = 0; + int written_2 = 0; + int read_1 = 0; + int read_2 = 0; + int fragments_1 = 0; + int fragments_2 = 0; + + if( msg_type == 0 ) + { + memset( msg_buf_1, 0x00, msg_len_1 ); + memset( msg_buf_2, 0xff, msg_len_2 ); + } + else + { + int i, j = 0; + for( i = 0; i < msg_len_1; i++ ) + { + msg_buf_1[i] = j++ & 0xFF; + } + for( i = 0; i < msg_len_2; i++ ) + { + msg_buf_2[i] = ( j -= 5 ) & 0xFF; + } + } + + while( read_1 < msg_len_2 || read_2 < msg_len_1 ) + { + /* ssl_1 sending */ + if( msg_len_1 > written_1 ) + { + ret = mbedtls_ssl_write_fragment( ssl_1, msg_buf_1, + msg_len_1, &written_1, + &fragments_1, + expected_fragments_1 ); + if( expected_fragments_1 == 0 ) + { + /* This error is expected when the message is too large and + * cannot be fragmented */ + TEST_ASSERT( ret == MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + msg_len_1 = 0; + } + else + { + TEST_ASSERT( ret == 0 ); + } + } + + /* ssl_2 sending */ + if( msg_len_2 > written_2 ) + { + ret = mbedtls_ssl_write_fragment( ssl_2, msg_buf_2, + msg_len_2, &written_2, + &fragments_2, + expected_fragments_2 ); + if( expected_fragments_2 == 0 ) + { + /* This error is expected when the message is too large and + * cannot be fragmented */ + TEST_ASSERT( ret == MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + msg_len_2 = 0; + } + else + { + TEST_ASSERT( ret == 0 ); + } + } + + /* ssl_1 reading */ + if( read_1 < msg_len_2 ) + { + ret = mbedtls_ssl_read_fragment( ssl_1, in_buf_1, + msg_len_2, &read_1, + expected_fragments_1 ); + TEST_ASSERT( ret == 0 ); + } + + /* ssl_2 reading */ + if( read_2 < msg_len_1 ) + { + ret = mbedtls_ssl_read_fragment( ssl_2, in_buf_2, + msg_len_1, &read_2, + expected_fragments_2 ); + TEST_ASSERT( ret == 0 ); + } + } + + ret = -1; + TEST_ASSERT( 0 == memcmp( msg_buf_1, in_buf_2, msg_len_1 ) ); + TEST_ASSERT( 0 == memcmp( msg_buf_2, in_buf_1, msg_len_2 ) ); + TEST_ASSERT( fragments_1 == expected_fragments_1 ); + TEST_ASSERT( fragments_2 == expected_fragments_2 ); + } + + ret = 0; + +exit: + free( msg_buf_1 ); + free( in_buf_1 ); + free( msg_buf_2 ); + free( in_buf_2 ); + + return ret; +} + /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -3262,15 +3458,11 @@ exit: /* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:!MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_PKCS1_V15 */ void send_application_data( int mfl, int cli_msg_len, int srv_msg_len, - const int expected_cli_frames, - const int expected_srv_frames ) + const int expected_cli_fragments, + const int expected_srv_fragments ) { enum { BUFFSIZE = 2048 }; mbedtls_endpoint server, client; - unsigned char *cli_msg_buf = malloc( cli_msg_len ); - unsigned char *cli_in_buf = malloc( srv_msg_len ); - unsigned char *srv_msg_buf = malloc( srv_msg_len ); - unsigned char *srv_in_buf = malloc( cli_msg_len ); int ret = -1; ret = mbedtls_endpoint_init( &server, MBEDTLS_SSL_IS_SERVER, MBEDTLS_PK_RSA, @@ -3302,83 +3494,79 @@ void send_application_data( int mfl, int cli_msg_len, int srv_msg_len, TEST_ASSERT( client.ssl.state == MBEDTLS_SSL_HANDSHAKE_OVER ); TEST_ASSERT( server.ssl.state == MBEDTLS_SSL_HANDSHAKE_OVER ); - /* Perform this test with two message types. At first use a message - * consisting of only 0x00 for the client and only 0xFF for the server. - * At the second time use message with generated data */ - for( int msg_type = 0; msg_type < 2; msg_type++ ) - { - int cli_writen = 0; - int srv_writen = 0; - int cli_read = 0; - int srv_read = 0; - int cli_fragments = 0; - int srv_fragments = 0; - - if( msg_type == 0 ) - { - memset( cli_msg_buf, 0x00, cli_msg_len ); - memset( srv_msg_buf, 0xff, srv_msg_len ); - } - else - { - int j = 0; - for( int i = 0; i < cli_msg_len; i++ ) - cli_msg_buf[i] = j++ & 0xFF; - for( int i = 0; i < srv_msg_len; i++ ) - srv_msg_buf[i] = ( j -= 5 ) & 0xFF; - } - - while( cli_read < srv_msg_len || srv_read < cli_msg_len ) - { - /* Client sending */ - if( cli_msg_len > cli_writen ) - { - ret = mbedtls_ssl_write_fragment( &(client.ssl), cli_msg_buf, - cli_msg_len, &cli_writen, &cli_fragments ); - TEST_ASSERT( ( ret >= 0 && ret <= cli_msg_len ) || - ret == MBEDTLS_ERR_SSL_WANT_WRITE ); - } - - /* Server sending */ - if( srv_msg_len > srv_writen ) - { - ret = mbedtls_ssl_write_fragment( &(server.ssl), srv_msg_buf, - srv_msg_len, &srv_writen, &srv_fragments ); - TEST_ASSERT( ( ret >= 0 && ret <= srv_msg_len ) || - ret == MBEDTLS_ERR_SSL_WANT_WRITE ); - } - - /* Client reading */ - if( cli_read < srv_msg_len ) - { - ret = mbedtls_ssl_read_fragment( &(client.ssl), cli_in_buf, - srv_msg_len, &cli_read ); - TEST_ASSERT( ( ret >= 0 && ret <= srv_msg_len ) || - ret == MBEDTLS_ERR_SSL_WANT_READ ); - } - - /* Server reading */ - if( srv_read < cli_msg_len ) - { - ret = mbedtls_ssl_read_fragment( &(server.ssl), srv_in_buf, - cli_msg_len, &srv_read ); - TEST_ASSERT( ( ret >= 0 && ret <= cli_msg_len ) || - ret == MBEDTLS_ERR_SSL_WANT_READ ); - } - } - - TEST_ASSERT( 0 == memcmp( cli_msg_buf, srv_in_buf, cli_msg_len ) ); - TEST_ASSERT( 0 == memcmp( srv_msg_buf, cli_in_buf, srv_msg_len ) ); - TEST_ASSERT( cli_fragments == expected_cli_frames ); - TEST_ASSERT( srv_fragments == expected_srv_frames ); - } + /* Start data exchanging test */ + ret = mbedtls_exchange_data( &(client.ssl), cli_msg_len, expected_cli_fragments, + &(server.ssl), srv_msg_len, expected_srv_fragments ); + TEST_ASSERT( ret == 0 ); exit: mbedtls_endpoint_free( &client, NULL ); mbedtls_endpoint_free( &server, NULL ); - free( cli_msg_buf ); - free( cli_in_buf ); - free( srv_msg_buf ); - free( srv_in_buf ); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:!MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_PKCS1_V15 */ +void send_application_data_dtls( int mfl, int cli_msg_len, int srv_msg_len, + const int expected_cli_fragments, + const int expected_srv_fragments ) +{ + enum { BUFFSIZE = 17000 }; +#if defined(MBEDTLS_TIMING_C) + mbedtls_timing_delay_context timer_client, timer_server; +#endif + mbedtls_endpoint server, client; + mbedtls_test_message_queue server_queue, client_queue; + mbedtls_test_message_socket_context server_context, client_context; + int ret = -1; + + /* Initializing endpoints and communication */ + ret = mbedtls_endpoint_init( &server, MBEDTLS_SSL_IS_SERVER, MBEDTLS_PK_RSA, + &server_context, &server_queue, &client_queue ); + TEST_ASSERT( ret == 0 ); + + ret = mbedtls_endpoint_init( &client, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_PK_RSA, + &client_context, &client_queue, &server_queue ); + TEST_ASSERT( ret == 0 ); + +#if defined(MBEDTLS_TIMING_C) + mbedtls_ssl_set_timer_cb( &client.ssl, &timer_client, + mbedtls_timing_set_delay, + mbedtls_timing_get_delay ); + + mbedtls_ssl_set_timer_cb( &server.ssl, &timer_server, + mbedtls_timing_set_delay, + mbedtls_timing_get_delay ); +#endif /* MBEDTLS_TIMING_C */ + +#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) + ret = mbedtls_ssl_conf_max_frag_len( &(server.conf), (unsigned char) mfl ); + TEST_ASSERT( ret == 0 ); + + ret = mbedtls_ssl_conf_max_frag_len( &(client.conf), (unsigned char) mfl ); + TEST_ASSERT( ret == 0 ); +#else + TEST_ASSERT( MBEDTLS_SSL_MAX_FRAG_LEN_NONE == mfl ); +#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ + + ret = mbedtls_mock_socket_connect( &(server.socket), &(client.socket), + BUFFSIZE ); + TEST_ASSERT( ret == 0 ); + + ret = mbedtls_move_handshake_to_state( &(client.ssl), + &(server.ssl), + MBEDTLS_SSL_HANDSHAKE_OVER ); + TEST_ASSERT( ret == 0 ); + TEST_ASSERT( client.ssl.state == MBEDTLS_SSL_HANDSHAKE_OVER ); + TEST_ASSERT( server.ssl.state == MBEDTLS_SSL_HANDSHAKE_OVER ); + + /* Start data exchanging test */ + ret = mbedtls_exchange_data( &(client.ssl), cli_msg_len, expected_cli_fragments, + &(server.ssl), srv_msg_len, expected_srv_fragments ); + TEST_ASSERT( ret == 0 ); + + +exit: + mbedtls_endpoint_free( &client, &client_context ); + mbedtls_endpoint_free( &server, &server_context ); } /* END_CASE */