I’m building a python app where a client side will request xml pages from a server (also running python).
I would like to do something on the line of puppet configuration management system. Puppet works as follow:
1) If the client runs for the 1st time, it generates a Certificate Signing Request and a private key. The former is an x509 certificate that is self-signed.
2) The client connects to the master (at this time the client is not authenticated) and sends its CSR, it will also receives the CA certificate and the CRL in return.
3) The master stores locally the CSR
4) The administrator checks the CSR and can eventually sign it (this process can be automated with autosigning). I strongly suggest verifying certificate fingerprint at this stage.
5) The client is then waiting for his signed certificate, which the master ultimately sends.
6) All next communications will use this client certificate. Both the master and client will authenticate each others by virtue of sharing the same CA.
(from http://www.masterzen.fr/2010/11/14/puppet-ssl-explained/)
The main things that I don’t know how to do are:
– Which are the best libs to use?
– What to use on the server side? Will Django behind apache/nginx be able to sign the certificate on the first run and do the auth using the certificates thereafter or I need to use something like twisted on the front end?
– The best way to send the CSR would be a POST to the server?
– Do any one knows if there is some code examples available that would cover both client and server sides?
– Is there any other way to establish a trusted connection between client/server without human iteration (what is the best practice for authentication between webservices)?
There’s a Python wrapper around M2Crypto called pki that makes creating CSRs and such easy. You should be able to use Django for this, I see no reason why you’d need Twisted.
You might as well send the CSR with a POST, yes, there’s nothing confidential in there – that’s the point.
The pki package I linked to has rather thorough docstrings that should get you going.
I don’t think you’ll be able to establish a “trusted connection” without any human intervention. Trust is a human concept – and so you’ll need to approve at least the first connection request, and hopefully you’ll verify if the person that’s trying to connect is truly authorized.
Note that “verify” in this context means calling a person and asking them who are they and why they’re trying to connect to your service, and asking them to confirm the fingerprint of the private key used for the CSR.