summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2020-03-13 10:37:06 +0100
committerJo-Philipp Wich <jo@mein.io>2020-05-06 19:44:09 +0200
commit40b563b1ea89dabb2b6cd90644908134a0c8eff2 (patch)
tree6401fcd312ee0c1ef1d0f548920a9413656dd208
parent30cebb4fc78e49e0432a404f7c9dd8c9a93b3cc3 (diff)
downloadustream-ssl-openwrt-19.07.tar.gz
ustream-openssl: clear error stack before SSL_read/SSL_writeopenwrt-19.07
The OpenSSL library uses a global error queue per thread which needs to be cleared prior to calling I/O functions in order to get reliable error results. Failure to do so will lead to stray errors reported by SSL_get_error() when an unrelated connection within the same thread encountered a TLS error since the last SSL_read() or SSL_write() on the current connection. This issue was frequently triggered by Google Chrome which usually initiates simultaneous TLS connections (presumably for protocol support probing) and subsequently closes most of them with a "certificate unknown" TLS error, causing the next SSL_get_error() to report an SSL library error instead of the expected SSL_WANT_READ or SSL_WANT_WRITE error states. Solve this issue by invoking ERR_clear_error() prior to invoking SSL_read() or SSL_write() to ensure that the subsequent SSL_get_error() returns current valid results. Signed-off-by: Jo-Philipp Wich <jo@mein.io> (cherry picked from commit 5e1bc3429cbf9c3be4db65ef5dbf21ea99cf5b95)
-rw-r--r--ustream-openssl.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/ustream-openssl.c b/ustream-openssl.c
index 1469473..fa99e67 100644
--- a/ustream-openssl.c
+++ b/ustream-openssl.c
@@ -256,6 +256,8 @@ __hidden enum ssl_conn_status __ustream_ssl_connect(struct ustream_ssl *us)
void *ssl = us->ssl;
int r;
+ ERR_clear_error();
+
if (us->server)
r = SSL_accept(ssl);
else
@@ -277,7 +279,11 @@ __hidden enum ssl_conn_status __ustream_ssl_connect(struct ustream_ssl *us)
__hidden int __ustream_ssl_write(struct ustream_ssl *us, const char *buf, int len)
{
void *ssl = us->ssl;
- int ret = SSL_write(ssl, buf, len);
+ int ret;
+
+ ERR_clear_error();
+
+ ret = SSL_write(ssl, buf, len);
if (ret < 0) {
int err = SSL_get_error(ssl, ret);
@@ -293,7 +299,11 @@ __hidden int __ustream_ssl_write(struct ustream_ssl *us, const char *buf, int le
__hidden int __ustream_ssl_read(struct ustream_ssl *us, char *buf, int len)
{
- int ret = SSL_read(us->ssl, buf, len);
+ int ret;
+
+ ERR_clear_error();
+
+ ret = SSL_read(us->ssl, buf, len);
if (ret < 0) {
ret = SSL_get_error(us->ssl, ret);