I am working on a Windows 10 computer and a Windows 10 virtual machine. I´ve created a tcp socket server/client application which is secured via python ssl. My code looks like this:
Server:
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
context.set_ciphers('ECDHE-ECDSA-AES256-GCM-SHA384')
context.load_cert_chain(certfile="cert.pem", keyfile="prKey.pem")
tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
tcpsock.bind((ip, port))
ssocket = context.wrap_socket(tcpsock, server_side=True)
Client:
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = True
context.load_verify_locations("cert.pem")
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssock = context.wrap_socket(sock, server_hostname=server_ip)
My friend created an official certificate to use for my server-side authentication. This was created and validated via OpenSSL if I understand correctly. However, when I try to connect to the running server with my client I receive the following error message (client-side error):
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1129)
I put the certificate + matching private key (pem format) on the virtual machine and I have a copy of the certificate (pem format) on my localhost.
I also have a certificate in cer file format, which I installed to the root windows certificate store (client and server side).
Since this did not work I kept researching and found out about the certifi
package. I installed it and found by usingprint(certifi.where())
a cacert.pem
file. Which contained multiple certificates. I added my friends certificate to that file via copy and paste, safe it but I still receive the same error.
Now I´m seriously kinda lost about what is wrong. When I disable context.verify_mode = ssl.CERT_REQUIRED
my code is working just fine, but I really want server-side authentication for my code..
I changed the client's code to:
context = ssl.create_default_context()
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = True
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssock = context.wrap_socket(sock, server_hostname=self.ip)
This way I don't have to hand a certificate file manually over. Instead, it seems like my Windows root certificate library gets scanned and finds my VM´s certificate automatically (since I installed the .cer file).
context.load_cert_chain(certfile="cert.cer", keyfile="prKey.pem")