1*eabc0478Schristos /* $NetBSD: bufferevent_openssl.c,v 1.7 2024/08/18 20:47:21 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 #include "event2/event-config.h" 358585484eSchristos #include "evconfig-private.h" 368585484eSchristos 378585484eSchristos #include <sys/types.h> 388585484eSchristos 398585484eSchristos #ifdef EVENT__HAVE_SYS_TIME_H 408585484eSchristos #include <sys/time.h> 418585484eSchristos #endif 428585484eSchristos 438585484eSchristos #include <errno.h> 448585484eSchristos #include <stdio.h> 458585484eSchristos #include <stdlib.h> 468585484eSchristos #include <string.h> 478585484eSchristos #ifdef EVENT__HAVE_STDARG_H 488585484eSchristos #include <stdarg.h> 498585484eSchristos #endif 508585484eSchristos #ifdef EVENT__HAVE_UNISTD_H 518585484eSchristos #include <unistd.h> 528585484eSchristos #endif 538585484eSchristos 548585484eSchristos #ifdef _WIN32 558585484eSchristos #include <winsock2.h> 568585484eSchristos #endif 578585484eSchristos 588585484eSchristos #include "event2/bufferevent.h" 598585484eSchristos #include "event2/bufferevent_struct.h" 608585484eSchristos #include "event2/bufferevent_ssl.h" 618585484eSchristos #include "event2/buffer.h" 628585484eSchristos #include "event2/event.h" 638585484eSchristos 648585484eSchristos #include "mm-internal.h" 658585484eSchristos #include "bufferevent-internal.h" 668585484eSchristos #include "log-internal.h" 678585484eSchristos 688585484eSchristos #include <openssl/ssl.h> 698585484eSchristos #include <openssl/err.h> 70*eabc0478Schristos #include "openssl-compat.h" 718585484eSchristos 728585484eSchristos /* 738585484eSchristos * Define an OpenSSL bio that targets a bufferevent. 748585484eSchristos */ 758585484eSchristos 768585484eSchristos /* -------------------- 778585484eSchristos A BIO is an OpenSSL abstraction that handles reading and writing data. The 788585484eSchristos library will happily speak SSL over anything that implements a BIO 798585484eSchristos interface. 808585484eSchristos 818585484eSchristos Here we define a BIO implementation that directs its output to a 828585484eSchristos bufferevent. We'll want to use this only when none of OpenSSL's built-in 838585484eSchristos IO mechanisms work for us. 848585484eSchristos -------------------- */ 858585484eSchristos 868585484eSchristos /* every BIO type needs its own integer type value. */ 878585484eSchristos #define BIO_TYPE_LIBEVENT 57 888585484eSchristos /* ???? Arguably, we should set BIO_TYPE_FILTER or BIO_TYPE_SOURCE_SINK on 898585484eSchristos * this. */ 908585484eSchristos 918585484eSchristos #if 0 928585484eSchristos static void 938585484eSchristos print_err(int val) 948585484eSchristos { 958585484eSchristos int err; 968585484eSchristos printf("Error was %d\n", val); 978585484eSchristos 988585484eSchristos while ((err = ERR_get_error())) { 998585484eSchristos const char *msg = (const char*)ERR_reason_error_string(err); 1008585484eSchristos const char *lib = (const char*)ERR_lib_error_string(err); 1018585484eSchristos const char *func = (const char*)ERR_func_error_string(err); 1028585484eSchristos 1038585484eSchristos printf("%s in %s %s\n", msg, lib, func); 1048585484eSchristos } 1058585484eSchristos } 1068585484eSchristos #else 1078585484eSchristos #define print_err(v) ((void)0) 1088585484eSchristos #endif 1098585484eSchristos 1108585484eSchristos /* Called to initialize a new BIO */ 1118585484eSchristos static int 1128585484eSchristos bio_bufferevent_new(BIO *b) 1138585484eSchristos { 114*eabc0478Schristos BIO_set_init(b, 0); 115*eabc0478Schristos BIO_set_data(b, NULL); /* We'll be putting the bufferevent in this field.*/ 1168585484eSchristos return 1; 1178585484eSchristos } 1188585484eSchristos 1198585484eSchristos /* Called to uninitialize the BIO. */ 1208585484eSchristos static int 1218585484eSchristos bio_bufferevent_free(BIO *b) 1228585484eSchristos { 1238585484eSchristos if (!b) 1248585484eSchristos return 0; 125*eabc0478Schristos if (BIO_get_shutdown(b)) { 126*eabc0478Schristos if (BIO_get_init(b) && BIO_get_data(b)) 127*eabc0478Schristos bufferevent_free(BIO_get_data(b)); 128*eabc0478Schristos BIO_free(b); 1298585484eSchristos } 1308585484eSchristos return 1; 1318585484eSchristos } 1328585484eSchristos 1338585484eSchristos /* Called to extract data from the BIO. */ 1348585484eSchristos static int 1358585484eSchristos bio_bufferevent_read(BIO *b, char *out, int outlen) 1368585484eSchristos { 1378585484eSchristos int r = 0; 1388585484eSchristos struct evbuffer *input; 1398585484eSchristos 1408585484eSchristos BIO_clear_retry_flags(b); 1418585484eSchristos 1428585484eSchristos if (!out) 1438585484eSchristos return 0; 144*eabc0478Schristos if (!BIO_get_data(b)) 1458585484eSchristos return -1; 1468585484eSchristos 147*eabc0478Schristos input = bufferevent_get_input(BIO_get_data(b)); 1488585484eSchristos if (evbuffer_get_length(input) == 0) { 1498585484eSchristos /* If there's no data to read, say so. */ 1508585484eSchristos BIO_set_retry_read(b); 1518585484eSchristos return -1; 1528585484eSchristos } else { 1538585484eSchristos r = evbuffer_remove(input, out, outlen); 1548585484eSchristos } 1558585484eSchristos 1568585484eSchristos return r; 1578585484eSchristos } 1588585484eSchristos 159*eabc0478Schristos /* Called to write data into the BIO */ 1608585484eSchristos static int 1618585484eSchristos bio_bufferevent_write(BIO *b, const char *in, int inlen) 1628585484eSchristos { 163*eabc0478Schristos struct bufferevent *bufev = BIO_get_data(b); 1648585484eSchristos struct evbuffer *output; 1658585484eSchristos size_t outlen; 1668585484eSchristos 1678585484eSchristos BIO_clear_retry_flags(b); 1688585484eSchristos 169*eabc0478Schristos if (!BIO_get_data(b)) 1708585484eSchristos return -1; 1718585484eSchristos 1728585484eSchristos output = bufferevent_get_output(bufev); 1738585484eSchristos outlen = evbuffer_get_length(output); 1748585484eSchristos 1758585484eSchristos /* Copy only as much data onto the output buffer as can fit under the 1768585484eSchristos * high-water mark. */ 1778585484eSchristos if (bufev->wm_write.high && bufev->wm_write.high <= (outlen+inlen)) { 1788585484eSchristos if (bufev->wm_write.high <= outlen) { 1798585484eSchristos /* If no data can fit, we'll need to retry later. */ 1808585484eSchristos BIO_set_retry_write(b); 1818585484eSchristos return -1; 1828585484eSchristos } 1838585484eSchristos inlen = bufev->wm_write.high - outlen; 1848585484eSchristos } 1858585484eSchristos 1868585484eSchristos EVUTIL_ASSERT(inlen > 0); 1878585484eSchristos evbuffer_add(output, in, inlen); 1888585484eSchristos return inlen; 1898585484eSchristos } 1908585484eSchristos 1918585484eSchristos /* Called to handle various requests */ 1928585484eSchristos static long 1938585484eSchristos bio_bufferevent_ctrl(BIO *b, int cmd, long num, void *ptr) 1948585484eSchristos { 195*eabc0478Schristos struct bufferevent *bufev = BIO_get_data(b); 1968585484eSchristos long ret = 1; 1978585484eSchristos 1988585484eSchristos switch (cmd) { 1998585484eSchristos case BIO_CTRL_GET_CLOSE: 200*eabc0478Schristos ret = BIO_get_shutdown(b); 2018585484eSchristos break; 2028585484eSchristos case BIO_CTRL_SET_CLOSE: 203*eabc0478Schristos BIO_set_shutdown(b, (int)num); 2048585484eSchristos break; 2058585484eSchristos case BIO_CTRL_PENDING: 2068585484eSchristos ret = evbuffer_get_length(bufferevent_get_input(bufev)) != 0; 2078585484eSchristos break; 2088585484eSchristos case BIO_CTRL_WPENDING: 2098585484eSchristos ret = evbuffer_get_length(bufferevent_get_output(bufev)) != 0; 2108585484eSchristos break; 2118585484eSchristos /* XXXX These two are given a special-case treatment because 2128585484eSchristos * of cargo-cultism. I should come up with a better reason. */ 2138585484eSchristos case BIO_CTRL_DUP: 2148585484eSchristos case BIO_CTRL_FLUSH: 2158585484eSchristos ret = 1; 2168585484eSchristos break; 2178585484eSchristos default: 2188585484eSchristos ret = 0; 2198585484eSchristos break; 2208585484eSchristos } 2218585484eSchristos return ret; 2228585484eSchristos } 2238585484eSchristos 2248585484eSchristos /* Called to write a string to the BIO */ 2258585484eSchristos static int 2268585484eSchristos bio_bufferevent_puts(BIO *b, const char *s) 2278585484eSchristos { 2288585484eSchristos return bio_bufferevent_write(b, s, strlen(s)); 2298585484eSchristos } 2308585484eSchristos 2318585484eSchristos /* Method table for the bufferevent BIO */ 232*eabc0478Schristos static BIO_METHOD *methods_bufferevent; 2338585484eSchristos 2348585484eSchristos /* Return the method table for the bufferevents BIO */ 2358585484eSchristos static BIO_METHOD * 2368585484eSchristos BIO_s_bufferevent(void) 2378585484eSchristos { 238*eabc0478Schristos if (methods_bufferevent == NULL) { 239*eabc0478Schristos methods_bufferevent = BIO_meth_new(BIO_TYPE_LIBEVENT, "bufferevent"); 240*eabc0478Schristos if (methods_bufferevent == NULL) 241*eabc0478Schristos return NULL; 242*eabc0478Schristos BIO_meth_set_write(methods_bufferevent, bio_bufferevent_write); 243*eabc0478Schristos BIO_meth_set_read(methods_bufferevent, bio_bufferevent_read); 244*eabc0478Schristos BIO_meth_set_puts(methods_bufferevent, bio_bufferevent_puts); 245*eabc0478Schristos BIO_meth_set_ctrl(methods_bufferevent, bio_bufferevent_ctrl); 246*eabc0478Schristos BIO_meth_set_create(methods_bufferevent, bio_bufferevent_new); 247*eabc0478Schristos BIO_meth_set_destroy(methods_bufferevent, bio_bufferevent_free); 248*eabc0478Schristos } 249*eabc0478Schristos return methods_bufferevent; 2508585484eSchristos } 2518585484eSchristos 2528585484eSchristos /* Create a new BIO to wrap communication around a bufferevent. If close_flag 2538585484eSchristos * is true, the bufferevent will be freed when the BIO is closed. */ 2548585484eSchristos static BIO * 255*eabc0478Schristos BIO_new_bufferevent(struct bufferevent *bufferevent) 2568585484eSchristos { 2578585484eSchristos BIO *result; 2588585484eSchristos if (!bufferevent) 2598585484eSchristos return NULL; 2608585484eSchristos if (!(result = BIO_new(BIO_s_bufferevent()))) 2618585484eSchristos return NULL; 262*eabc0478Schristos BIO_set_init(result, 1); 263*eabc0478Schristos BIO_set_data(result, bufferevent); 264*eabc0478Schristos /* We don't tell the BIO to close the bufferevent; we do it ourselves on 265*eabc0478Schristos * be_openssl_destruct() */ 266*eabc0478Schristos BIO_set_shutdown(result, 0); 2678585484eSchristos return result; 2688585484eSchristos } 2698585484eSchristos 2708585484eSchristos /* -------------------- 2718585484eSchristos Now, here's the OpenSSL-based implementation of bufferevent. 2728585484eSchristos 2738585484eSchristos The implementation comes in two flavors: one that connects its SSL object 2748585484eSchristos to an underlying bufferevent using a BIO_bufferevent, and one that has the 2758585484eSchristos SSL object connect to a socket directly. The latter should generally be 2768585484eSchristos faster, except on Windows, where your best bet is using a 2778585484eSchristos bufferevent_async. 2788585484eSchristos 2798585484eSchristos (OpenSSL supports many other BIO types, too. But we can't use any unless 2808585484eSchristos we have a good way to get notified when they become readable/writable.) 2818585484eSchristos -------------------- */ 2828585484eSchristos 2838585484eSchristos struct bio_data_counts { 2848585484eSchristos unsigned long n_written; 2858585484eSchristos unsigned long n_read; 2868585484eSchristos }; 2878585484eSchristos 2888585484eSchristos struct bufferevent_openssl { 2898585484eSchristos /* Shared fields with common bufferevent implementation code. 2908585484eSchristos If we were set up with an underlying bufferevent, we use the 2918585484eSchristos events here as timers only. If we have an SSL, then we use 2928585484eSchristos the events as socket events. 2938585484eSchristos */ 2948585484eSchristos struct bufferevent_private bev; 2958585484eSchristos /* An underlying bufferevent that we're directing our output to. 2968585484eSchristos If it's NULL, then we're connected to an fd, not an evbuffer. */ 2978585484eSchristos struct bufferevent *underlying; 2988585484eSchristos /* The SSL object doing our encryption. */ 2998585484eSchristos SSL *ssl; 3008585484eSchristos 3018585484eSchristos /* A callback that's invoked when data arrives on our outbuf so we 3028585484eSchristos know to write data to the SSL. */ 3038585484eSchristos struct evbuffer_cb_entry *outbuf_cb; 3048585484eSchristos 3058585484eSchristos /* A count of how much data the bios have read/written total. Used 3068585484eSchristos for rate-limiting. */ 3078585484eSchristos struct bio_data_counts counts; 3088585484eSchristos 3098585484eSchristos /* If this value is greater than 0, then the last SSL_write blocked, 3108585484eSchristos * and we need to try it again with this many bytes. */ 3118585484eSchristos ev_ssize_t last_write; 3128585484eSchristos 3138585484eSchristos #define NUM_ERRORS 3 3148585484eSchristos ev_uint32_t errors[NUM_ERRORS]; 3158585484eSchristos 3168585484eSchristos /* When we next get available space, we should say "read" instead of 3178585484eSchristos "write". This can happen if there's a renegotiation during a read 3188585484eSchristos operation. */ 3198585484eSchristos unsigned read_blocked_on_write : 1; 3208585484eSchristos /* When we next get data, we should say "write" instead of "read". */ 3218585484eSchristos unsigned write_blocked_on_read : 1; 3228585484eSchristos /* Treat TCP close before SSL close on SSL >= v3 as clean EOF. */ 3238585484eSchristos unsigned allow_dirty_shutdown : 1; 3248585484eSchristos /* XXX */ 3258585484eSchristos unsigned n_errors : 2; 3268585484eSchristos 3278585484eSchristos /* Are we currently connecting, accepting, or doing IO? */ 3288585484eSchristos unsigned state : 2; 329*eabc0478Schristos /* If we reset fd, we sould reset state too */ 330*eabc0478Schristos unsigned old_state : 2; 3318585484eSchristos }; 3328585484eSchristos 3338585484eSchristos static int be_openssl_enable(struct bufferevent *, short); 3348585484eSchristos static int be_openssl_disable(struct bufferevent *, short); 335b8ecfcfeSchristos static void be_openssl_unlink(struct bufferevent *); 3368585484eSchristos static void be_openssl_destruct(struct bufferevent *); 3378585484eSchristos static int be_openssl_adj_timeouts(struct bufferevent *); 3388585484eSchristos static int be_openssl_flush(struct bufferevent *bufev, 3398585484eSchristos short iotype, enum bufferevent_flush_mode mode); 3408585484eSchristos static int be_openssl_ctrl(struct bufferevent *, enum bufferevent_ctrl_op, union bufferevent_ctrl_data *); 3418585484eSchristos 3428585484eSchristos const struct bufferevent_ops bufferevent_ops_openssl = { 3438585484eSchristos "ssl", 3448585484eSchristos evutil_offsetof(struct bufferevent_openssl, bev.bev), 3458585484eSchristos be_openssl_enable, 3468585484eSchristos be_openssl_disable, 347b8ecfcfeSchristos be_openssl_unlink, 3488585484eSchristos be_openssl_destruct, 3498585484eSchristos be_openssl_adj_timeouts, 3508585484eSchristos be_openssl_flush, 3518585484eSchristos be_openssl_ctrl, 3528585484eSchristos }; 3538585484eSchristos 3548585484eSchristos /* Given a bufferevent, return a pointer to the bufferevent_openssl that 3558585484eSchristos * contains it, if any. */ 3568585484eSchristos static inline struct bufferevent_openssl * 3578585484eSchristos upcast(struct bufferevent *bev) 3588585484eSchristos { 3598585484eSchristos struct bufferevent_openssl *bev_o; 360*eabc0478Schristos if (!BEV_IS_OPENSSL(bev)) 3618585484eSchristos return NULL; 3628585484eSchristos bev_o = (void*)( ((char*)bev) - 3638585484eSchristos evutil_offsetof(struct bufferevent_openssl, bev.bev)); 364*eabc0478Schristos EVUTIL_ASSERT(BEV_IS_OPENSSL(&bev_o->bev.bev)); 3658585484eSchristos return bev_o; 3668585484eSchristos } 3678585484eSchristos 3688585484eSchristos static inline void 3698585484eSchristos put_error(struct bufferevent_openssl *bev_ssl, unsigned long err) 3708585484eSchristos { 3718585484eSchristos if (bev_ssl->n_errors == NUM_ERRORS) 3728585484eSchristos return; 3738585484eSchristos /* The error type according to openssl is "unsigned long", but 3748585484eSchristos openssl never uses more than 32 bits of it. It _can't_ use more 3758585484eSchristos than 32 bits of it, since it needs to report errors on systems 3768585484eSchristos where long is only 32 bits. 3778585484eSchristos */ 3788585484eSchristos bev_ssl->errors[bev_ssl->n_errors++] = (ev_uint32_t) err; 3798585484eSchristos } 3808585484eSchristos 3818585484eSchristos /* Have the base communications channel (either the underlying bufferevent or 3828585484eSchristos * ev_read and ev_write) start reading. Take the read-blocked-on-write flag 3838585484eSchristos * into account. */ 3848585484eSchristos static int 3858585484eSchristos start_reading(struct bufferevent_openssl *bev_ssl) 3868585484eSchristos { 3878585484eSchristos if (bev_ssl->underlying) { 3888585484eSchristos bufferevent_unsuspend_read_(bev_ssl->underlying, 3898585484eSchristos BEV_SUSPEND_FILT_READ); 3908585484eSchristos return 0; 3918585484eSchristos } else { 3928585484eSchristos struct bufferevent *bev = &bev_ssl->bev.bev; 3938585484eSchristos int r; 3948585484eSchristos r = bufferevent_add_event_(&bev->ev_read, &bev->timeout_read); 3958585484eSchristos if (r == 0 && bev_ssl->read_blocked_on_write) 3968585484eSchristos r = bufferevent_add_event_(&bev->ev_write, 3978585484eSchristos &bev->timeout_write); 3988585484eSchristos return r; 3998585484eSchristos } 4008585484eSchristos } 4018585484eSchristos 4028585484eSchristos /* Have the base communications channel (either the underlying bufferevent or 4038585484eSchristos * ev_read and ev_write) start writing. Take the write-blocked-on-read flag 4048585484eSchristos * into account. */ 4058585484eSchristos static int 4068585484eSchristos start_writing(struct bufferevent_openssl *bev_ssl) 4078585484eSchristos { 4088585484eSchristos int r = 0; 4098585484eSchristos if (bev_ssl->underlying) { 410*eabc0478Schristos if (bev_ssl->write_blocked_on_read) { 411*eabc0478Schristos bufferevent_unsuspend_read_(bev_ssl->underlying, 412*eabc0478Schristos BEV_SUSPEND_FILT_READ); 413*eabc0478Schristos } 4148585484eSchristos } else { 4158585484eSchristos struct bufferevent *bev = &bev_ssl->bev.bev; 4168585484eSchristos r = bufferevent_add_event_(&bev->ev_write, &bev->timeout_write); 4178585484eSchristos if (!r && bev_ssl->write_blocked_on_read) 4188585484eSchristos r = bufferevent_add_event_(&bev->ev_read, 4198585484eSchristos &bev->timeout_read); 4208585484eSchristos } 4218585484eSchristos return r; 4228585484eSchristos } 4238585484eSchristos 4248585484eSchristos static void 4258585484eSchristos stop_reading(struct bufferevent_openssl *bev_ssl) 4268585484eSchristos { 4278585484eSchristos if (bev_ssl->write_blocked_on_read) 4288585484eSchristos return; 4298585484eSchristos if (bev_ssl->underlying) { 4308585484eSchristos bufferevent_suspend_read_(bev_ssl->underlying, 4318585484eSchristos BEV_SUSPEND_FILT_READ); 4328585484eSchristos } else { 4338585484eSchristos struct bufferevent *bev = &bev_ssl->bev.bev; 4348585484eSchristos event_del(&bev->ev_read); 4358585484eSchristos } 4368585484eSchristos } 4378585484eSchristos 4388585484eSchristos static void 4398585484eSchristos stop_writing(struct bufferevent_openssl *bev_ssl) 4408585484eSchristos { 4418585484eSchristos if (bev_ssl->read_blocked_on_write) 4428585484eSchristos return; 4438585484eSchristos if (bev_ssl->underlying) { 444*eabc0478Schristos bufferevent_unsuspend_read_(bev_ssl->underlying, 445*eabc0478Schristos BEV_SUSPEND_FILT_READ); 4468585484eSchristos } else { 4478585484eSchristos struct bufferevent *bev = &bev_ssl->bev.bev; 4488585484eSchristos event_del(&bev->ev_write); 4498585484eSchristos } 4508585484eSchristos } 4518585484eSchristos 4528585484eSchristos static int 4538585484eSchristos set_rbow(struct bufferevent_openssl *bev_ssl) 4548585484eSchristos { 4558585484eSchristos if (!bev_ssl->underlying) 4568585484eSchristos stop_reading(bev_ssl); 4578585484eSchristos bev_ssl->read_blocked_on_write = 1; 4588585484eSchristos return start_writing(bev_ssl); 4598585484eSchristos } 4608585484eSchristos 4618585484eSchristos static int 4628585484eSchristos set_wbor(struct bufferevent_openssl *bev_ssl) 4638585484eSchristos { 4648585484eSchristos if (!bev_ssl->underlying) 4658585484eSchristos stop_writing(bev_ssl); 4668585484eSchristos bev_ssl->write_blocked_on_read = 1; 4678585484eSchristos return start_reading(bev_ssl); 4688585484eSchristos } 4698585484eSchristos 4708585484eSchristos static int 4718585484eSchristos clear_rbow(struct bufferevent_openssl *bev_ssl) 4728585484eSchristos { 4738585484eSchristos struct bufferevent *bev = &bev_ssl->bev.bev; 4748585484eSchristos int r = 0; 4758585484eSchristos bev_ssl->read_blocked_on_write = 0; 4768585484eSchristos if (!(bev->enabled & EV_WRITE)) 4778585484eSchristos stop_writing(bev_ssl); 4788585484eSchristos if (bev->enabled & EV_READ) 4798585484eSchristos r = start_reading(bev_ssl); 4808585484eSchristos return r; 4818585484eSchristos } 4828585484eSchristos 4838585484eSchristos 4848585484eSchristos static int 4858585484eSchristos clear_wbor(struct bufferevent_openssl *bev_ssl) 4868585484eSchristos { 4878585484eSchristos struct bufferevent *bev = &bev_ssl->bev.bev; 4888585484eSchristos int r = 0; 4898585484eSchristos bev_ssl->write_blocked_on_read = 0; 4908585484eSchristos if (!(bev->enabled & EV_READ)) 4918585484eSchristos stop_reading(bev_ssl); 4928585484eSchristos if (bev->enabled & EV_WRITE) 4938585484eSchristos r = start_writing(bev_ssl); 4948585484eSchristos return r; 4958585484eSchristos } 4968585484eSchristos 4978585484eSchristos static void 4988585484eSchristos conn_closed(struct bufferevent_openssl *bev_ssl, int when, int errcode, int ret) 4998585484eSchristos { 5008585484eSchristos int event = BEV_EVENT_ERROR; 5018585484eSchristos int dirty_shutdown = 0; 5028585484eSchristos unsigned long err; 5038585484eSchristos 5048585484eSchristos switch (errcode) { 5058585484eSchristos case SSL_ERROR_ZERO_RETURN: 5068585484eSchristos /* Possibly a clean shutdown. */ 5078585484eSchristos if (SSL_get_shutdown(bev_ssl->ssl) & SSL_RECEIVED_SHUTDOWN) 5088585484eSchristos event = BEV_EVENT_EOF; 5098585484eSchristos else 5108585484eSchristos dirty_shutdown = 1; 5118585484eSchristos break; 5128585484eSchristos case SSL_ERROR_SYSCALL: 5138585484eSchristos /* IO error; possibly a dirty shutdown. */ 514*eabc0478Schristos if ((ret == 0 || ret == -1) && ERR_peek_error() == 0) 5158585484eSchristos dirty_shutdown = 1; 516*eabc0478Schristos put_error(bev_ssl, errcode); 5178585484eSchristos break; 5188585484eSchristos case SSL_ERROR_SSL: 5198585484eSchristos /* Protocol error. */ 520*eabc0478Schristos put_error(bev_ssl, errcode); 5218585484eSchristos break; 5228585484eSchristos case SSL_ERROR_WANT_X509_LOOKUP: 5238585484eSchristos /* XXXX handle this. */ 524*eabc0478Schristos put_error(bev_ssl, errcode); 5258585484eSchristos break; 5268585484eSchristos case SSL_ERROR_NONE: 5278585484eSchristos case SSL_ERROR_WANT_READ: 5288585484eSchristos case SSL_ERROR_WANT_WRITE: 5298585484eSchristos case SSL_ERROR_WANT_CONNECT: 5308585484eSchristos case SSL_ERROR_WANT_ACCEPT: 5318585484eSchristos default: 5328585484eSchristos /* should be impossible; treat as normal error. */ 5338585484eSchristos event_warnx("BUG: Unexpected OpenSSL error code %d", errcode); 5348585484eSchristos break; 5358585484eSchristos } 5368585484eSchristos 5378585484eSchristos while ((err = ERR_get_error())) { 5388585484eSchristos put_error(bev_ssl, err); 5398585484eSchristos } 5408585484eSchristos 5418585484eSchristos if (dirty_shutdown && bev_ssl->allow_dirty_shutdown) 5428585484eSchristos event = BEV_EVENT_EOF; 5438585484eSchristos 5448585484eSchristos stop_reading(bev_ssl); 5458585484eSchristos stop_writing(bev_ssl); 5468585484eSchristos 5478585484eSchristos /* when is BEV_EVENT_{READING|WRITING} */ 5488585484eSchristos event = when | event; 549b8ecfcfeSchristos bufferevent_run_eventcb_(&bev_ssl->bev.bev, event, 0); 5508585484eSchristos } 5518585484eSchristos 5528585484eSchristos static void 5538585484eSchristos init_bio_counts(struct bufferevent_openssl *bev_ssl) 5548585484eSchristos { 555*eabc0478Schristos BIO *rbio, *wbio; 556*eabc0478Schristos 557*eabc0478Schristos wbio = SSL_get_wbio(bev_ssl->ssl); 558*eabc0478Schristos bev_ssl->counts.n_written = wbio ? BIO_number_written(wbio) : 0; 559*eabc0478Schristos rbio = SSL_get_rbio(bev_ssl->ssl); 560*eabc0478Schristos bev_ssl->counts.n_read = rbio ? BIO_number_read(rbio) : 0; 5618585484eSchristos } 5628585484eSchristos 5638585484eSchristos static inline void 5648585484eSchristos decrement_buckets(struct bufferevent_openssl *bev_ssl) 5658585484eSchristos { 5668585484eSchristos unsigned long num_w = BIO_number_written(SSL_get_wbio(bev_ssl->ssl)); 5678585484eSchristos unsigned long num_r = BIO_number_read(SSL_get_rbio(bev_ssl->ssl)); 5688585484eSchristos /* These next two subtractions can wrap around. That's okay. */ 5698585484eSchristos unsigned long w = num_w - bev_ssl->counts.n_written; 5708585484eSchristos unsigned long r = num_r - bev_ssl->counts.n_read; 5718585484eSchristos if (w) 5728585484eSchristos bufferevent_decrement_write_buckets_(&bev_ssl->bev, w); 5738585484eSchristos if (r) 5748585484eSchristos bufferevent_decrement_read_buckets_(&bev_ssl->bev, r); 5758585484eSchristos bev_ssl->counts.n_written = num_w; 5768585484eSchristos bev_ssl->counts.n_read = num_r; 5778585484eSchristos } 5788585484eSchristos 5798585484eSchristos #define OP_MADE_PROGRESS 1 5808585484eSchristos #define OP_BLOCKED 2 5818585484eSchristos #define OP_ERR 4 5828585484eSchristos 5838585484eSchristos /* Return a bitmask of OP_MADE_PROGRESS (if we read anything); OP_BLOCKED (if 5848585484eSchristos we're now blocked); and OP_ERR (if an error occurred). */ 5858585484eSchristos static int 5868585484eSchristos do_read(struct bufferevent_openssl *bev_ssl, int n_to_read) { 5878585484eSchristos /* Requires lock */ 5888585484eSchristos struct bufferevent *bev = &bev_ssl->bev.bev; 5898585484eSchristos struct evbuffer *input = bev->input; 5908585484eSchristos int r, n, i, n_used = 0, atmost; 5918585484eSchristos struct evbuffer_iovec space[2]; 5928585484eSchristos int result = 0; 5938585484eSchristos 5948585484eSchristos if (bev_ssl->bev.read_suspended) 5958585484eSchristos return 0; 5968585484eSchristos 5978585484eSchristos atmost = bufferevent_get_read_max_(&bev_ssl->bev); 5988585484eSchristos if (n_to_read > atmost) 5998585484eSchristos n_to_read = atmost; 6008585484eSchristos 6018585484eSchristos n = evbuffer_reserve_space(input, n_to_read, space, 2); 6028585484eSchristos if (n < 0) 6038585484eSchristos return OP_ERR; 6048585484eSchristos 6058585484eSchristos for (i=0; i<n; ++i) { 6068585484eSchristos if (bev_ssl->bev.read_suspended) 6078585484eSchristos break; 608*eabc0478Schristos ERR_clear_error(); 6098585484eSchristos r = SSL_read(bev_ssl->ssl, space[i].iov_base, space[i].iov_len); 6108585484eSchristos if (r>0) { 6118585484eSchristos result |= OP_MADE_PROGRESS; 6128585484eSchristos if (bev_ssl->read_blocked_on_write) 6138585484eSchristos if (clear_rbow(bev_ssl) < 0) 6148585484eSchristos return OP_ERR | result; 6158585484eSchristos ++n_used; 6168585484eSchristos space[i].iov_len = r; 6178585484eSchristos decrement_buckets(bev_ssl); 6188585484eSchristos } else { 6198585484eSchristos int err = SSL_get_error(bev_ssl->ssl, r); 6208585484eSchristos print_err(err); 6218585484eSchristos switch (err) { 6228585484eSchristos case SSL_ERROR_WANT_READ: 6238585484eSchristos /* Can't read until underlying has more data. */ 6248585484eSchristos if (bev_ssl->read_blocked_on_write) 6258585484eSchristos if (clear_rbow(bev_ssl) < 0) 6268585484eSchristos return OP_ERR | result; 6278585484eSchristos break; 6288585484eSchristos case SSL_ERROR_WANT_WRITE: 6298585484eSchristos /* This read operation requires a write, and the 6308585484eSchristos * underlying is full */ 6318585484eSchristos if (!bev_ssl->read_blocked_on_write) 6328585484eSchristos if (set_rbow(bev_ssl) < 0) 6338585484eSchristos return OP_ERR | result; 6348585484eSchristos break; 6358585484eSchristos default: 6368585484eSchristos conn_closed(bev_ssl, BEV_EVENT_READING, err, r); 6378585484eSchristos break; 6388585484eSchristos } 6398585484eSchristos result |= OP_BLOCKED; 6408585484eSchristos break; /* out of the loop */ 6418585484eSchristos } 6428585484eSchristos } 6438585484eSchristos 6448585484eSchristos if (n_used) { 6458585484eSchristos evbuffer_commit_space(input, space, n_used); 6468585484eSchristos if (bev_ssl->underlying) 6478585484eSchristos BEV_RESET_GENERIC_READ_TIMEOUT(bev); 6488585484eSchristos } 6498585484eSchristos 6508585484eSchristos return result; 6518585484eSchristos } 6528585484eSchristos 6538585484eSchristos /* Return a bitmask of OP_MADE_PROGRESS (if we wrote anything); OP_BLOCKED (if 6548585484eSchristos we're now blocked); and OP_ERR (if an error occurred). */ 6558585484eSchristos static int 6568585484eSchristos do_write(struct bufferevent_openssl *bev_ssl, int atmost) 6578585484eSchristos { 6588585484eSchristos int i, r, n, n_written = 0; 6598585484eSchristos struct bufferevent *bev = &bev_ssl->bev.bev; 6608585484eSchristos struct evbuffer *output = bev->output; 6618585484eSchristos struct evbuffer_iovec space[8]; 6628585484eSchristos int result = 0; 6638585484eSchristos 6648585484eSchristos if (bev_ssl->last_write > 0) 6658585484eSchristos atmost = bev_ssl->last_write; 6668585484eSchristos else 6678585484eSchristos atmost = bufferevent_get_write_max_(&bev_ssl->bev); 6688585484eSchristos 6698585484eSchristos n = evbuffer_peek(output, atmost, NULL, space, 8); 6708585484eSchristos if (n < 0) 6718585484eSchristos return OP_ERR | result; 6728585484eSchristos 6738585484eSchristos if (n > 8) 6748585484eSchristos n = 8; 6758585484eSchristos for (i=0; i < n; ++i) { 6768585484eSchristos if (bev_ssl->bev.write_suspended) 6778585484eSchristos break; 6788585484eSchristos 6798585484eSchristos /* SSL_write will (reasonably) return 0 if we tell it to 6808585484eSchristos send 0 data. Skip this case so we don't interpret the 6818585484eSchristos result as an error */ 6828585484eSchristos if (space[i].iov_len == 0) 6838585484eSchristos continue; 6848585484eSchristos 685*eabc0478Schristos ERR_clear_error(); 6868585484eSchristos r = SSL_write(bev_ssl->ssl, space[i].iov_base, 6878585484eSchristos space[i].iov_len); 6888585484eSchristos if (r > 0) { 6898585484eSchristos result |= OP_MADE_PROGRESS; 6908585484eSchristos if (bev_ssl->write_blocked_on_read) 6918585484eSchristos if (clear_wbor(bev_ssl) < 0) 6928585484eSchristos return OP_ERR | result; 6938585484eSchristos n_written += r; 6948585484eSchristos bev_ssl->last_write = -1; 6958585484eSchristos decrement_buckets(bev_ssl); 6968585484eSchristos } else { 6978585484eSchristos int err = SSL_get_error(bev_ssl->ssl, r); 6988585484eSchristos print_err(err); 6998585484eSchristos switch (err) { 7008585484eSchristos case SSL_ERROR_WANT_WRITE: 7018585484eSchristos /* Can't read until underlying has more data. */ 7028585484eSchristos if (bev_ssl->write_blocked_on_read) 7038585484eSchristos if (clear_wbor(bev_ssl) < 0) 7048585484eSchristos return OP_ERR | result; 7058585484eSchristos bev_ssl->last_write = space[i].iov_len; 7068585484eSchristos break; 7078585484eSchristos case SSL_ERROR_WANT_READ: 7088585484eSchristos /* This read operation requires a write, and the 7098585484eSchristos * underlying is full */ 7108585484eSchristos if (!bev_ssl->write_blocked_on_read) 7118585484eSchristos if (set_wbor(bev_ssl) < 0) 7128585484eSchristos return OP_ERR | result; 7138585484eSchristos bev_ssl->last_write = space[i].iov_len; 7148585484eSchristos break; 7158585484eSchristos default: 7168585484eSchristos conn_closed(bev_ssl, BEV_EVENT_WRITING, err, r); 7178585484eSchristos bev_ssl->last_write = -1; 7188585484eSchristos break; 7198585484eSchristos } 7208585484eSchristos result |= OP_BLOCKED; 7218585484eSchristos break; 7228585484eSchristos } 7238585484eSchristos } 7248585484eSchristos if (n_written) { 7258585484eSchristos evbuffer_drain(output, n_written); 7268585484eSchristos if (bev_ssl->underlying) 7278585484eSchristos BEV_RESET_GENERIC_WRITE_TIMEOUT(bev); 7288585484eSchristos 729*eabc0478Schristos bufferevent_trigger_nolock_(bev, EV_WRITE, BEV_OPT_DEFER_CALLBACKS); 7308585484eSchristos } 7318585484eSchristos return result; 7328585484eSchristos } 7338585484eSchristos 7348585484eSchristos #define WRITE_FRAME 15000 7358585484eSchristos 7368585484eSchristos #define READ_DEFAULT 4096 7378585484eSchristos 7388585484eSchristos /* Try to figure out how many bytes to read; return 0 if we shouldn't be 7398585484eSchristos * reading. */ 7408585484eSchristos static int 7418585484eSchristos bytes_to_read(struct bufferevent_openssl *bev) 7428585484eSchristos { 7438585484eSchristos struct evbuffer *input = bev->bev.bev.input; 7448585484eSchristos struct event_watermark *wm = &bev->bev.bev.wm_read; 7458585484eSchristos int result = READ_DEFAULT; 7468585484eSchristos ev_ssize_t limit; 7478585484eSchristos /* XXX 99% of this is generic code that nearly all bufferevents will 7488585484eSchristos * want. */ 7498585484eSchristos 7508585484eSchristos if (bev->write_blocked_on_read) { 7518585484eSchristos return 0; 7528585484eSchristos } 7538585484eSchristos 7548585484eSchristos if (! (bev->bev.bev.enabled & EV_READ)) { 7558585484eSchristos return 0; 7568585484eSchristos } 7578585484eSchristos 7588585484eSchristos if (bev->bev.read_suspended) { 7598585484eSchristos return 0; 7608585484eSchristos } 7618585484eSchristos 7628585484eSchristos if (wm->high) { 7638585484eSchristos if (evbuffer_get_length(input) >= wm->high) { 7648585484eSchristos return 0; 7658585484eSchristos } 7668585484eSchristos 7678585484eSchristos result = wm->high - evbuffer_get_length(input); 7688585484eSchristos } else { 7698585484eSchristos result = READ_DEFAULT; 7708585484eSchristos } 7718585484eSchristos 7728585484eSchristos /* Respect the rate limit */ 7738585484eSchristos limit = bufferevent_get_read_max_(&bev->bev); 7748585484eSchristos if (result > limit) { 7758585484eSchristos result = limit; 7768585484eSchristos } 7778585484eSchristos 7788585484eSchristos return result; 7798585484eSchristos } 7808585484eSchristos 7818585484eSchristos 7828585484eSchristos /* Things look readable. If write is blocked on read, write till it isn't. 7838585484eSchristos * Read from the underlying buffer until we block or we hit our high-water 7848585484eSchristos * mark. 7858585484eSchristos */ 7868585484eSchristos static void 7878585484eSchristos consider_reading(struct bufferevent_openssl *bev_ssl) 7888585484eSchristos { 7898585484eSchristos int r; 7908585484eSchristos int n_to_read; 7918585484eSchristos int all_result_flags = 0; 7928585484eSchristos 7938585484eSchristos while (bev_ssl->write_blocked_on_read) { 7948585484eSchristos r = do_write(bev_ssl, WRITE_FRAME); 7958585484eSchristos if (r & (OP_BLOCKED|OP_ERR)) 7968585484eSchristos break; 7978585484eSchristos } 7988585484eSchristos if (bev_ssl->write_blocked_on_read) 7998585484eSchristos return; 8008585484eSchristos 8018585484eSchristos n_to_read = bytes_to_read(bev_ssl); 8028585484eSchristos 8038585484eSchristos while (n_to_read) { 8048585484eSchristos r = do_read(bev_ssl, n_to_read); 8058585484eSchristos all_result_flags |= r; 8068585484eSchristos 8078585484eSchristos if (r & (OP_BLOCKED|OP_ERR)) 8088585484eSchristos break; 8098585484eSchristos 8108585484eSchristos if (bev_ssl->bev.read_suspended) 8118585484eSchristos break; 8128585484eSchristos 8138585484eSchristos /* Read all pending data. This won't hit the network 8148585484eSchristos * again, and will (most importantly) put us in a state 8158585484eSchristos * where we don't need to read anything else until the 8168585484eSchristos * socket is readable again. It'll potentially make us 8178585484eSchristos * overrun our read high-watermark (somewhat 8188585484eSchristos * regrettable). The damage to the rate-limit has 8198585484eSchristos * already been done, since OpenSSL went and read a 8208585484eSchristos * whole SSL record anyway. */ 8218585484eSchristos n_to_read = SSL_pending(bev_ssl->ssl); 8228585484eSchristos 8238585484eSchristos /* XXX This if statement is actually a bad bug, added to avoid 8248585484eSchristos * XXX a worse bug. 8258585484eSchristos * 8268585484eSchristos * The bad bug: It can potentially cause resource unfairness 8278585484eSchristos * by reading too much data from the underlying bufferevent; 8288585484eSchristos * it can potentially cause read looping if the underlying 8298585484eSchristos * bufferevent is a bufferevent_pair and deferred callbacks 8308585484eSchristos * aren't used. 8318585484eSchristos * 8328585484eSchristos * The worse bug: If we didn't do this, then we would 8338585484eSchristos * potentially not read any more from bev_ssl->underlying 8348585484eSchristos * until more data arrived there, which could lead to us 8358585484eSchristos * waiting forever. 8368585484eSchristos */ 8378585484eSchristos if (!n_to_read && bev_ssl->underlying) 8388585484eSchristos n_to_read = bytes_to_read(bev_ssl); 8398585484eSchristos } 8408585484eSchristos 8418585484eSchristos if (all_result_flags & OP_MADE_PROGRESS) { 8428585484eSchristos struct bufferevent *bev = &bev_ssl->bev.bev; 8438585484eSchristos 844b8ecfcfeSchristos bufferevent_trigger_nolock_(bev, EV_READ, 0); 8458585484eSchristos } 8468585484eSchristos 8478585484eSchristos if (!bev_ssl->underlying) { 8488585484eSchristos /* Should be redundant, but let's avoid busy-looping */ 8498585484eSchristos if (bev_ssl->bev.read_suspended || 8508585484eSchristos !(bev_ssl->bev.bev.enabled & EV_READ)) { 8518585484eSchristos event_del(&bev_ssl->bev.bev.ev_read); 8528585484eSchristos } 8538585484eSchristos } 8548585484eSchristos } 8558585484eSchristos 8568585484eSchristos static void 8578585484eSchristos consider_writing(struct bufferevent_openssl *bev_ssl) 8588585484eSchristos { 8598585484eSchristos int r; 8608585484eSchristos struct evbuffer *output = bev_ssl->bev.bev.output; 8618585484eSchristos struct evbuffer *target = NULL; 8628585484eSchristos struct event_watermark *wm = NULL; 8638585484eSchristos 8648585484eSchristos while (bev_ssl->read_blocked_on_write) { 8658585484eSchristos r = do_read(bev_ssl, 1024); /* XXXX 1024 is a hack */ 8668585484eSchristos if (r & OP_MADE_PROGRESS) { 8678585484eSchristos struct bufferevent *bev = &bev_ssl->bev.bev; 8688585484eSchristos 869b8ecfcfeSchristos bufferevent_trigger_nolock_(bev, EV_READ, 0); 8708585484eSchristos } 8718585484eSchristos if (r & (OP_ERR|OP_BLOCKED)) 8728585484eSchristos break; 8738585484eSchristos } 8748585484eSchristos if (bev_ssl->read_blocked_on_write) 8758585484eSchristos return; 8768585484eSchristos if (bev_ssl->underlying) { 8778585484eSchristos target = bev_ssl->underlying->output; 8788585484eSchristos wm = &bev_ssl->underlying->wm_write; 8798585484eSchristos } 8808585484eSchristos while ((bev_ssl->bev.bev.enabled & EV_WRITE) && 8818585484eSchristos (! bev_ssl->bev.write_suspended) && 8828585484eSchristos evbuffer_get_length(output) && 8838585484eSchristos (!target || (! wm->high || evbuffer_get_length(target) < wm->high))) { 8848585484eSchristos int n_to_write; 8858585484eSchristos if (wm && wm->high) 8868585484eSchristos n_to_write = wm->high - evbuffer_get_length(target); 8878585484eSchristos else 8888585484eSchristos n_to_write = WRITE_FRAME; 8898585484eSchristos r = do_write(bev_ssl, n_to_write); 8908585484eSchristos if (r & (OP_BLOCKED|OP_ERR)) 8918585484eSchristos break; 8928585484eSchristos } 8938585484eSchristos 8948585484eSchristos if (!bev_ssl->underlying) { 8958585484eSchristos if (evbuffer_get_length(output) == 0) { 8968585484eSchristos event_del(&bev_ssl->bev.bev.ev_write); 8978585484eSchristos } else if (bev_ssl->bev.write_suspended || 8988585484eSchristos !(bev_ssl->bev.bev.enabled & EV_WRITE)) { 8998585484eSchristos /* Should be redundant, but let's avoid busy-looping */ 9008585484eSchristos event_del(&bev_ssl->bev.bev.ev_write); 9018585484eSchristos } 9028585484eSchristos } 9038585484eSchristos } 9048585484eSchristos 9058585484eSchristos static void 9068585484eSchristos be_openssl_readcb(struct bufferevent *bev_base, void *ctx) 9078585484eSchristos { 9088585484eSchristos struct bufferevent_openssl *bev_ssl = ctx; 9098585484eSchristos consider_reading(bev_ssl); 9108585484eSchristos } 9118585484eSchristos 9128585484eSchristos static void 9138585484eSchristos be_openssl_writecb(struct bufferevent *bev_base, void *ctx) 9148585484eSchristos { 9158585484eSchristos struct bufferevent_openssl *bev_ssl = ctx; 9168585484eSchristos consider_writing(bev_ssl); 9178585484eSchristos } 9188585484eSchristos 9198585484eSchristos static void 9208585484eSchristos be_openssl_eventcb(struct bufferevent *bev_base, short what, void *ctx) 9218585484eSchristos { 9228585484eSchristos struct bufferevent_openssl *bev_ssl = ctx; 9238585484eSchristos int event = 0; 9248585484eSchristos 9258585484eSchristos if (what & BEV_EVENT_EOF) { 9268585484eSchristos if (bev_ssl->allow_dirty_shutdown) 9278585484eSchristos event = BEV_EVENT_EOF; 9288585484eSchristos else 9298585484eSchristos event = BEV_EVENT_ERROR; 9308585484eSchristos } else if (what & BEV_EVENT_TIMEOUT) { 9318585484eSchristos /* We sure didn't set this. Propagate it to the user. */ 9328585484eSchristos event = what; 9338585484eSchristos } else if (what & BEV_EVENT_ERROR) { 9348585484eSchristos /* An error occurred on the connection. Propagate it to the user. */ 9358585484eSchristos event = what; 9368585484eSchristos } else if (what & BEV_EVENT_CONNECTED) { 9378585484eSchristos /* Ignore it. We're saying SSL_connect() already, which will 9388585484eSchristos eat it. */ 9398585484eSchristos } 9408585484eSchristos if (event) 941b8ecfcfeSchristos bufferevent_run_eventcb_(&bev_ssl->bev.bev, event, 0); 9428585484eSchristos } 9438585484eSchristos 9448585484eSchristos static void 9458585484eSchristos be_openssl_readeventcb(evutil_socket_t fd, short what, void *ptr) 9468585484eSchristos { 9478585484eSchristos struct bufferevent_openssl *bev_ssl = ptr; 9488585484eSchristos bufferevent_incref_and_lock_(&bev_ssl->bev.bev); 9498585484eSchristos if (what == EV_TIMEOUT) { 9508585484eSchristos bufferevent_run_eventcb_(&bev_ssl->bev.bev, 951b8ecfcfeSchristos BEV_EVENT_TIMEOUT|BEV_EVENT_READING, 0); 9528585484eSchristos } else { 9538585484eSchristos consider_reading(bev_ssl); 9548585484eSchristos } 9558585484eSchristos bufferevent_decref_and_unlock_(&bev_ssl->bev.bev); 9568585484eSchristos } 9578585484eSchristos 9588585484eSchristos static void 9598585484eSchristos be_openssl_writeeventcb(evutil_socket_t fd, short what, void *ptr) 9608585484eSchristos { 9618585484eSchristos struct bufferevent_openssl *bev_ssl = ptr; 9628585484eSchristos bufferevent_incref_and_lock_(&bev_ssl->bev.bev); 9638585484eSchristos if (what == EV_TIMEOUT) { 9648585484eSchristos bufferevent_run_eventcb_(&bev_ssl->bev.bev, 965b8ecfcfeSchristos BEV_EVENT_TIMEOUT|BEV_EVENT_WRITING, 0); 9668585484eSchristos } else { 9678585484eSchristos consider_writing(bev_ssl); 9688585484eSchristos } 9698585484eSchristos bufferevent_decref_and_unlock_(&bev_ssl->bev.bev); 9708585484eSchristos } 9718585484eSchristos 972*eabc0478Schristos static evutil_socket_t 973*eabc0478Schristos be_openssl_auto_fd(struct bufferevent_openssl *bev_ssl, evutil_socket_t fd) 974*eabc0478Schristos { 975*eabc0478Schristos if (!bev_ssl->underlying) { 976*eabc0478Schristos struct bufferevent *bev = &bev_ssl->bev.bev; 977*eabc0478Schristos if (event_initialized(&bev->ev_read) && fd < 0) { 978*eabc0478Schristos fd = event_get_fd(&bev->ev_read); 979*eabc0478Schristos } 980*eabc0478Schristos } 981*eabc0478Schristos return fd; 982*eabc0478Schristos } 983*eabc0478Schristos 9848585484eSchristos static int 9858585484eSchristos set_open_callbacks(struct bufferevent_openssl *bev_ssl, evutil_socket_t fd) 9868585484eSchristos { 9878585484eSchristos if (bev_ssl->underlying) { 9888585484eSchristos bufferevent_setcb(bev_ssl->underlying, 9898585484eSchristos be_openssl_readcb, be_openssl_writecb, be_openssl_eventcb, 9908585484eSchristos bev_ssl); 9918585484eSchristos return 0; 9928585484eSchristos } else { 9938585484eSchristos struct bufferevent *bev = &bev_ssl->bev.bev; 9948585484eSchristos int rpending=0, wpending=0, r1=0, r2=0; 995*eabc0478Schristos 996*eabc0478Schristos if (event_initialized(&bev->ev_read)) { 9978585484eSchristos rpending = event_pending(&bev->ev_read, EV_READ, NULL); 9988585484eSchristos wpending = event_pending(&bev->ev_write, EV_WRITE, NULL); 999*eabc0478Schristos 10008585484eSchristos event_del(&bev->ev_read); 10018585484eSchristos event_del(&bev->ev_write); 10028585484eSchristos } 1003*eabc0478Schristos 10048585484eSchristos event_assign(&bev->ev_read, bev->ev_base, fd, 1005b8ecfcfeSchristos EV_READ|EV_PERSIST|EV_FINALIZE, 1006b8ecfcfeSchristos be_openssl_readeventcb, bev_ssl); 10078585484eSchristos event_assign(&bev->ev_write, bev->ev_base, fd, 1008b8ecfcfeSchristos EV_WRITE|EV_PERSIST|EV_FINALIZE, 1009b8ecfcfeSchristos be_openssl_writeeventcb, bev_ssl); 1010*eabc0478Schristos 10118585484eSchristos if (rpending) 10128585484eSchristos r1 = bufferevent_add_event_(&bev->ev_read, &bev->timeout_read); 10138585484eSchristos if (wpending) 10148585484eSchristos r2 = bufferevent_add_event_(&bev->ev_write, &bev->timeout_write); 1015*eabc0478Schristos 10168585484eSchristos return (r1<0 || r2<0) ? -1 : 0; 10178585484eSchristos } 10188585484eSchristos } 10198585484eSchristos 10208585484eSchristos static int 10218585484eSchristos do_handshake(struct bufferevent_openssl *bev_ssl) 10228585484eSchristos { 10238585484eSchristos int r; 10248585484eSchristos 10258585484eSchristos switch (bev_ssl->state) { 10268585484eSchristos default: 10278585484eSchristos case BUFFEREVENT_SSL_OPEN: 10288585484eSchristos EVUTIL_ASSERT(0); 10298585484eSchristos return -1; 10308585484eSchristos case BUFFEREVENT_SSL_CONNECTING: 10318585484eSchristos case BUFFEREVENT_SSL_ACCEPTING: 1032*eabc0478Schristos ERR_clear_error(); 10338585484eSchristos r = SSL_do_handshake(bev_ssl->ssl); 10348585484eSchristos break; 10358585484eSchristos } 10368585484eSchristos decrement_buckets(bev_ssl); 10378585484eSchristos 10388585484eSchristos if (r==1) { 1039*eabc0478Schristos evutil_socket_t fd = event_get_fd(&bev_ssl->bev.bev.ev_read); 10408585484eSchristos /* We're done! */ 10418585484eSchristos bev_ssl->state = BUFFEREVENT_SSL_OPEN; 1042*eabc0478Schristos set_open_callbacks(bev_ssl, fd); /* XXXX handle failure */ 10438585484eSchristos /* Call do_read and do_write as needed */ 10448585484eSchristos bufferevent_enable(&bev_ssl->bev.bev, bev_ssl->bev.bev.enabled); 10458585484eSchristos bufferevent_run_eventcb_(&bev_ssl->bev.bev, 1046b8ecfcfeSchristos BEV_EVENT_CONNECTED, 0); 10478585484eSchristos return 1; 10488585484eSchristos } else { 10498585484eSchristos int err = SSL_get_error(bev_ssl->ssl, r); 10508585484eSchristos print_err(err); 10518585484eSchristos switch (err) { 10528585484eSchristos case SSL_ERROR_WANT_WRITE: 10538585484eSchristos stop_reading(bev_ssl); 10548585484eSchristos return start_writing(bev_ssl); 10558585484eSchristos case SSL_ERROR_WANT_READ: 10568585484eSchristos stop_writing(bev_ssl); 10578585484eSchristos return start_reading(bev_ssl); 10588585484eSchristos default: 10598585484eSchristos conn_closed(bev_ssl, BEV_EVENT_READING, err, r); 10608585484eSchristos return -1; 10618585484eSchristos } 10628585484eSchristos } 10638585484eSchristos } 10648585484eSchristos 10658585484eSchristos static void 10668585484eSchristos be_openssl_handshakecb(struct bufferevent *bev_base, void *ctx) 10678585484eSchristos { 10688585484eSchristos struct bufferevent_openssl *bev_ssl = ctx; 10698585484eSchristos do_handshake(bev_ssl);/* XXX handle failure */ 10708585484eSchristos } 10718585484eSchristos 10728585484eSchristos static void 10738585484eSchristos be_openssl_handshakeeventcb(evutil_socket_t fd, short what, void *ptr) 10748585484eSchristos { 10758585484eSchristos struct bufferevent_openssl *bev_ssl = ptr; 10768585484eSchristos 10778585484eSchristos bufferevent_incref_and_lock_(&bev_ssl->bev.bev); 10788585484eSchristos if (what & EV_TIMEOUT) { 1079b8ecfcfeSchristos bufferevent_run_eventcb_(&bev_ssl->bev.bev, BEV_EVENT_TIMEOUT, 0); 10808585484eSchristos } else 10818585484eSchristos do_handshake(bev_ssl);/* XXX handle failure */ 10828585484eSchristos bufferevent_decref_and_unlock_(&bev_ssl->bev.bev); 10838585484eSchristos } 10848585484eSchristos 10858585484eSchristos static int 10868585484eSchristos set_handshake_callbacks(struct bufferevent_openssl *bev_ssl, evutil_socket_t fd) 10878585484eSchristos { 10888585484eSchristos if (bev_ssl->underlying) { 10898585484eSchristos bufferevent_setcb(bev_ssl->underlying, 10908585484eSchristos be_openssl_handshakecb, be_openssl_handshakecb, 10918585484eSchristos be_openssl_eventcb, 10928585484eSchristos bev_ssl); 1093*eabc0478Schristos 1094*eabc0478Schristos if (fd < 0) 1095*eabc0478Schristos return 0; 1096*eabc0478Schristos 1097*eabc0478Schristos if (bufferevent_setfd(bev_ssl->underlying, fd)) 1098*eabc0478Schristos return 1; 1099*eabc0478Schristos 11008585484eSchristos return do_handshake(bev_ssl); 11018585484eSchristos } else { 11028585484eSchristos struct bufferevent *bev = &bev_ssl->bev.bev; 1103*eabc0478Schristos 1104*eabc0478Schristos if (event_initialized(&bev->ev_read)) { 11058585484eSchristos event_del(&bev->ev_read); 11068585484eSchristos event_del(&bev->ev_write); 11078585484eSchristos } 1108*eabc0478Schristos 11098585484eSchristos event_assign(&bev->ev_read, bev->ev_base, fd, 1110b8ecfcfeSchristos EV_READ|EV_PERSIST|EV_FINALIZE, 1111b8ecfcfeSchristos be_openssl_handshakeeventcb, bev_ssl); 11128585484eSchristos event_assign(&bev->ev_write, bev->ev_base, fd, 1113b8ecfcfeSchristos EV_WRITE|EV_PERSIST|EV_FINALIZE, 1114b8ecfcfeSchristos be_openssl_handshakeeventcb, bev_ssl); 1115*eabc0478Schristos if (fd >= 0) 1116*eabc0478Schristos bufferevent_enable(bev, bev->enabled); 1117*eabc0478Schristos return 0; 11188585484eSchristos } 11198585484eSchristos } 11208585484eSchristos 11218585484eSchristos int 11228585484eSchristos bufferevent_ssl_renegotiate(struct bufferevent *bev) 11238585484eSchristos { 11248585484eSchristos struct bufferevent_openssl *bev_ssl = upcast(bev); 11258585484eSchristos if (!bev_ssl) 11268585484eSchristos return -1; 11278585484eSchristos if (SSL_renegotiate(bev_ssl->ssl) < 0) 11288585484eSchristos return -1; 11298585484eSchristos bev_ssl->state = BUFFEREVENT_SSL_CONNECTING; 1130*eabc0478Schristos if (set_handshake_callbacks(bev_ssl, be_openssl_auto_fd(bev_ssl, -1)) < 0) 11318585484eSchristos return -1; 11328585484eSchristos if (!bev_ssl->underlying) 11338585484eSchristos return do_handshake(bev_ssl); 11348585484eSchristos return 0; 11358585484eSchristos } 11368585484eSchristos 11378585484eSchristos static void 11388585484eSchristos be_openssl_outbuf_cb(struct evbuffer *buf, 11398585484eSchristos const struct evbuffer_cb_info *cbinfo, void *arg) 11408585484eSchristos { 11418585484eSchristos struct bufferevent_openssl *bev_ssl = arg; 11428585484eSchristos int r = 0; 11438585484eSchristos /* XXX need to hold a reference here. */ 11448585484eSchristos 11458585484eSchristos if (cbinfo->n_added && bev_ssl->state == BUFFEREVENT_SSL_OPEN) { 11468585484eSchristos if (cbinfo->orig_size == 0) 11478585484eSchristos r = bufferevent_add_event_(&bev_ssl->bev.bev.ev_write, 11488585484eSchristos &bev_ssl->bev.bev.timeout_write); 1149*eabc0478Schristos 1150*eabc0478Schristos if (bev_ssl->underlying) 11518585484eSchristos consider_writing(bev_ssl); 11528585484eSchristos } 11538585484eSchristos /* XXX Handle r < 0 */ 11548585484eSchristos (void)r; 11558585484eSchristos } 11568585484eSchristos 11578585484eSchristos 11588585484eSchristos static int 11598585484eSchristos be_openssl_enable(struct bufferevent *bev, short events) 11608585484eSchristos { 11618585484eSchristos struct bufferevent_openssl *bev_ssl = upcast(bev); 11628585484eSchristos int r1 = 0, r2 = 0; 11638585484eSchristos 11648585484eSchristos if (events & EV_READ) 11658585484eSchristos r1 = start_reading(bev_ssl); 11668585484eSchristos if (events & EV_WRITE) 11678585484eSchristos r2 = start_writing(bev_ssl); 11688585484eSchristos 11698585484eSchristos if (bev_ssl->underlying) { 11708585484eSchristos if (events & EV_READ) 11718585484eSchristos BEV_RESET_GENERIC_READ_TIMEOUT(bev); 11728585484eSchristos if (events & EV_WRITE) 11738585484eSchristos BEV_RESET_GENERIC_WRITE_TIMEOUT(bev); 11748585484eSchristos 11758585484eSchristos if (events & EV_READ) 11768585484eSchristos consider_reading(bev_ssl); 11778585484eSchristos if (events & EV_WRITE) 11788585484eSchristos consider_writing(bev_ssl); 11798585484eSchristos } 11808585484eSchristos return (r1 < 0 || r2 < 0) ? -1 : 0; 11818585484eSchristos } 11828585484eSchristos 11838585484eSchristos static int 11848585484eSchristos be_openssl_disable(struct bufferevent *bev, short events) 11858585484eSchristos { 11868585484eSchristos struct bufferevent_openssl *bev_ssl = upcast(bev); 11878585484eSchristos 11888585484eSchristos if (events & EV_READ) 11898585484eSchristos stop_reading(bev_ssl); 11908585484eSchristos if (events & EV_WRITE) 11918585484eSchristos stop_writing(bev_ssl); 11928585484eSchristos 11938585484eSchristos if (bev_ssl->underlying) { 11948585484eSchristos if (events & EV_READ) 11958585484eSchristos BEV_DEL_GENERIC_READ_TIMEOUT(bev); 11968585484eSchristos if (events & EV_WRITE) 11978585484eSchristos BEV_DEL_GENERIC_WRITE_TIMEOUT(bev); 11988585484eSchristos } 11998585484eSchristos return 0; 12008585484eSchristos } 12018585484eSchristos 12028585484eSchristos static void 1203b8ecfcfeSchristos be_openssl_unlink(struct bufferevent *bev) 12048585484eSchristos { 12058585484eSchristos struct bufferevent_openssl *bev_ssl = upcast(bev); 12068585484eSchristos 12078585484eSchristos if (bev_ssl->bev.options & BEV_OPT_CLOSE_ON_FREE) { 12088585484eSchristos if (bev_ssl->underlying) { 12098585484eSchristos if (BEV_UPCAST(bev_ssl->underlying)->refcnt < 2) { 12108585484eSchristos event_warnx("BEV_OPT_CLOSE_ON_FREE set on an " 12118585484eSchristos "bufferevent with too few references"); 12128585484eSchristos } else { 12138585484eSchristos bufferevent_free(bev_ssl->underlying); 1214b8ecfcfeSchristos /* We still have a reference to it, via our 1215b8ecfcfeSchristos * BIO. So we don't drop this. */ 1216b8ecfcfeSchristos // bev_ssl->underlying = NULL; 12178585484eSchristos } 12188585484eSchristos } 12198585484eSchristos } else { 12208585484eSchristos if (bev_ssl->underlying) { 12218585484eSchristos if (bev_ssl->underlying->errorcb == be_openssl_eventcb) 12228585484eSchristos bufferevent_setcb(bev_ssl->underlying, 12238585484eSchristos NULL,NULL,NULL,NULL); 12248585484eSchristos bufferevent_unsuspend_read_(bev_ssl->underlying, 12258585484eSchristos BEV_SUSPEND_FILT_READ); 12268585484eSchristos } 12278585484eSchristos } 12288585484eSchristos } 12298585484eSchristos 1230b8ecfcfeSchristos static void 1231b8ecfcfeSchristos be_openssl_destruct(struct bufferevent *bev) 1232b8ecfcfeSchristos { 1233b8ecfcfeSchristos struct bufferevent_openssl *bev_ssl = upcast(bev); 1234b8ecfcfeSchristos 1235b8ecfcfeSchristos if (bev_ssl->bev.options & BEV_OPT_CLOSE_ON_FREE) { 1236b8ecfcfeSchristos if (! bev_ssl->underlying) { 1237*eabc0478Schristos evutil_socket_t fd = EVUTIL_INVALID_SOCKET; 1238b8ecfcfeSchristos BIO *bio = SSL_get_wbio(bev_ssl->ssl); 1239b8ecfcfeSchristos if (bio) 1240b8ecfcfeSchristos fd = BIO_get_fd(bio, NULL); 1241b8ecfcfeSchristos if (fd >= 0) 1242b8ecfcfeSchristos evutil_closesocket(fd); 1243b8ecfcfeSchristos } 1244b8ecfcfeSchristos SSL_free(bev_ssl->ssl); 1245b8ecfcfeSchristos } 1246b8ecfcfeSchristos } 1247b8ecfcfeSchristos 12488585484eSchristos static int 12498585484eSchristos be_openssl_adj_timeouts(struct bufferevent *bev) 12508585484eSchristos { 12518585484eSchristos struct bufferevent_openssl *bev_ssl = upcast(bev); 12528585484eSchristos 12538585484eSchristos if (bev_ssl->underlying) { 12548585484eSchristos return bufferevent_generic_adj_timeouts_(bev); 12558585484eSchristos } else { 1256*eabc0478Schristos return bufferevent_generic_adj_existing_timeouts_(bev); 12578585484eSchristos } 12588585484eSchristos } 12598585484eSchristos 12608585484eSchristos static int 12618585484eSchristos be_openssl_flush(struct bufferevent *bufev, 12628585484eSchristos short iotype, enum bufferevent_flush_mode mode) 12638585484eSchristos { 12648585484eSchristos /* XXXX Implement this. */ 12658585484eSchristos return 0; 12668585484eSchristos } 12678585484eSchristos 12688585484eSchristos static int 1269*eabc0478Schristos be_openssl_set_fd(struct bufferevent_openssl *bev_ssl, 1270*eabc0478Schristos enum bufferevent_ssl_state state, evutil_socket_t fd) 1271*eabc0478Schristos { 1272*eabc0478Schristos bev_ssl->state = state; 1273*eabc0478Schristos 1274*eabc0478Schristos switch (state) { 1275*eabc0478Schristos case BUFFEREVENT_SSL_ACCEPTING: 1276*eabc0478Schristos if (!SSL_clear(bev_ssl->ssl)) 1277*eabc0478Schristos return -1; 1278*eabc0478Schristos SSL_set_accept_state(bev_ssl->ssl); 1279*eabc0478Schristos if (set_handshake_callbacks(bev_ssl, fd) < 0) 1280*eabc0478Schristos return -1; 1281*eabc0478Schristos break; 1282*eabc0478Schristos case BUFFEREVENT_SSL_CONNECTING: 1283*eabc0478Schristos if (!SSL_clear(bev_ssl->ssl)) 1284*eabc0478Schristos return -1; 1285*eabc0478Schristos SSL_set_connect_state(bev_ssl->ssl); 1286*eabc0478Schristos if (set_handshake_callbacks(bev_ssl, fd) < 0) 1287*eabc0478Schristos return -1; 1288*eabc0478Schristos break; 1289*eabc0478Schristos case BUFFEREVENT_SSL_OPEN: 1290*eabc0478Schristos if (set_open_callbacks(bev_ssl, fd) < 0) 1291*eabc0478Schristos return -1; 1292*eabc0478Schristos break; 1293*eabc0478Schristos default: 1294*eabc0478Schristos return -1; 1295*eabc0478Schristos } 1296*eabc0478Schristos 1297*eabc0478Schristos return 0; 1298*eabc0478Schristos } 1299*eabc0478Schristos 1300*eabc0478Schristos static int 13018585484eSchristos be_openssl_ctrl(struct bufferevent *bev, 13028585484eSchristos enum bufferevent_ctrl_op op, union bufferevent_ctrl_data *data) 13038585484eSchristos { 13048585484eSchristos struct bufferevent_openssl *bev_ssl = upcast(bev); 13058585484eSchristos switch (op) { 13068585484eSchristos case BEV_CTRL_SET_FD: 1307*eabc0478Schristos if (!bev_ssl->underlying) { 13088585484eSchristos BIO *bio; 1309*eabc0478Schristos bio = BIO_new_socket((int)data->fd, 0); 13108585484eSchristos SSL_set_bio(bev_ssl->ssl, bio, bio); 1311*eabc0478Schristos } else { 1312*eabc0478Schristos BIO *bio; 1313*eabc0478Schristos if (!(bio = BIO_new_bufferevent(bev_ssl->underlying))) 1314*eabc0478Schristos return -1; 1315*eabc0478Schristos SSL_set_bio(bev_ssl->ssl, bio, bio); 13168585484eSchristos } 1317*eabc0478Schristos 1318*eabc0478Schristos return be_openssl_set_fd(bev_ssl, bev_ssl->old_state, data->fd); 13198585484eSchristos case BEV_CTRL_GET_FD: 1320*eabc0478Schristos if (bev_ssl->underlying) { 1321*eabc0478Schristos data->fd = event_get_fd(&bev_ssl->underlying->ev_read); 1322*eabc0478Schristos } else { 13238585484eSchristos data->fd = event_get_fd(&bev->ev_read); 1324*eabc0478Schristos } 13258585484eSchristos return 0; 13268585484eSchristos case BEV_CTRL_GET_UNDERLYING: 13278585484eSchristos data->ptr = bev_ssl->underlying; 13288585484eSchristos return 0; 13298585484eSchristos case BEV_CTRL_CANCEL_ALL: 13308585484eSchristos default: 13318585484eSchristos return -1; 13328585484eSchristos } 13338585484eSchristos } 13348585484eSchristos 13358585484eSchristos SSL * 13368585484eSchristos bufferevent_openssl_get_ssl(struct bufferevent *bufev) 13378585484eSchristos { 13388585484eSchristos struct bufferevent_openssl *bev_ssl = upcast(bufev); 13398585484eSchristos if (!bev_ssl) 13408585484eSchristos return NULL; 13418585484eSchristos return bev_ssl->ssl; 13428585484eSchristos } 13438585484eSchristos 13448585484eSchristos static struct bufferevent * 13458585484eSchristos bufferevent_openssl_new_impl(struct event_base *base, 13468585484eSchristos struct bufferevent *underlying, 13478585484eSchristos evutil_socket_t fd, 13488585484eSchristos SSL *ssl, 13498585484eSchristos enum bufferevent_ssl_state state, 13508585484eSchristos int options) 13518585484eSchristos { 13528585484eSchristos struct bufferevent_openssl *bev_ssl = NULL; 13538585484eSchristos struct bufferevent_private *bev_p = NULL; 13548585484eSchristos int tmp_options = options & ~BEV_OPT_THREADSAFE; 13558585484eSchristos 1356*eabc0478Schristos /* Only one can be set. */ 13578585484eSchristos if (underlying != NULL && fd >= 0) 1358*eabc0478Schristos goto err; 13598585484eSchristos 13608585484eSchristos if (!(bev_ssl = mm_calloc(1, sizeof(struct bufferevent_openssl)))) 13618585484eSchristos goto err; 13628585484eSchristos 13638585484eSchristos bev_p = &bev_ssl->bev; 13648585484eSchristos 13658585484eSchristos if (bufferevent_init_common_(bev_p, base, 13668585484eSchristos &bufferevent_ops_openssl, tmp_options) < 0) 13678585484eSchristos goto err; 13688585484eSchristos 13698585484eSchristos /* Don't explode if we decide to realloc a chunk we're writing from in 13708585484eSchristos * the output buffer. */ 13718585484eSchristos SSL_set_mode(ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); 13728585484eSchristos 13738585484eSchristos bev_ssl->underlying = underlying; 13748585484eSchristos bev_ssl->ssl = ssl; 13758585484eSchristos 13768585484eSchristos bev_ssl->outbuf_cb = evbuffer_add_cb(bev_p->bev.output, 13778585484eSchristos be_openssl_outbuf_cb, bev_ssl); 13788585484eSchristos 13798585484eSchristos if (options & BEV_OPT_THREADSAFE) 13808585484eSchristos bufferevent_enable_locking_(&bev_ssl->bev.bev, NULL); 13818585484eSchristos 13828585484eSchristos if (underlying) { 13838585484eSchristos bufferevent_init_generic_timeout_cbs_(&bev_ssl->bev.bev); 13848585484eSchristos bufferevent_incref_(underlying); 13858585484eSchristos } 13868585484eSchristos 1387*eabc0478Schristos bev_ssl->old_state = state; 13888585484eSchristos bev_ssl->last_write = -1; 13898585484eSchristos 13908585484eSchristos init_bio_counts(bev_ssl); 13918585484eSchristos 1392*eabc0478Schristos fd = be_openssl_auto_fd(bev_ssl, fd); 1393*eabc0478Schristos if (be_openssl_set_fd(bev_ssl, state, fd)) 13948585484eSchristos goto err; 13958585484eSchristos 13968585484eSchristos if (underlying) { 13978585484eSchristos bufferevent_setwatermark(underlying, EV_READ, 0, 0); 13988585484eSchristos bufferevent_enable(underlying, EV_READ|EV_WRITE); 13998585484eSchristos if (state == BUFFEREVENT_SSL_OPEN) 14008585484eSchristos bufferevent_suspend_read_(underlying, 14018585484eSchristos BEV_SUSPEND_FILT_READ); 14028585484eSchristos } 14038585484eSchristos 14048585484eSchristos return &bev_ssl->bev.bev; 14058585484eSchristos err: 1406*eabc0478Schristos if (options & BEV_OPT_CLOSE_ON_FREE) 1407*eabc0478Schristos SSL_free(ssl); 1408*eabc0478Schristos if (bev_ssl) { 1409*eabc0478Schristos bev_ssl->ssl = NULL; 14108585484eSchristos bufferevent_free(&bev_ssl->bev.bev); 1411*eabc0478Schristos } 14128585484eSchristos return NULL; 14138585484eSchristos } 14148585484eSchristos 14158585484eSchristos struct bufferevent * 14168585484eSchristos bufferevent_openssl_filter_new(struct event_base *base, 14178585484eSchristos struct bufferevent *underlying, 14188585484eSchristos SSL *ssl, 14198585484eSchristos enum bufferevent_ssl_state state, 14208585484eSchristos int options) 14218585484eSchristos { 14228585484eSchristos BIO *bio; 1423*eabc0478Schristos struct bufferevent *bev; 1424*eabc0478Schristos 14258585484eSchristos if (!underlying) 1426*eabc0478Schristos goto err; 1427*eabc0478Schristos if (!(bio = BIO_new_bufferevent(underlying))) 1428*eabc0478Schristos goto err; 14298585484eSchristos 14308585484eSchristos SSL_set_bio(ssl, bio, bio); 14318585484eSchristos 1432*eabc0478Schristos bev = bufferevent_openssl_new_impl( 14338585484eSchristos base, underlying, -1, ssl, state, options); 1434*eabc0478Schristos return bev; 1435*eabc0478Schristos 1436*eabc0478Schristos err: 1437*eabc0478Schristos if (options & BEV_OPT_CLOSE_ON_FREE) 1438*eabc0478Schristos SSL_free(ssl); 1439*eabc0478Schristos return NULL; 14408585484eSchristos } 14418585484eSchristos 14428585484eSchristos struct bufferevent * 14438585484eSchristos bufferevent_openssl_socket_new(struct event_base *base, 14448585484eSchristos evutil_socket_t fd, 14458585484eSchristos SSL *ssl, 14468585484eSchristos enum bufferevent_ssl_state state, 14478585484eSchristos int options) 14488585484eSchristos { 14498585484eSchristos /* Does the SSL already have an fd? */ 14508585484eSchristos BIO *bio = SSL_get_wbio(ssl); 14518585484eSchristos long have_fd = -1; 14528585484eSchristos 14538585484eSchristos if (bio) 14548585484eSchristos have_fd = BIO_get_fd(bio, NULL); 14558585484eSchristos 14568585484eSchristos if (have_fd >= 0) { 14578585484eSchristos /* The SSL is already configured with an fd. */ 14588585484eSchristos if (fd < 0) { 14598585484eSchristos /* We should learn the fd from the SSL. */ 14608585484eSchristos fd = (evutil_socket_t) have_fd; 14618585484eSchristos } else if (have_fd == (long)fd) { 14628585484eSchristos /* We already know the fd from the SSL; do nothing */ 14638585484eSchristos } else { 14648585484eSchristos /* We specified an fd different from that of the SSL. 14658585484eSchristos This is probably an error on our part. Fail. */ 1466*eabc0478Schristos goto err; 14678585484eSchristos } 1468*eabc0478Schristos BIO_set_close(bio, 0); 14698585484eSchristos } else { 14708585484eSchristos /* The SSL isn't configured with a BIO with an fd. */ 14718585484eSchristos if (fd >= 0) { 14728585484eSchristos /* ... and we have an fd we want to use. */ 1473*eabc0478Schristos bio = BIO_new_socket((int)fd, 0); 14748585484eSchristos SSL_set_bio(ssl, bio, bio); 14758585484eSchristos } else { 14768585484eSchristos /* Leave the fd unset. */ 14778585484eSchristos } 14788585484eSchristos } 14798585484eSchristos 14808585484eSchristos return bufferevent_openssl_new_impl( 14818585484eSchristos base, NULL, fd, ssl, state, options); 1482*eabc0478Schristos 1483*eabc0478Schristos err: 1484*eabc0478Schristos if (options & BEV_OPT_CLOSE_ON_FREE) 1485*eabc0478Schristos SSL_free(ssl); 1486*eabc0478Schristos return NULL; 14878585484eSchristos } 14888585484eSchristos 14898585484eSchristos int 14908585484eSchristos bufferevent_openssl_get_allow_dirty_shutdown(struct bufferevent *bev) 14918585484eSchristos { 14928585484eSchristos int allow_dirty_shutdown = -1; 14938585484eSchristos struct bufferevent_openssl *bev_ssl; 14948585484eSchristos BEV_LOCK(bev); 14958585484eSchristos bev_ssl = upcast(bev); 14968585484eSchristos if (bev_ssl) 14978585484eSchristos allow_dirty_shutdown = bev_ssl->allow_dirty_shutdown; 14988585484eSchristos BEV_UNLOCK(bev); 14998585484eSchristos return allow_dirty_shutdown; 15008585484eSchristos } 15018585484eSchristos 15028585484eSchristos void 15038585484eSchristos bufferevent_openssl_set_allow_dirty_shutdown(struct bufferevent *bev, 15048585484eSchristos int allow_dirty_shutdown) 15058585484eSchristos { 15068585484eSchristos struct bufferevent_openssl *bev_ssl; 15078585484eSchristos BEV_LOCK(bev); 15088585484eSchristos bev_ssl = upcast(bev); 15098585484eSchristos if (bev_ssl) 15108585484eSchristos bev_ssl->allow_dirty_shutdown = !!allow_dirty_shutdown; 15118585484eSchristos BEV_UNLOCK(bev); 15128585484eSchristos } 15138585484eSchristos 15148585484eSchristos unsigned long 15158585484eSchristos bufferevent_get_openssl_error(struct bufferevent *bev) 15168585484eSchristos { 15178585484eSchristos unsigned long err = 0; 15188585484eSchristos struct bufferevent_openssl *bev_ssl; 15198585484eSchristos BEV_LOCK(bev); 15208585484eSchristos bev_ssl = upcast(bev); 15218585484eSchristos if (bev_ssl && bev_ssl->n_errors) { 15228585484eSchristos err = bev_ssl->errors[--bev_ssl->n_errors]; 15238585484eSchristos } 15248585484eSchristos BEV_UNLOCK(bev); 15258585484eSchristos return err; 15268585484eSchristos } 1527