1 1.7 christos /* $NetBSD: regress_ssl.c,v 1.8 2024/08/18 20:47:23 christos Exp $ */ 2 1.1 christos 3 1.1 christos /* 4 1.1 christos * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson 5 1.1 christos * 6 1.1 christos * Redistribution and use in source and binary forms, with or without 7 1.1 christos * modification, are permitted provided that the following conditions 8 1.1 christos * are met: 9 1.1 christos * 1. Redistributions of source code must retain the above copyright 10 1.1 christos * notice, this list of conditions and the following disclaimer. 11 1.1 christos * 2. Redistributions in binary form must reproduce the above copyright 12 1.1 christos * notice, this list of conditions and the following disclaimer in the 13 1.1 christos * documentation and/or other materials provided with the distribution. 14 1.1 christos * 3. The name of the author may not be used to endorse or promote products 15 1.1 christos * derived from this software without specific prior written permission. 16 1.1 christos * 17 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 1.1 christos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 1.1 christos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 1.1 christos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 1.1 christos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 1.1 christos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 1.1 christos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 1.1 christos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 1.1 christos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 1.1 christos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 1.1 christos */ 28 1.1 christos 29 1.2 christos // Get rid of OSX 10.7 and greater deprecation warnings. 30 1.2 christos #if defined(__APPLE__) && defined(__clang__) 31 1.2 christos #pragma clang diagnostic ignored "-Wdeprecated-declarations" 32 1.2 christos #endif 33 1.2 christos 34 1.1 christos #ifdef _WIN32 35 1.1 christos #include <winsock2.h> 36 1.1 christos #include <windows.h> 37 1.1 christos #endif 38 1.1 christos 39 1.8 christos #include "util-internal.h" 40 1.8 christos 41 1.1 christos #ifndef _WIN32 42 1.1 christos #include <sys/types.h> 43 1.1 christos #include <sys/socket.h> 44 1.1 christos #include <netinet/in.h> 45 1.1 christos #endif 46 1.1 christos 47 1.1 christos #include "event2/util.h" 48 1.1 christos #include "event2/event.h" 49 1.1 christos #include "event2/bufferevent_ssl.h" 50 1.8 christos #include "event2/bufferevent_struct.h" 51 1.1 christos #include "event2/buffer.h" 52 1.1 christos #include "event2/listener.h" 53 1.1 christos 54 1.1 christos #include "regress.h" 55 1.1 christos #include "tinytest.h" 56 1.1 christos #include "tinytest_macros.h" 57 1.1 christos 58 1.1 christos #include <openssl/err.h> 59 1.1 christos #include <openssl/pem.h> 60 1.8 christos #include "openssl-compat.h" 61 1.1 christos 62 1.1 christos #include <string.h> 63 1.8 christos #ifdef _WIN32 64 1.8 christos #include <io.h> 65 1.8 christos #define read _read 66 1.8 christos #define write _write 67 1.8 christos #else 68 1.8 christos #include <unistd.h> 69 1.8 christos #endif 70 1.1 christos 71 1.8 christos /* A pre-generated key, to save the cost of doing an RSA key generation step 72 1.8 christos * during the unit tests. It is published in this file, so you would have to 73 1.8 christos * be very foolish to consider using it in your own code. */ 74 1.1 christos static const char KEY[] = 75 1.1 christos "-----BEGIN RSA PRIVATE KEY-----\n" 76 1.8 christos "MIIEogIBAAKCAQEAtK07Ili0dkJb79m/sFmHoVJTWyLoveXex2yX/BtUzzcvZEOu\n" 77 1.8 christos "QLon/++5YOA48kzZm5K9mIwZkZhui1ZgJ5Bjq0LGAWTZGIn+NXjLFshPYvTKpOCW\n" 78 1.8 christos "uzL0Ir0LXMsBLYJQ5A4FomLNxs4I3H/dhDSGy/rSiJB1B4w2xNiwPK08/VL3zZqk\n" 79 1.8 christos "V+GsSvGIIkzhTMbqPJy9K8pqyjwOU2pgORS794yXciTGxWYjTDzJPgQ35YMDATaG\n" 80 1.8 christos "jr4HHo1zxU/Lj0pndSUK5rKLYxYQ3Uc8B3AVYDl9CP/GbOoQ4LBzS68JjcAUyp6i\n" 81 1.8 christos "6NfXlc2D9S9XgqVqwI+JqgJs0eW/+zPY2UEDWwIDAQABAoIBAD2HzV66FOM9YDAD\n" 82 1.8 christos "2RtGskEHV2nvLpIVadRCsFPkPvK+2X3s6rgSbbLkwh4y3lHuSCGKTNVZyQ9jeSos\n" 83 1.8 christos "xVxT+Q2HFQW+gYyw2gj91TQyDY8mzKhv8AVaqff2p5r3a7RC8CdqexK9UVUGL9Bg\n" 84 1.8 christos "H2F5vfpTtkVZ5PEoGDLblNFlMiMW/t1SobUeBVx+Msco/xqk9lFv1A9nnepGy0Gi\n" 85 1.8 christos "D+i6YNGTBsX22YhoCZl/ICxCL8lgqPei4FvBr9dBVh/jQgjuUBm2jz55p2r7+7Aw\n" 86 1.8 christos "khmXHReejoVokQ2+htgSgZNKlKuDy710ZpBqnDi8ynQi82Y2qCpyg/p/xcER54B6\n" 87 1.8 christos "hSftaiECgYEA2RkSoxU+nWk+BClQEUZRi88QK5W/M8oo1DvUs36hvPFkw3Jk/gz0\n" 88 1.8 christos "fgd5bnA+MXj0Fc0QHvbddPjIkyoI/evq9GPV+JYIuH5zabrlI3Jvya8q9QpAcEDO\n" 89 1.8 christos "KkL/O09qXVEW52S6l05nh4PLejyI7aTyTIN5nbVLac/+M8MY/qOjZksCgYEA1Q1o\n" 90 1.8 christos "L8kjSavU2xhQmSgZb9W62Do60sa3e73ljrDPoiyvbExldpSdziFYxHBD/Rep0ePf\n" 91 1.8 christos "eVSGS3VSwevt9/jSGo2Oa83TYYns9agBm03oR/Go/DukESdI792NsEM+PRFypVNy\n" 92 1.8 christos "AohWRLj0UU6DV+zLKp0VBavtx0ATeLFX0eN17TECgYBI2O/3Bz7uhQ0JSm+SjFz6\n" 93 1.8 christos "o+2SInp5P2G57aWu4VQWWY3tQ2p+EQzNaWam10UXRrXoxtmc+ktPX9e2AgnoYoyB\n" 94 1.8 christos "myqGcpnUhqHlnZAb999o9r1cYidDQ4uqhLauSTSwwXAFDzjJYsa8o03Y440y6QFh\n" 95 1.8 christos "CVD6yYXXqLJs3g96CqDexwKBgAHxq1+0QCQt8zVElYewO/svQhMzBNJjic0RQIT6\n" 96 1.8 christos "zAo4yij80XgxhvcYiszQEW6/xobpw2JCCS+rFGQ8mOFIXfJsFD6blDAxp/3d2JXo\n" 97 1.8 christos "MhRl+hrDGI4ng5zcsqxHEMxR2m/zwPiQ8eiSn3gWdVBaEsiCwmxY00ScKxFQ3PJH\n" 98 1.8 christos "Vw4hAoGAdZLd8KfjjG6lg7hfpVqavstqVi9LOgkHeCfdjn7JP+76kYrgLk/XdkrP\n" 99 1.8 christos "N/BHhtFVFjOi/mTQfQ5YfZImkm/1ePBy7437DT8BDkOxspa50kK4HPggHnU64h1w\n" 100 1.8 christos "lhdEOj7mAgHwGwwVZWOgs9Lq6vfztnSuhqjha1daESY6kDscPIQ=\n" 101 1.1 christos "-----END RSA PRIVATE KEY-----\n"; 102 1.1 christos 103 1.8 christos EVP_PKEY * 104 1.8 christos ssl_getkey(void) 105 1.1 christos { 106 1.1 christos EVP_PKEY *key; 107 1.1 christos BIO *bio; 108 1.1 christos 109 1.1 christos /* new read-only BIO backed by KEY. */ 110 1.1 christos bio = BIO_new_mem_buf((char*)KEY, -1); 111 1.1 christos tt_assert(bio); 112 1.1 christos 113 1.1 christos key = PEM_read_bio_PrivateKey(bio,NULL,NULL,NULL); 114 1.1 christos BIO_free(bio); 115 1.1 christos tt_assert(key); 116 1.1 christos 117 1.1 christos return key; 118 1.1 christos end: 119 1.1 christos return NULL; 120 1.1 christos } 121 1.1 christos 122 1.8 christos X509 * 123 1.8 christos ssl_getcert(EVP_PKEY *key) 124 1.1 christos { 125 1.1 christos /* Dummy code to make a quick-and-dirty valid certificate with 126 1.1 christos OpenSSL. Don't copy this code into your own program! It does a 127 1.1 christos number of things in a stupid and insecure way. */ 128 1.1 christos X509 *x509 = NULL; 129 1.1 christos X509_NAME *name = NULL; 130 1.1 christos int nid; 131 1.1 christos time_t now = time(NULL); 132 1.1 christos 133 1.1 christos tt_assert(key); 134 1.1 christos 135 1.1 christos x509 = X509_new(); 136 1.1 christos tt_assert(x509); 137 1.1 christos tt_assert(0 != X509_set_version(x509, 2)); 138 1.1 christos tt_assert(0 != ASN1_INTEGER_set(X509_get_serialNumber(x509), 139 1.1 christos (long)now)); 140 1.1 christos 141 1.1 christos name = X509_NAME_new(); 142 1.1 christos tt_assert(name); 143 1.1 christos nid = OBJ_txt2nid("commonName"); 144 1.1 christos tt_assert(NID_undef != nid); 145 1.1 christos tt_assert(0 != X509_NAME_add_entry_by_NID( 146 1.1 christos name, nid, MBSTRING_ASC, (unsigned char*)"example.com", 147 1.1 christos -1, -1, 0)); 148 1.1 christos 149 1.1 christos X509_set_subject_name(x509, name); 150 1.1 christos X509_set_issuer_name(x509, name); 151 1.8 christos X509_NAME_free(name); 152 1.1 christos 153 1.6 christos X509_time_adj(X509_getm_notBefore(x509), 0, &now); 154 1.6 christos now += 3600; 155 1.6 christos X509_time_adj(X509_getm_notAfter(x509), 0, &now); 156 1.1 christos X509_set_pubkey(x509, key); 157 1.1 christos tt_assert(0 != X509_sign(x509, key, EVP_sha1())); 158 1.1 christos 159 1.1 christos return x509; 160 1.1 christos end: 161 1.1 christos X509_free(x509); 162 1.8 christos X509_NAME_free(name); 163 1.1 christos return NULL; 164 1.1 christos } 165 1.1 christos 166 1.1 christos static int disable_tls_11_and_12 = 0; 167 1.1 christos static SSL_CTX *the_ssl_ctx = NULL; 168 1.1 christos 169 1.8 christos SSL_CTX * 170 1.1 christos get_ssl_ctx(void) 171 1.1 christos { 172 1.1 christos if (the_ssl_ctx) 173 1.1 christos return the_ssl_ctx; 174 1.1 christos the_ssl_ctx = SSL_CTX_new(SSLv23_method()); 175 1.1 christos if (!the_ssl_ctx) 176 1.1 christos return NULL; 177 1.1 christos if (disable_tls_11_and_12) { 178 1.1 christos #ifdef SSL_OP_NO_TLSv1_2 179 1.1 christos SSL_CTX_set_options(the_ssl_ctx, SSL_OP_NO_TLSv1_2); 180 1.1 christos #endif 181 1.1 christos #ifdef SSL_OP_NO_TLSv1_1 182 1.1 christos SSL_CTX_set_options(the_ssl_ctx, SSL_OP_NO_TLSv1_1); 183 1.1 christos #endif 184 1.1 christos } 185 1.1 christos return the_ssl_ctx; 186 1.1 christos } 187 1.1 christos 188 1.8 christos static int test_is_done; 189 1.8 christos static int n_connected; 190 1.8 christos static int got_close; 191 1.8 christos static int got_error; 192 1.8 christos static int got_timeout; 193 1.8 christos static int renegotiate_at = -1; 194 1.8 christos static int stop_when_connected; 195 1.8 christos static int pending_connect_events; 196 1.8 christos static struct event_base *exit_base; 197 1.8 christos static X509 *the_cert; 198 1.8 christos EVP_PKEY *the_key; 199 1.8 christos 200 1.8 christos void 201 1.1 christos init_ssl(void) 202 1.1 christos { 203 1.8 christos #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \ 204 1.8 christos (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) 205 1.1 christos SSL_library_init(); 206 1.1 christos ERR_load_crypto_strings(); 207 1.1 christos SSL_load_error_strings(); 208 1.1 christos OpenSSL_add_all_algorithms(); 209 1.8 christos if (SSLeay() != OPENSSL_VERSION_NUMBER) { 210 1.8 christos TT_DECLARE("WARN", 211 1.8 christos ("Version mismatch for openssl: compiled with %lx but running with %lx", 212 1.8 christos (unsigned long)OPENSSL_VERSION_NUMBER, (unsigned long)SSLeay())); 213 1.1 christos } 214 1.8 christos #endif 215 1.1 christos } 216 1.1 christos 217 1.8 christos static void * 218 1.8 christos ssl_test_setup(const struct testcase_t *testcase) 219 1.8 christos { 220 1.8 christos init_ssl(); 221 1.8 christos 222 1.8 christos the_key = ssl_getkey(); 223 1.8 christos EVUTIL_ASSERT(the_key); 224 1.8 christos 225 1.8 christos the_cert = ssl_getcert(the_key); 226 1.8 christos EVUTIL_ASSERT(the_cert); 227 1.8 christos 228 1.8 christos disable_tls_11_and_12 = 0; 229 1.8 christos 230 1.8 christos return basic_test_setup(testcase); 231 1.8 christos } 232 1.8 christos static int 233 1.8 christos ssl_test_cleanup(const struct testcase_t *testcase, void *ptr) 234 1.8 christos { 235 1.8 christos int ret = basic_test_cleanup(testcase, ptr); 236 1.8 christos if (!ret) { 237 1.8 christos return ret; 238 1.8 christos } 239 1.8 christos 240 1.8 christos test_is_done = 0; 241 1.8 christos n_connected = 0; 242 1.8 christos got_close = 0; 243 1.8 christos got_error = 0; 244 1.8 christos got_timeout = 0; 245 1.8 christos renegotiate_at = -1; 246 1.8 christos stop_when_connected = 0; 247 1.8 christos pending_connect_events = 0; 248 1.8 christos exit_base = NULL; 249 1.8 christos 250 1.8 christos X509_free(the_cert); 251 1.8 christos EVP_PKEY_free(the_key); 252 1.8 christos 253 1.8 christos SSL_CTX_free(the_ssl_ctx); 254 1.8 christos the_ssl_ctx = NULL; 255 1.8 christos 256 1.8 christos return 1; 257 1.8 christos } 258 1.8 christos const struct testcase_setup_t ssl_setup = { 259 1.8 christos ssl_test_setup, ssl_test_cleanup 260 1.8 christos }; 261 1.8 christos 262 1.8 christos 263 1.1 christos /* ==================== 264 1.1 christos Here's a simple test: we read a number from the input, increment it, and 265 1.1 christos reply, until we get to 1001. 266 1.1 christos */ 267 1.1 christos 268 1.8 christos enum regress_openssl_type 269 1.8 christos { 270 1.8 christos REGRESS_OPENSSL_SOCKETPAIR = 1, 271 1.8 christos REGRESS_OPENSSL_FILTER = 2, 272 1.8 christos REGRESS_OPENSSL_RENEGOTIATE = 4, 273 1.8 christos REGRESS_OPENSSL_OPEN = 8, 274 1.8 christos REGRESS_OPENSSL_DIRTY_SHUTDOWN = 16, 275 1.8 christos REGRESS_OPENSSL_FD = 32, 276 1.8 christos 277 1.8 christos REGRESS_OPENSSL_CLIENT = 64, 278 1.8 christos REGRESS_OPENSSL_SERVER = 128, 279 1.8 christos 280 1.8 christos REGRESS_OPENSSL_FREED = 256, 281 1.8 christos REGRESS_OPENSSL_TIMEOUT = 512, 282 1.8 christos REGRESS_OPENSSL_SLEEP = 1024, 283 1.8 christos 284 1.8 christos REGRESS_OPENSSL_CLIENT_WRITE = 2048, 285 1.8 christos 286 1.8 christos REGRESS_DEFERRED_CALLBACKS = 4096, 287 1.8 christos }; 288 1.8 christos 289 1.8 christos static void 290 1.8 christos bufferevent_openssl_check_fd(struct bufferevent *bev, int filter) 291 1.8 christos { 292 1.8 christos tt_fd_op(bufferevent_getfd(bev), !=, EVUTIL_INVALID_SOCKET); 293 1.8 christos tt_fd_op(bufferevent_setfd(bev, EVUTIL_INVALID_SOCKET), ==, 0); 294 1.8 christos if (filter) { 295 1.8 christos tt_fd_op(bufferevent_getfd(bev), !=, EVUTIL_INVALID_SOCKET); 296 1.8 christos } else { 297 1.8 christos tt_fd_op(bufferevent_getfd(bev), ==, EVUTIL_INVALID_SOCKET); 298 1.8 christos } 299 1.8 christos 300 1.8 christos end: 301 1.8 christos ; 302 1.8 christos } 303 1.8 christos static void 304 1.8 christos bufferevent_openssl_check_freed(struct bufferevent *bev) 305 1.8 christos { 306 1.8 christos tt_int_op(event_pending(&bev->ev_read, EVLIST_ALL, NULL), ==, 0); 307 1.8 christos tt_int_op(event_pending(&bev->ev_write, EVLIST_ALL, NULL), ==, 0); 308 1.8 christos 309 1.8 christos end: 310 1.8 christos ; 311 1.8 christos } 312 1.8 christos 313 1.8 christos static void 314 1.8 christos free_on_cb(struct bufferevent *bev, void *ctx) 315 1.8 christos { 316 1.8 christos TT_BLATHER(("free_on_cb: %p", bev)); 317 1.8 christos bufferevent_free(bev); 318 1.8 christos } 319 1.1 christos 320 1.1 christos static void 321 1.1 christos respond_to_number(struct bufferevent *bev, void *ctx) 322 1.1 christos { 323 1.1 christos struct evbuffer *b = bufferevent_get_input(bev); 324 1.1 christos char *line; 325 1.1 christos int n; 326 1.8 christos 327 1.8 christos enum regress_openssl_type type; 328 1.8 christos type = (enum regress_openssl_type)ctx; 329 1.8 christos 330 1.1 christos line = evbuffer_readln(b, NULL, EVBUFFER_EOL_LF); 331 1.1 christos if (! line) 332 1.1 christos return; 333 1.1 christos n = atoi(line); 334 1.1 christos if (n <= 0) 335 1.1 christos TT_FAIL(("Bad number: %s", line)); 336 1.3 christos free(line); 337 1.1 christos TT_BLATHER(("The number was %d", n)); 338 1.1 christos if (n == 1001) { 339 1.1 christos ++test_is_done; 340 1.1 christos bufferevent_free(bev); /* Should trigger close on other side. */ 341 1.1 christos return; 342 1.1 christos } 343 1.8 christos if ((type & REGRESS_OPENSSL_CLIENT) && n == renegotiate_at) { 344 1.1 christos SSL_renegotiate(bufferevent_openssl_get_ssl(bev)); 345 1.1 christos } 346 1.1 christos ++n; 347 1.1 christos evbuffer_add_printf(bufferevent_get_output(bev), 348 1.1 christos "%d\n", n); 349 1.1 christos TT_BLATHER(("Done reading; now writing.")); 350 1.1 christos bufferevent_enable(bev, EV_WRITE); 351 1.1 christos bufferevent_disable(bev, EV_READ); 352 1.1 christos } 353 1.1 christos 354 1.1 christos static void 355 1.1 christos done_writing_cb(struct bufferevent *bev, void *ctx) 356 1.1 christos { 357 1.1 christos struct evbuffer *b = bufferevent_get_output(bev); 358 1.1 christos if (evbuffer_get_length(b)) 359 1.1 christos return; 360 1.1 christos TT_BLATHER(("Done writing.")); 361 1.1 christos bufferevent_disable(bev, EV_WRITE); 362 1.1 christos bufferevent_enable(bev, EV_READ); 363 1.1 christos } 364 1.1 christos 365 1.1 christos static void 366 1.1 christos eventcb(struct bufferevent *bev, short what, void *ctx) 367 1.1 christos { 368 1.8 christos X509 *peer_cert = NULL; 369 1.8 christos enum regress_openssl_type type; 370 1.8 christos 371 1.8 christos type = (enum regress_openssl_type)ctx; 372 1.8 christos 373 1.1 christos TT_BLATHER(("Got event %d", (int)what)); 374 1.1 christos if (what & BEV_EVENT_CONNECTED) { 375 1.1 christos SSL *ssl; 376 1.1 christos ++n_connected; 377 1.1 christos ssl = bufferevent_openssl_get_ssl(bev); 378 1.1 christos tt_assert(ssl); 379 1.1 christos peer_cert = SSL_get_peer_certificate(ssl); 380 1.8 christos if (type & REGRESS_OPENSSL_SERVER) { 381 1.1 christos tt_assert(peer_cert == NULL); 382 1.1 christos } else { 383 1.1 christos tt_assert(peer_cert != NULL); 384 1.1 christos } 385 1.1 christos if (stop_when_connected) { 386 1.1 christos if (--pending_connect_events == 0) 387 1.1 christos event_base_loopexit(exit_base, NULL); 388 1.1 christos } 389 1.8 christos 390 1.8 christos if ((type & REGRESS_OPENSSL_CLIENT_WRITE) && (type & REGRESS_OPENSSL_CLIENT)) 391 1.8 christos evbuffer_add_printf(bufferevent_get_output(bev), "1\n"); 392 1.1 christos } else if (what & BEV_EVENT_EOF) { 393 1.1 christos TT_BLATHER(("Got a good EOF")); 394 1.1 christos ++got_close; 395 1.8 christos if (type & REGRESS_OPENSSL_FD) { 396 1.8 christos bufferevent_openssl_check_fd(bev, type & REGRESS_OPENSSL_FILTER); 397 1.8 christos } 398 1.8 christos if (type & REGRESS_OPENSSL_FREED) { 399 1.8 christos bufferevent_openssl_check_freed(bev); 400 1.8 christos } 401 1.1 christos bufferevent_free(bev); 402 1.1 christos } else if (what & BEV_EVENT_ERROR) { 403 1.1 christos TT_BLATHER(("Got an error.")); 404 1.1 christos ++got_error; 405 1.8 christos if (type & REGRESS_OPENSSL_FD) { 406 1.8 christos bufferevent_openssl_check_fd(bev, type & REGRESS_OPENSSL_FILTER); 407 1.8 christos } 408 1.8 christos if (type & REGRESS_OPENSSL_FREED) { 409 1.8 christos bufferevent_openssl_check_freed(bev); 410 1.8 christos } 411 1.8 christos bufferevent_free(bev); 412 1.8 christos } else if (what & BEV_EVENT_TIMEOUT) { 413 1.8 christos TT_BLATHER(("Got timeout.")); 414 1.8 christos ++got_timeout; 415 1.8 christos if (type & REGRESS_OPENSSL_FD) { 416 1.8 christos bufferevent_openssl_check_fd(bev, type & REGRESS_OPENSSL_FILTER); 417 1.8 christos } 418 1.8 christos if (type & REGRESS_OPENSSL_FREED) { 419 1.8 christos bufferevent_openssl_check_freed(bev); 420 1.8 christos } 421 1.1 christos bufferevent_free(bev); 422 1.1 christos } 423 1.8 christos 424 1.1 christos end: 425 1.8 christos if (peer_cert) 426 1.8 christos X509_free(peer_cert); 427 1.1 christos } 428 1.1 christos 429 1.1 christos static void 430 1.1 christos open_ssl_bufevs(struct bufferevent **bev1_out, struct bufferevent **bev2_out, 431 1.1 christos struct event_base *base, int is_open, int flags, SSL *ssl1, SSL *ssl2, 432 1.8 christos evutil_socket_t *fd_pair, struct bufferevent **underlying_pair, 433 1.8 christos enum regress_openssl_type type) 434 1.1 christos { 435 1.1 christos int state1 = is_open ? BUFFEREVENT_SSL_OPEN :BUFFEREVENT_SSL_CONNECTING; 436 1.1 christos int state2 = is_open ? BUFFEREVENT_SSL_OPEN :BUFFEREVENT_SSL_ACCEPTING; 437 1.8 christos int dirty_shutdown = type & REGRESS_OPENSSL_DIRTY_SHUTDOWN; 438 1.1 christos if (fd_pair) { 439 1.1 christos *bev1_out = bufferevent_openssl_socket_new( 440 1.1 christos base, fd_pair[0], ssl1, state1, flags); 441 1.1 christos *bev2_out = bufferevent_openssl_socket_new( 442 1.1 christos base, fd_pair[1], ssl2, state2, flags); 443 1.1 christos } else { 444 1.1 christos *bev1_out = bufferevent_openssl_filter_new( 445 1.1 christos base, underlying_pair[0], ssl1, state1, flags); 446 1.1 christos *bev2_out = bufferevent_openssl_filter_new( 447 1.1 christos base, underlying_pair[1], ssl2, state2, flags); 448 1.1 christos 449 1.1 christos } 450 1.1 christos bufferevent_setcb(*bev1_out, respond_to_number, done_writing_cb, 451 1.8 christos eventcb, (void*)(REGRESS_OPENSSL_CLIENT | (long)type)); 452 1.1 christos bufferevent_setcb(*bev2_out, respond_to_number, done_writing_cb, 453 1.8 christos eventcb, (void*)(REGRESS_OPENSSL_SERVER | (long)type)); 454 1.8 christos 455 1.8 christos bufferevent_openssl_set_allow_dirty_shutdown(*bev1_out, dirty_shutdown); 456 1.8 christos bufferevent_openssl_set_allow_dirty_shutdown(*bev2_out, dirty_shutdown); 457 1.1 christos } 458 1.1 christos 459 1.1 christos static void 460 1.1 christos regress_bufferevent_openssl(void *arg) 461 1.1 christos { 462 1.1 christos struct basic_test_data *data = arg; 463 1.1 christos 464 1.1 christos struct bufferevent *bev1, *bev2; 465 1.1 christos SSL *ssl1, *ssl2; 466 1.1 christos int flags = BEV_OPT_DEFER_CALLBACKS; 467 1.1 christos struct bufferevent *bev_ll[2] = { NULL, NULL }; 468 1.1 christos evutil_socket_t *fd_pair = NULL; 469 1.1 christos 470 1.8 christos enum regress_openssl_type type; 471 1.8 christos type = (enum regress_openssl_type)data->setup_data; 472 1.1 christos 473 1.8 christos if (type & REGRESS_OPENSSL_RENEGOTIATE) { 474 1.8 christos if (OPENSSL_VERSION_NUMBER >= 0x10001000 && 475 1.8 christos OPENSSL_VERSION_NUMBER < 0x1000104f) { 476 1.1 christos /* 1.0.1 up to 1.0.1c has a bug where TLS1.1 and 1.2 477 1.1 christos * can't renegotiate with themselves. Disable. */ 478 1.1 christos disable_tls_11_and_12 = 1; 479 1.1 christos } 480 1.1 christos renegotiate_at = 600; 481 1.1 christos } 482 1.1 christos 483 1.1 christos ssl1 = SSL_new(get_ssl_ctx()); 484 1.1 christos ssl2 = SSL_new(get_ssl_ctx()); 485 1.1 christos 486 1.8 christos SSL_use_certificate(ssl2, the_cert); 487 1.8 christos SSL_use_PrivateKey(ssl2, the_key); 488 1.1 christos 489 1.8 christos if (!(type & REGRESS_OPENSSL_OPEN)) 490 1.1 christos flags |= BEV_OPT_CLOSE_ON_FREE; 491 1.1 christos 492 1.8 christos if (!(type & REGRESS_OPENSSL_FILTER)) { 493 1.8 christos tt_assert(type & REGRESS_OPENSSL_SOCKETPAIR); 494 1.1 christos fd_pair = data->pair; 495 1.1 christos } else { 496 1.1 christos bev_ll[0] = bufferevent_socket_new(data->base, data->pair[0], 497 1.1 christos BEV_OPT_CLOSE_ON_FREE); 498 1.1 christos bev_ll[1] = bufferevent_socket_new(data->base, data->pair[1], 499 1.1 christos BEV_OPT_CLOSE_ON_FREE); 500 1.1 christos } 501 1.1 christos 502 1.1 christos open_ssl_bufevs(&bev1, &bev2, data->base, 0, flags, ssl1, ssl2, 503 1.8 christos fd_pair, bev_ll, type); 504 1.1 christos 505 1.8 christos if (!(type & REGRESS_OPENSSL_FILTER)) { 506 1.8 christos tt_fd_op(bufferevent_getfd(bev1), ==, data->pair[0]); 507 1.1 christos } else { 508 1.1 christos tt_ptr_op(bufferevent_get_underlying(bev1), ==, bev_ll[0]); 509 1.1 christos } 510 1.1 christos 511 1.8 christos if (type & REGRESS_OPENSSL_OPEN) { 512 1.1 christos pending_connect_events = 2; 513 1.1 christos stop_when_connected = 1; 514 1.1 christos exit_base = data->base; 515 1.1 christos event_base_dispatch(data->base); 516 1.1 christos /* Okay, now the renegotiation is done. Make new 517 1.1 christos * bufferevents to test opening in BUFFEREVENT_SSL_OPEN */ 518 1.1 christos flags |= BEV_OPT_CLOSE_ON_FREE; 519 1.1 christos bufferevent_free(bev1); 520 1.1 christos bufferevent_free(bev2); 521 1.1 christos bev1 = bev2 = NULL; 522 1.1 christos open_ssl_bufevs(&bev1, &bev2, data->base, 1, flags, ssl1, ssl2, 523 1.8 christos fd_pair, bev_ll, type); 524 1.1 christos } 525 1.1 christos 526 1.8 christos if (!(type & REGRESS_OPENSSL_TIMEOUT)) { 527 1.8 christos bufferevent_enable(bev1, EV_READ|EV_WRITE); 528 1.8 christos bufferevent_enable(bev2, EV_READ|EV_WRITE); 529 1.8 christos 530 1.8 christos if (!(type & REGRESS_OPENSSL_CLIENT_WRITE)) 531 1.8 christos evbuffer_add_printf(bufferevent_get_output(bev1), "1\n"); 532 1.8 christos 533 1.8 christos event_base_dispatch(data->base); 534 1.8 christos 535 1.8 christos tt_assert(test_is_done == 1); 536 1.8 christos tt_assert(n_connected == 2); 537 1.8 christos 538 1.8 christos /* We don't handle shutdown properly yet */ 539 1.8 christos if (type & REGRESS_OPENSSL_DIRTY_SHUTDOWN) { 540 1.8 christos tt_int_op(got_close, ==, 1); 541 1.8 christos tt_int_op(got_error, ==, 0); 542 1.8 christos } else { 543 1.8 christos tt_int_op(got_error, ==, 1); 544 1.8 christos } 545 1.8 christos tt_int_op(got_timeout, ==, 0); 546 1.8 christos } else { 547 1.8 christos struct timeval t = { 2, 0 }; 548 1.8 christos 549 1.8 christos bufferevent_enable(bev1, EV_READ|EV_WRITE); 550 1.8 christos bufferevent_disable(bev2, EV_READ|EV_WRITE); 551 1.8 christos 552 1.8 christos bufferevent_set_timeouts(bev1, &t, &t); 553 1.8 christos 554 1.8 christos if (!(type & REGRESS_OPENSSL_CLIENT_WRITE)) 555 1.8 christos evbuffer_add_printf(bufferevent_get_output(bev1), "1\n"); 556 1.8 christos 557 1.8 christos event_base_dispatch(data->base); 558 1.1 christos 559 1.8 christos tt_assert(test_is_done == 0); 560 1.8 christos tt_assert(n_connected == 0); 561 1.1 christos 562 1.8 christos tt_int_op(got_close, ==, 0); 563 1.8 christos tt_int_op(got_error, ==, 0); 564 1.8 christos tt_int_op(got_timeout, ==, 1); 565 1.1 christos 566 1.8 christos bufferevent_free(bev2); 567 1.8 christos } 568 1.1 christos 569 1.1 christos end: 570 1.1 christos return; 571 1.1 christos } 572 1.1 christos 573 1.1 christos static void 574 1.8 christos acceptcb_deferred(evutil_socket_t fd, short events, void *arg) 575 1.8 christos { 576 1.8 christos struct bufferevent *bev = arg; 577 1.8 christos bufferevent_enable(bev, EV_READ|EV_WRITE); 578 1.8 christos } 579 1.8 christos static void 580 1.1 christos acceptcb(struct evconnlistener *listener, evutil_socket_t fd, 581 1.1 christos struct sockaddr *addr, int socklen, void *arg) 582 1.1 christos { 583 1.1 christos struct basic_test_data *data = arg; 584 1.1 christos struct bufferevent *bev; 585 1.8 christos enum regress_openssl_type type; 586 1.1 christos SSL *ssl = SSL_new(get_ssl_ctx()); 587 1.1 christos 588 1.8 christos type = (enum regress_openssl_type)data->setup_data; 589 1.8 christos 590 1.8 christos SSL_use_certificate(ssl, the_cert); 591 1.8 christos SSL_use_PrivateKey(ssl, the_key); 592 1.1 christos 593 1.1 christos bev = bufferevent_openssl_socket_new( 594 1.8 christos data->base, fd, ssl, BUFFEREVENT_SSL_ACCEPTING, 595 1.1 christos BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS); 596 1.8 christos tt_assert(bev); 597 1.1 christos 598 1.1 christos bufferevent_setcb(bev, respond_to_number, NULL, eventcb, 599 1.8 christos (void*)(REGRESS_OPENSSL_SERVER)); 600 1.1 christos 601 1.8 christos if (type & REGRESS_OPENSSL_SLEEP) { 602 1.8 christos struct timeval when = { 1, 0 }; 603 1.8 christos event_base_once(data->base, -1, EV_TIMEOUT, 604 1.8 christos acceptcb_deferred, bev, &when); 605 1.8 christos bufferevent_disable(bev, EV_READ|EV_WRITE); 606 1.8 christos } else { 607 1.8 christos bufferevent_enable(bev, EV_READ|EV_WRITE); 608 1.8 christos } 609 1.1 christos 610 1.1 christos /* Only accept once, then disable ourself. */ 611 1.1 christos evconnlistener_disable(listener); 612 1.8 christos 613 1.8 christos end: 614 1.8 christos ; 615 1.8 christos } 616 1.8 christos 617 1.8 christos struct rwcount 618 1.8 christos { 619 1.8 christos evutil_socket_t fd; 620 1.8 christos size_t read; 621 1.8 christos size_t write; 622 1.8 christos }; 623 1.8 christos static int 624 1.8 christos bio_rwcount_new(BIO *b) 625 1.8 christos { 626 1.8 christos BIO_set_init(b, 0); 627 1.8 christos BIO_set_data(b, NULL); 628 1.8 christos return 1; 629 1.8 christos } 630 1.8 christos static int 631 1.8 christos bio_rwcount_free(BIO *b) 632 1.8 christos { 633 1.8 christos TT_BLATHER(("bio_rwcount_free: %p", b)); 634 1.8 christos if (!b) 635 1.8 christos return 0; 636 1.8 christos if (BIO_get_shutdown(b)) { 637 1.8 christos BIO_set_init(b, 0); 638 1.8 christos BIO_set_data(b, NULL); 639 1.8 christos } 640 1.8 christos return 1; 641 1.8 christos } 642 1.8 christos static int 643 1.8 christos bio_rwcount_read(BIO *b, char *out, int outlen) 644 1.8 christos { 645 1.8 christos struct rwcount *rw = BIO_get_data(b); 646 1.8 christos ev_ssize_t ret = recv(rw->fd, out, outlen, 0); 647 1.8 christos ++rw->read; 648 1.8 christos if (ret == -1 && EVUTIL_ERR_RW_RETRIABLE(EVUTIL_SOCKET_ERROR())) { 649 1.8 christos BIO_set_retry_read(b); 650 1.8 christos } 651 1.8 christos return ret; 652 1.8 christos } 653 1.8 christos static int 654 1.8 christos bio_rwcount_write(BIO *b, const char *in, int inlen) 655 1.8 christos { 656 1.8 christos struct rwcount *rw = BIO_get_data(b); 657 1.8 christos ev_ssize_t ret = send(rw->fd, in, inlen, 0); 658 1.8 christos ++rw->write; 659 1.8 christos if (ret == -1 && EVUTIL_ERR_RW_RETRIABLE(EVUTIL_SOCKET_ERROR())) { 660 1.8 christos BIO_set_retry_write(b); 661 1.8 christos } 662 1.8 christos return ret; 663 1.8 christos } 664 1.8 christos static long 665 1.8 christos bio_rwcount_ctrl(BIO *b, int cmd, long num, void *ptr) 666 1.8 christos { 667 1.8 christos struct rwcount *rw = BIO_get_data(b); 668 1.8 christos long ret = 0; 669 1.8 christos switch (cmd) { 670 1.8 christos case BIO_C_GET_FD: 671 1.8 christos ret = rw->fd; 672 1.8 christos break; 673 1.8 christos case BIO_CTRL_GET_CLOSE: 674 1.8 christos ret = BIO_get_shutdown(b); 675 1.8 christos break; 676 1.8 christos case BIO_CTRL_SET_CLOSE: 677 1.8 christos BIO_set_shutdown(b, (int)num); 678 1.8 christos break; 679 1.8 christos case BIO_CTRL_PENDING: 680 1.8 christos ret = 0; 681 1.8 christos break; 682 1.8 christos case BIO_CTRL_WPENDING: 683 1.8 christos ret = 0; 684 1.8 christos break; 685 1.8 christos case BIO_CTRL_DUP: 686 1.8 christos case BIO_CTRL_FLUSH: 687 1.8 christos ret = 1; 688 1.8 christos break; 689 1.8 christos } 690 1.8 christos return ret; 691 1.8 christos } 692 1.8 christos static int 693 1.8 christos bio_rwcount_puts(BIO *b, const char *s) 694 1.8 christos { 695 1.8 christos return bio_rwcount_write(b, s, strlen(s)); 696 1.8 christos } 697 1.8 christos #define BIO_TYPE_LIBEVENT_RWCOUNT 0xff1 698 1.8 christos static BIO_METHOD *methods_rwcount; 699 1.8 christos 700 1.8 christos static BIO_METHOD * 701 1.8 christos BIO_s_rwcount(void) 702 1.8 christos { 703 1.8 christos if (methods_rwcount == NULL) { 704 1.8 christos methods_rwcount = BIO_meth_new(BIO_TYPE_LIBEVENT_RWCOUNT, "rwcount"); 705 1.8 christos if (methods_rwcount == NULL) 706 1.8 christos return NULL; 707 1.8 christos BIO_meth_set_write(methods_rwcount, bio_rwcount_write); 708 1.8 christos BIO_meth_set_read(methods_rwcount, bio_rwcount_read); 709 1.8 christos BIO_meth_set_puts(methods_rwcount, bio_rwcount_puts); 710 1.8 christos BIO_meth_set_ctrl(methods_rwcount, bio_rwcount_ctrl); 711 1.8 christos BIO_meth_set_create(methods_rwcount, bio_rwcount_new); 712 1.8 christos BIO_meth_set_destroy(methods_rwcount, bio_rwcount_free); 713 1.8 christos } 714 1.8 christos return methods_rwcount; 715 1.8 christos } 716 1.8 christos static BIO * 717 1.8 christos BIO_new_rwcount(int close_flag) 718 1.8 christos { 719 1.8 christos BIO *result; 720 1.8 christos if (!(result = BIO_new(BIO_s_rwcount()))) 721 1.8 christos return NULL; 722 1.8 christos BIO_set_init(result, 1); 723 1.8 christos BIO_set_data(result, NULL); 724 1.8 christos BIO_set_shutdown(result, !!close_flag); 725 1.8 christos return result; 726 1.1 christos } 727 1.1 christos 728 1.1 christos static void 729 1.1 christos regress_bufferevent_openssl_connect(void *arg) 730 1.1 christos { 731 1.1 christos struct basic_test_data *data = arg; 732 1.1 christos 733 1.1 christos struct event_base *base = data->base; 734 1.1 christos 735 1.1 christos struct evconnlistener *listener; 736 1.1 christos struct bufferevent *bev; 737 1.1 christos struct sockaddr_in sin; 738 1.1 christos struct sockaddr_storage ss; 739 1.1 christos ev_socklen_t slen; 740 1.8 christos SSL *ssl; 741 1.8 christos struct rwcount rw = { -1, 0, 0 }; 742 1.8 christos enum regress_openssl_type type; 743 1.1 christos 744 1.8 christos type = (enum regress_openssl_type)data->setup_data; 745 1.1 christos 746 1.1 christos memset(&sin, 0, sizeof(sin)); 747 1.1 christos sin.sin_family = AF_INET; 748 1.1 christos sin.sin_addr.s_addr = htonl(0x7f000001); 749 1.1 christos 750 1.1 christos memset(&ss, 0, sizeof(ss)); 751 1.1 christos slen = sizeof(ss); 752 1.1 christos 753 1.1 christos listener = evconnlistener_new_bind(base, acceptcb, data, 754 1.1 christos LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, 755 1.1 christos -1, (struct sockaddr *)&sin, sizeof(sin)); 756 1.1 christos 757 1.1 christos tt_assert(listener); 758 1.1 christos tt_assert(evconnlistener_get_fd(listener) >= 0); 759 1.1 christos 760 1.8 christos ssl = SSL_new(get_ssl_ctx()); 761 1.8 christos tt_assert(ssl); 762 1.8 christos 763 1.1 christos bev = bufferevent_openssl_socket_new( 764 1.8 christos data->base, -1, ssl, 765 1.1 christos BUFFEREVENT_SSL_CONNECTING, 766 1.1 christos BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS); 767 1.1 christos tt_assert(bev); 768 1.1 christos 769 1.8 christos bufferevent_setcb(bev, respond_to_number, free_on_cb, eventcb, 770 1.8 christos (void*)(REGRESS_OPENSSL_CLIENT)); 771 1.1 christos 772 1.1 christos tt_assert(getsockname(evconnlistener_get_fd(listener), 773 1.1 christos (struct sockaddr*)&ss, &slen) == 0); 774 1.1 christos tt_assert(slen == sizeof(struct sockaddr_in)); 775 1.1 christos tt_int_op(((struct sockaddr*)&ss)->sa_family, ==, AF_INET); 776 1.1 christos 777 1.1 christos tt_assert(0 == 778 1.1 christos bufferevent_socket_connect(bev, (struct sockaddr*)&ss, slen)); 779 1.8 christos /* Possible only when we have fd, since be_openssl can and will overwrite 780 1.8 christos * bio otherwise before */ 781 1.8 christos if (type & REGRESS_OPENSSL_SLEEP) { 782 1.8 christos BIO *bio; 783 1.8 christos 784 1.8 christos rw.fd = bufferevent_getfd(bev); 785 1.8 christos bio = BIO_new_rwcount(0); 786 1.8 christos tt_assert(bio); 787 1.8 christos BIO_set_data(bio, &rw); 788 1.8 christos SSL_set_bio(ssl, bio, bio); 789 1.8 christos } 790 1.1 christos evbuffer_add_printf(bufferevent_get_output(bev), "1\n"); 791 1.1 christos bufferevent_enable(bev, EV_READ|EV_WRITE); 792 1.1 christos 793 1.1 christos event_base_dispatch(base); 794 1.8 christos 795 1.8 christos tt_int_op(rw.read, <=, 100); 796 1.8 christos tt_int_op(rw.write, <=, 100); 797 1.8 christos end: 798 1.8 christos evconnlistener_free(listener); 799 1.8 christos } 800 1.8 christos 801 1.8 christos struct wm_context 802 1.8 christos { 803 1.8 christos int server; 804 1.8 christos int flags; 805 1.8 christos struct evbuffer *data; 806 1.8 christos size_t to_read; 807 1.8 christos size_t wm_high; 808 1.8 christos size_t limit; 809 1.8 christos size_t get; 810 1.8 christos struct bufferevent *bev; 811 1.8 christos struct wm_context *neighbour; 812 1.8 christos }; 813 1.8 christos static void 814 1.8 christos wm_transfer(struct bufferevent *bev, void *arg) 815 1.8 christos { 816 1.8 christos struct wm_context *ctx = arg; 817 1.8 christos struct evbuffer *in = bufferevent_get_input(bev); 818 1.8 christos struct evbuffer *out = bufferevent_get_output(bev); 819 1.8 christos size_t len = evbuffer_get_length(in); 820 1.8 christos size_t drain = len < ctx->to_read ? len : ctx->to_read; 821 1.8 christos 822 1.8 christos if (ctx->get >= ctx->limit) { 823 1.8 christos TT_BLATHER(("wm_transfer-%s(%p): break", 824 1.8 christos ctx->server ? "server" : "client", bev)); 825 1.8 christos bufferevent_setcb(bev, NULL, NULL, NULL, NULL); 826 1.8 christos bufferevent_disable(bev, EV_READ); 827 1.8 christos if (ctx->neighbour->get >= ctx->neighbour->limit) { 828 1.8 christos event_base_loopbreak(bufferevent_get_base(bev)); 829 1.8 christos } 830 1.8 christos } else { 831 1.8 christos ctx->get += drain; 832 1.8 christos evbuffer_drain(in, drain); 833 1.8 christos } 834 1.8 christos 835 1.8 christos TT_BLATHER(("wm_transfer-%s(%p): " 836 1.8 christos "in: " EV_SIZE_FMT ", " 837 1.8 christos "out: " EV_SIZE_FMT ", " 838 1.8 christos "got: " EV_SIZE_FMT "", 839 1.8 christos ctx->server ? "server" : "client", bev, 840 1.8 christos evbuffer_get_length(in), 841 1.8 christos evbuffer_get_length(out), 842 1.8 christos ctx->get)); 843 1.8 christos 844 1.8 christos evbuffer_add_buffer_reference(out, ctx->data); 845 1.8 christos } 846 1.8 christos static void 847 1.8 christos wm_eventcb(struct bufferevent *bev, short what, void *arg) 848 1.8 christos { 849 1.8 christos struct wm_context *ctx = arg; 850 1.8 christos TT_BLATHER(("wm_eventcb-%s(%p): %i", 851 1.8 christos ctx->server ? "server" : "client", bev, what)); 852 1.8 christos if (what & BEV_EVENT_CONNECTED) { 853 1.8 christos } else { 854 1.8 christos ctx->get = 0; 855 1.8 christos } 856 1.8 christos } 857 1.8 christos static void 858 1.8 christos wm_acceptcb(struct evconnlistener *listener, evutil_socket_t fd, 859 1.8 christos struct sockaddr *addr, int socklen, void *arg) 860 1.8 christos { 861 1.8 christos struct wm_context *ctx = arg; 862 1.8 christos struct bufferevent *bev; 863 1.8 christos struct event_base *base = evconnlistener_get_base(listener); 864 1.8 christos SSL *ssl = SSL_new(get_ssl_ctx()); 865 1.8 christos 866 1.8 christos SSL_use_certificate(ssl, the_cert); 867 1.8 christos SSL_use_PrivateKey(ssl, the_key); 868 1.8 christos 869 1.8 christos bev = bufferevent_openssl_socket_new( 870 1.8 christos base, fd, ssl, BUFFEREVENT_SSL_ACCEPTING, ctx->flags); 871 1.8 christos 872 1.8 christos TT_BLATHER(("wm_transfer-%s(%p): accept", 873 1.8 christos ctx->server ? "server" : "client", bev)); 874 1.8 christos 875 1.8 christos bufferevent_setwatermark(bev, EV_READ, 0, ctx->wm_high); 876 1.8 christos bufferevent_setcb(bev, wm_transfer, NULL, wm_eventcb, ctx); 877 1.8 christos bufferevent_enable(bev, EV_READ|EV_WRITE); 878 1.8 christos ctx->bev = bev; 879 1.8 christos 880 1.8 christos /* Only accept once, then disable ourself. */ 881 1.8 christos evconnlistener_disable(listener); 882 1.8 christos } 883 1.8 christos static void 884 1.8 christos regress_bufferevent_openssl_wm(void *arg) 885 1.8 christos { 886 1.8 christos struct basic_test_data *data = arg; 887 1.8 christos struct event_base *base = data->base; 888 1.8 christos 889 1.8 christos struct evconnlistener *listener; 890 1.8 christos struct bufferevent *bev; 891 1.8 christos struct sockaddr_in sin; 892 1.8 christos struct sockaddr_storage ss; 893 1.8 christos enum regress_openssl_type type = 894 1.8 christos (enum regress_openssl_type)data->setup_data; 895 1.8 christos int bev_flags = BEV_OPT_CLOSE_ON_FREE; 896 1.8 christos ev_socklen_t slen; 897 1.8 christos SSL *ssl; 898 1.8 christos struct wm_context client, server; 899 1.8 christos char *payload; 900 1.8 christos size_t payload_len = 1<<10; 901 1.8 christos size_t wm_high = 5<<10; 902 1.8 christos 903 1.8 christos memset(&sin, 0, sizeof(sin)); 904 1.8 christos sin.sin_family = AF_INET; 905 1.8 christos sin.sin_addr.s_addr = htonl(0x7f000001); 906 1.8 christos 907 1.8 christos memset(&ss, 0, sizeof(ss)); 908 1.8 christos slen = sizeof(ss); 909 1.8 christos 910 1.8 christos if (type & REGRESS_DEFERRED_CALLBACKS) 911 1.8 christos bev_flags |= BEV_OPT_DEFER_CALLBACKS; 912 1.8 christos 913 1.8 christos memset(&client, 0, sizeof(client)); 914 1.8 christos memset(&server, 0, sizeof(server)); 915 1.8 christos client.server = 0; 916 1.8 christos server.server = 1; 917 1.8 christos client.flags = server.flags = bev_flags; 918 1.8 christos client.data = evbuffer_new(); 919 1.8 christos server.data = evbuffer_new(); 920 1.8 christos payload = calloc(1, payload_len); 921 1.8 christos memset(payload, 'A', payload_len); 922 1.8 christos evbuffer_add(server.data, payload, payload_len); 923 1.8 christos evbuffer_add(client.data, payload, payload_len); 924 1.8 christos client.wm_high = server.wm_high = wm_high; 925 1.8 christos client.limit = server.limit = wm_high<<3; 926 1.8 christos client.to_read = server.to_read = payload_len>>1; 927 1.8 christos 928 1.8 christos TT_BLATHER(("openssl_wm: " 929 1.8 christos "payload_len = " EV_SIZE_FMT ", " 930 1.8 christos "wm_high = " EV_SIZE_FMT ", " 931 1.8 christos "limit = " EV_SIZE_FMT ", " 932 1.8 christos "to_read: " EV_SIZE_FMT "", 933 1.8 christos payload_len, 934 1.8 christos wm_high, 935 1.8 christos server.limit, 936 1.8 christos server.to_read)); 937 1.8 christos 938 1.8 christos listener = evconnlistener_new_bind(base, wm_acceptcb, &server, 939 1.8 christos LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, 940 1.8 christos -1, (struct sockaddr *)&sin, sizeof(sin)); 941 1.8 christos 942 1.8 christos tt_assert(listener); 943 1.8 christos tt_assert(evconnlistener_get_fd(listener) >= 0); 944 1.8 christos 945 1.8 christos ssl = SSL_new(get_ssl_ctx()); 946 1.8 christos tt_assert(ssl); 947 1.8 christos 948 1.8 christos if (type & REGRESS_OPENSSL_FILTER) { 949 1.8 christos bev = bufferevent_socket_new(data->base, -1, client.flags); 950 1.8 christos tt_assert(bev); 951 1.8 christos bev = bufferevent_openssl_filter_new( 952 1.8 christos base, bev, ssl, BUFFEREVENT_SSL_CONNECTING, client.flags); 953 1.8 christos } else { 954 1.8 christos bev = bufferevent_openssl_socket_new( 955 1.8 christos data->base, -1, ssl, 956 1.8 christos BUFFEREVENT_SSL_CONNECTING, 957 1.8 christos client.flags); 958 1.8 christos } 959 1.8 christos tt_assert(bev); 960 1.8 christos client.bev = bev; 961 1.8 christos 962 1.8 christos server.neighbour = &client; 963 1.8 christos client.neighbour = &server; 964 1.8 christos 965 1.8 christos bufferevent_setwatermark(bev, EV_READ, 0, client.wm_high); 966 1.8 christos bufferevent_setcb(bev, wm_transfer, NULL, wm_eventcb, &client); 967 1.8 christos 968 1.8 christos tt_assert(getsockname(evconnlistener_get_fd(listener), 969 1.8 christos (struct sockaddr*)&ss, &slen) == 0); 970 1.8 christos 971 1.8 christos tt_assert(!bufferevent_socket_connect(bev, (struct sockaddr*)&ss, slen)); 972 1.8 christos tt_assert(!evbuffer_add_buffer_reference(bufferevent_get_output(bev), client.data)); 973 1.8 christos tt_assert(!bufferevent_enable(bev, EV_READ|EV_WRITE)); 974 1.8 christos 975 1.8 christos event_base_dispatch(base); 976 1.8 christos 977 1.8 christos tt_int_op(client.get, ==, client.limit); 978 1.8 christos tt_int_op(server.get, ==, server.limit); 979 1.8 christos 980 1.1 christos end: 981 1.8 christos free(payload); 982 1.8 christos evbuffer_free(client.data); 983 1.8 christos evbuffer_free(server.data); 984 1.8 christos evconnlistener_free(listener); 985 1.8 christos bufferevent_free(client.bev); 986 1.8 christos bufferevent_free(server.bev); 987 1.8 christos 988 1.8 christos /* XXX: by some reason otherise there is a leak */ 989 1.8 christos if (!(type & REGRESS_OPENSSL_FILTER)) 990 1.8 christos event_base_loop(base, EVLOOP_ONCE); 991 1.1 christos } 992 1.1 christos 993 1.1 christos struct testcase_t ssl_testcases[] = { 994 1.8 christos #define T(a) ((void *)(a)) 995 1.8 christos { "bufferevent_socketpair", regress_bufferevent_openssl, 996 1.8 christos TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_SOCKETPAIR) }, 997 1.8 christos { "bufferevent_socketpair_write_after_connect", regress_bufferevent_openssl, 998 1.8 christos TT_ISOLATED, &ssl_setup, 999 1.8 christos T(REGRESS_OPENSSL_SOCKETPAIR|REGRESS_OPENSSL_CLIENT_WRITE) }, 1000 1.1 christos { "bufferevent_filter", regress_bufferevent_openssl, 1001 1.8 christos TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_FILTER) }, 1002 1.8 christos { "bufferevent_filter_write_after_connect", regress_bufferevent_openssl, 1003 1.8 christos TT_ISOLATED, &ssl_setup, 1004 1.8 christos T(REGRESS_OPENSSL_FILTER|REGRESS_OPENSSL_CLIENT_WRITE) }, 1005 1.1 christos { "bufferevent_renegotiate_socketpair", regress_bufferevent_openssl, 1006 1.8 christos TT_ISOLATED, &ssl_setup, 1007 1.8 christos T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_RENEGOTIATE) }, 1008 1.1 christos { "bufferevent_renegotiate_filter", regress_bufferevent_openssl, 1009 1.8 christos TT_ISOLATED, &ssl_setup, 1010 1.8 christos T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_RENEGOTIATE) }, 1011 1.1 christos { "bufferevent_socketpair_startopen", regress_bufferevent_openssl, 1012 1.8 christos TT_ISOLATED, &ssl_setup, 1013 1.8 christos T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_OPEN) }, 1014 1.1 christos { "bufferevent_filter_startopen", regress_bufferevent_openssl, 1015 1.8 christos TT_ISOLATED, &ssl_setup, 1016 1.8 christos T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_OPEN) }, 1017 1.8 christos 1018 1.8 christos { "bufferevent_socketpair_dirty_shutdown", regress_bufferevent_openssl, 1019 1.8 christos TT_ISOLATED, &ssl_setup, 1020 1.8 christos T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_DIRTY_SHUTDOWN) }, 1021 1.8 christos { "bufferevent_filter_dirty_shutdown", regress_bufferevent_openssl, 1022 1.8 christos TT_ISOLATED, &ssl_setup, 1023 1.8 christos T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_DIRTY_SHUTDOWN) }, 1024 1.8 christos { "bufferevent_renegotiate_socketpair_dirty_shutdown", 1025 1.8 christos regress_bufferevent_openssl, 1026 1.8 christos TT_ISOLATED, 1027 1.8 christos &ssl_setup, 1028 1.8 christos T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_RENEGOTIATE | REGRESS_OPENSSL_DIRTY_SHUTDOWN) }, 1029 1.8 christos { "bufferevent_renegotiate_filter_dirty_shutdown", 1030 1.8 christos regress_bufferevent_openssl, 1031 1.8 christos TT_ISOLATED, 1032 1.8 christos &ssl_setup, 1033 1.8 christos T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_RENEGOTIATE | REGRESS_OPENSSL_DIRTY_SHUTDOWN) }, 1034 1.8 christos { "bufferevent_socketpair_startopen_dirty_shutdown", 1035 1.8 christos regress_bufferevent_openssl, 1036 1.8 christos TT_ISOLATED, &ssl_setup, 1037 1.8 christos T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_OPEN | REGRESS_OPENSSL_DIRTY_SHUTDOWN) }, 1038 1.8 christos { "bufferevent_filter_startopen_dirty_shutdown", 1039 1.8 christos regress_bufferevent_openssl, 1040 1.8 christos TT_ISOLATED, &ssl_setup, 1041 1.8 christos T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_OPEN | REGRESS_OPENSSL_DIRTY_SHUTDOWN) }, 1042 1.8 christos 1043 1.8 christos { "bufferevent_socketpair_fd", regress_bufferevent_openssl, 1044 1.8 christos TT_ISOLATED, &ssl_setup, 1045 1.8 christos T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_FD) }, 1046 1.8 christos { "bufferevent_socketpair_freed", regress_bufferevent_openssl, 1047 1.8 christos TT_ISOLATED, &ssl_setup, 1048 1.8 christos T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_FREED) }, 1049 1.8 christos { "bufferevent_socketpair_freed_fd", regress_bufferevent_openssl, 1050 1.8 christos TT_ISOLATED, &ssl_setup, 1051 1.8 christos T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_FREED | REGRESS_OPENSSL_FD) }, 1052 1.8 christos { "bufferevent_filter_freed_fd", regress_bufferevent_openssl, 1053 1.8 christos TT_ISOLATED, &ssl_setup, 1054 1.8 christos T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_FREED | REGRESS_OPENSSL_FD) }, 1055 1.8 christos 1056 1.8 christos { "bufferevent_socketpair_timeout", regress_bufferevent_openssl, 1057 1.8 christos TT_ISOLATED, &ssl_setup, 1058 1.8 christos T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_TIMEOUT) }, 1059 1.8 christos { "bufferevent_socketpair_timeout_freed_fd", regress_bufferevent_openssl, 1060 1.8 christos TT_ISOLATED, &ssl_setup, 1061 1.8 christos T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_TIMEOUT | REGRESS_OPENSSL_FREED | REGRESS_OPENSSL_FD) }, 1062 1.1 christos 1063 1.1 christos { "bufferevent_connect", regress_bufferevent_openssl_connect, 1064 1.8 christos TT_FORK|TT_NEED_BASE, &ssl_setup, NULL }, 1065 1.8 christos { "bufferevent_connect_sleep", regress_bufferevent_openssl_connect, 1066 1.8 christos TT_FORK|TT_NEED_BASE, &ssl_setup, T(REGRESS_OPENSSL_SLEEP) }, 1067 1.8 christos 1068 1.8 christos { "bufferevent_wm", regress_bufferevent_openssl_wm, 1069 1.8 christos TT_FORK|TT_NEED_BASE, &ssl_setup, NULL }, 1070 1.8 christos { "bufferevent_wm_filter", regress_bufferevent_openssl_wm, 1071 1.8 christos TT_FORK|TT_NEED_BASE, &ssl_setup, T(REGRESS_OPENSSL_FILTER) }, 1072 1.8 christos { "bufferevent_wm_defer", regress_bufferevent_openssl_wm, 1073 1.8 christos TT_FORK|TT_NEED_BASE, &ssl_setup, T(REGRESS_DEFERRED_CALLBACKS) }, 1074 1.8 christos { "bufferevent_wm_filter_defer", regress_bufferevent_openssl_wm, 1075 1.8 christos TT_FORK|TT_NEED_BASE, &ssl_setup, T(REGRESS_OPENSSL_FILTER|REGRESS_DEFERRED_CALLBACKS) }, 1076 1.8 christos 1077 1.8 christos #undef T 1078 1.1 christos 1079 1.1 christos END_OF_TESTCASES, 1080 1.1 christos }; 1081