views:

224

answers:

2

I have an application application framework that works in a peer-to-peer manner between unnamed hosts on a network. I want to have the traffic be encrypted, so I've implemented a setup with M2Crypto, but I've run into a snag. I have no idea what to put down for 'commonName' when creating the cert. It seems to want a domain name, but none of the computers running this will have one. I just put 'temphost' for the commonName, but apparently this an important parameter. I got this when trying to test it:

M2Crypto.SSL.Checker.WrongHost: Peer certificate commonName does not match host, expected 127.0.0.1, got temphost

Is there a way to generalize the commonName?

+1  A: 

In your use case the default host name checking is not appropriate. You might want to try just doing certificate fingerprint checking. First, get the fingerprints of each certificate (openssl x509 -fingerprint). Let's say you have peer A and peer B, with fingerprint A and fingerprint B, respectively.

On peer A side, you will make the following calls early on in your script:

from M2Crypto import SSL
SSL.Connection.clientPostConnectionCheck = SSL.Checker(peerCertHash='fingerprint B')

On peer B side you do the same, except use fingerprint A. Now the certificate checker will only check to make sure that the fingerprints match, and won't do further checks.

This approach does mean that it will override the post connection check for ALL SSL connections, so it is not suitable in all use cases. If you can control the creation of the SSL.Connection object, you could also call set_post_connection_check_callback() per instance, which would allow different checker to be used when needed.

Heikki Toivonen
Thanks, though the issue is that there are numerous peers added constantly and their certs are generated when the application is installed. Would this mean I would have to have each peer be aware of the fingerprints of all the other potential peers?
directedition
Ah, using this approach, yes. So, what I wrote above won't work for you then.
Heikki Toivonen
Are you sure you are really doing any authentication at all?
GregS
Yes, you are making sure that only a specific peer (certificate) you know about can communicate with you. The strength of this of course depends on the hash algorithm. Don't use MD5 or weaker.
Heikki Toivonen
+1  A: 

So based on your comment to my first answer I decided to offer another solution that might work for your case. Create your own CA cert and key. Then in your peers tell M2Crypto to accept only certificates that were signed by this CA (see this older stackoverflow question for APIs to use: http://stackoverflow.com/questions/1848160/what-is-the-difference-between-m2cryptos-set-client-ca-list-from-file-and-load/1849277#1849277).

Then early on in your scripts do this:

from M2Crypto import SSL
SSL.Connection.clientPostConnectionCheck = None

or if you need to be able to make other kinds of SSL connections, see if you can control the creation of SSL.Connection objects and call their set_post_connection_check_callback() with suitable checker.

After this your peers should accept any other peer as long as the peer's certificate was signed with your CA only.

If you can think of any extra information you could verify in a post connection check, you could put that info in the certs (maybe in commonName) and write your own checker to use (instead of None above).

Heikki Toivonen
Thanks! That seems to work!
directedition