I need to build an encrypted connection between two peers, and I need to authenticate both. Both peers already share a fingerprint (SHA256 hash) of the other peer public key. I'm not using X509 or OpenPGP keys/certs as they are too big and bulky for my needs and they don't fit in the security model.
I'm trying to build a connection with M2Crypto (nice library) by abusing its x509 model:
given the rsa private key, create a selfsigned almost-empty cert.
connect to the other peer offering my cert
verify the other peer cert public key fingerprint;
Is the following code secure? is it correct? is there a way do do it better (maybe with other libraries)? My doubts are about OpenSSL not actually using the certificate public key for authentication as I'm not requesting any verification of the certificates.
I just need to use encrypted streams authed by der-encoded rsa keys, any Free Software solution for python is welcome. I'd like M2Crypto more because I know it better and have already some code using it in the same project.
Here is my code (just the client peer, server should be similar):
other_fingerprints = [] #list of fingerprints, (binary data)
mysocket = ... #any socket object
CERTFILE, KEYFILE = "testcert","testkey" # private key wrapped in the cert
from M2Crypto import *
ctx = SSL.Context('sslv3')
ctx.set_verify(SSL.verify_none, depth=1)
ctx.load_cert(CERTFILE, KEYFILE)
c = SSL.Connection(ctx, mysocket)
c.connect_ssl()
peercert = c.get_peer_cert()
keyobj = peercert.get_pubkey()
keydata = keyobj.as_der()
md = EVP.MessageDigest('sha256')
md.update(keydata)
h = md.digest()
if h not in other_fingerprints:
raise(IOError) #other party not auth'ed
# from now on the connection is secure, right?
c.send("Hello secret world!")
print c.recv(4096)
c.close()
Thank you all in advance for your answers and advice.