3

This is not a duplicate for this post. I tried the solutions there and nothing works in my case.

I am using Windows and Python 3.6.5. I have a python script for a TLS client. The server I need to connect to uses a self-signed certificate. When I try to connect to it using my script, I get this error:

ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:833)

I need to parse the certificate. I tried to add my server's certificate .pem content to file named: cacert.pem which is in: C:\Python36\Lib\site-packages\certifi and run the program again. Nothing change. Here is my scripot. Please help me to make the client make exception for this server as I trust its certificate.

import socket, ssl
import itertools

context = ssl.SSLContext() 
context.verify_mode = ssl.CERT_OPTIONAL 
context.check_hostname = False

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
domain="192.168.56.3" # my server
ssl_sock = context.wrap_socket(s, server_hostname=domain)
ssl_sock.connect((domain, 443))

print("====== peer's certificate ======")
try:
    cert = ssl_sock.getpeercert()
    print(cert)
except SSLError as e:
    print("Error: ",e)
ssl_sock.close()
None
  • 281
  • 1
  • 6
  • 16
  • Hard to tell what is going one since there is no way to reproduce it based on the information. But, assuming that the code is using the cacert.pem where you've added the certificate then my guess is that the certificate is not a CA certificate, but only a self-signed non-CA certificate - which is not sufficient, – Steffen Ullrich Apr 27 '18 at 14:28
  • I think that this question is a dup of your other one: https://stackoverflow.com/questions/50055935/cant-receive-peers-certificate-in-opoenssl-python-client-using-ssl-sslcontext. – CristiFati Apr 27 '18 at 19:28

1 Answers1

3

This question has been idle for a while, but in case somebody is still struggling with connecting to a server with a self-signed certificate via Python ssl library:

You can use the load_verify_locations method of SSLContext to specify custom self-signed root certs (see Python Docs for load_verify_locations).

The forementioned code could be extended as follows:

...

context = ssl.SSLContext() 
context.verify_mode = ssl.CERT_OPTIONAL 
context.check_hostname = False

context.load_verify_locations(cafile='/path/to/your/cacert.pem')

...

Be aware that you also need to include public root certs in case you want to connect to other servers with public certificates with the same client/context. (you could for example append your cacert.pem content to the certifi root certificates and reference that folder / path instead).

See also this Python docs paragraph for more information: client-side operations.

nehtor.t
  • 469
  • 4
  • 11