xref: /freebsd/crypto/openssl/test/helpers/quictestlib.c (revision e7be843b4a162e68651d3911f0357ed464915629)
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), 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 
qtest_add_time(uint64_t millis)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 
qtest_get_time(void)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 
qtest_reset_time(void)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 
qtest_start_stopwatch(void)421 void qtest_start_stopwatch(void)
422 {
423     start_time = qtest_get_time();
424 }
425 
qtest_get_stopwatch_time(void)426 uint64_t qtest_get_stopwatch_time(void)
427 {
428     return ossl_time2ms(ossl_time_subtract(qtest_get_time(), start_time));
429 }
430 
qtest_create_injector(QUIC_TSERVER * ts)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 
qtest_supports_blocking(void)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;
run_server_thread(void)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 
qtest_wait_for_timeout(SSL * s,QUIC_TSERVER * qtserv)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 
qtest_create_quic_connection_ex(QUIC_TSERVER * qtserv,SSL * clientssl,int wanterr)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 
qtest_create_quic_connection(QUIC_TSERVER * qtserv,SSL * clientssl)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 
run_server_shutdown_thread(void)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 
qtest_shutdown(QUIC_TSERVER * qtserv,SSL * clientssl)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 
qtest_check_server_transport_err(QUIC_TSERVER * qtserv,uint64_t code)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 
qtest_check_server_protocol_err(QUIC_TSERVER * qtserv)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 
qtest_check_server_frame_encoding_err(QUIC_TSERVER * qtserv)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 
qtest_fault_free(QTEST_FAULT * fault)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 
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)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 
packet_plain_finish(void * arg)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 
qtest_fault_set_packet_plain_listener(QTEST_FAULT * fault,qtest_fault_on_packet_plain_cb pplaincb,void * pplaincbarg)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 */
qtest_fault_resize_plain_packet(QTEST_FAULT * fault,size_t newlen)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  */
qtest_fault_prepend_frame(QTEST_FAULT * fault,const unsigned char * frame,size_t frame_len)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 
handshake_mutate(const unsigned char * msgin,size_t msginlen,unsigned char ** msgout,size_t * msgoutlen,void * arg)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 
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), 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 
bio_msg_copy(BIO_MSG * dst,BIO_MSG * src)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 }
1375