diff options
author | Leorize <leorize+oss@disroot.org> | 2020-06-03 15:11:10 -0500 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2020-06-06 21:11:53 +0200 |
commit | 6cb94b5da6ac409915cc0ca3f50c50214edee0ef (patch) | |
tree | ec13cf8be68c3b9dc543aac813a978948a7c0e0e /lib | |
parent | f243f9aeb5c5ef6f59efadbee81feb918a20fae8 (diff) | |
download | Nim-6cb94b5da6ac409915cc0ca3f50c50214edee0ef.tar.gz |
asyncnet, net: clear openssl error queue before performing I/O
Per SSL_get_error(3): The current thread's error queue must be empty before the TLS/SSL I/O operation is attempted, or SSL_get_error() will not work reliably. There has been records of not clearing the error queue causing weird SSL errors when there shouldn't be any, see: https://github.com/openssl/openssl/issues/11889
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pure/asyncnet.nim | 1 | ||||
-rw-r--r-- | lib/pure/net.nim | 7 |
2 files changed, 8 insertions, 0 deletions
diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim index 8df839c14..bd9cd4312 100644 --- a/lib/pure/asyncnet.nim +++ b/lib/pure/asyncnet.nim @@ -718,6 +718,7 @@ proc close*(socket: AsyncSocket) = # established, see: # https://github.com/openssl/openssl/issues/710#issuecomment-253897666 if SSL_in_init(socket.sslHandle) == 0: + ErrClearError() SSL_shutdown(socket.sslHandle) else: 0 diff --git a/lib/pure/net.nim b/lib/pure/net.nim index c60caab08..af66c3a15 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -752,12 +752,14 @@ when defineSsl: # Discard result in case OpenSSL version doesn't support SNI, or we're # not using TLSv1+ discard SSL_set_tlsext_host_name(socket.sslHandle, hostname) + ErrClearError() let ret = SSL_connect(socket.sslHandle) socketError(socket, ret) when not defined(nimDisableCertificateValidation) and not defined(windows): if hostname.len > 0 and not isIpAddress(hostname): socket.checkCertName(hostname) of handshakeAsServer: + ErrClearError() let ret = SSL_accept(socket.sslHandle) socketError(socket, ret) @@ -926,6 +928,7 @@ proc acceptAddr*(server: Socket, client: var owned(Socket), address: var string, # We must wrap the client sock in a ssl context. server.sslContext.wrapSocket(client) + ErrClearError() let ret = SSL_accept(client.sslHandle) socketError(client, ret, false) @@ -955,6 +958,7 @@ when false: #defineSsl: if not client.isSsl or client.sslHandle == nil: server.sslContext.wrapSocket(client) + ErrClearError() let ret = SSL_accept(client.sslHandle) while ret <= 0: let err = SSL_get_error(client.sslHandle, ret) @@ -1135,6 +1139,7 @@ proc uniRecv(socket: Socket, buffer: pointer, size, flags: cint): int = assert(not socket.isClosed, "Cannot `recv` on a closed socket") when defineSsl: if socket.isSsl: + ErrClearError() return SSL_read(socket.sslHandle, buffer, size) return recv(socket.fd, buffer, size, flags) @@ -1484,6 +1489,7 @@ proc send*(socket: Socket, data: pointer, size: int): int {. assert(not socket.isClosed, "Cannot `send` on a closed socket") when defineSsl: if socket.isSsl: + ErrClearError() return SSL_write(socket.sslHandle, cast[cstring](data), size) when useWinVersion or defined(macosx): @@ -1768,6 +1774,7 @@ proc connect*(socket: Socket, address: string, # not using TLSv1+ discard SSL_set_tlsext_host_name(socket.sslHandle, address) + ErrClearError() let ret = SSL_connect(socket.sslHandle) socketError(socket, ret) when not defined(nimDisableCertificateValidation) and not defined(windows): |