diff options
author | Matt Caswell <matt@openssl.org> | 2023-07-28 15:32:57 +0100 |
---|---|---|
committer | Hugo Landau <hlandau@openssl.org> | 2023-08-02 20:27:07 +0100 |
commit | cf355bd6e5564694e589d3f96e8bde192519649c (patch) | |
tree | 875533809e3ec44d2a8d819251bb288caf8a92a1 /test | |
parent | f219abef51fd47fa5945d23bbdc379778e512dc5 (diff) |
Extend the test_quic_write_read() test to include resumption
We add an additional loop around test_quic_write_read() to repeat the
test but using a session obtained from the initial iteration to confirm
that we can successfully resume the session.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Hugo Landau <hlandau@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/21591)
Diffstat (limited to 'test')
-rw-r--r-- | test/helpers/quictestlib.c | 7 | ||||
-rw-r--r-- | test/helpers/quictestlib.h | 4 | ||||
-rw-r--r-- | test/quic_newcid_test.c | 2 | ||||
-rw-r--r-- | test/quicapitest.c | 200 | ||||
-rw-r--r-- | test/quicfaultstest.c | 8 |
5 files changed, 140 insertions, 81 deletions
diff --git a/test/helpers/quictestlib.c b/test/helpers/quictestlib.c index 98785e3306..d081b121e8 100644 --- a/test/helpers/quictestlib.c +++ b/test/helpers/quictestlib.c @@ -72,7 +72,7 @@ static OSSL_TIME fake_now_cb(void *arg) } int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx, - char *certfile, char *keyfile, + SSL_CTX *serverctx, char *certfile, char *keyfile, int flags, QUIC_TSERVER **qtserv, SSL **cssl, QTEST_FAULT **fault) { @@ -166,7 +166,9 @@ 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; - tserver_args.ctx = NULL; + if (serverctx != NULL && !TEST_true(SSL_CTX_up_ref(serverctx))) + goto err; + tserver_args.ctx = serverctx; if ((flags & QTEST_FLAG_FAKE_TIME) != 0) { fake_now = ossl_time_zero(); tserver_args.now_cb = fake_now_cb; @@ -187,6 +189,7 @@ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx, return 1; err: + SSL_CTX_free(tserver_args.ctx); BIO_ADDR_free(peeraddr); BIO_free(cbio); BIO_free(fisbio); diff --git a/test/helpers/quictestlib.h b/test/helpers/quictestlib.h index ee047bde0b..c4572db4cc 100644 --- a/test/helpers/quictestlib.h +++ b/test/helpers/quictestlib.h @@ -37,8 +37,8 @@ typedef struct qtest_fault_encrypted_extensions { * 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 flags, - QUIC_TSERVER **qtserv, SSL **cssl, + SSL_CTX *serverctx, 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 */ diff --git a/test/quic_newcid_test.c b/test/quic_newcid_test.c index 127439ff2a..cda55abca3 100644 --- a/test/quic_newcid_test.c +++ b/test/quic_newcid_test.c @@ -67,7 +67,7 @@ static int test_ncid_frame(int fail) if (!TEST_ptr(cctx)) goto err; - if (!TEST_true(qtest_create_quic_objects(NULL, cctx, cert, privkey, 0, + if (!TEST_true(qtest_create_quic_objects(NULL, cctx, NULL, cert, privkey, 0, &qtserv, &cssl, &fault))) goto err; diff --git a/test/quicapitest.c b/test/quicapitest.c index f5c8273382..3267b1b283 100644 --- a/test/quicapitest.c +++ b/test/quicapitest.c @@ -46,108 +46,164 @@ static int is_fips = 0; static int test_quic_write_read(int idx) { SSL_CTX *cctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_client_method()); + SSL_CTX *sctx = NULL; SSL *clientquic = NULL; QUIC_TSERVER *qtserv = NULL; - int j, ret = 0; + int j, k, ret = 0; unsigned char buf[20]; static char *msg = "A test message"; size_t msglen = strlen(msg); size_t numbytes = 0; int ssock = 0, csock = 0; uint64_t sid = UINT64_MAX; + SSL_SESSION *sess = NULL; if (idx >= 1 && !qtest_supports_blocking()) return TEST_skip("Blocking tests not supported in this build"); - if (!TEST_ptr(cctx) - || !TEST_true(qtest_create_quic_objects(libctx, cctx, cert, privkey, - 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; - - if (idx >= 1) { - if (!TEST_true(BIO_get_fd(ossl_quic_tserver_get0_rbio(qtserv), &ssock))) + for (k = 0; k < 2; k++) { + if (!TEST_ptr(cctx) + || !TEST_true(qtest_create_quic_objects(libctx, cctx, sctx, + cert, privkey, + idx >= 1 + ? QTEST_FLAG_BLOCK + : 0, + &qtserv, &clientquic, + NULL)) + || !TEST_true(SSL_set_tlsext_host_name(clientquic, "localhost"))) goto end; - if (!TEST_int_gt(csock = SSL_get_rfd(clientquic), 0)) - goto end; - } - sid = 0; /* client-initiated bidirectional stream */ + if (sess != NULL && !TEST_true(SSL_set_session(clientquic, sess))) + goto end; - for (j = 0; j < 2; j++) { - /* Check that sending and receiving app data is ok */ - if (!TEST_true(SSL_write_ex(clientquic, msg, msglen, &numbytes)) - || !TEST_size_t_eq(numbytes, msglen)) + if (!TEST_true(qtest_create_quic_connection(qtserv, clientquic))) goto end; + if (idx >= 1) { - do { - if (!TEST_true(wait_until_sock_readable(ssock))) + if (!TEST_true(BIO_get_fd(ossl_quic_tserver_get0_rbio(qtserv), + &ssock))) + goto end; + if (!TEST_int_gt(csock = SSL_get_rfd(clientquic), 0)) + goto end; + } + + sid = 0; /* client-initiated bidirectional stream */ + + for (j = 0; j < 2; j++) { + /* Check that sending and receiving app data is ok */ + if (!TEST_true(SSL_write_ex(clientquic, msg, msglen, &numbytes)) + || !TEST_size_t_eq(numbytes, msglen)) + goto end; + if (idx >= 1) { + do { + if (!TEST_true(wait_until_sock_readable(ssock))) + goto end; + + ossl_quic_tserver_tick(qtserv); + + if (!TEST_true(ossl_quic_tserver_read(qtserv, sid, buf, + sizeof(buf), + &numbytes))) + goto end; + } while (numbytes == 0); + + if (!TEST_mem_eq(buf, numbytes, msg, msglen)) goto end; + } - ossl_quic_tserver_tick(qtserv); + if (idx >= 2 && j > 0) + /* Introduce permanent socket error */ + BIO_closesocket(csock); - if (!TEST_true(ossl_quic_tserver_read(qtserv, sid, buf, sizeof(buf), - &numbytes))) + ossl_quic_tserver_tick(qtserv); + if (!TEST_true(ossl_quic_tserver_write(qtserv, sid, + (unsigned char *)msg, + msglen, &numbytes))) + goto end; + ossl_quic_tserver_tick(qtserv); + SSL_handle_events(clientquic); + + if (idx >= 2 && j > 0) { + if (!TEST_false(SSL_read_ex(clientquic, buf, 1, &numbytes)) + || !TEST_int_eq(SSL_get_error(clientquic, 0), + SSL_ERROR_SYSCALL) + || !TEST_false(SSL_write_ex(clientquic, msg, msglen, + &numbytes)) + || !TEST_int_eq(SSL_get_error(clientquic, 0), + SSL_ERROR_SYSCALL)) goto end; - } while (numbytes == 0); + break; + } - if (!TEST_mem_eq(buf, numbytes, msg, msglen)) + /* + * In blocking mode the SSL_read_ex call will block until the socket + * is readable and has our data. In non-blocking mode we're doing + * everything in memory, so it should be immediately available + */ + if (!TEST_true(SSL_read_ex(clientquic, buf, 1, &numbytes)) + || !TEST_size_t_eq(numbytes, 1) + || !TEST_true(SSL_has_pending(clientquic)) + || !TEST_int_eq(SSL_pending(clientquic), msglen - 1) + || !TEST_true(SSL_read_ex(clientquic, buf + 1, + sizeof(buf) - 1, &numbytes)) + || !TEST_mem_eq(buf, numbytes + 1, msg, msglen)) goto end; } - if (idx >= 2 && j > 0) - /* Introduce permanent socket error */ - BIO_closesocket(csock); + if (sess == NULL) { + /* We didn't supply a session so we're not expecting resumption */ + if (!TEST_false(SSL_session_reused(clientquic))) + goto end; + /* We should have a session ticket by now */ + sess = SSL_get1_session(clientquic); + if (!TEST_ptr(sess)) + goto end; + } else { + /* We supplied a session so we should have resumed */ + if (!TEST_true(SSL_session_reused(clientquic))) + goto end; + } - ossl_quic_tserver_tick(qtserv); - if (!TEST_true(ossl_quic_tserver_write(qtserv, sid, (unsigned char *)msg, - msglen, &numbytes))) - goto end; - ossl_quic_tserver_tick(qtserv); - SSL_handle_events(clientquic); - - if (idx >= 2 && j > 0) { - if (!TEST_false(SSL_read_ex(clientquic, buf, 1, &numbytes)) - || !TEST_int_eq(SSL_get_error(clientquic, 0), - SSL_ERROR_SYSCALL) - || !TEST_false(SSL_write_ex(clientquic, msg, msglen, - &numbytes)) - || !TEST_int_eq(SSL_get_error(clientquic, 0), - SSL_ERROR_SYSCALL)) + if (idx < 1) { + /* + * Blocking SSL_shutdown cannot be tested here due to requirement to + * tick TSERVER during drainage. + */ + if (!TEST_true(qtest_shutdown(qtserv, clientquic))) goto end; - break; + } else { + /* + * We cheat here because we have not shutdown correctly. We make the + * client think it has been shutdown normally so the session is + * eligible for reuse. + */ + SSL_CONNECTION_FROM_SSL(clientquic)->shutdown = SSL_SENT_SHUTDOWN; } - /* - * In blocking mode the SSL_read_ex call will block until the socket is - * readable and has our data. In non-blocking mode we're doing everything - * in memory, so it should be immediately available - */ - if (!TEST_true(SSL_read_ex(clientquic, buf, 1, &numbytes)) - || !TEST_size_t_eq(numbytes, 1) - || !TEST_true(SSL_has_pending(clientquic)) - || !TEST_int_eq(SSL_pending(clientquic), msglen - 1) - || !TEST_true(SSL_read_ex(clientquic, buf + 1, sizeof(buf) - 1, &numbytes)) - || !TEST_mem_eq(buf, numbytes + 1, msg, msglen)) - goto end; - } + if (sctx == NULL) { + sctx = ossl_quic_tserver_get0_ssl_ctx(qtserv); + if (!TEST_true(SSL_CTX_up_ref(sctx))) { + sctx = NULL; + goto end; + } + } + ossl_quic_tserver_free(qtserv); + qtserv = NULL; + SSL_free(clientquic); + clientquic = NULL; - if (idx < 1) - /* - * Blocking SSL_shutdown cannot be tested here due to requirement to - * tick TSERVER during drainage. - */ - if (!TEST_true(qtest_shutdown(qtserv, clientquic))) - goto end; + if (idx >= 2) + break; + } ret = 1; end: + SSL_SESSION_free(sess); ossl_quic_tserver_free(qtserv); SSL_free(clientquic); SSL_CTX_free(cctx); + SSL_CTX_free(sctx); return ret; } @@ -215,9 +271,9 @@ static int test_version(void) int testresult = 0; if (!TEST_ptr(cctx) - || !TEST_true(qtest_create_quic_objects(libctx, cctx, cert, privkey, - 0, &qtserv, &clientquic, - NULL)) + || !TEST_true(qtest_create_quic_objects(libctx, cctx, NULL, cert, + privkey, 0, &qtserv, + &clientquic, NULL)) || !TEST_true(qtest_create_quic_connection(qtserv, clientquic))) goto err; @@ -321,9 +377,9 @@ static int test_ssl_trace(void) if (!TEST_ptr(cctx) || !TEST_ptr(bio) - || !TEST_true(qtest_create_quic_objects(libctx, cctx, cert, privkey, - 0, &qtserv, &clientquic, - NULL))) + || !TEST_true(qtest_create_quic_objects(libctx, cctx, NULL, cert, + privkey, 0, &qtserv, + &clientquic, NULL))) goto err; SSL_set_msg_callback(clientquic, SSL_trace); @@ -649,7 +705,7 @@ static int test_bio_ssl(void) if (!TEST_int_eq(BIO_get_ssl(cbio, &clientquic), 1)) goto err; - if (!TEST_true(qtest_create_quic_objects(libctx, NULL, cert, privkey, + if (!TEST_true(qtest_create_quic_objects(libctx, NULL, NULL, cert, privkey, 0, &qtserv, &clientquic, NULL))) goto err; diff --git a/test/quicfaultstest.c b/test/quicfaultstest.c index af1bc1b2de..68e5cad8a0 100644 --- a/test/quicfaultstest.c +++ b/test/quicfaultstest.c @@ -34,7 +34,7 @@ static int test_basic(void) if (!TEST_ptr(cctx)) goto err; - if (!TEST_true(qtest_create_quic_objects(NULL, cctx, cert, privkey, 0, + if (!TEST_true(qtest_create_quic_objects(NULL, cctx, NULL, cert, privkey, 0, &qtserv, &cssl, NULL))) goto err; @@ -104,7 +104,7 @@ static int test_unknown_frame(void) if (!TEST_ptr(cctx)) goto err; - if (!TEST_true(qtest_create_quic_objects(NULL, cctx, cert, privkey, 0, + if (!TEST_true(qtest_create_quic_objects(NULL, cctx, NULL, cert, privkey, 0, &qtserv, &cssl, &fault))) goto err; @@ -184,7 +184,7 @@ static int test_no_transport_params(void) if (!TEST_ptr(cctx)) goto err; - if (!TEST_true(qtest_create_quic_objects(NULL, cctx, cert, privkey, 0, + if (!TEST_true(qtest_create_quic_objects(NULL, cctx, NULL, cert, privkey, 0, &qtserv, &cssl, &fault))) goto err; @@ -263,7 +263,7 @@ static int test_corrupted_data(int idx) if (!TEST_ptr(cctx)) goto err; - if (!TEST_true(qtest_create_quic_objects(NULL, cctx, cert, privkey, + if (!TEST_true(qtest_create_quic_objects(NULL, cctx, NULL, cert, privkey, QTEST_FLAG_FAKE_TIME, &qtserv, &cssl, &fault))) goto err; |