1 /*
2 * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 #include "internal/quic_port.h"
11 #include "internal/quic_channel.h"
12 #include "internal/quic_lcidm.h"
13 #include "internal/quic_srtm.h"
14 #include "internal/quic_txp.h"
15 #include "internal/ssl_unwrap.h"
16 #include "quic_port_local.h"
17 #include "quic_channel_local.h"
18 #include "quic_engine_local.h"
19 #include "quic_local.h"
20 #include "../ssl_local.h"
21 #include <openssl/rand.h>
22
23 /*
24 * QUIC Port Structure
25 * ===================
26 */
27 #define INIT_DCID_LEN 8
28
29 static int port_init(QUIC_PORT *port);
30 static void port_cleanup(QUIC_PORT *port);
31 static OSSL_TIME get_time(void *arg);
32 static void port_default_packet_handler(QUIC_URXE *e, void *arg,
33 const QUIC_CONN_ID *dcid);
34 static void port_rx_pre(QUIC_PORT *port);
35
36 /**
37 * @struct validation_token
38 * @brief Represents a validation token for secure connection handling.
39 *
40 * This struct is used to store information related to a validation token.
41 *
42 * @var validation_token::is_retry
43 * True iff this validation token is for a token sent in a RETRY packet.
44 * Otherwise, this token is from a NEW_TOKEN_packet. Iff this value is true,
45 * then ODCID and RSCID are set.
46 *
47 * @var validation_token::timestamp
48 * Time that the validation token was minted.
49 *
50 * @var validation_token::odcid
51 * An original connection ID (`QUIC_CONN_ID`) used to identify the QUIC
52 * connection. This ID helps associate the token with a specific connection.
53 * This will only be valid for validation tokens from RETRY packets.
54 *
55 * @var validation_token::rscid
56 * DCID that the client will use as the DCID of the subsequent initial packet
57 * i.e the "new" DCID.
58 * This will only be valid for validation tokens from RETRY packets.
59 *
60 * @var validation_token::remote_addr_len
61 * Length of the following character array.
62 *
63 * @var validation_token::remote_addr
64 * A character array holding the raw address of the client requesting the
65 * connection.
66 */
67 typedef struct validation_token {
68 OSSL_TIME timestamp;
69 QUIC_CONN_ID odcid;
70 QUIC_CONN_ID rscid;
71 size_t remote_addr_len;
72 unsigned char *remote_addr;
73 unsigned char is_retry;
74 } QUIC_VALIDATION_TOKEN;
75
76 /*
77 * Maximum length of a marshalled validation token.
78 *
79 * - timestamp is 8 bytes
80 * - odcid and rscid are maximally 42 bytes in total
81 * - remote_addr_len is a size_t (8 bytes)
82 * - remote_addr is in the worst case 110 bytes (in the case of using a
83 * maximally sized AF_UNIX socket)
84 * - is_retry is a single byte
85 */
86 #define MARSHALLED_TOKEN_MAX_LEN 169
87
88 /*
89 * Maximum length of an encrypted marshalled validation token.
90 *
91 * This will include the size of the marshalled validation token plus a 16 byte
92 * tag and a 12 byte IV, so in total 197 bytes.
93 */
94 #define ENCRYPTED_TOKEN_MAX_LEN (MARSHALLED_TOKEN_MAX_LEN + 16 + 12)
95
96 DEFINE_LIST_OF_IMPL(ch, QUIC_CHANNEL);
97 DEFINE_LIST_OF_IMPL(incoming_ch, QUIC_CHANNEL);
98 DEFINE_LIST_OF_IMPL(port, QUIC_PORT);
99
ossl_quic_port_new(const QUIC_PORT_ARGS * args)100 QUIC_PORT *ossl_quic_port_new(const QUIC_PORT_ARGS *args)
101 {
102 QUIC_PORT *port;
103
104 if ((port = OPENSSL_zalloc(sizeof(QUIC_PORT))) == NULL)
105 return NULL;
106
107 port->engine = args->engine;
108 port->channel_ctx = args->channel_ctx;
109 port->is_multi_conn = args->is_multi_conn;
110 port->validate_addr = args->do_addr_validation;
111 port->get_conn_user_ssl = args->get_conn_user_ssl;
112 port->user_ssl_arg = args->user_ssl_arg;
113
114 if (!port_init(port)) {
115 OPENSSL_free(port);
116 return NULL;
117 }
118
119 return port;
120 }
121
ossl_quic_port_free(QUIC_PORT * port)122 void ossl_quic_port_free(QUIC_PORT *port)
123 {
124 if (port == NULL)
125 return;
126
127 port_cleanup(port);
128 OPENSSL_free(port);
129 }
130
port_init(QUIC_PORT * port)131 static int port_init(QUIC_PORT *port)
132 {
133 size_t rx_short_dcid_len = (port->is_multi_conn ? INIT_DCID_LEN : 0);
134 int key_len;
135 EVP_CIPHER *cipher = NULL;
136 unsigned char *token_key = NULL;
137 int ret = 0;
138
139 if (port->engine == NULL || port->channel_ctx == NULL)
140 goto err;
141
142 if ((port->err_state = OSSL_ERR_STATE_new()) == NULL)
143 goto err;
144
145 if ((port->demux = ossl_quic_demux_new(/*BIO=*/NULL,
146 /*Short CID Len=*/rx_short_dcid_len,
147 get_time, port))
148 == NULL)
149 goto err;
150
151 ossl_quic_demux_set_default_handler(port->demux,
152 port_default_packet_handler,
153 port);
154
155 if ((port->srtm = ossl_quic_srtm_new(port->engine->libctx,
156 port->engine->propq))
157 == NULL)
158 goto err;
159
160 if ((port->lcidm = ossl_quic_lcidm_new(port->engine->libctx,
161 rx_short_dcid_len))
162 == NULL)
163 goto err;
164
165 port->rx_short_dcid_len = (unsigned char)rx_short_dcid_len;
166 port->tx_init_dcid_len = INIT_DCID_LEN;
167 port->state = QUIC_PORT_STATE_RUNNING;
168
169 ossl_list_port_insert_tail(&port->engine->port_list, port);
170 port->on_engine_list = 1;
171 port->bio_changed = 1;
172
173 /* Generate random key for token encryption */
174 if ((port->token_ctx = EVP_CIPHER_CTX_new()) == NULL
175 || (cipher = EVP_CIPHER_fetch(port->engine->libctx,
176 "AES-256-GCM", NULL))
177 == NULL
178 || !EVP_EncryptInit_ex(port->token_ctx, cipher, NULL, NULL, NULL)
179 || (key_len = EVP_CIPHER_CTX_get_key_length(port->token_ctx)) <= 0
180 || (token_key = OPENSSL_malloc(key_len)) == NULL
181 || !RAND_bytes_ex(port->engine->libctx, token_key, key_len, 0)
182 || !EVP_EncryptInit_ex(port->token_ctx, NULL, NULL, token_key, NULL))
183 goto err;
184
185 ret = 1;
186 err:
187 EVP_CIPHER_free(cipher);
188 OPENSSL_free(token_key);
189 if (!ret)
190 port_cleanup(port);
191 return ret;
192 }
193
port_cleanup(QUIC_PORT * port)194 static void port_cleanup(QUIC_PORT *port)
195 {
196 assert(ossl_list_ch_num(&port->channel_list) == 0);
197
198 ossl_quic_demux_free(port->demux);
199 port->demux = NULL;
200
201 ossl_quic_srtm_free(port->srtm);
202 port->srtm = NULL;
203
204 ossl_quic_lcidm_free(port->lcidm);
205 port->lcidm = NULL;
206
207 OSSL_ERR_STATE_free(port->err_state);
208 port->err_state = NULL;
209
210 if (port->on_engine_list) {
211 ossl_list_port_remove(&port->engine->port_list, port);
212 port->on_engine_list = 0;
213 }
214
215 EVP_CIPHER_CTX_free(port->token_ctx);
216 port->token_ctx = NULL;
217 }
218
port_transition_failed(QUIC_PORT * port)219 static void port_transition_failed(QUIC_PORT *port)
220 {
221 if (port->state == QUIC_PORT_STATE_FAILED)
222 return;
223
224 port->state = QUIC_PORT_STATE_FAILED;
225 }
226
ossl_quic_port_is_running(const QUIC_PORT * port)227 int ossl_quic_port_is_running(const QUIC_PORT *port)
228 {
229 return port->state == QUIC_PORT_STATE_RUNNING;
230 }
231
ossl_quic_port_get0_engine(QUIC_PORT * port)232 QUIC_ENGINE *ossl_quic_port_get0_engine(QUIC_PORT *port)
233 {
234 return port->engine;
235 }
236
ossl_quic_port_get0_reactor(QUIC_PORT * port)237 QUIC_REACTOR *ossl_quic_port_get0_reactor(QUIC_PORT *port)
238 {
239 return ossl_quic_engine_get0_reactor(port->engine);
240 }
241
ossl_quic_port_get0_demux(QUIC_PORT * port)242 QUIC_DEMUX *ossl_quic_port_get0_demux(QUIC_PORT *port)
243 {
244 return port->demux;
245 }
246
ossl_quic_port_get0_mutex(QUIC_PORT * port)247 CRYPTO_MUTEX *ossl_quic_port_get0_mutex(QUIC_PORT *port)
248 {
249 return ossl_quic_engine_get0_mutex(port->engine);
250 }
251
ossl_quic_port_get_time(QUIC_PORT * port)252 OSSL_TIME ossl_quic_port_get_time(QUIC_PORT *port)
253 {
254 return ossl_quic_engine_get_time(port->engine);
255 }
256
get_time(void * port)257 static OSSL_TIME get_time(void *port)
258 {
259 return ossl_quic_port_get_time((QUIC_PORT *)port);
260 }
261
ossl_quic_port_get_rx_short_dcid_len(const QUIC_PORT * port)262 int ossl_quic_port_get_rx_short_dcid_len(const QUIC_PORT *port)
263 {
264 return port->rx_short_dcid_len;
265 }
266
ossl_quic_port_get_tx_init_dcid_len(const QUIC_PORT * port)267 int ossl_quic_port_get_tx_init_dcid_len(const QUIC_PORT *port)
268 {
269 return port->tx_init_dcid_len;
270 }
271
ossl_quic_port_get_num_incoming_channels(const QUIC_PORT * port)272 size_t ossl_quic_port_get_num_incoming_channels(const QUIC_PORT *port)
273 {
274 return ossl_list_incoming_ch_num(&port->incoming_channel_list);
275 }
276
277 /*
278 * QUIC Port: Network BIO Configuration
279 * ====================================
280 */
281
282 /* Determines whether we can support a given poll descriptor. */
validate_poll_descriptor(const BIO_POLL_DESCRIPTOR * d)283 static int validate_poll_descriptor(const BIO_POLL_DESCRIPTOR *d)
284 {
285 if (d->type == BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD && d->value.fd < 0) {
286 ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT);
287 return 0;
288 }
289
290 return 1;
291 }
292
ossl_quic_port_get_net_rbio(QUIC_PORT * port)293 BIO *ossl_quic_port_get_net_rbio(QUIC_PORT *port)
294 {
295 return port->net_rbio;
296 }
297
ossl_quic_port_get_net_wbio(QUIC_PORT * port)298 BIO *ossl_quic_port_get_net_wbio(QUIC_PORT *port)
299 {
300 return port->net_wbio;
301 }
302
port_update_poll_desc(QUIC_PORT * port,BIO * net_bio,int for_write)303 static int port_update_poll_desc(QUIC_PORT *port, BIO *net_bio, int for_write)
304 {
305 BIO_POLL_DESCRIPTOR d = { 0 };
306
307 if (net_bio == NULL
308 || (!for_write && !BIO_get_rpoll_descriptor(net_bio, &d))
309 || (for_write && !BIO_get_wpoll_descriptor(net_bio, &d)))
310 /* Non-pollable BIO */
311 d.type = BIO_POLL_DESCRIPTOR_TYPE_NONE;
312
313 if (!validate_poll_descriptor(&d))
314 return 0;
315
316 /*
317 * TODO(QUIC MULTIPORT): We currently only support one port per
318 * engine/domain. This is necessitated because QUIC_REACTOR only supports a
319 * single pollable currently. In the future, once complete polling
320 * infrastructure has been implemented, this limitation can be removed.
321 *
322 * For now, just update the descriptor on the engine's reactor as we are
323 * guaranteed to be the only port under it.
324 */
325 if (for_write)
326 ossl_quic_reactor_set_poll_w(&port->engine->rtor, &d);
327 else
328 ossl_quic_reactor_set_poll_r(&port->engine->rtor, &d);
329
330 return 1;
331 }
332
ossl_quic_port_update_poll_descriptors(QUIC_PORT * port,int force)333 int ossl_quic_port_update_poll_descriptors(QUIC_PORT *port, int force)
334 {
335 int ok = 1;
336
337 if (!force && !port->bio_changed)
338 return 0;
339
340 if (!port_update_poll_desc(port, port->net_rbio, /*for_write=*/0))
341 ok = 0;
342
343 if (!port_update_poll_desc(port, port->net_wbio, /*for_write=*/1))
344 ok = 0;
345
346 port->bio_changed = 0;
347 return ok;
348 }
349
350 /*
351 * We need to determine our addressing mode. There are basically two ways we can
352 * use L4 addresses:
353 *
354 * - Addressed mode, in which our BIO_sendmmsg calls have destination
355 * addresses attached to them which we expect the underlying network BIO to
356 * handle;
357 *
358 * - Unaddressed mode, in which the BIO provided to us on the network side
359 * neither provides us with L4 addresses nor is capable of honouring ones we
360 * provide. We don't know where the QUIC traffic we send ends up exactly and
361 * trust the application to know what it is doing.
362 *
363 * Addressed mode is preferred because it enables support for connection
364 * migration, multipath, etc. in the future. Addressed mode is automatically
365 * enabled if we are using e.g. BIO_s_datagram, with or without BIO_s_connect.
366 *
367 * If we are passed a BIO_s_dgram_pair (or some custom BIO) we may have to use
368 * unaddressed mode unless that BIO supports capability flags indicating it can
369 * provide and honour L4 addresses.
370 *
371 * Our strategy for determining address mode is simple: we probe the underlying
372 * network BIOs for their capabilities. If the network BIOs support what we
373 * need, we use addressed mode. Otherwise, we use unaddressed mode.
374 *
375 * If addressed mode is chosen, we require an initial peer address to be set. If
376 * this is not set, we fail. If unaddressed mode is used, we do not require
377 * this, as such an address is superfluous, though it can be set if desired.
378 */
port_update_addressing_mode(QUIC_PORT * port)379 static void port_update_addressing_mode(QUIC_PORT *port)
380 {
381 long rcaps = 0, wcaps = 0;
382
383 if (port->net_rbio != NULL)
384 rcaps = BIO_dgram_get_effective_caps(port->net_rbio);
385
386 if (port->net_wbio != NULL)
387 wcaps = BIO_dgram_get_effective_caps(port->net_wbio);
388
389 port->addressed_mode_r = ((rcaps & BIO_DGRAM_CAP_PROVIDES_SRC_ADDR) != 0);
390 port->addressed_mode_w = ((wcaps & BIO_DGRAM_CAP_HANDLES_DST_ADDR) != 0);
391 port->bio_changed = 1;
392 }
393
ossl_quic_port_is_addressed_r(const QUIC_PORT * port)394 int ossl_quic_port_is_addressed_r(const QUIC_PORT *port)
395 {
396 return port->addressed_mode_r;
397 }
398
ossl_quic_port_is_addressed_w(const QUIC_PORT * port)399 int ossl_quic_port_is_addressed_w(const QUIC_PORT *port)
400 {
401 return port->addressed_mode_w;
402 }
403
ossl_quic_port_is_addressed(const QUIC_PORT * port)404 int ossl_quic_port_is_addressed(const QUIC_PORT *port)
405 {
406 return ossl_quic_port_is_addressed_r(port) && ossl_quic_port_is_addressed_w(port);
407 }
408
409 /*
410 * QUIC_PORT does not ref any BIO it is provided with, nor is any ref
411 * transferred to it. The caller (e.g., QUIC_CONNECTION) is responsible for
412 * ensuring the BIO lasts until the channel is freed or the BIO is switched out
413 * for another BIO by a subsequent successful call to this function.
414 */
ossl_quic_port_set_net_rbio(QUIC_PORT * port,BIO * net_rbio)415 int ossl_quic_port_set_net_rbio(QUIC_PORT *port, BIO *net_rbio)
416 {
417 if (port->net_rbio == net_rbio)
418 return 1;
419
420 if (!port_update_poll_desc(port, net_rbio, /*for_write=*/0))
421 return 0;
422
423 ossl_quic_demux_set_bio(port->demux, net_rbio);
424 port->net_rbio = net_rbio;
425 port_update_addressing_mode(port);
426 return 1;
427 }
428
ossl_quic_port_set_net_wbio(QUIC_PORT * port,BIO * net_wbio)429 int ossl_quic_port_set_net_wbio(QUIC_PORT *port, BIO *net_wbio)
430 {
431 QUIC_CHANNEL *ch;
432
433 if (port->net_wbio == net_wbio)
434 return 1;
435
436 if (!port_update_poll_desc(port, net_wbio, /*for_write=*/1))
437 return 0;
438
439 OSSL_LIST_FOREACH(ch, ch, &port->channel_list)
440 ossl_qtx_set_bio(ch->qtx, net_wbio);
441
442 port->net_wbio = net_wbio;
443 port_update_addressing_mode(port);
444 return 1;
445 }
446
ossl_quic_port_get_channel_ctx(QUIC_PORT * port)447 SSL_CTX *ossl_quic_port_get_channel_ctx(QUIC_PORT *port)
448 {
449 return port->channel_ctx;
450 }
451
452 /*
453 * QUIC Port: Channel Lifecycle
454 * ============================
455 */
456
port_new_handshake_layer(QUIC_PORT * port,QUIC_CHANNEL * ch)457 static SSL *port_new_handshake_layer(QUIC_PORT *port, QUIC_CHANNEL *ch)
458 {
459 SSL *tls = NULL;
460 SSL_CONNECTION *tls_conn = NULL;
461 SSL *user_ssl = NULL;
462 QUIC_CONNECTION *qc = NULL;
463 QUIC_LISTENER *ql = NULL;
464
465 /*
466 * It only makes sense to call this function if we know how to associate
467 * the handshake layer we are about to create with some user_ssl object.
468 */
469 if (!ossl_assert(port->get_conn_user_ssl != NULL))
470 return NULL;
471 user_ssl = port->get_conn_user_ssl(ch, port->user_ssl_arg);
472 if (user_ssl == NULL)
473 return NULL;
474 qc = (QUIC_CONNECTION *)user_ssl;
475 ql = (QUIC_LISTENER *)port->user_ssl_arg;
476
477 /*
478 * We expect the user_ssl to be newly created so it must not have an
479 * existing qc->tls
480 */
481 if (!ossl_assert(qc->tls == NULL)) {
482 SSL_free(user_ssl);
483 return NULL;
484 }
485
486 tls = ossl_ssl_connection_new_int(port->channel_ctx, user_ssl, TLS_method());
487 qc->tls = tls;
488 if (tls == NULL || (tls_conn = SSL_CONNECTION_FROM_SSL(tls)) == NULL) {
489 SSL_free(user_ssl);
490 return NULL;
491 }
492
493 if (ql != NULL && ql->obj.ssl.ctx->new_pending_conn_cb != NULL)
494 if (!ql->obj.ssl.ctx->new_pending_conn_cb(ql->obj.ssl.ctx, user_ssl,
495 ql->obj.ssl.ctx->new_pending_conn_arg)) {
496 SSL_free(user_ssl);
497 return NULL;
498 }
499
500 /* Override the user_ssl of the inner connection. */
501 tls_conn->s3.flags |= TLS1_FLAGS_QUIC | TLS1_FLAGS_QUIC_INTERNAL;
502
503 /* Restrict options derived from the SSL_CTX. */
504 tls_conn->options &= OSSL_QUIC_PERMITTED_OPTIONS_CONN;
505 tls_conn->pha_enabled = 0;
506 return tls;
507 }
508
port_make_channel(QUIC_PORT * port,SSL * tls,OSSL_QRX * qrx,int is_server,int is_tserver)509 static QUIC_CHANNEL *port_make_channel(QUIC_PORT *port, SSL *tls, OSSL_QRX *qrx,
510 int is_server, int is_tserver)
511 {
512 QUIC_CHANNEL_ARGS args = { 0 };
513 QUIC_CHANNEL *ch;
514
515 args.port = port;
516 args.is_server = is_server;
517 args.lcidm = port->lcidm;
518 args.srtm = port->srtm;
519 args.qrx = qrx;
520 args.is_tserver_ch = is_tserver;
521
522 /*
523 * Creating a a new channel is made a bit tricky here as there is a
524 * bit of a circular dependency. Initializing a channel requires that
525 * the ch->tls and optionally the qlog_title be configured prior to
526 * initialization, but we need the channel at least partially configured
527 * to create the new handshake layer, so we have to do this in a few steps.
528 */
529
530 /*
531 * start by allocation and provisioning as much of the channel as we can
532 */
533 ch = ossl_quic_channel_alloc(&args);
534 if (ch == NULL)
535 return NULL;
536
537 /*
538 * Fixup the channel tls connection here before we init the channel
539 */
540 ch->tls = (tls != NULL) ? tls : port_new_handshake_layer(port, ch);
541
542 if (ch->tls == NULL) {
543 OPENSSL_free(ch);
544 return NULL;
545 }
546
547 #ifndef OPENSSL_NO_QLOG
548 /*
549 * If we're using qlog, make sure the tls get further configured properly
550 */
551 ch->use_qlog = 1;
552 if (ch->tls->ctx->qlog_title != NULL) {
553 if ((ch->qlog_title = OPENSSL_strdup(ch->tls->ctx->qlog_title)) == NULL) {
554 OPENSSL_free(ch);
555 return NULL;
556 }
557 }
558 #endif
559
560 /*
561 * And finally init the channel struct
562 */
563 if (!ossl_quic_channel_init(ch)) {
564 OPENSSL_free(ch);
565 return NULL;
566 }
567
568 ossl_qtx_set_bio(ch->qtx, port->net_wbio);
569 return ch;
570 }
571
ossl_quic_port_create_outgoing(QUIC_PORT * port,SSL * tls)572 QUIC_CHANNEL *ossl_quic_port_create_outgoing(QUIC_PORT *port, SSL *tls)
573 {
574 return port_make_channel(port, tls, NULL, /* is_server= */ 0,
575 /* is_tserver= */ 0);
576 }
577
ossl_quic_port_create_incoming(QUIC_PORT * port,SSL * tls)578 QUIC_CHANNEL *ossl_quic_port_create_incoming(QUIC_PORT *port, SSL *tls)
579 {
580 QUIC_CHANNEL *ch;
581
582 assert(port->tserver_ch == NULL);
583
584 /*
585 * pass -1 for qrx to indicate port will create qrx
586 * later in port_default_packet_handler() when calling port_bind_channel().
587 */
588 ch = port_make_channel(port, tls, NULL, /* is_server= */ 1,
589 /* is_tserver_ch */ 1);
590 port->tserver_ch = ch;
591 port->allow_incoming = 1;
592 return ch;
593 }
594
ossl_quic_port_pop_incoming(QUIC_PORT * port)595 QUIC_CHANNEL *ossl_quic_port_pop_incoming(QUIC_PORT *port)
596 {
597 QUIC_CHANNEL *ch;
598
599 ch = ossl_list_incoming_ch_head(&port->incoming_channel_list);
600 if (ch == NULL)
601 return NULL;
602
603 ossl_list_incoming_ch_remove(&port->incoming_channel_list, ch);
604 return ch;
605 }
606
ossl_quic_port_have_incoming(QUIC_PORT * port)607 int ossl_quic_port_have_incoming(QUIC_PORT *port)
608 {
609 return ossl_list_incoming_ch_head(&port->incoming_channel_list) != NULL;
610 }
611
ossl_quic_port_drop_incoming(QUIC_PORT * port)612 void ossl_quic_port_drop_incoming(QUIC_PORT *port)
613 {
614 QUIC_CHANNEL *ch;
615 SSL *tls;
616 SSL *user_ssl;
617 SSL_CONNECTION *sc;
618
619 for (;;) {
620 ch = ossl_quic_port_pop_incoming(port);
621 if (ch == NULL)
622 break;
623
624 tls = ossl_quic_channel_get0_tls(ch);
625 /*
626 * The user ssl may or may not have been created via the
627 * get_conn_user_ssl callback in the QUIC stack. The
628 * differentiation being if the user_ssl pointer and tls pointer
629 * are different. If they are, then the user_ssl needs freeing here
630 * which sends us through ossl_quic_free, which then drops the actual
631 * ch->tls ref and frees the channel
632 */
633 sc = SSL_CONNECTION_FROM_SSL(tls);
634 if (sc == NULL)
635 break;
636
637 user_ssl = SSL_CONNECTION_GET_USER_SSL(sc);
638 if (user_ssl == tls) {
639 ossl_quic_channel_free(ch);
640 SSL_free(tls);
641 } else {
642 SSL_free(user_ssl);
643 }
644 }
645 }
646
ossl_quic_port_set_allow_incoming(QUIC_PORT * port,int allow_incoming)647 void ossl_quic_port_set_allow_incoming(QUIC_PORT *port, int allow_incoming)
648 {
649 port->allow_incoming = allow_incoming;
650 }
651
652 /*
653 * QUIC Port: Ticker-Mutator
654 * =========================
655 */
656
657 /*
658 * Tick function for this port. This does everything related to network I/O for
659 * this port's network BIOs, and services child channels.
660 */
ossl_quic_port_subtick(QUIC_PORT * port,QUIC_TICK_RESULT * res,uint32_t flags)661 void ossl_quic_port_subtick(QUIC_PORT *port, QUIC_TICK_RESULT *res,
662 uint32_t flags)
663 {
664 QUIC_CHANNEL *ch;
665
666 res->net_read_desired = ossl_quic_port_is_running(port);
667 res->net_write_desired = 0;
668 res->notify_other_threads = 0;
669 res->tick_deadline = ossl_time_infinite();
670
671 if (!port->engine->inhibit_tick) {
672 /* Handle any incoming data from network. */
673 if (ossl_quic_port_is_running(port))
674 port_rx_pre(port);
675
676 /* Iterate through all channels and service them. */
677 OSSL_LIST_FOREACH(ch, ch, &port->channel_list)
678 {
679 QUIC_TICK_RESULT subr = { 0 };
680
681 ossl_quic_channel_subtick(ch, &subr, flags);
682 ossl_quic_tick_result_merge_into(res, &subr);
683 }
684 }
685 }
686
687 /* Process incoming datagrams, if any. */
port_rx_pre(QUIC_PORT * port)688 static void port_rx_pre(QUIC_PORT *port)
689 {
690 int ret;
691
692 /*
693 * Originally, this check (don't RX before we have sent anything if we are
694 * not a server, because there can't be anything) was just intended as a
695 * minor optimisation. However, it is actually required on Windows, and
696 * removing this check will cause Windows to break.
697 *
698 * The reason is that under Win32, recvfrom() does not work on a UDP socket
699 * which has not had bind() called (???). However, calling sendto() will
700 * automatically bind an unbound UDP socket. Therefore, if we call a Winsock
701 * recv-type function before calling a Winsock send-type function, that call
702 * will fail with WSAEINVAL, which we will regard as a permanent network
703 * error.
704 *
705 * Therefore, this check is essential as we do not require our API users to
706 * bind a socket first when using the API in client mode.
707 */
708 if (!port->allow_incoming && !port->have_sent_any_pkt)
709 return;
710
711 /*
712 * Get DEMUX to BIO_recvmmsg from the network and queue incoming datagrams
713 * to the appropriate QRX instances.
714 */
715 ret = ossl_quic_demux_pump(port->demux);
716 if (ret == QUIC_DEMUX_PUMP_RES_PERMANENT_FAIL)
717 /*
718 * We don't care about transient failure, but permanent failure means we
719 * should tear down the port. All connections skip straight to the
720 * Terminated state as there is no point trying to send CONNECTION_CLOSE
721 * frames if the network BIO is not operating correctly.
722 */
723 ossl_quic_port_raise_net_error(port, NULL);
724 }
725
726 /*
727 * Handles an incoming connection request and potentially decides to make a
728 * connection from it. If a new connection is made, the new channel is written
729 * to *new_ch.
730 */
port_bind_channel(QUIC_PORT * port,const BIO_ADDR * peer,const QUIC_CONN_ID * scid,const QUIC_CONN_ID * dcid,const QUIC_CONN_ID * odcid,OSSL_QRX * qrx,QUIC_CHANNEL ** new_ch)731 static void port_bind_channel(QUIC_PORT *port, const BIO_ADDR *peer,
732 const QUIC_CONN_ID *scid, const QUIC_CONN_ID *dcid,
733 const QUIC_CONN_ID *odcid, OSSL_QRX *qrx,
734 QUIC_CHANNEL **new_ch)
735 {
736 QUIC_CHANNEL *ch;
737
738 /*
739 * If we're running with a simulated tserver, it will already have
740 * a dummy channel created, use that instead
741 */
742 if (port->tserver_ch != NULL) {
743 ch = port->tserver_ch;
744 port->tserver_ch = NULL;
745 ossl_quic_channel_bind_qrx(ch, qrx);
746 ossl_qrx_set_msg_callback(ch->qrx, ch->msg_callback,
747 ch->msg_callback_ssl);
748 ossl_qrx_set_msg_callback_arg(ch->qrx, ch->msg_callback_arg);
749 } else {
750 ch = port_make_channel(port, NULL, qrx, /* is_server= */ 1,
751 /* is_tserver */ 0);
752 }
753
754 if (ch == NULL)
755 return;
756
757 /*
758 * If we didn't provide a qrx here that means we need to set our initial
759 * secret here, since we just created a qrx
760 * Normally its not needed, as the initial secret gets added when we send
761 * our first server hello, but if we get a huge client hello, crossing
762 * multiple datagrams, we don't have a chance to do that, and datagrams
763 * after the first won't get decoded properly, for lack of secrets
764 */
765 if (qrx == NULL)
766 if (!ossl_quic_provide_initial_secret(ch->port->engine->libctx,
767 ch->port->engine->propq,
768 dcid, /* is_server */ 1,
769 ch->qrx, NULL))
770 return;
771
772 if (odcid->id_len != 0) {
773 /*
774 * If we have an odcid, then we went through server address validation
775 * and as such, this channel need not conform to the 3x validation cap
776 * See RFC 9000 s. 8.1
777 */
778 ossl_quic_tx_packetiser_set_validated(ch->txp);
779 if (!ossl_quic_bind_channel(ch, peer, scid, dcid, odcid)) {
780 ossl_quic_channel_free(ch);
781 return;
782 }
783 } else {
784 /*
785 * No odcid means we didn't do server validation, so we need to
786 * generate a cid via ossl_quic_channel_on_new_conn
787 */
788 if (!ossl_quic_channel_on_new_conn(ch, peer, scid, dcid)) {
789 ossl_quic_channel_free(ch);
790 return;
791 }
792 }
793
794 ossl_list_incoming_ch_insert_tail(&port->incoming_channel_list, ch);
795 *new_ch = ch;
796 }
797
port_try_handle_stateless_reset(QUIC_PORT * port,const QUIC_URXE * e)798 static int port_try_handle_stateless_reset(QUIC_PORT *port, const QUIC_URXE *e)
799 {
800 size_t i;
801 const unsigned char *data = ossl_quic_urxe_data(e);
802 void *opaque = NULL;
803
804 /*
805 * Perform some fast and cheap checks for a packet not being a stateless
806 * reset token. RFC 9000 s. 10.3 specifies this layout for stateless
807 * reset packets:
808 *
809 * Stateless Reset {
810 * Fixed Bits (2) = 1,
811 * Unpredictable Bits (38..),
812 * Stateless Reset Token (128),
813 * }
814 *
815 * It also specifies:
816 * However, endpoints MUST treat any packet ending in a valid
817 * stateless reset token as a Stateless Reset, as other QUIC
818 * versions might allow the use of a long header.
819 *
820 * We can rapidly check for the minimum length and that the first pair
821 * of bits in the first byte are 01 or 11.
822 *
823 * The function returns 1 if it is a stateless reset packet, 0 if it isn't
824 * and -1 if an error was encountered.
825 */
826 if (e->data_len < QUIC_STATELESS_RESET_TOKEN_LEN + 5
827 || (0100 & *data) != 0100)
828 return 0;
829
830 for (i = 0;; ++i) {
831 if (!ossl_quic_srtm_lookup(port->srtm,
832 (QUIC_STATELESS_RESET_TOKEN *)(data + e->data_len
833 - sizeof(QUIC_STATELESS_RESET_TOKEN)),
834 i, &opaque, NULL))
835 break;
836
837 assert(opaque != NULL);
838 ossl_quic_channel_on_stateless_reset((QUIC_CHANNEL *)opaque);
839 }
840
841 return i > 0;
842 }
843
cleanup_validation_token(QUIC_VALIDATION_TOKEN * token)844 static void cleanup_validation_token(QUIC_VALIDATION_TOKEN *token)
845 {
846 OPENSSL_free(token->remote_addr);
847 }
848
849 /**
850 * @brief Generates a validation token for a RETRY/NEW_TOKEN packet.
851 *
852 *
853 * @param peer Address of the client peer receiving the packet.
854 * @param odcid DCID of the connection attempt.
855 * @param rscid Retry source connection ID of the connection attempt.
856 * @param token Address of token to fill data.
857 *
858 * @return 1 if validation token is filled successfully, 0 otherwise.
859 */
generate_token(BIO_ADDR * peer,QUIC_CONN_ID odcid,QUIC_CONN_ID rscid,QUIC_VALIDATION_TOKEN * token,int is_retry)860 static int generate_token(BIO_ADDR *peer, QUIC_CONN_ID odcid,
861 QUIC_CONN_ID rscid, QUIC_VALIDATION_TOKEN *token,
862 int is_retry)
863 {
864 token->is_retry = is_retry;
865 token->timestamp = ossl_time_now();
866 token->remote_addr = NULL;
867 token->odcid = odcid;
868 token->rscid = rscid;
869
870 if (!BIO_ADDR_rawaddress(peer, NULL, &token->remote_addr_len)
871 || token->remote_addr_len == 0
872 || (token->remote_addr = OPENSSL_malloc(token->remote_addr_len)) == NULL
873 || !BIO_ADDR_rawaddress(peer, token->remote_addr,
874 &token->remote_addr_len)) {
875 cleanup_validation_token(token);
876 return 0;
877 }
878
879 return 1;
880 }
881
882 /**
883 * @brief Marshals a validation token into a new buffer.
884 *
885 * |buffer| should already be allocated and at least MARSHALLED_TOKEN_MAX_LEN
886 * bytes long. Stores the length of data stored in |buffer| in |buffer_len|.
887 *
888 * @param token Validation token.
889 * @param buffer Address to store the marshalled token.
890 * @param buffer_len Size of data stored in |buffer|.
891 */
marshal_validation_token(QUIC_VALIDATION_TOKEN * token,unsigned char * buffer,size_t * buffer_len)892 static int marshal_validation_token(QUIC_VALIDATION_TOKEN *token,
893 unsigned char *buffer, size_t *buffer_len)
894 {
895 WPACKET wpkt = { 0 };
896 BUF_MEM *buf_mem = BUF_MEM_new();
897
898 if (buffer == NULL || buf_mem == NULL
899 || (token->is_retry != 0 && token->is_retry != 1)) {
900 BUF_MEM_free(buf_mem);
901 return 0;
902 }
903
904 if (!WPACKET_init(&wpkt, buf_mem)
905 || !WPACKET_memset(&wpkt, token->is_retry, 1)
906 || !WPACKET_memcpy(&wpkt, &token->timestamp,
907 sizeof(token->timestamp))
908 || (token->is_retry
909 && (!WPACKET_sub_memcpy_u8(&wpkt, &token->odcid.id,
910 token->odcid.id_len)
911 || !WPACKET_sub_memcpy_u8(&wpkt, &token->rscid.id,
912 token->rscid.id_len)))
913 || !WPACKET_sub_memcpy_u8(&wpkt, token->remote_addr, token->remote_addr_len)
914 || !WPACKET_get_total_written(&wpkt, buffer_len)
915 || *buffer_len > MARSHALLED_TOKEN_MAX_LEN
916 || !WPACKET_finish(&wpkt)) {
917 WPACKET_cleanup(&wpkt);
918 BUF_MEM_free(buf_mem);
919 return 0;
920 }
921
922 memcpy(buffer, buf_mem->data, *buffer_len);
923 BUF_MEM_free(buf_mem);
924 return 1;
925 }
926
927 /**
928 * @brief Encrypts a validation token using AES-256-GCM
929 *
930 * @param port The QUIC port containing the encryption key
931 * @param plaintext The data to encrypt
932 * @param pt_len Length of the plaintext
933 * @param ciphertext Buffer to receive encrypted data. If NULL, ct_len will be
934 * set to the required buffer size and function returns
935 * immediately.
936 * @param ct_len Pointer to size_t that will receive the ciphertext length.
937 * This also includes bytes for QUIC_RETRY_INTEGRITY_TAG_LEN.
938 *
939 * @return 1 on success, 0 on failure
940 *
941 * The ciphertext format is:
942 * [EVP_GCM_IV_LEN bytes IV][encrypted data][EVP_GCM_TAG_LEN bytes tag]
943 */
encrypt_validation_token(const QUIC_PORT * port,const unsigned char * plaintext,size_t pt_len,unsigned char * ciphertext,size_t * ct_len)944 static int encrypt_validation_token(const QUIC_PORT *port,
945 const unsigned char *plaintext,
946 size_t pt_len,
947 unsigned char *ciphertext,
948 size_t *ct_len)
949 {
950 int iv_len, len, ret = 0;
951 size_t tag_len;
952 unsigned char *iv = ciphertext, *data, *tag;
953
954 if ((tag_len = EVP_CIPHER_CTX_get_tag_length(port->token_ctx)) == 0
955 || (iv_len = EVP_CIPHER_CTX_get_iv_length(port->token_ctx)) <= 0)
956 goto err;
957
958 *ct_len = iv_len + pt_len + tag_len + QUIC_RETRY_INTEGRITY_TAG_LEN;
959 if (ciphertext == NULL) {
960 ret = 1;
961 goto err;
962 }
963
964 data = ciphertext + iv_len;
965 tag = data + pt_len;
966
967 if (!RAND_bytes_ex(port->engine->libctx, ciphertext, iv_len, 0)
968 || !EVP_EncryptInit_ex(port->token_ctx, NULL, NULL, NULL, iv)
969 || !EVP_EncryptUpdate(port->token_ctx, data, &len, plaintext, pt_len)
970 || !EVP_EncryptFinal_ex(port->token_ctx, data + pt_len, &len)
971 || !EVP_CIPHER_CTX_ctrl(port->token_ctx, EVP_CTRL_GCM_GET_TAG, tag_len, tag))
972 goto err;
973
974 ret = 1;
975 err:
976 return ret;
977 }
978
979 /**
980 * @brief Decrypts a validation token using AES-256-GCM
981 *
982 * @param port The QUIC port containing the decryption key
983 * @param ciphertext The encrypted data (including IV and tag)
984 * @param ct_len Length of the ciphertext
985 * @param plaintext Buffer to receive decrypted data. If NULL, pt_len will be
986 * set to the required buffer size.
987 * @param pt_len Pointer to size_t that will receive the plaintext length
988 *
989 * @return 1 on success, 0 on failure
990 *
991 * Expected ciphertext format:
992 * [EVP_GCM_IV_LEN bytes IV][encrypted data][EVP_GCM_TAG_LEN bytes tag]
993 */
decrypt_validation_token(const QUIC_PORT * port,const unsigned char * ciphertext,size_t ct_len,unsigned char * plaintext,size_t * pt_len)994 static int decrypt_validation_token(const QUIC_PORT *port,
995 const unsigned char *ciphertext,
996 size_t ct_len,
997 unsigned char *plaintext,
998 size_t *pt_len)
999 {
1000 int iv_len, len = 0, ret = 0;
1001 size_t tag_len;
1002 const unsigned char *iv = ciphertext, *data, *tag;
1003
1004 if ((tag_len = EVP_CIPHER_CTX_get_tag_length(port->token_ctx)) == 0
1005 || (iv_len = EVP_CIPHER_CTX_get_iv_length(port->token_ctx)) <= 0)
1006 goto err;
1007
1008 /* Prevent decryption of a buffer that is not within reasonable bounds */
1009 if (ct_len < (iv_len + tag_len) || ct_len > ENCRYPTED_TOKEN_MAX_LEN)
1010 goto err;
1011
1012 *pt_len = ct_len - iv_len - tag_len;
1013 if (plaintext == NULL) {
1014 ret = 1;
1015 goto err;
1016 }
1017
1018 data = ciphertext + iv_len;
1019 tag = ciphertext + ct_len - tag_len;
1020
1021 if (!EVP_DecryptInit_ex(port->token_ctx, NULL, NULL, NULL, iv)
1022 || !EVP_DecryptUpdate(port->token_ctx, plaintext, &len, data,
1023 ct_len - iv_len - tag_len)
1024 || !EVP_CIPHER_CTX_ctrl(port->token_ctx, EVP_CTRL_GCM_SET_TAG, tag_len,
1025 (void *)tag)
1026 || !EVP_DecryptFinal_ex(port->token_ctx, plaintext + len, &len))
1027 goto err;
1028
1029 ret = 1;
1030
1031 err:
1032 return ret;
1033 }
1034
1035 /**
1036 * @brief Parses contents of a buffer into a validation token.
1037 *
1038 * VALIDATION_TOKEN should already be initialized. Does some basic sanity checks.
1039 *
1040 * @param token Validation token to fill data in.
1041 * @param buf Buffer of previously marshaled validation token.
1042 * @param buf_len Length of |buf|.
1043 */
parse_validation_token(QUIC_VALIDATION_TOKEN * token,const unsigned char * buf,size_t buf_len)1044 static int parse_validation_token(QUIC_VALIDATION_TOKEN *token,
1045 const unsigned char *buf, size_t buf_len)
1046 {
1047 PACKET pkt, subpkt;
1048
1049 if (buf == NULL || token == NULL)
1050 return 0;
1051
1052 token->remote_addr = NULL;
1053
1054 if (!PACKET_buf_init(&pkt, buf, buf_len)
1055 || !PACKET_copy_bytes(&pkt, &token->is_retry, sizeof(token->is_retry))
1056 || !(token->is_retry == 0 || token->is_retry == 1)
1057 || !PACKET_copy_bytes(&pkt, (unsigned char *)&token->timestamp,
1058 sizeof(token->timestamp))
1059 || (token->is_retry
1060 && (!PACKET_get_length_prefixed_1(&pkt, &subpkt)
1061 || (token->odcid.id_len = (unsigned char)PACKET_remaining(&subpkt))
1062 > QUIC_MAX_CONN_ID_LEN
1063 || !PACKET_copy_bytes(&subpkt,
1064 (unsigned char *)&token->odcid.id,
1065 token->odcid.id_len)
1066 || !PACKET_get_length_prefixed_1(&pkt, &subpkt)
1067 || (token->rscid.id_len = (unsigned char)PACKET_remaining(&subpkt))
1068 > QUIC_MAX_CONN_ID_LEN
1069 || !PACKET_copy_bytes(&subpkt, (unsigned char *)&token->rscid.id,
1070 token->rscid.id_len)))
1071 || !PACKET_get_length_prefixed_1(&pkt, &subpkt)
1072 || (token->remote_addr_len = PACKET_remaining(&subpkt)) == 0
1073 || (token->remote_addr = OPENSSL_malloc(token->remote_addr_len)) == NULL
1074 || !PACKET_copy_bytes(&subpkt, token->remote_addr, token->remote_addr_len)
1075 || PACKET_remaining(&pkt) != 0) {
1076 cleanup_validation_token(token);
1077 return 0;
1078 }
1079
1080 return 1;
1081 }
1082
1083 /**
1084 * @brief Sends a QUIC Retry packet to a client.
1085 *
1086 * This function constructs and sends a Retry packet to the specified client
1087 * using the provided connection header information. The Retry packet
1088 * includes a generated validation token and a new connection ID, following
1089 * the QUIC protocol specifications for connection establishment.
1090 *
1091 * @param port Pointer to the QUIC port from which to send the packet.
1092 * @param peer Address of the client peer receiving the packet.
1093 * @param client_hdr Header of the client's initial packet, containing
1094 * connection IDs and other relevant information.
1095 *
1096 * This function performs the following steps:
1097 * - Generates a validation token for the client.
1098 * - Sets the destination and source connection IDs.
1099 * - Calculates the integrity tag and sets the token length.
1100 * - Encodes and sends the packet via the BIO network interface.
1101 *
1102 * Error handling is included for failures in CID generation, encoding, and
1103 * network transmiss
1104 */
port_send_retry(QUIC_PORT * port,BIO_ADDR * peer,QUIC_PKT_HDR * client_hdr)1105 static void port_send_retry(QUIC_PORT *port,
1106 BIO_ADDR *peer,
1107 QUIC_PKT_HDR *client_hdr)
1108 {
1109 BIO_MSG msg[1];
1110 /*
1111 * Buffer is used for both marshalling the token as well as for the RETRY
1112 * packet. The size of buffer should not be less than
1113 * MARSHALLED_TOKEN_MAX_LEN.
1114 */
1115 unsigned char buffer[512];
1116 unsigned char ct_buf[ENCRYPTED_TOKEN_MAX_LEN];
1117 WPACKET wpkt;
1118 size_t written, token_buf_len, ct_len;
1119 QUIC_PKT_HDR hdr = { 0 };
1120 QUIC_VALIDATION_TOKEN token = { 0 };
1121 int ok;
1122
1123 if (!ossl_assert(sizeof(buffer) >= MARSHALLED_TOKEN_MAX_LEN))
1124 return;
1125 /*
1126 * 17.2.5.1 Sending a Retry packet
1127 * dst ConnId is src ConnId we got from client
1128 * src ConnId comes from local conn ID manager
1129 */
1130 memset(&hdr, 0, sizeof(QUIC_PKT_HDR));
1131 hdr.dst_conn_id = client_hdr->src_conn_id;
1132 /*
1133 * this is the random connection ID, we expect client is
1134 * going to send the ID with next INITIAL packet which
1135 * will also come with token we generate here.
1136 */
1137 ok = ossl_quic_lcidm_get_unused_cid(port->lcidm, &hdr.src_conn_id);
1138 if (ok == 0)
1139 goto err;
1140
1141 memset(&token, 0, sizeof(QUIC_VALIDATION_TOKEN));
1142
1143 /* Generate retry validation token */
1144 if (!generate_token(peer, client_hdr->dst_conn_id,
1145 hdr.src_conn_id, &token, 1)
1146 || !marshal_validation_token(&token, buffer, &token_buf_len)
1147 || !encrypt_validation_token(port, buffer, token_buf_len, NULL,
1148 &ct_len)
1149 || ct_len > ENCRYPTED_TOKEN_MAX_LEN
1150 || !encrypt_validation_token(port, buffer, token_buf_len, ct_buf,
1151 &ct_len)
1152 || !ossl_assert(ct_len >= QUIC_RETRY_INTEGRITY_TAG_LEN))
1153 goto err;
1154
1155 hdr.dst_conn_id = client_hdr->src_conn_id;
1156 hdr.type = QUIC_PKT_TYPE_RETRY;
1157 hdr.fixed = 1;
1158 hdr.version = 1;
1159 hdr.len = ct_len;
1160 hdr.data = ct_buf;
1161 ok = ossl_quic_calculate_retry_integrity_tag(port->engine->libctx,
1162 port->engine->propq, &hdr,
1163 &client_hdr->dst_conn_id,
1164 ct_buf + ct_len
1165 - QUIC_RETRY_INTEGRITY_TAG_LEN);
1166 if (ok == 0)
1167 goto err;
1168
1169 hdr.token = hdr.data;
1170 hdr.token_len = hdr.len;
1171
1172 msg[0].data = buffer;
1173 msg[0].peer = peer;
1174 msg[0].local = NULL;
1175 msg[0].flags = 0;
1176
1177 ok = WPACKET_init_static_len(&wpkt, buffer, sizeof(buffer), 0);
1178 if (ok == 0)
1179 goto err;
1180
1181 ok = ossl_quic_wire_encode_pkt_hdr(&wpkt, client_hdr->dst_conn_id.id_len,
1182 &hdr, NULL);
1183 if (ok == 0)
1184 goto err;
1185
1186 ok = WPACKET_get_total_written(&wpkt, &msg[0].data_len);
1187 if (ok == 0)
1188 goto err;
1189
1190 ok = WPACKET_finish(&wpkt);
1191 if (ok == 0)
1192 goto err;
1193
1194 /*
1195 * TODO(QUIC FUTURE) need to retry this in the event it return EAGAIN
1196 * on a non-blocking BIO
1197 */
1198 if (!BIO_sendmmsg(port->net_wbio, msg, sizeof(BIO_MSG), 1, 0, &written))
1199 ERR_raise_data(ERR_LIB_SSL, SSL_R_QUIC_NETWORK_ERROR,
1200 "port retry send failed due to network BIO I/O error");
1201
1202 err:
1203 cleanup_validation_token(&token);
1204 }
1205
1206 /**
1207 * @brief Sends a QUIC Version Negotiation packet to the specified peer.
1208 *
1209 * This function constructs and sends a Version Negotiation packet using
1210 * the connection IDs from the client's initial packet header. The
1211 * Version Negotiation packet indicates support for QUIC version 1.
1212 *
1213 * @param port Pointer to the QUIC_PORT structure representing the port
1214 * context used for network communication.
1215 * @param peer Pointer to the BIO_ADDR structure specifying the address
1216 * of the peer to which the Version Negotiation packet
1217 * will be sent.
1218 * @param client_hdr Pointer to the QUIC_PKT_HDR structure containing the
1219 * client's packet header used to extract connection IDs.
1220 *
1221 * @note The function will raise an error if sending the message fails.
1222 */
port_send_version_negotiation(QUIC_PORT * port,BIO_ADDR * peer,QUIC_PKT_HDR * client_hdr)1223 static void port_send_version_negotiation(QUIC_PORT *port, BIO_ADDR *peer,
1224 QUIC_PKT_HDR *client_hdr)
1225 {
1226 BIO_MSG msg[1];
1227 unsigned char buffer[1024];
1228 QUIC_PKT_HDR hdr;
1229 WPACKET wpkt;
1230 uint32_t supported_versions[1];
1231 size_t written;
1232 size_t i;
1233
1234 memset(&hdr, 0, sizeof(QUIC_PKT_HDR));
1235 /*
1236 * Reverse the source and dst conn ids
1237 */
1238 hdr.dst_conn_id = client_hdr->src_conn_id;
1239 hdr.src_conn_id = client_hdr->dst_conn_id;
1240
1241 /*
1242 * This is our list of supported protocol versions
1243 * Currently only QUIC_VERSION_1
1244 */
1245 supported_versions[0] = QUIC_VERSION_1;
1246
1247 /*
1248 * Fill out the header fields
1249 * Note: Version negotiation packets, must, unlike
1250 * other packet types have a version of 0
1251 */
1252 hdr.type = QUIC_PKT_TYPE_VERSION_NEG;
1253 hdr.version = 0;
1254 hdr.token = 0;
1255 hdr.token_len = 0;
1256 hdr.len = sizeof(supported_versions);
1257 hdr.data = (unsigned char *)supported_versions;
1258
1259 msg[0].data = buffer;
1260 msg[0].peer = peer;
1261 msg[0].local = NULL;
1262 msg[0].flags = 0;
1263
1264 if (!WPACKET_init_static_len(&wpkt, buffer, sizeof(buffer), 0))
1265 return;
1266
1267 if (!ossl_quic_wire_encode_pkt_hdr(&wpkt, client_hdr->dst_conn_id.id_len,
1268 &hdr, NULL))
1269 return;
1270
1271 /*
1272 * Add the array of supported versions to the end of the packet
1273 */
1274 for (i = 0; i < OSSL_NELEM(supported_versions); i++) {
1275 if (!WPACKET_put_bytes_u32(&wpkt, supported_versions[i]))
1276 return;
1277 }
1278
1279 if (!WPACKET_get_total_written(&wpkt, &msg[0].data_len))
1280 return;
1281
1282 if (!WPACKET_finish(&wpkt))
1283 return;
1284
1285 /*
1286 * Send it back to the client attempting to connect
1287 * TODO(QUIC FUTURE): Need to handle the EAGAIN case here, if the
1288 * BIO_sendmmsg call falls in a retryable manner
1289 */
1290 if (!BIO_sendmmsg(port->net_wbio, msg, sizeof(BIO_MSG), 1, 0, &written))
1291 ERR_raise_data(ERR_LIB_SSL, SSL_R_QUIC_NETWORK_ERROR,
1292 "port version negotiation send failed");
1293 }
1294
1295 /**
1296 * @brief definitions of token lifetimes
1297 *
1298 * RETRY tokens are only valid for 10 seconds
1299 * NEW_TOKEN tokens have a lifetime of 3600 sec (1 hour)
1300 */
1301
1302 #define RETRY_LIFETIME 10
1303 #define NEW_TOKEN_LIFETIME 3600
1304 /**
1305 * @brief Validates a received token in a QUIC packet header.
1306 *
1307 * This function checks the validity of a token contained in the provided
1308 * QUIC packet header (`QUIC_PKT_HDR *hdr`). The validation process involves
1309 * verifying that the token matches an expected format and value. If the
1310 * token is from a RETRY packet, the function extracts the original connection
1311 * ID (ODCID)/original source connection ID (SCID) and stores it in the provided
1312 * parameters. If the token is from a NEW_TOKEN packet, the values will be
1313 * derived instead.
1314 *
1315 * @param hdr Pointer to the QUIC packet header containing the token.
1316 * @param port Pointer to the QUIC port from which to send the packet.
1317 * @param peer Address of the client peer receiving the packet.
1318 * @param odcid Pointer to the connection ID structure to store the ODCID if the
1319 * token is valid.
1320 * @param scid Pointer to the connection ID structure to store the SCID if the
1321 * token is valid.
1322 *
1323 * @return 1 if the token is valid and ODCID/SCID are successfully set.
1324 * 0 otherwise.
1325 *
1326 * The function performs the following checks:
1327 * - Token length meets the required minimum.
1328 * - Buffer matches expected format.
1329 * - Peer address matches previous connection address.
1330 * - Token has not expired. Currently set to 10 seconds for tokens from RETRY
1331 * packets and 60 minutes for tokens from NEW_TOKEN packets. This may be
1332 * configurable in the future.
1333 */
port_validate_token(QUIC_PKT_HDR * hdr,QUIC_PORT * port,BIO_ADDR * peer,QUIC_CONN_ID * odcid,QUIC_CONN_ID * scid,uint8_t * gen_new_token)1334 static int port_validate_token(QUIC_PKT_HDR *hdr, QUIC_PORT *port,
1335 BIO_ADDR *peer, QUIC_CONN_ID *odcid,
1336 QUIC_CONN_ID *scid, uint8_t *gen_new_token)
1337 {
1338 int ret = 0;
1339 QUIC_VALIDATION_TOKEN token = { 0 };
1340 uint64_t time_diff;
1341 size_t remote_addr_len, dec_token_len;
1342 unsigned char *remote_addr = NULL, dec_token[MARSHALLED_TOKEN_MAX_LEN];
1343 OSSL_TIME now = ossl_time_now();
1344
1345 *gen_new_token = 0;
1346
1347 if (!decrypt_validation_token(port, hdr->token, hdr->token_len, NULL,
1348 &dec_token_len)
1349 || dec_token_len > MARSHALLED_TOKEN_MAX_LEN
1350 || !decrypt_validation_token(port, hdr->token, hdr->token_len,
1351 dec_token, &dec_token_len)
1352 || !parse_validation_token(&token, dec_token, dec_token_len))
1353 goto err;
1354
1355 /*
1356 * Validate token timestamp. Current time should not be before the token
1357 * timestamp.
1358 */
1359 if (ossl_time_compare(now, token.timestamp) < 0)
1360 goto err;
1361 time_diff = ossl_time2seconds(ossl_time_abs_difference(token.timestamp,
1362 now));
1363 if ((token.is_retry && time_diff > RETRY_LIFETIME)
1364 || (!token.is_retry && time_diff > NEW_TOKEN_LIFETIME))
1365 goto err;
1366
1367 /* Validate remote address */
1368 if (!BIO_ADDR_rawaddress(peer, NULL, &remote_addr_len)
1369 || remote_addr_len != token.remote_addr_len
1370 || (remote_addr = OPENSSL_malloc(remote_addr_len)) == NULL
1371 || !BIO_ADDR_rawaddress(peer, remote_addr, &remote_addr_len)
1372 || memcmp(remote_addr, token.remote_addr, remote_addr_len) != 0)
1373 goto err;
1374
1375 /*
1376 * Set ODCID and SCID. If the token is from a RETRY packet, retrieve both
1377 * from the token. Otherwise, generate a new ODCID and use the header's
1378 * source connection ID for SCID.
1379 */
1380 if (token.is_retry) {
1381 /*
1382 * We're parsing a packet header before its gone through AEAD validation
1383 * here, so there is a chance we are dealing with corrupted data. Make
1384 * Sure the dcid encoded in the token matches the headers dcid to
1385 * mitigate that.
1386 * TODO(QUIC FUTURE): Consider handling AEAD validation at the port
1387 * level rather than the QRX/channel level to eliminate the need for
1388 * this.
1389 */
1390 if (token.rscid.id_len != hdr->dst_conn_id.id_len
1391 || memcmp(&token.rscid.id, &hdr->dst_conn_id.id,
1392 token.rscid.id_len)
1393 != 0)
1394 goto err;
1395 *odcid = token.odcid;
1396 *scid = token.rscid;
1397 } else {
1398 if (!ossl_quic_lcidm_get_unused_cid(port->lcidm, odcid))
1399 goto err;
1400 *scid = hdr->src_conn_id;
1401 }
1402
1403 /*
1404 * Determine if we need to send a NEW_TOKEN frame
1405 * If we validated a retry token, we should always
1406 * send a NEW_TOKEN frame to the client
1407 *
1408 * If however, we validated a NEW_TOKEN, which may be
1409 * reused multiple times, only send a NEW_TOKEN frame
1410 * if the existing received token has less than 10% of its lifetime
1411 * remaining. This prevents us from constantly sending
1412 * NEW_TOKEN frames on every connection when not needed
1413 */
1414 if (token.is_retry) {
1415 *gen_new_token = 1;
1416 } else {
1417 if (time_diff > ((NEW_TOKEN_LIFETIME * 9) / 10))
1418 *gen_new_token = 1;
1419 }
1420
1421 ret = 1;
1422 err:
1423 cleanup_validation_token(&token);
1424 OPENSSL_free(remote_addr);
1425 return ret;
1426 }
1427
generate_new_token(QUIC_CHANNEL * ch,BIO_ADDR * peer)1428 static void generate_new_token(QUIC_CHANNEL *ch, BIO_ADDR *peer)
1429 {
1430 QUIC_CONN_ID rscid = { 0 };
1431 QUIC_VALIDATION_TOKEN token;
1432 unsigned char buffer[ENCRYPTED_TOKEN_MAX_LEN];
1433 unsigned char *ct_buf;
1434 size_t ct_len;
1435 size_t token_buf_len = 0;
1436
1437 /* Clients never send a NEW_TOKEN */
1438 if (!ch->is_server)
1439 return;
1440
1441 ct_buf = OPENSSL_zalloc(ENCRYPTED_TOKEN_MAX_LEN);
1442 if (ct_buf == NULL)
1443 return;
1444
1445 /*
1446 * NEW_TOKEN tokens may be used for multiple subsequent connections
1447 * within their timeout period, so don't reserve an rscid here
1448 * like we do for retry tokens, instead, just fill it with random
1449 * data, as we won't use it anyway
1450 */
1451 rscid.id_len = 8;
1452 if (!RAND_bytes_ex(ch->port->engine->libctx, rscid.id, 8, 0)) {
1453 OPENSSL_free(ct_buf);
1454 return;
1455 }
1456
1457 memset(&token, 0, sizeof(QUIC_VALIDATION_TOKEN));
1458
1459 if (!generate_token(peer, ch->init_dcid, rscid, &token, 0)
1460 || !marshal_validation_token(&token, buffer, &token_buf_len)
1461 || !encrypt_validation_token(ch->port, buffer, token_buf_len, NULL,
1462 &ct_len)
1463 || ct_len > ENCRYPTED_TOKEN_MAX_LEN
1464 || !encrypt_validation_token(ch->port, buffer, token_buf_len, ct_buf,
1465 &ct_len)
1466 || !ossl_assert(ct_len >= QUIC_RETRY_INTEGRITY_TAG_LEN)) {
1467 OPENSSL_free(ct_buf);
1468 cleanup_validation_token(&token);
1469 return;
1470 }
1471
1472 ch->pending_new_token = ct_buf;
1473 ch->pending_new_token_len = ct_len;
1474
1475 cleanup_validation_token(&token);
1476 }
1477
1478 /*
1479 * This is called by the demux when we get a packet not destined for any known
1480 * DCID.
1481 */
port_default_packet_handler(QUIC_URXE * e,void * arg,const QUIC_CONN_ID * dcid)1482 static void port_default_packet_handler(QUIC_URXE *e, void *arg,
1483 const QUIC_CONN_ID *dcid)
1484 {
1485 QUIC_PORT *port = arg;
1486 PACKET pkt;
1487 QUIC_PKT_HDR hdr;
1488 QUIC_CHANNEL *ch = NULL, *new_ch = NULL;
1489 QUIC_CONN_ID odcid, scid;
1490 uint8_t gen_new_token = 0;
1491 OSSL_QRX *qrx = NULL;
1492 OSSL_QRX *qrx_src = NULL;
1493 OSSL_QRX_ARGS qrx_args = { 0 };
1494 uint64_t cause_flags = 0;
1495 OSSL_QRX_PKT *qrx_pkt = NULL;
1496
1497 /* Don't handle anything if we are no longer running. */
1498 if (!ossl_quic_port_is_running(port))
1499 goto undesirable;
1500
1501 if (port_try_handle_stateless_reset(port, e))
1502 goto undesirable;
1503
1504 if (dcid != NULL
1505 && ossl_quic_lcidm_lookup(port->lcidm, dcid, NULL,
1506 (void **)&ch)) {
1507 assert(ch != NULL);
1508 ossl_quic_channel_inject(ch, e);
1509 return;
1510 }
1511
1512 /*
1513 * If we have an incoming packet which doesn't match any existing connection
1514 * we assume this is an attempt to make a new connection.
1515 */
1516 if (!port->allow_incoming)
1517 goto undesirable;
1518
1519 /*
1520 * We have got a packet for an unknown DCID. This might be an attempt to
1521 * open a new connection.
1522 */
1523 if (e->data_len < QUIC_MIN_INITIAL_DGRAM_LEN)
1524 goto undesirable;
1525
1526 if (!PACKET_buf_init(&pkt, ossl_quic_urxe_data(e), e->data_len))
1527 goto undesirable;
1528
1529 /*
1530 * We set short_conn_id_len to SIZE_MAX here which will cause the decode
1531 * operation to fail if we get a 1-RTT packet. This is fine since we only
1532 * care about Initial packets.
1533 */
1534 if (!ossl_quic_wire_decode_pkt_hdr(&pkt, SIZE_MAX, 1, 0, &hdr, NULL,
1535 &cause_flags)) {
1536 /*
1537 * If we fail due to a bad version, we know the packet up to the version
1538 * number was decoded, and we use it below to send a version
1539 * negotiation packet
1540 */
1541 if ((cause_flags & QUIC_PKT_HDR_DECODE_BAD_VERSION) == 0)
1542 goto undesirable;
1543 }
1544
1545 switch (hdr.version) {
1546 case QUIC_VERSION_1:
1547 break;
1548
1549 case QUIC_VERSION_NONE:
1550 default:
1551
1552 /*
1553 * If we get here, then we have a bogus version, and might need
1554 * to send a version negotiation packet. According to
1555 * RFC 9000 s. 6 and 14.1, we only do so however, if the UDP datagram
1556 * is a minimum of 1200 bytes in size
1557 */
1558 if (e->data_len < 1200)
1559 goto undesirable;
1560
1561 /*
1562 * If we don't get a supported version, respond with a ver
1563 * negotiation packet, and discard
1564 * TODO(QUIC FUTURE): Rate limit the reception of these
1565 */
1566 port_send_version_negotiation(port, &e->peer, &hdr);
1567 goto undesirable;
1568 }
1569
1570 /*
1571 * We only care about Initial packets which might be trying to establish a
1572 * connection.
1573 */
1574 if (hdr.type != QUIC_PKT_TYPE_INITIAL)
1575 goto undesirable;
1576
1577 odcid.id_len = 0;
1578
1579 /*
1580 * Create qrx now so we can check integrity of packet
1581 * which does not belong to any channel.
1582 */
1583 qrx_args.libctx = port->engine->libctx;
1584 qrx_args.demux = port->demux;
1585 qrx_args.short_conn_id_len = dcid->id_len;
1586 qrx_args.max_deferred = 32;
1587 qrx = ossl_qrx_new(&qrx_args);
1588 if (qrx == NULL)
1589 goto undesirable;
1590
1591 /*
1592 * Derive secrets for qrx only.
1593 */
1594 if (!ossl_quic_provide_initial_secret(port->engine->libctx,
1595 port->engine->propq,
1596 &hdr.dst_conn_id,
1597 /* is_server */ 1,
1598 qrx, NULL))
1599 goto undesirable;
1600
1601 if (ossl_qrx_validate_initial_packet(qrx, e, (const QUIC_CONN_ID *)dcid) == 0)
1602 goto undesirable;
1603
1604 if (port->validate_addr == 0) {
1605 /*
1606 * Forget qrx, because it becomes (almost) useless here. We must let
1607 * channel to create a new QRX for connection ID server chooses. The
1608 * validation keys for new DCID will be derived by
1609 * ossl_quic_channel_on_new_conn() when we will be creating channel.
1610 * See RFC 9000 section 7.2 negotiating connection id to better
1611 * understand what's going on here.
1612 *
1613 * Did we say qrx is almost useless? Why? Because qrx remembers packets
1614 * we just validated. Those packets must be injected to channel we are
1615 * going to create. We use qrx_src alias so we can read packets from
1616 * qrx and inject them to channel.
1617 */
1618 qrx_src = qrx;
1619 qrx = NULL;
1620 }
1621 /*
1622 * TODO(QUIC FUTURE): there should be some logic similar to accounting half-open
1623 * states in TCP. If we reach certain threshold, then we want to
1624 * validate clients.
1625 */
1626 if (port->validate_addr == 1 && hdr.token == NULL) {
1627 port_send_retry(port, &e->peer, &hdr);
1628 goto undesirable;
1629 }
1630
1631 /*
1632 * Note, even if we don't enforce the sending of retry frames for
1633 * server address validation, we may still get a token if we sent
1634 * a NEW_TOKEN frame during a prior connection, which we should still
1635 * validate here
1636 */
1637 if (hdr.token != NULL
1638 && port_validate_token(&hdr, port, &e->peer,
1639 &odcid, &scid,
1640 &gen_new_token)
1641 == 0) {
1642 /*
1643 * RFC 9000 s 8.1.3
1644 * When a server receives an Initial packet with an address
1645 * validation token, it MUST attempt to validate the token,
1646 * unless it has already completed address validation.
1647 * If the token is invalid, then the server SHOULD proceed as
1648 * if the client did not have a validated address,
1649 * including potentially sending a Retry packet
1650 * Note: If address validation is disabled, just act like
1651 * the request is valid
1652 */
1653 if (port->validate_addr == 1) {
1654 /*
1655 * Again: we should consider saving initial encryption level
1656 * secrets to token here to save some CPU cycles.
1657 */
1658 port_send_retry(port, &e->peer, &hdr);
1659 goto undesirable;
1660 }
1661
1662 /*
1663 * client is under amplification limit, until it completes
1664 * handshake.
1665 *
1666 * forget qrx so channel can create a new one
1667 * with valid initial encryption level keys.
1668 */
1669 qrx_src = qrx;
1670 qrx = NULL;
1671 }
1672
1673 port_bind_channel(port, &e->peer, &scid, &hdr.dst_conn_id,
1674 &odcid, qrx, &new_ch);
1675
1676 /*
1677 * if packet validates it gets moved to channel, we've just bound
1678 * to port.
1679 */
1680 if (new_ch == NULL)
1681 goto undesirable;
1682
1683 /*
1684 * Generate a token for sending in a later NEW_TOKEN frame
1685 */
1686 if (gen_new_token == 1)
1687 generate_new_token(new_ch, &e->peer);
1688
1689 if (qrx != NULL) {
1690 /*
1691 * The qrx belongs to channel now, so don't free it.
1692 */
1693 qrx = NULL;
1694 } else {
1695 /*
1696 * We still need to salvage packets from almost forgotten qrx
1697 * and pass them to channel.
1698 */
1699 while (ossl_qrx_read_pkt(qrx_src, &qrx_pkt) == 1)
1700 ossl_quic_channel_inject_pkt(new_ch, qrx_pkt);
1701 ossl_qrx_update_pn_space(qrx_src, new_ch->qrx);
1702 }
1703
1704 /*
1705 * If function reaches this place, then packet got validated in
1706 * ossl_qrx_validate_initial_packet(). Keep in mind the function
1707 * ossl_qrx_validate_initial_packet() decrypts the packet to validate it.
1708 * If packet validation was successful (and it was because we are here),
1709 * then the function puts the packet to qrx->rx_pending. We must not call
1710 * ossl_qrx_inject_urxe() here now, because we don't want to insert
1711 * the packet to qrx->urx_pending which keeps packet waiting for decryption.
1712 *
1713 * We are going to call ossl_quic_demux_release_urxe() to dispose buffer
1714 * which still holds encrypted data.
1715 */
1716
1717 undesirable:
1718 ossl_qrx_free(qrx);
1719 ossl_qrx_free(qrx_src);
1720 ossl_quic_demux_release_urxe(port->demux, e);
1721 }
1722
ossl_quic_port_raise_net_error(QUIC_PORT * port,QUIC_CHANNEL * triggering_ch)1723 void ossl_quic_port_raise_net_error(QUIC_PORT *port,
1724 QUIC_CHANNEL *triggering_ch)
1725 {
1726 QUIC_CHANNEL *ch;
1727
1728 if (!ossl_quic_port_is_running(port))
1729 return;
1730
1731 /*
1732 * Immediately capture any triggering error on the error stack, with a
1733 * cover error.
1734 */
1735 ERR_raise_data(ERR_LIB_SSL, SSL_R_QUIC_NETWORK_ERROR,
1736 "port failed due to network BIO I/O error");
1737 OSSL_ERR_STATE_save(port->err_state);
1738
1739 port_transition_failed(port);
1740
1741 /* Give the triggering channel (if any) the first notification. */
1742 if (triggering_ch != NULL)
1743 ossl_quic_channel_raise_net_error(triggering_ch);
1744
1745 OSSL_LIST_FOREACH(ch, ch, &port->channel_list)
1746 if (ch != triggering_ch)
1747 ossl_quic_channel_raise_net_error(ch);
1748 }
1749
ossl_quic_port_restore_err_state(const QUIC_PORT * port)1750 void ossl_quic_port_restore_err_state(const QUIC_PORT *port)
1751 {
1752 ERR_clear_error();
1753 OSSL_ERR_STATE_restore(port->err_state);
1754 }
1755