0

I need PyCharm (2019.1.1, on macOS Mojave) to accept my self-signed SSL certificate when running python-socketio client and flask-socketio server.

I have tried to add the self-signed certificate to PyCharm via Preferences/Tools/Server Certificates. However, it does not solve the problem. When python-socketio client attempted to connect to flask-socketio server, it gave me errors.

On the client side, the error was thrown like this:

Traceback (most recent call last):
  File "message_manager.py", line 218, in run
    namespaces=[self.channel])
  File "/Users/hqiu/PycharmProjects/gps_simulator/src/venv/lib/python3.7/site-packages/socketio/client.py", line 262, in connect
    engineio_path=socketio_path)
  File "/Users/hqiu/PycharmProjects/gps_simulator/src/venv/lib/python3.7/site-packages/engineio/client.py", line 170, in connect
    url, headers, engineio_path)
  File "/Users/hqiu/PycharmProjects/gps_simulator/src/venv/lib/python3.7/site-packages/engineio/client.py", line 308, in _connect_polling
    if self._connect_websocket(url, headers, engineio_path):
  File "/Users/hqiu/PycharmProjects/gps_simulator/src/venv/lib/python3.7/site-packages/engineio/client.py", line 346, in _connect_websocket
    cookie=cookies)
  File "/Users/hqiu/PycharmProjects/gps_simulator/src/venv/lib/python3.7/site-packages/websocket/_core.py", line 514, in create_connection
    websock.connect(url, **options)
  File "/Users/hqiu/PycharmProjects/gps_simulator/src/venv/lib/python3.7/site-packages/websocket/_core.py", line 223, in connect
    options.pop('socket', None))
  File "/Users/hqiu/PycharmProjects/gps_simulator/src/venv/lib/python3.7/site-packages/websocket/_http.py", line 126, in connect
    sock = _ssl_socket(sock, options.sslopt, hostname)
  File "/Users/hqiu/PycharmProjects/gps_simulator/src/venv/lib/python3.7/site-packages/websocket/_http.py", line 260, in _ssl_socket
    sock = _wrap_sni_socket(sock, sslopt, hostname, check_hostname)
  File "/Users/hqiu/PycharmProjects/gps_simulator/src/venv/lib/python3.7/site-packages/websocket/_http.py", line 239, in _wrap_sni_socket
    server_hostname=hostname,
  File "/Users/hqiu/anaconda3/lib/python3.7/ssl.py", line 412, in wrap_socket
    session=session
  File "/Users/hqiu/anaconda3/lib/python3.7/ssl.py", line 853, in _create
    self.do_handshake()
  File "/Users/hqiu/anaconda3/lib/python3.7/ssl.py", line 1117, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1056)

And this is the error log on server side:

(82268) accepted ('127.0.0.1', 63087)
8d0d93e8376c44919237c647ceb899b3: Sending packet OPEN data {'sid': '8d0d93e8376c44919237c647ceb899b3', 'upgrades': ['websocket'], 'pingTimeout': 60000, 'pingInterval': 25000}
8d0d93e8376c44919237c647ceb899b3: Sending packet MESSAGE data 0
127.0.0.1 - - [16/Oct/2019 12:44:33] "GET /socket.io/?transport=polling&EIO=3&t=1571238873.310223 HTTP/1.1" 200 349 0.000423    
(82268) accepted ('127.0.0.1', 63093)
Traceback (most recent call last):
  File "/Users/hqiu/PycharmProjects/gps_simulator/src/venv/lib/python3.7/site-packages/eventlet/hubs/kqueue.py", line 105, in wait
    readers.get(fileno, hub.noop).cb(fileno)
  File "/Users/hqiu/PycharmProjects/gps_simulator/src/venv/lib/python3.7/site-packages/eventlet/greenthread.py", line 221, in main
    result = function(*args, **kwargs)
  File "/Users/hqiu/PycharmProjects/gps_simulator/src/venv/lib/python3.7/site-packages/eventlet/wsgi.py", line 818, in process_request
    proto.__init__(conn_state, self)
  File "/Users/hqiu/PycharmProjects/gps_simulator/src/venv/lib/python3.7/site-packages/eventlet/wsgi.py", line 357, in __init__
    self.handle()
  File "/Users/hqiu/PycharmProjects/gps_simulator/src/venv/lib/python3.7/site-packages/eventlet/wsgi.py", line 390, in handle
    self.handle_one_request()
  File "/Users/hqiu/PycharmProjects/gps_simulator/src/venv/lib/python3.7/site-packages/eventlet/wsgi.py", line 419, in handle_one_request
    self.raw_requestline = self._read_request_line()
  File "/Users/hqiu/PycharmProjects/gps_simulator/src/venv/lib/python3.7/site-packages/eventlet/wsgi.py", line 402, in _read_request_line
    return self.rfile.readline(self.server.url_length_limit)
  File "/Users/hqiu/anaconda3/lib/python3.7/socket.py", line 589, in readinto
    return self._sock.recv_into(b)
  File "/Users/hqiu/PycharmProjects/gps_simulator/src/venv/lib/python3.7/site-packages/eventlet/green/ssl.py", line 241, in recv_into
    return self._base_recv(nbytes, flags, into=True, buffer_=buffer)
  File "/Users/hqiu/PycharmProjects/gps_simulator/src/venv/lib/python3.7/site-packages/eventlet/green/ssl.py", line 256, in _base_recv
    read = self.read(nbytes, buffer_)
  File "/Users/hqiu/PycharmProjects/gps_simulator/src/venv/lib/python3.7/site-packages/eventlet/green/ssl.py", line 176, in read
    super(GreenSSLSocket, self).read, *args, **kwargs)
  File "/Users/hqiu/PycharmProjects/gps_simulator/src/venv/lib/python3.7/site-packages/eventlet/green/ssl.py", line 150, in _call_trampolining
    return func(*a, **kw)
  File "/Users/hqiu/anaconda3/lib/python3.7/ssl.py", line 911, in read
    return self._sslobj.read(len, buffer)
