From: Neil Horman Date: Wed, 8 Jan 2025 19:08:36 +0000 (-0500) Subject: use internal callback to generate user ssl X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e86b74af7a30fe64770495c5077b1eddccbf28bb;p=thirdparty%2Fopenssl.git use internal callback to generate user ssl Reviewed-by: Matt Caswell Reviewed-by: Tomas Mraz Reviewed-by: Saša Nedvědický (Merged from https://github.com/openssl/openssl/pull/26361) --- diff --git a/include/internal/quic_channel.h b/include/internal/quic_channel.h index c01d4a025e0..c426cfad68d 100644 --- a/include/internal/quic_channel.h +++ b/include/internal/quic_channel.h @@ -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); diff --git a/ssl/quic/quic_channel.c b/ssl/quic/quic_channel.c index 80360f687c8..e2a46c7f81a 100644 --- a/ssl/quic/quic_channel.c +++ b/ssl/quic/quic_channel.c @@ -428,7 +428,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; @@ -451,11 +456,6 @@ QUIC_CHANNEL *ossl_quic_channel_new(const QUIC_CHANNEL_ARGS *args) } #endif - if (!ch_init(ch)) { - OPENSSL_free(ch); - return NULL; - } - return ch; } diff --git a/ssl/quic/quic_port.c b/ssl/quic/quic_port.c index 4377fb1d3e7..197afd5c9d6 100644 --- a/ssl/quic/quic_port.c +++ b/ssl/quic/quic_port.c @@ -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 @@ -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; }