SSL Certificate verify failed in Python3.6/3.7

Viewed 590

I am running the following code in python3.6 to connect to a storage.

[root@controller wuwy]# python3
Python 3.6.8 (default, Jan 11 2019, 02:17:16)
[GCC 8.2.1 20180905 (Red Hat 8.2.1-3)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pywbem
>>> ip = '193.168.11.113'
>>> user = '193_160_28_29'
>>> password = '193_160_28_29'
>>> url = 'https://193.168.11.113:5989'
>>> ca_certs = '/home/ca.cer'
>>> conn = pywbem.WBEMConnection(url,(user, password),default_namespace='root/example',ca_certs=ca_certs,no_verification=False)
>>> conn.EnumerateInstances('EXAMPLE_StorageProduct')

And I am getting the below error.

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.6/site-packages/pywbem/cim_operations.py", line 1919, in EnumerateInstances
    **extra)
  File "/usr/local/lib/python3.6/site-packages/pywbem/cim_operations.py", line 1232, in _imethodcall
    conn_id=self.conn_id)
  File "/usr/local/lib/python3.6/site-packages/pywbem/cim_http.py", line 776, in wbem_request
    client.endheaders()
  File "/usr/lib64/python3.6/http/client.py", line 1234, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/usr/lib64/python3.6/http/client.py", line 1026, in _send_output
    self.send(msg)
  File "/usr/local/lib/python3.6/site-packages/pywbem/cim_http.py", line 461, in send
    self.connect()  # pylint: disable=no-member
  File "/usr/local/lib/python3.6/site-packages/pywbem/cim_http.py", line 619, in connect
    return self.sock.connect((self.host, self.port))
  File "/usr/lib64/python3.6/ssl.py", line 1064, in connect
    self._real_connect(addr, False)
  File "/usr/lib64/python3.6/ssl.py", line 1055, in _real_connect
    self.do_handshake()
  File "/usr/lib64/python3.6/ssl.py", line 1032, in do_handshake
    self._sslobj.do_handshake()
  File "/usr/lib64/python3.6/ssl.py", line 648, in do_handshake
    raise ValueError("check_hostname needs server_hostname "
ValueError: check_hostname needs server_hostname argument

When I am running the same code in python3.7, error changed.

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/python3/lib/python3.7/site-packages/pywbem/_cim_operations.py", line 2494, in EnumerateInstances
    **extra)
  File "/usr/python3/lib/python3.7/site-packages/pywbem/_cim_operations.py", line 1763, in _imethodcall
    conn_id=self.conn_id)
  File "/usr/python3/lib/python3.7/site-packages/pywbem/_cim_http.py", line 824, in wbem_request
    client.endheaders()
  File "/usr/python3/lib/python3.7/http/client.py", line 1224, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/usr/python3/lib/python3.7/http/client.py", line 1016, in _send_output
    self.send(msg)
  File "/usr/python3/lib/python3.7/site-packages/pywbem/_cim_http.py", line 483, in send
    self.connect()  # pylint: disable=no-member
  File "/usr/python3/lib/python3.7/site-packages/pywbem/_cim_http.py", line 661, in connect
    conn_id=conn_id)
pywbem._exceptions.ConnectionError: SSL error <class 'ssl.SSLCertVerificationError'>: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: IP address mismatch, certificate is not valid for '193.168.11.113'. (_ssl.c:1045); OpenSSL version: OpenSSL 1.1.1c FIPS  28 May 2019

This code works fine with python2.7 version.

And I checked the CN and SAN of the certificate, seems no problem here.

So could anyone tell me what's the problem here?

1 Answers

I just had today a similar issue than yours with Python 3.7, but using Pika instead of PyWBEM, still, this might help:

It seems Python 3.7 uses OpenSSL's hostname verification algorithms. In my case, the certificate used in my client was not valid for the IP (I had declared the server ip, instead of the client one, where the client certificates are stored). I used Pika, an example based in the one (tls_example.py) in: https://pika.readthedocs.io/en/stable/examples/tls_mutual_authentication.html

I had something like

context = ssl.create_default_context(
cafile="PIKA_DIR/testdata/certs/ca_certificate.pem")
context.load_cert_chain("PIKA_DIR/testdata/certs/client_certificate.pem",
                        "PIKA_DIR/testdata/certs/client_key.pem")

ssl_options = pika.SSLOptions(context, '192.168.122.122')
conn_params = pika.ConnectionParameters(host='192.168.122.122', 
                                        port=5671,

As I said, I had to replace the pika.SSLOptions host for localhost, where I had the client certificate:

ssl_options = pika.SSLOptions(context, "localhost")

I would check in your case if you may have some similar issue. This helped me to find the solution: https://bugs.python.org/issue34440

Related