1 2 tlslite version 0.4.6 Mar 20 2013 3 Trevor Perrin <tlslite at trevp.net> 4 http://trevp.net/tlslite/ 5 ============================================================================ 6 7 8 Table of Contents 9 ================== 10 1 Introduction 11 2 License/Acknowledgements 12 3 Installation 13 4 Getting Started with the Command-Line Tools 14 5 Getting Started with the Library 15 6 Using TLS Lite with httplib 16 7 Using TLS Lite with poplib or imaplib 17 8 Using TLS Lite with smtplib 18 9 Using TLS Lite with SocketServer 19 10 Using TLS Lite with asyncore 20 11 SECURITY CONSIDERATIONS 21 12 History 22 23 24 1 Introduction 25 =============== 26 TLS Lite is an open source python library that implements SSL and TLS. TLS 27 Lite supports RSA and SRP ciphersuites. TLS Lite is pure python, however it 28 can use other libraries for faster crypto operations. TLS Lite integrates with 29 several stdlib neworking libraries. 30 31 API documentation is available in the 'docs' directory. 32 33 If you have questions or feedback, feel free to contact me. For discussing 34 improvements to tlslite, also see 'tlslite-dev (a] googlegroups.com'. 35 36 37 2 Licenses/Acknowledgements 38 ============================ 39 TLS Lite is written (mostly) by Trevor Perrin. It includes code from Bram 40 Cohen, Google, Kees Bos, Sam Rushing, Dimitris Moraitis, Marcelo Fernandez, 41 Martin von Loewis, and Dave Baggett. 42 43 All code in TLS Lite has either been dedicated to the public domain by its 44 authors, or placed under a BSD-style license. See the LICENSE file for 45 details. 46 47 Thanks to Edward Loper for Epydoc, which generated the API docs. 48 49 50 3 Installation 51 =============== 52 Requirements: 53 Python 2.6 or higher is required. Python 3 is supported. 54 55 Options: 56 - If you have the M2Crypto interface to OpenSSL, this will be used for fast 57 RSA operations and fast ciphers. 58 59 - If you have pycrypto this will be used for fast RSA operations and fast 60 ciphers. 61 62 - If you have the GMPY interface to GMP, this will be used for fast RSA and 63 SRP operations. 64 65 - These modules don't need to be present at installation - you can install 66 them any time. 67 68 Run 'python setup.py install' 69 70 Test the Installation: 71 - From the distribution's ./tests subdirectory, run: 72 ./tlstest.py server localhost:4443 . 73 - While the test server is waiting, run: 74 ./tlstest.py client localhost:4443 . 75 76 If both say "Test succeeded" at the end, you're ready to go. 77 78 79 4 Getting Started with the Command-Line Tools 80 ============================================== 81 tlslite installs two command-line scripts: 'tlsdb.py' and 'tls.py'. 82 83 'tls.py' lets you run test clients and servers. It can be used for testing 84 other TLS implementations, or as example code. Note that 'tls.py server' runs 85 an HTTPS server which will serve files rooted at the current directory by 86 default, so be careful. 87 88 'tlsdb.py' lets you manage SRP verifier databases. These databases are used by 89 a TLS server when authenticating clients with SRP. 90 91 X.509 92 ------ 93 To run an X.509 server, go to the ./tests directory and do: 94 95 tls.py server -k serverX509Key.pem -c serverX509Cert.pem localhost:4443 96 97 Try connecting to the server with a web browser, or with: 98 99 tls.py client localhost:4443 100 101 X.509 with TACK 102 ---------------- 103 To run an X.509 server using a TACK, install TACKpy, then run the same server 104 command as above with added arguments: 105 106 ... -t TACK1.pem localhost:4443 107 108 SRP 109 ---- 110 To run an SRP server, try something like: 111 112 tlsdb.py createsrp verifierDB 113 tlsdb.py add verifierDB alice abra123cadabra 1024 114 tlsdb.py add verifierDB bob swordfish 2048 115 116 tls.py server -v verifierDB localhost:4443 117 118 Then try connecting to the server with: 119 120 tls.py client localhost:4443 alice abra123cadabra 121 122 HTTPS 123 ------ 124 To run an HTTPS server with less typing, run ./tests/httpsserver.sh. 125 126 To run an HTTPS client, run ./tests/httpsclient.py. 127 128 129 5 Getting Started with the Library 130 =================================== 131 Whether you're writing a client or server, there are six steps: 132 133 1) Create a socket and connect it to the other party. 134 2) Construct a TLSConnection instance with the socket. 135 3) Call a handshake function on TLSConnection to perform the TLS handshake. 136 4) Check the results to make sure you're talking to the right party. 137 5) Use the TLSConnection to exchange data. 138 6) Call close() on the TLSConnection when you're done. 139 140 TLS Lite also integrates with several stdlib python libraries. See the 141 sections following this one for details. 142 143 5 Step 1 - create a socket 144 --------------------------- 145 Below demonstrates a socket connection to Amazon's secure site. 146 147 from socket import * 148 sock = socket(AF_INET, SOCK_STREAM) 149 sock.connect( ("www.amazon.com", 443) ) 150 151 5 Step 2 - construct a TLSConnection 152 ------------------------------------- 153 You can import tlslite objects individually, such as: 154 from tlslite import TLSConnection 155 156 Or import the most useful objects through: 157 from tlslite.api import * 158 159 Then do: 160 connection = TLSConnection(sock) 161 162 5 Step 3 - call a handshake function (client) 163 ---------------------------------------------- 164 If you're a client, there's two different handshake functions you can call, 165 depending on how you want to authenticate: 166 167 connection.handshakeClientCert() 168 connection.handshakeClientCert(certChain, privateKey) 169 170 connection.handshakeClientSRP("alice", "abra123cadabra") 171 172 The ClientCert function without arguments is used when connecting to a site 173 like Amazon, which doesn't require client authentication, but which will 174 authenticate itself using an X.509 certificate chain. 175 176 The ClientCert function can also be used to do client authentication with an 177 X.509 certificate chain and corresponding private key. To use X.509 chains, 178 you'll need some way of creating these, such as OpenSSL (see 179 http://www.openssl.org/docs/HOWTO/ for details). 180 181 Below is an example of loading an X.509 chain and private key: 182 183 from tlslite import X509, X509CertChain, parsePEMKey 184 s = open("./test/clientX509Cert.pem").read() 185 x509 = X509() 186 x509.parse(s) 187 certChain = X509CertChain([x509]) 188 s = open("./test/clientX509Key.pem").read() 189 privateKey = parsePEMKey(s, private=True) 190 191 The SRP function does mutual authentication with a username and password - see 192 RFC 5054 for details. 193 194 If you want more control over the handshake, you can pass in a 195 HandshakeSettings instance. For example, if you're performing SRP, but you 196 only want to use SRP parameters of at least 2048 bits, and you only want to 197 use the AES-256 cipher, and you only want to allow TLS (version 3.1), not SSL 198 (version 3.0), you can do: 199 200 settings = HandshakeSettings() 201 settings.minKeySize = 2048 202 settings.cipherNames = ["aes256"] 203 settings.minVersion = (3,1) 204 settings.useExperimentalTACKExtension = True # Needed for TACK support 205 206 connection.handshakeClientSRP("alice", "abra123cadabra", settings=settings) 207 208 If you want to check the server's certificate using TACK, you should set the 209 "useExperiementalTACKExtension" value in HandshakeSettings. (Eventually, TACK 210 support will be enabled by default, but for now it is an experimental feature 211 which relies on a temporary TLS Extension number, and should not be used for 212 production software.) This will cause the client to request the server to send 213 you a TACK (and/or any TACK Break Signatures): 214 215 Finally, every TLSConnection has a session object. You can try to resume a 216 previous session by passing in the session object from the old session. If the 217 server remembers this old session and supports resumption, the handshake will 218 finish more quickly. Otherwise, the full handshake will be done. For example: 219 220 connection.handshakeClientSRP("alice", "abra123cadabra") 221 . 222 . 223 oldSession = connection.session 224 connection2.handshakeClientSRP("alice", "abra123cadabra", session= 225 oldSession) 226 227 5 Step 3 - call a handshake function (server) 228 ---------------------------------------------- 229 If you're a server, there's only one handshake function, but you can pass it 230 several different parameters, depending on which types of authentication 231 you're willing to perform. 232 233 To perform SRP authentication, you have to pass in a database of password 234 verifiers. The VerifierDB class manages an in-memory or on-disk verifier 235 database. 236 237 verifierDB = VerifierDB("./test/verifierDB") 238 verifierDB.open() 239 connection.handshakeServer(verifierDB=verifierDB) 240 241 To perform authentication with a certificate and private key, the server must 242 load these as described in the previous section, then pass them in. If the 243 server sets the reqCert boolean to True, a certificate chain will be requested 244 from the client. 245 246 connection.handshakeServer(certChain=certChain, privateKey=privateKey, 247 reqCert=True) 248 249 You can pass in a verifier database and/or a certificate chain+private key. 250 The client will use one or both to authenticate the server. 251 252 You can also pass in a HandshakeSettings object, as described in the last 253 section, for finer control over handshaking details. 254 255 If you are passing in a certificate chain+private key, you may additionally 256 provide a TACK to assist the client in authenticating your certificate chain. 257 This requires the TACKpy library. Load a TACKpy.TACK object, then do: 258 259 settings = HandshakeSettings() 260 settings.useExperimentalTACKExtension = True # Needed for TACK support 261 262 connection.handshakeServer(certChain=certChain, privateKey=privateKey, 263 tack=tack, settings=settings) 264 265 Finally, the server can maintain a SessionCache, which will allow clients to 266 use session resumption: 267 268 sessionCache = SessionCache() 269 connection.handshakeServer(verifierDB=verifierDB, sessionCache=sessionCache) 270 271 It should be noted that the session cache, and the verifier databases, are all 272 thread-safe. 273 274 5 Step 4 - check the results 275 ----------------------------- 276 If the handshake completes without raising an exception, authentication 277 results will be stored in the connection's session object. The following 278 variables will be populated if applicable, or else set to None: 279 280 connection.session.srpUsername # string 281 connection.session.clientCertChain # X509CertChain 282 connection.session.serverCertChain # X509CertChain 283 connection.session.tackExt # TACKpy.TACK_Extension 284 285 X.509 chain objects return the end-entity fingerprint via getFingerprint(), 286 and ignore the other certificates. 287 288 TACK objects return the (validated) TACK ID via getTACKID(). 289 290 To save yourself the trouble of inspecting certificates and/or TACKs after the 291 handshake, you can pass a Checker object into the handshake function. The 292 checker will be called if the handshake completes successfully. If the other 293 party isn't approved by the checker, a subclass of TLSAuthenticationError will 294 be raised. 295 296 If the handshake fails for any reason, including a Checker error, an exception 297 will be raised and the socket will be closed. If the socket timed out or was 298 unexpectedly closed, a socket.error or TLSAbruptCloseError will be raised. 299 300 Otherwise, either a TLSLocalAlert or TLSRemoteAlert will be raised, depending 301 on whether the local or remote implementation signalled the error. The 302 exception object has a 'description' member which identifies the error based 303 on the codes in RFC 2246. A TLSLocalAlert also has a 'message' string that may 304 have more details. 305 306 Example of handling a remote alert: 307 308 try: 309 [...] 310 except TLSRemoteAlert as alert: 311 if alert.description == AlertDescription.unknown_psk_identity: 312 print "Unknown user." 313 [...] 314 315 Below are some common alerts and their probable causes, and whether they are 316 signalled by the client or server. 317 318 Client handshake_failure: 319 - SRP parameters are not recognized by client 320 - Server's TACK was unrelated to its certificate chain 321 322 Client insufficient_security: 323 - SRP parameters are too small 324 325 Client protocol_version: 326 - Client doesn't support the server's protocol version 327 328 Server protocol_version: 329 - Server doesn't support the client's protocol version 330 331 Server bad_record_mac: 332 - bad SRP username or password 333 334 Server unknown_psk_identity 335 - bad SRP username (bad_record_mac could be used for the same thing) 336 337 Server handshake_failure: 338 - no matching cipher suites 339 340 5 Step 5 - exchange data 341 ------------------------- 342 Now that you have a connection, you can call read() and write() as if it were 343 a socket.SSL object. You can also call send(), sendall(), recv(), and 344 makefile() as if it were a socket. These calls may raise TLSLocalAlert, 345 TLSRemoteAlert, socket.error, or TLSAbruptCloseError, just like the handshake 346 functions. 347 348 Once the TLS connection is closed by the other side, calls to read() or recv() 349 will return an empty string. If the socket is closed by the other side without 350 first closing the TLS connection, calls to read() or recv() will return a 351 TLSAbruptCloseError, and calls to write() or send() will return a 352 socket.error. 353 354 5 Step 6 - close the connection 355 -------------------------------- 356 When you're finished sending data, you should call close() to close the 357 connection and socket. When the connection is closed properly, the session 358 object can be used for session resumption. 359 360 If an exception is raised the connection will be automatically closed; you 361 don't need to call close(). Furthermore, you will probably not be able to 362 re-use the socket, the connection object, or the session object, and you 363 shouldn't even try. 364 365 By default, calling close() will close the underlying socket. If you set the 366 connection's closeSocket flag to False, the socket will remain open after 367 close. (NOTE: some TLS implementations will not respond properly to the 368 close_notify alert that close() generates, so the connection will hang if 369 closeSocket is set to True.) 370 371 372 6 Using TLS Lite with httplib 373 ============================== 374 TLS Lite comes with an HTTPTLSConnection class that extends httplib to work 375 over SSL/TLS connections. Depending on how you construct it, it will do 376 different types of authentication. 377 378 #No authentication whatsoever 379 h = HTTPTLSConnection("www.amazon.com", 443) 380 h.request("GET", "") 381 r = h.getresponse() 382 [...] 383 384 #Authenticate server based on its TACK ID 385 h = HTTPTLSConnection("localhost", 4443, 386 tackID="B3ARS.EQ61B.F34EL.9KKLN.3WEW5", hardTack=False) 387 [...] 388 389 #Mutually authenticate with SRP 390 h = HTTPTLSConnection("localhost", 443, 391 username="alice", password="abra123cadabra") 392 [...] 393 394 395 7 Using TLS Lite with poplib or imaplib 396 ======================================== 397 TLS Lite comes with POP3_TLS and IMAP4_TLS classes that extend poplib and 398 imaplib to work over SSL/TLS connections. These classes can be constructed 399 with the same parameters as HTTPTLSConnection (see previous section), and 400 behave similarly. 401 402 #To connect to a POP3 server over SSL and display its fingerprint: 403 from tlslite.api import * 404 p = POP3_TLS("---------.net", port=995) 405 print p.sock.session.serverCertChain.getFingerprint() 406 [...] 407 408 #To connect to an IMAP server once you know its fingerprint: 409 from tlslite.api import * 410 i = IMAP4_TLS("cyrus.andrew.cmu.edu", 411 x509Fingerprint="00c14371227b3b677ddb9c4901e6f2aee18d3e45") 412 [...] 413 414 415 8 Using TLS Lite with smtplib 416 ============================== 417 TLS Lite comes with an SMTP_TLS class that extends smtplib to work 418 over SSL/TLS connections. This class accepts the same parameters as 419 HTTPTLSConnection (see previous section), and behaves similarly. Depending 420 on how you call starttls(), it will do different types of authentication. 421 422 #To connect to an SMTP server once you know its fingerprint: 423 from tlslite.api import * 424 s = SMTP_TLS("----------.net", port=587) 425 s.ehlo() 426 s.starttls(x509Fingerprint="7e39be84a2e3a7ad071752e3001d931bf82c32dc") 427 [...] 428 429 430 9 Using TLS Lite with SocketServer 431 ==================================== 432 You can use TLS Lite to implement servers using Python's SocketServer 433 framework. TLS Lite comes with a TLSSocketServerMixIn class. You can combine 434 this with a TCPServer such as HTTPServer. To combine them, define a new class 435 that inherits from both of them (with the mix-in first). Then implement the 436 handshake() method, doing some sort of server handshake on the connection 437 argument. If the handshake method returns True, the RequestHandler will be 438 triggered. See the tests/httpsserver.py example. 439 440 441 10 Using TLS Lite with asyncore 442 ================================ 443 TLS Lite can be used with subclasses of asyncore.dispatcher. See the comments 444 in TLSAsyncDispatcherMixIn.py for details. This is still experimental, and 445 may not work with all asyncore.dispatcher subclasses. 446 447 448 11 Security Considerations 449 =========================== 450 TLS Lite is beta-quality code. It hasn't received much security analysis. Use 451 at your own risk. 452 453 TLS Lite is probably vulnerable to the "Lucky 13" timing attack if AES or 3DES 454 are used. Thus, TLS Lite prefers the RC4 cipher. 455 456 457 12 History 458 =========== 459 0.4.6 - 3/20/2013 460 - **API CHANGE**: TLSClosedConnectionError instead of ValueError when writing 461 to a closed connection. This inherits from socket.error, so should 462 interact better with SocketServer (see http://bugs.python.org/issue14574) 463 and other things expecting a socket.error in this situation. 464 - Added support for RC4-MD5 ciphersuite (if enabled in settings) 465 - This is allegedly necessary to connect to some Internet servers. 466 - Added TLSConnection.unread() function 467 - Switched to New-style classes (inherit from 'object') 468 - Minor cleanups 469 470 0.4.5 - (release engineering problem, skipped!) 471 472 0.4.4 - 2/25/2013 473 - Added Python 3 support (Martin von Loewis) 474 - Added NPN client support (Marcelo Fernandez) 475 - Switched to RC4 as preferred cipher 476 - faster in Python, avoids "Lucky 13" timing attacks 477 - Fixed bug when specifying ciphers for anon ciphersuites 478 - Made RSA hashAndVerify() tolerant of sigs w/o encoded NULL AlgorithmParam 479 - (this function is not used for TLS currently, and this tolerance may 480 not even be necessary) 481 0.4.3 - 9/27/2012 482 - Minor bugfix (0.4.2 doesn't load tackpy) 483 0.4.2 - 9/25/2012 484 - Updated TACK (compatible with tackpy 0.9.9) 485 0.4.1 - 5/22/2012 486 - Fixed RSA padding bugs (w/help from John Randolph) 487 - Updated TACK (compatible with tackpy 0.9.7) 488 - Added SNI 489 - Added NPN server support (Sam Rushing/Google) 490 - Added AnonDH (Dimitris Moraitis) 491 - Added X509CertChain.parsePemList 492 - Improved XML-RPC (Kees Bos) 493 494 0.4.0 - 2/11/2012 495 - Fixed pycrypto support 496 - Fixed python 2.6 problems 497 498 0.3.9.x - 2/7/2012 499 500 Much code cleanup, in particular decomposing the handshake functions so they 501 are readable. The main new feature is support for TACK, an experimental 502 authentication method that provides a new way to pin server certificates (See 503 https://github.com/moxie0/Convergence/wiki/TACK ). 504 505 Also: 506 507 - Security Fixes 508 - Sends SCSV ciphersuite as per RFC 5746, to signal non-renegotiated 509 Client Hello. Does not support renegotiation (never has). 510 - Change from e=3 to e=65537 for generated RSA keys, not strictly 511 necessary but mitigates risk of sloppy verifier. 512 - 1/(n-1) countermeasure for BEAST. 513 514 - Behavior changes: 515 - Split cmdline into tls.py and tlstest.py, improved options. 516 - Formalized LICENSE. 517 - Defaults to closing socket after sending close_notify, fixes hanging. 518 problem that would occur sometime when waiting for other party's 519 close_notify. 520 - Update SRP to RFC 5054 compliance. 521 - Removed client handshake "callbacks", no longer support the SRP 522 re-handshake idiom within a single handshake function. 523 524 - Bugfixes 525 - Added hashlib support, removes Deprecation Warning due to sha and md5. 526 - Handled GeneratorExit exceptions that are a new Python feature, and 527 interfere with the async code if not handled. 528 529 - Removed: 530 - Shared keys (it was based on an ancient I-D, not TLS-PSK). 531 - cryptlib support, it wasn't used much, we have enough other options. 532 - cryptoIDs (TACK is better). 533 - win32prng extension module, as os.urandom is now available. 534 - Twisted integration (unused?, slowed down loading). 535 - Jython code (ancient, didn't work). 536 - Compat support for python versions < 2.7. 537 538 - Additions 539 - Support for TACK via TACKpy. 540 - Support for CertificateRequest.certificate_authorities ("reqCAs") 541 - Added TLSConnection.shutdown() to better mimic socket. 542 - Enabled Session resumption for XMLRPCTransport. 543 544 0.3.8 - 2/21/2005 545 - Added support for poplib, imaplib, and smtplib 546 - Added python 2.4 windows installer 547 - Fixed occassional timing problems with test suite 548 0.3.7 - 10/05/2004 549 - Added support for Python 2.2 550 - Cleaned up compatibility code, and docs, a bit 551 0.3.6 - 9/28/2004 552 - Fixed script installation on UNIX 553 - Give better error message on old Python versions 554 0.3.5 - 9/16/2004 555 - TLS 1.1 support 556 - os.urandom() support 557 - Fixed win32prng on some systems 558 0.3.4 - 9/12/2004 559 - Updated for TLS/SRP draft 8 560 - Bugfix: was setting _versioncheck on SRP 1st hello, causing problems 561 with GnuTLS (which was offering TLS 1.1) 562 - Removed _versioncheck checking, since it could cause interop problems 563 - Minor bugfix: when cryptlib_py and and cryptoIDlib present, cryptlib 564 was complaining about being initialized twice 565 0.3.3 - 6/10/2004 566 - Updated for TLS/SRP draft 7 567 - Updated test cryptoID cert chains for cryptoIDlib 0.3.1 568 0.3.2 - 5/21/2004 569 - fixed bug when handling multiple handshake messages per record (e.g. IIS) 570 0.3.1 - 4/21/2004 571 - added xmlrpclib integration 572 - fixed hanging bug in Twisted integration 573 - fixed win32prng to work on a wider range of win32 sytems 574 - fixed import problem with cryptoIDlib 575 - fixed port allocation problem when test scripts are run on some UNIXes 576 - made tolerant of buggy IE sending wrong version in premaster secret 577 0.3.0 - 3/20/2004 578 - added API docs thanks to epydoc 579 - added X.509 path validation via cryptlib 580 - much cleaning/tweaking/re-factoring/minor fixes 581 0.2.7 - 3/12/2004 582 - changed Twisted error handling to use connectionLost() 583 - added ignoreAbruptClose 584 0.2.6 - 3/11/2004 585 - added Twisted errorHandler 586 - added TLSAbruptCloseError 587 - added 'integration' subdirectory 588 0.2.5 - 3/10/2004 589 - improved asynchronous support a bit 590 - added first-draft of Twisted support 591 0.2.4 - 3/5/2004 592 - cleaned up asyncore support 593 - added proof-of-concept for Twisted 594 0.2.3 - 3/4/2004 595 - added pycrypto RSA support 596 - added asyncore support 597 0.2.2 - 3/1/2004 598 - added GMPY support 599 - added pycrypto support 600 - added support for PEM-encoded private keys, in pure python 601 0.2.1 - 2/23/2004 602 - improved PRNG use (cryptlib, or /dev/random, or CryptoAPI) 603 - added RSA blinding, to avoid timing attacks 604 - don't install local copy of M2Crypto, too problematic 605 0.2.0 - 2/19/2004 606 - changed VerifierDB to take per-user parameters 607 - renamed tls_lite -> tlslite 608 0.1.9 - 2/16/2004 609 - added post-handshake 'Checker' 610 - made compatible with Python 2.2 611 - made more forgiving of abrupt closure, since everyone does it: 612 if the socket is closed while sending/recv'ing close_notify, 613 just ignore it. 614 0.1.8 - 2/12/2004 615 - TLSConnections now emulate sockets, including makefile() 616 - HTTPTLSConnection and TLSMixIn simplified as a result 617 0.1.7 - 2/11/2004 618 - fixed httplib.HTTPTLSConnection with multiple requests 619 - fixed SocketServer to handle close_notify 620 - changed handshakeClientNoAuth() to ignore CertificateRequests 621 - changed handshakeClient() to ignore non-resumable session arguments 622 0.1.6 - 2/10/2004 623 - fixed httplib support 624 0.1.5 - 2/09/2004 625 - added support for httplib and SocketServer 626 - added support for SSLv3 627 - added support for 3DES 628 - cleaned up read()/write() behavior 629 - improved HMAC speed 630 0.1.4 - 2/06/2004 631 - fixed dumb bug in tls.py 632 0.1.3 - 2/05/2004 633 - change read() to only return requested number of bytes 634 - added support for shared-key and in-memory databases 635 - added support for PEM-encoded X.509 certificates 636 - added support for SSLv2 ClientHello 637 - fixed shutdown/re-handshaking behavior 638 - cleaned up handling of missing_srp_username 639 - renamed readString()/writeString() -> read()/write() 640 - added documentation 641 0.1.2 - 2/04/2004 642 - added clienttest/servertest functions 643 - improved OpenSSL cipher wrappers speed 644 - fixed server when it has a key, but client selects plain SRP 645 - fixed server to postpone errors until it has read client's messages 646 - fixed ServerHello to only include extension data if necessary 647 0.1.1 - 2/02/2004 648 - fixed close_notify behavior 649 - fixed handling of empty application data packets 650 - fixed socket reads to not consume extra bytes 651 - added testing functions to tls.py 652 0.1.0 - 2/01/2004 653 - first release 654