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
fake_now_cb(void * arg)91 static OSSL_TIME fake_now_cb(void *arg)
92 {
93 return qtest_get_time();
94 }
95
noise_msg_callback(int write_p,int version,int content_type,const void * buf,size_t len,SSL * ssl,void * arg)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
qtest_create_quic_objects(OSSL_LIB_CTX * libctx,SSL_CTX * clientctx,SSL_CTX * serverctx,char * certfile,char * keyfile,int flags,QUIC_TSERVER ** qtserv,SSL ** cssl,QTEST_FAULT ** fault,BIO ** tracebio)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),
286 1))
287 goto err;
288 }
289
290 noisebio = BIO_new(bio_f_noisy_dgram_filter());
291
292 if (!TEST_ptr(noisebio))
293 goto err;
294 sbio = BIO_push(noisebio, sbio);
295 if ((flags & QTEST_FLAG_FAKE_TIME) != 0) {
296 if (!TEST_int_eq(BIO_ctrl(sbio, BIO_CTRL_NOISE_SET_NOW_CB,
297 0, &now_cb),
298 1))
299 goto err;
300 }
301
302 (void)BIO_ctrl(sbio, BIO_CTRL_NOISE_BACK_OFF, 2, NULL);
303
304 (*fault)->noiseargs.cbio = cbio;
305 (*fault)->noiseargs.sbio = sbio;
306 (*fault)->noiseargs.tracebio = tmpbio;
307 (*fault)->noiseargs.flags = flags;
308
309 SSL_set_msg_callback(*cssl, noise_msg_callback);
310 SSL_set_msg_callback_arg(*cssl, &(*fault)->noiseargs);
311 }
312
313 SSL_set_bio(*cssl, cbio, cbio);
314
315 if (!TEST_true(SSL_set_blocking_mode(*cssl,
316 (flags & QTEST_FLAG_BLOCK) != 0 ? 1 : 0)))
317 goto err;
318
319 if (!TEST_true(SSL_set1_initial_peer_addr(*cssl, peeraddr)))
320 goto err;
321
322 fisbio = BIO_new(qtest_get_bio_method());
323 if (!TEST_ptr(fisbio))
324 goto err;
325
326 BIO_set_data(fisbio, bdata);
327
328 if (!BIO_up_ref(sbio))
329 goto err;
330 if (!TEST_ptr(BIO_push(fisbio, sbio))) {
331 BIO_free(sbio);
332 goto err;
333 }
334
335 tserver_args.libctx = libctx;
336 tserver_args.net_rbio = sbio;
337 tserver_args.net_wbio = fisbio;
338 tserver_args.alpn = NULL;
339 if (serverctx != NULL && !TEST_true(SSL_CTX_up_ref(serverctx)))
340 goto err;
341 tserver_args.ctx = serverctx;
342 if (fake_now_lock == NULL) {
343 fake_now_lock = CRYPTO_THREAD_lock_new();
344 if (fake_now_lock == NULL)
345 goto err;
346 }
347 if ((flags & QTEST_FLAG_FAKE_TIME) != 0) {
348 using_fake_time = 1;
349 qtest_reset_time();
350 tserver_args.now_cb = fake_now_cb;
351 (void)ossl_quic_set_override_now_cb(*cssl, fake_now_cb, NULL);
352 } else {
353 using_fake_time = 0;
354 }
355
356 if (!TEST_ptr(*qtserv = ossl_quic_tserver_new(&tserver_args, certfile,
357 keyfile)))
358 goto err;
359
360 bdata->short_conn_id_len = ossl_quic_tserver_get_short_header_conn_id_len(*qtserv);
361 /* Ownership of fisbio and sbio is now held by *qtserv */
362 sbio = NULL;
363 fisbio = NULL;
364
365 if ((flags & QTEST_FLAG_NOISE) != 0)
366 ossl_quic_tserver_set_msg_callback(*qtserv, noise_msg_callback,
367 &(*fault)->noiseargs);
368
369 if (fault != NULL)
370 (*fault)->qtserv = *qtserv;
371
372 BIO_ADDR_free(peeraddr);
373
374 return 1;
375 err:
376 SSL_CTX_free(tserver_args.ctx);
377 BIO_ADDR_free(peeraddr);
378 BIO_free_all(cbio);
379 BIO_free_all(fisbio);
380 BIO_free_all(sbio);
381 SSL_free(*cssl);
382 *cssl = NULL;
383 ossl_quic_tserver_free(*qtserv);
384 if (fault != NULL)
385 OPENSSL_free(*fault);
386 OPENSSL_free(bdata);
387 BIO_free(tmpbio);
388 if (tracebio != NULL)
389 *tracebio = NULL;
390
391 return 0;
392 }
393
qtest_add_time(uint64_t millis)394 void qtest_add_time(uint64_t millis)
395 {
396 if (!CRYPTO_THREAD_write_lock(fake_now_lock))
397 return;
398 fake_now = ossl_time_add(fake_now, ossl_ms2time(millis));
399 CRYPTO_THREAD_unlock(fake_now_lock);
400 }
401
qtest_get_time(void)402 static OSSL_TIME qtest_get_time(void)
403 {
404 OSSL_TIME ret;
405
406 if (!CRYPTO_THREAD_read_lock(fake_now_lock))
407 return ossl_time_zero();
408 ret = fake_now;
409 CRYPTO_THREAD_unlock(fake_now_lock);
410 return ret;
411 }
412
qtest_reset_time(void)413 static void qtest_reset_time(void)
414 {
415 if (!CRYPTO_THREAD_write_lock(fake_now_lock))
416 return;
417 fake_now = ossl_time_zero();
418 CRYPTO_THREAD_unlock(fake_now_lock);
419 /* zero time can have a special meaning, bump it */
420 qtest_add_time(1);
421 }
422
qtest_start_stopwatch(void)423 void qtest_start_stopwatch(void)
424 {
425 start_time = qtest_get_time();
426 }
427
qtest_get_stopwatch_time(void)428 uint64_t qtest_get_stopwatch_time(void)
429 {
430 return ossl_time2ms(ossl_time_subtract(qtest_get_time(), start_time));
431 }
432
qtest_create_injector(QUIC_TSERVER * ts)433 QTEST_FAULT *qtest_create_injector(QUIC_TSERVER *ts)
434 {
435 QTEST_FAULT *f;
436
437 f = OPENSSL_zalloc(sizeof(*f));
438 if (f == NULL)
439 return NULL;
440
441 f->qtserv = ts;
442 return f;
443 }
444
qtest_supports_blocking(void)445 int qtest_supports_blocking(void)
446 {
447 #if !defined(OPENSSL_NO_POSIX_IO) && defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
448 return 1;
449 #else
450 return 0;
451 #endif
452 }
453
454 #define MAXLOOPS 1000
455
456 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
457 static int globserverret = 0;
458 static TSAN_QUALIFIER int abortserverthread = 0;
459 static QUIC_TSERVER *globtserv;
460 static const thread_t thread_zero;
run_server_thread(void)461 static void run_server_thread(void)
462 {
463 /*
464 * This will operate in a busy loop because the server does not block,
465 * but should be acceptable because it is local and we expect this to be
466 * fast
467 */
468 globserverret = qtest_create_quic_connection(globtserv, NULL);
469 }
470 #endif
471
qtest_wait_for_timeout(SSL * s,QUIC_TSERVER * qtserv)472 int qtest_wait_for_timeout(SSL *s, QUIC_TSERVER *qtserv)
473 {
474 struct timeval tv;
475 OSSL_TIME ctimeout, stimeout, mintimeout, now;
476 int cinf;
477
478 /* We don't need to wait in blocking mode */
479 if (s == NULL || SSL_get_blocking_mode(s))
480 return 1;
481
482 /* Don't wait if either BIO has data waiting */
483 if (BIO_pending(SSL_get_rbio(s)) > 0
484 || BIO_pending(ossl_quic_tserver_get0_rbio(qtserv)) > 0)
485 return 1;
486
487 /*
488 * Neither endpoint has data waiting to be read. We assume data transmission
489 * is instantaneous due to using mem based BIOs, so there is no data "in
490 * flight" and no more data will be sent by either endpoint until some time
491 * based event has occurred. Therefore, wait for a timeout to occur. This
492 * might happen if we are using the noisy BIO and datagrams have been lost.
493 */
494 if (!SSL_get_event_timeout(s, &tv, &cinf))
495 return 0;
496
497 if (using_fake_time)
498 now = qtest_get_time();
499 else
500 now = ossl_time_now();
501
502 ctimeout = cinf ? ossl_time_infinite() : ossl_time_from_timeval(tv);
503 stimeout = ossl_time_subtract(ossl_quic_tserver_get_deadline(qtserv), now);
504 mintimeout = ossl_time_min(ctimeout, stimeout);
505 if (ossl_time_is_infinite(mintimeout))
506 return 0;
507
508 if (using_fake_time)
509 qtest_add_time(ossl_time2ms(mintimeout));
510 else
511 OSSL_sleep(ossl_time2ms(mintimeout));
512
513 return 1;
514 }
515
qtest_create_quic_connection_ex(QUIC_TSERVER * qtserv,SSL * clientssl,int wanterr)516 int qtest_create_quic_connection_ex(QUIC_TSERVER *qtserv, SSL *clientssl,
517 int wanterr)
518 {
519 int retc = -1, rets = 0, abortctr = 0, ret = 0;
520 int clienterr = 0, servererr = 0;
521 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
522
523 /*
524 * Pointless initialisation to avoid bogus compiler warnings about using
525 * t uninitialised
526 */
527 thread_t t = thread_zero;
528
529 if (clientssl != NULL)
530 abortserverthread = 0;
531
532 /*
533 * Only set the client_ready flag to zero if we are the client
534 */
535 if (clientssl != NULL) {
536 ossl_crypto_mutex_lock(client_ready_mutex);
537 client_ready = 0;
538 ossl_crypto_mutex_unlock(client_ready_mutex);
539 }
540 #endif
541
542 if (!TEST_ptr(qtserv)) {
543 goto err;
544 } else if (clientssl == NULL) {
545 retc = 1;
546 } else if (SSL_get_blocking_mode(clientssl) > 0) {
547 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
548 /*
549 * clientssl is blocking. We will need a thread to complete the
550 * connection
551 */
552 globtserv = qtserv;
553 if (!TEST_true(run_thread(&t, run_server_thread)))
554 goto err;
555
556 qtserv = NULL;
557 rets = 1;
558 #else
559 TEST_error("No thread support in this build");
560 goto err;
561 #endif
562 }
563
564 do {
565 if (!clienterr && retc <= 0) {
566 int err;
567
568 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
569 ossl_crypto_mutex_lock(client_ready_mutex);
570 client_ready = 1;
571 ossl_crypto_condvar_broadcast(client_ready_cond);
572 ossl_crypto_mutex_unlock(client_ready_mutex);
573 #endif
574 retc = SSL_connect(clientssl);
575 if (retc <= 0) {
576 err = SSL_get_error(clientssl, retc);
577
578 if (err == wanterr) {
579 retc = 1;
580 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
581 if (qtserv == NULL && rets > 0)
582 tsan_store(&abortserverthread, 1);
583 else
584 #endif
585 rets = 1;
586 } else {
587 if (err != SSL_ERROR_WANT_READ
588 && err != SSL_ERROR_WANT_WRITE) {
589 TEST_info("SSL_connect() failed %d, %d", retc, err);
590 TEST_openssl_errors();
591 clienterr = 1;
592 }
593 }
594 }
595 }
596
597 qtest_add_time(1);
598 if (clientssl != NULL)
599 SSL_handle_events(clientssl);
600 if (qtserv != NULL) {
601 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
602 ossl_crypto_mutex_lock(client_ready_mutex);
603 for (;;) {
604 if (client_ready == 1)
605 break;
606 ossl_crypto_condvar_wait(client_ready_cond, client_ready_mutex);
607 }
608 ossl_crypto_mutex_unlock(client_ready_mutex);
609 #endif
610 ossl_quic_tserver_tick(qtserv);
611 }
612
613 if (!servererr && rets <= 0) {
614 servererr = ossl_quic_tserver_is_term_any(qtserv);
615 if (!servererr)
616 rets = ossl_quic_tserver_is_handshake_confirmed(qtserv);
617 }
618
619 if (clienterr && servererr)
620 goto err;
621
622 if (clientssl != NULL && ++abortctr == MAXLOOPS) {
623 TEST_info("No progress made");
624 goto err;
625 }
626
627 if ((retc <= 0 && !clienterr) || (rets <= 0 && !servererr)) {
628 if (!qtest_wait_for_timeout(clientssl, qtserv))
629 goto err;
630 }
631 } while ((retc <= 0 && !clienterr)
632 || (rets <= 0 && !servererr
633 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
634 && !tsan_load(&abortserverthread)
635 #endif
636 ));
637
638 if (qtserv == NULL && rets > 0) {
639 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
640 /*
641 * Make sure we unblock the server before we wait on completion here
642 * in case it didn't happen in the connect loop above
643 */
644 ossl_crypto_mutex_lock(client_ready_mutex);
645 client_ready = 1;
646 ossl_crypto_condvar_broadcast(client_ready_cond);
647 ossl_crypto_mutex_unlock(client_ready_mutex);
648 if (!TEST_true(wait_for_thread(t)) || !TEST_true(globserverret))
649 goto err;
650 #else
651 TEST_error("Should not happen");
652 goto err;
653 #endif
654 }
655
656 if (!clienterr && !servererr)
657 ret = 1;
658 err:
659 return ret;
660 }
661
qtest_create_quic_connection(QUIC_TSERVER * qtserv,SSL * clientssl)662 int qtest_create_quic_connection(QUIC_TSERVER *qtserv, SSL *clientssl)
663 {
664 return qtest_create_quic_connection_ex(qtserv, clientssl, SSL_ERROR_NONE);
665 }
666
667 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
668 static TSAN_QUALIFIER int shutdowndone;
669
run_server_shutdown_thread(void)670 static void run_server_shutdown_thread(void)
671 {
672 /*
673 * This will operate in a busy loop because the server does not block,
674 * but should be acceptable because it is local and we expect this to be
675 * fast
676 */
677 do {
678 ossl_quic_tserver_tick(globtserv);
679 } while (!tsan_load(&shutdowndone));
680 }
681 #endif
682
qtest_shutdown(QUIC_TSERVER * qtserv,SSL * clientssl)683 int qtest_shutdown(QUIC_TSERVER *qtserv, SSL *clientssl)
684 {
685 int tickserver = 1;
686 int ret = 0;
687 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
688 /*
689 * Pointless initialisation to avoid bogus compiler warnings about using
690 * t uninitialised
691 */
692 thread_t t = thread_zero;
693
694 ossl_crypto_condvar_free(&client_ready_cond);
695 client_ready_cond = NULL;
696 ossl_crypto_mutex_free(&client_ready_mutex);
697 client_ready_mutex = NULL;
698 #endif
699
700 if (SSL_get_blocking_mode(clientssl) > 0) {
701 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
702 /*
703 * clientssl is blocking. We will need a thread to complete the
704 * connection
705 */
706 globtserv = qtserv;
707 shutdowndone = 0;
708 if (!TEST_true(run_thread(&t, run_server_shutdown_thread)))
709 return 0;
710
711 tickserver = 0;
712 #else
713 TEST_error("No thread support in this build");
714 return 0;
715 #endif
716 }
717
718 /* Busy loop in non-blocking mode. It should be quick because its local */
719 for (;;) {
720 int rc = SSL_shutdown(clientssl);
721
722 if (rc == 1) {
723 ret = 1;
724 break;
725 }
726
727 if (rc < 0)
728 break;
729
730 if (tickserver)
731 ossl_quic_tserver_tick(qtserv);
732 }
733
734 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
735 tsan_store(&shutdowndone, 1);
736 if (!tickserver) {
737 if (!TEST_true(wait_for_thread(t)))
738 ret = 0;
739 }
740 #endif
741
742 return ret;
743 }
744
qtest_check_server_transport_err(QUIC_TSERVER * qtserv,uint64_t code)745 int qtest_check_server_transport_err(QUIC_TSERVER *qtserv, uint64_t code)
746 {
747 const QUIC_TERMINATE_CAUSE *cause;
748
749 ossl_quic_tserver_tick(qtserv);
750
751 /*
752 * Check that the server has closed with the specified code from the client
753 */
754 if (!TEST_true(ossl_quic_tserver_is_term_any(qtserv)))
755 return 0;
756
757 cause = ossl_quic_tserver_get_terminate_cause(qtserv);
758 if (!TEST_ptr(cause)
759 || !TEST_true(cause->remote)
760 || !TEST_false(cause->app)
761 || !TEST_uint64_t_eq(cause->error_code, code))
762 return 0;
763
764 return 1;
765 }
766
qtest_check_server_protocol_err(QUIC_TSERVER * qtserv)767 int qtest_check_server_protocol_err(QUIC_TSERVER *qtserv)
768 {
769 return qtest_check_server_transport_err(qtserv, OSSL_QUIC_ERR_PROTOCOL_VIOLATION);
770 }
771
qtest_check_server_frame_encoding_err(QUIC_TSERVER * qtserv)772 int qtest_check_server_frame_encoding_err(QUIC_TSERVER *qtserv)
773 {
774 return qtest_check_server_transport_err(qtserv, OSSL_QUIC_ERR_FRAME_ENCODING_ERROR);
775 }
776
qtest_fault_free(QTEST_FAULT * fault)777 void qtest_fault_free(QTEST_FAULT *fault)
778 {
779 if (fault == NULL)
780 return;
781
782 packet_plain_finish(fault);
783 handshake_finish(fault);
784
785 OPENSSL_free(fault);
786 }
787
packet_plain_mutate(const QUIC_PKT_HDR * hdrin,const OSSL_QTX_IOVEC * iovecin,size_t numin,QUIC_PKT_HDR ** hdrout,const OSSL_QTX_IOVEC ** iovecout,size_t * numout,void * arg)788 static int packet_plain_mutate(const QUIC_PKT_HDR *hdrin,
789 const OSSL_QTX_IOVEC *iovecin, size_t numin,
790 QUIC_PKT_HDR **hdrout,
791 const OSSL_QTX_IOVEC **iovecout,
792 size_t *numout,
793 void *arg)
794 {
795 QTEST_FAULT *fault = arg;
796 size_t i, bufsz = 0;
797 unsigned char *cur;
798 int grow_allowance;
799
800 /* Coalesce our data into a single buffer */
801
802 /* First calculate required buffer size */
803 for (i = 0; i < numin; i++)
804 bufsz += iovecin[i].buf_len;
805
806 fault->pplainio.buf_len = bufsz;
807
808 /*
809 * 1200 is QUIC payload length we use
810 * bufsz is what we got from txp
811 * 16 is the length of tag added by encryption
812 * 14 long header (we assume token length is 0,
813 * which is fine for server not so fine for client)
814 */
815 grow_allowance = 1200 - bufsz - 16 - 14;
816 grow_allowance -= hdrin->dst_conn_id.id_len;
817 grow_allowance -= hdrin->src_conn_id.id_len;
818 assert(grow_allowance >= 0);
819 bufsz += grow_allowance;
820
821 fault->pplainio.buf = cur = OPENSSL_malloc(bufsz);
822 if (cur == NULL) {
823 fault->pplainio.buf_len = 0;
824 return 0;
825 }
826
827 fault->pplainbuf_alloc = bufsz;
828
829 /* Copy in the data from the input buffers */
830 for (i = 0; i < numin; i++) {
831 memcpy(cur, iovecin[i].buf, iovecin[i].buf_len);
832 cur += iovecin[i].buf_len;
833 }
834
835 fault->pplainhdr = *hdrin;
836
837 /*
838 * Cast below is safe because we allocated the buffer
839 * mutation is best effort. we can inject frame if
840 * there is enough space. If there is not enough space
841 * we must give up.
842 */
843 if (fault->pplaincb != NULL)
844 fault->pplaincb(fault, &fault->pplainhdr,
845 (unsigned char *)fault->pplainio.buf,
846 fault->pplainio.buf_len, fault->pplaincbarg);
847
848 *hdrout = &fault->pplainhdr;
849 *iovecout = &fault->pplainio;
850 *numout = 1;
851
852 return 1;
853 }
854
packet_plain_finish(void * arg)855 static void packet_plain_finish(void *arg)
856 {
857 QTEST_FAULT *fault = arg;
858
859 /* Cast below is safe because we allocated the buffer */
860 OPENSSL_free((unsigned char *)fault->pplainio.buf);
861 fault->pplainio.buf_len = 0;
862 fault->pplainbuf_alloc = 0;
863 fault->pplainio.buf = NULL;
864 }
865
qtest_fault_set_packet_plain_listener(QTEST_FAULT * fault,qtest_fault_on_packet_plain_cb pplaincb,void * pplaincbarg)866 int qtest_fault_set_packet_plain_listener(QTEST_FAULT *fault,
867 qtest_fault_on_packet_plain_cb pplaincb,
868 void *pplaincbarg)
869 {
870 fault->pplaincb = pplaincb;
871 fault->pplaincbarg = pplaincbarg;
872
873 return ossl_quic_tserver_set_plain_packet_mutator(fault->qtserv,
874 packet_plain_mutate,
875 packet_plain_finish,
876 fault);
877 }
878
879 /* To be called from a packet_plain_listener callback */
qtest_fault_resize_plain_packet(QTEST_FAULT * fault,size_t newlen)880 int qtest_fault_resize_plain_packet(QTEST_FAULT *fault, size_t newlen)
881 {
882 unsigned char *buf;
883 size_t oldlen = fault->pplainio.buf_len;
884
885 /*
886 * Alloc'd size should always be non-zero, so if this fails we've been
887 * incorrectly called
888 */
889 if (fault->pplainbuf_alloc == 0)
890 return 0;
891
892 if (newlen > fault->pplainbuf_alloc) {
893 /* This exceeds our growth allowance. Fail */
894 return 0;
895 }
896
897 /* Cast below is safe because we allocated the buffer */
898 buf = (unsigned char *)fault->pplainio.buf;
899
900 if (newlen > oldlen) {
901 /* Extend packet with 0 bytes */
902 memset(buf + oldlen, 0, newlen - oldlen);
903 } /* else we're truncating or staying the same */
904
905 fault->pplainio.buf_len = newlen;
906 fault->pplainhdr.len = newlen;
907
908 return 1;
909 }
910
911 /*
912 * Prepend frame data into a packet. To be called from a packet_plain_listener
913 * callback
914 */
qtest_fault_prepend_frame(QTEST_FAULT * fault,const unsigned char * frame,size_t frame_len)915 int qtest_fault_prepend_frame(QTEST_FAULT *fault, const unsigned char *frame,
916 size_t frame_len)
917 {
918 unsigned char *buf;
919 size_t old_len;
920
921 /*
922 * Alloc'd size should always be non-zero, so if this fails we've been
923 * incorrectly called
924 */
925 if (fault->pplainbuf_alloc == 0)
926 return 0;
927
928 /* Cast below is safe because we allocated the buffer */
929 buf = (unsigned char *)fault->pplainio.buf;
930 old_len = fault->pplainio.buf_len;
931
932 /* Extend the size of the packet by the size of the new frame */
933 if (!TEST_true(qtest_fault_resize_plain_packet(fault,
934 old_len + frame_len)))
935 return 0;
936
937 memmove(buf + frame_len, buf, old_len);
938 memcpy(buf, frame, frame_len);
939
940 return 1;
941 }
942
handshake_mutate(const unsigned char * msgin,size_t msginlen,unsigned char ** msgout,size_t * msgoutlen,void * arg)943 static int handshake_mutate(const unsigned char *msgin, size_t msginlen,
944 unsigned char **msgout, size_t *msgoutlen,
945 void *arg)
946 {
947 QTEST_FAULT *fault = arg;
948 unsigned char *buf;
949 unsigned long payloadlen;
950 unsigned int msgtype;
951 PACKET pkt;
952
953 buf = OPENSSL_malloc(msginlen + GROWTH_ALLOWANCE);
954 if (buf == NULL)
955 return 0;
956
957 fault->handbuf = buf;
958 fault->handbuflen = msginlen;
959 fault->handbufalloc = msginlen + GROWTH_ALLOWANCE;
960 memcpy(buf, msgin, msginlen);
961
962 if (!PACKET_buf_init(&pkt, buf, msginlen)
963 || !PACKET_get_1(&pkt, &msgtype)
964 || !PACKET_get_net_3(&pkt, &payloadlen)
965 || PACKET_remaining(&pkt) != payloadlen)
966 return 0;
967
968 /* Parse specific message types */
969 switch (msgtype) {
970 case SSL3_MT_ENCRYPTED_EXTENSIONS: {
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
handshake_finish(void * arg)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
qtest_fault_set_handshake_listener(QTEST_FAULT * fault,qtest_fault_on_handshake_cb handshakecb,void * handshakecbarg)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
qtest_fault_set_hand_enc_ext_listener(QTEST_FAULT * fault,qtest_fault_on_enc_ext_cb encextcb,void * encextcbarg)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 */
qtest_fault_resize_handshake(QTEST_FAULT * fault,size_t newlen)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 */
qtest_fault_resize_message(QTEST_FAULT * fault,size_t newlen)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
qtest_fault_delete_extension(QTEST_FAULT * fault,unsigned int exttype,unsigned char * ext,size_t * extlen,BUF_MEM * old_ext)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
pcipher_sendmmsg(BIO * b,BIO_MSG * msg,size_t stride,size_t num_msg,uint64_t flags,size_t * num_processed)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
pcipher_ctrl(BIO * b,int cmd,long larg,void * parg)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
pcipher_destroy(BIO * b)1264 static int pcipher_destroy(BIO *b)
1265 {
1266 OPENSSL_free(BIO_get_data(b));
1267 return 1;
1268 }
1269
qtest_get_bio_method(void)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
qtest_fault_set_packet_cipher_listener(QTEST_FAULT * fault,qtest_fault_on_packet_cipher_cb pciphercb,void * pciphercbarg)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
qtest_fault_set_datagram_listener(QTEST_FAULT * fault,qtest_fault_on_datagram_cb datagramcb,void * datagramcbarg)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 */
qtest_fault_resize_datagram(QTEST_FAULT * fault,size_t newlen)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
qtest_fault_set_bw_limit(QTEST_FAULT * fault,size_t ctos_bw,size_t stoc_bw,int noise_rate)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),
1345 1))
1346 return 0;
1347 if (!TEST_int_eq(BIO_ctrl(sbio, BIO_CTRL_NOISE_SEND_BANDWIDTH,
1348 (long)stoc_bw, NULL),
1349 1))
1350 return 0;
1351 return 1;
1352 }
1353
bio_msg_copy(BIO_MSG * dst,BIO_MSG * src)1354 int bio_msg_copy(BIO_MSG *dst, BIO_MSG *src)
1355 {
1356 /*
1357 * Note it is assumed that the originally allocated data sizes for dst and
1358 * src are the same
1359 */
1360 memcpy(dst->data, src->data, src->data_len);
1361 dst->data_len = src->data_len;
1362 dst->flags = src->flags;
1363 if (dst->local != NULL) {
1364 if (src->local != NULL) {
1365 if (!TEST_true(BIO_ADDR_copy(dst->local, src->local)))
1366 return 0;
1367 } else {
1368 BIO_ADDR_clear(dst->local);
1369 }
1370 }
1371 if (!TEST_true(BIO_ADDR_copy(dst->peer, src->peer)))
1372 return 0;
1373
1374 return 1;
1375 }
1376