2 * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved.
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
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"
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"
27 #define GROWTH_ALLOWANCE 1024
29 struct noise_args_data_st
{
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
;
49 /* Handshake message mutations */
50 /* Handshake message buffer */
51 unsigned char *handbuf
;
52 /* Allocated size of the handshake message buffer */
54 /* Actual length of the handshake message */
56 qtest_fault_on_handshake_cb handshakecb
;
58 qtest_fault_on_enc_ext_cb encextcb
;
61 /* Cipher packet mutations */
62 qtest_fault_on_packet_cipher_cb pciphercb
;
65 /* Datagram mutations */
66 qtest_fault_on_datagram_cb datagramcb
;
68 /* The currently processed message */
70 /* Allocated size of msg data buffer */
72 struct noise_args_data_st noiseargs
;
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
;
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);
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
;
91 static OSSL_TIME
fake_now_cb(void *arg
)
93 return qtest_get_time();
96 static void noise_msg_callback(int write_p
, int version
, int content_type
,
97 const void *buf
, size_t len
, SSL
*ssl
,
100 struct noise_args_data_st
*noiseargs
= (struct noise_args_data_st
*)arg
;
102 if (content_type
== SSL3_RT_QUIC_FRAME_FULL
) {
106 if (!PACKET_buf_init(&pkt
, buf
, len
))
109 if (!ossl_quic_wire_peek_frame_header(&pkt
, &frame_type
, NULL
))
112 if (frame_type
== OSSL_QUIC_FRAME_TYPE_PING
) {
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.
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
);
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
);
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
)
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};
143 QTEST_DATA
*bdata
= NULL
;
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
)
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
;
162 bdata
= OPENSSL_zalloc(sizeof(QTEST_DATA
));
169 *fault
= OPENSSL_zalloc(sizeof(**fault
));
172 bdata
->fault
= *fault
;
176 *cssl
= SSL_new(clientctx
);
177 if (!TEST_ptr(*cssl
))
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
))
187 SSL_set_msg_callback(*cssl
, SSL_trace
);
188 SSL_set_msg_callback_arg(*cssl
, tmpbio
);
191 if (tracebio
!= NULL
)
194 /* SSL_set_alpn_protos returns 0 for success! */
195 if (!TEST_false(SSL_set_alpn_protos(*cssl
, alpn
, sizeof(alpn
))))
198 if (!TEST_ptr(peeraddr
= BIO_ADDR_new()))
201 if ((flags
& QTEST_FLAG_BLOCK
) != 0) {
202 #if !defined(OPENSSL_NO_POSIX_IO)
206 * For blocking mode we need to create actual sockets rather than doing
207 * everything in memory
209 if (!TEST_true(create_test_sockets(&cfd
, &sfd
, SOCK_DGRAM
, peeraddr
)))
211 cbio
= BIO_new_dgram(cfd
, 1);
212 if (!TEST_ptr(cbio
)) {
217 sbio
= BIO_new_dgram(sfd
, 1);
218 if (!TEST_ptr(sbio
)) {
226 BIO_ADDR
*localaddr
= NULL
;
228 if (!TEST_true(BIO_new_bio_dgram_pair(&cbio
, 0, &sbio
, 0)))
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
)))
235 if (!TEST_ptr(localaddr
= BIO_ADDR_new()))
237 /* Dummy client local addresses */
238 if (!TEST_true(BIO_ADDR_rawmake(localaddr
, AF_INET
, &ina
, sizeof(ina
),
240 BIO_ADDR_free(localaddr
);
243 if (!TEST_int_eq(BIO_dgram_set0_local_addr(cbio
, localaddr
), 1)) {
244 BIO_ADDR_free(localaddr
);
247 /* Dummy server address */
248 if (!TEST_true(BIO_ADDR_rawmake(peeraddr
, AF_INET
, &ina
, sizeof(ina
),
253 if ((flags
& QTEST_FLAG_PACKET_SPLIT
) != 0) {
254 BIO
*pktsplitbio
= BIO_new(bio_f_pkt_split_dgram_filter());
256 if (!TEST_ptr(pktsplitbio
))
258 cbio
= BIO_push(pktsplitbio
, cbio
);
259 BIO_set_data(pktsplitbio
, bdata
);
261 pktsplitbio
= BIO_new(bio_f_pkt_split_dgram_filter());
262 if (!TEST_ptr(pktsplitbio
))
264 sbio
= BIO_push(pktsplitbio
, sbio
);
265 BIO_set_data(pktsplitbio
, bdata
);
268 if ((flags
& QTEST_FLAG_NOISE
) != 0) {
270 struct bio_noise_now_cb_st now_cb
= { fake_now_cb
, NULL
};
273 * It is an error to not have a QTEST_FAULT object when introducing noise
275 if (!TEST_ptr(fault
))
278 noisebio
= BIO_new(bio_f_noisy_dgram_filter());
280 if (!TEST_ptr(noisebio
))
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
,
289 noisebio
= BIO_new(bio_f_noisy_dgram_filter());
291 if (!TEST_ptr(noisebio
))
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
,
300 (void)BIO_ctrl(sbio
, BIO_CTRL_NOISE_BACK_OFF
, 2, NULL
);
302 (*fault
)->noiseargs
.cbio
= cbio
;
303 (*fault
)->noiseargs
.sbio
= sbio
;
304 (*fault
)->noiseargs
.tracebio
= tmpbio
;
305 (*fault
)->noiseargs
.flags
= flags
;
307 SSL_set_msg_callback(*cssl
, noise_msg_callback
);
308 SSL_set_msg_callback_arg(*cssl
, &(*fault
)->noiseargs
);
311 SSL_set_bio(*cssl
, cbio
, cbio
);
313 if (!TEST_true(SSL_set_blocking_mode(*cssl
,
314 (flags
& QTEST_FLAG_BLOCK
) != 0 ? 1 : 0)))
317 if (!TEST_true(SSL_set1_initial_peer_addr(*cssl
, peeraddr
)))
320 fisbio
= BIO_new(qtest_get_bio_method());
321 if (!TEST_ptr(fisbio
))
324 BIO_set_data(fisbio
, bdata
);
326 if (!BIO_up_ref(sbio
))
328 if (!TEST_ptr(BIO_push(fisbio
, sbio
))) {
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
)))
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
)
345 if ((flags
& QTEST_FLAG_FAKE_TIME
) != 0) {
348 tserver_args
.now_cb
= fake_now_cb
;
349 (void)ossl_quic_set_override_now_cb(*cssl
, fake_now_cb
, NULL
);
354 if (!TEST_ptr(*qtserv
= ossl_quic_tserver_new(&tserver_args
, certfile
,
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 */
363 if ((flags
& QTEST_FLAG_NOISE
) != 0)
364 ossl_quic_tserver_set_msg_callback(*qtserv
, noise_msg_callback
,
365 &(*fault
)->noiseargs
);
368 (*fault
)->qtserv
= *qtserv
;
370 BIO_ADDR_free(peeraddr
);
374 SSL_CTX_free(tserver_args
.ctx
);
375 BIO_ADDR_free(peeraddr
);
377 BIO_free_all(fisbio
);
381 ossl_quic_tserver_free(*qtserv
);
383 OPENSSL_free(*fault
);
386 if (tracebio
!= NULL
)
392 void qtest_add_time(uint64_t millis
)
394 if (!CRYPTO_THREAD_write_lock(fake_now_lock
))
396 fake_now
= ossl_time_add(fake_now
, ossl_ms2time(millis
));
397 CRYPTO_THREAD_unlock(fake_now_lock
);
400 static OSSL_TIME
qtest_get_time(void)
404 if (!CRYPTO_THREAD_read_lock(fake_now_lock
))
405 return ossl_time_zero();
407 CRYPTO_THREAD_unlock(fake_now_lock
);
411 static void qtest_reset_time(void)
413 if (!CRYPTO_THREAD_write_lock(fake_now_lock
))
415 fake_now
= ossl_time_zero();
416 CRYPTO_THREAD_unlock(fake_now_lock
);
417 /* zero time can have a special meaning, bump it */
421 void qtest_start_stopwatch(void)
423 start_time
= qtest_get_time();
426 uint64_t qtest_get_stopwatch_time(void)
428 return ossl_time2ms(ossl_time_subtract(qtest_get_time(), start_time
));
431 QTEST_FAULT
*qtest_create_injector(QUIC_TSERVER
*ts
)
435 f
= OPENSSL_zalloc(sizeof(*f
));
444 int qtest_supports_blocking(void)
446 #if !defined(OPENSSL_NO_POSIX_IO) && defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
453 #define MAXLOOPS 1000
455 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
456 static int globserverret
= 0;
457 static TSAN_QUALIFIER
int abortserverthread
= 0;
458 static QUIC_TSERVER
*globtserv
;
459 static const thread_t thread_zero
;
460 static void run_server_thread(void)
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
467 globserverret
= qtest_create_quic_connection(globtserv
, NULL
);
471 int qtest_wait_for_timeout(SSL
*s
, QUIC_TSERVER
*qtserv
)
474 OSSL_TIME ctimeout
, stimeout
, mintimeout
, now
;
477 /* We don't need to wait in blocking mode */
478 if (s
== NULL
|| SSL_get_blocking_mode(s
))
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)
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.
493 if (!SSL_get_event_timeout(s
, &tv
, &cinf
))
497 now
= qtest_get_time();
499 now
= ossl_time_now();
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
))
508 qtest_add_time(ossl_time2ms(mintimeout
));
510 OSSL_sleep(ossl_time2ms(mintimeout
));
515 int qtest_create_quic_connection_ex(QUIC_TSERVER
*qtserv
, SSL
*clientssl
,
518 int retc
= -1, rets
= 0, abortctr
= 0, ret
= 0;
519 int clienterr
= 0, servererr
= 0;
520 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
523 * Pointless initialisation to avoid bogus compiler warnings about using
526 thread_t t
= thread_zero
;
528 if (clientssl
!= NULL
)
529 abortserverthread
= 0;
532 * Only set the client_ready flag to zero if we are the client
534 if (clientssl
!= NULL
) {
535 ossl_crypto_mutex_lock(client_ready_mutex
);
537 ossl_crypto_mutex_unlock(client_ready_mutex
);
541 if (!TEST_ptr(qtserv
)) {
543 } else if (clientssl
== NULL
) {
545 } else if (SSL_get_blocking_mode(clientssl
) > 0) {
546 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
548 * clientssl is blocking. We will need a thread to complete the
552 if (!TEST_true(run_thread(&t
, run_server_thread
)))
558 TEST_error("No thread support in this build");
564 if (!clienterr
&& retc
<= 0) {
567 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
568 ossl_crypto_mutex_lock(client_ready_mutex
);
570 ossl_crypto_condvar_broadcast(client_ready_cond
);
571 ossl_crypto_mutex_unlock(client_ready_mutex
);
573 retc
= SSL_connect(clientssl
);
575 err
= SSL_get_error(clientssl
, retc
);
577 if (err
== wanterr
) {
579 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
580 if (qtserv
== NULL
&& rets
> 0)
581 tsan_store(&abortserverthread
, 1);
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();
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
);
603 if (client_ready
== 1)
605 ossl_crypto_condvar_wait(client_ready_cond
, client_ready_mutex
);
607 ossl_crypto_mutex_unlock(client_ready_mutex
);
609 ossl_quic_tserver_tick(qtserv
);
612 if (!servererr
&& rets
<= 0) {
613 servererr
= ossl_quic_tserver_is_term_any(qtserv
);
615 rets
= ossl_quic_tserver_is_handshake_confirmed(qtserv
);
618 if (clienterr
&& servererr
)
621 if (clientssl
!= NULL
&& ++abortctr
== MAXLOOPS
) {
622 TEST_info("No progress made");
626 if ((retc
<= 0 && !clienterr
) || (rets
<= 0 && !servererr
)) {
627 if (!qtest_wait_for_timeout(clientssl
, qtserv
))
630 } while ((retc
<= 0 && !clienterr
)
631 || (rets
<= 0 && !servererr
632 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
633 && !tsan_load(&abortserverthread
)
637 if (qtserv
== NULL
&& rets
> 0) {
638 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
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
643 ossl_crypto_mutex_lock(client_ready_mutex
);
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
))
650 TEST_error("Should not happen");
655 if (!clienterr
&& !servererr
)
661 int qtest_create_quic_connection(QUIC_TSERVER
*qtserv
, SSL
*clientssl
)
663 return qtest_create_quic_connection_ex(qtserv
, clientssl
, SSL_ERROR_NONE
);
666 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
667 static TSAN_QUALIFIER
int shutdowndone
;
669 static void run_server_shutdown_thread(void)
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
677 ossl_quic_tserver_tick(globtserv
);
678 } while(!tsan_load(&shutdowndone
));
682 int qtest_shutdown(QUIC_TSERVER
*qtserv
, SSL
*clientssl
)
686 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
688 * Pointless initialisation to avoid bogus compiler warnings about using
691 thread_t t
= thread_zero
;
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
;
699 if (SSL_get_blocking_mode(clientssl
) > 0) {
700 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
702 * clientssl is blocking. We will need a thread to complete the
707 if (!TEST_true(run_thread(&t
, run_server_shutdown_thread
)))
712 TEST_error("No thread support in this build");
717 /* Busy loop in non-blocking mode. It should be quick because its local */
719 int rc
= SSL_shutdown(clientssl
);
730 ossl_quic_tserver_tick(qtserv
);
733 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
734 tsan_store(&shutdowndone
, 1);
736 if (!TEST_true(wait_for_thread(t
)))
744 int qtest_check_server_transport_err(QUIC_TSERVER
*qtserv
, uint64_t code
)
746 const QUIC_TERMINATE_CAUSE
*cause
;
748 ossl_quic_tserver_tick(qtserv
);
751 * Check that the server has closed with the specified code from the client
753 if (!TEST_true(ossl_quic_tserver_is_term_any(qtserv
)))
756 cause
= ossl_quic_tserver_get_terminate_cause(qtserv
);
758 || !TEST_true(cause
->remote
)
759 || !TEST_false(cause
->app
)
760 || !TEST_uint64_t_eq(cause
->error_code
, code
))
766 int qtest_check_server_protocol_err(QUIC_TSERVER
*qtserv
)
768 return qtest_check_server_transport_err(qtserv
, OSSL_QUIC_ERR_PROTOCOL_VIOLATION
);
771 int qtest_check_server_frame_encoding_err(QUIC_TSERVER
*qtserv
)
773 return qtest_check_server_transport_err(qtserv
, OSSL_QUIC_ERR_FRAME_ENCODING_ERROR
);
776 void qtest_fault_free(QTEST_FAULT
*fault
)
781 packet_plain_finish(fault
);
782 handshake_finish(fault
);
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
,
794 QTEST_FAULT
*fault
= arg
;
799 /* Coalesce our data into a single buffer */
801 /* First calculate required buffer size */
802 for (i
= 0; i
< numin
; i
++)
803 bufsz
+= iovecin
[i
].buf_len
;
805 fault
->pplainio
.buf_len
= bufsz
;
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)
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
;
820 fault
->pplainio
.buf
= cur
= OPENSSL_malloc(bufsz
);
822 fault
->pplainio
.buf_len
= 0;
826 fault
->pplainbuf_alloc
= bufsz
;
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
;
834 fault
->pplainhdr
= *hdrin
;
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
842 if (fault
->pplaincb
!= NULL
)
843 fault
->pplaincb(fault
, &fault
->pplainhdr
,
844 (unsigned char *)fault
->pplainio
.buf
,
845 fault
->pplainio
.buf_len
, fault
->pplaincbarg
);
847 *hdrout
= &fault
->pplainhdr
;
848 *iovecout
= &fault
->pplainio
;
854 static void packet_plain_finish(void *arg
)
856 QTEST_FAULT
*fault
= arg
;
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
;
865 int qtest_fault_set_packet_plain_listener(QTEST_FAULT
*fault
,
866 qtest_fault_on_packet_plain_cb pplaincb
,
869 fault
->pplaincb
= pplaincb
;
870 fault
->pplaincbarg
= pplaincbarg
;
872 return ossl_quic_tserver_set_plain_packet_mutator(fault
->qtserv
,
878 /* To be called from a packet_plain_listener callback */
879 int qtest_fault_resize_plain_packet(QTEST_FAULT
*fault
, size_t newlen
)
882 size_t oldlen
= fault
->pplainio
.buf_len
;
885 * Alloc'd size should always be non-zero, so if this fails we've been
888 if (fault
->pplainbuf_alloc
== 0)
891 if (newlen
> fault
->pplainbuf_alloc
) {
892 /* This exceeds our growth allowance. Fail */
896 /* Cast below is safe because we allocated the buffer */
897 buf
= (unsigned char *)fault
->pplainio
.buf
;
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 */
904 fault
->pplainio
.buf_len
= newlen
;
905 fault
->pplainhdr
.len
= newlen
;
911 * Prepend frame data into a packet. To be called from a packet_plain_listener
914 int qtest_fault_prepend_frame(QTEST_FAULT
*fault
, const unsigned char *frame
,
921 * Alloc'd size should always be non-zero, so if this fails we've been
924 if (fault
->pplainbuf_alloc
== 0)
927 /* Cast below is safe because we allocated the buffer */
928 buf
= (unsigned char *)fault
->pplainio
.buf
;
929 old_len
= fault
->pplainio
.buf_len
;
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
)))
936 memmove(buf
+ frame_len
, buf
, old_len
);
937 memcpy(buf
, frame
, frame_len
);
942 static int handshake_mutate(const unsigned char *msgin
, size_t msginlen
,
943 unsigned char **msgout
, size_t *msgoutlen
,
946 QTEST_FAULT
*fault
= arg
;
948 unsigned long payloadlen
;
949 unsigned int msgtype
;
952 buf
= OPENSSL_malloc(msginlen
+ GROWTH_ALLOWANCE
);
956 fault
->handbuf
= buf
;
957 fault
->handbuflen
= msginlen
;
958 fault
->handbufalloc
= msginlen
+ GROWTH_ALLOWANCE
;
959 memcpy(buf
, msgin
, msginlen
);
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
)
967 /* Parse specific message types */
969 case SSL3_MT_ENCRYPTED_EXTENSIONS
:
971 QTEST_ENCRYPTED_EXTENSIONS ee
;
973 if (fault
->encextcb
== NULL
)
977 * The EncryptedExtensions message is very simple. It just has an
978 * extensions block in it and nothing else.
980 ee
.extensions
= (unsigned char *)PACKET_data(&pkt
);
981 ee
.extensionslen
= payloadlen
;
982 if (!fault
->encextcb(fault
, &ee
, payloadlen
, fault
->encextcbarg
))
987 /* No specific handlers for these message types yet */
991 if (fault
->handshakecb
!= NULL
992 && !fault
->handshakecb(fault
, buf
, fault
->handbuflen
,
993 fault
->handshakecbarg
))
997 *msgoutlen
= fault
->handbuflen
;
1002 static void handshake_finish(void *arg
)
1004 QTEST_FAULT
*fault
= arg
;
1006 OPENSSL_free(fault
->handbuf
);
1007 fault
->handbuf
= NULL
;
1010 int qtest_fault_set_handshake_listener(QTEST_FAULT
*fault
,
1011 qtest_fault_on_handshake_cb handshakecb
,
1012 void *handshakecbarg
)
1014 fault
->handshakecb
= handshakecb
;
1015 fault
->handshakecbarg
= handshakecbarg
;
1017 return ossl_quic_tserver_set_handshake_mutator(fault
->qtserv
,
1023 int qtest_fault_set_hand_enc_ext_listener(QTEST_FAULT
*fault
,
1024 qtest_fault_on_enc_ext_cb encextcb
,
1027 fault
->encextcb
= encextcb
;
1028 fault
->encextcbarg
= encextcbarg
;
1030 return ossl_quic_tserver_set_handshake_mutator(fault
->qtserv
,
1036 /* To be called from a handshake_listener callback */
1037 int qtest_fault_resize_handshake(QTEST_FAULT
*fault
, size_t newlen
)
1040 size_t oldlen
= fault
->handbuflen
;
1043 * Alloc'd size should always be non-zero, so if this fails we've been
1044 * incorrectly called
1046 if (fault
->handbufalloc
== 0)
1049 if (newlen
> fault
->handbufalloc
) {
1050 /* This exceeds our growth allowance. Fail */
1054 buf
= (unsigned char *)fault
->handbuf
;
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 */
1061 fault
->handbuflen
= newlen
;
1065 /* To be called from message specific listener callbacks */
1066 int qtest_fault_resize_message(QTEST_FAULT
*fault
, size_t newlen
)
1068 /* First resize the underlying message */
1069 if (!qtest_fault_resize_handshake(fault
, newlen
+ SSL3_HM_HEADER_LENGTH
))
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);
1080 int qtest_fault_delete_extension(QTEST_FAULT
*fault
,
1081 unsigned int exttype
, unsigned char *ext
,
1085 PACKET pkt
, sub
, subext
;
1086 WPACKET old_ext_wpkt
;
1088 const unsigned char *start
, *end
;
1090 size_t msglen
= fault
->handbuflen
;
1092 if (!PACKET_buf_init(&pkt
, ext
, *extlen
))
1095 /* Extension block starts with 2 bytes for extension block length */
1096 if (!PACKET_as_length_prefixed_2(&pkt
, &sub
))
1100 start
= PACKET_data(&sub
);
1101 if (!PACKET_get_net_2(&sub
, &type
)
1102 || !PACKET_get_length_prefixed_2(&sub
, &subext
))
1104 } while (type
!= exttype
);
1107 end
= PACKET_data(&sub
);
1109 if (old_ext
!= NULL
) {
1110 if (!WPACKET_init(&old_ext_wpkt
, old_ext
))
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
);
1120 WPACKET_finish(&old_ext_wpkt
);
1121 old_ext
->length
= w
;
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.
1129 if (end
< ext
+ *extlen
)
1130 memmove((unsigned char *)start
, end
, end
- start
);
1133 * Calculate new extensions payload length =
1135 * - 2 extension block length bytes
1136 * - length of removed extension
1138 newlen
= *extlen
- 2 - (end
- start
);
1140 /* Fixup the length bytes for the extension block */
1141 ext
[0] = (unsigned char)((newlen
>> 8) & 0xff);
1142 ext
[1] = (unsigned char)((newlen
) & 0xff);
1145 * Length of the whole extension block is the new payload length plus the
1146 * 2 bytes for the length
1148 *extlen
= newlen
+ 2;
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
))
1160 #define BIO_TYPE_CIPHER_PACKET_FILTER (0x80 | BIO_TYPE_FILTER)
1162 static BIO_METHOD
*pcipherbiometh
= NULL
;
1164 # define BIO_MSG_N(array, stride, n) (*(BIO_MSG *)((char *)(array) + (n)*(stride)))
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
)
1170 BIO
*next
= BIO_next(b
);
1171 ossl_ssize_t ret
= 0;
1172 size_t i
= 0, tmpnump
;
1175 unsigned char *tmpdata
;
1176 QTEST_DATA
*bdata
= NULL
;
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
);
1191 for (i
= 0; i
< num_msg
; ++i
) {
1192 bdata
->fault
->msg
= BIO_MSG_N(msg
, stride
, i
);
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
)
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
;
1202 if (bdata
->fault
->pciphercb
!= NULL
) {
1203 if (!PACKET_buf_init(&pkt
, bdata
->fault
->msg
.data
, bdata
->fault
->msg
.data_len
))
1207 if (!ossl_quic_wire_decode_pkt_hdr(&pkt
,
1208 bdata
->short_conn_id_len
,
1209 1, 0, &hdr
, NULL
, NULL
))
1213 * hdr.data is const - but its our buffer so casting away the
1216 if (!bdata
->fault
->pciphercb(bdata
->fault
, &hdr
,
1217 (unsigned char *)hdr
.data
, hdr
.len
,
1218 bdata
->fault
->pciphercbarg
))
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.
1228 } while (PACKET_remaining(&pkt
) > 0);
1231 if (bdata
->fault
->datagramcb
!= NULL
1232 && !bdata
->fault
->datagramcb(bdata
->fault
, &bdata
->fault
->msg
, stride
,
1233 bdata
->fault
->datagramcbarg
))
1236 if (!BIO_sendmmsg(next
, &bdata
->fault
->msg
, stride
, 1, flags
, &tmpnump
)) {
1241 OPENSSL_free(bdata
->fault
->msg
.data
);
1242 bdata
->fault
->msg
.data
= NULL
;
1243 bdata
->fault
->msgalloc
= 0;
1249 OPENSSL_free(bdata
->fault
->msg
.data
);
1250 bdata
->fault
->msg
.data
= NULL
;
1254 static long pcipher_ctrl(BIO
*b
, int cmd
, long larg
, void *parg
)
1256 BIO
*next
= BIO_next(b
);
1261 return BIO_ctrl(next
, cmd
, larg
, parg
);
1264 static int pcipher_destroy(BIO
*b
)
1266 OPENSSL_free(BIO_get_data(b
));
1270 BIO_METHOD
*qtest_get_bio_method(void)
1274 if (pcipherbiometh
!= NULL
)
1275 return pcipherbiometh
;
1277 tmp
= BIO_meth_new(BIO_TYPE_CIPHER_PACKET_FILTER
, "Cipher Packet Filter");
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
)))
1287 pcipherbiometh
= tmp
;
1291 return pcipherbiometh
;
1294 int qtest_fault_set_packet_cipher_listener(QTEST_FAULT
*fault
,
1295 qtest_fault_on_packet_cipher_cb pciphercb
,
1298 fault
->pciphercb
= pciphercb
;
1299 fault
->pciphercbarg
= pciphercbarg
;
1304 int qtest_fault_set_datagram_listener(QTEST_FAULT
*fault
,
1305 qtest_fault_on_datagram_cb datagramcb
,
1306 void *datagramcbarg
)
1308 fault
->datagramcb
= datagramcb
;
1309 fault
->datagramcbarg
= datagramcbarg
;
1314 /* To be called from a datagram_listener callback */
1315 int qtest_fault_resize_datagram(QTEST_FAULT
*fault
, size_t newlen
)
1317 if (newlen
> fault
->msgalloc
)
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
);
1324 fault
->msg
.data_len
= newlen
;
1329 int qtest_fault_set_bw_limit(QTEST_FAULT
*fault
,
1330 size_t ctos_bw
, size_t stoc_bw
,
1333 BIO
*sbio
= fault
->noiseargs
.sbio
;
1334 BIO
*cbio
= fault
->noiseargs
.cbio
;
1336 if (!TEST_ptr(sbio
) || !TEST_ptr(cbio
))
1338 if (!TEST_int_eq(BIO_ctrl(sbio
, BIO_CTRL_NOISE_RATE
, noise_rate
, NULL
), 1))
1340 if (!TEST_int_eq(BIO_ctrl(cbio
, BIO_CTRL_NOISE_RATE
, noise_rate
, NULL
), 1))
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))
1346 if (!TEST_int_eq(BIO_ctrl(sbio
, BIO_CTRL_NOISE_SEND_BANDWIDTH
,
1347 (long)stoc_bw
, NULL
), 1))
1353 int bio_msg_copy(BIO_MSG
*dst
, BIO_MSG
*src
)
1356 * Note it is assumed that the originally allocated data sizes for dst and
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
)))
1367 BIO_ADDR_clear(dst
->local
);
1370 if (!TEST_true(BIO_ADDR_copy(dst
->peer
, src
->peer
)))