Joeri
Joeri

Reputation: 646

Python ssl unable to connect to TLS1.2 server with TLS1.2 client

I'm working on a python3 socket + ssl server to use for data exchange between a server and a client. I have made a client that works with Google.com, python.org and my own apache2 web server.

When I fire up my server and try to connect via open ssl with openssl s_client -connect myserver.com:8443 it returns:

    CONNECTED(00000003)
    140035580617152:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:../ssl/record/ssl3_record.c:252:
    ---
    no peer certificate available
    ---
    No client certificate CA names sent
    ---
    SSL handshake has read 5 bytes and written 176 bytes
    Verification: OK
    ---
    New, (NONE), Cipher is (NONE)
    Secure Renegotiation IS NOT supported
    Compression: NONE
    Expansion: NONE
    No ALPN negotiated
    SSL-Session:
        Protocol  : TLSv1.2
        Cipher    : 0000
        Session-ID: 
        Session-ID-ctx: 
        Master-Key: 
        PSK identity: None
        PSK identity hint: None
        SRP username: None
        Start Time: 1547929149
        Timeout   : 7200 (sec)
        Verify return code: 0 (ok)
        Extended master secret: no
    ---

I'm not sure about this but it looks like TLSv1.2 is supported. When I try to connect to it with my client though I get the following error

    Traceback (most recent call last):
      File "client-1.py", line 38, in <module>
        sock.connect((HOST, PORT))
      File "/usr/lib/python3.6/ssl.py", line 1109, in connect
        self._real_connect(addr, False)
      File "/usr/lib/python3.6/ssl.py", line 1100, in _real_connect
        self.do_handshake()
      File "/usr/lib/python3.6/ssl.py", line 1077, in do_handshake
        self._sslobj.do_handshake()
      File "/usr/lib/python3.6/ssl.py", line 689, in do_handshake
        self._sslobj.do_handshake()
    ssl.SSLError: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:847)

The weird part is then when I use my client to connect to, for example, my own apache2 server (with ssl) it returns TLSv1.2 which really makes me wonder whether the problem lies with my client or my server

I have already tried to use different TLS / SSL versions on the server and the client but none of then have worked so far. One of the other things I tried was updating OpenSSL and as of 1/19/2019 it is on the newest version available on Ubuntu 18.04

My server looks as follows

import socket
import sys
from _thread import *
import ssl

context = ssl.SSLContext()
ssl.PROTOCOL_TLS_SERVER
#context.load_cert_chain(certfile="ssl/localhost/localhost.crt", keyfile="ssl/localhost/localhost.key")
context.load_cert_chain(certfile="ssl/certificate.crt", keyfile="ssl/private.key")


host = ''
port = 8443
print(port)

buffer = 134217700 #128 MiB

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




def log_client_to_file(ip, port, data, file):
    #context manager
    with open(file, 'a') as f:
        f.write("User sent data from:\n\tIP: %s\n\tPort: %s\nData:\n%s\n\n" % (ip, port, data))

    #close file
    f.close()

def conn_process(buffer):
    data_tmp = conn.recv(buffer)
    data = str.encode('')
    while len(data_tmp) > 2:
        data += data_tmp
        data_tmp = conn.recv(buffer
        if len(data_tmp) < 2:
            data += data_tmp
            break
    return data

try:
    s.bind((host,port))
except socket.error as e:
    print(str(e))


s.listen(4)


print('Server is up and waiting for connection')
def client_threaded(conn, ip, port, file):
    conn.send(str.encode('Connected'))

    while True:

        data = conn_process(buffer)

        reply = 'Server output: %s' % data.decode('utf-8')
        if not data:
            break
        conn.sendall(str.encode(reply))
        log_client_to_file(ip, port, data, file)

while True:
    conn, addr = s.accept()
    print('connected to: %s:%s' % (addr[0], str(addr[1])))


    start_new_thread(client_threaded, (conn, addr[0], str(addr[1]), 'connections.log'))

s.close()


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

Now, my client is built up like this,

import socket
import ssl

HOST = 'myserver.com'
PORT = 8443


args = ssl.SSLContext()
ssl.PROTOCOL_TLS_CLIENT
args.verify_mode = ssl.CERT_NONE
args.check_hostname = False
#ssl.ca_certs="ssl/ca_bundle.crt",

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock = args.wrap_socket(s, server_hostname=HOST)

sock.connect((HOST, PORT))

print(sock.version())

Note: since I am working with self signed certificates for testing purposes I do not validate them yet

Since Both the client and the server use TLS I expected the connection not to be an issue, but I keep getting the aforementioned error, ssl.SSLError: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:847) which surprises me since I can't find any errors. Maybe you guys know what I am doing wrong and how I can fix it

Note, I am using python 3.6 and OpenSSL 1.1.0g 2 Nov 2017

Upvotes: 0

Views: 3238

Answers (1)

Steffen Ullrich
Steffen Ullrich

Reputation: 123541

I'm not sure about this but it looks like TLSv1.2 is supported.

No it doesn't.

... ssl3_get_record:wrong version number:../ssl/record/ssl3_record.c:252:
...
SSL handshake has read 5 bytes and written 176 bytes
...
   Protocol  : TLSv1.2
   Cipher    : 0000

This shows that the clients starts the TLS handshake with a ClientHello (176 bytes) and gets only 5 bytes back from the server, which is too short for the expected response inside the TLS handshake. And these 5 bytes don't contain a TLS version number and that's why it croaks with wrong version number. This is also indicated by no common cipher: Cipher : 0000.

Looking at the code of your server it seems to me that you are setting up some SSL context at the beginning (and the shown code seems to be broken too) but never actually use it, i.e. your server is plain TCP only. No wonder the client croaks about it.

Upvotes: 1

Related Questions