A 16-line python application that demonstrates SSL client authentication over HTTPS. We also explain the basics of how to set up Apache to require SSL client authentication. This assumes at least Python-2.2 compiled with SSL support, and Apache with mod_ssl.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #!/usr/bin/env python
import httplib
CERTFILE = '/home/robr/mycert'
HOSTNAME = 'localhost'
conn = httplib.HTTPSConnection(
HOSTNAME,
key_file = CERTFILE,
cert_file = CERTFILE
)
conn.putrequest('GET', '/ssltest/')
conn.endheaders()
response = conn.getresponse()
print response.read()
|
"mycert" is a PEM formatted certificate file that includes both the public certificate and the private key. If you read the code, you will notice that you can keep the public and private in seperate files if you care to.
SSL authentication generally requires that you set up your own certificate authority. You want to make sure you are the only one giving out keys to your empire.
Apache needs to be set up to require SSL client authentication. In my httpd.conf file I have the following:
SSLCACertificatePath /etc/httpd/conf/ssl.crt SSLCACertificateFile /etc/httpd/conf/ssl.crt/myCA.crt SSLVerifyClient require SSLVerifyDepth 2 SSLRequireSSL
If you have SSLCACertificateFile defined elsewhere in your config file, you'll need to resolve the conflict. It seems that Apache cannot refer to more than one SSLCACertificateFile. Multiple CA certs can exist in one file, but you may not want everyone with certs from all of your accepted CAs access to all of your content.
So why use SSL client authentication? It's a convenient way to do client authentication between web-enabled applications. It's good for SOAP or XML-RPC implementations, or custom apps that communicate via HTTP/HTTPS.
References: http://httpd.apache.org/docs-2.0/ssl/ssl_howto.html http://www.pseudonym.org/ssl/ssl_cook.html
Doesn't do authentication. According to the Python documentation:
class HTTPSConnection( host[, port, key_file, cert_file]) A subclass of HTTPConnection that uses SSL for communication with secure servers. Default port is 443. key_file is the name of a PEM formatted file that contains your private key. cert_file is a PEM formatted certificate chain file.
If this doesn't do certificate verification, it seems to be very incomplete. Is there anyway to verify the certs or is this planned in a future release? The article/code snippet should state this defiency.
Authentication to Apache worked. I believe the comment in the Python docs means that Python code does not check or verify the peer certificate. However, the files do seem to be presented to the connection peer properly. When tested against Apache, an unexpected certificate was rejected and only certificates from the proper authorities were accepted.