]> git.ipfire.org Git - thirdparty/openssl.git/blob - test/helpers/quictestlib.c
Remove accidentally left debug statements from ec.c
[thirdparty/openssl.git] / test / helpers / quictestlib.c
1 /*
2 * Copyright 2022-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 <assert.h>
11 #include <openssl/configuration.h>
12 #include <openssl/bio.h>
13 #include "internal/e_os.h" /* For struct timeval */
14 #include "quictestlib.h"
15 #include "ssltestlib.h"
16 #include "../testutil.h"
17 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
18 # include "../threadstest.h"
19 #endif
20 #include "internal/quic_ssl.h"
21 #include "internal/quic_wire_pkt.h"
22 #include "internal/quic_record_tx.h"
23 #include "internal/quic_error.h"
24 #include "internal/packet.h"
25 #include "internal/tsan_assist.h"
26
27 #define GROWTH_ALLOWANCE 1024
28
29 struct noise_args_data_st {
30 BIO *cbio;
31 BIO *sbio;
32 BIO *tracebio;
33 int flags;
34 };
35
36 struct qtest_fault {
37 QUIC_TSERVER *qtserv;
38
39 /* Plain packet mutations */
40 /* Header for the plaintext packet */
41 QUIC_PKT_HDR pplainhdr;
42 /* iovec for the plaintext packet data buffer */
43 OSSL_QTX_IOVEC pplainio;
44 /* Allocated size of the plaintext packet data buffer */
45 size_t pplainbuf_alloc;
46 qtest_fault_on_packet_plain_cb pplaincb;
47 void *pplaincbarg;
48
49 /* Handshake message mutations */
50 /* Handshake message buffer */
51 unsigned char *handbuf;
52 /* Allocated size of the handshake message buffer */
53 size_t handbufalloc;
54 /* Actual length of the handshake message */
55 size_t handbuflen;
56 qtest_fault_on_handshake_cb handshakecb;
57 void *handshakecbarg;
58 qtest_fault_on_enc_ext_cb encextcb;
59 void *encextcbarg;
60
61 /* Cipher packet mutations */
62 qtest_fault_on_packet_cipher_cb pciphercb;
63 void *pciphercbarg;
64
65 /* Datagram mutations */
66 qtest_fault_on_datagram_cb datagramcb;
67 void *datagramcbarg;
68 /* The currently processed message */
69 BIO_MSG msg;
70 /* Allocated size of msg data buffer */
71 size_t msgalloc;
72 struct noise_args_data_st noiseargs;
73 };
74
75 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
76 static int client_ready = 0;
77 static CRYPTO_CONDVAR *client_ready_cond = NULL;
78 static CRYPTO_MUTEX *client_ready_mutex = NULL;
79 #endif
80
81 static void packet_plain_finish(void *arg);
82 static void handshake_finish(void *arg);
83 static OSSL_TIME qtest_get_time(void);
84 static void qtest_reset_time(void);
85
86 static int using_fake_time = 0;
87 static OSSL_TIME fake_now;
88 static CRYPTO_RWLOCK *fake_now_lock = NULL;
89 static OSSL_TIME start_time;
90
91 static OSSL_TIME fake_now_cb(void *arg)
92 {
93 return qtest_get_time();
94 }
95
96 static void noise_msg_callback(int write_p, int version, int content_type,
97 const void *buf, size_t len, SSL *ssl,
98 void *arg)
99 {
100 struct noise_args_data_st *noiseargs = (struct noise_args_data_st *)arg;
101
102 if (content_type == SSL3_RT_QUIC_FRAME_FULL) {
103 PACKET pkt;
104 uint64_t frame_type;
105
106 if (!PACKET_buf_init(&pkt, buf, len))
107 return;
108
109 if (!ossl_quic_wire_peek_frame_header(&pkt, &frame_type, NULL))
110 return;
111
112 if (frame_type == OSSL_QUIC_FRAME_TYPE_PING) {
113 /*
114 * If either endpoint issues a ping frame then we are in danger
115 * of our noise being too much such that the connection itself
116 * fails. We back off on the noise for a bit to avoid that.
117 */
118 (void)BIO_ctrl(noiseargs->cbio, BIO_CTRL_NOISE_BACK_OFF, 1, NULL);
119 (void)BIO_ctrl(noiseargs->sbio, BIO_CTRL_NOISE_BACK_OFF, 1, NULL);
120 }
121 }
122
123 #ifndef OPENSSL_NO_SSL_TRACE
124 if ((noiseargs->flags & QTEST_FLAG_CLIENT_TRACE) != 0
125 && !SSL_is_server(ssl))
126 SSL_trace(write_p, version, content_type, buf, len, ssl,
127 noiseargs->tracebio);
128 #endif
129 }
130
131 int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx,
132 SSL_CTX *serverctx, char *certfile, char *keyfile,
133 int flags, QUIC_TSERVER **qtserv, SSL **cssl,
134 QTEST_FAULT **fault, BIO **tracebio)
135 {
136 /* ALPN value as recognised by QUIC_TSERVER */
137 unsigned char alpn[] = { 8, 'o', 's', 's', 'l', 't', 'e', 's', 't' };
138 QUIC_TSERVER_ARGS tserver_args = {0};
139 BIO *cbio = NULL, *sbio = NULL, *fisbio = NULL;
140 BIO_ADDR *peeraddr = NULL;
141 struct in_addr ina = {0};
142 BIO *tmpbio = NULL;
143 QTEST_DATA *bdata = NULL;
144
145 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
146 if (client_ready_cond == NULL) {
147 client_ready_cond = ossl_crypto_condvar_new();
148 if (client_ready_cond == NULL)
149 return 0;
150 }
151
152 if (client_ready_mutex == NULL) {
153 client_ready_mutex = ossl_crypto_mutex_new();
154 if (client_ready_mutex == NULL) {
155 ossl_crypto_condvar_free(&client_ready_cond);
156 client_ready_cond = NULL;
157 return 0;
158 }
159 }
160 #endif
161
162 bdata = OPENSSL_zalloc(sizeof(QTEST_DATA));
163 if (bdata == NULL)
164 return 0;
165
166 *qtserv = NULL;
167
168 if (fault != NULL) {
169 *fault = OPENSSL_zalloc(sizeof(**fault));
170 if (*fault == NULL)
171 goto err;
172 bdata->fault = *fault;
173 }
174
175 if (*cssl == NULL) {
176 *cssl = SSL_new(clientctx);
177 if (!TEST_ptr(*cssl))
178 goto err;
179 }
180
181 #ifndef OPENSSL_NO_SSL_TRACE
182 if ((flags & QTEST_FLAG_CLIENT_TRACE) != 0) {
183 tmpbio = BIO_new_fp(stdout, BIO_NOCLOSE);
184 if (!TEST_ptr(tmpbio))
185 goto err;
186
187 SSL_set_msg_callback(*cssl, SSL_trace);
188 SSL_set_msg_callback_arg(*cssl, tmpbio);
189 }
190 #endif
191 if (tracebio != NULL)
192 *tracebio = tmpbio;
193
194 /* SSL_set_alpn_protos returns 0 for success! */
195 if (!TEST_false(SSL_set_alpn_protos(*cssl, alpn, sizeof(alpn))))
196 goto err;
197
198 if (!TEST_ptr(peeraddr = BIO_ADDR_new()))
199 goto err;
200
201 if ((flags & QTEST_FLAG_BLOCK) != 0) {
202 #if !defined(OPENSSL_NO_POSIX_IO)
203 int cfd, sfd;
204
205 /*
206 * For blocking mode we need to create actual sockets rather than doing
207 * everything in memory
208 */
209 if (!TEST_true(create_test_sockets(&cfd, &sfd, SOCK_DGRAM, peeraddr)))
210 goto err;
211 cbio = BIO_new_dgram(cfd, 1);
212 if (!TEST_ptr(cbio)) {
213 close(cfd);
214 close(sfd);
215 goto err;
216 }
217 sbio = BIO_new_dgram(sfd, 1);
218 if (!TEST_ptr(sbio)) {
219 close(sfd);
220 goto err;
221 }
222 #else
223 goto err;
224 #endif
225 } else {
226 BIO_ADDR *localaddr = NULL;
227
228 if (!TEST_true(BIO_new_bio_dgram_pair(&cbio, 0, &sbio, 0)))
229 goto err;
230
231 if (!TEST_true(BIO_dgram_set_caps(cbio, BIO_DGRAM_CAP_HANDLES_DST_ADDR))
232 || !TEST_true(BIO_dgram_set_caps(sbio, BIO_DGRAM_CAP_HANDLES_DST_ADDR)))
233 goto err;
234
235 if (!TEST_ptr(localaddr = BIO_ADDR_new()))
236 goto err;
237 /* Dummy client local addresses */
238 if (!TEST_true(BIO_ADDR_rawmake(localaddr, AF_INET, &ina, sizeof(ina),
239 htons(0)))) {
240 BIO_ADDR_free(localaddr);
241 goto err;
242 }
243 if (!TEST_int_eq(BIO_dgram_set0_local_addr(cbio, localaddr), 1)) {
244 BIO_ADDR_free(localaddr);
245 goto err;
246 }
247 /* Dummy server address */
248 if (!TEST_true(BIO_ADDR_rawmake(peeraddr, AF_INET, &ina, sizeof(ina),
249 htons(0))))
250 goto err;
251 }
252
253 if ((flags & QTEST_FLAG_PACKET_SPLIT) != 0) {
254 BIO *pktsplitbio = BIO_new(bio_f_pkt_split_dgram_filter());
255
256 if (!TEST_ptr(pktsplitbio))
257 goto err;
258 cbio = BIO_push(pktsplitbio, cbio);
259 BIO_set_data(pktsplitbio, bdata);
260
261 pktsplitbio = BIO_new(bio_f_pkt_split_dgram_filter());
262 if (!TEST_ptr(pktsplitbio))
263 goto err;
264 sbio = BIO_push(pktsplitbio, sbio);
265 BIO_set_data(pktsplitbio, bdata);
266 }
267
268 if ((flags & QTEST_FLAG_NOISE) != 0) {
269 BIO *noisebio;
270 struct bio_noise_now_cb_st now_cb = { fake_now_cb, NULL };
271
272 /*
273 * It is an error to not have a QTEST_FAULT object when introducing noise
274 */
275 if (!TEST_ptr(fault))
276 goto err;
277
278 noisebio = BIO_new(bio_f_noisy_dgram_filter());
279
280 if (!TEST_ptr(noisebio))
281 goto err;
282 cbio = BIO_push(noisebio, cbio);
283 if ((flags & QTEST_FLAG_FAKE_TIME) != 0) {
284 if (!TEST_int_eq(BIO_ctrl(cbio, BIO_CTRL_NOISE_SET_NOW_CB,
285 0, &now_cb), 1))
286 goto err;
287 }
288
289 noisebio = BIO_new(bio_f_noisy_dgram_filter());
290
291 if (!TEST_ptr(noisebio))
292 goto err;
293 sbio = BIO_push(noisebio, sbio);
294 if ((flags & QTEST_FLAG_FAKE_TIME) != 0) {
295 if (!TEST_int_eq(BIO_ctrl(sbio, BIO_CTRL_NOISE_SET_NOW_CB,
296 0, &now_cb), 1))
297 goto err;
298 }
299
300 (void)BIO_ctrl(sbio, BIO_CTRL_NOISE_BACK_OFF, 2, NULL);
301
302 (*fault)->noiseargs.cbio = cbio;
303 (*fault)->noiseargs.sbio = sbio;
304 (*fault)->noiseargs.tracebio = tmpbio;
305 (*fault)->noiseargs.flags = flags;
306
307 SSL_set_msg_callback(*cssl, noise_msg_callback);
308 SSL_set_msg_callback_arg(*cssl, &(*fault)->noiseargs);
309 }
310
311 SSL_set_bio(*cssl, cbio, cbio);
312
313 if (!TEST_true(SSL_set_blocking_mode(*cssl,
314 (flags & QTEST_FLAG_BLOCK) != 0 ? 1 : 0)))
315 goto err;
316
317 if (!TEST_true(SSL_set1_initial_peer_addr(*cssl, peeraddr)))
318 goto err;
319
320 fisbio = BIO_new(qtest_get_bio_method());
321 if (!TEST_ptr(fisbio))
322 goto err;
323
324 BIO_set_data(fisbio, bdata);
325
326 if (!BIO_up_ref(sbio))
327 goto err;
328 if (!TEST_ptr(BIO_push(fisbio, sbio))) {
329 BIO_free(sbio);
330 goto err;
331 }
332
333 tserver_args.libctx = libctx;
334 tserver_args.net_rbio = sbio;
335 tserver_args.net_wbio = fisbio;
336 tserver_args.alpn = NULL;
337 if (serverctx != NULL && !TEST_true(SSL_CTX_up_ref(serverctx)))
338 goto err;
339 tserver_args.ctx = serverctx;
340 if (fake_now_lock == NULL) {
341 fake_now_lock = CRYPTO_THREAD_lock_new();
342 if (fake_now_lock == NULL)
343 goto err;
344 }
345 if ((flags & QTEST_FLAG_FAKE_TIME) != 0) {
346 using_fake_time = 1;
347 qtest_reset_time();
348 tserver_args.now_cb = fake_now_cb;
349 (void)ossl_quic_set_override_now_cb(*cssl, fake_now_cb, NULL);
350 } else {
351 using_fake_time = 0;
352 }
353
354 if (!TEST_ptr(*qtserv = ossl_quic_tserver_new(&tserver_args, certfile,
355 keyfile)))
356 goto err;
357
358 bdata->short_conn_id_len = ossl_quic_tserver_get_short_header_conn_id_len(*qtserv);
359 /* Ownership of fisbio and sbio is now held by *qtserv */
360 sbio = NULL;
361 fisbio = NULL;
362
363 if ((flags & QTEST_FLAG_NOISE) != 0)
364 ossl_quic_tserver_set_msg_callback(*qtserv, noise_msg_callback,
365 &(*fault)->noiseargs);
366
367 if (fault != NULL)
368 (*fault)->qtserv = *qtserv;
369
370 BIO_ADDR_free(peeraddr);
371
372 return 1;
373 err:
374 SSL_CTX_free(tserver_args.ctx);
375 BIO_ADDR_free(peeraddr);
376 BIO_free_all(cbio);
377 BIO_free_all(fisbio);
378 BIO_free_all(sbio);
379 SSL_free(*cssl);
380 *cssl = NULL;
381 ossl_quic_tserver_free(*qtserv);
382 if (fault != NULL)
383 OPENSSL_free(*fault);
384 OPENSSL_free(bdata);
385 BIO_free(tmpbio);
386 if (tracebio != NULL)
387 *tracebio = NULL;
388
389 return 0;
390 }
391
392 void qtest_add_time(uint64_t millis)
393 {
394 if (!CRYPTO_THREAD_write_lock(fake_now_lock))
395 return;
396 fake_now = ossl_time_add(fake_now, ossl_ms2time(millis));
397 CRYPTO_THREAD_unlock(fake_now_lock);
398 }
399
400 static OSSL_TIME qtest_get_time(void)
401 {
402 OSSL_TIME ret;
403
404 if (!CRYPTO_THREAD_read_lock(fake_now_lock))
405 return ossl_time_zero();
406 ret = fake_now;
407 CRYPTO_THREAD_unlock(fake_now_lock);
408 return ret;
409 }
410
411 static void qtest_reset_time(void)
412 {
413 if (!CRYPTO_THREAD_write_lock(fake_now_lock))
414 return;
415 fake_now = ossl_time_zero();
416 CRYPTO_THREAD_unlock(fake_now_lock);
417 /* zero time can have a special meaning, bump it */
418 qtest_add_time(1);
419 }
420
421 void qtest_start_stopwatch(void)
422 {
423 start_time = qtest_get_time();
424 }
425
426 uint64_t qtest_get_stopwatch_time(void)
427 {
428 return ossl_time2ms(ossl_time_subtract(qtest_get_time(), start_time));
429 }
430
431 QTEST_FAULT *qtest_create_injector(QUIC_TSERVER *ts)
432 {
433 QTEST_FAULT *f;
434
435 f = OPENSSL_zalloc(sizeof(*f));
436 if (f == NULL)
437 return NULL;
438
439 f->qtserv = ts;
440 return f;
441
442 }
443
444 int qtest_supports_blocking(void)
445 {
446 #if !defined(OPENSSL_NO_POSIX_IO) && defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
447 return 1;
448 #else
449 return 0;
450 #endif
451 }
452
453 #define MAXLOOPS 1000
454
455 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
456 static int globserverret = 0;
457 static TSAN_QUALIFIER int abortserverthread = 0;
458 static QUIC_TSERVER *globtserv;
459 static const thread_t thread_zero;
460 static void run_server_thread(void)
461 {
462 /*
463 * This will operate in a busy loop because the server does not block,
464 * but should be acceptable because it is local and we expect this to be
465 * fast
466 */
467 globserverret = qtest_create_quic_connection(globtserv, NULL);
468 }
469 #endif
470
471 int qtest_wait_for_timeout(SSL *s, QUIC_TSERVER *qtserv)
472 {
473 struct timeval tv;
474 OSSL_TIME ctimeout, stimeout, mintimeout, now;
475 int cinf;
476
477 /* We don't need to wait in blocking mode */
478 if (s == NULL || SSL_get_blocking_mode(s))
479 return 1;
480
481 /* Don't wait if either BIO has data waiting */
482 if (BIO_pending(SSL_get_rbio(s)) > 0
483 || BIO_pending(ossl_quic_tserver_get0_rbio(qtserv)) > 0)
484 return 1;
485
486 /*
487 * Neither endpoint has data waiting to be read. We assume data transmission
488 * is instantaneous due to using mem based BIOs, so there is no data "in
489 * flight" and no more data will be sent by either endpoint until some time
490 * based event has occurred. Therefore, wait for a timeout to occur. This
491 * might happen if we are using the noisy BIO and datagrams have been lost.
492 */
493 if (!SSL_get_event_timeout(s, &tv, &cinf))
494 return 0;
495
496 if (using_fake_time)
497 now = qtest_get_time();
498 else
499 now = ossl_time_now();
500
501 ctimeout = cinf ? ossl_time_infinite() : ossl_time_from_timeval(tv);
502 stimeout = ossl_time_subtract(ossl_quic_tserver_get_deadline(qtserv), now);
503 mintimeout = ossl_time_min(ctimeout, stimeout);
504 if (ossl_time_is_infinite(mintimeout))
505 return 0;
506
507 if (using_fake_time)
508 qtest_add_time(ossl_time2ms(mintimeout));
509 else
510 OSSL_sleep(ossl_time2ms(mintimeout));
511
512 return 1;
513 }
514
515 int qtest_create_quic_connection_ex(QUIC_TSERVER *qtserv, SSL *clientssl,
516 int wanterr)
517 {
518 int retc = -1, rets = 0, abortctr = 0, ret = 0;
519 int clienterr = 0, servererr = 0;
520 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
521
522 /*
523 * Pointless initialisation to avoid bogus compiler warnings about using
524 * t uninitialised
525 */
526 thread_t t = thread_zero;
527
528 if (clientssl != NULL)
529 abortserverthread = 0;
530
531 /*
532 * Only set the client_ready flag to zero if we are the client
533 */
534 if (clientssl != NULL) {
535 ossl_crypto_mutex_lock(client_ready_mutex);
536 client_ready = 0;
537 ossl_crypto_mutex_unlock(client_ready_mutex);
538 }
539 #endif
540
541 if (!TEST_ptr(qtserv)) {
542 goto err;
543 } else if (clientssl == NULL) {
544 retc = 1;
545 } else if (SSL_get_blocking_mode(clientssl) > 0) {
546 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
547 /*
548 * clientssl is blocking. We will need a thread to complete the
549 * connection
550 */
551 globtserv = qtserv;
552 if (!TEST_true(run_thread(&t, run_server_thread)))
553 goto err;
554
555 qtserv = NULL;
556 rets = 1;
557 #else
558 TEST_error("No thread support in this build");
559 goto err;
560 #endif
561 }
562
563 do {
564 if (!clienterr && retc <= 0) {
565 int err;
566
567 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
568 ossl_crypto_mutex_lock(client_ready_mutex);
569 client_ready = 1;
570 ossl_crypto_condvar_broadcast(client_ready_cond);
571 ossl_crypto_mutex_unlock(client_ready_mutex);
572 #endif
573 retc = SSL_connect(clientssl);
574 if (retc <= 0) {
575 err = SSL_get_error(clientssl, retc);
576
577 if (err == wanterr) {
578 retc = 1;
579 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
580 if (qtserv == NULL && rets > 0)
581 tsan_store(&abortserverthread, 1);
582 else
583 #endif
584 rets = 1;
585 } else {
586 if (err != SSL_ERROR_WANT_READ
587 && err != SSL_ERROR_WANT_WRITE) {
588 TEST_info("SSL_connect() failed %d, %d", retc, err);
589 TEST_openssl_errors();
590 clienterr = 1;
591 }
592 }
593 }
594 }
595
596 qtest_add_time(1);
597 if (clientssl != NULL)
598 SSL_handle_events(clientssl);
599 if (qtserv != NULL) {
600 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
601 ossl_crypto_mutex_lock(client_ready_mutex);
602 for (;;) {
603 if (client_ready == 1)
604 break;
605 ossl_crypto_condvar_wait(client_ready_cond, client_ready_mutex);
606 }
607 ossl_crypto_mutex_unlock(client_ready_mutex);
608 #endif
609 ossl_quic_tserver_tick(qtserv);
610 }
611
612 if (!servererr && rets <= 0) {
613 servererr = ossl_quic_tserver_is_term_any(qtserv);
614 if (!servererr)
615 rets = ossl_quic_tserver_is_handshake_confirmed(qtserv);
616 }
617
618 if (clienterr && servererr)
619 goto err;
620
621 if (clientssl != NULL && ++abortctr == MAXLOOPS) {
622 TEST_info("No progress made");
623 goto err;
624 }
625
626 if ((retc <= 0 && !clienterr) || (rets <= 0 && !servererr)) {
627 if (!qtest_wait_for_timeout(clientssl, qtserv))
628 goto err;
629 }
630 } while ((retc <= 0 && !clienterr)
631 || (rets <= 0 && !servererr
632 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
633 && !tsan_load(&abortserverthread)
634 #endif
635 ));
636
637 if (qtserv == NULL && rets > 0) {
638 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
639 /*
640 * Make sure we unblock the server before we wait on completion here
641 * in case it didn't happen in the connect loop above
642 */
643 ossl_crypto_mutex_lock(client_ready_mutex);
644 client_ready = 1;
645 ossl_crypto_condvar_broadcast(client_ready_cond);
646 ossl_crypto_mutex_unlock(client_ready_mutex);
647 if (!TEST_true(wait_for_thread(t)) || !TEST_true(globserverret))
648 goto err;
649 #else
650 TEST_error("Should not happen");
651 goto err;
652 #endif
653 }
654
655 if (!clienterr && !servererr)
656 ret = 1;
657 err:
658 return ret;
659 }
660
661 int qtest_create_quic_connection(QUIC_TSERVER *qtserv, SSL *clientssl)
662 {
663 return qtest_create_quic_connection_ex(qtserv, clientssl, SSL_ERROR_NONE);
664 }
665
666 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
667 static TSAN_QUALIFIER int shutdowndone;
668
669 static void run_server_shutdown_thread(void)
670 {
671 /*
672 * This will operate in a busy loop because the server does not block,
673 * but should be acceptable because it is local and we expect this to be
674 * fast
675 */
676 do {
677 ossl_quic_tserver_tick(globtserv);
678 } while(!tsan_load(&shutdowndone));
679 }
680 #endif
681
682 int qtest_shutdown(QUIC_TSERVER *qtserv, SSL *clientssl)
683 {
684 int tickserver = 1;
685 int ret = 0;
686 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
687 /*
688 * Pointless initialisation to avoid bogus compiler warnings about using
689 * t uninitialised
690 */
691 thread_t t = thread_zero;
692
693 ossl_crypto_condvar_free(&client_ready_cond);
694 client_ready_cond = NULL;
695 ossl_crypto_mutex_free(&client_ready_mutex);
696 client_ready_mutex = NULL;
697 #endif
698
699 if (SSL_get_blocking_mode(clientssl) > 0) {
700 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
701 /*
702 * clientssl is blocking. We will need a thread to complete the
703 * connection
704 */
705 globtserv = qtserv;
706 shutdowndone = 0;
707 if (!TEST_true(run_thread(&t, run_server_shutdown_thread)))
708 return 0;
709
710 tickserver = 0;
711 #else
712 TEST_error("No thread support in this build");
713 return 0;
714 #endif
715 }
716
717 /* Busy loop in non-blocking mode. It should be quick because its local */
718 for (;;) {
719 int rc = SSL_shutdown(clientssl);
720
721 if (rc == 1) {
722 ret = 1;
723 break;
724 }
725
726 if (rc < 0)
727 break;
728
729 if (tickserver)
730 ossl_quic_tserver_tick(qtserv);
731 }
732
733 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
734 tsan_store(&shutdowndone, 1);
735 if (!tickserver) {
736 if (!TEST_true(wait_for_thread(t)))
737 ret = 0;
738 }
739 #endif
740
741 return ret;
742 }
743
744 int qtest_check_server_transport_err(QUIC_TSERVER *qtserv, uint64_t code)
745 {
746 const QUIC_TERMINATE_CAUSE *cause;
747
748 ossl_quic_tserver_tick(qtserv);
749
750 /*
751 * Check that the server has closed with the specified code from the client
752 */
753 if (!TEST_true(ossl_quic_tserver_is_term_any(qtserv)))
754 return 0;
755
756 cause = ossl_quic_tserver_get_terminate_cause(qtserv);
757 if (!TEST_ptr(cause)
758 || !TEST_true(cause->remote)
759 || !TEST_false(cause->app)
760 || !TEST_uint64_t_eq(cause->error_code, code))
761 return 0;
762
763 return 1;
764 }
765
766 int qtest_check_server_protocol_err(QUIC_TSERVER *qtserv)
767 {
768 return qtest_check_server_transport_err(qtserv, OSSL_QUIC_ERR_PROTOCOL_VIOLATION);
769 }
770
771 int qtest_check_server_frame_encoding_err(QUIC_TSERVER *qtserv)
772 {
773 return qtest_check_server_transport_err(qtserv, OSSL_QUIC_ERR_FRAME_ENCODING_ERROR);
774 }
775
776 void qtest_fault_free(QTEST_FAULT *fault)
777 {
778 if (fault == NULL)
779 return;
780
781 packet_plain_finish(fault);
782 handshake_finish(fault);
783
784 OPENSSL_free(fault);
785 }
786
787 static int packet_plain_mutate(const QUIC_PKT_HDR *hdrin,
788 const OSSL_QTX_IOVEC *iovecin, size_t numin,
789 QUIC_PKT_HDR **hdrout,
790 const OSSL_QTX_IOVEC **iovecout,
791 size_t *numout,
792 void *arg)
793 {
794 QTEST_FAULT *fault = arg;
795 size_t i, bufsz = 0;
796 unsigned char *cur;
797 int grow_allowance;
798
799 /* Coalesce our data into a single buffer */
800
801 /* First calculate required buffer size */
802 for (i = 0; i < numin; i++)
803 bufsz += iovecin[i].buf_len;
804
805 fault->pplainio.buf_len = bufsz;
806
807 /*
808 * 1200 is QUIC payload length we use
809 * bufsz is what we got from txp
810 * 16 is the length of tag added by encryption
811 * 14 long header (we assume token length is 0,
812 * which is fine for server not so fine for client)
813 */
814 grow_allowance = 1200 - bufsz - 16 - 14;
815 grow_allowance -= hdrin->dst_conn_id.id_len;
816 grow_allowance -= hdrin->src_conn_id.id_len;
817 assert(grow_allowance >= 0);
818 bufsz += grow_allowance;
819
820 fault->pplainio.buf = cur = OPENSSL_malloc(bufsz);
821 if (cur == NULL) {
822 fault->pplainio.buf_len = 0;
823 return 0;
824 }
825
826 fault->pplainbuf_alloc = bufsz;
827
828 /* Copy in the data from the input buffers */
829 for (i = 0; i < numin; i++) {
830 memcpy(cur, iovecin[i].buf, iovecin[i].buf_len);
831 cur += iovecin[i].buf_len;
832 }
833
834 fault->pplainhdr = *hdrin;
835
836 /*
837 * Cast below is safe because we allocated the buffer
838 * mutation is best effort. we can inject frame if
839 * there is enough space. If there is not enough space
840 * we must give up.
841 */
842 if (fault->pplaincb != NULL)
843 fault->pplaincb(fault, &fault->pplainhdr,
844 (unsigned char *)fault->pplainio.buf,
845 fault->pplainio.buf_len, fault->pplaincbarg);
846
847 *hdrout = &fault->pplainhdr;
848 *iovecout = &fault->pplainio;
849 *numout = 1;
850
851 return 1;
852 }
853
854 static void packet_plain_finish(void *arg)
855 {
856 QTEST_FAULT *fault = arg;
857
858 /* Cast below is safe because we allocated the buffer */
859 OPENSSL_free((unsigned char *)fault->pplainio.buf);
860 fault->pplainio.buf_len = 0;
861 fault->pplainbuf_alloc = 0;
862 fault->pplainio.buf = NULL;
863 }
864
865 int qtest_fault_set_packet_plain_listener(QTEST_FAULT *fault,
866 qtest_fault_on_packet_plain_cb pplaincb,
867 void *pplaincbarg)
868 {
869 fault->pplaincb = pplaincb;
870 fault->pplaincbarg = pplaincbarg;
871
872 return ossl_quic_tserver_set_plain_packet_mutator(fault->qtserv,
873 packet_plain_mutate,
874 packet_plain_finish,
875 fault);
876 }
877
878 /* To be called from a packet_plain_listener callback */
879 int qtest_fault_resize_plain_packet(QTEST_FAULT *fault, size_t newlen)
880 {
881 unsigned char *buf;
882 size_t oldlen = fault->pplainio.buf_len;
883
884 /*
885 * Alloc'd size should always be non-zero, so if this fails we've been
886 * incorrectly called
887 */
888 if (fault->pplainbuf_alloc == 0)
889 return 0;
890
891 if (newlen > fault->pplainbuf_alloc) {
892 /* This exceeds our growth allowance. Fail */
893 return 0;
894 }
895
896 /* Cast below is safe because we allocated the buffer */
897 buf = (unsigned char *)fault->pplainio.buf;
898
899 if (newlen > oldlen) {
900 /* Extend packet with 0 bytes */
901 memset(buf + oldlen, 0, newlen - oldlen);
902 } /* else we're truncating or staying the same */
903
904 fault->pplainio.buf_len = newlen;
905 fault->pplainhdr.len = newlen;
906
907 return 1;
908 }
909
910 /*
911 * Prepend frame data into a packet. To be called from a packet_plain_listener
912 * callback
913 */
914 int qtest_fault_prepend_frame(QTEST_FAULT *fault, const unsigned char *frame,
915 size_t frame_len)
916 {
917 unsigned char *buf;
918 size_t old_len;
919
920 /*
921 * Alloc'd size should always be non-zero, so if this fails we've been
922 * incorrectly called
923 */
924 if (fault->pplainbuf_alloc == 0)
925 return 0;
926
927 /* Cast below is safe because we allocated the buffer */
928 buf = (unsigned char *)fault->pplainio.buf;
929 old_len = fault->pplainio.buf_len;
930
931 /* Extend the size of the packet by the size of the new frame */
932 if (!TEST_true(qtest_fault_resize_plain_packet(fault,
933 old_len + frame_len)))
934 return 0;
935
936 memmove(buf + frame_len, buf, old_len);
937 memcpy(buf, frame, frame_len);
938
939 return 1;
940 }
941
942 static int handshake_mutate(const unsigned char *msgin, size_t msginlen,
943 unsigned char **msgout, size_t *msgoutlen,
944 void *arg)
945 {
946 QTEST_FAULT *fault = arg;
947 unsigned char *buf;
948 unsigned long payloadlen;
949 unsigned int msgtype;
950 PACKET pkt;
951
952 buf = OPENSSL_malloc(msginlen + GROWTH_ALLOWANCE);
953 if (buf == NULL)
954 return 0;
955
956 fault->handbuf = buf;
957 fault->handbuflen = msginlen;
958 fault->handbufalloc = msginlen + GROWTH_ALLOWANCE;
959 memcpy(buf, msgin, msginlen);
960
961 if (!PACKET_buf_init(&pkt, buf, msginlen)
962 || !PACKET_get_1(&pkt, &msgtype)
963 || !PACKET_get_net_3(&pkt, &payloadlen)
964 || PACKET_remaining(&pkt) != payloadlen)
965 return 0;
966
967 /* Parse specific message types */
968 switch (msgtype) {
969 case SSL3_MT_ENCRYPTED_EXTENSIONS:
970 {
971 QTEST_ENCRYPTED_EXTENSIONS ee;
972
973 if (fault->encextcb == NULL)
974 break;
975
976 /*
977 * The EncryptedExtensions message is very simple. It just has an
978 * extensions block in it and nothing else.
979 */
980 ee.extensions = (unsigned char *)PACKET_data(&pkt);
981 ee.extensionslen = payloadlen;
982 if (!fault->encextcb(fault, &ee, payloadlen, fault->encextcbarg))
983 return 0;
984 }
985
986 default:
987 /* No specific handlers for these message types yet */
988 break;
989 }
990
991 if (fault->handshakecb != NULL
992 && !fault->handshakecb(fault, buf, fault->handbuflen,
993 fault->handshakecbarg))
994 return 0;
995
996 *msgout = buf;
997 *msgoutlen = fault->handbuflen;
998
999 return 1;
1000 }
1001
1002 static void handshake_finish(void *arg)
1003 {
1004 QTEST_FAULT *fault = arg;
1005
1006 OPENSSL_free(fault->handbuf);
1007 fault->handbuf = NULL;
1008 }
1009
1010 int qtest_fault_set_handshake_listener(QTEST_FAULT *fault,
1011 qtest_fault_on_handshake_cb handshakecb,
1012 void *handshakecbarg)
1013 {
1014 fault->handshakecb = handshakecb;
1015 fault->handshakecbarg = handshakecbarg;
1016
1017 return ossl_quic_tserver_set_handshake_mutator(fault->qtserv,
1018 handshake_mutate,
1019 handshake_finish,
1020 fault);
1021 }
1022
1023 int qtest_fault_set_hand_enc_ext_listener(QTEST_FAULT *fault,
1024 qtest_fault_on_enc_ext_cb encextcb,
1025 void *encextcbarg)
1026 {
1027 fault->encextcb = encextcb;
1028 fault->encextcbarg = encextcbarg;
1029
1030 return ossl_quic_tserver_set_handshake_mutator(fault->qtserv,
1031 handshake_mutate,
1032 handshake_finish,
1033 fault);
1034 }
1035
1036 /* To be called from a handshake_listener callback */
1037 int qtest_fault_resize_handshake(QTEST_FAULT *fault, size_t newlen)
1038 {
1039 unsigned char *buf;
1040 size_t oldlen = fault->handbuflen;
1041
1042 /*
1043 * Alloc'd size should always be non-zero, so if this fails we've been
1044 * incorrectly called
1045 */
1046 if (fault->handbufalloc == 0)
1047 return 0;
1048
1049 if (newlen > fault->handbufalloc) {
1050 /* This exceeds our growth allowance. Fail */
1051 return 0;
1052 }
1053
1054 buf = (unsigned char *)fault->handbuf;
1055
1056 if (newlen > oldlen) {
1057 /* Extend packet with 0 bytes */
1058 memset(buf + oldlen, 0, newlen - oldlen);
1059 } /* else we're truncating or staying the same */
1060
1061 fault->handbuflen = newlen;
1062 return 1;
1063 }
1064
1065 /* To be called from message specific listener callbacks */
1066 int qtest_fault_resize_message(QTEST_FAULT *fault, size_t newlen)
1067 {
1068 /* First resize the underlying message */
1069 if (!qtest_fault_resize_handshake(fault, newlen + SSL3_HM_HEADER_LENGTH))
1070 return 0;
1071
1072 /* Fixup the handshake message header */
1073 fault->handbuf[1] = (unsigned char)((newlen >> 16) & 0xff);
1074 fault->handbuf[2] = (unsigned char)((newlen >> 8) & 0xff);
1075 fault->handbuf[3] = (unsigned char)((newlen ) & 0xff);
1076
1077 return 1;
1078 }
1079
1080 int qtest_fault_delete_extension(QTEST_FAULT *fault,
1081 unsigned int exttype, unsigned char *ext,
1082 size_t *extlen,
1083 BUF_MEM *old_ext)
1084 {
1085 PACKET pkt, sub, subext;
1086 WPACKET old_ext_wpkt;
1087 unsigned int type;
1088 const unsigned char *start, *end;
1089 size_t newlen, w;
1090 size_t msglen = fault->handbuflen;
1091
1092 if (!PACKET_buf_init(&pkt, ext, *extlen))
1093 return 0;
1094
1095 /* Extension block starts with 2 bytes for extension block length */
1096 if (!PACKET_as_length_prefixed_2(&pkt, &sub))
1097 return 0;
1098
1099 do {
1100 start = PACKET_data(&sub);
1101 if (!PACKET_get_net_2(&sub, &type)
1102 || !PACKET_get_length_prefixed_2(&sub, &subext))
1103 return 0;
1104 } while (type != exttype);
1105
1106 /* Found it */
1107 end = PACKET_data(&sub);
1108
1109 if (old_ext != NULL) {
1110 if (!WPACKET_init(&old_ext_wpkt, old_ext))
1111 return 0;
1112
1113 if (!WPACKET_memcpy(&old_ext_wpkt, PACKET_data(&subext),
1114 PACKET_remaining(&subext))
1115 || !WPACKET_get_total_written(&old_ext_wpkt, &w)) {
1116 WPACKET_cleanup(&old_ext_wpkt);
1117 return 0;
1118 }
1119
1120 WPACKET_finish(&old_ext_wpkt);
1121 old_ext->length = w;
1122 }
1123
1124 /*
1125 * If we're not the last extension we need to move the rest earlier. The
1126 * cast below is safe because we own the underlying buffer and we're no
1127 * longer making PACKET calls.
1128 */
1129 if (end < ext + *extlen)
1130 memmove((unsigned char *)start, end, end - start);
1131
1132 /*
1133 * Calculate new extensions payload length =
1134 * Original length
1135 * - 2 extension block length bytes
1136 * - length of removed extension
1137 */
1138 newlen = *extlen - 2 - (end - start);
1139
1140 /* Fixup the length bytes for the extension block */
1141 ext[0] = (unsigned char)((newlen >> 8) & 0xff);
1142 ext[1] = (unsigned char)((newlen ) & 0xff);
1143
1144 /*
1145 * Length of the whole extension block is the new payload length plus the
1146 * 2 bytes for the length
1147 */
1148 *extlen = newlen + 2;
1149
1150 /* We can now resize the message */
1151 if ((size_t)(end - start) + SSL3_HM_HEADER_LENGTH > msglen)
1152 return 0; /* Should not happen */
1153 msglen -= (end - start) + SSL3_HM_HEADER_LENGTH;
1154 if (!qtest_fault_resize_message(fault, msglen))
1155 return 0;
1156
1157 return 1;
1158 }
1159
1160 #define BIO_TYPE_CIPHER_PACKET_FILTER (0x80 | BIO_TYPE_FILTER)
1161
1162 static BIO_METHOD *pcipherbiometh = NULL;
1163
1164 # define BIO_MSG_N(array, stride, n) (*(BIO_MSG *)((char *)(array) + (n)*(stride)))
1165
1166 static int pcipher_sendmmsg(BIO *b, BIO_MSG *msg, size_t stride,
1167 size_t num_msg, uint64_t flags,
1168 size_t *num_processed)
1169 {
1170 BIO *next = BIO_next(b);
1171 ossl_ssize_t ret = 0;
1172 size_t i = 0, tmpnump;
1173 QUIC_PKT_HDR hdr;
1174 PACKET pkt;
1175 unsigned char *tmpdata;
1176 QTEST_DATA *bdata = NULL;
1177
1178 if (next == NULL)
1179 return 0;
1180
1181 bdata = BIO_get_data(b);
1182 if (bdata == NULL || bdata->fault == NULL
1183 || (bdata->fault->pciphercb == NULL && bdata->fault->datagramcb == NULL))
1184 return BIO_sendmmsg(next, msg, stride, num_msg, flags, num_processed);
1185
1186 if (num_msg == 0) {
1187 *num_processed = 0;
1188 return 1;
1189 }
1190
1191 for (i = 0; i < num_msg; ++i) {
1192 bdata->fault->msg = BIO_MSG_N(msg, stride, i);
1193
1194 /* Take a copy of the data so that callbacks can modify it */
1195 tmpdata = OPENSSL_malloc(bdata->fault->msg.data_len + GROWTH_ALLOWANCE);
1196 if (tmpdata == NULL)
1197 return 0;
1198 memcpy(tmpdata, bdata->fault->msg.data, bdata->fault->msg.data_len);
1199 bdata->fault->msg.data = tmpdata;
1200 bdata->fault->msgalloc = bdata->fault->msg.data_len + GROWTH_ALLOWANCE;
1201
1202 if (bdata->fault->pciphercb != NULL) {
1203 if (!PACKET_buf_init(&pkt, bdata->fault->msg.data, bdata->fault->msg.data_len))
1204 return 0;
1205
1206 do {
1207 if (!ossl_quic_wire_decode_pkt_hdr(&pkt,
1208 bdata->short_conn_id_len,
1209 1, 0, &hdr, NULL, NULL))
1210 goto out;
1211
1212 /*
1213 * hdr.data is const - but its our buffer so casting away the
1214 * const is safe
1215 */
1216 if (!bdata->fault->pciphercb(bdata->fault, &hdr,
1217 (unsigned char *)hdr.data, hdr.len,
1218 bdata->fault->pciphercbarg))
1219 goto out;
1220
1221 /*
1222 * At the moment modifications to hdr by the callback
1223 * are ignored. We might need to rewrite the QUIC header to
1224 * enable tests to change this. We also don't yet have a
1225 * mechanism for the callback to change the encrypted data
1226 * length. It's not clear if that's needed or not.
1227 */
1228 } while (PACKET_remaining(&pkt) > 0);
1229 }
1230
1231 if (bdata->fault->datagramcb != NULL
1232 && !bdata->fault->datagramcb(bdata->fault, &bdata->fault->msg, stride,
1233 bdata->fault->datagramcbarg))
1234 goto out;
1235
1236 if (!BIO_sendmmsg(next, &bdata->fault->msg, stride, 1, flags, &tmpnump)) {
1237 *num_processed = i;
1238 goto out;
1239 }
1240
1241 OPENSSL_free(bdata->fault->msg.data);
1242 bdata->fault->msg.data = NULL;
1243 bdata->fault->msgalloc = 0;
1244 }
1245
1246 *num_processed = i;
1247 out:
1248 ret = i > 0;
1249 OPENSSL_free(bdata->fault->msg.data);
1250 bdata->fault->msg.data = NULL;
1251 return ret;
1252 }
1253
1254 static long pcipher_ctrl(BIO *b, int cmd, long larg, void *parg)
1255 {
1256 BIO *next = BIO_next(b);
1257
1258 if (next == NULL)
1259 return -1;
1260
1261 return BIO_ctrl(next, cmd, larg, parg);
1262 }
1263
1264 static int pcipher_destroy(BIO *b)
1265 {
1266 OPENSSL_free(BIO_get_data(b));
1267 return 1;
1268 }
1269
1270 BIO_METHOD *qtest_get_bio_method(void)
1271 {
1272 BIO_METHOD *tmp;
1273
1274 if (pcipherbiometh != NULL)
1275 return pcipherbiometh;
1276
1277 tmp = BIO_meth_new(BIO_TYPE_CIPHER_PACKET_FILTER, "Cipher Packet Filter");
1278
1279 if (!TEST_ptr(tmp))
1280 return NULL;
1281
1282 if (!TEST_true(BIO_meth_set_sendmmsg(tmp, pcipher_sendmmsg))
1283 || !TEST_true(BIO_meth_set_ctrl(tmp, pcipher_ctrl))
1284 || !TEST_true(BIO_meth_set_destroy(tmp, pcipher_destroy)))
1285 goto err;
1286
1287 pcipherbiometh = tmp;
1288 tmp = NULL;
1289 err:
1290 BIO_meth_free(tmp);
1291 return pcipherbiometh;
1292 }
1293
1294 int qtest_fault_set_packet_cipher_listener(QTEST_FAULT *fault,
1295 qtest_fault_on_packet_cipher_cb pciphercb,
1296 void *pciphercbarg)
1297 {
1298 fault->pciphercb = pciphercb;
1299 fault->pciphercbarg = pciphercbarg;
1300
1301 return 1;
1302 }
1303
1304 int qtest_fault_set_datagram_listener(QTEST_FAULT *fault,
1305 qtest_fault_on_datagram_cb datagramcb,
1306 void *datagramcbarg)
1307 {
1308 fault->datagramcb = datagramcb;
1309 fault->datagramcbarg = datagramcbarg;
1310
1311 return 1;
1312 }
1313
1314 /* To be called from a datagram_listener callback */
1315 int qtest_fault_resize_datagram(QTEST_FAULT *fault, size_t newlen)
1316 {
1317 if (newlen > fault->msgalloc)
1318 return 0;
1319
1320 if (newlen > fault->msg.data_len)
1321 memset((unsigned char *)fault->msg.data + fault->msg.data_len, 0,
1322 newlen - fault->msg.data_len);
1323
1324 fault->msg.data_len = newlen;
1325
1326 return 1;
1327 }
1328
1329 int qtest_fault_set_bw_limit(QTEST_FAULT *fault,
1330 size_t ctos_bw, size_t stoc_bw,
1331 int noise_rate)
1332 {
1333 BIO *sbio = fault->noiseargs.sbio;
1334 BIO *cbio = fault->noiseargs.cbio;
1335
1336 if (!TEST_ptr(sbio) || !TEST_ptr(cbio))
1337 return 0;
1338 if (!TEST_int_eq(BIO_ctrl(sbio, BIO_CTRL_NOISE_RATE, noise_rate, NULL), 1))
1339 return 0;
1340 if (!TEST_int_eq(BIO_ctrl(cbio, BIO_CTRL_NOISE_RATE, noise_rate, NULL), 1))
1341 return 0;
1342 /* We set the bandwidth limit on the sending side */
1343 if (!TEST_int_eq(BIO_ctrl(cbio, BIO_CTRL_NOISE_SEND_BANDWIDTH,
1344 (long)ctos_bw, NULL), 1))
1345 return 0;
1346 if (!TEST_int_eq(BIO_ctrl(sbio, BIO_CTRL_NOISE_SEND_BANDWIDTH,
1347 (long)stoc_bw, NULL), 1))
1348 return 0;
1349 return 1;
1350 }
1351
1352
1353 int bio_msg_copy(BIO_MSG *dst, BIO_MSG *src)
1354 {
1355 /*
1356 * Note it is assumed that the originally allocated data sizes for dst and
1357 * src are the same
1358 */
1359 memcpy(dst->data, src->data, src->data_len);
1360 dst->data_len = src->data_len;
1361 dst->flags = src->flags;
1362 if (dst->local != NULL) {
1363 if (src->local != NULL) {
1364 if (!TEST_true(BIO_ADDR_copy(dst->local, src->local)))
1365 return 0;
1366 } else {
1367 BIO_ADDR_clear(dst->local);
1368 }
1369 }
1370 if (!TEST_true(BIO_ADDR_copy(dst->peer, src->peer)))
1371 return 0;
1372
1373 return 1;
1374 }