I am using python and SSL module to establish a TLS connection to a server. Then I would like to send some data to this server. To do this, I have a CA-Certificate, Client Certificate, and Client Certificate Key in a file called "cert.pem". Although my server code works fine, my client code fails to connect to the server. I just mimicked the SSL module example and I do not understand why it fails.
The server code that works fine:
import socket, ssl
cert_chain = 'cert.pem'
host_addr = socket.gethostbyname(socket.gethostname())
host_port = 10023
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.load_cert_chain(certfile=cert_chain)
bindsocket = socket.socket()
bindsocket.bind((host_addr, host_port))
bindsocket.listen(5)
while True:
print("Waiting for client")
newsocket, fromaddr = bindsocket.accept()
conn = context.wrap_socket(newsocket, server_side=True)
print("SSL established. Peer: {}".format(conn.getpeercert()))
buf = b'' # Buffer to hold received client data
try:
while True:
data = conn.recv(4096)
if data: # Client sent us data. Append to buffer
buf += data
else: # No more data from client. Show buffer and close connection.
print("Received:", buf)
break
finally:
print("Closing connection")
conn.shutdown(socket.SHUT_RDWR)
conn.close()
The client code that fails:
import socket, ssl
server_addr = '**.***.***.***'
server_port = 3335
cert_chain = 'cert.pem'
context = ssl.create_default_context()
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.load_verify_locations("/etc/ssl/certs/ca-bundle.crt")
conn = context.wrap_socket(socket.socket(socket.AF_INET), server_hostname=server_addr)
conn.connect((server_addr, server_port))
conn.send(b"Hello, world!")
conn.close()
When I run the client code, I get this error:
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1091)
However when I simply use this command, I am able to send data:
openssl s_client -connect 127.0.0.1:10023
Questions
- What is wrong with my client code?
- Why the
openssl s_client
command works but the python code does not?
I highly appreciate any suggestions to improve the code.