]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Allow qtestlib to use a "fake_now" implementation
authorMatt Caswell <matt@openssl.org>
Mon, 3 Jul 2023 15:58:46 +0000 (16:58 +0100)
committerPauli <pauli@openssl.org>
Thu, 6 Jul 2023 02:55:21 +0000 (12:55 +1000)
We then use it in test_corrupted_data() to remove an OSSL_sleep() which
may fail in some builds.

Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/21332)

test/helpers/quictestlib.c
test/helpers/quictestlib.h
test/quicapitest.c
test/quicfaultstest.c

index 76fc7674111b8dacecc1fcb415d02051ccb65914..52cf587c32a51b303695b21001ba1b37f25c42bb 100644 (file)
@@ -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)
index 4660498de22f2a38568795a2d9b9cb641fe95dc6..90e1b68c1fa3a49e8c2903a12319f9b43240ea83 100644 (file)
@@ -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
  */
index 6dc57badeefefc45a906b07f491524738be6e0ab..4ed10a33fc5d43eac05a6ea916468d62698d84d6 100644 (file)
@@ -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;
index 70d0c96af549bd4427d438c25f5bb06ae50192eb..4d1cae01e4c07dd4c6e7426a92a149309c1c37a1 100644 (file)
@@ -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,