summaryrefslogtreecommitdiffstats
path: root/ssl
diff options
context:
space:
mode:
authorPauli <pauli@openssl.org>2023-05-26 11:23:48 +1000
committerPauli <pauli@openssl.org>2023-06-01 17:24:43 +1000
commit985429f4f4423de71cae270330586da990e6797f (patch)
tree035f5d627f85efdd7c1375e7e97f256aebc5f014 /ssl
parent73f59aa8ebee4231ef8d4072b474974c571efb96 (diff)
QUIC: CID conformance
Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/21078)
Diffstat (limited to 'ssl')
-rw-r--r--ssl/quic/quic_channel.c47
1 files changed, 40 insertions, 7 deletions
diff --git a/ssl/quic/quic_channel.c b/ssl/quic/quic_channel.c
index d75ac4c334..d4437c4d90 100644
--- a/ssl/quic/quic_channel.c
+++ b/ssl/quic/quic_channel.c
@@ -2169,17 +2169,44 @@ void ossl_quic_channel_on_new_conn_id(QUIC_CHANNEL *ch,
if (f->retire_prior_to > new_retire_prior_to)
new_retire_prior_to = f->retire_prior_to;
- if (new_remote_seq_num - new_retire_prior_to > 1
- /*
- * RFC allows connection termination if we see 2 times the limit
- * of conn ids to retire. We are a little bit more liberal.
- */
- || new_retire_prior_to - ch->cur_retire_prior_to > 10) {
- /* Violation of our active conn id limit */
+ /*
+ * RFC 9000-5.1.1: An endpoint MUST NOT provide more connection IDs
+ * than the peer's limit.
+ *
+ * After processing a NEW_CONNECTION_ID frame and adding and retiring
+ * active connection IDs, if the number of active connection IDs exceeds
+ * the value advertised in its active_connection_id_limit transport
+ * parameter, an endpoint MUST close the connection with an error of
+ * type CONNECTION_ID_LIMIT_ERROR.
+ */
+ if (new_remote_seq_num - new_retire_prior_to > 1) {
ossl_quic_channel_raise_protocol_error(ch,
QUIC_ERR_CONNECTION_ID_LIMIT_ERROR,
OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID,
"active_connection_id limit violated");
+ return;
+ }
+
+ /*
+ * RFC 9000-5.1.1: An endpoint MAY send connection IDs that temporarily
+ * exceed a peer's limit if the NEW_CONNECTION_ID frame also requires
+ * the retirement of any excess, by including a sufficiently large
+ * value in the Retire Prior To field.
+ *
+ * RFC 9000-5.1.2: An endpoint SHOULD allow for sending and tracking
+ * a number of RETIRE_CONNECTION_ID frames of at least twice the value
+ * of the active_connection_id_limit transport parameter. An endpoint
+ * MUST NOT forget a connection ID without retiring it, though it MAY
+ * choose to treat having connection IDs in need of retirement that
+ * exceed this limit as a connection error of type CONNECTION_ID_LIMIT_ERROR.
+ *
+ * We are a little bit more liberal than the minimum mandated.
+ */
+ if (new_retire_prior_to - ch->cur_retire_prior_to > 10) {
+ ossl_quic_channel_raise_protocol_error(ch,
+ QUIC_ERR_CONNECTION_ID_LIMIT_ERROR,
+ OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID,
+ "retiring connection id limit violated");
return;
}
@@ -2189,6 +2216,12 @@ void ossl_quic_channel_on_new_conn_id(QUIC_CHANNEL *ch,
ch->cur_remote_dcid = f->conn_id;
ossl_quic_tx_packetiser_set_cur_dcid(ch->txp, &ch->cur_remote_dcid);
}
+ /*
+ * RFC 9000-5.1.2: Upon receipt of an increased Retire Prior To
+ * field, the peer MUST stop using the corresponding connection IDs
+ * and retire them with RETIRE_CONNECTION_ID frames before adding the
+ * newly provided connection ID to the set of active connection IDs.
+ */
while (new_retire_prior_to > ch->cur_retire_prior_to) {
if (!ch_enqueue_retire_conn_id(ch, ch->cur_retire_prior_to))
break;