]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
adding test for SSL_listen_ex
authorNeil Horman <nhorman@openssl.org>
Sat, 12 Apr 2025 19:06:16 +0000 (15:06 -0400)
committerNeil Horman <nhorman@openssl.org>
Fri, 5 Dec 2025 15:13:25 +0000 (10:13 -0500)
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/27397)

test/quicapitest.c

index c0fcb4411e3a07a4e1c7d92f2cc8d37d04086bc9..209e31d8e8a3593f8213b86898a61d470242afca 100644 (file)
@@ -33,6 +33,12 @@ static char *datadir = NULL;
 
 static int is_fips = 0;
 
+static BIO_ADDR *create_addr(struct in_addr *ina, short int port);
+static int bio_addr_bind(BIO *bio, BIO_ADDR *addr);
+static SSL *ql_create(SSL_CTX *ssl_ctx, BIO *bio);
+static SSL_CTX *create_server_ctx(void);
+static int qc_init(SSL *qconn, BIO_ADDR *dst_addr);
+
 /* The ssltrace test assumes some options are switched on/off */
 #if !defined(OPENSSL_NO_SSL_TRACE) \
     && defined(OPENSSL_NO_BROTLI) && defined(OPENSSL_NO_ZSTD) \
@@ -2681,6 +2687,142 @@ static int create_quic_ssl_objects(SSL_CTX *sctx, SSL_CTX *cctx,
     return ret;
 }
 
+static int test_ssl_client_as_ossl_quic_method(void)
+{
+    SSL_CTX *cctx = NULL, *sctx = NULL;
+    SSL *clientssl = NULL, *serverssl = NULL, *qlistener = NULL;
+    SSL *testssl = NULL;
+    int testresult = 0;
+    int ret, i;
+
+    if (!TEST_ptr(sctx = create_server_ctx())
+        || !TEST_ptr(cctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_method())))
+        goto err;
+
+    if (!create_quic_ssl_objects(sctx, cctx, &qlistener, &clientssl))
+        goto err;
+
+    /* Calling SSL_accept() on a listener is expected to fail */
+    ret = SSL_accept(qlistener);
+    if (!TEST_int_le(ret, 0)
+        || !TEST_int_eq(SSL_get_error(qlistener, ret), SSL_ERROR_SSL))
+        goto err;
+
+    /* Send ClientHello and server retry */
+    for (i = 0; i < 2; i++) {
+        ret = SSL_connect(clientssl);
+        if (!TEST_int_le(ret, 0)
+            || !TEST_int_eq(SSL_get_error(clientssl, ret), SSL_ERROR_WANT_READ))
+            goto err;
+        SSL_handle_events(qlistener);
+    }
+
+    /* We expect a server SSL object which has not yet completed its handshake */
+    serverssl = SSL_accept_connection(qlistener, 0);
+    if (!TEST_ptr(serverssl) || !TEST_false(SSL_is_init_finished(serverssl)))
+        goto err;
+
+    /* Call SSL_accept() and SSL_connect() until we are connected */
+    if (!TEST_true(create_bare_ssl_connection(serverssl, clientssl,
+                                              SSL_ERROR_NONE, 0, 0)))
+        goto err;
+
+    /*
+     * Now that we have used SSL_accept_connection, make sure that SSL_listen_ex
+     * returns an error to us
+     */
+    testssl = SSL_new(cctx);
+    if (!TEST_ptr(testssl))
+        goto err;
+    if (!TEST_int_eq(SSL_listen_ex(qlistener, testssl), -1))
+        goto err;
+    if (!TEST_true((ERR_GET_REASON(ERR_get_error())) ==
+                   ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED))
+        goto err;
+    ERR_clear_error();
+
+    testresult = 1;
+
+ err:
+    SSL_free(serverssl);
+    SSL_free(testssl);
+    SSL_free(clientssl);
+    SSL_free(qlistener);
+    SSL_CTX_free(sctx);
+    SSL_CTX_free(cctx);
+
+    return testresult;
+}
+
+static int test_ssl_listen_ex(void)
+{
+    SSL_CTX *cctx = NULL, *sctx = NULL, *qmctx = NULL;
+    SSL *clientssl = NULL, *serverssl = NULL, *qlistener = NULL;
+    int testresult = 0;
+    int ret = 0, i;
+
+    if (!TEST_ptr(sctx = create_server_ctx())
+        || !TEST_ptr(cctx = create_client_ctx()))
+        goto err;
+
+    if (!create_quic_ssl_objects(sctx, cctx, &qlistener, &clientssl))
+        goto err;
+
+    qmctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_method());
+    if (!TEST_ptr(qmctx))
+        goto err;
+
+    serverssl = SSL_new(qmctx);
+    if (!TEST_ptr(serverssl))
+        goto err;
+
+    /* Send ClientHello and server retry */
+    for (i = 0; i < 5; i++) {
+        ret = SSL_connect(clientssl);
+        if (!TEST_int_le(ret, 0)
+            || !TEST_int_eq(SSL_get_error(clientssl, ret), SSL_ERROR_WANT_READ))
+            goto err;
+        ret = SSL_listen_ex(qlistener, serverssl);
+        if (ret == 1)
+            break;
+        SSL_handle_events(qlistener);
+    }
+
+    /*
+     * Check to make sure we got a good return code from SSL_listen_ex
+     */
+    if (!TEST_int_eq(ret, 1))
+        goto err;
+
+    /* Call SSL_accept() and SSL_connect() until we are connected */
+    if (!TEST_true(create_bare_ssl_connection(serverssl, clientssl,
+                                              SSL_ERROR_NONE, 0, 0)))
+
+    /*
+     * Ensure that, now that we have used SSL_listen_ex, SSL_accept_connection
+     * produces an error
+     */
+    if (!TEST_ptr_null(SSL_accept_connection(qlistener, 0)))
+        goto err;
+
+    if (!TEST_true((ERR_GET_REASON(ERR_get_error())) ==
+                   ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED))
+        goto err;
+
+    ERR_clear_error();
+    testresult = 1;
+
+ err:
+    SSL_free(serverssl);
+    SSL_free(clientssl);
+    SSL_free(qlistener);
+    SSL_CTX_free(sctx);
+    SSL_CTX_free(cctx);
+    SSL_CTX_free(qmctx);
+
+    return testresult;
+}
+
 static int test_ssl_accept_connection(void)
 {
     SSL_CTX *cctx = NULL, *sctx = NULL;
@@ -3260,6 +3402,8 @@ int setup_tests(void)
     ADD_TEST(test_quic_forbidden_options);
     ADD_ALL_TESTS(test_quic_set_fd, 3);
     ADD_TEST(test_bio_ssl);
+    ADD_TEST(test_ssl_listen_ex);
+    ADD_TEST(test_ssl_client_as_ossl_quic_method);
     ADD_TEST(test_back_pressure);
     ADD_TEST(test_multiple_dgrams);
     ADD_ALL_TESTS(test_non_io_retry, 2);