#-*- coding: utf-8 -*- import socket import ssl import httplib class HTTPSClientAuthConnection(httplib.HTTPSConnection): """ Class to make a HTTPS connection, with support for full client-based SSL Authentication""" def __init__(self, host, port, key_file, cert_file, ca_file, timeout=None): httplib.HTTPSConnection.__init__(self, host, key_file=key_file, cert_file=cert_file) self.key_file = key_file self.cert_file = cert_file self.ca_file = ca_file self.timeout = timeout def connect(self): """ Connect to a host on a given (SSL) port. If ca_file is pointing somewhere, use it to check Server Certificate. Redefined/copied and extended from httplib.py:1105 (Python 2.6.x). This is needed to pass cert_reqs=ssl.CERT_REQUIRED as parameter to ssl.wrap_socket(), which forces SSL to check server certificate against our client certificate. """ sock = socket.create_connection((self.host, self.port), self.timeout) if self._tunnel_host: self.sock = sock self._tunnel() # If there's no CA File, don't force Server Certificate Check if self.ca_file: self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, ca_certs=self.ca_file, cert_reqs=ssl.CERT_REQUIRED) else: self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, cert_reqs=ssl.CERT_NONE) if __name__ == '__main__': # Little test-case of our class import sys if len(sys.argv) != 6: print 'usage: python https_auth_handler.py host port key_file cert_file ca_file' sys.exit(1) else: host, port, key_file, cert_file, ca_file = sys.argv[1:] conn = HTTPSClientAuthConnection(host, port, key_file=key_file, cert_file=cert_file, ca_file=ca_file) conn.request('GET', '/') response = conn.getresponse() print response.status, response.reason data = response.read() print data conn.close()