1

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 !

Zohar81
  • 4,554
  • 5
  • 29
  • 82
  • *"... protocols 2 and 3 ..."* - SSLv2 and SSLv3 are old and broken and therefore disabled today. The newest is actually TLS 1.3 which your stack does not seem to support yet. But TLS 1.2 is fine, use this. Also, you don't need to explicitly set a context, it will use a default context when nothing is given and this default context is typically what you want anyway. *"I've got this following https client ..."* - better use a more modern source for learning. – Steffen Ullrich Jun 24 '21 at 16:32
  • @SteffenUllrich, thanks for your helpful comment. The server is based on `aiohttp.web` and it looks like it doesn't support none of the protocols listed above. I'm willing to adopt better http client package (preferably built-in within python3 but not mandatory) Perhaps you can recommend any replacement to http.client and support more ssl protocols ? – Zohar81 Jun 25 '21 at 11:03
  • The protocol support you have is likely fine. My guess is that your server side is the problem. Such irritating error messaging happen also, if the server does not speak TLS at all. Unfortunately nothing is known about the server, so I can only guess. – Steffen Ullrich Jun 25 '21 at 11:12
  • @SteffenUllrich, My first suspicion was on the client side since it worked when i used the following `curl` commandline : `curl -X POST -H "Content-type: application/json" -H "Accept: application/json" -d '{"param":"value"}' "http://192.168.11.1:444/post"` ... when using client.http the ssl version error comes from protocol handshake (updated the question with full callstack) – Zohar81 Jun 25 '21 at 11:22

1 Answers1

2

... 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.

Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172