[OpenWrt-Devel] [PATCH ustream-ssl] ustream-openssl: clear error stack before SSL_read/SSL_write

Jo-Philipp Wich jo at mein.io
Fri Mar 13 07:41:01 EDT 2020

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

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 at mein.io>
 ustream-openssl.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/ustream-openssl.c b/ustream-openssl.c
index 049aa40..f8e848d 100644
--- a/ustream-openssl.c
+++ b/ustream-openssl.c
@@ -266,6 +266,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);
@@ -287,7 +289,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);
@@ -303,7 +309,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);

openwrt-devel mailing list
openwrt-devel at lists.openwrt.org

More information about the openwrt-devel mailing list