summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHugo Landau <hlandau@openssl.org>2022-10-31 17:39:45 +0000
committerHugo Landau <hlandau@openssl.org>2023-01-13 13:20:12 +0000
commitcda88bafe7532083a1e7c5bc08a9971735724c10 (patch)
treef3578853a90af2d2f8ae8e8d8b1f11ac216f9586
parentdf038685644eb1bc4618f678b52fc22f0101235f (diff)
QUIC TXP: Don't send STREAM frames until handshake is complete
Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/19703)
-rw-r--r--include/internal/quic_txp.h8
-rw-r--r--ssl/quic/quic_txp.c12
-rw-r--r--test/quic_txp_test.c11
3 files changed, 29 insertions, 2 deletions
diff --git a/include/internal/quic_txp.h b/include/internal/quic_txp.h
index 0ba14d356f..6a55b95717 100644
--- a/include/internal/quic_txp.h
+++ b/include/internal/quic_txp.h
@@ -134,6 +134,14 @@ int ossl_quic_tx_packetiser_set_peer(OSSL_QUIC_TX_PACKETISER *txp,
int ossl_quic_tx_packetiser_discard_enc_level(OSSL_QUIC_TX_PACKETISER *txp,
uint32_t enc_level);
+/*
+ * Informs the TX packetiser that the handshake is complete. The TX packetiser
+ * will not send 1-RTT application data until the handshake is complete,
+ * as the authenticity of the peer is not confirmed until the handshake
+ * complete event occurs.
+ */
+void ossl_quic_tx_packetiser_notify_handshake_complete(OSSL_QUIC_TX_PACKETISER *txp);
+
/* Asks the TXP to generate a HANDSHAKE_DONE frame in the next 1-RTT packet. */
void ossl_quic_tx_packetiser_schedule_handshake_done(OSSL_QUIC_TX_PACKETISER *txp);
diff --git a/ssl/quic/quic_txp.c b/ssl/quic/quic_txp.c
index 5fa9070acd..1042c69f44 100644
--- a/ssl/quic/quic_txp.c
+++ b/ssl/quic/quic_txp.c
@@ -59,6 +59,9 @@ struct ossl_quic_tx_packetiser_st {
*/
unsigned int want_conn_close : 1;
+ /* Has the handshake been completed? */
+ unsigned int handshake_complete : 1;
+
OSSL_QUIC_FRAME_CONN_CLOSE conn_close_frame;
/* Internal state - packet assembly. */
@@ -443,6 +446,11 @@ int ossl_quic_tx_packetiser_discard_enc_level(OSSL_QUIC_TX_PACKETISER *txp,
return 1;
}
+void ossl_quic_tx_packetiser_notify_handshake_complete(OSSL_QUIC_TX_PACKETISER *txp)
+{
+ txp->handshake_complete = 1;
+}
+
void ossl_quic_tx_packetiser_schedule_handshake_done(OSSL_QUIC_TX_PACKETISER *txp)
{
txp->want_handshake_done = 1;
@@ -796,7 +804,7 @@ static int txp_el_pending(OSSL_QUIC_TX_PACKETISER *txp, uint32_t enc_level,
}
}
- if (a.allow_stream_rel) {
+ if (a.allow_stream_rel && txp->handshake_complete) {
QUIC_STREAM_ITER it;
/* If there are any active streams, 0/1-RTT wants to produce a packet.
@@ -1944,7 +1952,7 @@ static int txp_generate_for_el_actual(OSSL_QUIC_TX_PACKETISER *txp,
goto fatal_err;
/* Stream-specific frames */
- if (a.allow_stream_rel)
+ if (a.allow_stream_rel && txp->handshake_complete)
if (!txp_generate_stream_related(txp, &h, pn_space, tpkt, min_ppl,
&have_ack_eliciting,
&tmp_head))
diff --git a/test/quic_txp_test.c b/test/quic_txp_test.c
index 54d4a8679f..ab9b943c7e 100644
--- a/test/quic_txp_test.c
+++ b/test/quic_txp_test.c
@@ -227,6 +227,7 @@ err:
#define OPK_RESET_STREAM 19 /* Mark stream for RESET_STREAM */
#define OPK_CONN_TXFC_BUMP 20 /* Bump connection TXFC CWM */
#define OPK_STREAM_TXFC_BUMP 21 /* Bump stream TXFC CWM */
+#define OPK_HANDSHAKE_COMPLETE 22 /* Mark handshake as complete */
struct script_op {
uint32_t opcode;
@@ -280,6 +281,8 @@ struct script_op {
{ OPK_CONN_TXFC_BUMP, (cwm) },
#define OP_STREAM_TXFC_BUMP(id, cwm) \
{ OPK_STREAM_TXFC_BUMP, (cwm), (id) },
+#define OP_HANDSHAKE_COMPLETE() \
+ { OPK_HANDSHAKE_COMPLETE },
static int schedule_handshake_done(struct helper *h)
{
@@ -601,6 +604,7 @@ static int check_stream_9(struct helper *h)
static const struct script_op script_9[] = {
OP_PROVIDE_SECRET(QUIC_ENC_LEVEL_1RTT, QRL_SUITE_AES128GCM, secret_1)
+ OP_HANDSHAKE_COMPLETE()
OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
OP_STREAM_NEW(42)
OP_STREAM_SEND(42, stream_9)
@@ -909,6 +913,7 @@ static int check_stream_10d(struct helper *h)
static const struct script_op script_10[] = {
OP_PROVIDE_SECRET(QUIC_ENC_LEVEL_1RTT, QRL_SUITE_AES128GCM, secret_1)
+ OP_HANDSHAKE_COMPLETE()
OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
OP_STREAM_NEW(42)
OP_STREAM_NEW(43)
@@ -982,6 +987,7 @@ static int check_stream_12(struct helper *h)
static const struct script_op script_12[] = {
OP_PROVIDE_SECRET(QUIC_ENC_LEVEL_1RTT, QRL_SUITE_AES128GCM, secret_1)
+ OP_HANDSHAKE_COMPLETE()
OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
OP_STREAM_NEW(42)
OP_STOP_SENDING(42, 4568)
@@ -1014,6 +1020,7 @@ static ossl_unused int check_stream_13(struct helper *h)
static const struct script_op script_13[] = {
OP_PROVIDE_SECRET(QUIC_ENC_LEVEL_1RTT, QRL_SUITE_AES128GCM, secret_1)
+ OP_HANDSHAKE_COMPLETE()
OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
OP_STREAM_NEW(42)
OP_CONN_TXFC_BUMP(8)
@@ -1065,6 +1072,7 @@ static int check_14(struct helper *h)
static const struct script_op script_14[] = {
OP_PROVIDE_SECRET(QUIC_ENC_LEVEL_1RTT, QRL_SUITE_AES128GCM, secret_1)
+ OP_HANDSHAKE_COMPLETE()
OP_TXP_GENERATE_NONE(TX_PACKETISER_ARCHETYPE_NORMAL)
OP_CHECK(gen_conn_close)
OP_TXP_GENERATE(TX_PACKETISER_ARCHETYPE_NORMAL)
@@ -1399,6 +1407,9 @@ static int run_script(const struct script_op *script)
ossl_quic_stream_map_update_state(h.args.qsm, s);
}
break;
+ case OPK_HANDSHAKE_COMPLETE:
+ ossl_quic_tx_packetiser_notify_handshake_complete(h.txp);
+ break;
default:
TEST_error("bad opcode");
goto err;