From: Matt Caswell Date: Mon, 3 Jul 2023 15:58:46 +0000 (+0100) Subject: Allow qtestlib to use a "fake_now" implementation X-Git-Tag: openssl-3.2.0-alpha1~496 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f9fcc7c727f0589fcd1f28ef09c8e10deee4f229;p=thirdparty%2Fopenssl.git Allow qtestlib to use a "fake_now" implementation We then use it in test_corrupted_data() to remove an OSSL_sleep() which may fail in some builds. Reviewed-by: Tim Hudson Reviewed-by: Tomas Mraz Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/21332) --- diff --git a/test/helpers/quictestlib.c b/test/helpers/quictestlib.c index 76fc7674111..52cf587c32a 100644 --- a/test/helpers/quictestlib.c +++ b/test/helpers/quictestlib.c @@ -66,9 +66,16 @@ static void handshake_finish(void *arg); static BIO_METHOD *get_bio_method(void); +static OSSL_TIME fake_now; + +static OSSL_TIME fake_now_cb(void *arg) +{ + return fake_now; +} + int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx, char *certfile, char *keyfile, - int block, QUIC_TSERVER **qtserv, SSL **cssl, + int flags, QUIC_TSERVER **qtserv, SSL **cssl, QTEST_FAULT **fault) { /* ALPN value as recognised by QUIC_TSERVER */ @@ -92,7 +99,7 @@ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx, if (!TEST_ptr(peeraddr = BIO_ADDR_new())) goto err; - if (block) { + if ((flags & QTEST_FLAG_BLOCK) != 0) { #if !defined(OPENSSL_NO_POSIX_IO) int cfd, sfd; @@ -132,7 +139,8 @@ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx, SSL_set_bio(*cssl, cbio, cbio); - if (!TEST_true(SSL_set_blocking_mode(*cssl, block))) + if (!TEST_true(SSL_set_blocking_mode(*cssl, + (flags & QTEST_FLAG_BLOCK) != 0 ? 1 : 0))) goto err; if (!TEST_true(SSL_set_initial_peer_addr(*cssl, peeraddr))) @@ -157,6 +165,10 @@ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx, tserver_args.net_rbio = sbio; tserver_args.net_wbio = fisbio; tserver_args.alpn = NULL; + if ((flags & QTEST_FLAG_FAKE_TIME) != 0) { + fake_now = ossl_time_zero(); + tserver_args.now_cb = fake_now_cb; + } if (!TEST_ptr(*qtserv = ossl_quic_tserver_new(&tserver_args, certfile, keyfile))) @@ -186,6 +198,11 @@ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx, return 0; } +void qtest_add_time(uint64_t millis) +{ + fake_now = ossl_time_add(fake_now, ossl_ms2time(millis)); +} + int qtest_supports_blocking(void) { #if !defined(OPENSSL_NO_POSIX_IO) && defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) @@ -271,6 +288,7 @@ int qtest_create_quic_connection(QUIC_TSERVER *qtserv, SSL *clientssl) if (!clienterr && retc <= 0) SSL_handle_events(clientssl); if (!servererr && rets <= 0) { + qtest_add_time(1); ossl_quic_tserver_tick(qtserv); servererr = ossl_quic_tserver_is_term_any(qtserv); if (!servererr) diff --git a/test/helpers/quictestlib.h b/test/helpers/quictestlib.h index 4660498de22..90e1b68c1fa 100644 --- a/test/helpers/quictestlib.h +++ b/test/helpers/quictestlib.h @@ -24,16 +24,26 @@ typedef struct qtest_fault_encrypted_extensions { size_t extensionslen; } QTEST_ENCRYPTED_EXTENSIONS; +/* Flags for use with qtest_create_quic_objects() */ + +/* Indicates whether we are using blocking mode or not */ +#define QTEST_FLAG_BLOCK 1 +/* Use fake time rather than real time */ +#define QTEST_FLAG_FAKE_TIME 2 + /* * Given an SSL_CTX for the client and filenames for the server certificate and * keyfile, create a server and client instances as well as a fault injector - * instance. |block| indicates whether we are using blocking mode or not. + * instance. |flags| is the logical or of flags defined above, or 0 if none. */ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx, - char *certfile, char *keyfile, int block, + char *certfile, char *keyfile, int flags, QUIC_TSERVER **qtserv, SSL **cssl, QTEST_FAULT **fault); +/* Where QTEST_FLAG_FAKE_TIME is used, add millis to the current time */ +void qtest_add_time(uint64_t millis); + /* * Free up a Fault Injector instance */ diff --git a/test/quicapitest.c b/test/quicapitest.c index 6dc57badeef..4ed10a33fc5 100644 --- a/test/quicapitest.c +++ b/test/quicapitest.c @@ -58,8 +58,8 @@ static int test_quic_write_read(int idx) if (!TEST_ptr(cctx) || !TEST_true(qtest_create_quic_objects(libctx, cctx, cert, privkey, - idx, &qtserv, &clientquic, - NULL)) + idx == 1 ? QTEST_FLAG_BLOCK : 0, + &qtserv, &clientquic, NULL)) || !TEST_true(SSL_set_tlsext_host_name(clientquic, "localhost")) || !TEST_true(qtest_create_quic_connection(qtserv, clientquic))) goto end; diff --git a/test/quicfaultstest.c b/test/quicfaultstest.c index 70d0c96af54..4d1cae01e4c 100644 --- a/test/quicfaultstest.c +++ b/test/quicfaultstest.c @@ -273,8 +273,9 @@ static int test_corrupted_data(int idx) if (!TEST_ptr(cctx)) goto err; - if (!TEST_true(qtest_create_quic_objects(NULL, cctx, cert, privkey, 0, - &qtserv, &cssl, &fault))) + if (!TEST_true(qtest_create_quic_objects(NULL, cctx, cert, privkey, + QTEST_FLAG_FAKE_TIME, &qtserv, + &cssl, &fault))) goto err; if (idx == 0) { @@ -315,16 +316,9 @@ static int test_corrupted_data(int idx) * Introduce a small delay so that the above packet has time to be detected * as lost. Loss detection times are based on RTT which should be very * fast for us since there isn't really a network. The loss delay timer is - * always at least 1ms though. We sleep for 100ms. - * TODO(QUIC): This assumes the calculated RTT will always be way less than - * 100ms - which it should be...but can we always guarantee this? An - * alternative might be to put in our own ossl_time_now() implementation for - * these tests and control the timer as part of the test. This approach has - * the added advantage that the test will behave reliably when run in a - * debugger. Without it may get unreliable debugging results. This would - * require some significant refactoring of the ssl/quic code though. + * always at least 1ms though. We skip forward 100ms */ - OSSL_sleep(100); + qtest_add_time(100); /* Send rest of message */ if (!TEST_true(ossl_quic_tserver_write(qtserv, sid, (unsigned char *)msg + 5,