File openssl-Fix_SSL_accept.patch of Package openssl-3

From 8a73447fce853778467f34e131efe0b01656851b Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Mon, 7 Apr 2025 09:58:30 +0100
Subject: [PATCH 1/5] Fix SSL_accept()

If you have a QUIC server SSL connection object, you should be able to
call SSL_accept() on it.

Fixes #27282
---
 ssl/quic/quic_method.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/ssl/quic/quic_method.c b/ssl/quic/quic_method.c
index 0de2bca47e6bb..8092855efc61a 100644
--- a/ssl/quic/quic_method.c
+++ b/ssl/quic/quic_method.c
@@ -23,5 +23,5 @@ IMPLEMENT_quic_meth_func(OSSL_QUIC_ANY_VERSION,
 
 IMPLEMENT_quic_meth_func(OSSL_QUIC_ANY_VERSION,
                          OSSL_QUIC_server_method,
-                         ssl_undefined_function,
-                         ossl_quic_connect, ssl3_undef_enc_method)
+                         ossl_quic_accept,
+                         ssl_undefined_function, ssl3_undef_enc_method)

From c2bdbb4b2b80bc84ca12e859923ab084cf21677e Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Mon, 7 Apr 2025 10:12:55 +0100
Subject: [PATCH 2/5] Document the state of the object you get from
 SSL_accept_connection()

The object may or may not have completed its handshake.

See also:
https://github.com/openssl/openssl/pull/27239#issuecomment-2772148408
---
 doc/man3/SSL_new_listener.pod | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/doc/man3/SSL_new_listener.pod b/doc/man3/SSL_new_listener.pod
index b830bd11bd174..291c103381e7e 100644
--- a/doc/man3/SSL_new_listener.pod
+++ b/doc/man3/SSL_new_listener.pod
@@ -130,6 +130,14 @@ connection is created and returned on success. If no incoming connection is
 available and the listener SSL object is configured in nonblocking mode, NULL is
 returned.
 
+The new SSL object returned from SSL_accept_connection() may or may not have
+completed its handshake at the point it is returned. Optionally, you may use the
+function L<SSL_is_init_finished(3)> to determine this. You may call the
+functions L<SSL_accept(3)>, L<SSL_do_handshake(3)> or L<SSL_handle_events(3)> to
+progress the state of the SSL object towards handshake completion. Other "I/O"
+functions may also implicitly progress the state of the handshake such as
+L<SSL_poll(3)>, L<SSL_read(3)> and L<SSL_write(3)>.
+
 The B<SSL_ACCEPT_CONNECTION_NO_BLOCK> flag may be specified to
 SSL_accept_connection(). If specified, the call does not block even if the
 listener SSL object is configured in blocking mode.

From 4abd8e0764fc1bc9e0080b9610bbdebfd194fc78 Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Mon, 7 Apr 2025 11:45:25 +0100
Subject: [PATCH 3/5] Add a test for calling SSL_accept() on an accepted
 connection

---
 test/quicapitest.c | 113 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 113 insertions(+)

diff --git a/test/quicapitest.c b/test/quicapitest.c
index 38dd42c18460b..1cd803a246ded 100644
--- a/test/quicapitest.c
+++ b/test/quicapitest.c
@@ -2502,6 +2502,18 @@ static int select_alpn(SSL *ssl, const unsigned char **out,
     return SSL_TLSEXT_ERR_ALERT_FATAL;
 }
 
+static SSL_CTX *create_client_ctx(void)
+{
+    SSL_CTX *ssl_ctx;
+
+    if (!TEST_ptr(ssl_ctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_client_method()))) {
+        SSL_CTX_free(ssl_ctx);
+        ssl_ctx = NULL;
+    }
+
+    return ssl_ctx;
+}
+
 static SSL_CTX *create_server_ctx(void)
 {
     SSL_CTX *ssl_ctx;
@@ -2687,6 +2699,106 @@ static int test_server_method_with_ssl_new(void)
     return ret;
 }
 