ssl.SSLError: [SSL: TLSV1_ALERT_UNKNOWN_CA] tlsv1 alert unknown ca (_ssl.c:2488)

So my question is, how to add self-signed certificate to PyCharm on macOS and let the Python find it?

Please give me some ideas.

Tyrion
  • 405
  • 8
  • 22

2 Answers2

0

I don't believe PyCharm communicates SSL certificate settings to Python. The Socket.IO client does not officially support self-signed certificates at this time, but it has been requested. See this and this for the two issues related to SSL certificates in the client.

That said, the long-polling transport is implemented via the requests package, so you can set the REQUESTS_CA_BUNDLE environment variable to tell requests about your certificate. But obviously this does not work for WebSocket.

Miguel Grinberg
  • 65,299
  • 14
  • 133
  • 152
  • Hi, thanks for the answer! Do you mean that, if I am running Python with PyCharm now, I couldn't set up Socketio communication with SSL? – Tyrion Oct 17 '19 at 11:16
  • Well, I meant two things. First, the certs that you set in PyCharm are for PyCharm, they are not seen by Python (at least I don't think they are). Since Socket.IO uses the requests package for long-polling, you can use the requests environment variable to select a self-signed cert, but of course this will not work with WebSocket, so it is a partial solution. – Miguel Grinberg Oct 17 '19 at 18:30
0

Perhaps you could adjust your system-wide Certificate Trust settings to accept your self-signed certificate. On macOS, this is available in Keychain Access.

noɥʇʎԀʎzɐɹƆ
  • 9,967
  • 2
  • 50
  • 67
  • Hi noɥʇʎԀʎzɐɹƆ, I tried, it didn't work. But thank you for the idea! – Tyrion Oct 17 '19 at 10:39
  • You need to not only add the certificate but also mark it as trusted – noɥʇʎԀʎzɐɹƆ Oct 17 '19 at 21:06
  • Have you contacted JetBrains support? – noɥʇʎԀʎzɐɹƆ Oct 17 '19 at 21:06
  • Hi, I set it as "always trust" in the KeyChain. Yea, that's a good idea! I will contact JetBrains for help. – Tyrion Oct 18 '19 at 11:22
  • Are you connecting from within a PyCharm tool or from within your code itself? – noɥʇʎԀʎzɐɹƆ Oct 18 '19 at 20:32
  • Hi, I am trying to set the connection within the code itself. And I contacted the PyCharm support. They said that PyCharm cannot pass the certificate to Python. They suggested me to do it in my code. – Tyrion Oct 21 '19 at 11:06
  • @Tyrion Oh, that makes your problem much easier to solve. Next time, give more context to your question so we can answer it better. Add some context on which Python library you're using to connect, and I'll answer your question – noɥʇʎԀʎzɐɹƆ Oct 22 '19 at 12:05
  • Do you need help figuring out which library you're using? – noɥʇʎԀʎzɐɹƆ Oct 23 '19 at 20:52
  • Hi noɥʇʎԀʎzɐɹƆ, thanks! Truth be told, I didn't know the difference between Python library and Python module when you answered the question. So I googled online and got understand. I am using two libraries for socketio communication. The client side is python-socketio 4.3.1, and Flask-SocketIO 4.2.1 is on server side. – Tyrion Oct 24 '19 at 18:30
  • @Tyrion socketio uses the built-in ssl library https://docs.python.org/3/library/ssl.html#ssl.SSLContext.load_cert_chain – noɥʇʎԀʎzɐɹƆ Oct 24 '19 at 20:41
  • Thank you! I'll look into that. – Tyrion Oct 25 '19 at 10:55