1 /* $NetBSD: regress_ssl.c,v 1.6 2021/05/30 00:19:08 joerg 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 static void *xkey = __UNCONST(KEY); 103 104 EVP_PKEY * 105 ssl_getkey(void) 106 { 107 EVP_PKEY *key; 108 BIO *bio; 109 110 /* new read-only BIO backed by KEY. */ 111 bio = BIO_new_mem_buf(xkey, -1); 112 tt_assert(bio); 113 114 key = PEM_read_bio_PrivateKey(bio,NULL,NULL,NULL); 115 BIO_free(bio); 116 tt_assert(key); 117 118 return key; 119 end: 120 return NULL; 121 } 122 123 X509 * 124 ssl_getcert(EVP_PKEY *key) 125 { 126 /* Dummy code to make a quick-and-dirty valid certificate with 127 OpenSSL. Don't copy this code into your own program! It does a 128 number of things in a stupid and insecure way. */ 129 X509 *x509 = NULL; 130 X509_NAME *name = NULL; 131 int nid; 132 time_t now = time(NULL); 133 134 tt_assert(key); 135 136 x509 = X509_new(); 137 tt_assert(x509); 138 tt_assert(0 != X509_set_version(x509, 2)); 139 tt_assert(0 != ASN1_INTEGER_set(X509_get_serialNumber(x509), 140 (long)now)); 141 142 name = X509_NAME_new(); 143 tt_assert(name); 144 nid = OBJ_txt2nid("commonName"); 145 tt_assert(NID_undef != nid); 146 tt_assert(0 != X509_NAME_add_entry_by_NID( 147 name, nid, MBSTRING_ASC, __UNCONST("example.com"), 148 -1, -1, 0)); 149 150 X509_set_subject_name(x509, name); 151 X509_set_issuer_name(x509, name); 152 X509_NAME_free(name); 153 154 X509_time_adj(X509_getm_notBefore(x509), 0, &now); 155 now += 3600; 156 X509_time_adj(X509_getm_notAfter(x509), 0, &now); 157 X509_set_pubkey(x509, key); 158 tt_assert(0 != X509_sign(x509, key, EVP_sha1())); 159 160 return x509; 161 end: 162 X509_free(x509); 163 X509_NAME_free(name); 164 return NULL; 165 } 166 167 static int disable_tls_11_and_12 = 0; 168 static SSL_CTX *the_ssl_ctx = NULL; 169 170 SSL_CTX * 171 get_ssl_ctx(void) 172 { 173 if (the_ssl_ctx) 174 return the_ssl_ctx; 175 the_ssl_ctx = SSL_CTX_new(SSLv23_method()); 176 if (!the_ssl_ctx) 177 return NULL; 178 if (disable_tls_11_and_12) { 179 #ifdef SSL_OP_NO_TLSv1_2 180 SSL_CTX_set_options(the_ssl_ctx, SSL_OP_NO_TLSv1_2); 181 #endif 182 #ifdef SSL_OP_NO_TLSv1_1 183 SSL_CTX_set_options(the_ssl_ctx, SSL_OP_NO_TLSv1_1); 184 #endif 185 } 186 return the_ssl_ctx; 187 } 188 189 static int test_is_done; 190 static int n_connected; 191 static int got_close; 192 static int got_error; 193 static int got_timeout; 194 static int renegotiate_at = -1; 195 static int stop_when_connected; 196 static int pending_connect_events; 197 static struct event_base *exit_base; 198 static X509 *the_cert; 199 EVP_PKEY *the_key; 200 201 void 202 init_ssl(void) 203 { 204 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \ 205 (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) 206 SSL_library_init(); 207 ERR_load_crypto_strings(); 208 SSL_load_error_strings(); 209 OpenSSL_add_all_algorithms(); 210 if (SSLeay() != OPENSSL_VERSION_NUMBER) { 211 TT_DECLARE("WARN", 212 ("Version mismatch for openssl: compiled with %lx but running with %lx", 213 (unsigned long)OPENSSL_VERSION_NUMBER, (unsigned long)SSLeay())); 214 } 215 #endif 216 } 217 218 static void * 219 ssl_test_setup(const struct testcase_t *testcase) 220 { 221 init_ssl(); 222 223 the_key = ssl_getkey(); 224 EVUTIL_ASSERT(the_key); 225 226 the_cert = ssl_getcert(the_key); 227 EVUTIL_ASSERT(the_cert); 228 229 disable_tls_11_and_12 = 0; 230 231 return basic_test_setup(testcase); 232 } 233 static int 234 ssl_test_cleanup(const struct testcase_t *testcase, void *ptr) 235 { 236 int ret = basic_test_cleanup(testcase, ptr); 237 if (!ret) { 238 return ret; 239 } 240 241 test_is_done = 0; 242 n_connected = 0; 243 got_close = 0; 244 got_error = 0; 245 got_timeout = 0; 246 renegotiate_at = -1; 247 stop_when_connected = 0; 248 pending_connect_events = 0; 249 exit_base = NULL; 250 251 X509_free(the_cert); 252 EVP_PKEY_free(the_key); 253 254 SSL_CTX_free(the_ssl_ctx); 255 the_ssl_ctx = NULL; 256 257 return 1; 258 } 259 const struct testcase_setup_t ssl_setup = { 260 ssl_test_setup, ssl_test_cleanup 261 }; 262 263 264 /* ==================== 265 Here's a simple test: we read a number from the input, increment it, and 266 reply, until we get to 1001. 267 */ 268 269 enum regress_openssl_type 270 { 271 REGRESS_OPENSSL_SOCKETPAIR = 1, 272 REGRESS_OPENSSL_FILTER = 2, 273 REGRESS_OPENSSL_RENEGOTIATE = 4, 274 REGRESS_OPENSSL_OPEN = 8, 275 REGRESS_OPENSSL_DIRTY_SHUTDOWN = 16, 276 REGRESS_OPENSSL_FD = 32, 277 278 REGRESS_OPENSSL_CLIENT = 64, 279 REGRESS_OPENSSL_SERVER = 128, 280 281 REGRESS_OPENSSL_FREED = 256, 282 REGRESS_OPENSSL_TIMEOUT = 512, 283 REGRESS_OPENSSL_SLEEP = 1024, 284 285 REGRESS_OPENSSL_CLIENT_WRITE = 2048, 286 287 REGRESS_DEFERRED_CALLBACKS = 4096, 288 }; 289 290 static void 291 bufferevent_openssl_check_fd(struct bufferevent *bev, int filter) 292 { 293 tt_fd_op(bufferevent_getfd(bev), !=, EVUTIL_INVALID_SOCKET); 294 tt_fd_op(bufferevent_setfd(bev, EVUTIL_INVALID_SOCKET), ==, 0); 295 if (filter) { 296 tt_fd_op(bufferevent_getfd(bev), !=, EVUTIL_INVALID_SOCKET); 297 } else { 298 tt_fd_op(bufferevent_getfd(bev), ==, EVUTIL_INVALID_SOCKET); 299 } 300 301 end: 302 ; 303 } 304 static void 305 bufferevent_openssl_check_freed(struct bufferevent *bev) 306 { 307 tt_int_op(event_pending(&bev->ev_read, EVLIST_ALL, NULL), ==, 0); 308 tt_int_op(event_pending(&bev->ev_write, EVLIST_ALL, NULL), ==, 0); 309 310 end: 311 ; 312 } 313 314 static void 315 free_on_cb(struct bufferevent *bev, void *ctx) 316 { 317 TT_BLATHER(("free_on_cb: %p", bev)); 318 bufferevent_free(bev); 319 } 320 321 static void 322 respond_to_number(struct bufferevent *bev, void *ctx) 323 { 324 struct evbuffer *b = bufferevent_get_input(bev); 325 char *line; 326 int n; 327 328 enum regress_openssl_type type; 329 type = (enum regress_openssl_type)(uintptr_t)ctx; 330 331 line = evbuffer_readln(b, NULL, EVBUFFER_EOL_LF); 332 if (! line) 333 return; 334 n = atoi(line); 335 if (n <= 0) 336 TT_FAIL(("Bad number: %s", line)); 337 free(line); 338 TT_BLATHER(("The number was %d", n)); 339 if (n == 1001) { 340 ++test_is_done; 341 bufferevent_free(bev); /* Should trigger close on other side. */ 342 return; 343 } 344 if ((type & REGRESS_OPENSSL_CLIENT) && n == renegotiate_at) { 345 SSL_renegotiate(bufferevent_openssl_get_ssl(bev)); 346 } 347 ++n; 348 evbuffer_add_printf(bufferevent_get_output(bev), 349 "%d\n", n); 350 TT_BLATHER(("Done reading; now writing.")); 351 bufferevent_enable(bev, EV_WRITE); 352 bufferevent_disable(bev, EV_READ); 353 } 354 355 static void 356 done_writing_cb(struct bufferevent *bev, void *ctx) 357 { 358 struct evbuffer *b = bufferevent_get_output(bev); 359 if (evbuffer_get_length(b)) 360 return; 361 TT_BLATHER(("Done writing.")); 362 bufferevent_disable(bev, EV_WRITE); 363 bufferevent_enable(bev, EV_READ); 364 } 365 366 static void 367 eventcb(struct bufferevent *bev, short what, void *ctx) 368 { 369 X509 *peer_cert = NULL; 370 enum regress_openssl_type type; 371 type = (enum regress_openssl_type)(uintptr_t)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)(uintptr_t)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)(uintptr_t)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)(uintptr_t)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)(uintptr_t)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