3

I'm seeing a weird issue when starting a TLS connection to any host. If I don't set any timeout on the socket, it works fine. If I do, it breaks before the timeout with a OpenSSL.SSL.WantReadError. For example if I set timeout to 100, it will break after a second anyway.

For now I use a workaround of setting a timeout on connection, but then removing it before the handshake. How can I fix this to respect the timeout instead?

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(2)

ctx = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_METHOD)
ctx.set_options(OpenSSL.SSL.OP_NO_SSLv2 | OpenSSL.SSL.OP_NO_SSLv3)
ctx.set_verify(OpenSSL.SSL.VERIFY_NONE, lambda _a, _b, _c, _d, _e: None)
conn = OpenSSL.SSL.Connection(ctx, s)
conn.set_tlsext_host_name(hostname.encode('utf-8'))
conn.connect((ip, port))

s.settimeout(None)

try:
    conn.do_handshake()
except OpenSSL.SSL.WantReadError:
    # this happens on every connection
viraptor
  • 33,322
  • 10
  • 107
  • 191
  • What happens if you set conn.setblocking(1) ? Check this [question](http://stackoverflow.com/questions/675130/tls-connection-with-timeouts-and-a-few-other-difficulties) for a detailed answer – Sreekumar R Oct 31 '14 at 09:18
  • @SreekumarR This doesn't seem to make sense here. From the docs: `s.setblocking(1) is equivalent to s.settimeout(None)`. This is not what I need. – viraptor Nov 03 '14 at 11:07
  • Also check WantReadError in the [openssl document](https://pythonhosted.org/pyOpenSSL/api/ssl.html) . Try using select() to make sure it is writable before calling do_handshake() – Sreekumar R Nov 03 '14 at 12:22
  • You're hitting a known Python + OpenSSL bug: https://github.com/pyca/pyopenssl/issues/168 – andres.riancho Apr 13 '18 at 12:50

1 Answers1

0

Solution:

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setblocking(1)
Son Nguyen
  • 195
  • 1
  • 10
  • 1
    While this code may answer the question, providing additional context regarding _how_ and/or _why_ it solves the problem would improve the answer's long-term value. – Dev-iL Mar 14 '17 at 17:21
  • Sockets are blocking by default. Also from documentation: `setblocking(True) is equivalent to settimeout(None)` - I do want timeout. – viraptor Mar 15 '17 at 00:34