mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-02-15 03:40:08 +00:00
Merge pull request #8854 from ronald-cron-arm/tls13-srv-max-early-data-size
TLS 1.3: Enforce max_early_data_size on server
This commit is contained in:
commit
7e1f9f290f
include/mbedtls
library
tests
include/test
src/test_helpers
suites
@ -1859,7 +1859,8 @@ struct mbedtls_ssl_context {
|
||||
* within a single datagram. */
|
||||
#endif /* MBEDTLS_SSL_PROTO_DTLS */
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_SRV_C)
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
||||
#if defined(MBEDTLS_SSL_SRV_C)
|
||||
/*
|
||||
* One of:
|
||||
* MBEDTLS_SSL_EARLY_DATA_NO_DISCARD
|
||||
@ -1868,6 +1869,8 @@ struct mbedtls_ssl_context {
|
||||
*/
|
||||
uint8_t MBEDTLS_PRIVATE(discard_early_data_record);
|
||||
#endif
|
||||
uint32_t MBEDTLS_PRIVATE(total_early_data_size); /*!< Number of received/written early data bytes */
|
||||
#endif /* MBEDTLS_SSL_EARLY_DATA */
|
||||
|
||||
/*
|
||||
* Record layer (outgoing data)
|
||||
|
@ -2150,6 +2150,9 @@ int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl,
|
||||
unsigned char *buf,
|
||||
const unsigned char *end,
|
||||
size_t *out_len);
|
||||
|
||||
int mbedtls_ssl_tls13_check_early_data_len(mbedtls_ssl_context *ssl,
|
||||
size_t early_data_len);
|
||||
#endif /* MBEDTLS_SSL_EARLY_DATA */
|
||||
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
@ -4005,7 +4005,11 @@ static int ssl_prepare_record_content(mbedtls_ssl_context *ssl,
|
||||
MBEDTLS_SSL_EARLY_DATA_TRY_TO_DEPROTECT_AND_DISCARD)) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
3, ("EarlyData: deprotect and discard app data records."));
|
||||
/* TODO: Add max_early_data_size check here, see issue 6347 */
|
||||
|
||||
ret = mbedtls_ssl_tls13_check_early_data_len(ssl, rec->data_len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_SRV_C */
|
||||
@ -4129,9 +4133,15 @@ static int ssl_prepare_record_content(mbedtls_ssl_context *ssl,
|
||||
*/
|
||||
if (ssl->discard_early_data_record == MBEDTLS_SSL_EARLY_DATA_DISCARD) {
|
||||
if (rec->type == MBEDTLS_SSL_MSG_APPLICATION_DATA) {
|
||||
|
||||
ret = mbedtls_ssl_tls13_check_early_data_len(ssl, rec->data_len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
3, ("EarlyData: Ignore application message before 2nd ClientHello"));
|
||||
/* TODO: Add max_early_data_size check here, see issue 6347 */
|
||||
|
||||
return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
|
||||
} else if (rec->type == MBEDTLS_SSL_MSG_HANDSHAKE) {
|
||||
ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD;
|
||||
|
@ -1101,6 +1101,7 @@ static int ssl_handshake_init(mbedtls_ssl_context *ssl)
|
||||
#if defined(MBEDTLS_SSL_SRV_C)
|
||||
ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD;
|
||||
#endif
|
||||
ssl->total_early_data_size = 0;
|
||||
#endif /* MBEDTLS_SSL_EARLY_DATA */
|
||||
|
||||
/* Initialize structures */
|
||||
|
@ -1454,6 +1454,54 @@ int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_SRV_C)
|
||||
int mbedtls_ssl_tls13_check_early_data_len(mbedtls_ssl_context *ssl,
|
||||
size_t early_data_len)
|
||||
{
|
||||
/*
|
||||
* This function should be called only while an handshake is in progress
|
||||
* and thus a session under negotiation. Add a sanity check to detect a
|
||||
* misuse.
|
||||
*/
|
||||
if (ssl->session_negotiate == NULL) {
|
||||
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
/* RFC 8446 section 4.6.1
|
||||
*
|
||||
* A server receiving more than max_early_data_size bytes of 0-RTT data
|
||||
* SHOULD terminate the connection with an "unexpected_message" alert.
|
||||
* Note that if it is still possible to send early_data_len bytes of early
|
||||
* data, it means that early_data_len is smaller than max_early_data_size
|
||||
* (type uint32_t) and can fit in an uint32_t. We use this further
|
||||
* down.
|
||||
*/
|
||||
if (early_data_len >
|
||||
(ssl->session_negotiate->max_early_data_size -
|
||||
ssl->total_early_data_size)) {
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG(
|
||||
2, ("EarlyData: Too much early data received, %u + %" MBEDTLS_PRINTF_SIZET " > %u",
|
||||
ssl->total_early_data_size, early_data_len,
|
||||
ssl->session_negotiate->max_early_data_size));
|
||||
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(
|
||||
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE,
|
||||
MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE);
|
||||
return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
|
||||
}
|
||||
|
||||
/*
|
||||
* early_data_len has been checked to be less than max_early_data_size
|
||||
* that is uint32_t. Its cast to an uint32_t below is thus safe. We need
|
||||
* the cast to appease some compilers.
|
||||
*/
|
||||
ssl->total_early_data_size += (uint32_t) early_data_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_SRV_C */
|
||||
#endif /* MBEDTLS_SSL_EARLY_DATA */
|
||||
|
||||
/* Reset SSL context and update hash for handling HRR.
|
||||
|
@ -2906,17 +2906,14 @@ static int ssl_tls13_end_of_early_data_coordinate(mbedtls_ssl_context *ssl)
|
||||
}
|
||||
|
||||
if (ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("Received early data"));
|
||||
/* RFC 8446 section 4.6.1
|
||||
*
|
||||
* A server receiving more than max_early_data_size bytes of 0-RTT data
|
||||
* SHOULD terminate the connection with an "unexpected_message" alert.
|
||||
*
|
||||
* TODO: Add received data size check here.
|
||||
*/
|
||||
if (ssl->in_offt == NULL) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(3, ("Received early data"));
|
||||
/* Set the reading pointer */
|
||||
ssl->in_offt = ssl->in_msg;
|
||||
ret = mbedtls_ssl_tls13_check_early_data_len(ssl, ssl->in_msglen);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return SSL_GOT_EARLY_DATA;
|
||||
}
|
||||
@ -3134,6 +3131,7 @@ static int ssl_tls13_prepare_new_session_ticket(mbedtls_ssl_context *ssl,
|
||||
ssl->conf->max_early_data_size > 0) {
|
||||
mbedtls_ssl_tls13_session_set_ticket_flags(
|
||||
session, MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA);
|
||||
session->max_early_data_size = ssl->conf->max_early_data_size;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_EARLY_DATA */
|
||||
|
||||
|
@ -114,6 +114,7 @@ typedef struct mbedtls_test_handshake_test_options {
|
||||
void (*cli_log_fun)(void *, int, const char *, int, const char *);
|
||||
int resize_buffers;
|
||||
int early_data;
|
||||
int max_early_data_size;
|
||||
#if defined(MBEDTLS_SSL_CACHE_C)
|
||||
mbedtls_ssl_cache_context *cache;
|
||||
#endif
|
||||
|
@ -67,6 +67,7 @@ void mbedtls_test_init_handshake_options(
|
||||
opts->legacy_renegotiation = MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION;
|
||||
opts->resize_buffers = 1;
|
||||
opts->early_data = MBEDTLS_SSL_EARLY_DATA_DISABLED;
|
||||
opts->max_early_data_size = -1;
|
||||
#if defined(MBEDTLS_SSL_CACHE_C)
|
||||
TEST_CALLOC(opts->cache, 1);
|
||||
mbedtls_ssl_cache_init(opts->cache);
|
||||
@ -825,6 +826,13 @@ int mbedtls_test_ssl_endpoint_init(
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA)
|
||||
mbedtls_ssl_conf_early_data(&(ep->conf), options->early_data);
|
||||
#if defined(MBEDTLS_SSL_SRV_C)
|
||||
if (endpoint_type == MBEDTLS_SSL_IS_SERVER &&
|
||||
(options->max_early_data_size >= 0)) {
|
||||
mbedtls_ssl_conf_max_early_data_size(&(ep->conf),
|
||||
options->max_early_data_size);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_CACHE_C) && defined(MBEDTLS_SSL_SRV_C)
|
||||
|
@ -3309,3 +3309,39 @@ tls13_write_early_data:TEST_EARLY_DATA_SERVER_REJECTS
|
||||
|
||||
TLS 1.3 write early data, hello retry request
|
||||
tls13_write_early_data:TEST_EARLY_DATA_HRR
|
||||
|
||||
TLS 1.3 srv, max early data size, dflt, wsz=96
|
||||
tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:-1:96
|
||||
|
||||
TLS 1.3 srv, max early data size, dflt, wsz=128
|
||||
tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:-1:128
|
||||
|
||||
TLS 1.3 srv, max early data size, 3, wsz=2
|
||||
tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:3:2
|
||||
|
||||
TLS 1.3 srv, max early data size, 3, wsz=3
|
||||
tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:3:3
|
||||
|
||||
TLS 1.3 srv, max early data size, 98, wsz=23
|
||||
tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:98:23
|
||||
|
||||
TLS 1.3 srv, max early data size, 98, wsz=49
|
||||
tls13_srv_max_early_data_size:TEST_EARLY_DATA_ACCEPTED:98:49
|
||||
|
||||
TLS 1.3 srv, max early data size, server rejects, dflt, wsz=128
|
||||
tls13_srv_max_early_data_size:TEST_EARLY_DATA_SERVER_REJECTS:-1:128
|
||||
|
||||
TLS 1.3 srv, max early data size, server rejects, 3, wsz=3
|
||||
tls13_srv_max_early_data_size:TEST_EARLY_DATA_SERVER_REJECTS:3:3
|
||||
|
||||
TLS 1.3 srv, max early data size, server rejects, 98, wsz=49
|
||||
tls13_srv_max_early_data_size:TEST_EARLY_DATA_SERVER_REJECTS:98:49
|
||||
|
||||
TLS 1.3 srv, max early data size, HRR, dflt, wsz=128
|
||||
tls13_srv_max_early_data_size:TEST_EARLY_DATA_HRR:-1:128
|
||||
|
||||
TLS 1.3 srv, max early data size, HRR, 3, wsz=3
|
||||
tls13_srv_max_early_data_size:TEST_EARLY_DATA_HRR:3:3
|
||||
|
||||
TLS 1.3 srv, max early data size, HRR, 98, wsz=49
|
||||
tls13_srv_max_early_data_size:TEST_EARLY_DATA_HRR:97:0
|
||||
|
@ -18,6 +18,47 @@
|
||||
#define TEST_EARLY_DATA_SERVER_REJECTS 2
|
||||
#define TEST_EARLY_DATA_HRR 3
|
||||
|
||||
#if (!defined(MBEDTLS_SSL_PROTO_TLS1_2)) && \
|
||||
defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C) && \
|
||||
defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_DEBUG_C) && \
|
||||
defined(MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE) && \
|
||||
defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) && \
|
||||
defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED) && \
|
||||
defined(MBEDTLS_MD_CAN_SHA256) && \
|
||||
defined(MBEDTLS_ECP_HAVE_SECP256R1) && defined(MBEDTLS_ECP_HAVE_SECP384R1) && \
|
||||
defined(MBEDTLS_PK_CAN_ECDSA_VERIFY) && defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
/*
|
||||
* Test function to write early data for negative tests where
|
||||
* mbedtls_ssl_write_early_data() cannot be used.
|
||||
*/
|
||||
static int write_early_data(mbedtls_ssl_context *ssl,
|
||||
unsigned char *buf, size_t len)
|
||||
{
|
||||
int ret = mbedtls_ssl_get_max_out_record_payload(ssl);
|
||||
|
||||
TEST_ASSERT(ret > 0);
|
||||
TEST_LE_U(len, (size_t) ret);
|
||||
|
||||
ret = mbedtls_ssl_flush_output(ssl);
|
||||
TEST_EQUAL(ret, 0);
|
||||
TEST_EQUAL(ssl->out_left, 0);
|
||||
|
||||
ssl->out_msglen = len;
|
||||
ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA;
|
||||
if (len > 0) {
|
||||
memcpy(ssl->out_msg, buf, len);
|
||||
}
|
||||
|
||||
ret = mbedtls_ssl_write_record(ssl, 1);
|
||||
TEST_EQUAL(ret, 0);
|
||||
|
||||
ret = len;
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* END_HEADER */
|
||||
|
||||
/* BEGIN_DEPENDENCIES
|
||||
@ -4168,6 +4209,10 @@ void tls13_write_early_data(int scenario)
|
||||
break;
|
||||
|
||||
case TEST_EARLY_DATA_HRR:
|
||||
/*
|
||||
* Remove server support for the group negotiated in
|
||||
* mbedtls_test_get_tls13_ticket() forcing a HelloRetryRequest.
|
||||
*/
|
||||
server_options.group_list = group_list + 1;
|
||||
break;
|
||||
|
||||
@ -4457,3 +4502,259 @@ exit:
|
||||
PSA_DONE();
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/*
|
||||
* The !MBEDTLS_SSL_PROTO_TLS1_2 dependency of tls13_early_data() below is
|
||||
* a temporary workaround to not run the test in Windows-2013 where there is
|
||||
* an issue with mbedtls_vsnprintf().
|
||||
*/
|
||||
/* BEGIN_CASE depends_on:!MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_EARLY_DATA:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_DEBUG_C:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED:MBEDTLS_MD_CAN_SHA256:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_PK_CAN_ECDSA_VERIFY:MBEDTLS_SSL_SESSION_TICKETS */
|
||||
void tls13_srv_max_early_data_size(int scenario, int max_early_data_size_arg, int write_size_arg)
|
||||
{
|
||||
int ret = -1;
|
||||
mbedtls_test_ssl_endpoint client_ep, server_ep;
|
||||
mbedtls_test_handshake_test_options client_options;
|
||||
mbedtls_test_handshake_test_options server_options;
|
||||
mbedtls_ssl_session saved_session;
|
||||
mbedtls_test_ssl_log_pattern server_pattern = { NULL, 0 };
|
||||
uint16_t group_list[3] = {
|
||||
MBEDTLS_SSL_IANA_TLS_GROUP_SECP256R1,
|
||||
MBEDTLS_SSL_IANA_TLS_GROUP_SECP384R1,
|
||||
MBEDTLS_SSL_IANA_TLS_GROUP_NONE
|
||||
};
|
||||
char pattern[128];
|
||||
unsigned char *buf_write = NULL;
|
||||
uint32_t write_size = (uint32_t) write_size_arg;
|
||||
unsigned char *buf_read = NULL;
|
||||
uint32_t read_size;
|
||||
uint32_t expanded_early_data_chunk_size = 0;
|
||||
uint32_t written_early_data_size = 0;
|
||||
uint32_t max_early_data_size;
|
||||
|
||||
mbedtls_platform_zeroize(&client_ep, sizeof(client_ep));
|
||||
mbedtls_platform_zeroize(&server_ep, sizeof(server_ep));
|
||||
mbedtls_test_init_handshake_options(&client_options);
|
||||
mbedtls_test_init_handshake_options(&server_options);
|
||||
mbedtls_ssl_session_init(&saved_session);
|
||||
PSA_INIT();
|
||||
|
||||
TEST_CALLOC(buf_write, write_size);
|
||||
|
||||
/*
|
||||
* Allocate a smaller buffer for early data reading to exercise the reading
|
||||
* of data in one record in multiple calls.
|
||||
*/
|
||||
read_size = (write_size / 2) + 1;
|
||||
TEST_CALLOC(buf_read, read_size);
|
||||
|
||||
/*
|
||||
* Run first handshake to get a ticket from the server.
|
||||
*/
|
||||
|
||||
client_options.pk_alg = MBEDTLS_PK_ECDSA;
|
||||
client_options.group_list = group_list;
|
||||
client_options.early_data = MBEDTLS_SSL_EARLY_DATA_ENABLED;
|
||||
server_options.pk_alg = MBEDTLS_PK_ECDSA;
|
||||
server_options.group_list = group_list;
|
||||
server_options.early_data = MBEDTLS_SSL_EARLY_DATA_ENABLED;
|
||||
server_options.max_early_data_size = max_early_data_size_arg;
|
||||
|
||||
ret = mbedtls_test_get_tls13_ticket(&client_options, &server_options,
|
||||
&saved_session);
|
||||
TEST_EQUAL(ret, 0);
|
||||
|
||||
/*
|
||||
* Prepare for handshake with the ticket.
|
||||
*/
|
||||
server_options.srv_log_fun = mbedtls_test_ssl_log_analyzer;
|
||||
server_options.srv_log_obj = &server_pattern;
|
||||
server_pattern.pattern = pattern;
|
||||
|
||||
switch (scenario) {
|
||||
case TEST_EARLY_DATA_ACCEPTED:
|
||||
break;
|
||||
|
||||
case TEST_EARLY_DATA_SERVER_REJECTS:
|
||||
server_options.early_data = MBEDTLS_SSL_EARLY_DATA_DISABLED;
|
||||
ret = mbedtls_snprintf(pattern, sizeof(pattern),
|
||||
"EarlyData: deprotect and discard app data records.");
|
||||
TEST_ASSERT(ret < (int) sizeof(pattern));
|
||||
mbedtls_debug_set_threshold(3);
|
||||
break;
|
||||
|
||||
case TEST_EARLY_DATA_HRR:
|
||||
/*
|
||||
* Remove server support for the group negotiated in
|
||||
* mbedtls_test_get_tls13_ticket() forcing an HelloRetryRequest.
|
||||
*/
|
||||
server_options.group_list = group_list + 1;
|
||||
ret = mbedtls_snprintf(
|
||||
pattern, sizeof(pattern),
|
||||
"EarlyData: Ignore application message before 2nd ClientHello");
|
||||
TEST_ASSERT(ret < (int) sizeof(pattern));
|
||||
mbedtls_debug_set_threshold(3);
|
||||
break;
|
||||
|
||||
default:
|
||||
TEST_FAIL("Unknown scenario.");
|
||||
}
|
||||
|
||||
ret = mbedtls_test_ssl_endpoint_init(&client_ep, MBEDTLS_SSL_IS_CLIENT,
|
||||
&client_options, NULL, NULL, NULL);
|
||||
TEST_EQUAL(ret, 0);
|
||||
|
||||
ret = mbedtls_test_ssl_endpoint_init(&server_ep, MBEDTLS_SSL_IS_SERVER,
|
||||
&server_options, NULL, NULL, NULL);
|
||||
TEST_EQUAL(ret, 0);
|
||||
|
||||
mbedtls_ssl_conf_session_tickets_cb(&server_ep.conf,
|
||||
mbedtls_test_ticket_write,
|
||||
mbedtls_test_ticket_parse,
|
||||
NULL);
|
||||
|
||||
ret = mbedtls_test_mock_socket_connect(&(client_ep.socket),
|
||||
&(server_ep.socket), 1024);
|
||||
TEST_EQUAL(ret, 0);
|
||||
|
||||
max_early_data_size = saved_session.max_early_data_size;
|
||||
|
||||
ret = mbedtls_ssl_set_session(&(client_ep.ssl), &saved_session);
|
||||
TEST_EQUAL(ret, 0);
|
||||
|
||||
/*
|
||||
* Start an handshake based on the ticket up to the point where early data
|
||||
* can be sent from client side. Then send in a loop as much early data as
|
||||
* possible without going over the maximum permitted size for the ticket.
|
||||
* Finally, do a last writting to go past that maximum permitted size and
|
||||
* check that we detect it.
|
||||
*/
|
||||
TEST_EQUAL(mbedtls_test_move_handshake_to_state(
|
||||
&(client_ep.ssl), &(server_ep.ssl),
|
||||
MBEDTLS_SSL_SERVER_HELLO), 0);
|
||||
|
||||
TEST_ASSERT(client_ep.ssl.early_data_status !=
|
||||
MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT);
|
||||
|
||||
ret = mbedtls_ssl_handshake(&(server_ep.ssl));
|
||||
TEST_EQUAL(ret, MBEDTLS_ERR_SSL_WANT_READ);
|
||||
|
||||
/*
|
||||
* Write and if possible read as much as possible chunks of write_size
|
||||
* bytes data without getting over the max_early_data_size limit.
|
||||
*/
|
||||
do {
|
||||
uint32_t read_early_data_size = 0;
|
||||
|
||||
/*
|
||||
* The contents of the early data are not very important, write a
|
||||
* pattern that varies byte-by-byte and is different for every chunk of
|
||||
* early data.
|
||||
*/
|
||||
if ((written_early_data_size + write_size) > max_early_data_size) {
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the server rejected early data, base the determination of when
|
||||
* to stop the loop on the expanded size (padding and encryption
|
||||
* expansion) of early data on server side and the number of early data
|
||||
* received so far by the server (multiple of the expanded size).
|
||||
*/
|
||||
if ((expanded_early_data_chunk_size != 0) &&
|
||||
((server_ep.ssl.total_early_data_size +
|
||||
expanded_early_data_chunk_size) > max_early_data_size)) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < write_size; i++) {
|
||||
buf_write[i] = (unsigned char) (written_early_data_size + i);
|
||||
}
|
||||
|
||||
ret = write_early_data(&(client_ep.ssl), buf_write, write_size);
|
||||
TEST_EQUAL(ret, write_size);
|
||||
written_early_data_size += write_size;
|
||||
|
||||
switch (scenario) {
|
||||
case TEST_EARLY_DATA_ACCEPTED:
|
||||
while (read_early_data_size < write_size) {
|
||||
ret = mbedtls_ssl_handshake(&(server_ep.ssl));
|
||||
TEST_EQUAL(ret, MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA);
|
||||
|
||||
ret = mbedtls_ssl_read_early_data(&(server_ep.ssl),
|
||||
buf_read, read_size);
|
||||
TEST_ASSERT(ret > 0);
|
||||
|
||||
TEST_MEMORY_COMPARE(buf_read, ret,
|
||||
buf_write + read_early_data_size, ret);
|
||||
read_early_data_size += ret;
|
||||
|
||||
TEST_EQUAL(server_ep.ssl.total_early_data_size,
|
||||
written_early_data_size);
|
||||
}
|
||||
break;
|
||||
|
||||
case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */
|
||||
case TEST_EARLY_DATA_HRR:
|
||||
ret = mbedtls_ssl_handshake(&(server_ep.ssl));
|
||||
/*
|
||||
* In this write loop we try to always stay below the
|
||||
* max_early_data_size limit but if max_early_data_size is very
|
||||
* small we may exceed the max_early_data_size limit on the
|
||||
* first write. In TEST_EARLY_DATA_SERVER_REJECTS/
|
||||
* TEST_EARLY_DATA_HRR scenario, this is for sure the case if
|
||||
* max_early_data_size is smaller than the smallest possible
|
||||
* inner content/protected record. Take into account this
|
||||
* possibility here but only for max_early_data_size values
|
||||
* that are close to write_size. Below, '1' is for the inner
|
||||
* type byte and '16' is to take into account some AEAD
|
||||
* expansion (tag, ...).
|
||||
*/
|
||||
if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE) {
|
||||
if (scenario == TEST_EARLY_DATA_SERVER_REJECTS) {
|
||||
TEST_LE_U(max_early_data_size,
|
||||
write_size + 1 +
|
||||
MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY);
|
||||
} else {
|
||||
TEST_LE_U(max_early_data_size,
|
||||
write_size + 1 + 16 +
|
||||
MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY);
|
||||
}
|
||||
goto exit;
|
||||
}
|
||||
|
||||
TEST_ASSERT(ret == MBEDTLS_ERR_SSL_WANT_READ);
|
||||
|
||||
TEST_EQUAL(server_pattern.counter, 1);
|
||||
server_pattern.counter = 0;
|
||||
if (expanded_early_data_chunk_size == 0) {
|
||||
expanded_early_data_chunk_size = server_ep.ssl.total_early_data_size;
|
||||
}
|
||||
break;
|
||||
}
|
||||
TEST_LE_U(server_ep.ssl.total_early_data_size, max_early_data_size);
|
||||
} while (1);
|
||||
|
||||
mbedtls_debug_set_threshold(3);
|
||||
ret = write_early_data(&(client_ep.ssl), buf_write, write_size);
|
||||
TEST_EQUAL(ret, write_size);
|
||||
|
||||
ret = mbedtls_snprintf(pattern, sizeof(pattern),
|
||||
"EarlyData: Too much early data received");
|
||||
TEST_ASSERT(ret < (int) sizeof(pattern));
|
||||
|
||||
ret = mbedtls_ssl_handshake(&(server_ep.ssl));
|
||||
TEST_EQUAL(ret, MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE);
|
||||
TEST_EQUAL(server_pattern.counter, 1);
|
||||
|
||||
exit:
|
||||
mbedtls_test_ssl_endpoint_free(&client_ep, NULL);
|
||||
mbedtls_test_ssl_endpoint_free(&server_ep, NULL);
|
||||
mbedtls_test_free_handshake_options(&client_options);
|
||||
mbedtls_test_free_handshake_options(&server_options);
|
||||
mbedtls_ssl_session_free(&saved_session);
|
||||
mbedtls_free(buf_write);
|
||||
mbedtls_free(buf_read);
|
||||
mbedtls_debug_set_threshold(0);
|
||||
PSA_DONE();
|
||||
}
|
||||
/* END_CASE */
|
||||
|
Loading…
x
Reference in New Issue
Block a user