Skip to content

Commit

Permalink
Add initial QUIC support for the msg_callback
Browse files Browse the repository at this point in the history
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 #20914)
  • Loading branch information
mattcaswell committed May 24, 2023
1 parent 6dea91f commit 63dfde8
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 37 deletions.
5 changes: 5 additions & 0 deletions include/internal/quic_channel.h
Expand Up @@ -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;
Expand Down
8 changes: 8 additions & 0 deletions include/internal/quic_record_rx.h
Expand Up @@ -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
* ======================
Expand Down Expand Up @@ -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. */
Expand Down
3 changes: 3 additions & 0 deletions include/openssl/ssl3.h
Expand Up @@ -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

Expand Down
21 changes: 14 additions & 7 deletions ssl/quic/quic_channel.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
5 changes: 5 additions & 0 deletions ssl/quic/quic_channel_local.h
Expand Up @@ -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
Expand Down
42 changes: 34 additions & 8 deletions ssl/quic/quic_impl.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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))
Expand Down
5 changes: 5 additions & 0 deletions ssl/quic/quic_local.h
Expand Up @@ -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. */
Expand Down
12 changes: 12 additions & 0 deletions ssl/quic/quic_record_rx.c
Expand Up @@ -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);
Expand All @@ -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;
}

Expand Down Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions ssl/s3_lib.c
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down
21 changes: 1 addition & 20 deletions ssl/ssl_lib.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
6 changes: 4 additions & 2 deletions ssl/ssl_local.h
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 63dfde8

Please sign in to comment.