pythonsocketssslregistrar

Python Sockets SSL: certificate verify failed


I am attempting to use python sockets to make an Extensible Provisioning Protocol (EPP) request to a domain registrar, which only accepts requests over ssl.

Certificate file: www.myDomain.se.crt Key File: mydomain.pem

openssl s_client -connect epptestv3.iis.se:700 -cert www.myDomain.se.crt -key mydomain.pem

When I try making request using openssl client I successfully get greeting response from registrar, but when I use following code in python i get ssl certificate error.

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(15)
sock.connect(('epptestv3.iis.se', 700))
sock.settimeout(60)  # regular timeout


ssl_keyfile='myDomain.pem'
ssl_certfile='www.myDomain.se.crt'
ssl_ciphers='AES256-GCM-SHA384'
ssl_version=ssl.PROTOCOL_TLSv1_2

sock = ssl.wrap_socket(sock,
                        ssl_keyfile,
                        ssl_certfile,
                        ssl_version=ssl_version,
                        ciphers=ssl_ciphers,
                        server_side=False,
                        cert_reqs=ssl.CERT_REQUIRED,
                        ca_certs=None
                        )

After executing script I get following error:

Traceback (most recent call last):
  File "server_connect.py", line 54, in <module>
    ca_certs=ssl_keyfile
  File "/usr/lib/python2.7/ssl.py", line 933, in wrap_socket
    ciphers=ciphers)
  File "/usr/lib/python2.7/ssl.py", line 601, in __init__
    self.do_handshake()
  File "/usr/lib/python2.7/ssl.py", line 830, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)

Any idea what's wrong here?


Solution

  • From your code:

                        cert_reqs=ssl.CERT_REQUIRED,
                        ca_certs=None
    

    From the documentation of wrap_socket:

    If the value of this parameter is not CERT_NONE, then the ca_certs parameter must point to a file of CA certificates.

    Essentially you are asking in your code to validate the certificate from the server (CERT_REQUIRED) but specify at the same time that you have no trusted root (ca_certs=None). But without trusted root certificates no validation can be done.

    Note that changing your code to use CERT_NONE instead would be a bad idea. It would probably work since no certificate validation will be done but it would be open to man in the middle attacks.