Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/openssl/ssl/quic/quic_port.c
108777 views
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
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
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
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
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
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
227
int ossl_quic_port_is_running(const QUIC_PORT *port)
228
{
229
return port->state == QUIC_PORT_STATE_RUNNING;
230
}
231
232
QUIC_ENGINE *ossl_quic_port_get0_engine(QUIC_PORT *port)
233
{
234
return port->engine;
235
}
236
237
QUIC_REACTOR *ossl_quic_port_get0_reactor(QUIC_PORT *port)
238
{
239
return ossl_quic_engine_get0_reactor(port->engine);
240
}
241
242
QUIC_DEMUX *ossl_quic_port_get0_demux(QUIC_PORT *port)
243
{
244
return port->demux;
245
}
246
247
CRYPTO_MUTEX *ossl_quic_port_get0_mutex(QUIC_PORT *port)
248
{
249
return ossl_quic_engine_get0_mutex(port->engine);
250
}
251
252
OSSL_TIME ossl_quic_port_get_time(QUIC_PORT *port)
253
{
254
return ossl_quic_engine_get_time(port->engine);
255
}
256
257
static OSSL_TIME get_time(void *port)
258
{
259
return ossl_quic_port_get_time((QUIC_PORT *)port);
260
}
261
262
int ossl_quic_port_get_rx_short_dcid_len(const QUIC_PORT *port)
263
{
264
return port->rx_short_dcid_len;
265
}
266
267
int ossl_quic_port_get_tx_init_dcid_len(const QUIC_PORT *port)
268
{
269
return port->tx_init_dcid_len;
270
}
271
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. */
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
293
BIO *ossl_quic_port_get_net_rbio(QUIC_PORT *port)
294
{
295
return port->net_rbio;
296
}
297
298
BIO *ossl_quic_port_get_net_wbio(QUIC_PORT *port)
299
{
300
return port->net_wbio;
301
}
302
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
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
*/
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
394
int ossl_quic_port_is_addressed_r(const QUIC_PORT *port)
395
{
396
return port->addressed_mode_r;
397
}
398
399
int ossl_quic_port_is_addressed_w(const QUIC_PORT *port)
400
{
401
return port->addressed_mode_w;
402
}
403
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
*/
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
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
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
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
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
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
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
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
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
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
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
*/
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. */
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
*/
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
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
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
*/
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
*/
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
*/
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
*/
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
*/
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
*/
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
*/
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
*/
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
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
*/
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
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
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
1756