title: What do I need to distribute (keys, certs) for Python w/ SSL-socket connection?
body: <p>I'm trying to write a generic server-client application that will be able to exchange data amongst servers. 
  I've read over quite a few OpenSSL documents, and I have successfully setup my own CA and created a cert (and private key) for testing purposes.</p>
  
  <p>I'm stuck with Python 2.3, so I can't use the standard "ssl" library. Instead, I'm stuck with PyOpenSSL, which doesn't seem bad, but there aren't many documents out there about it.</p>
  
  <p>My question isn't really about getting it working. I'm more confused about the certificates and where they need to go. </p>
  
  <p>Here are my two programs that <strong>do</strong> work:</p>
  
  <p><strong>Server:</strong></p>
  
  <pre><code>#!/bin/env python
  
  from OpenSSL import SSL
  import socket
  import pickle
  
  def verify_cb(conn, cert, errnum, depth, ok):
      print('Got cert: %s' % cert.get_subject())
      return ok
  
  
  ctx = SSL.Context(SSL.TLSv1_METHOD)
  ctx.set_verify(SSL.VERIFY_PEER|SSL.VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb)
  
  # ??????
  ctx.use_privatekey_file('./Dmgr-key.pem')
  ctx.use_certificate_file('Dmgr-cert.pem')
  # ??????
  ctx.load_verify_locations('./CAcert.pem')
  
  server = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM))
  
  server.bind(('', 50000))
  server.listen(3)
  
  a, b = server.accept()
  
  c = a.recv(1024)
  print(c)
  </code></pre>
  
  <p><strong>Client:</strong></p>
  
  <pre><code>from OpenSSL import SSL
  import socket
  import pickle
  
  
  def verify_cb(conn, cert, errnum, depth, ok):
      print('Got cert: %s' % cert.get_subject())
      return ok
  
  ctx = SSL.Context(SSL.TLSv1_METHOD)
  ctx.set_verify(SSL.VERIFY_PEER, verify_cb)
  
  # ??????????
  ctx.use_privatekey_file('/home/justin/code/work/CA/private/Dmgr-key.pem')
  ctx.use_certificate_file('/home/justin/code/work/CA/Dmgr-cert.pem')
  # ?????????
  ctx.load_verify_locations('/home/justin/code/work/CA/CAcert.pem')
  
  sock = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM))
  sock.connect(('10.0.0.3', 50000))
  
  a = Tester(2, 2)
  b = pickle.dumps(a)
  sock.send("Hello, world")
  
  sock.flush()
  sock.send(b)
  sock.shutdown()
  sock.close()
  </code></pre>
  
  <p>I found this information from <a href="ftp://ftp.pbone.net/mirror/ftp.pld-linux.org/dists/2.0/PLD/i586/PLD/RPMS/python-pyOpenSSL-examples-0.6-2.i586.rpm" rel="nofollow">ftp://ftp.pbone.net/mirror/ftp.pld-linux.org/dists/2.0/PLD/i586/PLD/RPMS/python-pyOpenSSL-examples-0.6-2.i586.rpm</a> which contains some example scripts. </p>
  
  <p>As you might gather, I don't fully understand the sections between the " # ????????." I don't get why the certificate and private key are needed on both the client and server. I'm not sure where each should go, but shouldn't I only need to distribute one part of the key (probably the public part)? It undermines the purpose of having asymmetric keys if you still need both on each server, right?</p>
  
  <p>I tried alternating removing either the pkey or cert on either box, and I get the following error no matter which I remove:</p>
  
  <blockquote>
    <p>OpenSSL.SSL.Error: [('SSL routines', 'SSL3_READ_BYTES', 'sslv3 alert handshake failure'), ('SSL routines', 'SSL3_WRITE_BYTES', 'ssl handshake failure')]</p>
  </blockquote>
  
  <p>Could someone explain if this is the expected behavior for SSL. Do I really need to distribute the private key and public cert to all my clients?
  I'm trying to avoid any huge security problems, and leaking private keys would tend to be a big one...</p>
  
  <p>Thanks for the help!</p>
  
  <p>==================================================================</p>
  
  <p>Thanks to caf for helping me figure out the problem. Based on his recommendation, I created two new certificate pairs: spaceman and dmgr. I then put both of the "spaceman" parts (key, cert) in the client program, and the same for the "dmgr" keys. </p>
  
  <p>Basically, only the following two lines in <strong>Client</strong> changed, although there was plently of work with openssl on the side. </p>
  
  <pre><code>ctx.use_privatekey_file('/home/justin/code/work/CA/private/Dmgr-key.pem')
  ctx.use_certificate_file('/home/justin/code/work/CA/Dmgr-cert.pem')
  </code></pre>
  
  <p>Corrected version:</p>
  
  <pre><code>ctx.use_privatekey_file('/home/justin/code/work/CA/private/spaceman-key.pem')
  ctx.use_certificate_file('/home/justin/code/work/CA/spacemancert.pem')
  </code></pre>