Package: libpython3.5-minimal
Version: 3.5.4-2
Severity: normal

Dear Maintainer,

Trying to use the "ssl" module to connect to a server that only supports TLS 1.0 (confirmed by <https://www.ssllabs.com/ssltest>) leads to an error:

wraith:~$ python3
Python 3.5.4 (default, Aug 12 2017, 14:08:14) [GCC 7.1.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
import socket, ssl
host = "vc.csi.cam.ac.uk"
ctx = ssl.create_default_context()
ctx.wrap_socket(socket.create_connection((host, 443)), server_hostname=host)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.5/ssl.py", line 385, in wrap_socket
    _context=self)
  File "/usr/lib/python3.5/ssl.py", line 760, in __init__
    self.do_handshake()
  File "/usr/lib/python3.5/ssl.py", line 996, in do_handshake
    self._sslobj.do_handshake()
  File "/usr/lib/python3.5/ssl.py", line 641, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: VERSION_TOO_LOW] version too low (_ssl.c:719)

This does not happen in Python 3.4.2 on oldstable.

The obvious way to enable a deprecated protocol is to modify the context options as described in /usr/share/doc/python3.5-doc/html/library/ssl.html for SSLv3, but that doesn't work:

ctx.options &= ~ssl.OP_NO_TLSv1
ctx.wrap_socket(socket.create_connection((host, 443)), server_hostname=host)
Traceback (most recent call last):
...
ssl.SSLError: [SSL: VERSION_TOO_LOW] version too low (_ssl.c:719)

That's not surprising, since the default options don't include that flag:

ssl.create_default_context().options & ssl.OP_NO_TLSv1
0

The only way I've found to make the connection work is to use the deprecated PROTOCOL_TLSv1:

ctx = ssl.SSLContext(protocol=ssl.PROTOCOL_TLSv1)
ctx.wrap_socket(socket.create_connection((host, 443)), server_hostname=host)
<ssl.SSLSocket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, 
proto=6, laddr=('131.111.56.57', 43808), raddr=('131.111.9.13', 443)>

But that loses me all of the automatic security I get from create_default_context, so I have to re-enable certificate checking and perhaps disable some ciphers. It's also fragile as (if the documentation is to be believed) PROTOCOL_TLSv1 _only_ supports TLS 1.0, and not TLS 1.1 or TLS 1.2, so if the server is upgraded my code may surprisingly break, or at least not transparently upgrade to a newer TLS version.

At the very least, the documentation should be updated to describe this behaviour, but I think it would be better if it were possible to re-enable TLS 1.0 support by modifying a context returned by ssl.create_default_context() rather than by re-implementing it.

-- System Information:
Debian Release: buster/sid
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: i386 (i686)

Kernel: Linux 4.11.0-1-686-pae (SMP w/8 CPU cores)
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8), 
LANGUAGE=en_GB.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
Init: systemd (via /run/systemd/system)

Versions of packages libpython3.5-minimal depends on:
ii  libc6      2.24-17
ii  libssl1.1  1.1.0f-5

Versions of packages libpython3.5-minimal recommends:
ii  libpython3.5-stdlib  3.5.4-2

libpython3.5-minimal suggests no packages.

-- no debconf information

--
Ben Harris, University of Cambridge Information Services.

Reply via email to