Index: third_party/tlslite/README |
diff --git a/third_party/tlslite/readme.txt b/third_party/tlslite/README |
similarity index 40% |
rename from third_party/tlslite/readme.txt |
rename to third_party/tlslite/README |
index c1f1b3840c7eff91e1b40049633e4945c57ad660..1b3247abe4fc9ec3f7769a8e67507d87176f1978 100644 |
--- a/third_party/tlslite/readme.txt |
+++ b/third_party/tlslite/README |
@@ -1,6 +1,6 @@ |
-tlslite version 0.3.8 February 21, 2005 |
-Trevor Perrin <trevp at trevp.net> |
+tlslite version 0.4.6 Mar 20 2013 |
+Trevor Perrin <tlslite at trevp.net> |
http://trevp.net/tlslite/ |
============================================================================ |
@@ -13,37 +13,36 @@ Table of Contents |
4 Getting Started with the Command-Line Tools |
5 Getting Started with the Library |
6 Using TLS Lite with httplib |
-7 Using TLS Lite with xmlrpclib |
-8 Using TLS Lite with poplib or imaplib |
-9 Using TLS Lite with smtplib |
-10 Using TLS Lite with SocketServer |
-11 Using TLS Lite with asyncore |
-12 Using TLS Lite with Twisted |
-13 SECURITY CONSIDERATIONS |
-14 History |
-15 References |
- |
- |
-1 Introduction |
-=============== |
-TLS Lite is a free python library that implements SSL v3, TLS v1, and |
-TLS v1.1 [0]. TLS Lite supports non-traditional authentication methods |
-such as SRP [1], shared keys [2], and cryptoIDs [3], in addition to X.509 |
-certificates. TLS Lite is pure python, however it can access OpenSSL [4], |
-cryptlib [5], pycrypto [9], and GMPY [10] for faster crypto operations. TLS |
-Lite integrates with httplib, xmlrpclib, poplib, imaplib, smtplib, |
-SocketServer, asyncore, and Twisted. |
+7 Using TLS Lite with poplib or imaplib |
+8 Using TLS Lite with smtplib |
+9 Using TLS Lite with SocketServer |
+10 Using TLS Lite with asyncore |
+11 SECURITY CONSIDERATIONS |
+12 History |
+ |
+ |
+1 Introduction |
+=============== |
+TLS Lite is an open source python library that implements SSL and TLS. TLS |
+Lite supports RSA and SRP ciphersuites. TLS Lite is pure python, however it |
+can use other libraries for faster crypto operations. TLS Lite integrates with |
+several stdlib neworking libraries. |
API documentation is available in the 'docs' directory. |
-If you have questions or feedback, feel free to contact me. |
+If you have questions or feedback, feel free to contact me. For discussing |
+improvements to tlslite, also see 'tlslite-dev@googlegroups.com'. |
2 Licenses/Acknowledgements |
============================ |
-All code here is public domain. |
+TLS Lite is written (mostly) by Trevor Perrin. It includes code from Bram |
+Cohen, Google, Kees Bos, Sam Rushing, Dimitris Moraitis, Marcelo Fernandez, |
+Martin von Loewis, and Dave Baggett. |
-Thanks to Bram Cohen for his public domain Rijndael implementation. |
+All code in TLS Lite has either been dedicated to the public domain by its |
+authors, or placed under a BSD-style license. See the LICENSE file for |
+details. |
Thanks to Edward Loper for Epydoc, which generated the API docs. |
@@ -51,84 +50,86 @@ Thanks to Edward Loper for Epydoc, which generated the API docs. |
3 Installation |
=============== |
Requirements: |
- Python 2.2 or greater is required. |
+ Python 2.6 or higher is required. Python 3 is supported. |
Options: |
- - If you have cryptoIDlib [8], you can use cryptoID certificate chains for |
- authentication. CryptoIDlib is the sister library to TLS Lite; it was |
- written by the same author, and has a similar interface. |
- |
- - If you have the M2Crypto [6] interface to OpenSSL, this will be used for |
- fast RSA operations and fast ciphers. |
+ - If you have the M2Crypto interface to OpenSSL, this will be used for fast |
+ RSA operations and fast ciphers. |
- - If you have the cryptlib_py [7] interface to cryptlib, this will be used |
- for random number generation and fast ciphers. If TLS Lite can't find an |
- OS-level random-number generator (i.e. /dev/urandom on UNIX or CryptoAPI on |
- Windows), then you must MUST install cryptlib. |
+ - If you have pycrypto this will be used for fast RSA operations and fast |
+ ciphers. |
- - If you have pycrypto [9], this will be used for fast ciphers and fast RSA |
- operations. |
- |
- - If you have the GMPY [10] interface to GMP, this will be used for fast RSA |
- and SRP operations. |
+ - If you have the GMPY interface to GMP, this will be used for fast RSA and |
+ SRP operations. |
- These modules don't need to be present at installation - you can install |
- them any time. |
- |
-On Windows: |
- Run the installer in the 'installers' directory. |
- *OR* |
- Run 'setup.py install' (this only works if your system has a compiler |
- available). |
+ them any time. |
-Anywhere else: |
- - Run 'python setup.py install' |
+Run 'python setup.py install' |
Test the Installation: |
- - The 'tls.py' script should have been copied onto your path. If not, |
- you may have to copy it there manually. |
- - From the distribution's ./test subdirectory, run: |
- tls.py servertest localhost:4443 . |
+ - From the distribution's ./tests subdirectory, run: |
+ ./tlstest.py server localhost:4443 . |
- While the test server is waiting, run: |
- tls.py clienttest localhost:4443 . |
+ ./tlstest.py client localhost:4443 . |
If both say "Test succeeded" at the end, you're ready to go. |
- (WARNING: Be careful running these (or any) scripts from the distribution's |
- root directory. Depending on your path, the scripts may load the local copy |
- of the library instead of the installed version, with unpredictable |
- results). |
- |
4 Getting Started with the Command-Line Tools |
============================================== |
-tlslite comes with two command-line scripts: 'tlsdb.py' and 'tls.py'. They |
-can be run with no arguments to see a list of commands. |
+tlslite installs two command-line scripts: 'tlsdb.py' and 'tls.py'. |
+ |
+'tls.py' lets you run test clients and servers. It can be used for testing |
+other TLS implementations, or as example code. Note that 'tls.py server' runs |
+an HTTPS server which will serve files rooted at the current directory by |
+default, so be careful. |
-'tlsdb.py' lets you manage shared key or verifier databases. These databases |
-store usernames associated with either shared keys, or SRP password verifiers. |
-These databases are used by a TLS server when authenticating clients with |
-shared keys or SRP. |
+'tlsdb.py' lets you manage SRP verifier databases. These databases are used by |
+a TLS server when authenticating clients with SRP. |
-'tls.py' lets you run test clients and servers. It can be used for testing |
-other TLS implementations, or as example code for using tlslite. To run an |
-SRP server, try something like: |
+X.509 |
+------ |
+To run an X.509 server, go to the ./tests directory and do: |
+ |
+ tls.py server -k serverX509Key.pem -c serverX509Cert.pem localhost:4443 |
+ |
+Try connecting to the server with a web browser, or with: |
+ |
+ tls.py client localhost:4443 |
+ |
+X.509 with TACK |
+---------------- |
+To run an X.509 server using a TACK, install TACKpy, then run the same server |
+command as above with added arguments: |
+ |
+ ... -t TACK1.pem localhost:4443 |
+ |
+SRP |
+---- |
+To run an SRP server, try something like: |
tlsdb.py createsrp verifierDB |
tlsdb.py add verifierDB alice abra123cadabra 1024 |
tlsdb.py add verifierDB bob swordfish 2048 |
- tls.py serversrp localhost:443 verifierDB |
+ tls.py server -v verifierDB localhost:4443 |
+ |
+Then try connecting to the server with: |
+ |
+ tls.py client localhost:4443 alice abra123cadabra |
-Then you can try connecting to the server with: |
+HTTPS |
+------ |
+To run an HTTPS server with less typing, run ./tests/httpsserver.sh. |
- tls.py clientsrp localhost:443 alice abra123cadabra |
+To run an HTTPS client, run ./tests/httpsclient.py. |
5 Getting Started with the Library |
=================================== |
-Using the library is simple. Whether you're writing a client or server, there |
-are six steps: |
+Whether you're writing a client or server, there are six steps: |
+ |
1) Create a socket and connect it to the other party. |
2) Construct a TLSConnection instance with the socket. |
3) Call a handshake function on TLSConnection to perform the TLS handshake. |
@@ -136,58 +137,50 @@ are six steps: |
5) Use the TLSConnection to exchange data. |
6) Call close() on the TLSConnection when you're done. |
-TLS Lite also integrates with httplib, xmlrpclib, poplib, imaplib, smtplib, |
-SocketServer, asyncore, and Twisted. When used with these, some of the steps |
-are performed for you. See the sections following this one for details. |
+TLS Lite also integrates with several stdlib python libraries. See the |
+sections following this one for details. |
5 Step 1 - create a socket |
--------------------------- |
-Below demonstrates a socket connection to Amazon's secure site. It's a good |
-idea to set the timeout value, so if the other side fails to respond you won't |
-end up waiting forever. |
+Below demonstrates a socket connection to Amazon's secure site. |
from socket import * |
sock = socket(AF_INET, SOCK_STREAM) |
sock.connect( ("www.amazon.com", 443) ) |
- sock.settimeout(10) #Only on python 2.3 or greater |
5 Step 2 - construct a TLSConnection |
------------------------------------- |
+You can import tlslite objects individually, such as: |
+ from tlslite import TLSConnection |
+ |
+Or import the most useful objects through: |
from tlslite.api import * |
+ |
+Then do: |
connection = TLSConnection(sock) |
5 Step 3 - call a handshake function (client) |
---------------------------------------------- |
-If you're a client, there's several different handshake functions you can |
-call, depending on how you want to authenticate: |
+If you're a client, there's two different handshake functions you can call, |
+depending on how you want to authenticate: |
connection.handshakeClientCert() |
connection.handshakeClientCert(certChain, privateKey) |
+ |
connection.handshakeClientSRP("alice", "abra123cadabra") |
- connection.handshakeClientSharedKey("alice", "PaVBVZkYqAjCQCu6UBL2xgsnZhw") |
- connection.handshakeClientUnknown(srpCallback, certCallback) |
The ClientCert function without arguments is used when connecting to a site |
-like Amazon, which doesn't require client authentication. The server will |
-authenticate with a certificate chain. |
+like Amazon, which doesn't require client authentication, but which will |
+authenticate itself using an X.509 certificate chain. |
The ClientCert function can also be used to do client authentication with an |
-X.509 or cryptoID certificate chain. To use cryptoID chains, you'll need the |
-cryptoIDlib library [8]. To use X.509 chains, you'll need some way of |
-creating these, such as OpenSSL (see http://www.openssl.org/docs/HOWTO/ for |
-details). |
- |
-Below are examples of loading cryptoID and X.509 certificate chains: |
- |
- #Load cryptoID certChain and privateKey. Requires cryptoIDlib. |
- from cryptoIDlib.CertChain import CertChain |
- s = open("./test/clientCryptoIDChain.xml").read() |
- certChain = CertChain() |
- certChain.parse(s) |
- s = open("./test/clientCryptoIDKey.xml").read() |
- privateKey = parseXMLKey(s, private=True) |
- |
- #Load X.509 certChain and privateKey. |
+X.509 certificate chain and corresponding private key. To use X.509 chains, |
+you'll need some way of creating these, such as OpenSSL (see |
+http://www.openssl.org/docs/HOWTO/ for details). |
+ |
+Below is an example of loading an X.509 chain and private key: |
+ |
+ from tlslite import X509, X509CertChain, parsePEMKey |
s = open("./test/clientX509Cert.pem").read() |
x509 = X509() |
x509.parse(s) |
@@ -195,43 +188,34 @@ Below are examples of loading cryptoID and X.509 certificate chains: |
s = open("./test/clientX509Key.pem").read() |
privateKey = parsePEMKey(s, private=True) |
-The SRP and SharedKey functions both do mutual authentication with a username |
-and password. The difference is this: SRP is slow but safer when using low- |
-entropy passwords, since the SRP protocol is not vulnerable to offline |
-dictionary attacks. Using shared keys is faster, but it's only safe when |
-used with high-entropy secrets. In general, you should prefer SRP for human- |
-memorable passwords, and use shared keys only when your performance needs |
-outweigh the inconvenience of handling large random strings. |
- |
-[WARNING: shared keys and SRP are internet-drafts; these protocols may change, |
-which means future versions of tlslite may not be compatible with this one. |
-This is less likely with SRP, more likely with shared-keys.] |
- |
-The Unknown function is used when you're not sure if the server requires |
-client authentication. If the server requests SRP or certificate-based |
-authentication, the appropriate callback will be triggered, and you should |
-return a tuple containing either a (username, password) or (certChain, |
-privateKey), as appropriate. Alternatively, you can return None, which will |
-cancel the handshake from an SRP callback, or cause it to continue without |
-client authentication (if the server is willing) from a certificate callback. |
+The SRP function does mutual authentication with a username and password - see |
+RFC 5054 for details. |
If you want more control over the handshake, you can pass in a |
-HandshakeSettings instance. For example, if you're performing SRP, but you |
-only want to use SRP parameters of at least 2048 bits, and you only want to use |
-the AES-256 cipher, and you only want to allow TLS (version 3.1), not SSL |
+HandshakeSettings instance. For example, if you're performing SRP, but you |
+only want to use SRP parameters of at least 2048 bits, and you only want to |
+use the AES-256 cipher, and you only want to allow TLS (version 3.1), not SSL |
(version 3.0), you can do: |
settings = HandshakeSettings() |
settings.minKeySize = 2048 |
settings.cipherNames = ["aes256"] |
settings.minVersion = (3,1) |
+ settings.useExperimentalTACKExtension = True # Needed for TACK support |
+ |
connection.handshakeClientSRP("alice", "abra123cadabra", settings=settings) |
-Finally, every TLSConnection has a session object. You can try to resume a |
-previous session by passing in the session object from the old session. If |
-the server remembers this old session and supports resumption, the handshake |
-will finish more quickly. Otherwise, the full handshake will be done. For |
-example: |
+If you want to check the server's certificate using TACK, you should set the |
+"useExperiementalTACKExtension" value in HandshakeSettings. (Eventually, TACK |
+support will be enabled by default, but for now it is an experimental feature |
+which relies on a temporary TLS Extension number, and should not be used for |
+production software.) This will cause the client to request the server to send |
+you a TACK (and/or any TACK Break Signatures): |
+ |
+Finally, every TLSConnection has a session object. You can try to resume a |
+previous session by passing in the session object from the old session. If the |
+server remembers this old session and supports resumption, the handshake will |
+finish more quickly. Otherwise, the full handshake will be done. For example: |
connection.handshakeClientSRP("alice", "abra123cadabra") |
. |
@@ -250,28 +234,10 @@ To perform SRP authentication, you have to pass in a database of password |
verifiers. The VerifierDB class manages an in-memory or on-disk verifier |
database. |
- #On-disk database (use no-arg constructor if you want an in-memory DB) |
verifierDB = VerifierDB("./test/verifierDB") |
- |
- #Open the pre-existing database (can also 'create()' a new one) |
verifierDB.open() |
- |
- #Add to the database |
- verifier = VerifierDB.makeVerifier("alice", "abra123cadabra", 2048) |
- verifierDB["alice"] = verifier |
- |
- #Perform a handshake using the database |
connection.handshakeServer(verifierDB=verifierDB) |
-To perform shared key authentication, you have to pass in a database of shared |
-keys. The SharedKeyDB class manages an in-memory or on-disk shared key |
-database. |
- |
- sharedKeyDB = SharedKeyDB("./test/sharedkeyDB") |
- sharedKeyDB.open() |
- sharedKeyDB["alice"] = "PaVBVZkYqAjCQCu6UBL2xgsnZhw" |
- connection.handshakeServer(sharedKeyDB=sharedKeyDB) |
- |
To perform authentication with a certificate and private key, the server must |
load these as described in the previous section, then pass them in. If the |
server sets the reqCert boolean to True, a certificate chain will be requested |
@@ -280,20 +246,30 @@ from the client. |
connection.handshakeServer(certChain=certChain, privateKey=privateKey, |
reqCert=True) |
-You can pass in any combination of a verifier database, a shared key database, |
-and a certificate chain/private key. The client will use one of them to |
-authenticate. In the case of SRP and a certificate chain/private key, they |
-both may be used. |
+You can pass in a verifier database and/or a certificate chain+private key. |
+The client will use one or both to authenticate the server. |
You can also pass in a HandshakeSettings object, as described in the last |
-section, for finer control over handshaking details. Finally, the server can |
-maintain a SessionCache, which will allow clients to use session resumption: |
+section, for finer control over handshaking details. |
+ |
+If you are passing in a certificate chain+private key, you may additionally |
+provide a TACK to assist the client in authenticating your certificate chain. |
+This requires the TACKpy library. Load a TACKpy.TACK object, then do: |
+ |
+ settings = HandshakeSettings() |
+ settings.useExperimentalTACKExtension = True # Needed for TACK support |
+ |
+ connection.handshakeServer(certChain=certChain, privateKey=privateKey, |
+ tack=tack, settings=settings) |
+ |
+Finally, the server can maintain a SessionCache, which will allow clients to |
+use session resumption: |
sessionCache = SessionCache() |
connection.handshakeServer(verifierDB=verifierDB, sessionCache=sessionCache) |
-It should be noted that the session cache, and the verifier and shared key |
-databases, are all thread-safe. |
+It should be noted that the session cache, and the verifier databases, are all |
+thread-safe. |
5 Step 4 - check the results |
----------------------------- |
@@ -301,71 +277,47 @@ If the handshake completes without raising an exception, authentication |
results will be stored in the connection's session object. The following |
variables will be populated if applicable, or else set to None: |
- connection.session.srpUsername #string |
- connection.session.sharedKeyUsername #string |
- connection.session.clientCertChain #X509CertChain or |
- #cryptoIDlib.CertChain.CertChain |
- connection.session.serverCertChain #X509CertChain or |
- #cryptoIDlib.CertChain.CertChain |
- |
-Both types of certificate chain object support the getFingerprint() function, |
-but with a difference. X.509 objects return the end-entity fingerprint, and |
-ignore the other certificates. CryptoID fingerprints (aka "cryptoIDs") are |
-based on the root cryptoID certificate, so you have to call validate() on the |
-CertChain to be sure you're really talking to the cryptoID. |
- |
-X.509 certificate chain objects may also be validated against a list of |
-trusted root certificates. See the API documentation for details. |
- |
-To save yourself the trouble of inspecting fingerprints after the handshake, |
-you can pass a Checker object into the handshake function. The checker will be |
-called if the handshake completes successfully. If the other party's |
-certificate chain isn't approved by the checker, a subclass of |
-TLSAuthenticationError will be raised. For example, to perform a handshake |
-with a server based on its X.509 fingerprint, do: |
+ connection.session.srpUsername # string |
+ connection.session.clientCertChain # X509CertChain |
+ connection.session.serverCertChain # X509CertChain |
+ connection.session.tackExt # TACKpy.TACK_Extension |
- try: |
- checker = Checker(\ |
- x509Fingerprint='e049ff930af76d43ff4c658b268786f4df1296f2') |
- connection.handshakeClientCert(checker=checker) |
- except TLSAuthenticationError: |
- print "Authentication failure" |
- |
-If the handshake fails for any reason, an exception will be raised. If the |
-socket timed out or was unexpectedly closed, a socket.error or |
-TLSAbruptCloseError will be raised. Otherwise, either a TLSLocalAlert or |
-TLSRemoteAlert will be raised, depending on whether the local or remote |
-implementation signalled the error. The exception object has a 'description' |
-member which identifies the error based on the codes in RFC 2246. A |
-TLSLocalAlert also has a 'message' string that may have more details. |
+X.509 chain objects return the end-entity fingerprint via getFingerprint(), |
+and ignore the other certificates. |
+ |
+TACK objects return the (validated) TACK ID via getTACKID(). |
+ |
+To save yourself the trouble of inspecting certificates and/or TACKs after the |
+handshake, you can pass a Checker object into the handshake function. The |
+checker will be called if the handshake completes successfully. If the other |
+party isn't approved by the checker, a subclass of TLSAuthenticationError will |
+be raised. |
+ |
+If the handshake fails for any reason, including a Checker error, an exception |
+will be raised and the socket will be closed. If the socket timed out or was |
+unexpectedly closed, a socket.error or TLSAbruptCloseError will be raised. |
+ |
+Otherwise, either a TLSLocalAlert or TLSRemoteAlert will be raised, depending |
+on whether the local or remote implementation signalled the error. The |
+exception object has a 'description' member which identifies the error based |
+on the codes in RFC 2246. A TLSLocalAlert also has a 'message' string that may |
+have more details. |
Example of handling a remote alert: |
try: |
[...] |
- except TLSRemoteAlert, alert: |
- if alert.description == AlertDescription.unknown_srp_username: |
+ except TLSRemoteAlert as alert: |
+ if alert.description == AlertDescription.unknown_psk_identity: |
print "Unknown user." |
[...] |
-Figuring out what went wrong based on the alert may require some |
-interpretation, particularly with remote alerts where you don't have an error |
-string, and where the remote implementation may not be signalling alerts |
-properly. Many alerts signal an implementation error, and so should rarely be |
-seen in normal operation (unexpected_message, decode_error, illegal_parameter, |
-internal_error, etc.). |
- |
-Others alerts are more likely to occur. Below are some common alerts and |
-their probable causes, and whether they are signalled by the client or server. |
+Below are some common alerts and their probable causes, and whether they are |
+signalled by the client or server. |
-Client bad_record_mac: |
- - bad shared key password |
- |
-Client handshake failure: |
+Client handshake_failure: |
- SRP parameters are not recognized by client |
- |
-Client user_canceled: |
- - The client might have returned None from an SRP callback. |
+ - Server's TACK was unrelated to its certificate chain |
Client insufficient_security: |
- SRP parameters are too small |
@@ -379,43 +331,42 @@ Server protocol_version: |
Server bad_record_mac: |
- bad SRP username or password |
-Server unknown_srp_username |
+Server unknown_psk_identity |
- bad SRP username (bad_record_mac could be used for the same thing) |
Server handshake_failure: |
- - bad shared key username |
- no matching cipher suites |
5 Step 5 - exchange data |
------------------------- |
Now that you have a connection, you can call read() and write() as if it were |
-a socket.SSL object. You can also call send(), sendall(), recv(), and |
-makefile() as if it were a socket. These calls may raise TLSLocalAlert, |
+a socket.SSL object. You can also call send(), sendall(), recv(), and |
+makefile() as if it were a socket. These calls may raise TLSLocalAlert, |
TLSRemoteAlert, socket.error, or TLSAbruptCloseError, just like the handshake |
functions. |
Once the TLS connection is closed by the other side, calls to read() or recv() |
-will return an empty string. If the socket is closed by the other side |
-without first closing the TLS connection, calls to read() or recv() will return |
-a TLSAbruptCloseError, and calls to write() or send() will return a |
+will return an empty string. If the socket is closed by the other side without |
+first closing the TLS connection, calls to read() or recv() will return a |
+TLSAbruptCloseError, and calls to write() or send() will return a |
socket.error. |
5 Step 6 - close the connection |
-------------------------------- |
When you're finished sending data, you should call close() to close the |
-connection down. When the connection is closed properly, the socket stays |
-open and can be used for exchanging non-secure data, the session object can be |
-used for session resumption, and the connection object can be re-used by |
-calling another handshake function. |
- |
-If an exception is raised, the connection will be automatically closed; you |
-don't need to call close(). Furthermore, you will probably not be able to re- |
-use the socket, the connection object, or the session object, and you |
+connection and socket. When the connection is closed properly, the session |
+object can be used for session resumption. |
+ |
+If an exception is raised the connection will be automatically closed; you |
+don't need to call close(). Furthermore, you will probably not be able to |
+re-use the socket, the connection object, or the session object, and you |
shouldn't even try. |
-By default, calling close() will leave the socket open. If you set the |
-connection's closeSocket flag to True, the connection will take ownership of |
-the socket, and close it when the connection is closed. |
+By default, calling close() will close the underlying socket. If you set the |
+connection's closeSocket flag to False, the socket will remain open after |
+close. (NOTE: some TLS implementations will not respond properly to the |
+close_notify alert that close() generates, so the connection will hang if |
+closeSocket is set to True.) |
6 Using TLS Lite with httplib |
@@ -430,20 +381,9 @@ different types of authentication. |
r = h.getresponse() |
[...] |
- #Authenticate server based on its X.509 fingerprint |
- h = HTTPTLSConnection("www.amazon.com", 443, |
- x509Fingerprint="e049ff930af76d43ff4c658b268786f4df1296f2") |
- [...] |
- |
- #Authenticate server based on its X.509 chain (requires cryptlib_py [7]) |
- h = HTTPTLSConnection("www.amazon.com", 443, |
- x509TrustList=[verisignCert], |
- x509CommonName="www.amazon.com") |
- [...] |
- |
- #Authenticate server based on its cryptoID |
- h = HTTPTLSConnection("localhost", 443, |
- cryptoID="dmqb6.fq345.cxk6g.5fha3") |
+ #Authenticate server based on its TACK ID |
+ h = HTTPTLSConnection("localhost", 4443, |
+ tackID="B3ARS.EQ61B.F34EL.9KKLN.3WEW5", hardTack=False) |
[...] |
#Mutually authenticate with SRP |
@@ -451,42 +391,8 @@ different types of authentication. |
username="alice", password="abra123cadabra") |
[...] |
- #Mutually authenticate with a shared key |
- h = HTTPTLSConnection("localhost", 443, |
- username="alice", sharedKey="PaVBVZkYqAjCQCu6UBL2xgsnZhw") |
- [...] |
- |
- #Mutually authenticate with SRP, *AND* authenticate the server based |
- #on its cryptoID |
- h = HTTPTLSConnection("localhost", 443, |
- username="alice", password="abra123cadabra", |
- cryptoID="dmqb6.fq345.cxk6g.5fha3") |
- [...] |
- |
- |
-7 Using TLS Lite with xmlrpclib |
-================================ |
-TLS Lite comes with an XMLRPCTransport class that extends xmlrpclib to work |
-over SSL/TLS connections. This class accepts the same parameters as |
-HTTPTLSConnection (see previous section), and behaves similarly. Depending on |
-how you construct it, it will do different types of authentication. |
- |
- from tlslite.api import XMLRPCTransport |
- from xmlrpclib import ServerProxy |
- |
- #No authentication whatsoever |
- transport = XMLRPCTransport() |
- server = ServerProxy("https://localhost", transport) |
- server.someFunc(2, 3) |
- [...] |
- |
- #Authenticate server based on its X.509 fingerprint |
- transport = XMLRPCTransport(\ |
- x509Fingerprint="e049ff930af76d43ff4c658b268786f4df1296f2") |
- [...] |
- |
-8 Using TLS Lite with poplib or imaplib |
+7 Using TLS Lite with poplib or imaplib |
======================================== |
TLS Lite comes with POP3_TLS and IMAP4_TLS classes that extend poplib and |
imaplib to work over SSL/TLS connections. These classes can be constructed |
@@ -495,7 +401,7 @@ behave similarly. |
#To connect to a POP3 server over SSL and display its fingerprint: |
from tlslite.api import * |
- p = POP3_TLS("---------.net") |
+ p = POP3_TLS("---------.net", port=995) |
print p.sock.session.serverCertChain.getFingerprint() |
[...] |
@@ -506,7 +412,7 @@ behave similarly. |
[...] |
-9 Using TLS Lite with smtplib |
+8 Using TLS Lite with smtplib |
============================== |
TLS Lite comes with an SMTP_TLS class that extends smtplib to work |
over SSL/TLS connections. This class accepts the same parameters as |
@@ -515,12 +421,13 @@ on how you call starttls(), it will do different types of authentication. |
#To connect to an SMTP server once you know its fingerprint: |
from tlslite.api import * |
- s = SMTP_TLS("----------.net") |
+ s = SMTP_TLS("----------.net", port=587) |
+ s.ehlo() |
s.starttls(x509Fingerprint="7e39be84a2e3a7ad071752e3001d931bf82c32dc") |
[...] |
-10 Using TLS Lite with SocketServer |
+9 Using TLS Lite with SocketServer |
==================================== |
You can use TLS Lite to implement servers using Python's SocketServer |
framework. TLS Lite comes with a TLSSocketServerMixIn class. You can combine |
@@ -528,141 +435,112 @@ this with a TCPServer such as HTTPServer. To combine them, define a new class |
that inherits from both of them (with the mix-in first). Then implement the |
handshake() method, doing some sort of server handshake on the connection |
argument. If the handshake method returns True, the RequestHandler will be |
-triggered. Below is a complete example of a threaded HTTPS server. |
- |
- from SocketServer import * |
- from BaseHTTPServer import * |
- from SimpleHTTPServer import * |
- from tlslite.api import * |
- |
- s = open("./serverX509Cert.pem").read() |
- x509 = X509() |
- x509.parse(s) |
- certChain = X509CertChain([x509]) |
- |
- s = open("./serverX509Key.pem").read() |
- privateKey = parsePEMKey(s, private=True) |
- |
- sessionCache = SessionCache() |
- |
- class MyHTTPServer(ThreadingMixIn, TLSSocketServerMixIn, HTTPServer): |
- def handshake(self, tlsConnection): |
- try: |
- tlsConnection.handshakeServer(certChain=certChain, |
- privateKey=privateKey, |
- sessionCache=sessionCache) |
- tlsConnection.ignoreAbruptClose = True |
- return True |
- except TLSError, error: |
- print "Handshake failure:", str(error) |
- return False |
+triggered. See the tests/httpsserver.py example. |
- httpd = MyHTTPServer(('localhost', 443), SimpleHTTPRequestHandler) |
- httpd.serve_forever() |
- |
-11 Using TLS Lite with asyncore |
+10 Using TLS Lite with asyncore |
================================ |
TLS Lite can be used with subclasses of asyncore.dispatcher. See the comments |
in TLSAsyncDispatcherMixIn.py for details. This is still experimental, and |
may not work with all asyncore.dispatcher subclasses. |
-Below is an example of combining Medusa's http_channel with |
-TLSAsyncDispatcherMixIn: |
- |
- class http_tls_channel(TLSAsyncDispatcherMixIn, |
- http_server.http_channel): |
- ac_in_buffer_size = 16384 |
- |
- def __init__ (self, server, conn, addr): |
- http_server.http_channel.__init__(self, server, conn, addr) |
- TLSAsyncDispatcherMixIn.__init__(self, conn) |
- self.tlsConnection.ignoreAbruptClose = True |
- self.setServerHandshakeOp(certChain=certChain, |
- privateKey=privateKey) |
- |
- |
-12 Using TLS Lite with Twisted |
-=============================== |
-TLS Lite can be used with Twisted protocols. Below is a complete example of |
-using TLS Lite with a Twisted echo server. |
- |
-There are two server implementations below. Echo is the original protocol, |
-which is oblivious to TLS. Echo1 subclasses Echo and negotiates TLS when the |
-client connects. Echo2 subclasses Echo and negotiates TLS when the client |
-sends "STARTTLS". |
- |
- from twisted.internet.protocol import Protocol, Factory |
- from twisted.internet import reactor |
- from twisted.protocols.policies import WrappingFactory |
- from twisted.protocols.basic import LineReceiver |
- from twisted.python import log |
- from twisted.python.failure import Failure |
- import sys |
- from tlslite.api import * |
- |
- s = open("./serverX509Cert.pem").read() |
- x509 = X509() |
- x509.parse(s) |
- certChain = X509CertChain([x509]) |
- |
- s = open("./serverX509Key.pem").read() |
- privateKey = parsePEMKey(s, private=True) |
- |
- verifierDB = VerifierDB("verifierDB") |
- verifierDB.open() |
- |
- class Echo(LineReceiver): |
- def connectionMade(self): |
- self.transport.write("Welcome to the echo server!\r\n") |
- |
- def lineReceived(self, line): |
- self.transport.write(line + "\r\n") |
- |
- class Echo1(Echo): |
- def connectionMade(self): |
- if not self.transport.tlsStarted: |
- self.transport.setServerHandshakeOp(certChain=certChain, |
- privateKey=privateKey, |
- verifierDB=verifierDB) |
- else: |
- Echo.connectionMade(self) |
- |
- def connectionLost(self, reason): |
- pass #Handle any TLS exceptions here |
- |
- class Echo2(Echo): |
- def lineReceived(self, data): |
- if data == "STARTTLS": |
- self.transport.setServerHandshakeOp(certChain=certChain, |
- privateKey=privateKey, |
- verifierDB=verifierDB) |
- else: |
- Echo.lineReceived(self, data) |
- |
- def connectionLost(self, reason): |
- pass #Handle any TLS exceptions here |
- |
- factory = Factory() |
- factory.protocol = Echo1 |
- #factory.protocol = Echo2 |
- |
- wrappingFactory = WrappingFactory(factory) |
- wrappingFactory.protocol = TLSTwistedProtocolWrapper |
- log.startLogging(sys.stdout) |
- reactor.listenTCP(1079, wrappingFactory) |
- reactor.run() |
- |
- |
-13 Security Considerations |
+11 Security Considerations |
=========================== |
-TLS Lite is beta-quality code. It hasn't received much security analysis. |
-Use at your own risk. |
+TLS Lite is beta-quality code. It hasn't received much security analysis. Use |
+at your own risk. |
+TLS Lite is probably vulnerable to the "Lucky 13" timing attack if AES or 3DES |
+are used. Thus, TLS Lite prefers the RC4 cipher. |
-14 History |
+ |
+12 History |
=========== |
+0.4.6 - 3/20/2013 |
+ - **API CHANGE**: TLSClosedConnectionError instead of ValueError when writing |
+ to a closed connection. This inherits from socket.error, so should |
+ interact better with SocketServer (see http://bugs.python.org/issue14574) |
+ and other things expecting a socket.error in this situation. |
+ - Added support for RC4-MD5 ciphersuite (if enabled in settings) |
+ - This is allegedly necessary to connect to some Internet servers. |
+ - Added TLSConnection.unread() function |
+ - Switched to New-style classes (inherit from 'object') |
+ - Minor cleanups |
+ |
+0.4.5 - (release engineering problem, skipped!) |
+ |
+0.4.4 - 2/25/2013 |
+ - Added Python 3 support (Martin von Loewis) |
+ - Added NPN client support (Marcelo Fernandez) |
+ - Switched to RC4 as preferred cipher |
+ - faster in Python, avoids "Lucky 13" timing attacks |
+ - Fixed bug when specifying ciphers for anon ciphersuites |
+ - Made RSA hashAndVerify() tolerant of sigs w/o encoded NULL AlgorithmParam |
+ - (this function is not used for TLS currently, and this tolerance may |
+ not even be necessary) |
+0.4.3 - 9/27/2012 |
+ - Minor bugfix (0.4.2 doesn't load tackpy) |
+0.4.2 - 9/25/2012 |
+ - Updated TACK (compatible with tackpy 0.9.9) |
+0.4.1 - 5/22/2012 |
+ - Fixed RSA padding bugs (w/help from John Randolph) |
+ - Updated TACK (compatible with tackpy 0.9.7) |
+ - Added SNI |
+ - Added NPN server support (Sam Rushing/Google) |
+ - Added AnonDH (Dimitris Moraitis) |
+ - Added X509CertChain.parsePemList |
+ - Improved XML-RPC (Kees Bos) |
+ |
+0.4.0 - 2/11/2012 |
+ - Fixed pycrypto support |
+ - Fixed python 2.6 problems |
+ |
+0.3.9.x - 2/7/2012 |
+ |
+Much code cleanup, in particular decomposing the handshake functions so they |
+are readable. The main new feature is support for TACK, an experimental |
+authentication method that provides a new way to pin server certificates (See |
+https://github.com/moxie0/Convergence/wiki/TACK ). |
+ |
+Also: |
+ |
+ - Security Fixes |
+ - Sends SCSV ciphersuite as per RFC 5746, to signal non-renegotiated |
+ Client Hello. Does not support renegotiation (never has). |
+ - Change from e=3 to e=65537 for generated RSA keys, not strictly |
+ necessary but mitigates risk of sloppy verifier. |
+ - 1/(n-1) countermeasure for BEAST. |
+ |
+ - Behavior changes: |
+ - Split cmdline into tls.py and tlstest.py, improved options. |
+ - Formalized LICENSE. |
+ - Defaults to closing socket after sending close_notify, fixes hanging. |
+ problem that would occur sometime when waiting for other party's |
+ close_notify. |
+ - Update SRP to RFC 5054 compliance. |
+ - Removed client handshake "callbacks", no longer support the SRP |
+ re-handshake idiom within a single handshake function. |
+ |
+ - Bugfixes |
+ - Added hashlib support, removes Deprecation Warning due to sha and md5. |
+ - Handled GeneratorExit exceptions that are a new Python feature, and |
+ interfere with the async code if not handled. |
+ |
+ - Removed: |
+ - Shared keys (it was based on an ancient I-D, not TLS-PSK). |
+ - cryptlib support, it wasn't used much, we have enough other options. |
+ - cryptoIDs (TACK is better). |
+ - win32prng extension module, as os.urandom is now available. |
+ - Twisted integration (unused?, slowed down loading). |
+ - Jython code (ancient, didn't work). |
+ - Compat support for python versions < 2.7. |
+ |
+ - Additions |
+ - Support for TACK via TACKpy. |
+ - Support for CertificateRequest.certificate_authorities ("reqCAs") |
+ - Added TLSConnection.shutdown() to better mimic socket. |
+ - Enabled Session resumption for XMLRPCTransport. |
+ |
0.3.8 - 2/21/2005 |
- Added support for poplib, imaplib, and smtplib |
- Added python 2.4 windows installer |
@@ -773,43 +651,3 @@ Use at your own risk. |
- added testing functions to tls.py |
0.1.0 - 2/01/2004 |
- first release |
- |
- |
-15 References |
-============== |
-[0] http://www.ietf.org/html.charters/tls-charter.html |
-[1] http://www.trevp.net/tls_srp/draft-ietf-tls-srp-07.html |
-[2] http://www.ietf.org/internet-drafts/draft-ietf-tls-sharedkeys-02.txt |
-[3] http://www.trevp.net/cryptoID/ |
-[4] http://www.openssl.org/ |
-[5] http://www.cs.auckland.ac.nz/~pgut001/cryptlib/ |
-[6] http://sandbox.rulemaker.net/ngps/m2/ |
-[7] http://trevp.net/cryptlibConverter/ |
-[8] http://www.trevp.net/cryptoID/ |
-[9] http://www.amk.ca/python/code/crypto.html |
-[10] http://gmpy.sourceforge.net/ |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |