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