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;