]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Add initial QUIC support for the msg_callback
authorMatt Caswell <matt@openssl.org>
Mon, 1 May 2023 14:40:28 +0000 (15:40 +0100)
committerMatt Caswell <matt@openssl.org>
Wed, 24 May 2023 11:18:27 +0000 (12:18 +0100)
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)

include/internal/quic_channel.h
include/internal/quic_record_rx.h
include/openssl/ssl3.h
ssl/quic/quic_channel.c
ssl/quic/quic_channel_local.h
ssl/quic/quic_impl.c
ssl/quic/quic_local.h
ssl/quic/quic_record_rx.c
ssl/s3_lib.c
ssl/ssl_lib.c
ssl/ssl_local.h

index 6dbf08665de8b21e81d5df19feab85ad5ea0d103..ac73097985884ede8f71c01c848e073bb1f723a3 100644 (file)
@@ -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;
index 95c0fa56351d7283c20083fb99782925f30db0b5..48173479936e667e32f4bc6d1e79d51a8a275687 100644 (file)
@@ -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. */
index 6c172f45f964c40160fdba24adbe504fcef4cf9e..f993d0baa068a3fc58cc166688dbf2e68a7ca182 100644 (file)
@@ -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
 
index 4325434c4fe6359322060f8f7988dce9112e0317..2f655f61cddd87bc50cb6e7feb68962661452e99 100644 (file)
@@ -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);
index 99fbb1db68e640f4cef0282dffd8ae8883878893..ad2c0b458a876def08f025f8932a930e50295eda 100644 (file)
@@ -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
index cd54eda1c2111ed5e7ff818be01f728834f15239..c623a3c0b97aab5d6b90bc493ec7154dee339744 100644 (file)
@@ -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))
index 6ba0f1ee780e270d47cdffa16403a1f7d70fc191..9cedc947b2898cb5c0308df82bb0b93c8d251349 100644 (file)
@@ -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. */
index cde8f67d224d3996688e34481d757ff43d5d672d..7171896b1dfbbbb48305f398632691ccaf932158 100644 (file)
@@ -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
index 17e318b85746c48f9734530d5b66ba65f3433ee9..835af33fea396c18543cfe6857cab1e223d08163 100644 (file)
@@ -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;
     }
index 567396caa45966eb0307c1d1bfece244e7f554f0..3bd9e8b48c417ee1d763adba0f29ed867d30a889 100644 (file)
@@ -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)
index 485b18fb21db4007090e1b86105de4b3859719a0..be834d8f688c7b781f3b0f62c1b3276b82453a25 100644 (file)
@@ -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;