OLD | NEW |
1 #! python | 1 #!/usr/bin/env python |
2 | 2 |
| 3 # Authors: |
| 4 # Trevor Perrin |
| 5 # Marcelo Fernandez - bugfix and NPN support |
| 6 # Martin von Loewis - python 3 port |
| 7 # |
| 8 # See the LICENSE file for legal information regarding use of this file. |
| 9 from __future__ import print_function |
3 import sys | 10 import sys |
4 import os | 11 import os |
5 import os.path | 12 import os.path |
6 import socket | 13 import socket |
7 import thread | |
8 import time | 14 import time |
9 import httplib | 15 import getopt |
10 import BaseHTTPServer | |
11 import SimpleHTTPServer | |
12 | |
13 | |
14 try: | 16 try: |
15 from cryptoIDlib.api import * | 17 import httplib |
16 cryptoIDlibLoaded = True | 18 from SocketServer import * |
17 except: | 19 from BaseHTTPServer import * |
18 cryptoIDlibLoaded = False | 20 from SimpleHTTPServer import * |
| 21 except ImportError: |
| 22 # Python 3.x |
| 23 from http import client as httplib |
| 24 from socketserver import * |
| 25 from http.server import * |
19 | 26 |
20 if __name__ != "__main__": | 27 if __name__ != "__main__": |
21 raise "This must be run as a command, not used as a module!" | 28 raise "This must be run as a command, not used as a module!" |
22 | 29 |
23 #import tlslite | |
24 #from tlslite.constants import AlertDescription, Fault | |
25 | |
26 #from tlslite.utils.jython_compat import formatExceptionTrace | |
27 #from tlslite.X509 import X509, X509CertChain | |
28 | |
29 from tlslite.api import * | 30 from tlslite.api import * |
30 | 31 from tlslite import __version__ |
31 def parsePrivateKey(s): | 32 |
| 33 try: |
| 34 from tack.structures.Tack import Tack |
| 35 |
| 36 except ImportError: |
| 37 pass |
| 38 |
| 39 def printUsage(s=None): |
| 40 if s: |
| 41 print("ERROR: %s" % s) |
| 42 |
| 43 print("") |
| 44 print("Version: %s" % __version__) |
| 45 print("") |
| 46 print("RNG: %s" % prngName) |
| 47 print("") |
| 48 print("Modules:") |
| 49 if tackpyLoaded: |
| 50 print(" tackpy : Loaded") |
| 51 else: |
| 52 print(" tackpy : Not Loaded") |
| 53 if m2cryptoLoaded: |
| 54 print(" M2Crypto : Loaded") |
| 55 else: |
| 56 print(" M2Crypto : Not Loaded") |
| 57 if pycryptoLoaded: |
| 58 print(" pycrypto : Loaded") |
| 59 else: |
| 60 print(" pycrypto : Not Loaded") |
| 61 if gmpyLoaded: |
| 62 print(" GMPY : Loaded") |
| 63 else: |
| 64 print(" GMPY : Not Loaded") |
| 65 |
| 66 print("") |
| 67 print("""Commands: |
| 68 |
| 69 server |
| 70 [-k KEY] [-c CERT] [-t TACK] [-v VERIFIERDB] [-d DIR] |
| 71 [--reqcert] HOST:PORT |
| 72 |
| 73 client |
| 74 [-k KEY] [-c CERT] [-u USER] [-p PASS] |
| 75 HOST:PORT |
| 76 """) |
| 77 sys.exit(-1) |
| 78 |
| 79 def printError(s): |
| 80 """Print error message and exit""" |
| 81 sys.stderr.write("ERROR: %s\n" % s) |
| 82 sys.exit(-1) |
| 83 |
| 84 |
| 85 def handleArgs(argv, argString, flagsList=[]): |
| 86 # Convert to getopt argstring format: |
| 87 # Add ":" after each arg, ie "abc" -> "a:b:c:" |
| 88 getOptArgString = ":".join(argString) + ":" |
32 try: | 89 try: |
33 return parsePEMKey(s, private=True) | 90 opts, argv = getopt.getopt(argv, getOptArgString, flagsList) |
34 except Exception, e: | 91 except getopt.GetoptError as e: |
35 print e | 92 printError(e) |
36 return parseXMLKey(s, private=True) | 93 # Default values if arg not present |
37 | 94 privateKey = None |
38 | 95 certChain = None |
39 def clientTest(address, dir): | 96 username = None |
40 | 97 password = None |
| 98 tacks = None |
| 99 verifierDB = None |
| 100 reqCert = False |
| 101 directory = None |
| 102 |
| 103 for opt, arg in opts: |
| 104 if opt == "-k": |
| 105 s = open(arg, "rb").read() |
| 106 privateKey = parsePEMKey(s, private=True) |
| 107 elif opt == "-c": |
| 108 s = open(arg, "rb").read() |
| 109 x509 = X509() |
| 110 x509.parse(s) |
| 111 certChain = X509CertChain([x509]) |
| 112 elif opt == "-u": |
| 113 username = arg |
| 114 elif opt == "-p": |
| 115 password = arg |
| 116 elif opt == "-t": |
| 117 if tackpyLoaded: |
| 118 s = open(arg, "rU").read() |
| 119 tacks = Tack.createFromPemList(s) |
| 120 elif opt == "-v": |
| 121 verifierDB = VerifierDB(arg) |
| 122 verifierDB.open() |
| 123 elif opt == "-d": |
| 124 directory = arg |
| 125 elif opt == "--reqcert": |
| 126 reqCert = True |
| 127 else: |
| 128 assert(False) |
| 129 |
| 130 if not argv: |
| 131 printError("Missing address") |
| 132 if len(argv)>1: |
| 133 printError("Too many arguments") |
41 #Split address into hostname/port tuple | 134 #Split address into hostname/port tuple |
| 135 address = argv[0] |
42 address = address.split(":") | 136 address = address.split(":") |
43 if len(address)==1: | 137 if len(address) != 2: |
44 address.append("4443") | 138 raise SyntaxError("Must specify <host>:<port>") |
45 address = ( address[0], int(address[1]) ) | 139 address = ( address[0], int(address[1]) ) |
46 | 140 |
47 def connect(): | 141 # Populate the return list |
48 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | 142 retList = [address] |
49 if hasattr(sock, 'settimeout'): #It's a python 2.3 feature | 143 if "k" in argString: |
50 sock.settimeout(5) | 144 retList.append(privateKey) |
51 sock.connect(address) | 145 if "c" in argString: |
52 c = TLSConnection(sock) | 146 retList.append(certChain) |
53 return c | 147 if "u" in argString: |
54 | 148 retList.append(username) |
55 test = 0 | 149 if "p" in argString: |
56 | 150 retList.append(password) |
57 badFault = False | 151 if "t" in argString: |
58 | 152 retList.append(tacks) |
59 print "Test 1 - good shared key" | 153 if "v" in argString: |
60 connection = connect() | 154 retList.append(verifierDB) |
61 connection.handshakeClientSharedKey("shared", "key") | 155 if "d" in argString: |
| 156 retList.append(directory) |
| 157 if "reqcert" in flagsList: |
| 158 retList.append(reqCert) |
| 159 return retList |
| 160 |
| 161 |
| 162 def printGoodConnection(connection, seconds): |
| 163 print(" Handshake time: %.3f seconds" % seconds) |
| 164 print(" Version: %s" % connection.getVersionName()) |
| 165 print(" Cipher: %s %s" % (connection.getCipherName(), |
| 166 connection.getCipherImplementation())) |
| 167 if connection.session.srpUsername: |
| 168 print(" Client SRP username: %s" % connection.session.srpUsername) |
| 169 if connection.session.clientCertChain: |
| 170 print(" Client X.509 SHA1 fingerprint: %s" % |
| 171 connection.session.clientCertChain.getFingerprint()) |
| 172 if connection.session.serverCertChain: |
| 173 print(" Server X.509 SHA1 fingerprint: %s" % |
| 174 connection.session.serverCertChain.getFingerprint()) |
| 175 if connection.session.serverName: |
| 176 print(" SNI: %s" % connection.session.serverName) |
| 177 if connection.session.tackExt: |
| 178 if connection.session.tackInHelloExt: |
| 179 emptyStr = "\n (via TLS Extension)" |
| 180 else: |
| 181 emptyStr = "\n (via TACK Certificate)" |
| 182 print(" TACK: %s" % emptyStr) |
| 183 print(str(connection.session.tackExt)) |
| 184 print(" Next-Protocol Negotiated: %s" % connection.next_proto) |
| 185 |
| 186 |
| 187 def clientCmd(argv): |
| 188 (address, privateKey, certChain, username, password) = \ |
| 189 handleArgs(argv, "kcup") |
| 190 |
| 191 if (certChain and not privateKey) or (not certChain and privateKey): |
| 192 raise SyntaxError("Must specify CERT and KEY together") |
| 193 if (username and not password) or (not username and password): |
| 194 raise SyntaxError("Must specify USER with PASS") |
| 195 if certChain and username: |
| 196 raise SyntaxError("Can use SRP or client cert for auth, not both") |
| 197 |
| 198 #Connect to server |
| 199 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
| 200 sock.settimeout(5) |
| 201 sock.connect(address) |
| 202 connection = TLSConnection(sock) |
| 203 |
| 204 settings = HandshakeSettings() |
| 205 settings.useExperimentalTackExtension = True |
| 206 |
| 207 try: |
| 208 start = time.clock() |
| 209 if username and password: |
| 210 connection.handshakeClientSRP(username, password, |
| 211 settings=settings, serverName=address[0]) |
| 212 else: |
| 213 connection.handshakeClientCert(certChain, privateKey, |
| 214 settings=settings, serverName=address[0]) |
| 215 stop = time.clock() |
| 216 print("Handshake success") |
| 217 except TLSLocalAlert as a: |
| 218 if a.description == AlertDescription.user_canceled: |
| 219 print(str(a)) |
| 220 else: |
| 221 raise |
| 222 sys.exit(-1) |
| 223 except TLSRemoteAlert as a: |
| 224 if a.description == AlertDescription.unknown_psk_identity: |
| 225 if username: |
| 226 print("Unknown username") |
| 227 else: |
| 228 raise |
| 229 elif a.description == AlertDescription.bad_record_mac: |
| 230 if username: |
| 231 print("Bad username or password") |
| 232 else: |
| 233 raise |
| 234 elif a.description == AlertDescription.handshake_failure: |
| 235 print("Unable to negotiate mutually acceptable parameters") |
| 236 else: |
| 237 raise |
| 238 sys.exit(-1) |
| 239 printGoodConnection(connection, stop-start) |
62 connection.close() | 240 connection.close() |
63 connection.sock.close() | 241 |
64 | 242 |
65 print "Test 2 - shared key faults" | 243 def serverCmd(argv): |
66 for fault in Fault.clientSharedKeyFaults + Fault.genericFaults: | 244 (address, privateKey, certChain, tacks, |
67 connection = connect() | 245 verifierDB, directory, reqCert) = handleArgs(argv, "kctbvd", ["reqcert"]
) |
68 connection.fault = fault | 246 |
69 try: | 247 |
70 connection.handshakeClientSharedKey("shared", "key") | 248 if (certChain and not privateKey) or (not certChain and privateKey): |
71 print " Good Fault %s" % (Fault.faultNames[fault]) | 249 raise SyntaxError("Must specify CERT and KEY together") |
72 except TLSFaultError, e: | 250 if tacks and not certChain: |
73 print " BAD FAULT %s: %s" % (Fault.faultNames[fault], str(e)) | 251 raise SyntaxError("Must specify CERT with Tacks") |
74 badFault = True | 252 |
75 connection.sock.close() | 253 print("I am an HTTPS test server, I will listen on %s:%d" % |
76 | 254 (address[0], address[1])) |
77 print "Test 3 - good SRP" | 255 if directory: |
78 connection = connect() | 256 os.chdir(directory) |
79 connection.handshakeClientSRP("test", "password") | 257 print("Serving files from %s" % os.getcwd()) |
80 connection.close() | 258 |
81 | 259 if certChain and privateKey: |
82 print "Test 4 - SRP faults" | 260 print("Using certificate and private key...") |
83 for fault in Fault.clientSrpFaults + Fault.genericFaults: | 261 if verifierDB: |
84 connection = connect() | 262 print("Using verifier DB...") |
85 connection.fault = fault | 263 if tacks: |
86 try: | 264 print("Using Tacks...") |
87 connection.handshakeClientSRP("test", "password") | 265 |
88 print " Good Fault %s" % (Fault.faultNames[fault]) | 266 ############# |
89 except TLSFaultError, e: | 267 sessionCache = SessionCache() |
90 print " BAD FAULT %s: %s" % (Fault.faultNames[fault], str(e)) | 268 |
91 badFault = True | 269 class MyHTTPServer(ThreadingMixIn, TLSSocketServerMixIn, HTTPServer): |
92 connection.sock.close() | 270 def handshake(self, connection): |
93 | 271 print("About to handshake...") |
94 print "Test 5 - good SRP: unknown_srp_username idiom" | 272 activationFlags = 0 |
95 def srpCallback(): | 273 if tacks: |
96 return ("test", "password") | 274 if len(tacks) == 1: |
97 connection = connect() | 275 activationFlags = 1 |
98 connection.handshakeClientUnknown(srpCallback=srpCallback) | 276 elif len(tacks) == 2: |
99 connection.close() | 277 activationFlags = 3 |
100 connection.sock.close() | 278 |
101 | |
102 print "Test 6 - good SRP: with X.509 certificate" | |
103 connection = connect() | |
104 connection.handshakeClientSRP("test", "password") | |
105 assert(isinstance(connection.session.serverCertChain, X509CertChain)) | |
106 connection.close() | |
107 connection.sock.close() | |
108 | |
109 print "Test 7 - X.509 with SRP faults" | |
110 for fault in Fault.clientSrpFaults + Fault.genericFaults: | |
111 connection = connect() | |
112 connection.fault = fault | |
113 try: | |
114 connection.handshakeClientSRP("test", "password") | |
115 print " Good Fault %s" % (Fault.faultNames[fault]) | |
116 except TLSFaultError, e: | |
117 print " BAD FAULT %s: %s" % (Fault.faultNames[fault], str(e)) | |
118 badFault = True | |
119 connection.sock.close() | |
120 | |
121 if cryptoIDlibLoaded: | |
122 print "Test 8 - good SRP: with cryptoID certificate chain" | |
123 connection = connect() | |
124 connection.handshakeClientSRP("test", "password") | |
125 assert(isinstance(connection.session.serverCertChain, CertChain)) | |
126 if not (connection.session.serverCertChain.validate()): | |
127 print connection.session.serverCertChain.validate(listProblems=True) | |
128 | |
129 connection.close() | |
130 connection.sock.close() | |
131 | |
132 print "Test 9 - CryptoID with SRP faults" | |
133 for fault in Fault.clientSrpFaults + Fault.genericFaults: | |
134 connection = connect() | |
135 connection.fault = fault | |
136 try: | 279 try: |
137 connection.handshakeClientSRP("test", "password") | |
138 print " Good Fault %s" % (Fault.faultNames[fault]) | |
139 except TLSFaultError, e: | |
140 print " BAD FAULT %s: %s" % (Fault.faultNames[fault], str(e)) | |
141 badFault = True | |
142 connection.sock.close() | |
143 | |
144 print "Test 10 - good X509" | |
145 connection = connect() | |
146 connection.handshakeClientCert() | |
147 assert(isinstance(connection.session.serverCertChain, X509CertChain)) | |
148 connection.close() | |
149 connection.sock.close() | |
150 | |
151 print "Test 10.a - good X509, SSLv3" | |
152 connection = connect() | |
153 settings = HandshakeSettings() | |
154 settings.minVersion = (3,0) | |
155 settings.maxVersion = (3,0) | |
156 connection.handshakeClientCert(settings=settings) | |
157 assert(isinstance(connection.session.serverCertChain, X509CertChain)) | |
158 connection.close() | |
159 connection.sock.close() | |
160 | |
161 print "Test 11 - X.509 faults" | |
162 for fault in Fault.clientNoAuthFaults + Fault.genericFaults: | |
163 connection = connect() | |
164 connection.fault = fault | |
165 try: | |
166 connection.handshakeClientCert() | |
167 print " Good Fault %s" % (Fault.faultNames[fault]) | |
168 except TLSFaultError, e: | |
169 print " BAD FAULT %s: %s" % (Fault.faultNames[fault], str(e)) | |
170 badFault = True | |
171 connection.sock.close() | |
172 | |
173 if cryptoIDlibLoaded: | |
174 print "Test 12 - good cryptoID" | |
175 connection = connect() | |
176 connection.handshakeClientCert() | |
177 assert(isinstance(connection.session.serverCertChain, CertChain)) | |
178 assert(connection.session.serverCertChain.validate()) | |
179 connection.close() | |
180 connection.sock.close() | |
181 | |
182 print "Test 13 - cryptoID faults" | |
183 for fault in Fault.clientNoAuthFaults + Fault.genericFaults: | |
184 connection = connect() | |
185 connection.fault = fault | |
186 try: | |
187 connection.handshakeClientCert() | |
188 print " Good Fault %s" % (Fault.faultNames[fault]) | |
189 except TLSFaultError, e: | |
190 print " BAD FAULT %s: %s" % (Fault.faultNames[fault], str(e)) | |
191 badFault = True | |
192 connection.sock.close() | |
193 | |
194 print "Test 14 - good mutual X509" | |
195 x509Cert = X509().parse(open(os.path.join(dir, "clientX509Cert.pem")).read()
) | |
196 x509Chain = X509CertChain([x509Cert]) | |
197 s = open(os.path.join(dir, "clientX509Key.pem")).read() | |
198 x509Key = parsePEMKey(s, private=True) | |
199 | |
200 connection = connect() | |
201 connection.handshakeClientCert(x509Chain, x509Key) | |
202 assert(isinstance(connection.session.serverCertChain, X509CertChain)) | |
203 connection.close() | |
204 connection.sock.close() | |
205 | |
206 print "Test 14.a - good mutual X509, SSLv3" | |
207 connection = connect() | |
208 settings = HandshakeSettings() | |
209 settings.minVersion = (3,0) | |
210 settings.maxVersion = (3,0) | |
211 connection.handshakeClientCert(x509Chain, x509Key, settings=settings) | |
212 assert(isinstance(connection.session.serverCertChain, X509CertChain)) | |
213 connection.close() | |
214 connection.sock.close() | |
215 | |
216 print "Test 15 - mutual X.509 faults" | |
217 for fault in Fault.clientCertFaults + Fault.genericFaults: | |
218 connection = connect() | |
219 connection.fault = fault | |
220 try: | |
221 connection.handshakeClientCert(x509Chain, x509Key) | |
222 print " Good Fault %s" % (Fault.faultNames[fault]) | |
223 except TLSFaultError, e: | |
224 print " BAD FAULT %s: %s" % (Fault.faultNames[fault], str(e)) | |
225 badFault = True | |
226 connection.sock.close() | |
227 | |
228 if cryptoIDlibLoaded: | |
229 print "Test 16 - good mutual cryptoID" | |
230 cryptoIDChain = CertChain().parse(open(os.path.join(dir, "serverCryptoID
Chain.xml"), "r").read()) | |
231 cryptoIDKey = parseXMLKey(open(os.path.join(dir, "serverCryptoIDKey.xml"
), "r").read(), private=True) | |
232 | |
233 connection = connect() | |
234 connection.handshakeClientCert(cryptoIDChain, cryptoIDKey) | |
235 assert(isinstance(connection.session.serverCertChain, CertChain)) | |
236 assert(connection.session.serverCertChain.validate()) | |
237 connection.close() | |
238 connection.sock.close() | |
239 | |
240 print "Test 17 - mutual cryptoID faults" | |
241 for fault in Fault.clientCertFaults + Fault.genericFaults: | |
242 connection = connect() | |
243 connection.fault = fault | |
244 try: | |
245 connection.handshakeClientCert(cryptoIDChain, cryptoIDKey) | |
246 print " Good Fault %s" % (Fault.faultNames[fault]) | |
247 except TLSFaultError, e: | |
248 print " BAD FAULT %s: %s" % (Fault.faultNames[fault], str(e)) | |
249 badFault = True | |
250 connection.sock.close() | |
251 | |
252 print "Test 18 - good SRP, prepare to resume..." | |
253 connection = connect() | |
254 connection.handshakeClientSRP("test", "password") | |
255 connection.close() | |
256 connection.sock.close() | |
257 session = connection.session | |
258 | |
259 print "Test 19 - resumption" | |
260 connection = connect() | |
261 connection.handshakeClientSRP("test", "garbage", session=session) | |
262 #Don't close! -- see below | |
263 | |
264 print "Test 20 - invalidated resumption" | |
265 connection.sock.close() #Close the socket without a close_notify! | |
266 connection = connect() | |
267 try: | |
268 connection.handshakeClientSRP("test", "garbage", session=session) | |
269 assert() | |
270 except TLSRemoteAlert, alert: | |
271 if alert.description != AlertDescription.bad_record_mac: | |
272 raise | |
273 connection.sock.close() | |
274 | |
275 print "Test 21 - HTTPS test X.509" | |
276 address = address[0], address[1]+1 | |
277 if hasattr(socket, "timeout"): | |
278 timeoutEx = socket.timeout | |
279 else: | |
280 timeoutEx = socket.error | |
281 while 1: | |
282 try: | |
283 time.sleep(2) | |
284 htmlBody = open(os.path.join(dir, "index.html")).read() | |
285 fingerprint = None | |
286 for y in range(2): | |
287 h = HTTPTLSConnection(\ | |
288 address[0], address[1], x509Fingerprint=fingerprint) | |
289 for x in range(3): | |
290 h.request("GET", "/index.html") | |
291 r = h.getresponse() | |
292 assert(r.status == 200) | |
293 s = r.read() | |
294 assert(s == htmlBody) | |
295 fingerprint = h.tlsSession.serverCertChain.getFingerprint() | |
296 assert(fingerprint) | |
297 time.sleep(2) | |
298 break | |
299 except timeoutEx: | |
300 print "timeout, retrying..." | |
301 pass | |
302 | |
303 if cryptoIDlibLoaded: | |
304 print "Test 21a - HTTPS test SRP+cryptoID" | |
305 address = address[0], address[1]+1 | |
306 if hasattr(socket, "timeout"): | |
307 timeoutEx = socket.timeout | |
308 else: | |
309 timeoutEx = socket.error | |
310 while 1: | |
311 try: | |
312 time.sleep(2) #Time to generate key and cryptoID | |
313 htmlBody = open(os.path.join(dir, "index.html")).read() | |
314 fingerprint = None | |
315 protocol = None | |
316 for y in range(2): | |
317 h = HTTPTLSConnection(\ | |
318 address[0], address[1], | |
319 username="test", password="password", | |
320 cryptoID=fingerprint, protocol=protocol) | |
321 for x in range(3): | |
322 h.request("GET", "/index.html") | |
323 r = h.getresponse() | |
324 assert(r.status == 200) | |
325 s = r.read() | |
326 assert(s == htmlBody) | |
327 fingerprint = h.tlsSession.serverCertChain.cryptoID | |
328 assert(fingerprint) | |
329 protocol = "urn:whatever" | |
330 time.sleep(2) | |
331 break | |
332 except timeoutEx: | |
333 print "timeout, retrying..." | |
334 pass | |
335 | |
336 address = address[0], address[1]+1 | |
337 | |
338 implementations = [] | |
339 if cryptlibpyLoaded: | |
340 implementations.append("cryptlib") | |
341 if m2cryptoLoaded: | |
342 implementations.append("openssl") | |
343 if pycryptoLoaded: | |
344 implementations.append("pycrypto") | |
345 implementations.append("python") | |
346 | |
347 print "Test 22 - different ciphers" | |
348 for implementation in implementations: | |
349 for cipher in ["aes128", "aes256", "rc4"]: | |
350 | |
351 print "Test 22:", | |
352 connection = connect() | |
353 | |
354 settings = HandshakeSettings() | |
355 settings.cipherNames = [cipher] | |
356 settings.cipherImplementations = [implementation, "python"] | |
357 connection.handshakeClientSharedKey("shared", "key", settings=settin
gs) | |
358 print ("%s %s" % (connection.getCipherName(), connection.getCipherIm
plementation())) | |
359 | |
360 connection.write("hello") | |
361 h = connection.read(min=5, max=5) | |
362 assert(h == "hello") | |
363 connection.close() | |
364 connection.sock.close() | |
365 | |
366 print "Test 23 - throughput test" | |
367 for implementation in implementations: | |
368 for cipher in ["aes128", "aes256", "3des", "rc4"]: | |
369 if cipher == "3des" and implementation not in ("openssl", "cryptlib"
, "pycrypto"): | |
370 continue | |
371 | |
372 print "Test 23:", | |
373 connection = connect() | |
374 | |
375 settings = HandshakeSettings() | |
376 settings.cipherNames = [cipher] | |
377 settings.cipherImplementations = [implementation, "python"] | |
378 connection.handshakeClientSharedKey("shared", "key", settings=settin
gs) | |
379 print ("%s %s:" % (connection.getCipherName(), connection.getCipherI
mplementation())), | |
380 | |
381 startTime = time.clock() | |
382 connection.write("hello"*10000) | |
383 h = connection.read(min=50000, max=50000) | |
384 stopTime = time.clock() | |
385 print "100K exchanged at rate of %d bytes/sec" % int(100000/(stopTim
e-startTime)) | |
386 | |
387 assert(h == "hello"*10000) | |
388 connection.close() | |
389 connection.sock.close() | |
390 | |
391 print "Test 24 - Internet servers test" | |
392 try: | |
393 i = IMAP4_TLS("cyrus.andrew.cmu.edu") | |
394 i.login("anonymous", "anonymous@anonymous.net") | |
395 i.logout() | |
396 print "Test 24: IMAP4 good" | |
397 p = POP3_TLS("pop.gmail.com") | |
398 p.quit() | |
399 print "Test 24: POP3 good" | |
400 except socket.error, e: | |
401 print "Non-critical error: socket error trying to reach internet server:
", e | |
402 | |
403 if not badFault: | |
404 print "Test succeeded" | |
405 else: | |
406 print "Test failed" | |
407 | |
408 | |
409 def serverTest(address, dir): | |
410 #Split address into hostname/port tuple | |
411 address = address.split(":") | |
412 if len(address)==1: | |
413 address.append("4443") | |
414 address = ( address[0], int(address[1]) ) | |
415 | |
416 #Connect to server | |
417 lsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
418 lsock.bind(address) | |
419 lsock.listen(5) | |
420 | |
421 def connect(): | |
422 return TLSConnection(lsock.accept()[0]) | |
423 | |
424 print "Test 1 - good shared key" | |
425 sharedKeyDB = SharedKeyDB() | |
426 sharedKeyDB["shared"] = "key" | |
427 sharedKeyDB["shared2"] = "key2" | |
428 connection = connect() | |
429 connection.handshakeServer(sharedKeyDB=sharedKeyDB) | |
430 connection.close() | |
431 connection.sock.close() | |
432 | |
433 print "Test 2 - shared key faults" | |
434 for fault in Fault.clientSharedKeyFaults + Fault.genericFaults: | |
435 connection = connect() | |
436 connection.fault = fault | |
437 try: | |
438 connection.handshakeServer(sharedKeyDB=sharedKeyDB) | |
439 assert() | |
440 except: | |
441 pass | |
442 connection.sock.close() | |
443 | |
444 print "Test 3 - good SRP" | |
445 #verifierDB = tlslite.VerifierDB(os.path.join(dir, "verifierDB")) | |
446 #verifierDB.open() | |
447 verifierDB = VerifierDB() | |
448 verifierDB.create() | |
449 entry = VerifierDB.makeVerifier("test", "password", 1536) | |
450 verifierDB["test"] = entry | |
451 | |
452 connection = connect() | |
453 connection.handshakeServer(verifierDB=verifierDB) | |
454 connection.close() | |
455 connection.sock.close() | |
456 | |
457 print "Test 4 - SRP faults" | |
458 for fault in Fault.clientSrpFaults + Fault.genericFaults: | |
459 connection = connect() | |
460 connection.fault = fault | |
461 try: | |
462 connection.handshakeServer(verifierDB=verifierDB) | |
463 assert() | |
464 except: | |
465 pass | |
466 connection.sock.close() | |
467 | |
468 print "Test 5 - good SRP: unknown_srp_username idiom" | |
469 connection = connect() | |
470 connection.handshakeServer(verifierDB=verifierDB) | |
471 connection.close() | |
472 connection.sock.close() | |
473 | |
474 print "Test 6 - good SRP: with X.509 cert" | |
475 x509Cert = X509().parse(open(os.path.join(dir, "serverX509Cert.pem")).read()
) | |
476 x509Chain = X509CertChain([x509Cert]) | |
477 s = open(os.path.join(dir, "serverX509Key.pem")).read() | |
478 x509Key = parsePEMKey(s, private=True) | |
479 | |
480 connection = connect() | |
481 connection.handshakeServer(verifierDB=verifierDB, \ | |
482 certChain=x509Chain, privateKey=x509Key) | |
483 connection.close() | |
484 connection.sock.close() | |
485 | |
486 print "Test 7 - X.509 with SRP faults" | |
487 for fault in Fault.clientSrpFaults + Fault.genericFaults: | |
488 connection = connect() | |
489 connection.fault = fault | |
490 try: | |
491 connection.handshakeServer(verifierDB=verifierDB, \ | |
492 certChain=x509Chain, privateKey=x509Key) | |
493 assert() | |
494 except: | |
495 pass | |
496 connection.sock.close() | |
497 | |
498 if cryptoIDlibLoaded: | |
499 print "Test 8 - good SRP: with cryptoID certs" | |
500 cryptoIDChain = CertChain().parse(open(os.path.join(dir, "serverCryptoID
Chain.xml"), "r").read()) | |
501 cryptoIDKey = parseXMLKey(open(os.path.join(dir, "serverCryptoIDKey.xml"
), "r").read(), private=True) | |
502 connection = connect() | |
503 connection.handshakeServer(verifierDB=verifierDB, \ | |
504 certChain=cryptoIDChain, privateKey=cryptoIDK
ey) | |
505 connection.close() | |
506 connection.sock.close() | |
507 | |
508 print "Test 9 - cryptoID with SRP faults" | |
509 for fault in Fault.clientSrpFaults + Fault.genericFaults: | |
510 connection = connect() | |
511 connection.fault = fault | |
512 try: | |
513 connection.handshakeServer(verifierDB=verifierDB, \ | |
514 certChain=cryptoIDChain, privateKey=c
ryptoIDKey) | |
515 assert() | |
516 except: | |
517 pass | |
518 connection.sock.close() | |
519 | |
520 print "Test 10 - good X.509" | |
521 connection = connect() | |
522 connection.handshakeServer(certChain=x509Chain, privateKey=x509Key) | |
523 connection.close() | |
524 connection.sock.close() | |
525 | |
526 print "Test 10.a - good X.509, SSL v3" | |
527 connection = connect() | |
528 settings = HandshakeSettings() | |
529 settings.minVersion = (3,0) | |
530 settings.maxVersion = (3,0) | |
531 connection.handshakeServer(certChain=x509Chain, privateKey=x509Key, settings
=settings) | |
532 connection.close() | |
533 connection.sock.close() | |
534 | |
535 print "Test 11 - X.509 faults" | |
536 for fault in Fault.clientNoAuthFaults + Fault.genericFaults: | |
537 connection = connect() | |
538 connection.fault = fault | |
539 try: | |
540 connection.handshakeServer(certChain=x509Chain, privateKey=x509Key) | |
541 assert() | |
542 except: | |
543 pass | |
544 connection.sock.close() | |
545 | |
546 if cryptoIDlibLoaded: | |
547 print "Test 12 - good cryptoID" | |
548 connection = connect() | |
549 connection.handshakeServer(certChain=cryptoIDChain, privateKey=cryptoIDK
ey) | |
550 connection.close() | |
551 connection.sock.close() | |
552 | |
553 print "Test 13 - cryptoID faults" | |
554 for fault in Fault.clientNoAuthFaults + Fault.genericFaults: | |
555 connection = connect() | |
556 connection.fault = fault | |
557 try: | |
558 connection.handshakeServer(certChain=cryptoIDChain, privateKey=c
ryptoIDKey) | |
559 assert() | |
560 except: | |
561 pass | |
562 connection.sock.close() | |
563 | |
564 print "Test 14 - good mutual X.509" | |
565 connection = connect() | |
566 connection.handshakeServer(certChain=x509Chain, privateKey=x509Key, reqCert=
True) | |
567 assert(isinstance(connection.session.serverCertChain, X509CertChain)) | |
568 connection.close() | |
569 connection.sock.close() | |
570 | |
571 print "Test 14a - good mutual X.509, SSLv3" | |
572 connection = connect() | |
573 settings = HandshakeSettings() | |
574 settings.minVersion = (3,0) | |
575 settings.maxVersion = (3,0) | |
576 connection.handshakeServer(certChain=x509Chain, privateKey=x509Key, reqCert=
True, settings=settings) | |
577 assert(isinstance(connection.session.serverCertChain, X509CertChain)) | |
578 connection.close() | |
579 connection.sock.close() | |
580 | |
581 print "Test 15 - mutual X.509 faults" | |
582 for fault in Fault.clientCertFaults + Fault.genericFaults: | |
583 connection = connect() | |
584 connection.fault = fault | |
585 try: | |
586 connection.handshakeServer(certChain=x509Chain, privateKey=x509Key,
reqCert=True) | |
587 assert() | |
588 except: | |
589 pass | |
590 connection.sock.close() | |
591 | |
592 if cryptoIDlibLoaded: | |
593 print "Test 16 - good mutual cryptoID" | |
594 connection = connect() | |
595 connection.handshakeServer(certChain=cryptoIDChain, privateKey=cryptoIDK
ey, reqCert=True) | |
596 assert(isinstance(connection.session.serverCertChain, CertChain)) | |
597 assert(connection.session.serverCertChain.validate()) | |
598 connection.close() | |
599 connection.sock.close() | |
600 | |
601 print "Test 17 - mutual cryptoID faults" | |
602 for fault in Fault.clientCertFaults + Fault.genericFaults: | |
603 connection = connect() | |
604 connection.fault = fault | |
605 try: | |
606 connection.handshakeServer(certChain=cryptoIDChain, privateKey=c
ryptoIDKey, reqCert=True) | |
607 assert() | |
608 except: | |
609 pass | |
610 connection.sock.close() | |
611 | |
612 print "Test 18 - good SRP, prepare to resume" | |
613 sessionCache = SessionCache() | |
614 connection = connect() | |
615 connection.handshakeServer(verifierDB=verifierDB, sessionCache=sessionCache) | |
616 connection.close() | |
617 connection.sock.close() | |
618 | |
619 print "Test 19 - resumption" | |
620 connection = connect() | |
621 connection.handshakeServer(verifierDB=verifierDB, sessionCache=sessionCache) | |
622 #Don't close! -- see next test | |
623 | |
624 print "Test 20 - invalidated resumption" | |
625 try: | |
626 connection.read(min=1, max=1) | |
627 assert() #Client is going to close the socket without a close_notify | |
628 except TLSAbruptCloseError, e: | |
629 pass | |
630 connection = connect() | |
631 try: | |
632 connection.handshakeServer(verifierDB=verifierDB, sessionCache=sessionCa
che) | |
633 except TLSLocalAlert, alert: | |
634 if alert.description != AlertDescription.bad_record_mac: | |
635 raise | |
636 connection.sock.close() | |
637 | |
638 print "Test 21 - HTTPS test X.509" | |
639 | |
640 #Close the current listening socket | |
641 lsock.close() | |
642 | |
643 #Create and run an HTTP Server using TLSSocketServerMixIn | |
644 class MyHTTPServer(TLSSocketServerMixIn, | |
645 BaseHTTPServer.HTTPServer): | |
646 def handshake(self, tlsConnection): | |
647 tlsConnection.handshakeServer(certChain=x509Chain, privateKey=x5
09Key) | |
648 return True | |
649 cd = os.getcwd() | |
650 os.chdir(dir) | |
651 address = address[0], address[1]+1 | |
652 httpd = MyHTTPServer(address, SimpleHTTPServer.SimpleHTTPRequestHandler) | |
653 for x in range(6): | |
654 httpd.handle_request() | |
655 httpd.server_close() | |
656 cd = os.chdir(cd) | |
657 | |
658 if cryptoIDlibLoaded: | |
659 print "Test 21a - HTTPS test SRP+cryptoID" | |
660 | |
661 #Create and run an HTTP Server using TLSSocketServerMixIn | |
662 class MyHTTPServer(TLSSocketServerMixIn, | |
663 BaseHTTPServer.HTTPServer): | |
664 def handshake(self, tlsConnection): | |
665 tlsConnection.handshakeServer(certChain=cryptoIDChain, priva
teKey=cryptoIDKey, | |
666 verifierDB=verifierDB) | |
667 return True | |
668 cd = os.getcwd() | |
669 os.chdir(dir) | |
670 address = address[0], address[1]+1 | |
671 httpd = MyHTTPServer(address, SimpleHTTPServer.SimpleHTTPRequestHandler) | |
672 for x in range(6): | |
673 httpd.handle_request() | |
674 httpd.server_close() | |
675 cd = os.chdir(cd) | |
676 | |
677 #Re-connect the listening socket | |
678 lsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
679 address = address[0], address[1]+1 | |
680 lsock.bind(address) | |
681 lsock.listen(5) | |
682 | |
683 def connect(): | |
684 return TLSConnection(lsock.accept()[0]) | |
685 | |
686 implementations = [] | |
687 if cryptlibpyLoaded: | |
688 implementations.append("cryptlib") | |
689 if m2cryptoLoaded: | |
690 implementations.append("openssl") | |
691 if pycryptoLoaded: | |
692 implementations.append("pycrypto") | |
693 implementations.append("python") | |
694 | |
695 print "Test 22 - different ciphers" | |
696 for implementation in ["python"] * len(implementations): | |
697 for cipher in ["aes128", "aes256", "rc4"]: | |
698 | |
699 print "Test 22:", | |
700 connection = connect() | |
701 | |
702 settings = HandshakeSettings() | |
703 settings.cipherNames = [cipher] | |
704 settings.cipherImplementations = [implementation, "python"] | |
705 | |
706 connection.handshakeServer(sharedKeyDB=sharedKeyDB, settings=setting
s) | |
707 print connection.getCipherName(), connection.getCipherImplementation
() | |
708 h = connection.read(min=5, max=5) | |
709 assert(h == "hello") | |
710 connection.write(h) | |
711 connection.close() | |
712 connection.sock.close() | |
713 | |
714 print "Test 23 - throughput test" | |
715 for implementation in implementations: | |
716 for cipher in ["aes128", "aes256", "3des", "rc4"]: | |
717 if cipher == "3des" and implementation not in ("openssl", "cryptlib"
, "pycrypto"): | |
718 continue | |
719 | |
720 print "Test 23:", | |
721 connection = connect() | |
722 | |
723 settings = HandshakeSettings() | |
724 settings.cipherNames = [cipher] | |
725 settings.cipherImplementations = [implementation, "python"] | |
726 | |
727 connection.handshakeServer(sharedKeyDB=sharedKeyDB, settings=setting
s) | |
728 print connection.getCipherName(), connection.getCipherImplementation
() | |
729 h = connection.read(min=50000, max=50000) | |
730 assert(h == "hello"*10000) | |
731 connection.write(h) | |
732 connection.close() | |
733 connection.sock.close() | |
734 | |
735 print "Test succeeded" | |
736 | |
737 | |
738 | |
739 | |
740 | |
741 | |
742 | |
743 | |
744 | |
745 | |
746 | |
747 | |
748 if len(sys.argv) == 1 or (len(sys.argv)==2 and sys.argv[1].lower().endswith("hel
p")): | |
749 print "" | |
750 print "Version: 0.3.8" | |
751 print "" | |
752 print "RNG: %s" % prngName | |
753 print "" | |
754 print "Modules:" | |
755 if cryptlibpyLoaded: | |
756 print " cryptlib_py : Loaded" | |
757 else: | |
758 print " cryptlib_py : Not Loaded" | |
759 if m2cryptoLoaded: | |
760 print " M2Crypto : Loaded" | |
761 else: | |
762 print " M2Crypto : Not Loaded" | |
763 if pycryptoLoaded: | |
764 print " pycrypto : Loaded" | |
765 else: | |
766 print " pycrypto : Not Loaded" | |
767 if gmpyLoaded: | |
768 print " GMPY : Loaded" | |
769 else: | |
770 print " GMPY : Not Loaded" | |
771 if cryptoIDlibLoaded: | |
772 print " cryptoIDlib : Loaded" | |
773 else: | |
774 print " cryptoIDlib : Not Loaded" | |
775 print "" | |
776 print "Commands:" | |
777 print "" | |
778 print " clientcert <server> [<chain> <key>]" | |
779 print " clientsharedkey <server> <user> <pass>" | |
780 print " clientsrp <server> <user> <pass>" | |
781 print " clienttest <server> <dir>" | |
782 print "" | |
783 print " serversrp <server> <verifierDB>" | |
784 print " servercert <server> <chain> <key> [req]" | |
785 print " serversrpcert <server> <verifierDB> <chain> <key>" | |
786 print " serversharedkey <server> <sharedkeyDB>" | |
787 print " servertest <server> <dir>" | |
788 sys.exit() | |
789 | |
790 cmd = sys.argv[1].lower() | |
791 | |
792 class Args: | |
793 def __init__(self, argv): | |
794 self.argv = argv | |
795 def get(self, index): | |
796 if len(self.argv)<=index: | |
797 raise SyntaxError("Not enough arguments") | |
798 return self.argv[index] | |
799 def getLast(self, index): | |
800 if len(self.argv)>index+1: | |
801 raise SyntaxError("Too many arguments") | |
802 return self.get(index) | |
803 | |
804 args = Args(sys.argv) | |
805 | |
806 def reformatDocString(s): | |
807 lines = s.splitlines() | |
808 newLines = [] | |
809 for line in lines: | |
810 newLines.append(" " + line.strip()) | |
811 return "\n".join(newLines) | |
812 | |
813 try: | |
814 if cmd == "clienttest": | |
815 address = args.get(2) | |
816 dir = args.getLast(3) | |
817 clientTest(address, dir) | |
818 sys.exit() | |
819 | |
820 elif cmd.startswith("client"): | |
821 address = args.get(2) | |
822 | |
823 #Split address into hostname/port tuple | |
824 address = address.split(":") | |
825 if len(address)==1: | |
826 address.append("4443") | |
827 address = ( address[0], int(address[1]) ) | |
828 | |
829 def connect(): | |
830 #Connect to server | |
831 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
832 if hasattr(sock, "settimeout"): | |
833 sock.settimeout(5) | |
834 sock.connect(address) | |
835 | |
836 #Instantiate TLSConnections | |
837 return TLSConnection(sock) | |
838 | |
839 try: | |
840 if cmd == "clientsrp": | |
841 username = args.get(3) | |
842 password = args.getLast(4) | |
843 connection = connect() | |
844 start = time.clock() | 280 start = time.clock() |
845 connection.handshakeClientSRP(username, password) | 281 settings = HandshakeSettings() |
846 elif cmd == "clientsharedkey": | 282 settings.useExperimentalTackExtension=True |
847 username = args.get(3) | 283 connection.handshakeServer(certChain=certChain, |
848 password = args.getLast(4) | 284 privateKey=privateKey, |
849 connection = connect() | 285 verifierDB=verifierDB, |
850 start = time.clock() | 286 tacks=tacks, |
851 connection.handshakeClientSharedKey(username, password) | 287 activationFlags=activationFlags, |
852 elif cmd == "clientcert": | 288 sessionCache=sessionCache, |
853 certChain = None | 289 settings=settings, |
854 privateKey = None | 290 nextProtos=[b"http/1.1"]) |
855 if len(sys.argv) > 3: | 291 # As an example (does not work her
e): |
856 certFilename = args.get(3) | 292 #nextProtos=[b"spdy/3", b"spdy/2",
b"http/1.1"]) |
857 keyFilename = args.getLast(4) | 293 stop = time.clock() |
858 | 294 except TLSRemoteAlert as a: |
859 s1 = open(certFilename, "rb").read() | 295 if a.description == AlertDescription.user_canceled: |
860 s2 = open(keyFilename, "rb").read() | 296 print(str(a)) |
861 | 297 return False |
862 #Try to create cryptoID cert chain | |
863 if cryptoIDlibLoaded: | |
864 try: | |
865 certChain = CertChain().parse(s1) | |
866 privateKey = parsePrivateKey(s2) | |
867 except: | |
868 certChain = None | |
869 privateKey = None | |
870 | |
871 #Try to create X.509 cert chain | |
872 if not certChain: | |
873 x509 = X509() | |
874 x509.parse(s1) | |
875 certChain = X509CertChain([x509]) | |
876 privateKey = parsePrivateKey(s2) | |
877 | |
878 connection = connect() | |
879 start = time.clock() | |
880 connection.handshakeClientCert(certChain, privateKey) | |
881 else: | |
882 raise SyntaxError("Unknown command") | |
883 | |
884 except TLSLocalAlert, a: | |
885 if a.description == AlertDescription.bad_record_mac: | |
886 if cmd == "clientsharedkey": | |
887 print "Bad sharedkey password" | |
888 else: | 298 else: |
889 raise | 299 raise |
890 elif a.description == AlertDescription.user_canceled: | 300 except TLSLocalAlert as a: |
891 print str(a) | 301 if a.description == AlertDescription.unknown_psk_identity: |
892 else: | 302 if username: |
893 raise | 303 print("Unknown username") |
894 sys.exit() | 304 return False |
895 except TLSRemoteAlert, a: | 305 else: |
896 if a.description == AlertDescription.unknown_srp_username: | 306 raise |
897 if cmd == "clientsrp": | |
898 print "Unknown username" | |
899 else: | |
900 raise | |
901 elif a.description == AlertDescription.bad_record_mac: | |
902 if cmd == "clientsrp": | |
903 print "Bad username or password" | |
904 else: | |
905 raise | |
906 elif a.description == AlertDescription.handshake_failure: | |
907 print "Unable to negotiate mutually acceptable parameters" | |
908 else: | |
909 raise | |
910 sys.exit() | |
911 | |
912 stop = time.clock() | |
913 print "Handshake success" | |
914 print " Handshake time: %.4f seconds" % (stop - start) | |
915 print " Version: %s.%s" % connection.version | |
916 print " Cipher: %s %s" % (connection.getCipherName(), connection.getCip
herImplementation()) | |
917 if connection.session.srpUsername: | |
918 print " Client SRP username: %s" % connection.session.srpUsername | |
919 if connection.session.sharedKeyUsername: | |
920 print " Client shared key username: %s" % connection.session.shared
KeyUsername | |
921 if connection.session.clientCertChain: | |
922 print " Client fingerprint: %s" % connection.session.clientCertChai
n.getFingerprint() | |
923 if connection.session.serverCertChain: | |
924 print " Server fingerprint: %s" % connection.session.serverCertChai
n.getFingerprint() | |
925 connection.close() | |
926 connection.sock.close() | |
927 | |
928 elif cmd.startswith("server"): | |
929 address = args.get(2) | |
930 | |
931 #Split address into hostname/port tuple | |
932 address = address.split(":") | |
933 if len(address)==1: | |
934 address.append("4443") | |
935 address = ( address[0], int(address[1]) ) | |
936 | |
937 verifierDBFilename = None | |
938 sharedKeyDBFilename = None | |
939 certFilename = None | |
940 keyFilename = None | |
941 sharedKeyDB = None | |
942 reqCert = False | |
943 | |
944 if cmd == "serversrp": | |
945 verifierDBFilename = args.getLast(3) | |
946 elif cmd == "servercert": | |
947 certFilename = args.get(3) | |
948 keyFilename = args.get(4) | |
949 if len(sys.argv)>=6: | |
950 req = args.getLast(5) | |
951 if req.lower() != "req": | |
952 raise SyntaxError() | |
953 reqCert = True | |
954 elif cmd == "serversrpcert": | |
955 verifierDBFilename = args.get(3) | |
956 certFilename = args.get(4) | |
957 keyFilename = args.getLast(5) | |
958 elif cmd == "serversharedkey": | |
959 sharedKeyDBFilename = args.getLast(3) | |
960 elif cmd == "servertest": | |
961 address = args.get(2) | |
962 dir = args.getLast(3) | |
963 serverTest(address, dir) | |
964 sys.exit() | |
965 | |
966 verifierDB = None | |
967 if verifierDBFilename: | |
968 verifierDB = VerifierDB(verifierDBFilename) | |
969 verifierDB.open() | |
970 | |
971 sharedKeyDB = None | |
972 if sharedKeyDBFilename: | |
973 sharedKeyDB = SharedKeyDB(sharedKeyDBFilename) | |
974 sharedKeyDB.open() | |
975 | |
976 certChain = None | |
977 privateKey = None | |
978 if certFilename: | |
979 s1 = open(certFilename, "rb").read() | |
980 s2 = open(keyFilename, "rb").read() | |
981 | |
982 #Try to create cryptoID cert chain | |
983 if cryptoIDlibLoaded: | |
984 try: | |
985 certChain = CertChain().parse(s1) | |
986 privateKey = parsePrivateKey(s2) | |
987 except: | |
988 certChain = None | |
989 privateKey = None | |
990 | |
991 #Try to create X.509 cert chain | |
992 if not certChain: | |
993 x509 = X509() | |
994 x509.parse(s1) | |
995 certChain = X509CertChain([x509]) | |
996 privateKey = parsePrivateKey(s2) | |
997 | |
998 | |
999 | |
1000 #Create handler function - performs handshake, then echos all bytes rece
ived | |
1001 def handler(sock): | |
1002 try: | |
1003 connection = TLSConnection(sock) | |
1004 settings = HandshakeSettings() | |
1005 connection.handshakeServer(sharedKeyDB=sharedKeyDB, verifierDB=v
erifierDB, \ | |
1006 certChain=certChain, privateKey=priva
teKey, \ | |
1007 reqCert=reqCert, settings=settings) | |
1008 print "Handshake success" | |
1009 print " Version: %s.%s" % connection.version | |
1010 print " Cipher: %s %s" % (connection.getCipherName(), connectio
n.getCipherImplementation()) | |
1011 if connection.session.srpUsername: | |
1012 print " Client SRP username: %s" % connection.session.srpUs
ername | |
1013 if connection.session.sharedKeyUsername: | |
1014 print " Client shared key username: %s" % connection.sessio
n.sharedKeyUsername | |
1015 if connection.session.clientCertChain: | |
1016 print " Client fingerprint: %s" % connection.session.client
CertChain.getFingerprint() | |
1017 if connection.session.serverCertChain: | |
1018 print " Server fingerprint: %s" % connection.session.server
CertChain.getFingerprint() | |
1019 | |
1020 s = "" | |
1021 while 1: | |
1022 newS = connection.read() | |
1023 if not newS: | |
1024 break | |
1025 s += newS | |
1026 if s[-1]=='\n': | |
1027 connection.write(s) | |
1028 s = "" | |
1029 except TLSLocalAlert, a: | |
1030 if a.description == AlertDescription.unknown_srp_username: | |
1031 print "Unknown SRP username" | |
1032 elif a.description == AlertDescription.bad_record_mac: | 307 elif a.description == AlertDescription.bad_record_mac: |
1033 if cmd == "serversrp" or cmd == "serversrpcert": | 308 if username: |
1034 print "Bad SRP password for:", connection.allegedSrpUser
name | 309 print("Bad username or password") |
| 310 return False |
1035 else: | 311 else: |
1036 raise | 312 raise |
1037 elif a.description == AlertDescription.handshake_failure: | 313 elif a.description == AlertDescription.handshake_failure: |
1038 print "Unable to negotiate mutually acceptable parameters" | 314 print("Unable to negotiate mutually acceptable parameters") |
| 315 return False |
1039 else: | 316 else: |
1040 raise | 317 raise |
1041 except TLSRemoteAlert, a: | 318 |
1042 if a.description == AlertDescription.bad_record_mac: | 319 connection.ignoreAbruptClose = True |
1043 if cmd == "serversharedkey": | 320 printGoodConnection(connection, stop-start) |
1044 print "Bad sharedkey password for:", connection.allegedS
haredKeyUsername | 321 return True |
1045 else: | 322 |
1046 raise | 323 httpd = MyHTTPServer(address, SimpleHTTPRequestHandler) |
1047 elif a.description == AlertDescription.user_canceled: | 324 httpd.serve_forever() |
1048 print "Handshake cancelled" | 325 |
1049 elif a.description == AlertDescription.handshake_failure: | 326 |
1050 print "Unable to negotiate mutually acceptable parameters" | 327 if __name__ == '__main__': |
1051 elif a.description == AlertDescription.close_notify: | 328 if len(sys.argv) < 2: |
1052 pass | 329 printUsage("Missing command") |
1053 else: | 330 elif sys.argv[1] == "client"[:len(sys.argv[1])]: |
1054 raise | 331 clientCmd(sys.argv[2:]) |
1055 | 332 elif sys.argv[1] == "server"[:len(sys.argv[1])]: |
1056 #Run multi-threaded server | 333 serverCmd(sys.argv[2:]) |
1057 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | 334 else: |
1058 sock.bind(address) | 335 printUsage("Unknown command: %s" % sys.argv[1]) |
1059 sock.listen(5) | 336 |
1060 while 1: | |
1061 (newsock, cliAddress) = sock.accept() | |
1062 thread.start_new_thread(handler, (newsock,)) | |
1063 | |
1064 | |
1065 else: | |
1066 print "Bad command: '%s'" % cmd | |
1067 except TLSRemoteAlert, a: | |
1068 print str(a) | |
1069 raise | |
1070 | |
1071 | |
1072 | |
1073 | |
1074 | |
OLD | NEW |