1*e7be843bSPierre Pronchery /*
2*e7be843bSPierre Pronchery * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved.
3*e7be843bSPierre Pronchery *
4*e7be843bSPierre Pronchery * Licensed under the Apache License 2.0 (the "License"). You may not use
5*e7be843bSPierre Pronchery * this file except in compliance with the License. You can obtain a copy
6*e7be843bSPierre Pronchery * in the file LICENSE in the source distribution or at
7*e7be843bSPierre Pronchery * https://www.openssl.org/source/license.html
8*e7be843bSPierre Pronchery */
9*e7be843bSPierre Pronchery
10*e7be843bSPierre Pronchery #include "internal/packet_quic.h"
11*e7be843bSPierre Pronchery #include "internal/nelem.h"
12*e7be843bSPierre Pronchery #include "internal/quic_wire.h"
13*e7be843bSPierre Pronchery #include "internal/quic_record_rx.h"
14*e7be843bSPierre Pronchery #include "internal/quic_ackm.h"
15*e7be843bSPierre Pronchery #include "internal/quic_rx_depack.h"
16*e7be843bSPierre Pronchery #include "internal/quic_error.h"
17*e7be843bSPierre Pronchery #include "internal/quic_fc.h"
18*e7be843bSPierre Pronchery #include "internal/quic_channel.h"
19*e7be843bSPierre Pronchery #include "internal/sockets.h"
20*e7be843bSPierre Pronchery
21*e7be843bSPierre Pronchery #include "quic_local.h"
22*e7be843bSPierre Pronchery #include "quic_channel_local.h"
23*e7be843bSPierre Pronchery #include "../ssl_local.h"
24*e7be843bSPierre Pronchery
25*e7be843bSPierre Pronchery /*
26*e7be843bSPierre Pronchery * Helper functions to process different frame types.
27*e7be843bSPierre Pronchery *
28*e7be843bSPierre Pronchery * Typically, those that are ACK eliciting will take an OSSL_ACKM_RX_PKT
29*e7be843bSPierre Pronchery * pointer argument, the few that aren't ACK eliciting will not. This makes
30*e7be843bSPierre Pronchery * them a verifiable pattern against tables where this is specified.
31*e7be843bSPierre Pronchery */
32*e7be843bSPierre Pronchery static int depack_do_implicit_stream_create(QUIC_CHANNEL *ch,
33*e7be843bSPierre Pronchery uint64_t stream_id,
34*e7be843bSPierre Pronchery uint64_t frame_type,
35*e7be843bSPierre Pronchery QUIC_STREAM **result);
36*e7be843bSPierre Pronchery
depack_do_frame_padding(PACKET * pkt)37*e7be843bSPierre Pronchery static int depack_do_frame_padding(PACKET *pkt)
38*e7be843bSPierre Pronchery {
39*e7be843bSPierre Pronchery /* We ignore this frame */
40*e7be843bSPierre Pronchery ossl_quic_wire_decode_padding(pkt);
41*e7be843bSPierre Pronchery return 1;
42*e7be843bSPierre Pronchery }
43*e7be843bSPierre Pronchery
depack_do_frame_ping(PACKET * pkt,QUIC_CHANNEL * ch,uint32_t enc_level,OSSL_ACKM_RX_PKT * ackm_data)44*e7be843bSPierre Pronchery static int depack_do_frame_ping(PACKET *pkt, QUIC_CHANNEL *ch,
45*e7be843bSPierre Pronchery uint32_t enc_level,
46*e7be843bSPierre Pronchery OSSL_ACKM_RX_PKT *ackm_data)
47*e7be843bSPierre Pronchery {
48*e7be843bSPierre Pronchery /* We ignore this frame, apart from eliciting an ACK */
49*e7be843bSPierre Pronchery if (!ossl_quic_wire_decode_frame_ping(pkt)) {
50*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
51*e7be843bSPierre Pronchery OSSL_QUIC_ERR_FRAME_ENCODING_ERROR,
52*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_PING,
53*e7be843bSPierre Pronchery "decode error");
54*e7be843bSPierre Pronchery return 0;
55*e7be843bSPierre Pronchery }
56*e7be843bSPierre Pronchery
57*e7be843bSPierre Pronchery ossl_quic_tx_packetiser_schedule_ack_eliciting(ch->txp, enc_level);
58*e7be843bSPierre Pronchery return 1;
59*e7be843bSPierre Pronchery }
60*e7be843bSPierre Pronchery
depack_do_frame_ack(PACKET * pkt,QUIC_CHANNEL * ch,int packet_space,OSSL_TIME received,uint64_t frame_type,OSSL_QRX_PKT * qpacket)61*e7be843bSPierre Pronchery static int depack_do_frame_ack(PACKET *pkt, QUIC_CHANNEL *ch,
62*e7be843bSPierre Pronchery int packet_space, OSSL_TIME received,
63*e7be843bSPierre Pronchery uint64_t frame_type,
64*e7be843bSPierre Pronchery OSSL_QRX_PKT *qpacket)
65*e7be843bSPierre Pronchery {
66*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_ACK ack;
67*e7be843bSPierre Pronchery OSSL_QUIC_ACK_RANGE *p;
68*e7be843bSPierre Pronchery uint64_t total_ranges = 0;
69*e7be843bSPierre Pronchery uint32_t ack_delay_exp = ch->rx_ack_delay_exp;
70*e7be843bSPierre Pronchery
71*e7be843bSPierre Pronchery if (!ossl_quic_wire_peek_frame_ack_num_ranges(pkt, &total_ranges)
72*e7be843bSPierre Pronchery /* In case sizeof(uint64_t) > sizeof(size_t) */
73*e7be843bSPierre Pronchery || total_ranges > SIZE_MAX / sizeof(OSSL_QUIC_ACK_RANGE))
74*e7be843bSPierre Pronchery goto malformed;
75*e7be843bSPierre Pronchery
76*e7be843bSPierre Pronchery if (ch->num_ack_range_scratch < (size_t)total_ranges) {
77*e7be843bSPierre Pronchery if ((p = OPENSSL_realloc(ch->ack_range_scratch,
78*e7be843bSPierre Pronchery sizeof(OSSL_QUIC_ACK_RANGE)
79*e7be843bSPierre Pronchery * (size_t)total_ranges)) == NULL)
80*e7be843bSPierre Pronchery goto malformed;
81*e7be843bSPierre Pronchery
82*e7be843bSPierre Pronchery ch->ack_range_scratch = p;
83*e7be843bSPierre Pronchery ch->num_ack_range_scratch = (size_t)total_ranges;
84*e7be843bSPierre Pronchery }
85*e7be843bSPierre Pronchery
86*e7be843bSPierre Pronchery ack.ack_ranges = ch->ack_range_scratch;
87*e7be843bSPierre Pronchery ack.num_ack_ranges = (size_t)total_ranges;
88*e7be843bSPierre Pronchery
89*e7be843bSPierre Pronchery if (!ossl_quic_wire_decode_frame_ack(pkt, ack_delay_exp, &ack, NULL))
90*e7be843bSPierre Pronchery goto malformed;
91*e7be843bSPierre Pronchery
92*e7be843bSPierre Pronchery if (qpacket->hdr->type == QUIC_PKT_TYPE_1RTT
93*e7be843bSPierre Pronchery && (qpacket->key_epoch < ossl_qrx_get_key_epoch(ch->qrx)
94*e7be843bSPierre Pronchery || ch->rxku_expected)
95*e7be843bSPierre Pronchery && ack.ack_ranges[0].end >= ch->txku_pn) {
96*e7be843bSPierre Pronchery /*
97*e7be843bSPierre Pronchery * RFC 9001 s. 6.2: An endpoint that receives an acknowledgment that is
98*e7be843bSPierre Pronchery * carried in a packet protected with old keys where any acknowledged
99*e7be843bSPierre Pronchery * packet was protected with newer keys MAY treat that as a connection
100*e7be843bSPierre Pronchery * error of type KEY_UPDATE_ERROR.
101*e7be843bSPierre Pronchery *
102*e7be843bSPierre Pronchery * Two cases to handle here:
103*e7be843bSPierre Pronchery *
104*e7be843bSPierre Pronchery * - We did spontaneous TXKU, the peer has responded in kind and we
105*e7be843bSPierre Pronchery * have detected RXKU; !ch->rxku_expected, but then it sent a packet
106*e7be843bSPierre Pronchery * with old keys acknowledging a packet in the new key epoch.
107*e7be843bSPierre Pronchery *
108*e7be843bSPierre Pronchery * This also covers the case where we got RXKU and triggered
109*e7be843bSPierre Pronchery * solicited TXKU, and then for some reason the peer sent an ACK of
110*e7be843bSPierre Pronchery * a PN in our new TX key epoch with old keys.
111*e7be843bSPierre Pronchery *
112*e7be843bSPierre Pronchery * - We did spontaneous TXKU; ch->txku_pn is the starting PN of our
113*e7be843bSPierre Pronchery * new TX key epoch; the peer has not initiated a solicited TXKU in
114*e7be843bSPierre Pronchery * response (so we have not detected RXKU); in this case the RX key
115*e7be843bSPierre Pronchery * epoch has not incremented and ch->rxku_expected is still 1.
116*e7be843bSPierre Pronchery */
117*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
118*e7be843bSPierre Pronchery OSSL_QUIC_ERR_KEY_UPDATE_ERROR,
119*e7be843bSPierre Pronchery frame_type,
120*e7be843bSPierre Pronchery "acked packet which initiated a "
121*e7be843bSPierre Pronchery "key update without a "
122*e7be843bSPierre Pronchery "corresponding key update");
123*e7be843bSPierre Pronchery return 0;
124*e7be843bSPierre Pronchery }
125*e7be843bSPierre Pronchery
126*e7be843bSPierre Pronchery if (!ossl_ackm_on_rx_ack_frame(ch->ackm, &ack,
127*e7be843bSPierre Pronchery packet_space, received))
128*e7be843bSPierre Pronchery goto malformed;
129*e7be843bSPierre Pronchery
130*e7be843bSPierre Pronchery ++ch->diag_num_rx_ack;
131*e7be843bSPierre Pronchery return 1;
132*e7be843bSPierre Pronchery
133*e7be843bSPierre Pronchery malformed:
134*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
135*e7be843bSPierre Pronchery OSSL_QUIC_ERR_FRAME_ENCODING_ERROR,
136*e7be843bSPierre Pronchery frame_type,
137*e7be843bSPierre Pronchery "decode error");
138*e7be843bSPierre Pronchery return 0;
139*e7be843bSPierre Pronchery }
140*e7be843bSPierre Pronchery
depack_do_frame_reset_stream(PACKET * pkt,QUIC_CHANNEL * ch,OSSL_ACKM_RX_PKT * ackm_data)141*e7be843bSPierre Pronchery static int depack_do_frame_reset_stream(PACKET *pkt,
142*e7be843bSPierre Pronchery QUIC_CHANNEL *ch,
143*e7be843bSPierre Pronchery OSSL_ACKM_RX_PKT *ackm_data)
144*e7be843bSPierre Pronchery {
145*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_RESET_STREAM frame_data;
146*e7be843bSPierre Pronchery QUIC_STREAM *stream = NULL;
147*e7be843bSPierre Pronchery uint64_t fce;
148*e7be843bSPierre Pronchery
149*e7be843bSPierre Pronchery if (!ossl_quic_wire_decode_frame_reset_stream(pkt, &frame_data)) {
150*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
151*e7be843bSPierre Pronchery OSSL_QUIC_ERR_FRAME_ENCODING_ERROR,
152*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_RESET_STREAM,
153*e7be843bSPierre Pronchery "decode error");
154*e7be843bSPierre Pronchery return 0;
155*e7be843bSPierre Pronchery }
156*e7be843bSPierre Pronchery
157*e7be843bSPierre Pronchery if (!depack_do_implicit_stream_create(ch, frame_data.stream_id,
158*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_RESET_STREAM,
159*e7be843bSPierre Pronchery &stream))
160*e7be843bSPierre Pronchery return 0; /* error already raised for us */
161*e7be843bSPierre Pronchery
162*e7be843bSPierre Pronchery if (stream == NULL)
163*e7be843bSPierre Pronchery return 1; /* old deleted stream, not a protocol violation, ignore */
164*e7be843bSPierre Pronchery
165*e7be843bSPierre Pronchery if (!ossl_quic_stream_has_recv(stream)) {
166*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
167*e7be843bSPierre Pronchery OSSL_QUIC_ERR_STREAM_STATE_ERROR,
168*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_RESET_STREAM,
169*e7be843bSPierre Pronchery "RESET_STREAM frame for "
170*e7be843bSPierre Pronchery "TX only stream");
171*e7be843bSPierre Pronchery return 0;
172*e7be843bSPierre Pronchery }
173*e7be843bSPierre Pronchery
174*e7be843bSPierre Pronchery /*
175*e7be843bSPierre Pronchery * The final size field of the RESET_STREAM frame must be used to determine
176*e7be843bSPierre Pronchery * how much flow control credit the aborted stream was considered to have
177*e7be843bSPierre Pronchery * consumed.
178*e7be843bSPierre Pronchery *
179*e7be843bSPierre Pronchery * We also need to ensure that if we already have a final size for the
180*e7be843bSPierre Pronchery * stream, the RESET_STREAM frame's Final Size field matches this; we SHOULD
181*e7be843bSPierre Pronchery * terminate the connection otherwise (RFC 9000 s. 4.5). The RXFC takes care
182*e7be843bSPierre Pronchery * of this for us.
183*e7be843bSPierre Pronchery */
184*e7be843bSPierre Pronchery if (!ossl_quic_rxfc_on_rx_stream_frame(&stream->rxfc,
185*e7be843bSPierre Pronchery frame_data.final_size, /*is_fin=*/1)) {
186*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
187*e7be843bSPierre Pronchery OSSL_QUIC_ERR_INTERNAL_ERROR,
188*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_RESET_STREAM,
189*e7be843bSPierre Pronchery "internal error (flow control)");
190*e7be843bSPierre Pronchery return 0;
191*e7be843bSPierre Pronchery }
192*e7be843bSPierre Pronchery
193*e7be843bSPierre Pronchery /* Has a flow control error occurred? */
194*e7be843bSPierre Pronchery fce = ossl_quic_rxfc_get_error(&stream->rxfc, 0);
195*e7be843bSPierre Pronchery if (fce != OSSL_QUIC_ERR_NO_ERROR) {
196*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
197*e7be843bSPierre Pronchery fce,
198*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_RESET_STREAM,
199*e7be843bSPierre Pronchery "flow control violation");
200*e7be843bSPierre Pronchery return 0;
201*e7be843bSPierre Pronchery }
202*e7be843bSPierre Pronchery
203*e7be843bSPierre Pronchery /*
204*e7be843bSPierre Pronchery * Depending on the receive part state this is handled either as a reset
205*e7be843bSPierre Pronchery * transition or a no-op (e.g. if a reset has already been received before,
206*e7be843bSPierre Pronchery * or the application already retired a FIN). Best effort - there are no
207*e7be843bSPierre Pronchery * protocol error conditions we need to check for here.
208*e7be843bSPierre Pronchery */
209*e7be843bSPierre Pronchery ossl_quic_stream_map_notify_reset_recv_part(&ch->qsm, stream,
210*e7be843bSPierre Pronchery frame_data.app_error_code,
211*e7be843bSPierre Pronchery frame_data.final_size);
212*e7be843bSPierre Pronchery
213*e7be843bSPierre Pronchery ossl_quic_stream_map_update_state(&ch->qsm, stream);
214*e7be843bSPierre Pronchery return 1;
215*e7be843bSPierre Pronchery }
216*e7be843bSPierre Pronchery
depack_do_frame_stop_sending(PACKET * pkt,QUIC_CHANNEL * ch,OSSL_ACKM_RX_PKT * ackm_data)217*e7be843bSPierre Pronchery static int depack_do_frame_stop_sending(PACKET *pkt,
218*e7be843bSPierre Pronchery QUIC_CHANNEL *ch,
219*e7be843bSPierre Pronchery OSSL_ACKM_RX_PKT *ackm_data)
220*e7be843bSPierre Pronchery {
221*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_STOP_SENDING frame_data;
222*e7be843bSPierre Pronchery QUIC_STREAM *stream = NULL;
223*e7be843bSPierre Pronchery
224*e7be843bSPierre Pronchery if (!ossl_quic_wire_decode_frame_stop_sending(pkt, &frame_data)) {
225*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
226*e7be843bSPierre Pronchery OSSL_QUIC_ERR_FRAME_ENCODING_ERROR,
227*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_STOP_SENDING,
228*e7be843bSPierre Pronchery "decode error");
229*e7be843bSPierre Pronchery return 0;
230*e7be843bSPierre Pronchery }
231*e7be843bSPierre Pronchery
232*e7be843bSPierre Pronchery if (!depack_do_implicit_stream_create(ch, frame_data.stream_id,
233*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_STOP_SENDING,
234*e7be843bSPierre Pronchery &stream))
235*e7be843bSPierre Pronchery return 0; /* error already raised for us */
236*e7be843bSPierre Pronchery
237*e7be843bSPierre Pronchery if (stream == NULL)
238*e7be843bSPierre Pronchery return 1; /* old deleted stream, not a protocol violation, ignore */
239*e7be843bSPierre Pronchery
240*e7be843bSPierre Pronchery if (!ossl_quic_stream_has_send(stream)) {
241*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
242*e7be843bSPierre Pronchery OSSL_QUIC_ERR_STREAM_STATE_ERROR,
243*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_STOP_SENDING,
244*e7be843bSPierre Pronchery "STOP_SENDING frame for "
245*e7be843bSPierre Pronchery "RX only stream");
246*e7be843bSPierre Pronchery return 0;
247*e7be843bSPierre Pronchery }
248*e7be843bSPierre Pronchery
249*e7be843bSPierre Pronchery stream->peer_stop_sending = 1;
250*e7be843bSPierre Pronchery stream->peer_stop_sending_aec = frame_data.app_error_code;
251*e7be843bSPierre Pronchery
252*e7be843bSPierre Pronchery /*
253*e7be843bSPierre Pronchery * RFC 9000 s. 3.5: Receiving a STOP_SENDING frame means we must respond in
254*e7be843bSPierre Pronchery * turn with a RESET_STREAM frame for the same part of the stream. The other
255*e7be843bSPierre Pronchery * part is unaffected.
256*e7be843bSPierre Pronchery */
257*e7be843bSPierre Pronchery ossl_quic_stream_map_reset_stream_send_part(&ch->qsm, stream,
258*e7be843bSPierre Pronchery frame_data.app_error_code);
259*e7be843bSPierre Pronchery return 1;
260*e7be843bSPierre Pronchery }
261*e7be843bSPierre Pronchery
depack_do_frame_crypto(PACKET * pkt,QUIC_CHANNEL * ch,OSSL_QRX_PKT * parent_pkt,OSSL_ACKM_RX_PKT * ackm_data,uint64_t * datalen)262*e7be843bSPierre Pronchery static int depack_do_frame_crypto(PACKET *pkt, QUIC_CHANNEL *ch,
263*e7be843bSPierre Pronchery OSSL_QRX_PKT *parent_pkt,
264*e7be843bSPierre Pronchery OSSL_ACKM_RX_PKT *ackm_data,
265*e7be843bSPierre Pronchery uint64_t *datalen)
266*e7be843bSPierre Pronchery {
267*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_CRYPTO f;
268*e7be843bSPierre Pronchery QUIC_RSTREAM *rstream;
269*e7be843bSPierre Pronchery QUIC_RXFC *rxfc;
270*e7be843bSPierre Pronchery
271*e7be843bSPierre Pronchery *datalen = 0;
272*e7be843bSPierre Pronchery
273*e7be843bSPierre Pronchery if (!ossl_quic_wire_decode_frame_crypto(pkt, 0, &f)) {
274*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
275*e7be843bSPierre Pronchery OSSL_QUIC_ERR_FRAME_ENCODING_ERROR,
276*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_CRYPTO,
277*e7be843bSPierre Pronchery "decode error");
278*e7be843bSPierre Pronchery return 0;
279*e7be843bSPierre Pronchery }
280*e7be843bSPierre Pronchery
281*e7be843bSPierre Pronchery if (f.len == 0)
282*e7be843bSPierre Pronchery return 1; /* nothing to do */
283*e7be843bSPierre Pronchery
284*e7be843bSPierre Pronchery rstream = ch->crypto_recv[ackm_data->pkt_space];
285*e7be843bSPierre Pronchery if (!ossl_assert(rstream != NULL))
286*e7be843bSPierre Pronchery /*
287*e7be843bSPierre Pronchery * This should not happen; we should only have a NULL stream here if
288*e7be843bSPierre Pronchery * the EL has been discarded, and if the EL has been discarded we
289*e7be843bSPierre Pronchery * shouldn't be here.
290*e7be843bSPierre Pronchery */
291*e7be843bSPierre Pronchery return 0;
292*e7be843bSPierre Pronchery
293*e7be843bSPierre Pronchery rxfc = &ch->crypto_rxfc[ackm_data->pkt_space];
294*e7be843bSPierre Pronchery
295*e7be843bSPierre Pronchery if (!ossl_quic_rxfc_on_rx_stream_frame(rxfc, f.offset + f.len,
296*e7be843bSPierre Pronchery /*is_fin=*/0)) {
297*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
298*e7be843bSPierre Pronchery OSSL_QUIC_ERR_INTERNAL_ERROR,
299*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_CRYPTO,
300*e7be843bSPierre Pronchery "internal error (crypto RXFC)");
301*e7be843bSPierre Pronchery return 0;
302*e7be843bSPierre Pronchery }
303*e7be843bSPierre Pronchery
304*e7be843bSPierre Pronchery if (ossl_quic_rxfc_get_error(rxfc, 0) != OSSL_QUIC_ERR_NO_ERROR) {
305*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_CRYPTO_BUFFER_EXCEEDED,
306*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_CRYPTO,
307*e7be843bSPierre Pronchery "exceeded maximum crypto buffer");
308*e7be843bSPierre Pronchery return 0;
309*e7be843bSPierre Pronchery }
310*e7be843bSPierre Pronchery
311*e7be843bSPierre Pronchery if (!ossl_quic_rstream_queue_data(rstream, parent_pkt,
312*e7be843bSPierre Pronchery f.offset, f.data, f.len, 0)) {
313*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
314*e7be843bSPierre Pronchery OSSL_QUIC_ERR_INTERNAL_ERROR,
315*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_CRYPTO,
316*e7be843bSPierre Pronchery "internal error (rstream queue)");
317*e7be843bSPierre Pronchery return 0;
318*e7be843bSPierre Pronchery }
319*e7be843bSPierre Pronchery
320*e7be843bSPierre Pronchery ch->did_crypto_frame = 1;
321*e7be843bSPierre Pronchery *datalen = f.len;
322*e7be843bSPierre Pronchery
323*e7be843bSPierre Pronchery return 1;
324*e7be843bSPierre Pronchery }
325*e7be843bSPierre Pronchery
depack_do_frame_new_token(PACKET * pkt,QUIC_CHANNEL * ch,OSSL_ACKM_RX_PKT * ackm_data)326*e7be843bSPierre Pronchery static int depack_do_frame_new_token(PACKET *pkt, QUIC_CHANNEL *ch,
327*e7be843bSPierre Pronchery OSSL_ACKM_RX_PKT *ackm_data)
328*e7be843bSPierre Pronchery {
329*e7be843bSPierre Pronchery const uint8_t *token;
330*e7be843bSPierre Pronchery size_t token_len;
331*e7be843bSPierre Pronchery
332*e7be843bSPierre Pronchery if (!ossl_quic_wire_decode_frame_new_token(pkt, &token, &token_len)) {
333*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
334*e7be843bSPierre Pronchery OSSL_QUIC_ERR_FRAME_ENCODING_ERROR,
335*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_NEW_TOKEN,
336*e7be843bSPierre Pronchery "decode error");
337*e7be843bSPierre Pronchery return 0;
338*e7be843bSPierre Pronchery }
339*e7be843bSPierre Pronchery
340*e7be843bSPierre Pronchery if (token_len == 0) {
341*e7be843bSPierre Pronchery /*
342*e7be843bSPierre Pronchery * RFC 9000 s. 19.7: "A client MUST treat receipt of a NEW_TOKEN frame
343*e7be843bSPierre Pronchery * with an empty Token field as a connection error of type
344*e7be843bSPierre Pronchery * FRAME_ENCODING_ERROR."
345*e7be843bSPierre Pronchery */
346*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
347*e7be843bSPierre Pronchery OSSL_QUIC_ERR_FRAME_ENCODING_ERROR,
348*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_NEW_TOKEN,
349*e7be843bSPierre Pronchery "zero-length NEW_TOKEN");
350*e7be843bSPierre Pronchery return 0;
351*e7be843bSPierre Pronchery }
352*e7be843bSPierre Pronchery
353*e7be843bSPierre Pronchery /* store the new token in our token cache */
354*e7be843bSPierre Pronchery if (!ossl_quic_set_peer_token(ossl_quic_port_get_channel_ctx(ch->port),
355*e7be843bSPierre Pronchery &ch->cur_peer_addr, token, token_len))
356*e7be843bSPierre Pronchery return 0;
357*e7be843bSPierre Pronchery
358*e7be843bSPierre Pronchery return 1;
359*e7be843bSPierre Pronchery }
360*e7be843bSPierre Pronchery
361*e7be843bSPierre Pronchery /*
362*e7be843bSPierre Pronchery * Returns 1 if no protocol violation has occurred. In this case *result will be
363*e7be843bSPierre Pronchery * non-NULL unless this is an old deleted stream and we should ignore the frame
364*e7be843bSPierre Pronchery * causing this function to be called. Returns 0 on protocol violation.
365*e7be843bSPierre Pronchery */
depack_do_implicit_stream_create(QUIC_CHANNEL * ch,uint64_t stream_id,uint64_t frame_type,QUIC_STREAM ** result)366*e7be843bSPierre Pronchery static int depack_do_implicit_stream_create(QUIC_CHANNEL *ch,
367*e7be843bSPierre Pronchery uint64_t stream_id,
368*e7be843bSPierre Pronchery uint64_t frame_type,
369*e7be843bSPierre Pronchery QUIC_STREAM **result)
370*e7be843bSPierre Pronchery {
371*e7be843bSPierre Pronchery QUIC_STREAM *stream;
372*e7be843bSPierre Pronchery uint64_t peer_role, stream_ordinal;
373*e7be843bSPierre Pronchery uint64_t *p_next_ordinal_local, *p_next_ordinal_remote;
374*e7be843bSPierre Pronchery QUIC_RXFC *max_streams_fc;
375*e7be843bSPierre Pronchery int is_uni, is_remote_init;
376*e7be843bSPierre Pronchery
377*e7be843bSPierre Pronchery stream = ossl_quic_stream_map_get_by_id(&ch->qsm, stream_id);
378*e7be843bSPierre Pronchery if (stream != NULL) {
379*e7be843bSPierre Pronchery *result = stream;
380*e7be843bSPierre Pronchery return 1;
381*e7be843bSPierre Pronchery }
382*e7be843bSPierre Pronchery
383*e7be843bSPierre Pronchery /*
384*e7be843bSPierre Pronchery * If we do not yet have a stream with the given ID, there are three
385*e7be843bSPierre Pronchery * possibilities:
386*e7be843bSPierre Pronchery *
387*e7be843bSPierre Pronchery * (a) The stream ID is for a remotely-created stream and the peer
388*e7be843bSPierre Pronchery * is creating a stream.
389*e7be843bSPierre Pronchery *
390*e7be843bSPierre Pronchery * (b) The stream ID is for a locally-created stream which has
391*e7be843bSPierre Pronchery * previously been deleted.
392*e7be843bSPierre Pronchery *
393*e7be843bSPierre Pronchery * (c) The stream ID is for a locally-created stream which does
394*e7be843bSPierre Pronchery * not exist yet. This is a protocol violation and we must
395*e7be843bSPierre Pronchery * terminate the connection in this case.
396*e7be843bSPierre Pronchery *
397*e7be843bSPierre Pronchery * We distinguish between (b) and (c) using the stream ID allocator
398*e7be843bSPierre Pronchery * variable. Since stream ordinals are allocated monotonically, we
399*e7be843bSPierre Pronchery * simply determine if the stream ordinal is in the future.
400*e7be843bSPierre Pronchery */
401*e7be843bSPierre Pronchery peer_role = ch->is_server
402*e7be843bSPierre Pronchery ? QUIC_STREAM_INITIATOR_CLIENT
403*e7be843bSPierre Pronchery : QUIC_STREAM_INITIATOR_SERVER;
404*e7be843bSPierre Pronchery
405*e7be843bSPierre Pronchery is_remote_init = ((stream_id & QUIC_STREAM_INITIATOR_MASK) == peer_role);
406*e7be843bSPierre Pronchery is_uni = ((stream_id & QUIC_STREAM_DIR_MASK) == QUIC_STREAM_DIR_UNI);
407*e7be843bSPierre Pronchery
408*e7be843bSPierre Pronchery stream_ordinal = stream_id >> 2;
409*e7be843bSPierre Pronchery
410*e7be843bSPierre Pronchery if (is_remote_init) {
411*e7be843bSPierre Pronchery /*
412*e7be843bSPierre Pronchery * Peer-created stream which does not yet exist. Create it. QUIC stream
413*e7be843bSPierre Pronchery * ordinals within a given stream type MUST be used in sequence and
414*e7be843bSPierre Pronchery * receiving a STREAM frame for ordinal n must implicitly create streams
415*e7be843bSPierre Pronchery * with ordinals [0, n) within that stream type even if no explicit
416*e7be843bSPierre Pronchery * STREAM frames are received for those ordinals.
417*e7be843bSPierre Pronchery */
418*e7be843bSPierre Pronchery p_next_ordinal_remote = is_uni
419*e7be843bSPierre Pronchery ? &ch->next_remote_stream_ordinal_uni
420*e7be843bSPierre Pronchery : &ch->next_remote_stream_ordinal_bidi;
421*e7be843bSPierre Pronchery
422*e7be843bSPierre Pronchery /* Check this isn't violating stream count flow control. */
423*e7be843bSPierre Pronchery max_streams_fc = is_uni
424*e7be843bSPierre Pronchery ? &ch->max_streams_uni_rxfc
425*e7be843bSPierre Pronchery : &ch->max_streams_bidi_rxfc;
426*e7be843bSPierre Pronchery
427*e7be843bSPierre Pronchery if (!ossl_quic_rxfc_on_rx_stream_frame(max_streams_fc,
428*e7be843bSPierre Pronchery stream_ordinal + 1,
429*e7be843bSPierre Pronchery /*is_fin=*/0)) {
430*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
431*e7be843bSPierre Pronchery OSSL_QUIC_ERR_INTERNAL_ERROR,
432*e7be843bSPierre Pronchery frame_type,
433*e7be843bSPierre Pronchery "internal error (stream count RXFC)");
434*e7be843bSPierre Pronchery return 0;
435*e7be843bSPierre Pronchery }
436*e7be843bSPierre Pronchery
437*e7be843bSPierre Pronchery if (ossl_quic_rxfc_get_error(max_streams_fc, 0) != OSSL_QUIC_ERR_NO_ERROR) {
438*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_STREAM_LIMIT_ERROR,
439*e7be843bSPierre Pronchery frame_type,
440*e7be843bSPierre Pronchery "exceeded maximum allowed streams");
441*e7be843bSPierre Pronchery return 0;
442*e7be843bSPierre Pronchery }
443*e7be843bSPierre Pronchery
444*e7be843bSPierre Pronchery /*
445*e7be843bSPierre Pronchery * Create the named stream and any streams coming before it yet to be
446*e7be843bSPierre Pronchery * created.
447*e7be843bSPierre Pronchery */
448*e7be843bSPierre Pronchery while (*p_next_ordinal_remote <= stream_ordinal) {
449*e7be843bSPierre Pronchery uint64_t cur_stream_id = (*p_next_ordinal_remote << 2) |
450*e7be843bSPierre Pronchery (stream_id
451*e7be843bSPierre Pronchery & (QUIC_STREAM_DIR_MASK | QUIC_STREAM_INITIATOR_MASK));
452*e7be843bSPierre Pronchery
453*e7be843bSPierre Pronchery stream = ossl_quic_channel_new_stream_remote(ch, cur_stream_id);
454*e7be843bSPierre Pronchery if (stream == NULL) {
455*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
456*e7be843bSPierre Pronchery OSSL_QUIC_ERR_INTERNAL_ERROR,
457*e7be843bSPierre Pronchery frame_type,
458*e7be843bSPierre Pronchery "internal error (stream allocation)");
459*e7be843bSPierre Pronchery return 0;
460*e7be843bSPierre Pronchery }
461*e7be843bSPierre Pronchery
462*e7be843bSPierre Pronchery ++*p_next_ordinal_remote;
463*e7be843bSPierre Pronchery }
464*e7be843bSPierre Pronchery
465*e7be843bSPierre Pronchery *result = stream;
466*e7be843bSPierre Pronchery } else {
467*e7be843bSPierre Pronchery /* Locally-created stream which does not yet exist. */
468*e7be843bSPierre Pronchery p_next_ordinal_local = is_uni
469*e7be843bSPierre Pronchery ? &ch->next_local_stream_ordinal_uni
470*e7be843bSPierre Pronchery : &ch->next_local_stream_ordinal_bidi;
471*e7be843bSPierre Pronchery
472*e7be843bSPierre Pronchery if (stream_ordinal >= *p_next_ordinal_local) {
473*e7be843bSPierre Pronchery /*
474*e7be843bSPierre Pronchery * We never created this stream yet, this is a protocol
475*e7be843bSPierre Pronchery * violation.
476*e7be843bSPierre Pronchery */
477*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
478*e7be843bSPierre Pronchery OSSL_QUIC_ERR_STREAM_STATE_ERROR,
479*e7be843bSPierre Pronchery frame_type,
480*e7be843bSPierre Pronchery "STREAM frame for nonexistent "
481*e7be843bSPierre Pronchery "stream");
482*e7be843bSPierre Pronchery return 0;
483*e7be843bSPierre Pronchery }
484*e7be843bSPierre Pronchery
485*e7be843bSPierre Pronchery /*
486*e7be843bSPierre Pronchery * Otherwise this is for an old locally-initiated stream which we
487*e7be843bSPierre Pronchery * have subsequently deleted. Ignore the data; it may simply be a
488*e7be843bSPierre Pronchery * retransmission. We already take care of notifying the peer of the
489*e7be843bSPierre Pronchery * termination of the stream during the stream deletion lifecycle.
490*e7be843bSPierre Pronchery */
491*e7be843bSPierre Pronchery *result = NULL;
492*e7be843bSPierre Pronchery }
493*e7be843bSPierre Pronchery
494*e7be843bSPierre Pronchery return 1;
495*e7be843bSPierre Pronchery }
496*e7be843bSPierre Pronchery
depack_do_frame_stream(PACKET * pkt,QUIC_CHANNEL * ch,OSSL_QRX_PKT * parent_pkt,OSSL_ACKM_RX_PKT * ackm_data,uint64_t frame_type,uint64_t * datalen)497*e7be843bSPierre Pronchery static int depack_do_frame_stream(PACKET *pkt, QUIC_CHANNEL *ch,
498*e7be843bSPierre Pronchery OSSL_QRX_PKT *parent_pkt,
499*e7be843bSPierre Pronchery OSSL_ACKM_RX_PKT *ackm_data,
500*e7be843bSPierre Pronchery uint64_t frame_type,
501*e7be843bSPierre Pronchery uint64_t *datalen)
502*e7be843bSPierre Pronchery {
503*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_STREAM frame_data;
504*e7be843bSPierre Pronchery QUIC_STREAM *stream;
505*e7be843bSPierre Pronchery uint64_t fce;
506*e7be843bSPierre Pronchery size_t rs_avail;
507*e7be843bSPierre Pronchery int rs_fin = 0;
508*e7be843bSPierre Pronchery
509*e7be843bSPierre Pronchery *datalen = 0;
510*e7be843bSPierre Pronchery
511*e7be843bSPierre Pronchery if (!ossl_quic_wire_decode_frame_stream(pkt, 0, &frame_data)) {
512*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
513*e7be843bSPierre Pronchery OSSL_QUIC_ERR_FRAME_ENCODING_ERROR,
514*e7be843bSPierre Pronchery frame_type,
515*e7be843bSPierre Pronchery "decode error");
516*e7be843bSPierre Pronchery return 0;
517*e7be843bSPierre Pronchery }
518*e7be843bSPierre Pronchery
519*e7be843bSPierre Pronchery if (!depack_do_implicit_stream_create(ch, frame_data.stream_id,
520*e7be843bSPierre Pronchery frame_type, &stream))
521*e7be843bSPierre Pronchery return 0; /* protocol error raised by above call */
522*e7be843bSPierre Pronchery
523*e7be843bSPierre Pronchery if (stream == NULL)
524*e7be843bSPierre Pronchery /*
525*e7be843bSPierre Pronchery * Data for old stream which is not a protocol violation but should be
526*e7be843bSPierre Pronchery * ignored, so stop here.
527*e7be843bSPierre Pronchery */
528*e7be843bSPierre Pronchery return 1;
529*e7be843bSPierre Pronchery
530*e7be843bSPierre Pronchery if (!ossl_quic_stream_has_recv(stream)) {
531*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
532*e7be843bSPierre Pronchery OSSL_QUIC_ERR_STREAM_STATE_ERROR,
533*e7be843bSPierre Pronchery frame_type,
534*e7be843bSPierre Pronchery "STREAM frame for TX only "
535*e7be843bSPierre Pronchery "stream");
536*e7be843bSPierre Pronchery return 0;
537*e7be843bSPierre Pronchery }
538*e7be843bSPierre Pronchery
539*e7be843bSPierre Pronchery /* Notify stream flow controller. */
540*e7be843bSPierre Pronchery if (!ossl_quic_rxfc_on_rx_stream_frame(&stream->rxfc,
541*e7be843bSPierre Pronchery frame_data.offset + frame_data.len,
542*e7be843bSPierre Pronchery frame_data.is_fin)) {
543*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
544*e7be843bSPierre Pronchery OSSL_QUIC_ERR_INTERNAL_ERROR,
545*e7be843bSPierre Pronchery frame_type,
546*e7be843bSPierre Pronchery "internal error (flow control)");
547*e7be843bSPierre Pronchery return 0;
548*e7be843bSPierre Pronchery }
549*e7be843bSPierre Pronchery
550*e7be843bSPierre Pronchery /* Has a flow control error occurred? */
551*e7be843bSPierre Pronchery fce = ossl_quic_rxfc_get_error(&stream->rxfc, 0);
552*e7be843bSPierre Pronchery if (fce != OSSL_QUIC_ERR_NO_ERROR) {
553*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
554*e7be843bSPierre Pronchery fce,
555*e7be843bSPierre Pronchery frame_type,
556*e7be843bSPierre Pronchery "flow control violation");
557*e7be843bSPierre Pronchery return 0;
558*e7be843bSPierre Pronchery }
559*e7be843bSPierre Pronchery
560*e7be843bSPierre Pronchery switch (stream->recv_state) {
561*e7be843bSPierre Pronchery case QUIC_RSTREAM_STATE_RECV:
562*e7be843bSPierre Pronchery case QUIC_RSTREAM_STATE_SIZE_KNOWN:
563*e7be843bSPierre Pronchery /*
564*e7be843bSPierre Pronchery * It only makes sense to process incoming STREAM frames in these
565*e7be843bSPierre Pronchery * states.
566*e7be843bSPierre Pronchery */
567*e7be843bSPierre Pronchery break;
568*e7be843bSPierre Pronchery
569*e7be843bSPierre Pronchery case QUIC_RSTREAM_STATE_DATA_RECVD:
570*e7be843bSPierre Pronchery case QUIC_RSTREAM_STATE_DATA_READ:
571*e7be843bSPierre Pronchery case QUIC_RSTREAM_STATE_RESET_RECVD:
572*e7be843bSPierre Pronchery case QUIC_RSTREAM_STATE_RESET_READ:
573*e7be843bSPierre Pronchery default:
574*e7be843bSPierre Pronchery /*
575*e7be843bSPierre Pronchery * We have no use for STREAM frames once the receive part reaches any of
576*e7be843bSPierre Pronchery * these states, so just ignore.
577*e7be843bSPierre Pronchery */
578*e7be843bSPierre Pronchery return 1;
579*e7be843bSPierre Pronchery }
580*e7be843bSPierre Pronchery
581*e7be843bSPierre Pronchery /* If we are in RECV, auto-transition to SIZE_KNOWN on FIN. */
582*e7be843bSPierre Pronchery if (frame_data.is_fin
583*e7be843bSPierre Pronchery && !ossl_quic_stream_recv_get_final_size(stream, NULL)) {
584*e7be843bSPierre Pronchery
585*e7be843bSPierre Pronchery /* State was already checked above, so can't fail. */
586*e7be843bSPierre Pronchery ossl_quic_stream_map_notify_size_known_recv_part(&ch->qsm, stream,
587*e7be843bSPierre Pronchery frame_data.offset
588*e7be843bSPierre Pronchery + frame_data.len);
589*e7be843bSPierre Pronchery }
590*e7be843bSPierre Pronchery
591*e7be843bSPierre Pronchery /*
592*e7be843bSPierre Pronchery * If we requested STOP_SENDING do not bother buffering the data. Note that
593*e7be843bSPierre Pronchery * this must happen after RXFC checks above as even if we sent STOP_SENDING
594*e7be843bSPierre Pronchery * we must still enforce correct flow control (RFC 9000 s. 3.5).
595*e7be843bSPierre Pronchery */
596*e7be843bSPierre Pronchery if (stream->stop_sending)
597*e7be843bSPierre Pronchery return 1; /* not an error - packet reordering, etc. */
598*e7be843bSPierre Pronchery
599*e7be843bSPierre Pronchery /*
600*e7be843bSPierre Pronchery * The receive stream buffer may or may not choose to consume the data
601*e7be843bSPierre Pronchery * without copying by reffing the OSSL_QRX_PKT. In this case
602*e7be843bSPierre Pronchery * ossl_qrx_pkt_release() will be eventually called when the data is no
603*e7be843bSPierre Pronchery * longer needed.
604*e7be843bSPierre Pronchery *
605*e7be843bSPierre Pronchery * It is OK for the peer to send us a zero-length non-FIN STREAM frame,
606*e7be843bSPierre Pronchery * which is a no-op, aside from the fact that it ensures the stream exists.
607*e7be843bSPierre Pronchery * In this case we have nothing to report to the receive buffer.
608*e7be843bSPierre Pronchery */
609*e7be843bSPierre Pronchery if ((frame_data.len > 0 || frame_data.is_fin)
610*e7be843bSPierre Pronchery && !ossl_quic_rstream_queue_data(stream->rstream, parent_pkt,
611*e7be843bSPierre Pronchery frame_data.offset,
612*e7be843bSPierre Pronchery frame_data.data,
613*e7be843bSPierre Pronchery frame_data.len,
614*e7be843bSPierre Pronchery frame_data.is_fin)) {
615*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
616*e7be843bSPierre Pronchery OSSL_QUIC_ERR_INTERNAL_ERROR,
617*e7be843bSPierre Pronchery frame_type,
618*e7be843bSPierre Pronchery "internal error (rstream queue)");
619*e7be843bSPierre Pronchery return 0;
620*e7be843bSPierre Pronchery }
621*e7be843bSPierre Pronchery
622*e7be843bSPierre Pronchery /*
623*e7be843bSPierre Pronchery * rs_fin will be 1 only if we can read all data up to and including the FIN
624*e7be843bSPierre Pronchery * without any gaps before it; this implies we have received all data. Avoid
625*e7be843bSPierre Pronchery * calling ossl_quic_rstream_available() where it is not necessary as it is
626*e7be843bSPierre Pronchery * more expensive.
627*e7be843bSPierre Pronchery */
628*e7be843bSPierre Pronchery if (stream->recv_state == QUIC_RSTREAM_STATE_SIZE_KNOWN
629*e7be843bSPierre Pronchery && !ossl_quic_rstream_available(stream->rstream, &rs_avail, &rs_fin)) {
630*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
631*e7be843bSPierre Pronchery OSSL_QUIC_ERR_INTERNAL_ERROR,
632*e7be843bSPierre Pronchery frame_type,
633*e7be843bSPierre Pronchery "internal error (rstream available)");
634*e7be843bSPierre Pronchery return 0;
635*e7be843bSPierre Pronchery }
636*e7be843bSPierre Pronchery
637*e7be843bSPierre Pronchery if (rs_fin)
638*e7be843bSPierre Pronchery ossl_quic_stream_map_notify_totally_received(&ch->qsm, stream);
639*e7be843bSPierre Pronchery
640*e7be843bSPierre Pronchery *datalen = frame_data.len;
641*e7be843bSPierre Pronchery
642*e7be843bSPierre Pronchery return 1;
643*e7be843bSPierre Pronchery }
644*e7be843bSPierre Pronchery
update_streams(QUIC_STREAM * s,void * arg)645*e7be843bSPierre Pronchery static void update_streams(QUIC_STREAM *s, void *arg)
646*e7be843bSPierre Pronchery {
647*e7be843bSPierre Pronchery QUIC_CHANNEL *ch = arg;
648*e7be843bSPierre Pronchery
649*e7be843bSPierre Pronchery ossl_quic_stream_map_update_state(&ch->qsm, s);
650*e7be843bSPierre Pronchery }
651*e7be843bSPierre Pronchery
update_streams_bidi(QUIC_STREAM * s,void * arg)652*e7be843bSPierre Pronchery static void update_streams_bidi(QUIC_STREAM *s, void *arg)
653*e7be843bSPierre Pronchery {
654*e7be843bSPierre Pronchery QUIC_CHANNEL *ch = arg;
655*e7be843bSPierre Pronchery
656*e7be843bSPierre Pronchery if (!ossl_quic_stream_is_bidi(s))
657*e7be843bSPierre Pronchery return;
658*e7be843bSPierre Pronchery
659*e7be843bSPierre Pronchery ossl_quic_stream_map_update_state(&ch->qsm, s);
660*e7be843bSPierre Pronchery }
661*e7be843bSPierre Pronchery
update_streams_uni(QUIC_STREAM * s,void * arg)662*e7be843bSPierre Pronchery static void update_streams_uni(QUIC_STREAM *s, void *arg)
663*e7be843bSPierre Pronchery {
664*e7be843bSPierre Pronchery QUIC_CHANNEL *ch = arg;
665*e7be843bSPierre Pronchery
666*e7be843bSPierre Pronchery if (ossl_quic_stream_is_bidi(s))
667*e7be843bSPierre Pronchery return;
668*e7be843bSPierre Pronchery
669*e7be843bSPierre Pronchery ossl_quic_stream_map_update_state(&ch->qsm, s);
670*e7be843bSPierre Pronchery }
671*e7be843bSPierre Pronchery
depack_do_frame_max_data(PACKET * pkt,QUIC_CHANNEL * ch,OSSL_ACKM_RX_PKT * ackm_data)672*e7be843bSPierre Pronchery static int depack_do_frame_max_data(PACKET *pkt, QUIC_CHANNEL *ch,
673*e7be843bSPierre Pronchery OSSL_ACKM_RX_PKT *ackm_data)
674*e7be843bSPierre Pronchery {
675*e7be843bSPierre Pronchery uint64_t max_data = 0;
676*e7be843bSPierre Pronchery
677*e7be843bSPierre Pronchery if (!ossl_quic_wire_decode_frame_max_data(pkt, &max_data)) {
678*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
679*e7be843bSPierre Pronchery OSSL_QUIC_ERR_FRAME_ENCODING_ERROR,
680*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_MAX_DATA,
681*e7be843bSPierre Pronchery "decode error");
682*e7be843bSPierre Pronchery return 0;
683*e7be843bSPierre Pronchery }
684*e7be843bSPierre Pronchery
685*e7be843bSPierre Pronchery ossl_quic_txfc_bump_cwm(&ch->conn_txfc, max_data);
686*e7be843bSPierre Pronchery ossl_quic_stream_map_visit(&ch->qsm, update_streams, ch);
687*e7be843bSPierre Pronchery return 1;
688*e7be843bSPierre Pronchery }
689*e7be843bSPierre Pronchery
depack_do_frame_max_stream_data(PACKET * pkt,QUIC_CHANNEL * ch,OSSL_ACKM_RX_PKT * ackm_data)690*e7be843bSPierre Pronchery static int depack_do_frame_max_stream_data(PACKET *pkt,
691*e7be843bSPierre Pronchery QUIC_CHANNEL *ch,
692*e7be843bSPierre Pronchery OSSL_ACKM_RX_PKT *ackm_data)
693*e7be843bSPierre Pronchery {
694*e7be843bSPierre Pronchery uint64_t stream_id = 0;
695*e7be843bSPierre Pronchery uint64_t max_stream_data = 0;
696*e7be843bSPierre Pronchery QUIC_STREAM *stream;
697*e7be843bSPierre Pronchery
698*e7be843bSPierre Pronchery if (!ossl_quic_wire_decode_frame_max_stream_data(pkt, &stream_id,
699*e7be843bSPierre Pronchery &max_stream_data)) {
700*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
701*e7be843bSPierre Pronchery OSSL_QUIC_ERR_FRAME_ENCODING_ERROR,
702*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA,
703*e7be843bSPierre Pronchery "decode error");
704*e7be843bSPierre Pronchery return 0;
705*e7be843bSPierre Pronchery }
706*e7be843bSPierre Pronchery
707*e7be843bSPierre Pronchery if (!depack_do_implicit_stream_create(ch, stream_id,
708*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA,
709*e7be843bSPierre Pronchery &stream))
710*e7be843bSPierre Pronchery return 0; /* error already raised for us */
711*e7be843bSPierre Pronchery
712*e7be843bSPierre Pronchery if (stream == NULL)
713*e7be843bSPierre Pronchery return 1; /* old deleted stream, not a protocol violation, ignore */
714*e7be843bSPierre Pronchery
715*e7be843bSPierre Pronchery if (!ossl_quic_stream_has_send(stream)) {
716*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
717*e7be843bSPierre Pronchery OSSL_QUIC_ERR_STREAM_STATE_ERROR,
718*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA,
719*e7be843bSPierre Pronchery "MAX_STREAM_DATA for TX only "
720*e7be843bSPierre Pronchery "stream");
721*e7be843bSPierre Pronchery return 0;
722*e7be843bSPierre Pronchery }
723*e7be843bSPierre Pronchery
724*e7be843bSPierre Pronchery ossl_quic_txfc_bump_cwm(&stream->txfc, max_stream_data);
725*e7be843bSPierre Pronchery ossl_quic_stream_map_update_state(&ch->qsm, stream);
726*e7be843bSPierre Pronchery return 1;
727*e7be843bSPierre Pronchery }
728*e7be843bSPierre Pronchery
depack_do_frame_max_streams(PACKET * pkt,QUIC_CHANNEL * ch,OSSL_ACKM_RX_PKT * ackm_data,uint64_t frame_type)729*e7be843bSPierre Pronchery static int depack_do_frame_max_streams(PACKET *pkt,
730*e7be843bSPierre Pronchery QUIC_CHANNEL *ch,
731*e7be843bSPierre Pronchery OSSL_ACKM_RX_PKT *ackm_data,
732*e7be843bSPierre Pronchery uint64_t frame_type)
733*e7be843bSPierre Pronchery {
734*e7be843bSPierre Pronchery uint64_t max_streams = 0;
735*e7be843bSPierre Pronchery
736*e7be843bSPierre Pronchery if (!ossl_quic_wire_decode_frame_max_streams(pkt, &max_streams)) {
737*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
738*e7be843bSPierre Pronchery OSSL_QUIC_ERR_FRAME_ENCODING_ERROR,
739*e7be843bSPierre Pronchery frame_type,
740*e7be843bSPierre Pronchery "decode error");
741*e7be843bSPierre Pronchery return 0;
742*e7be843bSPierre Pronchery }
743*e7be843bSPierre Pronchery
744*e7be843bSPierre Pronchery if (max_streams > (((uint64_t)1) << 60)) {
745*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
746*e7be843bSPierre Pronchery OSSL_QUIC_ERR_FRAME_ENCODING_ERROR,
747*e7be843bSPierre Pronchery frame_type,
748*e7be843bSPierre Pronchery "invalid max streams value");
749*e7be843bSPierre Pronchery return 0;
750*e7be843bSPierre Pronchery }
751*e7be843bSPierre Pronchery
752*e7be843bSPierre Pronchery switch (frame_type) {
753*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI:
754*e7be843bSPierre Pronchery if (max_streams > ch->max_local_streams_bidi)
755*e7be843bSPierre Pronchery ch->max_local_streams_bidi = max_streams;
756*e7be843bSPierre Pronchery
757*e7be843bSPierre Pronchery /* Some streams may now be able to send. */
758*e7be843bSPierre Pronchery ossl_quic_stream_map_visit(&ch->qsm, update_streams_bidi, ch);
759*e7be843bSPierre Pronchery break;
760*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_UNI:
761*e7be843bSPierre Pronchery if (max_streams > ch->max_local_streams_uni)
762*e7be843bSPierre Pronchery ch->max_local_streams_uni = max_streams;
763*e7be843bSPierre Pronchery
764*e7be843bSPierre Pronchery /* Some streams may now be able to send. */
765*e7be843bSPierre Pronchery ossl_quic_stream_map_visit(&ch->qsm, update_streams_uni, ch);
766*e7be843bSPierre Pronchery break;
767*e7be843bSPierre Pronchery default:
768*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
769*e7be843bSPierre Pronchery OSSL_QUIC_ERR_FRAME_ENCODING_ERROR,
770*e7be843bSPierre Pronchery frame_type,
771*e7be843bSPierre Pronchery "decode error");
772*e7be843bSPierre Pronchery return 0;
773*e7be843bSPierre Pronchery }
774*e7be843bSPierre Pronchery
775*e7be843bSPierre Pronchery return 1;
776*e7be843bSPierre Pronchery }
777*e7be843bSPierre Pronchery
depack_do_frame_data_blocked(PACKET * pkt,QUIC_CHANNEL * ch,OSSL_ACKM_RX_PKT * ackm_data)778*e7be843bSPierre Pronchery static int depack_do_frame_data_blocked(PACKET *pkt,
779*e7be843bSPierre Pronchery QUIC_CHANNEL *ch,
780*e7be843bSPierre Pronchery OSSL_ACKM_RX_PKT *ackm_data)
781*e7be843bSPierre Pronchery {
782*e7be843bSPierre Pronchery uint64_t max_data = 0;
783*e7be843bSPierre Pronchery
784*e7be843bSPierre Pronchery if (!ossl_quic_wire_decode_frame_data_blocked(pkt, &max_data)) {
785*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
786*e7be843bSPierre Pronchery OSSL_QUIC_ERR_FRAME_ENCODING_ERROR,
787*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_DATA_BLOCKED,
788*e7be843bSPierre Pronchery "decode error");
789*e7be843bSPierre Pronchery return 0;
790*e7be843bSPierre Pronchery }
791*e7be843bSPierre Pronchery
792*e7be843bSPierre Pronchery /* No-op - informative/debugging frame. */
793*e7be843bSPierre Pronchery return 1;
794*e7be843bSPierre Pronchery }
795*e7be843bSPierre Pronchery
depack_do_frame_stream_data_blocked(PACKET * pkt,QUIC_CHANNEL * ch,OSSL_ACKM_RX_PKT * ackm_data)796*e7be843bSPierre Pronchery static int depack_do_frame_stream_data_blocked(PACKET *pkt,
797*e7be843bSPierre Pronchery QUIC_CHANNEL *ch,
798*e7be843bSPierre Pronchery OSSL_ACKM_RX_PKT *ackm_data)
799*e7be843bSPierre Pronchery {
800*e7be843bSPierre Pronchery uint64_t stream_id = 0;
801*e7be843bSPierre Pronchery uint64_t max_data = 0;
802*e7be843bSPierre Pronchery QUIC_STREAM *stream;
803*e7be843bSPierre Pronchery
804*e7be843bSPierre Pronchery if (!ossl_quic_wire_decode_frame_stream_data_blocked(pkt, &stream_id,
805*e7be843bSPierre Pronchery &max_data)) {
806*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
807*e7be843bSPierre Pronchery OSSL_QUIC_ERR_FRAME_ENCODING_ERROR,
808*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED,
809*e7be843bSPierre Pronchery "decode error");
810*e7be843bSPierre Pronchery return 0;
811*e7be843bSPierre Pronchery }
812*e7be843bSPierre Pronchery
813*e7be843bSPierre Pronchery /*
814*e7be843bSPierre Pronchery * This is an informative/debugging frame, so we don't have to do anything,
815*e7be843bSPierre Pronchery * but it does trigger stream creation.
816*e7be843bSPierre Pronchery */
817*e7be843bSPierre Pronchery if (!depack_do_implicit_stream_create(ch, stream_id,
818*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED,
819*e7be843bSPierre Pronchery &stream))
820*e7be843bSPierre Pronchery return 0; /* error already raised for us */
821*e7be843bSPierre Pronchery
822*e7be843bSPierre Pronchery if (stream == NULL)
823*e7be843bSPierre Pronchery return 1; /* old deleted stream, not a protocol violation, ignore */
824*e7be843bSPierre Pronchery
825*e7be843bSPierre Pronchery if (!ossl_quic_stream_has_recv(stream)) {
826*e7be843bSPierre Pronchery /*
827*e7be843bSPierre Pronchery * RFC 9000 s. 19.14: "An endpoint that receives a STREAM_DATA_BLOCKED
828*e7be843bSPierre Pronchery * frame for a send-only stream MUST terminate the connection with error
829*e7be843bSPierre Pronchery * STREAM_STATE_ERROR."
830*e7be843bSPierre Pronchery */
831*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
832*e7be843bSPierre Pronchery OSSL_QUIC_ERR_STREAM_STATE_ERROR,
833*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED,
834*e7be843bSPierre Pronchery "STREAM_DATA_BLOCKED frame for "
835*e7be843bSPierre Pronchery "TX only stream");
836*e7be843bSPierre Pronchery return 0;
837*e7be843bSPierre Pronchery }
838*e7be843bSPierre Pronchery
839*e7be843bSPierre Pronchery /* No-op - informative/debugging frame. */
840*e7be843bSPierre Pronchery return 1;
841*e7be843bSPierre Pronchery }
842*e7be843bSPierre Pronchery
depack_do_frame_streams_blocked(PACKET * pkt,QUIC_CHANNEL * ch,OSSL_ACKM_RX_PKT * ackm_data,uint64_t frame_type)843*e7be843bSPierre Pronchery static int depack_do_frame_streams_blocked(PACKET *pkt,
844*e7be843bSPierre Pronchery QUIC_CHANNEL *ch,
845*e7be843bSPierre Pronchery OSSL_ACKM_RX_PKT *ackm_data,
846*e7be843bSPierre Pronchery uint64_t frame_type)
847*e7be843bSPierre Pronchery {
848*e7be843bSPierre Pronchery uint64_t max_data = 0;
849*e7be843bSPierre Pronchery
850*e7be843bSPierre Pronchery if (!ossl_quic_wire_decode_frame_streams_blocked(pkt, &max_data)) {
851*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
852*e7be843bSPierre Pronchery OSSL_QUIC_ERR_FRAME_ENCODING_ERROR,
853*e7be843bSPierre Pronchery frame_type,
854*e7be843bSPierre Pronchery "decode error");
855*e7be843bSPierre Pronchery return 0;
856*e7be843bSPierre Pronchery }
857*e7be843bSPierre Pronchery
858*e7be843bSPierre Pronchery if (max_data > (((uint64_t)1) << 60)) {
859*e7be843bSPierre Pronchery /*
860*e7be843bSPierre Pronchery * RFC 9000 s. 19.14: "This value cannot exceed 2**60, as it is not
861*e7be843bSPierre Pronchery * possible to encode stream IDs larger than 2**62 - 1. Receipt of a
862*e7be843bSPierre Pronchery * frame that encodes a larger stream ID MUST be treated as a connection
863*e7be843bSPierre Pronchery * error of type STREAM_LIMIT_ERROR or FRAME_ENCODING_ERROR."
864*e7be843bSPierre Pronchery */
865*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
866*e7be843bSPierre Pronchery OSSL_QUIC_ERR_STREAM_LIMIT_ERROR,
867*e7be843bSPierre Pronchery frame_type,
868*e7be843bSPierre Pronchery "invalid stream count limit");
869*e7be843bSPierre Pronchery return 0;
870*e7be843bSPierre Pronchery }
871*e7be843bSPierre Pronchery
872*e7be843bSPierre Pronchery /* No-op - informative/debugging frame. */
873*e7be843bSPierre Pronchery return 1;
874*e7be843bSPierre Pronchery }
875*e7be843bSPierre Pronchery
depack_do_frame_new_conn_id(PACKET * pkt,QUIC_CHANNEL * ch,OSSL_ACKM_RX_PKT * ackm_data)876*e7be843bSPierre Pronchery static int depack_do_frame_new_conn_id(PACKET *pkt,
877*e7be843bSPierre Pronchery QUIC_CHANNEL *ch,
878*e7be843bSPierre Pronchery OSSL_ACKM_RX_PKT *ackm_data)
879*e7be843bSPierre Pronchery {
880*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_NEW_CONN_ID frame_data;
881*e7be843bSPierre Pronchery
882*e7be843bSPierre Pronchery if (!ossl_quic_wire_decode_frame_new_conn_id(pkt, &frame_data)) {
883*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
884*e7be843bSPierre Pronchery OSSL_QUIC_ERR_FRAME_ENCODING_ERROR,
885*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID,
886*e7be843bSPierre Pronchery "decode error");
887*e7be843bSPierre Pronchery return 0;
888*e7be843bSPierre Pronchery }
889*e7be843bSPierre Pronchery
890*e7be843bSPierre Pronchery ossl_quic_channel_on_new_conn_id(ch, &frame_data);
891*e7be843bSPierre Pronchery
892*e7be843bSPierre Pronchery return 1;
893*e7be843bSPierre Pronchery }
894*e7be843bSPierre Pronchery
depack_do_frame_retire_conn_id(PACKET * pkt,QUIC_CHANNEL * ch,OSSL_ACKM_RX_PKT * ackm_data)895*e7be843bSPierre Pronchery static int depack_do_frame_retire_conn_id(PACKET *pkt,
896*e7be843bSPierre Pronchery QUIC_CHANNEL *ch,
897*e7be843bSPierre Pronchery OSSL_ACKM_RX_PKT *ackm_data)
898*e7be843bSPierre Pronchery {
899*e7be843bSPierre Pronchery uint64_t seq_num;
900*e7be843bSPierre Pronchery
901*e7be843bSPierre Pronchery if (!ossl_quic_wire_decode_frame_retire_conn_id(pkt, &seq_num)) {
902*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
903*e7be843bSPierre Pronchery OSSL_QUIC_ERR_FRAME_ENCODING_ERROR,
904*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID,
905*e7be843bSPierre Pronchery "decode error");
906*e7be843bSPierre Pronchery return 0;
907*e7be843bSPierre Pronchery }
908*e7be843bSPierre Pronchery
909*e7be843bSPierre Pronchery /*
910*e7be843bSPierre Pronchery * RFC 9000 s. 19.16: "An endpoint cannot send this frame if it was provided
911*e7be843bSPierre Pronchery * with a zero-length connection ID by its peer. An endpoint that provides a
912*e7be843bSPierre Pronchery * zero-length connection ID MUST treat receipt of a RETIRE_CONNECTION_ID
913*e7be843bSPierre Pronchery * frame as a connection error of type PROTOCOL_VIOLATION."
914*e7be843bSPierre Pronchery *
915*e7be843bSPierre Pronchery * Since we always use a zero-length SCID as a client, there is no case
916*e7be843bSPierre Pronchery * where it is valid for a server to send this. Our server support is
917*e7be843bSPierre Pronchery * currently non-conformant and for internal testing use; simply handle it
918*e7be843bSPierre Pronchery * as a no-op in this case.
919*e7be843bSPierre Pronchery *
920*e7be843bSPierre Pronchery * TODO(QUIC FUTURE): Revise and implement correctly for server support.
921*e7be843bSPierre Pronchery */
922*e7be843bSPierre Pronchery if (!ch->is_server) {
923*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
924*e7be843bSPierre Pronchery OSSL_QUIC_ERR_PROTOCOL_VIOLATION,
925*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID,
926*e7be843bSPierre Pronchery "conn has zero-length CID");
927*e7be843bSPierre Pronchery return 0;
928*e7be843bSPierre Pronchery }
929*e7be843bSPierre Pronchery
930*e7be843bSPierre Pronchery return 1;
931*e7be843bSPierre Pronchery }
932*e7be843bSPierre Pronchery
free_path_response(unsigned char * buf,size_t buf_len,void * arg)933*e7be843bSPierre Pronchery static void free_path_response(unsigned char *buf, size_t buf_len, void *arg)
934*e7be843bSPierre Pronchery {
935*e7be843bSPierre Pronchery OPENSSL_free(buf);
936*e7be843bSPierre Pronchery }
937*e7be843bSPierre Pronchery
depack_do_frame_path_challenge(PACKET * pkt,QUIC_CHANNEL * ch,OSSL_ACKM_RX_PKT * ackm_data)938*e7be843bSPierre Pronchery static int depack_do_frame_path_challenge(PACKET *pkt,
939*e7be843bSPierre Pronchery QUIC_CHANNEL *ch,
940*e7be843bSPierre Pronchery OSSL_ACKM_RX_PKT *ackm_data)
941*e7be843bSPierre Pronchery {
942*e7be843bSPierre Pronchery uint64_t frame_data = 0;
943*e7be843bSPierre Pronchery unsigned char *encoded = NULL;
944*e7be843bSPierre Pronchery size_t encoded_len;
945*e7be843bSPierre Pronchery WPACKET wpkt;
946*e7be843bSPierre Pronchery
947*e7be843bSPierre Pronchery if (!ossl_quic_wire_decode_frame_path_challenge(pkt, &frame_data)) {
948*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
949*e7be843bSPierre Pronchery OSSL_QUIC_ERR_FRAME_ENCODING_ERROR,
950*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE,
951*e7be843bSPierre Pronchery "decode error");
952*e7be843bSPierre Pronchery return 0;
953*e7be843bSPierre Pronchery }
954*e7be843bSPierre Pronchery
955*e7be843bSPierre Pronchery /*
956*e7be843bSPierre Pronchery * RFC 9000 s. 8.2.2: On receiving a PATH_CHALLENGE frame, an endpoint MUST
957*e7be843bSPierre Pronchery * respond by echoing the data contained in the PATH_CHALLENGE frame in a
958*e7be843bSPierre Pronchery * PATH_RESPONSE frame.
959*e7be843bSPierre Pronchery *
960*e7be843bSPierre Pronchery * TODO(QUIC FUTURE): We should try to avoid allocation here in the future.
961*e7be843bSPierre Pronchery */
962*e7be843bSPierre Pronchery encoded_len = sizeof(uint64_t) + 1;
963*e7be843bSPierre Pronchery if ((encoded = OPENSSL_malloc(encoded_len)) == NULL)
964*e7be843bSPierre Pronchery goto err;
965*e7be843bSPierre Pronchery
966*e7be843bSPierre Pronchery if (!WPACKET_init_static_len(&wpkt, encoded, encoded_len, 0))
967*e7be843bSPierre Pronchery goto err;
968*e7be843bSPierre Pronchery
969*e7be843bSPierre Pronchery if (!ossl_quic_wire_encode_frame_path_response(&wpkt, frame_data)) {
970*e7be843bSPierre Pronchery WPACKET_cleanup(&wpkt);
971*e7be843bSPierre Pronchery goto err;
972*e7be843bSPierre Pronchery }
973*e7be843bSPierre Pronchery
974*e7be843bSPierre Pronchery WPACKET_finish(&wpkt);
975*e7be843bSPierre Pronchery
976*e7be843bSPierre Pronchery if (!ossl_quic_cfq_add_frame(ch->cfq, 0, QUIC_PN_SPACE_APP,
977*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE,
978*e7be843bSPierre Pronchery QUIC_CFQ_ITEM_FLAG_UNRELIABLE,
979*e7be843bSPierre Pronchery encoded, encoded_len,
980*e7be843bSPierre Pronchery free_path_response, NULL))
981*e7be843bSPierre Pronchery goto err;
982*e7be843bSPierre Pronchery
983*e7be843bSPierre Pronchery return 1;
984*e7be843bSPierre Pronchery
985*e7be843bSPierre Pronchery err:
986*e7be843bSPierre Pronchery OPENSSL_free(encoded);
987*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_INTERNAL_ERROR,
988*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE,
989*e7be843bSPierre Pronchery "internal error");
990*e7be843bSPierre Pronchery return 0;
991*e7be843bSPierre Pronchery }
992*e7be843bSPierre Pronchery
depack_do_frame_path_response(PACKET * pkt,QUIC_CHANNEL * ch,OSSL_ACKM_RX_PKT * ackm_data)993*e7be843bSPierre Pronchery static int depack_do_frame_path_response(PACKET *pkt,
994*e7be843bSPierre Pronchery QUIC_CHANNEL *ch,
995*e7be843bSPierre Pronchery OSSL_ACKM_RX_PKT *ackm_data)
996*e7be843bSPierre Pronchery {
997*e7be843bSPierre Pronchery uint64_t frame_data = 0;
998*e7be843bSPierre Pronchery
999*e7be843bSPierre Pronchery if (!ossl_quic_wire_decode_frame_path_response(pkt, &frame_data)) {
1000*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
1001*e7be843bSPierre Pronchery OSSL_QUIC_ERR_FRAME_ENCODING_ERROR,
1002*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE,
1003*e7be843bSPierre Pronchery "decode error");
1004*e7be843bSPierre Pronchery return 0;
1005*e7be843bSPierre Pronchery }
1006*e7be843bSPierre Pronchery
1007*e7be843bSPierre Pronchery /* TODO(QUIC MULTIPATH): ADD CODE to send |frame_data| to the ch manager */
1008*e7be843bSPierre Pronchery
1009*e7be843bSPierre Pronchery return 1;
1010*e7be843bSPierre Pronchery }
1011*e7be843bSPierre Pronchery
depack_do_frame_conn_close(PACKET * pkt,QUIC_CHANNEL * ch,uint64_t frame_type)1012*e7be843bSPierre Pronchery static int depack_do_frame_conn_close(PACKET *pkt, QUIC_CHANNEL *ch,
1013*e7be843bSPierre Pronchery uint64_t frame_type)
1014*e7be843bSPierre Pronchery {
1015*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_CONN_CLOSE frame_data;
1016*e7be843bSPierre Pronchery
1017*e7be843bSPierre Pronchery if (!ossl_quic_wire_decode_frame_conn_close(pkt, &frame_data)) {
1018*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
1019*e7be843bSPierre Pronchery OSSL_QUIC_ERR_FRAME_ENCODING_ERROR,
1020*e7be843bSPierre Pronchery frame_type,
1021*e7be843bSPierre Pronchery "decode error");
1022*e7be843bSPierre Pronchery return 0;
1023*e7be843bSPierre Pronchery }
1024*e7be843bSPierre Pronchery
1025*e7be843bSPierre Pronchery ossl_quic_channel_on_remote_conn_close(ch, &frame_data);
1026*e7be843bSPierre Pronchery return 1;
1027*e7be843bSPierre Pronchery }
1028*e7be843bSPierre Pronchery
depack_do_frame_handshake_done(PACKET * pkt,QUIC_CHANNEL * ch,OSSL_ACKM_RX_PKT * ackm_data)1029*e7be843bSPierre Pronchery static int depack_do_frame_handshake_done(PACKET *pkt,
1030*e7be843bSPierre Pronchery QUIC_CHANNEL *ch,
1031*e7be843bSPierre Pronchery OSSL_ACKM_RX_PKT *ackm_data)
1032*e7be843bSPierre Pronchery {
1033*e7be843bSPierre Pronchery if (!ossl_quic_wire_decode_frame_handshake_done(pkt)) {
1034*e7be843bSPierre Pronchery /* This can fail only with an internal error. */
1035*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
1036*e7be843bSPierre Pronchery OSSL_QUIC_ERR_INTERNAL_ERROR,
1037*e7be843bSPierre Pronchery OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE,
1038*e7be843bSPierre Pronchery "internal error (decode frame handshake done)");
1039*e7be843bSPierre Pronchery return 0;
1040*e7be843bSPierre Pronchery }
1041*e7be843bSPierre Pronchery
1042*e7be843bSPierre Pronchery ossl_quic_channel_on_handshake_confirmed(ch);
1043*e7be843bSPierre Pronchery return 1;
1044*e7be843bSPierre Pronchery }
1045*e7be843bSPierre Pronchery
1046*e7be843bSPierre Pronchery /* Main frame processor */
1047*e7be843bSPierre Pronchery
depack_process_frames(QUIC_CHANNEL * ch,PACKET * pkt,OSSL_QRX_PKT * parent_pkt,uint32_t enc_level,OSSL_TIME received,OSSL_ACKM_RX_PKT * ackm_data)1048*e7be843bSPierre Pronchery static int depack_process_frames(QUIC_CHANNEL *ch, PACKET *pkt,
1049*e7be843bSPierre Pronchery OSSL_QRX_PKT *parent_pkt, uint32_t enc_level,
1050*e7be843bSPierre Pronchery OSSL_TIME received, OSSL_ACKM_RX_PKT *ackm_data)
1051*e7be843bSPierre Pronchery {
1052*e7be843bSPierre Pronchery uint32_t pkt_type = parent_pkt->hdr->type;
1053*e7be843bSPierre Pronchery uint32_t packet_space = ossl_quic_enc_level_to_pn_space(enc_level);
1054*e7be843bSPierre Pronchery
1055*e7be843bSPierre Pronchery if (PACKET_remaining(pkt) == 0) {
1056*e7be843bSPierre Pronchery /*
1057*e7be843bSPierre Pronchery * RFC 9000 s. 12.4: An endpoint MUST treat receipt of a packet
1058*e7be843bSPierre Pronchery * containing no frames as a connection error of type
1059*e7be843bSPierre Pronchery * PROTOCOL_VIOLATION.
1060*e7be843bSPierre Pronchery */
1061*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
1062*e7be843bSPierre Pronchery OSSL_QUIC_ERR_PROTOCOL_VIOLATION,
1063*e7be843bSPierre Pronchery 0,
1064*e7be843bSPierre Pronchery "empty packet payload");
1065*e7be843bSPierre Pronchery return 0;
1066*e7be843bSPierre Pronchery }
1067*e7be843bSPierre Pronchery
1068*e7be843bSPierre Pronchery while (PACKET_remaining(pkt) > 0) {
1069*e7be843bSPierre Pronchery int was_minimal;
1070*e7be843bSPierre Pronchery uint64_t frame_type;
1071*e7be843bSPierre Pronchery const unsigned char *sof = NULL;
1072*e7be843bSPierre Pronchery uint64_t datalen = 0;
1073*e7be843bSPierre Pronchery
1074*e7be843bSPierre Pronchery if (ch->msg_callback != NULL)
1075*e7be843bSPierre Pronchery sof = PACKET_data(pkt);
1076*e7be843bSPierre Pronchery
1077*e7be843bSPierre Pronchery if (!ossl_quic_wire_peek_frame_header(pkt, &frame_type, &was_minimal)) {
1078*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
1079*e7be843bSPierre Pronchery OSSL_QUIC_ERR_PROTOCOL_VIOLATION,
1080*e7be843bSPierre Pronchery 0,
1081*e7be843bSPierre Pronchery "malformed frame header");
1082*e7be843bSPierre Pronchery return 0;
1083*e7be843bSPierre Pronchery }
1084*e7be843bSPierre Pronchery
1085*e7be843bSPierre Pronchery if (!was_minimal) {
1086*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
1087*e7be843bSPierre Pronchery OSSL_QUIC_ERR_PROTOCOL_VIOLATION,
1088*e7be843bSPierre Pronchery frame_type,
1089*e7be843bSPierre Pronchery "non-minimal frame type encoding");
1090*e7be843bSPierre Pronchery return 0;
1091*e7be843bSPierre Pronchery }
1092*e7be843bSPierre Pronchery
1093*e7be843bSPierre Pronchery /*
1094*e7be843bSPierre Pronchery * There are only a few frame types which are not ACK-eliciting. Handle
1095*e7be843bSPierre Pronchery * these centrally to make error handling cases more resilient, as we
1096*e7be843bSPierre Pronchery * should tell the ACKM about an ACK-eliciting frame even if it was not
1097*e7be843bSPierre Pronchery * successfully handled.
1098*e7be843bSPierre Pronchery */
1099*e7be843bSPierre Pronchery switch (frame_type) {
1100*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_PADDING:
1101*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN:
1102*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN:
1103*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT:
1104*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_APP:
1105*e7be843bSPierre Pronchery break;
1106*e7be843bSPierre Pronchery default:
1107*e7be843bSPierre Pronchery ackm_data->is_ack_eliciting = 1;
1108*e7be843bSPierre Pronchery break;
1109*e7be843bSPierre Pronchery }
1110*e7be843bSPierre Pronchery
1111*e7be843bSPierre Pronchery switch (frame_type) {
1112*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_PING:
1113*e7be843bSPierre Pronchery /* Allowed in all packet types */
1114*e7be843bSPierre Pronchery if (!depack_do_frame_ping(pkt, ch, enc_level, ackm_data))
1115*e7be843bSPierre Pronchery return 0;
1116*e7be843bSPierre Pronchery break;
1117*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_PADDING:
1118*e7be843bSPierre Pronchery /* Allowed in all packet types */
1119*e7be843bSPierre Pronchery if (!depack_do_frame_padding(pkt))
1120*e7be843bSPierre Pronchery return 0;
1121*e7be843bSPierre Pronchery break;
1122*e7be843bSPierre Pronchery
1123*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN:
1124*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN:
1125*e7be843bSPierre Pronchery /* ACK frames are valid everywhere except in 0RTT packets */
1126*e7be843bSPierre Pronchery if (pkt_type == QUIC_PKT_TYPE_0RTT) {
1127*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
1128*e7be843bSPierre Pronchery OSSL_QUIC_ERR_PROTOCOL_VIOLATION,
1129*e7be843bSPierre Pronchery frame_type,
1130*e7be843bSPierre Pronchery "ACK not valid in 0-RTT");
1131*e7be843bSPierre Pronchery return 0;
1132*e7be843bSPierre Pronchery }
1133*e7be843bSPierre Pronchery if (!depack_do_frame_ack(pkt, ch, packet_space, received,
1134*e7be843bSPierre Pronchery frame_type, parent_pkt))
1135*e7be843bSPierre Pronchery return 0;
1136*e7be843bSPierre Pronchery break;
1137*e7be843bSPierre Pronchery
1138*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_RESET_STREAM:
1139*e7be843bSPierre Pronchery /* RESET_STREAM frames are valid in 0RTT and 1RTT packets */
1140*e7be843bSPierre Pronchery if (pkt_type != QUIC_PKT_TYPE_0RTT
1141*e7be843bSPierre Pronchery && pkt_type != QUIC_PKT_TYPE_1RTT) {
1142*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
1143*e7be843bSPierre Pronchery OSSL_QUIC_ERR_PROTOCOL_VIOLATION,
1144*e7be843bSPierre Pronchery frame_type,
1145*e7be843bSPierre Pronchery "RESET_STREAM not valid in "
1146*e7be843bSPierre Pronchery "INITIAL/HANDSHAKE");
1147*e7be843bSPierre Pronchery return 0;
1148*e7be843bSPierre Pronchery }
1149*e7be843bSPierre Pronchery if (!depack_do_frame_reset_stream(pkt, ch, ackm_data))
1150*e7be843bSPierre Pronchery return 0;
1151*e7be843bSPierre Pronchery break;
1152*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_STOP_SENDING:
1153*e7be843bSPierre Pronchery /* STOP_SENDING frames are valid in 0RTT and 1RTT packets */
1154*e7be843bSPierre Pronchery if (pkt_type != QUIC_PKT_TYPE_0RTT
1155*e7be843bSPierre Pronchery && pkt_type != QUIC_PKT_TYPE_1RTT) {
1156*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
1157*e7be843bSPierre Pronchery OSSL_QUIC_ERR_PROTOCOL_VIOLATION,
1158*e7be843bSPierre Pronchery frame_type,
1159*e7be843bSPierre Pronchery "STOP_SENDING not valid in "
1160*e7be843bSPierre Pronchery "INITIAL/HANDSHAKE");
1161*e7be843bSPierre Pronchery return 0;
1162*e7be843bSPierre Pronchery }
1163*e7be843bSPierre Pronchery if (!depack_do_frame_stop_sending(pkt, ch, ackm_data))
1164*e7be843bSPierre Pronchery return 0;
1165*e7be843bSPierre Pronchery break;
1166*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_CRYPTO:
1167*e7be843bSPierre Pronchery /* CRYPTO frames are valid everywhere except in 0RTT packets */
1168*e7be843bSPierre Pronchery if (pkt_type == QUIC_PKT_TYPE_0RTT) {
1169*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
1170*e7be843bSPierre Pronchery OSSL_QUIC_ERR_PROTOCOL_VIOLATION,
1171*e7be843bSPierre Pronchery frame_type,
1172*e7be843bSPierre Pronchery "CRYPTO frame not valid in 0-RTT");
1173*e7be843bSPierre Pronchery return 0;
1174*e7be843bSPierre Pronchery }
1175*e7be843bSPierre Pronchery if (!depack_do_frame_crypto(pkt, ch, parent_pkt, ackm_data, &datalen))
1176*e7be843bSPierre Pronchery return 0;
1177*e7be843bSPierre Pronchery break;
1178*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_NEW_TOKEN:
1179*e7be843bSPierre Pronchery /* NEW_TOKEN frames are valid in 1RTT packets */
1180*e7be843bSPierre Pronchery if (pkt_type != QUIC_PKT_TYPE_1RTT) {
1181*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
1182*e7be843bSPierre Pronchery OSSL_QUIC_ERR_PROTOCOL_VIOLATION,
1183*e7be843bSPierre Pronchery frame_type,
1184*e7be843bSPierre Pronchery "NEW_TOKEN valid only in 1-RTT");
1185*e7be843bSPierre Pronchery return 0;
1186*e7be843bSPierre Pronchery }
1187*e7be843bSPierre Pronchery
1188*e7be843bSPierre Pronchery /*
1189*e7be843bSPierre Pronchery * RFC 9000 s. 19.7: "A server MUST treat receipt of a NEW_TOKEN
1190*e7be843bSPierre Pronchery * frame as a connection error of type PROTOCOL_VIOLATION."
1191*e7be843bSPierre Pronchery */
1192*e7be843bSPierre Pronchery if (ch->is_server) {
1193*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
1194*e7be843bSPierre Pronchery OSSL_QUIC_ERR_PROTOCOL_VIOLATION,
1195*e7be843bSPierre Pronchery frame_type,
1196*e7be843bSPierre Pronchery "NEW_TOKEN can only be sent by a server");
1197*e7be843bSPierre Pronchery return 0;
1198*e7be843bSPierre Pronchery }
1199*e7be843bSPierre Pronchery
1200*e7be843bSPierre Pronchery if (!depack_do_frame_new_token(pkt, ch, ackm_data))
1201*e7be843bSPierre Pronchery return 0;
1202*e7be843bSPierre Pronchery break;
1203*e7be843bSPierre Pronchery
1204*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_STREAM:
1205*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_STREAM_FIN:
1206*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_STREAM_LEN:
1207*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_STREAM_LEN_FIN:
1208*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_STREAM_OFF:
1209*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_FIN:
1210*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN:
1211*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN_FIN:
1212*e7be843bSPierre Pronchery /* STREAM frames are valid in 0RTT and 1RTT packets */
1213*e7be843bSPierre Pronchery if (pkt_type != QUIC_PKT_TYPE_0RTT
1214*e7be843bSPierre Pronchery && pkt_type != QUIC_PKT_TYPE_1RTT) {
1215*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
1216*e7be843bSPierre Pronchery OSSL_QUIC_ERR_PROTOCOL_VIOLATION,
1217*e7be843bSPierre Pronchery frame_type,
1218*e7be843bSPierre Pronchery "STREAM valid only in 0/1-RTT");
1219*e7be843bSPierre Pronchery return 0;
1220*e7be843bSPierre Pronchery }
1221*e7be843bSPierre Pronchery if (!depack_do_frame_stream(pkt, ch, parent_pkt, ackm_data,
1222*e7be843bSPierre Pronchery frame_type, &datalen))
1223*e7be843bSPierre Pronchery return 0;
1224*e7be843bSPierre Pronchery break;
1225*e7be843bSPierre Pronchery
1226*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_MAX_DATA:
1227*e7be843bSPierre Pronchery /* MAX_DATA frames are valid in 0RTT and 1RTT packets */
1228*e7be843bSPierre Pronchery if (pkt_type != QUIC_PKT_TYPE_0RTT
1229*e7be843bSPierre Pronchery && pkt_type != QUIC_PKT_TYPE_1RTT) {
1230*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
1231*e7be843bSPierre Pronchery OSSL_QUIC_ERR_PROTOCOL_VIOLATION,
1232*e7be843bSPierre Pronchery frame_type,
1233*e7be843bSPierre Pronchery "MAX_DATA valid only in 0/1-RTT");
1234*e7be843bSPierre Pronchery return 0;
1235*e7be843bSPierre Pronchery }
1236*e7be843bSPierre Pronchery if (!depack_do_frame_max_data(pkt, ch, ackm_data))
1237*e7be843bSPierre Pronchery return 0;
1238*e7be843bSPierre Pronchery break;
1239*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA:
1240*e7be843bSPierre Pronchery /* MAX_STREAM_DATA frames are valid in 0RTT and 1RTT packets */
1241*e7be843bSPierre Pronchery if (pkt_type != QUIC_PKT_TYPE_0RTT
1242*e7be843bSPierre Pronchery && pkt_type != QUIC_PKT_TYPE_1RTT) {
1243*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
1244*e7be843bSPierre Pronchery OSSL_QUIC_ERR_PROTOCOL_VIOLATION,
1245*e7be843bSPierre Pronchery frame_type,
1246*e7be843bSPierre Pronchery "MAX_STREAM_DATA valid only in 0/1-RTT");
1247*e7be843bSPierre Pronchery return 0;
1248*e7be843bSPierre Pronchery }
1249*e7be843bSPierre Pronchery if (!depack_do_frame_max_stream_data(pkt, ch, ackm_data))
1250*e7be843bSPierre Pronchery return 0;
1251*e7be843bSPierre Pronchery break;
1252*e7be843bSPierre Pronchery
1253*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI:
1254*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_UNI:
1255*e7be843bSPierre Pronchery /* MAX_STREAMS frames are valid in 0RTT and 1RTT packets */
1256*e7be843bSPierre Pronchery if (pkt_type != QUIC_PKT_TYPE_0RTT
1257*e7be843bSPierre Pronchery && pkt_type != QUIC_PKT_TYPE_1RTT) {
1258*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
1259*e7be843bSPierre Pronchery OSSL_QUIC_ERR_PROTOCOL_VIOLATION,
1260*e7be843bSPierre Pronchery frame_type,
1261*e7be843bSPierre Pronchery "MAX_STREAMS valid only in 0/1-RTT");
1262*e7be843bSPierre Pronchery return 0;
1263*e7be843bSPierre Pronchery }
1264*e7be843bSPierre Pronchery if (!depack_do_frame_max_streams(pkt, ch, ackm_data,
1265*e7be843bSPierre Pronchery frame_type))
1266*e7be843bSPierre Pronchery return 0;
1267*e7be843bSPierre Pronchery break;
1268*e7be843bSPierre Pronchery
1269*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_DATA_BLOCKED:
1270*e7be843bSPierre Pronchery /* DATA_BLOCKED frames are valid in 0RTT and 1RTT packets */
1271*e7be843bSPierre Pronchery if (pkt_type != QUIC_PKT_TYPE_0RTT
1272*e7be843bSPierre Pronchery && pkt_type != QUIC_PKT_TYPE_1RTT) {
1273*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
1274*e7be843bSPierre Pronchery OSSL_QUIC_ERR_PROTOCOL_VIOLATION,
1275*e7be843bSPierre Pronchery frame_type,
1276*e7be843bSPierre Pronchery "DATA_BLOCKED valid only in 0/1-RTT");
1277*e7be843bSPierre Pronchery return 0;
1278*e7be843bSPierre Pronchery }
1279*e7be843bSPierre Pronchery if (!depack_do_frame_data_blocked(pkt, ch, ackm_data))
1280*e7be843bSPierre Pronchery return 0;
1281*e7be843bSPierre Pronchery break;
1282*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED:
1283*e7be843bSPierre Pronchery /* STREAM_DATA_BLOCKED frames are valid in 0RTT and 1RTT packets */
1284*e7be843bSPierre Pronchery if (pkt_type != QUIC_PKT_TYPE_0RTT
1285*e7be843bSPierre Pronchery && pkt_type != QUIC_PKT_TYPE_1RTT) {
1286*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
1287*e7be843bSPierre Pronchery OSSL_QUIC_ERR_PROTOCOL_VIOLATION,
1288*e7be843bSPierre Pronchery frame_type,
1289*e7be843bSPierre Pronchery "STREAM_DATA_BLOCKED valid only in 0/1-RTT");
1290*e7be843bSPierre Pronchery return 0;
1291*e7be843bSPierre Pronchery }
1292*e7be843bSPierre Pronchery if (!depack_do_frame_stream_data_blocked(pkt, ch, ackm_data))
1293*e7be843bSPierre Pronchery return 0;
1294*e7be843bSPierre Pronchery break;
1295*e7be843bSPierre Pronchery
1296*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI:
1297*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_UNI:
1298*e7be843bSPierre Pronchery /* STREAMS_BLOCKED frames are valid in 0RTT and 1RTT packets */
1299*e7be843bSPierre Pronchery if (pkt_type != QUIC_PKT_TYPE_0RTT
1300*e7be843bSPierre Pronchery && pkt_type != QUIC_PKT_TYPE_1RTT) {
1301*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
1302*e7be843bSPierre Pronchery OSSL_QUIC_ERR_PROTOCOL_VIOLATION,
1303*e7be843bSPierre Pronchery frame_type,
1304*e7be843bSPierre Pronchery "STREAMS valid only in 0/1-RTT");
1305*e7be843bSPierre Pronchery return 0;
1306*e7be843bSPierre Pronchery }
1307*e7be843bSPierre Pronchery if (!depack_do_frame_streams_blocked(pkt, ch, ackm_data,
1308*e7be843bSPierre Pronchery frame_type))
1309*e7be843bSPierre Pronchery return 0;
1310*e7be843bSPierre Pronchery break;
1311*e7be843bSPierre Pronchery
1312*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID:
1313*e7be843bSPierre Pronchery /* NEW_CONN_ID frames are valid in 0RTT and 1RTT packets */
1314*e7be843bSPierre Pronchery if (pkt_type != QUIC_PKT_TYPE_0RTT
1315*e7be843bSPierre Pronchery && pkt_type != QUIC_PKT_TYPE_1RTT) {
1316*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
1317*e7be843bSPierre Pronchery OSSL_QUIC_ERR_PROTOCOL_VIOLATION,
1318*e7be843bSPierre Pronchery frame_type,
1319*e7be843bSPierre Pronchery "NEW_CONN_ID valid only in 0/1-RTT");
1320*e7be843bSPierre Pronchery }
1321*e7be843bSPierre Pronchery if (!depack_do_frame_new_conn_id(pkt, ch, ackm_data))
1322*e7be843bSPierre Pronchery return 0;
1323*e7be843bSPierre Pronchery break;
1324*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID:
1325*e7be843bSPierre Pronchery /* RETIRE_CONN_ID frames are valid in 0RTT and 1RTT packets */
1326*e7be843bSPierre Pronchery if (pkt_type != QUIC_PKT_TYPE_0RTT
1327*e7be843bSPierre Pronchery && pkt_type != QUIC_PKT_TYPE_1RTT) {
1328*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
1329*e7be843bSPierre Pronchery OSSL_QUIC_ERR_PROTOCOL_VIOLATION,
1330*e7be843bSPierre Pronchery frame_type,
1331*e7be843bSPierre Pronchery "RETIRE_CONN_ID valid only in 0/1-RTT");
1332*e7be843bSPierre Pronchery return 0;
1333*e7be843bSPierre Pronchery }
1334*e7be843bSPierre Pronchery if (!depack_do_frame_retire_conn_id(pkt, ch, ackm_data))
1335*e7be843bSPierre Pronchery return 0;
1336*e7be843bSPierre Pronchery break;
1337*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE:
1338*e7be843bSPierre Pronchery /* PATH_CHALLENGE frames are valid in 0RTT and 1RTT packets */
1339*e7be843bSPierre Pronchery if (pkt_type != QUIC_PKT_TYPE_0RTT
1340*e7be843bSPierre Pronchery && pkt_type != QUIC_PKT_TYPE_1RTT) {
1341*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
1342*e7be843bSPierre Pronchery OSSL_QUIC_ERR_PROTOCOL_VIOLATION,
1343*e7be843bSPierre Pronchery frame_type,
1344*e7be843bSPierre Pronchery "PATH_CHALLENGE valid only in 0/1-RTT");
1345*e7be843bSPierre Pronchery return 0;
1346*e7be843bSPierre Pronchery }
1347*e7be843bSPierre Pronchery if (!depack_do_frame_path_challenge(pkt, ch, ackm_data))
1348*e7be843bSPierre Pronchery return 0;
1349*e7be843bSPierre Pronchery
1350*e7be843bSPierre Pronchery break;
1351*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE:
1352*e7be843bSPierre Pronchery /* PATH_RESPONSE frames are valid in 1RTT packets */
1353*e7be843bSPierre Pronchery if (pkt_type != QUIC_PKT_TYPE_1RTT) {
1354*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
1355*e7be843bSPierre Pronchery OSSL_QUIC_ERR_PROTOCOL_VIOLATION,
1356*e7be843bSPierre Pronchery frame_type,
1357*e7be843bSPierre Pronchery "PATH_CHALLENGE valid only in 1-RTT");
1358*e7be843bSPierre Pronchery return 0;
1359*e7be843bSPierre Pronchery }
1360*e7be843bSPierre Pronchery if (!depack_do_frame_path_response(pkt, ch, ackm_data))
1361*e7be843bSPierre Pronchery return 0;
1362*e7be843bSPierre Pronchery break;
1363*e7be843bSPierre Pronchery
1364*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_APP:
1365*e7be843bSPierre Pronchery /* CONN_CLOSE_APP frames are valid in 0RTT and 1RTT packets */
1366*e7be843bSPierre Pronchery if (pkt_type != QUIC_PKT_TYPE_0RTT
1367*e7be843bSPierre Pronchery && pkt_type != QUIC_PKT_TYPE_1RTT) {
1368*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
1369*e7be843bSPierre Pronchery OSSL_QUIC_ERR_PROTOCOL_VIOLATION,
1370*e7be843bSPierre Pronchery frame_type,
1371*e7be843bSPierre Pronchery "CONN_CLOSE (APP) valid only in 0/1-RTT");
1372*e7be843bSPierre Pronchery return 0;
1373*e7be843bSPierre Pronchery }
1374*e7be843bSPierre Pronchery /* FALLTHRU */
1375*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT:
1376*e7be843bSPierre Pronchery /* CONN_CLOSE_TRANSPORT frames are valid in all packets */
1377*e7be843bSPierre Pronchery if (!depack_do_frame_conn_close(pkt, ch, frame_type))
1378*e7be843bSPierre Pronchery return 0;
1379*e7be843bSPierre Pronchery break;
1380*e7be843bSPierre Pronchery
1381*e7be843bSPierre Pronchery case OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE:
1382*e7be843bSPierre Pronchery /* HANDSHAKE_DONE frames are valid in 1RTT packets */
1383*e7be843bSPierre Pronchery if (pkt_type != QUIC_PKT_TYPE_1RTT) {
1384*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
1385*e7be843bSPierre Pronchery OSSL_QUIC_ERR_PROTOCOL_VIOLATION,
1386*e7be843bSPierre Pronchery frame_type,
1387*e7be843bSPierre Pronchery "HANDSHAKE_DONE valid only in 1-RTT");
1388*e7be843bSPierre Pronchery return 0;
1389*e7be843bSPierre Pronchery }
1390*e7be843bSPierre Pronchery if (!depack_do_frame_handshake_done(pkt, ch, ackm_data))
1391*e7be843bSPierre Pronchery return 0;
1392*e7be843bSPierre Pronchery break;
1393*e7be843bSPierre Pronchery
1394*e7be843bSPierre Pronchery default:
1395*e7be843bSPierre Pronchery /* Unknown frame type */
1396*e7be843bSPierre Pronchery ossl_quic_channel_raise_protocol_error(ch,
1397*e7be843bSPierre Pronchery OSSL_QUIC_ERR_FRAME_ENCODING_ERROR,
1398*e7be843bSPierre Pronchery frame_type,
1399*e7be843bSPierre Pronchery "Unknown frame type received");
1400*e7be843bSPierre Pronchery return 0;
1401*e7be843bSPierre Pronchery }
1402*e7be843bSPierre Pronchery
1403*e7be843bSPierre Pronchery if (ch->msg_callback != NULL) {
1404*e7be843bSPierre Pronchery int ctype = SSL3_RT_QUIC_FRAME_FULL;
1405*e7be843bSPierre Pronchery
1406*e7be843bSPierre Pronchery size_t framelen = PACKET_data(pkt) - sof;
1407*e7be843bSPierre Pronchery
1408*e7be843bSPierre Pronchery if (frame_type == OSSL_QUIC_FRAME_TYPE_PADDING) {
1409*e7be843bSPierre Pronchery ctype = SSL3_RT_QUIC_FRAME_PADDING;
1410*e7be843bSPierre Pronchery } else if (OSSL_QUIC_FRAME_TYPE_IS_STREAM(frame_type)
1411*e7be843bSPierre Pronchery || frame_type == OSSL_QUIC_FRAME_TYPE_CRYPTO) {
1412*e7be843bSPierre Pronchery ctype = SSL3_RT_QUIC_FRAME_HEADER;
1413*e7be843bSPierre Pronchery framelen -= (size_t)datalen;
1414*e7be843bSPierre Pronchery }
1415*e7be843bSPierre Pronchery
1416*e7be843bSPierre Pronchery ch->msg_callback(0, OSSL_QUIC1_VERSION, ctype, sof, framelen,
1417*e7be843bSPierre Pronchery ch->msg_callback_ssl, ch->msg_callback_arg);
1418*e7be843bSPierre Pronchery }
1419*e7be843bSPierre Pronchery }
1420*e7be843bSPierre Pronchery
1421*e7be843bSPierre Pronchery return 1;
1422*e7be843bSPierre Pronchery }
1423*e7be843bSPierre Pronchery
1424*e7be843bSPierre Pronchery QUIC_NEEDS_LOCK
ossl_quic_handle_frames(QUIC_CHANNEL * ch,OSSL_QRX_PKT * qpacket)1425*e7be843bSPierre Pronchery int ossl_quic_handle_frames(QUIC_CHANNEL *ch, OSSL_QRX_PKT *qpacket)
1426*e7be843bSPierre Pronchery {
1427*e7be843bSPierre Pronchery PACKET pkt;
1428*e7be843bSPierre Pronchery OSSL_ACKM_RX_PKT ackm_data;
1429*e7be843bSPierre Pronchery uint32_t enc_level;
1430*e7be843bSPierre Pronchery size_t dgram_len = qpacket->datagram_len;
1431*e7be843bSPierre Pronchery
1432*e7be843bSPierre Pronchery /*
1433*e7be843bSPierre Pronchery * ok has three states:
1434*e7be843bSPierre Pronchery * -1 error with ackm_data uninitialized
1435*e7be843bSPierre Pronchery * 0 error with ackm_data initialized
1436*e7be843bSPierre Pronchery * 1 success (ackm_data initialized)
1437*e7be843bSPierre Pronchery */
1438*e7be843bSPierre Pronchery int ok = -1; /* Assume the worst */
1439*e7be843bSPierre Pronchery
1440*e7be843bSPierre Pronchery if (ch == NULL)
1441*e7be843bSPierre Pronchery goto end;
1442*e7be843bSPierre Pronchery
1443*e7be843bSPierre Pronchery ch->did_crypto_frame = 0;
1444*e7be843bSPierre Pronchery
1445*e7be843bSPierre Pronchery /* Initialize |ackm_data| (and reinitialize |ok|)*/
1446*e7be843bSPierre Pronchery memset(&ackm_data, 0, sizeof(ackm_data));
1447*e7be843bSPierre Pronchery /*
1448*e7be843bSPierre Pronchery * ASSUMPTION: All packets that aren't special case have a
1449*e7be843bSPierre Pronchery * packet number.
1450*e7be843bSPierre Pronchery */
1451*e7be843bSPierre Pronchery ackm_data.pkt_num = qpacket->pn;
1452*e7be843bSPierre Pronchery ackm_data.time = qpacket->time;
1453*e7be843bSPierre Pronchery enc_level = ossl_quic_pkt_type_to_enc_level(qpacket->hdr->type);
1454*e7be843bSPierre Pronchery if (enc_level >= QUIC_ENC_LEVEL_NUM)
1455*e7be843bSPierre Pronchery /*
1456*e7be843bSPierre Pronchery * Retry and Version Negotiation packets should not be passed to this
1457*e7be843bSPierre Pronchery * function.
1458*e7be843bSPierre Pronchery */
1459*e7be843bSPierre Pronchery goto end;
1460*e7be843bSPierre Pronchery
1461*e7be843bSPierre Pronchery ok = 0; /* Still assume the worst */
1462*e7be843bSPierre Pronchery ackm_data.pkt_space = ossl_quic_enc_level_to_pn_space(enc_level);
1463*e7be843bSPierre Pronchery
1464*e7be843bSPierre Pronchery /*
1465*e7be843bSPierre Pronchery * RFC 9000 s. 8.1
1466*e7be843bSPierre Pronchery * We can consider the connection to be validated, if we receive a packet
1467*e7be843bSPierre Pronchery * from the client protected via handshake keys, meaning that the
1468*e7be843bSPierre Pronchery * amplification limit no longer applies (i.e. we can set it as validated.
1469*e7be843bSPierre Pronchery * Otherwise, add the size of this packet to the unvalidated credit for
1470*e7be843bSPierre Pronchery * the connection.
1471*e7be843bSPierre Pronchery */
1472*e7be843bSPierre Pronchery if (enc_level == QUIC_ENC_LEVEL_HANDSHAKE)
1473*e7be843bSPierre Pronchery ossl_quic_tx_packetiser_set_validated(ch->txp);
1474*e7be843bSPierre Pronchery else
1475*e7be843bSPierre Pronchery ossl_quic_tx_packetiser_add_unvalidated_credit(ch->txp, dgram_len);
1476*e7be843bSPierre Pronchery
1477*e7be843bSPierre Pronchery /* Now that special cases are out of the way, parse frames */
1478*e7be843bSPierre Pronchery if (!PACKET_buf_init(&pkt, qpacket->hdr->data, qpacket->hdr->len)
1479*e7be843bSPierre Pronchery || !depack_process_frames(ch, &pkt, qpacket,
1480*e7be843bSPierre Pronchery enc_level,
1481*e7be843bSPierre Pronchery qpacket->time,
1482*e7be843bSPierre Pronchery &ackm_data))
1483*e7be843bSPierre Pronchery goto end;
1484*e7be843bSPierre Pronchery
1485*e7be843bSPierre Pronchery ok = 1;
1486*e7be843bSPierre Pronchery end:
1487*e7be843bSPierre Pronchery /*
1488*e7be843bSPierre Pronchery * ASSUMPTION: If this function is called at all, |qpacket| is
1489*e7be843bSPierre Pronchery * a legitimate packet, even if its contents aren't.
1490*e7be843bSPierre Pronchery * Therefore, we call ossl_ackm_on_rx_packet() unconditionally, as long as
1491*e7be843bSPierre Pronchery * |ackm_data| has at least been initialized.
1492*e7be843bSPierre Pronchery */
1493*e7be843bSPierre Pronchery if (ok >= 0)
1494*e7be843bSPierre Pronchery ossl_ackm_on_rx_packet(ch->ackm, &ackm_data);
1495*e7be843bSPierre Pronchery
1496*e7be843bSPierre Pronchery return ok > 0;
1497*e7be843bSPierre Pronchery }
1498