1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
# $Id$
import httplib, BaseHTTPServer, tlslite.api, glob
"""
HTTPS utilities, both client and server.
At the moment this only knows how to use the PEM certs in my
subversion repository; generalizing it would not be hard, but the more
general version should use SQL anyway.
"""
class CertInfo(object):
self.cert-dir = "biz-certs/"
def __init__(self, myname):
f = open(self.cert-dir + myname + "-EE.key", "r")
self.privateKey = tlslite.api.parsePEMKey(f.read(), private=True)
f.close()
chain = []
for file in glob.glob(self.cert-dir + myname + "-*.cer"):
f = open(file, "r")
x509 = tlslite.api.X509()
x509.parse(f.read())
f.close()
chain.append(x509)
self.certChain = tlslite.api.X509CertChain(chain)
self.x509TrustList = []
for file in glob.glob(self.cert-dir + "*-Root.cer"):
if file != self.cert-dir + myname + "-Root.cer":
f = open(file, "r")
x509 = tlslite.api.X509()
x509.parse(f.read())
f.close()
x509TrustList.append(x509)
return {"privateKey" : privateKey,
"certChain" : certChain,
"x509TrustList" : x509TrustList}
def client(msg, certInfo, host="localhost", port=4433, url="/"):
httpc = tlslite.api.HTTPTLSConnection(host, port, privateKey=certInfo.privatekey, certChain=certInfo.certChain, x509TrustList=certInfo.x509TrustList)
httpc.connect()
httpc.request("POST", url, msg, {"Content-Type":"application/x-rpki"})
response = httpc.getresponse()
assert response.status == httplib.OK
return response.read()
class requestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
rpki_handler = None # Subclass must bind
def do_POST(self):
assert self.headers["Content-Type"] == "application/x-rpki"
self.query_string = self.rfile.read(int(self.headers["Content-Length"]))
rcode, rtext = self.rpki_handler(self.query_string)
self.send_response(rcode)
self.send_header("Content-Type", "application/x-rpki")
self.end_headers()
self.wfile.write(rtext)
class httpServer(tlslite.api.TLSSocketServerMixIn, BaseHTTPServer.HTTPServer):
rpki_certChain = None # Must be set
rpki_privateKey = None # Must be set
rpki_sessionCache = None # Must be set
def handshake(self, tlsConnection):
try:
assert sessionCache
tlsConnection.handshakeServer(certChain=self.rpki_certChain,
privateKey=self.rpki_privateKey,
sessionCache=self.rpki_sessionCache)
tlsConnection.ignoreAbruptClose = True
return True
except tlslite.api.TLSError, error:
print "TLS handshake failure:", str(error)
return False
def server(handler=None, port=4433, privateKey=None, certChain=None, **kwargs):
# BaseHTTPServer.HTTPServer takes a class, not an instance, so
# binding our handler requires creating a new subclass. Weird.
class boundRequestHandler(requestHandler):
rpki_handler = handler
httpd = httpServer(("", 4433), boundRequestHandler)
httpd.rpki_privateKey = privateKey
httpd.rpki_certChain = certChain
httpd.rpki_sessionCache = tlslite.api.SessionCache()
httpd.serve_forever()
|