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