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

(cherry picked from commit c6c74ce2652fd02527a1212e36cbfd788962132a)
This commit is contained in:
David Benjamin 2017-04-20 18:03:50 -04:00 committed by Azat Khuzhin
parent 56faf02bae
commit 29b7a516fd
No known key found for this signature in database
GPG Key ID: B86086848EF8686D

View File

@ -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;