pythonsocketshttpsslhttp.client

Setting newer ssl version in python http.client.HTTPSConnection


I've got this following https client that attempt to send simple POST request to a remove server.

!/usr/bin/python3

import http.client
import json
import ssl

context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)

connection = http.client.HTTPSConnection('192.168.11.1', 444, context = context)

headers = {'Content-type': 'application/json',
           'Accept': 'application/json',
           'Content-Length': '0'}

foo = {'ver': '111'}
json_foo = json.dumps(foo)

connection.request('POST', '/post', json_foo, headers)

response = connection.getresponse()

print(response.read().decode())

However, when doing so I get [SSL: WRONG_VERSION_NUMBER] wrong version number So I've tried to set the ssl protocol manually to newer version (by using ssl.SSLContext when create the connection).

Here's the callstack :

  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/http/client.py", line 1245, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/http/client.py", line 1291, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/http/client.py", line 1240, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/http/client.py", line 1008, in _send_output
    self.send(msg)
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/http/client.py", line 948, in send
    self.connect()
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/http/client.py", line 1414, in connect
    self.sock = self._context.wrap_socket(self.sock,
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/ssl.py", line 500, in wrap_socket
    return self.sslsocket_class._create(
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/ssl.py", line 1040, in _create
    self.do_handshake()
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/ssl.py", line 1309, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1108)

However, in python3, this is the options I have. Unfortunately, protocols 2 and 3 aren't part of the list.

PROTOCOL_SSLv23     
PROTOCOL_TLS_SERVER 
PROTOCOL_TLSv1_2
PROTOCOL_TLS        
PROTOCOL_TLSv1
PROTOCOL_TLS_CLIENT 
PROTOCOL_TLSv1_1

Any idea how do I upgrade the ssl version of the socket inside the http connection ? Do i need to upgrade the ssl package ? I thought it's relatively updated in python3 (3.8.2)

thanks !


Solution

  • ... it worked when i used ... curl ..."http://192.168.11.1:444/post"

    What you are successfully doing with curl is a plain HTTP request (http://... not https://...). What you are trying (and failing) with your code is a HTTPS request, i.e. HTTP over TLS. The error message is the result of attempting to speak TLS against a server which does not support TLS.