mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2026-07-30 08:16:38 +08:00
Merge pull request #1652 from ronald-cron-arm/hsm-do-not-span-key-change
Hsm do not span key change
This commit is contained in:
commit
9baa16385d
7
ChangeLog.d/drop-early-data.txt
Normal file
7
ChangeLog.d/drop-early-data.txt
Normal file
@ -0,0 +1,7 @@
|
||||
Security
|
||||
* Fixed a TLS 1.3 record-boundary validation issue that could allow
|
||||
unauthenticated plaintext data to be processed across a key change. In
|
||||
servers with MBEDTLS_SSL_EARLY_DATA enabled, this could be exploited by a
|
||||
man-in-the-middle attacker to cause loss of 0-RTT early data.
|
||||
Reported by Ben Smyth.
|
||||
CVE-2026-TODO.
|
||||
@ -2016,6 +2016,19 @@ static int ssl_tls13_process_server_hello(mbedtls_ssl_context *ssl)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* TLS 1.3 is negotiated. Check that ServerHello/HRR ends at a record
|
||||
* boundary. For HRR, which does not trigger a key update, this checks
|
||||
* that HRR terminates the server flight.
|
||||
*/
|
||||
if (ssl->in_hslen != ssl->in_msglen) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("ServerHello end not aligned with a record boundary"));
|
||||
ret = MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE,
|
||||
MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_server_hello(ssl, buf,
|
||||
buf + buf_len,
|
||||
is_hrr));
|
||||
|
||||
@ -50,20 +50,55 @@ int mbedtls_ssl_tls13_fetch_handshake_msg(mbedtls_ssl_context *ssl,
|
||||
unsigned char **buf,
|
||||
size_t *buf_len)
|
||||
{
|
||||
int ret;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
int require_record_boundary;
|
||||
|
||||
if ((ret = mbedtls_ssl_read_record(ssl, 0)) != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
|
||||
goto cleanup;
|
||||
/* Require record-boundary alignment by default. The exceptions below are
|
||||
* handshake messages that may legitimately be followed by additional
|
||||
* handshake messages in the same record. Using the default behaviour for a
|
||||
* message that should be exempt is an interoperability bug; exempting a
|
||||
* message that should not be exempt may have security implications.
|
||||
*/
|
||||
switch (hs_type) {
|
||||
case MBEDTLS_SSL_HS_NEW_SESSION_TICKET:
|
||||
case MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS:
|
||||
case MBEDTLS_SSL_HS_CERTIFICATE:
|
||||
case MBEDTLS_SSL_HS_CERTIFICATE_REQUEST:
|
||||
case MBEDTLS_SSL_HS_CERTIFICATE_VERIFY:
|
||||
/*
|
||||
* For TLS 1.3, ServerHello (including HelloRetryRequest) must end at a
|
||||
* record boundary, but not for TLS 1.2. At this point the ServerHello
|
||||
* has not yet been processed, so we do not know whether it negotiates
|
||||
* TLS 1.3 or TLS 1.2. Defer the boundary check until the protocol
|
||||
* version is known to be TLS 1.3.
|
||||
*/
|
||||
case MBEDTLS_SSL_HS_SERVER_HELLO:
|
||||
require_record_boundary = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* ClientHello, EndOfEarlyData, Finished, and KeyUpdate.
|
||||
*/
|
||||
require_record_boundary = 1;
|
||||
}
|
||||
|
||||
ret = mbedtls_ssl_read_record(ssl, 0);
|
||||
if (ret != 0) {
|
||||
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
|
||||
if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ||
|
||||
ssl->in_msg[0] != hs_type) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("Receive unexpected handshake message."));
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE,
|
||||
MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE);
|
||||
ret = MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
|
||||
goto cleanup;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (require_record_boundary && (ssl->in_hslen != ssl->in_msglen)) {
|
||||
MBEDTLS_SSL_DEBUG_MSG(1, ("Handshake message %s end not aligned with a record boundary",
|
||||
mbedtls_ssl_get_hs_msg_name(hs_type)));
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -73,11 +108,15 @@ int mbedtls_ssl_tls13_fetch_handshake_msg(mbedtls_ssl_context *ssl,
|
||||
* uint24 length;
|
||||
* ...
|
||||
*/
|
||||
*buf = ssl->in_msg + 4;
|
||||
*buf = ssl->in_msg + 4;
|
||||
*buf_len = ssl->in_hslen - 4;
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
|
||||
error:
|
||||
if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE) {
|
||||
MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE,
|
||||
MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -3586,3 +3586,25 @@ send_invalid_sig_alg:MBEDTLS_SSL_SIG_ECDSA:MBEDTLS_SSL_HASH_SHA512:MBEDTLS_ERR_S
|
||||
TLS 1.2 NewSessionTicket: failing ticket callback leaves lifetime unset
|
||||
depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:PSA_HAVE_ALG_SOME_RSA_SIGN:PSA_WANT_ECC_SECP_R1_384:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
|
||||
write_new_session_ticket_mem
|
||||
|
||||
TLS 1.3 drop early data
|
||||
tls13_drop_early_data:0
|
||||
|
||||
TLS 1.3 drop early data and insert an EndOfEarlyData
|
||||
tls13_drop_early_data:1
|
||||
|
||||
TLS 1.3 ClientHello record boundary alignment enforcement
|
||||
tls13_record_boundary_alignment:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_HS_CLIENT_HELLO
|
||||
|
||||
TLS 1.3 ServerHello record boundary alignment enforcement
|
||||
tls13_record_boundary_alignment:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_HS_SERVER_HELLO
|
||||
|
||||
TLS 1.3 server Finished record boundary alignment enforcement
|
||||
tls13_record_boundary_alignment:MBEDTLS_SSL_IS_CLIENT:MBEDTLS_SSL_HS_FINISHED
|
||||
|
||||
TLS 1.3 client Finished record boundary alignment enforcement
|
||||
tls13_record_boundary_alignment:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_HS_FINISHED
|
||||
|
||||
TLS 1.3 EndOfEarlyData record boundary alignment enforcement
|
||||
depends_on:MBEDTLS_SSL_EARLY_DATA:MBEDTLS_SSL_SESSION_TICKETS
|
||||
tls13_record_boundary_alignment:MBEDTLS_SSL_IS_SERVER:MBEDTLS_SSL_HS_END_OF_EARLY_DATA
|
||||
|
||||
@ -552,6 +552,51 @@ exit:
|
||||
|
||||
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED etc */
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && defined(MBEDTLS_DEBUG_C) && \
|
||||
defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_SRV_C) && \
|
||||
defined(MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE) && \
|
||||
defined(MBEDTLS_TEST_HAS_DEFAULT_EC_GROUP) && \
|
||||
defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) && \
|
||||
defined(PSA_WANT_ALG_SHA_256) && \
|
||||
defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && \
|
||||
defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN)
|
||||
typedef struct {
|
||||
/* Context for `tls_tweak_in_msglen()`. The debug callback
|
||||
* watches for "<= read record" in the SSL debug trace. When the pattern is
|
||||
* detected, it increases by `nb_bytes` the 'in_msglen' field of the
|
||||
* associated SSL context.
|
||||
*/
|
||||
mbedtls_ssl_context *ssl;
|
||||
int armed;
|
||||
int nb_bytes;
|
||||
int triggered;
|
||||
} tls_tweak_in_msglen_context;
|
||||
|
||||
static void tls_tweak_in_msglen(void *ctx, int level,
|
||||
const char *file, int line,
|
||||
const char *str)
|
||||
{
|
||||
tls_tweak_in_msglen_context *tweak_in_msglen_ctx = ctx;
|
||||
|
||||
(void) level;
|
||||
(void) file;
|
||||
(void) line;
|
||||
|
||||
if (!tweak_in_msglen_ctx->armed) {
|
||||
return;
|
||||
}
|
||||
if (strstr(str, "<= read record") == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
tweak_in_msglen_ctx->ssl->in_msglen += tweak_in_msglen_ctx->nb_bytes;
|
||||
tweak_in_msglen_ctx->armed = 0;
|
||||
tweak_in_msglen_ctx->triggered++;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* END_HEADER */
|
||||
|
||||
/* BEGIN_DEPENDENCIES
|
||||
@ -6778,3 +6823,315 @@ exit:
|
||||
MD_OR_USE_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_TEST_HAS_DEFAULT_EC_GROUP:PSA_WANT_ALG_SHA_256:MBEDTLS_X509_RSASSA_PSS_SUPPORT:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:MBEDTLS_SSL_SESSION_TICKETS */
|
||||
void tls13_drop_early_data(int insert_end_of_early_data)
|
||||
{
|
||||
int ret = -1;
|
||||
mbedtls_test_ssl_endpoint client_ep, server_ep;
|
||||
memset(&client_ep, 0, sizeof(client_ep));
|
||||
memset(&server_ep, 0, sizeof(server_ep));
|
||||
|
||||
mbedtls_test_handshake_test_options client_options, server_options;
|
||||
mbedtls_test_init_handshake_options(&client_options);
|
||||
mbedtls_test_init_handshake_options(&server_options);
|
||||
|
||||
mbedtls_ssl_session saved_session;
|
||||
mbedtls_ssl_session_init(&saved_session);
|
||||
|
||||
const char *early_data = "This is early data.";
|
||||
size_t early_data_len = strlen(early_data);
|
||||
unsigned char buf[256];
|
||||
|
||||
PSA_INIT();
|
||||
|
||||
/*
|
||||
* Run first handshake to get a ticket from the server.
|
||||
*/
|
||||
|
||||
client_options.early_data = MBEDTLS_SSL_EARLY_DATA_ENABLED;
|
||||
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.
|
||||
*/
|
||||
ret = mbedtls_test_ssl_endpoint_init(&client_ep, MBEDTLS_SSL_IS_CLIENT,
|
||||
&client_options);
|
||||
TEST_EQUAL(ret, 0);
|
||||
|
||||
ret = mbedtls_test_ssl_endpoint_init(&server_ep, MBEDTLS_SSL_IS_SERVER,
|
||||
&server_options);
|
||||
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);
|
||||
|
||||
/*
|
||||
* Initiate handshake with ticket, up to the point where the client has
|
||||
* written the ClientHello and only the ClientHello in its output socket
|
||||
* buffer.
|
||||
*/
|
||||
#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
|
||||
TEST_EQUAL(mbedtls_test_move_handshake_to_state(
|
||||
&(client_ep.ssl), &(server_ep.ssl),
|
||||
MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO), 0);
|
||||
#else
|
||||
TEST_EQUAL(mbedtls_test_move_handshake_to_state(
|
||||
&(client_ep.ssl), &(server_ep.ssl),
|
||||
MBEDTLS_SSL_SERVER_HELLO), 0);
|
||||
#endif
|
||||
TEST_EQUAL(mbedtls_ssl_flush_output(&client_ep.ssl), 0);
|
||||
|
||||
if (insert_end_of_early_data) {
|
||||
/*
|
||||
* Append an EndOfEarlyData message at the end of the record, just
|
||||
* after the ClientHello message.
|
||||
*/
|
||||
unsigned char *client_output_buffer = client_ep.socket.output->buffer;
|
||||
size_t record_size = MBEDTLS_GET_UINT16_BE(client_output_buffer, 3);
|
||||
|
||||
MBEDTLS_PUT_UINT16_BE(record_size + 4, client_output_buffer, 3);
|
||||
unsigned char end_of_early_data[] = { 0x05, 0x00, 0x00, 0x00 };
|
||||
ret = mbedtls_test_ssl_buffer_put(client_ep.socket.output,
|
||||
end_of_early_data,
|
||||
sizeof(end_of_early_data));
|
||||
TEST_EQUAL(ret, (int) sizeof(end_of_early_data));
|
||||
}
|
||||
|
||||
/* The server read the record containing the ClientHello. */
|
||||
ret = mbedtls_test_move_handshake_to_state(&(server_ep.ssl),
|
||||
&(client_ep.ssl),
|
||||
MBEDTLS_SSL_SERVER_HELLO);
|
||||
if (insert_end_of_early_data) {
|
||||
/*
|
||||
* If an EndOfEarlyData message was appended to the record containing
|
||||
* the ClientHello then the end of the ClientHello does not align with
|
||||
* the record boundary and the handshake fails.
|
||||
*/
|
||||
TEST_EQUAL(ret, MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
TEST_EQUAL(ret, 0);
|
||||
/* The client application writes early data */
|
||||
ret = mbedtls_ssl_write_early_data(&(client_ep.ssl),
|
||||
(unsigned char *) early_data,
|
||||
early_data_len);
|
||||
TEST_EQUAL(ret, early_data_len);
|
||||
|
||||
/* Drop early data */
|
||||
TEST_ASSERT(client_ep.socket.output->content_length <= sizeof(buf));
|
||||
mbedtls_test_ssl_buffer_get(client_ep.socket.output, buf, sizeof(buf));
|
||||
TEST_EQUAL(server_ep.socket.input->content_length, 0);
|
||||
|
||||
/* Resume the handshake */
|
||||
ret = mbedtls_test_move_handshake_to_state(&(server_ep.ssl),
|
||||
&(client_ep.ssl),
|
||||
MBEDTLS_SSL_HANDSHAKE_OVER);
|
||||
/*
|
||||
* The early data were dropped. The EndOfEarlyData message is encrypted
|
||||
* with the record number 1, but the server expects it to be encrypted
|
||||
* with record number 0. Thus the handshake fails with
|
||||
* MBEDTLS_ERR_SSL_INVALID_MAC.
|
||||
*/
|
||||
TEST_EQUAL(ret, MBEDTLS_ERR_SSL_INVALID_MAC);
|
||||
|
||||
exit:
|
||||
mbedtls_test_ssl_endpoint_free(&client_ep);
|
||||
mbedtls_test_ssl_endpoint_free(&server_ep);
|
||||
mbedtls_test_free_handshake_options(&client_options);
|
||||
mbedtls_test_free_handshake_options(&server_options);
|
||||
mbedtls_ssl_session_free(&saved_session);
|
||||
PSA_DONE();
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_DEBUG_C:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_TEST_HAS_DEFAULT_EC_GROUP:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_SHA_256:MBEDTLS_X509_RSASSA_PSS_SUPPORT:PSA_WANT_ALG_RSA_PKCS1V15_SIGN */
|
||||
void tls13_record_boundary_alignment(int endpoint, int handshake_message)
|
||||
{
|
||||
int ret = -1;
|
||||
int target_state, peer_target_state, encrypted;
|
||||
mbedtls_test_ssl_endpoint client_ep, server_ep;
|
||||
memset(&client_ep, 0, sizeof(client_ep));
|
||||
memset(&server_ep, 0, sizeof(server_ep));
|
||||
|
||||
mbedtls_test_handshake_test_options client_options, server_options;
|
||||
mbedtls_test_init_handshake_options(&client_options);
|
||||
mbedtls_test_init_handshake_options(&server_options);
|
||||
|
||||
mbedtls_ssl_session saved_session;
|
||||
mbedtls_ssl_session_init(&saved_session);
|
||||
|
||||
tls_tweak_in_msglen_context tweak_in_msglen_ctx;
|
||||
memset(&tweak_in_msglen_ctx, 0, sizeof(tweak_in_msglen_ctx));
|
||||
|
||||
mbedtls_test_mock_socket *socket = NULL;
|
||||
mbedtls_ssl_context *ssl_ctx = NULL;
|
||||
mbedtls_ssl_context *peer_ssl_ctx = NULL;
|
||||
unsigned char additional_empty_hs_msg[4] = { 0, 0, 0, 0 };
|
||||
|
||||
PSA_INIT();
|
||||
|
||||
switch (handshake_message) {
|
||||
case MBEDTLS_SSL_HS_CLIENT_HELLO:
|
||||
TEST_EQUAL(endpoint, MBEDTLS_SSL_IS_SERVER);
|
||||
target_state = MBEDTLS_SSL_CLIENT_HELLO;
|
||||
peer_target_state = MBEDTLS_SSL_SERVER_HELLO;
|
||||
additional_empty_hs_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE;
|
||||
encrypted = 0;
|
||||
break;
|
||||
|
||||
case MBEDTLS_SSL_HS_SERVER_HELLO:
|
||||
TEST_EQUAL(endpoint, MBEDTLS_SSL_IS_CLIENT);
|
||||
target_state = MBEDTLS_SSL_SERVER_HELLO;
|
||||
peer_target_state = MBEDTLS_SSL_ENCRYPTED_EXTENSIONS;
|
||||
additional_empty_hs_msg[0] = MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS;
|
||||
encrypted = 0;
|
||||
break;
|
||||
|
||||
case MBEDTLS_SSL_HS_FINISHED:
|
||||
if (endpoint == MBEDTLS_SSL_IS_CLIENT) {
|
||||
target_state = MBEDTLS_SSL_SERVER_FINISHED;
|
||||
peer_target_state = MBEDTLS_SSL_CLIENT_CERTIFICATE;
|
||||
} else {
|
||||
target_state = MBEDTLS_SSL_CLIENT_FINISHED;
|
||||
peer_target_state = MBEDTLS_SSL_FLUSH_BUFFERS;
|
||||
}
|
||||
/* Finished messages are not followed by any handshake message,
|
||||
* insert an empty Finished message at the end of the record.
|
||||
*/
|
||||
additional_empty_hs_msg[0] = MBEDTLS_SSL_HS_FINISHED;
|
||||
encrypted = 1;
|
||||
break;
|
||||
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
case MBEDTLS_SSL_HS_END_OF_EARLY_DATA:
|
||||
TEST_EQUAL(endpoint, MBEDTLS_SSL_IS_SERVER);
|
||||
target_state = MBEDTLS_SSL_END_OF_EARLY_DATA;
|
||||
peer_target_state = MBEDTLS_SSL_CLIENT_CERTIFICATE;
|
||||
additional_empty_hs_msg[0] = MBEDTLS_SSL_HS_FINISHED;
|
||||
encrypted = 1;
|
||||
client_options.early_data = MBEDTLS_SSL_EARLY_DATA_ENABLED;
|
||||
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);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
TEST_FAIL("Handshake message type not supported");
|
||||
}
|
||||
|
||||
if (endpoint == MBEDTLS_SSL_IS_CLIENT) {
|
||||
ssl_ctx = &client_ep.ssl;
|
||||
peer_ssl_ctx = &server_ep.ssl;
|
||||
socket = &client_ep.socket;
|
||||
client_options.cli_log_obj = &tweak_in_msglen_ctx;
|
||||
client_options.cli_log_fun = tls_tweak_in_msglen;
|
||||
} else {
|
||||
ssl_ctx = &server_ep.ssl;
|
||||
peer_ssl_ctx = &client_ep.ssl;
|
||||
socket = &server_ep.socket;
|
||||
server_options.srv_log_obj = &tweak_in_msglen_ctx;
|
||||
server_options.srv_log_fun = tls_tweak_in_msglen;
|
||||
}
|
||||
|
||||
mbedtls_debug_set_threshold(2);
|
||||
tweak_in_msglen_ctx.ssl = ssl_ctx;
|
||||
|
||||
TEST_EQUAL(mbedtls_test_ssl_endpoint_init(&client_ep, MBEDTLS_SSL_IS_CLIENT,
|
||||
&client_options), 0);
|
||||
TEST_EQUAL(mbedtls_test_ssl_endpoint_init(&server_ep, MBEDTLS_SSL_IS_SERVER,
|
||||
&server_options), 0);
|
||||
|
||||
#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
if (handshake_message == MBEDTLS_SSL_HS_END_OF_EARLY_DATA) {
|
||||
mbedtls_ssl_conf_session_tickets_cb(&server_ep.conf,
|
||||
mbedtls_test_ticket_write,
|
||||
mbedtls_test_ticket_parse,
|
||||
NULL);
|
||||
|
||||
ret = mbedtls_ssl_set_session(&(client_ep.ssl), &saved_session);
|
||||
TEST_EQUAL(ret, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_EQUAL(mbedtls_test_mock_socket_connect(&(client_ep.socket),
|
||||
&(server_ep.socket), 1024), 0);
|
||||
|
||||
TEST_EQUAL(mbedtls_test_move_handshake_to_state(
|
||||
ssl_ctx, peer_ssl_ctx, target_state), 0);
|
||||
TEST_EQUAL(mbedtls_ssl_flush_output(ssl_ctx), 0);
|
||||
/*
|
||||
* Advance the peer further through the handshake so that it emits the
|
||||
* messages needed by the endpoint under test to proceed through its next
|
||||
* step.
|
||||
*/
|
||||
TEST_ASSERT(peer_target_state != -1);
|
||||
TEST_EQUAL(mbedtls_test_move_handshake_to_state(
|
||||
peer_ssl_ctx, ssl_ctx, peer_target_state), 0);
|
||||
TEST_EQUAL(mbedtls_ssl_flush_output(peer_ssl_ctx), 0);
|
||||
TEST_EQUAL(ssl_ctx->state, target_state);
|
||||
|
||||
if (encrypted) {
|
||||
/*
|
||||
* If the message we want to test the record boundary enforcement is
|
||||
* encrypted, we cannot manipulate easily the record that contains it.
|
||||
* In that case, we tamper with the record size after the record has been
|
||||
* fetched from the socket buffer and decrypted by
|
||||
* `mbedtls_ssl_read_record()`.
|
||||
*/
|
||||
tweak_in_msglen_ctx.armed = 1;
|
||||
tweak_in_msglen_ctx.nb_bytes = sizeof(additional_empty_hs_msg);
|
||||
} else {
|
||||
/*
|
||||
* In case of the unencrypted ClientHello or ServerHello, add an
|
||||
* additional byte to the record that contains the handshake message.
|
||||
* The byte is added in the socket buffer, before to be fetched by
|
||||
* `mbedtls_ssl_read_record()`, simulating a man-in-the-middle tampering
|
||||
* with the record.
|
||||
*/
|
||||
unsigned char *input_buffer = socket->input->buffer;
|
||||
size_t record_size = MBEDTLS_GET_UINT16_BE(input_buffer, 3);
|
||||
ret = mbedtls_test_ssl_buffer_put(socket->input, additional_empty_hs_msg,
|
||||
sizeof(additional_empty_hs_msg));
|
||||
TEST_EQUAL(ret, (int) sizeof(additional_empty_hs_msg));
|
||||
MBEDTLS_PUT_UINT16_BE(record_size + sizeof(additional_empty_hs_msg),
|
||||
input_buffer, 3);
|
||||
}
|
||||
|
||||
ret = mbedtls_ssl_handshake_step(ssl_ctx);
|
||||
TEST_EQUAL(ret, MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE);
|
||||
TEST_EQUAL(ssl_ctx->in_msglen,
|
||||
ssl_ctx->in_hslen + sizeof(additional_empty_hs_msg));
|
||||
TEST_EQUAL(ssl_ctx->in_msgtype, MBEDTLS_SSL_MSG_HANDSHAKE);
|
||||
TEST_EQUAL(ssl_ctx->in_msg[0], handshake_message);
|
||||
|
||||
if (encrypted) {
|
||||
TEST_EQUAL(tweak_in_msglen_ctx.triggered, 1);
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_test_ssl_endpoint_free(&client_ep);
|
||||
mbedtls_test_ssl_endpoint_free(&server_ep);
|
||||
mbedtls_test_free_handshake_options(&client_options);
|
||||
mbedtls_test_free_handshake_options(&server_options);
|
||||
mbedtls_debug_set_threshold(0);
|
||||
mbedtls_ssl_session_free(&saved_session);
|
||||
PSA_DONE();
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user