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 (at] 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 1075