aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHugo Landau <hlandau@openssl.org>2023-07-25 11:32:25 +0100
committerMatt Caswell <matt@openssl.org>2023-08-08 14:33:42 +0100
commit2a6f1f2f6e321abe6deb2ce89084ece4aa50b3de (patch)
treead11f25a84b0237d8e148f6ed943130ae04d9bc7
parent0c1cc36bbb3b29a43cf08572b1176e5ee8e37ce2 (diff)
downloadopenssl-2a6f1f2f6e321abe6deb2ce89084ece4aa50b3de.tar.gz
QUIC QRX: Don't process 1-RTT packets 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/21547)
-rw-r--r--include/internal/quic_record_rx.h11
-rw-r--r--ssl/quic/quic_channel.c3
-rw-r--r--ssl/quic/quic_record_rx.c19
-rw-r--r--test/quic_record_test.c1
4 files changed, 34 insertions, 0 deletions
diff --git a/include/internal/quic_record_rx.h b/include/internal/quic_record_rx.h
index 19545c3e3a..ed5cdefb2f 100644
--- a/include/internal/quic_record_rx.h
+++ b/include/internal/quic_record_rx.h
@@ -339,6 +339,17 @@ int ossl_qrx_set_late_validation_cb(OSSL_QRX *qrx,
void ossl_qrx_inject_urxe(OSSL_QRX *qrx, QUIC_URXE *e);
/*
+ * Decryption of 1-RTT packets must be explicitly enabled by calling this
+ * function. This is to comply with the requirement that we not process 1-RTT
+ * packets until the handshake is complete, even if we already have 1-RTT
+ * secrets. Even if a 1-RTT secret is provisioned for the QRX, incoming 1-RTT
+ * packets will be handled as though no key is available until this function is
+ * called. Calling this function will then requeue any such deferred packets for
+ * processing.
+ */
+void ossl_qrx_allow_1rtt_processing(OSSL_QRX *qrx);
+
+/*
* Key Update (RX)
* ===============
*
diff --git a/ssl/quic/quic_channel.c b/ssl/quic/quic_channel.c
index fa9866bdde..615fef48a4 100644
--- a/ssl/quic/quic_channel.c
+++ b/ssl/quic/quic_channel.c
@@ -951,6 +951,9 @@ static int ch_on_handshake_complete(void *arg)
OPENSSL_free(ch->local_transport_params);
ch->local_transport_params = NULL;
+ /* Tell the QRX it can now process 1-RTT packets. */
+ ossl_qrx_allow_1rtt_processing(ch->qrx);
+
/* Tell TXP the handshake is complete. */
ossl_quic_tx_packetiser_notify_handshake_complete(ch->txp);
diff --git a/ssl/quic/quic_record_rx.c b/ssl/quic/quic_record_rx.c
index 74693900cf..feb32d9272 100644
--- a/ssl/quic/quic_record_rx.c
+++ b/ssl/quic/quic_record_rx.c
@@ -158,6 +158,9 @@ struct ossl_qrx_st {
/* Initial key phase. For debugging use only; always 0 in real use. */
unsigned char init_key_phase_bit;
+ /* Are we allowed to process 1-RTT packets yet? */
+ unsigned char allow_1rtt;
+
/* Message callback related arguments */
ossl_msg_cb msg_callback;
void *msg_callback_arg;
@@ -883,6 +886,13 @@ static int qrx_process_pkt(OSSL_QRX *qrx, QUIC_URXE *urxe,
switch (ossl_qrl_enc_level_set_have_el(&qrx->el_set, enc_level)) {
case 1:
/* We have keys. */
+ if (enc_level == QUIC_ENC_LEVEL_1RTT && !qrx->allow_1rtt)
+ /*
+ * But we cannot process 1-RTT packets until the handshake is
+ * completed (RFC 9000 s. 5.7).
+ */
+ goto cannot_decrypt;
+
break;
case 0:
/* No keys yet. */
@@ -1314,6 +1324,15 @@ uint64_t ossl_qrx_get_max_forged_pkt_count(OSSL_QRX *qrx,
: ossl_qrl_get_suite_max_forged_pkt(el->suite_id);
}
+void ossl_qrx_allow_1rtt_processing(OSSL_QRX *qrx)
+{
+ if (qrx->allow_1rtt)
+ return;
+
+ qrx->allow_1rtt = 1;
+ qrx_requeue_deferred(qrx);
+}
+
void ossl_qrx_set_msg_callback(OSSL_QRX *qrx, ossl_msg_cb msg_callback,
SSL *msg_callback_ssl)
{
diff --git a/test/quic_record_test.c b/test/quic_record_test.c
index d2b18882c5..ef0aa9bd62 100644
--- a/test/quic_record_test.c
+++ b/test/quic_record_test.c
@@ -1744,6 +1744,7 @@ static int rx_state_ensure(struct rx_state *s)
&& !TEST_ptr(s->qrx = ossl_qrx_new(&s->args)))
return 0;
+ ossl_qrx_allow_1rtt_processing(s->qrx);
return 1;
}