summaryrefslogtreecommitdiff
path: root/bufferevent_openssl.c
diff options
context:
space:
mode:
authorDavid Benjamin <davidben@google.com>2017-04-20 18:03:50 -0400
committerDavid Benjamin <davidben@google.com>2017-04-21 19:19:04 -0400
commitc6c74ce2652fd02527a1212e36cbfd788962132a (patch)
treeb5861eda09dc6dc731d75309a753bff36b81f56e /bufferevent_openssl.c
parent92cc0b9c3db38088f79c5d1e432c429fbc366968 (diff)
downloadlibevent-c6c74ce2652fd02527a1212e36cbfd788962132a.tar.gz
Explicitly call SSL_clear when reseting the fd.
If reconnecting the via BEV_CTRL_SET_FD, bufferevent_openssl.c expects OpenSSL to reuse the configuration state in the SSL object but retain connection state. This corresponds to the SSL_clear API. The code currently only calls SSL_set_connect_state or SSL_set_accept_state. Due to a quirk in OpenSSL, doing this causes the handshake to implicitly SSL_clear the next time it is entered. However, this, in the intervening time, leaves the SSL object in an odd state as the connection state has not been dropped yet. This behavior also does not appear to be documented by OpenSSL. Instead, call SSL_clear explicitly: https://www.openssl.org/docs/manmaster/man3/SSL_clear.html
Diffstat (limited to 'bufferevent_openssl.c')
-rw-r--r--bufferevent_openssl.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/bufferevent_openssl.c b/bufferevent_openssl.c
index 252627ec..f7f5c0f1 100644
--- a/bufferevent_openssl.c
+++ b/bufferevent_openssl.c
@@ -1267,11 +1267,15 @@ be_openssl_set_fd(struct bufferevent_openssl *bev_ssl,
switch (state) {
case BUFFEREVENT_SSL_ACCEPTING:
+ if (!SSL_clear(bev_ssl->ssl))
+ return -1;
SSL_set_accept_state(bev_ssl->ssl);
if (set_handshake_callbacks(bev_ssl, fd) < 0)
return -1;
break;
case BUFFEREVENT_SSL_CONNECTING:
+ if (!SSL_clear(bev_ssl->ssl))
+ return -1;
SSL_set_connect_state(bev_ssl->ssl);
if (set_handshake_callbacks(bev_ssl, fd) < 0)
return -1;