+static int create_quic_ssl_objects(SSL_CTX *sctx, SSL_CTX *cctx,
+                                   SSL **lssl, SSL **cssl)
+{
+    BIO_ADDR *addr = NULL;
+    struct in_addr ina;
+    BIO *cbio = NULL, *sbio = NULL;
+    int ret = 0;
+
+    *cssl = *lssl = NULL;
+    ina.s_addr = htonl(0x1f000001);
+
+    if (!TEST_true(BIO_new_bio_dgram_pair(&cbio, 0, &sbio, 0)))
+        goto err;
+
+    if (!TEST_ptr(addr = create_addr(&ina, 8040)))
+        goto err;
+
+    if (!TEST_true(bio_addr_bind(sbio, addr)))
+        goto err;
+    addr = NULL;
+
+    *lssl = ql_create(sctx, sbio);
+    sbio = NULL;
+    if (!TEST_ptr(*lssl))
+        goto err;
+
+    if (!TEST_ptr(*cssl = SSL_new(cctx)))
+        goto err;
+
+    if (!TEST_ptr(addr = create_addr(&ina, 8040)))
+        goto err;
+    if (!TEST_true(bio_addr_bind(cbio, addr)))
+        goto err;
+    if(!TEST_ptr(addr = BIO_ADDR_dup(addr)))
+        goto err;
+
+    if (!TEST_true(qc_init(*cssl, addr)))
+        goto err;
+    SSL_set_bio(*cssl, cbio, cbio);
+    cbio = NULL;
+
+    ret = 1;
+
+ err:
+    if (!ret) {
+        SSL_free(*cssl);
+        SSL_free(*lssl);
+        *cssl = *lssl = NULL;
+    }
+    BIO_free(cbio);
+    BIO_free(sbio);
+
+    return ret;
+}
+
+static int test_ssl_accept_connection(void)
+{
+    SSL_CTX *cctx = NULL, *sctx = NULL;
+    SSL *clientssl = NULL, *serverssl = NULL, *qlistener = NULL;
+    int testresult = 0;
+    int ret, 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;
+
+    /* 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;
+
+    testresult = 1;
+
+ err:
+    SSL_free(serverssl);
+    SSL_free(clientssl);
+    SSL_free(qlistener);
+    SSL_CTX_free(sctx);
+    SSL_CTX_free(cctx);
+
+    return testresult;
+}
+
 /***********************************************************************************/
 OPT_TEST_DECLARE_USAGE("provider config certsdir datadir\n")
 
@@ -2786,6 +2898,7 @@ int setup_tests(void)
     ADD_TEST(test_new_token);
 #endif
     ADD_TEST(test_server_method_with_ssl_new);
+    ADD_TEST(test_ssl_accept_connection);
     return 1;
  err:
     cleanup_tests();

From 25b60daff6e60db0ea65471c16bf529ac07f237c Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Mon, 7 Apr 2025 13:02:59 +0100
Subject: [PATCH 4/5] fixup! Add a test for calling SSL_accept() on an accepted
 connection

---
 test/quicapitest.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/test/quicapitest.c b/test/quicapitest.c
index 1cd803a246ded..9f466f298a34a 100644
--- a/test/quicapitest.c
+++ b/test/quicapitest.c
@@ -2732,7 +2732,7 @@ static int create_quic_ssl_objects(SSL_CTX *sctx, SSL_CTX *cctx,
         goto err;
     if (!TEST_true(bio_addr_bind(cbio, addr)))
         goto err;
-    if(!TEST_ptr(addr = BIO_ADDR_dup(addr)))
+    if (!TEST_ptr(addr = BIO_ADDR_dup(addr)))
         goto err;
 
     if (!TEST_true(qc_init(*cssl, addr)))
@@ -2784,7 +2784,7 @@ static int test_ssl_accept_connection(void)
 
     /* Call SSL_accept() and SSL_connect() until we are connected */
     if (!TEST_true(create_bare_ssl_connection(serverssl, clientssl,
-                   SSL_ERROR_NONE, 0, 0)))
+                                              SSL_ERROR_NONE, 0, 0)))
         goto err;
 
     testresult = 1;

From f0fa7c61370b97d3037f60b639b70abba5ed0989 Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Mon, 7 Apr 2025 13:54:35 +0100
Subject: [PATCH 5/5] fixup! Add a test for calling SSL_accept() on an accepted
 connection

---
 test/quicapitest.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/test/quicapitest.c b/test/quicapitest.c
index 9f466f298a34a..25b7d242cf327 100644
--- a/test/quicapitest.c
+++ b/test/quicapitest.c
@@ -2732,11 +2732,12 @@ static int create_quic_ssl_objects(SSL_CTX *sctx, SSL_CTX *cctx,
         goto err;
     if (!TEST_true(bio_addr_bind(cbio, addr)))
         goto err;
-    if (!TEST_ptr(addr = BIO_ADDR_dup(addr)))
-        goto err;
 
-    if (!TEST_true(qc_init(*cssl, addr)))
+    if (!TEST_true(qc_init(*cssl, addr))) {
+        addr = NULL;
         goto err;
+    }
+    addr = NULL;
     SSL_set_bio(*cssl, cbio, cbio);
     cbio = NULL;
 
@@ -2750,6 +2751,7 @@ static int create_quic_ssl_objects(SSL_CTX *sctx, SSL_CTX *cctx,
     }
     BIO_free(cbio);
     BIO_free(sbio);
+    BIO_ADDR_free(addr);
 
     return ret;
 }
openSUSE Build Service is sponsored by