initial.commit | 4c2903c | 2008-07-27 00:38:33 +0000 | [diff] [blame^] | 1 | #! python |
| 2 | |
| 3 | import sys |
| 4 | import os |
| 5 | import os.path |
| 6 | import socket |
| 7 | import thread |
| 8 | import time |
| 9 | import httplib |
| 10 | import BaseHTTPServer |
| 11 | import SimpleHTTPServer |
| 12 | |
| 13 | |
| 14 | try: |
| 15 | from cryptoIDlib.api import * |
| 16 | cryptoIDlibLoaded = True |
| 17 | except: |
| 18 | cryptoIDlibLoaded = False |
| 19 | |
| 20 | if __name__ != "__main__": |
| 21 | raise "This must be run as a command, not used as a module!" |
| 22 | |
| 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 | |
| 31 | def parsePrivateKey(s): |
| 32 | try: |
| 33 | return parsePEMKey(s, private=True) |
| 34 | except Exception, e: |
| 35 | print e |
| 36 | return parseXMLKey(s, private=True) |
| 37 | |
| 38 | |
| 39 | def clientTest(address, dir): |
| 40 | |
| 41 | #Split address into hostname/port tuple |
| 42 | address = address.split(":") |
| 43 | if len(address)==1: |
| 44 | address.append("4443") |
| 45 | address = ( address[0], int(address[1]) ) |
| 46 | |
| 47 | def connect(): |
| 48 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
| 49 | if hasattr(sock, 'settimeout'): #It's a python 2.3 feature |
| 50 | sock.settimeout(5) |
| 51 | sock.connect(address) |
| 52 | c = TLSConnection(sock) |
| 53 | return c |
| 54 | |
| 55 | test = 0 |
| 56 | |
| 57 | badFault = False |
| 58 | |
| 59 | print "Test 1 - good shared key" |
| 60 | connection = connect() |
| 61 | connection.handshakeClientSharedKey("shared", "key") |
| 62 | connection.close() |
| 63 | connection.sock.close() |
| 64 | |
| 65 | print "Test 2 - shared key faults" |
| 66 | for fault in Fault.clientSharedKeyFaults + Fault.genericFaults: |
| 67 | connection = connect() |
| 68 | connection.fault = fault |
| 69 | try: |
| 70 | connection.handshakeClientSharedKey("shared", "key") |
| 71 | print " Good Fault %s" % (Fault.faultNames[fault]) |
| 72 | except TLSFaultError, e: |
| 73 | print " BAD FAULT %s: %s" % (Fault.faultNames[fault], str(e)) |
| 74 | badFault = True |
| 75 | connection.sock.close() |
| 76 | |
| 77 | print "Test 3 - good SRP" |
| 78 | connection = connect() |
| 79 | connection.handshakeClientSRP("test", "password") |
| 80 | connection.close() |
| 81 | |
| 82 | print "Test 4 - SRP faults" |
| 83 | for fault in Fault.clientSrpFaults + Fault.genericFaults: |
| 84 | connection = connect() |
| 85 | connection.fault = fault |
| 86 | try: |
| 87 | connection.handshakeClientSRP("test", "password") |
| 88 | print " Good Fault %s" % (Fault.faultNames[fault]) |
| 89 | except TLSFaultError, e: |
| 90 | print " BAD FAULT %s: %s" % (Fault.faultNames[fault], str(e)) |
| 91 | badFault = True |
| 92 | connection.sock.close() |
| 93 | |
| 94 | print "Test 5 - good SRP: unknown_srp_username idiom" |
| 95 | def srpCallback(): |
| 96 | return ("test", "password") |
| 97 | connection = connect() |
| 98 | connection.handshakeClientUnknown(srpCallback=srpCallback) |
| 99 | connection.close() |
| 100 | connection.sock.close() |
| 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: |
| 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, "serverCryptoIDChain.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=settings) |
| 358 | print ("%s %s" % (connection.getCipherName(), connection.getCipherImplementation())) |
| 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=settings) |
| 379 | print ("%s %s:" % (connection.getCipherName(), connection.getCipherImplementation())), |
| 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/(stopTime-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, "serverCryptoIDChain.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=cryptoIDKey) |
| 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=cryptoIDKey) |
| 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=cryptoIDKey) |
| 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=cryptoIDKey) |
| 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=cryptoIDKey, 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=cryptoIDKey, 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=sessionCache) |
| 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=x509Key) |
| 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, privateKey=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=settings) |
| 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=settings) |
| 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("help")): |
| 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() |
| 845 | connection.handshakeClientSRP(username, password) |
| 846 | elif cmd == "clientsharedkey": |
| 847 | username = args.get(3) |
| 848 | password = args.getLast(4) |
| 849 | connection = connect() |
| 850 | start = time.clock() |
| 851 | connection.handshakeClientSharedKey(username, password) |
| 852 | elif cmd == "clientcert": |
| 853 | certChain = None |
| 854 | privateKey = None |
| 855 | if len(sys.argv) > 3: |
| 856 | certFilename = args.get(3) |
| 857 | keyFilename = args.getLast(4) |
| 858 | |
| 859 | s1 = open(certFilename, "rb").read() |
| 860 | s2 = open(keyFilename, "rb").read() |
| 861 | |
| 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: |
| 889 | raise |
| 890 | elif a.description == AlertDescription.user_canceled: |
| 891 | print str(a) |
| 892 | else: |
| 893 | raise |
| 894 | sys.exit() |
| 895 | except TLSRemoteAlert, a: |
| 896 | if a.description == AlertDescription.unknown_srp_username: |
| 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.getCipherImplementation()) |
| 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.sharedKeyUsername |
| 921 | if connection.session.clientCertChain: |
| 922 | print " Client fingerprint: %s" % connection.session.clientCertChain.getFingerprint() |
| 923 | if connection.session.serverCertChain: |
| 924 | print " Server fingerprint: %s" % connection.session.serverCertChain.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 received |
| 1001 | def handler(sock): |
| 1002 | try: |
| 1003 | connection = TLSConnection(sock) |
| 1004 | settings = HandshakeSettings() |
| 1005 | connection.handshakeServer(sharedKeyDB=sharedKeyDB, verifierDB=verifierDB, \ |
| 1006 | certChain=certChain, privateKey=privateKey, \ |
| 1007 | reqCert=reqCert, settings=settings) |
| 1008 | print "Handshake success" |
| 1009 | print " Version: %s.%s" % connection.version |
| 1010 | print " Cipher: %s %s" % (connection.getCipherName(), connection.getCipherImplementation()) |
| 1011 | if connection.session.srpUsername: |
| 1012 | print " Client SRP username: %s" % connection.session.srpUsername |
| 1013 | if connection.session.sharedKeyUsername: |
| 1014 | print " Client shared key username: %s" % connection.session.sharedKeyUsername |
| 1015 | if connection.session.clientCertChain: |
| 1016 | print " Client fingerprint: %s" % connection.session.clientCertChain.getFingerprint() |
| 1017 | if connection.session.serverCertChain: |
| 1018 | print " Server fingerprint: %s" % connection.session.serverCertChain.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: |
| 1033 | if cmd == "serversrp" or cmd == "serversrpcert": |
| 1034 | print "Bad SRP password for:", connection.allegedSrpUsername |
| 1035 | else: |
| 1036 | raise |
| 1037 | elif a.description == AlertDescription.handshake_failure: |
| 1038 | print "Unable to negotiate mutually acceptable parameters" |
| 1039 | else: |
| 1040 | raise |
| 1041 | except TLSRemoteAlert, a: |
| 1042 | if a.description == AlertDescription.bad_record_mac: |
| 1043 | if cmd == "serversharedkey": |
| 1044 | print "Bad sharedkey password for:", connection.allegedSharedKeyUsername |
| 1045 | else: |
| 1046 | raise |
| 1047 | elif a.description == AlertDescription.user_canceled: |
| 1048 | print "Handshake cancelled" |
| 1049 | elif a.description == AlertDescription.handshake_failure: |
| 1050 | print "Unable to negotiate mutually acceptable parameters" |
| 1051 | elif a.description == AlertDescription.close_notify: |
| 1052 | pass |
| 1053 | else: |
| 1054 | raise |
| 1055 | |
| 1056 | #Run multi-threaded server |
| 1057 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
| 1058 | sock.bind(address) |
| 1059 | sock.listen(5) |
| 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 | |