Enable tracing of packets that have been sent
[openssl.git] / test / helpers / quictestlib.c
1 /*
2  * Copyright 2022 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 "quictestlib.h"
14 #include "ssltestlib.h"
15 #include "../testutil.h"
16 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
17 # include "../threadstest.h"
18 #endif
19 #include "internal/quic_wire_pkt.h"
20 #include "internal/quic_record_tx.h"
21 #include "internal/quic_error.h"
22 #include "internal/packet.h"
23
24 #define GROWTH_ALLOWANCE 1024
25
26 struct qtest_fault {
27     QUIC_TSERVER *qtserv;
28
29     /* Plain packet mutations */
30     /* Header for the plaintext packet */
31     QUIC_PKT_HDR pplainhdr;
32     /* iovec for the plaintext packet data buffer */
33     OSSL_QTX_IOVEC pplainio;
34     /* Allocted size of the plaintext packet data buffer */
35     size_t pplainbuf_alloc;
36     qtest_fault_on_packet_plain_cb pplaincb;
37     void *pplaincbarg;
38
39     /* Handshake message mutations */
40     /* Handshake message buffer */
41     unsigned char *handbuf;
42     /* Allocated size of the handshake message buffer */
43     size_t handbufalloc;
44     /* Actual length of the handshake message */
45     size_t handbuflen;
46     qtest_fault_on_handshake_cb handshakecb;
47     void *handshakecbarg;
48     qtest_fault_on_enc_ext_cb encextcb;
49     void *encextcbarg;
50
51     /* Cipher packet mutations */
52     qtest_fault_on_packet_cipher_cb pciphercb;
53     void *pciphercbarg;
54
55     /* Datagram mutations */
56     qtest_fault_on_datagram_cb datagramcb;
57     void *datagramcbarg;
58     /* The currently processed message */
59     BIO_MSG msg;
60     /* Allocated size of msg data buffer */
61     size_t msgalloc;
62 };
63
64 static void packet_plain_finish(void *arg);
65 static void handshake_finish(void *arg);
66
67 static BIO_METHOD *get_bio_method(void);
68
69 int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx,
70                               char *certfile, char *keyfile,
71                               int block, QUIC_TSERVER **qtserv, SSL **cssl,
72                               QTEST_FAULT **fault)
73 {
74     /* ALPN value as recognised by QUIC_TSERVER */
75     unsigned char alpn[] = { 8, 'o', 's', 's', 'l', 't', 'e', 's', 't' };
76     QUIC_TSERVER_ARGS tserver_args = {0};
77     BIO *cbio = NULL, *sbio = NULL, *fisbio = NULL;
78     BIO_ADDR *peeraddr = NULL;
79     struct in_addr ina = {0};
80
81     *qtserv = NULL;
82     if (fault != NULL)
83         *fault = NULL;
84     *cssl = SSL_new(clientctx);
85     if (!TEST_ptr(*cssl))
86         return 0;
87
88     /* SSL_set_alpn_protos returns 0 for success! */
89     if (!TEST_false(SSL_set_alpn_protos(*cssl, alpn, sizeof(alpn))))
90         goto err;
91
92     if (!TEST_ptr(peeraddr = BIO_ADDR_new()))
93         goto err;
94
95     if (block) {
96 #if !defined(OPENSSL_NO_POSIX_IO)
97         int cfd, sfd;
98
99         /*
100          * For blocking mode we need to create actual sockets rather than doing
101          * everything in memory
102          */
103         if (!TEST_true(create_test_sockets(&cfd, &sfd, SOCK_DGRAM, peeraddr)))
104             goto err;
105         cbio = BIO_new_dgram(cfd, 1);
106         if (!TEST_ptr(cbio)) {
107             close(cfd);
108             close(sfd);
109             goto err;
110         }
111         sbio = BIO_new_dgram(sfd, 1);
112         if (!TEST_ptr(sbio)) {
113             close(sfd);
114             goto err;
115         }
116 #else
117         goto err;
118 #endif
119     } else {
120         if (!TEST_true(BIO_new_bio_dgram_pair(&cbio, 0, &sbio, 0)))
121             goto err;
122
123         if (!TEST_true(BIO_dgram_set_caps(cbio, BIO_DGRAM_CAP_HANDLES_DST_ADDR))
124                 || !TEST_true(BIO_dgram_set_caps(sbio, BIO_DGRAM_CAP_HANDLES_DST_ADDR)))
125             goto err;
126
127         /* Dummy server address */
128         if (!TEST_true(BIO_ADDR_rawmake(peeraddr, AF_INET, &ina, sizeof(ina),
129                                         htons(0))))
130             goto err;
131     }
132
133     SSL_set_bio(*cssl, cbio, cbio);
134
135     if (!TEST_true(SSL_set_blocking_mode(*cssl, block)))
136         goto err;
137
138     if (!TEST_true(SSL_set_initial_peer_addr(*cssl, peeraddr)))
139         goto err;
140
141     if (fault != NULL) {
142         *fault = OPENSSL_zalloc(sizeof(**fault));
143         if (*fault == NULL)
144             goto err;
145     }
146
147     fisbio = BIO_new(get_bio_method());
148     if (!TEST_ptr(fisbio))
149         goto err;
150
151     BIO_set_data(fisbio, fault == NULL ? NULL : *fault);
152
153     if (!TEST_ptr(BIO_push(fisbio, sbio)))
154         goto err;
155
156     tserver_args.libctx = libctx;
157     tserver_args.net_rbio = sbio;
158     tserver_args.net_wbio = fisbio;
159
160     if (!TEST_ptr(*qtserv = ossl_quic_tserver_new(&tserver_args, certfile,
161                                                   keyfile)))
162         goto err;
163
164     /* Ownership of fisbio and sbio is now held by *qtserv */
165     sbio = NULL;
166     fisbio = NULL;
167
168     if (fault != NULL)
169         (*fault)->qtserv = *qtserv;
170
171     BIO_ADDR_free(peeraddr);
172
173     return 1;
174  err:
175     BIO_ADDR_free(peeraddr);
176     BIO_free(cbio);
177     BIO_free(fisbio);
178     BIO_free(sbio);
179     SSL_free(*cssl);
180     *cssl = NULL;
181     ossl_quic_tserver_free(*qtserv);
182     if (fault != NULL)
183         OPENSSL_free(*fault);
184
185     return 0;
186 }
187
188 int qtest_supports_blocking(void)
189 {
190 #if !defined(OPENSSL_NO_POSIX_IO) && defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
191     return 1;
192 #else
193     return 0;
194 #endif
195 }
196
197 #define MAXLOOPS    1000
198
199 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
200 static int globserverret = 0;
201 static QUIC_TSERVER *globtserv;
202 static const thread_t thread_zero;
203
204 static void run_server_thread(void)
205 {
206     /*
207      * This will operate in a busy loop because the server does not block,
208      * but should be acceptable because it is local and we expect this to be
209      * fast
210      */
211     globserverret = qtest_create_quic_connection(globtserv, NULL);
212 }
213 #endif
214
215 int qtest_create_quic_connection(QUIC_TSERVER *qtserv, SSL *clientssl)
216 {
217     int retc = -1, rets = 0, err, abortctr = 0, ret = 0;
218     int clienterr = 0, servererr = 0;
219 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
220     /*
221      * Pointless initialisation to avoid bogus compiler warnings about using
222      * t uninitialised
223      */
224     thread_t t = thread_zero;
225 #endif
226
227     if (!TEST_ptr(qtserv)) {
228         goto err;
229     } else if (clientssl == NULL) {
230         retc = 1;
231     } else if (SSL_get_blocking_mode(clientssl) > 0) {
232 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
233         /*
234          * clientssl is blocking. We will need a thread to complete the
235          * connection
236          */
237         globtserv = qtserv;
238         if (!TEST_true(run_thread(&t, run_server_thread)))
239             goto err;
240
241         qtserv = NULL;
242         rets = 1;
243 #else
244         TEST_error("No thread support in this build");
245         goto err;
246 #endif
247     }
248
249     do {
250         err = SSL_ERROR_WANT_WRITE;
251         while (!clienterr && retc <= 0 && err == SSL_ERROR_WANT_WRITE) {
252             retc = SSL_connect(clientssl);
253             if (retc <= 0)
254                 err = SSL_get_error(clientssl, retc);
255         }
256
257         if (!clienterr && retc <= 0 && err != SSL_ERROR_WANT_READ) {
258             TEST_info("SSL_connect() failed %d, %d", retc, err);
259             TEST_openssl_errors();
260             clienterr = 1;
261         }
262
263         /*
264          * We're cheating. We don't take any notice of SSL_get_tick_timeout()
265          * and tick everytime around the loop anyway. This is inefficient. We
266          * can get away with it in test code because we control both ends of
267          * the communications and don't expect network delays. This shouldn't
268          * be done in a real application.
269          */
270         if (!clienterr && retc <= 0)
271             SSL_tick(clientssl);
272         if (!servererr && rets <= 0) {
273             ossl_quic_tserver_tick(qtserv);
274             servererr = ossl_quic_tserver_is_term_any(qtserv);
275             if (!servererr)
276                 rets = ossl_quic_tserver_is_handshake_confirmed(qtserv);
277         }
278
279         if (clienterr && servererr)
280             goto err;
281
282         if (clientssl != NULL && ++abortctr == MAXLOOPS) {
283             TEST_info("No progress made");
284             goto err;
285         }
286     } while ((retc <= 0 && !clienterr) || (rets <= 0 && !servererr));
287
288     if (qtserv == NULL && rets > 0) {
289 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
290         if (!TEST_true(wait_for_thread(t)) || !TEST_true(globserverret))
291             goto err;
292 #else
293         TEST_error("Should not happen");
294         goto err;
295 #endif
296     }
297
298     if (!clienterr && !servererr)
299         ret = 1;
300  err:
301     return ret;
302 }
303
304 int qtest_shutdown(QUIC_TSERVER *qtserv, SSL *clientssl)
305 {
306     /* Busy loop in non-blocking mode. It should be quick because its local */
307     while (SSL_shutdown(clientssl) != 1)
308         ossl_quic_tserver_tick(qtserv);
309
310     return 1;
311 }
312
313 int qtest_check_server_transport_err(QUIC_TSERVER *qtserv, uint64_t code)
314 {
315     const QUIC_TERMINATE_CAUSE *cause;
316
317     ossl_quic_tserver_tick(qtserv);
318
319     /*
320      * Check that the server has closed with the specified code from the client
321      */
322     if (!TEST_true(ossl_quic_tserver_is_term_any(qtserv)))
323         return 0;
324
325     cause = ossl_quic_tserver_get_terminate_cause(qtserv);
326     if  (!TEST_ptr(cause)
327             || !TEST_true(cause->remote)
328             || !TEST_uint64_t_eq(cause->error_code, code))
329         return 0;
330
331     return 1;
332 }
333
334 int qtest_check_server_protocol_err(QUIC_TSERVER *qtserv)
335 {
336     return qtest_check_server_transport_err(qtserv, QUIC_ERR_PROTOCOL_VIOLATION);
337 }
338
339 void qtest_fault_free(QTEST_FAULT *fault)
340 {
341     if (fault == NULL)
342         return;
343
344     packet_plain_finish(fault);
345     handshake_finish(fault);
346
347     OPENSSL_free(fault);
348 }
349
350 static int packet_plain_mutate(const QUIC_PKT_HDR *hdrin,
351                                const OSSL_QTX_IOVEC *iovecin, size_t numin,
352                                QUIC_PKT_HDR **hdrout,
353                                const OSSL_QTX_IOVEC **iovecout,
354                                size_t *numout,
355                                void *arg)
356 {
357     QTEST_FAULT *fault = arg;
358     size_t i, bufsz = 0;
359     unsigned char *cur;
360
361     /* Coalesce our data into a single buffer */
362
363     /* First calculate required buffer size */
364     for (i = 0; i < numin; i++)
365         bufsz += iovecin[i].buf_len;
366
367     fault->pplainio.buf_len = bufsz;
368
369     /* Add an allowance for possible growth */
370     bufsz += GROWTH_ALLOWANCE;
371
372     fault->pplainio.buf = cur = OPENSSL_malloc(bufsz);
373     if (cur == NULL) {
374         fault->pplainio.buf_len = 0;
375         return 0;
376     }
377
378     fault->pplainbuf_alloc = bufsz;
379
380     /* Copy in the data from the input buffers */
381     for (i = 0; i < numin; i++) {
382         memcpy(cur, iovecin[i].buf, iovecin[i].buf_len);
383         cur += iovecin[i].buf_len;
384     }
385
386     fault->pplainhdr = *hdrin;
387
388     /* Cast below is safe because we allocated the buffer */
389     if (fault->pplaincb != NULL
390             && !fault->pplaincb(fault, &fault->pplainhdr,
391                                 (unsigned char *)fault->pplainio.buf,
392                                 fault->pplainio.buf_len, fault->pplaincbarg))
393         return 0;
394
395     *hdrout = &fault->pplainhdr;
396     *iovecout = &fault->pplainio;
397     *numout = 1;
398
399     return 1;
400 }
401
402 static void packet_plain_finish(void *arg)
403 {
404     QTEST_FAULT *fault = arg;
405
406     /* Cast below is safe because we allocated the buffer */
407     OPENSSL_free((unsigned char *)fault->pplainio.buf);
408     fault->pplainio.buf_len = 0;
409     fault->pplainbuf_alloc = 0;
410     fault->pplainio.buf = NULL;
411 }
412
413 int qtest_fault_set_packet_plain_listener(QTEST_FAULT *fault,
414                                           qtest_fault_on_packet_plain_cb pplaincb,
415                                           void *pplaincbarg)
416 {
417     fault->pplaincb = pplaincb;
418     fault->pplaincbarg = pplaincbarg;
419
420     return ossl_quic_tserver_set_plain_packet_mutator(fault->qtserv,
421                                                       packet_plain_mutate,
422                                                       packet_plain_finish,
423                                                       fault);
424 }
425
426 /* To be called from a packet_plain_listener callback */
427 int qtest_fault_resize_plain_packet(QTEST_FAULT *fault, size_t newlen)
428 {
429     unsigned char *buf;
430     size_t oldlen = fault->pplainio.buf_len;
431
432     /*
433      * Alloc'd size should always be non-zero, so if this fails we've been
434      * incorrectly called
435      */
436     if (fault->pplainbuf_alloc == 0)
437         return 0;
438
439     if (newlen > fault->pplainbuf_alloc) {
440         /* This exceeds our growth allowance. Fail */
441         return 0;
442     }
443
444     /* Cast below is safe because we allocated the buffer */
445     buf = (unsigned char *)fault->pplainio.buf;
446
447     if (newlen > oldlen) {
448         /* Extend packet with 0 bytes */
449         memset(buf + oldlen, 0, newlen - oldlen);
450     } /* else we're truncating or staying the same */
451
452     fault->pplainio.buf_len = newlen;
453     fault->pplainhdr.len = newlen;
454
455     return 1;
456 }
457
458 /*
459  * Prepend frame data into a packet. To be called from a packet_plain_listener
460  * callback
461  */
462 int qtest_fault_prepend_frame(QTEST_FAULT *fault, unsigned char *frame,
463                               size_t frame_len)
464 {
465     unsigned char *buf;
466     size_t old_len;
467
468     /*
469      * Alloc'd size should always be non-zero, so if this fails we've been
470      * incorrectly called
471      */
472     if (fault->pplainbuf_alloc == 0)
473         return 0;
474
475     /* Cast below is safe because we allocated the buffer */
476     buf = (unsigned char *)fault->pplainio.buf;
477     old_len = fault->pplainio.buf_len;
478
479     /* Extend the size of the packet by the size of the new frame */
480     if (!TEST_true(qtest_fault_resize_plain_packet(fault,
481                                                    old_len + frame_len)))
482         return 0;
483
484     memmove(buf + frame_len, buf, old_len);
485     memcpy(buf, frame, frame_len);
486
487     return 1;
488 }
489
490 static int handshake_mutate(const unsigned char *msgin, size_t msginlen,
491                             unsigned char **msgout, size_t *msgoutlen,
492                             void *arg)
493 {
494     QTEST_FAULT *fault = arg;
495     unsigned char *buf;
496     unsigned long payloadlen;
497     unsigned int msgtype;
498     PACKET pkt;
499
500     buf = OPENSSL_malloc(msginlen + GROWTH_ALLOWANCE);
501     if (buf == NULL)
502         return 0;
503
504     fault->handbuf = buf;
505     fault->handbuflen = msginlen;
506     fault->handbufalloc = msginlen + GROWTH_ALLOWANCE;
507     memcpy(buf, msgin, msginlen);
508
509     if (!PACKET_buf_init(&pkt, buf, msginlen)
510             || !PACKET_get_1(&pkt, &msgtype)
511             || !PACKET_get_net_3(&pkt, &payloadlen)
512             || PACKET_remaining(&pkt) != payloadlen)
513         return 0;
514
515     /* Parse specific message types */
516     switch (msgtype) {
517     case SSL3_MT_ENCRYPTED_EXTENSIONS:
518     {
519         QTEST_ENCRYPTED_EXTENSIONS ee;
520
521         if (fault->encextcb == NULL)
522             break;
523
524         /*
525          * The EncryptedExtensions message is very simple. It just has an
526          * extensions block in it and nothing else.
527          */
528         ee.extensions = (unsigned char *)PACKET_data(&pkt);
529         ee.extensionslen = payloadlen;
530         if (!fault->encextcb(fault, &ee, payloadlen, fault->encextcbarg))
531             return 0;
532     }
533
534     default:
535         /* No specific handlers for these message types yet */
536         break;
537     }
538
539     if (fault->handshakecb != NULL
540             && !fault->handshakecb(fault, buf, fault->handbuflen,
541                                    fault->handshakecbarg))
542         return 0;
543
544     *msgout = buf;
545     *msgoutlen = fault->handbuflen;
546
547     return 1;
548 }
549
550 static void handshake_finish(void *arg)
551 {
552     QTEST_FAULT *fault = arg;
553
554     OPENSSL_free(fault->handbuf);
555     fault->handbuf = NULL;
556 }
557
558 int qtest_fault_set_handshake_listener(QTEST_FAULT *fault,
559                                        qtest_fault_on_handshake_cb handshakecb,
560                                        void *handshakecbarg)
561 {
562     fault->handshakecb = handshakecb;
563     fault->handshakecbarg = handshakecbarg;
564
565     return ossl_quic_tserver_set_handshake_mutator(fault->qtserv,
566                                                    handshake_mutate,
567                                                    handshake_finish,
568                                                    fault);
569 }
570
571 int qtest_fault_set_hand_enc_ext_listener(QTEST_FAULT *fault,
572                                           qtest_fault_on_enc_ext_cb encextcb,
573                                           void *encextcbarg)
574 {
575     fault->encextcb = encextcb;
576     fault->encextcbarg = encextcbarg;
577
578     return ossl_quic_tserver_set_handshake_mutator(fault->qtserv,
579                                                    handshake_mutate,
580                                                    handshake_finish,
581                                                    fault);
582 }
583
584 /* To be called from a handshake_listener callback */
585 int qtest_fault_resize_handshake(QTEST_FAULT *fault, size_t newlen)
586 {
587     unsigned char *buf;
588     size_t oldlen = fault->handbuflen;
589
590     /*
591      * Alloc'd size should always be non-zero, so if this fails we've been
592      * incorrectly called
593      */
594     if (fault->handbufalloc == 0)
595         return 0;
596
597     if (newlen > fault->handbufalloc) {
598         /* This exceeds our growth allowance. Fail */
599         return 0;
600     }
601
602     buf = (unsigned char *)fault->handbuf;
603
604     if (newlen > oldlen) {
605         /* Extend packet with 0 bytes */
606         memset(buf + oldlen, 0, newlen - oldlen);
607     } /* else we're truncating or staying the same */
608
609     fault->handbuflen = newlen;
610     return 1;
611 }
612
613 /* To be called from message specific listener callbacks */
614 int qtest_fault_resize_message(QTEST_FAULT *fault, size_t newlen)
615 {
616     /* First resize the underlying message */
617     if (!qtest_fault_resize_handshake(fault, newlen + SSL3_HM_HEADER_LENGTH))
618         return 0;
619
620     /* Fixup the handshake message header */
621     fault->handbuf[1] = (unsigned char)((newlen >> 16) & 0xff);
622     fault->handbuf[2] = (unsigned char)((newlen >>  8) & 0xff);
623     fault->handbuf[3] = (unsigned char)((newlen      ) & 0xff);
624
625     return 1;
626 }
627
628 int qtest_fault_delete_extension(QTEST_FAULT *fault,
629                                  unsigned int exttype, unsigned char *ext,
630                                  size_t *extlen)
631 {
632     PACKET pkt, sub, subext;
633     unsigned int type;
634     const unsigned char *start, *end;
635     size_t newlen;
636     size_t msglen = fault->handbuflen;
637
638     if (!PACKET_buf_init(&pkt, ext, *extlen))
639         return 0;
640
641     /* Extension block starts with 2 bytes for extension block length */
642     if (!PACKET_as_length_prefixed_2(&pkt, &sub))
643         return 0;
644
645     do {
646         start = PACKET_data(&sub);
647         if (!PACKET_get_net_2(&sub, &type)
648                 || !PACKET_get_length_prefixed_2(&sub, &subext))
649             return 0;
650     } while (type != exttype);
651
652     /* Found it */
653     end = PACKET_data(&sub);
654
655     /*
656      * If we're not the last extension we need to move the rest earlier. The
657      * cast below is safe because we own the underlying buffer and we're no
658      * longer making PACKET calls.
659      */
660     if (end < ext + *extlen)
661         memmove((unsigned char *)start, end, end - start);
662
663     /*
664      * Calculate new extensions payload length =
665      * Original length
666      * - 2 extension block length bytes
667      * - length of removed extension
668      */
669     newlen = *extlen - 2 - (end - start);
670
671     /* Fixup the length bytes for the extension block */
672     ext[0] = (unsigned char)((newlen >> 8) & 0xff);
673     ext[1] = (unsigned char)((newlen     ) & 0xff);
674
675     /*
676      * Length of the whole extension block is the new payload length plus the
677      * 2 bytes for the length
678      */
679     *extlen = newlen + 2;
680
681     /* We can now resize the message */
682     if ((size_t)(end - start) + SSL3_HM_HEADER_LENGTH > msglen)
683         return 0; /* Should not happen */
684     msglen -= (end - start) + SSL3_HM_HEADER_LENGTH;
685     if (!qtest_fault_resize_message(fault, msglen))
686         return 0;
687
688     return 1;
689 }
690
691 #define BIO_TYPE_CIPHER_PACKET_FILTER  (0x80 | BIO_TYPE_FILTER)
692
693 static BIO_METHOD *pcipherbiometh = NULL;
694
695 # define BIO_MSG_N(array, stride, n) (*(BIO_MSG *)((char *)(array) + (n)*(stride)))
696
697 static int pcipher_sendmmsg(BIO *b, BIO_MSG *msg, size_t stride,
698                             size_t num_msg, uint64_t flags,
699                             size_t *num_processed)
700 {
701     QTEST_FAULT *fault;
702     BIO *next = BIO_next(b);
703     ossl_ssize_t ret = 0;
704     size_t i = 0, tmpnump;
705     QUIC_PKT_HDR hdr;
706     PACKET pkt;
707     unsigned char *tmpdata;
708
709     if (next == NULL)
710         return 0;
711
712     fault = BIO_get_data(b);
713     if (fault == NULL
714             || (fault->pciphercb == NULL && fault->datagramcb == NULL))
715         return BIO_sendmmsg(next, msg, stride, num_msg, flags, num_processed);
716
717     if (num_msg == 0) {
718         *num_processed = 0;
719         return 1;
720     }
721
722     for (i = 0; i < num_msg; ++i) {
723         fault->msg = BIO_MSG_N(msg, stride, i);
724
725         /* Take a copy of the data so that callbacks can modify it */
726         tmpdata = OPENSSL_malloc(fault->msg.data_len + GROWTH_ALLOWANCE);
727         if (tmpdata == NULL)
728             return 0;
729         memcpy(tmpdata, fault->msg.data, fault->msg.data_len);
730         fault->msg.data = tmpdata;
731         fault->msgalloc = fault->msg.data_len + GROWTH_ALLOWANCE;
732
733         if (fault->pciphercb != NULL) {
734             if (!PACKET_buf_init(&pkt, fault->msg.data, fault->msg.data_len))
735                 return 0;
736
737             do {
738                 if (!ossl_quic_wire_decode_pkt_hdr(&pkt,
739                         0 /* TODO(QUIC): Not sure how this should be set*/, 1,
740                         0, &hdr, NULL))
741                     goto out;
742
743                 /*
744                  * hdr.data is const - but its our buffer so casting away the
745                  * const is safe
746                  */
747                 if (!fault->pciphercb(fault, &hdr, (unsigned char *)hdr.data,
748                                     hdr.len, fault->pciphercbarg))
749                     goto out;
750
751                 /*
752                  * TODO(QUIC): At the moment modifications to hdr by the callback
753                  * are ignored. We might need to rewrite the QUIC header to
754                  * enable tests to change this. We also don't yet have a
755                  * mechanism for the callback to change the encrypted data
756                  * length. It's not clear if that's needed or not.
757                  */
758             } while (PACKET_remaining(&pkt) > 0);
759         }
760
761         if (fault->datagramcb != NULL
762                 && !fault->datagramcb(fault, &fault->msg, stride,
763                                       fault->datagramcbarg))
764             goto out;
765
766         if (!BIO_sendmmsg(next, &fault->msg, stride, 1, flags, &tmpnump)) {
767             *num_processed = i;
768             goto out;
769         }
770
771         OPENSSL_free(fault->msg.data);
772         fault->msg.data = NULL;
773         fault->msgalloc = 0;
774     }
775
776     *num_processed = i;
777 out:
778     ret = i > 0;
779     OPENSSL_free(fault->msg.data);
780     fault->msg.data = NULL;
781     return ret;
782 }
783
784 static long pcipher_ctrl(BIO *b, int cmd, long larg, void *parg)
785 {
786     BIO *next = BIO_next(b);
787
788     if (next == NULL)
789         return -1;
790
791     return BIO_ctrl(next, cmd, larg, parg);
792 }
793
794 static BIO_METHOD *get_bio_method(void)
795 {
796     BIO_METHOD *tmp;
797
798     if (pcipherbiometh != NULL)
799         return pcipherbiometh;
800
801     tmp = BIO_meth_new(BIO_TYPE_CIPHER_PACKET_FILTER, "Cipher Packet Filter");
802
803     if (!TEST_ptr(tmp))
804         return NULL;
805
806     if (!TEST_true(BIO_meth_set_sendmmsg(tmp, pcipher_sendmmsg))
807             || !TEST_true(BIO_meth_set_ctrl(tmp, pcipher_ctrl)))
808         goto err;
809
810     pcipherbiometh = tmp;
811     tmp = NULL;
812  err:
813     BIO_meth_free(tmp);
814     return pcipherbiometh;
815 }
816
817 int qtest_fault_set_packet_cipher_listener(QTEST_FAULT *fault,
818                                            qtest_fault_on_packet_cipher_cb pciphercb,
819                                            void *pciphercbarg)
820 {
821     fault->pciphercb = pciphercb;
822     fault->pciphercbarg = pciphercbarg;
823
824     return 1;
825 }
826
827 int qtest_fault_set_datagram_listener(QTEST_FAULT *fault,
828                                       qtest_fault_on_datagram_cb datagramcb,
829                                       void *datagramcbarg)
830 {
831     fault->datagramcb = datagramcb;
832     fault->datagramcbarg = datagramcbarg;
833
834     return 1;
835 }
836
837 /* To be called from a datagram_listener callback */
838 int qtest_fault_resize_datagram(QTEST_FAULT *fault, size_t newlen)
839 {
840     if (newlen > fault->msgalloc)
841             return 0;
842
843     if (newlen > fault->msg.data_len)
844         memset((unsigned char *)fault->msg.data + fault->msg.data_len, 0,
845                 newlen - fault->msg.data_len);
846
847     fault->msg.data_len = newlen;
848
849     return 1;
850 }