xref: /netbsd-src/external/bsd/ntp/dist/sntp/libevent/bufferevent_openssl.c (revision eabc0478de71e4e011a5b4e0392741e01d491794)
1 /*	$NetBSD: bufferevent_openssl.c,v 1.7 2024/08/18 20:47:21 christos Exp $	*/
2 
3 /*
4  * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 // Get rid of OSX 10.7 and greater deprecation warnings.
30 #if defined(__APPLE__) && defined(__clang__)
31 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
32 #endif
33 
34 #include "event2/event-config.h"
35 #include "evconfig-private.h"
36 
37 #include <sys/types.h>
38 
39 #ifdef EVENT__HAVE_SYS_TIME_H
40 #include <sys/time.h>
41 #endif
42 
43 #include <errno.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #ifdef EVENT__HAVE_STDARG_H
48 #include <stdarg.h>
49 #endif
50 #ifdef EVENT__HAVE_UNISTD_H
51 #include <unistd.h>
52 #endif
53 
54 #ifdef _WIN32
55 #include <winsock2.h>
56 #endif
57 
58 #include "event2/bufferevent.h"
59 #include "event2/bufferevent_struct.h"
60 #include "event2/bufferevent_ssl.h"
61 #include "event2/buffer.h"
62 #include "event2/event.h"
63 
64 #include "mm-internal.h"
65 #include "bufferevent-internal.h"
66 #include "log-internal.h"
67 
68 #include <openssl/ssl.h>
69 #include <openssl/err.h>
70 #include "openssl-compat.h"
71 
72 /*
73  * Define an OpenSSL bio that targets a bufferevent.
74  */
75 
76 /* --------------------
77    A BIO is an OpenSSL abstraction that handles reading and writing data.  The
78    library will happily speak SSL over anything that implements a BIO
79    interface.
80 
81    Here we define a BIO implementation that directs its output to a
82    bufferevent.  We'll want to use this only when none of OpenSSL's built-in
83    IO mechanisms work for us.
84    -------------------- */
85 
86 /* every BIO type needs its own integer type value. */
87 #define BIO_TYPE_LIBEVENT 57
88 /* ???? Arguably, we should set BIO_TYPE_FILTER or BIO_TYPE_SOURCE_SINK on
89  * this. */
90 
91 #if 0
92 static void
93 print_err(int val)
94 {
95 	int err;
96 	printf("Error was %d\n", val);
97 
98 	while ((err = ERR_get_error())) {
99 		const char *msg = (const char*)ERR_reason_error_string(err);
100 		const char *lib = (const char*)ERR_lib_error_string(err);
101 		const char *func = (const char*)ERR_func_error_string(err);
102 
103 		printf("%s in %s %s\n", msg, lib, func);
104 	}
105 }
106 #else
107 #define print_err(v) ((void)0)
108 #endif
109 
110 /* Called to initialize a new BIO */
111 static int
112 bio_bufferevent_new(BIO *b)
113 {
114 	BIO_set_init(b, 0);
115 	BIO_set_data(b, NULL); /* We'll be putting the bufferevent in this field.*/
116 	return 1;
117 }
118 
119 /* Called to uninitialize the BIO. */
120 static int
121 bio_bufferevent_free(BIO *b)
122 {
123 	if (!b)
124 		return 0;
125 	if (BIO_get_shutdown(b)) {
126 		if (BIO_get_init(b) && BIO_get_data(b))
127 			bufferevent_free(BIO_get_data(b));
128 		BIO_free(b);
129 	}
130 	return 1;
131 }
132 
133 /* Called to extract data from the BIO. */
134 static int
135 bio_bufferevent_read(BIO *b, char *out, int outlen)
136 {
137 	int r = 0;
138 	struct evbuffer *input;
139 
140 	BIO_clear_retry_flags(b);
141 
142 	if (!out)
143 		return 0;
144 	if (!BIO_get_data(b))
145 		return -1;
146 
147 	input = bufferevent_get_input(BIO_get_data(b));
148 	if (evbuffer_get_length(input) == 0) {
149 		/* If there's no data to read, say so. */
150 		BIO_set_retry_read(b);
151 		return -1;
152 	} else {
153 		r = evbuffer_remove(input, out, outlen);
154 	}
155 
156 	return r;
157 }
158 
159 /* Called to write data into the BIO */
160 static int
161 bio_bufferevent_write(BIO *b, const char *in, int inlen)
162 {
163 	struct bufferevent *bufev = BIO_get_data(b);
164 	struct evbuffer *output;
165 	size_t outlen;
166 
167 	BIO_clear_retry_flags(b);
168 
169 	if (!BIO_get_data(b))
170 		return -1;
171 
172 	output = bufferevent_get_output(bufev);
173 	outlen = evbuffer_get_length(output);
174 
175 	/* Copy only as much data onto the output buffer as can fit under the
176 	 * high-water mark. */
177 	if (bufev->wm_write.high && bufev->wm_write.high <= (outlen+inlen)) {
178 		if (bufev->wm_write.high <= outlen) {
179 			/* If no data can fit, we'll need to retry later. */
180 			BIO_set_retry_write(b);
181 			return -1;
182 		}
183 		inlen = bufev->wm_write.high - outlen;
184 	}
185 
186 	EVUTIL_ASSERT(inlen > 0);
187 	evbuffer_add(output, in, inlen);
188 	return inlen;
189 }
190 
191 /* Called to handle various requests */
192 static long
193 bio_bufferevent_ctrl(BIO *b, int cmd, long num, void *ptr)
194 {
195 	struct bufferevent *bufev = BIO_get_data(b);
196 	long ret = 1;
197 
198 	switch (cmd) {
199 	case BIO_CTRL_GET_CLOSE:
200 		ret = BIO_get_shutdown(b);
201 		break;
202 	case BIO_CTRL_SET_CLOSE:
203 		BIO_set_shutdown(b, (int)num);
204 		break;
205 	case BIO_CTRL_PENDING:
206 		ret = evbuffer_get_length(bufferevent_get_input(bufev)) != 0;
207 		break;
208 	case BIO_CTRL_WPENDING:
209 		ret = evbuffer_get_length(bufferevent_get_output(bufev)) != 0;
210 		break;
211 	/* XXXX These two are given a special-case treatment because
212 	 * of cargo-cultism.  I should come up with a better reason. */
213 	case BIO_CTRL_DUP:
214 	case BIO_CTRL_FLUSH:
215 		ret = 1;
216 		break;
217 	default:
218 		ret = 0;
219 		break;
220 	}
221 	return ret;
222 }
223 
224 /* Called to write a string to the BIO */
225 static int
226 bio_bufferevent_puts(BIO *b, const char *s)
227 {
228 	return bio_bufferevent_write(b, s, strlen(s));
229 }
230 
231 /* Method table for the bufferevent BIO */
232 static BIO_METHOD *methods_bufferevent;
233 
234 /* Return the method table for the bufferevents BIO */
235 static BIO_METHOD *
236 BIO_s_bufferevent(void)
237 {
238 	if (methods_bufferevent == NULL) {
239 		methods_bufferevent = BIO_meth_new(BIO_TYPE_LIBEVENT, "bufferevent");
240 		if (methods_bufferevent == NULL)
241 			return NULL;
242 		BIO_meth_set_write(methods_bufferevent, bio_bufferevent_write);
243 		BIO_meth_set_read(methods_bufferevent, bio_bufferevent_read);
244 		BIO_meth_set_puts(methods_bufferevent, bio_bufferevent_puts);
245 		BIO_meth_set_ctrl(methods_bufferevent, bio_bufferevent_ctrl);
246 		BIO_meth_set_create(methods_bufferevent, bio_bufferevent_new);
247 		BIO_meth_set_destroy(methods_bufferevent, bio_bufferevent_free);
248 	}
249 	return methods_bufferevent;
250 }
251 
252 /* Create a new BIO to wrap communication around a bufferevent.  If close_flag
253  * is true, the bufferevent will be freed when the BIO is closed. */
254 static BIO *
255 BIO_new_bufferevent(struct bufferevent *bufferevent)
256 {
257 	BIO *result;
258 	if (!bufferevent)
259 		return NULL;
260 	if (!(result = BIO_new(BIO_s_bufferevent())))
261 		return NULL;
262 	BIO_set_init(result, 1);
263 	BIO_set_data(result, bufferevent);
264 	/* We don't tell the BIO to close the bufferevent; we do it ourselves on
265 	 * be_openssl_destruct() */
266 	BIO_set_shutdown(result, 0);
267 	return result;
268 }
269 
270 /* --------------------
271    Now, here's the OpenSSL-based implementation of bufferevent.
272 
273    The implementation comes in two flavors: one that connects its SSL object
274    to an underlying bufferevent using a BIO_bufferevent, and one that has the
275    SSL object connect to a socket directly.  The latter should generally be
276    faster, except on Windows, where your best bet is using a
277    bufferevent_async.
278 
279    (OpenSSL supports many other BIO types, too.  But we can't use any unless
280    we have a good way to get notified when they become readable/writable.)
281    -------------------- */
282 
283 struct bio_data_counts {
284 	unsigned long n_written;
285 	unsigned long n_read;
286 };
287 
288 struct bufferevent_openssl {
289 	/* Shared fields with common bufferevent implementation code.
290 	   If we were set up with an underlying bufferevent, we use the
291 	   events here as timers only.  If we have an SSL, then we use
292 	   the events as socket events.
293 	 */
294 	struct bufferevent_private bev;
295 	/* An underlying bufferevent that we're directing our output to.
296 	   If it's NULL, then we're connected to an fd, not an evbuffer. */
297 	struct bufferevent *underlying;
298 	/* The SSL object doing our encryption. */
299 	SSL *ssl;
300 
301 	/* A callback that's invoked when data arrives on our outbuf so we
302 	   know to write data to the SSL. */
303 	struct evbuffer_cb_entry *outbuf_cb;
304 
305 	/* A count of how much data the bios have read/written total.  Used
306 	   for rate-limiting. */
307 	struct bio_data_counts counts;
308 
309 	/* If this value is greater than 0, then the last SSL_write blocked,
310 	 * and we need to try it again with this many bytes. */
311 	ev_ssize_t last_write;
312 
313 #define NUM_ERRORS 3
314 	ev_uint32_t errors[NUM_ERRORS];
315 
316 	/* When we next get available space, we should say "read" instead of
317 	   "write". This can happen if there's a renegotiation during a read
318 	   operation. */
319 	unsigned read_blocked_on_write : 1;
320 	/* When we next get data, we should say "write" instead of "read". */
321 	unsigned write_blocked_on_read : 1;
322 	/* Treat TCP close before SSL close on SSL >= v3 as clean EOF. */
323 	unsigned allow_dirty_shutdown : 1;
324 	/* XXX */
325 	unsigned n_errors : 2;
326 
327 	/* Are we currently connecting, accepting, or doing IO? */
328 	unsigned state : 2;
329 	/* If we reset fd, we sould reset state too */
330 	unsigned old_state : 2;
331 };
332 
333 static int be_openssl_enable(struct bufferevent *, short);
334 static int be_openssl_disable(struct bufferevent *, short);
335 static void be_openssl_unlink(struct bufferevent *);
336 static void be_openssl_destruct(struct bufferevent *);
337 static int be_openssl_adj_timeouts(struct bufferevent *);
338 static int be_openssl_flush(struct bufferevent *bufev,
339     short iotype, enum bufferevent_flush_mode mode);
340 static int be_openssl_ctrl(struct bufferevent *, enum bufferevent_ctrl_op, union bufferevent_ctrl_data *);
341 
342 const struct bufferevent_ops bufferevent_ops_openssl = {
343 	"ssl",
344 	evutil_offsetof(struct bufferevent_openssl, bev.bev),
345 	be_openssl_enable,
346 	be_openssl_disable,
347 	be_openssl_unlink,
348 	be_openssl_destruct,
349 	be_openssl_adj_timeouts,
350 	be_openssl_flush,
351 	be_openssl_ctrl,
352 };
353 
354 /* Given a bufferevent, return a pointer to the bufferevent_openssl that
355  * contains it, if any. */
356 static inline struct bufferevent_openssl *
357 upcast(struct bufferevent *bev)
358 {
359 	struct bufferevent_openssl *bev_o;
360 	if (!BEV_IS_OPENSSL(bev))
361 		return NULL;
362 	bev_o = (void*)( ((char*)bev) -
363 			 evutil_offsetof(struct bufferevent_openssl, bev.bev));
364 	EVUTIL_ASSERT(BEV_IS_OPENSSL(&bev_o->bev.bev));
365 	return bev_o;
366 }
367 
368 static inline void
369 put_error(struct bufferevent_openssl *bev_ssl, unsigned long err)
370 {
371 	if (bev_ssl->n_errors == NUM_ERRORS)
372 		return;
373 	/* The error type according to openssl is "unsigned long", but
374 	   openssl never uses more than 32 bits of it.  It _can't_ use more
375 	   than 32 bits of it, since it needs to report errors on systems
376 	   where long is only 32 bits.
377 	 */
378 	bev_ssl->errors[bev_ssl->n_errors++] = (ev_uint32_t) err;
379 }
380 
381 /* Have the base communications channel (either the underlying bufferevent or
382  * ev_read and ev_write) start reading.  Take the read-blocked-on-write flag
383  * into account. */
384 static int
385 start_reading(struct bufferevent_openssl *bev_ssl)
386 {
387 	if (bev_ssl->underlying) {
388 		bufferevent_unsuspend_read_(bev_ssl->underlying,
389 		    BEV_SUSPEND_FILT_READ);
390 		return 0;
391 	} else {
392 		struct bufferevent *bev = &bev_ssl->bev.bev;
393 		int r;
394 		r = bufferevent_add_event_(&bev->ev_read, &bev->timeout_read);
395 		if (r == 0 && bev_ssl->read_blocked_on_write)
396 			r = bufferevent_add_event_(&bev->ev_write,
397 			    &bev->timeout_write);
398 		return r;
399 	}
400 }
401 
402 /* Have the base communications channel (either the underlying bufferevent or
403  * ev_read and ev_write) start writing.  Take the write-blocked-on-read flag
404  * into account. */
405 static int
406 start_writing(struct bufferevent_openssl *bev_ssl)
407 {
408 	int r = 0;
409 	if (bev_ssl->underlying) {
410 		if (bev_ssl->write_blocked_on_read) {
411 			bufferevent_unsuspend_read_(bev_ssl->underlying,
412 			    BEV_SUSPEND_FILT_READ);
413 		}
414 	} else {
415 		struct bufferevent *bev = &bev_ssl->bev.bev;
416 		r = bufferevent_add_event_(&bev->ev_write, &bev->timeout_write);
417 		if (!r && bev_ssl->write_blocked_on_read)
418 			r = bufferevent_add_event_(&bev->ev_read,
419 			    &bev->timeout_read);
420 	}
421 	return r;
422 }
423 
424 static void
425 stop_reading(struct bufferevent_openssl *bev_ssl)
426 {
427 	if (bev_ssl->write_blocked_on_read)
428 		return;
429 	if (bev_ssl->underlying) {
430 		bufferevent_suspend_read_(bev_ssl->underlying,
431 		    BEV_SUSPEND_FILT_READ);
432 	} else {
433 		struct bufferevent *bev = &bev_ssl->bev.bev;
434 		event_del(&bev->ev_read);
435 	}
436 }
437 
438 static void
439 stop_writing(struct bufferevent_openssl *bev_ssl)
440 {
441 	if (bev_ssl->read_blocked_on_write)
442 		return;
443 	if (bev_ssl->underlying) {
444 		bufferevent_unsuspend_read_(bev_ssl->underlying,
445 		    BEV_SUSPEND_FILT_READ);
446 	} else {
447 		struct bufferevent *bev = &bev_ssl->bev.bev;
448 		event_del(&bev->ev_write);
449 	}
450 }
451 
452 static int
453 set_rbow(struct bufferevent_openssl *bev_ssl)
454 {
455 	if (!bev_ssl->underlying)
456 		stop_reading(bev_ssl);
457 	bev_ssl->read_blocked_on_write = 1;
458 	return start_writing(bev_ssl);
459 }
460 
461 static int
462 set_wbor(struct bufferevent_openssl *bev_ssl)
463 {
464 	if (!bev_ssl->underlying)
465 		stop_writing(bev_ssl);
466 	bev_ssl->write_blocked_on_read = 1;
467 	return start_reading(bev_ssl);
468 }
469 
470 static int
471 clear_rbow(struct bufferevent_openssl *bev_ssl)
472 {
473 	struct bufferevent *bev = &bev_ssl->bev.bev;
474 	int r = 0;
475 	bev_ssl->read_blocked_on_write = 0;
476 	if (!(bev->enabled & EV_WRITE))
477 		stop_writing(bev_ssl);
478 	if (bev->enabled & EV_READ)
479 		r = start_reading(bev_ssl);
480 	return r;
481 }
482 
483 
484 static int
485 clear_wbor(struct bufferevent_openssl *bev_ssl)
486 {
487 	struct bufferevent *bev = &bev_ssl->bev.bev;
488 	int r = 0;
489 	bev_ssl->write_blocked_on_read = 0;
490 	if (!(bev->enabled & EV_READ))
491 		stop_reading(bev_ssl);
492 	if (bev->enabled & EV_WRITE)
493 		r = start_writing(bev_ssl);
494 	return r;
495 }
496 
497 static void
498 conn_closed(struct bufferevent_openssl *bev_ssl, int when, int errcode, int ret)
499 {
500 	int event = BEV_EVENT_ERROR;
501 	int dirty_shutdown = 0;
502 	unsigned long err;
503 
504 	switch (errcode) {
505 	case SSL_ERROR_ZERO_RETURN:
506 		/* Possibly a clean shutdown. */
507 		if (SSL_get_shutdown(bev_ssl->ssl) & SSL_RECEIVED_SHUTDOWN)
508 			event = BEV_EVENT_EOF;
509 		else
510 			dirty_shutdown = 1;
511 		break;
512 	case SSL_ERROR_SYSCALL:
513 		/* IO error; possibly a dirty shutdown. */
514 		if ((ret == 0 || ret == -1) && ERR_peek_error() == 0)
515 			dirty_shutdown = 1;
516 		put_error(bev_ssl, errcode);
517 		break;
518 	case SSL_ERROR_SSL:
519 		/* Protocol error. */
520 		put_error(bev_ssl, errcode);
521 		break;
522 	case SSL_ERROR_WANT_X509_LOOKUP:
523 		/* XXXX handle this. */
524 		put_error(bev_ssl, errcode);
525 		break;
526 	case SSL_ERROR_NONE:
527 	case SSL_ERROR_WANT_READ:
528 	case SSL_ERROR_WANT_WRITE:
529 	case SSL_ERROR_WANT_CONNECT:
530 	case SSL_ERROR_WANT_ACCEPT:
531 	default:
532 		/* should be impossible; treat as normal error. */
533 		event_warnx("BUG: Unexpected OpenSSL error code %d", errcode);
534 		break;
535 	}
536 
537 	while ((err = ERR_get_error())) {
538 		put_error(bev_ssl, err);
539 	}
540 
541 	if (dirty_shutdown && bev_ssl->allow_dirty_shutdown)
542 		event = BEV_EVENT_EOF;
543 
544 	stop_reading(bev_ssl);
545 	stop_writing(bev_ssl);
546 
547 	/* when is BEV_EVENT_{READING|WRITING} */
548 	event = when | event;
549 	bufferevent_run_eventcb_(&bev_ssl->bev.bev, event, 0);
550 }
551 
552 static void
553 init_bio_counts(struct bufferevent_openssl *bev_ssl)
554 {
555 	BIO *rbio, *wbio;
556 
557 	wbio = SSL_get_wbio(bev_ssl->ssl);
558 	bev_ssl->counts.n_written = wbio ? BIO_number_written(wbio) : 0;
559 	rbio = SSL_get_rbio(bev_ssl->ssl);
560 	bev_ssl->counts.n_read = rbio ? BIO_number_read(rbio) : 0;
561 }
562 
563 static inline void
564 decrement_buckets(struct bufferevent_openssl *bev_ssl)
565 {
566 	unsigned long num_w = BIO_number_written(SSL_get_wbio(bev_ssl->ssl));
567 	unsigned long num_r = BIO_number_read(SSL_get_rbio(bev_ssl->ssl));
568 	/* These next two subtractions can wrap around. That's okay. */
569 	unsigned long w = num_w - bev_ssl->counts.n_written;
570 	unsigned long r = num_r - bev_ssl->counts.n_read;
571 	if (w)
572 		bufferevent_decrement_write_buckets_(&bev_ssl->bev, w);
573 	if (r)
574 		bufferevent_decrement_read_buckets_(&bev_ssl->bev, r);
575 	bev_ssl->counts.n_written = num_w;
576 	bev_ssl->counts.n_read = num_r;
577 }
578 
579 #define OP_MADE_PROGRESS 1
580 #define OP_BLOCKED 2
581 #define OP_ERR 4
582 
583 /* Return a bitmask of OP_MADE_PROGRESS (if we read anything); OP_BLOCKED (if
584    we're now blocked); and OP_ERR (if an error occurred). */
585 static int
586 do_read(struct bufferevent_openssl *bev_ssl, int n_to_read) {
587 	/* Requires lock */
588 	struct bufferevent *bev = &bev_ssl->bev.bev;
589 	struct evbuffer *input = bev->input;
590 	int r, n, i, n_used = 0, atmost;
591 	struct evbuffer_iovec space[2];
592 	int result = 0;
593 
594 	if (bev_ssl->bev.read_suspended)
595 		return 0;
596 
597 	atmost = bufferevent_get_read_max_(&bev_ssl->bev);
598 	if (n_to_read > atmost)
599 		n_to_read = atmost;
600 
601 	n = evbuffer_reserve_space(input, n_to_read, space, 2);
602 	if (n < 0)
603 		return OP_ERR;
604 
605 	for (i=0; i<n; ++i) {
606 		if (bev_ssl->bev.read_suspended)
607 			break;
608 		ERR_clear_error();
609 		r = SSL_read(bev_ssl->ssl, space[i].iov_base, space[i].iov_len);
610 		if (r>0) {
611 			result |= OP_MADE_PROGRESS;
612 			if (bev_ssl->read_blocked_on_write)
613 				if (clear_rbow(bev_ssl) < 0)
614 					return OP_ERR | result;
615 			++n_used;
616 			space[i].iov_len = r;
617 			decrement_buckets(bev_ssl);
618 		} else {
619 			int err = SSL_get_error(bev_ssl->ssl, r);
620 			print_err(err);
621 			switch (err) {
622 			case SSL_ERROR_WANT_READ:
623 				/* Can't read until underlying has more data. */
624 				if (bev_ssl->read_blocked_on_write)
625 					if (clear_rbow(bev_ssl) < 0)
626 						return OP_ERR | result;
627 				break;
628 			case SSL_ERROR_WANT_WRITE:
629 				/* This read operation requires a write, and the
630 				 * underlying is full */
631 				if (!bev_ssl->read_blocked_on_write)
632 					if (set_rbow(bev_ssl) < 0)
633 						return OP_ERR | result;
634 				break;
635 			default:
636 				conn_closed(bev_ssl, BEV_EVENT_READING, err, r);
637 				break;
638 			}
639 			result |= OP_BLOCKED;
640 			break; /* out of the loop */
641 		}
642 	}
643 
644 	if (n_used) {
645 		evbuffer_commit_space(input, space, n_used);
646 		if (bev_ssl->underlying)
647 			BEV_RESET_GENERIC_READ_TIMEOUT(bev);
648 	}
649 
650 	return result;
651 }
652 
653 /* Return a bitmask of OP_MADE_PROGRESS (if we wrote anything); OP_BLOCKED (if
654    we're now blocked); and OP_ERR (if an error occurred). */
655 static int
656 do_write(struct bufferevent_openssl *bev_ssl, int atmost)
657 {
658 	int i, r, n, n_written = 0;
659 	struct bufferevent *bev = &bev_ssl->bev.bev;
660 	struct evbuffer *output = bev->output;
661 	struct evbuffer_iovec space[8];
662 	int result = 0;
663 
664 	if (bev_ssl->last_write > 0)
665 		atmost = bev_ssl->last_write;
666 	else
667 		atmost = bufferevent_get_write_max_(&bev_ssl->bev);
668 
669 	n = evbuffer_peek(output, atmost, NULL, space, 8);
670 	if (n < 0)
671 		return OP_ERR | result;
672 
673 	if (n > 8)
674 		n = 8;
675 	for (i=0; i < n; ++i) {
676 		if (bev_ssl->bev.write_suspended)
677 			break;
678 
679 		/* SSL_write will (reasonably) return 0 if we tell it to
680 		   send 0 data.  Skip this case so we don't interpret the
681 		   result as an error */
682 		if (space[i].iov_len == 0)
683 			continue;
684 
685 		ERR_clear_error();
686 		r = SSL_write(bev_ssl->ssl, space[i].iov_base,
687 		    space[i].iov_len);
688 		if (r > 0) {
689 			result |= OP_MADE_PROGRESS;
690 			if (bev_ssl->write_blocked_on_read)
691 				if (clear_wbor(bev_ssl) < 0)
692 					return OP_ERR | result;
693 			n_written += r;
694 			bev_ssl->last_write = -1;
695 			decrement_buckets(bev_ssl);
696 		} else {
697 			int err = SSL_get_error(bev_ssl->ssl, r);
698 			print_err(err);
699 			switch (err) {
700 			case SSL_ERROR_WANT_WRITE:
701 				/* Can't read until underlying has more data. */
702 				if (bev_ssl->write_blocked_on_read)
703 					if (clear_wbor(bev_ssl) < 0)
704 						return OP_ERR | result;
705 				bev_ssl->last_write = space[i].iov_len;
706 				break;
707 			case SSL_ERROR_WANT_READ:
708 				/* This read operation requires a write, and the
709 				 * underlying is full */
710 				if (!bev_ssl->write_blocked_on_read)
711 					if (set_wbor(bev_ssl) < 0)
712 						return OP_ERR | result;
713 				bev_ssl->last_write = space[i].iov_len;
714 				break;
715 			default:
716 				conn_closed(bev_ssl, BEV_EVENT_WRITING, err, r);
717 				bev_ssl->last_write = -1;
718 				break;
719 			}
720 			result |= OP_BLOCKED;
721 			break;
722 		}
723 	}
724 	if (n_written) {
725 		evbuffer_drain(output, n_written);
726 		if (bev_ssl->underlying)
727 			BEV_RESET_GENERIC_WRITE_TIMEOUT(bev);
728 
729 		bufferevent_trigger_nolock_(bev, EV_WRITE, BEV_OPT_DEFER_CALLBACKS);
730 	}
731 	return result;
732 }
733 
734 #define WRITE_FRAME 15000
735 
736 #define READ_DEFAULT 4096
737 
738 /* Try to figure out how many bytes to read; return 0 if we shouldn't be
739  * reading. */
740 static int
741 bytes_to_read(struct bufferevent_openssl *bev)
742 {
743 	struct evbuffer *input = bev->bev.bev.input;
744 	struct event_watermark *wm = &bev->bev.bev.wm_read;
745 	int result = READ_DEFAULT;
746 	ev_ssize_t limit;
747 	/* XXX 99% of this is generic code that nearly all bufferevents will
748 	 * want. */
749 
750 	if (bev->write_blocked_on_read) {
751 		return 0;
752 	}
753 
754 	if (! (bev->bev.bev.enabled & EV_READ)) {
755 		return 0;
756 	}
757 
758 	if (bev->bev.read_suspended) {
759 		return 0;
760 	}
761 
762 	if (wm->high) {
763 		if (evbuffer_get_length(input) >= wm->high) {
764 			return 0;
765 		}
766 
767 		result = wm->high - evbuffer_get_length(input);
768 	} else {
769 		result = READ_DEFAULT;
770 	}
771 
772 	/* Respect the rate limit */
773 	limit = bufferevent_get_read_max_(&bev->bev);
774 	if (result > limit) {
775 		result = limit;
776 	}
777 
778 	return result;
779 }
780 
781 
782 /* Things look readable.  If write is blocked on read, write till it isn't.
783  * Read from the underlying buffer until we block or we hit our high-water
784  * mark.
785  */
786 static void
787 consider_reading(struct bufferevent_openssl *bev_ssl)
788 {
789 	int r;
790 	int n_to_read;
791 	int all_result_flags = 0;
792 
793 	while (bev_ssl->write_blocked_on_read) {
794 		r = do_write(bev_ssl, WRITE_FRAME);
795 		if (r & (OP_BLOCKED|OP_ERR))
796 			break;
797 	}
798 	if (bev_ssl->write_blocked_on_read)
799 		return;
800 
801 	n_to_read = bytes_to_read(bev_ssl);
802 
803 	while (n_to_read) {
804 		r = do_read(bev_ssl, n_to_read);
805 		all_result_flags |= r;
806 
807 		if (r & (OP_BLOCKED|OP_ERR))
808 			break;
809 
810 		if (bev_ssl->bev.read_suspended)
811 			break;
812 
813 		/* Read all pending data.  This won't hit the network
814 		 * again, and will (most importantly) put us in a state
815 		 * where we don't need to read anything else until the
816 		 * socket is readable again.  It'll potentially make us
817 		 * overrun our read high-watermark (somewhat
818 		 * regrettable).  The damage to the rate-limit has
819 		 * already been done, since OpenSSL went and read a
820 		 * whole SSL record anyway. */
821 		n_to_read = SSL_pending(bev_ssl->ssl);
822 
823 		/* XXX This if statement is actually a bad bug, added to avoid
824 		 * XXX a worse bug.
825 		 *
826 		 * The bad bug: It can potentially cause resource unfairness
827 		 * by reading too much data from the underlying bufferevent;
828 		 * it can potentially cause read looping if the underlying
829 		 * bufferevent is a bufferevent_pair and deferred callbacks
830 		 * aren't used.
831 		 *
832 		 * The worse bug: If we didn't do this, then we would
833 		 * potentially not read any more from bev_ssl->underlying
834 		 * until more data arrived there, which could lead to us
835 		 * waiting forever.
836 		 */
837 		if (!n_to_read && bev_ssl->underlying)
838 			n_to_read = bytes_to_read(bev_ssl);
839 	}
840 
841 	if (all_result_flags & OP_MADE_PROGRESS) {
842 		struct bufferevent *bev = &bev_ssl->bev.bev;
843 
844 		bufferevent_trigger_nolock_(bev, EV_READ, 0);
845 	}
846 
847 	if (!bev_ssl->underlying) {
848 		/* Should be redundant, but let's avoid busy-looping */
849 		if (bev_ssl->bev.read_suspended ||
850 		    !(bev_ssl->bev.bev.enabled & EV_READ)) {
851 			event_del(&bev_ssl->bev.bev.ev_read);
852 		}
853 	}
854 }
855 
856 static void
857 consider_writing(struct bufferevent_openssl *bev_ssl)
858 {
859 	int r;
860 	struct evbuffer *output = bev_ssl->bev.bev.output;
861 	struct evbuffer *target = NULL;
862 	struct event_watermark *wm = NULL;
863 
864 	while (bev_ssl->read_blocked_on_write) {
865 		r = do_read(bev_ssl, 1024); /* XXXX 1024 is a hack */
866 		if (r & OP_MADE_PROGRESS) {
867 			struct bufferevent *bev = &bev_ssl->bev.bev;
868 
869 			bufferevent_trigger_nolock_(bev, EV_READ, 0);
870 		}
871 		if (r & (OP_ERR|OP_BLOCKED))
872 			break;
873 	}
874 	if (bev_ssl->read_blocked_on_write)
875 		return;
876 	if (bev_ssl->underlying) {
877 		target = bev_ssl->underlying->output;
878 		wm = &bev_ssl->underlying->wm_write;
879 	}
880 	while ((bev_ssl->bev.bev.enabled & EV_WRITE) &&
881 	    (! bev_ssl->bev.write_suspended) &&
882 	    evbuffer_get_length(output) &&
883 	    (!target || (! wm->high || evbuffer_get_length(target) < wm->high))) {
884 		int n_to_write;
885 		if (wm && wm->high)
886 			n_to_write = wm->high - evbuffer_get_length(target);
887 		else
888 			n_to_write = WRITE_FRAME;
889 		r = do_write(bev_ssl, n_to_write);
890 		if (r & (OP_BLOCKED|OP_ERR))
891 			break;
892 	}
893 
894 	if (!bev_ssl->underlying) {
895 		if (evbuffer_get_length(output) == 0) {
896 			event_del(&bev_ssl->bev.bev.ev_write);
897 		} else if (bev_ssl->bev.write_suspended ||
898 		    !(bev_ssl->bev.bev.enabled & EV_WRITE)) {
899 			/* Should be redundant, but let's avoid busy-looping */
900 			event_del(&bev_ssl->bev.bev.ev_write);
901 		}
902 	}
903 }
904 
905 static void
906 be_openssl_readcb(struct bufferevent *bev_base, void *ctx)
907 {
908 	struct bufferevent_openssl *bev_ssl = ctx;
909 	consider_reading(bev_ssl);
910 }
911 
912 static void
913 be_openssl_writecb(struct bufferevent *bev_base, void *ctx)
914 {
915 	struct bufferevent_openssl *bev_ssl = ctx;
916 	consider_writing(bev_ssl);
917 }
918 
919 static void
920 be_openssl_eventcb(struct bufferevent *bev_base, short what, void *ctx)
921 {
922 	struct bufferevent_openssl *bev_ssl = ctx;
923 	int event = 0;
924 
925 	if (what & BEV_EVENT_EOF) {
926 		if (bev_ssl->allow_dirty_shutdown)
927 			event = BEV_EVENT_EOF;
928 		else
929 			event = BEV_EVENT_ERROR;
930 	} else if (what & BEV_EVENT_TIMEOUT) {
931 		/* We sure didn't set this.  Propagate it to the user. */
932 		event = what;
933 	} else if (what & BEV_EVENT_ERROR) {
934 		/* An error occurred on the connection.  Propagate it to the user. */
935 		event = what;
936 	} else if (what & BEV_EVENT_CONNECTED) {
937 		/* Ignore it.  We're saying SSL_connect() already, which will
938 		   eat it. */
939 	}
940 	if (event)
941 		bufferevent_run_eventcb_(&bev_ssl->bev.bev, event, 0);
942 }
943 
944 static void
945 be_openssl_readeventcb(evutil_socket_t fd, short what, void *ptr)
946 {
947 	struct bufferevent_openssl *bev_ssl = ptr;
948 	bufferevent_incref_and_lock_(&bev_ssl->bev.bev);
949 	if (what == EV_TIMEOUT) {
950 		bufferevent_run_eventcb_(&bev_ssl->bev.bev,
951 		    BEV_EVENT_TIMEOUT|BEV_EVENT_READING, 0);
952 	} else {
953 		consider_reading(bev_ssl);
954 	}
955 	bufferevent_decref_and_unlock_(&bev_ssl->bev.bev);
956 }
957 
958 static void
959 be_openssl_writeeventcb(evutil_socket_t fd, short what, void *ptr)
960 {
961 	struct bufferevent_openssl *bev_ssl = ptr;
962 	bufferevent_incref_and_lock_(&bev_ssl->bev.bev);
963 	if (what == EV_TIMEOUT) {
964 		bufferevent_run_eventcb_(&bev_ssl->bev.bev,
965 		    BEV_EVENT_TIMEOUT|BEV_EVENT_WRITING, 0);
966 	} else {
967 		consider_writing(bev_ssl);
968 	}
969 	bufferevent_decref_and_unlock_(&bev_ssl->bev.bev);
970 }
971 
972 static evutil_socket_t
973 be_openssl_auto_fd(struct bufferevent_openssl *bev_ssl, evutil_socket_t fd)
974 {
975 	if (!bev_ssl->underlying) {
976 		struct bufferevent *bev = &bev_ssl->bev.bev;
977 		if (event_initialized(&bev->ev_read) && fd < 0) {
978 			fd = event_get_fd(&bev->ev_read);
979 		}
980 	}
981 	return fd;
982 }
983 
984 static int
985 set_open_callbacks(struct bufferevent_openssl *bev_ssl, evutil_socket_t fd)
986 {
987 	if (bev_ssl->underlying) {
988 		bufferevent_setcb(bev_ssl->underlying,
989 		    be_openssl_readcb, be_openssl_writecb, be_openssl_eventcb,
990 		    bev_ssl);
991 		return 0;
992 	} else {
993 		struct bufferevent *bev = &bev_ssl->bev.bev;
994 		int rpending=0, wpending=0, r1=0, r2=0;
995 
996 		if (event_initialized(&bev->ev_read)) {
997 			rpending = event_pending(&bev->ev_read, EV_READ, NULL);
998 			wpending = event_pending(&bev->ev_write, EV_WRITE, NULL);
999 
1000 			event_del(&bev->ev_read);
1001 			event_del(&bev->ev_write);
1002 		}
1003 
1004 		event_assign(&bev->ev_read, bev->ev_base, fd,
1005 		    EV_READ|EV_PERSIST|EV_FINALIZE,
1006 		    be_openssl_readeventcb, bev_ssl);
1007 		event_assign(&bev->ev_write, bev->ev_base, fd,
1008 		    EV_WRITE|EV_PERSIST|EV_FINALIZE,
1009 		    be_openssl_writeeventcb, bev_ssl);
1010 
1011 		if (rpending)
1012 			r1 = bufferevent_add_event_(&bev->ev_read, &bev->timeout_read);
1013 		if (wpending)
1014 			r2 = bufferevent_add_event_(&bev->ev_write, &bev->timeout_write);
1015 
1016 		return (r1<0 || r2<0) ? -1 : 0;
1017 	}
1018 }
1019 
1020 static int
1021 do_handshake(struct bufferevent_openssl *bev_ssl)
1022 {
1023 	int r;
1024 
1025 	switch (bev_ssl->state) {
1026 	default:
1027 	case BUFFEREVENT_SSL_OPEN:
1028 		EVUTIL_ASSERT(0);
1029 		return -1;
1030 	case BUFFEREVENT_SSL_CONNECTING:
1031 	case BUFFEREVENT_SSL_ACCEPTING:
1032 		ERR_clear_error();
1033 		r = SSL_do_handshake(bev_ssl->ssl);
1034 		break;
1035 	}
1036 	decrement_buckets(bev_ssl);
1037 
1038 	if (r==1) {
1039 		evutil_socket_t fd = event_get_fd(&bev_ssl->bev.bev.ev_read);
1040 		/* We're done! */
1041 		bev_ssl->state = BUFFEREVENT_SSL_OPEN;
1042 		set_open_callbacks(bev_ssl, fd); /* XXXX handle failure */
1043 		/* Call do_read and do_write as needed */
1044 		bufferevent_enable(&bev_ssl->bev.bev, bev_ssl->bev.bev.enabled);
1045 		bufferevent_run_eventcb_(&bev_ssl->bev.bev,
1046 		    BEV_EVENT_CONNECTED, 0);
1047 		return 1;
1048 	} else {
1049 		int err = SSL_get_error(bev_ssl->ssl, r);
1050 		print_err(err);
1051 		switch (err) {
1052 		case SSL_ERROR_WANT_WRITE:
1053 			stop_reading(bev_ssl);
1054 			return start_writing(bev_ssl);
1055 		case SSL_ERROR_WANT_READ:
1056 			stop_writing(bev_ssl);
1057 			return start_reading(bev_ssl);
1058 		default:
1059 			conn_closed(bev_ssl, BEV_EVENT_READING, err, r);
1060 			return -1;
1061 		}
1062 	}
1063 }
1064 
1065 static void
1066 be_openssl_handshakecb(struct bufferevent *bev_base, void *ctx)
1067 {
1068 	struct bufferevent_openssl *bev_ssl = ctx;
1069 	do_handshake(bev_ssl);/* XXX handle failure */
1070 }
1071 
1072 static void
1073 be_openssl_handshakeeventcb(evutil_socket_t fd, short what, void *ptr)
1074 {
1075 	struct bufferevent_openssl *bev_ssl = ptr;
1076 
1077 	bufferevent_incref_and_lock_(&bev_ssl->bev.bev);
1078 	if (what & EV_TIMEOUT) {
1079 		bufferevent_run_eventcb_(&bev_ssl->bev.bev, BEV_EVENT_TIMEOUT, 0);
1080 	} else
1081 		do_handshake(bev_ssl);/* XXX handle failure */
1082 	bufferevent_decref_and_unlock_(&bev_ssl->bev.bev);
1083 }
1084 
1085 static int
1086 set_handshake_callbacks(struct bufferevent_openssl *bev_ssl, evutil_socket_t fd)
1087 {
1088 	if (bev_ssl->underlying) {
1089 		bufferevent_setcb(bev_ssl->underlying,
1090 		    be_openssl_handshakecb, be_openssl_handshakecb,
1091 		    be_openssl_eventcb,
1092 		    bev_ssl);
1093 
1094 		if (fd < 0)
1095 			return 0;
1096 
1097 		if (bufferevent_setfd(bev_ssl->underlying, fd))
1098 			return 1;
1099 
1100 		return do_handshake(bev_ssl);
1101 	} else {
1102 		struct bufferevent *bev = &bev_ssl->bev.bev;
1103 
1104 		if (event_initialized(&bev->ev_read)) {
1105 			event_del(&bev->ev_read);
1106 			event_del(&bev->ev_write);
1107 		}
1108 
1109 		event_assign(&bev->ev_read, bev->ev_base, fd,
1110 		    EV_READ|EV_PERSIST|EV_FINALIZE,
1111 		    be_openssl_handshakeeventcb, bev_ssl);
1112 		event_assign(&bev->ev_write, bev->ev_base, fd,
1113 		    EV_WRITE|EV_PERSIST|EV_FINALIZE,
1114 		    be_openssl_handshakeeventcb, bev_ssl);
1115 		if (fd >= 0)
1116 			bufferevent_enable(bev, bev->enabled);
1117 		return 0;
1118 	}
1119 }
1120 
1121 int
1122 bufferevent_ssl_renegotiate(struct bufferevent *bev)
1123 {
1124 	struct bufferevent_openssl *bev_ssl = upcast(bev);
1125 	if (!bev_ssl)
1126 		return -1;
1127 	if (SSL_renegotiate(bev_ssl->ssl) < 0)
1128 		return -1;
1129 	bev_ssl->state = BUFFEREVENT_SSL_CONNECTING;
1130 	if (set_handshake_callbacks(bev_ssl, be_openssl_auto_fd(bev_ssl, -1)) < 0)
1131 		return -1;
1132 	if (!bev_ssl->underlying)
1133 		return do_handshake(bev_ssl);
1134 	return 0;
1135 }
1136 
1137 static void
1138 be_openssl_outbuf_cb(struct evbuffer *buf,
1139     const struct evbuffer_cb_info *cbinfo, void *arg)
1140 {
1141 	struct bufferevent_openssl *bev_ssl = arg;
1142 	int r = 0;
1143 	/* XXX need to hold a reference here. */
1144 
1145 	if (cbinfo->n_added && bev_ssl->state == BUFFEREVENT_SSL_OPEN) {
1146 		if (cbinfo->orig_size == 0)
1147 			r = bufferevent_add_event_(&bev_ssl->bev.bev.ev_write,
1148 			    &bev_ssl->bev.bev.timeout_write);
1149 
1150 		if (bev_ssl->underlying)
1151 			consider_writing(bev_ssl);
1152 	}
1153 	/* XXX Handle r < 0 */
1154 	(void)r;
1155 }
1156 
1157 
1158 static int
1159 be_openssl_enable(struct bufferevent *bev, short events)
1160 {
1161 	struct bufferevent_openssl *bev_ssl = upcast(bev);
1162 	int r1 = 0, r2 = 0;
1163 
1164 	if (events & EV_READ)
1165 		r1 = start_reading(bev_ssl);
1166 	if (events & EV_WRITE)
1167 		r2 = start_writing(bev_ssl);
1168 
1169 	if (bev_ssl->underlying) {
1170 		if (events & EV_READ)
1171 			BEV_RESET_GENERIC_READ_TIMEOUT(bev);
1172 		if (events & EV_WRITE)
1173 			BEV_RESET_GENERIC_WRITE_TIMEOUT(bev);
1174 
1175 		if (events & EV_READ)
1176 			consider_reading(bev_ssl);
1177 		if (events & EV_WRITE)
1178 			consider_writing(bev_ssl);
1179 	}
1180 	return (r1 < 0 || r2 < 0) ? -1 : 0;
1181 }
1182 
1183 static int
1184 be_openssl_disable(struct bufferevent *bev, short events)
1185 {
1186 	struct bufferevent_openssl *bev_ssl = upcast(bev);
1187 
1188 	if (events & EV_READ)
1189 		stop_reading(bev_ssl);
1190 	if (events & EV_WRITE)
1191 		stop_writing(bev_ssl);
1192 
1193 	if (bev_ssl->underlying) {
1194 		if (events & EV_READ)
1195 			BEV_DEL_GENERIC_READ_TIMEOUT(bev);
1196 		if (events & EV_WRITE)
1197 			BEV_DEL_GENERIC_WRITE_TIMEOUT(bev);
1198 	}
1199 	return 0;
1200 }
1201 
1202 static void
1203 be_openssl_unlink(struct bufferevent *bev)
1204 {
1205 	struct bufferevent_openssl *bev_ssl = upcast(bev);
1206 
1207 	if (bev_ssl->bev.options & BEV_OPT_CLOSE_ON_FREE) {
1208 		if (bev_ssl->underlying) {
1209 			if (BEV_UPCAST(bev_ssl->underlying)->refcnt < 2) {
1210 				event_warnx("BEV_OPT_CLOSE_ON_FREE set on an "
1211 				    "bufferevent with too few references");
1212 			} else {
1213 				bufferevent_free(bev_ssl->underlying);
1214 				/* We still have a reference to it, via our
1215 				 * BIO. So we don't drop this. */
1216 				// bev_ssl->underlying = NULL;
1217 			}
1218 		}
1219 	} else {
1220 		if (bev_ssl->underlying) {
1221 			if (bev_ssl->underlying->errorcb == be_openssl_eventcb)
1222 				bufferevent_setcb(bev_ssl->underlying,
1223 				    NULL,NULL,NULL,NULL);
1224 			bufferevent_unsuspend_read_(bev_ssl->underlying,
1225 			    BEV_SUSPEND_FILT_READ);
1226 		}
1227 	}
1228 }
1229 
1230 static void
1231 be_openssl_destruct(struct bufferevent *bev)
1232 {
1233 	struct bufferevent_openssl *bev_ssl = upcast(bev);
1234 
1235 	if (bev_ssl->bev.options & BEV_OPT_CLOSE_ON_FREE) {
1236 		if (! bev_ssl->underlying) {
1237 			evutil_socket_t fd = EVUTIL_INVALID_SOCKET;
1238 			BIO *bio = SSL_get_wbio(bev_ssl->ssl);
1239 			if (bio)
1240 				fd = BIO_get_fd(bio, NULL);
1241 			if (fd >= 0)
1242 				evutil_closesocket(fd);
1243 		}
1244 		SSL_free(bev_ssl->ssl);
1245 	}
1246 }
1247 
1248 static int
1249 be_openssl_adj_timeouts(struct bufferevent *bev)
1250 {
1251 	struct bufferevent_openssl *bev_ssl = upcast(bev);
1252 
1253 	if (bev_ssl->underlying) {
1254 		return bufferevent_generic_adj_timeouts_(bev);
1255 	} else {
1256 		return bufferevent_generic_adj_existing_timeouts_(bev);
1257 	}
1258 }
1259 
1260 static int
1261 be_openssl_flush(struct bufferevent *bufev,
1262     short iotype, enum bufferevent_flush_mode mode)
1263 {
1264 	/* XXXX Implement this. */
1265 	return 0;
1266 }
1267 
1268 static int
1269 be_openssl_set_fd(struct bufferevent_openssl *bev_ssl,
1270     enum bufferevent_ssl_state state, evutil_socket_t fd)
1271 {
1272 	bev_ssl->state = state;
1273 
1274 	switch (state) {
1275 	case BUFFEREVENT_SSL_ACCEPTING:
1276 		if (!SSL_clear(bev_ssl->ssl))
1277 			return -1;
1278 		SSL_set_accept_state(bev_ssl->ssl);
1279 		if (set_handshake_callbacks(bev_ssl, fd) < 0)
1280 			return -1;
1281 		break;
1282 	case BUFFEREVENT_SSL_CONNECTING:
1283 		if (!SSL_clear(bev_ssl->ssl))
1284 			return -1;
1285 		SSL_set_connect_state(bev_ssl->ssl);
1286 		if (set_handshake_callbacks(bev_ssl, fd) < 0)
1287 			return -1;
1288 		break;
1289 	case BUFFEREVENT_SSL_OPEN:
1290 		if (set_open_callbacks(bev_ssl, fd) < 0)
1291 			return -1;
1292 		break;
1293 	default:
1294 		return -1;
1295 	}
1296 
1297 	return 0;
1298 }
1299 
1300 static int
1301 be_openssl_ctrl(struct bufferevent *bev,
1302     enum bufferevent_ctrl_op op, union bufferevent_ctrl_data *data)
1303 {
1304 	struct bufferevent_openssl *bev_ssl = upcast(bev);
1305 	switch (op) {
1306 	case BEV_CTRL_SET_FD:
1307 		if (!bev_ssl->underlying) {
1308 			BIO *bio;
1309 			bio = BIO_new_socket((int)data->fd, 0);
1310 			SSL_set_bio(bev_ssl->ssl, bio, bio);
1311 		} else {
1312 			BIO *bio;
1313 			if (!(bio = BIO_new_bufferevent(bev_ssl->underlying)))
1314 				return -1;
1315 			SSL_set_bio(bev_ssl->ssl, bio, bio);
1316 		}
1317 
1318 		return be_openssl_set_fd(bev_ssl, bev_ssl->old_state, data->fd);
1319 	case BEV_CTRL_GET_FD:
1320 		if (bev_ssl->underlying) {
1321 			data->fd = event_get_fd(&bev_ssl->underlying->ev_read);
1322 		} else {
1323 			data->fd = event_get_fd(&bev->ev_read);
1324 		}
1325 		return 0;
1326 	case BEV_CTRL_GET_UNDERLYING:
1327 		data->ptr = bev_ssl->underlying;
1328 		return 0;
1329 	case BEV_CTRL_CANCEL_ALL:
1330 	default:
1331 		return -1;
1332 	}
1333 }
1334 
1335 SSL *
1336 bufferevent_openssl_get_ssl(struct bufferevent *bufev)
1337 {
1338 	struct bufferevent_openssl *bev_ssl = upcast(bufev);
1339 	if (!bev_ssl)
1340 		return NULL;
1341 	return bev_ssl->ssl;
1342 }
1343 
1344 static struct bufferevent *
1345 bufferevent_openssl_new_impl(struct event_base *base,
1346     struct bufferevent *underlying,
1347     evutil_socket_t fd,
1348     SSL *ssl,
1349     enum bufferevent_ssl_state state,
1350     int options)
1351 {
1352 	struct bufferevent_openssl *bev_ssl = NULL;
1353 	struct bufferevent_private *bev_p = NULL;
1354 	int tmp_options = options & ~BEV_OPT_THREADSAFE;
1355 
1356 	/* Only one can be set. */
1357 	if (underlying != NULL && fd >= 0)
1358 		goto err;
1359 
1360 	if (!(bev_ssl = mm_calloc(1, sizeof(struct bufferevent_openssl))))
1361 		goto err;
1362 
1363 	bev_p = &bev_ssl->bev;
1364 
1365 	if (bufferevent_init_common_(bev_p, base,
1366 		&bufferevent_ops_openssl, tmp_options) < 0)
1367 		goto err;
1368 
1369 	/* Don't explode if we decide to realloc a chunk we're writing from in
1370 	 * the output buffer. */
1371 	SSL_set_mode(ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
1372 
1373 	bev_ssl->underlying = underlying;
1374 	bev_ssl->ssl = ssl;
1375 
1376 	bev_ssl->outbuf_cb = evbuffer_add_cb(bev_p->bev.output,
1377 	    be_openssl_outbuf_cb, bev_ssl);
1378 
1379 	if (options & BEV_OPT_THREADSAFE)
1380 		bufferevent_enable_locking_(&bev_ssl->bev.bev, NULL);
1381 
1382 	if (underlying) {
1383 		bufferevent_init_generic_timeout_cbs_(&bev_ssl->bev.bev);
1384 		bufferevent_incref_(underlying);
1385 	}
1386 
1387 	bev_ssl->old_state = state;
1388 	bev_ssl->last_write = -1;
1389 
1390 	init_bio_counts(bev_ssl);
1391 
1392 	fd = be_openssl_auto_fd(bev_ssl, fd);
1393 	if (be_openssl_set_fd(bev_ssl, state, fd))
1394 		goto err;
1395 
1396 	if (underlying) {
1397 		bufferevent_setwatermark(underlying, EV_READ, 0, 0);
1398 		bufferevent_enable(underlying, EV_READ|EV_WRITE);
1399 		if (state == BUFFEREVENT_SSL_OPEN)
1400 			bufferevent_suspend_read_(underlying,
1401 			    BEV_SUSPEND_FILT_READ);
1402 	}
1403 
1404 	return &bev_ssl->bev.bev;
1405 err:
1406 	if (options & BEV_OPT_CLOSE_ON_FREE)
1407 		SSL_free(ssl);
1408 	if (bev_ssl) {
1409 		bev_ssl->ssl = NULL;
1410 		bufferevent_free(&bev_ssl->bev.bev);
1411 	}
1412 	return NULL;
1413 }
1414 
1415 struct bufferevent *
1416 bufferevent_openssl_filter_new(struct event_base *base,
1417     struct bufferevent *underlying,
1418     SSL *ssl,
1419     enum bufferevent_ssl_state state,
1420     int options)
1421 {
1422 	BIO *bio;
1423 	struct bufferevent *bev;
1424 
1425 	if (!underlying)
1426 		goto err;
1427 	if (!(bio = BIO_new_bufferevent(underlying)))
1428 		goto err;
1429 
1430 	SSL_set_bio(ssl, bio, bio);
1431 
1432 	bev = bufferevent_openssl_new_impl(
1433 		base, underlying, -1, ssl, state, options);
1434 	return bev;
1435 
1436 err:
1437 	if (options & BEV_OPT_CLOSE_ON_FREE)
1438 		SSL_free(ssl);
1439 	return NULL;
1440 }
1441 
1442 struct bufferevent *
1443 bufferevent_openssl_socket_new(struct event_base *base,
1444     evutil_socket_t fd,
1445     SSL *ssl,
1446     enum bufferevent_ssl_state state,
1447     int options)
1448 {
1449 	/* Does the SSL already have an fd? */
1450 	BIO *bio = SSL_get_wbio(ssl);
1451 	long have_fd = -1;
1452 
1453 	if (bio)
1454 		have_fd = BIO_get_fd(bio, NULL);
1455 
1456 	if (have_fd >= 0) {
1457 		/* The SSL is already configured with an fd. */
1458 		if (fd < 0) {
1459 			/* We should learn the fd from the SSL. */
1460 			fd = (evutil_socket_t) have_fd;
1461 		} else if (have_fd == (long)fd) {
1462 			/* We already know the fd from the SSL; do nothing */
1463 		} else {
1464 			/* We specified an fd different from that of the SSL.
1465 			   This is probably an error on our part.  Fail. */
1466 			goto err;
1467 		}
1468 		BIO_set_close(bio, 0);
1469 	} else {
1470 		/* The SSL isn't configured with a BIO with an fd. */
1471 		if (fd >= 0) {
1472 			/* ... and we have an fd we want to use. */
1473 			bio = BIO_new_socket((int)fd, 0);
1474 			SSL_set_bio(ssl, bio, bio);
1475 		} else {
1476 			/* Leave the fd unset. */
1477 		}
1478 	}
1479 
1480 	return bufferevent_openssl_new_impl(
1481 		base, NULL, fd, ssl, state, options);
1482 
1483 err:
1484 	if (options & BEV_OPT_CLOSE_ON_FREE)
1485 		SSL_free(ssl);
1486 	return NULL;
1487 }
1488 
1489 int
1490 bufferevent_openssl_get_allow_dirty_shutdown(struct bufferevent *bev)
1491 {
1492 	int allow_dirty_shutdown = -1;
1493 	struct bufferevent_openssl *bev_ssl;
1494 	BEV_LOCK(bev);
1495 	bev_ssl = upcast(bev);
1496 	if (bev_ssl)
1497 		allow_dirty_shutdown = bev_ssl->allow_dirty_shutdown;
1498 	BEV_UNLOCK(bev);
1499 	return allow_dirty_shutdown;
1500 }
1501 
1502 void
1503 bufferevent_openssl_set_allow_dirty_shutdown(struct bufferevent *bev,
1504     int allow_dirty_shutdown)
1505 {
1506 	struct bufferevent_openssl *bev_ssl;
1507 	BEV_LOCK(bev);
1508 	bev_ssl = upcast(bev);
1509 	if (bev_ssl)
1510 		bev_ssl->allow_dirty_shutdown = !!allow_dirty_shutdown;
1511 	BEV_UNLOCK(bev);
1512 }
1513 
1514 unsigned long
1515 bufferevent_get_openssl_error(struct bufferevent *bev)
1516 {
1517 	unsigned long err = 0;
1518 	struct bufferevent_openssl *bev_ssl;
1519 	BEV_LOCK(bev);
1520 	bev_ssl = upcast(bev);
1521 	if (bev_ssl && bev_ssl->n_errors) {
1522 		err = bev_ssl->errors[--bev_ssl->n_errors];
1523 	}
1524 	BEV_UNLOCK(bev);
1525 	return err;
1526 }
1527