Fix intermittent sslapitest early data related failures

Early data is time sensitive. We have an approx 8 second allowance between
writing the early data and reading it. If we exceed that time tests will
fail. This can sometimes (rarely) occur in normal CI operation. We can try
and detect this and just ignore the result of such test failures if the test
has taken too long. We assume anything over 7 seconds is too long.

This is a partial fix for #22605

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/23966)

(cherry picked from commit 1848c561ec)
This commit is contained in:
Matt Caswell 2024-03-25 12:32:17 +00:00
parent eb3b903af9
commit 91d5fd54ee
2 changed files with 69 additions and 17 deletions

View File

@ -531,7 +531,7 @@ IF[{- !$disabled{tests} -}]
SOURCE[sslapitest]=sslapitest.c helpers/ssltestlib.c filterprov.c tls-provider.c
INCLUDE[sslapitest]=../include ../apps/include ..
DEPEND[sslapitest]=../libcrypto ../libssl libtestutil.a
DEPEND[sslapitest]=../libcrypto.a ../libssl.a libtestutil.a
SOURCE[ssl_handshake_rtt_test]=ssl_handshake_rtt_test.c helpers/ssltestlib.c
INCLUDE[ssl_handshake_rtt_test]=../include ../apps/include ..

View File

@ -3511,6 +3511,25 @@ static int setupearly_data_test(SSL_CTX **cctx, SSL_CTX **sctx, SSL **clientssl,
return 1;
}
static int check_early_data_timeout(OSSL_TIME timer)
{
int res = 0;
/*
* Early data is time sensitive. We have an approx 8 second allowance
* between writing the early data and reading it. If we exceed that time
* then this test will fail. This can sometimes (rarely) occur in normal CI
* operation. We can try and detect this and just ignore the result of this
* test if it has taken too long. We assume anything over 7 seconds is too
* long
*/
timer = ossl_time_subtract(ossl_time_now(), timer);
if (ossl_time_compare(timer, ossl_seconds2time(7)) >= 0)
res = TEST_skip("Test took too long, ignoring result");
return res;
}
static int test_early_data_read_write(int idx)
{
SSL_CTX *cctx = NULL, *sctx = NULL;
@ -3520,6 +3539,7 @@ static int test_early_data_read_write(int idx)
unsigned char buf[20], data[1024];
size_t readbytes, written, eoedlen, rawread, rawwritten;
BIO *rbio;
OSSL_TIME timer;
/* Artificially give the next 2 tickets some age for non PSK sessions */
if (idx != 2)
@ -3533,13 +3553,20 @@ static int test_early_data_read_write(int idx)
artificial_ticket_time = 0;
/* Write and read some early data */
timer = ossl_time_now();
if (!TEST_true(SSL_write_early_data(clientssl, MSG1, strlen(MSG1),
&written))
|| !TEST_size_t_eq(written, strlen(MSG1))
|| !TEST_int_eq(SSL_read_early_data(serverssl, buf,
sizeof(buf), &readbytes),
SSL_READ_EARLY_DATA_SUCCESS)
|| !TEST_mem_eq(MSG1, readbytes, buf, strlen(MSG1))
|| !TEST_size_t_eq(written, strlen(MSG1)))
goto end;
if (!TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf),
&readbytes),
SSL_READ_EARLY_DATA_SUCCESS)) {
testresult = check_early_data_timeout(timer);
goto end;
}
if (!TEST_mem_eq(MSG1, readbytes, buf, strlen(MSG1))
|| !TEST_int_eq(SSL_get_early_data_status(serverssl),
SSL_EARLY_DATA_ACCEPTED))
goto end;
@ -3756,6 +3783,7 @@ static int test_early_data_replay_int(int idx, int usecb, int confopt)
SSL_SESSION *sess = NULL;
size_t readbytes, written;
unsigned char buf[20];
OSSL_TIME timer;
allow_ed_cb_called = 0;
@ -3810,6 +3838,7 @@ static int test_early_data_replay_int(int idx, int usecb, int confopt)
goto end;
/* Write and read some early data */
timer = ossl_time_now();
if (!TEST_true(SSL_write_early_data(clientssl, MSG1, strlen(MSG1),
&written))
|| !TEST_size_t_eq(written, strlen(MSG1)))
@ -3830,8 +3859,11 @@ static int test_early_data_replay_int(int idx, int usecb, int confopt)
/* In this case the callback decides to accept the early data */
if (!TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf),
&readbytes),
SSL_READ_EARLY_DATA_SUCCESS)
|| !TEST_mem_eq(MSG1, strlen(MSG1), buf, readbytes)
SSL_READ_EARLY_DATA_SUCCESS)) {
testresult = check_early_data_timeout(timer);
goto end;
}
if (!TEST_mem_eq(MSG1, strlen(MSG1), buf, readbytes)
/*
* Server will have sent its flight so client can now send
* end of early data and complete its half of the handshake
@ -4348,13 +4380,19 @@ static int test_early_data_psk(int idx)
|| !TEST_int_eq(ERR_GET_REASON(ERR_get_error()), err))
goto end;
} else {
OSSL_TIME timer = ossl_time_now();
if (!TEST_true(SSL_write_early_data(clientssl, MSG1, strlen(MSG1),
&written)))
goto end;
if (!TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf),
&readbytes), readearlyres)
|| (readearlyres == SSL_READ_EARLY_DATA_SUCCESS
&readbytes), readearlyres)) {
testresult = check_early_data_timeout(timer);
goto end;
}
if ((readearlyres == SSL_READ_EARLY_DATA_SUCCESS
&& !TEST_mem_eq(buf, readbytes, MSG1, strlen(MSG1)))
|| !TEST_int_eq(SSL_get_early_data_status(serverssl), edstatus)
|| !TEST_int_eq(SSL_connect(clientssl), connectres))
@ -4392,6 +4430,7 @@ static int test_early_data_psk_with_all_ciphers(int idx)
unsigned char buf[20];
size_t readbytes, written;
const SSL_CIPHER *cipher;
OSSL_TIME timer;
const char *cipher_str[] = {
TLS1_3_RFC_AES_128_GCM_SHA256,
TLS1_3_RFC_AES_256_GCM_SHA384,
@ -4449,14 +4488,19 @@ static int test_early_data_psk_with_all_ciphers(int idx)
goto end;
SSL_set_connect_state(clientssl);
timer = ossl_time_now();
if (!TEST_true(SSL_write_early_data(clientssl, MSG1, strlen(MSG1),
&written)))
goto end;
if (!TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf),
&readbytes),
SSL_READ_EARLY_DATA_SUCCESS)
|| !TEST_mem_eq(buf, readbytes, MSG1, strlen(MSG1))
SSL_READ_EARLY_DATA_SUCCESS)) {
testresult = check_early_data_timeout(timer);
goto end;
}
if (!TEST_mem_eq(buf, readbytes, MSG1, strlen(MSG1))
|| !TEST_int_eq(SSL_get_early_data_status(serverssl),
SSL_EARLY_DATA_ACCEPTED)
|| !TEST_int_eq(SSL_connect(clientssl), 1)
@ -7772,6 +7816,7 @@ static int test_info_callback(int tst)
SSL_SESSION *sess = NULL;
size_t written, readbytes;
unsigned char buf[80];
OSSL_TIME timer;
/* early_data tests */
if (!TEST_true(setupearly_data_test(&cctx, &sctx, &clientssl,
@ -7786,13 +7831,20 @@ static int test_info_callback(int tst)
sslapi_info_callback);
/* Write and read some early data and then complete the connection */
timer = ossl_time_now();
if (!TEST_true(SSL_write_early_data(clientssl, MSG1, strlen(MSG1),
&written))
|| !TEST_size_t_eq(written, strlen(MSG1))
|| !TEST_int_eq(SSL_read_early_data(serverssl, buf,
sizeof(buf), &readbytes),
SSL_READ_EARLY_DATA_SUCCESS)
|| !TEST_mem_eq(MSG1, readbytes, buf, strlen(MSG1))
|| !TEST_size_t_eq(written, strlen(MSG1)))
goto end;
if (!TEST_int_eq(SSL_read_early_data(serverssl, buf,
sizeof(buf), &readbytes),
SSL_READ_EARLY_DATA_SUCCESS)) {
testresult = check_early_data_timeout(timer);
goto end;
}
if (!TEST_mem_eq(MSG1, readbytes, buf, strlen(MSG1))
|| !TEST_int_eq(SSL_get_early_data_status(serverssl),
SSL_EARLY_DATA_ACCEPTED)
|| !TEST_true(create_ssl_connection(serverssl, clientssl,