diff options
author | Matt Caswell <matt@openssl.org> | 2023-05-01 15:40:28 +0100 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2023-05-24 12:18:27 +0100 |
commit | 63dfde87c46f8ad037ad5b5e635e609f4909578e (patch) | |
tree | 7f360b776e5aa174bc48bb2d1d9bd9f58ca2c7e7 | |
parent | 6dea91f56dcbcb0979dd36790664808ad960faf9 (diff) |
Add initial QUIC support for the msg_callback
At this stage we just support msg_callback on receipt of a datagram.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Hugo Landau <hlandau@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/20914)
-rw-r--r-- | include/internal/quic_channel.h | 5 | ||||
-rw-r--r-- | include/internal/quic_record_rx.h | 8 | ||||
-rw-r--r-- | include/openssl/ssl3.h | 3 | ||||
-rw-r--r-- | ssl/quic/quic_channel.c | 21 | ||||
-rw-r--r-- | ssl/quic/quic_channel_local.h | 5 | ||||
-rw-r--r-- | ssl/quic/quic_impl.c | 42 | ||||
-rw-r--r-- | ssl/quic/quic_local.h | 5 | ||||
-rw-r--r-- | ssl/quic/quic_record_rx.c | 12 | ||||
-rw-r--r-- | ssl/s3_lib.c | 8 | ||||
-rw-r--r-- | ssl/ssl_lib.c | 21 | ||||
-rw-r--r-- | ssl/ssl_local.h | 6 |
11 files changed, 99 insertions, 37 deletions
diff --git a/include/internal/quic_channel.h b/include/internal/quic_channel.h index 6dbf08665d..ac73097985 100644 --- a/include/internal/quic_channel.h +++ b/include/internal/quic_channel.h @@ -130,6 +130,11 @@ typedef struct quic_channel_args_st { */ OSSL_TIME (*now_cb)(void *arg); void *now_cb_arg; + + /* Message callback related arguments */ + ossl_msg_cb msg_callback; + void *msg_callback_arg; + SSL *msg_callback_s; } QUIC_CHANNEL_ARGS; typedef struct quic_channel_st QUIC_CHANNEL; diff --git a/include/internal/quic_record_rx.h b/include/internal/quic_record_rx.h index 95c0fa5635..4817347993 100644 --- a/include/internal/quic_record_rx.h +++ b/include/internal/quic_record_rx.h @@ -18,6 +18,9 @@ # ifndef OPENSSL_NO_QUIC +typedef void (*ossl_msg_cb)(int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg); + /* * QUIC Record Layer - RX * ====================== @@ -45,6 +48,11 @@ typedef struct ossl_qrx_args_st { /* Initial key phase. For debugging use only; always 0 in real use. */ unsigned char init_key_phase_bit; + + /* Message callback related arguments */ + ossl_msg_cb msg_callback; + void *msg_callback_arg; + SSL *msg_callback_s; } OSSL_QRX_ARGS; /* Instantiates a new QRX. */ diff --git a/include/openssl/ssl3.h b/include/openssl/ssl3.h index 6c172f45f9..f993d0baa0 100644 --- a/include/openssl/ssl3.h +++ b/include/openssl/ssl3.h @@ -239,6 +239,9 @@ extern "C" { # define SSL3_RT_HEADER 0x100 # define SSL3_RT_INNER_CONTENT_TYPE 0x101 +/* Pseudo content types for QUIC */ +# define SSL3_RT_QUIC_DATAGRAM 0x200 + # define SSL3_AL_WARNING 1 # define SSL3_AL_FATAL 2 diff --git a/ssl/quic/quic_channel.c b/ssl/quic/quic_channel.c index 4325434c4f..2f655f61cd 100644 --- a/ssl/quic/quic_channel.c +++ b/ssl/quic/quic_channel.c @@ -239,6 +239,10 @@ static int ch_init(QUIC_CHANNEL *ch) qrx_args.demux = ch->demux; qrx_args.short_conn_id_len = rx_short_cid_len; qrx_args.max_deferred = 32; + /* Callback related arguments */ + qrx_args.msg_callback = ch->msg_callback; + qrx_args.msg_callback_arg = ch->msg_callback_arg; + qrx_args.msg_callback_s = ch->msg_callback_s; if ((ch->qrx = ossl_qrx_new(&qrx_args)) == NULL) goto err; @@ -347,13 +351,16 @@ QUIC_CHANNEL *ossl_quic_channel_new(const QUIC_CHANNEL_ARGS *args) if ((ch = OPENSSL_zalloc(sizeof(*ch))) == NULL) return NULL; - ch->libctx = args->libctx; - ch->propq = args->propq; - ch->is_server = args->is_server; - ch->tls = args->tls; - ch->mutex = args->mutex; - ch->now_cb = args->now_cb; - ch->now_cb_arg = args->now_cb_arg; + ch->libctx = args->libctx; + ch->propq = args->propq; + ch->is_server = args->is_server; + ch->tls = args->tls; + ch->mutex = args->mutex; + ch->now_cb = args->now_cb; + ch->now_cb_arg = args->now_cb_arg; + ch->msg_callback = args->msg_callback; + ch->msg_callback_arg = args->msg_callback_arg; + ch->msg_callback_s = args->msg_callback_s; if (!ch_init(ch)) { OPENSSL_free(ch); diff --git a/ssl/quic/quic_channel_local.h b/ssl/quic/quic_channel_local.h index 99fbb1db68..ad2c0b458a 100644 --- a/ssl/quic/quic_channel_local.h +++ b/ssl/quic/quic_channel_local.h @@ -93,6 +93,11 @@ struct quic_channel_st { OSSL_QTX *qtx; OSSL_QRX *qrx; + /* Message callback related arguments */ + ossl_msg_cb msg_callback; + void *msg_callback_arg; + SSL *msg_callback_s; + /* * Send and receive parts of the crypto streams. * crypto_send[QUIC_PN_SPACE_APP] is the 1-RTT crypto stream. There is no diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c index cd54eda1c2..c623a3c0b9 100644 --- a/ssl/quic/quic_impl.c +++ b/ssl/quic/quic_impl.c @@ -326,6 +326,9 @@ SSL *ossl_quic_new(SSL_CTX *ctx) qc->default_blocking = 1; qc->incoming_stream_policy = SSL_INCOMING_STREAM_POLICY_AUTO; qc->last_error = SSL_ERROR_NONE; + qc->msg_callback = ctx->msg_callback; + qc->msg_callback_arg = ctx->msg_callback_arg; + qc->msg_callback_s = ssl_base; if (!create_channel(qc)) goto err; @@ -1040,6 +1043,12 @@ long ossl_quic_ctrl(SSL *s, int cmd, long larg, void *parg) } return ctx.qc->default_ssl_mode; + + case SSL_CTRL_SET_MSG_CALLBACK_ARG: + ctx.qc->msg_callback_arg = parg; + /* This ctrl also needs to be passed to the internal SSL object */ + return SSL_ctrl(ctx.qc->tls, cmd, larg, parg); + default: /* Probably a TLS related ctrl. Defer to our internal SSL object */ return SSL_ctrl(ctx.qc->tls, cmd, larg, parg); @@ -1111,13 +1120,16 @@ static int create_channel(QUIC_CONNECTION *qc) { QUIC_CHANNEL_ARGS args = {0}; - args.libctx = qc->ssl.ctx->libctx; - args.propq = qc->ssl.ctx->propq; - args.is_server = qc->as_server; - args.tls = qc->tls; - args.mutex = qc->mutex; - args.now_cb = qc->override_now_cb; - args.now_cb_arg = qc->override_now_cb_arg; + args.libctx = qc->ssl.ctx->libctx; + args.propq = qc->ssl.ctx->propq; + args.is_server = qc->as_server; + args.tls = qc->tls; + args.mutex = qc->mutex; + args.now_cb = qc->override_now_cb; + args.now_cb_arg = qc->override_now_cb_arg; + args.msg_callback = qc->msg_callback; + args.msg_callback_arg = qc->msg_callback_arg; + args.msg_callback_s = qc->msg_callback_s; qc->ch = ossl_quic_channel_new(&args); if (qc->ch == NULL) @@ -2653,7 +2665,21 @@ long ossl_quic_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) long ossl_quic_callback_ctrl(SSL *s, int cmd, void (*fp) (void)) { - return ssl3_callback_ctrl(s, cmd, fp); + QCTX ctx; + + if (!expect_quic_conn_only(s, &ctx)) + return 0; + + switch (cmd) { + case SSL_CTRL_SET_MSG_CALLBACK: + ctx.qc->msg_callback = (ossl_msg_cb)fp; + /* This callback also needs to be set on the internal SSL object */ + return ssl3_callback_ctrl(ctx.qc->tls, cmd, fp);; + + default: + /* Probably a TLS related ctrl. Defer to our internal SSL object */ + return ssl3_callback_ctrl(ctx.qc->tls, cmd, fp); + } } long ossl_quic_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void)) diff --git a/ssl/quic/quic_local.h b/ssl/quic/quic_local.h index 6ba0f1ee78..9cedc947b2 100644 --- a/ssl/quic/quic_local.h +++ b/ssl/quic/quic_local.h @@ -195,6 +195,11 @@ struct quic_conn_st { * and SSL_ERROR_WANT_WRITE. */ int last_error; + + /* Message callback related arguments */ + ossl_msg_cb msg_callback; + void *msg_callback_arg; + SSL *msg_callback_s; }; /* Internal calls to the QUIC CSM which come from various places. */ diff --git a/ssl/quic/quic_record_rx.c b/ssl/quic/quic_record_rx.c index cde8f67d22..7171896b1d 100644 --- a/ssl/quic/quic_record_rx.c +++ b/ssl/quic/quic_record_rx.c @@ -145,6 +145,11 @@ struct ossl_qrx_st { /* Initial key phase. For debugging use only; always 0 in real use. */ unsigned char init_key_phase_bit; + + /* Message callback related arguments */ + ossl_msg_cb msg_callback; + void *msg_callback_arg; + SSL *msg_callback_s; }; static void qrx_on_rx(QUIC_URXE *urxe, void *arg); @@ -170,6 +175,9 @@ OSSL_QRX *ossl_qrx_new(const OSSL_QRX_ARGS *args) qrx->short_conn_id_len = args->short_conn_id_len; qrx->init_key_phase_bit = args->init_key_phase_bit; qrx->max_deferred = args->max_deferred; + qrx->msg_callback = args->msg_callback; + qrx->msg_callback_arg = args->msg_callback_arg; + qrx->msg_callback_s = args->msg_callback_s; return qrx; } @@ -980,6 +988,10 @@ static int qrx_process_datagram(OSSL_QRX *qrx, QUIC_URXE *e, if (!PACKET_buf_init(&pkt, data, data_len)) return 0; + if (qrx->msg_callback != NULL) + qrx->msg_callback(0, OSSL_QUIC1_VERSION, SSL3_RT_QUIC_DATAGRAM, data, + data_len, qrx->msg_callback_s, qrx->msg_callback_arg); + for (; PACKET_remaining(&pkt) > 0; ++pkt_idx) { /* * A packet smallest than the minimum possible QUIC packet size is not diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 17e318b857..835af33fea 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -3761,6 +3761,10 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) return (int)sc->ext.peer_supportedgroups_len; } + case SSL_CTRL_SET_MSG_CALLBACK_ARG: + sc->msg_callback_arg = parg; + return 1; + default: break; } @@ -3792,6 +3796,10 @@ long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp) (void)) sc->not_resumable_session_cb = (int (*)(SSL *, int))fp; ret = 1; break; + + case SSL_CTRL_SET_MSG_CALLBACK: + sc->msg_callback = (ossl_msg_cb)fp; + return 1; default: break; } diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 567396caa4..3bd9e8b48c 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -2864,10 +2864,6 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) RECORD_LAYER_set_read_ahead(&sc->rlayer, larg); return l; - case SSL_CTRL_SET_MSG_CALLBACK_ARG: - sc->msg_callback_arg = parg; - return 1; - case SSL_CTRL_MODE: { OSSL_PARAM options[2], *opts = options; @@ -2962,22 +2958,7 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) long SSL_callback_ctrl(SSL *s, int cmd, void (*fp) (void)) { - SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); - - if (sc == NULL) - return 0; - - switch (cmd) { - case SSL_CTRL_SET_MSG_CALLBACK: - sc->msg_callback = (void (*) - (int write_p, int version, int content_type, - const void *buf, size_t len, SSL *ssl, - void *arg))(fp); - return 1; - - default: - return s->method->ssl_callback_ctrl(s, cmd, fp); - } + return s->method->ssl_callback_ctrl(s, cmd, fp); } LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx) diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h index 485b18fb21..be834d8f68 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -799,6 +799,9 @@ typedef struct { # define TLS_GROUP_FFDHE_FOR_TLS1_3 (TLS_GROUP_FFDHE|TLS_GROUP_ONLY_FOR_TLS1_3) +typedef void (*ossl_msg_cb)(int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg); + struct ssl_ctx_st { OSSL_LIB_CTX *libctx; @@ -939,8 +942,7 @@ struct ssl_ctx_st { int read_ahead; /* callback that allows applications to peek at protocol messages */ - void (*msg_callback) (int write_p, int version, int content_type, - const void *buf, size_t len, SSL *ssl, void *arg); + ossl_msg_cb msg_callback; void *msg_callback_arg; uint32_t verify_mode; |