diff options
author | Hugo Landau <hlandau@openssl.org> | 2023-07-25 11:32:25 +0100 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2023-08-08 14:33:42 +0100 |
commit | 2a6f1f2f6e321abe6deb2ce89084ece4aa50b3de (patch) | |
tree | ad11f25a84b0237d8e148f6ed943130ae04d9bc7 | |
parent | 0c1cc36bbb3b29a43cf08572b1176e5ee8e37ce2 (diff) | |
download | openssl-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.h | 11 | ||||
-rw-r--r-- | ssl/quic/quic_channel.c | 3 | ||||
-rw-r--r-- | ssl/quic/quic_record_rx.c | 19 | ||||
-rw-r--r-- | test/quic_record_test.c | 1 |
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; } |