Merge pull request #8755 from ronald-cron-arm/tls13-client-early-data-status

TLS 1.3: Refine and test client early data status
This commit is contained in:
Manuel Pégourié-Gonnard 2024-02-13 20:36:42 +00:00 committed by GitHub
commit e6c80bc6e5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 607 additions and 208 deletions

View file

@ -5106,9 +5106,9 @@ int mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl);
#if defined(MBEDTLS_SSL_EARLY_DATA)
#define MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT 0
#define MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED 1
#define MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED 2
#define MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT 1
#define MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED 2
#define MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED 3
#if defined(MBEDTLS_SSL_SRV_C)
/**

View file

@ -731,14 +731,23 @@ struct mbedtls_ssl_handshake_params {
uint8_t key_exchange_mode; /*!< Selected key exchange mode */
/** Number of HelloRetryRequest messages received/sent from/to the server. */
int hello_retry_request_count;
uint8_t hello_retry_request_count;
#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
/**
* Number of dummy change_cipher_spec (CCS) record sent. Used to send only
* one CCS per handshake without having to complicate the handshake state
* transitions.
*/
uint8_t ccs_count;
#endif
#if defined(MBEDTLS_SSL_SRV_C)
/** selected_group of key_share extension in HelloRetryRequest message. */
uint16_t hrr_selected_group;
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
uint8_t tls13_kex_modes; /*!< Key exchange modes supported by the client */
#endif
/** selected_group of key_share extension in HelloRetryRequest message. */
uint16_t hrr_selected_group;
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
uint16_t new_session_tickets_count; /*!< number of session tickets */
#endif
@ -2136,6 +2145,38 @@ int mbedtls_ssl_tls13_write_early_data_ext(mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
size_t *out_len);
#if defined(MBEDTLS_SSL_CLI_C)
/*
* The client has not sent the first ClientHello yet, it is unknown if the
* client will send an early data indication extension or not.
*/
#define MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN 0
/*
* The client has sent an early data indication extension in its first
* ClientHello, it has not received the response (ServerHello or
* HelloRetryRequest) from the server yet. The transform to protect early data
* is not set and early data cannot be sent yet.
*/
#define MBEDTLS_SSL_EARLY_DATA_STATUS_SENT 4
/*
* The client has sent an early data indication extension in its first
* ClientHello, it has not received the response (ServerHello or
* HelloRetryRequest) from the server yet. The transform to protect early data
* has been set and early data can be written now.
*/
#define MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE 5
/*
* The client has sent an early data indication extension in its first
* ClientHello, the server has accepted them and the client has received the
* server Finished message. It cannot send early data to the server anymore.
*/
#define MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED 6
#endif /* MBEDTLS_SSL_CLI_C */
#endif /* MBEDTLS_SSL_EARLY_DATA */
#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */

View file

@ -1100,7 +1100,7 @@ static int ssl_handshake_init(mbedtls_ssl_context *ssl)
#if defined(MBEDTLS_SSL_EARLY_DATA)
#if defined(MBEDTLS_SSL_CLI_C)
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT;
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN;
#endif
#if defined(MBEDTLS_SSL_SRV_C)
ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD;

View file

@ -1180,26 +1180,21 @@ int mbedtls_ssl_tls13_write_client_hello_exts(mbedtls_ssl_context *ssl,
#endif
#if defined(MBEDTLS_SSL_EARLY_DATA)
if (mbedtls_ssl_conf_tls13_is_some_psk_enabled(ssl) &&
ssl_tls13_early_data_has_valid_ticket(ssl) &&
ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_ENABLED &&
ssl->handshake->hello_retry_request_count == 0) {
if (ssl->handshake->hello_retry_request_count == 0) {
if (mbedtls_ssl_conf_tls13_is_some_psk_enabled(ssl) &&
ssl_tls13_early_data_has_valid_ticket(ssl) &&
ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_ENABLED) {
ret = mbedtls_ssl_tls13_write_early_data_ext(
ssl, 0, p, end, &ext_len);
if (ret != 0) {
return ret;
}
p += ext_len;
ret = mbedtls_ssl_tls13_write_early_data_ext(
ssl, 0, p, end, &ext_len);
if (ret != 0) {
return ret;
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_SENT;
} else {
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT;
}
p += ext_len;
/* Initializes the status to `rejected`. It will be updated to
* `accepted` if the EncryptedExtension message contain an early data
* indication extension.
*/
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED;
} else {
MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write early_data extension"));
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT;
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
@ -1236,7 +1231,7 @@ int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl)
size_t psk_len;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED) {
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_SENT) {
MBEDTLS_SSL_DEBUG_MSG(
1, ("Set hs psk for early data when writing the first psk"));
@ -1299,6 +1294,7 @@ int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl)
1, ("Switch to early data keys for outbound traffic"));
mbedtls_ssl_set_outbound_transform(
ssl, ssl->handshake->transform_earlydata);
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE;
#endif
}
#endif /* MBEDTLS_SSL_EARLY_DATA */
@ -1971,6 +1967,13 @@ static int ssl_tls13_postprocess_hrr(mbedtls_ssl_context *ssl)
}
ssl->session_negotiate->ciphersuite = ssl->handshake->ciphersuite_info->id;
#if defined(MBEDTLS_SSL_EARLY_DATA)
if (ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT) {
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED;
}
#endif
return 0;
}
@ -2230,6 +2233,8 @@ static int ssl_tls13_process_encrypted_extensions(mbedtls_ssl_context *ssl)
}
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED;
} else if (ssl->early_data_status != MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT) {
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED;
}
#endif
@ -2567,9 +2572,8 @@ static int ssl_tls13_process_server_finished(mbedtls_ssl_context *ssl)
#if defined(MBEDTLS_SSL_EARLY_DATA)
if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED) {
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED;
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_END_OF_EARLY_DATA);
} else if (ssl->early_data_status == MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED) {
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
} else
#endif /* MBEDTLS_SSL_EARLY_DATA */
{
@ -3059,18 +3063,25 @@ int mbedtls_ssl_tls13_handshake_client_step(mbedtls_ssl_context *ssl)
*/
#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
case MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO:
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
if (ret == 0) {
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO);
ret = 0;
if (ssl->handshake->ccs_count == 0) {
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
if (ret != 0) {
break;
}
}
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO);
break;
case MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED:
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
if (ret == 0) {
mbedtls_ssl_handshake_set_state(
ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
ret = 0;
if (ssl->handshake->ccs_count == 0) {
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
if (ret != 0) {
break;
}
}
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
break;
#if defined(MBEDTLS_SSL_EARLY_DATA)
@ -3083,6 +3094,7 @@ int mbedtls_ssl_tls13_handshake_client_step(mbedtls_ssl_context *ssl)
1, ("Switch to early data keys for outbound traffic"));
mbedtls_ssl_set_outbound_transform(
ssl, ssl->handshake->transform_earlydata);
ssl->early_data_status = MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE;
}
break;
#endif /* MBEDTLS_SSL_EARLY_DATA */

