1*eabc0478Schristos /* $NetBSD: regress_ssl.c,v 1.8 2024/08/18 20:47:23 christos Exp $ */ 28585484eSchristos 38585484eSchristos /* 48585484eSchristos * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson 58585484eSchristos * 68585484eSchristos * Redistribution and use in source and binary forms, with or without 78585484eSchristos * modification, are permitted provided that the following conditions 88585484eSchristos * are met: 98585484eSchristos * 1. Redistributions of source code must retain the above copyright 108585484eSchristos * notice, this list of conditions and the following disclaimer. 118585484eSchristos * 2. Redistributions in binary form must reproduce the above copyright 128585484eSchristos * notice, this list of conditions and the following disclaimer in the 138585484eSchristos * documentation and/or other materials provided with the distribution. 148585484eSchristos * 3. The name of the author may not be used to endorse or promote products 158585484eSchristos * derived from this software without specific prior written permission. 168585484eSchristos * 178585484eSchristos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 188585484eSchristos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 198585484eSchristos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 208585484eSchristos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 218585484eSchristos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 228585484eSchristos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 238585484eSchristos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 248585484eSchristos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 258585484eSchristos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 268585484eSchristos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 278585484eSchristos */ 288585484eSchristos 29b8ecfcfeSchristos // Get rid of OSX 10.7 and greater deprecation warnings. 30b8ecfcfeSchristos #if defined(__APPLE__) && defined(__clang__) 31b8ecfcfeSchristos #pragma clang diagnostic ignored "-Wdeprecated-declarations" 32b8ecfcfeSchristos #endif 33b8ecfcfeSchristos 348585484eSchristos #ifdef _WIN32 358585484eSchristos #include <winsock2.h> 368585484eSchristos #include <windows.h> 378585484eSchristos #endif 388585484eSchristos 39*eabc0478Schristos #include "util-internal.h" 40*eabc0478Schristos 418585484eSchristos #ifndef _WIN32 428585484eSchristos #include <sys/types.h> 438585484eSchristos #include <sys/socket.h> 448585484eSchristos #include <netinet/in.h> 458585484eSchristos #endif 468585484eSchristos 478585484eSchristos #include "event2/util.h" 488585484eSchristos #include "event2/event.h" 498585484eSchristos #include "event2/bufferevent_ssl.h" 50*eabc0478Schristos #include "event2/bufferevent_struct.h" 518585484eSchristos #include "event2/buffer.h" 528585484eSchristos #include "event2/listener.h" 538585484eSchristos 548585484eSchristos #include "regress.h" 558585484eSchristos #include "tinytest.h" 568585484eSchristos #include "tinytest_macros.h" 578585484eSchristos 588585484eSchristos #include <openssl/err.h> 598585484eSchristos #include <openssl/pem.h> 60*eabc0478Schristos #include "openssl-compat.h" 618585484eSchristos 628585484eSchristos #include <string.h> 63*eabc0478Schristos #ifdef _WIN32 64*eabc0478Schristos #include <io.h> 65*eabc0478Schristos #define read _read 66*eabc0478Schristos #define write _write 67*eabc0478Schristos #else 68*eabc0478Schristos #include <unistd.h> 69*eabc0478Schristos #endif 708585484eSchristos 71*eabc0478Schristos /* A pre-generated key, to save the cost of doing an RSA key generation step 72*eabc0478Schristos * during the unit tests. It is published in this file, so you would have to 73*eabc0478Schristos * be very foolish to consider using it in your own code. */ 748585484eSchristos static const char KEY[] = 758585484eSchristos "-----BEGIN RSA PRIVATE KEY-----\n" 76*eabc0478Schristos "MIIEogIBAAKCAQEAtK07Ili0dkJb79m/sFmHoVJTWyLoveXex2yX/BtUzzcvZEOu\n" 77*eabc0478Schristos "QLon/++5YOA48kzZm5K9mIwZkZhui1ZgJ5Bjq0LGAWTZGIn+NXjLFshPYvTKpOCW\n" 78*eabc0478Schristos "uzL0Ir0LXMsBLYJQ5A4FomLNxs4I3H/dhDSGy/rSiJB1B4w2xNiwPK08/VL3zZqk\n" 79*eabc0478Schristos "V+GsSvGIIkzhTMbqPJy9K8pqyjwOU2pgORS794yXciTGxWYjTDzJPgQ35YMDATaG\n" 80*eabc0478Schristos "jr4HHo1zxU/Lj0pndSUK5rKLYxYQ3Uc8B3AVYDl9CP/GbOoQ4LBzS68JjcAUyp6i\n" 81*eabc0478Schristos "6NfXlc2D9S9XgqVqwI+JqgJs0eW/+zPY2UEDWwIDAQABAoIBAD2HzV66FOM9YDAD\n" 82*eabc0478Schristos "2RtGskEHV2nvLpIVadRCsFPkPvK+2X3s6rgSbbLkwh4y3lHuSCGKTNVZyQ9jeSos\n" 83*eabc0478Schristos "xVxT+Q2HFQW+gYyw2gj91TQyDY8mzKhv8AVaqff2p5r3a7RC8CdqexK9UVUGL9Bg\n" 84*eabc0478Schristos "H2F5vfpTtkVZ5PEoGDLblNFlMiMW/t1SobUeBVx+Msco/xqk9lFv1A9nnepGy0Gi\n" 85*eabc0478Schristos "D+i6YNGTBsX22YhoCZl/ICxCL8lgqPei4FvBr9dBVh/jQgjuUBm2jz55p2r7+7Aw\n" 86*eabc0478Schristos "khmXHReejoVokQ2+htgSgZNKlKuDy710ZpBqnDi8ynQi82Y2qCpyg/p/xcER54B6\n" 87*eabc0478Schristos "hSftaiECgYEA2RkSoxU+nWk+BClQEUZRi88QK5W/M8oo1DvUs36hvPFkw3Jk/gz0\n" 88*eabc0478Schristos "fgd5bnA+MXj0Fc0QHvbddPjIkyoI/evq9GPV+JYIuH5zabrlI3Jvya8q9QpAcEDO\n" 89*eabc0478Schristos "KkL/O09qXVEW52S6l05nh4PLejyI7aTyTIN5nbVLac/+M8MY/qOjZksCgYEA1Q1o\n" 90*eabc0478Schristos "L8kjSavU2xhQmSgZb9W62Do60sa3e73ljrDPoiyvbExldpSdziFYxHBD/Rep0ePf\n" 91*eabc0478Schristos "eVSGS3VSwevt9/jSGo2Oa83TYYns9agBm03oR/Go/DukESdI792NsEM+PRFypVNy\n" 92*eabc0478Schristos "AohWRLj0UU6DV+zLKp0VBavtx0ATeLFX0eN17TECgYBI2O/3Bz7uhQ0JSm+SjFz6\n" 93*eabc0478Schristos "o+2SInp5P2G57aWu4VQWWY3tQ2p+EQzNaWam10UXRrXoxtmc+ktPX9e2AgnoYoyB\n" 94*eabc0478Schristos "myqGcpnUhqHlnZAb999o9r1cYidDQ4uqhLauSTSwwXAFDzjJYsa8o03Y440y6QFh\n" 95*eabc0478Schristos "CVD6yYXXqLJs3g96CqDexwKBgAHxq1+0QCQt8zVElYewO/svQhMzBNJjic0RQIT6\n" 96*eabc0478Schristos "zAo4yij80XgxhvcYiszQEW6/xobpw2JCCS+rFGQ8mOFIXfJsFD6blDAxp/3d2JXo\n" 97*eabc0478Schristos "MhRl+hrDGI4ng5zcsqxHEMxR2m/zwPiQ8eiSn3gWdVBaEsiCwmxY00ScKxFQ3PJH\n" 98*eabc0478Schristos "Vw4hAoGAdZLd8KfjjG6lg7hfpVqavstqVi9LOgkHeCfdjn7JP+76kYrgLk/XdkrP\n" 99*eabc0478Schristos "N/BHhtFVFjOi/mTQfQ5YfZImkm/1ePBy7437DT8BDkOxspa50kK4HPggHnU64h1w\n" 100*eabc0478Schristos "lhdEOj7mAgHwGwwVZWOgs9Lq6vfztnSuhqjha1daESY6kDscPIQ=\n" 1018585484eSchristos "-----END RSA PRIVATE KEY-----\n"; 1028585484eSchristos 103*eabc0478Schristos EVP_PKEY * 104*eabc0478Schristos ssl_getkey(void) 1058585484eSchristos { 1068585484eSchristos EVP_PKEY *key; 1078585484eSchristos BIO *bio; 1088585484eSchristos 1098585484eSchristos /* new read-only BIO backed by KEY. */ 1108585484eSchristos bio = BIO_new_mem_buf((char*)KEY, -1); 1118585484eSchristos tt_assert(bio); 1128585484eSchristos 1138585484eSchristos key = PEM_read_bio_PrivateKey(bio,NULL,NULL,NULL); 1148585484eSchristos BIO_free(bio); 1158585484eSchristos tt_assert(key); 1168585484eSchristos 1178585484eSchristos return key; 1188585484eSchristos end: 1198585484eSchristos return NULL; 1208585484eSchristos } 1218585484eSchristos 122*eabc0478Schristos X509 * 123*eabc0478Schristos ssl_getcert(EVP_PKEY *key) 1248585484eSchristos { 1258585484eSchristos /* Dummy code to make a quick-and-dirty valid certificate with 1268585484eSchristos OpenSSL. Don't copy this code into your own program! It does a 1278585484eSchristos number of things in a stupid and insecure way. */ 1288585484eSchristos X509 *x509 = NULL; 1298585484eSchristos X509_NAME *name = NULL; 1308585484eSchristos int nid; 1318585484eSchristos time_t now = time(NULL); 1328585484eSchristos 1338585484eSchristos tt_assert(key); 1348585484eSchristos 1358585484eSchristos x509 = X509_new(); 1368585484eSchristos tt_assert(x509); 1378585484eSchristos tt_assert(0 != X509_set_version(x509, 2)); 1388585484eSchristos tt_assert(0 != ASN1_INTEGER_set(X509_get_serialNumber(x509), 1398585484eSchristos (long)now)); 1408585484eSchristos 1418585484eSchristos name = X509_NAME_new(); 1428585484eSchristos tt_assert(name); 1438585484eSchristos nid = OBJ_txt2nid("commonName"); 1448585484eSchristos tt_assert(NID_undef != nid); 1458585484eSchristos tt_assert(0 != X509_NAME_add_entry_by_NID( 1468585484eSchristos name, nid, MBSTRING_ASC, (unsigned char*)"example.com", 1478585484eSchristos -1, -1, 0)); 1488585484eSchristos 1498585484eSchristos X509_set_subject_name(x509, name); 1508585484eSchristos X509_set_issuer_name(x509, name); 151*eabc0478Schristos X509_NAME_free(name); 1528585484eSchristos 153ccc794f0Schristos X509_time_adj(X509_getm_notBefore(x509), 0, &now); 154ccc794f0Schristos now += 3600; 155ccc794f0Schristos X509_time_adj(X509_getm_notAfter(x509), 0, &now); 1568585484eSchristos X509_set_pubkey(x509, key); 1578585484eSchristos tt_assert(0 != X509_sign(x509, key, EVP_sha1())); 1588585484eSchristos 1598585484eSchristos return x509; 1608585484eSchristos end: 1618585484eSchristos X509_free(x509); 162*eabc0478Schristos X509_NAME_free(name); 1638585484eSchristos return NULL; 1648585484eSchristos } 1658585484eSchristos 1668585484eSchristos static int disable_tls_11_and_12 = 0; 1678585484eSchristos static SSL_CTX *the_ssl_ctx = NULL; 1688585484eSchristos 169*eabc0478Schristos SSL_CTX * 1708585484eSchristos get_ssl_ctx(void) 1718585484eSchristos { 1728585484eSchristos if (the_ssl_ctx) 1738585484eSchristos return the_ssl_ctx; 1748585484eSchristos the_ssl_ctx = SSL_CTX_new(SSLv23_method()); 1758585484eSchristos if (!the_ssl_ctx) 1768585484eSchristos return NULL; 1778585484eSchristos if (disable_tls_11_and_12) { 1788585484eSchristos #ifdef SSL_OP_NO_TLSv1_2 1798585484eSchristos SSL_CTX_set_options(the_ssl_ctx, SSL_OP_NO_TLSv1_2); 1808585484eSchristos #endif 1818585484eSchristos #ifdef SSL_OP_NO_TLSv1_1 1828585484eSchristos SSL_CTX_set_options(the_ssl_ctx, SSL_OP_NO_TLSv1_1); 1838585484eSchristos #endif 1848585484eSchristos } 1858585484eSchristos return the_ssl_ctx; 1868585484eSchristos } 1878585484eSchristos 188*eabc0478Schristos static int test_is_done; 189*eabc0478Schristos static int n_connected; 190*eabc0478Schristos static int got_close; 191*eabc0478Schristos static int got_error; 192*eabc0478Schristos static int got_timeout; 193*eabc0478Schristos static int renegotiate_at = -1; 194*eabc0478Schristos static int stop_when_connected; 195*eabc0478Schristos static int pending_connect_events; 196*eabc0478Schristos static struct event_base *exit_base; 197*eabc0478Schristos static X509 *the_cert; 198*eabc0478Schristos EVP_PKEY *the_key; 199*eabc0478Schristos 200*eabc0478Schristos void 2018585484eSchristos init_ssl(void) 2028585484eSchristos { 203*eabc0478Schristos #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \ 204*eabc0478Schristos (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) 2058585484eSchristos SSL_library_init(); 2068585484eSchristos ERR_load_crypto_strings(); 2078585484eSchristos SSL_load_error_strings(); 2088585484eSchristos OpenSSL_add_all_algorithms(); 209*eabc0478Schristos if (SSLeay() != OPENSSL_VERSION_NUMBER) { 210*eabc0478Schristos TT_DECLARE("WARN", 211*eabc0478Schristos ("Version mismatch for openssl: compiled with %lx but running with %lx", 212*eabc0478Schristos (unsigned long)OPENSSL_VERSION_NUMBER, (unsigned long)SSLeay())); 2138585484eSchristos } 214*eabc0478Schristos #endif 2158585484eSchristos } 2168585484eSchristos 217*eabc0478Schristos static void * 218*eabc0478Schristos ssl_test_setup(const struct testcase_t *testcase) 219*eabc0478Schristos { 220*eabc0478Schristos init_ssl(); 221*eabc0478Schristos 222*eabc0478Schristos the_key = ssl_getkey(); 223*eabc0478Schristos EVUTIL_ASSERT(the_key); 224*eabc0478Schristos 225*eabc0478Schristos the_cert = ssl_getcert(the_key); 226*eabc0478Schristos EVUTIL_ASSERT(the_cert); 227*eabc0478Schristos 228*eabc0478Schristos disable_tls_11_and_12 = 0; 229*eabc0478Schristos 230*eabc0478Schristos return basic_test_setup(testcase); 231*eabc0478Schristos } 232*eabc0478Schristos static int 233*eabc0478Schristos ssl_test_cleanup(const struct testcase_t *testcase, void *ptr) 234*eabc0478Schristos { 235*eabc0478Schristos int ret = basic_test_cleanup(testcase, ptr); 236*eabc0478Schristos if (!ret) { 237*eabc0478Schristos return ret; 238*eabc0478Schristos } 239*eabc0478Schristos 240*eabc0478Schristos test_is_done = 0; 241*eabc0478Schristos n_connected = 0; 242*eabc0478Schristos got_close = 0; 243*eabc0478Schristos got_error = 0; 244*eabc0478Schristos got_timeout = 0; 245*eabc0478Schristos renegotiate_at = -1; 246*eabc0478Schristos stop_when_connected = 0; 247*eabc0478Schristos pending_connect_events = 0; 248*eabc0478Schristos exit_base = NULL; 249*eabc0478Schristos 250*eabc0478Schristos X509_free(the_cert); 251*eabc0478Schristos EVP_PKEY_free(the_key); 252*eabc0478Schristos 253*eabc0478Schristos SSL_CTX_free(the_ssl_ctx); 254*eabc0478Schristos the_ssl_ctx = NULL; 255*eabc0478Schristos 256*eabc0478Schristos return 1; 257*eabc0478Schristos } 258*eabc0478Schristos const struct testcase_setup_t ssl_setup = { 259*eabc0478Schristos ssl_test_setup, ssl_test_cleanup 260*eabc0478Schristos }; 261*eabc0478Schristos 262*eabc0478Schristos 2638585484eSchristos /* ==================== 2648585484eSchristos Here's a simple test: we read a number from the input, increment it, and 2658585484eSchristos reply, until we get to 1001. 2668585484eSchristos */ 2678585484eSchristos 268*eabc0478Schristos enum regress_openssl_type 269*eabc0478Schristos { 270*eabc0478Schristos REGRESS_OPENSSL_SOCKETPAIR = 1, 271*eabc0478Schristos REGRESS_OPENSSL_FILTER = 2, 272*eabc0478Schristos REGRESS_OPENSSL_RENEGOTIATE = 4, 273*eabc0478Schristos REGRESS_OPENSSL_OPEN = 8, 274*eabc0478Schristos REGRESS_OPENSSL_DIRTY_SHUTDOWN = 16, 275*eabc0478Schristos REGRESS_OPENSSL_FD = 32, 276*eabc0478Schristos 277*eabc0478Schristos REGRESS_OPENSSL_CLIENT = 64, 278*eabc0478Schristos REGRESS_OPENSSL_SERVER = 128, 279*eabc0478Schristos 280*eabc0478Schristos REGRESS_OPENSSL_FREED = 256, 281*eabc0478Schristos REGRESS_OPENSSL_TIMEOUT = 512, 282*eabc0478Schristos REGRESS_OPENSSL_SLEEP = 1024, 283*eabc0478Schristos 284*eabc0478Schristos REGRESS_OPENSSL_CLIENT_WRITE = 2048, 285*eabc0478Schristos 286*eabc0478Schristos REGRESS_DEFERRED_CALLBACKS = 4096, 287*eabc0478Schristos }; 288*eabc0478Schristos 289*eabc0478Schristos static void 290*eabc0478Schristos bufferevent_openssl_check_fd(struct bufferevent *bev, int filter) 291*eabc0478Schristos { 292*eabc0478Schristos tt_fd_op(bufferevent_getfd(bev), !=, EVUTIL_INVALID_SOCKET); 293*eabc0478Schristos tt_fd_op(bufferevent_setfd(bev, EVUTIL_INVALID_SOCKET), ==, 0); 294*eabc0478Schristos if (filter) { 295*eabc0478Schristos tt_fd_op(bufferevent_getfd(bev), !=, EVUTIL_INVALID_SOCKET); 296*eabc0478Schristos } else { 297*eabc0478Schristos tt_fd_op(bufferevent_getfd(bev), ==, EVUTIL_INVALID_SOCKET); 298*eabc0478Schristos } 299*eabc0478Schristos 300*eabc0478Schristos end: 301*eabc0478Schristos ; 302*eabc0478Schristos } 303*eabc0478Schristos static void 304*eabc0478Schristos bufferevent_openssl_check_freed(struct bufferevent *bev) 305*eabc0478Schristos { 306*eabc0478Schristos tt_int_op(event_pending(&bev->ev_read, EVLIST_ALL, NULL), ==, 0); 307*eabc0478Schristos tt_int_op(event_pending(&bev->ev_write, EVLIST_ALL, NULL), ==, 0); 308*eabc0478Schristos 309*eabc0478Schristos end: 310*eabc0478Schristos ; 311*eabc0478Schristos } 312*eabc0478Schristos 313*eabc0478Schristos static void 314*eabc0478Schristos free_on_cb(struct bufferevent *bev, void *ctx) 315*eabc0478Schristos { 316*eabc0478Schristos TT_BLATHER(("free_on_cb: %p", bev)); 317*eabc0478Schristos bufferevent_free(bev); 318*eabc0478Schristos } 3198585484eSchristos 3208585484eSchristos static void 3218585484eSchristos respond_to_number(struct bufferevent *bev, void *ctx) 3228585484eSchristos { 3238585484eSchristos struct evbuffer *b = bufferevent_get_input(bev); 3248585484eSchristos char *line; 3258585484eSchristos int n; 326*eabc0478Schristos 327*eabc0478Schristos enum regress_openssl_type type; 328*eabc0478Schristos type = (enum regress_openssl_type)ctx; 329*eabc0478Schristos 3308585484eSchristos line = evbuffer_readln(b, NULL, EVBUFFER_EOL_LF); 3318585484eSchristos if (! line) 3328585484eSchristos return; 3338585484eSchristos n = atoi(line); 3348585484eSchristos if (n <= 0) 3358585484eSchristos TT_FAIL(("Bad number: %s", line)); 3367476e6e4Schristos free(line); 3378585484eSchristos TT_BLATHER(("The number was %d", n)); 3388585484eSchristos if (n == 1001) { 3398585484eSchristos ++test_is_done; 3408585484eSchristos bufferevent_free(bev); /* Should trigger close on other side. */ 3418585484eSchristos return; 3428585484eSchristos } 343*eabc0478Schristos if ((type & REGRESS_OPENSSL_CLIENT) && n == renegotiate_at) { 3448585484eSchristos SSL_renegotiate(bufferevent_openssl_get_ssl(bev)); 3458585484eSchristos } 3468585484eSchristos ++n; 3478585484eSchristos evbuffer_add_printf(bufferevent_get_output(bev), 3488585484eSchristos "%d\n", n); 3498585484eSchristos TT_BLATHER(("Done reading; now writing.")); 3508585484eSchristos bufferevent_enable(bev, EV_WRITE); 3518585484eSchristos bufferevent_disable(bev, EV_READ); 3528585484eSchristos } 3538585484eSchristos 3548585484eSchristos static void 3558585484eSchristos done_writing_cb(struct bufferevent *bev, void *ctx) 3568585484eSchristos { 3578585484eSchristos struct evbuffer *b = bufferevent_get_output(bev); 3588585484eSchristos if (evbuffer_get_length(b)) 3598585484eSchristos return; 3608585484eSchristos TT_BLATHER(("Done writing.")); 3618585484eSchristos bufferevent_disable(bev, EV_WRITE); 3628585484eSchristos bufferevent_enable(bev, EV_READ); 3638585484eSchristos } 3648585484eSchristos 3658585484eSchristos static void 3668585484eSchristos eventcb(struct bufferevent *bev, short what, void *ctx) 3678585484eSchristos { 368*eabc0478Schristos X509 *peer_cert = NULL; 369*eabc0478Schristos enum regress_openssl_type type; 370*eabc0478Schristos 371*eabc0478Schristos type = (enum regress_openssl_type)ctx; 372*eabc0478Schristos 3738585484eSchristos TT_BLATHER(("Got event %d", (int)what)); 3748585484eSchristos if (what & BEV_EVENT_CONNECTED) { 3758585484eSchristos SSL *ssl; 3768585484eSchristos ++n_connected; 3778585484eSchristos ssl = bufferevent_openssl_get_ssl(bev); 3788585484eSchristos tt_assert(ssl); 3798585484eSchristos peer_cert = SSL_get_peer_certificate(ssl); 380*eabc0478Schristos if (type & REGRESS_OPENSSL_SERVER) { 3818585484eSchristos tt_assert(peer_cert == NULL); 3828585484eSchristos } else { 3838585484eSchristos tt_assert(peer_cert != NULL); 3848585484eSchristos } 3858585484eSchristos if (stop_when_connected) { 3868585484eSchristos if (--pending_connect_events == 0) 3878585484eSchristos event_base_loopexit(exit_base, NULL); 3888585484eSchristos } 389*eabc0478Schristos 390*eabc0478Schristos if ((type & REGRESS_OPENSSL_CLIENT_WRITE) && (type & REGRESS_OPENSSL_CLIENT)) 391*eabc0478Schristos evbuffer_add_printf(bufferevent_get_output(bev), "1\n"); 3928585484eSchristos } else if (what & BEV_EVENT_EOF) { 3938585484eSchristos TT_BLATHER(("Got a good EOF")); 3948585484eSchristos ++got_close; 395*eabc0478Schristos if (type & REGRESS_OPENSSL_FD) { 396*eabc0478Schristos bufferevent_openssl_check_fd(bev, type & REGRESS_OPENSSL_FILTER); 397*eabc0478Schristos } 398*eabc0478Schristos if (type & REGRESS_OPENSSL_FREED) { 399*eabc0478Schristos bufferevent_openssl_check_freed(bev); 400*eabc0478Schristos } 4018585484eSchristos bufferevent_free(bev); 4028585484eSchristos } else if (what & BEV_EVENT_ERROR) { 4038585484eSchristos TT_BLATHER(("Got an error.")); 4048585484eSchristos ++got_error; 405*eabc0478Schristos if (type & REGRESS_OPENSSL_FD) { 406*eabc0478Schristos bufferevent_openssl_check_fd(bev, type & REGRESS_OPENSSL_FILTER); 407*eabc0478Schristos } 408*eabc0478Schristos if (type & REGRESS_OPENSSL_FREED) { 409*eabc0478Schristos bufferevent_openssl_check_freed(bev); 410*eabc0478Schristos } 411*eabc0478Schristos bufferevent_free(bev); 412*eabc0478Schristos } else if (what & BEV_EVENT_TIMEOUT) { 413*eabc0478Schristos TT_BLATHER(("Got timeout.")); 414*eabc0478Schristos ++got_timeout; 415*eabc0478Schristos if (type & REGRESS_OPENSSL_FD) { 416*eabc0478Schristos bufferevent_openssl_check_fd(bev, type & REGRESS_OPENSSL_FILTER); 417*eabc0478Schristos } 418*eabc0478Schristos if (type & REGRESS_OPENSSL_FREED) { 419*eabc0478Schristos bufferevent_openssl_check_freed(bev); 420*eabc0478Schristos } 4218585484eSchristos bufferevent_free(bev); 4228585484eSchristos } 423*eabc0478Schristos 4248585484eSchristos end: 425*eabc0478Schristos if (peer_cert) 426*eabc0478Schristos X509_free(peer_cert); 4278585484eSchristos } 4288585484eSchristos 4298585484eSchristos static void 4308585484eSchristos open_ssl_bufevs(struct bufferevent **bev1_out, struct bufferevent **bev2_out, 4318585484eSchristos struct event_base *base, int is_open, int flags, SSL *ssl1, SSL *ssl2, 432*eabc0478Schristos evutil_socket_t *fd_pair, struct bufferevent **underlying_pair, 433*eabc0478Schristos enum regress_openssl_type type) 4348585484eSchristos { 4358585484eSchristos int state1 = is_open ? BUFFEREVENT_SSL_OPEN :BUFFEREVENT_SSL_CONNECTING; 4368585484eSchristos int state2 = is_open ? BUFFEREVENT_SSL_OPEN :BUFFEREVENT_SSL_ACCEPTING; 437*eabc0478Schristos int dirty_shutdown = type & REGRESS_OPENSSL_DIRTY_SHUTDOWN; 4388585484eSchristos if (fd_pair) { 4398585484eSchristos *bev1_out = bufferevent_openssl_socket_new( 4408585484eSchristos base, fd_pair[0], ssl1, state1, flags); 4418585484eSchristos *bev2_out = bufferevent_openssl_socket_new( 4428585484eSchristos base, fd_pair[1], ssl2, state2, flags); 4438585484eSchristos } else { 4448585484eSchristos *bev1_out = bufferevent_openssl_filter_new( 4458585484eSchristos base, underlying_pair[0], ssl1, state1, flags); 4468585484eSchristos *bev2_out = bufferevent_openssl_filter_new( 4478585484eSchristos base, underlying_pair[1], ssl2, state2, flags); 4488585484eSchristos 4498585484eSchristos } 4508585484eSchristos bufferevent_setcb(*bev1_out, respond_to_number, done_writing_cb, 451*eabc0478Schristos eventcb, (void*)(REGRESS_OPENSSL_CLIENT | (long)type)); 4528585484eSchristos bufferevent_setcb(*bev2_out, respond_to_number, done_writing_cb, 453*eabc0478Schristos eventcb, (void*)(REGRESS_OPENSSL_SERVER | (long)type)); 454*eabc0478Schristos 455*eabc0478Schristos bufferevent_openssl_set_allow_dirty_shutdown(*bev1_out, dirty_shutdown); 456*eabc0478Schristos bufferevent_openssl_set_allow_dirty_shutdown(*bev2_out, dirty_shutdown); 4578585484eSchristos } 4588585484eSchristos 4598585484eSchristos static void 4608585484eSchristos regress_bufferevent_openssl(void *arg) 4618585484eSchristos { 4628585484eSchristos struct basic_test_data *data = arg; 4638585484eSchristos 4648585484eSchristos struct bufferevent *bev1, *bev2; 4658585484eSchristos SSL *ssl1, *ssl2; 4668585484eSchristos int flags = BEV_OPT_DEFER_CALLBACKS; 4678585484eSchristos struct bufferevent *bev_ll[2] = { NULL, NULL }; 4688585484eSchristos evutil_socket_t *fd_pair = NULL; 4698585484eSchristos 470*eabc0478Schristos enum regress_openssl_type type; 471*eabc0478Schristos type = (enum regress_openssl_type)data->setup_data; 4728585484eSchristos 473*eabc0478Schristos if (type & REGRESS_OPENSSL_RENEGOTIATE) { 474*eabc0478Schristos if (OPENSSL_VERSION_NUMBER >= 0x10001000 && 475*eabc0478Schristos OPENSSL_VERSION_NUMBER < 0x1000104f) { 4768585484eSchristos /* 1.0.1 up to 1.0.1c has a bug where TLS1.1 and 1.2 4778585484eSchristos * can't renegotiate with themselves. Disable. */ 4788585484eSchristos disable_tls_11_and_12 = 1; 4798585484eSchristos } 4808585484eSchristos renegotiate_at = 600; 4818585484eSchristos } 4828585484eSchristos 4838585484eSchristos ssl1 = SSL_new(get_ssl_ctx()); 4848585484eSchristos ssl2 = SSL_new(get_ssl_ctx()); 4858585484eSchristos 486*eabc0478Schristos SSL_use_certificate(ssl2, the_cert); 487*eabc0478Schristos SSL_use_PrivateKey(ssl2, the_key); 4888585484eSchristos 489*eabc0478Schristos if (!(type & REGRESS_OPENSSL_OPEN)) 4908585484eSchristos flags |= BEV_OPT_CLOSE_ON_FREE; 4918585484eSchristos 492*eabc0478Schristos if (!(type & REGRESS_OPENSSL_FILTER)) { 493*eabc0478Schristos tt_assert(type & REGRESS_OPENSSL_SOCKETPAIR); 4948585484eSchristos fd_pair = data->pair; 4958585484eSchristos } else { 4968585484eSchristos bev_ll[0] = bufferevent_socket_new(data->base, data->pair[0], 4978585484eSchristos BEV_OPT_CLOSE_ON_FREE); 4988585484eSchristos bev_ll[1] = bufferevent_socket_new(data->base, data->pair[1], 4998585484eSchristos BEV_OPT_CLOSE_ON_FREE); 5008585484eSchristos } 5018585484eSchristos 5028585484eSchristos open_ssl_bufevs(&bev1, &bev2, data->base, 0, flags, ssl1, ssl2, 503*eabc0478Schristos fd_pair, bev_ll, type); 5048585484eSchristos 505*eabc0478Schristos if (!(type & REGRESS_OPENSSL_FILTER)) { 506*eabc0478Schristos tt_fd_op(bufferevent_getfd(bev1), ==, data->pair[0]); 5078585484eSchristos } else { 5088585484eSchristos tt_ptr_op(bufferevent_get_underlying(bev1), ==, bev_ll[0]); 5098585484eSchristos } 5108585484eSchristos 511*eabc0478Schristos if (type & REGRESS_OPENSSL_OPEN) { 5128585484eSchristos pending_connect_events = 2; 5138585484eSchristos stop_when_connected = 1; 5148585484eSchristos exit_base = data->base; 5158585484eSchristos event_base_dispatch(data->base); 5168585484eSchristos /* Okay, now the renegotiation is done. Make new 5178585484eSchristos * bufferevents to test opening in BUFFEREVENT_SSL_OPEN */ 5188585484eSchristos flags |= BEV_OPT_CLOSE_ON_FREE; 5198585484eSchristos bufferevent_free(bev1); 5208585484eSchristos bufferevent_free(bev2); 5218585484eSchristos bev1 = bev2 = NULL; 5228585484eSchristos open_ssl_bufevs(&bev1, &bev2, data->base, 1, flags, ssl1, ssl2, 523*eabc0478Schristos fd_pair, bev_ll, type); 5248585484eSchristos } 5258585484eSchristos 526*eabc0478Schristos if (!(type & REGRESS_OPENSSL_TIMEOUT)) { 5278585484eSchristos bufferevent_enable(bev1, EV_READ|EV_WRITE); 5288585484eSchristos bufferevent_enable(bev2, EV_READ|EV_WRITE); 5298585484eSchristos 530*eabc0478Schristos if (!(type & REGRESS_OPENSSL_CLIENT_WRITE)) 5318585484eSchristos evbuffer_add_printf(bufferevent_get_output(bev1), "1\n"); 5328585484eSchristos 5338585484eSchristos event_base_dispatch(data->base); 5348585484eSchristos 5358585484eSchristos tt_assert(test_is_done == 1); 5368585484eSchristos tt_assert(n_connected == 2); 5378585484eSchristos 538*eabc0478Schristos /* We don't handle shutdown properly yet */ 539*eabc0478Schristos if (type & REGRESS_OPENSSL_DIRTY_SHUTDOWN) { 5408585484eSchristos tt_int_op(got_close, ==, 1); 5418585484eSchristos tt_int_op(got_error, ==, 0); 542*eabc0478Schristos } else { 543*eabc0478Schristos tt_int_op(got_error, ==, 1); 544*eabc0478Schristos } 545*eabc0478Schristos tt_int_op(got_timeout, ==, 0); 546*eabc0478Schristos } else { 547*eabc0478Schristos struct timeval t = { 2, 0 }; 548*eabc0478Schristos 549*eabc0478Schristos bufferevent_enable(bev1, EV_READ|EV_WRITE); 550*eabc0478Schristos bufferevent_disable(bev2, EV_READ|EV_WRITE); 551*eabc0478Schristos 552*eabc0478Schristos bufferevent_set_timeouts(bev1, &t, &t); 553*eabc0478Schristos 554*eabc0478Schristos if (!(type & REGRESS_OPENSSL_CLIENT_WRITE)) 555*eabc0478Schristos evbuffer_add_printf(bufferevent_get_output(bev1), "1\n"); 556*eabc0478Schristos 557*eabc0478Schristos event_base_dispatch(data->base); 558*eabc0478Schristos 559*eabc0478Schristos tt_assert(test_is_done == 0); 560*eabc0478Schristos tt_assert(n_connected == 0); 561*eabc0478Schristos 562*eabc0478Schristos tt_int_op(got_close, ==, 0); 563*eabc0478Schristos tt_int_op(got_error, ==, 0); 564*eabc0478Schristos tt_int_op(got_timeout, ==, 1); 565*eabc0478Schristos 566*eabc0478Schristos bufferevent_free(bev2); 567*eabc0478Schristos } 568*eabc0478Schristos 5698585484eSchristos end: 5708585484eSchristos return; 5718585484eSchristos } 5728585484eSchristos 5738585484eSchristos static void 574*eabc0478Schristos acceptcb_deferred(evutil_socket_t fd, short events, void *arg) 575*eabc0478Schristos { 576*eabc0478Schristos struct bufferevent *bev = arg; 577*eabc0478Schristos bufferevent_enable(bev, EV_READ|EV_WRITE); 578*eabc0478Schristos } 579*eabc0478Schristos static void 5808585484eSchristos acceptcb(struct evconnlistener *listener, evutil_socket_t fd, 5818585484eSchristos struct sockaddr *addr, int socklen, void *arg) 5828585484eSchristos { 5838585484eSchristos struct basic_test_data *data = arg; 5848585484eSchristos struct bufferevent *bev; 585*eabc0478Schristos enum regress_openssl_type type; 5868585484eSchristos SSL *ssl = SSL_new(get_ssl_ctx()); 5878585484eSchristos 588*eabc0478Schristos type = (enum regress_openssl_type)data->setup_data; 589*eabc0478Schristos 590*eabc0478Schristos SSL_use_certificate(ssl, the_cert); 591*eabc0478Schristos SSL_use_PrivateKey(ssl, the_key); 5928585484eSchristos 5938585484eSchristos bev = bufferevent_openssl_socket_new( 594*eabc0478Schristos data->base, fd, ssl, BUFFEREVENT_SSL_ACCEPTING, 5958585484eSchristos BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS); 596*eabc0478Schristos tt_assert(bev); 5978585484eSchristos 5988585484eSchristos bufferevent_setcb(bev, respond_to_number, NULL, eventcb, 599*eabc0478Schristos (void*)(REGRESS_OPENSSL_SERVER)); 6008585484eSchristos 601*eabc0478Schristos if (type & REGRESS_OPENSSL_SLEEP) { 602*eabc0478Schristos struct timeval when = { 1, 0 }; 603*eabc0478Schristos event_base_once(data->base, -1, EV_TIMEOUT, 604*eabc0478Schristos acceptcb_deferred, bev, &when); 605*eabc0478Schristos bufferevent_disable(bev, EV_READ|EV_WRITE); 606*eabc0478Schristos } else { 6078585484eSchristos bufferevent_enable(bev, EV_READ|EV_WRITE); 608*eabc0478Schristos } 6098585484eSchristos 6108585484eSchristos /* Only accept once, then disable ourself. */ 6118585484eSchristos evconnlistener_disable(listener); 612*eabc0478Schristos 613*eabc0478Schristos end: 614*eabc0478Schristos ; 615*eabc0478Schristos } 616*eabc0478Schristos 617*eabc0478Schristos struct rwcount 618*eabc0478Schristos { 619*eabc0478Schristos evutil_socket_t fd; 620*eabc0478Schristos size_t read; 621*eabc0478Schristos size_t write; 622*eabc0478Schristos }; 623*eabc0478Schristos static int 624*eabc0478Schristos bio_rwcount_new(BIO *b) 625*eabc0478Schristos { 626*eabc0478Schristos BIO_set_init(b, 0); 627*eabc0478Schristos BIO_set_data(b, NULL); 628*eabc0478Schristos return 1; 629*eabc0478Schristos } 630*eabc0478Schristos static int 631*eabc0478Schristos bio_rwcount_free(BIO *b) 632*eabc0478Schristos { 633*eabc0478Schristos TT_BLATHER(("bio_rwcount_free: %p", b)); 634*eabc0478Schristos if (!b) 635*eabc0478Schristos return 0; 636*eabc0478Schristos if (BIO_get_shutdown(b)) { 637*eabc0478Schristos BIO_set_init(b, 0); 638*eabc0478Schristos BIO_set_data(b, NULL); 639*eabc0478Schristos } 640*eabc0478Schristos return 1; 641*eabc0478Schristos } 642*eabc0478Schristos static int 643*eabc0478Schristos bio_rwcount_read(BIO *b, char *out, int outlen) 644*eabc0478Schristos { 645*eabc0478Schristos struct rwcount *rw = BIO_get_data(b); 646*eabc0478Schristos ev_ssize_t ret = recv(rw->fd, out, outlen, 0); 647*eabc0478Schristos ++rw->read; 648*eabc0478Schristos if (ret == -1 && EVUTIL_ERR_RW_RETRIABLE(EVUTIL_SOCKET_ERROR())) { 649*eabc0478Schristos BIO_set_retry_read(b); 650*eabc0478Schristos } 651*eabc0478Schristos return ret; 652*eabc0478Schristos } 653*eabc0478Schristos static int 654*eabc0478Schristos bio_rwcount_write(BIO *b, const char *in, int inlen) 655*eabc0478Schristos { 656*eabc0478Schristos struct rwcount *rw = BIO_get_data(b); 657*eabc0478Schristos ev_ssize_t ret = send(rw->fd, in, inlen, 0); 658*eabc0478Schristos ++rw->write; 659*eabc0478Schristos if (ret == -1 && EVUTIL_ERR_RW_RETRIABLE(EVUTIL_SOCKET_ERROR())) { 660*eabc0478Schristos BIO_set_retry_write(b); 661*eabc0478Schristos } 662*eabc0478Schristos return ret; 663*eabc0478Schristos } 664*eabc0478Schristos static long 665*eabc0478Schristos bio_rwcount_ctrl(BIO *b, int cmd, long num, void *ptr) 666*eabc0478Schristos { 667*eabc0478Schristos struct rwcount *rw = BIO_get_data(b); 668*eabc0478Schristos long ret = 0; 669*eabc0478Schristos switch (cmd) { 670*eabc0478Schristos case BIO_C_GET_FD: 671*eabc0478Schristos ret = rw->fd; 672*eabc0478Schristos break; 673*eabc0478Schristos case BIO_CTRL_GET_CLOSE: 674*eabc0478Schristos ret = BIO_get_shutdown(b); 675*eabc0478Schristos break; 676*eabc0478Schristos case BIO_CTRL_SET_CLOSE: 677*eabc0478Schristos BIO_set_shutdown(b, (int)num); 678*eabc0478Schristos break; 679*eabc0478Schristos case BIO_CTRL_PENDING: 680*eabc0478Schristos ret = 0; 681*eabc0478Schristos break; 682*eabc0478Schristos case BIO_CTRL_WPENDING: 683*eabc0478Schristos ret = 0; 684*eabc0478Schristos break; 685*eabc0478Schristos case BIO_CTRL_DUP: 686*eabc0478Schristos case BIO_CTRL_FLUSH: 687*eabc0478Schristos ret = 1; 688*eabc0478Schristos break; 689*eabc0478Schristos } 690*eabc0478Schristos return ret; 691*eabc0478Schristos } 692*eabc0478Schristos static int 693*eabc0478Schristos bio_rwcount_puts(BIO *b, const char *s) 694*eabc0478Schristos { 695*eabc0478Schristos return bio_rwcount_write(b, s, strlen(s)); 696*eabc0478Schristos } 697*eabc0478Schristos #define BIO_TYPE_LIBEVENT_RWCOUNT 0xff1 698*eabc0478Schristos static BIO_METHOD *methods_rwcount; 699*eabc0478Schristos 700*eabc0478Schristos static BIO_METHOD * 701*eabc0478Schristos BIO_s_rwcount(void) 702*eabc0478Schristos { 703*eabc0478Schristos if (methods_rwcount == NULL) { 704*eabc0478Schristos methods_rwcount = BIO_meth_new(BIO_TYPE_LIBEVENT_RWCOUNT, "rwcount"); 705*eabc0478Schristos if (methods_rwcount == NULL) 706*eabc0478Schristos return NULL; 707*eabc0478Schristos BIO_meth_set_write(methods_rwcount, bio_rwcount_write); 708*eabc0478Schristos BIO_meth_set_read(methods_rwcount, bio_rwcount_read); 709*eabc0478Schristos BIO_meth_set_puts(methods_rwcount, bio_rwcount_puts); 710*eabc0478Schristos BIO_meth_set_ctrl(methods_rwcount, bio_rwcount_ctrl); 711*eabc0478Schristos BIO_meth_set_create(methods_rwcount, bio_rwcount_new); 712*eabc0478Schristos BIO_meth_set_destroy(methods_rwcount, bio_rwcount_free); 713*eabc0478Schristos } 714*eabc0478Schristos return methods_rwcount; 715*eabc0478Schristos } 716*eabc0478Schristos static BIO * 717*eabc0478Schristos BIO_new_rwcount(int close_flag) 718*eabc0478Schristos { 719*eabc0478Schristos BIO *result; 720*eabc0478Schristos if (!(result = BIO_new(BIO_s_rwcount()))) 721*eabc0478Schristos return NULL; 722*eabc0478Schristos BIO_set_init(result, 1); 723*eabc0478Schristos BIO_set_data(result, NULL); 724*eabc0478Schristos BIO_set_shutdown(result, !!close_flag); 725*eabc0478Schristos return result; 7268585484eSchristos } 7278585484eSchristos 7288585484eSchristos static void 7298585484eSchristos regress_bufferevent_openssl_connect(void *arg) 7308585484eSchristos { 7318585484eSchristos struct basic_test_data *data = arg; 7328585484eSchristos 7338585484eSchristos struct event_base *base = data->base; 7348585484eSchristos 7358585484eSchristos struct evconnlistener *listener; 7368585484eSchristos struct bufferevent *bev; 7378585484eSchristos struct sockaddr_in sin; 7388585484eSchristos struct sockaddr_storage ss; 7398585484eSchristos ev_socklen_t slen; 740*eabc0478Schristos SSL *ssl; 741*eabc0478Schristos struct rwcount rw = { -1, 0, 0 }; 742*eabc0478Schristos enum regress_openssl_type type; 7438585484eSchristos 744*eabc0478Schristos type = (enum regress_openssl_type)data->setup_data; 7458585484eSchristos 7468585484eSchristos memset(&sin, 0, sizeof(sin)); 7478585484eSchristos sin.sin_family = AF_INET; 7488585484eSchristos sin.sin_addr.s_addr = htonl(0x7f000001); 7498585484eSchristos 7508585484eSchristos memset(&ss, 0, sizeof(ss)); 7518585484eSchristos slen = sizeof(ss); 7528585484eSchristos 7538585484eSchristos listener = evconnlistener_new_bind(base, acceptcb, data, 7548585484eSchristos LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, 7558585484eSchristos -1, (struct sockaddr *)&sin, sizeof(sin)); 7568585484eSchristos 7578585484eSchristos tt_assert(listener); 7588585484eSchristos tt_assert(evconnlistener_get_fd(listener) >= 0); 7598585484eSchristos 760*eabc0478Schristos ssl = SSL_new(get_ssl_ctx()); 761*eabc0478Schristos tt_assert(ssl); 762*eabc0478Schristos 7638585484eSchristos bev = bufferevent_openssl_socket_new( 764*eabc0478Schristos data->base, -1, ssl, 7658585484eSchristos BUFFEREVENT_SSL_CONNECTING, 7668585484eSchristos BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS); 7678585484eSchristos tt_assert(bev); 7688585484eSchristos 769*eabc0478Schristos bufferevent_setcb(bev, respond_to_number, free_on_cb, eventcb, 770*eabc0478Schristos (void*)(REGRESS_OPENSSL_CLIENT)); 7718585484eSchristos 7728585484eSchristos tt_assert(getsockname(evconnlistener_get_fd(listener), 7738585484eSchristos (struct sockaddr*)&ss, &slen) == 0); 7748585484eSchristos tt_assert(slen == sizeof(struct sockaddr_in)); 7758585484eSchristos tt_int_op(((struct sockaddr*)&ss)->sa_family, ==, AF_INET); 7768585484eSchristos 7778585484eSchristos tt_assert(0 == 7788585484eSchristos bufferevent_socket_connect(bev, (struct sockaddr*)&ss, slen)); 779*eabc0478Schristos /* Possible only when we have fd, since be_openssl can and will overwrite 780*eabc0478Schristos * bio otherwise before */ 781*eabc0478Schristos if (type & REGRESS_OPENSSL_SLEEP) { 782*eabc0478Schristos BIO *bio; 783*eabc0478Schristos 784*eabc0478Schristos rw.fd = bufferevent_getfd(bev); 785*eabc0478Schristos bio = BIO_new_rwcount(0); 786*eabc0478Schristos tt_assert(bio); 787*eabc0478Schristos BIO_set_data(bio, &rw); 788*eabc0478Schristos SSL_set_bio(ssl, bio, bio); 789*eabc0478Schristos } 7908585484eSchristos evbuffer_add_printf(bufferevent_get_output(bev), "1\n"); 7918585484eSchristos bufferevent_enable(bev, EV_READ|EV_WRITE); 7928585484eSchristos 7938585484eSchristos event_base_dispatch(base); 794*eabc0478Schristos 795*eabc0478Schristos tt_int_op(rw.read, <=, 100); 796*eabc0478Schristos tt_int_op(rw.write, <=, 100); 7978585484eSchristos end: 798*eabc0478Schristos evconnlistener_free(listener); 799*eabc0478Schristos } 800*eabc0478Schristos 801*eabc0478Schristos struct wm_context 802*eabc0478Schristos { 803*eabc0478Schristos int server; 804*eabc0478Schristos int flags; 805*eabc0478Schristos struct evbuffer *data; 806*eabc0478Schristos size_t to_read; 807*eabc0478Schristos size_t wm_high; 808*eabc0478Schristos size_t limit; 809*eabc0478Schristos size_t get; 810*eabc0478Schristos struct bufferevent *bev; 811*eabc0478Schristos struct wm_context *neighbour; 812*eabc0478Schristos }; 813*eabc0478Schristos static void 814*eabc0478Schristos wm_transfer(struct bufferevent *bev, void *arg) 815*eabc0478Schristos { 816*eabc0478Schristos struct wm_context *ctx = arg; 817*eabc0478Schristos struct evbuffer *in = bufferevent_get_input(bev); 818*eabc0478Schristos struct evbuffer *out = bufferevent_get_output(bev); 819*eabc0478Schristos size_t len = evbuffer_get_length(in); 820*eabc0478Schristos size_t drain = len < ctx->to_read ? len : ctx->to_read; 821*eabc0478Schristos 822*eabc0478Schristos if (ctx->get >= ctx->limit) { 823*eabc0478Schristos TT_BLATHER(("wm_transfer-%s(%p): break", 824*eabc0478Schristos ctx->server ? "server" : "client", bev)); 825*eabc0478Schristos bufferevent_setcb(bev, NULL, NULL, NULL, NULL); 826*eabc0478Schristos bufferevent_disable(bev, EV_READ); 827*eabc0478Schristos if (ctx->neighbour->get >= ctx->neighbour->limit) { 828*eabc0478Schristos event_base_loopbreak(bufferevent_get_base(bev)); 829*eabc0478Schristos } 830*eabc0478Schristos } else { 831*eabc0478Schristos ctx->get += drain; 832*eabc0478Schristos evbuffer_drain(in, drain); 833*eabc0478Schristos } 834*eabc0478Schristos 835*eabc0478Schristos TT_BLATHER(("wm_transfer-%s(%p): " 836*eabc0478Schristos "in: " EV_SIZE_FMT ", " 837*eabc0478Schristos "out: " EV_SIZE_FMT ", " 838*eabc0478Schristos "got: " EV_SIZE_FMT "", 839*eabc0478Schristos ctx->server ? "server" : "client", bev, 840*eabc0478Schristos evbuffer_get_length(in), 841*eabc0478Schristos evbuffer_get_length(out), 842*eabc0478Schristos ctx->get)); 843*eabc0478Schristos 844*eabc0478Schristos evbuffer_add_buffer_reference(out, ctx->data); 845*eabc0478Schristos } 846*eabc0478Schristos static void 847*eabc0478Schristos wm_eventcb(struct bufferevent *bev, short what, void *arg) 848*eabc0478Schristos { 849*eabc0478Schristos struct wm_context *ctx = arg; 850*eabc0478Schristos TT_BLATHER(("wm_eventcb-%s(%p): %i", 851*eabc0478Schristos ctx->server ? "server" : "client", bev, what)); 852*eabc0478Schristos if (what & BEV_EVENT_CONNECTED) { 853*eabc0478Schristos } else { 854*eabc0478Schristos ctx->get = 0; 855*eabc0478Schristos } 856*eabc0478Schristos } 857*eabc0478Schristos static void 858*eabc0478Schristos wm_acceptcb(struct evconnlistener *listener, evutil_socket_t fd, 859*eabc0478Schristos struct sockaddr *addr, int socklen, void *arg) 860*eabc0478Schristos { 861*eabc0478Schristos struct wm_context *ctx = arg; 862*eabc0478Schristos struct bufferevent *bev; 863*eabc0478Schristos struct event_base *base = evconnlistener_get_base(listener); 864*eabc0478Schristos SSL *ssl = SSL_new(get_ssl_ctx()); 865*eabc0478Schristos 866*eabc0478Schristos SSL_use_certificate(ssl, the_cert); 867*eabc0478Schristos SSL_use_PrivateKey(ssl, the_key); 868*eabc0478Schristos 869*eabc0478Schristos bev = bufferevent_openssl_socket_new( 870*eabc0478Schristos base, fd, ssl, BUFFEREVENT_SSL_ACCEPTING, ctx->flags); 871*eabc0478Schristos 872*eabc0478Schristos TT_BLATHER(("wm_transfer-%s(%p): accept", 873*eabc0478Schristos ctx->server ? "server" : "client", bev)); 874*eabc0478Schristos 875*eabc0478Schristos bufferevent_setwatermark(bev, EV_READ, 0, ctx->wm_high); 876*eabc0478Schristos bufferevent_setcb(bev, wm_transfer, NULL, wm_eventcb, ctx); 877*eabc0478Schristos bufferevent_enable(bev, EV_READ|EV_WRITE); 878*eabc0478Schristos ctx->bev = bev; 879*eabc0478Schristos 880*eabc0478Schristos /* Only accept once, then disable ourself. */ 881*eabc0478Schristos evconnlistener_disable(listener); 882*eabc0478Schristos } 883*eabc0478Schristos static void 884*eabc0478Schristos regress_bufferevent_openssl_wm(void *arg) 885*eabc0478Schristos { 886*eabc0478Schristos struct basic_test_data *data = arg; 887*eabc0478Schristos struct event_base *base = data->base; 888*eabc0478Schristos 889*eabc0478Schristos struct evconnlistener *listener; 890*eabc0478Schristos struct bufferevent *bev; 891*eabc0478Schristos struct sockaddr_in sin; 892*eabc0478Schristos struct sockaddr_storage ss; 893*eabc0478Schristos enum regress_openssl_type type = 894*eabc0478Schristos (enum regress_openssl_type)data->setup_data; 895*eabc0478Schristos int bev_flags = BEV_OPT_CLOSE_ON_FREE; 896*eabc0478Schristos ev_socklen_t slen; 897*eabc0478Schristos SSL *ssl; 898*eabc0478Schristos struct wm_context client, server; 899*eabc0478Schristos char *payload; 900*eabc0478Schristos size_t payload_len = 1<<10; 901*eabc0478Schristos size_t wm_high = 5<<10; 902*eabc0478Schristos 903*eabc0478Schristos memset(&sin, 0, sizeof(sin)); 904*eabc0478Schristos sin.sin_family = AF_INET; 905*eabc0478Schristos sin.sin_addr.s_addr = htonl(0x7f000001); 906*eabc0478Schristos 907*eabc0478Schristos memset(&ss, 0, sizeof(ss)); 908*eabc0478Schristos slen = sizeof(ss); 909*eabc0478Schristos 910*eabc0478Schristos if (type & REGRESS_DEFERRED_CALLBACKS) 911*eabc0478Schristos bev_flags |= BEV_OPT_DEFER_CALLBACKS; 912*eabc0478Schristos 913*eabc0478Schristos memset(&client, 0, sizeof(client)); 914*eabc0478Schristos memset(&server, 0, sizeof(server)); 915*eabc0478Schristos client.server = 0; 916*eabc0478Schristos server.server = 1; 917*eabc0478Schristos client.flags = server.flags = bev_flags; 918*eabc0478Schristos client.data = evbuffer_new(); 919*eabc0478Schristos server.data = evbuffer_new(); 920*eabc0478Schristos payload = calloc(1, payload_len); 921*eabc0478Schristos memset(payload, 'A', payload_len); 922*eabc0478Schristos evbuffer_add(server.data, payload, payload_len); 923*eabc0478Schristos evbuffer_add(client.data, payload, payload_len); 924*eabc0478Schristos client.wm_high = server.wm_high = wm_high; 925*eabc0478Schristos client.limit = server.limit = wm_high<<3; 926*eabc0478Schristos client.to_read = server.to_read = payload_len>>1; 927*eabc0478Schristos 928*eabc0478Schristos TT_BLATHER(("openssl_wm: " 929*eabc0478Schristos "payload_len = " EV_SIZE_FMT ", " 930*eabc0478Schristos "wm_high = " EV_SIZE_FMT ", " 931*eabc0478Schristos "limit = " EV_SIZE_FMT ", " 932*eabc0478Schristos "to_read: " EV_SIZE_FMT "", 933*eabc0478Schristos payload_len, 934*eabc0478Schristos wm_high, 935*eabc0478Schristos server.limit, 936*eabc0478Schristos server.to_read)); 937*eabc0478Schristos 938*eabc0478Schristos listener = evconnlistener_new_bind(base, wm_acceptcb, &server, 939*eabc0478Schristos LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, 940*eabc0478Schristos -1, (struct sockaddr *)&sin, sizeof(sin)); 941*eabc0478Schristos 942*eabc0478Schristos tt_assert(listener); 943*eabc0478Schristos tt_assert(evconnlistener_get_fd(listener) >= 0); 944*eabc0478Schristos 945*eabc0478Schristos ssl = SSL_new(get_ssl_ctx()); 946*eabc0478Schristos tt_assert(ssl); 947*eabc0478Schristos 948*eabc0478Schristos if (type & REGRESS_OPENSSL_FILTER) { 949*eabc0478Schristos bev = bufferevent_socket_new(data->base, -1, client.flags); 950*eabc0478Schristos tt_assert(bev); 951*eabc0478Schristos bev = bufferevent_openssl_filter_new( 952*eabc0478Schristos base, bev, ssl, BUFFEREVENT_SSL_CONNECTING, client.flags); 953*eabc0478Schristos } else { 954*eabc0478Schristos bev = bufferevent_openssl_socket_new( 955*eabc0478Schristos data->base, -1, ssl, 956*eabc0478Schristos BUFFEREVENT_SSL_CONNECTING, 957*eabc0478Schristos client.flags); 958*eabc0478Schristos } 959*eabc0478Schristos tt_assert(bev); 960*eabc0478Schristos client.bev = bev; 961*eabc0478Schristos 962*eabc0478Schristos server.neighbour = &client; 963*eabc0478Schristos client.neighbour = &server; 964*eabc0478Schristos 965*eabc0478Schristos bufferevent_setwatermark(bev, EV_READ, 0, client.wm_high); 966*eabc0478Schristos bufferevent_setcb(bev, wm_transfer, NULL, wm_eventcb, &client); 967*eabc0478Schristos 968*eabc0478Schristos tt_assert(getsockname(evconnlistener_get_fd(listener), 969*eabc0478Schristos (struct sockaddr*)&ss, &slen) == 0); 970*eabc0478Schristos 971*eabc0478Schristos tt_assert(!bufferevent_socket_connect(bev, (struct sockaddr*)&ss, slen)); 972*eabc0478Schristos tt_assert(!evbuffer_add_buffer_reference(bufferevent_get_output(bev), client.data)); 973*eabc0478Schristos tt_assert(!bufferevent_enable(bev, EV_READ|EV_WRITE)); 974*eabc0478Schristos 975*eabc0478Schristos event_base_dispatch(base); 976*eabc0478Schristos 977*eabc0478Schristos tt_int_op(client.get, ==, client.limit); 978*eabc0478Schristos tt_int_op(server.get, ==, server.limit); 979*eabc0478Schristos 980*eabc0478Schristos end: 981*eabc0478Schristos free(payload); 982*eabc0478Schristos evbuffer_free(client.data); 983*eabc0478Schristos evbuffer_free(server.data); 984*eabc0478Schristos evconnlistener_free(listener); 985*eabc0478Schristos bufferevent_free(client.bev); 986*eabc0478Schristos bufferevent_free(server.bev); 987*eabc0478Schristos 988*eabc0478Schristos /* XXX: by some reason otherise there is a leak */ 989*eabc0478Schristos if (!(type & REGRESS_OPENSSL_FILTER)) 990*eabc0478Schristos event_base_loop(base, EVLOOP_ONCE); 9918585484eSchristos } 9928585484eSchristos 9938585484eSchristos struct testcase_t ssl_testcases[] = { 994*eabc0478Schristos #define T(a) ((void *)(a)) 995*eabc0478Schristos { "bufferevent_socketpair", regress_bufferevent_openssl, 996*eabc0478Schristos TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_SOCKETPAIR) }, 997*eabc0478Schristos { "bufferevent_socketpair_write_after_connect", regress_bufferevent_openssl, 998*eabc0478Schristos TT_ISOLATED, &ssl_setup, 999*eabc0478Schristos T(REGRESS_OPENSSL_SOCKETPAIR|REGRESS_OPENSSL_CLIENT_WRITE) }, 10008585484eSchristos { "bufferevent_filter", regress_bufferevent_openssl, 1001*eabc0478Schristos TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_FILTER) }, 1002*eabc0478Schristos { "bufferevent_filter_write_after_connect", regress_bufferevent_openssl, 1003*eabc0478Schristos TT_ISOLATED, &ssl_setup, 1004*eabc0478Schristos T(REGRESS_OPENSSL_FILTER|REGRESS_OPENSSL_CLIENT_WRITE) }, 10058585484eSchristos { "bufferevent_renegotiate_socketpair", regress_bufferevent_openssl, 1006*eabc0478Schristos TT_ISOLATED, &ssl_setup, 1007*eabc0478Schristos T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_RENEGOTIATE) }, 10088585484eSchristos { "bufferevent_renegotiate_filter", regress_bufferevent_openssl, 1009*eabc0478Schristos TT_ISOLATED, &ssl_setup, 1010*eabc0478Schristos T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_RENEGOTIATE) }, 10118585484eSchristos { "bufferevent_socketpair_startopen", regress_bufferevent_openssl, 1012*eabc0478Schristos TT_ISOLATED, &ssl_setup, 1013*eabc0478Schristos T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_OPEN) }, 10148585484eSchristos { "bufferevent_filter_startopen", regress_bufferevent_openssl, 1015*eabc0478Schristos TT_ISOLATED, &ssl_setup, 1016*eabc0478Schristos T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_OPEN) }, 1017*eabc0478Schristos 1018*eabc0478Schristos { "bufferevent_socketpair_dirty_shutdown", regress_bufferevent_openssl, 1019*eabc0478Schristos TT_ISOLATED, &ssl_setup, 1020*eabc0478Schristos T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_DIRTY_SHUTDOWN) }, 1021*eabc0478Schristos { "bufferevent_filter_dirty_shutdown", regress_bufferevent_openssl, 1022*eabc0478Schristos TT_ISOLATED, &ssl_setup, 1023*eabc0478Schristos T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_DIRTY_SHUTDOWN) }, 1024*eabc0478Schristos { "bufferevent_renegotiate_socketpair_dirty_shutdown", 1025*eabc0478Schristos regress_bufferevent_openssl, 1026*eabc0478Schristos TT_ISOLATED, 1027*eabc0478Schristos &ssl_setup, 1028*eabc0478Schristos T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_RENEGOTIATE | REGRESS_OPENSSL_DIRTY_SHUTDOWN) }, 1029*eabc0478Schristos { "bufferevent_renegotiate_filter_dirty_shutdown", 1030*eabc0478Schristos regress_bufferevent_openssl, 1031*eabc0478Schristos TT_ISOLATED, 1032*eabc0478Schristos &ssl_setup, 1033*eabc0478Schristos T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_RENEGOTIATE | REGRESS_OPENSSL_DIRTY_SHUTDOWN) }, 1034*eabc0478Schristos { "bufferevent_socketpair_startopen_dirty_shutdown", 1035*eabc0478Schristos regress_bufferevent_openssl, 1036*eabc0478Schristos TT_ISOLATED, &ssl_setup, 1037*eabc0478Schristos T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_OPEN | REGRESS_OPENSSL_DIRTY_SHUTDOWN) }, 1038*eabc0478Schristos { "bufferevent_filter_startopen_dirty_shutdown", 1039*eabc0478Schristos regress_bufferevent_openssl, 1040*eabc0478Schristos TT_ISOLATED, &ssl_setup, 1041*eabc0478Schristos T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_OPEN | REGRESS_OPENSSL_DIRTY_SHUTDOWN) }, 1042*eabc0478Schristos 1043*eabc0478Schristos { "bufferevent_socketpair_fd", regress_bufferevent_openssl, 1044*eabc0478Schristos TT_ISOLATED, &ssl_setup, 1045*eabc0478Schristos T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_FD) }, 1046*eabc0478Schristos { "bufferevent_socketpair_freed", regress_bufferevent_openssl, 1047*eabc0478Schristos TT_ISOLATED, &ssl_setup, 1048*eabc0478Schristos T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_FREED) }, 1049*eabc0478Schristos { "bufferevent_socketpair_freed_fd", regress_bufferevent_openssl, 1050*eabc0478Schristos TT_ISOLATED, &ssl_setup, 1051*eabc0478Schristos T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_FREED | REGRESS_OPENSSL_FD) }, 1052*eabc0478Schristos { "bufferevent_filter_freed_fd", regress_bufferevent_openssl, 1053*eabc0478Schristos TT_ISOLATED, &ssl_setup, 1054*eabc0478Schristos T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_FREED | REGRESS_OPENSSL_FD) }, 1055*eabc0478Schristos 1056*eabc0478Schristos { "bufferevent_socketpair_timeout", regress_bufferevent_openssl, 1057*eabc0478Schristos TT_ISOLATED, &ssl_setup, 1058*eabc0478Schristos T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_TIMEOUT) }, 1059*eabc0478Schristos { "bufferevent_socketpair_timeout_freed_fd", regress_bufferevent_openssl, 1060*eabc0478Schristos TT_ISOLATED, &ssl_setup, 1061*eabc0478Schristos T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_TIMEOUT | REGRESS_OPENSSL_FREED | REGRESS_OPENSSL_FD) }, 10628585484eSchristos 10638585484eSchristos { "bufferevent_connect", regress_bufferevent_openssl_connect, 1064*eabc0478Schristos TT_FORK|TT_NEED_BASE, &ssl_setup, NULL }, 1065*eabc0478Schristos { "bufferevent_connect_sleep", regress_bufferevent_openssl_connect, 1066*eabc0478Schristos TT_FORK|TT_NEED_BASE, &ssl_setup, T(REGRESS_OPENSSL_SLEEP) }, 1067*eabc0478Schristos 1068*eabc0478Schristos { "bufferevent_wm", regress_bufferevent_openssl_wm, 1069*eabc0478Schristos TT_FORK|TT_NEED_BASE, &ssl_setup, NULL }, 1070*eabc0478Schristos { "bufferevent_wm_filter", regress_bufferevent_openssl_wm, 1071*eabc0478Schristos TT_FORK|TT_NEED_BASE, &ssl_setup, T(REGRESS_OPENSSL_FILTER) }, 1072*eabc0478Schristos { "bufferevent_wm_defer", regress_bufferevent_openssl_wm, 1073*eabc0478Schristos TT_FORK|TT_NEED_BASE, &ssl_setup, T(REGRESS_DEFERRED_CALLBACKS) }, 1074*eabc0478Schristos { "bufferevent_wm_filter_defer", regress_bufferevent_openssl_wm, 1075*eabc0478Schristos TT_FORK|TT_NEED_BASE, &ssl_setup, T(REGRESS_OPENSSL_FILTER|REGRESS_DEFERRED_CALLBACKS) }, 1076*eabc0478Schristos 1077*eabc0478Schristos #undef T 10788585484eSchristos 10798585484eSchristos END_OF_TESTCASES, 10808585484eSchristos }; 1081