]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
use internal callback to generate user ssl
authorNeil Horman <nhorman@openssl.org>
Wed, 8 Jan 2025 19:08:36 +0000 (14:08 -0500)
committerNeil Horman <nhorman@openssl.org>
Mon, 17 Feb 2025 16:27:33 +0000 (11:27 -0500)
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26361)

include/internal/quic_channel.h
ssl/quic/quic_channel.c
ssl/quic/quic_port.c

index c01d4a025e07c46458773e633a08707bc2d09b11..c426cfad68da58b689abef2d339ad061f18abe2b 100644 (file)
@@ -175,7 +175,9 @@ typedef struct quic_terminate_cause_st {
  *
  * Only QUIC_PORT should use this function.
  */
-QUIC_CHANNEL *ossl_quic_channel_new(const QUIC_CHANNEL_ARGS *args);
+QUIC_CHANNEL *ossl_quic_channel_alloc(const QUIC_CHANNEL_ARGS *args);
+int ossl_quic_channel_init(QUIC_CHANNEL *ch);
+
 
 /* No-op if ch is NULL. */
 void ossl_quic_channel_free(QUIC_CHANNEL *ch);
index 8b061630a6c47a6c6bcf0f332e7780d428a5526c..d8ec096b34bae9ebbdb6edd861f90fac142d87c5 100644 (file)
@@ -429,7 +429,12 @@ static void ch_cleanup(QUIC_CHANNEL *ch)
 #endif
 }
 
-QUIC_CHANNEL *ossl_quic_channel_new(const QUIC_CHANNEL_ARGS *args)
+int ossl_quic_channel_init(QUIC_CHANNEL *ch)
+{
+    return ch_init(ch);
+}
+
+QUIC_CHANNEL *ossl_quic_channel_alloc(const QUIC_CHANNEL_ARGS *args)
 {
     QUIC_CHANNEL *ch = NULL;
 
@@ -452,11 +457,6 @@ QUIC_CHANNEL *ossl_quic_channel_new(const QUIC_CHANNEL_ARGS *args)
     }
 #endif
 
-    if (!ch_init(ch)) {
-        OPENSSL_free(ch);
-        return NULL;
-    }
-
     return ch;
 }
 
index 4377fb1d3e7ebc551ad7efe5f0bf9e41778f26ad..197afd5c9d645251e7f4c8fdd39fa9d6112b74ad 100644 (file)
@@ -16,6 +16,7 @@
 #include "quic_port_local.h"
 #include "quic_channel_local.h"
 #include "quic_engine_local.h"
+#include "quic_local.h"
 #include "../ssl_local.h"
 #include <openssl/rand.h>
 
@@ -444,20 +445,35 @@ int ossl_quic_port_set_net_wbio(QUIC_PORT *port, BIO *net_wbio)
  * ============================
  */
 
-static SSL *port_new_handshake_layer(QUIC_PORT *port)
+static SSL *port_new_handshake_layer(QUIC_PORT *port, QUIC_CHANNEL *ch)
 {
     SSL *tls = NULL;
     SSL_CONNECTION *tls_conn = NULL;
+    SSL *user_ssl = NULL;
+    QUIC_CONNECTION *qc = NULL;
+
+    if (port->get_conn_user_ssl != NULL) {
+        user_ssl = port->get_conn_user_ssl(ch, port->user_ssl_arg);
+        if (user_ssl == NULL)
+            return NULL;
+        qc = (QUIC_CONNECTION *)user_ssl;
+    }
 
-    /*
-     * TODO(QUIC SERVER): NULL below needs to be replaced with a real user SSL
-     * object of either the listener or the domain which is associated with
-     * the port. https://github.com/openssl/project/issues/918
-     */
-    tls = ossl_ssl_connection_new_int(port->channel_ctx, NULL, TLS_method());
+    tls = ossl_ssl_connection_new_int(port->channel_ctx, user_ssl, TLS_method());
     if (tls == NULL || (tls_conn = SSL_CONNECTION_FROM_SSL(tls)) == NULL)
         return NULL;
 
+    /*
+     * If we got a user ssl, which will be embedded in a quic connection
+     * we need to fix up the connections tls pointer here
+     */
+    if (qc != NULL)
+        qc->tls = tls;
+
+    if (ql != NULL && ql->obj.ssl.ctx->new_pending_ssl_cb != NULL)
+        ql->obj.ssl.ctx->new_pending_ssl_cb(ql->obj.ssl.ctx, user_ssl,
+                                            ql->obj.ssl.ctx->new_pending_ssl_arg);
+
     /* Override the user_ssl of the inner connection. */
     tls_conn->s3.flags      |= TLS1_FLAGS_QUIC;
 
@@ -474,22 +490,49 @@ static QUIC_CHANNEL *port_make_channel(QUIC_PORT *port, SSL *tls, int is_server)
 
     args.port       = port;
     args.is_server  = is_server;
-    args.tls        = (tls != NULL ? tls : port_new_handshake_layer(port));
     args.lcidm      = port->lcidm;
     args.srtm       = port->srtm;
-    if (args.tls == NULL)
+
+    /*
+     * Creating a a new channel is made a bit tricky here as there is a
+     * bit of a circular dependency.  Initalizing a channel requires that
+     * the ch->tls and optionally the qlog_title be configured prior to
+     * initalization, but we need the channel at least partially configured
+     * to create the new handshake layer, so we have to do this in a few steps.
+     */
+
+    /*
+     * start by allocation and provisioning as much of the channel as we can
+     */
+    ch = ossl_quic_channel_alloc(&args);
+    if (ch == NULL)
         return NULL;
 
+    /*
+     * Fixup the channel tls connection here before we init the channel
+     */
+    ch->tls = (tls != NULL) ? tls : port_new_handshake_layer(port, ch);
+
 #ifndef OPENSSL_NO_QLOG
-    args.use_qlog   = 1; /* disabled if env not set */
-    args.qlog_title = args.tls->ctx->qlog_title;
+    /*
+     * If we're using qlog, make sure the tls get further configured properly
+     */
+    ch->use_qlog = 1;
+    if (ch->tls->ctx->qlog_title != NULL) {
+        if ((ch->qlog_title = OPENSSL_strdup(ch->tls->ctx->qlog_title)) == NULL) {
+            OPENSSL_free(ch);
+            return NULL;
+        }
+    }
 #endif
 
-    ch = ossl_quic_channel_new(&args);
-    if (ch == NULL) {
-        if (tls == NULL)
-            SSL_free(args.tls);
-
+    /*
+     * And finally init the channel struct
+     */
+    if (!ossl_quic_channel_init(ch)) {
+        if (ch->tls == NULL)
+            SSL_free(ch->tls);
+        OPENSSL_free(ch);
         return NULL;
     }