1 /* 2 * Copyright 2022-2024 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 <openssl/ssl.h> 11 #include <internal/quic_tserver.h> 12 13 /* Type to represent the Fault Injector */ 14 typedef struct qtest_fault QTEST_FAULT; 15 16 /* 17 * Structure representing a parsed EncryptedExtension message. Listeners can 18 * make changes to the contents of structure objects as required and the fault 19 * injector will reconstruct the message to be sent on 20 */ 21 typedef struct qtest_fault_encrypted_extensions { 22 /* EncryptedExtension messages just have an extensions block */ 23 unsigned char *extensions; 24 size_t extensionslen; 25 } QTEST_ENCRYPTED_EXTENSIONS; 26 27 /* Flags for use with qtest_create_quic_objects() */ 28 29 /* Indicates whether we are using blocking mode or not */ 30 #define QTEST_FLAG_BLOCK (1 << 0) 31 /* Use fake time rather than real time */ 32 #define QTEST_FLAG_FAKE_TIME (1 << 1) 33 /* Introduce noise in the BIO */ 34 #define QTEST_FLAG_NOISE (1 << 2) 35 /* Split datagrams such that each datagram contains one packet */ 36 #define QTEST_FLAG_PACKET_SPLIT (1 << 3) 37 /* Turn on client side tracing */ 38 #define QTEST_FLAG_CLIENT_TRACE (1 << 4) 39 /* 40 * Given an SSL_CTX for the client and filenames for the server certificate and 41 * keyfile, create a server and client instances as well as a fault injector 42 * instance. |flags| is the logical or of flags defined above, or 0 if none. 43 */ 44 int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx, 45 SSL_CTX *serverctx, char *certfile, char *keyfile, 46 int flags, QUIC_TSERVER **qtserv, SSL **cssl, 47 QTEST_FAULT **fault, BIO **tracebio); 48 49 /* Where QTEST_FLAG_FAKE_TIME is used, add millis to the current time */ 50 void qtest_add_time(uint64_t millis); 51 52 /* Starts time measurement */ 53 void qtest_start_stopwatch(void); 54 /* Returns the duration from the start in millis */ 55 uint64_t qtest_get_stopwatch_time(void); 56 57 QTEST_FAULT *qtest_create_injector(QUIC_TSERVER *ts); 58 59 BIO_METHOD *qtest_get_bio_method(void); 60 61 /* 62 * Free up a Fault Injector instance 63 */ 64 void qtest_fault_free(QTEST_FAULT *fault); 65 66 /* Returns 1 if the quictestlib supports blocking tests */ 67 int qtest_supports_blocking(void); 68 69 /* 70 * Run the TLS handshake to create a QUIC connection between the client and 71 * server. 72 */ 73 int qtest_create_quic_connection(QUIC_TSERVER *qtserv, SSL *clientssl); 74 75 /* 76 * Check if both client and server have no data to read and are waiting on a 77 * timeout. If so, wait until the timeout has expired. 78 */ 79 int qtest_wait_for_timeout(SSL *s, QUIC_TSERVER *qtserv); 80 81 /* 82 * Same as qtest_create_quic_connection but will stop (successfully) if the 83 * clientssl indicates SSL_ERROR_WANT_XXX as specified by |wanterr| 84 */ 85 int qtest_create_quic_connection_ex(QUIC_TSERVER *qtserv, SSL *clientssl, 86 int wanterr); 87 88 /* 89 * Shutdown the client SSL object gracefully 90 */ 91 int qtest_shutdown(QUIC_TSERVER *qtserv, SSL *clientssl); 92 93 /* 94 * Confirm that the server has received the given transport error code. 95 */ 96 int qtest_check_server_transport_err(QUIC_TSERVER *qtserv, uint64_t code); 97 98 /* 99 * Confirm the server has received a protocol error. Equivalent to calling 100 * qtest_check_server_transport_err with a code of QUIC_ERR_PROTOCOL_VIOLATION 101 */ 102 int qtest_check_server_protocol_err(QUIC_TSERVER *qtserv); 103 104 /* 105 * Confirm the server has received a frame encoding error. Equivalent to calling 106 * qtest_check_server_transport_err with a code of QUIC_ERR_FRAME_ENCODING_ERROR 107 */ 108 int qtest_check_server_frame_encoding_err(QUIC_TSERVER *qtserv); 109 110 /* 111 * Enable tests to listen for pre-encryption QUIC packets being sent 112 */ 113 typedef int (*qtest_fault_on_packet_plain_cb)(QTEST_FAULT *fault, 114 QUIC_PKT_HDR *hdr, 115 unsigned char *buf, 116 size_t len, 117 void *cbarg); 118 119 int qtest_fault_set_packet_plain_listener(QTEST_FAULT *fault, 120 qtest_fault_on_packet_plain_cb pplaincb, 121 void *pplaincbarg); 122 123 124 /* 125 * Helper function to be called from a packet_plain_listener callback if it 126 * wants to resize the packet (either to add new data to it, or to truncate it). 127 * The buf provided to packet_plain_listener is over allocated, so this just 128 * changes the logical size and never changes the actual address of the buf. 129 * This will fail if a large resize is attempted that exceeds the over 130 * allocation. 131 */ 132 int qtest_fault_resize_plain_packet(QTEST_FAULT *fault, size_t newlen); 133 134 /* 135 * Prepend frame data into a packet. To be called from a packet_plain_listener 136 * callback 137 */ 138 int qtest_fault_prepend_frame(QTEST_FAULT *fault, const unsigned char *frame, 139 size_t frame_len); 140 141 /* 142 * The general handshake message listener is sent the entire handshake message 143 * data block, including the handshake header itself 144 */ 145 typedef int (*qtest_fault_on_handshake_cb)(QTEST_FAULT *fault, 146 unsigned char *msg, 147 size_t msglen, 148 void *handshakecbarg); 149 150 int qtest_fault_set_handshake_listener(QTEST_FAULT *fault, 151 qtest_fault_on_handshake_cb handshakecb, 152 void *handshakecbarg); 153 154 /* 155 * Helper function to be called from a handshake_listener callback if it wants 156 * to resize the handshake message (either to add new data to it, or to truncate 157 * it). newlen must include the length of the handshake message header. The 158 * handshake message buffer is over allocated, so this just changes the logical 159 * size and never changes the actual address of the buf. 160 * This will fail if a large resize is attempted that exceeds the over 161 * allocation. 162 */ 163 int qtest_fault_resize_handshake(QTEST_FAULT *fault, size_t newlen); 164 165 /* 166 * Add listeners for specific types of frame here. E.g. we might 167 * expect to see an "ACK" frame listener which will be passed pre-parsed ack 168 * data that can be modified as required. 169 */ 170 171 /* 172 * Handshake message specific listeners. Unlike the general handshake message 173 * listener these messages are pre-parsed and supplied with message specific 174 * data and exclude the handshake header 175 */ 176 typedef int (*qtest_fault_on_enc_ext_cb)(QTEST_FAULT *fault, 177 QTEST_ENCRYPTED_EXTENSIONS *ee, 178 size_t eelen, 179 void *encextcbarg); 180 181 int qtest_fault_set_hand_enc_ext_listener(QTEST_FAULT *fault, 182 qtest_fault_on_enc_ext_cb encextcb, 183 void *encextcbarg); 184 185 /* Add listeners for other types of handshake message here */ 186 187 188 /* 189 * Helper function to be called from message specific listener callbacks. newlen 190 * is the new length of the specific message excluding the handshake message 191 * header. The buffers provided to the message specific listeners are over 192 * allocated, so this just changes the logical size and never changes the actual 193 * address of the buffer. This will fail if a large resize is attempted that 194 * exceeds the over allocation. 195 */ 196 int qtest_fault_resize_message(QTEST_FAULT *fault, size_t newlen); 197 198 /* 199 * Helper function to delete an extension from an extension block. |exttype| is 200 * the type of the extension to be deleted. |ext| points to the extension block. 201 * On entry |*extlen| contains the length of the extension block. It is updated 202 * with the new length on exit. If old_ext is non-NULL, the deleted extension 203 * is appended to the given BUF_MEM. 204 */ 205 int qtest_fault_delete_extension(QTEST_FAULT *fault, 206 unsigned int exttype, unsigned char *ext, 207 size_t *extlen, 208 BUF_MEM *old_ext); 209 210 /* 211 * Add additional helper functions for querying extensions here (e.g. 212 * finding or adding them). We could also provide a "listener" API for listening 213 * for specific extension types 214 */ 215 216 /* 217 * Enable tests to listen for post-encryption QUIC packets being sent 218 */ 219 typedef int (*qtest_fault_on_packet_cipher_cb)(QTEST_FAULT *fault, 220 /* The parsed packet header */ 221 QUIC_PKT_HDR *hdr, 222 /* The packet payload data */ 223 unsigned char *buf, 224 /* Length of the payload */ 225 size_t len, 226 void *cbarg); 227 228 int qtest_fault_set_packet_cipher_listener(QTEST_FAULT *fault, 229 qtest_fault_on_packet_cipher_cb pciphercb, 230 void *picphercbarg); 231 232 /* 233 * Enable tests to listen for datagrams being sent 234 */ 235 typedef int (*qtest_fault_on_datagram_cb)(QTEST_FAULT *fault, 236 BIO_MSG *m, 237 size_t stride, 238 void *cbarg); 239 240 int qtest_fault_set_datagram_listener(QTEST_FAULT *fault, 241 qtest_fault_on_datagram_cb datagramcb, 242 void *datagramcbarg); 243 244 /* 245 * To be called from a datagram_listener callback. The datagram buffer is over 246 * allocated, so this just changes the logical size and never changes the actual 247 * address of the buffer. This will fail if a large resize is attempted that 248 * exceeds the over allocation. 249 */ 250 int qtest_fault_resize_datagram(QTEST_FAULT *fault, size_t newlen); 251 252 /* 253 * Set bandwidth and noise rate on noisy dgram filter. 254 * Arguments with values of 0 mean no limit/no noise. 255 */ 256 257 int qtest_fault_set_bw_limit(QTEST_FAULT *fault, 258 size_t ctos_bw, size_t stoc_bw, 259 int noise_rate); 260 261 /* Copy a BIO_MSG */ 262 int bio_msg_copy(BIO_MSG *dst, BIO_MSG *src); 263 264 #define BIO_CTRL_NOISE_BACK_OFF 1001 265 #define BIO_CTRL_NOISE_RATE 1002 266 #define BIO_CTRL_NOISE_RECV_BANDWIDTH 1003 267 #define BIO_CTRL_NOISE_SEND_BANDWIDTH 1004 268 #define BIO_CTRL_NOISE_SET_NOW_CB 1005 269 270 struct bio_noise_now_cb_st { 271 OSSL_TIME (*now_cb)(void *); 272 void *now_cb_arg; 273 }; 274 275 /* BIO filter for simulating a noisy UDP socket */ 276 const BIO_METHOD *bio_f_noisy_dgram_filter(void); 277 278 /* Free the BIO filter method object */ 279 void bio_f_noisy_dgram_filter_free(void); 280 281 /* 282 * BIO filter for splitting QUIC datagrams containing multiple packets into 283 * individual datagrams. 284 */ 285 const BIO_METHOD *bio_f_pkt_split_dgram_filter(void); 286 287 /* Free the BIO filter method object */ 288 void bio_f_pkt_split_dgram_filter_free(void); 289