View file

@ -1390,6 +1390,8 @@ int mbedtls_ssl_tls13_write_change_cipher_spec(mbedtls_ssl_context *ssl)
/* Dispatch message */
MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_write_record(ssl, 0));
ssl->handshake->ccs_count++;
cleanup:
MBEDTLS_SSL_DEBUG_MSG(2, ("<= write change cipher spec"));

View file

@ -3482,10 +3482,14 @@ int mbedtls_ssl_tls13_handshake_server_step(mbedtls_ssl_context *ssl)
break;
case MBEDTLS_SSL_SERVER_CCS_AFTER_SERVER_HELLO:
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
if (ret == 0) {
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS);
ret = 0;
if (ssl->handshake->ccs_count == 0) {
ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
if (ret != 0) {
break;
}
}
mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS);
break;
#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */

View file

@ -85,6 +85,7 @@ typedef struct mbedtls_test_ssl_log_pattern {
typedef struct mbedtls_test_handshake_test_options {
const char *cipher;
uint16_t *group_list;
mbedtls_ssl_protocol_version client_min_version;
mbedtls_ssl_protocol_version client_max_version;
mbedtls_ssl_protocol_version server_min_version;
@ -112,6 +113,7 @@ typedef struct mbedtls_test_handshake_test_options {
void (*srv_log_fun)(void *, int, const char *, int, const char *);
void (*cli_log_fun)(void *, int, const char *, int, const char *);
int resize_buffers;
int early_data;
#if defined(MBEDTLS_SSL_CACHE_C)
mbedtls_ssl_cache_context *cache;
#endif
@ -440,8 +442,7 @@ int mbedtls_test_ssl_endpoint_init(
mbedtls_test_handshake_test_options *options,
mbedtls_test_message_socket_context *dtls_context,
mbedtls_test_ssl_message_queue *input_queue,
mbedtls_test_ssl_message_queue *output_queue,
uint16_t *group_list);
mbedtls_test_ssl_message_queue *output_queue);
/*
* Deinitializes endpoint represented by \p ep.
@ -599,6 +600,17 @@ int mbedtls_test_ticket_parse(void *p_ticket, mbedtls_ssl_session *session,
unsigned char *buf, size_t len);
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
#if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_SRV_C) && \
defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS) && \
defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
int mbedtls_test_get_tls13_ticket(
mbedtls_test_handshake_test_options *client_options,
mbedtls_test_handshake_test_options *server_options,
mbedtls_ssl_session *session);
#endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_SSL_SRV_C &&
MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS &&
MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
#define ECJPAKE_TEST_PWD "bla"
#if defined(MBEDTLS_USE_PSA_CRYPTO)

View file

@ -49,36 +49,26 @@ void mbedtls_test_init_handshake_options(
srand(rng_seed);
rng_seed += 0xD0;
#endif
memset(opts, 0, sizeof(*opts));
opts->cipher = "";
opts->client_min_version = MBEDTLS_SSL_VERSION_UNKNOWN;
opts->client_max_version = MBEDTLS_SSL_VERSION_UNKNOWN;
opts->server_min_version = MBEDTLS_SSL_VERSION_UNKNOWN;
opts->server_max_version = MBEDTLS_SSL_VERSION_UNKNOWN;
opts->expected_negotiated_version = MBEDTLS_SSL_VERSION_TLS1_3;
opts->expected_handshake_result = 0;
opts->expected_ciphersuite = 0;
opts->pk_alg = MBEDTLS_PK_RSA;
opts->opaque_alg = 0;
opts->opaque_alg2 = 0;
opts->opaque_usage = 0;
opts->psk_str = NULL;
opts->dtls = 0;
opts->srv_auth_mode = MBEDTLS_SSL_VERIFY_NONE;
opts->serialize = 0;
opts->mfl = MBEDTLS_SSL_MAX_FRAG_LEN_NONE;
opts->cli_msg_len = 100;
opts->srv_msg_len = 100;
opts->expected_cli_fragments = 1;
opts->expected_srv_fragments = 1;
opts->renegotiate = 0;
opts->legacy_renegotiation = MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION;
opts->srv_log_obj = NULL;
opts->cli_log_obj = NULL;
opts->srv_log_fun = NULL;
opts->cli_log_fun = NULL;
opts->resize_buffers = 1;
opts->early_data = MBEDTLS_SSL_EARLY_DATA_DISABLED;
#if defined(MBEDTLS_SSL_CACHE_C)
opts->cache = NULL;
TEST_CALLOC(opts->cache, 1);
mbedtls_ssl_cache_init(opts->cache);
#if defined(MBEDTLS_HAVE_TIME)
@ -733,8 +723,7 @@ int mbedtls_test_ssl_endpoint_init(
mbedtls_test_handshake_test_options *options,
mbedtls_test_message_socket_context *dtls_context,
mbedtls_test_ssl_message_queue *input_queue,
mbedtls_test_ssl_message_queue *output_queue,
uint16_t *group_list)
mbedtls_test_ssl_message_queue *output_queue)
{
int ret = -1;
uintptr_t user_data_n;
@ -818,12 +807,16 @@ int mbedtls_test_ssl_endpoint_init(
}
}
if (group_list != NULL) {
mbedtls_ssl_conf_groups(&(ep->conf), group_list);
if (options->group_list != NULL) {
mbedtls_ssl_conf_groups(&(ep->conf), options->group_list);
}
mbedtls_ssl_conf_authmode(&(ep->conf), MBEDTLS_SSL_VERIFY_REQUIRED);
#if defined(MBEDTLS_SSL_EARLY_DATA)
mbedtls_ssl_conf_early_data(&(ep->conf), options->early_data);
#endif
#if defined(MBEDTLS_SSL_CACHE_C) && defined(MBEDTLS_SSL_SRV_C)
if (endpoint_type == MBEDTLS_SSL_IS_SERVER && options->cache != NULL) {
mbedtls_ssl_conf_session_cache(&(ep->conf), options->cache,
@ -2006,7 +1999,7 @@ void mbedtls_test_ssl_perform_handshake(
MBEDTLS_SSL_IS_CLIENT,
options, &client_context,
&client_queue,
&server_queue, NULL) == 0);
&server_queue) == 0);
#if defined(MBEDTLS_TIMING_C)
mbedtls_ssl_set_timer_cb(&client.ssl, &timer_client,
mbedtls_timing_set_delay,
@ -2016,7 +2009,7 @@ void mbedtls_test_ssl_perform_handshake(
TEST_ASSERT(mbedtls_test_ssl_endpoint_init(&client,
MBEDTLS_SSL_IS_CLIENT,
options, NULL, NULL,
NULL, NULL) == 0);
NULL) == 0);
}
if (strlen(options->cipher) > 0) {
@ -2029,7 +2022,7 @@ void mbedtls_test_ssl_perform_handshake(
MBEDTLS_SSL_IS_SERVER,
options, &server_context,
&server_queue,
&client_queue, NULL) == 0);
&client_queue) == 0);
#if defined(MBEDTLS_TIMING_C)
mbedtls_ssl_set_timer_cb(&server.ssl, &timer_server,
mbedtls_timing_set_delay,
@ -2038,7 +2031,7 @@ void mbedtls_test_ssl_perform_handshake(
} else {
TEST_ASSERT(mbedtls_test_ssl_endpoint_init(&server,
MBEDTLS_SSL_IS_SERVER,
options, NULL, NULL, NULL,
options, NULL, NULL,
NULL) == 0);
}
@ -2462,4 +2455,60 @@ int mbedtls_test_ticket_parse(void *p_ticket, mbedtls_ssl_session *session,
return mbedtls_ssl_session_load(session, buf, len);
}
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
#if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_SRV_C) && \
defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_SSL_SESSION_TICKETS) && \
defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
int mbedtls_test_get_tls13_ticket(
mbedtls_test_handshake_test_options *client_options,
mbedtls_test_handshake_test_options *server_options,
mbedtls_ssl_session *session)
{
int ret = -1;
unsigned char buf[64];
mbedtls_test_ssl_endpoint client_ep, server_ep;
mbedtls_platform_zeroize(&client_ep, sizeof(client_ep));
mbedtls_platform_zeroize(&server_ep, sizeof(server_ep));
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);
TEST_EQUAL(mbedtls_test_move_handshake_to_state(
&(server_ep.ssl), &(client_ep.ssl),
MBEDTLS_SSL_HANDSHAKE_OVER), 0);
TEST_EQUAL(server_ep.ssl.handshake->new_session_tickets_count, 0);
do {
ret = mbedtls_ssl_read(&(client_ep.ssl), buf, sizeof(buf));
} while (ret != MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET);
ret = mbedtls_ssl_get_session(&(client_ep.ssl), session);
TEST_EQUAL(ret, 0);
exit:
mbedtls_test_ssl_endpoint_free(&client_ep, NULL);
mbedtls_test_ssl_endpoint_free(&server_ep, NULL);
return ret;
}
#endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_SSL_SRV_C &&
MBEDTLS_SSL_PROTO_TLS1_3 && MBEDTLS_SSL_SESSION_TICKETS &&
MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
#endif /* MBEDTLS_SSL_TLS_C */

View file

@ -3274,11 +3274,23 @@ elliptic_curve_get_properties
TLS 1.3 resume session with ticket
tls13_resume_session_with_ticket
TLS 1.3 early data, reference
tls13_early_data:TEST_EARLY_DATA_REFERENCE
TLS 1.3 early data, early data accepted
tls13_early_data:TEST_EARLY_DATA_ACCEPTED
TLS 1.3 early data, deprotect and discard
tls13_early_data:TEST_EARLY_DATA_DEPROTECT_AND_DISCARD
TLS 1.3 early data, server rejects early data
tls13_early_data:TEST_EARLY_DATA_SERVER_REJECTS
TLS 1.3 early data, discard after HRR
tls13_early_data:TEST_EARLY_DATA_DISCARD_AFTER_HRR
tls13_early_data:TEST_EARLY_DATA_HRR
TLS 1.3 cli, early data status, early data accepted
tls13_cli_early_data_status:TEST_EARLY_DATA_ACCEPTED
TLS 1.3 cli, early data status, no early data indication
tls13_cli_early_data_status:TEST_EARLY_DATA_NO_INDICATION_SENT
TLS 1.3 cli, early data status, server rejects early data
tls13_cli_early_data_status:TEST_EARLY_DATA_SERVER_REJECTS
TLS 1.3 cli, early data status, hello retry request
tls13_cli_early_data_status:TEST_EARLY_DATA_HRR

View file

@ -13,9 +13,10 @@
#define SSL_MESSAGE_QUEUE_INIT { NULL, 0, 0, 0 }
/* Mnemonics for the early data test scenarios */
#define TEST_EARLY_DATA_REFERENCE 0
#define TEST_EARLY_DATA_DEPROTECT_AND_DISCARD 1
#define TEST_EARLY_DATA_DISCARD_AFTER_HRR 2
#define TEST_EARLY_DATA_ACCEPTED 0
#define TEST_EARLY_DATA_NO_INDICATION_SENT 1
#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) && \
@ -2457,7 +2458,7 @@ void mbedtls_endpoint_sanity(int endpoint_type)
MD_OR_USE_PSA_INIT();
ret = mbedtls_test_ssl_endpoint_init(NULL, endpoint_type, &options,
NULL, NULL, NULL, NULL);
NULL, NULL, NULL);
TEST_ASSERT(MBEDTLS_ERR_SSL_BAD_INPUT_DATA == ret);
ret = mbedtls_test_ssl_endpoint_certificate_init(NULL, options.pk_alg,
@ -2465,7 +2466,7 @@ void mbedtls_endpoint_sanity(int endpoint_type)
TEST_ASSERT(MBEDTLS_ERR_SSL_BAD_INPUT_DATA == ret);
ret = mbedtls_test_ssl_endpoint_init(&ep, endpoint_type, &options,
NULL, NULL, NULL, NULL);
NULL, NULL, NULL);
TEST_ASSERT(ret == 0);
exit:
@ -2509,14 +2510,14 @@ void move_handshake_to_state(int endpoint_type, int tls_version, int state, int
mbedtls_platform_zeroize(&second_ep, sizeof(second_ep));
ret = mbedtls_test_ssl_endpoint_init(&base_ep, endpoint_type, &options,
NULL, NULL, NULL, NULL);
NULL, NULL, NULL);
TEST_ASSERT(ret == 0);
ret = mbedtls_test_ssl_endpoint_init(
&second_ep,
(endpoint_type == MBEDTLS_SSL_IS_SERVER) ?
MBEDTLS_SSL_IS_CLIENT : MBEDTLS_SSL_IS_SERVER,
&options, NULL, NULL, NULL, NULL);
&options, NULL, NULL, NULL);
TEST_ASSERT(ret == 0);
@ -3069,11 +3070,10 @@ void force_bad_session_id_len()
TEST_ASSERT(mbedtls_test_ssl_endpoint_init(&client, MBEDTLS_SSL_IS_CLIENT,
&options, NULL, NULL,
NULL, NULL) == 0);
NULL) == 0);
TEST_ASSERT(mbedtls_test_ssl_endpoint_init(&server, MBEDTLS_SSL_IS_SERVER,
&options, NULL, NULL, NULL,
NULL) == 0);
&options, NULL, NULL, NULL) == 0);
mbedtls_debug_set_threshold(1);
mbedtls_ssl_conf_dbg(&server.conf, options.srv_log_fun,
@ -3248,8 +3248,9 @@ void raw_key_agreement_fail(int bad_server_ecdhe_key)
mbedtls_test_ssl_endpoint client, server;
mbedtls_psa_stats_t stats;
size_t free_slots_before = -1;
mbedtls_test_handshake_test_options options;
mbedtls_test_init_handshake_options(&options);
mbedtls_test_handshake_test_options client_options, server_options;
mbedtls_test_init_handshake_options(&client_options);
mbedtls_test_init_handshake_options(&server_options);
uint16_t iana_tls_group_list[] = { MBEDTLS_SSL_IANA_TLS_GROUP_SECP256R1,
MBEDTLS_SSL_IANA_TLS_GROUP_NONE };
@ -3257,21 +3258,22 @@ void raw_key_agreement_fail(int bad_server_ecdhe_key)
mbedtls_platform_zeroize(&client, sizeof(client));
mbedtls_platform_zeroize(&server, sizeof(server));
options.pk_alg = MBEDTLS_PK_ECDSA;
options.server_min_version = MBEDTLS_SSL_VERSION_TLS1_2;
options.server_max_version = MBEDTLS_SSL_VERSION_TLS1_2;
/* Client side, force SECP256R1 to make one key bitflip fail
* the raw key agreement. Flipping the first byte makes the
* required 0x04 identifier invalid. */
client_options.pk_alg = MBEDTLS_PK_ECDSA;
client_options.group_list = iana_tls_group_list;
TEST_EQUAL(mbedtls_test_ssl_endpoint_init(&client, MBEDTLS_SSL_IS_CLIENT,
&options, NULL, NULL,
NULL, iana_tls_group_list), 0);
&client_options, NULL, NULL,
NULL), 0);
/* Server side */
server_options.pk_alg = MBEDTLS_PK_ECDSA;
server_options.server_min_version = MBEDTLS_SSL_VERSION_TLS1_2;
server_options.server_max_version = MBEDTLS_SSL_VERSION_TLS1_2;
TEST_EQUAL(mbedtls_test_ssl_endpoint_init(&server, MBEDTLS_SSL_IS_SERVER,
&options, NULL, NULL,
NULL, NULL), 0);
&server_options, NULL, NULL,
NULL), 0);
TEST_EQUAL(mbedtls_test_mock_socket_connect(&(client.socket),
&(server.socket),
@ -3307,7 +3309,8 @@ void raw_key_agreement_fail(int bad_server_ecdhe_key)
exit:
mbedtls_test_ssl_endpoint_free(&client, NULL);
mbedtls_test_ssl_endpoint_free(&server, NULL);
mbedtls_test_free_handshake_options(&options);
mbedtls_test_free_handshake_options(&client_options);
mbedtls_test_free_handshake_options(&server_options);
MD_OR_USE_PSA_DONE();
}
@ -3336,15 +3339,13 @@ void tls13_server_certificate_msg_invalid_vector_len()
client_options.pk_alg = MBEDTLS_PK_ECDSA;
ret = mbedtls_test_ssl_endpoint_init(&client_ep, MBEDTLS_SSL_IS_CLIENT,
&client_options, NULL, NULL, NULL,
NULL);
&client_options, NULL, NULL, NULL);
TEST_EQUAL(ret, 0);
mbedtls_test_init_handshake_options(&server_options);
server_options.pk_alg = MBEDTLS_PK_ECDSA;
ret = mbedtls_test_ssl_endpoint_init(&server_ep, MBEDTLS_SSL_IS_SERVER,
&server_options, NULL, NULL, NULL,
NULL);
&server_options, NULL, NULL, NULL);
TEST_EQUAL(ret, 0);
ret = mbedtls_test_mock_socket_connect(&(client_ep.socket),
@ -3572,15 +3573,11 @@ exit:
void tls13_resume_session_with_ticket()
{
int ret = -1;
unsigned char buf[64];
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;
/*
* Test set-up
*/
mbedtls_platform_zeroize(&client_ep, sizeof(client_ep));
mbedtls_platform_zeroize(&server_ep, sizeof(server_ep));
mbedtls_test_init_handshake_options(&client_options);
@ -3589,16 +3586,27 @@ void tls13_resume_session_with_ticket()
PSA_INIT();
/*
* Run first handshake to get a ticket from the server.
*/
client_options.pk_alg = MBEDTLS_PK_ECDSA;
ret = mbedtls_test_ssl_endpoint_init(&client_ep, MBEDTLS_SSL_IS_CLIENT,
&client_options, NULL, NULL, NULL,
NULL);
server_options.pk_alg = MBEDTLS_PK_ECDSA;
ret = mbedtls_test_get_tls13_ticket(&client_options, &server_options,
&saved_session);
TEST_EQUAL(ret, 0);
/*
* Prepare for handshake with the ticket.
*/
ret = mbedtls_test_ssl_endpoint_init(&client_ep, MBEDTLS_SSL_IS_CLIENT,
&client_options, NULL, NULL, NULL);
TEST_EQUAL(ret, 0);
server_options.pk_alg = MBEDTLS_PK_ECDSA;
ret = mbedtls_test_ssl_endpoint_init(&server_ep, MBEDTLS_SSL_IS_SERVER,
&server_options, NULL, NULL, NULL,
NULL);
&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,
@ -3609,41 +3617,12 @@ void tls13_resume_session_with_ticket()
&(server_ep.socket), 1024);
TEST_EQUAL(ret, 0);
/*
* Run initial handshake: ephemeral key exchange mode, certificate with
* SECP256R1 key, CA certificate with SECP384R1 key, ECDSA signature
* algorithm. Then, get the ticket sent by the server at the end of its
* handshake sequence.
*/
TEST_EQUAL(mbedtls_test_move_handshake_to_state(
&(server_ep.ssl), &(client_ep.ssl),
MBEDTLS_SSL_HANDSHAKE_OVER), 0);
do {
ret = mbedtls_ssl_read(&(client_ep.ssl), buf, sizeof(buf));
} while (ret != MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET);
/*
* Save client session and reset the SSL context of the two endpoints.
*/
ret = mbedtls_ssl_get_session(&(client_ep.ssl), &saved_session);
TEST_EQUAL(ret, 0);
ret = mbedtls_ssl_session_reset(&(client_ep.ssl));
TEST_EQUAL(ret, 0);
ret = mbedtls_ssl_session_reset(&(server_ep.ssl));
TEST_EQUAL(ret, 0);
/*
* Set saved session on client side and handshake using the ticket
* included in that session.
*/
ret = mbedtls_ssl_set_session(&(client_ep.ssl), &saved_session);
TEST_EQUAL(ret, 0);
/*
* Handshake with ticket.
*
* Run the handshake up to MBEDTLS_SSL_HANDSHAKE_WRAPUP and not
* MBEDTLS_SSL_HANDSHAKE_OVER to preserve handshake data for the checks
* below.
@ -3690,9 +3669,6 @@ void tls13_early_data(int scenario)
MBEDTLS_SSL_IANA_TLS_GROUP_NONE
};
/*
* Test set-up
*/
mbedtls_platform_zeroize(&client_ep, sizeof(client_ep));
mbedtls_platform_zeroize(&server_ep, sizeof(server_ep));
mbedtls_test_init_handshake_options(&client_options);
@ -3701,21 +3677,56 @@ void tls13_early_data(int scenario)
PSA_INIT();
client_options.pk_alg = MBEDTLS_PK_ECDSA;
ret = mbedtls_test_ssl_endpoint_init(&client_ep, MBEDTLS_SSL_IS_CLIENT,
&client_options, NULL, NULL, NULL,
group_list);
TEST_EQUAL(ret, 0);
mbedtls_ssl_conf_early_data(&client_ep.conf, MBEDTLS_SSL_EARLY_DATA_ENABLED);
/*
* 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;
ret = mbedtls_test_get_tls13_ticket(&client_options, &server_options,
&saved_session);
TEST_EQUAL(ret, 0);
/*
* Prepare for handshake with the ticket.
*/
switch (scenario) {
case TEST_EARLY_DATA_ACCEPTED:
break;
case TEST_EARLY_DATA_SERVER_REJECTS:
mbedtls_debug_set_threshold(3);
server_pattern.pattern =
"EarlyData: deprotect and discard app data records.";
server_options.early_data = MBEDTLS_SSL_EARLY_DATA_DISABLED;
break;
case TEST_EARLY_DATA_HRR:
mbedtls_debug_set_threshold(3);
server_pattern.pattern =
"EarlyData: Ignore application message before 2nd ClientHello";
server_options.group_list = group_list + 1;
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);
server_options.srv_log_fun = mbedtls_test_ssl_log_analyzer;
server_options.srv_log_obj = &server_pattern;
ret = mbedtls_test_ssl_endpoint_init(&server_ep, MBEDTLS_SSL_IS_SERVER,
&server_options, NULL, NULL, NULL,
group_list);
&server_options, NULL, NULL, NULL);
TEST_EQUAL(ret, 0);
mbedtls_ssl_conf_early_data(&server_ep.conf, MBEDTLS_SSL_EARLY_DATA_ENABLED);
mbedtls_ssl_conf_session_tickets_cb(&server_ep.conf,
mbedtls_test_ticket_write,
mbedtls_test_ticket_parse,
@ -3725,69 +3736,12 @@ void tls13_early_data(int scenario)
&(server_ep.socket), 1024);
TEST_EQUAL(ret, 0);
/*
* Run initial handshake: ephemeral key exchange mode, certificate with
* SECP256R1 key, CA certificate with SECP384R1 key, ECDSA signature
* algorithm. Then, get the ticket sent by the server at the end of its
* handshake sequence.
*/
TEST_EQUAL(mbedtls_test_move_handshake_to_state(
&(server_ep.ssl), &(client_ep.ssl),
MBEDTLS_SSL_HANDSHAKE_OVER), 0);
do {
ret = mbedtls_ssl_read(&(client_ep.ssl), buf, sizeof(buf));
} while (ret != MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET);
/*
* Save client session and reset the SSL context of the two endpoints.
*/
ret = mbedtls_ssl_get_session(&(client_ep.ssl), &saved_session);
TEST_EQUAL(ret, 0);
ret = mbedtls_ssl_session_reset(&(client_ep.ssl));
TEST_EQUAL(ret, 0);
ret = mbedtls_ssl_session_reset(&(server_ep.ssl));
TEST_EQUAL(ret, 0);
/*
* Set saved session on client side and start handshake using the ticket
* included in that session.
*/
ret = mbedtls_ssl_set_session(&(client_ep.ssl), &saved_session);
TEST_EQUAL(ret, 0);
switch (scenario) {
case TEST_EARLY_DATA_REFERENCE:
break;
case TEST_EARLY_DATA_DEPROTECT_AND_DISCARD:
mbedtls_debug_set_threshold(3);
server_pattern.pattern =
"EarlyData: deprotect and discard app data records.";
mbedtls_ssl_conf_early_data(&server_ep.conf,
MBEDTLS_SSL_EARLY_DATA_DISABLED);
break;
case TEST_EARLY_DATA_DISCARD_AFTER_HRR:
mbedtls_debug_set_threshold(3);
server_pattern.pattern =
"EarlyData: Ignore application message before 2nd ClientHello";
mbedtls_ssl_conf_groups(&server_ep.conf, group_list + 1);
/*
* Need to reset again to reconstruct the group list in the
* handshake structure from the configured one.
*/
ret = mbedtls_ssl_session_reset(&(server_ep.ssl));
TEST_EQUAL(ret, 0);
break;
default:
TEST_FAIL("Unknown scenario.");
}
/*
* Handshake with ticket and send early data.
*/
TEST_EQUAL(mbedtls_test_move_handshake_to_state(
&(client_ep.ssl), &(server_ep.ssl),
MBEDTLS_SSL_SERVER_HELLO), 0);
@ -3804,7 +3758,7 @@ void tls13_early_data(int scenario)
MBEDTLS_SSL_HANDSHAKE_WRAPUP);
switch (scenario) {
case TEST_EARLY_DATA_REFERENCE:
case TEST_EARLY_DATA_ACCEPTED:
TEST_EQUAL(ret, MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA);
TEST_EQUAL(server_ep.ssl.handshake->early_data_accepted, 1);
TEST_EQUAL(mbedtls_ssl_read_early_data(&(server_ep.ssl),
@ -3812,8 +3766,8 @@ void tls13_early_data(int scenario)
TEST_MEMORY_COMPARE(buf, early_data_len, early_data, early_data_len);
break;
case TEST_EARLY_DATA_DEPROTECT_AND_DISCARD: /* Intentional fallthrough */
case TEST_EARLY_DATA_DISCARD_AFTER_HRR:
case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */
case TEST_EARLY_DATA_HRR:
TEST_EQUAL(ret, 0);
TEST_EQUAL(server_ep.ssl.handshake->early_data_accepted, 0);
TEST_EQUAL(server_pattern.counter, 1);
@ -3834,3 +3788,316 @@ exit:
PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_SSL_EARLY_DATA:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_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_cli_early_data_status(int scenario)
{
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;
uint16_t group_list[3] = {
MBEDTLS_SSL_IANA_TLS_GROUP_SECP256R1,
MBEDTLS_SSL_IANA_TLS_GROUP_SECP384R1,
MBEDTLS_SSL_IANA_TLS_GROUP_NONE
};
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();
/*
* Run first handshake to get a ticket from the server.
*/
client_options.pk_alg = MBEDTLS_PK_ECDSA;
client_options.early_data = MBEDTLS_SSL_EARLY_DATA_ENABLED;
server_options.pk_alg = MBEDTLS_PK_ECDSA;
server_options.early_data = MBEDTLS_SSL_EARLY_DATA_ENABLED;
if (scenario == TEST_EARLY_DATA_HRR) {
client_options.group_list = group_list;
server_options.group_list = group_list;
}
ret = mbedtls_test_get_tls13_ticket(&client_options, &server_options,
&saved_session);
TEST_EQUAL(ret, 0);
/*
* Prepare for handshake with the ticket.
*/
switch (scenario) {
case TEST_EARLY_DATA_ACCEPTED:
break;
case TEST_EARLY_DATA_NO_INDICATION_SENT:
client_options.early_data = MBEDTLS_SSL_EARLY_DATA_DISABLED;
break;
case TEST_EARLY_DATA_SERVER_REJECTS:
server_options.early_data = MBEDTLS_SSL_EARLY_DATA_DISABLED;
break;
case TEST_EARLY_DATA_HRR:
server_options.group_list = group_list + 1;
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);
ret = mbedtls_ssl_set_session(&(client_ep.ssl), &saved_session);
TEST_EQUAL(ret, 0);
/*
* Go through the handshake sequence, state by state, checking the early
* data status each time.
*/
do {
int state = client_ep.ssl.state;
/* Progress the handshake from at least one state */
while (client_ep.ssl.state == state) {
ret = mbedtls_ssl_handshake_step(&(client_ep.ssl));
TEST_ASSERT((ret == 0) ||
(ret == MBEDTLS_ERR_SSL_WANT_READ) ||
(ret == MBEDTLS_ERR_SSL_WANT_WRITE));
if (client_ep.ssl.state != state) {
break;
}
ret = mbedtls_ssl_handshake_step(&(server_ep.ssl));
TEST_ASSERT((ret == 0) ||
(ret == MBEDTLS_ERR_SSL_WANT_READ) ||
(ret == MBEDTLS_ERR_SSL_WANT_WRITE));
}
switch (client_ep.ssl.state) {
case MBEDTLS_SSL_CLIENT_HELLO:
switch (scenario) {
case TEST_EARLY_DATA_ACCEPTED: /* Intentional fallthrough */
case TEST_EARLY_DATA_NO_INDICATION_SENT: /* Intentional fallthrough */
case TEST_EARLY_DATA_SERVER_REJECTS:
TEST_EQUAL(client_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN);
break;
case TEST_EARLY_DATA_HRR:
if (client_ep.ssl.handshake->hello_retry_request_count == 0) {
TEST_EQUAL(client_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_UNKNOWN);
} else {
TEST_EQUAL(client_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED);
}
break;
}
break;
case MBEDTLS_SSL_SERVER_HELLO:
switch (scenario) {
case TEST_EARLY_DATA_ACCEPTED: /* Intentional fallthrough */
case TEST_EARLY_DATA_SERVER_REJECTS:
TEST_EQUAL(client_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE);
break;
case TEST_EARLY_DATA_NO_INDICATION_SENT:
TEST_EQUAL(client_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT);
break;
case TEST_EARLY_DATA_HRR:
if (client_ep.ssl.handshake->hello_retry_request_count == 0) {
TEST_EQUAL(client_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE);
} else {
TEST_EQUAL(client_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED);
}
break;
}
break;
case MBEDTLS_SSL_ENCRYPTED_EXTENSIONS:
switch (scenario) {
case TEST_EARLY_DATA_ACCEPTED: /* Intentional fallthrough */
case TEST_EARLY_DATA_SERVER_REJECTS:
TEST_EQUAL(client_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_CAN_WRITE);
break;
case TEST_EARLY_DATA_NO_INDICATION_SENT:
TEST_EQUAL(client_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT);
break;
case TEST_EARLY_DATA_HRR:
TEST_EQUAL(client_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED);
break;
}
break;
case MBEDTLS_SSL_SERVER_FINISHED:
switch (scenario) {
case TEST_EARLY_DATA_ACCEPTED:
TEST_EQUAL(client_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED);
break;
case TEST_EARLY_DATA_NO_INDICATION_SENT:
TEST_EQUAL(client_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT);
break;
case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */
case TEST_EARLY_DATA_HRR:
TEST_EQUAL(client_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED);
break;
}
break;
case MBEDTLS_SSL_END_OF_EARLY_DATA:
TEST_EQUAL(scenario, TEST_EARLY_DATA_ACCEPTED);
TEST_EQUAL(client_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED);
break;
case MBEDTLS_SSL_CLIENT_CERTIFICATE:
switch (scenario) {
case TEST_EARLY_DATA_ACCEPTED:
TEST_EQUAL(client_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED);
break;
case TEST_EARLY_DATA_NO_INDICATION_SENT:
TEST_EQUAL(client_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT);
break;
case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */
case TEST_EARLY_DATA_HRR:
TEST_EQUAL(client_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED);
break;
}
break;
case MBEDTLS_SSL_CLIENT_FINISHED:
switch (scenario) {
case TEST_EARLY_DATA_ACCEPTED:
TEST_EQUAL(client_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED);
break;
case TEST_EARLY_DATA_NO_INDICATION_SENT:
TEST_EQUAL(client_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT);
break;
case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */
case TEST_EARLY_DATA_HRR:
TEST_EQUAL(client_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED);
break;
}
break;
#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
case MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO:
TEST_ASSERT(scenario != TEST_EARLY_DATA_NO_INDICATION_SENT);
switch (scenario) {
case TEST_EARLY_DATA_ACCEPTED: /* Intentional fallthrough */
case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */
case TEST_EARLY_DATA_HRR:
TEST_EQUAL(client_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_SENT);
break;
}
break;
case MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO:
TEST_ASSERT(scenario == TEST_EARLY_DATA_HRR);
TEST_EQUAL(client_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED);
break;
case MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED:
TEST_ASSERT(scenario != TEST_EARLY_DATA_ACCEPTED);
switch (scenario) {
case TEST_EARLY_DATA_NO_INDICATION_SENT:
TEST_EQUAL(client_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT);
break;
case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */
case TEST_EARLY_DATA_HRR:
TEST_EQUAL(client_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED);
break;
}
break;
#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
case MBEDTLS_SSL_FLUSH_BUFFERS: /* Intentional fallthrough */
case MBEDTLS_SSL_HANDSHAKE_WRAPUP: /* Intentional fallthrough */
case MBEDTLS_SSL_HANDSHAKE_OVER:
switch (scenario) {
case TEST_EARLY_DATA_ACCEPTED:
TEST_EQUAL(client_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_SERVER_FINISHED_RECEIVED);
break;
case TEST_EARLY_DATA_NO_INDICATION_SENT:
TEST_EQUAL(client_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_SENT);
break;
case TEST_EARLY_DATA_SERVER_REJECTS: /* Intentional fallthrough */
case TEST_EARLY_DATA_HRR:
TEST_EQUAL(client_ep.ssl.early_data_status,
MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED);
break;
}
break;
default:
TEST_FAIL("Unexpected state.");
}
} while (client_ep.ssl.state != MBEDTLS_SSL_HANDSHAKE_OVER);
#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
TEST_EQUAL(client_ep.ssl.handshake->ccs_count, 1);
#endif
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);
PSA_DONE();
}
/* END_CASE */