title: How to communicate with a server using a TLS connection?
body: <p>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 <em>CA-Certificate</em>, <em>Client Certificate</em>, and <em>Client Certificate Key</em> in a file called &quot;cert.pem&quot;. Although my server code works fine, my client code fails to connect to the server. I just mimicked the <a href="https://docs.python.org/3.7/library/ssl.html#ssl.SSLContext.load_cert_chain" rel="nofollow noreferrer">SSL module example</a> and I do not understand why it fails.</p>
  <p>The <strong>server code</strong> that works fine:</p>
  <pre><code>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(&quot;Waiting for client&quot;)
    newsocket, fromaddr = bindsocket.accept()
    conn = context.wrap_socket(newsocket, server_side=True)
    print(&quot;SSL established. Peer: {}&quot;.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(&quot;Received:&quot;, buf)
          break
    finally:
      print(&quot;Closing connection&quot;)
      conn.shutdown(socket.SHUT_RDWR)
      conn.close()
  </code></pre>
  <p>The <strong>client code</strong> that fails:</p>
  <pre><code>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(&quot;/etc/ssl/certs/ca-bundle.crt&quot;)
  conn = context.wrap_socket(socket.socket(socket.AF_INET), server_hostname=server_addr)
  conn.connect((server_addr, server_port))
  
  conn.send(b&quot;Hello, world!&quot;)
  conn.close()
  </code></pre>
  <p>When I run the client code, I get this error:</p>
  <blockquote>
  <p>ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1091)</p>
  </blockquote>
  <p>However when I simply use <a href="https://stackoverflow.com/a/63278147/9696715">this command</a>, I am able to send data:</p>
  <pre><code>openssl s_client -connect 127.0.0.1:10023
  </code></pre>
  <h1>Questions</h1>
  <ul>
  <li>What is wrong with my client code?</li>
  <li>Why the <code>openssl s_client</code> command works but the python code does not?</li>
  </ul>
  <p>I highly appreciate any suggestions to improve the code.</p>