Home | History | Annotate | Download | only in scripts
      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