diff options
Diffstat (limited to 'test/quicapitest.c')
| -rw-r--r-- | test/quicapitest.c | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/test/quicapitest.c b/test/quicapitest.c index c61dda6f7f7f..d40413898a6f 100644 --- a/test/quicapitest.c +++ b/test/quicapitest.c @@ -19,6 +19,7 @@ #include "testutil.h" #include "testutil/output.h" #include "../ssl/ssl_local.h" +#include "../ssl/quic/quic_channel_local.h" #include "internal/quic_error.h" static OSSL_LIB_CTX *libctx = NULL; @@ -2689,6 +2690,84 @@ err: return testresult; } +/* + * Verify that the SSL* received in the info callback after SSL_new_from_listener + * is the outer QUIC connection object, not the inner TLS SSL. + */ +static SSL *new_from_listener_info_cb_ssl = NULL; + +static void new_from_listener_info_cb(const SSL *ssl, int type, int val) +{ + if (type == SSL_CB_HANDSHAKE_DONE) + new_from_listener_info_cb_ssl = (SSL *)ssl; +} + +static int test_ssl_new_from_listener_user_ssl(void) +{ + SSL_CTX *lctx = NULL, *sctx = NULL; + SSL *qlistener = NULL, *qserver = NULL, *qconn = NULL; + BIO *lbio = NULL, *sbio = NULL; + BIO_ADDR *addr = NULL; + struct in_addr ina; + int ret = 0, chk; + + ina.s_addr = htonl(0x1f000001); + new_from_listener_info_cb_ssl = NULL; + + if (!TEST_ptr(lctx = create_server_ctx()) + || !TEST_ptr(sctx = create_server_ctx()) + || !TEST_true(BIO_new_bio_dgram_pair(&lbio, 0, &sbio, 0))) + goto err; + + /* + * Register an info callback on the listener CTX. The inner TLS connection + * created by ossl_quic_new_from_listener inherits this CTX, so when the TLS + * handshake completes it invokes the callback with user_ssl. That must be + * qconn (the outer QUIC object), not the inner TLS SSL object. + */ + SSL_CTX_set_info_callback(lctx, new_from_listener_info_cb); + + if (!TEST_ptr(addr = create_addr(&ina, 8041)) + || !TEST_true(bio_addr_bind(lbio, addr))) + goto err; + addr = NULL; + + if (!TEST_ptr(addr = create_addr(&ina, 4081)) + || !TEST_true(bio_addr_bind(sbio, addr))) + goto err; + addr = NULL; + + qlistener = ql_create(lctx, lbio); + lbio = NULL; + qserver = ql_create(sctx, sbio); + sbio = NULL; + if (!TEST_ptr(qlistener) || !TEST_ptr(qserver) + || !TEST_ptr(qconn = SSL_new_from_listener(qlistener, 0)) + || !TEST_ptr(addr = create_addr(&ina, 4081)) + || !TEST_true(qc_init(qconn, addr))) + goto err; + + while ((chk = SSL_do_handshake(qconn)) == -1) { + SSL_handle_events(qserver); + SSL_handle_events(qlistener); + } + + ret = TEST_int_gt(chk, 0) + && TEST_ptr(new_from_listener_info_cb_ssl) + && TEST_ptr_eq(new_from_listener_info_cb_ssl, qconn); + +err: + SSL_free(qconn); + SSL_free(qlistener); + SSL_free(qserver); + BIO_free(lbio); + BIO_free(sbio); + SSL_CTX_free(sctx); + SSL_CTX_free(lctx); + BIO_ADDR_free(addr); + return ret; +} + static int test_server_method_with_ssl_new(void) { SSL_CTX *ctx = NULL; @@ -2941,6 +3020,74 @@ err: return TEST_skip("EC(X) keys are not supported in this build"); #endif } + +static int test_quic_resize_txe(void) +{ + SSL_CTX *cctx = NULL; + SSL *clientquic = NULL; + QUIC_TSERVER *qtserv = NULL; + QUIC_CHANNEL *ch = NULL; + unsigned char msg[] = "resize test"; + unsigned char buf[sizeof(msg)]; + size_t numbytes = 0; + int ret = 0; + + if (!TEST_ptr(cctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_client_method()))) + goto end; + + if (!TEST_true(qtest_create_quic_objects(libctx, cctx, NULL, + cert, privkey, 0, + &qtserv, &clientquic, + NULL, NULL))) + goto end; + + if (!TEST_true(qtest_create_quic_connection(qtserv, clientquic))) + goto end; + + /* + * Client writes first to open stream 0 (client-initiated bidirectional). + * The server must see the stream before it can write back on it. + */ + if (!TEST_true(SSL_write_ex(clientquic, msg, sizeof(msg), &numbytes)) + || !TEST_size_t_eq(numbytes, sizeof(msg))) + goto end; + + ossl_quic_tserver_tick(qtserv); + if (!TEST_true(ossl_quic_tserver_read(qtserv, 0, buf, sizeof(buf), + &numbytes))) + goto end; + + /* + * Increase the server's QTX MDPL above the initial allocation size + * (QUIC_MIN_INITIAL_DGRAM_LEN = 1200). All TXEs in the free list have + * alloc_len = 1200, so the next write will trigger qtx_resize_txe. + */ + ch = ossl_quic_tserver_get_channel(qtserv); + if (!TEST_true(ossl_qtx_set_mdpl(ch->qtx, + QUIC_MIN_INITIAL_DGRAM_LEN + 250))) + goto end; + + /* Trigger a server write: exercises qtx_resize_txe via qtx_reserve_txe */ + if (!TEST_true(ossl_quic_tserver_write(qtserv, 0, + msg, sizeof(msg), &numbytes)) + || !TEST_size_t_eq(numbytes, sizeof(msg))) + goto end; + + ossl_quic_tserver_tick(qtserv); + SSL_handle_events(clientquic); + + if (!TEST_true(SSL_read_ex(clientquic, buf, sizeof(buf), &numbytes)) + || !TEST_mem_eq(buf, numbytes, msg, sizeof(msg))) + goto end; + + ret = 1; +end: + ossl_quic_tserver_free(qtserv); + SSL_free(clientquic); + SSL_CTX_free(cctx); + return ret; +} + /***********************************************************************************/ OPT_TEST_DECLARE_USAGE("provider config certsdir datadir\n") @@ -3036,6 +3183,7 @@ int setup_tests(void) ADD_TEST(test_domain_flags); ADD_TEST(test_early_ticks); ADD_TEST(test_ssl_new_from_listener); + ADD_TEST(test_ssl_new_from_listener_user_ssl); #ifndef OPENSSL_NO_SSL_TRACE ADD_TEST(test_new_token); #endif @@ -3043,6 +3191,8 @@ int setup_tests(void) ADD_TEST(test_ssl_accept_connection); ADD_TEST(test_ssl_set_verify); ADD_TEST(test_client_hello_retry); + ADD_TEST(test_quic_resize_txe); + return 1; err: cleanup_tests(); |
