]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
stitch in ssls for SSL_listen_ex
authorNeil Horman <nhorman@openssl.org>
Fri, 11 Apr 2025 20:44:41 +0000 (16:44 -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)

include/internal/quic_channel.h
ssl/quic/quic_channel.c
ssl/quic/quic_impl.c
ssl/ssl_lib.c

index 1d008abd6330a513c6aba4231dc2709f7de6dc9e..71aa9e9294bbabacbe4e37a89923f5956bd5fe95 100644 (file)
@@ -319,6 +319,9 @@ OSSL_STATM *ossl_quic_channel_get_statm(QUIC_CHANNEL *ch);
 /* Gets the TLS handshake layer used with the channel. */
 SSL *ossl_quic_channel_get0_tls(QUIC_CHANNEL *ch);
 
+/* Sets the TLS handshake layer used for the channel */
+void ossl_quic_channel_set0_tls(QUIC_CHANNEL *ch, SSL *ssl);
+
 /* Gets the channels short header connection id length */
 size_t ossl_quic_channel_get_short_header_conn_id_len(QUIC_CHANNEL *ch);
 
index c7c60d97e9bc39321de2dc76fd8e1fabe87a0190..2e3d1b0bb105b6ef208edc1b74c5aeea40de2322 100644 (file)
@@ -561,6 +561,12 @@ SSL *ossl_quic_channel_get0_tls(QUIC_CHANNEL *ch)
     return ch->tls;
 }
 
+void ossl_quic_channel_set0_tls(QUIC_CHANNEL *ch, SSL *ssl)
+{
+    SSL_free(ch->tls);
+    ch->tls = ssl;
+}
+
 static void free_buf_mem(unsigned char *buf, size_t buf_len, void *arg)
 {
     BUF_MEM_free((BUF_MEM *)arg);
index 122264b09c80d9fdbfde01687ae520933483118d..84eac8cd7716f6496e76d7a4ced08d62c2eaa254 100644 (file)
@@ -410,6 +410,11 @@ static int expect_quic_cs(const SSL *s, QCTX *ctx)
     return expect_quic_as(s, ctx, QCTX_C | QCTX_S);
 }
 
+static int expect_quic_c(const SSL *s, QCTX *ctx)
+{
+    return expect_quic_as(s, ctx, QCTX_C);
+}
+
 static int expect_quic_csl(const SSL *s, QCTX *ctx)
 {
     return expect_quic_as(s, ctx, QCTX_C | QCTX_S | QCTX_L);
@@ -4634,13 +4639,16 @@ int ossl_quic_peeloff_conn(SSL *listener, SSL *new_conn)
     QCTX lctx;
     QCTX cctx;
     QUIC_CHANNEL *new_ch;
+    QUIC_CONNECTION *qc = NULL;
+    QUIC_LISTENER *ql = NULL;
+    SSL *tls = NULL;
     int ret = 0;
 
     if (!expect_quic_listener(listener, &lctx))
-        return 0;
+        return -1;
 
-    if (!expect_quic_cs(new_conn, &cctx))
-        return 0;
+    if (!expect_quic_c(new_conn, &cctx))
+        return -1;
 
     qctx_lock_for_io(&lctx);
     if (ossl_quic_port_get_using_peeloff(lctx.ql->port) == -1) {
@@ -4653,9 +4661,37 @@ int ossl_quic_peeloff_conn(SSL *listener, SSL *new_conn)
     ossl_quic_port_set_using_peeloff(lctx.ql->port, 1);
     new_ch = ossl_quic_port_pop_incoming(lctx.ql->port);
     if (new_ch != NULL) {
-        /*
-         * Do our cloning work here
-         */
+        qc = cctx.qc;
+        ql = lctx.ql;
+        ossl_quic_channel_free(qc->ch);
+        ossl_quic_port_free(qc->port);
+        ossl_quic_engine_free(qc->engine);
+        qc->obj.engine = ql->engine;
+        qc->engine = ql->engine;
+        qc->port = ql->port;
+        qc->pending = 1;
+#if defined(OPENSSL_THREADS)
+        ossl_crypto_mutex_free(&qc->mutex);
+        qc->mutex = ql->mutex;
+#endif
+        qc->ch = new_ch;
+        tls = ossl_ssl_connection_new_int(ossl_quic_port_get_channel_ctx(lctx.ql->port),
+                                          new_conn, TLS_method());
+        if (tls == NULL)
+            goto out;
+        SSL_free(qc->tls);
+        ossl_quic_channel_set0_tls(new_ch, tls);
+        qc->tls = tls;
+        ossl_quic_channel_get_peer_addr(new_ch, &qc->init_peer_addr); /* best effort */
+        qc->started = 1;
+        qc->as_server = 1;
+        qc->as_server_state = 1;
+        qc->default_stream_mode = SSL_DEFAULT_STREAM_MODE_AUTO_BIDI;
+        qc->default_ssl_options = ql->obj.ssl.ctx->options & OSSL_QUIC_PERMITTED_OPTIONS;
+        qc->incoming_stream_policy = SSL_INCOMING_STREAM_POLICY_AUTO;
+        qc->last_error = SSL_ERROR_NONE;
+        qc_update_reject_policy(qc);
+        ret = 1;
     }
 out:
     qctx_unlock(&lctx);
@@ -4701,9 +4737,9 @@ SSL *ossl_quic_accept_connection(SSL *ssl, uint64_t flags)
     if (ossl_quic_port_get_using_peeloff(ctx.ql->port) == 1) {
         QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED,
                                     "This listener is using SSL_accept_ex");
-        goto out; 
+        goto out;
     }
-    
+
     ossl_quic_port_set_using_peeloff(ctx.ql->port, -1);
 
     /* Wait for an incoming connection if needed. */
index 502d450b5e3a4b709c4b674082383c27ec1ec9a7..deeb4dea8fecd0daf0432a1b39f7192be98c0c85 100644 (file)
@@ -8059,16 +8059,19 @@ int SSL_get_peer_addr(SSL *ssl, BIO_ADDR *peer_addr)
     return ossl_quic_get_peer_addr(ssl, peer_addr);
 #else
     return 0;
+#endif
 }
 
 int SSL_listen_ex(SSL *listener, SSL *new_conn)
 {
 #ifndef OPENSSL_NO_QUIC
-    if (!IS_QUIC(listener) || !IS_QUIC(new_conn))
+    if (IS_QUIC(listener) && IS_QUIC(new_conn))
         return ossl_quic_peeloff_conn(listener, new_conn);
-#else
-    return 0;
+    else
 #endif
+    ERR_raise_data(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT,
+                       "SSL_listen_ex only operates on QUIC SSL objects");
+    return 0;
 }
 
 int SSL_listen(SSL *ssl)