diff options
author | Jo-Philipp Wich <jo@mein.io> | 2020-03-13 10:37:06 +0100 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2020-03-13 12:05:11 +0100 |
commit | 5e1bc3429cbf9c3be4db65ef5dbf21ea99cf5b95 (patch) | |
tree | 9bf611e96263e32c800162c979ce5e1a1d5cd32d | |
parent | f7f93addafb8a2a45c601d9cffe249eb6c73de23 (diff) | |
download | ustream-ssl-5e1bc3429cbf9c3be4db65ef5dbf21ea99cf5b95.tar.gz |
ustream-openssl: clear error stack before SSL_read/SSL_write
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>
-rw-r--r-- | ustream-openssl.c | 14 |
1 files 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); else @@ -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); |