diff options
author | Jocelyn Turcotte <jocelyn.turcotte@digia.com> | 2014-08-08 14:30:41 +0200 |
---|---|---|
committer | Jocelyn Turcotte <jocelyn.turcotte@digia.com> | 2014-08-12 13:49:54 +0200 |
commit | ab0a50979b9eb4dfa3320eff7e187e41efedf7a9 (patch) | |
tree | 498dfb8a97ff3361a9f7486863a52bb4e26bb898 /chromium/third_party/tlslite | |
parent | 4ce69f7403811819800e7c5ae1318b2647e778d1 (diff) | |
download | qtwebengine-chromium-ab0a50979b9eb4dfa3320eff7e187e41efedf7a9.tar.gz |
Update Chromium to beta version 37.0.2062.68
Change-Id: I188e3b5aff1bec75566014291b654eb19f5bc8ca
Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'chromium/third_party/tlslite')
106 files changed, 7225 insertions, 9395 deletions
diff --git a/chromium/third_party/tlslite/LICENSE b/chromium/third_party/tlslite/LICENSE index 3c952fc6c01..8ba3b791ccd 100644 --- a/chromium/third_party/tlslite/LICENSE +++ b/chromium/third_party/tlslite/LICENSE @@ -1 +1,67 @@ -All code here is public domain. + +TLS Lite includes code from different sources. All code is either dedicated to +the public domain by its authors, or available under a BSD-style license. In +particular: + +- + +Code written by Trevor Perrin, Kees Bos, Sam Rushing, Dimitris Moraitis, +Marcelo Fernandez, Martin von Loewis, and Dave Baggett is available under the +following terms: + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or distribute +this software, either in source code form or as a compiled binary, for any +purpose, commercial or non-commercial, and by any means. + +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +- + +Code written by Bram Cohen (rijndael.py) was dedicated to the public domain by +its author. See rijndael.py for details. + +- + +Code written by Google is available under the following terms: + +Copyright (c) 2008, The Chromium Authors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of the Google Inc. nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/chromium/third_party/tlslite/MANIFEST.in b/chromium/third_party/tlslite/MANIFEST.in new file mode 100644 index 00000000000..340da6966c0 --- /dev/null +++ b/chromium/third_party/tlslite/MANIFEST.in @@ -0,0 +1,6 @@ +recursive-include tests * +recursive-include docs * +include LICENSE +include README +include Makefile +include MANIFEST.in
\ No newline at end of file diff --git a/chromium/third_party/tlslite/Makefile b/chromium/third_party/tlslite/Makefile new file mode 100644 index 00000000000..6d9e7ac8c9b --- /dev/null +++ b/chromium/third_party/tlslite/Makefile @@ -0,0 +1,24 @@ + +.PHONY : default +default: + @echo To install tlslite run \"./setup.py install\" or \"make install\" + +.PHONY: install +install: + ./setup.py install + +.PHONY : clean +clean: + rm -rf tlslite/*.pyc + rm -rf tlslite/utils/*.pyc + rm -rf tlslite/integration/*.pyc + rm -rf dist + rm -rf docs + rm -rf build + rm -f MANIFEST + +docs: + epydoc --html -v --introspect-only -o docs tlslite + +dist: docs + ./setup.py sdist diff --git a/chromium/third_party/tlslite/PKG-INFO b/chromium/third_party/tlslite/PKG-INFO new file mode 100644 index 00000000000..b03c85b5695 --- /dev/null +++ b/chromium/third_party/tlslite/PKG-INFO @@ -0,0 +1,10 @@ +Metadata-Version: 1.0 +Name: tlslite +Version: 0.4.6 +Summary: tlslite implements SSL and TLS. +Home-page: http://trevp.net/tlslite/ +Author: Trevor Perrin +Author-email: tlslite@trevp.net +License: public domain and BSD +Description: UNKNOWN +Platform: UNKNOWN diff --git a/chromium/third_party/tlslite/README b/chromium/third_party/tlslite/README new file mode 100644 index 00000000000..1b3247abe4f --- /dev/null +++ b/chromium/third_party/tlslite/README @@ -0,0 +1,653 @@ + +tlslite version 0.4.6 Mar 20 2013 +Trevor Perrin <tlslite at trevp.net> +http://trevp.net/tlslite/ +============================================================================ + + +Table of Contents +================== +1 Introduction +2 License/Acknowledgements +3 Installation +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 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. For discussing +improvements to tlslite, also see 'tlslite-dev@googlegroups.com'. + + +2 Licenses/Acknowledgements +============================ +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. + +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. + + +3 Installation +=============== +Requirements: + Python 2.6 or higher is required. Python 3 is supported. + +Options: + - If you have the M2Crypto interface to OpenSSL, this will be used for fast + RSA operations and fast ciphers. + + - If you have pycrypto this will be used for fast RSA operations and fast + ciphers. + + - 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. + +Run 'python setup.py install' + +Test the Installation: + - From the distribution's ./tests subdirectory, run: + ./tlstest.py server localhost:4443 . + - While the test server is waiting, run: + ./tlstest.py client localhost:4443 . + + If both say "Test succeeded" at the end, you're ready to go. + + +4 Getting Started with the Command-Line Tools +============================================== +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 SRP verifier databases. These databases are used by +a TLS server when authenticating clients with SRP. + +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 server -v verifierDB localhost:4443 + +Then try connecting to the server with: + + tls.py client localhost:4443 alice abra123cadabra + +HTTPS +------ +To run an HTTPS server with less typing, run ./tests/httpsserver.sh. + +To run an HTTPS client, run ./tests/httpsclient.py. + + +5 Getting Started with the Library +=================================== +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. +4) Check the results to make sure you're talking to the right party. +5) Use the TLSConnection to exchange data. +6) Call close() on the TLSConnection when you're done. + +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. + + from socket import * + sock = socket(AF_INET, SOCK_STREAM) + sock.connect( ("www.amazon.com", 443) ) + +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 two different handshake functions you can call, +depending on how you want to authenticate: + + connection.handshakeClientCert() + connection.handshakeClientCert(certChain, privateKey) + + connection.handshakeClientSRP("alice", "abra123cadabra") + +The ClientCert function without arguments is used when connecting to a site +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 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) + certChain = X509CertChain([x509]) + s = open("./test/clientX509Key.pem").read() + privateKey = parsePEMKey(s, private=True) + +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 +(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) + +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") + . + . + oldSession = connection.session + connection2.handshakeClientSRP("alice", "abra123cadabra", session= + oldSession) + +5 Step 3 - call a handshake function (server) +---------------------------------------------- +If you're a server, there's only one handshake function, but you can pass it +several different parameters, depending on which types of authentication +you're willing to perform. + +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. + + verifierDB = VerifierDB("./test/verifierDB") + verifierDB.open() + connection.handshakeServer(verifierDB=verifierDB) + +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 +from the client. + + connection.handshakeServer(certChain=certChain, privateKey=privateKey, + reqCert=True) + +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. + +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 databases, are all +thread-safe. + +5 Step 4 - check the results +----------------------------- +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.clientCertChain # X509CertChain + connection.session.serverCertChain # X509CertChain + connection.session.tackExt # TACKpy.TACK_Extension + +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 as alert: + if alert.description == AlertDescription.unknown_psk_identity: + print "Unknown user." + [...] + +Below are some common alerts and their probable causes, and whether they are +signalled by the client or server. + +Client handshake_failure: + - SRP parameters are not recognized by client + - Server's TACK was unrelated to its certificate chain + +Client insufficient_security: + - SRP parameters are too small + +Client protocol_version: + - Client doesn't support the server's protocol version + +Server protocol_version: + - Server doesn't support the client's protocol version + +Server bad_record_mac: + - bad SRP username or password + +Server unknown_psk_identity + - bad SRP username (bad_record_mac could be used for the same thing) + +Server handshake_failure: + - 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, +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 +socket.error. + +5 Step 6 - close the connection +-------------------------------- +When you're finished sending data, you should call close() to close the +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 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 +============================== +TLS Lite comes with an HTTPTLSConnection class that extends httplib to work +over SSL/TLS connections. Depending on how you construct it, it will do +different types of authentication. + + #No authentication whatsoever + h = HTTPTLSConnection("www.amazon.com", 443) + h.request("GET", "") + r = h.getresponse() + [...] + + #Authenticate server based on its TACK ID + h = HTTPTLSConnection("localhost", 4443, + tackID="B3ARS.EQ61B.F34EL.9KKLN.3WEW5", hardTack=False) + [...] + + #Mutually authenticate with SRP + h = HTTPTLSConnection("localhost", 443, + username="alice", password="abra123cadabra") + [...] + + +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 +with the same parameters as HTTPTLSConnection (see previous section), and +behave similarly. + + #To connect to a POP3 server over SSL and display its fingerprint: + from tlslite.api import * + p = POP3_TLS("---------.net", port=995) + print p.sock.session.serverCertChain.getFingerprint() + [...] + + #To connect to an IMAP server once you know its fingerprint: + from tlslite.api import * + i = IMAP4_TLS("cyrus.andrew.cmu.edu", + x509Fingerprint="00c14371227b3b677ddb9c4901e6f2aee18d3e45") + [...] + + +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 +HTTPTLSConnection (see previous section), and behaves similarly. Depending +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", port=587) + s.ehlo() + s.starttls(x509Fingerprint="7e39be84a2e3a7ad071752e3001d931bf82c32dc") + [...] + + +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 +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. See the tests/httpsserver.py example. + + +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. + + +11 Security Considerations +=========================== +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. + + +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 + - Fixed occassional timing problems with test suite +0.3.7 - 10/05/2004 + - Added support for Python 2.2 + - Cleaned up compatibility code, and docs, a bit +0.3.6 - 9/28/2004 + - Fixed script installation on UNIX + - Give better error message on old Python versions +0.3.5 - 9/16/2004 + - TLS 1.1 support + - os.urandom() support + - Fixed win32prng on some systems +0.3.4 - 9/12/2004 + - Updated for TLS/SRP draft 8 + - Bugfix: was setting _versioncheck on SRP 1st hello, causing problems + with GnuTLS (which was offering TLS 1.1) + - Removed _versioncheck checking, since it could cause interop problems + - Minor bugfix: when cryptlib_py and and cryptoIDlib present, cryptlib + was complaining about being initialized twice +0.3.3 - 6/10/2004 + - Updated for TLS/SRP draft 7 + - Updated test cryptoID cert chains for cryptoIDlib 0.3.1 +0.3.2 - 5/21/2004 + - fixed bug when handling multiple handshake messages per record (e.g. IIS) +0.3.1 - 4/21/2004 + - added xmlrpclib integration + - fixed hanging bug in Twisted integration + - fixed win32prng to work on a wider range of win32 sytems + - fixed import problem with cryptoIDlib + - fixed port allocation problem when test scripts are run on some UNIXes + - made tolerant of buggy IE sending wrong version in premaster secret +0.3.0 - 3/20/2004 + - added API docs thanks to epydoc + - added X.509 path validation via cryptlib + - much cleaning/tweaking/re-factoring/minor fixes +0.2.7 - 3/12/2004 + - changed Twisted error handling to use connectionLost() + - added ignoreAbruptClose +0.2.6 - 3/11/2004 + - added Twisted errorHandler + - added TLSAbruptCloseError + - added 'integration' subdirectory +0.2.5 - 3/10/2004 + - improved asynchronous support a bit + - added first-draft of Twisted support +0.2.4 - 3/5/2004 + - cleaned up asyncore support + - added proof-of-concept for Twisted +0.2.3 - 3/4/2004 + - added pycrypto RSA support + - added asyncore support +0.2.2 - 3/1/2004 + - added GMPY support + - added pycrypto support + - added support for PEM-encoded private keys, in pure python +0.2.1 - 2/23/2004 + - improved PRNG use (cryptlib, or /dev/random, or CryptoAPI) + - added RSA blinding, to avoid timing attacks + - don't install local copy of M2Crypto, too problematic +0.2.0 - 2/19/2004 + - changed VerifierDB to take per-user parameters + - renamed tls_lite -> tlslite +0.1.9 - 2/16/2004 + - added post-handshake 'Checker' + - made compatible with Python 2.2 + - made more forgiving of abrupt closure, since everyone does it: + if the socket is closed while sending/recv'ing close_notify, + just ignore it. +0.1.8 - 2/12/2004 + - TLSConnections now emulate sockets, including makefile() + - HTTPTLSConnection and TLSMixIn simplified as a result +0.1.7 - 2/11/2004 + - fixed httplib.HTTPTLSConnection with multiple requests + - fixed SocketServer to handle close_notify + - changed handshakeClientNoAuth() to ignore CertificateRequests + - changed handshakeClient() to ignore non-resumable session arguments +0.1.6 - 2/10/2004 + - fixed httplib support +0.1.5 - 2/09/2004 + - added support for httplib and SocketServer + - added support for SSLv3 + - added support for 3DES + - cleaned up read()/write() behavior + - improved HMAC speed +0.1.4 - 2/06/2004 + - fixed dumb bug in tls.py +0.1.3 - 2/05/2004 + - change read() to only return requested number of bytes + - added support for shared-key and in-memory databases + - added support for PEM-encoded X.509 certificates + - added support for SSLv2 ClientHello + - fixed shutdown/re-handshaking behavior + - cleaned up handling of missing_srp_username + - renamed readString()/writeString() -> read()/write() + - added documentation +0.1.2 - 2/04/2004 + - added clienttest/servertest functions + - improved OpenSSL cipher wrappers speed + - fixed server when it has a key, but client selects plain SRP + - fixed server to postpone errors until it has read client's messages + - fixed ServerHello to only include extension data if necessary +0.1.1 - 2/02/2004 + - fixed close_notify behavior + - fixed handling of empty application data packets + - fixed socket reads to not consume extra bytes + - added testing functions to tls.py +0.1.0 - 2/01/2004 + - first release diff --git a/chromium/third_party/tlslite/README.chromium b/chromium/third_party/tlslite/README.chromium index ed0d793eedd..5487bfc89a7 100644 --- a/chromium/third_party/tlslite/README.chromium +++ b/chromium/third_party/tlslite/README.chromium @@ -1,36 +1,18 @@ Name: tlslite URL: http://trevp.net/tlslite/ -Version: 0.3.8 +Version: 0.4.6 Security Critical: No -License: Public domain +License: Public domain and BSD -Local Modifications: +Description: Python TLS implementation for use with test server. + +Source: https://pypi.python.org/packages/source/t/tlslite/tlslite-0.4.6.tar.gz +MD5: 2f92ebea557802969653f29c7faafbc2 +SHA-512: 7b933499dfdafbdf3775c7e86bbc82a6fcee0b37a818d9106fe84436176df7f4 + 2f185f61a64c6548214909cfce530f5d143414173ffc8f074faf87f34c87f38c -- patches/close_notify.patch: tlslite/TLSRecordLayer.py was changed to force - the socket to be closed when the SSL connection is closed. This is is - necessary at this point since WinHTTP does not seem to react to the SSL - close notify. It's also needed to prevent a hang on Linux. See also - http://sourceforge.net/mailarchive/forum.php?thread_name=41C9B18B.2010201%40ag.com&forum_name=tlslite-users -- patches/python26.patch: Replace sha, md5 module imports with hashlib, as - they are deprecated in Python 2.6 -- patches/ca_request.patch: tlslite/X509.py was changed to obtain the - DER-encoded distinguished name for a certificate, without requiring any - addition libraries. - tlslite/utils/ASN1Parser.py was changed to allow obtaining the unparsed - data for an element in a SEQUENCE, in addition to providing the parsed - value (tag and length removed) - tlslite/messages.py was changed from accepting/returning a single byte - array in the CertificateRequest message for the CA names to accept a list - of byte arrays, each containing a DER-encoded distinguished name. - tlslite/TLSConnection.py was changed to take a list of such byte arrays - when creating a TLS server that will request client authentication. -- patches/send_certificate_types.patch: tlslite/message.py was changed to - default to a certificate_types of [rsa_sign] in CertificateRequest. Apple's - Secure Transport library rejects an empty list and raises an SSL protocol - error. -- patches/parse_chain.patch: tlslite/X509CertChain.py and tlslite/X509.py were - updated to add a parseChain method, that can parse multiple certificates from - a PEM string. +Local Modifications: +- Drop docs/, scripts/, and tests/ directories. - patches/tls_intolerant.patch: allow TLSLite to simulate a TLS-intolerant server. - patches/channel_id.patch: add basic ChannelID support. (Signatures are not checked.) @@ -39,3 +21,17 @@ Local Modifications: - patches/fallback_scsv.patch: add support for TLS_FALLBACK_SCSV. See https://tools.ietf.org/html/draft-bmoeller-tls-downgrade-scsv-01 - patches/status_request.patch: add support for sending stapled OCSP responses. +- patches/pycrypto.patch: fix PyCrypto support code. +- patches/client_cipher_preferences.patch: honor client cipher preferences. + tlslite's current ordering will otherwise negotiate + TLS_RSA_WITH_3DES_EDE_CBC_SHA. +- patches/ssl3_padding.patch: SSL3 requires minimal padding in CBC mode. +- patches/srp_cert.patch: Prefer srp + cert over srp, to fix tlslite tests after + client_cipher_preferences.patch. +- patches/fix_test_file.patch: Fix #! line in random test file to appease our + presubmit checks. +- patches/dhe_rsa.patch: Implement DHE_RSA-based cipher suites. +- patches/req_cert_types.patch: Add a reqCertTypes parameter to populate the + certificate_types field of CertificateRequest. +- patches/ignore_write_failure.patch: Don't invalidate sessions on write + failures. diff --git a/chromium/third_party/tlslite/make_release.py b/chromium/third_party/tlslite/make_release.py deleted file mode 100644 index d2898798f27..00000000000 --- a/chromium/third_party/tlslite/make_release.py +++ /dev/null @@ -1,61 +0,0 @@ - -#When run on (my) windows box, this builds and cleans everything in -#preparation for a release. - -import os -import sys - -#Replace version strings -if len(sys.argv)>1: - oldVersion = sys.argv[1] - newVersion = sys.argv[2] - query = raw_input("Replace %s with %s?: " % (oldVersion, newVersion)) - if query == "y": - #First, scan through and make sure the replacement is possible - for filename in ("setup.py", "tlslite\\__init__.py", "scripts\\tls.py", "scripts\\tlsdb.py"): - s = open(filename, "rU").read() - x = s.count(oldVersion) - if filename.endswith("__init__.py"): - if x != 2: - print "Error, old version appears in %s %s times" % (filename, x) - sys.exit() - else: - if x != 1: - print "Error, old version appears in %s %s times" % (filename, x) - sys.exit() - - #Then perform it - for filename in ("setup.py", "tlslite\\__init__.py", "scripts\\tls.py", "scripts\\tlsdb.py"): - os.system("copy %s .." % filename) #save a backup copy in case something goes awry - s = open(filename, "r").read() - f = open(filename, "w") - f.write(s.replace(oldVersion, newVersion)) - f.close() - - -#Make windows installers -os.system("del installers\*.exe") - -#Python 2.3 -os.system("rmdir build /s /q") -os.system("python23 setup.py bdist_wininst -o") -os.system("copy dist\* installers") - -#Python 2.4 -os.system("rmdir build /s /q") -os.system("python24 setup.py bdist_wininst -o") -os.system("copy dist\* installers") - - -#Make documentation -os.system("python23 c:\\devtools\\python23\\scripts\\epydoc.py --html -o docs tlslite") - -#Delete excess files -os.system("del tlslite\\*.pyc") -os.system("del tlslite\\utils\\*.pyc") -os.system("del tlslite\\integration\\*.pyc") -os.system("rmdir build /s /q") -os.system("rmdir dist /s /q") - - - diff --git a/chromium/third_party/tlslite/patches/ca_request.patch b/chromium/third_party/tlslite/patches/ca_request.patch deleted file mode 100644 index c1270c05c02..00000000000 --- a/chromium/third_party/tlslite/patches/ca_request.patch +++ /dev/null @@ -1,176 +0,0 @@ -Only in chromium: patches -diff -aur tlslite-0.3.8/tlslite/TLSConnection.py chromium/tlslite/TLSConnection.py ---- tlslite-0.3.8/tlslite/TLSConnection.py 2004-10-06 01:55:37.000000000 -0400 -+++ chromium/tlslite/TLSConnection.py 2010-08-18 22:17:30.962786700 -0400 -@@ -931,7 +931,8 @@ - - def handshakeServer(self, sharedKeyDB=None, verifierDB=None, - certChain=None, privateKey=None, reqCert=False, -- sessionCache=None, settings=None, checker=None): -+ sessionCache=None, settings=None, checker=None, -+ reqCAs=None): - """Perform a handshake in the role of server. - - This function performs an SSL or TLS handshake. Depending on -@@ -997,6 +998,11 @@ - invoked to examine the other party's authentication - credentials, if the handshake completes succesfully. - -+ @type reqCAs: list of L{array.array} of unsigned bytes -+ @param reqCAs: A collection of DER-encoded DistinguishedNames that -+ will be sent along with a certificate request. This does not affect -+ verification. -+ - @raise socket.error: If a socket error occurs. - @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed - without a preceding alert. -@@ -1006,13 +1012,14 @@ - """ - for result in self.handshakeServerAsync(sharedKeyDB, verifierDB, - certChain, privateKey, reqCert, sessionCache, settings, -- checker): -+ checker, reqCAs): - pass - - - def handshakeServerAsync(self, sharedKeyDB=None, verifierDB=None, - certChain=None, privateKey=None, reqCert=False, -- sessionCache=None, settings=None, checker=None): -+ sessionCache=None, settings=None, checker=None, -+ reqCAs=None): - """Start a server handshake operation on the TLS connection. - - This function returns a generator which behaves similarly to -@@ -1028,14 +1035,15 @@ - sharedKeyDB=sharedKeyDB, - verifierDB=verifierDB, certChain=certChain, - privateKey=privateKey, reqCert=reqCert, -- sessionCache=sessionCache, settings=settings) -+ sessionCache=sessionCache, settings=settings, -+ reqCAs=reqCAs) - for result in self._handshakeWrapperAsync(handshaker, checker): - yield result - - - def _handshakeServerAsyncHelper(self, sharedKeyDB, verifierDB, - certChain, privateKey, reqCert, sessionCache, -- settings): -+ settings, reqCAs): - - self._handshakeStart(client=False) - -@@ -1045,6 +1053,8 @@ - raise ValueError("Caller passed a certChain but no privateKey") - if privateKey and not certChain: - raise ValueError("Caller passed a privateKey but no certChain") -+ if reqCAs and not reqCert: -+ raise ValueError("Caller passed reqCAs but not reqCert") - - if not settings: - settings = HandshakeSettings() -@@ -1380,7 +1390,9 @@ - msgs.append(ServerHello().create(self.version, serverRandom, - sessionID, cipherSuite, certificateType)) - msgs.append(Certificate(certificateType).create(serverCertChain)) -- if reqCert: -+ if reqCert and reqCAs: -+ msgs.append(CertificateRequest().create([], reqCAs)) -+ elif reqCert: - msgs.append(CertificateRequest()) - msgs.append(ServerHelloDone()) - for result in self._sendMsgs(msgs): -diff -aur tlslite-0.3.8/tlslite/X509.py chromium/tlslite/X509.py ---- tlslite-0.3.8/tlslite/X509.py 2004-03-19 21:43:19.000000000 -0400 -+++ chromium/tlslite/X509.py 2010-08-18 22:17:30.967787000 -0400 -@@ -13,11 +13,15 @@ - - @type publicKey: L{tlslite.utils.RSAKey.RSAKey} - @ivar publicKey: The subject public key from the certificate. -+ -+ @type subject: L{array.array} of unsigned bytes -+ @ivar subject: The DER-encoded ASN.1 subject distinguished name. - """ - - def __init__(self): - self.bytes = createByteArraySequence([]) - self.publicKey = None -+ self.subject = None - - def parse(self, s): - """Parse a PEM-encoded X.509 certificate. -@@ -63,6 +67,10 @@ - else: - subjectPublicKeyInfoIndex = 5 - -+ #Get the subject -+ self.subject = tbsCertificateP.getChildBytes(\ -+ subjectPublicKeyInfoIndex - 1) -+ - #Get the subjectPublicKeyInfo - subjectPublicKeyInfoP = tbsCertificateP.getChild(\ - subjectPublicKeyInfoIndex) -diff -aur tlslite-0.3.8/tlslite/messages.py chromium/tlslite/messages.py ---- tlslite-0.3.8/tlslite/messages.py 2004-10-06 01:01:24.000000000 -0400 -+++ chromium/tlslite/messages.py 2010-08-18 22:17:30.976787500 -0400 -@@ -338,8 +338,7 @@ - def __init__(self): - self.contentType = ContentType.handshake - self.certificate_types = [] -- #treat as opaque bytes for now -- self.certificate_authorities = createByteArraySequence([]) -+ self.certificate_authorities = [] - - def create(self, certificate_types, certificate_authorities): - self.certificate_types = certificate_types -@@ -349,7 +348,13 @@ - def parse(self, p): - p.startLengthCheck(3) - self.certificate_types = p.getVarList(1, 1) -- self.certificate_authorities = p.getVarBytes(2) -+ ca_list_length = p.get(2) -+ index = 0 -+ self.certificate_authorities = [] -+ while index != ca_list_length: -+ ca_bytes = p.getVarBytes(2) -+ self.certificate_authorities.append(ca_bytes) -+ index += len(ca_bytes)+2 - p.stopLengthCheck() - return self - -@@ -357,7 +362,14 @@ - w = HandshakeMsg.preWrite(self, HandshakeType.certificate_request, - trial) - w.addVarSeq(self.certificate_types, 1, 1) -- w.addVarSeq(self.certificate_authorities, 1, 2) -+ caLength = 0 -+ #determine length -+ for ca_dn in self.certificate_authorities: -+ caLength += len(ca_dn)+2 -+ w.add(caLength, 2) -+ #add bytes -+ for ca_dn in self.certificate_authorities: -+ w.addVarSeq(ca_dn, 1, 2) - return HandshakeMsg.postWrite(self, w, trial) - - class ServerKeyExchange(HandshakeMsg): -diff -aur tlslite-0.3.8/tlslite/utils/ASN1Parser.py chromium/tlslite/utils/ASN1Parser.py ---- tlslite-0.3.8/tlslite/utils/ASN1Parser.py 2004-10-06 01:02:40.000000000 -0400 -+++ chromium/tlslite/utils/ASN1Parser.py 2010-08-18 22:17:30.979787700 -0400 -@@ -16,13 +16,16 @@ - - #Assuming this is a sequence... - def getChild(self, which): -+ return ASN1Parser(self.getChildBytes(which)) -+ -+ def getChildBytes(self, which): - p = Parser(self.value) - for x in range(which+1): - markIndex = p.index - p.get(1) #skip Type - length = self._getASN1Length(p) - p.getFixBytes(length) -- return ASN1Parser(p.bytes[markIndex : p.index]) -+ return p.bytes[markIndex : p.index] - - #Decode the ASN.1 DER length field - def _getASN1Length(self, p): diff --git a/chromium/third_party/tlslite/patches/channel_id.patch b/chromium/third_party/tlslite/patches/channel_id.patch index 472406edad7..0fe16924b57 100644 --- a/chromium/third_party/tlslite/patches/channel_id.patch +++ b/chromium/third_party/tlslite/patches/channel_id.patch @@ -1,194 +1,65 @@ -diff --git a/third_party/tlslite/tlslite/TLSConnection.py b/third_party/tlslite/tlslite/TLSConnection.py -index f8811a9..e882e2c 100644 ---- a/third_party/tlslite/tlslite/TLSConnection.py -+++ b/third_party/tlslite/tlslite/TLSConnection.py -@@ -611,6 +611,8 @@ class TLSConnection(TLSRecordLayer): - settings.cipherImplementations) - - #Exchange ChangeCipherSpec and Finished messages -+ for result in self._getChangeCipherSpec(): -+ yield result - for result in self._getFinished(): - yield result - for result in self._sendFinished(): -@@ -920,6 +922,8 @@ class TLSConnection(TLSRecordLayer): - #Exchange ChangeCipherSpec and Finished messages - for result in self._sendFinished(): - yield result -+ for result in self._getChangeCipherSpec(): -+ yield result - for result in self._getFinished(): - yield result - -@@ -1089,6 +1093,7 @@ class TLSConnection(TLSRecordLayer): - clientCertChain = None - serverCertChain = None #We may set certChain to this later - postFinishedError = None -+ doingChannelID = False - - #Tentatively set version to most-desirable version, so if an error - #occurs parsing the ClientHello, this is what we'll use for the -@@ -1208,6 +1213,8 @@ class TLSConnection(TLSRecordLayer): - serverHello.create(self.version, serverRandom, - session.sessionID, session.cipherSuite, - certificateType) -+ serverHello.channel_id = clientHello.channel_id -+ doingChannelID = clientHello.channel_id - for result in self._sendMsg(serverHello): - yield result - -@@ -1221,6 +1228,11 @@ class TLSConnection(TLSRecordLayer): - #Exchange ChangeCipherSpec and Finished messages - for result in self._sendFinished(): - yield result -+ for result in self._getChangeCipherSpec(): -+ yield result -+ if doingChannelID: -+ for result in self._getEncryptedExtensions(): -+ yield result - for result in self._getFinished(): - yield result - -@@ -1399,8 +1411,12 @@ class TLSConnection(TLSRecordLayer): - #Send ServerHello, Certificate[, CertificateRequest], - #ServerHelloDone - msgs = [] -- msgs.append(ServerHello().create(self.version, serverRandom, -- sessionID, cipherSuite, certificateType)) -+ serverHello = ServerHello().create( -+ self.version, serverRandom, -+ sessionID, cipherSuite, certificateType) -+ serverHello.channel_id = clientHello.channel_id -+ doingChannelID = clientHello.channel_id -+ msgs.append(serverHello) - msgs.append(Certificate(certificateType).create(serverCertChain)) - if reqCert and reqCAs: - msgs.append(CertificateRequest().create([], reqCAs)) -@@ -1528,6 +1544,11 @@ class TLSConnection(TLSRecordLayer): - settings.cipherImplementations) - - #Exchange ChangeCipherSpec and Finished messages -+ for result in self._getChangeCipherSpec(): -+ yield result -+ if doingChannelID: -+ for result in self._getEncryptedExtensions(): -+ yield result - for result in self._getFinished(): - yield result - -diff --git a/third_party/tlslite/tlslite/TLSRecordLayer.py b/third_party/tlslite/tlslite/TLSRecordLayer.py -index 1bbd09d..933b95a 100644 ---- a/third_party/tlslite/tlslite/TLSRecordLayer.py -+++ b/third_party/tlslite/tlslite/TLSRecordLayer.py -@@ -714,6 +714,8 @@ class TLSRecordLayer: - self.version).parse(p) - elif subType == HandshakeType.finished: - yield Finished(self.version).parse(p) -+ elif subType == HandshakeType.encrypted_extensions: -+ yield EncryptedExtensions().parse(p) - else: - raise AssertionError() - -@@ -1067,7 +1069,7 @@ class TLSRecordLayer: - for result in self._sendMsg(finished): - yield result - -- def _getFinished(self): -+ def _getChangeCipherSpec(self): - #Get and check ChangeCipherSpec - for result in self._getMsg(ContentType.change_cipher_spec): - if result in (0,1): -@@ -1082,6 +1084,15 @@ class TLSRecordLayer: - #Switch to pending read state - self._changeReadState() - -+ def _getEncryptedExtensions(self): -+ for result in self._getMsg(ContentType.handshake, -+ HandshakeType.encrypted_extensions): -+ if result in (0,1): -+ yield result -+ encrypted_extensions = result -+ self.channel_id = encrypted_extensions.channel_id_key -+ -+ def _getFinished(self): - #Calculate verification data - verifyData = self._calcFinished(False) - diff --git a/third_party/tlslite/tlslite/constants.py b/third_party/tlslite/tlslite/constants.py -index 04302c0..e357dd0 100644 +index d52e596..79ad145 100755 --- a/third_party/tlslite/tlslite/constants.py +++ b/third_party/tlslite/tlslite/constants.py -@@ -22,6 +22,7 @@ class HandshakeType: - certificate_verify = 15 +@@ -31,6 +31,7 @@ class HandshakeType: client_key_exchange = 16 finished = 20 + next_protocol = 67 + encrypted_extensions = 203 class ContentType: change_cipher_spec = 20 -@@ -30,6 +31,9 @@ class ContentType: - application_data = 23 - all = (20,21,22,23) - -+class ExtensionType: -+ channel_id = 30031 -+ - class AlertLevel: - warning = 1 - fatal = 2 +@@ -45,6 +46,7 @@ class ExtensionType: # RFC 6066 / 4366 + cert_type = 9 # RFC 6091 + tack = 0xF300 + supports_npn = 13172 ++ channel_id = 30032 + + class NameType: + host_name = 0 diff --git a/third_party/tlslite/tlslite/messages.py b/third_party/tlslite/tlslite/messages.py -index dc6ed32..fa4d817 100644 +index 7ef4e3f..246082e 100755 --- a/third_party/tlslite/tlslite/messages.py +++ b/third_party/tlslite/tlslite/messages.py -@@ -130,6 +130,7 @@ class ClientHello(HandshakeMsg): - self.certificate_types = [CertificateType.x509] - self.compression_methods = [] # a list of 8-bit values - self.srp_username = None # a string +@@ -112,6 +112,7 @@ class ClientHello(HandshakeMsg): + self.tack = False + self.supports_npn = False + self.server_name = bytearray(0) + self.channel_id = False def create(self, version, random, session_id, cipher_suites, - certificate_types=None, srp_username=None): -@@ -174,6 +175,8 @@ class ClientHello(HandshakeMsg): - self.srp_username = bytesToString(p.getVarBytes(1)) - elif extType == 7: - self.certificate_types = p.getVarList(1, 1) + certificate_types=None, srpUsername=None, +@@ -179,6 +180,8 @@ class ClientHello(HandshakeMsg): + if name_type == NameType.host_name: + self.server_name = hostNameBytes + break + elif extType == ExtensionType.channel_id: + self.channel_id = True else: - p.getFixBytes(extLength) - soFar += 4 + extLength -@@ -220,6 +223,7 @@ class ServerHello(HandshakeMsg): - self.cipher_suite = 0 - self.certificate_type = CertificateType.x509 - self.compression_method = 0 + _ = p.getFixBytes(extLength) + index2 = p.index +@@ -243,6 +246,7 @@ class ServerHello(HandshakeMsg): + self.tackExt = None + self.next_protos_advertised = None + self.next_protos = None + self.channel_id = False def create(self, version, random, session_id, cipher_suite, - certificate_type): -@@ -266,6 +270,9 @@ class ServerHello(HandshakeMsg): - CertificateType.x509: - extLength += 5 - -+ if self.channel_id: -+ extLength += 4 -+ - if extLength != 0: - w.add(extLength, 2) - -@@ -275,6 +282,10 @@ class ServerHello(HandshakeMsg): - w.add(1, 2) - w.add(self.certificate_type, 1) - + certificate_type, tackExt, next_protos_advertised): +@@ -329,6 +333,9 @@ class ServerHello(HandshakeMsg): + w2.add(ExtensionType.supports_npn, 2) + w2.add(len(encoded_next_protos_advertised), 2) + w2.addFixSeq(encoded_next_protos_advertised, 1) + if self.channel_id: -+ w.add(ExtensionType.channel_id, 2) -+ w.add(0, 2) -+ - return HandshakeMsg.postWrite(self, w, trial) - - class Certificate(HandshakeMsg): -@@ -567,6 +578,28 @@ class Finished(HandshakeMsg): ++ w2.add(ExtensionType.channel_id, 2) ++ w2.add(0, 2) + if len(w2.bytes): + w.add(len(w2.bytes), 2) + w.bytes += w2.bytes +@@ -656,6 +663,28 @@ class Finished(HandshakeMsg): w.addFixSeq(self.verify_data, 1) - return HandshakeMsg.postWrite(self, w, trial) + return self.postWrite(w) +class EncryptedExtensions(HandshakeMsg): + def __init__(self): @@ -212,6 +83,91 @@ index dc6ed32..fa4d817 100644 + p.stopLengthCheck() + return self + - class ApplicationData(Msg): + class ApplicationData(object): def __init__(self): self.contentType = ContentType.application_data +diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py +index 8415592..e7c5140 100755 +--- a/third_party/tlslite/tlslite/tlsconnection.py ++++ b/third_party/tlslite/tlslite/tlsconnection.py +@@ -1155,6 +1155,7 @@ class TLSConnection(TLSRecordLayer): + serverHello.create(self.version, getRandomBytes(32), sessionID, \ + cipherSuite, CertificateType.x509, tackExt, + nextProtos) ++ serverHello.channel_id = clientHello.channel_id + + # Perform the SRP key exchange + clientCertChain = None +@@ -1191,7 +1192,7 @@ class TLSConnection(TLSRecordLayer): + for result in self._serverFinished(premasterSecret, + clientHello.random, serverHello.random, + cipherSuite, settings.cipherImplementations, +- nextProtos): ++ nextProtos, clientHello.channel_id): + if result in (0,1): yield result + else: break + masterSecret = result +@@ -1609,7 +1610,8 @@ class TLSConnection(TLSRecordLayer): + + + def _serverFinished(self, premasterSecret, clientRandom, serverRandom, +- cipherSuite, cipherImplementations, nextProtos): ++ cipherSuite, cipherImplementations, nextProtos, ++ doingChannelID): + masterSecret = calcMasterSecret(self.version, premasterSecret, + clientRandom, serverRandom) + +@@ -1620,7 +1622,8 @@ class TLSConnection(TLSRecordLayer): + + #Exchange ChangeCipherSpec and Finished messages + for result in self._getFinished(masterSecret, +- expect_next_protocol=nextProtos is not None): ++ expect_next_protocol=nextProtos is not None, ++ expect_channel_id=doingChannelID): + yield result + + for result in self._sendFinished(masterSecret): +@@ -1657,7 +1660,8 @@ class TLSConnection(TLSRecordLayer): + for result in self._sendMsg(finished): + yield result + +- def _getFinished(self, masterSecret, expect_next_protocol=False, nextProto=None): ++ def _getFinished(self, masterSecret, expect_next_protocol=False, nextProto=None, ++ expect_channel_id=False): + #Get and check ChangeCipherSpec + for result in self._getMsg(ContentType.change_cipher_spec): + if result in (0,1): +@@ -1690,6 +1694,20 @@ class TLSConnection(TLSRecordLayer): + if nextProto: + self.next_proto = nextProto + ++ #Server Finish - Are we waiting for a EncryptedExtensions? ++ if expect_channel_id: ++ for result in self._getMsg(ContentType.handshake, HandshakeType.encrypted_extensions): ++ if result in (0,1): ++ yield result ++ if result is None: ++ for result in self._sendError(AlertDescription.unexpected_message, ++ "Didn't get EncryptedExtensions message"): ++ yield result ++ encrypted_extensions = result ++ self.channel_id = result.channel_id_key ++ else: ++ self.channel_id = None ++ + #Calculate verification data + verifyData = self._calcFinished(masterSecret, False) + +diff --git a/third_party/tlslite/tlslite/tlsrecordlayer.py b/third_party/tlslite/tlslite/tlsrecordlayer.py +index b0833fe..ff08cbf 100755 +--- a/third_party/tlslite/tlslite/tlsrecordlayer.py ++++ b/third_party/tlslite/tlslite/tlsrecordlayer.py +@@ -800,6 +800,8 @@ class TLSRecordLayer(object): + yield Finished(self.version).parse(p) + elif subType == HandshakeType.next_protocol: + yield NextProtocol().parse(p) ++ elif subType == HandshakeType.encrypted_extensions: ++ yield EncryptedExtensions().parse(p) + else: + raise AssertionError() + diff --git a/chromium/third_party/tlslite/patches/client_cipher_preferences.patch b/chromium/third_party/tlslite/patches/client_cipher_preferences.patch new file mode 100644 index 00000000000..971939cabeb --- /dev/null +++ b/chromium/third_party/tlslite/patches/client_cipher_preferences.patch @@ -0,0 +1,18 @@ +diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py +index b9797d2..20cd85b 100755 +--- a/third_party/tlslite/tlslite/tlsconnection.py ++++ b/third_party/tlslite/tlslite/tlsconnection.py +@@ -1386,10 +1386,9 @@ class TLSConnection(TLSRecordLayer): + #the only time we won't use it is if we're resuming a + #session, in which case we use the ciphersuite from the session. + # +- #Given the current ciphersuite ordering, this means we prefer SRP +- #over non-SRP. +- for cipherSuite in cipherSuites: +- if cipherSuite in clientHello.cipher_suites: ++ #Use the client's preferences for now. ++ for cipherSuite in clientHello.cipher_suites: ++ if cipherSuite in cipherSuites: + break + else: + for result in self._sendError(\ diff --git a/chromium/third_party/tlslite/patches/close_notify.patch b/chromium/third_party/tlslite/patches/close_notify.patch deleted file mode 100644 index 94afa2061ad..00000000000 --- a/chromium/third_party/tlslite/patches/close_notify.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff -u tlslite-0.3.8/tlslite/TLSRecordLayer.py chromium//tlslite/TLSRecordLayer.py ---- tlslite-0.3.8/tlslite/TLSRecordLayer.py 2005-02-21 21:31:41.000000000 -0800 -+++ chromium/tlslite/TLSRecordLayer.py 2008-11-25 21:58:04.000000000 -0800 -@@ -322,6 +322,12 @@ - AlertDescription.close_notify, AlertLevel.warning)): - yield result - alert = None -+ # Forcing a shutdown as the OS does not seem to be -+ # responsive to the close notify. -+ prevCloseSocket = self.closeSocket -+ self.closeSocket = True -+ self._shutdown(True) -+ self.closeSocket = prevCloseSocket - while not alert: - for result in self._getMsg((ContentType.alert, \ - ContentType.application_data)): diff --git a/chromium/third_party/tlslite/patches/dhe_rsa.patch b/chromium/third_party/tlslite/patches/dhe_rsa.patch new file mode 100644 index 00000000000..1466851a66b --- /dev/null +++ b/chromium/third_party/tlslite/patches/dhe_rsa.patch @@ -0,0 +1,417 @@ +diff --git a/third_party/tlslite/tlslite/constants.py b/third_party/tlslite/tlslite/constants.py +index 52c20ac..feca423 100644 +--- a/third_party/tlslite/tlslite/constants.py ++++ b/third_party/tlslite/tlslite/constants.py +@@ -143,6 +143,10 @@ class CipherSuite: + + TLS_RSA_WITH_RC4_128_MD5 = 0x0004 + ++ TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x0016 ++ TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033 ++ TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039 ++ + TLS_DH_ANON_WITH_AES_128_CBC_SHA = 0x0034 + TLS_DH_ANON_WITH_AES_256_CBC_SHA = 0x003A + +@@ -150,17 +154,20 @@ class CipherSuite: + tripleDESSuites.append(TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA) + tripleDESSuites.append(TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA) + tripleDESSuites.append(TLS_RSA_WITH_3DES_EDE_CBC_SHA) ++ tripleDESSuites.append(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA) + + aes128Suites = [] + aes128Suites.append(TLS_SRP_SHA_WITH_AES_128_CBC_SHA) + aes128Suites.append(TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA) + aes128Suites.append(TLS_RSA_WITH_AES_128_CBC_SHA) ++ aes128Suites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA) + aes128Suites.append(TLS_DH_ANON_WITH_AES_128_CBC_SHA) + + aes256Suites = [] + aes256Suites.append(TLS_SRP_SHA_WITH_AES_256_CBC_SHA) + aes256Suites.append(TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA) + aes256Suites.append(TLS_RSA_WITH_AES_256_CBC_SHA) ++ aes256Suites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA) + aes256Suites.append(TLS_DH_ANON_WITH_AES_256_CBC_SHA) + + rc4Suites = [] +@@ -178,6 +185,9 @@ class CipherSuite: + shaSuites.append(TLS_RSA_WITH_AES_128_CBC_SHA) + shaSuites.append(TLS_RSA_WITH_AES_256_CBC_SHA) + shaSuites.append(TLS_RSA_WITH_RC4_128_SHA) ++ shaSuites.append(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA) ++ shaSuites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA) ++ shaSuites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA) + shaSuites.append(TLS_DH_ANON_WITH_AES_128_CBC_SHA) + shaSuites.append(TLS_DH_ANON_WITH_AES_256_CBC_SHA) + +@@ -188,6 +198,7 @@ class CipherSuite: + def _filterSuites(suites, settings): + macNames = settings.macNames + cipherNames = settings.cipherNames ++ keyExchangeNames = settings.keyExchangeNames + macSuites = [] + if "sha" in macNames: + macSuites += CipherSuite.shaSuites +@@ -204,7 +215,20 @@ class CipherSuite: + if "rc4" in cipherNames: + cipherSuites += CipherSuite.rc4Suites + +- return [s for s in suites if s in macSuites and s in cipherSuites] ++ keyExchangeSuites = [] ++ if "rsa" in keyExchangeNames: ++ keyExchangeSuites += CipherSuite.certSuites ++ if "dhe_rsa" in keyExchangeNames: ++ keyExchangeSuites += CipherSuite.dheCertSuites ++ if "srp_sha" in keyExchangeNames: ++ keyExchangeSuites += CipherSuite.srpSuites ++ if "srp_sha_rsa" in keyExchangeNames: ++ keyExchangeSuites += CipherSuite.srpCertSuites ++ if "dh_anon" in keyExchangeNames: ++ keyExchangeSuites += CipherSuite.anonSuites ++ ++ return [s for s in suites if s in macSuites and ++ s in cipherSuites and s in keyExchangeSuites] + + srpSuites = [] + srpSuites.append(TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA) +@@ -236,12 +260,22 @@ class CipherSuite: + certSuites.append(TLS_RSA_WITH_AES_256_CBC_SHA) + certSuites.append(TLS_RSA_WITH_RC4_128_SHA) + certSuites.append(TLS_RSA_WITH_RC4_128_MD5) +- certAllSuites = srpCertSuites + certSuites + + @staticmethod + def getCertSuites(settings): + return CipherSuite._filterSuites(CipherSuite.certSuites, settings) + ++ dheCertSuites = [] ++ dheCertSuites.append(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA) ++ dheCertSuites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA) ++ dheCertSuites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA) ++ ++ @staticmethod ++ def getDheCertSuites(settings): ++ return CipherSuite._filterSuites(CipherSuite.dheCertSuites, settings) ++ ++ certAllSuites = srpCertSuites + certSuites + dheCertSuites ++ + anonSuites = [] + anonSuites.append(TLS_DH_ANON_WITH_AES_128_CBC_SHA) + anonSuites.append(TLS_DH_ANON_WITH_AES_256_CBC_SHA) +@@ -250,6 +284,8 @@ class CipherSuite: + def getAnonSuites(settings): + return CipherSuite._filterSuites(CipherSuite.anonSuites, settings) + ++ dhAllSuites = dheCertSuites + anonSuites ++ + @staticmethod + def canonicalCipherName(ciphersuite): + "Return the canonical name of the cipher whose number is provided." +diff --git a/third_party/tlslite/tlslite/handshakesettings.py b/third_party/tlslite/tlslite/handshakesettings.py +index 7a38ee2..e0bc0e6 100644 +--- a/third_party/tlslite/tlslite/handshakesettings.py ++++ b/third_party/tlslite/tlslite/handshakesettings.py +@@ -13,7 +13,9 @@ from .utils import cipherfactory + # RC4 is preferred as faster in Python, works in SSL3, and immune to CBC + # issues such as timing attacks + CIPHER_NAMES = ["rc4", "aes256", "aes128", "3des"] +-MAC_NAMES = ["sha"] # "md5" is allowed ++MAC_NAMES = ["sha"] # Don't allow "md5" by default. ++ALL_MAC_NAMES = ["sha", "md5"] ++KEY_EXCHANGE_NAMES = ["rsa", "dhe_rsa", "srp_sha", "srp_sha_rsa", "dh_anon"] + CIPHER_IMPLEMENTATIONS = ["openssl", "pycrypto", "python"] + CERTIFICATE_TYPES = ["x509"] + +@@ -102,6 +104,7 @@ class HandshakeSettings(object): + self.maxKeySize = 8193 + self.cipherNames = CIPHER_NAMES + self.macNames = MAC_NAMES ++ self.keyExchangeNames = KEY_EXCHANGE_NAMES + self.cipherImplementations = CIPHER_IMPLEMENTATIONS + self.certificateTypes = CERTIFICATE_TYPES + self.minVersion = (3,0) +@@ -116,6 +119,7 @@ class HandshakeSettings(object): + other.maxKeySize = self.maxKeySize + other.cipherNames = self.cipherNames + other.macNames = self.macNames ++ other.keyExchangeNames = self.keyExchangeNames + other.cipherImplementations = self.cipherImplementations + other.certificateTypes = self.certificateTypes + other.minVersion = self.minVersion +@@ -148,6 +152,12 @@ class HandshakeSettings(object): + for s in other.cipherNames: + if s not in CIPHER_NAMES: + raise ValueError("Unknown cipher name: '%s'" % s) ++ for s in other.macNames: ++ if s not in ALL_MAC_NAMES: ++ raise ValueError("Unknown MAC name: '%s'" % s) ++ for s in other.keyExchangeNames: ++ if s not in KEY_EXCHANGE_NAMES: ++ raise ValueError("Unknown key exchange name: '%s'" % s) + for s in other.cipherImplementations: + if s not in CIPHER_IMPLEMENTATIONS: + raise ValueError("Unknown cipher implementation: '%s'" % s) +diff --git a/third_party/tlslite/tlslite/messages.py b/third_party/tlslite/tlslite/messages.py +index 532d86b..550b387 100644 +--- a/third_party/tlslite/tlslite/messages.py ++++ b/third_party/tlslite/tlslite/messages.py +@@ -533,31 +533,31 @@ class ServerKeyExchange(HandshakeMsg): + p.stopLengthCheck() + return self + +- def write(self): ++ def write_params(self): + w = Writer() + if self.cipherSuite in CipherSuite.srpAllSuites: + w.addVarSeq(numberToByteArray(self.srp_N), 1, 2) + w.addVarSeq(numberToByteArray(self.srp_g), 1, 2) + w.addVarSeq(self.srp_s, 1, 1) + w.addVarSeq(numberToByteArray(self.srp_B), 1, 2) +- if self.cipherSuite in CipherSuite.srpCertSuites: +- w.addVarSeq(self.signature, 1, 2) +- elif self.cipherSuite in CipherSuite.anonSuites: ++ elif self.cipherSuite in CipherSuite.dhAllSuites: + w.addVarSeq(numberToByteArray(self.dh_p), 1, 2) + w.addVarSeq(numberToByteArray(self.dh_g), 1, 2) + w.addVarSeq(numberToByteArray(self.dh_Ys), 1, 2) +- if self.cipherSuite in []: # TODO support for signed_params +- w.addVarSeq(self.signature, 1, 2) ++ else: ++ assert(False) ++ return w.bytes ++ ++ def write(self): ++ w = Writer() ++ w.bytes += self.write_params() ++ if self.cipherSuite in CipherSuite.certAllSuites: ++ w.addVarSeq(self.signature, 1, 2) + return self.postWrite(w) + + def hash(self, clientRandom, serverRandom): +- oldCipherSuite = self.cipherSuite +- self.cipherSuite = None +- try: +- bytes = clientRandom + serverRandom + self.write()[4:] +- return MD5(bytes) + SHA1(bytes) +- finally: +- self.cipherSuite = oldCipherSuite ++ bytes = clientRandom + serverRandom + self.write_params() ++ return MD5(bytes) + SHA1(bytes) + + class ServerHelloDone(HandshakeMsg): + def __init__(self): +@@ -607,7 +607,7 @@ class ClientKeyExchange(HandshakeMsg): + p.getFixBytes(len(p.bytes)-p.index) + else: + raise AssertionError() +- elif self.cipherSuite in CipherSuite.anonSuites: ++ elif self.cipherSuite in CipherSuite.dhAllSuites: + self.dh_Yc = bytesToNumber(p.getVarBytes(2)) + else: + raise AssertionError() +diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py +index 20cd85b..e6f7820 100644 +--- a/third_party/tlslite/tlslite/tlsconnection.py ++++ b/third_party/tlslite/tlslite/tlsconnection.py +@@ -23,6 +23,103 @@ from .mathtls import * + from .handshakesettings import HandshakeSettings + from .utils.tackwrapper import * + ++class KeyExchange(object): ++ def __init__(self, cipherSuite, clientHello, serverHello, privateKey): ++ """ ++ Initializes the KeyExchange. privateKey is the signing private key. ++ """ ++ self.cipherSuite = cipherSuite ++ self.clientHello = clientHello ++ self.serverHello = serverHello ++ self.privateKey = privateKey ++ ++ def makeServerKeyExchange(): ++ """ ++ Returns a ServerKeyExchange object for the server's initial leg in the ++ handshake. If the key exchange method does not send ServerKeyExchange ++ (e.g. RSA), it returns None. ++ """ ++ raise NotImplementedError() ++ ++ def processClientKeyExchange(clientKeyExchange): ++ """ ++ Processes the client's ClientKeyExchange message and returns the ++ premaster secret. Raises TLSLocalAlert on error. ++ """ ++ raise NotImplementedError() ++ ++class RSAKeyExchange(KeyExchange): ++ def makeServerKeyExchange(self): ++ return None ++ ++ def processClientKeyExchange(self, clientKeyExchange): ++ premasterSecret = self.privateKey.decrypt(\ ++ clientKeyExchange.encryptedPreMasterSecret) ++ ++ # On decryption failure randomize premaster secret to avoid ++ # Bleichenbacher's "million message" attack ++ randomPreMasterSecret = getRandomBytes(48) ++ if not premasterSecret: ++ premasterSecret = randomPreMasterSecret ++ elif len(premasterSecret)!=48: ++ premasterSecret = randomPreMasterSecret ++ else: ++ versionCheck = (premasterSecret[0], premasterSecret[1]) ++ if versionCheck != self.clientHello.client_version: ++ #Tolerate buggy IE clients ++ if versionCheck != self.serverHello.server_version: ++ premasterSecret = randomPreMasterSecret ++ return premasterSecret ++ ++def _hexStringToNumber(s): ++ s = s.replace(" ", "").replace("\n", "") ++ if len(s) % 2 != 0: ++ raise ValueError("Length is not even") ++ return bytesToNumber(bytearray(s.decode("hex"))) ++ ++class DHE_RSAKeyExchange(KeyExchange): ++ # 2048-bit MODP Group (RFC 3526, Section 3) ++ dh_p = _hexStringToNumber(""" ++FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 ++29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD ++EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 ++E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED ++EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D ++C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F ++83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D ++670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B ++E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 ++DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510 ++15728E5A 8AACAA68 FFFFFFFF FFFFFFFF""") ++ dh_g = 2 ++ ++ # RFC 3526, Section 8. ++ strength = 160 ++ ++ def makeServerKeyExchange(self): ++ # Per RFC 3526, Section 1, the exponent should have double the entropy ++ # of the strength of the curve. ++ self.dh_Xs = bytesToNumber(getRandomBytes(self.strength * 2 / 8)) ++ dh_Ys = powMod(self.dh_g, self.dh_Xs, self.dh_p) ++ ++ serverKeyExchange = ServerKeyExchange(self.cipherSuite) ++ serverKeyExchange.createDH(self.dh_p, self.dh_g, dh_Ys) ++ serverKeyExchange.signature = self.privateKey.sign( ++ serverKeyExchange.hash(self.clientHello.random, ++ self.serverHello.random)) ++ return serverKeyExchange ++ ++ def processClientKeyExchange(self, clientKeyExchange): ++ dh_Yc = clientKeyExchange.dh_Yc ++ ++ # First half of RFC 2631, Section 2.1.5. Validate the client's public ++ # key. ++ if not 2 <= dh_Yc <= self.dh_p - 1: ++ raise TLSLocalAlert(AlertDescription.illegal_parameter, ++ "Invalid dh_Yc value") ++ ++ S = powMod(dh_Yc, self.dh_Xs, self.dh_p) ++ return numberToByteArray(S) + + class TLSConnection(TLSRecordLayer): + """ +@@ -500,6 +597,8 @@ class TLSConnection(TLSRecordLayer): + cipherSuites += CipherSuite.getSrpAllSuites(settings) + elif certParams: + cipherSuites += CipherSuite.getCertSuites(settings) ++ # TODO: Client DHE_RSA not supported. ++ # cipherSuites += CipherSuite.getDheCertSuites(settings) + elif anonParams: + cipherSuites += CipherSuite.getAnonSuites(settings) + else: +@@ -1204,10 +1303,23 @@ class TLSConnection(TLSRecordLayer): + else: break + premasterSecret = result + +- # Perform the RSA key exchange +- elif cipherSuite in CipherSuite.certSuites: ++ # Perform the RSA or DHE_RSA key exchange ++ elif (cipherSuite in CipherSuite.certSuites or ++ cipherSuite in CipherSuite.dheCertSuites): ++ if cipherSuite in CipherSuite.certSuites: ++ keyExchange = RSAKeyExchange(cipherSuite, ++ clientHello, ++ serverHello, ++ privateKey) ++ elif cipherSuite in CipherSuite.dheCertSuites: ++ keyExchange = DHE_RSAKeyExchange(cipherSuite, ++ clientHello, ++ serverHello, ++ privateKey) ++ else: ++ assert(False) + for result in self._serverCertKeyExchange(clientHello, serverHello, +- certChain, privateKey, ++ certChain, keyExchange, + reqCert, reqCAs, cipherSuite, + settings, ocspResponse): + if result in (0,1): yield result +@@ -1268,6 +1380,7 @@ class TLSConnection(TLSRecordLayer): + cipherSuites += CipherSuite.getSrpSuites(settings) + elif certChain: + cipherSuites += CipherSuite.getCertSuites(settings) ++ cipherSuites += CipherSuite.getDheCertSuites(settings) + elif anon: + cipherSuites += CipherSuite.getAnonSuites(settings) + else: +@@ -1483,11 +1596,11 @@ class TLSConnection(TLSRecordLayer): + + + def _serverCertKeyExchange(self, clientHello, serverHello, +- serverCertChain, privateKey, ++ serverCertChain, keyExchange, + reqCert, reqCAs, cipherSuite, + settings, ocspResponse): +- #Send ServerHello, Certificate[, CertificateRequest], +- #ServerHelloDone ++ #Send ServerHello, Certificate[, ServerKeyExchange] ++ #[, CertificateRequest], ServerHelloDone + msgs = [] + + # If we verify a client cert chain, return it +@@ -1497,6 +1610,9 @@ class TLSConnection(TLSRecordLayer): + msgs.append(Certificate(CertificateType.x509).create(serverCertChain)) + if serverHello.status_request: + msgs.append(CertificateStatus().create(ocspResponse)) ++ serverKeyExchange = keyExchange.makeServerKeyExchange() ++ if serverKeyExchange is not None: ++ msgs.append(serverKeyExchange) + if reqCert and reqCAs: + msgs.append(CertificateRequest().create(\ + [ClientCertificateType.rsa_sign], reqCAs)) +@@ -1555,21 +1671,13 @@ class TLSConnection(TLSRecordLayer): + else: break + clientKeyExchange = result + +- #Decrypt ClientKeyExchange +- premasterSecret = privateKey.decrypt(\ +- clientKeyExchange.encryptedPreMasterSecret) +- +- # On decryption failure randomize premaster secret to avoid +- # Bleichenbacher's "million message" attack +- randomPreMasterSecret = getRandomBytes(48) +- versionCheck = (premasterSecret[0], premasterSecret[1]) +- if not premasterSecret: +- premasterSecret = randomPreMasterSecret +- elif len(premasterSecret)!=48: +- premasterSecret = randomPreMasterSecret +- elif versionCheck != clientHello.client_version: +- if versionCheck != self.version: #Tolerate buggy IE clients +- premasterSecret = randomPreMasterSecret ++ #Process ClientKeyExchange ++ try: ++ premasterSecret = \ ++ keyExchange.processClientKeyExchange(clientKeyExchange) ++ except TLSLocalAlert, alert: ++ for result in self._sendError(alert.description, alert.message): ++ yield result + + #Get and check CertificateVerify, if relevant + if clientCertChain: diff --git a/chromium/third_party/tlslite/patches/fallback_scsv.patch b/chromium/third_party/tlslite/patches/fallback_scsv.patch index e4fb3d86c03..9a64f11b9d5 100644 --- a/chromium/third_party/tlslite/patches/fallback_scsv.patch +++ b/chromium/third_party/tlslite/patches/fallback_scsv.patch @@ -1,29 +1,55 @@ -diff --git a/third_party/tlslite/tlslite/TLSConnection.py b/third_party/tlslite/tlslite/TLSConnection.py -index d2270a9..e6ce187 100644 ---- a/third_party/tlslite/tlslite/TLSConnection.py -+++ b/third_party/tlslite/tlslite/TLSConnection.py -@@ -937,7 +937,8 @@ class TLSConnection(TLSRecordLayer): - certChain=None, privateKey=None, reqCert=False, - sessionCache=None, settings=None, checker=None, - reqCAs=None, tlsIntolerant=0, -- signedCertTimestamps=None): -+ signedCertTimestamps=None, +diff --git a/third_party/tlslite/tlslite/constants.py b/third_party/tlslite/tlslite/constants.py +index b3bad2d..d132b78 100755 +--- a/third_party/tlslite/tlslite/constants.py ++++ b/third_party/tlslite/tlslite/constants.py +@@ -106,6 +106,7 @@ class AlertDescription: + protocol_version = 70 + insufficient_security = 71 + internal_error = 80 ++ inappropriate_fallback = 86 + user_canceled = 90 + no_renegotiation = 100 + unknown_psk_identity = 115 +@@ -117,6 +118,9 @@ class CipherSuite: + # We actually don't do any renegotiation, but this + # prevents renegotiation attacks + TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0x00FF ++ ++ # draft-bmoeller-tls-downgrade-scsv-01 ++ TLS_FALLBACK_SCSV = 0x5600 + + TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA = 0xC01A + TLS_SRP_SHA_WITH_AES_128_CBC_SHA = 0xC01D +diff --git a/third_party/tlslite/tlslite/errors.py b/third_party/tlslite/tlslite/errors.py +index 22c298c..001ef33 100755 +--- a/third_party/tlslite/tlslite/errors.py ++++ b/third_party/tlslite/tlslite/errors.py +@@ -63,6 +63,7 @@ class TLSAlert(TLSError): + AlertDescription.protocol_version: "protocol_version",\ + AlertDescription.insufficient_security: "insufficient_security",\ + AlertDescription.internal_error: "internal_error",\ ++ AlertDescription.inappropriate_fallback: "inappropriate_fallback",\ + AlertDescription.user_canceled: "user_canceled",\ + AlertDescription.no_renegotiation: "no_renegotiation",\ + AlertDescription.unknown_psk_identity: "unknown_psk_identity"} +diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py +index 45b0bbb..bd92161 100755 +--- a/third_party/tlslite/tlslite/tlsconnection.py ++++ b/third_party/tlslite/tlslite/tlsconnection.py +@@ -966,7 +966,8 @@ class TLSConnection(TLSRecordLayer): + reqCAs = None, + tacks=None, activationFlags=0, + nextProtos=None, anon=False, +- tlsIntolerant=None, signedCertTimestamps=None): ++ tlsIntolerant=None, signedCertTimestamps=None, + fallbackSCSV=False): """Perform a handshake in the role of server. This function performs an SSL or TLS handshake. Depending on -@@ -1014,6 +1014,19 @@ class TLSConnection(TLSRecordLayer): +@@ -1045,6 +1046,11 @@ class TLSConnection(TLSRecordLayer): binary 8-bit string) that will be sent as a TLS extension whenever the client announces support for the extension. -+ @type tlsIntolerant: int -+ @param tlsIntolerant: if non-zero, the server will simulate TLS -+ version intolerance by returning a fatal, handshake_failure alert. -+ The versions to which it's intolerant vary depending on the value: -+ 1: reject all TLS versions. -+ 2: reject TLS 1.1 or higher. -+ 3: reject TLS 1.2 or higher. -+ + @type fallbackSCSV: bool + @param fallbackSCSV: if true, the server will implement + TLS_FALLBACK_SCSV and thus reject connections using less than the @@ -32,29 +58,29 @@ index d2270a9..e6ce187 100644 @raise socket.error: If a socket error occurs. @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed without a preceding alert. -@@ -1022,7 +1023,8 @@ class TLSConnection(TLSRecordLayer): - """ - for result in self.handshakeServerAsync(sharedKeyDB, verifierDB, - certChain, privateKey, reqCert, sessionCache, settings, -- checker, reqCAs, tlsIntolerant, signedCertTimestamps): -+ checker, reqCAs, tlsIntolerant, signedCertTimestamps, -+ fallbackSCSV): +@@ -1057,7 +1063,8 @@ class TLSConnection(TLSRecordLayer): + checker, reqCAs, + tacks=tacks, activationFlags=activationFlags, + nextProtos=nextProtos, anon=anon, tlsIntolerant=tlsIntolerant, +- signedCertTimestamps=signedCertTimestamps): ++ signedCertTimestamps=signedCertTimestamps, ++ fallbackSCSV=fallbackSCSV): pass -@@ -1030,7 +1032,8 @@ class TLSConnection(TLSRecordLayer): - certChain=None, privateKey=None, reqCert=False, - sessionCache=None, settings=None, checker=None, - reqCAs=None, tlsIntolerant=0, -- signedCertTimestamps=None): +@@ -1068,7 +1075,8 @@ class TLSConnection(TLSRecordLayer): + tacks=None, activationFlags=0, + nextProtos=None, anon=False, + tlsIntolerant=None, +- signedCertTimestamps=None + signedCertTimestamps=None, -+ fallbackSCSV=False): ++ fallbackSCSV=False + ): """Start a server handshake operation on the TLS connection. - This function returns a generator which behaves similarly to -@@ -1049,7 +1052,8 @@ class TLSConnection(TLSRecordLayer): - sessionCache=sessionCache, settings=settings, - reqCAs=reqCAs, +@@ -1089,7 +1097,8 @@ class TLSConnection(TLSRecordLayer): + tacks=tacks, activationFlags=activationFlags, + nextProtos=nextProtos, anon=anon, tlsIntolerant=tlsIntolerant, - signedCertTimestamps=signedCertTimestamps) + signedCertTimestamps=signedCertTimestamps, @@ -62,58 +88,44 @@ index d2270a9..e6ce187 100644 for result in self._handshakeWrapperAsync(handshaker, checker): yield result -@@ -1057,7 +1061,8 @@ class TLSConnection(TLSRecordLayer): - def _handshakeServerAsyncHelper(self, sharedKeyDB, verifierDB, - certChain, privateKey, reqCert, - sessionCache, settings, reqCAs, -- tlsIntolerant, signedCertTimestamps): -+ tlsIntolerant, signedCertTimestamps, -+ fallbackSCSV): +@@ -1099,7 +1108,7 @@ class TLSConnection(TLSRecordLayer): + settings, reqCAs, + tacks, activationFlags, + nextProtos, anon, +- tlsIntolerant, signedCertTimestamps): ++ tlsIntolerant, signedCertTimestamps, fallbackSCSV): self._handshakeStart(client=False) -@@ -1141,12 +1146,18 @@ class TLSConnection(TLSRecordLayer): - yield result +@@ -1134,7 +1143,7 @@ class TLSConnection(TLSRecordLayer): + # Handle ClientHello and resumption + for result in self._serverGetClientHello(settings, certChain,\ + verifierDB, sessionCache, +- anon, tlsIntolerant): ++ anon, tlsIntolerant, fallbackSCSV): + if result in (0,1): yield result + elif result == None: + self._handshakeDone(resumed=True) +@@ -1234,7 +1243,7 @@ class TLSConnection(TLSRecordLayer): + - #If client's version is too high, propose my highest version -- elif clientHello.client_version > settings.maxVersion: -+ if clientHello.client_version > settings.maxVersion: + def _serverGetClientHello(self, settings, certChain, verifierDB, +- sessionCache, anon, tlsIntolerant): ++ sessionCache, anon, tlsIntolerant, fallbackSCSV): + #Initialize acceptable cipher suites + cipherSuites = [] + if verifierDB: +@@ -1280,6 +1289,13 @@ class TLSConnection(TLSRecordLayer): + elif clientHello.client_version > settings.maxVersion: self.version = settings.maxVersion -- + ++ #Detect if the client performed an inappropriate fallback. ++ elif fallbackSCSV and clientHello.client_version < settings.maxVersion: ++ if CipherSuite.TLS_FALLBACK_SCSV in clientHello.cipher_suites: ++ for result in self._sendError(\ ++ AlertDescription.inappropriate_fallback): ++ yield result ++ else: #Set the version to the client's version - self.version = clientHello.client_version -+ if (fallbackSCSV and -+ clientHello.client_version < settings.maxVersion): -+ for cipherSuite in clientHello.cipher_suites: -+ if cipherSuite == 0x5600: -+ for result in self._sendError(\ -+ AlertDescription.inappropriate_fallback): -+ yield result - - #Get the client nonce; create server nonce - clientRandom = clientHello.random -diff --git a/third_party/tlslite/tlslite/constants.py b/third_party/tlslite/tlslite/constants.py -index b5a345a..23e3dcb 100644 ---- a/third_party/tlslite/tlslite/constants.py -+++ b/third_party/tlslite/tlslite/constants.py -@@ -91,6 +91,7 @@ class AlertDescription: - protocol_version = 70 - insufficient_security = 71 - internal_error = 80 -+ inappropriate_fallback = 86 - user_canceled = 90 - no_renegotiation = 100 - unknown_srp_username = 120 -diff --git a/third_party/tlslite/tlslite/errors.py b/third_party/tlslite/tlslite/errors.py -index c7f7ba8..45087e6 100644 ---- a/third_party/tlslite/tlslite/errors.py -+++ b/third_party/tlslite/tlslite/errors.py -@@ -48,6 +48,7 @@ class TLSAlert(TLSError): - AlertDescription.protocol_version: "protocol_version",\ - AlertDescription.insufficient_security: "insufficient_security",\ - AlertDescription.internal_error: "internal_error",\ -+ AlertDescription.inappropriate_fallback: "inappropriate_fallback",\ - AlertDescription.user_canceled: "user_canceled",\ - AlertDescription.no_renegotiation: "no_renegotiation",\ - AlertDescription.unknown_srp_username: "unknown_srp_username",\ + self.version = clientHello.client_version diff --git a/chromium/third_party/tlslite/patches/fix_test_file.patch b/chromium/third_party/tlslite/patches/fix_test_file.patch new file mode 100644 index 00000000000..891b5565ca1 --- /dev/null +++ b/chromium/third_party/tlslite/patches/fix_test_file.patch @@ -0,0 +1,8 @@ +diff --git a/third_party/tlslite/tests/httpsserver.sh b/third_party/tlslite/tests/httpsserver.sh +index 046eb2e..7449ad7 100755 +--- a/third_party/tlslite/tests/httpsserver.sh ++++ b/third_party/tlslite/tests/httpsserver.sh +@@ -1,2 +1,2 @@ +-# /bin/sh ++#!/bin/sh + python ../scripts/tls.py server -k serverX509Key.pem -c serverX509Cert.pem -t TACK1.pem localhost:4443 diff --git a/chromium/third_party/tlslite/patches/ignore_write_failure.patch b/chromium/third_party/tlslite/patches/ignore_write_failure.patch new file mode 100644 index 00000000000..169e4d5871f --- /dev/null +++ b/chromium/third_party/tlslite/patches/ignore_write_failure.patch @@ -0,0 +1,15 @@ +diff --git a/third_party/tlslite/tlslite/tlsrecordlayer.py b/third_party/tlslite/tlslite/tlsrecordlayer.py +index 8b92221..370dc9a 100644 +--- a/third_party/tlslite/tlslite/tlsrecordlayer.py ++++ b/third_party/tlslite/tlslite/tlsrecordlayer.py +@@ -286,7 +286,9 @@ class TLSRecordLayer(object): + except GeneratorExit: + raise + except Exception: +- self._shutdown(False) ++ # Don't invalidate the session on write failure if abrupt closes are ++ # okay. ++ self._shutdown(self.ignoreAbruptClose) + raise + + def close(self): diff --git a/chromium/third_party/tlslite/patches/parse_chain.patch b/chromium/third_party/tlslite/patches/parse_chain.patch deleted file mode 100644 index 3a547332a3f..00000000000 --- a/chromium/third_party/tlslite/patches/parse_chain.patch +++ /dev/null @@ -1,89 +0,0 @@ -diff -aurb tlslite-0.3.8/tlslite/X509.py chromium/tlslite/X509.py ---- tlslite-0.3.8/tlslite/X509.py Fri Mar 19 18:43:19 2004 -+++ chromium/tlslite/X509.py Wed Feb 29 11:53:54 2012 -@@ -91,6 +91,7 @@ - - #Create a public key instance - self.publicKey = _createPublicRSAKey(n, e) -+ return self - - def getFingerprint(self): - """Get the hex-encoded fingerprint of this certificate. -diff -aurb tlslite-0.3.8/tlslite/X509CertChain.py chromium/tlslite/X509CertChain.py ---- tlslite-0.3.8/tlslite/X509CertChain.py Fri Mar 19 18:49:58 2004 -+++ chromium/tlslite/X509CertChain.py Wed Feb 29 11:53:42 2012 -@@ -1,6 +1,7 @@ - """Class representing an X.509 certificate chain.""" - - from utils import cryptomath -+from X509 import X509 - - class X509CertChain: - """This class represents a chain of X.509 certificates. -@@ -23,6 +24,66 @@ - self.x509List = x509List - else: - self.x509List = [] -+ -+ def parseChain(self, s): -+ """Parse a PEM-encoded X.509 certificate file chain file. -+ -+ @type s: str -+ @param s: A PEM-encoded (eg: Base64) X.509 certificate file, with every -+ certificate wrapped within "-----BEGIN CERTIFICATE-----" and -+ "-----END CERTIFICATE-----" tags). Extraneous data outside such tags, -+ such as human readable representations, will be ignored. -+ """ -+ -+ class PEMIterator(object): -+ """Simple iterator over PEM-encoded certificates within a string. -+ -+ @type data: string -+ @ivar data: A string containing PEM-encoded (Base64) certificates, -+ with every certificate wrapped within "-----BEGIN CERTIFICATE-----" -+ and "-----END CERTIFICATE-----" tags). Extraneous data outside such -+ tags, such as human readable representations, will be ignored. -+ -+ @type index: integer -+ @ivar index: The current offset within data to begin iterating from. -+ """ -+ -+ _CERTIFICATE_HEADER = "----BEGIN CERTIFICATE-----" -+ """The PEM encoding block header for X.509 certificates.""" -+ -+ _CERTIFICATE_FOOTER = "----END CERTIFICATE-----" -+ """The PEM encoding block footer for X.509 certificates.""" -+ -+ def __init__(self, s): -+ self.data = s -+ self.index = 0 -+ -+ def __iter__(self): -+ return self -+ -+ def next(self): -+ """Iterates and returns the next L{tlslite.X509.X509} -+ certificate in data. -+ -+ @rtype tlslite.X509.X509 -+ """ -+ -+ self.index = self.data.find(self._CERTIFICATE_HEADER, -+ self.index) -+ if self.index == -1: -+ raise StopIteration -+ end = self.data.find(self._CERTIFICATE_FOOTER, self.index) -+ if end == -1: -+ raise StopIteration -+ -+ certStr = self.data[self.index+len(self._CERTIFICATE_HEADER) : -+ end] -+ self.index = end + len(self._CERTIFICATE_FOOTER) -+ bytes = cryptomath.base64ToBytes(certStr) -+ return X509().parseBinary(bytes) -+ -+ self.x509List = list(PEMIterator(s)) -+ return self - - def getNumCerts(self): - """Get the number of certificates in this chain. diff --git a/chromium/third_party/tlslite/patches/pycrypto_python2.patch b/chromium/third_party/tlslite/patches/pycrypto_python2.patch new file mode 100644 index 00000000000..923c1d4d6b0 --- /dev/null +++ b/chromium/third_party/tlslite/patches/pycrypto_python2.patch @@ -0,0 +1,51 @@ +diff --git a/third_party/tlslite/tlslite/utils/compat.py b/third_party/tlslite/tlslite/utils/compat.py +index 2bcaede..db95ac1 100755 +--- a/third_party/tlslite/tlslite/utils/compat.py ++++ b/third_party/tlslite/tlslite/utils/compat.py +@@ -51,6 +51,9 @@ if sys.version_info >= (3,0): + def readStdinBinary(): + return sys.stdin.buffer.read() + ++ def long(n): ++ return n ++ + else: + # Python 2.6 requires strings instead of bytearrays in a couple places, + # so we define this function so it does the conversion if needed. +diff --git a/third_party/tlslite/tlslite/utils/cryptomath.py b/third_party/tlslite/tlslite/utils/cryptomath.py +index ce56b4b..30354b2 100755 +--- a/third_party/tlslite/tlslite/utils/cryptomath.py ++++ b/third_party/tlslite/tlslite/utils/cryptomath.py +@@ -94,7 +94,9 @@ def bytesToNumber(b): + byte = b[count] + total += multiplier * byte + multiplier *= 256 +- return total ++ # Force-cast to long to appease PyCrypto. ++ # https://github.com/trevp/tlslite/issues/15 ++ return long(total) + + def numberToByteArray(n, howManyBytes=None): + """Convert an integer into a bytearray, zero-pad to howManyBytes. +diff --git a/third_party/tlslite/tlslite/utils/pycrypto_rsakey.py b/third_party/tlslite/tlslite/utils/pycrypto_rsakey.py +index 3d56228..4de5436 100755 +--- a/third_party/tlslite/tlslite/utils/pycrypto_rsakey.py ++++ b/third_party/tlslite/tlslite/utils/pycrypto_rsakey.py +@@ -26,13 +26,13 @@ if pycryptoLoaded: + return self.rsa.has_private() + + def _rawPrivateKeyOp(self, m): +- s = numberToString(m, numBytes(self.n)) +- c = stringToNumber(self.rsa.decrypt((s,))) ++ s = bytes(numberToByteArray(m, numBytes(self.n))) ++ c = bytesToNumber(bytearray(self.rsa.decrypt((s,)))) + return c + + def _rawPublicKeyOp(self, c): +- s = numberToString(c, numBytes(self.n)) +- m = stringToNumber(self.rsa.encrypt(s, None)[0]) ++ s = bytes(numberToByteArray(c, numBytes(self.n))) ++ m = bytesToNumber(bytearray(self.rsa.encrypt(s, None)[0])) + return m + + def generate(bits): diff --git a/chromium/third_party/tlslite/patches/python26.patch b/chromium/third_party/tlslite/patches/python26.patch deleted file mode 100644 index d2c3072a638..00000000000 --- a/chromium/third_party/tlslite/patches/python26.patch +++ /dev/null @@ -1,95 +0,0 @@ -diff -aur tlslite-0.3.8/tlslite/TLSRecordLayer.py chromium/tlslite/TLSRecordLayer.py ---- tlslite-0.3.8/tlslite/TLSRecordLayer.py 2005-02-22 00:31:41.000000000 -0500 -+++ chromium/tlslite/TLSRecordLayer.py 2010-08-14 16:54:14.506283500 -0400 -@@ -12,8 +12,19 @@ - from utils.cryptomath import getRandomBytes - from utils import hmac - from FileObject import FileObject --import sha --import md5 -+ -+# The sha module is deprecated in Python 2.6 -+try: -+ import sha -+except ImportError: -+ from hashlib import sha1 as sha -+ -+# The md5 module is deprecated in Python 2.6 -+try: -+ import md5 -+except ImportError: -+ from hashlib import md5 -+ - import socket - import errno - import traceback -diff -aur tlslite-0.3.8/tlslite/mathtls.py chromium/tlslite/mathtls.py ---- tlslite-0.3.8/tlslite/mathtls.py 2004-10-06 01:01:15.000000000 -0400 -+++ chromium/tlslite/mathtls.py 2010-08-14 16:54:14.526283600 -0400 -@@ -4,8 +4,18 @@ - from utils.cryptomath import * - - import hmac --import md5 --import sha -+ -+# The sha module is deprecated in Python 2.6 -+try: -+ import sha -+except ImportError: -+ from hashlib import sha1 as sha -+ -+# The md5 module is deprecated in Python 2.6 -+try: -+ import md5 -+except ImportError: -+ from hashlib import md5 - - #1024, 1536, 2048, 3072, 4096, 6144, and 8192 bit groups] - goodGroupParameters = [(2,0xEEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE48E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B297BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9AFD5138FE8376435B9FC61D2FC0EB06E3),\ -diff -aur tlslite-0.3.8/tlslite/messages.py chromium/tlslite/messages.py ---- tlslite-0.3.8/tlslite/messages.py 2004-10-06 01:01:24.000000000 -0400 -+++ chromium/tlslite/messages.py 2010-08-14 16:54:14.536283600 -0400 -@@ -8,8 +8,17 @@ - from X509 import X509 - from X509CertChain import X509CertChain - --import sha --import md5 -+# The sha module is deprecated in Python 2.6 -+try: -+ import sha -+except ImportError: -+ from hashlib import sha1 as sha -+ -+# The md5 module is deprecated in Python 2.6 -+try: -+ import md5 -+except ImportError: -+ from hashlib import md5 - - class RecordHeader3: - def __init__(self): -diff -aur tlslite-0.3.8/tlslite/utils/cryptomath.py chromium/tlslite/utils/cryptomath.py ---- tlslite-0.3.8/tlslite/utils/cryptomath.py 2004-10-06 01:02:53.000000000 -0400 -+++ chromium/tlslite/utils/cryptomath.py 2010-08-14 16:54:14.556283600 -0400 -@@ -6,7 +6,18 @@ - import math - import base64 - import binascii --import sha -+ -+# The sha module is deprecated in Python 2.6 -+try: -+ import sha -+except ImportError: -+ from hashlib import sha1 as sha -+ -+# The md5 module is deprecated in Python 2.6 -+try: -+ import md5 -+except ImportError: -+ from hashlib import md5 - - from compat import * - diff --git a/chromium/third_party/tlslite/patches/req_cert_types.patch b/chromium/third_party/tlslite/patches/req_cert_types.patch new file mode 100644 index 00000000000..2774e777968 --- /dev/null +++ b/chromium/third_party/tlslite/patches/req_cert_types.patch @@ -0,0 +1,153 @@ +diff --git a/third_party/tlslite/tlslite/api.py b/third_party/tlslite/tlslite/api.py +index faef6cb..562fb81 100644 +--- a/third_party/tlslite/tlslite/api.py ++++ b/third_party/tlslite/tlslite/api.py +@@ -2,7 +2,8 @@ + # See the LICENSE file for legal information regarding use of this file. + + __version__ = "0.4.6" +-from .constants import AlertLevel, AlertDescription, Fault ++from .constants import AlertLevel, AlertDescription, ClientCertificateType, \ ++ Fault + from .errors import * + from .checker import Checker + from .handshakesettings import HandshakeSettings +diff --git a/third_party/tlslite/tlslite/constants.py b/third_party/tlslite/tlslite/constants.py +index 30d1f9f..457b339 100644 +--- a/third_party/tlslite/tlslite/constants.py ++++ b/third_party/tlslite/tlslite/constants.py +@@ -14,10 +14,14 @@ class CertificateType: + openpgp = 1 + + class ClientCertificateType: ++ # http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-2 + rsa_sign = 1 + dss_sign = 2 + rsa_fixed_dh = 3 + dss_fixed_dh = 4 ++ ecdsa_sign = 64 ++ rsa_fixed_ecdh = 65 ++ ecdsa_fixed_ecdh = 66 + + class HandshakeType: + hello_request = 0 +diff --git a/third_party/tlslite/tlslite/messages.py b/third_party/tlslite/tlslite/messages.py +index 550b387..c8a913c 100644 +--- a/third_party/tlslite/tlslite/messages.py ++++ b/third_party/tlslite/tlslite/messages.py +@@ -454,9 +454,7 @@ class CertificateStatus(HandshakeMsg): + class CertificateRequest(HandshakeMsg): + def __init__(self): + HandshakeMsg.__init__(self, HandshakeType.certificate_request) +- #Apple's Secure Transport library rejects empty certificate_types, so +- #default to rsa_sign. +- self.certificate_types = [ClientCertificateType.rsa_sign] ++ self.certificate_types = [] + self.certificate_authorities = [] + + def create(self, certificate_types, certificate_authorities): +diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py +index e6f7820..044ad59 100644 +--- a/third_party/tlslite/tlslite/tlsconnection.py ++++ b/third_party/tlslite/tlslite/tlsconnection.py +@@ -1062,7 +1062,7 @@ class TLSConnection(TLSRecordLayer): + def handshakeServer(self, verifierDB=None, + certChain=None, privateKey=None, reqCert=False, + sessionCache=None, settings=None, checker=None, +- reqCAs = None, ++ reqCAs = None, reqCertTypes = None, + tacks=None, activationFlags=0, + nextProtos=None, anon=False, + tlsIntolerant=None, signedCertTimestamps=None, +@@ -1130,6 +1130,10 @@ class TLSConnection(TLSRecordLayer): + will be sent along with a certificate request. This does not affect + verification. + ++ @type reqCertTypes: list of int ++ @param reqCertTypes: A list of certificate_type values to be sent ++ along with a certificate request. This does not affect verification. ++ + @type nextProtos: list of strings. + @param nextProtos: A list of upper layer protocols to expose to the + clients through the Next-Protocol Negotiation Extension, +@@ -1169,7 +1173,7 @@ class TLSConnection(TLSRecordLayer): + """ + for result in self.handshakeServerAsync(verifierDB, + certChain, privateKey, reqCert, sessionCache, settings, +- checker, reqCAs, ++ checker, reqCAs, reqCertTypes, + tacks=tacks, activationFlags=activationFlags, + nextProtos=nextProtos, anon=anon, tlsIntolerant=tlsIntolerant, + signedCertTimestamps=signedCertTimestamps, +@@ -1180,7 +1184,7 @@ class TLSConnection(TLSRecordLayer): + def handshakeServerAsync(self, verifierDB=None, + certChain=None, privateKey=None, reqCert=False, + sessionCache=None, settings=None, checker=None, +- reqCAs=None, ++ reqCAs=None, reqCertTypes=None, + tacks=None, activationFlags=0, + nextProtos=None, anon=False, + tlsIntolerant=None, +@@ -1203,7 +1207,7 @@ class TLSConnection(TLSRecordLayer): + verifierDB=verifierDB, certChain=certChain, + privateKey=privateKey, reqCert=reqCert, + sessionCache=sessionCache, settings=settings, +- reqCAs=reqCAs, ++ reqCAs=reqCAs, reqCertTypes=reqCertTypes, + tacks=tacks, activationFlags=activationFlags, + nextProtos=nextProtos, anon=anon, + tlsIntolerant=tlsIntolerant, +@@ -1216,7 +1220,7 @@ class TLSConnection(TLSRecordLayer): + + def _handshakeServerAsyncHelper(self, verifierDB, + certChain, privateKey, reqCert, sessionCache, +- settings, reqCAs, ++ settings, reqCAs, reqCertTypes, + tacks, activationFlags, + nextProtos, anon, + tlsIntolerant, signedCertTimestamps, fallbackSCSV, +@@ -1232,6 +1236,8 @@ class TLSConnection(TLSRecordLayer): + raise ValueError("Caller passed a privateKey but no certChain") + if reqCAs and not reqCert: + raise ValueError("Caller passed reqCAs but not reqCert") ++ if reqCertTypes and not reqCert: ++ raise ValueError("Caller passed reqCertTypes but not reqCert") + if certChain and not isinstance(certChain, X509CertChain): + raise ValueError("Unrecognized certificate type") + if activationFlags and not tacks: +@@ -1320,7 +1326,7 @@ class TLSConnection(TLSRecordLayer): + assert(False) + for result in self._serverCertKeyExchange(clientHello, serverHello, + certChain, keyExchange, +- reqCert, reqCAs, cipherSuite, ++ reqCert, reqCAs, reqCertTypes, cipherSuite, + settings, ocspResponse): + if result in (0,1): yield result + else: break +@@ -1597,7 +1603,7 @@ class TLSConnection(TLSRecordLayer): + + def _serverCertKeyExchange(self, clientHello, serverHello, + serverCertChain, keyExchange, +- reqCert, reqCAs, cipherSuite, ++ reqCert, reqCAs, reqCertTypes, cipherSuite, + settings, ocspResponse): + #Send ServerHello, Certificate[, ServerKeyExchange] + #[, CertificateRequest], ServerHelloDone +@@ -1613,11 +1619,12 @@ class TLSConnection(TLSRecordLayer): + serverKeyExchange = keyExchange.makeServerKeyExchange() + if serverKeyExchange is not None: + msgs.append(serverKeyExchange) +- if reqCert and reqCAs: +- msgs.append(CertificateRequest().create(\ +- [ClientCertificateType.rsa_sign], reqCAs)) +- elif reqCert: +- msgs.append(CertificateRequest()) ++ if reqCert: ++ reqCAs = reqCAs or [] ++ #Apple's Secure Transport library rejects empty certificate_types, ++ #so default to rsa_sign. ++ reqCertTypes = reqCertTypes or [ClientCertificateType.rsa_sign] ++ msgs.append(CertificateRequest().create(reqCertTypes, reqCAs)) + msgs.append(ServerHelloDone()) + for result in self._sendMsgs(msgs): + yield result diff --git a/chromium/third_party/tlslite/patches/send_certificate_types.patch b/chromium/third_party/tlslite/patches/send_certificate_types.patch deleted file mode 100644 index 14b293587f8..00000000000 --- a/chromium/third_party/tlslite/patches/send_certificate_types.patch +++ /dev/null @@ -1,32 +0,0 @@ -diff --git a/tlslite/constants.py b/tlslite/constants.py -index 8f2d559..04302c0 100644 ---- a/tlslite/constants.py -+++ b/tlslite/constants.py -@@ -5,6 +5,12 @@ class CertificateType: - openpgp = 1 - cryptoID = 2 - -+class ClientCertificateType: -+ rsa_sign = 1 -+ dss_sign = 2 -+ rsa_fixed_dh = 3 -+ dss_fixed_dh = 4 -+ - class HandshakeType: - hello_request = 0 - client_hello = 1 -diff --git a/tlslite/messages.py b/tlslite/messages.py -index 06c46b9..8bcec2c 100644 ---- a/tlslite/messages.py -+++ b/tlslite/messages.py -@@ -346,7 +346,9 @@ class Certificate(HandshakeMsg): - class CertificateRequest(HandshakeMsg): - def __init__(self): - self.contentType = ContentType.handshake -- self.certificate_types = [] -+ #Apple's implementation rejects empty certificate_types, so -+ #default to rsa_sign. -+ self.certificate_types = [ClientCertificateType.rsa_sign] - #treat as opaque bytes for now - self.certificate_authorities = createByteArraySequence([]) - diff --git a/chromium/third_party/tlslite/patches/signed_certificate_timestamps.patch b/chromium/third_party/tlslite/patches/signed_certificate_timestamps.patch index 55db061d141..21bcacc9bd7 100644 --- a/chromium/third_party/tlslite/patches/signed_certificate_timestamps.patch +++ b/chromium/third_party/tlslite/patches/signed_certificate_timestamps.patch @@ -1,20 +1,72 @@ -diff --git a/third_party/tlslite/tlslite/TLSConnection.py b/third_party/tlslite/tlslite/TLSConnection.py -index e882e2c..d2270a9 100644 ---- a/third_party/tlslite/tlslite/TLSConnection.py -+++ b/third_party/tlslite/tlslite/TLSConnection.py -@@ -936,7 +936,8 @@ class TLSConnection(TLSRecordLayer): - def handshakeServer(self, sharedKeyDB=None, verifierDB=None, - certChain=None, privateKey=None, reqCert=False, - sessionCache=None, settings=None, checker=None, -- reqCAs=None, tlsIntolerant=0): -+ reqCAs=None, tlsIntolerant=0, -+ signedCertTimestamps=None): +diff --git a/third_party/tlslite/tlslite/constants.py b/third_party/tlslite/tlslite/constants.py +index 79ad145..b3bad2d 100755 +--- a/third_party/tlslite/tlslite/constants.py ++++ b/third_party/tlslite/tlslite/constants.py +@@ -44,6 +44,7 @@ class ExtensionType: # RFC 6066 / 4366 + server_name = 0 # RFC 6066 / 4366 + srp = 12 # RFC 5054 + cert_type = 9 # RFC 6091 ++ signed_cert_timestamps = 18 # RFC 6962 + tack = 0xF300 + supports_npn = 13172 + channel_id = 30031 +diff --git a/third_party/tlslite/tlslite/messages.py b/third_party/tlslite/tlslite/messages.py +index 246082e..5a2cd6c 100755 +--- a/third_party/tlslite/tlslite/messages.py ++++ b/third_party/tlslite/tlslite/messages.py +@@ -113,6 +113,7 @@ class ClientHello(HandshakeMsg): + self.supports_npn = False + self.server_name = bytearray(0) + self.channel_id = False ++ self.support_signed_cert_timestamps = False + + def create(self, version, random, session_id, cipher_suites, + certificate_types=None, srpUsername=None, +@@ -182,6 +183,10 @@ class ClientHello(HandshakeMsg): + break + elif extType == ExtensionType.channel_id: + self.channel_id = True ++ elif extType == ExtensionType.signed_cert_timestamps: ++ if extLength: ++ raise SyntaxError() ++ self.support_signed_cert_timestamps = True + else: + _ = p.getFixBytes(extLength) + index2 = p.index +@@ -247,6 +252,7 @@ class ServerHello(HandshakeMsg): + self.next_protos_advertised = None + self.next_protos = None + self.channel_id = False ++ self.signed_cert_timestamps = None + + def create(self, version, random, session_id, cipher_suite, + certificate_type, tackExt, next_protos_advertised): +@@ -336,6 +342,9 @@ class ServerHello(HandshakeMsg): + if self.channel_id: + w2.add(ExtensionType.channel_id, 2) + w2.add(0, 2) ++ if self.signed_cert_timestamps: ++ w2.add(ExtensionType.signed_cert_timestamps, 2) ++ w2.addVarSeq(bytearray(self.signed_cert_timestamps), 1, 2) + if len(w2.bytes): + w.add(len(w2.bytes), 2) + w.bytes += w2.bytes +diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py +index e7c5140..45b0bbb 100755 +--- a/third_party/tlslite/tlslite/tlsconnection.py ++++ b/third_party/tlslite/tlslite/tlsconnection.py +@@ -966,7 +966,7 @@ class TLSConnection(TLSRecordLayer): + reqCAs = None, + tacks=None, activationFlags=0, + nextProtos=None, anon=False, +- tlsIntolerant=None): ++ tlsIntolerant=None, signedCertTimestamps=None): """Perform a handshake in the role of server. This function performs an SSL or TLS handshake. Depending on -@@ -1007,6 +1008,11 @@ class TLSConnection(TLSRecordLayer): - will be sent along with a certificate request. This does not affect - verification. +@@ -1040,6 +1040,11 @@ class TLSConnection(TLSRecordLayer): + simulate TLS version intolerance by returning a fatal handshake_failure + alert to all TLS versions tlsIntolerant or higher. + @type signedCertTimestamps: str + @param signedCertTimestamps: A SignedCertificateTimestampList (as a @@ -24,124 +76,61 @@ index e882e2c..d2270a9 100644 @raise socket.error: If a socket error occurs. @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed without a preceding alert. -@@ -1016,14 +1022,15 @@ class TLSConnection(TLSRecordLayer): - """ - for result in self.handshakeServerAsync(sharedKeyDB, verifierDB, +@@ -1051,7 +1056,8 @@ class TLSConnection(TLSRecordLayer): certChain, privateKey, reqCert, sessionCache, settings, -- checker, reqCAs, tlsIntolerant): -+ checker, reqCAs, tlsIntolerant, signedCertTimestamps): + checker, reqCAs, + tacks=tacks, activationFlags=activationFlags, +- nextProtos=nextProtos, anon=anon, tlsIntolerant=tlsIntolerant): ++ nextProtos=nextProtos, anon=anon, tlsIntolerant=tlsIntolerant, ++ signedCertTimestamps=signedCertTimestamps): pass - def handshakeServerAsync(self, sharedKeyDB=None, verifierDB=None, - certChain=None, privateKey=None, reqCert=False, - sessionCache=None, settings=None, checker=None, -- reqCAs=None, tlsIntolerant=0): -+ reqCAs=None, tlsIntolerant=0, -+ signedCertTimestamps=None): +@@ -1061,7 +1067,8 @@ class TLSConnection(TLSRecordLayer): + reqCAs=None, + tacks=None, activationFlags=0, + nextProtos=None, anon=False, +- tlsIntolerant=None ++ tlsIntolerant=None, ++ signedCertTimestamps=None + ): """Start a server handshake operation on the TLS connection. - This function returns a generator which behaves similarly to -@@ -1041,14 +1048,16 @@ class TLSConnection(TLSRecordLayer): - privateKey=privateKey, reqCert=reqCert, - sessionCache=sessionCache, settings=settings, - reqCAs=reqCAs, +@@ -1081,7 +1088,8 @@ class TLSConnection(TLSRecordLayer): + reqCAs=reqCAs, + tacks=tacks, activationFlags=activationFlags, + nextProtos=nextProtos, anon=anon, - tlsIntolerant=tlsIntolerant) + tlsIntolerant=tlsIntolerant, + signedCertTimestamps=signedCertTimestamps) for result in self._handshakeWrapperAsync(handshaker, checker): yield result - - def _handshakeServerAsyncHelper(self, sharedKeyDB, verifierDB, -- certChain, privateKey, reqCert, sessionCache, -- settings, reqCAs, tlsIntolerant): -+ certChain, privateKey, reqCert, -+ sessionCache, settings, reqCAs, -+ tlsIntolerant, signedCertTimestamps): +@@ -1091,7 +1099,7 @@ class TLSConnection(TLSRecordLayer): + settings, reqCAs, + tacks, activationFlags, + nextProtos, anon, +- tlsIntolerant): ++ tlsIntolerant, signedCertTimestamps): self._handshakeStart(client=False) -@@ -1060,6 +1069,9 @@ class TLSConnection(TLSRecordLayer): - raise ValueError("Caller passed a privateKey but no certChain") - if reqCAs and not reqCert: - raise ValueError("Caller passed reqCAs but not reqCert") +@@ -1112,6 +1120,9 @@ class TLSConnection(TLSRecordLayer): + raise ValueError("tackpy is not loaded") + if not settings or not settings.useExperimentalTackExtension: + raise ValueError("useExperimentalTackExtension not enabled") + if signedCertTimestamps and not certChain: + raise ValueError("Caller passed signedCertTimestamps but no " + "certChain") if not settings: settings = HandshakeSettings() -@@ -1415,6 +1427,8 @@ class TLSConnection(TLSRecordLayer): - self.version, serverRandom, - sessionID, cipherSuite, certificateType) - serverHello.channel_id = clientHello.channel_id -+ if clientHello.support_signed_cert_timestamps: -+ serverHello.signed_cert_timestamps = signedCertTimestamps - doingChannelID = clientHello.channel_id - msgs.append(serverHello) - msgs.append(Certificate(certificateType).create(serverCertChain)) -diff --git a/third_party/tlslite/tlslite/constants.py b/third_party/tlslite/tlslite/constants.py -index e357dd0..b5a345a 100644 ---- a/third_party/tlslite/tlslite/constants.py -+++ b/third_party/tlslite/tlslite/constants.py -@@ -32,6 +32,7 @@ class ContentType: - all = (20,21,22,23) - - class ExtensionType: -+ signed_cert_timestamps = 18 # signed_certificate_timestamp in RFC 6962 - channel_id = 30031 - - class AlertLevel: -diff --git a/third_party/tlslite/tlslite/messages.py b/third_party/tlslite/tlslite/messages.py -index fa4d817..296f422 100644 ---- a/third_party/tlslite/tlslite/messages.py -+++ b/third_party/tlslite/tlslite/messages.py -@@ -131,6 +131,7 @@ class ClientHello(HandshakeMsg): - self.compression_methods = [] # a list of 8-bit values - self.srp_username = None # a string - self.channel_id = False -+ self.support_signed_cert_timestamps = False - - def create(self, version, random, session_id, cipher_suites, - certificate_types=None, srp_username=None): -@@ -177,6 +178,10 @@ class ClientHello(HandshakeMsg): - self.certificate_types = p.getVarList(1, 1) - elif extType == ExtensionType.channel_id: - self.channel_id = True -+ elif extType == ExtensionType.signed_cert_timestamps: -+ if extLength: -+ raise SyntaxError() -+ self.support_signed_cert_timestamps = True - else: - p.getFixBytes(extLength) - soFar += 4 + extLength -@@ -224,6 +229,7 @@ class ServerHello(HandshakeMsg): - self.certificate_type = CertificateType.x509 - self.compression_method = 0 - self.channel_id = False -+ self.signed_cert_timestamps = None - - def create(self, version, random, session_id, cipher_suite, - certificate_type): -@@ -273,6 +279,9 @@ class ServerHello(HandshakeMsg): - if self.channel_id: - extLength += 4 - -+ if self.signed_cert_timestamps: -+ extLength += 4 + len(self.signed_cert_timestamps) -+ - if extLength != 0: - w.add(extLength, 2) - -@@ -286,6 +295,10 @@ class ServerHello(HandshakeMsg): - w.add(ExtensionType.channel_id, 2) - w.add(0, 2) - -+ if self.signed_cert_timestamps: -+ w.add(ExtensionType.signed_cert_timestamps, 2) -+ w.addVarSeq(stringToBytes(self.signed_cert_timestamps), 1, 2) -+ - return HandshakeMsg.postWrite(self, w, trial) - - class Certificate(HandshakeMsg): +@@ -1156,6 +1167,8 @@ class TLSConnection(TLSRecordLayer): + cipherSuite, CertificateType.x509, tackExt, + nextProtos) + serverHello.channel_id = clientHello.channel_id ++ if clientHello.support_signed_cert_timestamps: ++ serverHello.signed_cert_timestamps = signedCertTimestamps + + # Perform the SRP key exchange + clientCertChain = None diff --git a/chromium/third_party/tlslite/patches/srp_cert.patch b/chromium/third_party/tlslite/patches/srp_cert.patch new file mode 100644 index 00000000000..8ea579caf5f --- /dev/null +++ b/chromium/third_party/tlslite/patches/srp_cert.patch @@ -0,0 +1,13 @@ +diff --git a/third_party/tlslite/tlslite/constants.py b/third_party/tlslite/tlslite/constants.py +index ceaa903..52c20ac 100644 +--- a/third_party/tlslite/tlslite/constants.py ++++ b/third_party/tlslite/tlslite/constants.py +@@ -224,7 +224,7 @@ class CipherSuite: + def getSrpCertSuites(settings): + return CipherSuite._filterSuites(CipherSuite.srpCertSuites, settings) + +- srpAllSuites = srpSuites + srpCertSuites ++ srpAllSuites = srpCertSuites + srpSuites + + @staticmethod + def getSrpAllSuites(settings): diff --git a/chromium/third_party/tlslite/patches/ssl3_padding.patch b/chromium/third_party/tlslite/patches/ssl3_padding.patch new file mode 100644 index 00000000000..2c6e28acc61 --- /dev/null +++ b/chromium/third_party/tlslite/patches/ssl3_padding.patch @@ -0,0 +1,18 @@ +diff --git a/third_party/tlslite/tlslite/tlsrecordlayer.py b/third_party/tlslite/tlslite/tlsrecordlayer.py +index ff08cbf..8b92221 100644 +--- a/third_party/tlslite/tlslite/tlsrecordlayer.py ++++ b/third_party/tlslite/tlslite/tlsrecordlayer.py +@@ -586,10 +586,10 @@ class TLSRecordLayer(object): + if self.version == (3,2): + b = self.fixedIVBlock + b + +- #Add padding: b = b+ (macBytes + paddingBytes) +- currentLength = len(b) + len(macBytes) + 1 ++ #Add padding: b = b + (macBytes + paddingBytes) ++ currentLength = len(b) + len(macBytes) + blockLength = self._writeState.encContext.block_size +- paddingLength = blockLength-(currentLength % blockLength) ++ paddingLength = blockLength - 1 - (currentLength % blockLength) + + paddingBytes = bytearray([paddingLength] * (paddingLength+1)) + if self.fault == Fault.badPadding: diff --git a/chromium/third_party/tlslite/patches/status_request.patch b/chromium/third_party/tlslite/patches/status_request.patch index 15f01d42809..cfd7f6f19c6 100644 --- a/chromium/third_party/tlslite/patches/status_request.patch +++ b/chromium/third_party/tlslite/patches/status_request.patch @@ -1,125 +1,41 @@ -diff --git a/third_party/tlslite/tlslite/TLSConnection.py b/third_party/tlslite/tlslite/TLSConnection.py -index e6ce187..94ee5eb 100644 ---- a/third_party/tlslite/tlslite/TLSConnection.py -+++ b/third_party/tlslite/tlslite/TLSConnection.py -@@ -937,8 +937,8 @@ class TLSConnection(TLSRecordLayer): - certChain=None, privateKey=None, reqCert=False, - sessionCache=None, settings=None, checker=None, - reqCAs=None, tlsIntolerant=0, -- signedCertTimestamps=None, -- fallbackSCSV=False): -+ signedCertTimestamps=None, fallbackSCSV=False, -+ ocspResponse=None): - """Perform a handshake in the role of server. - - This function performs an SSL or TLS handshake. Depending on -@@ -1014,6 +1014,16 @@ class TLSConnection(TLSRecordLayer): - binary 8-bit string) that will be sent as a TLS extension whenever - the client announces support for the extension. - -+ @type ocspResponse: str -+ @param ocspResponse: An OCSP response (as a binary 8-bit string) that -+ will be sent stapled in the handshake whenever the client announces -+ support for the status_request extension. -+ Note that the response is sent independent of the ClientHello -+ status_request extension contents, and is thus only meant for testing -+ environments. Real OCSP stapling is more complicated as it requires -+ choosing a suitable response based on the ClientHello status_request -+ extension contents. -+ - @raise socket.error: If a socket error occurs. - @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed - without a preceding alert. -@@ -1024,7 +1034,7 @@ class TLSConnection(TLSRecordLayer): - for result in self.handshakeServerAsync(sharedKeyDB, verifierDB, - certChain, privateKey, reqCert, sessionCache, settings, - checker, reqCAs, tlsIntolerant, signedCertTimestamps, -- fallbackSCSV): -+ fallbackSCSV, ocspResponse): - pass - - -@@ -1033,7 +1043,7 @@ class TLSConnection(TLSRecordLayer): - sessionCache=None, settings=None, checker=None, - reqCAs=None, tlsIntolerant=0, - signedCertTimestamps=None, -- fallbackSCSV=False): -+ fallbackSCSV=False, ocspResponse=None): - """Start a server handshake operation on the TLS connection. - - This function returns a generator which behaves similarly to -@@ -1053,7 +1063,8 @@ class TLSConnection(TLSRecordLayer): - reqCAs=reqCAs, - tlsIntolerant=tlsIntolerant, - signedCertTimestamps=signedCertTimestamps, -- fallbackSCSV=fallbackSCSV) -+ fallbackSCSV=fallbackSCSV, ocspResponse=ocspResponse) -+ - for result in self._handshakeWrapperAsync(handshaker, checker): - yield result - -@@ -1062,7 +1073,7 @@ class TLSConnection(TLSRecordLayer): - certChain, privateKey, reqCert, - sessionCache, settings, reqCAs, - tlsIntolerant, signedCertTimestamps, -- fallbackSCSV): -+ fallbackSCSV, ocspResponse): - - self._handshakeStart(client=False) - -@@ -1439,10 +1450,14 @@ class TLSConnection(TLSRecordLayer): - sessionID, cipherSuite, certificateType) - serverHello.channel_id = clientHello.channel_id - if clientHello.support_signed_cert_timestamps: -- serverHello.signed_cert_timestamps = signedCertTimestamps -+ serverHello.signed_cert_timestamps = signedCertTimestamps -+ serverHello.status_request = (clientHello.status_request and -+ ocspResponse) - doingChannelID = clientHello.channel_id - msgs.append(serverHello) - msgs.append(Certificate(certificateType).create(serverCertChain)) -+ if serverHello.status_request: -+ msgs.append(CertificateStatus().create(ocspResponse)) - if reqCert and reqCAs: - msgs.append(CertificateRequest().create([], reqCAs)) - elif reqCert: diff --git a/third_party/tlslite/tlslite/constants.py b/third_party/tlslite/tlslite/constants.py -index 23e3dcb..d027ef5 100644 +index d132b78..ceaa903 100755 --- a/third_party/tlslite/tlslite/constants.py +++ b/third_party/tlslite/tlslite/constants.py -@@ -22,6 +22,7 @@ class HandshakeType: +@@ -30,6 +30,7 @@ class HandshakeType: certificate_verify = 15 client_key_exchange = 16 finished = 20 + certificate_status = 22 + next_protocol = 67 encrypted_extensions = 203 - class ContentType: -@@ -31,7 +32,11 @@ class ContentType: +@@ -40,8 +41,12 @@ class ContentType: application_data = 23 all = (20,21,22,23) +class CertificateStatusType: + ocsp = 1 + - class ExtensionType: -+ status_request = 5 # OCSP stapling - signed_cert_timestamps = 18 # signed_certificate_timestamp in RFC 6962 - channel_id = 30031 - + class ExtensionType: # RFC 6066 / 4366 + server_name = 0 # RFC 6066 / 4366 ++ status_request = 5 # RFC 6066 / 4366 + srp = 12 # RFC 5054 + cert_type = 9 # RFC 6091 + signed_cert_timestamps = 18 # RFC 6962 diff --git a/third_party/tlslite/tlslite/messages.py b/third_party/tlslite/tlslite/messages.py -index 296f422..497ef60 100644 +index 5a2cd6c..532d86b 100755 --- a/third_party/tlslite/tlslite/messages.py +++ b/third_party/tlslite/tlslite/messages.py -@@ -132,6 +132,7 @@ class ClientHello(HandshakeMsg): - self.srp_username = None # a string +@@ -114,6 +114,7 @@ class ClientHello(HandshakeMsg): + self.server_name = bytearray(0) self.channel_id = False self.support_signed_cert_timestamps = False + self.status_request = False def create(self, version, random, session_id, cipher_suites, - certificate_types=None, srp_username=None): -@@ -182,6 +183,19 @@ class ClientHello(HandshakeMsg): + certificate_types=None, srpUsername=None, +@@ -187,6 +188,19 @@ class ClientHello(HandshakeMsg): if extLength: raise SyntaxError() self.support_signed_cert_timestamps = True @@ -137,44 +53,33 @@ index 296f422..497ef60 100644 + p.getFixBytes(extLength) + self.status_request = True else: - p.getFixBytes(extLength) - soFar += 4 + extLength -@@ -230,6 +244,7 @@ class ServerHello(HandshakeMsg): - self.compression_method = 0 + _ = p.getFixBytes(extLength) + index2 = p.index +@@ -253,6 +267,7 @@ class ServerHello(HandshakeMsg): + self.next_protos = None self.channel_id = False self.signed_cert_timestamps = None + self.status_request = False def create(self, version, random, session_id, cipher_suite, - certificate_type): -@@ -282,6 +297,9 @@ class ServerHello(HandshakeMsg): + certificate_type, tackExt, next_protos_advertised): +@@ -345,6 +360,9 @@ class ServerHello(HandshakeMsg): if self.signed_cert_timestamps: - extLength += 4 + len(self.signed_cert_timestamps) - + w2.add(ExtensionType.signed_cert_timestamps, 2) + w2.addVarSeq(bytearray(self.signed_cert_timestamps), 1, 2) + if self.status_request: -+ extLength += 4 -+ - if extLength != 0: - w.add(extLength, 2) - -@@ -299,6 +317,10 @@ class ServerHello(HandshakeMsg): - w.add(ExtensionType.signed_cert_timestamps, 2) - w.addVarSeq(stringToBytes(self.signed_cert_timestamps), 1, 2) - -+ if self.status_request: -+ w.add(ExtensionType.status_request, 2) -+ w.add(0, 2) -+ - return HandshakeMsg.postWrite(self, w, trial) - - class Certificate(HandshakeMsg): -@@ -367,6 +389,37 @@ class Certificate(HandshakeMsg): ++ w2.add(ExtensionType.status_request, 2) ++ w2.add(0, 2) + if len(w2.bytes): + w.add(len(w2.bytes), 2) + w.bytes += w2.bytes +@@ -402,6 +420,37 @@ class Certificate(HandshakeMsg): raise AssertionError() - return HandshakeMsg.postWrite(self, w, trial) + return self.postWrite(w) +class CertificateStatus(HandshakeMsg): + def __init__(self): -+ self.contentType = ContentType.handshake ++ HandshakeMsg.__init__(self, HandshakeType.certificate_status) + + def create(self, ocsp_response): + self.ocsp_response = ocsp_response @@ -194,15 +99,120 @@ index 296f422..497ef60 100644 + # Can't be empty + raise SyntaxError() + self.ocsp_response = ocsp_response ++ p.stopLengthCheck() + return self + -+ def write(self, trial=False): -+ w = HandshakeMsg.preWrite(self, HandshakeType.certificate_status, -+ trial) ++ def write(self): ++ w = Writer() + w.add(CertificateStatusType.ocsp, 1) -+ w.addVarSeq(stringToBytes(self.ocsp_response), 1, 3) -+ return HandshakeMsg.postWrite(self, w, trial) ++ w.addVarSeq(bytearray(self.ocsp_response), 1, 3) ++ return self.postWrite(w) + class CertificateRequest(HandshakeMsg): def __init__(self): - self.contentType = ContentType.handshake + HandshakeMsg.__init__(self, HandshakeType.certificate_request) +diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py +index bd92161..b9797d2 100755 +--- a/third_party/tlslite/tlslite/tlsconnection.py ++++ b/third_party/tlslite/tlslite/tlsconnection.py +@@ -967,7 +967,7 @@ class TLSConnection(TLSRecordLayer): + tacks=None, activationFlags=0, + nextProtos=None, anon=False, + tlsIntolerant=None, signedCertTimestamps=None, +- fallbackSCSV=False): ++ fallbackSCSV=False, ocspResponse=None): + """Perform a handshake in the role of server. + + This function performs an SSL or TLS handshake. Depending on +@@ -1051,6 +1051,16 @@ class TLSConnection(TLSRecordLayer): + TLS_FALLBACK_SCSV and thus reject connections using less than the + server's maximum TLS version that include this cipher suite. + ++ @type ocspResponse: str ++ @param ocspResponse: An OCSP response (as a binary 8-bit string) that ++ will be sent stapled in the handshake whenever the client announces ++ support for the status_request extension. ++ Note that the response is sent independent of the ClientHello ++ status_request extension contents, and is thus only meant for testing ++ environments. Real OCSP stapling is more complicated as it requires ++ choosing a suitable response based on the ClientHello status_request ++ extension contents. ++ + @raise socket.error: If a socket error occurs. + @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed + without a preceding alert. +@@ -1064,7 +1074,7 @@ class TLSConnection(TLSRecordLayer): + tacks=tacks, activationFlags=activationFlags, + nextProtos=nextProtos, anon=anon, tlsIntolerant=tlsIntolerant, + signedCertTimestamps=signedCertTimestamps, +- fallbackSCSV=fallbackSCSV): ++ fallbackSCSV=fallbackSCSV, ocspResponse=ocspResponse): + pass + + +@@ -1076,7 +1086,8 @@ class TLSConnection(TLSRecordLayer): + nextProtos=None, anon=False, + tlsIntolerant=None, + signedCertTimestamps=None, +- fallbackSCSV=False ++ fallbackSCSV=False, ++ ocspResponse=None + ): + """Start a server handshake operation on the TLS connection. + +@@ -1098,7 +1109,8 @@ class TLSConnection(TLSRecordLayer): + nextProtos=nextProtos, anon=anon, + tlsIntolerant=tlsIntolerant, + signedCertTimestamps=signedCertTimestamps, +- fallbackSCSV=fallbackSCSV) ++ fallbackSCSV=fallbackSCSV, ++ ocspResponse=ocspResponse) + for result in self._handshakeWrapperAsync(handshaker, checker): + yield result + +@@ -1108,7 +1120,8 @@ class TLSConnection(TLSRecordLayer): + settings, reqCAs, + tacks, activationFlags, + nextProtos, anon, +- tlsIntolerant, signedCertTimestamps, fallbackSCSV): ++ tlsIntolerant, signedCertTimestamps, fallbackSCSV, ++ ocspResponse): + + self._handshakeStart(client=False) + +@@ -1178,6 +1191,8 @@ class TLSConnection(TLSRecordLayer): + serverHello.channel_id = clientHello.channel_id + if clientHello.support_signed_cert_timestamps: + serverHello.signed_cert_timestamps = signedCertTimestamps ++ if clientHello.status_request: ++ serverHello.status_request = ocspResponse + + # Perform the SRP key exchange + clientCertChain = None +@@ -1194,7 +1209,7 @@ class TLSConnection(TLSRecordLayer): + for result in self._serverCertKeyExchange(clientHello, serverHello, + certChain, privateKey, + reqCert, reqCAs, cipherSuite, +- settings): ++ settings, ocspResponse): + if result in (0,1): yield result + else: break + (premasterSecret, clientCertChain) = result +@@ -1471,7 +1486,7 @@ class TLSConnection(TLSRecordLayer): + def _serverCertKeyExchange(self, clientHello, serverHello, + serverCertChain, privateKey, + reqCert, reqCAs, cipherSuite, +- settings): ++ settings, ocspResponse): + #Send ServerHello, Certificate[, CertificateRequest], + #ServerHelloDone + msgs = [] +@@ -1481,6 +1496,8 @@ class TLSConnection(TLSRecordLayer): + + msgs.append(serverHello) + msgs.append(Certificate(CertificateType.x509).create(serverCertChain)) ++ if serverHello.status_request: ++ msgs.append(CertificateStatus().create(ocspResponse)) + if reqCert and reqCAs: + msgs.append(CertificateRequest().create(\ + [ClientCertificateType.rsa_sign], reqCAs)) diff --git a/chromium/third_party/tlslite/patches/tls_intolerant.patch b/chromium/third_party/tlslite/patches/tls_intolerant.patch index 53fe4d4c900..23723342de6 100644 --- a/chromium/third_party/tlslite/patches/tls_intolerant.patch +++ b/chromium/third_party/tlslite/patches/tls_intolerant.patch @@ -1,62 +1,93 @@ -Index: third_party/tlslite/tlslite/TLSConnection.py -=================================================================== ---- third_party/tlslite/tlslite/TLSConnection.py (revision 134128) -+++ third_party/tlslite/tlslite/TLSConnection.py (working copy) -@@ -932,7 +932,7 @@ - def handshakeServer(self, sharedKeyDB=None, verifierDB=None, - certChain=None, privateKey=None, reqCert=False, +diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py +index e8dd859..8415592 100755 +--- a/third_party/tlslite/tlslite/tlsconnection.py ++++ b/third_party/tlslite/tlslite/tlsconnection.py +@@ -965,7 +965,8 @@ class TLSConnection(TLSRecordLayer): sessionCache=None, settings=None, checker=None, -- reqCAs=None): -+ reqCAs=None, tlsIntolerant=0): + reqCAs = None, + tacks=None, activationFlags=0, +- nextProtos=None, anon=False): ++ nextProtos=None, anon=False, ++ tlsIntolerant=None): """Perform a handshake in the role of server. This function performs an SSL or TLS handshake. Depending on -@@ -1012,14 +1012,14 @@ - """ - for result in self.handshakeServerAsync(sharedKeyDB, verifierDB, +@@ -1034,6 +1035,11 @@ class TLSConnection(TLSRecordLayer): + clients through the Next-Protocol Negotiation Extension, + if they support it. + ++ @type tlsIntolerant: (int, int) or None ++ @param tlsIntolerant: If tlsIntolerant is not None, the server will ++ simulate TLS version intolerance by returning a fatal handshake_failure ++ alert to all TLS versions tlsIntolerant or higher. ++ + @raise socket.error: If a socket error occurs. + @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed + without a preceding alert. +@@ -1045,7 +1051,7 @@ class TLSConnection(TLSRecordLayer): certChain, privateKey, reqCert, sessionCache, settings, -- checker, reqCAs): -+ checker, reqCAs, tlsIntolerant): + checker, reqCAs, + tacks=tacks, activationFlags=activationFlags, +- nextProtos=nextProtos, anon=anon): ++ nextProtos=nextProtos, anon=anon, tlsIntolerant=tlsIntolerant): pass - def handshakeServerAsync(self, sharedKeyDB=None, verifierDB=None, - certChain=None, privateKey=None, reqCert=False, +@@ -1054,7 +1060,8 @@ class TLSConnection(TLSRecordLayer): sessionCache=None, settings=None, checker=None, -- reqCAs=None): -+ reqCAs=None, tlsIntolerant=0): + reqCAs=None, + tacks=None, activationFlags=0, +- nextProtos=None, anon=False ++ nextProtos=None, anon=False, ++ tlsIntolerant=None + ): """Start a server handshake operation on the TLS connection. - This function returns a generator which behaves similarly to -@@ -1036,14 +1036,15 @@ - verifierDB=verifierDB, certChain=certChain, - privateKey=privateKey, reqCert=reqCert, - sessionCache=sessionCache, settings=settings, -- reqCAs=reqCAs) -+ reqCAs=reqCAs, +@@ -1073,7 +1080,8 @@ class TLSConnection(TLSRecordLayer): + sessionCache=sessionCache, settings=settings, + reqCAs=reqCAs, + tacks=tacks, activationFlags=activationFlags, +- nextProtos=nextProtos, anon=anon) ++ nextProtos=nextProtos, anon=anon, + tlsIntolerant=tlsIntolerant) for result in self._handshakeWrapperAsync(handshaker, checker): yield result - - def _handshakeServerAsyncHelper(self, sharedKeyDB, verifierDB, +@@ -1082,7 +1090,8 @@ class TLSConnection(TLSRecordLayer): certChain, privateKey, reqCert, sessionCache, -- settings, reqCAs): -+ settings, reqCAs, tlsIntolerant): + settings, reqCAs, + tacks, activationFlags, +- nextProtos, anon): ++ nextProtos, anon, ++ tlsIntolerant): self._handshakeStart(client=False) -@@ -1111,6 +1112,17 @@ +@@ -1114,7 +1123,7 @@ class TLSConnection(TLSRecordLayer): + # Handle ClientHello and resumption + for result in self._serverGetClientHello(settings, certChain,\ + verifierDB, sessionCache, +- anon): ++ anon, tlsIntolerant): + if result in (0,1): yield result + elif result == None: + self._handshakeDone(resumed=True) +@@ -1211,7 +1220,7 @@ class TLSConnection(TLSRecordLayer): + + + def _serverGetClientHello(self, settings, certChain, verifierDB, +- sessionCache, anon): ++ sessionCache, anon, tlsIntolerant): + #Initialize acceptable cipher suites + cipherSuites = [] + if verifierDB: +@@ -1246,6 +1255,13 @@ class TLSConnection(TLSRecordLayer): "Too old version: %s" % str(clientHello.client_version)): yield result -+ #If tlsIntolerant is nonzero, reject certain TLS versions. -+ #1: reject all TLS versions. -+ #2: reject TLS 1.1 or higher. -+ #3: reject TLS 1.2 or higher. -+ if (tlsIntolerant == 1 and clientHello.client_version > (3, 0) or -+ tlsIntolerant == 2 and clientHello.client_version > (3, 1) or -+ tlsIntolerant == 3 and clientHello.client_version > (3, 2)): ++ #If simulating TLS intolerance, reject certain TLS versions. ++ elif (tlsIntolerant is not None and ++ clientHello.client_version >= tlsIntolerant): + for result in self._sendError(\ + AlertDescription.handshake_failure): + yield result diff --git a/chromium/third_party/tlslite/readme.txt b/chromium/third_party/tlslite/readme.txt deleted file mode 100644 index c1f1b3840c7..00000000000 --- a/chromium/third_party/tlslite/readme.txt +++ /dev/null @@ -1,815 +0,0 @@ - -tlslite version 0.3.8 February 21, 2005 -Trevor Perrin <trevp at trevp.net> -http://trevp.net/tlslite/ -============================================================================ - - -Table of Contents -================== -1 Introduction -2 License/Acknowledgements -3 Installation -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. - -API documentation is available in the 'docs' directory. - -If you have questions or feedback, feel free to contact me. - - -2 Licenses/Acknowledgements -============================ -All code here is public domain. - -Thanks to Bram Cohen for his public domain Rijndael implementation. - -Thanks to Edward Loper for Epydoc, which generated the API docs. - - -3 Installation -=============== -Requirements: - Python 2.2 or greater is required. - -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 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 [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. - - - 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). - -Anywhere else: - - 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 . - - While the test server is waiting, run: - tls.py clienttest 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. - -'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. - -'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: - - tlsdb.py createsrp verifierDB - tlsdb.py add verifierDB alice abra123cadabra 1024 - tlsdb.py add verifierDB bob swordfish 2048 - - tls.py serversrp localhost:443 verifierDB - -Then you can try connecting to the server with: - - tls.py clientsrp localhost:443 alice abra123cadabra - - -5 Getting Started with the Library -=================================== -Using the library is simple. 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. -4) Check the results to make sure you're talking to the right party. -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. - -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. - - 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 -------------------------------------- - from tlslite.api import * - 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: - - 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. - -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. - s = open("./test/clientX509Cert.pem").read() - x509 = X509() - x509.parse(s) - certChain = X509CertChain([x509]) - 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. - -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 -(version 3.0), you can do: - - settings = HandshakeSettings() - settings.minKeySize = 2048 - settings.cipherNames = ["aes256"] - settings.minVersion = (3,1) - 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: - - connection.handshakeClientSRP("alice", "abra123cadabra") - . - . - oldSession = connection.session - connection2.handshakeClientSRP("alice", "abra123cadabra", session= - oldSession) - -5 Step 3 - call a handshake function (server) ----------------------------------------------- -If you're a server, there's only one handshake function, but you can pass it -several different parameters, depending on which types of authentication -you're willing to perform. - -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 -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 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: - - 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. - -5 Step 4 - check the results ------------------------------ -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: - - 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. - -Example of handling a remote alert: - - try: - [...] - except TLSRemoteAlert, alert: - if alert.description == AlertDescription.unknown_srp_username: - 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. - -Client bad_record_mac: - - bad shared key password - -Client handshake failure: - - SRP parameters are not recognized by client - -Client user_canceled: - - The client might have returned None from an SRP callback. - -Client insufficient_security: - - SRP parameters are too small - -Client protocol_version: - - Client doesn't support the server's protocol version - -Server protocol_version: - - Server doesn't support the client's protocol version - -Server bad_record_mac: - - bad SRP username or password - -Server unknown_srp_username - - 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, -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 -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 -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. - - -6 Using TLS Lite with httplib -============================== -TLS Lite comes with an HTTPTLSConnection class that extends httplib to work -over SSL/TLS connections. Depending on how you construct it, it will do -different types of authentication. - - #No authentication whatsoever - h = HTTPTLSConnection("www.amazon.com", 443) - h.request("GET", "") - 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") - [...] - - #Mutually authenticate with SRP - h = HTTPTLSConnection("localhost", 443, - 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 -======================================== -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 -with the same parameters as HTTPTLSConnection (see previous section), and -behave similarly. - - #To connect to a POP3 server over SSL and display its fingerprint: - from tlslite.api import * - p = POP3_TLS("---------.net") - print p.sock.session.serverCertChain.getFingerprint() - [...] - - #To connect to an IMAP server once you know its fingerprint: - from tlslite.api import * - i = IMAP4_TLS("cyrus.andrew.cmu.edu", - x509Fingerprint="00c14371227b3b677ddb9c4901e6f2aee18d3e45") - [...] - - -9 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 -HTTPTLSConnection (see previous section), and behaves similarly. Depending -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.starttls(x509Fingerprint="7e39be84a2e3a7ad071752e3001d931bf82c32dc") - [...] - - -10 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 -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 - - httpd = MyHTTPServer(('localhost', 443), SimpleHTTPRequestHandler) - httpd.serve_forever() - - -11 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 -=========================== -TLS Lite is beta-quality code. It hasn't received much security analysis. -Use at your own risk. - - -14 History -=========== -0.3.8 - 2/21/2005 - - Added support for poplib, imaplib, and smtplib - - Added python 2.4 windows installer - - Fixed occassional timing problems with test suite -0.3.7 - 10/05/2004 - - Added support for Python 2.2 - - Cleaned up compatibility code, and docs, a bit -0.3.6 - 9/28/2004 - - Fixed script installation on UNIX - - Give better error message on old Python versions -0.3.5 - 9/16/2004 - - TLS 1.1 support - - os.urandom() support - - Fixed win32prng on some systems -0.3.4 - 9/12/2004 - - Updated for TLS/SRP draft 8 - - Bugfix: was setting _versioncheck on SRP 1st hello, causing problems - with GnuTLS (which was offering TLS 1.1) - - Removed _versioncheck checking, since it could cause interop problems - - Minor bugfix: when cryptlib_py and and cryptoIDlib present, cryptlib - was complaining about being initialized twice -0.3.3 - 6/10/2004 - - Updated for TLS/SRP draft 7 - - Updated test cryptoID cert chains for cryptoIDlib 0.3.1 -0.3.2 - 5/21/2004 - - fixed bug when handling multiple handshake messages per record (e.g. IIS) -0.3.1 - 4/21/2004 - - added xmlrpclib integration - - fixed hanging bug in Twisted integration - - fixed win32prng to work on a wider range of win32 sytems - - fixed import problem with cryptoIDlib - - fixed port allocation problem when test scripts are run on some UNIXes - - made tolerant of buggy IE sending wrong version in premaster secret -0.3.0 - 3/20/2004 - - added API docs thanks to epydoc - - added X.509 path validation via cryptlib - - much cleaning/tweaking/re-factoring/minor fixes -0.2.7 - 3/12/2004 - - changed Twisted error handling to use connectionLost() - - added ignoreAbruptClose -0.2.6 - 3/11/2004 - - added Twisted errorHandler - - added TLSAbruptCloseError - - added 'integration' subdirectory -0.2.5 - 3/10/2004 - - improved asynchronous support a bit - - added first-draft of Twisted support -0.2.4 - 3/5/2004 - - cleaned up asyncore support - - added proof-of-concept for Twisted -0.2.3 - 3/4/2004 - - added pycrypto RSA support - - added asyncore support -0.2.2 - 3/1/2004 - - added GMPY support - - added pycrypto support - - added support for PEM-encoded private keys, in pure python -0.2.1 - 2/23/2004 - - improved PRNG use (cryptlib, or /dev/random, or CryptoAPI) - - added RSA blinding, to avoid timing attacks - - don't install local copy of M2Crypto, too problematic -0.2.0 - 2/19/2004 - - changed VerifierDB to take per-user parameters - - renamed tls_lite -> tlslite -0.1.9 - 2/16/2004 - - added post-handshake 'Checker' - - made compatible with Python 2.2 - - made more forgiving of abrupt closure, since everyone does it: - if the socket is closed while sending/recv'ing close_notify, - just ignore it. -0.1.8 - 2/12/2004 - - TLSConnections now emulate sockets, including makefile() - - HTTPTLSConnection and TLSMixIn simplified as a result -0.1.7 - 2/11/2004 - - fixed httplib.HTTPTLSConnection with multiple requests - - fixed SocketServer to handle close_notify - - changed handshakeClientNoAuth() to ignore CertificateRequests - - changed handshakeClient() to ignore non-resumable session arguments -0.1.6 - 2/10/2004 - - fixed httplib support -0.1.5 - 2/09/2004 - - added support for httplib and SocketServer - - added support for SSLv3 - - added support for 3DES - - cleaned up read()/write() behavior - - improved HMAC speed -0.1.4 - 2/06/2004 - - fixed dumb bug in tls.py -0.1.3 - 2/05/2004 - - change read() to only return requested number of bytes - - added support for shared-key and in-memory databases - - added support for PEM-encoded X.509 certificates - - added support for SSLv2 ClientHello - - fixed shutdown/re-handshaking behavior - - cleaned up handling of missing_srp_username - - renamed readString()/writeString() -> read()/write() - - added documentation -0.1.2 - 2/04/2004 - - added clienttest/servertest functions - - improved OpenSSL cipher wrappers speed - - fixed server when it has a key, but client selects plain SRP - - fixed server to postpone errors until it has read client's messages - - fixed ServerHello to only include extension data if necessary -0.1.1 - 2/02/2004 - - fixed close_notify behavior - - fixed handling of empty application data packets - - fixed socket reads to not consume extra bytes - - 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/ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/chromium/third_party/tlslite/scripts/tls.py b/chromium/third_party/tlslite/scripts/tls.py index fa2c663f3b0..48035ce2cd1 100644..100755 --- a/chromium/third_party/tlslite/scripts/tls.py +++ b/chromium/third_party/tlslite/scripts/tls.py @@ -1,1074 +1,336 @@ -#! python - +#!/usr/bin/env python + +# Authors: +# Trevor Perrin +# Marcelo Fernandez - bugfix and NPN support +# Martin von Loewis - python 3 port +# +# See the LICENSE file for legal information regarding use of this file. +from __future__ import print_function import sys import os import os.path import socket -import thread import time -import httplib -import BaseHTTPServer -import SimpleHTTPServer - - +import getopt try: - from cryptoIDlib.api import * - cryptoIDlibLoaded = True -except: - cryptoIDlibLoaded = False + import httplib + from SocketServer import * + from BaseHTTPServer import * + from SimpleHTTPServer import * +except ImportError: + # Python 3.x + from http import client as httplib + from socketserver import * + from http.server import * if __name__ != "__main__": raise "This must be run as a command, not used as a module!" -#import tlslite -#from tlslite.constants import AlertDescription, Fault - -#from tlslite.utils.jython_compat import formatExceptionTrace -#from tlslite.X509 import X509, X509CertChain - from tlslite.api import * +from tlslite import __version__ -def parsePrivateKey(s): - try: - return parsePEMKey(s, private=True) - except Exception, e: - print e - return parseXMLKey(s, private=True) - - -def clientTest(address, dir): - - #Split address into hostname/port tuple - address = address.split(":") - if len(address)==1: - address.append("4443") - address = ( address[0], int(address[1]) ) - - def connect(): - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - if hasattr(sock, 'settimeout'): #It's a python 2.3 feature - sock.settimeout(5) - sock.connect(address) - c = TLSConnection(sock) - return c - - test = 0 - - badFault = False - - print "Test 1 - good shared key" - connection = connect() - connection.handshakeClientSharedKey("shared", "key") - connection.close() - connection.sock.close() - - print "Test 2 - shared key faults" - for fault in Fault.clientSharedKeyFaults + Fault.genericFaults: - connection = connect() - connection.fault = fault - try: - connection.handshakeClientSharedKey("shared", "key") - print " Good Fault %s" % (Fault.faultNames[fault]) - except TLSFaultError, e: - print " BAD FAULT %s: %s" % (Fault.faultNames[fault], str(e)) - badFault = True - connection.sock.close() - - print "Test 3 - good SRP" - connection = connect() - connection.handshakeClientSRP("test", "password") - connection.close() - - print "Test 4 - SRP faults" - for fault in Fault.clientSrpFaults + Fault.genericFaults: - connection = connect() - connection.fault = fault - try: - connection.handshakeClientSRP("test", "password") - print " Good Fault %s" % (Fault.faultNames[fault]) - except TLSFaultError, e: - print " BAD FAULT %s: %s" % (Fault.faultNames[fault], str(e)) - badFault = True - connection.sock.close() - - print "Test 5 - good SRP: unknown_srp_username idiom" - def srpCallback(): - return ("test", "password") - connection = connect() - connection.handshakeClientUnknown(srpCallback=srpCallback) - connection.close() - connection.sock.close() - - print "Test 6 - good SRP: with X.509 certificate" - connection = connect() - connection.handshakeClientSRP("test", "password") - assert(isinstance(connection.session.serverCertChain, X509CertChain)) - connection.close() - connection.sock.close() - - print "Test 7 - X.509 with SRP faults" - for fault in Fault.clientSrpFaults + Fault.genericFaults: - connection = connect() - connection.fault = fault - try: - connection.handshakeClientSRP("test", "password") - print " Good Fault %s" % (Fault.faultNames[fault]) - except TLSFaultError, e: - print " BAD FAULT %s: %s" % (Fault.faultNames[fault], str(e)) - badFault = True - connection.sock.close() - - if cryptoIDlibLoaded: - print "Test 8 - good SRP: with cryptoID certificate chain" - connection = connect() - connection.handshakeClientSRP("test", "password") - assert(isinstance(connection.session.serverCertChain, CertChain)) - if not (connection.session.serverCertChain.validate()): - print connection.session.serverCertChain.validate(listProblems=True) - - connection.close() - connection.sock.close() - - print "Test 9 - CryptoID with SRP faults" - for fault in Fault.clientSrpFaults + Fault.genericFaults: - connection = connect() - connection.fault = fault - try: - connection.handshakeClientSRP("test", "password") - print " Good Fault %s" % (Fault.faultNames[fault]) - except TLSFaultError, e: - print " BAD FAULT %s: %s" % (Fault.faultNames[fault], str(e)) - badFault = True - connection.sock.close() - - print "Test 10 - good X509" - connection = connect() - connection.handshakeClientCert() - assert(isinstance(connection.session.serverCertChain, X509CertChain)) - connection.close() - connection.sock.close() - - print "Test 10.a - good X509, SSLv3" - connection = connect() - settings = HandshakeSettings() - settings.minVersion = (3,0) - settings.maxVersion = (3,0) - connection.handshakeClientCert(settings=settings) - assert(isinstance(connection.session.serverCertChain, X509CertChain)) - connection.close() - connection.sock.close() - - print "Test 11 - X.509 faults" - for fault in Fault.clientNoAuthFaults + Fault.genericFaults: - connection = connect() - connection.fault = fault - try: - connection.handshakeClientCert() - print " Good Fault %s" % (Fault.faultNames[fault]) - except TLSFaultError, e: - print " BAD FAULT %s: %s" % (Fault.faultNames[fault], str(e)) - badFault = True - connection.sock.close() - - if cryptoIDlibLoaded: - print "Test 12 - good cryptoID" - connection = connect() - connection.handshakeClientCert() - assert(isinstance(connection.session.serverCertChain, CertChain)) - assert(connection.session.serverCertChain.validate()) - connection.close() - connection.sock.close() - - print "Test 13 - cryptoID faults" - for fault in Fault.clientNoAuthFaults + Fault.genericFaults: - connection = connect() - connection.fault = fault - try: - connection.handshakeClientCert() - print " Good Fault %s" % (Fault.faultNames[fault]) - except TLSFaultError, e: - print " BAD FAULT %s: %s" % (Fault.faultNames[fault], str(e)) - badFault = True - connection.sock.close() - - print "Test 14 - good mutual X509" - x509Cert = X509().parse(open(os.path.join(dir, "clientX509Cert.pem")).read()) - x509Chain = X509CertChain([x509Cert]) - s = open(os.path.join(dir, "clientX509Key.pem")).read() - x509Key = parsePEMKey(s, private=True) - - connection = connect() - connection.handshakeClientCert(x509Chain, x509Key) - assert(isinstance(connection.session.serverCertChain, X509CertChain)) - connection.close() - connection.sock.close() - - print "Test 14.a - good mutual X509, SSLv3" - connection = connect() - settings = HandshakeSettings() - settings.minVersion = (3,0) - settings.maxVersion = (3,0) - connection.handshakeClientCert(x509Chain, x509Key, settings=settings) - assert(isinstance(connection.session.serverCertChain, X509CertChain)) - connection.close() - connection.sock.close() - - print "Test 15 - mutual X.509 faults" - for fault in Fault.clientCertFaults + Fault.genericFaults: - connection = connect() - connection.fault = fault - try: - connection.handshakeClientCert(x509Chain, x509Key) - print " Good Fault %s" % (Fault.faultNames[fault]) - except TLSFaultError, e: - print " BAD FAULT %s: %s" % (Fault.faultNames[fault], str(e)) - badFault = True - connection.sock.close() - - if cryptoIDlibLoaded: - print "Test 16 - good mutual cryptoID" - cryptoIDChain = CertChain().parse(open(os.path.join(dir, "serverCryptoIDChain.xml"), "r").read()) - cryptoIDKey = parseXMLKey(open(os.path.join(dir, "serverCryptoIDKey.xml"), "r").read(), private=True) - - connection = connect() - connection.handshakeClientCert(cryptoIDChain, cryptoIDKey) - assert(isinstance(connection.session.serverCertChain, CertChain)) - assert(connection.session.serverCertChain.validate()) - connection.close() - connection.sock.close() - - print "Test 17 - mutual cryptoID faults" - for fault in Fault.clientCertFaults + Fault.genericFaults: - connection = connect() - connection.fault = fault - try: - connection.handshakeClientCert(cryptoIDChain, cryptoIDKey) - print " Good Fault %s" % (Fault.faultNames[fault]) - except TLSFaultError, e: - print " BAD FAULT %s: %s" % (Fault.faultNames[fault], str(e)) - badFault = True - connection.sock.close() - - print "Test 18 - good SRP, prepare to resume..." - connection = connect() - connection.handshakeClientSRP("test", "password") - connection.close() - connection.sock.close() - session = connection.session - - print "Test 19 - resumption" - connection = connect() - connection.handshakeClientSRP("test", "garbage", session=session) - #Don't close! -- see below - - print "Test 20 - invalidated resumption" - connection.sock.close() #Close the socket without a close_notify! - connection = connect() - try: - connection.handshakeClientSRP("test", "garbage", session=session) - assert() - except TLSRemoteAlert, alert: - if alert.description != AlertDescription.bad_record_mac: - raise - connection.sock.close() - - print "Test 21 - HTTPS test X.509" - address = address[0], address[1]+1 - if hasattr(socket, "timeout"): - timeoutEx = socket.timeout +try: + from tack.structures.Tack import Tack + +except ImportError: + pass + +def printUsage(s=None): + if s: + print("ERROR: %s" % s) + + print("") + print("Version: %s" % __version__) + print("") + print("RNG: %s" % prngName) + print("") + print("Modules:") + if tackpyLoaded: + print(" tackpy : Loaded") else: - timeoutEx = socket.error - while 1: - try: - time.sleep(2) - htmlBody = open(os.path.join(dir, "index.html")).read() - fingerprint = None - for y in range(2): - h = HTTPTLSConnection(\ - address[0], address[1], x509Fingerprint=fingerprint) - for x in range(3): - h.request("GET", "/index.html") - r = h.getresponse() - assert(r.status == 200) - s = r.read() - assert(s == htmlBody) - fingerprint = h.tlsSession.serverCertChain.getFingerprint() - assert(fingerprint) - time.sleep(2) - break - except timeoutEx: - print "timeout, retrying..." - pass - - if cryptoIDlibLoaded: - print "Test 21a - HTTPS test SRP+cryptoID" - address = address[0], address[1]+1 - if hasattr(socket, "timeout"): - timeoutEx = socket.timeout - else: - timeoutEx = socket.error - while 1: - try: - time.sleep(2) #Time to generate key and cryptoID - htmlBody = open(os.path.join(dir, "index.html")).read() - fingerprint = None - protocol = None - for y in range(2): - h = HTTPTLSConnection(\ - address[0], address[1], - username="test", password="password", - cryptoID=fingerprint, protocol=protocol) - for x in range(3): - h.request("GET", "/index.html") - r = h.getresponse() - assert(r.status == 200) - s = r.read() - assert(s == htmlBody) - fingerprint = h.tlsSession.serverCertChain.cryptoID - assert(fingerprint) - protocol = "urn:whatever" - time.sleep(2) - break - except timeoutEx: - print "timeout, retrying..." - pass - - address = address[0], address[1]+1 - - implementations = [] - if cryptlibpyLoaded: - implementations.append("cryptlib") + print(" tackpy : Not Loaded") if m2cryptoLoaded: - implementations.append("openssl") + print(" M2Crypto : Loaded") + else: + print(" M2Crypto : Not Loaded") if pycryptoLoaded: - implementations.append("pycrypto") - implementations.append("python") - - print "Test 22 - different ciphers" - for implementation in implementations: - for cipher in ["aes128", "aes256", "rc4"]: - - print "Test 22:", - connection = connect() - - settings = HandshakeSettings() - settings.cipherNames = [cipher] - settings.cipherImplementations = [implementation, "python"] - connection.handshakeClientSharedKey("shared", "key", settings=settings) - print ("%s %s" % (connection.getCipherName(), connection.getCipherImplementation())) - - connection.write("hello") - h = connection.read(min=5, max=5) - assert(h == "hello") - connection.close() - connection.sock.close() - - print "Test 23 - throughput test" - for implementation in implementations: - for cipher in ["aes128", "aes256", "3des", "rc4"]: - if cipher == "3des" and implementation not in ("openssl", "cryptlib", "pycrypto"): - continue - - print "Test 23:", - connection = connect() - - settings = HandshakeSettings() - settings.cipherNames = [cipher] - settings.cipherImplementations = [implementation, "python"] - connection.handshakeClientSharedKey("shared", "key", settings=settings) - print ("%s %s:" % (connection.getCipherName(), connection.getCipherImplementation())), - - startTime = time.clock() - connection.write("hello"*10000) - h = connection.read(min=50000, max=50000) - stopTime = time.clock() - print "100K exchanged at rate of %d bytes/sec" % int(100000/(stopTime-startTime)) - - assert(h == "hello"*10000) - connection.close() - connection.sock.close() - - print "Test 24 - Internet servers test" - try: - i = IMAP4_TLS("cyrus.andrew.cmu.edu") - i.login("anonymous", "anonymous@anonymous.net") - i.logout() - print "Test 24: IMAP4 good" - p = POP3_TLS("pop.gmail.com") - p.quit() - print "Test 24: POP3 good" - except socket.error, e: - print "Non-critical error: socket error trying to reach internet server: ", e - - if not badFault: - print "Test succeeded" + print(" pycrypto : Loaded") else: - print "Test failed" - - -def serverTest(address, dir): + print(" pycrypto : Not Loaded") + if gmpyLoaded: + print(" GMPY : Loaded") + else: + print(" GMPY : Not Loaded") + + print("") + print("""Commands: + + server + [-k KEY] [-c CERT] [-t TACK] [-v VERIFIERDB] [-d DIR] + [--reqcert] HOST:PORT + + client + [-k KEY] [-c CERT] [-u USER] [-p PASS] + HOST:PORT +""") + sys.exit(-1) + +def printError(s): + """Print error message and exit""" + sys.stderr.write("ERROR: %s\n" % s) + sys.exit(-1) + + +def handleArgs(argv, argString, flagsList=[]): + # Convert to getopt argstring format: + # Add ":" after each arg, ie "abc" -> "a:b:c:" + getOptArgString = ":".join(argString) + ":" + try: + opts, argv = getopt.getopt(argv, getOptArgString, flagsList) + except getopt.GetoptError as e: + printError(e) + # Default values if arg not present + privateKey = None + certChain = None + username = None + password = None + tacks = None + verifierDB = None + reqCert = False + directory = None + + for opt, arg in opts: + if opt == "-k": + s = open(arg, "rb").read() + privateKey = parsePEMKey(s, private=True) + elif opt == "-c": + s = open(arg, "rb").read() + x509 = X509() + x509.parse(s) + certChain = X509CertChain([x509]) + elif opt == "-u": + username = arg + elif opt == "-p": + password = arg + elif opt == "-t": + if tackpyLoaded: + s = open(arg, "rU").read() + tacks = Tack.createFromPemList(s) + elif opt == "-v": + verifierDB = VerifierDB(arg) + verifierDB.open() + elif opt == "-d": + directory = arg + elif opt == "--reqcert": + reqCert = True + else: + assert(False) + + if not argv: + printError("Missing address") + if len(argv)>1: + printError("Too many arguments") #Split address into hostname/port tuple + address = argv[0] address = address.split(":") - if len(address)==1: - address.append("4443") + if len(address) != 2: + raise SyntaxError("Must specify <host>:<port>") address = ( address[0], int(address[1]) ) - #Connect to server - lsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - lsock.bind(address) - lsock.listen(5) - - def connect(): - return TLSConnection(lsock.accept()[0]) - - print "Test 1 - good shared key" - sharedKeyDB = SharedKeyDB() - sharedKeyDB["shared"] = "key" - sharedKeyDB["shared2"] = "key2" - connection = connect() - connection.handshakeServer(sharedKeyDB=sharedKeyDB) - connection.close() - connection.sock.close() - - print "Test 2 - shared key faults" - for fault in Fault.clientSharedKeyFaults + Fault.genericFaults: - connection = connect() - connection.fault = fault - try: - connection.handshakeServer(sharedKeyDB=sharedKeyDB) - assert() - except: - pass - connection.sock.close() - - print "Test 3 - good SRP" - #verifierDB = tlslite.VerifierDB(os.path.join(dir, "verifierDB")) - #verifierDB.open() - verifierDB = VerifierDB() - verifierDB.create() - entry = VerifierDB.makeVerifier("test", "password", 1536) - verifierDB["test"] = entry - - connection = connect() - connection.handshakeServer(verifierDB=verifierDB) - connection.close() - connection.sock.close() - - print "Test 4 - SRP faults" - for fault in Fault.clientSrpFaults + Fault.genericFaults: - connection = connect() - connection.fault = fault - try: - connection.handshakeServer(verifierDB=verifierDB) - assert() - except: - pass - connection.sock.close() - - print "Test 5 - good SRP: unknown_srp_username idiom" - connection = connect() - connection.handshakeServer(verifierDB=verifierDB) - connection.close() - connection.sock.close() - - print "Test 6 - good SRP: with X.509 cert" - x509Cert = X509().parse(open(os.path.join(dir, "serverX509Cert.pem")).read()) - x509Chain = X509CertChain([x509Cert]) - s = open(os.path.join(dir, "serverX509Key.pem")).read() - x509Key = parsePEMKey(s, private=True) - - connection = connect() - connection.handshakeServer(verifierDB=verifierDB, \ - certChain=x509Chain, privateKey=x509Key) - connection.close() - connection.sock.close() - - print "Test 7 - X.509 with SRP faults" - for fault in Fault.clientSrpFaults + Fault.genericFaults: - connection = connect() - connection.fault = fault - try: - connection.handshakeServer(verifierDB=verifierDB, \ - certChain=x509Chain, privateKey=x509Key) - assert() - except: - pass - connection.sock.close() - - if cryptoIDlibLoaded: - print "Test 8 - good SRP: with cryptoID certs" - cryptoIDChain = CertChain().parse(open(os.path.join(dir, "serverCryptoIDChain.xml"), "r").read()) - cryptoIDKey = parseXMLKey(open(os.path.join(dir, "serverCryptoIDKey.xml"), "r").read(), private=True) - connection = connect() - connection.handshakeServer(verifierDB=verifierDB, \ - certChain=cryptoIDChain, privateKey=cryptoIDKey) - connection.close() - connection.sock.close() - - print "Test 9 - cryptoID with SRP faults" - for fault in Fault.clientSrpFaults + Fault.genericFaults: - connection = connect() - connection.fault = fault - try: - connection.handshakeServer(verifierDB=verifierDB, \ - certChain=cryptoIDChain, privateKey=cryptoIDKey) - assert() - except: - pass - connection.sock.close() - - print "Test 10 - good X.509" - connection = connect() - connection.handshakeServer(certChain=x509Chain, privateKey=x509Key) - connection.close() - connection.sock.close() - - print "Test 10.a - good X.509, SSL v3" - connection = connect() - settings = HandshakeSettings() - settings.minVersion = (3,0) - settings.maxVersion = (3,0) - connection.handshakeServer(certChain=x509Chain, privateKey=x509Key, settings=settings) - connection.close() - connection.sock.close() - - print "Test 11 - X.509 faults" - for fault in Fault.clientNoAuthFaults + Fault.genericFaults: - connection = connect() - connection.fault = fault - try: - connection.handshakeServer(certChain=x509Chain, privateKey=x509Key) - assert() - except: - pass - connection.sock.close() - - if cryptoIDlibLoaded: - print "Test 12 - good cryptoID" - connection = connect() - connection.handshakeServer(certChain=cryptoIDChain, privateKey=cryptoIDKey) - connection.close() - connection.sock.close() - - print "Test 13 - cryptoID faults" - for fault in Fault.clientNoAuthFaults + Fault.genericFaults: - connection = connect() - connection.fault = fault - try: - connection.handshakeServer(certChain=cryptoIDChain, privateKey=cryptoIDKey) - assert() - except: - pass - connection.sock.close() - - print "Test 14 - good mutual X.509" - connection = connect() - connection.handshakeServer(certChain=x509Chain, privateKey=x509Key, reqCert=True) - assert(isinstance(connection.session.serverCertChain, X509CertChain)) - connection.close() - connection.sock.close() + # Populate the return list + retList = [address] + if "k" in argString: + retList.append(privateKey) + if "c" in argString: + retList.append(certChain) + if "u" in argString: + retList.append(username) + if "p" in argString: + retList.append(password) + if "t" in argString: + retList.append(tacks) + if "v" in argString: + retList.append(verifierDB) + if "d" in argString: + retList.append(directory) + if "reqcert" in flagsList: + retList.append(reqCert) + return retList + + +def printGoodConnection(connection, seconds): + print(" Handshake time: %.3f seconds" % seconds) + print(" Version: %s" % connection.getVersionName()) + print(" Cipher: %s %s" % (connection.getCipherName(), + connection.getCipherImplementation())) + if connection.session.srpUsername: + print(" Client SRP username: %s" % connection.session.srpUsername) + if connection.session.clientCertChain: + print(" Client X.509 SHA1 fingerprint: %s" % + connection.session.clientCertChain.getFingerprint()) + if connection.session.serverCertChain: + print(" Server X.509 SHA1 fingerprint: %s" % + connection.session.serverCertChain.getFingerprint()) + if connection.session.serverName: + print(" SNI: %s" % connection.session.serverName) + if connection.session.tackExt: + if connection.session.tackInHelloExt: + emptyStr = "\n (via TLS Extension)" + else: + emptyStr = "\n (via TACK Certificate)" + print(" TACK: %s" % emptyStr) + print(str(connection.session.tackExt)) + print(" Next-Protocol Negotiated: %s" % connection.next_proto) + + +def clientCmd(argv): + (address, privateKey, certChain, username, password) = \ + handleArgs(argv, "kcup") + + if (certChain and not privateKey) or (not certChain and privateKey): + raise SyntaxError("Must specify CERT and KEY together") + if (username and not password) or (not username and password): + raise SyntaxError("Must specify USER with PASS") + if certChain and username: + raise SyntaxError("Can use SRP or client cert for auth, not both") - print "Test 14a - good mutual X.509, SSLv3" - connection = connect() + #Connect to server + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.settimeout(5) + sock.connect(address) + connection = TLSConnection(sock) + settings = HandshakeSettings() - settings.minVersion = (3,0) - settings.maxVersion = (3,0) - connection.handshakeServer(certChain=x509Chain, privateKey=x509Key, reqCert=True, settings=settings) - assert(isinstance(connection.session.serverCertChain, X509CertChain)) - connection.close() - connection.sock.close() - - print "Test 15 - mutual X.509 faults" - for fault in Fault.clientCertFaults + Fault.genericFaults: - connection = connect() - connection.fault = fault - try: - connection.handshakeServer(certChain=x509Chain, privateKey=x509Key, reqCert=True) - assert() - except: - pass - connection.sock.close() - - if cryptoIDlibLoaded: - print "Test 16 - good mutual cryptoID" - connection = connect() - connection.handshakeServer(certChain=cryptoIDChain, privateKey=cryptoIDKey, reqCert=True) - assert(isinstance(connection.session.serverCertChain, CertChain)) - assert(connection.session.serverCertChain.validate()) - connection.close() - connection.sock.close() - - print "Test 17 - mutual cryptoID faults" - for fault in Fault.clientCertFaults + Fault.genericFaults: - connection = connect() - connection.fault = fault - try: - connection.handshakeServer(certChain=cryptoIDChain, privateKey=cryptoIDKey, reqCert=True) - assert() - except: - pass - connection.sock.close() - - print "Test 18 - good SRP, prepare to resume" - sessionCache = SessionCache() - connection = connect() - connection.handshakeServer(verifierDB=verifierDB, sessionCache=sessionCache) - connection.close() - connection.sock.close() - - print "Test 19 - resumption" - connection = connect() - connection.handshakeServer(verifierDB=verifierDB, sessionCache=sessionCache) - #Don't close! -- see next test - - print "Test 20 - invalidated resumption" - try: - connection.read(min=1, max=1) - assert() #Client is going to close the socket without a close_notify - except TLSAbruptCloseError, e: - pass - connection = connect() + settings.useExperimentalTackExtension = True + try: - connection.handshakeServer(verifierDB=verifierDB, sessionCache=sessionCache) - except TLSLocalAlert, alert: - if alert.description != AlertDescription.bad_record_mac: + start = time.clock() + if username and password: + connection.handshakeClientSRP(username, password, + settings=settings, serverName=address[0]) + else: + connection.handshakeClientCert(certChain, privateKey, + settings=settings, serverName=address[0]) + stop = time.clock() + print("Handshake success") + except TLSLocalAlert as a: + if a.description == AlertDescription.user_canceled: + print(str(a)) + else: raise - connection.sock.close() - - print "Test 21 - HTTPS test X.509" - - #Close the current listening socket - lsock.close() - - #Create and run an HTTP Server using TLSSocketServerMixIn - class MyHTTPServer(TLSSocketServerMixIn, - BaseHTTPServer.HTTPServer): - def handshake(self, tlsConnection): - tlsConnection.handshakeServer(certChain=x509Chain, privateKey=x509Key) - return True - cd = os.getcwd() - os.chdir(dir) - address = address[0], address[1]+1 - httpd = MyHTTPServer(address, SimpleHTTPServer.SimpleHTTPRequestHandler) - for x in range(6): - httpd.handle_request() - httpd.server_close() - cd = os.chdir(cd) - - if cryptoIDlibLoaded: - print "Test 21a - HTTPS test SRP+cryptoID" - - #Create and run an HTTP Server using TLSSocketServerMixIn - class MyHTTPServer(TLSSocketServerMixIn, - BaseHTTPServer.HTTPServer): - def handshake(self, tlsConnection): - tlsConnection.handshakeServer(certChain=cryptoIDChain, privateKey=cryptoIDKey, - verifierDB=verifierDB) - return True - cd = os.getcwd() - os.chdir(dir) - address = address[0], address[1]+1 - httpd = MyHTTPServer(address, SimpleHTTPServer.SimpleHTTPRequestHandler) - for x in range(6): - httpd.handle_request() - httpd.server_close() - cd = os.chdir(cd) - - #Re-connect the listening socket - lsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - address = address[0], address[1]+1 - lsock.bind(address) - lsock.listen(5) - - def connect(): - return TLSConnection(lsock.accept()[0]) - - implementations = [] - if cryptlibpyLoaded: - implementations.append("cryptlib") - if m2cryptoLoaded: - implementations.append("openssl") - if pycryptoLoaded: - implementations.append("pycrypto") - implementations.append("python") - - print "Test 22 - different ciphers" - for implementation in ["python"] * len(implementations): - for cipher in ["aes128", "aes256", "rc4"]: - - print "Test 22:", - connection = connect() - - settings = HandshakeSettings() - settings.cipherNames = [cipher] - settings.cipherImplementations = [implementation, "python"] - - connection.handshakeServer(sharedKeyDB=sharedKeyDB, settings=settings) - print connection.getCipherName(), connection.getCipherImplementation() - h = connection.read(min=5, max=5) - assert(h == "hello") - connection.write(h) - connection.close() - connection.sock.close() - - print "Test 23 - throughput test" - for implementation in implementations: - for cipher in ["aes128", "aes256", "3des", "rc4"]: - if cipher == "3des" and implementation not in ("openssl", "cryptlib", "pycrypto"): - continue - - print "Test 23:", - connection = connect() - - settings = HandshakeSettings() - settings.cipherNames = [cipher] - settings.cipherImplementations = [implementation, "python"] - - connection.handshakeServer(sharedKeyDB=sharedKeyDB, settings=settings) - print connection.getCipherName(), connection.getCipherImplementation() - h = connection.read(min=50000, max=50000) - assert(h == "hello"*10000) - connection.write(h) - connection.close() - connection.sock.close() - - print "Test succeeded" - - - - - - - - - - - - -if len(sys.argv) == 1 or (len(sys.argv)==2 and sys.argv[1].lower().endswith("help")): - print "" - print "Version: 0.3.8" - print "" - print "RNG: %s" % prngName - print "" - print "Modules:" - if cryptlibpyLoaded: - print " cryptlib_py : Loaded" - else: - print " cryptlib_py : Not Loaded" - if m2cryptoLoaded: - print " M2Crypto : Loaded" - else: - print " M2Crypto : Not Loaded" - if pycryptoLoaded: - print " pycrypto : Loaded" - else: - print " pycrypto : Not Loaded" - if gmpyLoaded: - print " GMPY : Loaded" - else: - print " GMPY : Not Loaded" - if cryptoIDlibLoaded: - print " cryptoIDlib : Loaded" - else: - print " cryptoIDlib : Not Loaded" - print "" - print "Commands:" - print "" - print " clientcert <server> [<chain> <key>]" - print " clientsharedkey <server> <user> <pass>" - print " clientsrp <server> <user> <pass>" - print " clienttest <server> <dir>" - print "" - print " serversrp <server> <verifierDB>" - print " servercert <server> <chain> <key> [req]" - print " serversrpcert <server> <verifierDB> <chain> <key>" - print " serversharedkey <server> <sharedkeyDB>" - print " servertest <server> <dir>" - sys.exit() - -cmd = sys.argv[1].lower() - -class Args: - def __init__(self, argv): - self.argv = argv - def get(self, index): - if len(self.argv)<=index: - raise SyntaxError("Not enough arguments") - return self.argv[index] - def getLast(self, index): - if len(self.argv)>index+1: - raise SyntaxError("Too many arguments") - return self.get(index) - -args = Args(sys.argv) - -def reformatDocString(s): - lines = s.splitlines() - newLines = [] - for line in lines: - newLines.append(" " + line.strip()) - return "\n".join(newLines) - -try: - if cmd == "clienttest": - address = args.get(2) - dir = args.getLast(3) - clientTest(address, dir) - sys.exit() - - elif cmd.startswith("client"): - address = args.get(2) - - #Split address into hostname/port tuple - address = address.split(":") - if len(address)==1: - address.append("4443") - address = ( address[0], int(address[1]) ) - - def connect(): - #Connect to server - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - if hasattr(sock, "settimeout"): - sock.settimeout(5) - sock.connect(address) - - #Instantiate TLSConnections - return TLSConnection(sock) - - try: - if cmd == "clientsrp": - username = args.get(3) - password = args.getLast(4) - connection = connect() - start = time.clock() - connection.handshakeClientSRP(username, password) - elif cmd == "clientsharedkey": - username = args.get(3) - password = args.getLast(4) - connection = connect() - start = time.clock() - connection.handshakeClientSharedKey(username, password) - elif cmd == "clientcert": - certChain = None - privateKey = None - if len(sys.argv) > 3: - certFilename = args.get(3) - keyFilename = args.getLast(4) - - s1 = open(certFilename, "rb").read() - s2 = open(keyFilename, "rb").read() - - #Try to create cryptoID cert chain - if cryptoIDlibLoaded: - try: - certChain = CertChain().parse(s1) - privateKey = parsePrivateKey(s2) - except: - certChain = None - privateKey = None - - #Try to create X.509 cert chain - if not certChain: - x509 = X509() - x509.parse(s1) - certChain = X509CertChain([x509]) - privateKey = parsePrivateKey(s2) - - connection = connect() - start = time.clock() - connection.handshakeClientCert(certChain, privateKey) - else: - raise SyntaxError("Unknown command") - - except TLSLocalAlert, a: - if a.description == AlertDescription.bad_record_mac: - if cmd == "clientsharedkey": - print "Bad sharedkey password" - else: - raise - elif a.description == AlertDescription.user_canceled: - print str(a) + sys.exit(-1) + except TLSRemoteAlert as a: + if a.description == AlertDescription.unknown_psk_identity: + if username: + print("Unknown username") else: raise - sys.exit() - except TLSRemoteAlert, a: - if a.description == AlertDescription.unknown_srp_username: - if cmd == "clientsrp": - print "Unknown username" - else: - raise - elif a.description == AlertDescription.bad_record_mac: - if cmd == "clientsrp": - print "Bad username or password" - else: - raise - elif a.description == AlertDescription.handshake_failure: - print "Unable to negotiate mutually acceptable parameters" + elif a.description == AlertDescription.bad_record_mac: + if username: + print("Bad username or password") else: raise - sys.exit() - - stop = time.clock() - print "Handshake success" - print " Handshake time: %.4f seconds" % (stop - start) - print " Version: %s.%s" % connection.version - print " Cipher: %s %s" % (connection.getCipherName(), connection.getCipherImplementation()) - if connection.session.srpUsername: - print " Client SRP username: %s" % connection.session.srpUsername - if connection.session.sharedKeyUsername: - print " Client shared key username: %s" % connection.session.sharedKeyUsername - if connection.session.clientCertChain: - print " Client fingerprint: %s" % connection.session.clientCertChain.getFingerprint() - if connection.session.serverCertChain: - print " Server fingerprint: %s" % connection.session.serverCertChain.getFingerprint() - connection.close() - connection.sock.close() - - elif cmd.startswith("server"): - address = args.get(2) - - #Split address into hostname/port tuple - address = address.split(":") - if len(address)==1: - address.append("4443") - address = ( address[0], int(address[1]) ) - - verifierDBFilename = None - sharedKeyDBFilename = None - certFilename = None - keyFilename = None - sharedKeyDB = None - reqCert = False - - if cmd == "serversrp": - verifierDBFilename = args.getLast(3) - elif cmd == "servercert": - certFilename = args.get(3) - keyFilename = args.get(4) - if len(sys.argv)>=6: - req = args.getLast(5) - if req.lower() != "req": - raise SyntaxError() - reqCert = True - elif cmd == "serversrpcert": - verifierDBFilename = args.get(3) - certFilename = args.get(4) - keyFilename = args.getLast(5) - elif cmd == "serversharedkey": - sharedKeyDBFilename = args.getLast(3) - elif cmd == "servertest": - address = args.get(2) - dir = args.getLast(3) - serverTest(address, dir) - sys.exit() - - verifierDB = None - if verifierDBFilename: - verifierDB = VerifierDB(verifierDBFilename) - verifierDB.open() - - sharedKeyDB = None - if sharedKeyDBFilename: - sharedKeyDB = SharedKeyDB(sharedKeyDBFilename) - sharedKeyDB.open() - - certChain = None - privateKey = None - if certFilename: - s1 = open(certFilename, "rb").read() - s2 = open(keyFilename, "rb").read() - - #Try to create cryptoID cert chain - if cryptoIDlibLoaded: - try: - certChain = CertChain().parse(s1) - privateKey = parsePrivateKey(s2) - except: - certChain = None - privateKey = None + elif a.description == AlertDescription.handshake_failure: + print("Unable to negotiate mutually acceptable parameters") + else: + raise + sys.exit(-1) + printGoodConnection(connection, stop-start) + connection.close() - #Try to create X.509 cert chain - if not certChain: - x509 = X509() - x509.parse(s1) - certChain = X509CertChain([x509]) - privateKey = parsePrivateKey(s2) +def serverCmd(argv): + (address, privateKey, certChain, tacks, + verifierDB, directory, reqCert) = handleArgs(argv, "kctbvd", ["reqcert"]) + + + if (certChain and not privateKey) or (not certChain and privateKey): + raise SyntaxError("Must specify CERT and KEY together") + if tacks and not certChain: + raise SyntaxError("Must specify CERT with Tacks") + + print("I am an HTTPS test server, I will listen on %s:%d" % + (address[0], address[1])) + if directory: + os.chdir(directory) + print("Serving files from %s" % os.getcwd()) + + if certChain and privateKey: + print("Using certificate and private key...") + if verifierDB: + print("Using verifier DB...") + if tacks: + print("Using Tacks...") + + ############# + sessionCache = SessionCache() + class MyHTTPServer(ThreadingMixIn, TLSSocketServerMixIn, HTTPServer): + def handshake(self, connection): + print("About to handshake...") + activationFlags = 0 + if tacks: + if len(tacks) == 1: + activationFlags = 1 + elif len(tacks) == 2: + activationFlags = 3 - #Create handler function - performs handshake, then echos all bytes received - def handler(sock): try: - connection = TLSConnection(sock) + start = time.clock() settings = HandshakeSettings() - connection.handshakeServer(sharedKeyDB=sharedKeyDB, verifierDB=verifierDB, \ - certChain=certChain, privateKey=privateKey, \ - reqCert=reqCert, settings=settings) - print "Handshake success" - print " Version: %s.%s" % connection.version - print " Cipher: %s %s" % (connection.getCipherName(), connection.getCipherImplementation()) - if connection.session.srpUsername: - print " Client SRP username: %s" % connection.session.srpUsername - if connection.session.sharedKeyUsername: - print " Client shared key username: %s" % connection.session.sharedKeyUsername - if connection.session.clientCertChain: - print " Client fingerprint: %s" % connection.session.clientCertChain.getFingerprint() - if connection.session.serverCertChain: - print " Server fingerprint: %s" % connection.session.serverCertChain.getFingerprint() - - s = "" - while 1: - newS = connection.read() - if not newS: - break - s += newS - if s[-1]=='\n': - connection.write(s) - s = "" - except TLSLocalAlert, a: - if a.description == AlertDescription.unknown_srp_username: - print "Unknown SRP username" - elif a.description == AlertDescription.bad_record_mac: - if cmd == "serversrp" or cmd == "serversrpcert": - print "Bad SRP password for:", connection.allegedSrpUsername - else: - raise - elif a.description == AlertDescription.handshake_failure: - print "Unable to negotiate mutually acceptable parameters" + settings.useExperimentalTackExtension=True + connection.handshakeServer(certChain=certChain, + privateKey=privateKey, + verifierDB=verifierDB, + tacks=tacks, + activationFlags=activationFlags, + sessionCache=sessionCache, + settings=settings, + nextProtos=[b"http/1.1"]) + # As an example (does not work here): + #nextProtos=[b"spdy/3", b"spdy/2", b"http/1.1"]) + stop = time.clock() + except TLSRemoteAlert as a: + if a.description == AlertDescription.user_canceled: + print(str(a)) + return False else: raise - except TLSRemoteAlert, a: - if a.description == AlertDescription.bad_record_mac: - if cmd == "serversharedkey": - print "Bad sharedkey password for:", connection.allegedSharedKeyUsername + except TLSLocalAlert as a: + if a.description == AlertDescription.unknown_psk_identity: + if username: + print("Unknown username") + return False + else: + raise + elif a.description == AlertDescription.bad_record_mac: + if username: + print("Bad username or password") + return False else: raise - elif a.description == AlertDescription.user_canceled: - print "Handshake cancelled" elif a.description == AlertDescription.handshake_failure: - print "Unable to negotiate mutually acceptable parameters" - elif a.description == AlertDescription.close_notify: - pass + print("Unable to negotiate mutually acceptable parameters") + return False else: raise - - #Run multi-threaded server - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sock.bind(address) - sock.listen(5) - while 1: - (newsock, cliAddress) = sock.accept() - thread.start_new_thread(handler, (newsock,)) - - + + connection.ignoreAbruptClose = True + printGoodConnection(connection, stop-start) + return True + + httpd = MyHTTPServer(address, SimpleHTTPRequestHandler) + httpd.serve_forever() + + +if __name__ == '__main__': + if len(sys.argv) < 2: + printUsage("Missing command") + elif sys.argv[1] == "client"[:len(sys.argv[1])]: + clientCmd(sys.argv[2:]) + elif sys.argv[1] == "server"[:len(sys.argv[1])]: + serverCmd(sys.argv[2:]) else: - print "Bad command: '%s'" % cmd -except TLSRemoteAlert, a: - print str(a) - raise - - - - + printUsage("Unknown command: %s" % sys.argv[1]) diff --git a/chromium/third_party/tlslite/scripts/tlsdb.py b/chromium/third_party/tlslite/scripts/tlsdb.py index bdd524e6417..476d61899f6 100644..100755 --- a/chromium/third_party/tlslite/scripts/tlsdb.py +++ b/chromium/third_party/tlslite/scripts/tlsdb.py @@ -1,61 +1,52 @@ -#! python +#!/usr/bin/env python +# Authors: +# Trevor Perrin +# Martin von Loewis - python 3 port +# +# See the LICENSE file for legal information regarding use of this file. + +from __future__ import print_function import sys import os import socket -import thread import math -try: - import cryptoIDlib - cryptoIDlibLoaded = True -except: - cryptoIDlibLoaded = False - - if __name__ != "__main__": raise "This must be run as a command, not used as a module!" -from tlslite.api import * +from tlslite import * +from tlslite import __version__ if len(sys.argv) == 1 or (len(sys.argv)==2 and sys.argv[1].lower().endswith("help")): - print "" - print "Version: 0.3.8" - print "" - print "RNG: %s" % prngName - print "" - print "Modules:" - if cryptlibpyLoaded: - print " cryptlib_py : Loaded" - else: - print " cryptlib_py : Not Loaded" + print("") + print("Version: %s" % __version__) + print("") + print("RNG: %s" % prngName) + print("") + print("Modules:") if m2cryptoLoaded: - print " M2Crypto : Loaded" + print(" M2Crypto : Loaded") else: - print " M2Crypto : Not Loaded" + print(" M2Crypto : Not Loaded") if pycryptoLoaded: - print " pycrypto : Loaded" + print(" pycrypto : Loaded") else: - print " pycrypto : Not Loaded" + print(" pycrypto : Not Loaded") if gmpyLoaded: - print " GMPY : Loaded" + print(" GMPY : Loaded") else: - print " GMPY : Not Loaded" - if cryptoIDlibLoaded: - print " cryptoIDlib : Loaded" - else: - print " cryptoIDlib : Not Loaded" - print "" - print "Commands:" - print "" - print " createsrp <db>" - print " createsharedkey <db>" - print "" - print " add <db> <user> <pass> [<bits>]" - print " del <db> <user>" - print " check <db> <user> [<pass>]" - print " list <db>" + print(" GMPY : Not Loaded") + print("") + print("Commands:") + print("") + print(" createsrp <db>") + print("") + print(" add <db> <user> <pass> [<bits>]") + print(" del <db> <user>") + print(" check <db> <user> [<pass>]") + print(" list <db>") sys.exit() cmd = sys.argv[1].lower() @@ -85,9 +76,9 @@ try: if cmd == "help": command = args.getLast(2).lower() if command == "valid": - print "" + print("") else: - print "Bad command: '%s'" % command + print("Bad command: '%s'" % command) elif cmd == "createsrp": dbName = args.get(2) @@ -95,46 +86,25 @@ try: db = VerifierDB(dbName) db.create() - elif cmd == "createsharedkey": - dbName = args.getLast(2) - - db = SharedKeyDB(dbName) - db.create() - elif cmd == "add": dbName = args.get(2) username = args.get(3) password = args.get(4) - try: - db = VerifierDB(dbName) - db.open() - if username in db: - print "User already in database!" - sys.exit() - bits = int(args.getLast(5)) - N, g, salt, verifier = VerifierDB.makeVerifier(username, password, bits) - db[username] = N, g, salt, verifier - except ValueError: - db = SharedKeyDB(dbName) - db.open() - if username in db: - print "User already in database!" - sys.exit() - args.getLast(4) - db[username] = password + db = VerifierDB(dbName) + db.open() + if username in db: + print("User already in database!") + sys.exit() + bits = int(args.getLast(5)) + N, g, salt, verifier = VerifierDB.makeVerifier(username, password, bits) + db[username] = N, g, salt, verifier elif cmd == "del": dbName = args.get(2) username = args.getLast(3) - - try: - db = VerifierDB(dbName) - db.open() - except ValueError: - db = SharedKeyDB(dbName) - db.open() - + db = VerifierDB(dbName) + db.open() del(db[username]) elif cmd == "check": @@ -145,50 +115,36 @@ try: else: password = None - try: - db = VerifierDB(dbName) - db.open() - except ValueError: - db = SharedKeyDB(dbName) - db.open() + db = VerifierDB(dbName) + db.open() try: db[username] - print "Username exists" + print("Username exists") if password: if db.check(username, password): - print "Password is correct" + print("Password is correct") else: - print "Password is wrong" + print("Password is wrong") except KeyError: - print "Username does not exist" + print("Username does not exist") sys.exit() elif cmd == "list": dbName = args.get(2) - - try: - db = VerifierDB(dbName) - db.open() - except ValueError: - db = SharedKeyDB(dbName) - db.open() - - if isinstance(db, VerifierDB): - print "Verifier Database" - def numBits(n): - if n==0: - return 0 - return int(math.floor(math.log(n, 2))+1) - for username in db.keys(): - N, g, s, v = db[username] - print numBits(N), username - else: - print "Shared Key Database" - for username in db.keys(): - print username + db = VerifierDB(dbName) + db.open() + + print("Verifier Database") + def numBits(n): + if n==0: + return 0 + return int(math.floor(math.log(n, 2))+1) + for username in db.keys(): + N, g, s, v = db[username] + print(numBits(N), username) else: - print "Bad command: '%s'" % cmd + print("Bad command: '%s'" % cmd) except: raise diff --git a/chromium/third_party/tlslite/setup.py b/chromium/third_party/tlslite/setup.py index e3417c4ea49..51ef011f1d1 100644..100755 --- a/chromium/third_party/tlslite/setup.py +++ b/chromium/third_party/tlslite/setup.py @@ -1,26 +1,16 @@ #!/usr/bin/env python -import sys -from distutils.core import setup, Extension +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. -if sys.version_info < (2, 2): - raise AssertionError("Python 2.2 or later required") - -if sys.platform == "win32": - ext = Extension("tlslite.utils.win32prng", - sources=["tlslite/utils/win32prng.c"], - libraries=["advapi32"]) - exts = [ext] -else: - exts = None +from distutils.core import setup setup(name="tlslite", - version="0.3.8", + version="0.4.6", author="Trevor Perrin", - author_email="trevp@trevp.net", + author_email="tlslite@trevp.net", url="http://trevp.net/tlslite/", - description="tlslite implements SSL and TLS with SRP, shared-keys, cryptoID, or X.509 authentication.", - license="public domain", + description="tlslite implements SSL and TLS.", + license="public domain and BSD", scripts=["scripts/tls.py", "scripts/tlsdb.py"], - packages=["tlslite", "tlslite.utils", "tlslite.integration"], - ext_modules=exts) + packages=["tlslite", "tlslite.utils", "tlslite.integration"],) diff --git a/chromium/third_party/tlslite/tlslite/Checker.py b/chromium/third_party/tlslite/tlslite/Checker.py deleted file mode 100644 index f978697628e..00000000000 --- a/chromium/third_party/tlslite/tlslite/Checker.py +++ /dev/null @@ -1,146 +0,0 @@ -"""Class for post-handshake certificate checking.""" - -from utils.cryptomath import hashAndBase64 -from X509 import X509 -from X509CertChain import X509CertChain -from errors import * - - -class Checker: - """This class is passed to a handshake function to check the other - party's certificate chain. - - If a handshake function completes successfully, but the Checker - judges the other party's certificate chain to be missing or - inadequate, a subclass of - L{tlslite.errors.TLSAuthenticationError} will be raised. - - Currently, the Checker can check either an X.509 or a cryptoID - chain (for the latter, cryptoIDlib must be installed). - """ - - def __init__(self, cryptoID=None, protocol=None, - x509Fingerprint=None, - x509TrustList=None, x509CommonName=None, - checkResumedSession=False): - """Create a new Checker instance. - - You must pass in one of these argument combinations: - - cryptoID[, protocol] (requires cryptoIDlib) - - x509Fingerprint - - x509TrustList[, x509CommonName] (requires cryptlib_py) - - @type cryptoID: str - @param cryptoID: A cryptoID which the other party's certificate - chain must match. The cryptoIDlib module must be installed. - Mutually exclusive with all of the 'x509...' arguments. - - @type protocol: str - @param protocol: A cryptoID protocol URI which the other - party's certificate chain must match. Requires the 'cryptoID' - argument. - - @type x509Fingerprint: str - @param x509Fingerprint: A hex-encoded X.509 end-entity - fingerprint which the other party's end-entity certificate must - match. Mutually exclusive with the 'cryptoID' and - 'x509TrustList' arguments. - - @type x509TrustList: list of L{tlslite.X509.X509} - @param x509TrustList: A list of trusted root certificates. The - other party must present a certificate chain which extends to - one of these root certificates. The cryptlib_py module must be - installed. Mutually exclusive with the 'cryptoID' and - 'x509Fingerprint' arguments. - - @type x509CommonName: str - @param x509CommonName: The end-entity certificate's 'CN' field - must match this value. For a web server, this is typically a - server name such as 'www.amazon.com'. Mutually exclusive with - the 'cryptoID' and 'x509Fingerprint' arguments. Requires the - 'x509TrustList' argument. - - @type checkResumedSession: bool - @param checkResumedSession: If resumed sessions should be - checked. This defaults to False, on the theory that if the - session was checked once, we don't need to bother - re-checking it. - """ - - if cryptoID and (x509Fingerprint or x509TrustList): - raise ValueError() - if x509Fingerprint and x509TrustList: - raise ValueError() - if x509CommonName and not x509TrustList: - raise ValueError() - if protocol and not cryptoID: - raise ValueError() - if cryptoID: - import cryptoIDlib #So we raise an error here - if x509TrustList: - import cryptlib_py #So we raise an error here - self.cryptoID = cryptoID - self.protocol = protocol - self.x509Fingerprint = x509Fingerprint - self.x509TrustList = x509TrustList - self.x509CommonName = x509CommonName - self.checkResumedSession = checkResumedSession - - def __call__(self, connection): - """Check a TLSConnection. - - When a Checker is passed to a handshake function, this will - be called at the end of the function. - - @type connection: L{tlslite.TLSConnection.TLSConnection} - @param connection: The TLSConnection to examine. - - @raise tlslite.errors.TLSAuthenticationError: If the other - party's certificate chain is missing or bad. - """ - if not self.checkResumedSession and connection.resumed: - return - - if self.cryptoID or self.x509Fingerprint or self.x509TrustList: - if connection._client: - chain = connection.session.serverCertChain - else: - chain = connection.session.clientCertChain - - if self.x509Fingerprint or self.x509TrustList: - if isinstance(chain, X509CertChain): - if self.x509Fingerprint: - if chain.getFingerprint() != self.x509Fingerprint: - raise TLSFingerprintError(\ - "X.509 fingerprint mismatch: %s, %s" % \ - (chain.getFingerprint(), self.x509Fingerprint)) - else: #self.x509TrustList - if not chain.validate(self.x509TrustList): - raise TLSValidationError("X.509 validation failure") - if self.x509CommonName and \ - (chain.getCommonName() != self.x509CommonName): - raise TLSAuthorizationError(\ - "X.509 Common Name mismatch: %s, %s" % \ - (chain.getCommonName(), self.x509CommonName)) - elif chain: - raise TLSAuthenticationTypeError() - else: - raise TLSNoAuthenticationError() - elif self.cryptoID: - import cryptoIDlib.CertChain - if isinstance(chain, cryptoIDlib.CertChain.CertChain): - if chain.cryptoID != self.cryptoID: - raise TLSFingerprintError(\ - "cryptoID mismatch: %s, %s" % \ - (chain.cryptoID, self.cryptoID)) - if self.protocol: - if not chain.checkProtocol(self.protocol): - raise TLSAuthorizationError(\ - "cryptoID protocol mismatch") - if not chain.validate(): - raise TLSValidationError("cryptoID validation failure") - elif chain: - raise TLSAuthenticationTypeError() - else: - raise TLSNoAuthenticationError() - diff --git a/chromium/third_party/tlslite/tlslite/FileObject.py b/chromium/third_party/tlslite/tlslite/FileObject.py deleted file mode 100644 index 6ee02b2436b..00000000000 --- a/chromium/third_party/tlslite/tlslite/FileObject.py +++ /dev/null @@ -1,220 +0,0 @@ -"""Class returned by TLSConnection.makefile().""" - -class FileObject: - """This class provides a file object interface to a - L{tlslite.TLSConnection.TLSConnection}. - - Call makefile() on a TLSConnection to create a FileObject instance. - - This class was copied, with minor modifications, from the - _fileobject class in socket.py. Note that fileno() is not - implemented.""" - - default_bufsize = 16384 #TREV: changed from 8192 - - def __init__(self, sock, mode='rb', bufsize=-1): - self._sock = sock - self.mode = mode # Not actually used in this version - if bufsize < 0: - bufsize = self.default_bufsize - self.bufsize = bufsize - self.softspace = False - if bufsize == 0: - self._rbufsize = 1 - elif bufsize == 1: - self._rbufsize = self.default_bufsize - else: - self._rbufsize = bufsize - self._wbufsize = bufsize - self._rbuf = "" # A string - self._wbuf = [] # A list of strings - - def _getclosed(self): - return self._sock is not None - closed = property(_getclosed, doc="True if the file is closed") - - def close(self): - try: - if self._sock: - for result in self._sock._decrefAsync(): #TREV - pass - finally: - self._sock = None - - def __del__(self): - try: - self.close() - except: - # close() may fail if __init__ didn't complete - pass - - def flush(self): - if self._wbuf: - buffer = "".join(self._wbuf) - self._wbuf = [] - self._sock.sendall(buffer) - - #def fileno(self): - # raise NotImplementedError() #TREV - - def write(self, data): - data = str(data) # XXX Should really reject non-string non-buffers - if not data: - return - self._wbuf.append(data) - if (self._wbufsize == 0 or - self._wbufsize == 1 and '\n' in data or - self._get_wbuf_len() >= self._wbufsize): - self.flush() - - def writelines(self, list): - # XXX We could do better here for very long lists - # XXX Should really reject non-string non-buffers - self._wbuf.extend(filter(None, map(str, list))) - if (self._wbufsize <= 1 or - self._get_wbuf_len() >= self._wbufsize): - self.flush() - - def _get_wbuf_len(self): - buf_len = 0 - for x in self._wbuf: - buf_len += len(x) - return buf_len - - def read(self, size=-1): - data = self._rbuf - if size < 0: - # Read until EOF - buffers = [] - if data: - buffers.append(data) - self._rbuf = "" - if self._rbufsize <= 1: - recv_size = self.default_bufsize - else: - recv_size = self._rbufsize - while True: - data = self._sock.recv(recv_size) - if not data: - break - buffers.append(data) - return "".join(buffers) - else: - # Read until size bytes or EOF seen, whichever comes first - buf_len = len(data) - if buf_len >= size: - self._rbuf = data[size:] - return data[:size] - buffers = [] - if data: - buffers.append(data) - self._rbuf = "" - while True: - left = size - buf_len - recv_size = max(self._rbufsize, left) - data = self._sock.recv(recv_size) - if not data: - break - buffers.append(data) - n = len(data) - if n >= left: - self._rbuf = data[left:] - buffers[-1] = data[:left] - break - buf_len += n - return "".join(buffers) - - def readline(self, size=-1): - data = self._rbuf - if size < 0: - # Read until \n or EOF, whichever comes first - if self._rbufsize <= 1: - # Speed up unbuffered case - assert data == "" - buffers = [] - recv = self._sock.recv - while data != "\n": - data = recv(1) - if not data: - break - buffers.append(data) - return "".join(buffers) - nl = data.find('\n') - if nl >= 0: - nl += 1 - self._rbuf = data[nl:] - return data[:nl] - buffers = [] - if data: - buffers.append(data) - self._rbuf = "" - while True: - data = self._sock.recv(self._rbufsize) - if not data: - break - buffers.append(data) - nl = data.find('\n') - if nl >= 0: - nl += 1 - self._rbuf = data[nl:] - buffers[-1] = data[:nl] - break - return "".join(buffers) - else: - # Read until size bytes or \n or EOF seen, whichever comes first - nl = data.find('\n', 0, size) - if nl >= 0: - nl += 1 - self._rbuf = data[nl:] - return data[:nl] - buf_len = len(data) - if buf_len >= size: - self._rbuf = data[size:] - return data[:size] - buffers = [] - if data: - buffers.append(data) - self._rbuf = "" - while True: - data = self._sock.recv(self._rbufsize) - if not data: - break - buffers.append(data) - left = size - buf_len - nl = data.find('\n', 0, left) - if nl >= 0: - nl += 1 - self._rbuf = data[nl:] - buffers[-1] = data[:nl] - break - n = len(data) - if n >= left: - self._rbuf = data[left:] - buffers[-1] = data[:left] - break - buf_len += n - return "".join(buffers) - - def readlines(self, sizehint=0): - total = 0 - list = [] - while True: - line = self.readline() - if not line: - break - list.append(line) - total += len(line) - if sizehint and total >= sizehint: - break - return list - - # Iterator protocols - - def __iter__(self): - return self - - def next(self): - line = self.readline() - if not line: - raise StopIteration - return line diff --git a/chromium/third_party/tlslite/tlslite/Session.py b/chromium/third_party/tlslite/tlslite/Session.py deleted file mode 100644 index a951f458942..00000000000 --- a/chromium/third_party/tlslite/tlslite/Session.py +++ /dev/null @@ -1,131 +0,0 @@ -"""Class representing a TLS session.""" - -from utils.compat import * -from mathtls import * -from constants import * - -class Session: - """ - This class represents a TLS session. - - TLS distinguishes between connections and sessions. A new - handshake creates both a connection and a session. Data is - transmitted over the connection. - - The session contains a more permanent record of the handshake. The - session can be inspected to determine handshake results. The - session can also be used to create a new connection through - "session resumption". If the client and server both support this, - they can create a new connection based on an old session without - the overhead of a full handshake. - - The session for a L{tlslite.TLSConnection.TLSConnection} can be - retrieved from the connection's 'session' attribute. - - @type srpUsername: str - @ivar srpUsername: The client's SRP username (or None). - - @type sharedKeyUsername: str - @ivar sharedKeyUsername: The client's shared-key username (or - None). - - @type clientCertChain: L{tlslite.X509CertChain.X509CertChain} or - L{cryptoIDlib.CertChain.CertChain} - @ivar clientCertChain: The client's certificate chain (or None). - - @type serverCertChain: L{tlslite.X509CertChain.X509CertChain} or - L{cryptoIDlib.CertChain.CertChain} - @ivar serverCertChain: The server's certificate chain (or None). - """ - - def __init__(self): - self.masterSecret = createByteArraySequence([]) - self.sessionID = createByteArraySequence([]) - self.cipherSuite = 0 - self.srpUsername = None - self.sharedKeyUsername = None - self.clientCertChain = None - self.serverCertChain = None - self.resumable = False - self.sharedKey = False - - def _clone(self): - other = Session() - other.masterSecret = self.masterSecret - other.sessionID = self.sessionID - other.cipherSuite = self.cipherSuite - other.srpUsername = self.srpUsername - other.sharedKeyUsername = self.sharedKeyUsername - other.clientCertChain = self.clientCertChain - other.serverCertChain = self.serverCertChain - other.resumable = self.resumable - other.sharedKey = self.sharedKey - return other - - def _calcMasterSecret(self, version, premasterSecret, clientRandom, - serverRandom): - if version == (3,0): - self.masterSecret = PRF_SSL(premasterSecret, - concatArrays(clientRandom, serverRandom), 48) - elif version in ((3,1), (3,2)): - self.masterSecret = PRF(premasterSecret, "master secret", - concatArrays(clientRandom, serverRandom), 48) - else: - raise AssertionError() - - def valid(self): - """If this session can be used for session resumption. - - @rtype: bool - @return: If this session can be used for session resumption. - """ - return self.resumable or self.sharedKey - - def _setResumable(self, boolean): - #Only let it be set if this isn't a shared key - if not self.sharedKey: - #Only let it be set to True if the sessionID is non-null - if (not boolean) or (boolean and self.sessionID): - self.resumable = boolean - - def getCipherName(self): - """Get the name of the cipher used with this connection. - - @rtype: str - @return: The name of the cipher used with this connection. - Either 'aes128', 'aes256', 'rc4', or '3des'. - """ - if self.cipherSuite in CipherSuite.aes128Suites: - return "aes128" - elif self.cipherSuite in CipherSuite.aes256Suites: - return "aes256" - elif self.cipherSuite in CipherSuite.rc4Suites: - return "rc4" - elif self.cipherSuite in CipherSuite.tripleDESSuites: - return "3des" - else: - return None - - def _createSharedKey(self, sharedKeyUsername, sharedKey): - if len(sharedKeyUsername)>16: - raise ValueError() - if len(sharedKey)>47: - raise ValueError() - - self.sharedKeyUsername = sharedKeyUsername - - self.sessionID = createByteArrayZeros(16) - for x in range(len(sharedKeyUsername)): - self.sessionID[x] = ord(sharedKeyUsername[x]) - - premasterSecret = createByteArrayZeros(48) - sharedKey = chr(len(sharedKey)) + sharedKey - for x in range(48): - premasterSecret[x] = ord(sharedKey[x % len(sharedKey)]) - - self.masterSecret = PRF(premasterSecret, "shared secret", - createByteArraySequence([]), 48) - self.sharedKey = True - return self - - diff --git a/chromium/third_party/tlslite/tlslite/SharedKeyDB.py b/chromium/third_party/tlslite/tlslite/SharedKeyDB.py deleted file mode 100644 index 3246ec7f155..00000000000 --- a/chromium/third_party/tlslite/tlslite/SharedKeyDB.py +++ /dev/null @@ -1,58 +0,0 @@ -"""Class for storing shared keys.""" - -from utils.cryptomath import * -from utils.compat import * -from mathtls import * -from Session import Session -from BaseDB import BaseDB - -class SharedKeyDB(BaseDB): - """This class represent an in-memory or on-disk database of shared - keys. - - A SharedKeyDB can be passed to a server handshake function to - authenticate a client based on one of the shared keys. - - This class is thread-safe. - """ - - def __init__(self, filename=None): - """Create a new SharedKeyDB. - - @type filename: str - @param filename: Filename for an on-disk database, or None for - an in-memory database. If the filename already exists, follow - this with a call to open(). To create a new on-disk database, - follow this with a call to create(). - """ - BaseDB.__init__(self, filename, "shared key") - - def _getItem(self, username, valueStr): - session = Session() - session._createSharedKey(username, valueStr) - return session - - def __setitem__(self, username, sharedKey): - """Add a shared key to the database. - - @type username: str - @param username: The username to associate the shared key with. - Must be less than or equal to 16 characters in length, and must - not already be in the database. - - @type sharedKey: str - @param sharedKey: The shared key to add. Must be less than 48 - characters in length. - """ - BaseDB.__setitem__(self, username, sharedKey) - - def _setItem(self, username, value): - if len(username)>16: - raise ValueError("username too long") - if len(value)>=48: - raise ValueError("shared key too long") - return value - - def _checkItem(self, value, username, param): - newSession = self._getItem(username, param) - return value.masterSecret == newSession.masterSecret
\ No newline at end of file diff --git a/chromium/third_party/tlslite/tlslite/TLSConnection.py b/chromium/third_party/tlslite/tlslite/TLSConnection.py deleted file mode 100644 index 0c3453666e4..00000000000 --- a/chromium/third_party/tlslite/tlslite/TLSConnection.py +++ /dev/null @@ -1,1698 +0,0 @@ -""" -MAIN CLASS FOR TLS LITE (START HERE!). -""" -from __future__ import generators - -import socket -from utils.compat import formatExceptionTrace -from TLSRecordLayer import TLSRecordLayer -from Session import Session -from constants import * -from utils.cryptomath import getRandomBytes -from errors import * -from messages import * -from mathtls import * -from HandshakeSettings import HandshakeSettings - - -class TLSConnection(TLSRecordLayer): - """ - This class wraps a socket and provides TLS handshaking and data - transfer. - - To use this class, create a new instance, passing a connected - socket into the constructor. Then call some handshake function. - If the handshake completes without raising an exception, then a TLS - connection has been negotiated. You can transfer data over this - connection as if it were a socket. - - This class provides both synchronous and asynchronous versions of - its key functions. The synchronous versions should be used when - writing single-or multi-threaded code using blocking sockets. The - asynchronous versions should be used when performing asynchronous, - event-based I/O with non-blocking sockets. - - Asynchronous I/O is a complicated subject; typically, you should - not use the asynchronous functions directly, but should use some - framework like asyncore or Twisted which TLS Lite integrates with - (see - L{tlslite.integration.TLSAsyncDispatcherMixIn.TLSAsyncDispatcherMixIn} or - L{tlslite.integration.TLSTwistedProtocolWrapper.TLSTwistedProtocolWrapper}). - """ - - - def __init__(self, sock): - """Create a new TLSConnection instance. - - @param sock: The socket data will be transmitted on. The - socket should already be connected. It may be in blocking or - non-blocking mode. - - @type sock: L{socket.socket} - """ - TLSRecordLayer.__init__(self, sock) - - def handshakeClientSRP(self, username, password, session=None, - settings=None, checker=None, async=False): - """Perform an SRP handshake in the role of client. - - This function performs a TLS/SRP handshake. SRP mutually - authenticates both parties to each other using only a - username and password. This function may also perform a - combined SRP and server-certificate handshake, if the server - chooses to authenticate itself with a certificate chain in - addition to doing SRP. - - TLS/SRP is non-standard. Most TLS implementations don't - support it. See - U{http://www.ietf.org/html.charters/tls-charter.html} or - U{http://trevp.net/tlssrp/} for the latest information on - TLS/SRP. - - Like any handshake function, this can be called on a closed - TLS connection, or on a TLS connection that is already open. - If called on an open connection it performs a re-handshake. - - If the function completes without raising an exception, the - TLS connection will be open and available for data transfer. - - If an exception is raised, the connection will have been - automatically closed (if it was ever open). - - @type username: str - @param username: The SRP username. - - @type password: str - @param password: The SRP password. - - @type session: L{tlslite.Session.Session} - @param session: A TLS session to attempt to resume. This - session must be an SRP session performed with the same username - and password as were passed in. If the resumption does not - succeed, a full SRP handshake will be performed. - - @type settings: L{tlslite.HandshakeSettings.HandshakeSettings} - @param settings: Various settings which can be used to control - the ciphersuites, certificate types, and SSL/TLS versions - offered by the client. - - @type checker: L{tlslite.Checker.Checker} - @param checker: A Checker instance. This instance will be - invoked to examine the other party's authentication - credentials, if the handshake completes succesfully. - - @type async: bool - @param async: If False, this function will block until the - handshake is completed. If True, this function will return a - generator. Successive invocations of the generator will - return 0 if it is waiting to read from the socket, 1 if it is - waiting to write to the socket, or will raise StopIteration if - the handshake operation is completed. - - @rtype: None or an iterable - @return: If 'async' is True, a generator object will be - returned. - - @raise socket.error: If a socket error occurs. - @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed - without a preceding alert. - @raise tlslite.errors.TLSAlert: If a TLS alert is signalled. - @raise tlslite.errors.TLSAuthenticationError: If the checker - doesn't like the other party's authentication credentials. - """ - handshaker = self._handshakeClientAsync(srpParams=(username, password), - session=session, settings=settings, checker=checker) - if async: - return handshaker - for result in handshaker: - pass - - def handshakeClientCert(self, certChain=None, privateKey=None, - session=None, settings=None, checker=None, - async=False): - """Perform a certificate-based handshake in the role of client. - - This function performs an SSL or TLS handshake. The server - will authenticate itself using an X.509 or cryptoID certificate - chain. If the handshake succeeds, the server's certificate - chain will be stored in the session's serverCertChain attribute. - Unless a checker object is passed in, this function does no - validation or checking of the server's certificate chain. - - If the server requests client authentication, the - client will send the passed-in certificate chain, and use the - passed-in private key to authenticate itself. If no - certificate chain and private key were passed in, the client - will attempt to proceed without client authentication. The - server may or may not allow this. - - Like any handshake function, this can be called on a closed - TLS connection, or on a TLS connection that is already open. - If called on an open connection it performs a re-handshake. - - If the function completes without raising an exception, the - TLS connection will be open and available for data transfer. - - If an exception is raised, the connection will have been - automatically closed (if it was ever open). - - @type certChain: L{tlslite.X509CertChain.X509CertChain} or - L{cryptoIDlib.CertChain.CertChain} - @param certChain: The certificate chain to be used if the - server requests client authentication. - - @type privateKey: L{tlslite.utils.RSAKey.RSAKey} - @param privateKey: The private key to be used if the server - requests client authentication. - - @type session: L{tlslite.Session.Session} - @param session: A TLS session to attempt to resume. If the - resumption does not succeed, a full handshake will be - performed. - - @type settings: L{tlslite.HandshakeSettings.HandshakeSettings} - @param settings: Various settings which can be used to control - the ciphersuites, certificate types, and SSL/TLS versions - offered by the client. - - @type checker: L{tlslite.Checker.Checker} - @param checker: A Checker instance. This instance will be - invoked to examine the other party's authentication - credentials, if the handshake completes succesfully. - - @type async: bool - @param async: If False, this function will block until the - handshake is completed. If True, this function will return a - generator. Successive invocations of the generator will - return 0 if it is waiting to read from the socket, 1 if it is - waiting to write to the socket, or will raise StopIteration if - the handshake operation is completed. - - @rtype: None or an iterable - @return: If 'async' is True, a generator object will be - returned. - - @raise socket.error: If a socket error occurs. - @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed - without a preceding alert. - @raise tlslite.errors.TLSAlert: If a TLS alert is signalled. - @raise tlslite.errors.TLSAuthenticationError: If the checker - doesn't like the other party's authentication credentials. - """ - handshaker = self._handshakeClientAsync(certParams=(certChain, - privateKey), session=session, settings=settings, - checker=checker) - if async: - return handshaker - for result in handshaker: - pass - - def handshakeClientUnknown(self, srpCallback=None, certCallback=None, - session=None, settings=None, checker=None, - async=False): - """Perform a to-be-determined type of handshake in the role of client. - - This function performs an SSL or TLS handshake. If the server - requests client certificate authentication, the - certCallback will be invoked and should return a (certChain, - privateKey) pair. If the callback returns None, the library - will attempt to proceed without client authentication. The - server may or may not allow this. - - If the server requests SRP authentication, the srpCallback - will be invoked and should return a (username, password) pair. - If the callback returns None, the local implementation will - signal a user_canceled error alert. - - After the handshake completes, the client can inspect the - connection's session attribute to determine what type of - authentication was performed. - - Like any handshake function, this can be called on a closed - TLS connection, or on a TLS connection that is already open. - If called on an open connection it performs a re-handshake. - - If the function completes without raising an exception, the - TLS connection will be open and available for data transfer. - - If an exception is raised, the connection will have been - automatically closed (if it was ever open). - - @type srpCallback: callable - @param srpCallback: The callback to be used if the server - requests SRP authentication. If None, the client will not - offer support for SRP ciphersuites. - - @type certCallback: callable - @param certCallback: The callback to be used if the server - requests client certificate authentication. - - @type session: L{tlslite.Session.Session} - @param session: A TLS session to attempt to resume. If the - resumption does not succeed, a full handshake will be - performed. - - @type settings: L{tlslite.HandshakeSettings.HandshakeSettings} - @param settings: Various settings which can be used to control - the ciphersuites, certificate types, and SSL/TLS versions - offered by the client. - - @type checker: L{tlslite.Checker.Checker} - @param checker: A Checker instance. This instance will be - invoked to examine the other party's authentication - credentials, if the handshake completes succesfully. - - @type async: bool - @param async: If False, this function will block until the - handshake is completed. If True, this function will return a - generator. Successive invocations of the generator will - return 0 if it is waiting to read from the socket, 1 if it is - waiting to write to the socket, or will raise StopIteration if - the handshake operation is completed. - - @rtype: None or an iterable - @return: If 'async' is True, a generator object will be - returned. - - @raise socket.error: If a socket error occurs. - @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed - without a preceding alert. - @raise tlslite.errors.TLSAlert: If a TLS alert is signalled. - @raise tlslite.errors.TLSAuthenticationError: If the checker - doesn't like the other party's authentication credentials. - """ - handshaker = self._handshakeClientAsync(unknownParams=(srpCallback, - certCallback), session=session, settings=settings, - checker=checker) - if async: - return handshaker - for result in handshaker: - pass - - def handshakeClientSharedKey(self, username, sharedKey, settings=None, - checker=None, async=False): - """Perform a shared-key handshake in the role of client. - - This function performs a shared-key handshake. Using shared - symmetric keys of high entropy (128 bits or greater) mutually - authenticates both parties to each other. - - TLS with shared-keys is non-standard. Most TLS - implementations don't support it. See - U{http://www.ietf.org/html.charters/tls-charter.html} for the - latest information on TLS with shared-keys. If the shared-keys - Internet-Draft changes or is superceded, TLS Lite will track - those changes, so the shared-key support in later versions of - TLS Lite may become incompatible with this version. - - Like any handshake function, this can be called on a closed - TLS connection, or on a TLS connection that is already open. - If called on an open connection it performs a re-handshake. - - If the function completes without raising an exception, the - TLS connection will be open and available for data transfer. - - If an exception is raised, the connection will have been - automatically closed (if it was ever open). - - @type username: str - @param username: The shared-key username. - - @type sharedKey: str - @param sharedKey: The shared key. - - @type settings: L{tlslite.HandshakeSettings.HandshakeSettings} - @param settings: Various settings which can be used to control - the ciphersuites, certificate types, and SSL/TLS versions - offered by the client. - - @type checker: L{tlslite.Checker.Checker} - @param checker: A Checker instance. This instance will be - invoked to examine the other party's authentication - credentials, if the handshake completes succesfully. - - @type async: bool - @param async: If False, this function will block until the - handshake is completed. If True, this function will return a - generator. Successive invocations of the generator will - return 0 if it is waiting to read from the socket, 1 if it is - waiting to write to the socket, or will raise StopIteration if - the handshake operation is completed. - - @rtype: None or an iterable - @return: If 'async' is True, a generator object will be - returned. - - @raise socket.error: If a socket error occurs. - @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed - without a preceding alert. - @raise tlslite.errors.TLSAlert: If a TLS alert is signalled. - @raise tlslite.errors.TLSAuthenticationError: If the checker - doesn't like the other party's authentication credentials. - """ - handshaker = self._handshakeClientAsync(sharedKeyParams=(username, - sharedKey), settings=settings, checker=checker) - if async: - return handshaker - for result in handshaker: - pass - - def _handshakeClientAsync(self, srpParams=(), certParams=(), - unknownParams=(), sharedKeyParams=(), - session=None, settings=None, checker=None, - recursive=False): - - handshaker = self._handshakeClientAsyncHelper(srpParams=srpParams, - certParams=certParams, unknownParams=unknownParams, - sharedKeyParams=sharedKeyParams, session=session, - settings=settings, recursive=recursive) - for result in self._handshakeWrapperAsync(handshaker, checker): - yield result - - - def _handshakeClientAsyncHelper(self, srpParams, certParams, unknownParams, - sharedKeyParams, session, settings, recursive): - if not recursive: - self._handshakeStart(client=True) - - #Unpack parameters - srpUsername = None # srpParams - password = None # srpParams - clientCertChain = None # certParams - privateKey = None # certParams - srpCallback = None # unknownParams - certCallback = None # unknownParams - #session # sharedKeyParams (or session) - #settings # settings - - if srpParams: - srpUsername, password = srpParams - elif certParams: - clientCertChain, privateKey = certParams - elif unknownParams: - srpCallback, certCallback = unknownParams - elif sharedKeyParams: - session = Session()._createSharedKey(*sharedKeyParams) - - if not settings: - settings = HandshakeSettings() - settings = settings._filter() - - #Validate parameters - if srpUsername and not password: - raise ValueError("Caller passed a username but no password") - if password and not srpUsername: - raise ValueError("Caller passed a password but no username") - - if clientCertChain and not privateKey: - raise ValueError("Caller passed a certChain but no privateKey") - if privateKey and not clientCertChain: - raise ValueError("Caller passed a privateKey but no certChain") - - if clientCertChain: - foundType = False - try: - import cryptoIDlib.CertChain - if isinstance(clientCertChain, cryptoIDlib.CertChain.CertChain): - if "cryptoID" not in settings.certificateTypes: - raise ValueError("Client certificate doesn't "\ - "match Handshake Settings") - settings.certificateTypes = ["cryptoID"] - foundType = True - except ImportError: - pass - if not foundType and isinstance(clientCertChain, - X509CertChain): - if "x509" not in settings.certificateTypes: - raise ValueError("Client certificate doesn't match "\ - "Handshake Settings") - settings.certificateTypes = ["x509"] - foundType = True - if not foundType: - raise ValueError("Unrecognized certificate type") - - - if session: - if not session.valid(): - session = None #ignore non-resumable sessions... - elif session.resumable and \ - (session.srpUsername != srpUsername): - raise ValueError("Session username doesn't match") - - #Add Faults to parameters - if srpUsername and self.fault == Fault.badUsername: - srpUsername += "GARBAGE" - if password and self.fault == Fault.badPassword: - password += "GARBAGE" - if sharedKeyParams: - identifier = sharedKeyParams[0] - sharedKey = sharedKeyParams[1] - if self.fault == Fault.badIdentifier: - identifier += "GARBAGE" - session = Session()._createSharedKey(identifier, sharedKey) - elif self.fault == Fault.badSharedKey: - sharedKey += "GARBAGE" - session = Session()._createSharedKey(identifier, sharedKey) - - - #Initialize locals - serverCertChain = None - cipherSuite = 0 - certificateType = CertificateType.x509 - premasterSecret = None - - #Get client nonce - clientRandom = getRandomBytes(32) - - #Initialize acceptable ciphersuites - cipherSuites = [] - if srpParams: - cipherSuites += CipherSuite.getSrpRsaSuites(settings.cipherNames) - cipherSuites += CipherSuite.getSrpSuites(settings.cipherNames) - elif certParams: - cipherSuites += CipherSuite.getRsaSuites(settings.cipherNames) - elif unknownParams: - if srpCallback: - cipherSuites += \ - CipherSuite.getSrpRsaSuites(settings.cipherNames) - cipherSuites += \ - CipherSuite.getSrpSuites(settings.cipherNames) - cipherSuites += CipherSuite.getRsaSuites(settings.cipherNames) - elif sharedKeyParams: - cipherSuites += CipherSuite.getRsaSuites(settings.cipherNames) - else: - cipherSuites += CipherSuite.getRsaSuites(settings.cipherNames) - - #Initialize acceptable certificate types - certificateTypes = settings._getCertificateTypes() - - #Tentatively set the version to the client's minimum version. - #We'll use this for the ClientHello, and if an error occurs - #parsing the Server Hello, we'll use this version for the response - self.version = settings.maxVersion - - #Either send ClientHello (with a resumable session)... - if session: - #If it's a resumable (i.e. not a shared-key session), then its - #ciphersuite must be one of the acceptable ciphersuites - if (not sharedKeyParams) and \ - session.cipherSuite not in cipherSuites: - raise ValueError("Session's cipher suite not consistent "\ - "with parameters") - else: - clientHello = ClientHello() - clientHello.create(settings.maxVersion, clientRandom, - session.sessionID, cipherSuites, - certificateTypes, session.srpUsername) - - #Or send ClientHello (without) - else: - clientHello = ClientHello() - clientHello.create(settings.maxVersion, clientRandom, - createByteArraySequence([]), cipherSuites, - certificateTypes, srpUsername) - for result in self._sendMsg(clientHello): - yield result - - #Get ServerHello (or missing_srp_username) - for result in self._getMsg((ContentType.handshake, - ContentType.alert), - HandshakeType.server_hello): - if result in (0,1): - yield result - else: - break - msg = result - - if isinstance(msg, ServerHello): - serverHello = msg - elif isinstance(msg, Alert): - alert = msg - - #If it's not a missing_srp_username, re-raise - if alert.description != AlertDescription.missing_srp_username: - self._shutdown(False) - raise TLSRemoteAlert(alert) - - #If we're not in SRP callback mode, we won't have offered SRP - #without a username, so we shouldn't get this alert - if not srpCallback: - for result in self._sendError(\ - AlertDescription.unexpected_message): - yield result - srpParams = srpCallback() - #If the callback returns None, cancel the handshake - if srpParams == None: - for result in self._sendError(AlertDescription.user_canceled): - yield result - - #Recursively perform handshake - for result in self._handshakeClientAsyncHelper(srpParams, - None, None, None, None, settings, True): - yield result - return - - #Get the server version. Do this before anything else, so any - #error alerts will use the server's version - self.version = serverHello.server_version - - #Future responses from server must use this version - self._versionCheck = True - - #Check ServerHello - if serverHello.server_version < settings.minVersion: - for result in self._sendError(\ - AlertDescription.protocol_version, - "Too old version: %s" % str(serverHello.server_version)): - yield result - if serverHello.server_version > settings.maxVersion: - for result in self._sendError(\ - AlertDescription.protocol_version, - "Too new version: %s" % str(serverHello.server_version)): - yield result - if serverHello.cipher_suite not in cipherSuites: - for result in self._sendError(\ - AlertDescription.illegal_parameter, - "Server responded with incorrect ciphersuite"): - yield result - if serverHello.certificate_type not in certificateTypes: - for result in self._sendError(\ - AlertDescription.illegal_parameter, - "Server responded with incorrect certificate type"): - yield result - if serverHello.compression_method != 0: - for result in self._sendError(\ - AlertDescription.illegal_parameter, - "Server responded with incorrect compression method"): - yield result - - #Get the server nonce - serverRandom = serverHello.random - - #If the server agrees to resume - if session and session.sessionID and \ - serverHello.session_id == session.sessionID: - - #If a shared-key, we're flexible about suites; otherwise the - #server-chosen suite has to match the session's suite - if sharedKeyParams: - session.cipherSuite = serverHello.cipher_suite - elif serverHello.cipher_suite != session.cipherSuite: - for result in self._sendError(\ - AlertDescription.illegal_parameter,\ - "Server's ciphersuite doesn't match session"): - yield result - - #Set the session for this connection - self.session = session - - #Calculate pending connection states - self._calcPendingStates(clientRandom, serverRandom, - settings.cipherImplementations) - - #Exchange ChangeCipherSpec and Finished messages - for result in self._getChangeCipherSpec(): - yield result - for result in self._getFinished(): - yield result - for result in self._sendFinished(): - yield result - - #Mark the connection as open - self._handshakeDone(resumed=True) - - #If server DOES NOT agree to resume - else: - - if sharedKeyParams: - for result in self._sendError(\ - AlertDescription.user_canceled, - "Was expecting a shared-key resumption"): - yield result - - #We've already validated these - cipherSuite = serverHello.cipher_suite - certificateType = serverHello.certificate_type - - #If the server chose an SRP suite... - if cipherSuite in CipherSuite.srpSuites: - #Get ServerKeyExchange, ServerHelloDone - for result in self._getMsg(ContentType.handshake, - HandshakeType.server_key_exchange, cipherSuite): - if result in (0,1): - yield result - else: - break - serverKeyExchange = result - - for result in self._getMsg(ContentType.handshake, - HandshakeType.server_hello_done): - if result in (0,1): - yield result - else: - break - serverHelloDone = result - - #If the server chose an SRP+RSA suite... - elif cipherSuite in CipherSuite.srpRsaSuites: - #Get Certificate, ServerKeyExchange, ServerHelloDone - for result in self._getMsg(ContentType.handshake, - HandshakeType.certificate, certificateType): - if result in (0,1): - yield result - else: - break - serverCertificate = result - - for result in self._getMsg(ContentType.handshake, - HandshakeType.server_key_exchange, cipherSuite): - if result in (0,1): - yield result - else: - break - serverKeyExchange = result - - for result in self._getMsg(ContentType.handshake, - HandshakeType.server_hello_done): - if result in (0,1): - yield result - else: - break - serverHelloDone = result - - #If the server chose an RSA suite... - elif cipherSuite in CipherSuite.rsaSuites: - #Get Certificate[, CertificateRequest], ServerHelloDone - for result in self._getMsg(ContentType.handshake, - HandshakeType.certificate, certificateType): - if result in (0,1): - yield result - else: - break - serverCertificate = result - - for result in self._getMsg(ContentType.handshake, - (HandshakeType.server_hello_done, - HandshakeType.certificate_request)): - if result in (0,1): - yield result - else: - break - msg = result - - certificateRequest = None - if isinstance(msg, CertificateRequest): - certificateRequest = msg - for result in self._getMsg(ContentType.handshake, - HandshakeType.server_hello_done): - if result in (0,1): - yield result - else: - break - serverHelloDone = result - elif isinstance(msg, ServerHelloDone): - serverHelloDone = msg - else: - raise AssertionError() - - - #Calculate SRP premaster secret, if server chose an SRP or - #SRP+RSA suite - if cipherSuite in CipherSuite.srpSuites + \ - CipherSuite.srpRsaSuites: - #Get and check the server's group parameters and B value - N = serverKeyExchange.srp_N - g = serverKeyExchange.srp_g - s = serverKeyExchange.srp_s - B = serverKeyExchange.srp_B - - if (g,N) not in goodGroupParameters: - for result in self._sendError(\ - AlertDescription.untrusted_srp_parameters, - "Unknown group parameters"): - yield result - if numBits(N) < settings.minKeySize: - for result in self._sendError(\ - AlertDescription.untrusted_srp_parameters, - "N value is too small: %d" % numBits(N)): - yield result - if numBits(N) > settings.maxKeySize: - for result in self._sendError(\ - AlertDescription.untrusted_srp_parameters, - "N value is too large: %d" % numBits(N)): - yield result - if B % N == 0: - for result in self._sendError(\ - AlertDescription.illegal_parameter, - "Suspicious B value"): - yield result - - #Check the server's signature, if server chose an - #SRP+RSA suite - if cipherSuite in CipherSuite.srpRsaSuites: - #Hash ServerKeyExchange/ServerSRPParams - hashBytes = serverKeyExchange.hash(clientRandom, - serverRandom) - - #Extract signature bytes from ServerKeyExchange - sigBytes = serverKeyExchange.signature - if len(sigBytes) == 0: - for result in self._sendError(\ - AlertDescription.illegal_parameter, - "Server sent an SRP ServerKeyExchange "\ - "message without a signature"): - yield result - - #Get server's public key from the Certificate message - for result in self._getKeyFromChain(serverCertificate, - settings): - if result in (0,1): - yield result - else: - break - publicKey, serverCertChain = result - - #Verify signature - if not publicKey.verify(sigBytes, hashBytes): - for result in self._sendError(\ - AlertDescription.decrypt_error, - "Signature failed to verify"): - yield result - - - #Calculate client's ephemeral DH values (a, A) - a = bytesToNumber(getRandomBytes(32)) - A = powMod(g, a, N) - - #Calculate client's static DH values (x, v) - x = makeX(bytesToString(s), srpUsername, password) - v = powMod(g, x, N) - - #Calculate u - u = makeU(N, A, B) - - #Calculate premaster secret - k = makeK(N, g) - S = powMod((B - (k*v)) % N, a+(u*x), N) - - if self.fault == Fault.badA: - A = N - S = 0 - premasterSecret = numberToBytes(S) - - #Send ClientKeyExchange - for result in self._sendMsg(\ - ClientKeyExchange(cipherSuite).createSRP(A)): - yield result - - - #Calculate RSA premaster secret, if server chose an RSA suite - elif cipherSuite in CipherSuite.rsaSuites: - - #Handle the presence of a CertificateRequest - if certificateRequest: - if unknownParams and certCallback: - certParamsNew = certCallback() - if certParamsNew: - clientCertChain, privateKey = certParamsNew - - #Get server's public key from the Certificate message - for result in self._getKeyFromChain(serverCertificate, - settings): - if result in (0,1): - yield result - else: - break - publicKey, serverCertChain = result - - - #Calculate premaster secret - premasterSecret = getRandomBytes(48) - premasterSecret[0] = settings.maxVersion[0] - premasterSecret[1] = settings.maxVersion[1] - - if self.fault == Fault.badPremasterPadding: - premasterSecret[0] = 5 - if self.fault == Fault.shortPremasterSecret: - premasterSecret = premasterSecret[:-1] - - #Encrypt premaster secret to server's public key - encryptedPreMasterSecret = publicKey.encrypt(premasterSecret) - - #If client authentication was requested, send Certificate - #message, either with certificates or empty - if certificateRequest: - clientCertificate = Certificate(certificateType) - - if clientCertChain: - #Check to make sure we have the same type of - #certificates the server requested - wrongType = False - if certificateType == CertificateType.x509: - if not isinstance(clientCertChain, X509CertChain): - wrongType = True - elif certificateType == CertificateType.cryptoID: - if not isinstance(clientCertChain, - cryptoIDlib.CertChain.CertChain): - wrongType = True - if wrongType: - for result in self._sendError(\ - AlertDescription.handshake_failure, - "Client certificate is of wrong type"): - yield result - - clientCertificate.create(clientCertChain) - - for result in self._sendMsg(clientCertificate): - yield result - else: - #The server didn't request client auth, so we - #zeroize these so the clientCertChain won't be - #stored in the session. - privateKey = None - clientCertChain = None - - #Send ClientKeyExchange - clientKeyExchange = ClientKeyExchange(cipherSuite, - self.version) - clientKeyExchange.createRSA(encryptedPreMasterSecret) - for result in self._sendMsg(clientKeyExchange): - yield result - - #If client authentication was requested and we have a - #private key, send CertificateVerify - if certificateRequest and privateKey: - if self.version == (3,0): - #Create a temporary session object, just for the - #purpose of creating the CertificateVerify - session = Session() - session._calcMasterSecret(self.version, - premasterSecret, - clientRandom, - serverRandom) - verifyBytes = self._calcSSLHandshakeHash(\ - session.masterSecret, "") - elif self.version in ((3,1), (3,2)): - verifyBytes = stringToBytes(\ - self._handshake_md5.digest() + \ - self._handshake_sha.digest()) - if self.fault == Fault.badVerifyMessage: - verifyBytes[0] = ((verifyBytes[0]+1) % 256) - signedBytes = privateKey.sign(verifyBytes) - certificateVerify = CertificateVerify() - certificateVerify.create(signedBytes) - for result in self._sendMsg(certificateVerify): - yield result - - - #Create the session object - self.session = Session() - self.session._calcMasterSecret(self.version, premasterSecret, - clientRandom, serverRandom) - self.session.sessionID = serverHello.session_id - self.session.cipherSuite = cipherSuite - self.session.srpUsername = srpUsername - self.session.clientCertChain = clientCertChain - self.session.serverCertChain = serverCertChain - - #Calculate pending connection states - self._calcPendingStates(clientRandom, serverRandom, - settings.cipherImplementations) - - #Exchange ChangeCipherSpec and Finished messages - for result in self._sendFinished(): - yield result - for result in self._getChangeCipherSpec(): - yield result - for result in self._getFinished(): - yield result - - #Mark the connection as open - self.session._setResumable(True) - self._handshakeDone(resumed=False) - - - - def handshakeServer(self, sharedKeyDB=None, verifierDB=None, - certChain=None, privateKey=None, reqCert=False, - sessionCache=None, settings=None, checker=None, - reqCAs=None, tlsIntolerant=0, - signedCertTimestamps=None, fallbackSCSV=False, - ocspResponse=None): - """Perform a handshake in the role of server. - - This function performs an SSL or TLS handshake. Depending on - the arguments and the behavior of the client, this function can - perform a shared-key, SRP, or certificate-based handshake. It - can also perform a combined SRP and server-certificate - handshake. - - Like any handshake function, this can be called on a closed - TLS connection, or on a TLS connection that is already open. - If called on an open connection it performs a re-handshake. - This function does not send a Hello Request message before - performing the handshake, so if re-handshaking is required, - the server must signal the client to begin the re-handshake - through some other means. - - If the function completes without raising an exception, the - TLS connection will be open and available for data transfer. - - If an exception is raised, the connection will have been - automatically closed (if it was ever open). - - @type sharedKeyDB: L{tlslite.SharedKeyDB.SharedKeyDB} - @param sharedKeyDB: A database of shared symmetric keys - associated with usernames. If the client performs a - shared-key handshake, the session's sharedKeyUsername - attribute will be set. - - @type verifierDB: L{tlslite.VerifierDB.VerifierDB} - @param verifierDB: A database of SRP password verifiers - associated with usernames. If the client performs an SRP - handshake, the session's srpUsername attribute will be set. - - @type certChain: L{tlslite.X509CertChain.X509CertChain} or - L{cryptoIDlib.CertChain.CertChain} - @param certChain: The certificate chain to be used if the - client requests server certificate authentication. - - @type privateKey: L{tlslite.utils.RSAKey.RSAKey} - @param privateKey: The private key to be used if the client - requests server certificate authentication. - - @type reqCert: bool - @param reqCert: Whether to request client certificate - authentication. This only applies if the client chooses server - certificate authentication; if the client chooses SRP or - shared-key authentication, this will be ignored. If the client - performs a client certificate authentication, the sessions's - clientCertChain attribute will be set. - - @type sessionCache: L{tlslite.SessionCache.SessionCache} - @param sessionCache: An in-memory cache of resumable sessions. - The client can resume sessions from this cache. Alternatively, - if the client performs a full handshake, a new session will be - added to the cache. - - @type settings: L{tlslite.HandshakeSettings.HandshakeSettings} - @param settings: Various settings which can be used to control - the ciphersuites and SSL/TLS version chosen by the server. - - @type checker: L{tlslite.Checker.Checker} - @param checker: A Checker instance. This instance will be - invoked to examine the other party's authentication - credentials, if the handshake completes succesfully. - - @type reqCAs: list of L{array.array} of unsigned bytes - @param reqCAs: A collection of DER-encoded DistinguishedNames that - will be sent along with a certificate request. This does not affect - verification. - - @type signedCertTimestamps: str - @param signedCertTimestamps: A SignedCertificateTimestampList (as a - binary 8-bit string) that will be sent as a TLS extension whenever - the client announces support for the extension. - - @type tlsIntolerant: int - @param tlsIntolerant: if non-zero, the server will simulate TLS - version intolerance by returning a fatal, handshake_failure alert. - The versions to which it's intolerant vary depending on the value: - 1: reject all TLS versions. - 2: reject TLS 1.1 or higher. - 3: reject TLS 1.2 or higher. - - @type fallbackSCSV: bool - @param fallbackSCSV: if true, the server will implement - TLS_FALLBACK_SCSV and thus reject connections using less than the - server's maximum TLS version that include this cipher suite. - - @type ocspResponse: str - @param ocspResponse: An OCSP response (as a binary 8-bit string) that - will be sent stapled in the handshake whenever the client announces - support for the status_request extension. - Note that the response is sent independent of the ClientHello - status_request extension contents, and is thus only meant for testing - environments. Real OCSP stapling is more complicated as it requires - choosing a suitable response based on the ClientHello status_request - extension contents. - - @raise socket.error: If a socket error occurs. - @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed - without a preceding alert. - @raise tlslite.errors.TLSAlert: If a TLS alert is signalled. - @raise tlslite.errors.TLSAuthenticationError: If the checker - doesn't like the other party's authentication credentials. - """ - for result in self.handshakeServerAsync(sharedKeyDB, verifierDB, - certChain, privateKey, reqCert, sessionCache, settings, - checker, reqCAs, tlsIntolerant, signedCertTimestamps, - fallbackSCSV, ocspResponse): - pass - - - def handshakeServerAsync(self, sharedKeyDB=None, verifierDB=None, - certChain=None, privateKey=None, reqCert=False, - sessionCache=None, settings=None, checker=None, - reqCAs=None, tlsIntolerant=0, - signedCertTimestamps=None, - fallbackSCSV=False, ocspResponse=None): - """Start a server handshake operation on the TLS connection. - - This function returns a generator which behaves similarly to - handshakeServer(). Successive invocations of the generator - will return 0 if it is waiting to read from the socket, 1 if it is - waiting to write to the socket, or it will raise StopIteration - if the handshake operation is complete. - - @rtype: iterable - @return: A generator; see above for details. - """ - handshaker = self._handshakeServerAsyncHelper(\ - sharedKeyDB=sharedKeyDB, - verifierDB=verifierDB, certChain=certChain, - privateKey=privateKey, reqCert=reqCert, - sessionCache=sessionCache, settings=settings, - reqCAs=reqCAs, - tlsIntolerant=tlsIntolerant, - signedCertTimestamps=signedCertTimestamps, - fallbackSCSV=fallbackSCSV, ocspResponse=ocspResponse) - - for result in self._handshakeWrapperAsync(handshaker, checker): - yield result - - - def _handshakeServerAsyncHelper(self, sharedKeyDB, verifierDB, - certChain, privateKey, reqCert, - sessionCache, settings, reqCAs, - tlsIntolerant, signedCertTimestamps, - fallbackSCSV, ocspResponse): - - self._handshakeStart(client=False) - - if (not sharedKeyDB) and (not verifierDB) and (not certChain): - raise ValueError("Caller passed no authentication credentials") - if certChain and not privateKey: - raise ValueError("Caller passed a certChain but no privateKey") - if privateKey and not certChain: - raise ValueError("Caller passed a privateKey but no certChain") - if reqCAs and not reqCert: - raise ValueError("Caller passed reqCAs but not reqCert") - if signedCertTimestamps and not certChain: - raise ValueError("Caller passed signedCertTimestamps but no " - "certChain") - - if not settings: - settings = HandshakeSettings() - settings = settings._filter() - - #Initialize acceptable cipher suites - cipherSuites = [] - if verifierDB: - if certChain: - cipherSuites += \ - CipherSuite.getSrpRsaSuites(settings.cipherNames) - cipherSuites += CipherSuite.getSrpSuites(settings.cipherNames) - if sharedKeyDB or certChain: - cipherSuites += CipherSuite.getRsaSuites(settings.cipherNames) - - #Initialize acceptable certificate type - certificateType = None - if certChain: - try: - import cryptoIDlib.CertChain - if isinstance(certChain, cryptoIDlib.CertChain.CertChain): - certificateType = CertificateType.cryptoID - except ImportError: - pass - if isinstance(certChain, X509CertChain): - certificateType = CertificateType.x509 - if certificateType == None: - raise ValueError("Unrecognized certificate type") - - #Initialize locals - clientCertChain = None - serverCertChain = None #We may set certChain to this later - postFinishedError = None - doingChannelID = False - - #Tentatively set version to most-desirable version, so if an error - #occurs parsing the ClientHello, this is what we'll use for the - #error alert - self.version = settings.maxVersion - - #Get ClientHello - for result in self._getMsg(ContentType.handshake, - HandshakeType.client_hello): - if result in (0,1): - yield result - else: - break - clientHello = result - - #If client's version is too low, reject it - if clientHello.client_version < settings.minVersion: - self.version = settings.minVersion - for result in self._sendError(\ - AlertDescription.protocol_version, - "Too old version: %s" % str(clientHello.client_version)): - yield result - - #If tlsIntolerant is nonzero, reject certain TLS versions. - #1: reject all TLS versions. - #2: reject TLS 1.1 or higher. - #3: reject TLS 1.2 or higher. - if (tlsIntolerant == 1 and clientHello.client_version > (3, 0) or - tlsIntolerant == 2 and clientHello.client_version > (3, 1) or - tlsIntolerant == 3 and clientHello.client_version > (3, 2)): - for result in self._sendError(\ - AlertDescription.handshake_failure): - yield result - - #If client's version is too high, propose my highest version - if clientHello.client_version > settings.maxVersion: - self.version = settings.maxVersion - else: - #Set the version to the client's version - self.version = clientHello.client_version - if (fallbackSCSV and - clientHello.client_version < settings.maxVersion): - for cipherSuite in clientHello.cipher_suites: - if cipherSuite == 0x5600: - for result in self._sendError(\ - AlertDescription.inappropriate_fallback): - yield result - - #Get the client nonce; create server nonce - clientRandom = clientHello.random - serverRandom = getRandomBytes(32) - - #Calculate the first cipher suite intersection. - #This is the 'privileged' ciphersuite. We'll use it if we're - #doing a shared-key resumption or a new negotiation. In fact, - #the only time we won't use it is if we're resuming a non-sharedkey - #session, in which case we use the ciphersuite from the session. - # - #Given the current ciphersuite ordering, this means we prefer SRP - #over non-SRP. - for cipherSuite in cipherSuites: - if cipherSuite in clientHello.cipher_suites: - break - else: - for result in self._sendError(\ - AlertDescription.handshake_failure): - yield result - - #If resumption was requested... - if clientHello.session_id and (sharedKeyDB or sessionCache): - session = None - - #Check in the sharedKeys container - if sharedKeyDB and len(clientHello.session_id)==16: - try: - #Trim off zero padding, if any - for x in range(16): - if clientHello.session_id[x]==0: - break - self.allegedSharedKeyUsername = bytesToString(\ - clientHello.session_id[:x]) - session = sharedKeyDB[self.allegedSharedKeyUsername] - if not session.sharedKey: - raise AssertionError() - #use privileged ciphersuite - session.cipherSuite = cipherSuite - except KeyError: - pass - - #Then check in the session cache - if sessionCache and not session: - try: - session = sessionCache[bytesToString(\ - clientHello.session_id)] - if session.sharedKey: - raise AssertionError() - if not session.resumable: - raise AssertionError() - #Check for consistency with ClientHello - if session.cipherSuite not in cipherSuites: - for result in self._sendError(\ - AlertDescription.handshake_failure): - yield result - if session.cipherSuite not in clientHello.cipher_suites: - for result in self._sendError(\ - AlertDescription.handshake_failure): - yield result - if clientHello.srp_username: - if clientHello.srp_username != session.srpUsername: - for result in self._sendError(\ - AlertDescription.handshake_failure): - yield result - except KeyError: - pass - - #If a session is found.. - if session: - #Set the session - self.session = session - - #Send ServerHello - serverHello = ServerHello() - serverHello.create(self.version, serverRandom, - session.sessionID, session.cipherSuite, - certificateType) - serverHello.channel_id = clientHello.channel_id - doingChannelID = clientHello.channel_id - for result in self._sendMsg(serverHello): - yield result - - #From here on, the client's messages must have the right version - self._versionCheck = True - - #Calculate pending connection states - self._calcPendingStates(clientRandom, serverRandom, - settings.cipherImplementations) - - #Exchange ChangeCipherSpec and Finished messages - for result in self._sendFinished(): - yield result - for result in self._getChangeCipherSpec(): - yield result - if doingChannelID: - for result in self._getEncryptedExtensions(): - yield result - for result in self._getFinished(): - yield result - - #Mark the connection as open - self._handshakeDone(resumed=True) - return - - - #If not a resumption... - - #TRICKY: we might have chosen an RSA suite that was only deemed - #acceptable because of the shared-key resumption. If the shared- - #key resumption failed, because the identifier wasn't recognized, - #we might fall through to here, where we have an RSA suite - #chosen, but no certificate. - if cipherSuite in CipherSuite.rsaSuites and not certChain: - for result in self._sendError(\ - AlertDescription.handshake_failure): - yield result - - #If an RSA suite is chosen, check for certificate type intersection - #(We do this check down here because if the mismatch occurs but the - # client is using a shared-key session, it's okay) - if cipherSuite in CipherSuite.rsaSuites + \ - CipherSuite.srpRsaSuites: - if certificateType not in clientHello.certificate_types: - for result in self._sendError(\ - AlertDescription.handshake_failure, - "the client doesn't support my certificate type"): - yield result - - #Move certChain -> serverCertChain, now that we're using it - serverCertChain = certChain - - - #Create sessionID - if sessionCache: - sessionID = getRandomBytes(32) - else: - sessionID = createByteArraySequence([]) - - #If we've selected an SRP suite, exchange keys and calculate - #premaster secret: - if cipherSuite in CipherSuite.srpSuites + CipherSuite.srpRsaSuites: - - #If there's no SRP username... - if not clientHello.srp_username: - - #Ask the client to re-send ClientHello with one - for result in self._sendMsg(Alert().create(\ - AlertDescription.missing_srp_username, - AlertLevel.warning)): - yield result - - #Get ClientHello - for result in self._getMsg(ContentType.handshake, - HandshakeType.client_hello): - if result in (0,1): - yield result - else: - break - clientHello = result - - #Check ClientHello - #If client's version is too low, reject it (COPIED CODE; BAD!) - if clientHello.client_version < settings.minVersion: - self.version = settings.minVersion - for result in self._sendError(\ - AlertDescription.protocol_version, - "Too old version: %s" % str(clientHello.client_version)): - yield result - - #If client's version is too high, propose my highest version - elif clientHello.client_version > settings.maxVersion: - self.version = settings.maxVersion - - else: - #Set the version to the client's version - self.version = clientHello.client_version - - #Recalculate the privileged cipher suite, making sure to - #pick an SRP suite - cipherSuites = [c for c in cipherSuites if c in \ - CipherSuite.srpSuites + \ - CipherSuite.srpRsaSuites] - for cipherSuite in cipherSuites: - if cipherSuite in clientHello.cipher_suites: - break - else: - for result in self._sendError(\ - AlertDescription.handshake_failure): - yield result - - #Get the client nonce; create server nonce - clientRandom = clientHello.random - serverRandom = getRandomBytes(32) - - #The username better be there, this time - if not clientHello.srp_username: - for result in self._sendError(\ - AlertDescription.illegal_parameter, - "Client resent a hello, but without the SRP"\ - " username"): - yield result - - - #Get username - self.allegedSrpUsername = clientHello.srp_username - - #Get parameters from username - try: - entry = verifierDB[self.allegedSrpUsername] - except KeyError: - for result in self._sendError(\ - AlertDescription.unknown_srp_username): - yield result - (N, g, s, v) = entry - - #Calculate server's ephemeral DH values (b, B) - b = bytesToNumber(getRandomBytes(32)) - k = makeK(N, g) - B = (powMod(g, b, N) + (k*v)) % N - - #Create ServerKeyExchange, signing it if necessary - serverKeyExchange = ServerKeyExchange(cipherSuite) - serverKeyExchange.createSRP(N, g, stringToBytes(s), B) - if cipherSuite in CipherSuite.srpRsaSuites: - hashBytes = serverKeyExchange.hash(clientRandom, - serverRandom) - serverKeyExchange.signature = privateKey.sign(hashBytes) - - #Send ServerHello[, Certificate], ServerKeyExchange, - #ServerHelloDone - msgs = [] - serverHello = ServerHello() - serverHello.create(self.version, serverRandom, sessionID, - cipherSuite, certificateType) - msgs.append(serverHello) - if cipherSuite in CipherSuite.srpRsaSuites: - certificateMsg = Certificate(certificateType) - certificateMsg.create(serverCertChain) - msgs.append(certificateMsg) - msgs.append(serverKeyExchange) - msgs.append(ServerHelloDone()) - for result in self._sendMsgs(msgs): - yield result - - #From here on, the client's messages must have the right version - self._versionCheck = True - - #Get and check ClientKeyExchange - for result in self._getMsg(ContentType.handshake, - HandshakeType.client_key_exchange, - cipherSuite): - if result in (0,1): - yield result - else: - break - clientKeyExchange = result - A = clientKeyExchange.srp_A - if A % N == 0: - postFinishedError = (AlertDescription.illegal_parameter, - "Suspicious A value") - #Calculate u - u = makeU(N, A, B) - - #Calculate premaster secret - S = powMod((A * powMod(v,u,N)) % N, b, N) - premasterSecret = numberToBytes(S) - - - #If we've selected an RSA suite, exchange keys and calculate - #premaster secret: - elif cipherSuite in CipherSuite.rsaSuites: - - #Send ServerHello, Certificate[, CertificateRequest], - #ServerHelloDone - msgs = [] - serverHello = ServerHello().create( - self.version, serverRandom, - sessionID, cipherSuite, certificateType) - serverHello.channel_id = clientHello.channel_id - if clientHello.support_signed_cert_timestamps: - serverHello.signed_cert_timestamps = signedCertTimestamps - serverHello.status_request = (clientHello.status_request and - ocspResponse) - doingChannelID = clientHello.channel_id - msgs.append(serverHello) - msgs.append(Certificate(certificateType).create(serverCertChain)) - if serverHello.status_request: - msgs.append(CertificateStatus().create(ocspResponse)) - if reqCert and reqCAs: - msgs.append(CertificateRequest().create([], reqCAs)) - elif reqCert: - msgs.append(CertificateRequest()) - msgs.append(ServerHelloDone()) - for result in self._sendMsgs(msgs): - yield result - - #From here on, the client's messages must have the right version - self._versionCheck = True - - #Get [Certificate,] (if was requested) - if reqCert: - if self.version == (3,0): - for result in self._getMsg((ContentType.handshake, - ContentType.alert), - HandshakeType.certificate, - certificateType): - if result in (0,1): - yield result - else: - break - msg = result - - if isinstance(msg, Alert): - #If it's not a no_certificate alert, re-raise - alert = msg - if alert.description != \ - AlertDescription.no_certificate: - self._shutdown(False) - raise TLSRemoteAlert(alert) - elif isinstance(msg, Certificate): - clientCertificate = msg - if clientCertificate.certChain and \ - clientCertificate.certChain.getNumCerts()!=0: - clientCertChain = clientCertificate.certChain - else: - raise AssertionError() - elif self.version in ((3,1), (3,2)): - for result in self._getMsg(ContentType.handshake, - HandshakeType.certificate, - certificateType): - if result in (0,1): - yield result - else: - break - clientCertificate = result - if clientCertificate.certChain and \ - clientCertificate.certChain.getNumCerts()!=0: - clientCertChain = clientCertificate.certChain - else: - raise AssertionError() - - #Get ClientKeyExchange - for result in self._getMsg(ContentType.handshake, - HandshakeType.client_key_exchange, - cipherSuite): - if result in (0,1): - yield result - else: - break - clientKeyExchange = result - - #Decrypt ClientKeyExchange - premasterSecret = privateKey.decrypt(\ - clientKeyExchange.encryptedPreMasterSecret) - - randomPreMasterSecret = getRandomBytes(48) - versionCheck = (premasterSecret[0], premasterSecret[1]) - if not premasterSecret: - premasterSecret = randomPreMasterSecret - elif len(premasterSecret)!=48: - premasterSecret = randomPreMasterSecret - elif versionCheck != clientHello.client_version: - if versionCheck != self.version: #Tolerate buggy IE clients - premasterSecret = randomPreMasterSecret - - #Get and check CertificateVerify, if relevant - if clientCertChain: - if self.version == (3,0): - #Create a temporary session object, just for the purpose - #of checking the CertificateVerify - session = Session() - session._calcMasterSecret(self.version, premasterSecret, - clientRandom, serverRandom) - verifyBytes = self._calcSSLHandshakeHash(\ - session.masterSecret, "") - elif self.version in ((3,1), (3,2)): - verifyBytes = stringToBytes(self._handshake_md5.digest() +\ - self._handshake_sha.digest()) - for result in self._getMsg(ContentType.handshake, - HandshakeType.certificate_verify): - if result in (0,1): - yield result - else: - break - certificateVerify = result - publicKey = clientCertChain.getEndEntityPublicKey() - if len(publicKey) < settings.minKeySize: - postFinishedError = (AlertDescription.handshake_failure, - "Client's public key too small: %d" % len(publicKey)) - if len(publicKey) > settings.maxKeySize: - postFinishedError = (AlertDescription.handshake_failure, - "Client's public key too large: %d" % len(publicKey)) - - if not publicKey.verify(certificateVerify.signature, - verifyBytes): - postFinishedError = (AlertDescription.decrypt_error, - "Signature failed to verify") - - - #Create the session object - self.session = Session() - self.session._calcMasterSecret(self.version, premasterSecret, - clientRandom, serverRandom) - self.session.sessionID = sessionID - self.session.cipherSuite = cipherSuite - self.session.srpUsername = self.allegedSrpUsername - self.session.clientCertChain = clientCertChain - self.session.serverCertChain = serverCertChain - - #Calculate pending connection states - self._calcPendingStates(clientRandom, serverRandom, - settings.cipherImplementations) - - #Exchange ChangeCipherSpec and Finished messages - for result in self._getChangeCipherSpec(): - yield result - if doingChannelID: - for result in self._getEncryptedExtensions(): - yield result - for result in self._getFinished(): - yield result - - #If we were holding a post-finished error until receiving the client - #finished message, send it now. We delay the call until this point - #because calling sendError() throws an exception, and our caller might - #shut down the socket upon receiving the exception. If he did, and the - #client was still sending its ChangeCipherSpec or Finished messages, it - #would cause a socket error on the client side. This is a lot of - #consideration to show to misbehaving clients, but this would also - #cause problems with fault-testing. - if postFinishedError: - for result in self._sendError(*postFinishedError): - yield result - - for result in self._sendFinished(): - yield result - - #Add the session object to the session cache - if sessionCache and sessionID: - sessionCache[bytesToString(sessionID)] = self.session - - #Mark the connection as open - self.session._setResumable(True) - self._handshakeDone(resumed=False) - - - def _handshakeWrapperAsync(self, handshaker, checker): - if not self.fault: - try: - for result in handshaker: - yield result - if checker: - try: - checker(self) - except TLSAuthenticationError: - alert = Alert().create(AlertDescription.close_notify, - AlertLevel.fatal) - for result in self._sendMsg(alert): - yield result - raise - except: - self._shutdown(False) - raise - else: - try: - for result in handshaker: - yield result - if checker: - try: - checker(self) - except TLSAuthenticationError: - alert = Alert().create(AlertDescription.close_notify, - AlertLevel.fatal) - for result in self._sendMsg(alert): - yield result - raise - except socket.error, e: - raise TLSFaultError("socket error!") - except TLSAbruptCloseError, e: - raise TLSFaultError("abrupt close error!") - except TLSAlert, alert: - if alert.description not in Fault.faultAlerts[self.fault]: - raise TLSFaultError(str(alert)) - else: - pass - except: - self._shutdown(False) - raise - else: - raise TLSFaultError("No error!") - - - def _getKeyFromChain(self, certificate, settings): - #Get and check cert chain from the Certificate message - certChain = certificate.certChain - if not certChain or certChain.getNumCerts() == 0: - for result in self._sendError(AlertDescription.illegal_parameter, - "Other party sent a Certificate message without "\ - "certificates"): - yield result - - #Get and check public key from the cert chain - publicKey = certChain.getEndEntityPublicKey() - if len(publicKey) < settings.minKeySize: - for result in self._sendError(AlertDescription.handshake_failure, - "Other party's public key too small: %d" % len(publicKey)): - yield result - if len(publicKey) > settings.maxKeySize: - for result in self._sendError(AlertDescription.handshake_failure, - "Other party's public key too large: %d" % len(publicKey)): - yield result - - yield publicKey, certChain diff --git a/chromium/third_party/tlslite/tlslite/X509CertChain.py b/chromium/third_party/tlslite/tlslite/X509CertChain.py deleted file mode 100644 index db55fa5a324..00000000000 --- a/chromium/third_party/tlslite/tlslite/X509CertChain.py +++ /dev/null @@ -1,242 +0,0 @@ -"""Class representing an X.509 certificate chain.""" - -from utils import cryptomath -from X509 import X509 - -class X509CertChain: - """This class represents a chain of X.509 certificates. - - @type x509List: list - @ivar x509List: A list of L{tlslite.X509.X509} instances, - starting with the end-entity certificate and with every - subsequent certificate certifying the previous. - """ - - def __init__(self, x509List=None): - """Create a new X509CertChain. - - @type x509List: list - @param x509List: A list of L{tlslite.X509.X509} instances, - starting with the end-entity certificate and with every - subsequent certificate certifying the previous. - """ - if x509List: - self.x509List = x509List - else: - self.x509List = [] - - def parseChain(self, s): - """Parse a PEM-encoded X.509 certificate file chain file. - - @type s: str - @param s: A PEM-encoded (eg: Base64) X.509 certificate file, with every - certificate wrapped within "-----BEGIN CERTIFICATE-----" and - "-----END CERTIFICATE-----" tags). Extraneous data outside such tags, - such as human readable representations, will be ignored. - """ - - class PEMIterator(object): - """Simple iterator over PEM-encoded certificates within a string. - - @type data: string - @ivar data: A string containing PEM-encoded (Base64) certificates, - with every certificate wrapped within "-----BEGIN CERTIFICATE-----" - and "-----END CERTIFICATE-----" tags). Extraneous data outside such - tags, such as human readable representations, will be ignored. - - @type index: integer - @ivar index: The current offset within data to begin iterating from. - """ - - _CERTIFICATE_HEADER = "-----BEGIN CERTIFICATE-----" - """The PEM encoding block header for X.509 certificates.""" - - _CERTIFICATE_FOOTER = "-----END CERTIFICATE-----" - """The PEM encoding block footer for X.509 certificates.""" - - def __init__(self, s): - self.data = s - self.index = 0 - - def __iter__(self): - return self - - def next(self): - """Iterates and returns the next L{tlslite.X509.X509} - certificate in data. - - @rtype tlslite.X509.X509 - """ - - self.index = self.data.find(self._CERTIFICATE_HEADER, - self.index) - if self.index == -1: - raise StopIteration - end = self.data.find(self._CERTIFICATE_FOOTER, self.index) - if end == -1: - raise StopIteration - - certStr = self.data[self.index+len(self._CERTIFICATE_HEADER) : - end] - self.index = end + len(self._CERTIFICATE_FOOTER) - bytes = cryptomath.base64ToBytes(certStr) - return X509().parseBinary(bytes) - - self.x509List = list(PEMIterator(s)) - return self - - def getNumCerts(self): - """Get the number of certificates in this chain. - - @rtype: int - """ - return len(self.x509List) - - def getEndEntityPublicKey(self): - """Get the public key from the end-entity certificate. - - @rtype: L{tlslite.utils.RSAKey.RSAKey} - """ - if self.getNumCerts() == 0: - raise AssertionError() - return self.x509List[0].publicKey - - def getFingerprint(self): - """Get the hex-encoded fingerprint of the end-entity certificate. - - @rtype: str - @return: A hex-encoded fingerprint. - """ - if self.getNumCerts() == 0: - raise AssertionError() - return self.x509List[0].getFingerprint() - - def getCommonName(self): - """Get the Subject's Common Name from the end-entity certificate. - - The cryptlib_py module must be installed in order to use this - function. - - @rtype: str or None - @return: The CN component of the certificate's subject DN, if - present. - """ - if self.getNumCerts() == 0: - raise AssertionError() - return self.x509List[0].getCommonName() - - def validate(self, x509TrustList): - """Check the validity of the certificate chain. - - This checks that every certificate in the chain validates with - the subsequent one, until some certificate validates with (or - is identical to) one of the passed-in root certificates. - - The cryptlib_py module must be installed in order to use this - function. - - @type x509TrustList: list of L{tlslite.X509.X509} - @param x509TrustList: A list of trusted root certificates. The - certificate chain must extend to one of these certificates to - be considered valid. - """ - - import cryptlib_py - c1 = None - c2 = None - lastC = None - rootC = None - - try: - rootFingerprints = [c.getFingerprint() for c in x509TrustList] - - #Check that every certificate in the chain validates with the - #next one - for cert1, cert2 in zip(self.x509List, self.x509List[1:]): - - #If we come upon a root certificate, we're done. - if cert1.getFingerprint() in rootFingerprints: - return True - - c1 = cryptlib_py.cryptImportCert(cert1.writeBytes(), - cryptlib_py.CRYPT_UNUSED) - c2 = cryptlib_py.cryptImportCert(cert2.writeBytes(), - cryptlib_py.CRYPT_UNUSED) - try: - cryptlib_py.cryptCheckCert(c1, c2) - except: - return False - cryptlib_py.cryptDestroyCert(c1) - c1 = None - cryptlib_py.cryptDestroyCert(c2) - c2 = None - - #If the last certificate is one of the root certificates, we're - #done. - if self.x509List[-1].getFingerprint() in rootFingerprints: - return True - - #Otherwise, find a root certificate that the last certificate - #chains to, and validate them. - lastC = cryptlib_py.cryptImportCert(self.x509List[-1].writeBytes(), - cryptlib_py.CRYPT_UNUSED) - for rootCert in x509TrustList: - rootC = cryptlib_py.cryptImportCert(rootCert.writeBytes(), - cryptlib_py.CRYPT_UNUSED) - if self._checkChaining(lastC, rootC): - try: - cryptlib_py.cryptCheckCert(lastC, rootC) - return True - except: - return False - return False - finally: - if not (c1 is None): - cryptlib_py.cryptDestroyCert(c1) - if not (c2 is None): - cryptlib_py.cryptDestroyCert(c2) - if not (lastC is None): - cryptlib_py.cryptDestroyCert(lastC) - if not (rootC is None): - cryptlib_py.cryptDestroyCert(rootC) - - - - def _checkChaining(self, lastC, rootC): - import cryptlib_py - import array - def compareNames(name): - try: - length = cryptlib_py.cryptGetAttributeString(lastC, name, None) - lastName = array.array('B', [0] * length) - cryptlib_py.cryptGetAttributeString(lastC, name, lastName) - lastName = lastName.tostring() - except cryptlib_py.CryptException, e: - if e[0] == cryptlib_py.CRYPT_ERROR_NOTFOUND: - lastName = None - try: - length = cryptlib_py.cryptGetAttributeString(rootC, name, None) - rootName = array.array('B', [0] * length) - cryptlib_py.cryptGetAttributeString(rootC, name, rootName) - rootName = rootName.tostring() - except cryptlib_py.CryptException, e: - if e[0] == cryptlib_py.CRYPT_ERROR_NOTFOUND: - rootName = None - - return lastName == rootName - - cryptlib_py.cryptSetAttribute(lastC, - cryptlib_py.CRYPT_CERTINFO_ISSUERNAME, - cryptlib_py.CRYPT_UNUSED) - - if not compareNames(cryptlib_py.CRYPT_CERTINFO_COUNTRYNAME): - return False - if not compareNames(cryptlib_py.CRYPT_CERTINFO_LOCALITYNAME): - return False - if not compareNames(cryptlib_py.CRYPT_CERTINFO_ORGANIZATIONNAME): - return False - if not compareNames(cryptlib_py.CRYPT_CERTINFO_ORGANIZATIONALUNITNAME): - return False - if not compareNames(cryptlib_py.CRYPT_CERTINFO_COMMONNAME): - return False - return True
\ No newline at end of file diff --git a/chromium/third_party/tlslite/tlslite/__init__.py b/chromium/third_party/tlslite/tlslite/__init__.py index 47cfd1c6f18..2a7589eef71 100644 --- a/chromium/third_party/tlslite/tlslite/__init__.py +++ b/chromium/third_party/tlslite/tlslite/__init__.py @@ -1,39 +1,28 @@ -""" -TLS Lite is a free python library that implements SSL v3, TLS v1, and -TLS v1.1. TLS Lite supports non-traditional authentication methods -such as SRP, shared keys, and cryptoIDs, in addition to X.509 -certificates. TLS Lite is pure python, however it can access OpenSSL, -cryptlib, pycrypto, and GMPY for faster crypto operations. TLS Lite -integrates with httplib, xmlrpclib, poplib, imaplib, smtplib, -SocketServer, asyncore, and Twisted. +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + +"""TLS Lite is a free 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. To use, do:: + from tlslite import TLSConnection, ... + +If you want to import the most useful objects, the cleanest way is: + from tlslite.api import * -Then use the L{tlslite.TLSConnection.TLSConnection} class with a socket, -or use one of the integration classes in L{tlslite.integration}. +Then use the L{tlslite.TLSConnection.TLSConnection} class with a socket. +(Or, use one of the integration classes in L{tlslite.integration}). -@version: 0.3.8 +@version: 0.4.6 """ -__version__ = "0.3.8" - -__all__ = ["api", - "BaseDB", - "Checker", - "constants", - "errors", - "FileObject", - "HandshakeSettings", - "mathtls", - "messages", - "Session", - "SessionCache", - "SharedKeyDB", - "TLSConnection", - "TLSRecordLayer", - "VerifierDB", - "X509", - "X509CertChain", - "integration", - "utils"] + +from tlslite.api import * +from tlslite.api import __version__ # Unsure why this is needed, but it is diff --git a/chromium/third_party/tlslite/tlslite/api.py b/chromium/third_party/tlslite/tlslite/api.py index eebfbc6091e..562fb811fac 100644 --- a/chromium/third_party/tlslite/tlslite/api.py +++ b/chromium/third_party/tlslite/tlslite/api.py @@ -1,75 +1,32 @@ -"""Import this module for easy access to TLS Lite objects. - -The TLS Lite API consists of classes, functions, and variables spread -throughout this package. Instead of importing them individually with:: - - from tlslite.TLSConnection import TLSConnection - from tlslite.HandshakeSettings import HandshakeSettings - from tlslite.errors import * - . - . - -It's easier to do:: - - from tlslite.api import * - -This imports all the important objects (TLSConnection, Checker, -HandshakeSettings, etc.) into the global namespace. In particular, it -imports:: - - from constants import AlertLevel, AlertDescription, Fault - from errors import * - from Checker import Checker - from HandshakeSettings import HandshakeSettings - from Session import Session - from SessionCache import SessionCache - from SharedKeyDB import SharedKeyDB - from TLSConnection import TLSConnection - from VerifierDB import VerifierDB - from X509 import X509 - from X509CertChain import X509CertChain - - from integration.HTTPTLSConnection import HTTPTLSConnection - from integration.POP3_TLS import POP3_TLS - from integration.IMAP4_TLS import IMAP4_TLS - from integration.SMTP_TLS import SMTP_TLS - from integration.XMLRPCTransport import XMLRPCTransport - from integration.TLSSocketServerMixIn import TLSSocketServerMixIn - from integration.TLSAsyncDispatcherMixIn import TLSAsyncDispatcherMixIn - from integration.TLSTwistedProtocolWrapper import TLSTwistedProtocolWrapper - from utils.cryptomath import cryptlibpyLoaded, m2cryptoLoaded, - gmpyLoaded, pycryptoLoaded, prngName - from utils.keyfactory import generateRSAKey, parsePEMKey, parseXMLKey, - parseAsPublicKey, parsePrivateKey -""" - -from constants import AlertLevel, AlertDescription, Fault -from errors import * -from Checker import Checker -from HandshakeSettings import HandshakeSettings -from Session import Session -from SessionCache import SessionCache -from SharedKeyDB import SharedKeyDB -from TLSConnection import TLSConnection -from VerifierDB import VerifierDB -from X509 import X509 -from X509CertChain import X509CertChain - -from integration.HTTPTLSConnection import HTTPTLSConnection -from integration.TLSSocketServerMixIn import TLSSocketServerMixIn -from integration.TLSAsyncDispatcherMixIn import TLSAsyncDispatcherMixIn -from integration.POP3_TLS import POP3_TLS -from integration.IMAP4_TLS import IMAP4_TLS -from integration.SMTP_TLS import SMTP_TLS -from integration.XMLRPCTransport import XMLRPCTransport -try: - import twisted - del(twisted) - from integration.TLSTwistedProtocolWrapper import TLSTwistedProtocolWrapper -except ImportError: - pass - -from utils.cryptomath import cryptlibpyLoaded, m2cryptoLoaded, gmpyLoaded, \ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + +__version__ = "0.4.6" +from .constants import AlertLevel, AlertDescription, ClientCertificateType, \ + Fault +from .errors import * +from .checker import Checker +from .handshakesettings import HandshakeSettings +from .session import Session +from .sessioncache import SessionCache +from .tlsconnection import TLSConnection +from .verifierdb import VerifierDB +from .x509 import X509 +from .x509certchain import X509CertChain + +from .integration.httptlsconnection import HTTPTLSConnection +from .integration.tlssocketservermixin import TLSSocketServerMixIn +from .integration.tlsasyncdispatchermixin import TLSAsyncDispatcherMixIn +from .integration.pop3_tls import POP3_TLS +from .integration.imap4_tls import IMAP4_TLS +from .integration.smtp_tls import SMTP_TLS +from .integration.xmlrpctransport import XMLRPCTransport +from .integration.xmlrpcserver import TLSXMLRPCRequestHandler, \ + TLSXMLRPCServer, \ + MultiPathTLSXMLRPCServer + +from .utils.cryptomath import m2cryptoLoaded, gmpyLoaded, \ pycryptoLoaded, prngName -from utils.keyfactory import generateRSAKey, parsePEMKey, parseXMLKey, \ +from .utils.keyfactory import generateRSAKey, parsePEMKey, \ parseAsPublicKey, parsePrivateKey +from .utils.tackwrapper import tackpyLoaded diff --git a/chromium/third_party/tlslite/tlslite/BaseDB.py b/chromium/third_party/tlslite/tlslite/basedb.py index 4988c1501cc..e6b79442f70 100644 --- a/chromium/third_party/tlslite/tlslite/BaseDB.py +++ b/chromium/third_party/tlslite/tlslite/basedb.py @@ -1,9 +1,19 @@ +# Authors: +# Trevor Perrin +# Martin von Loewis - python 3 port +# +# See the LICENSE file for legal information regarding use of this file. + """Base class for SharedKeyDB and VerifierDB.""" -import anydbm -import thread +try: + import anydbm +except ImportError: + # Python 3 + import dbm as anydbm +import threading -class BaseDB: +class BaseDB(object): def __init__(self, filename, type): self.type = type self.filename = filename @@ -11,7 +21,7 @@ class BaseDB: self.db = None else: self.db = {} - self.lock = thread.allocate_lock() + self.lock = threading.Lock() def create(self): """Create a new on-disk database. @@ -117,4 +127,4 @@ class BaseDB: finally: self.lock.release() usernames = [u for u in usernames if not u.startswith("--Reserved--")] - return usernames
\ No newline at end of file + return usernames diff --git a/chromium/third_party/tlslite/tlslite/checker.py b/chromium/third_party/tlslite/tlslite/checker.py new file mode 100644 index 00000000000..4f2ee820e0a --- /dev/null +++ b/chromium/third_party/tlslite/tlslite/checker.py @@ -0,0 +1,77 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + +"""Class for post-handshake certificate checking.""" + +from .x509 import X509 +from .x509certchain import X509CertChain +from .errors import * + + +class Checker(object): + """This class is passed to a handshake function to check the other + party's certificate chain. + + If a handshake function completes successfully, but the Checker + judges the other party's certificate chain to be missing or + inadequate, a subclass of + L{tlslite.errors.TLSAuthenticationError} will be raised. + + Currently, the Checker can check an X.509 chain. + """ + + def __init__(self, + x509Fingerprint=None, + checkResumedSession=False): + """Create a new Checker instance. + + You must pass in one of these argument combinations: + - x509Fingerprint + + @type x509Fingerprint: str + @param x509Fingerprint: A hex-encoded X.509 end-entity + fingerprint which the other party's end-entity certificate must + match. + + @type checkResumedSession: bool + @param checkResumedSession: If resumed sessions should be + checked. This defaults to False, on the theory that if the + session was checked once, we don't need to bother + re-checking it. + """ + + self.x509Fingerprint = x509Fingerprint + self.checkResumedSession = checkResumedSession + + def __call__(self, connection): + """Check a TLSConnection. + + When a Checker is passed to a handshake function, this will + be called at the end of the function. + + @type connection: L{tlslite.tlsconnection.TLSConnection} + @param connection: The TLSConnection to examine. + + @raise tlslite.errors.TLSAuthenticationError: If the other + party's certificate chain is missing or bad. + """ + if not self.checkResumedSession and connection.resumed: + return + + if self.x509Fingerprint: + if connection._client: + chain = connection.session.serverCertChain + else: + chain = connection.session.clientCertChain + + if self.x509Fingerprint: + if isinstance(chain, X509CertChain): + if self.x509Fingerprint: + if chain.getFingerprint() != self.x509Fingerprint: + raise TLSFingerprintError(\ + "X.509 fingerprint mismatch: %s, %s" % \ + (chain.getFingerprint(), self.x509Fingerprint)) + elif chain: + raise TLSAuthenticationTypeError() + else: + raise TLSNoAuthenticationError()
\ No newline at end of file diff --git a/chromium/third_party/tlslite/tlslite/constants.py b/chromium/third_party/tlslite/tlslite/constants.py index d027ef5f093..457b33934de 100644 --- a/chromium/third_party/tlslite/tlslite/constants.py +++ b/chromium/third_party/tlslite/tlslite/constants.py @@ -1,16 +1,28 @@ +# Authors: +# Trevor Perrin +# Google - defining ClientCertificateType +# Google (adapted by Sam Rushing) - NPN support +# Dimitris Moraitis - Anon ciphersuites +# Dave Baggett (Arcode Corporation) - canonicalCipherName +# +# See the LICENSE file for legal information regarding use of this file. + """Constants used in various places.""" class CertificateType: x509 = 0 openpgp = 1 - cryptoID = 2 class ClientCertificateType: + # http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-2 rsa_sign = 1 dss_sign = 2 rsa_fixed_dh = 3 dss_fixed_dh = 4 - + ecdsa_sign = 64 + rsa_fixed_ecdh = 65 + ecdsa_fixed_ecdh = 66 + class HandshakeType: hello_request = 0 client_hello = 1 @@ -23,6 +35,7 @@ class HandshakeType: client_key_exchange = 16 finished = 20 certificate_status = 22 + next_protocol = 67 encrypted_extensions = 203 class ContentType: @@ -35,10 +48,18 @@ class ContentType: class CertificateStatusType: ocsp = 1 -class ExtensionType: - status_request = 5 # OCSP stapling - signed_cert_timestamps = 18 # signed_certificate_timestamp in RFC 6962 - channel_id = 30031 +class ExtensionType: # RFC 6066 / 4366 + server_name = 0 # RFC 6066 / 4366 + status_request = 5 # RFC 6066 / 4366 + srp = 12 # RFC 5054 + cert_type = 9 # RFC 6091 + signed_cert_timestamps = 18 # RFC 6962 + tack = 0xF300 + supports_npn = 13172 + channel_id = 30032 + +class NameType: + host_name = 0 class AlertLevel: warning = 1 @@ -48,7 +69,7 @@ class AlertDescription: """ @cvar bad_record_mac: A TLS record failed to decrypt properly. - If this occurs during a shared-key or SRP handshake it most likely + If this occurs during a SRP handshake it most likely indicates a bad password. It may also indicate an implementation error, or some tampering with the data in transit. @@ -56,8 +77,6 @@ class AlertDescription: may also be signalled by the server if the SRP username is unknown to the server, but it doesn't wish to reveal that fact. - This alert will be signalled by the client if the shared-key username is - bad. @cvar handshake_failure: A problem occurred while handshaking. @@ -99,126 +118,232 @@ class AlertDescription: inappropriate_fallback = 86 user_canceled = 90 no_renegotiation = 100 - unknown_srp_username = 120 - missing_srp_username = 121 - untrusted_srp_parameters = 122 + unknown_psk_identity = 115 + class CipherSuite: - TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA = 0x0050 - TLS_SRP_SHA_WITH_AES_128_CBC_SHA = 0x0053 - TLS_SRP_SHA_WITH_AES_256_CBC_SHA = 0x0056 + # Weird pseudo-ciphersuite from RFC 5746 + # Signals that "secure renegotiation" is supported + # We actually don't do any renegotiation, but this + # prevents renegotiation attacks + TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0x00FF + + # draft-bmoeller-tls-downgrade-scsv-01 + TLS_FALLBACK_SCSV = 0x5600 + + TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA = 0xC01A + TLS_SRP_SHA_WITH_AES_128_CBC_SHA = 0xC01D + TLS_SRP_SHA_WITH_AES_256_CBC_SHA = 0xC020 + + TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA = 0xC01B + TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA = 0xC01E + TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA = 0xC021 - TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA = 0x0051 - TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA = 0x0054 - TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA = 0x0057 TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x000A TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035 TLS_RSA_WITH_RC4_128_SHA = 0x0005 + + TLS_RSA_WITH_RC4_128_MD5 = 0x0004 - srpSuites = [] - srpSuites.append(TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA) - srpSuites.append(TLS_SRP_SHA_WITH_AES_128_CBC_SHA) - srpSuites.append(TLS_SRP_SHA_WITH_AES_256_CBC_SHA) - def getSrpSuites(ciphers): - suites = [] - for cipher in ciphers: - if cipher == "aes128": - suites.append(CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA) - elif cipher == "aes256": - suites.append(CipherSuite.TLS_SRP_SHA_WITH_AES_256_CBC_SHA) - elif cipher == "3des": - suites.append(CipherSuite.TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA) - return suites - getSrpSuites = staticmethod(getSrpSuites) - - srpRsaSuites = [] - srpRsaSuites.append(TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA) - srpRsaSuites.append(TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA) - srpRsaSuites.append(TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA) - def getSrpRsaSuites(ciphers): - suites = [] - for cipher in ciphers: - if cipher == "aes128": - suites.append(CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA) - elif cipher == "aes256": - suites.append(CipherSuite.TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA) - elif cipher == "3des": - suites.append(CipherSuite.TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA) - return suites - getSrpRsaSuites = staticmethod(getSrpRsaSuites) - - rsaSuites = [] - rsaSuites.append(TLS_RSA_WITH_3DES_EDE_CBC_SHA) - rsaSuites.append(TLS_RSA_WITH_AES_128_CBC_SHA) - rsaSuites.append(TLS_RSA_WITH_AES_256_CBC_SHA) - rsaSuites.append(TLS_RSA_WITH_RC4_128_SHA) - def getRsaSuites(ciphers): - suites = [] - for cipher in ciphers: - if cipher == "aes128": - suites.append(CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA) - elif cipher == "aes256": - suites.append(CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA) - elif cipher == "rc4": - suites.append(CipherSuite.TLS_RSA_WITH_RC4_128_SHA) - elif cipher == "3des": - suites.append(CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA) - return suites - getRsaSuites = staticmethod(getRsaSuites) + TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x0016 + TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033 + TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039 + + TLS_DH_ANON_WITH_AES_128_CBC_SHA = 0x0034 + TLS_DH_ANON_WITH_AES_256_CBC_SHA = 0x003A tripleDESSuites = [] tripleDESSuites.append(TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA) tripleDESSuites.append(TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA) tripleDESSuites.append(TLS_RSA_WITH_3DES_EDE_CBC_SHA) + tripleDESSuites.append(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA) aes128Suites = [] aes128Suites.append(TLS_SRP_SHA_WITH_AES_128_CBC_SHA) aes128Suites.append(TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA) aes128Suites.append(TLS_RSA_WITH_AES_128_CBC_SHA) + aes128Suites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA) + aes128Suites.append(TLS_DH_ANON_WITH_AES_128_CBC_SHA) aes256Suites = [] aes256Suites.append(TLS_SRP_SHA_WITH_AES_256_CBC_SHA) aes256Suites.append(TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA) aes256Suites.append(TLS_RSA_WITH_AES_256_CBC_SHA) + aes256Suites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA) + aes256Suites.append(TLS_DH_ANON_WITH_AES_256_CBC_SHA) rc4Suites = [] rc4Suites.append(TLS_RSA_WITH_RC4_128_SHA) + rc4Suites.append(TLS_RSA_WITH_RC4_128_MD5) + + shaSuites = [] + shaSuites.append(TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA) + shaSuites.append(TLS_SRP_SHA_WITH_AES_128_CBC_SHA) + shaSuites.append(TLS_SRP_SHA_WITH_AES_256_CBC_SHA) + shaSuites.append(TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA) + shaSuites.append(TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA) + shaSuites.append(TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA) + shaSuites.append(TLS_RSA_WITH_3DES_EDE_CBC_SHA) + shaSuites.append(TLS_RSA_WITH_AES_128_CBC_SHA) + shaSuites.append(TLS_RSA_WITH_AES_256_CBC_SHA) + shaSuites.append(TLS_RSA_WITH_RC4_128_SHA) + shaSuites.append(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA) + shaSuites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA) + shaSuites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA) + shaSuites.append(TLS_DH_ANON_WITH_AES_128_CBC_SHA) + shaSuites.append(TLS_DH_ANON_WITH_AES_256_CBC_SHA) + + md5Suites = [] + md5Suites.append(TLS_RSA_WITH_RC4_128_MD5) + + @staticmethod + def _filterSuites(suites, settings): + macNames = settings.macNames + cipherNames = settings.cipherNames + keyExchangeNames = settings.keyExchangeNames + macSuites = [] + if "sha" in macNames: + macSuites += CipherSuite.shaSuites + if "md5" in macNames: + macSuites += CipherSuite.md5Suites + + cipherSuites = [] + if "aes128" in cipherNames: + cipherSuites += CipherSuite.aes128Suites + if "aes256" in cipherNames: + cipherSuites += CipherSuite.aes256Suites + if "3des" in cipherNames: + cipherSuites += CipherSuite.tripleDESSuites + if "rc4" in cipherNames: + cipherSuites += CipherSuite.rc4Suites + + keyExchangeSuites = [] + if "rsa" in keyExchangeNames: + keyExchangeSuites += CipherSuite.certSuites + if "dhe_rsa" in keyExchangeNames: + keyExchangeSuites += CipherSuite.dheCertSuites + if "srp_sha" in keyExchangeNames: + keyExchangeSuites += CipherSuite.srpSuites + if "srp_sha_rsa" in keyExchangeNames: + keyExchangeSuites += CipherSuite.srpCertSuites + if "dh_anon" in keyExchangeNames: + keyExchangeSuites += CipherSuite.anonSuites + + return [s for s in suites if s in macSuites and + s in cipherSuites and s in keyExchangeSuites] - + srpSuites = [] + srpSuites.append(TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA) + srpSuites.append(TLS_SRP_SHA_WITH_AES_128_CBC_SHA) + srpSuites.append(TLS_SRP_SHA_WITH_AES_256_CBC_SHA) + + @staticmethod + def getSrpSuites(settings): + return CipherSuite._filterSuites(CipherSuite.srpSuites, settings) + + srpCertSuites = [] + srpCertSuites.append(TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA) + srpCertSuites.append(TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA) + srpCertSuites.append(TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA) + + @staticmethod + def getSrpCertSuites(settings): + return CipherSuite._filterSuites(CipherSuite.srpCertSuites, settings) + + srpAllSuites = srpCertSuites + srpSuites + + @staticmethod + def getSrpAllSuites(settings): + return CipherSuite._filterSuites(CipherSuite.srpAllSuites, settings) + + certSuites = [] + certSuites.append(TLS_RSA_WITH_3DES_EDE_CBC_SHA) + certSuites.append(TLS_RSA_WITH_AES_128_CBC_SHA) + certSuites.append(TLS_RSA_WITH_AES_256_CBC_SHA) + certSuites.append(TLS_RSA_WITH_RC4_128_SHA) + certSuites.append(TLS_RSA_WITH_RC4_128_MD5) + + @staticmethod + def getCertSuites(settings): + return CipherSuite._filterSuites(CipherSuite.certSuites, settings) + + dheCertSuites = [] + dheCertSuites.append(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA) + dheCertSuites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA) + dheCertSuites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA) + + @staticmethod + def getDheCertSuites(settings): + return CipherSuite._filterSuites(CipherSuite.dheCertSuites, settings) + + certAllSuites = srpCertSuites + certSuites + dheCertSuites + + anonSuites = [] + anonSuites.append(TLS_DH_ANON_WITH_AES_128_CBC_SHA) + anonSuites.append(TLS_DH_ANON_WITH_AES_256_CBC_SHA) + + @staticmethod + def getAnonSuites(settings): + return CipherSuite._filterSuites(CipherSuite.anonSuites, settings) + + dhAllSuites = dheCertSuites + anonSuites + + @staticmethod + def canonicalCipherName(ciphersuite): + "Return the canonical name of the cipher whose number is provided." + if ciphersuite in CipherSuite.aes128Suites: + return "aes128" + elif ciphersuite in CipherSuite.aes256Suites: + return "aes256" + elif ciphersuite in CipherSuite.rc4Suites: + return "rc4" + elif ciphersuite in CipherSuite.tripleDESSuites: + return "3des" + else: + return None + + @staticmethod + def canonicalMacName(ciphersuite): + "Return the canonical name of the MAC whose number is provided." + if ciphersuite in CipherSuite.shaSuites: + return "sha" + elif ciphersuite in CipherSuite.md5Suites: + return "md5" + else: + return None + + +# The following faults are induced as part of testing. The faultAlerts +# dictionary describes the allowed alerts that may be triggered by these +# faults. class Fault: badUsername = 101 badPassword = 102 badA = 103 - clientSrpFaults = range(101,104) + clientSrpFaults = list(range(101,104)) badVerifyMessage = 601 - clientCertFaults = range(601,602) + clientCertFaults = list(range(601,602)) badPremasterPadding = 501 shortPremasterSecret = 502 - clientNoAuthFaults = range(501,503) - - badIdentifier = 401 - badSharedKey = 402 - clientSharedKeyFaults = range(401,403) + clientNoAuthFaults = list(range(501,503)) badB = 201 - serverFaults = range(201,202) + serverFaults = list(range(201,202)) badFinished = 300 badMAC = 301 badPadding = 302 - genericFaults = range(300,303) + genericFaults = list(range(300,303)) faultAlerts = {\ - badUsername: (AlertDescription.unknown_srp_username, \ + badUsername: (AlertDescription.unknown_psk_identity, \ AlertDescription.bad_record_mac),\ badPassword: (AlertDescription.bad_record_mac,),\ badA: (AlertDescription.illegal_parameter,),\ - badIdentifier: (AlertDescription.handshake_failure,),\ - badSharedKey: (AlertDescription.bad_record_mac,),\ badPremasterPadding: (AlertDescription.bad_record_mac,),\ shortPremasterSecret: (AlertDescription.bad_record_mac,),\ badVerifyMessage: (AlertDescription.decrypt_error,),\ @@ -231,8 +356,6 @@ class Fault: badUsername: "bad username",\ badPassword: "bad password",\ badA: "bad A",\ - badIdentifier: "bad identifier",\ - badSharedKey: "bad sharedkey",\ badPremasterPadding: "bad premaster padding",\ shortPremasterSecret: "short premaster secret",\ badVerifyMessage: "bad verify message",\ diff --git a/chromium/third_party/tlslite/tlslite/errors.py b/chromium/third_party/tlslite/tlslite/errors.py index 45087e6e079..001ef33e00b 100644 --- a/chromium/third_party/tlslite/tlslite/errors.py +++ b/chromium/third_party/tlslite/tlslite/errors.py @@ -1,13 +1,28 @@ +# Authors: +# Trevor Perrin +# Dave Baggett (Arcode Corporation) - Added TLSUnsupportedError. +# +# See the LICENSE file for legal information regarding use of this file. + """Exception classes. @sort: TLSError, TLSAbruptCloseError, TLSAlert, TLSLocalAlert, TLSRemoteAlert, TLSAuthenticationError, TLSNoAuthenticationError, TLSAuthenticationTypeError, -TLSFingerprintError, TLSAuthorizationError, TLSValidationError, TLSFaultError +TLSFingerprintError, TLSAuthorizationError, TLSValidationError, TLSFaultError, +TLSUnsupportedError """ +import socket -from constants import AlertDescription, AlertLevel +from .constants import AlertDescription, AlertLevel class TLSError(Exception): """Base class for all TLS Lite exceptions.""" + + def __str__(self): + """"At least print out the Exception time for str(...).""" + return repr(self) + +class TLSClosedConnectionError(TLSError, socket.error): + """An attempt was made to use the connection after it was closed.""" pass class TLSAbruptCloseError(TLSError): @@ -51,8 +66,7 @@ class TLSAlert(TLSError): AlertDescription.inappropriate_fallback: "inappropriate_fallback",\ AlertDescription.user_canceled: "user_canceled",\ AlertDescription.no_renegotiation: "no_renegotiation",\ - AlertDescription.unknown_srp_username: "unknown_srp_username",\ - AlertDescription.missing_srp_username: "missing_srp_username"} + AlertDescription.unknown_psk_identity: "unknown_psk_identity"} class TLSLocalAlert(TLSAlert): """A TLS alert has been signalled by the local implementation. @@ -138,7 +152,10 @@ class TLSAuthorizationError(TLSAuthenticationError): class TLSValidationError(TLSAuthenticationError): """The Checker has determined that the other party's certificate chain is invalid.""" - pass + def __init__(self, msg, info=None): + # Include a dict containing info about this validation failure + TLSAuthenticationError.__init__(self, msg) + self.info = info class TLSFaultError(TLSError): """The other party responded incorrectly to an induced fault. @@ -148,3 +165,9 @@ class TLSFaultError(TLSError): faulty behavior, and the other party doesn't respond appropriately. """ pass + + +class TLSUnsupportedError(TLSError): + """The implementation doesn't support the requested (or required) + capabilities.""" + pass diff --git a/chromium/third_party/tlslite/tlslite/HandshakeSettings.py b/chromium/third_party/tlslite/tlslite/handshakesettings.py index c7c3223e515..e0bc0e661c5 100644 --- a/chromium/third_party/tlslite/tlslite/HandshakeSettings.py +++ b/chromium/third_party/tlslite/tlslite/handshakesettings.py @@ -1,13 +1,28 @@ +# Authors: +# Trevor Perrin +# Dave Baggett (Arcode Corporation) - cleanup handling of constants +# +# See the LICENSE file for legal information regarding use of this file. + """Class for setting handshake parameters.""" -from constants import CertificateType -from utils import cryptomath -from utils import cipherfactory +from .constants import CertificateType +from .utils import cryptomath +from .utils import cipherfactory + +# RC4 is preferred as faster in Python, works in SSL3, and immune to CBC +# issues such as timing attacks +CIPHER_NAMES = ["rc4", "aes256", "aes128", "3des"] +MAC_NAMES = ["sha"] # Don't allow "md5" by default. +ALL_MAC_NAMES = ["sha", "md5"] +KEY_EXCHANGE_NAMES = ["rsa", "dhe_rsa", "srp_sha", "srp_sha_rsa", "dh_anon"] +CIPHER_IMPLEMENTATIONS = ["openssl", "pycrypto", "python"] +CERTIFICATE_TYPES = ["x509"] -class HandshakeSettings: +class HandshakeSettings(object): """This class encapsulates various parameters that can be used with a TLS handshake. - @sort: minKeySize, maxKeySize, cipherNames, certificateTypes, + @sort: minKeySize, maxKeySize, cipherNames, macNames, certificateTypes, minVersion, maxVersion @type minKeySize: int @@ -40,19 +55,25 @@ class HandshakeSettings: add-on library that supports 3DES, then '3des' will be silently removed. - The default value is ['aes256', 'aes128', '3des', 'rc4']. + The default value is ['rc4', 'aes256', 'aes128', '3des']. + + @type macNames: list + @ivar macNames: The allowed MAC algorithms. + + The allowed values in this list are 'sha' and 'md5'. + + The default value is ['sha']. + @type certificateTypes: list @ivar certificateTypes: The allowed certificate types, in order of preference. - The allowed values in this list are 'x509' and 'cryptoID'. This - list is only used with a client handshake. The client will - advertise to the server which certificate types are supported, and - will check that the server uses one of the appropriate types. + The only allowed certificate type is 'x509'. This list is only used with a + client handshake. The client will advertise to the server which certificate + types are supported, and will check that the server uses one of the + appropriate types. - NOTE: If 'cryptoID' is used in this list, but cryptoIDlib is not - installed, then 'cryptoID' will be silently removed. @type minVersion: tuple @ivar minVersion: The minimum allowed SSL/TLS version. @@ -71,23 +92,34 @@ class HandshakeSettings: The default is (3,2). (WARNING: Some servers may (improperly) reject clients which offer support for TLS 1.1. In this case, try lowering maxVersion to (3,1)). + + @type useExperimentalTackExtension: bool + @ivar useExperimentalTackExtension: Whether to enabled TACK support. + + Note that TACK support is not standardized by IETF and uses a temporary + TLS Extension number, so should NOT be used in production software. """ def __init__(self): self.minKeySize = 1023 self.maxKeySize = 8193 - self.cipherNames = ["aes256", "aes128", "3des", "rc4"] - self.cipherImplementations = ["cryptlib", "openssl", "pycrypto", - "python"] - self.certificateTypes = ["x509", "cryptoID"] + self.cipherNames = CIPHER_NAMES + self.macNames = MAC_NAMES + self.keyExchangeNames = KEY_EXCHANGE_NAMES + self.cipherImplementations = CIPHER_IMPLEMENTATIONS + self.certificateTypes = CERTIFICATE_TYPES self.minVersion = (3,0) self.maxVersion = (3,2) + self.useExperimentalTackExtension = False - #Filters out options that are not supported + # Validates the min/max fields, and certificateTypes + # Filters out unsupported cipherNames and cipherImplementations def _filter(self): other = HandshakeSettings() other.minKeySize = self.minKeySize other.maxKeySize = self.maxKeySize other.cipherNames = self.cipherNames + other.macNames = self.macNames + other.keyExchangeNames = self.keyExchangeNames other.cipherImplementations = self.cipherImplementations other.certificateTypes = self.certificateTypes other.minVersion = self.minVersion @@ -97,24 +129,15 @@ class HandshakeSettings: other.cipherNames = [e for e in self.cipherNames if e != "3des"] if len(other.cipherNames)==0: raise ValueError("No supported ciphers") - - try: - import cryptoIDlib - except ImportError: - other.certificateTypes = [e for e in self.certificateTypes \ - if e != "cryptoID"] if len(other.certificateTypes)==0: raise ValueError("No supported certificate types") - if not cryptomath.cryptlibpyLoaded: - other.cipherImplementations = [e for e in \ - self.cipherImplementations if e != "cryptlib"] if not cryptomath.m2cryptoLoaded: - other.cipherImplementations = [e for e in \ - other.cipherImplementations if e != "openssl"] + other.cipherImplementations = \ + [e for e in other.cipherImplementations if e != "openssl"] if not cryptomath.pycryptoLoaded: - other.cipherImplementations = [e for e in \ - other.cipherImplementations if e != "pycrypto"] + other.cipherImplementations = \ + [e for e in other.cipherImplementations if e != "pycrypto"] if len(other.cipherImplementations)==0: raise ValueError("No supported cipher implementations") @@ -127,13 +150,19 @@ class HandshakeSettings: if other.maxKeySize>16384: raise ValueError("maxKeySize too large") for s in other.cipherNames: - if s not in ("aes256", "aes128", "rc4", "3des"): + if s not in CIPHER_NAMES: raise ValueError("Unknown cipher name: '%s'" % s) + for s in other.macNames: + if s not in ALL_MAC_NAMES: + raise ValueError("Unknown MAC name: '%s'" % s) + for s in other.keyExchangeNames: + if s not in KEY_EXCHANGE_NAMES: + raise ValueError("Unknown key exchange name: '%s'" % s) for s in other.cipherImplementations: - if s not in ("cryptlib", "openssl", "python", "pycrypto"): + if s not in CIPHER_IMPLEMENTATIONS: raise ValueError("Unknown cipher implementation: '%s'" % s) for s in other.certificateTypes: - if s not in ("x509", "cryptoID"): + if s not in CERTIFICATE_TYPES: raise ValueError("Unknown certificate type: '%s'" % s) if other.minVersion > other.maxVersion: @@ -152,8 +181,6 @@ class HandshakeSettings: for ct in self.certificateTypes: if ct == "x509": l.append(CertificateType.x509) - elif ct == "cryptoID": - l.append(CertificateType.cryptoID) else: raise AssertionError() return l diff --git a/chromium/third_party/tlslite/tlslite/integration/ClientHelper.py b/chromium/third_party/tlslite/tlslite/integration/ClientHelper.py deleted file mode 100644 index 7918e4af43f..00000000000 --- a/chromium/third_party/tlslite/tlslite/integration/ClientHelper.py +++ /dev/null @@ -1,163 +0,0 @@ -""" -A helper class for using TLS Lite with stdlib clients -(httplib, xmlrpclib, imaplib, poplib). -""" - -from tlslite.Checker import Checker - -class ClientHelper: - """This is a helper class used to integrate TLS Lite with various - TLS clients (e.g. poplib, smtplib, httplib, etc.)""" - - def __init__(self, - username=None, password=None, sharedKey=None, - certChain=None, privateKey=None, - cryptoID=None, protocol=None, - x509Fingerprint=None, - x509TrustList=None, x509CommonName=None, - settings = None): - """ - For client authentication, use one of these argument - combinations: - - username, password (SRP) - - username, sharedKey (shared-key) - - certChain, privateKey (certificate) - - For server authentication, you can either rely on the - implicit mutual authentication performed by SRP or - shared-keys, or you can do certificate-based server - authentication with one of these argument combinations: - - cryptoID[, protocol] (requires cryptoIDlib) - - x509Fingerprint - - x509TrustList[, x509CommonName] (requires cryptlib_py) - - Certificate-based server authentication is compatible with - SRP or certificate-based client authentication. It is - not compatible with shared-keys. - - The constructor does not perform the TLS handshake itself, but - simply stores these arguments for later. The handshake is - performed only when this class needs to connect with the - server. Then you should be prepared to handle TLS-specific - exceptions. See the client handshake functions in - L{tlslite.TLSConnection.TLSConnection} for details on which - exceptions might be raised. - - @type username: str - @param username: SRP or shared-key username. Requires the - 'password' or 'sharedKey' argument. - - @type password: str - @param password: SRP password for mutual authentication. - Requires the 'username' argument. - - @type sharedKey: str - @param sharedKey: Shared key for mutual authentication. - Requires the 'username' argument. - - @type certChain: L{tlslite.X509CertChain.X509CertChain} or - L{cryptoIDlib.CertChain.CertChain} - @param certChain: Certificate chain for client authentication. - Requires the 'privateKey' argument. Excludes the SRP or - shared-key related arguments. - - @type privateKey: L{tlslite.utils.RSAKey.RSAKey} - @param privateKey: Private key for client authentication. - Requires the 'certChain' argument. Excludes the SRP or - shared-key related arguments. - - @type cryptoID: str - @param cryptoID: cryptoID for server authentication. Mutually - exclusive with the 'x509...' arguments. - - @type protocol: str - @param protocol: cryptoID protocol URI for server - authentication. Requires the 'cryptoID' argument. - - @type x509Fingerprint: str - @param x509Fingerprint: Hex-encoded X.509 fingerprint for - server authentication. Mutually exclusive with the 'cryptoID' - and 'x509TrustList' arguments. - - @type x509TrustList: list of L{tlslite.X509.X509} - @param x509TrustList: A list of trusted root certificates. The - other party must present a certificate chain which extends to - one of these root certificates. The cryptlib_py module must be - installed to use this parameter. Mutually exclusive with the - 'cryptoID' and 'x509Fingerprint' arguments. - - @type x509CommonName: str - @param x509CommonName: The end-entity certificate's 'CN' field - must match this value. For a web server, this is typically a - server name such as 'www.amazon.com'. Mutually exclusive with - the 'cryptoID' and 'x509Fingerprint' arguments. Requires the - 'x509TrustList' argument. - - @type settings: L{tlslite.HandshakeSettings.HandshakeSettings} - @param settings: Various settings which can be used to control - the ciphersuites, certificate types, and SSL/TLS versions - offered by the client. - """ - - self.username = None - self.password = None - self.sharedKey = None - self.certChain = None - self.privateKey = None - self.checker = None - - #SRP Authentication - if username and password and not \ - (sharedKey or certChain or privateKey): - self.username = username - self.password = password - - #Shared Key Authentication - elif username and sharedKey and not \ - (password or certChain or privateKey): - self.username = username - self.sharedKey = sharedKey - - #Certificate Chain Authentication - elif certChain and privateKey and not \ - (username or password or sharedKey): - self.certChain = certChain - self.privateKey = privateKey - - #No Authentication - elif not password and not username and not \ - sharedKey and not certChain and not privateKey: - pass - - else: - raise ValueError("Bad parameters") - - #Authenticate the server based on its cryptoID or fingerprint - if sharedKey and (cryptoID or protocol or x509Fingerprint): - raise ValueError("Can't use shared keys with other forms of"\ - "authentication") - - self.checker = Checker(cryptoID, protocol, x509Fingerprint, - x509TrustList, x509CommonName) - self.settings = settings - - self.tlsSession = None - - def _handshake(self, tlsConnection): - if self.username and self.password: - tlsConnection.handshakeClientSRP(username=self.username, - password=self.password, - checker=self.checker, - settings=self.settings, - session=self.tlsSession) - elif self.username and self.sharedKey: - tlsConnection.handshakeClientSharedKey(username=self.username, - sharedKey=self.sharedKey, - settings=self.settings) - else: - tlsConnection.handshakeClientCert(certChain=self.certChain, - privateKey=self.privateKey, - checker=self.checker, - settings=self.settings, - session=self.tlsSession) - self.tlsSession = tlsConnection.session
\ No newline at end of file diff --git a/chromium/third_party/tlslite/tlslite/integration/HTTPTLSConnection.py b/chromium/third_party/tlslite/tlslite/integration/HTTPTLSConnection.py deleted file mode 100644 index 051d8e68666..00000000000 --- a/chromium/third_party/tlslite/tlslite/integration/HTTPTLSConnection.py +++ /dev/null @@ -1,169 +0,0 @@ -"""TLS Lite + httplib.""" - -import socket -import httplib -from tlslite.TLSConnection import TLSConnection -from tlslite.integration.ClientHelper import ClientHelper - - -class HTTPBaseTLSConnection(httplib.HTTPConnection): - """This abstract class provides a framework for adding TLS support - to httplib.""" - - default_port = 443 - - def __init__(self, host, port=None, strict=None): - if strict == None: - #Python 2.2 doesn't support strict - httplib.HTTPConnection.__init__(self, host, port) - else: - httplib.HTTPConnection.__init__(self, host, port, strict) - - def connect(self): - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - if hasattr(sock, 'settimeout'): - sock.settimeout(10) - sock.connect((self.host, self.port)) - - #Use a TLSConnection to emulate a socket - self.sock = TLSConnection(sock) - - #When httplib closes this, close the socket - self.sock.closeSocket = True - self._handshake(self.sock) - - def _handshake(self, tlsConnection): - """Called to perform some sort of handshake. - - This method must be overridden in a subclass to do some type of - handshake. This method will be called after the socket has - been connected but before any data has been sent. If this - method does not raise an exception, the TLS connection will be - considered valid. - - This method may (or may not) be called every time an HTTP - request is performed, depending on whether the underlying HTTP - connection is persistent. - - @type tlsConnection: L{tlslite.TLSConnection.TLSConnection} - @param tlsConnection: The connection to perform the handshake - on. - """ - raise NotImplementedError() - - -class HTTPTLSConnection(HTTPBaseTLSConnection, ClientHelper): - """This class extends L{HTTPBaseTLSConnection} to support the - common types of handshaking.""" - - def __init__(self, host, port=None, - username=None, password=None, sharedKey=None, - certChain=None, privateKey=None, - cryptoID=None, protocol=None, - x509Fingerprint=None, - x509TrustList=None, x509CommonName=None, - settings = None): - """Create a new HTTPTLSConnection. - - For client authentication, use one of these argument - combinations: - - username, password (SRP) - - username, sharedKey (shared-key) - - certChain, privateKey (certificate) - - For server authentication, you can either rely on the - implicit mutual authentication performed by SRP or - shared-keys, or you can do certificate-based server - authentication with one of these argument combinations: - - cryptoID[, protocol] (requires cryptoIDlib) - - x509Fingerprint - - x509TrustList[, x509CommonName] (requires cryptlib_py) - - Certificate-based server authentication is compatible with - SRP or certificate-based client authentication. It is - not compatible with shared-keys. - - The constructor does not perform the TLS handshake itself, but - simply stores these arguments for later. The handshake is - performed only when this class needs to connect with the - server. Thus you should be prepared to handle TLS-specific - exceptions when calling methods inherited from - L{httplib.HTTPConnection} such as request(), connect(), and - send(). See the client handshake functions in - L{tlslite.TLSConnection.TLSConnection} for details on which - exceptions might be raised. - - @type host: str - @param host: Server to connect to. - - @type port: int - @param port: Port to connect to. - - @type username: str - @param username: SRP or shared-key username. Requires the - 'password' or 'sharedKey' argument. - - @type password: str - @param password: SRP password for mutual authentication. - Requires the 'username' argument. - - @type sharedKey: str - @param sharedKey: Shared key for mutual authentication. - Requires the 'username' argument. - - @type certChain: L{tlslite.X509CertChain.X509CertChain} or - L{cryptoIDlib.CertChain.CertChain} - @param certChain: Certificate chain for client authentication. - Requires the 'privateKey' argument. Excludes the SRP or - shared-key related arguments. - - @type privateKey: L{tlslite.utils.RSAKey.RSAKey} - @param privateKey: Private key for client authentication. - Requires the 'certChain' argument. Excludes the SRP or - shared-key related arguments. - - @type cryptoID: str - @param cryptoID: cryptoID for server authentication. Mutually - exclusive with the 'x509...' arguments. - - @type protocol: str - @param protocol: cryptoID protocol URI for server - authentication. Requires the 'cryptoID' argument. - - @type x509Fingerprint: str - @param x509Fingerprint: Hex-encoded X.509 fingerprint for - server authentication. Mutually exclusive with the 'cryptoID' - and 'x509TrustList' arguments. - - @type x509TrustList: list of L{tlslite.X509.X509} - @param x509TrustList: A list of trusted root certificates. The - other party must present a certificate chain which extends to - one of these root certificates. The cryptlib_py module must be - installed to use this parameter. Mutually exclusive with the - 'cryptoID' and 'x509Fingerprint' arguments. - - @type x509CommonName: str - @param x509CommonName: The end-entity certificate's 'CN' field - must match this value. For a web server, this is typically a - server name such as 'www.amazon.com'. Mutually exclusive with - the 'cryptoID' and 'x509Fingerprint' arguments. Requires the - 'x509TrustList' argument. - - @type settings: L{tlslite.HandshakeSettings.HandshakeSettings} - @param settings: Various settings which can be used to control - the ciphersuites, certificate types, and SSL/TLS versions - offered by the client. - """ - - HTTPBaseTLSConnection.__init__(self, host, port) - - ClientHelper.__init__(self, - username, password, sharedKey, - certChain, privateKey, - cryptoID, protocol, - x509Fingerprint, - x509TrustList, x509CommonName, - settings) - - def _handshake(self, tlsConnection): - ClientHelper._handshake(self, tlsConnection)
\ No newline at end of file diff --git a/chromium/third_party/tlslite/tlslite/integration/IMAP4_TLS.py b/chromium/third_party/tlslite/tlslite/integration/IMAP4_TLS.py deleted file mode 100644 index 0535801b188..00000000000 --- a/chromium/third_party/tlslite/tlslite/integration/IMAP4_TLS.py +++ /dev/null @@ -1,132 +0,0 @@ -"""TLS Lite + imaplib.""" - -import socket -from imaplib import IMAP4 -from tlslite.TLSConnection import TLSConnection -from tlslite.integration.ClientHelper import ClientHelper - -# IMAP TLS PORT -IMAP4_TLS_PORT = 993 - -class IMAP4_TLS(IMAP4, ClientHelper): - """This class extends L{imaplib.IMAP4} with TLS support.""" - - def __init__(self, host = '', port = IMAP4_TLS_PORT, - username=None, password=None, sharedKey=None, - certChain=None, privateKey=None, - cryptoID=None, protocol=None, - x509Fingerprint=None, - x509TrustList=None, x509CommonName=None, - settings=None): - """Create a new IMAP4_TLS. - - For client authentication, use one of these argument - combinations: - - username, password (SRP) - - username, sharedKey (shared-key) - - certChain, privateKey (certificate) - - For server authentication, you can either rely on the - implicit mutual authentication performed by SRP or - shared-keys, or you can do certificate-based server - authentication with one of these argument combinations: - - cryptoID[, protocol] (requires cryptoIDlib) - - x509Fingerprint - - x509TrustList[, x509CommonName] (requires cryptlib_py) - - Certificate-based server authentication is compatible with - SRP or certificate-based client authentication. It is - not compatible with shared-keys. - - The caller should be prepared to handle TLS-specific - exceptions. See the client handshake functions in - L{tlslite.TLSConnection.TLSConnection} for details on which - exceptions might be raised. - - @type host: str - @param host: Server to connect to. - - @type port: int - @param port: Port to connect to. - - @type username: str - @param username: SRP or shared-key username. Requires the - 'password' or 'sharedKey' argument. - - @type password: str - @param password: SRP password for mutual authentication. - Requires the 'username' argument. - - @type sharedKey: str - @param sharedKey: Shared key for mutual authentication. - Requires the 'username' argument. - - @type certChain: L{tlslite.X509CertChain.X509CertChain} or - L{cryptoIDlib.CertChain.CertChain} - @param certChain: Certificate chain for client authentication. - Requires the 'privateKey' argument. Excludes the SRP or - shared-key related arguments. - - @type privateKey: L{tlslite.utils.RSAKey.RSAKey} - @param privateKey: Private key for client authentication. - Requires the 'certChain' argument. Excludes the SRP or - shared-key related arguments. - - @type cryptoID: str - @param cryptoID: cryptoID for server authentication. Mutually - exclusive with the 'x509...' arguments. - - @type protocol: str - @param protocol: cryptoID protocol URI for server - authentication. Requires the 'cryptoID' argument. - - @type x509Fingerprint: str - @param x509Fingerprint: Hex-encoded X.509 fingerprint for - server authentication. Mutually exclusive with the 'cryptoID' - and 'x509TrustList' arguments. - - @type x509TrustList: list of L{tlslite.X509.X509} - @param x509TrustList: A list of trusted root certificates. The - other party must present a certificate chain which extends to - one of these root certificates. The cryptlib_py module must be - installed to use this parameter. Mutually exclusive with the - 'cryptoID' and 'x509Fingerprint' arguments. - - @type x509CommonName: str - @param x509CommonName: The end-entity certificate's 'CN' field - must match this value. For a web server, this is typically a - server name such as 'www.amazon.com'. Mutually exclusive with - the 'cryptoID' and 'x509Fingerprint' arguments. Requires the - 'x509TrustList' argument. - - @type settings: L{tlslite.HandshakeSettings.HandshakeSettings} - @param settings: Various settings which can be used to control - the ciphersuites, certificate types, and SSL/TLS versions - offered by the client. - """ - - ClientHelper.__init__(self, - username, password, sharedKey, - certChain, privateKey, - cryptoID, protocol, - x509Fingerprint, - x509TrustList, x509CommonName, - settings) - - IMAP4.__init__(self, host, port) - - - def open(self, host = '', port = IMAP4_TLS_PORT): - """Setup connection to remote server on "host:port". - - This connection will be used by the routines: - read, readline, send, shutdown. - """ - self.host = host - self.port = port - self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.sock.connect((host, port)) - self.sock = TLSConnection(self.sock) - self.sock.closeSocket = True - ClientHelper._handshake(self, self.sock) - self.file = self.sock.makefile('rb')
\ No newline at end of file diff --git a/chromium/third_party/tlslite/tlslite/integration/IntegrationHelper.py b/chromium/third_party/tlslite/tlslite/integration/IntegrationHelper.py deleted file mode 100644 index ca81a4865d9..00000000000 --- a/chromium/third_party/tlslite/tlslite/integration/IntegrationHelper.py +++ /dev/null @@ -1,52 +0,0 @@ - -class IntegrationHelper: - - def __init__(self, - username=None, password=None, sharedKey=None, - certChain=None, privateKey=None, - cryptoID=None, protocol=None, - x509Fingerprint=None, - x509TrustList=None, x509CommonName=None, - settings = None): - - self.username = None - self.password = None - self.sharedKey = None - self.certChain = None - self.privateKey = None - self.checker = None - - #SRP Authentication - if username and password and not \ - (sharedKey or certChain or privateKey): - self.username = username - self.password = password - - #Shared Key Authentication - elif username and sharedKey and not \ - (password or certChain or privateKey): - self.username = username - self.sharedKey = sharedKey - - #Certificate Chain Authentication - elif certChain and privateKey and not \ - (username or password or sharedKey): - self.certChain = certChain - self.privateKey = privateKey - - #No Authentication - elif not password and not username and not \ - sharedKey and not certChain and not privateKey: - pass - - else: - raise ValueError("Bad parameters") - - #Authenticate the server based on its cryptoID or fingerprint - if sharedKey and (cryptoID or protocol or x509Fingerprint): - raise ValueError("Can't use shared keys with other forms of"\ - "authentication") - - self.checker = Checker(cryptoID, protocol, x509Fingerprint, - x509TrustList, x509CommonName) - self.settings = settings
\ No newline at end of file diff --git a/chromium/third_party/tlslite/tlslite/integration/POP3_TLS.py b/chromium/third_party/tlslite/tlslite/integration/POP3_TLS.py deleted file mode 100644 index 71530cc5320..00000000000 --- a/chromium/third_party/tlslite/tlslite/integration/POP3_TLS.py +++ /dev/null @@ -1,142 +0,0 @@ -"""TLS Lite + poplib.""" - -import socket -from poplib import POP3 -from tlslite.TLSConnection import TLSConnection -from tlslite.integration.ClientHelper import ClientHelper - -# POP TLS PORT -POP3_TLS_PORT = 995 - -class POP3_TLS(POP3, ClientHelper): - """This class extends L{poplib.POP3} with TLS support.""" - - def __init__(self, host, port = POP3_TLS_PORT, - username=None, password=None, sharedKey=None, - certChain=None, privateKey=None, - cryptoID=None, protocol=None, - x509Fingerprint=None, - x509TrustList=None, x509CommonName=None, - settings=None): - """Create a new POP3_TLS. - - For client authentication, use one of these argument - combinations: - - username, password (SRP) - - username, sharedKey (shared-key) - - certChain, privateKey (certificate) - - For server authentication, you can either rely on the - implicit mutual authentication performed by SRP or - shared-keys, or you can do certificate-based server - authentication with one of these argument combinations: - - cryptoID[, protocol] (requires cryptoIDlib) - - x509Fingerprint - - x509TrustList[, x509CommonName] (requires cryptlib_py) - - Certificate-based server authentication is compatible with - SRP or certificate-based client authentication. It is - not compatible with shared-keys. - - The caller should be prepared to handle TLS-specific - exceptions. See the client handshake functions in - L{tlslite.TLSConnection.TLSConnection} for details on which - exceptions might be raised. - - @type host: str - @param host: Server to connect to. - - @type port: int - @param port: Port to connect to. - - @type username: str - @param username: SRP or shared-key username. Requires the - 'password' or 'sharedKey' argument. - - @type password: str - @param password: SRP password for mutual authentication. - Requires the 'username' argument. - - @type sharedKey: str - @param sharedKey: Shared key for mutual authentication. - Requires the 'username' argument. - - @type certChain: L{tlslite.X509CertChain.X509CertChain} or - L{cryptoIDlib.CertChain.CertChain} - @param certChain: Certificate chain for client authentication. - Requires the 'privateKey' argument. Excludes the SRP or - shared-key related arguments. - - @type privateKey: L{tlslite.utils.RSAKey.RSAKey} - @param privateKey: Private key for client authentication. - Requires the 'certChain' argument. Excludes the SRP or - shared-key related arguments. - - @type cryptoID: str - @param cryptoID: cryptoID for server authentication. Mutually - exclusive with the 'x509...' arguments. - - @type protocol: str - @param protocol: cryptoID protocol URI for server - authentication. Requires the 'cryptoID' argument. - - @type x509Fingerprint: str - @param x509Fingerprint: Hex-encoded X.509 fingerprint for - server authentication. Mutually exclusive with the 'cryptoID' - and 'x509TrustList' arguments. - - @type x509TrustList: list of L{tlslite.X509.X509} - @param x509TrustList: A list of trusted root certificates. The - other party must present a certificate chain which extends to - one of these root certificates. The cryptlib_py module must be - installed to use this parameter. Mutually exclusive with the - 'cryptoID' and 'x509Fingerprint' arguments. - - @type x509CommonName: str - @param x509CommonName: The end-entity certificate's 'CN' field - must match this value. For a web server, this is typically a - server name such as 'www.amazon.com'. Mutually exclusive with - the 'cryptoID' and 'x509Fingerprint' arguments. Requires the - 'x509TrustList' argument. - - @type settings: L{tlslite.HandshakeSettings.HandshakeSettings} - @param settings: Various settings which can be used to control - the ciphersuites, certificate types, and SSL/TLS versions - offered by the client. - """ - - self.host = host - self.port = port - msg = "getaddrinfo returns an empty list" - self.sock = None - for res in socket.getaddrinfo(self.host, self.port, 0, socket.SOCK_STREAM): - af, socktype, proto, canonname, sa = res - try: - self.sock = socket.socket(af, socktype, proto) - self.sock.connect(sa) - except socket.error, msg: - if self.sock: - self.sock.close() - self.sock = None - continue - break - if not self.sock: - raise socket.error, msg - - ### New code below (all else copied from poplib) - ClientHelper.__init__(self, - username, password, sharedKey, - certChain, privateKey, - cryptoID, protocol, - x509Fingerprint, - x509TrustList, x509CommonName, - settings) - - self.sock = TLSConnection(self.sock) - self.sock.closeSocket = True - ClientHelper._handshake(self, self.sock) - ### - - self.file = self.sock.makefile('rb') - self._debugging = 0 - self.welcome = self._getresp()
\ No newline at end of file diff --git a/chromium/third_party/tlslite/tlslite/integration/SMTP_TLS.py b/chromium/third_party/tlslite/tlslite/integration/SMTP_TLS.py deleted file mode 100644 index 8421523c146..00000000000 --- a/chromium/third_party/tlslite/tlslite/integration/SMTP_TLS.py +++ /dev/null @@ -1,114 +0,0 @@ -"""TLS Lite + smtplib.""" - -from smtplib import SMTP -from tlslite.TLSConnection import TLSConnection -from tlslite.integration.ClientHelper import ClientHelper - -class SMTP_TLS(SMTP): - """This class extends L{smtplib.SMTP} with TLS support.""" - - def starttls(self, - username=None, password=None, sharedKey=None, - certChain=None, privateKey=None, - cryptoID=None, protocol=None, - x509Fingerprint=None, - x509TrustList=None, x509CommonName=None, - settings=None): - """Puts the connection to the SMTP server into TLS mode. - - If the server supports TLS, this will encrypt the rest of the SMTP - session. - - For client authentication, use one of these argument - combinations: - - username, password (SRP) - - username, sharedKey (shared-key) - - certChain, privateKey (certificate) - - For server authentication, you can either rely on the - implicit mutual authentication performed by SRP or - shared-keys, or you can do certificate-based server - authentication with one of these argument combinations: - - cryptoID[, protocol] (requires cryptoIDlib) - - x509Fingerprint - - x509TrustList[, x509CommonName] (requires cryptlib_py) - - Certificate-based server authentication is compatible with - SRP or certificate-based client authentication. It is - not compatible with shared-keys. - - The caller should be prepared to handle TLS-specific - exceptions. See the client handshake functions in - L{tlslite.TLSConnection.TLSConnection} for details on which - exceptions might be raised. - - @type username: str - @param username: SRP or shared-key username. Requires the - 'password' or 'sharedKey' argument. - - @type password: str - @param password: SRP password for mutual authentication. - Requires the 'username' argument. - - @type sharedKey: str - @param sharedKey: Shared key for mutual authentication. - Requires the 'username' argument. - - @type certChain: L{tlslite.X509CertChain.X509CertChain} or - L{cryptoIDlib.CertChain.CertChain} - @param certChain: Certificate chain for client authentication. - Requires the 'privateKey' argument. Excludes the SRP or - shared-key related arguments. - - @type privateKey: L{tlslite.utils.RSAKey.RSAKey} - @param privateKey: Private key for client authentication. - Requires the 'certChain' argument. Excludes the SRP or - shared-key related arguments. - - @type cryptoID: str - @param cryptoID: cryptoID for server authentication. Mutually - exclusive with the 'x509...' arguments. - - @type protocol: str - @param protocol: cryptoID protocol URI for server - authentication. Requires the 'cryptoID' argument. - - @type x509Fingerprint: str - @param x509Fingerprint: Hex-encoded X.509 fingerprint for - server authentication. Mutually exclusive with the 'cryptoID' - and 'x509TrustList' arguments. - - @type x509TrustList: list of L{tlslite.X509.X509} - @param x509TrustList: A list of trusted root certificates. The - other party must present a certificate chain which extends to - one of these root certificates. The cryptlib_py module must be - installed to use this parameter. Mutually exclusive with the - 'cryptoID' and 'x509Fingerprint' arguments. - - @type x509CommonName: str - @param x509CommonName: The end-entity certificate's 'CN' field - must match this value. For a web server, this is typically a - server name such as 'www.amazon.com'. Mutually exclusive with - the 'cryptoID' and 'x509Fingerprint' arguments. Requires the - 'x509TrustList' argument. - - @type settings: L{tlslite.HandshakeSettings.HandshakeSettings} - @param settings: Various settings which can be used to control - the ciphersuites, certificate types, and SSL/TLS versions - offered by the client. - """ - (resp, reply) = self.docmd("STARTTLS") - if resp == 220: - helper = ClientHelper( - username, password, sharedKey, - certChain, privateKey, - cryptoID, protocol, - x509Fingerprint, - x509TrustList, x509CommonName, - settings) - conn = TLSConnection(self.sock) - conn.closeSocket = True - helper._handshake(conn) - self.sock = conn - self.file = conn.makefile('rb') - return (resp, reply)
\ No newline at end of file diff --git a/chromium/third_party/tlslite/tlslite/integration/TLSTwistedProtocolWrapper.py b/chromium/third_party/tlslite/tlslite/integration/TLSTwistedProtocolWrapper.py deleted file mode 100644 index 6e1b5cadbf0..00000000000 --- a/chromium/third_party/tlslite/tlslite/integration/TLSTwistedProtocolWrapper.py +++ /dev/null @@ -1,196 +0,0 @@ -"""TLS Lite + Twisted.""" - -from twisted.protocols.policies import ProtocolWrapper, WrappingFactory -from twisted.python.failure import Failure - -from AsyncStateMachine import AsyncStateMachine -from tlslite.TLSConnection import TLSConnection -from tlslite.errors import * - -import socket -import errno - - -#The TLSConnection is created around a "fake socket" that -#plugs it into the underlying Twisted transport -class _FakeSocket: - def __init__(self, wrapper): - self.wrapper = wrapper - self.data = "" - - def send(self, data): - ProtocolWrapper.write(self.wrapper, data) - return len(data) - - def recv(self, numBytes): - if self.data == "": - raise socket.error, (errno.EWOULDBLOCK, "") - returnData = self.data[:numBytes] - self.data = self.data[numBytes:] - return returnData - -class TLSTwistedProtocolWrapper(ProtocolWrapper, AsyncStateMachine): - """This class can wrap Twisted protocols to add TLS support. - - 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() - - This class works as follows: - - Data comes in and is given to the AsyncStateMachine for handling. - AsyncStateMachine will forward events to this class, and we'll - pass them on to the ProtocolHandler, which will proxy them to the - wrapped protocol. The wrapped protocol may then call back into - this class, and these calls will be proxied into the - AsyncStateMachine. - - The call graph looks like this: - - self.dataReceived - - AsyncStateMachine.inReadEvent - - self.out(Connect|Close|Read)Event - - ProtocolWrapper.(connectionMade|loseConnection|dataReceived) - - self.(loseConnection|write|writeSequence) - - AsyncStateMachine.(setCloseOp|setWriteOp) - """ - - #WARNING: IF YOU COPY-AND-PASTE THE ABOVE CODE, BE SURE TO REMOVE - #THE EXTRA ESCAPING AROUND "\\r\\n" - - def __init__(self, factory, wrappedProtocol): - ProtocolWrapper.__init__(self, factory, wrappedProtocol) - AsyncStateMachine.__init__(self) - self.fakeSocket = _FakeSocket(self) - self.tlsConnection = TLSConnection(self.fakeSocket) - self.tlsStarted = False - self.connectionLostCalled = False - - def connectionMade(self): - try: - ProtocolWrapper.connectionMade(self) - except TLSError, e: - self.connectionLost(Failure(e)) - ProtocolWrapper.loseConnection(self) - - def dataReceived(self, data): - try: - if not self.tlsStarted: - ProtocolWrapper.dataReceived(self, data) - else: - self.fakeSocket.data += data - while self.fakeSocket.data: - AsyncStateMachine.inReadEvent(self) - except TLSError, e: - self.connectionLost(Failure(e)) - ProtocolWrapper.loseConnection(self) - - def connectionLost(self, reason): - if not self.connectionLostCalled: - ProtocolWrapper.connectionLost(self, reason) - self.connectionLostCalled = True - - - def outConnectEvent(self): - ProtocolWrapper.connectionMade(self) - - def outCloseEvent(self): - ProtocolWrapper.loseConnection(self) - - def outReadEvent(self, data): - if data == "": - ProtocolWrapper.loseConnection(self) - else: - ProtocolWrapper.dataReceived(self, data) - - - def setServerHandshakeOp(self, **args): - self.tlsStarted = True - AsyncStateMachine.setServerHandshakeOp(self, **args) - - def loseConnection(self): - if not self.tlsStarted: - ProtocolWrapper.loseConnection(self) - else: - AsyncStateMachine.setCloseOp(self) - - def write(self, data): - if not self.tlsStarted: - ProtocolWrapper.write(self, data) - else: - #Because of the FakeSocket, write operations are guaranteed to - #terminate immediately. - AsyncStateMachine.setWriteOp(self, data) - - def writeSequence(self, seq): - if not self.tlsStarted: - ProtocolWrapper.writeSequence(self, seq) - else: - #Because of the FakeSocket, write operations are guaranteed to - #terminate immediately. - AsyncStateMachine.setWriteOp(self, "".join(seq))
\ No newline at end of file diff --git a/chromium/third_party/tlslite/tlslite/integration/XMLRPCTransport.py b/chromium/third_party/tlslite/tlslite/integration/XMLRPCTransport.py deleted file mode 100644 index 87a035d2ca6..00000000000 --- a/chromium/third_party/tlslite/tlslite/integration/XMLRPCTransport.py +++ /dev/null @@ -1,137 +0,0 @@ -"""TLS Lite + xmlrpclib.""" - -import xmlrpclib -import httplib -from tlslite.integration.HTTPTLSConnection import HTTPTLSConnection -from tlslite.integration.ClientHelper import ClientHelper - - -class XMLRPCTransport(xmlrpclib.Transport, ClientHelper): - """Handles an HTTPS transaction to an XML-RPC server.""" - - def __init__(self, - username=None, password=None, sharedKey=None, - certChain=None, privateKey=None, - cryptoID=None, protocol=None, - x509Fingerprint=None, - x509TrustList=None, x509CommonName=None, - settings=None): - """Create a new XMLRPCTransport. - - An instance of this class can be passed to L{xmlrpclib.ServerProxy} - to use TLS with XML-RPC calls:: - - from tlslite.api import XMLRPCTransport - from xmlrpclib import ServerProxy - - transport = XMLRPCTransport(user="alice", password="abra123") - server = ServerProxy("https://localhost", transport) - - For client authentication, use one of these argument - combinations: - - username, password (SRP) - - username, sharedKey (shared-key) - - certChain, privateKey (certificate) - - For server authentication, you can either rely on the - implicit mutual authentication performed by SRP or - shared-keys, or you can do certificate-based server - authentication with one of these argument combinations: - - cryptoID[, protocol] (requires cryptoIDlib) - - x509Fingerprint - - x509TrustList[, x509CommonName] (requires cryptlib_py) - - Certificate-based server authentication is compatible with - SRP or certificate-based client authentication. It is - not compatible with shared-keys. - - The constructor does not perform the TLS handshake itself, but - simply stores these arguments for later. The handshake is - performed only when this class needs to connect with the - server. Thus you should be prepared to handle TLS-specific - exceptions when calling methods of L{xmlrpclib.ServerProxy}. See the - client handshake functions in - L{tlslite.TLSConnection.TLSConnection} for details on which - exceptions might be raised. - - @type username: str - @param username: SRP or shared-key username. Requires the - 'password' or 'sharedKey' argument. - - @type password: str - @param password: SRP password for mutual authentication. - Requires the 'username' argument. - - @type sharedKey: str - @param sharedKey: Shared key for mutual authentication. - Requires the 'username' argument. - - @type certChain: L{tlslite.X509CertChain.X509CertChain} or - L{cryptoIDlib.CertChain.CertChain} - @param certChain: Certificate chain for client authentication. - Requires the 'privateKey' argument. Excludes the SRP or - shared-key related arguments. - - @type privateKey: L{tlslite.utils.RSAKey.RSAKey} - @param privateKey: Private key for client authentication. - Requires the 'certChain' argument. Excludes the SRP or - shared-key related arguments. - - @type cryptoID: str - @param cryptoID: cryptoID for server authentication. Mutually - exclusive with the 'x509...' arguments. - - @type protocol: str - @param protocol: cryptoID protocol URI for server - authentication. Requires the 'cryptoID' argument. - - @type x509Fingerprint: str - @param x509Fingerprint: Hex-encoded X.509 fingerprint for - server authentication. Mutually exclusive with the 'cryptoID' - and 'x509TrustList' arguments. - - @type x509TrustList: list of L{tlslite.X509.X509} - @param x509TrustList: A list of trusted root certificates. The - other party must present a certificate chain which extends to - one of these root certificates. The cryptlib_py module must be - installed to use this parameter. Mutually exclusive with the - 'cryptoID' and 'x509Fingerprint' arguments. - - @type x509CommonName: str - @param x509CommonName: The end-entity certificate's 'CN' field - must match this value. For a web server, this is typically a - server name such as 'www.amazon.com'. Mutually exclusive with - the 'cryptoID' and 'x509Fingerprint' arguments. Requires the - 'x509TrustList' argument. - - @type settings: L{tlslite.HandshakeSettings.HandshakeSettings} - @param settings: Various settings which can be used to control - the ciphersuites, certificate types, and SSL/TLS versions - offered by the client. - """ - - ClientHelper.__init__(self, - username, password, sharedKey, - certChain, privateKey, - cryptoID, protocol, - x509Fingerprint, - x509TrustList, x509CommonName, - settings) - - - def make_connection(self, host): - # create a HTTPS connection object from a host descriptor - host, extra_headers, x509 = self.get_host_info(host) - http = HTTPTLSConnection(host, None, - self.username, self.password, - self.sharedKey, - self.certChain, self.privateKey, - self.checker.cryptoID, - self.checker.protocol, - self.checker.x509Fingerprint, - self.checker.x509TrustList, - self.checker.x509CommonName, - self.settings) - http2 = httplib.HTTP() - http2._setup(http) - return http2
\ No newline at end of file diff --git a/chromium/third_party/tlslite/tlslite/integration/__init__.py b/chromium/third_party/tlslite/tlslite/integration/__init__.py index 960f4065f26..663dfb6de4a 100644 --- a/chromium/third_party/tlslite/tlslite/integration/__init__.py +++ b/chromium/third_party/tlslite/tlslite/integration/__init__.py @@ -1,17 +1,13 @@ -"""Classes for integrating TLS Lite with other packages.""" +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. -__all__ = ["AsyncStateMachine", - "HTTPTLSConnection", - "POP3_TLS", - "IMAP4_TLS", - "SMTP_TLS", - "XMLRPCTransport", - "TLSSocketServerMixIn", - "TLSAsyncDispatcherMixIn", - "TLSTwistedProtocolWrapper"] +"""Classes for integrating TLS Lite with other packages.""" -try: - import twisted - del twisted -except ImportError: - del __all__[__all__.index("TLSTwistedProtocolWrapper")] +__all__ = ["asyncstatemachine", + "httptlsconnection", + "pop3_tls", + "imap4_tls", + "smtp_tls", + "xmlrpctransport", + "tlssocketservermixin", + "tlsasyncdispatchermixin"] diff --git a/chromium/third_party/tlslite/tlslite/integration/AsyncStateMachine.py b/chromium/third_party/tlslite/tlslite/integration/asyncstatemachine.py index 01c7efe688e..50a6f4a355c 100644 --- a/chromium/third_party/tlslite/tlslite/integration/AsyncStateMachine.py +++ b/chromium/third_party/tlslite/tlslite/integration/asyncstatemachine.py @@ -1,3 +1,6 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + """ A state machine for using TLS Lite with asynchronous I/O. """ @@ -203,7 +206,7 @@ class AsyncStateMachine: """Start a handshake operation. The arguments passed to this function will be forwarded to - L{tlslite.TLSConnection.TLSConnection.handshakeServerAsync}. + L{tlslite.tlsconnection.TLSConnection.handshakeServerAsync}. """ handshaker = self.tlsConnection.handshakeServerAsync(**args) self.setHandshakeOp(handshaker) diff --git a/chromium/third_party/tlslite/tlslite/integration/clienthelper.py b/chromium/third_party/tlslite/tlslite/integration/clienthelper.py new file mode 100644 index 00000000000..62e59616499 --- /dev/null +++ b/chromium/third_party/tlslite/tlslite/integration/clienthelper.py @@ -0,0 +1,122 @@ +# Authors: +# Trevor Perrin +# Dimitris Moraitis - Anon ciphersuites +# +# See the LICENSE file for legal information regarding use of this file. + +""" +A helper class for using TLS Lite with stdlib clients +(httplib, xmlrpclib, imaplib, poplib). +""" + +from tlslite.checker import Checker + +class ClientHelper(object): + """This is a helper class used to integrate TLS Lite with various + TLS clients (e.g. poplib, smtplib, httplib, etc.)""" + + def __init__(self, + username=None, password=None, + certChain=None, privateKey=None, + checker=None, + settings = None, + anon = False): + """ + For client authentication, use one of these argument + combinations: + - username, password (SRP) + - certChain, privateKey (certificate) + + For server authentication, you can either rely on the + implicit mutual authentication performed by SRP, + or you can do certificate-based server + authentication with one of these argument combinations: + - x509Fingerprint + + Certificate-based server authentication is compatible with + SRP or certificate-based client authentication. + + The constructor does not perform the TLS handshake itself, but + simply stores these arguments for later. The handshake is + performed only when this class needs to connect with the + server. Then you should be prepared to handle TLS-specific + exceptions. See the client handshake functions in + L{tlslite.TLSConnection.TLSConnection} for details on which + exceptions might be raised. + + @type username: str + @param username: SRP username. Requires the + 'password' argument. + + @type password: str + @param password: SRP password for mutual authentication. + Requires the 'username' argument. + + @type certChain: L{tlslite.x509certchain.X509CertChain} + @param certChain: Certificate chain for client authentication. + Requires the 'privateKey' argument. Excludes the SRP arguments. + + @type privateKey: L{tlslite.utils.rsakey.RSAKey} + @param privateKey: Private key for client authentication. + Requires the 'certChain' argument. Excludes the SRP arguments. + + @type checker: L{tlslite.checker.Checker} + @param checker: Callable object called after handshaking to + evaluate the connection and raise an Exception if necessary. + + @type settings: L{tlslite.handshakesettings.HandshakeSettings} + @param settings: Various settings which can be used to control + the ciphersuites, certificate types, and SSL/TLS versions + offered by the client. + """ + + self.username = None + self.password = None + self.certChain = None + self.privateKey = None + self.checker = None + self.anon = anon + + #SRP Authentication + if username and password and not \ + (certChain or privateKey): + self.username = username + self.password = password + + #Certificate Chain Authentication + elif certChain and privateKey and not \ + (username or password): + self.certChain = certChain + self.privateKey = privateKey + + #No Authentication + elif not password and not username and not \ + certChain and not privateKey: + pass + + else: + raise ValueError("Bad parameters") + + self.checker = checker + self.settings = settings + + self.tlsSession = None + + def _handshake(self, tlsConnection): + if self.username and self.password: + tlsConnection.handshakeClientSRP(username=self.username, + password=self.password, + checker=self.checker, + settings=self.settings, + session=self.tlsSession) + elif self.anon: + tlsConnection.handshakeClientAnonymous(session=self.tlsSession, + settings=self.settings, + checker=self.checker) + else: + tlsConnection.handshakeClientCert(certChain=self.certChain, + privateKey=self.privateKey, + checker=self.checker, + settings=self.settings, + session=self.tlsSession) + self.tlsSession = tlsConnection.session
\ No newline at end of file diff --git a/chromium/third_party/tlslite/tlslite/integration/httptlsconnection.py b/chromium/third_party/tlslite/tlslite/integration/httptlsconnection.py new file mode 100644 index 00000000000..d8a002f9a7c --- /dev/null +++ b/chromium/third_party/tlslite/tlslite/integration/httptlsconnection.py @@ -0,0 +1,112 @@ +# Authors: +# Trevor Perrin +# Kees Bos - Added ignoreAbruptClose parameter +# Dimitris Moraitis - Anon ciphersuites +# Martin von Loewis - python 3 port +# +# See the LICENSE file for legal information regarding use of this file. + +"""TLS Lite + httplib.""" + +import socket +try: + import httplib +except ImportError: + # Python 3 + from http import client as httplib +from tlslite.tlsconnection import TLSConnection +from tlslite.integration.clienthelper import ClientHelper + + +class HTTPTLSConnection(httplib.HTTPConnection, ClientHelper): + """This class extends L{httplib.HTTPConnection} to support TLS.""" + + def __init__(self, host, port=None, strict=None, + timeout=socket._GLOBAL_DEFAULT_TIMEOUT, + source_address=None, + username=None, password=None, + certChain=None, privateKey=None, + checker=None, + settings=None, + ignoreAbruptClose=False, + anon=False): + """Create a new HTTPTLSConnection. + + For client authentication, use one of these argument + combinations: + - username, password (SRP) + - certChain, privateKey (certificate) + + For server authentication, you can either rely on the + implicit mutual authentication performed by SRP + or you can do certificate-based server + authentication with one of these argument combinations: + - x509Fingerprint + + Certificate-based server authentication is compatible with + SRP or certificate-based client authentication. + + The constructor does not perform the TLS handshake itself, but + simply stores these arguments for later. The handshake is + performed only when this class needs to connect with the + server. Thus you should be prepared to handle TLS-specific + exceptions when calling methods inherited from + L{httplib.HTTPConnection} such as request(), connect(), and + send(). See the client handshake functions in + L{tlslite.TLSConnection.TLSConnection} for details on which + exceptions might be raised. + + @type host: str + @param host: Server to connect to. + + @type port: int + @param port: Port to connect to. + + @type username: str + @param username: SRP username. Requires the + 'password' argument. + + @type password: str + @param password: SRP password for mutual authentication. + Requires the 'username' argument. + + @type certChain: L{tlslite.x509certchain.X509CertChain} or + @param certChain: Certificate chain for client authentication. + Requires the 'privateKey' argument. Excludes the SRP arguments. + + @type privateKey: L{tlslite.utils.rsakey.RSAKey} + @param privateKey: Private key for client authentication. + Requires the 'certChain' argument. Excludes the SRP arguments. + + @type checker: L{tlslite.checker.Checker} + @param checker: Callable object called after handshaking to + evaluate the connection and raise an Exception if necessary. + + @type settings: L{tlslite.handshakesettings.HandshakeSettings} + @param settings: Various settings which can be used to control + the ciphersuites, certificate types, and SSL/TLS versions + offered by the client. + + @type ignoreAbruptClose: bool + @param ignoreAbruptClose: ignore the TLSAbruptCloseError on + unexpected hangup. + """ + if source_address: + httplib.HTTPConnection.__init__(self, host, port, strict, + timeout, source_address) + if not source_address: + httplib.HTTPConnection.__init__(self, host, port, strict, + timeout) + self.ignoreAbruptClose = ignoreAbruptClose + ClientHelper.__init__(self, + username, password, + certChain, privateKey, + checker, + settings, + anon) + + def connect(self): + httplib.HTTPConnection.connect(self) + self.sock = TLSConnection(self.sock) + self.sock.ignoreAbruptClose = self.ignoreAbruptClose + ClientHelper._handshake(self, self.sock) diff --git a/chromium/third_party/tlslite/tlslite/integration/imap4_tls.py b/chromium/third_party/tlslite/tlslite/integration/imap4_tls.py new file mode 100644 index 00000000000..4703a316279 --- /dev/null +++ b/chromium/third_party/tlslite/tlslite/integration/imap4_tls.py @@ -0,0 +1,96 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + +"""TLS Lite + imaplib.""" + +import socket +from imaplib import IMAP4 +from tlslite.tlsconnection import TLSConnection +from tlslite.integration.clienthelper import ClientHelper + +# IMAP TLS PORT +IMAP4_TLS_PORT = 993 + +class IMAP4_TLS(IMAP4, ClientHelper): + """This class extends L{imaplib.IMAP4} with TLS support.""" + + def __init__(self, host = '', port = IMAP4_TLS_PORT, + username=None, password=None, + certChain=None, privateKey=None, + checker=None, + settings=None): + """Create a new IMAP4_TLS. + + For client authentication, use one of these argument + combinations: + - username, password (SRP) + - certChain, privateKey (certificate) + + For server authentication, you can either rely on the + implicit mutual authentication performed by SRP + or you can do certificate-based server + authentication with one of these argument combinations: + - x509Fingerprint + + Certificate-based server authentication is compatible with + SRP or certificate-based client authentication. + + The caller should be prepared to handle TLS-specific + exceptions. See the client handshake functions in + L{tlslite.TLSConnection.TLSConnection} for details on which + exceptions might be raised. + + @type host: str + @param host: Server to connect to. + + @type port: int + @param port: Port to connect to. + + @type username: str + @param username: SRP username. Requires the + 'password' argument. + + @type password: str + @param password: SRP password for mutual authentication. + Requires the 'username' argument. + + @type certChain: L{tlslite.x509certchain.X509CertChain} + @param certChain: Certificate chain for client authentication. + Requires the 'privateKey' argument. Excludes the SRP arguments. + + @type privateKey: L{tlslite.utils.rsakey.RSAKey} + @param privateKey: Private key for client authentication. + Requires the 'certChain' argument. Excludes the SRP arguments. + + @type checker: L{tlslite.checker.Checker} + @param checker: Callable object called after handshaking to + evaluate the connection and raise an Exception if necessary. + + @type settings: L{tlslite.handshakesettings.HandshakeSettings} + @param settings: Various settings which can be used to control + the ciphersuites, certificate types, and SSL/TLS versions + offered by the client. + """ + + ClientHelper.__init__(self, + username, password, + certChain, privateKey, + checker, + settings) + + IMAP4.__init__(self, host, port) + + + def open(self, host = '', port = IMAP4_TLS_PORT): + """Setup connection to remote server on "host:port". + + This connection will be used by the routines: + read, readline, send, shutdown. + """ + self.host = host + self.port = port + self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.sock.connect((host, port)) + self.sock = TLSConnection(self.sock) + ClientHelper._handshake(self, self.sock) + self.file = self.sock.makefile('rb')
\ No newline at end of file diff --git a/chromium/third_party/tlslite/tlslite/integration/pop3_tls.py b/chromium/third_party/tlslite/tlslite/integration/pop3_tls.py new file mode 100644 index 00000000000..64f6124e125 --- /dev/null +++ b/chromium/third_party/tlslite/tlslite/integration/pop3_tls.py @@ -0,0 +1,84 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + +"""TLS Lite + poplib.""" + +import socket +from poplib import POP3, POP3_SSL_PORT +from tlslite.tlsconnection import TLSConnection +from tlslite.integration.clienthelper import ClientHelper + +class POP3_TLS(POP3, ClientHelper): + """This class extends L{poplib.POP3} with TLS support.""" + + def __init__(self, host, port = POP3_SSL_PORT, + timeout=socket._GLOBAL_DEFAULT_TIMEOUT, + username=None, password=None, + certChain=None, privateKey=None, + checker=None, + settings=None): + """Create a new POP3_TLS. + + For client authentication, use one of these argument + combinations: + - username, password (SRP) + - certChain, privateKey (certificate) + + For server authentication, you can either rely on the + implicit mutual authentication performed by SRP or + you can do certificate-based server + authentication with one of these argument combinations: + - x509Fingerprint + + Certificate-based server authentication is compatible with + SRP or certificate-based client authentication. + + The caller should be prepared to handle TLS-specific + exceptions. See the client handshake functions in + L{tlslite.TLSConnection.TLSConnection} for details on which + exceptions might be raised. + + @type host: str + @param host: Server to connect to. + + @type port: int + @param port: Port to connect to. + + @type username: str + @param username: SRP username. + + @type password: str + @param password: SRP password for mutual authentication. + Requires the 'username' argument. + + @type certChain: L{tlslite.x509certchain.X509CertChain} + @param certChain: Certificate chain for client authentication. + Requires the 'privateKey' argument. Excludes the SRP argument. + + @type privateKey: L{tlslite.utils.rsakey.RSAKey} + @param privateKey: Private key for client authentication. + Requires the 'certChain' argument. Excludes the SRP argument. + + @type checker: L{tlslite.checker.Checker} + @param checker: Callable object called after handshaking to + evaluate the connection and raise an Exception if necessary. + + @type settings: L{tlslite.handshakesettings.HandshakeSettings} + @param settings: Various settings which can be used to control + the ciphersuites, certificate types, and SSL/TLS versions + offered by the client. + """ + self.host = host + self.port = port + sock = socket.create_connection((host, port), timeout) + ClientHelper.__init__(self, + username, password, + certChain, privateKey, + checker, + settings) + connection = TLSConnection(sock) + ClientHelper._handshake(self, connection) + self.sock = connection + self.file = self.sock.makefile('rb') + self._debugging = 0 + self.welcome = self._getresp()
\ No newline at end of file diff --git a/chromium/third_party/tlslite/tlslite/integration/smtp_tls.py b/chromium/third_party/tlslite/tlslite/integration/smtp_tls.py new file mode 100644 index 00000000000..d42147324bd --- /dev/null +++ b/chromium/third_party/tlslite/tlslite/integration/smtp_tls.py @@ -0,0 +1,78 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + +"""TLS Lite + smtplib.""" + +from smtplib import SMTP +from tlslite.tlsconnection import TLSConnection +from tlslite.integration.clienthelper import ClientHelper + +class SMTP_TLS(SMTP): + """This class extends L{smtplib.SMTP} with TLS support.""" + + def starttls(self, + username=None, password=None, + certChain=None, privateKey=None, + checker=None, + settings=None): + """Puts the connection to the SMTP server into TLS mode. + + If the server supports TLS, this will encrypt the rest of the SMTP + session. + + For client authentication, use one of these argument + combinations: + - username, password (SRP) + - certChain, privateKey (certificate) + + For server authentication, you can either rely on the + implicit mutual authentication performed by SRP or + you can do certificate-based server + authentication with one of these argument combinations: + - x509Fingerprint + + Certificate-based server authentication is compatible with + SRP or certificate-based client authentication. + + The caller should be prepared to handle TLS-specific + exceptions. See the client handshake functions in + L{tlslite.TLSConnection.TLSConnection} for details on which + exceptions might be raised. + + @type username: str + @param username: SRP username. Requires the + 'password' argument. + + @type password: str + @param password: SRP password for mutual authentication. + Requires the 'username' argument. + + @type certChain: L{tlslite.x509certchain.X509CertChain} + @param certChain: Certificate chain for client authentication. + Requires the 'privateKey' argument. Excludes the SRP arguments. + + @type privateKey: L{tlslite.utils.rsakey.RSAKey} + @param privateKey: Private key for client authentication. + Requires the 'certChain' argument. Excludes the SRP arguments. + + @type checker: L{tlslite.checker.Checker} + @param checker: Callable object called after handshaking to + evaluate the connection and raise an Exception if necessary. + + @type settings: L{tlslite.handshakesettings.HandshakeSettings} + @param settings: Various settings which can be used to control + the ciphersuites, certificate types, and SSL/TLS versions + offered by the client. + """ + (resp, reply) = self.docmd("STARTTLS") + if resp == 220: + helper = ClientHelper( + username, password, + certChain, privateKey, + checker, + settings) + conn = TLSConnection(self.sock) + helper._handshake(conn) + self.sock = conn + self.file = conn.makefile('rb') + return (resp, reply)
\ No newline at end of file diff --git a/chromium/third_party/tlslite/tlslite/integration/TLSAsyncDispatcherMixIn.py b/chromium/third_party/tlslite/tlslite/integration/tlsasyncdispatchermixin.py index fd9868ff1c4..dc3259662ab 100644 --- a/chromium/third_party/tlslite/tlslite/integration/TLSAsyncDispatcherMixIn.py +++ b/chromium/third_party/tlslite/tlslite/integration/tlsasyncdispatchermixin.py @@ -1,9 +1,15 @@ +# Authors: +# Trevor Perrin +# Martin von Loewis - python 3 port +# +# See the LICENSE file for legal information regarding use of this file. + """TLS Lite + asyncore.""" import asyncore -from tlslite.TLSConnection import TLSConnection -from AsyncStateMachine import AsyncStateMachine +from tlslite.tlsconnection import TLSConnection +from .asyncstatemachine import AsyncStateMachine class TLSAsyncDispatcherMixIn(AsyncStateMachine): @@ -41,7 +47,7 @@ class TLSAsyncDispatcherMixIn(AsyncStateMachine): Add the following text into 'start_medusa.py', in the 'HTTP Server' section:: - from tlslite.api import * + from tlslite import * s = open("./serverX509Cert.pem").read() x509 = X509() x509.parse(s) @@ -136,4 +142,4 @@ class TLSAsyncDispatcherMixIn(AsyncStateMachine): if hasattr(self, "tlsConnection"): self.setCloseOp() else: - asyncore.dispatcher.close(self)
\ No newline at end of file + asyncore.dispatcher.close(self) diff --git a/chromium/third_party/tlslite/tlslite/integration/TLSSocketServerMixIn.py b/chromium/third_party/tlslite/tlslite/integration/tlssocketservermixin.py index dd4f945dd07..8e2182f65d0 100644 --- a/chromium/third_party/tlslite/tlslite/integration/TLSSocketServerMixIn.py +++ b/chromium/third_party/tlslite/tlslite/integration/tlssocketservermixin.py @@ -1,6 +1,9 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + """TLS Lite + SocketServer.""" -from tlslite.TLSConnection import TLSConnection +from tlslite.tlsconnection import TLSConnection class TLSSocketServerMixIn: """ @@ -17,7 +20,7 @@ class TLSSocketServerMixIn: from SocketServer import * from BaseHTTPServer import * from SimpleHTTPServer import * - from tlslite.api import * + from tlslite import * s = open("./serverX509Cert.pem").read() x509 = X509() diff --git a/chromium/third_party/tlslite/tlslite/integration/xmlrpcserver.py b/chromium/third_party/tlslite/tlslite/integration/xmlrpcserver.py new file mode 100644 index 00000000000..c4f40cd94dc --- /dev/null +++ b/chromium/third_party/tlslite/tlslite/integration/xmlrpcserver.py @@ -0,0 +1,55 @@ +# Authors: +# Kees Bos +# Martin von Loewis - python 3 port +# +# See the LICENSE file for legal information regarding use of this file. + +"""xmlrpcserver.py - simple XML RPC server supporting TLS""" +try: + from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler +except ImportError: + # Python 3 + from xmlrpc.server import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler +from .tlssocketservermixin import TLSSocketServerMixIn + + +class TLSXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): + """XMLRPCRequestHandler using TLS""" + + # Redefine the setup method (see SocketServer.StreamRequestHandler) + def setup(self): + self.connection = self.request + if getattr(self, 'timeout', None) is not None: + # Python 2.7 + self.connection.settimeout(self.timeout) + self.rfile = self.connection.makefile('rb', self.rbufsize) + self.wfile = self.connection.makefile('wb', self.wbufsize) + + def do_POST(self): + """Handles the HTTPS POST request.""" + SimpleXMLRPCRequestHandler.do_POST(self) + try: + # shut down the connection + self.connection.shutdown() + except: + pass + + +class TLSXMLRPCServer(TLSSocketServerMixIn, + SimpleXMLRPCServer): + """Simple XML-RPC server using TLS""" + + def __init__(self, addr, *args, **kwargs): + if not args and not 'requestHandler' in kwargs: + kwargs['requestHandler'] = TLSXMLRPCRequestHandler + SimpleXMLRPCServer.__init__(self, addr, *args, **kwargs) + + +class MultiPathTLSXMLRPCServer(TLSXMLRPCServer): + """Multipath XML-RPC Server using TLS""" + + def __init__(self, addr, *args, **kwargs): + TLSXMLRPCServer.__init__(addr, *args, **kwargs) + self.dispatchers = {} + self.allow_none = allow_none + self.encoding = encoding diff --git a/chromium/third_party/tlslite/tlslite/integration/xmlrpctransport.py b/chromium/third_party/tlslite/tlslite/integration/xmlrpctransport.py new file mode 100644 index 00000000000..de7fc5af50e --- /dev/null +++ b/chromium/third_party/tlslite/tlslite/integration/xmlrpctransport.py @@ -0,0 +1,133 @@ +# Authors: +# Trevor Perrin +# Kees Bos - Fixes for compatibility with different Python versions +# Martin von Loewis - python 3 port +# +# See the LICENSE file for legal information regarding use of this file. + + +"""TLS Lite + xmlrpclib.""" + +try: + import xmlrpclib + import httplib +except ImportError: + # Python 3 + from xmlrpc import client as xmlrpclib + from http import client as httplib +from tlslite.integration.httptlsconnection import HTTPTLSConnection +from tlslite.integration.clienthelper import ClientHelper +import tlslite.errors + + +class XMLRPCTransport(xmlrpclib.Transport, ClientHelper): + """Handles an HTTPS transaction to an XML-RPC server.""" + + # Pre python 2.7, the make_connection returns a HTTP class + transport = xmlrpclib.Transport() + conn_class_is_http = not hasattr(transport, '_connection') + del(transport) + + def __init__(self, use_datetime=0, + username=None, password=None, + certChain=None, privateKey=None, + checker=None, + settings=None, + ignoreAbruptClose=False): + """Create a new XMLRPCTransport. + + An instance of this class can be passed to L{xmlrpclib.ServerProxy} + to use TLS with XML-RPC calls:: + + from tlslite import XMLRPCTransport + from xmlrpclib import ServerProxy + + transport = XMLRPCTransport(user="alice", password="abra123") + server = ServerProxy("https://localhost", transport) + + For client authentication, use one of these argument + combinations: + - username, password (SRP) + - certChain, privateKey (certificate) + + For server authentication, you can either rely on the + implicit mutual authentication performed by SRP or + you can do certificate-based server + authentication with one of these argument combinations: + - x509Fingerprint + + Certificate-based server authentication is compatible with + SRP or certificate-based client authentication. + + The constructor does not perform the TLS handshake itself, but + simply stores these arguments for later. The handshake is + performed only when this class needs to connect with the + server. Thus you should be prepared to handle TLS-specific + exceptions when calling methods of L{xmlrpclib.ServerProxy}. See the + client handshake functions in + L{tlslite.TLSConnection.TLSConnection} for details on which + exceptions might be raised. + + @type username: str + @param username: SRP username. Requires the + 'password' argument. + + @type password: str + @param password: SRP password for mutual authentication. + Requires the 'username' argument. + + @type certChain: L{tlslite.x509certchain.X509CertChain} + @param certChain: Certificate chain for client authentication. + Requires the 'privateKey' argument. Excludes the SRP arguments. + + @type privateKey: L{tlslite.utils.rsakey.RSAKey} + @param privateKey: Private key for client authentication. + Requires the 'certChain' argument. Excludes the SRP arguments. + + @type checker: L{tlslite.checker.Checker} + @param checker: Callable object called after handshaking to + evaluate the connection and raise an Exception if necessary. + + @type settings: L{tlslite.handshakesettings.HandshakeSettings} + @param settings: Various settings which can be used to control + the ciphersuites, certificate types, and SSL/TLS versions + offered by the client. + + @type ignoreAbruptClose: bool + @param ignoreAbruptClose: ignore the TLSAbruptCloseError on + unexpected hangup. + """ + + # self._connection is new in python 2.7, since we're using it here, + # we'll add this ourselves too, just in case we're pre-2.7 + self._connection = (None, None) + xmlrpclib.Transport.__init__(self, use_datetime) + self.ignoreAbruptClose = ignoreAbruptClose + ClientHelper.__init__(self, + username, password, + certChain, privateKey, + checker, + settings) + + def make_connection(self, host): + # return an existing connection if possible. This allows + # HTTP/1.1 keep-alive. + if self._connection and host == self._connection[0]: + http = self._connection[1] + else: + # create a HTTPS connection object from a host descriptor + chost, extra_headers, x509 = self.get_host_info(host) + + http = HTTPTLSConnection(chost, None, + username=self.username, password=self.password, + certChain=self.certChain, privateKey=self.privateKey, + checker=self.checker, + settings=self.settings, + ignoreAbruptClose=self.ignoreAbruptClose) + # store the host argument along with the connection object + self._connection = host, http + if not self.conn_class_is_http: + return http + http2 = httplib.HTTP() + http2._setup(http) + return http2 diff --git a/chromium/third_party/tlslite/tlslite/mathtls.py b/chromium/third_party/tlslite/tlslite/mathtls.py index 7f75904fe92..6e2377a64f2 100644 --- a/chromium/third_party/tlslite/tlslite/mathtls.py +++ b/chromium/third_party/tlslite/tlslite/mathtls.py @@ -1,22 +1,16 @@ +# Authors: +# Trevor Perrin +# Dave Baggett (Arcode Corporation) - MD5 support for MAC_SSL +# +# See the LICENSE file for legal information regarding use of this file. + """Miscellaneous helper functions.""" -from utils.compat import * -from utils.cryptomath import * +from .utils.compat import * +from .utils.cryptomath import * import hmac -# The sha module is deprecated in Python 2.6 -try: - import sha -except ImportError: - from hashlib import sha1 as sha - -# The md5 module is deprecated in Python 2.6 -try: - import md5 -except ImportError: - from hashlib import md5 - #1024, 1536, 2048, 3072, 4096, 6144, and 8192 bit groups] goodGroupParameters = [(2,0xEEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE48E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B297BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9AFD5138FE8376435B9FC61D2FC0EB06E3),\ (2,0x9DEF3CAFB939277AB1F12A8617A47BBBDBA51DF499AC4C80BEEEA9614B19CC4D5F4F5F556E27CBDE51C6A94BE4607A291558903BA0D0F84380B655BB9A22E8DCDF028A7CEC67F0D08134B1C8B97989149B609E0BE3BAB63D47548381DBC5B1FC764E3F4B53DD9DA1158BFD3E2B9C8CF56EDF019539349627DB2FD53D24B7C48665772E437D6C7F8CE442734AF7CCB7AE837C264AE3A9BEB87F8A2FE9B8B5292E5A021FFF5E91479E8CE7A28C2442C6F315180F93499A234DCF76E3FED135F9BB),\ @@ -26,30 +20,29 @@ goodGroupParameters = [(2,0xEEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2 (5,0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF),\ (5,0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E438777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F5683423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD922222E04A4037C0713EB57A81A23F0C73473FC646CEA306B4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A364597E899A0255DC164F31CC50846851DF9AB48195DED7EA1B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F924009438B481C6CD7889A002ED5EE382BC9190DA6FC026E479558E4475677E9AA9E3050E2765694DFC81F56E880B96E7160C980DD98EDD3DFFFFFFFFFFFFFFFFF)] -def P_hash(hashModule, secret, seed, length): - bytes = createByteArrayZeros(length) - secret = bytesToString(secret) - seed = bytesToString(seed) +def P_hash(macFunc, secret, seed, length): + bytes = bytearray(length) A = seed index = 0 while 1: - A = hmac.HMAC(secret, A, hashModule).digest() - output = hmac.HMAC(secret, A+seed, hashModule).digest() + A = macFunc(secret, A) + output = macFunc(secret, A + seed) for c in output: if index >= length: return bytes - bytes[index] = ord(c) + bytes[index] = c index += 1 return bytes def PRF(secret, label, seed, length): #Split the secret into left and right halves + # which may share a byte if len is odd S1 = secret[ : int(math.ceil(len(secret)/2.0))] S2 = secret[ int(math.floor(len(secret)/2.0)) : ] #Run the left half through P_MD5 and the right half through P_SHA1 - p_md5 = P_hash(md5, S1, concatArrays(stringToBytes(label), seed), length) - p_sha1 = P_hash(sha, S2, concatArrays(stringToBytes(label), seed), length) + p_md5 = P_hash(HMAC_MD5, S1, label + seed, length) + p_sha1 = P_hash(HMAC_SHA1, S2, label + seed, length) #XOR the output values and return the result for x in range(length): @@ -58,123 +51,95 @@ def PRF(secret, label, seed, length): def PRF_SSL(secret, seed, length): - secretStr = bytesToString(secret) - seedStr = bytesToString(seed) - bytes = createByteArrayZeros(length) + bytes = bytearray(length) index = 0 for x in range(26): - A = chr(ord('A')+x) * (x+1) # 'A', 'BB', 'CCC', etc.. - input = secretStr + sha.sha(A + secretStr + seedStr).digest() - output = md5.md5(input).digest() + A = bytearray([ord('A')+x] * (x+1)) # 'A', 'BB', 'CCC', etc.. + input = secret + SHA1(A + secret + seed) + output = MD5(input) for c in output: if index >= length: return bytes - bytes[index] = ord(c) + bytes[index] = c index += 1 return bytes +def calcMasterSecret(version, premasterSecret, clientRandom, serverRandom): + if version == (3,0): + masterSecret = PRF_SSL(premasterSecret, + clientRandom + serverRandom, 48) + elif version in ((3,1), (3,2)): + masterSecret = PRF(premasterSecret, b"master secret", + clientRandom + serverRandom, 48) + else: + raise AssertionError() + return masterSecret + + def makeX(salt, username, password): if len(username)>=256: raise ValueError("username too long") if len(salt)>=256: raise ValueError("salt too long") - return stringToNumber(sha.sha(salt + sha.sha(username + ":" + password)\ - .digest()).digest()) + innerHashResult = SHA1(username + bytearray(b":") + password) + outerHashResult = SHA1(salt + innerHashResult) + return bytesToNumber(outerHashResult) #This function is used by VerifierDB.makeVerifier def makeVerifier(username, password, bits): bitsIndex = {1024:0, 1536:1, 2048:2, 3072:3, 4096:4, 6144:5, 8192:6}[bits] g,N = goodGroupParameters[bitsIndex] - salt = bytesToString(getRandomBytes(16)) + salt = getRandomBytes(16) x = makeX(salt, username, password) verifier = powMod(g, x, N) return N, g, salt, verifier def PAD(n, x): - nLength = len(numberToString(n)) - s = numberToString(x) - if len(s) < nLength: - s = ("\0" * (nLength-len(s))) + s - return s + nLength = len(numberToByteArray(n)) + b = numberToByteArray(x) + if len(b) < nLength: + b = (b"\0" * (nLength-len(b))) + b + return b def makeU(N, A, B): - return stringToNumber(sha.sha(PAD(N, A) + PAD(N, B)).digest()) + return bytesToNumber(SHA1(PAD(N, A) + PAD(N, B))) def makeK(N, g): - return stringToNumber(sha.sha(numberToString(N) + PAD(N, g)).digest()) - + return bytesToNumber(SHA1(numberToByteArray(N) + PAD(N, g))) -""" -MAC_SSL -Modified from Python HMAC by Trevor -""" +def createHMAC(k, digestmod=hashlib.sha1): + return hmac.HMAC(k, digestmod=digestmod) -class MAC_SSL: - """MAC_SSL class. +def createMAC_SSL(k, digestmod=None): + mac = MAC_SSL() + mac.create(k, digestmod=digestmod) + return mac - This supports the API for Cryptographic Hash Functions (PEP 247). - """ - def __init__(self, key, msg = None, digestmod = None): - """Create a new MAC_SSL object. +class MAC_SSL(object): + def create(self, k, digestmod=None): + self.digestmod = digestmod or hashlib.sha1 + # Repeat pad bytes 48 times for MD5; 40 times for other hash functions. + self.digest_size = 16 if (self.digestmod is hashlib.md5) else 20 + repeat = 40 if self.digest_size == 20 else 48 + opad = b"\x5C" * repeat + ipad = b"\x36" * repeat - key: key for the keyed hash object. - msg: Initial input for the hash, if provided. - digestmod: A module supporting PEP 247. Defaults to the md5 module. - """ - if digestmod is None: - import md5 - digestmod = md5 + self.ohash = self.digestmod(k + opad) + self.ihash = self.digestmod(k + ipad) - if key == None: #TREVNEW - for faster copying - return #TREVNEW - - self.digestmod = digestmod - self.outer = digestmod.new() - self.inner = digestmod.new() - self.digest_size = digestmod.digest_size - - ipad = "\x36" * 40 - opad = "\x5C" * 40 - - self.inner.update(key) - self.inner.update(ipad) - self.outer.update(key) - self.outer.update(opad) - if msg is not None: - self.update(msg) - - - def update(self, msg): - """Update this hashing object with the string msg. - """ - self.inner.update(msg) + def update(self, m): + self.ihash.update(m) def copy(self): - """Return a separate copy of this hashing object. - - An update to this copy won't affect the original object. - """ - other = MAC_SSL(None) #TREVNEW - for faster copying - other.digest_size = self.digest_size #TREVNEW - other.digestmod = self.digestmod - other.inner = self.inner.copy() - other.outer = self.outer.copy() - return other + new = MAC_SSL() + new.ihash = self.ihash.copy() + new.ohash = self.ohash.copy() + new.digestmod = self.digestmod + new.digest_size = self.digest_size + return new def digest(self): - """Return the hash value of this hashing object. - - This returns a string containing 8-bit data. The object is - not altered in any way by this function; you can continue - updating the object after calling this function. - """ - h = self.outer.copy() - h.update(self.inner.digest()) - return h.digest() - - def hexdigest(self): - """Like digest(), but returns a string of hexadecimal digits instead. - """ - return "".join([hex(ord(x))[2:].zfill(2) - for x in tuple(self.digest())]) + ohash2 = self.ohash.copy() + ohash2.update(self.ihash.digest()) + return bytearray(ohash2.digest()) diff --git a/chromium/third_party/tlslite/tlslite/messages.py b/chromium/third_party/tlslite/tlslite/messages.py index 497ef6048df..c8a913ce249 100644 --- a/chromium/third_party/tlslite/tlslite/messages.py +++ b/chromium/third_party/tlslite/tlslite/messages.py @@ -1,26 +1,23 @@ +# Authors: +# Trevor Perrin +# Google - handling CertificateRequest.certificate_types +# Google (adapted by Sam Rushing and Marcelo Fernandez) - NPN support +# Dimitris Moraitis - Anon ciphersuites +# +# See the LICENSE file for legal information regarding use of this file. + """Classes representing TLS messages.""" -from utils.compat import * -from utils.cryptomath import * -from errors import * -from utils.codec import * -from constants import * -from X509 import X509 -from X509CertChain import X509CertChain - -# The sha module is deprecated in Python 2.6 -try: - import sha -except ImportError: - from hashlib import sha1 as sha - -# The md5 module is deprecated in Python 2.6 -try: - import md5 -except ImportError: - from hashlib import md5 - -class RecordHeader3: +from .utils.compat import * +from .utils.cryptomath import * +from .errors import * +from .utils.codec import * +from .constants import * +from .x509 import X509 +from .x509certchain import X509CertChain +from .utils.tackwrapper import * + +class RecordHeader3(object): def __init__(self): self.type = 0 self.version = (0,0) @@ -34,7 +31,7 @@ class RecordHeader3: return self def write(self): - w = Writer(5) + w = Writer() w.add(self.type, 1) w.add(self.version[0], 1) w.add(self.version[1], 1) @@ -48,7 +45,7 @@ class RecordHeader3: self.ssl2 = False return self -class RecordHeader2: +class RecordHeader2(object): def __init__(self): self.type = 0 self.version = (0,0) @@ -65,22 +62,7 @@ class RecordHeader2: return self -class Msg: - def preWrite(self, trial): - if trial: - w = Writer() - else: - length = self.write(True) - w = Writer(length) - return w - - def postWrite(self, w, trial): - if trial: - return w.index - else: - return w.bytes - -class Alert(Msg): +class Alert(object): def __init__(self): self.contentType = ContentType.alert self.level = 0 @@ -99,50 +81,56 @@ class Alert(Msg): return self def write(self): - w = Writer(2) + w = Writer() w.add(self.level, 1) w.add(self.description, 1) return w.bytes -class HandshakeMsg(Msg): - def preWrite(self, handshakeType, trial): - if trial: - w = Writer() - w.add(handshakeType, 1) - w.add(0, 3) - else: - length = self.write(True) - w = Writer(length) - w.add(handshakeType, 1) - w.add(length-4, 3) - return w - +class HandshakeMsg(object): + def __init__(self, handshakeType): + self.contentType = ContentType.handshake + self.handshakeType = handshakeType + + def postWrite(self, w): + headerWriter = Writer() + headerWriter.add(self.handshakeType, 1) + headerWriter.add(len(w.bytes), 3) + return headerWriter.bytes + w.bytes class ClientHello(HandshakeMsg): def __init__(self, ssl2=False): - self.contentType = ContentType.handshake + HandshakeMsg.__init__(self, HandshakeType.client_hello) self.ssl2 = ssl2 self.client_version = (0,0) - self.random = createByteArrayZeros(32) - self.session_id = createByteArraySequence([]) + self.random = bytearray(32) + self.session_id = bytearray(0) self.cipher_suites = [] # a list of 16-bit values self.certificate_types = [CertificateType.x509] self.compression_methods = [] # a list of 8-bit values self.srp_username = None # a string + self.tack = False + self.supports_npn = False + self.server_name = bytearray(0) self.channel_id = False self.support_signed_cert_timestamps = False self.status_request = False def create(self, version, random, session_id, cipher_suites, - certificate_types=None, srp_username=None): + certificate_types=None, srpUsername=None, + tack=False, supports_npn=False, serverName=None): self.client_version = version self.random = random self.session_id = session_id self.cipher_suites = cipher_suites self.certificate_types = certificate_types self.compression_methods = [0] - self.srp_username = srp_username + if srpUsername: + self.srp_username = bytearray(srpUsername, "utf-8") + self.tack = tack + self.supports_npn = supports_npn + if serverName: + self.server_name = bytearray(serverName, "utf-8") return self def parse(self, p): @@ -151,12 +139,12 @@ class ClientHello(HandshakeMsg): cipherSpecsLength = p.get(2) sessionIDLength = p.get(2) randomLength = p.get(2) - self.cipher_suites = p.getFixList(3, int(cipherSpecsLength/3)) + self.cipher_suites = p.getFixList(3, cipherSpecsLength//3) self.session_id = p.getFixBytes(sessionIDLength) self.random = p.getFixBytes(randomLength) if len(self.random) < 32: zeroBytes = 32-len(self.random) - self.random = createByteArrayZeros(zeroBytes) + self.random + self.random = bytearray(zeroBytes) + self.random self.compression_methods = [0]#Fake this value #We're not doing a stopLengthCheck() for SSLv2, oh well.. @@ -173,10 +161,27 @@ class ClientHello(HandshakeMsg): while soFar != totalExtLength: extType = p.get(2) extLength = p.get(2) - if extType == 6: - self.srp_username = bytesToString(p.getVarBytes(1)) - elif extType == 7: + index1 = p.index + if extType == ExtensionType.srp: + self.srp_username = p.getVarBytes(1) + elif extType == ExtensionType.cert_type: self.certificate_types = p.getVarList(1, 1) + elif extType == ExtensionType.tack: + self.tack = True + elif extType == ExtensionType.supports_npn: + self.supports_npn = True + elif extType == ExtensionType.server_name: + serverNameListBytes = p.getFixBytes(extLength) + p2 = Parser(serverNameListBytes) + p2.startLengthCheck(2) + while 1: + if p2.atLengthCheck(): + break # no host_name, oh well + name_type = p2.get(1) + hostNameBytes = p2.getVarBytes(2) + if name_type == NameType.host_name: + self.server_name = hostNameBytes + break elif extType == ExtensionType.channel_id: self.channel_id = True elif extType == ExtensionType.signed_cert_timestamps: @@ -197,13 +202,16 @@ class ClientHello(HandshakeMsg): p.getFixBytes(extLength) self.status_request = True else: - p.getFixBytes(extLength) + _ = p.getFixBytes(extLength) + index2 = p.index + if index2 - index1 != extLength: + raise SyntaxError("Bad length for extension_data") soFar += 4 + extLength p.stopLengthCheck() return self - def write(self, trial=False): - w = HandshakeMsg.preWrite(self, HandshakeType.client_hello, trial) + def write(self): + w = Writer() w.add(self.client_version[0], 1) w.add(self.client_version[1], 1) w.addFixSeq(self.random, 1) @@ -211,49 +219,66 @@ class ClientHello(HandshakeMsg): w.addVarSeq(self.cipher_suites, 2, 2) w.addVarSeq(self.compression_methods, 1, 1) - extLength = 0 - if self.certificate_types and self.certificate_types != \ - [CertificateType.x509]: - extLength += 5 + len(self.certificate_types) - if self.srp_username: - extLength += 5 + len(self.srp_username) - if extLength > 0: - w.add(extLength, 2) - + w2 = Writer() # For Extensions if self.certificate_types and self.certificate_types != \ [CertificateType.x509]: - w.add(7, 2) - w.add(len(self.certificate_types)+1, 2) - w.addVarSeq(self.certificate_types, 1, 1) + w2.add(ExtensionType.cert_type, 2) + w2.add(len(self.certificate_types)+1, 2) + w2.addVarSeq(self.certificate_types, 1, 1) if self.srp_username: - w.add(6, 2) - w.add(len(self.srp_username)+1, 2) - w.addVarSeq(stringToBytes(self.srp_username), 1, 1) - - return HandshakeMsg.postWrite(self, w, trial) - + w2.add(ExtensionType.srp, 2) + w2.add(len(self.srp_username)+1, 2) + w2.addVarSeq(self.srp_username, 1, 1) + if self.supports_npn: + w2.add(ExtensionType.supports_npn, 2) + w2.add(0, 2) + if self.server_name: + w2.add(ExtensionType.server_name, 2) + w2.add(len(self.server_name)+5, 2) + w2.add(len(self.server_name)+3, 2) + w2.add(NameType.host_name, 1) + w2.addVarSeq(self.server_name, 1, 2) + if self.tack: + w2.add(ExtensionType.tack, 2) + w2.add(0, 2) + if len(w2.bytes): + w.add(len(w2.bytes), 2) + w.bytes += w2.bytes + return self.postWrite(w) + +class BadNextProtos(Exception): + def __init__(self, l): + self.length = l + + def __str__(self): + return 'Cannot encode a list of next protocols because it contains an element with invalid length %d. Element lengths must be 0 < x < 256' % self.length class ServerHello(HandshakeMsg): def __init__(self): - self.contentType = ContentType.handshake + HandshakeMsg.__init__(self, HandshakeType.server_hello) self.server_version = (0,0) - self.random = createByteArrayZeros(32) - self.session_id = createByteArraySequence([]) + self.random = bytearray(32) + self.session_id = bytearray(0) self.cipher_suite = 0 self.certificate_type = CertificateType.x509 self.compression_method = 0 + self.tackExt = None + self.next_protos_advertised = None + self.next_protos = None self.channel_id = False self.signed_cert_timestamps = None self.status_request = False def create(self, version, random, session_id, cipher_suite, - certificate_type): + certificate_type, tackExt, next_protos_advertised): self.server_version = version self.random = random self.session_id = session_id self.cipher_suite = cipher_suite self.certificate_type = certificate_type self.compression_method = 0 + self.tackExt = tackExt + self.next_protos_advertised = next_protos_advertised return self def parse(self, p): @@ -269,16 +294,43 @@ class ServerHello(HandshakeMsg): while soFar != totalExtLength: extType = p.get(2) extLength = p.get(2) - if extType == 7: + if extType == ExtensionType.cert_type: + if extLength != 1: + raise SyntaxError() self.certificate_type = p.get(1) + elif extType == ExtensionType.tack and tackpyLoaded: + self.tackExt = TackExtension(p.getFixBytes(extLength)) + elif extType == ExtensionType.supports_npn: + self.next_protos = self.__parse_next_protos(p.getFixBytes(extLength)) else: p.getFixBytes(extLength) soFar += 4 + extLength p.stopLengthCheck() return self - def write(self, trial=False): - w = HandshakeMsg.preWrite(self, HandshakeType.server_hello, trial) + def __parse_next_protos(self, b): + protos = [] + while True: + if len(b) == 0: + break + l = b[0] + b = b[1:] + if len(b) < l: + raise BadNextProtos(len(b)) + protos.append(b[:l]) + b = b[l:] + return protos + + def __next_protos_encoded(self): + b = bytearray() + for e in self.next_protos_advertised: + if len(e) > 255 or len(e) == 0: + raise BadNextProtos(len(e)) + b += bytearray( [len(e)] ) + bytearray(e) + return b + + def write(self): + w = Writer() w.add(self.server_version[0], 1) w.add(self.server_version[1], 1) w.addFixSeq(self.random, 1) @@ -286,47 +338,41 @@ class ServerHello(HandshakeMsg): w.add(self.cipher_suite, 2) w.add(self.compression_method, 1) - extLength = 0 + w2 = Writer() # For Extensions if self.certificate_type and self.certificate_type != \ CertificateType.x509: - extLength += 5 - + w2.add(ExtensionType.cert_type, 2) + w2.add(1, 2) + w2.add(self.certificate_type, 1) + if self.tackExt: + b = self.tackExt.serialize() + w2.add(ExtensionType.tack, 2) + w2.add(len(b), 2) + w2.bytes += b + if self.next_protos_advertised is not None: + encoded_next_protos_advertised = self.__next_protos_encoded() + w2.add(ExtensionType.supports_npn, 2) + w2.add(len(encoded_next_protos_advertised), 2) + w2.addFixSeq(encoded_next_protos_advertised, 1) if self.channel_id: - extLength += 4 - + w2.add(ExtensionType.channel_id, 2) + w2.add(0, 2) if self.signed_cert_timestamps: - extLength += 4 + len(self.signed_cert_timestamps) - + w2.add(ExtensionType.signed_cert_timestamps, 2) + w2.addVarSeq(bytearray(self.signed_cert_timestamps), 1, 2) if self.status_request: - extLength += 4 + w2.add(ExtensionType.status_request, 2) + w2.add(0, 2) + if len(w2.bytes): + w.add(len(w2.bytes), 2) + w.bytes += w2.bytes + return self.postWrite(w) - if extLength != 0: - w.add(extLength, 2) - - if self.certificate_type and self.certificate_type != \ - CertificateType.x509: - w.add(7, 2) - w.add(1, 2) - w.add(self.certificate_type, 1) - - if self.channel_id: - w.add(ExtensionType.channel_id, 2) - w.add(0, 2) - - if self.signed_cert_timestamps: - w.add(ExtensionType.signed_cert_timestamps, 2) - w.addVarSeq(stringToBytes(self.signed_cert_timestamps), 1, 2) - - if self.status_request: - w.add(ExtensionType.status_request, 2) - w.add(0, 2) - - return HandshakeMsg.postWrite(self, w, trial) class Certificate(HandshakeMsg): def __init__(self, certificateType): + HandshakeMsg.__init__(self, HandshakeType.certificate) self.certificateType = certificateType - self.contentType = ContentType.handshake self.certChain = None def create(self, certChain): @@ -347,23 +393,14 @@ class Certificate(HandshakeMsg): index += len(certBytes)+3 if certificate_list: self.certChain = X509CertChain(certificate_list) - elif self.certificateType == CertificateType.cryptoID: - s = bytesToString(p.getVarBytes(2)) - if s: - try: - import cryptoIDlib.CertChain - except ImportError: - raise SyntaxError(\ - "cryptoID cert chain received, cryptoIDlib not present") - self.certChain = cryptoIDlib.CertChain.CertChain().parse(s) else: raise AssertionError() p.stopLengthCheck() return self - def write(self, trial=False): - w = HandshakeMsg.preWrite(self, HandshakeType.certificate, trial) + def write(self): + w = Writer() if self.certificateType == CertificateType.x509: chainLength = 0 if self.certChain: @@ -379,19 +416,13 @@ class Certificate(HandshakeMsg): for cert in certificate_list: bytes = cert.writeBytes() w.addVarSeq(bytes, 1, 3) - elif self.certificateType == CertificateType.cryptoID: - if self.certChain: - bytes = stringToBytes(self.certChain.write()) - else: - bytes = createByteArraySequence([]) - w.addVarSeq(bytes, 1, 2) else: raise AssertionError() - return HandshakeMsg.postWrite(self, w, trial) + return self.postWrite(w) class CertificateStatus(HandshakeMsg): def __init__(self): - self.contentType = ContentType.handshake + HandshakeMsg.__init__(self, HandshakeType.certificate_status) def create(self, ocsp_response): self.ocsp_response = ocsp_response @@ -411,21 +442,19 @@ class CertificateStatus(HandshakeMsg): # Can't be empty raise SyntaxError() self.ocsp_response = ocsp_response + p.stopLengthCheck() return self - def write(self, trial=False): - w = HandshakeMsg.preWrite(self, HandshakeType.certificate_status, - trial) + def write(self): + w = Writer() w.add(CertificateStatusType.ocsp, 1) - w.addVarSeq(stringToBytes(self.ocsp_response), 1, 3) - return HandshakeMsg.postWrite(self, w, trial) + w.addVarSeq(bytearray(self.ocsp_response), 1, 3) + return self.postWrite(w) class CertificateRequest(HandshakeMsg): def __init__(self): - self.contentType = ContentType.handshake - #Apple's Secure Transport library rejects empty certificate_types, so - #default to rsa_sign. - self.certificate_types = [ClientCertificateType.rsa_sign] + HandshakeMsg.__init__(self, HandshakeType.certificate_request) + self.certificate_types = [] self.certificate_authorities = [] def create(self, certificate_types, certificate_authorities): @@ -446,9 +475,8 @@ class CertificateRequest(HandshakeMsg): p.stopLengthCheck() return self - def write(self, trial=False): - w = HandshakeMsg.preWrite(self, HandshakeType.certificate_request, - trial) + def write(self): + w = Writer() w.addVarSeq(self.certificate_types, 1, 1) caLength = 0 #determine length @@ -458,17 +486,21 @@ class CertificateRequest(HandshakeMsg): #add bytes for ca_dn in self.certificate_authorities: w.addVarSeq(ca_dn, 1, 2) - return HandshakeMsg.postWrite(self, w, trial) + return self.postWrite(w) class ServerKeyExchange(HandshakeMsg): def __init__(self, cipherSuite): + HandshakeMsg.__init__(self, HandshakeType.server_key_exchange) self.cipherSuite = cipherSuite - self.contentType = ContentType.handshake - self.srp_N = 0L - self.srp_g = 0L - self.srp_s = createByteArraySequence([]) - self.srp_B = 0L - self.signature = createByteArraySequence([]) + self.srp_N = 0 + self.srp_g = 0 + self.srp_s = bytearray(0) + self.srp_B = 0 + # Anon DH params: + self.dh_p = 0 + self.dh_g = 0 + self.dh_Ys = 0 + self.signature = bytearray(0) def createSRP(self, srp_N, srp_g, srp_s, srp_B): self.srp_N = srp_N @@ -476,42 +508,58 @@ class ServerKeyExchange(HandshakeMsg): self.srp_s = srp_s self.srp_B = srp_B return self + + def createDH(self, dh_p, dh_g, dh_Ys): + self.dh_p = dh_p + self.dh_g = dh_g + self.dh_Ys = dh_Ys + return self def parse(self, p): p.startLengthCheck(3) - self.srp_N = bytesToNumber(p.getVarBytes(2)) - self.srp_g = bytesToNumber(p.getVarBytes(2)) - self.srp_s = p.getVarBytes(1) - self.srp_B = bytesToNumber(p.getVarBytes(2)) - if self.cipherSuite in CipherSuite.srpRsaSuites: - self.signature = p.getVarBytes(2) + if self.cipherSuite in CipherSuite.srpAllSuites: + self.srp_N = bytesToNumber(p.getVarBytes(2)) + self.srp_g = bytesToNumber(p.getVarBytes(2)) + self.srp_s = p.getVarBytes(1) + self.srp_B = bytesToNumber(p.getVarBytes(2)) + if self.cipherSuite in CipherSuite.srpCertSuites: + self.signature = p.getVarBytes(2) + elif self.cipherSuite in CipherSuite.anonSuites: + self.dh_p = bytesToNumber(p.getVarBytes(2)) + self.dh_g = bytesToNumber(p.getVarBytes(2)) + self.dh_Ys = bytesToNumber(p.getVarBytes(2)) p.stopLengthCheck() return self - def write(self, trial=False): - w = HandshakeMsg.preWrite(self, HandshakeType.server_key_exchange, - trial) - w.addVarSeq(numberToBytes(self.srp_N), 1, 2) - w.addVarSeq(numberToBytes(self.srp_g), 1, 2) - w.addVarSeq(self.srp_s, 1, 1) - w.addVarSeq(numberToBytes(self.srp_B), 1, 2) - if self.cipherSuite in CipherSuite.srpRsaSuites: + def write_params(self): + w = Writer() + if self.cipherSuite in CipherSuite.srpAllSuites: + w.addVarSeq(numberToByteArray(self.srp_N), 1, 2) + w.addVarSeq(numberToByteArray(self.srp_g), 1, 2) + w.addVarSeq(self.srp_s, 1, 1) + w.addVarSeq(numberToByteArray(self.srp_B), 1, 2) + elif self.cipherSuite in CipherSuite.dhAllSuites: + w.addVarSeq(numberToByteArray(self.dh_p), 1, 2) + w.addVarSeq(numberToByteArray(self.dh_g), 1, 2) + w.addVarSeq(numberToByteArray(self.dh_Ys), 1, 2) + else: + assert(False) + return w.bytes + + def write(self): + w = Writer() + w.bytes += self.write_params() + if self.cipherSuite in CipherSuite.certAllSuites: w.addVarSeq(self.signature, 1, 2) - return HandshakeMsg.postWrite(self, w, trial) + return self.postWrite(w) def hash(self, clientRandom, serverRandom): - oldCipherSuite = self.cipherSuite - self.cipherSuite = None - try: - bytes = clientRandom + serverRandom + self.write()[4:] - s = bytesToString(bytes) - return stringToBytes(md5.md5(s).digest() + sha.sha(s).digest()) - finally: - self.cipherSuite = oldCipherSuite + bytes = clientRandom + serverRandom + self.write_params() + return MD5(bytes) + SHA1(bytes) class ServerHelloDone(HandshakeMsg): def __init__(self): - self.contentType = ContentType.handshake + HandshakeMsg.__init__(self, HandshakeType.server_hello_done) def create(self): return self @@ -521,17 +569,17 @@ class ServerHelloDone(HandshakeMsg): p.stopLengthCheck() return self - def write(self, trial=False): - w = HandshakeMsg.preWrite(self, HandshakeType.server_hello_done, trial) - return HandshakeMsg.postWrite(self, w, trial) + def write(self): + w = Writer() + return self.postWrite(w) class ClientKeyExchange(HandshakeMsg): def __init__(self, cipherSuite, version=None): + HandshakeMsg.__init__(self, HandshakeType.client_key_exchange) self.cipherSuite = cipherSuite self.version = version - self.contentType = ContentType.handshake self.srp_A = 0 - self.encryptedPreMasterSecret = createByteArraySequence([]) + self.encryptedPreMasterSecret = bytearray(0) def createSRP(self, srp_A): self.srp_A = srp_A @@ -540,13 +588,16 @@ class ClientKeyExchange(HandshakeMsg): def createRSA(self, encryptedPreMasterSecret): self.encryptedPreMasterSecret = encryptedPreMasterSecret return self - + + def createDH(self, dh_Yc): + self.dh_Yc = dh_Yc + return self + def parse(self, p): p.startLengthCheck(3) - if self.cipherSuite in CipherSuite.srpSuites + \ - CipherSuite.srpRsaSuites: + if self.cipherSuite in CipherSuite.srpAllSuites: self.srp_A = bytesToNumber(p.getVarBytes(2)) - elif self.cipherSuite in CipherSuite.rsaSuites: + elif self.cipherSuite in CipherSuite.certSuites: if self.version in ((3,1), (3,2)): self.encryptedPreMasterSecret = p.getVarBytes(2) elif self.version == (3,0): @@ -554,32 +605,34 @@ class ClientKeyExchange(HandshakeMsg): p.getFixBytes(len(p.bytes)-p.index) else: raise AssertionError() + elif self.cipherSuite in CipherSuite.dhAllSuites: + self.dh_Yc = bytesToNumber(p.getVarBytes(2)) else: raise AssertionError() p.stopLengthCheck() return self - def write(self, trial=False): - w = HandshakeMsg.preWrite(self, HandshakeType.client_key_exchange, - trial) - if self.cipherSuite in CipherSuite.srpSuites + \ - CipherSuite.srpRsaSuites: - w.addVarSeq(numberToBytes(self.srp_A), 1, 2) - elif self.cipherSuite in CipherSuite.rsaSuites: + def write(self): + w = Writer() + if self.cipherSuite in CipherSuite.srpAllSuites: + w.addVarSeq(numberToByteArray(self.srp_A), 1, 2) + elif self.cipherSuite in CipherSuite.certSuites: if self.version in ((3,1), (3,2)): w.addVarSeq(self.encryptedPreMasterSecret, 1, 2) elif self.version == (3,0): w.addFixSeq(self.encryptedPreMasterSecret, 1) else: raise AssertionError() + elif self.cipherSuite in CipherSuite.anonSuites: + w.addVarSeq(numberToByteArray(self.dh_Yc), 1, 2) else: raise AssertionError() - return HandshakeMsg.postWrite(self, w, trial) + return self.postWrite(w) class CertificateVerify(HandshakeMsg): def __init__(self): - self.contentType = ContentType.handshake - self.signature = createByteArraySequence([]) + HandshakeMsg.__init__(self, HandshakeType.certificate_verify) + self.signature = bytearray(0) def create(self, signature): self.signature = signature @@ -591,13 +644,12 @@ class CertificateVerify(HandshakeMsg): p.stopLengthCheck() return self - def write(self, trial=False): - w = HandshakeMsg.preWrite(self, HandshakeType.certificate_verify, - trial) + def write(self): + w = Writer() w.addVarSeq(self.signature, 1, 2) - return HandshakeMsg.postWrite(self, w, trial) + return self.postWrite(w) -class ChangeCipherSpec(Msg): +class ChangeCipherSpec(object): def __init__(self): self.contentType = ContentType.change_cipher_spec self.type = 1 @@ -612,17 +664,40 @@ class ChangeCipherSpec(Msg): p.stopLengthCheck() return self - def write(self, trial=False): - w = Msg.preWrite(self, trial) + def write(self): + w = Writer() w.add(self.type,1) - return Msg.postWrite(self, w, trial) + return w.bytes + + +class NextProtocol(HandshakeMsg): + def __init__(self): + HandshakeMsg.__init__(self, HandshakeType.next_protocol) + self.next_proto = None + + def create(self, next_proto): + self.next_proto = next_proto + return self + + def parse(self, p): + p.startLengthCheck(3) + self.next_proto = p.getVarBytes(1) + _ = p.getVarBytes(1) + p.stopLengthCheck() + return self + def write(self, trial=False): + w = Writer() + w.addVarSeq(self.next_proto, 1, 1) + paddingLen = 32 - ((len(self.next_proto) + 2) % 32) + w.addVarSeq(bytearray(paddingLen), 1, 1) + return self.postWrite(w) class Finished(HandshakeMsg): def __init__(self, version): - self.contentType = ContentType.handshake + HandshakeMsg.__init__(self, HandshakeType.finished) self.version = version - self.verify_data = createByteArraySequence([]) + self.verify_data = bytearray(0) def create(self, verify_data): self.verify_data = verify_data @@ -639,10 +714,10 @@ class Finished(HandshakeMsg): p.stopLengthCheck() return self - def write(self, trial=False): - w = HandshakeMsg.preWrite(self, HandshakeType.finished, trial) + def write(self): + w = Writer() w.addFixSeq(self.verify_data, 1) - return HandshakeMsg.postWrite(self, w, trial) + return self.postWrite(w) class EncryptedExtensions(HandshakeMsg): def __init__(self): @@ -666,14 +741,19 @@ class EncryptedExtensions(HandshakeMsg): p.stopLengthCheck() return self -class ApplicationData(Msg): +class ApplicationData(object): def __init__(self): self.contentType = ContentType.application_data - self.bytes = createByteArraySequence([]) + self.bytes = bytearray(0) def create(self, bytes): self.bytes = bytes return self + + def splitFirstByte(self): + newMsg = ApplicationData().create(self.bytes[:1]) + self.bytes = self.bytes[1:] + return newMsg def parse(self, p): self.bytes = p.bytes diff --git a/chromium/third_party/tlslite/tlslite/session.py b/chromium/third_party/tlslite/tlslite/session.py new file mode 100644 index 00000000000..6aadf58e054 --- /dev/null +++ b/chromium/third_party/tlslite/tlslite/session.py @@ -0,0 +1,126 @@ +# Authors: +# Trevor Perrin +# Dave Baggett (Arcode Corporation) - canonicalCipherName +# +# See the LICENSE file for legal information regarding use of this file. + +"""Class representing a TLS session.""" + +from .utils.compat import * +from .mathtls import * +from .constants import * + +class Session(object): + """ + This class represents a TLS session. + + TLS distinguishes between connections and sessions. A new + handshake creates both a connection and a session. Data is + transmitted over the connection. + + The session contains a more permanent record of the handshake. The + session can be inspected to determine handshake results. The + session can also be used to create a new connection through + "session resumption". If the client and server both support this, + they can create a new connection based on an old session without + the overhead of a full handshake. + + The session for a L{tlslite.TLSConnection.TLSConnection} can be + retrieved from the connection's 'session' attribute. + + @type srpUsername: str + @ivar srpUsername: The client's SRP username (or None). + + @type clientCertChain: L{tlslite.x509certchain.X509CertChain} + @ivar clientCertChain: The client's certificate chain (or None). + + @type serverCertChain: L{tlslite.x509certchain.X509CertChain} + @ivar serverCertChain: The server's certificate chain (or None). + + @type tackExt: L{tack.structures.TackExtension.TackExtension} + @ivar tackExt: The server's TackExtension (or None). + + @type tackInHelloExt: L{bool} + @ivar tackInHelloExt: True if a TACK was presented via TLS Extension. + """ + + def __init__(self): + self.masterSecret = bytearray(0) + self.sessionID = bytearray(0) + self.cipherSuite = 0 + self.srpUsername = "" + self.clientCertChain = None + self.serverCertChain = None + self.tackExt = None + self.tackInHelloExt = False + self.serverName = "" + self.resumable = False + + def create(self, masterSecret, sessionID, cipherSuite, + srpUsername, clientCertChain, serverCertChain, + tackExt, tackInHelloExt, serverName, resumable=True): + self.masterSecret = masterSecret + self.sessionID = sessionID + self.cipherSuite = cipherSuite + self.srpUsername = srpUsername + self.clientCertChain = clientCertChain + self.serverCertChain = serverCertChain + self.tackExt = tackExt + self.tackInHelloExt = tackInHelloExt + self.serverName = serverName + self.resumable = resumable + + def _clone(self): + other = Session() + other.masterSecret = self.masterSecret + other.sessionID = self.sessionID + other.cipherSuite = self.cipherSuite + other.srpUsername = self.srpUsername + other.clientCertChain = self.clientCertChain + other.serverCertChain = self.serverCertChain + other.tackExt = self.tackExt + other.tackInHelloExt = self.tackInHelloExt + other.serverName = self.serverName + other.resumable = self.resumable + return other + + def valid(self): + """If this session can be used for session resumption. + + @rtype: bool + @return: If this session can be used for session resumption. + """ + return self.resumable and self.sessionID + + def _setResumable(self, boolean): + #Only let it be set to True if the sessionID is non-null + if (not boolean) or (boolean and self.sessionID): + self.resumable = boolean + + def getTackId(self): + if self.tackExt and self.tackExt.tack: + return self.tackExt.tack.getTackId() + else: + return None + + def getBreakSigs(self): + if self.tackExt and self.tackExt.break_sigs: + return self.tackExt.break_sigs + else: + return None + + def getCipherName(self): + """Get the name of the cipher used with this connection. + + @rtype: str + @return: The name of the cipher used with this connection. + """ + return CipherSuite.canonicalCipherName(self.cipherSuite) + + def getMacName(self): + """Get the name of the HMAC hash algo used with this connection. + + @rtype: str + @return: The name of the HMAC hash algo used with this connection. + """ + return CipherSuite.canonicalMacName(self.cipherSuite) diff --git a/chromium/third_party/tlslite/tlslite/SessionCache.py b/chromium/third_party/tlslite/tlslite/sessioncache.py index 34cf0b0ec4e..7071d10b067 100644 --- a/chromium/third_party/tlslite/tlslite/SessionCache.py +++ b/chromium/third_party/tlslite/tlslite/sessioncache.py @@ -1,9 +1,15 @@ +# Authors: +# Trevor Perrin +# Martin von Loewis - python 3 port +# +# See the LICENSE file for legal information regarding use of this file. + """Class for caching TLS sessions.""" -import thread +import threading import time -class SessionCache: +class SessionCache(object): """This class is used by the server to cache TLS sessions. Caching sessions allows the client to use TLS session resumption @@ -31,7 +37,7 @@ class SessionCache: @param maxAge: The number of seconds before a session expires from the cache. The default is 14400 (i.e. 4 hours).""" - self.lock = thread.allocate_lock() + self.lock = threading.Lock() # Maps sessionIDs to sessions self.entriesDict = {} @@ -47,7 +53,7 @@ class SessionCache: self.lock.acquire() try: self._purge() #Delete old items, so we're assured of a new one - session = self.entriesDict[sessionID] + session = self.entriesDict[bytes(sessionID)] #When we add sessions they're resumable, but it's possible #for the session to be invalidated later on (if a fatal alert @@ -66,7 +72,7 @@ class SessionCache: self.lock.acquire() try: #Add the new element - self.entriesDict[sessionID] = session + self.entriesDict[bytes(sessionID)] = session self.entriesList[self.lastIndex] = (sessionID, time.time()) self.lastIndex = (self.lastIndex+1) % len(self.entriesList) diff --git a/chromium/third_party/tlslite/tlslite/tlsconnection.py b/chromium/third_party/tlslite/tlslite/tlsconnection.py new file mode 100644 index 00000000000..044ad5969a7 --- /dev/null +++ b/chromium/third_party/tlslite/tlslite/tlsconnection.py @@ -0,0 +1,1934 @@ +# Authors: +# Trevor Perrin +# Google - added reqCAs parameter +# Google (adapted by Sam Rushing and Marcelo Fernandez) - NPN support +# Dimitris Moraitis - Anon ciphersuites +# Martin von Loewis - python 3 port +# +# See the LICENSE file for legal information regarding use of this file. + +""" +MAIN CLASS FOR TLS LITE (START HERE!). +""" + +import socket +from .utils.compat import formatExceptionTrace +from .tlsrecordlayer import TLSRecordLayer +from .session import Session +from .constants import * +from .utils.cryptomath import getRandomBytes +from .errors import * +from .messages import * +from .mathtls import * +from .handshakesettings import HandshakeSettings +from .utils.tackwrapper import * + +class KeyExchange(object): + def __init__(self, cipherSuite, clientHello, serverHello, privateKey): + """ + Initializes the KeyExchange. privateKey is the signing private key. + """ + self.cipherSuite = cipherSuite + self.clientHello = clientHello + self.serverHello = serverHello + self.privateKey = privateKey + + def makeServerKeyExchange(): + """ + Returns a ServerKeyExchange object for the server's initial leg in the + handshake. If the key exchange method does not send ServerKeyExchange + (e.g. RSA), it returns None. + """ + raise NotImplementedError() + + def processClientKeyExchange(clientKeyExchange): + """ + Processes the client's ClientKeyExchange message and returns the + premaster secret. Raises TLSLocalAlert on error. + """ + raise NotImplementedError() + +class RSAKeyExchange(KeyExchange): + def makeServerKeyExchange(self): + return None + + def processClientKeyExchange(self, clientKeyExchange): + premasterSecret = self.privateKey.decrypt(\ + clientKeyExchange.encryptedPreMasterSecret) + + # On decryption failure randomize premaster secret to avoid + # Bleichenbacher's "million message" attack + randomPreMasterSecret = getRandomBytes(48) + if not premasterSecret: + premasterSecret = randomPreMasterSecret + elif len(premasterSecret)!=48: + premasterSecret = randomPreMasterSecret + else: + versionCheck = (premasterSecret[0], premasterSecret[1]) + if versionCheck != self.clientHello.client_version: + #Tolerate buggy IE clients + if versionCheck != self.serverHello.server_version: + premasterSecret = randomPreMasterSecret + return premasterSecret + +def _hexStringToNumber(s): + s = s.replace(" ", "").replace("\n", "") + if len(s) % 2 != 0: + raise ValueError("Length is not even") + return bytesToNumber(bytearray(s.decode("hex"))) + +class DHE_RSAKeyExchange(KeyExchange): + # 2048-bit MODP Group (RFC 3526, Section 3) + dh_p = _hexStringToNumber(""" +FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 +29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD +EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 +E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED +EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D +C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F +83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D +670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B +E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 +DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510 +15728E5A 8AACAA68 FFFFFFFF FFFFFFFF""") + dh_g = 2 + + # RFC 3526, Section 8. + strength = 160 + + def makeServerKeyExchange(self): + # Per RFC 3526, Section 1, the exponent should have double the entropy + # of the strength of the curve. + self.dh_Xs = bytesToNumber(getRandomBytes(self.strength * 2 / 8)) + dh_Ys = powMod(self.dh_g, self.dh_Xs, self.dh_p) + + serverKeyExchange = ServerKeyExchange(self.cipherSuite) + serverKeyExchange.createDH(self.dh_p, self.dh_g, dh_Ys) + serverKeyExchange.signature = self.privateKey.sign( + serverKeyExchange.hash(self.clientHello.random, + self.serverHello.random)) + return serverKeyExchange + + def processClientKeyExchange(self, clientKeyExchange): + dh_Yc = clientKeyExchange.dh_Yc + + # First half of RFC 2631, Section 2.1.5. Validate the client's public + # key. + if not 2 <= dh_Yc <= self.dh_p - 1: + raise TLSLocalAlert(AlertDescription.illegal_parameter, + "Invalid dh_Yc value") + + S = powMod(dh_Yc, self.dh_Xs, self.dh_p) + return numberToByteArray(S) + +class TLSConnection(TLSRecordLayer): + """ + This class wraps a socket and provides TLS handshaking and data + transfer. + + To use this class, create a new instance, passing a connected + socket into the constructor. Then call some handshake function. + If the handshake completes without raising an exception, then a TLS + connection has been negotiated. You can transfer data over this + connection as if it were a socket. + + This class provides both synchronous and asynchronous versions of + its key functions. The synchronous versions should be used when + writing single-or multi-threaded code using blocking sockets. The + asynchronous versions should be used when performing asynchronous, + event-based I/O with non-blocking sockets. + + Asynchronous I/O is a complicated subject; typically, you should + not use the asynchronous functions directly, but should use some + framework like asyncore or Twisted which TLS Lite integrates with + (see + L{tlslite.integration.tlsasyncdispatchermixin.TLSAsyncDispatcherMixIn}). + """ + + def __init__(self, sock): + """Create a new TLSConnection instance. + + @param sock: The socket data will be transmitted on. The + socket should already be connected. It may be in blocking or + non-blocking mode. + + @type sock: L{socket.socket} + """ + TLSRecordLayer.__init__(self, sock) + + #********************************************************* + # Client Handshake Functions + #********************************************************* + + def handshakeClientAnonymous(self, session=None, settings=None, + checker=None, serverName="", + async=False): + """Perform an anonymous handshake in the role of client. + + This function performs an SSL or TLS handshake using an + anonymous Diffie Hellman ciphersuite. + + Like any handshake function, this can be called on a closed + TLS connection, or on a TLS connection that is already open. + If called on an open connection it performs a re-handshake. + + If the function completes without raising an exception, the + TLS connection will be open and available for data transfer. + + If an exception is raised, the connection will have been + automatically closed (if it was ever open). + + @type session: L{tlslite.Session.Session} + @param session: A TLS session to attempt to resume. If the + resumption does not succeed, a full handshake will be + performed. + + @type settings: L{tlslite.HandshakeSettings.HandshakeSettings} + @param settings: Various settings which can be used to control + the ciphersuites, certificate types, and SSL/TLS versions + offered by the client. + + @type checker: L{tlslite.Checker.Checker} + @param checker: A Checker instance. This instance will be + invoked to examine the other party's authentication + credentials, if the handshake completes succesfully. + + @type serverName: string + @param serverName: The ServerNameIndication TLS Extension. + + @type async: bool + @param async: If False, this function will block until the + handshake is completed. If True, this function will return a + generator. Successive invocations of the generator will + return 0 if it is waiting to read from the socket, 1 if it is + waiting to write to the socket, or will raise StopIteration if + the handshake operation is completed. + + @rtype: None or an iterable + @return: If 'async' is True, a generator object will be + returned. + + @raise socket.error: If a socket error occurs. + @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed + without a preceding alert. + @raise tlslite.errors.TLSAlert: If a TLS alert is signalled. + @raise tlslite.errors.TLSAuthenticationError: If the checker + doesn't like the other party's authentication credentials. + """ + handshaker = self._handshakeClientAsync(anonParams=(True), + session=session, + settings=settings, + checker=checker, + serverName=serverName) + if async: + return handshaker + for result in handshaker: + pass + + def handshakeClientSRP(self, username, password, session=None, + settings=None, checker=None, + reqTack=True, serverName="", + async=False): + """Perform an SRP handshake in the role of client. + + This function performs a TLS/SRP handshake. SRP mutually + authenticates both parties to each other using only a + username and password. This function may also perform a + combined SRP and server-certificate handshake, if the server + chooses to authenticate itself with a certificate chain in + addition to doing SRP. + + If the function completes without raising an exception, the + TLS connection will be open and available for data transfer. + + If an exception is raised, the connection will have been + automatically closed (if it was ever open). + + @type username: str + @param username: The SRP username. + + @type password: str + @param password: The SRP password. + + @type session: L{tlslite.session.Session} + @param session: A TLS session to attempt to resume. This + session must be an SRP session performed with the same username + and password as were passed in. If the resumption does not + succeed, a full SRP handshake will be performed. + + @type settings: L{tlslite.handshakesettings.HandshakeSettings} + @param settings: Various settings which can be used to control + the ciphersuites, certificate types, and SSL/TLS versions + offered by the client. + + @type checker: L{tlslite.checker.Checker} + @param checker: A Checker instance. This instance will be + invoked to examine the other party's authentication + credentials, if the handshake completes succesfully. + + @type reqTack: bool + @param reqTack: Whether or not to send a "tack" TLS Extension, + requesting the server return a TackExtension if it has one. + + @type serverName: string + @param serverName: The ServerNameIndication TLS Extension. + + @type async: bool + @param async: If False, this function will block until the + handshake is completed. If True, this function will return a + generator. Successive invocations of the generator will + return 0 if it is waiting to read from the socket, 1 if it is + waiting to write to the socket, or will raise StopIteration if + the handshake operation is completed. + + @rtype: None or an iterable + @return: If 'async' is True, a generator object will be + returned. + + @raise socket.error: If a socket error occurs. + @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed + without a preceding alert. + @raise tlslite.errors.TLSAlert: If a TLS alert is signalled. + @raise tlslite.errors.TLSAuthenticationError: If the checker + doesn't like the other party's authentication credentials. + """ + handshaker = self._handshakeClientAsync(srpParams=(username, password), + session=session, settings=settings, checker=checker, + reqTack=reqTack, serverName=serverName) + # The handshaker is a Python Generator which executes the handshake. + # It allows the handshake to be run in a "piecewise", asynchronous + # fashion, returning 1 when it is waiting to able to write, 0 when + # it is waiting to read. + # + # If 'async' is True, the generator is returned to the caller, + # otherwise it is executed to completion here. + if async: + return handshaker + for result in handshaker: + pass + + def handshakeClientCert(self, certChain=None, privateKey=None, + session=None, settings=None, checker=None, + nextProtos=None, reqTack=True, serverName="", + async=False): + """Perform a certificate-based handshake in the role of client. + + This function performs an SSL or TLS handshake. The server + will authenticate itself using an X.509 certificate + chain. If the handshake succeeds, the server's certificate + chain will be stored in the session's serverCertChain attribute. + Unless a checker object is passed in, this function does no + validation or checking of the server's certificate chain. + + If the server requests client authentication, the + client will send the passed-in certificate chain, and use the + passed-in private key to authenticate itself. If no + certificate chain and private key were passed in, the client + will attempt to proceed without client authentication. The + server may or may not allow this. + + If the function completes without raising an exception, the + TLS connection will be open and available for data transfer. + + If an exception is raised, the connection will have been + automatically closed (if it was ever open). + + @type certChain: L{tlslite.x509certchain.X509CertChain} + @param certChain: The certificate chain to be used if the + server requests client authentication. + + @type privateKey: L{tlslite.utils.rsakey.RSAKey} + @param privateKey: The private key to be used if the server + requests client authentication. + + @type session: L{tlslite.session.Session} + @param session: A TLS session to attempt to resume. If the + resumption does not succeed, a full handshake will be + performed. + + @type settings: L{tlslite.handshakesettings.HandshakeSettings} + @param settings: Various settings which can be used to control + the ciphersuites, certificate types, and SSL/TLS versions + offered by the client. + + @type checker: L{tlslite.checker.Checker} + @param checker: A Checker instance. This instance will be + invoked to examine the other party's authentication + credentials, if the handshake completes succesfully. + + @type nextProtos: list of strings. + @param nextProtos: A list of upper layer protocols ordered by + preference, to use in the Next-Protocol Negotiation Extension. + + @type reqTack: bool + @param reqTack: Whether or not to send a "tack" TLS Extension, + requesting the server return a TackExtension if it has one. + + @type serverName: string + @param serverName: The ServerNameIndication TLS Extension. + + @type async: bool + @param async: If False, this function will block until the + handshake is completed. If True, this function will return a + generator. Successive invocations of the generator will + return 0 if it is waiting to read from the socket, 1 if it is + waiting to write to the socket, or will raise StopIteration if + the handshake operation is completed. + + @rtype: None or an iterable + @return: If 'async' is True, a generator object will be + returned. + + @raise socket.error: If a socket error occurs. + @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed + without a preceding alert. + @raise tlslite.errors.TLSAlert: If a TLS alert is signalled. + @raise tlslite.errors.TLSAuthenticationError: If the checker + doesn't like the other party's authentication credentials. + """ + handshaker = self._handshakeClientAsync(certParams=(certChain, + privateKey), session=session, settings=settings, + checker=checker, serverName=serverName, + nextProtos=nextProtos, reqTack=reqTack) + # The handshaker is a Python Generator which executes the handshake. + # It allows the handshake to be run in a "piecewise", asynchronous + # fashion, returning 1 when it is waiting to able to write, 0 when + # it is waiting to read. + # + # If 'async' is True, the generator is returned to the caller, + # otherwise it is executed to completion here. + if async: + return handshaker + for result in handshaker: + pass + + + def _handshakeClientAsync(self, srpParams=(), certParams=(), anonParams=(), + session=None, settings=None, checker=None, + nextProtos=None, serverName="", reqTack=True): + + handshaker = self._handshakeClientAsyncHelper(srpParams=srpParams, + certParams=certParams, + anonParams=anonParams, + session=session, + settings=settings, + serverName=serverName, + nextProtos=nextProtos, + reqTack=reqTack) + for result in self._handshakeWrapperAsync(handshaker, checker): + yield result + + + def _handshakeClientAsyncHelper(self, srpParams, certParams, anonParams, + session, settings, serverName, nextProtos, reqTack): + + self._handshakeStart(client=True) + + #Unpack parameters + srpUsername = None # srpParams[0] + password = None # srpParams[1] + clientCertChain = None # certParams[0] + privateKey = None # certParams[1] + + # Allow only one of (srpParams, certParams, anonParams) + if srpParams: + assert(not certParams) + assert(not anonParams) + srpUsername, password = srpParams + if certParams: + assert(not srpParams) + assert(not anonParams) + clientCertChain, privateKey = certParams + if anonParams: + assert(not srpParams) + assert(not certParams) + + #Validate parameters + if srpUsername and not password: + raise ValueError("Caller passed a username but no password") + if password and not srpUsername: + raise ValueError("Caller passed a password but no username") + if clientCertChain and not privateKey: + raise ValueError("Caller passed a certChain but no privateKey") + if privateKey and not clientCertChain: + raise ValueError("Caller passed a privateKey but no certChain") + if reqTack: + if not tackpyLoaded: + reqTack = False + if not settings or not settings.useExperimentalTackExtension: + reqTack = False + if nextProtos is not None: + if len(nextProtos) == 0: + raise ValueError("Caller passed no nextProtos") + + # Validates the settings and filters out any unsupported ciphers + # or crypto libraries that were requested + if not settings: + settings = HandshakeSettings() + settings = settings._filter() + + if clientCertChain: + if not isinstance(clientCertChain, X509CertChain): + raise ValueError("Unrecognized certificate type") + if "x509" not in settings.certificateTypes: + raise ValueError("Client certificate doesn't match "\ + "Handshake Settings") + + if session: + # session.valid() ensures session is resumable and has + # non-empty sessionID + if not session.valid(): + session = None #ignore non-resumable sessions... + elif session.resumable: + if session.srpUsername != srpUsername: + raise ValueError("Session username doesn't match") + if session.serverName != serverName: + raise ValueError("Session servername doesn't match") + + #Add Faults to parameters + if srpUsername and self.fault == Fault.badUsername: + srpUsername += "GARBAGE" + if password and self.fault == Fault.badPassword: + password += "GARBAGE" + + #Tentatively set the version to the client's minimum version. + #We'll use this for the ClientHello, and if an error occurs + #parsing the Server Hello, we'll use this version for the response + self.version = settings.maxVersion + + # OK Start sending messages! + # ***************************** + + # Send the ClientHello. + for result in self._clientSendClientHello(settings, session, + srpUsername, srpParams, certParams, + anonParams, serverName, nextProtos, + reqTack): + if result in (0,1): yield result + else: break + clientHello = result + + #Get the ServerHello. + for result in self._clientGetServerHello(settings, clientHello): + if result in (0,1): yield result + else: break + serverHello = result + cipherSuite = serverHello.cipher_suite + + # Choose a matching Next Protocol from server list against ours + # (string or None) + nextProto = self._clientSelectNextProto(nextProtos, serverHello) + + #If the server elected to resume the session, it is handled here. + for result in self._clientResume(session, serverHello, + clientHello.random, + settings.cipherImplementations, + nextProto): + if result in (0,1): yield result + else: break + if result == "resumed_and_finished": + self._handshakeDone(resumed=True) + return + + #If the server selected an SRP ciphersuite, the client finishes + #reading the post-ServerHello messages, then derives a + #premasterSecret and sends a corresponding ClientKeyExchange. + if cipherSuite in CipherSuite.srpAllSuites: + for result in self._clientSRPKeyExchange(\ + settings, cipherSuite, serverHello.certificate_type, + srpUsername, password, + clientHello.random, serverHello.random, + serverHello.tackExt): + if result in (0,1): yield result + else: break + (premasterSecret, serverCertChain, tackExt) = result + + #If the server selected an anonymous ciphersuite, the client + #finishes reading the post-ServerHello messages. + elif cipherSuite in CipherSuite.anonSuites: + for result in self._clientAnonKeyExchange(settings, cipherSuite, + clientHello.random, serverHello.random): + if result in (0,1): yield result + else: break + (premasterSecret, serverCertChain, tackExt) = result + + #If the server selected a certificate-based RSA ciphersuite, + #the client finishes reading the post-ServerHello messages. If + #a CertificateRequest message was sent, the client responds with + #a Certificate message containing its certificate chain (if any), + #and also produces a CertificateVerify message that signs the + #ClientKeyExchange. + else: + for result in self._clientRSAKeyExchange(settings, cipherSuite, + clientCertChain, privateKey, + serverHello.certificate_type, + clientHello.random, serverHello.random, + serverHello.tackExt): + if result in (0,1): yield result + else: break + (premasterSecret, serverCertChain, clientCertChain, + tackExt) = result + + #After having previously sent a ClientKeyExchange, the client now + #initiates an exchange of Finished messages. + for result in self._clientFinished(premasterSecret, + clientHello.random, + serverHello.random, + cipherSuite, settings.cipherImplementations, + nextProto): + if result in (0,1): yield result + else: break + masterSecret = result + + # Create the session object which is used for resumptions + self.session = Session() + self.session.create(masterSecret, serverHello.session_id, cipherSuite, + srpUsername, clientCertChain, serverCertChain, + tackExt, serverHello.tackExt!=None, serverName) + self._handshakeDone(resumed=False) + + + def _clientSendClientHello(self, settings, session, srpUsername, + srpParams, certParams, anonParams, + serverName, nextProtos, reqTack): + #Initialize acceptable ciphersuites + cipherSuites = [CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV] + if srpParams: + cipherSuites += CipherSuite.getSrpAllSuites(settings) + elif certParams: + cipherSuites += CipherSuite.getCertSuites(settings) + # TODO: Client DHE_RSA not supported. + # cipherSuites += CipherSuite.getDheCertSuites(settings) + elif anonParams: + cipherSuites += CipherSuite.getAnonSuites(settings) + else: + assert(False) + + #Initialize acceptable certificate types + certificateTypes = settings._getCertificateTypes() + + #Either send ClientHello (with a resumable session)... + if session and session.sessionID: + #If it's resumable, then its + #ciphersuite must be one of the acceptable ciphersuites + if session.cipherSuite not in cipherSuites: + raise ValueError("Session's cipher suite not consistent "\ + "with parameters") + else: + clientHello = ClientHello() + clientHello.create(settings.maxVersion, getRandomBytes(32), + session.sessionID, cipherSuites, + certificateTypes, + session.srpUsername, + reqTack, nextProtos is not None, + session.serverName) + + #Or send ClientHello (without) + else: + clientHello = ClientHello() + clientHello.create(settings.maxVersion, getRandomBytes(32), + bytearray(0), cipherSuites, + certificateTypes, + srpUsername, + reqTack, nextProtos is not None, + serverName) + for result in self._sendMsg(clientHello): + yield result + yield clientHello + + + def _clientGetServerHello(self, settings, clientHello): + for result in self._getMsg(ContentType.handshake, + HandshakeType.server_hello): + if result in (0,1): yield result + else: break + serverHello = result + + #Get the server version. Do this before anything else, so any + #error alerts will use the server's version + self.version = serverHello.server_version + + #Future responses from server must use this version + self._versionCheck = True + + #Check ServerHello + if serverHello.server_version < settings.minVersion: + for result in self._sendError(\ + AlertDescription.protocol_version, + "Too old version: %s" % str(serverHello.server_version)): + yield result + if serverHello.server_version > settings.maxVersion: + for result in self._sendError(\ + AlertDescription.protocol_version, + "Too new version: %s" % str(serverHello.server_version)): + yield result + if serverHello.cipher_suite not in clientHello.cipher_suites: + for result in self._sendError(\ + AlertDescription.illegal_parameter, + "Server responded with incorrect ciphersuite"): + yield result + if serverHello.certificate_type not in clientHello.certificate_types: + for result in self._sendError(\ + AlertDescription.illegal_parameter, + "Server responded with incorrect certificate type"): + yield result + if serverHello.compression_method != 0: + for result in self._sendError(\ + AlertDescription.illegal_parameter, + "Server responded with incorrect compression method"): + yield result + if serverHello.tackExt: + if not clientHello.tack: + for result in self._sendError(\ + AlertDescription.illegal_parameter, + "Server responded with unrequested Tack Extension"): + yield result + if serverHello.next_protos and not clientHello.supports_npn: + for result in self._sendError(\ + AlertDescription.illegal_parameter, + "Server responded with unrequested NPN Extension"): + yield result + if not serverHello.tackExt.verifySignatures(): + for result in self._sendError(\ + AlertDescription.decrypt_error, + "TackExtension contains an invalid signature"): + yield result + yield serverHello + + def _clientSelectNextProto(self, nextProtos, serverHello): + # nextProtos is None or non-empty list of strings + # serverHello.next_protos is None or possibly-empty list of strings + # + # !!! We assume the client may have specified nextProtos as a list of + # strings so we convert them to bytearrays (it's awkward to require + # the user to specify a list of bytearrays or "bytes", and in + # Python 2.6 bytes() is just an alias for str() anyways... + if nextProtos is not None and serverHello.next_protos is not None: + for p in nextProtos: + if bytearray(p) in serverHello.next_protos: + return bytearray(p) + else: + # If the client doesn't support any of server's protocols, + # or the server doesn't advertise any (next_protos == []) + # the client SHOULD select the first protocol it supports. + return bytearray(nextProtos[0]) + return None + + def _clientResume(self, session, serverHello, clientRandom, + cipherImplementations, nextProto): + #If the server agrees to resume + if session and session.sessionID and \ + serverHello.session_id == session.sessionID: + + if serverHello.cipher_suite != session.cipherSuite: + for result in self._sendError(\ + AlertDescription.illegal_parameter,\ + "Server's ciphersuite doesn't match session"): + yield result + + #Calculate pending connection states + self._calcPendingStates(session.cipherSuite, + session.masterSecret, + clientRandom, serverHello.random, + cipherImplementations) + + #Exchange ChangeCipherSpec and Finished messages + for result in self._getFinished(session.masterSecret): + yield result + for result in self._sendFinished(session.masterSecret, nextProto): + yield result + + #Set the session for this connection + self.session = session + yield "resumed_and_finished" + + def _clientSRPKeyExchange(self, settings, cipherSuite, certificateType, + srpUsername, password, + clientRandom, serverRandom, tackExt): + + #If the server chose an SRP+RSA suite... + if cipherSuite in CipherSuite.srpCertSuites: + #Get Certificate, ServerKeyExchange, ServerHelloDone + for result in self._getMsg(ContentType.handshake, + HandshakeType.certificate, certificateType): + if result in (0,1): yield result + else: break + serverCertificate = result + else: + serverCertificate = None + + for result in self._getMsg(ContentType.handshake, + HandshakeType.server_key_exchange, cipherSuite): + if result in (0,1): yield result + else: break + serverKeyExchange = result + + for result in self._getMsg(ContentType.handshake, + HandshakeType.server_hello_done): + if result in (0,1): yield result + else: break + serverHelloDone = result + + #Calculate SRP premaster secret + #Get and check the server's group parameters and B value + N = serverKeyExchange.srp_N + g = serverKeyExchange.srp_g + s = serverKeyExchange.srp_s + B = serverKeyExchange.srp_B + + if (g,N) not in goodGroupParameters: + for result in self._sendError(\ + AlertDescription.insufficient_security, + "Unknown group parameters"): + yield result + if numBits(N) < settings.minKeySize: + for result in self._sendError(\ + AlertDescription.insufficient_security, + "N value is too small: %d" % numBits(N)): + yield result + if numBits(N) > settings.maxKeySize: + for result in self._sendError(\ + AlertDescription.insufficient_security, + "N value is too large: %d" % numBits(N)): + yield result + if B % N == 0: + for result in self._sendError(\ + AlertDescription.illegal_parameter, + "Suspicious B value"): + yield result + + #Check the server's signature, if server chose an + #SRP+RSA suite + serverCertChain = None + if cipherSuite in CipherSuite.srpCertSuites: + #Hash ServerKeyExchange/ServerSRPParams + hashBytes = serverKeyExchange.hash(clientRandom, serverRandom) + + #Extract signature bytes from ServerKeyExchange + sigBytes = serverKeyExchange.signature + if len(sigBytes) == 0: + for result in self._sendError(\ + AlertDescription.illegal_parameter, + "Server sent an SRP ServerKeyExchange "\ + "message without a signature"): + yield result + + # Get server's public key from the Certificate message + # Also validate the chain against the ServerHello's TACKext (if any) + # If none, and a TACK cert is present, return its TACKext + for result in self._clientGetKeyFromChain(serverCertificate, + settings, tackExt): + if result in (0,1): yield result + else: break + publicKey, serverCertChain, tackExt = result + + #Verify signature + if not publicKey.verify(sigBytes, hashBytes): + for result in self._sendError(\ + AlertDescription.decrypt_error, + "Signature failed to verify"): + yield result + + #Calculate client's ephemeral DH values (a, A) + a = bytesToNumber(getRandomBytes(32)) + A = powMod(g, a, N) + + #Calculate client's static DH values (x, v) + x = makeX(s, bytearray(srpUsername, "utf-8"), + bytearray(password, "utf-8")) + v = powMod(g, x, N) + + #Calculate u + u = makeU(N, A, B) + + #Calculate premaster secret + k = makeK(N, g) + S = powMod((B - (k*v)) % N, a+(u*x), N) + + if self.fault == Fault.badA: + A = N + S = 0 + + premasterSecret = numberToByteArray(S) + + #Send ClientKeyExchange + for result in self._sendMsg(\ + ClientKeyExchange(cipherSuite).createSRP(A)): + yield result + yield (premasterSecret, serverCertChain, tackExt) + + + def _clientRSAKeyExchange(self, settings, cipherSuite, + clientCertChain, privateKey, + certificateType, + clientRandom, serverRandom, + tackExt): + + #Get Certificate[, CertificateRequest], ServerHelloDone + for result in self._getMsg(ContentType.handshake, + HandshakeType.certificate, certificateType): + if result in (0,1): yield result + else: break + serverCertificate = result + + # Get CertificateRequest or ServerHelloDone + for result in self._getMsg(ContentType.handshake, + (HandshakeType.server_hello_done, + HandshakeType.certificate_request)): + if result in (0,1): yield result + else: break + msg = result + certificateRequest = None + if isinstance(msg, CertificateRequest): + certificateRequest = msg + # We got CertificateRequest, so this must be ServerHelloDone + for result in self._getMsg(ContentType.handshake, + HandshakeType.server_hello_done): + if result in (0,1): yield result + else: break + serverHelloDone = result + elif isinstance(msg, ServerHelloDone): + serverHelloDone = msg + + # Get server's public key from the Certificate message + # Also validate the chain against the ServerHello's TACKext (if any) + # If none, and a TACK cert is present, return its TACKext + for result in self._clientGetKeyFromChain(serverCertificate, + settings, tackExt): + if result in (0,1): yield result + else: break + publicKey, serverCertChain, tackExt = result + + #Calculate premaster secret + premasterSecret = getRandomBytes(48) + premasterSecret[0] = settings.maxVersion[0] + premasterSecret[1] = settings.maxVersion[1] + + if self.fault == Fault.badPremasterPadding: + premasterSecret[0] = 5 + if self.fault == Fault.shortPremasterSecret: + premasterSecret = premasterSecret[:-1] + + #Encrypt premaster secret to server's public key + encryptedPreMasterSecret = publicKey.encrypt(premasterSecret) + + #If client authentication was requested, send Certificate + #message, either with certificates or empty + if certificateRequest: + clientCertificate = Certificate(certificateType) + + if clientCertChain: + #Check to make sure we have the same type of + #certificates the server requested + wrongType = False + if certificateType == CertificateType.x509: + if not isinstance(clientCertChain, X509CertChain): + wrongType = True + if wrongType: + for result in self._sendError(\ + AlertDescription.handshake_failure, + "Client certificate is of wrong type"): + yield result + + clientCertificate.create(clientCertChain) + for result in self._sendMsg(clientCertificate): + yield result + else: + #The server didn't request client auth, so we + #zeroize these so the clientCertChain won't be + #stored in the session. + privateKey = None + clientCertChain = None + + #Send ClientKeyExchange + clientKeyExchange = ClientKeyExchange(cipherSuite, + self.version) + clientKeyExchange.createRSA(encryptedPreMasterSecret) + for result in self._sendMsg(clientKeyExchange): + yield result + + #If client authentication was requested and we have a + #private key, send CertificateVerify + if certificateRequest and privateKey: + if self.version == (3,0): + masterSecret = calcMasterSecret(self.version, + premasterSecret, + clientRandom, + serverRandom) + verifyBytes = self._calcSSLHandshakeHash(masterSecret, b"") + elif self.version in ((3,1), (3,2)): + verifyBytes = self._handshake_md5.digest() + \ + self._handshake_sha.digest() + if self.fault == Fault.badVerifyMessage: + verifyBytes[0] = ((verifyBytes[0]+1) % 256) + signedBytes = privateKey.sign(verifyBytes) + certificateVerify = CertificateVerify() + certificateVerify.create(signedBytes) + for result in self._sendMsg(certificateVerify): + yield result + yield (premasterSecret, serverCertChain, clientCertChain, tackExt) + + def _clientAnonKeyExchange(self, settings, cipherSuite, clientRandom, + serverRandom): + for result in self._getMsg(ContentType.handshake, + HandshakeType.server_key_exchange, cipherSuite): + if result in (0,1): yield result + else: break + serverKeyExchange = result + + for result in self._getMsg(ContentType.handshake, + HandshakeType.server_hello_done): + if result in (0,1): yield result + else: break + serverHelloDone = result + + #calculate Yc + dh_p = serverKeyExchange.dh_p + dh_g = serverKeyExchange.dh_g + dh_Xc = bytesToNumber(getRandomBytes(32)) + dh_Ys = serverKeyExchange.dh_Ys + dh_Yc = powMod(dh_g, dh_Xc, dh_p) + + #Send ClientKeyExchange + for result in self._sendMsg(\ + ClientKeyExchange(cipherSuite, self.version).createDH(dh_Yc)): + yield result + + #Calculate premaster secret + S = powMod(dh_Ys, dh_Xc, dh_p) + premasterSecret = numberToByteArray(S) + + yield (premasterSecret, None, None) + + def _clientFinished(self, premasterSecret, clientRandom, serverRandom, + cipherSuite, cipherImplementations, nextProto): + + masterSecret = calcMasterSecret(self.version, premasterSecret, + clientRandom, serverRandom) + self._calcPendingStates(cipherSuite, masterSecret, + clientRandom, serverRandom, + cipherImplementations) + + #Exchange ChangeCipherSpec and Finished messages + for result in self._sendFinished(masterSecret, nextProto): + yield result + for result in self._getFinished(masterSecret, nextProto=nextProto): + yield result + yield masterSecret + + def _clientGetKeyFromChain(self, certificate, settings, tackExt=None): + #Get and check cert chain from the Certificate message + certChain = certificate.certChain + if not certChain or certChain.getNumCerts() == 0: + for result in self._sendError(AlertDescription.illegal_parameter, + "Other party sent a Certificate message without "\ + "certificates"): + yield result + + #Get and check public key from the cert chain + publicKey = certChain.getEndEntityPublicKey() + if len(publicKey) < settings.minKeySize: + for result in self._sendError(AlertDescription.handshake_failure, + "Other party's public key too small: %d" % len(publicKey)): + yield result + if len(publicKey) > settings.maxKeySize: + for result in self._sendError(AlertDescription.handshake_failure, + "Other party's public key too large: %d" % len(publicKey)): + yield result + + # If there's no TLS Extension, look for a TACK cert + if tackpyLoaded: + if not tackExt: + tackExt = certChain.getTackExt() + + # If there's a TACK (whether via TLS or TACK Cert), check that it + # matches the cert chain + if tackExt and tackExt.tacks: + for tack in tackExt.tacks: + if not certChain.checkTack(tack): + for result in self._sendError( + AlertDescription.illegal_parameter, + "Other party's TACK doesn't match their public key"): + yield result + + yield publicKey, certChain, tackExt + + + #********************************************************* + # Server Handshake Functions + #********************************************************* + + + def handshakeServer(self, verifierDB=None, + certChain=None, privateKey=None, reqCert=False, + sessionCache=None, settings=None, checker=None, + reqCAs = None, reqCertTypes = None, + tacks=None, activationFlags=0, + nextProtos=None, anon=False, + tlsIntolerant=None, signedCertTimestamps=None, + fallbackSCSV=False, ocspResponse=None): + """Perform a handshake in the role of server. + + This function performs an SSL or TLS handshake. Depending on + the arguments and the behavior of the client, this function can + perform an SRP, or certificate-based handshake. It + can also perform a combined SRP and server-certificate + handshake. + + Like any handshake function, this can be called on a closed + TLS connection, or on a TLS connection that is already open. + If called on an open connection it performs a re-handshake. + This function does not send a Hello Request message before + performing the handshake, so if re-handshaking is required, + the server must signal the client to begin the re-handshake + through some other means. + + If the function completes without raising an exception, the + TLS connection will be open and available for data transfer. + + If an exception is raised, the connection will have been + automatically closed (if it was ever open). + + @type verifierDB: L{tlslite.verifierdb.VerifierDB} + @param verifierDB: A database of SRP password verifiers + associated with usernames. If the client performs an SRP + handshake, the session's srpUsername attribute will be set. + + @type certChain: L{tlslite.x509certchain.X509CertChain} + @param certChain: The certificate chain to be used if the + client requests server certificate authentication. + + @type privateKey: L{tlslite.utils.rsakey.RSAKey} + @param privateKey: The private key to be used if the client + requests server certificate authentication. + + @type reqCert: bool + @param reqCert: Whether to request client certificate + authentication. This only applies if the client chooses server + certificate authentication; if the client chooses SRP + authentication, this will be ignored. If the client + performs a client certificate authentication, the sessions's + clientCertChain attribute will be set. + + @type sessionCache: L{tlslite.sessioncache.SessionCache} + @param sessionCache: An in-memory cache of resumable sessions. + The client can resume sessions from this cache. Alternatively, + if the client performs a full handshake, a new session will be + added to the cache. + + @type settings: L{tlslite.handshakesettings.HandshakeSettings} + @param settings: Various settings which can be used to control + the ciphersuites and SSL/TLS version chosen by the server. + + @type checker: L{tlslite.checker.Checker} + @param checker: A Checker instance. This instance will be + invoked to examine the other party's authentication + credentials, if the handshake completes succesfully. + + @type reqCAs: list of L{bytearray} of unsigned bytes + @param reqCAs: A collection of DER-encoded DistinguishedNames that + will be sent along with a certificate request. This does not affect + verification. + + @type reqCertTypes: list of int + @param reqCertTypes: A list of certificate_type values to be sent + along with a certificate request. This does not affect verification. + + @type nextProtos: list of strings. + @param nextProtos: A list of upper layer protocols to expose to the + clients through the Next-Protocol Negotiation Extension, + if they support it. + + @type tlsIntolerant: (int, int) or None + @param tlsIntolerant: If tlsIntolerant is not None, the server will + simulate TLS version intolerance by returning a fatal handshake_failure + alert to all TLS versions tlsIntolerant or higher. + + @type signedCertTimestamps: str + @param signedCertTimestamps: A SignedCertificateTimestampList (as a + binary 8-bit string) that will be sent as a TLS extension whenever + the client announces support for the extension. + + @type fallbackSCSV: bool + @param fallbackSCSV: if true, the server will implement + TLS_FALLBACK_SCSV and thus reject connections using less than the + server's maximum TLS version that include this cipher suite. + + @type ocspResponse: str + @param ocspResponse: An OCSP response (as a binary 8-bit string) that + will be sent stapled in the handshake whenever the client announces + support for the status_request extension. + Note that the response is sent independent of the ClientHello + status_request extension contents, and is thus only meant for testing + environments. Real OCSP stapling is more complicated as it requires + choosing a suitable response based on the ClientHello status_request + extension contents. + + @raise socket.error: If a socket error occurs. + @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed + without a preceding alert. + @raise tlslite.errors.TLSAlert: If a TLS alert is signalled. + @raise tlslite.errors.TLSAuthenticationError: If the checker + doesn't like the other party's authentication credentials. + """ + for result in self.handshakeServerAsync(verifierDB, + certChain, privateKey, reqCert, sessionCache, settings, + checker, reqCAs, reqCertTypes, + tacks=tacks, activationFlags=activationFlags, + nextProtos=nextProtos, anon=anon, tlsIntolerant=tlsIntolerant, + signedCertTimestamps=signedCertTimestamps, + fallbackSCSV=fallbackSCSV, ocspResponse=ocspResponse): + pass + + + def handshakeServerAsync(self, verifierDB=None, + certChain=None, privateKey=None, reqCert=False, + sessionCache=None, settings=None, checker=None, + reqCAs=None, reqCertTypes=None, + tacks=None, activationFlags=0, + nextProtos=None, anon=False, + tlsIntolerant=None, + signedCertTimestamps=None, + fallbackSCSV=False, + ocspResponse=None + ): + """Start a server handshake operation on the TLS connection. + + This function returns a generator which behaves similarly to + handshakeServer(). Successive invocations of the generator + will return 0 if it is waiting to read from the socket, 1 if it is + waiting to write to the socket, or it will raise StopIteration + if the handshake operation is complete. + + @rtype: iterable + @return: A generator; see above for details. + """ + handshaker = self._handshakeServerAsyncHelper(\ + verifierDB=verifierDB, certChain=certChain, + privateKey=privateKey, reqCert=reqCert, + sessionCache=sessionCache, settings=settings, + reqCAs=reqCAs, reqCertTypes=reqCertTypes, + tacks=tacks, activationFlags=activationFlags, + nextProtos=nextProtos, anon=anon, + tlsIntolerant=tlsIntolerant, + signedCertTimestamps=signedCertTimestamps, + fallbackSCSV=fallbackSCSV, + ocspResponse=ocspResponse) + for result in self._handshakeWrapperAsync(handshaker, checker): + yield result + + + def _handshakeServerAsyncHelper(self, verifierDB, + certChain, privateKey, reqCert, sessionCache, + settings, reqCAs, reqCertTypes, + tacks, activationFlags, + nextProtos, anon, + tlsIntolerant, signedCertTimestamps, fallbackSCSV, + ocspResponse): + + self._handshakeStart(client=False) + + if (not verifierDB) and (not certChain) and not anon: + raise ValueError("Caller passed no authentication credentials") + if certChain and not privateKey: + raise ValueError("Caller passed a certChain but no privateKey") + if privateKey and not certChain: + raise ValueError("Caller passed a privateKey but no certChain") + if reqCAs and not reqCert: + raise ValueError("Caller passed reqCAs but not reqCert") + if reqCertTypes and not reqCert: + raise ValueError("Caller passed reqCertTypes but not reqCert") + if certChain and not isinstance(certChain, X509CertChain): + raise ValueError("Unrecognized certificate type") + if activationFlags and not tacks: + raise ValueError("Nonzero activationFlags requires tacks") + if tacks: + if not tackpyLoaded: + raise ValueError("tackpy is not loaded") + if not settings or not settings.useExperimentalTackExtension: + raise ValueError("useExperimentalTackExtension not enabled") + if signedCertTimestamps and not certChain: + raise ValueError("Caller passed signedCertTimestamps but no " + "certChain") + + if not settings: + settings = HandshakeSettings() + settings = settings._filter() + + # OK Start exchanging messages + # ****************************** + + # Handle ClientHello and resumption + for result in self._serverGetClientHello(settings, certChain,\ + verifierDB, sessionCache, + anon, tlsIntolerant, fallbackSCSV): + if result in (0,1): yield result + elif result == None: + self._handshakeDone(resumed=True) + return # Handshake was resumed, we're done + else: break + (clientHello, cipherSuite) = result + + #If not a resumption... + + # Create the ServerHello message + if sessionCache: + sessionID = getRandomBytes(32) + else: + sessionID = bytearray(0) + + if not clientHello.supports_npn: + nextProtos = None + + # If not doing a certificate-based suite, discard the TACK + if not cipherSuite in CipherSuite.certAllSuites: + tacks = None + + # Prepare a TACK Extension if requested + if clientHello.tack: + tackExt = TackExtension.create(tacks, activationFlags) + else: + tackExt = None + serverHello = ServerHello() + serverHello.create(self.version, getRandomBytes(32), sessionID, \ + cipherSuite, CertificateType.x509, tackExt, + nextProtos) + serverHello.channel_id = clientHello.channel_id + if clientHello.support_signed_cert_timestamps: + serverHello.signed_cert_timestamps = signedCertTimestamps + if clientHello.status_request: + serverHello.status_request = ocspResponse + + # Perform the SRP key exchange + clientCertChain = None + if cipherSuite in CipherSuite.srpAllSuites: + for result in self._serverSRPKeyExchange(clientHello, serverHello, + verifierDB, cipherSuite, + privateKey, certChain): + if result in (0,1): yield result + else: break + premasterSecret = result + + # Perform the RSA or DHE_RSA key exchange + elif (cipherSuite in CipherSuite.certSuites or + cipherSuite in CipherSuite.dheCertSuites): + if cipherSuite in CipherSuite.certSuites: + keyExchange = RSAKeyExchange(cipherSuite, + clientHello, + serverHello, + privateKey) + elif cipherSuite in CipherSuite.dheCertSuites: + keyExchange = DHE_RSAKeyExchange(cipherSuite, + clientHello, + serverHello, + privateKey) + else: + assert(False) + for result in self._serverCertKeyExchange(clientHello, serverHello, + certChain, keyExchange, + reqCert, reqCAs, reqCertTypes, cipherSuite, + settings, ocspResponse): + if result in (0,1): yield result + else: break + (premasterSecret, clientCertChain) = result + + # Perform anonymous Diffie Hellman key exchange + elif cipherSuite in CipherSuite.anonSuites: + for result in self._serverAnonKeyExchange(clientHello, serverHello, + cipherSuite, settings): + if result in (0,1): yield result + else: break + premasterSecret = result + + else: + assert(False) + + # Exchange Finished messages + for result in self._serverFinished(premasterSecret, + clientHello.random, serverHello.random, + cipherSuite, settings.cipherImplementations, + nextProtos, clientHello.channel_id): + if result in (0,1): yield result + else: break + masterSecret = result + + #Create the session object + self.session = Session() + if cipherSuite in CipherSuite.certAllSuites: + serverCertChain = certChain + else: + serverCertChain = None + srpUsername = None + serverName = None + if clientHello.srp_username: + srpUsername = clientHello.srp_username.decode("utf-8") + if clientHello.server_name: + serverName = clientHello.server_name.decode("utf-8") + self.session.create(masterSecret, serverHello.session_id, cipherSuite, + srpUsername, clientCertChain, serverCertChain, + tackExt, serverHello.tackExt!=None, serverName) + + #Add the session object to the session cache + if sessionCache and sessionID: + sessionCache[sessionID] = self.session + + self._handshakeDone(resumed=False) + + + def _serverGetClientHello(self, settings, certChain, verifierDB, + sessionCache, anon, tlsIntolerant, fallbackSCSV): + #Initialize acceptable cipher suites + cipherSuites = [] + if verifierDB: + if certChain: + cipherSuites += \ + CipherSuite.getSrpCertSuites(settings) + cipherSuites += CipherSuite.getSrpSuites(settings) + elif certChain: + cipherSuites += CipherSuite.getCertSuites(settings) + cipherSuites += CipherSuite.getDheCertSuites(settings) + elif anon: + cipherSuites += CipherSuite.getAnonSuites(settings) + else: + assert(False) + + #Tentatively set version to most-desirable version, so if an error + #occurs parsing the ClientHello, this is what we'll use for the + #error alert + self.version = settings.maxVersion + + #Get ClientHello + for result in self._getMsg(ContentType.handshake, + HandshakeType.client_hello): + if result in (0,1): yield result + else: break + clientHello = result + + #If client's version is too low, reject it + if clientHello.client_version < settings.minVersion: + self.version = settings.minVersion + for result in self._sendError(\ + AlertDescription.protocol_version, + "Too old version: %s" % str(clientHello.client_version)): + yield result + + #If simulating TLS intolerance, reject certain TLS versions. + elif (tlsIntolerant is not None and + clientHello.client_version >= tlsIntolerant): + for result in self._sendError(\ + AlertDescription.handshake_failure): + yield result + + #If client's version is too high, propose my highest version + elif clientHello.client_version > settings.maxVersion: + self.version = settings.maxVersion + + #Detect if the client performed an inappropriate fallback. + elif fallbackSCSV and clientHello.client_version < settings.maxVersion: + if CipherSuite.TLS_FALLBACK_SCSV in clientHello.cipher_suites: + for result in self._sendError(\ + AlertDescription.inappropriate_fallback): + yield result + + else: + #Set the version to the client's version + self.version = clientHello.client_version + + #If resumption was requested and we have a session cache... + if clientHello.session_id and sessionCache: + session = None + + #Check in the session cache + if sessionCache and not session: + try: + session = sessionCache[clientHello.session_id] + if not session.resumable: + raise AssertionError() + #Check for consistency with ClientHello + if session.cipherSuite not in cipherSuites: + for result in self._sendError(\ + AlertDescription.handshake_failure): + yield result + if session.cipherSuite not in clientHello.cipher_suites: + for result in self._sendError(\ + AlertDescription.handshake_failure): + yield result + if clientHello.srp_username: + if not session.srpUsername or \ + clientHello.srp_username != bytearray(session.srpUsername, "utf-8"): + for result in self._sendError(\ + AlertDescription.handshake_failure): + yield result + if clientHello.server_name: + if not session.serverName or \ + clientHello.server_name != bytearray(session.serverName, "utf-8"): + for result in self._sendError(\ + AlertDescription.handshake_failure): + yield result + except KeyError: + pass + + #If a session is found.. + if session: + #Send ServerHello + serverHello = ServerHello() + serverHello.create(self.version, getRandomBytes(32), + session.sessionID, session.cipherSuite, + CertificateType.x509, None, None) + for result in self._sendMsg(serverHello): + yield result + + #From here on, the client's messages must have right version + self._versionCheck = True + + #Calculate pending connection states + self._calcPendingStates(session.cipherSuite, + session.masterSecret, + clientHello.random, + serverHello.random, + settings.cipherImplementations) + + #Exchange ChangeCipherSpec and Finished messages + for result in self._sendFinished(session.masterSecret): + yield result + for result in self._getFinished(session.masterSecret): + yield result + + #Set the session + self.session = session + + yield None # Handshake done! + + #Calculate the first cipher suite intersection. + #This is the 'privileged' ciphersuite. We'll use it if we're + #doing a new negotiation. In fact, + #the only time we won't use it is if we're resuming a + #session, in which case we use the ciphersuite from the session. + # + #Use the client's preferences for now. + for cipherSuite in clientHello.cipher_suites: + if cipherSuite in cipherSuites: + break + else: + for result in self._sendError(\ + AlertDescription.handshake_failure, + "No mutual ciphersuite"): + yield result + if cipherSuite in CipherSuite.srpAllSuites and \ + not clientHello.srp_username: + for result in self._sendError(\ + AlertDescription.unknown_psk_identity, + "Client sent a hello, but without the SRP username"): + yield result + + #If an RSA suite is chosen, check for certificate type intersection + if cipherSuite in CipherSuite.certAllSuites and CertificateType.x509 \ + not in clientHello.certificate_types: + for result in self._sendError(\ + AlertDescription.handshake_failure, + "the client doesn't support my certificate type"): + yield result + + # If resumption was not requested, or + # we have no session cache, or + # the client's session_id was not found in cache: + yield (clientHello, cipherSuite) + + def _serverSRPKeyExchange(self, clientHello, serverHello, verifierDB, + cipherSuite, privateKey, serverCertChain): + + srpUsername = clientHello.srp_username.decode("utf-8") + self.allegedSrpUsername = srpUsername + #Get parameters from username + try: + entry = verifierDB[srpUsername] + except KeyError: + for result in self._sendError(\ + AlertDescription.unknown_psk_identity): + yield result + (N, g, s, v) = entry + + #Calculate server's ephemeral DH values (b, B) + b = bytesToNumber(getRandomBytes(32)) + k = makeK(N, g) + B = (powMod(g, b, N) + (k*v)) % N + + #Create ServerKeyExchange, signing it if necessary + serverKeyExchange = ServerKeyExchange(cipherSuite) + serverKeyExchange.createSRP(N, g, s, B) + if cipherSuite in CipherSuite.srpCertSuites: + hashBytes = serverKeyExchange.hash(clientHello.random, + serverHello.random) + serverKeyExchange.signature = privateKey.sign(hashBytes) + + #Send ServerHello[, Certificate], ServerKeyExchange, + #ServerHelloDone + msgs = [] + msgs.append(serverHello) + if cipherSuite in CipherSuite.srpCertSuites: + certificateMsg = Certificate(CertificateType.x509) + certificateMsg.create(serverCertChain) + msgs.append(certificateMsg) + msgs.append(serverKeyExchange) + msgs.append(ServerHelloDone()) + for result in self._sendMsgs(msgs): + yield result + + #From here on, the client's messages must have the right version + self._versionCheck = True + + #Get and check ClientKeyExchange + for result in self._getMsg(ContentType.handshake, + HandshakeType.client_key_exchange, + cipherSuite): + if result in (0,1): yield result + else: break + clientKeyExchange = result + A = clientKeyExchange.srp_A + if A % N == 0: + for result in self._sendError(AlertDescription.illegal_parameter, + "Suspicious A value"): + yield result + assert(False) # Just to ensure we don't fall through somehow + + #Calculate u + u = makeU(N, A, B) + + #Calculate premaster secret + S = powMod((A * powMod(v,u,N)) % N, b, N) + premasterSecret = numberToByteArray(S) + + yield premasterSecret + + + def _serverCertKeyExchange(self, clientHello, serverHello, + serverCertChain, keyExchange, + reqCert, reqCAs, reqCertTypes, cipherSuite, + settings, ocspResponse): + #Send ServerHello, Certificate[, ServerKeyExchange] + #[, CertificateRequest], ServerHelloDone + msgs = [] + + # If we verify a client cert chain, return it + clientCertChain = None + + msgs.append(serverHello) + msgs.append(Certificate(CertificateType.x509).create(serverCertChain)) + if serverHello.status_request: + msgs.append(CertificateStatus().create(ocspResponse)) + serverKeyExchange = keyExchange.makeServerKeyExchange() + if serverKeyExchange is not None: + msgs.append(serverKeyExchange) + if reqCert: + reqCAs = reqCAs or [] + #Apple's Secure Transport library rejects empty certificate_types, + #so default to rsa_sign. + reqCertTypes = reqCertTypes or [ClientCertificateType.rsa_sign] + msgs.append(CertificateRequest().create(reqCertTypes, reqCAs)) + msgs.append(ServerHelloDone()) + for result in self._sendMsgs(msgs): + yield result + + #From here on, the client's messages must have the right version + self._versionCheck = True + + #Get [Certificate,] (if was requested) + if reqCert: + if self.version == (3,0): + for result in self._getMsg((ContentType.handshake, + ContentType.alert), + HandshakeType.certificate, + CertificateType.x509): + if result in (0,1): yield result + else: break + msg = result + + if isinstance(msg, Alert): + #If it's not a no_certificate alert, re-raise + alert = msg + if alert.description != \ + AlertDescription.no_certificate: + self._shutdown(False) + raise TLSRemoteAlert(alert) + elif isinstance(msg, Certificate): + clientCertificate = msg + if clientCertificate.certChain and \ + clientCertificate.certChain.getNumCerts()!=0: + clientCertChain = clientCertificate.certChain + else: + raise AssertionError() + elif self.version in ((3,1), (3,2)): + for result in self._getMsg(ContentType.handshake, + HandshakeType.certificate, + CertificateType.x509): + if result in (0,1): yield result + else: break + clientCertificate = result + if clientCertificate.certChain and \ + clientCertificate.certChain.getNumCerts()!=0: + clientCertChain = clientCertificate.certChain + else: + raise AssertionError() + + #Get ClientKeyExchange + for result in self._getMsg(ContentType.handshake, + HandshakeType.client_key_exchange, + cipherSuite): + if result in (0,1): yield result + else: break + clientKeyExchange = result + + #Process ClientKeyExchange + try: + premasterSecret = \ + keyExchange.processClientKeyExchange(clientKeyExchange) + except TLSLocalAlert, alert: + for result in self._sendError(alert.description, alert.message): + yield result + + #Get and check CertificateVerify, if relevant + if clientCertChain: + if self.version == (3,0): + masterSecret = calcMasterSecret(self.version, premasterSecret, + clientHello.random, serverHello.random) + verifyBytes = self._calcSSLHandshakeHash(masterSecret, b"") + elif self.version in ((3,1), (3,2)): + verifyBytes = self._handshake_md5.digest() + \ + self._handshake_sha.digest() + for result in self._getMsg(ContentType.handshake, + HandshakeType.certificate_verify): + if result in (0,1): yield result + else: break + certificateVerify = result + publicKey = clientCertChain.getEndEntityPublicKey() + if len(publicKey) < settings.minKeySize: + for result in self._sendError(\ + AlertDescription.handshake_failure, + "Client's public key too small: %d" % len(publicKey)): + yield result + + if len(publicKey) > settings.maxKeySize: + for result in self._sendError(\ + AlertDescription.handshake_failure, + "Client's public key too large: %d" % len(publicKey)): + yield result + + if not publicKey.verify(certificateVerify.signature, verifyBytes): + for result in self._sendError(\ + AlertDescription.decrypt_error, + "Signature failed to verify"): + yield result + yield (premasterSecret, clientCertChain) + + + def _serverAnonKeyExchange(self, clientHello, serverHello, cipherSuite, + settings): + # Calculate DH p, g, Xs, Ys + dh_p = getRandomSafePrime(32, False) + dh_g = getRandomNumber(2, dh_p) + dh_Xs = bytesToNumber(getRandomBytes(32)) + dh_Ys = powMod(dh_g, dh_Xs, dh_p) + + #Create ServerKeyExchange + serverKeyExchange = ServerKeyExchange(cipherSuite) + serverKeyExchange.createDH(dh_p, dh_g, dh_Ys) + + #Send ServerHello[, Certificate], ServerKeyExchange, + #ServerHelloDone + msgs = [] + msgs.append(serverHello) + msgs.append(serverKeyExchange) + msgs.append(ServerHelloDone()) + for result in self._sendMsgs(msgs): + yield result + + #From here on, the client's messages must have the right version + self._versionCheck = True + + #Get and check ClientKeyExchange + for result in self._getMsg(ContentType.handshake, + HandshakeType.client_key_exchange, + cipherSuite): + if result in (0,1): + yield result + else: + break + clientKeyExchange = result + dh_Yc = clientKeyExchange.dh_Yc + + if dh_Yc % dh_p == 0: + for result in self._sendError(AlertDescription.illegal_parameter, + "Suspicious dh_Yc value"): + yield result + assert(False) # Just to ensure we don't fall through somehow + + #Calculate premaster secre + S = powMod(dh_Yc,dh_Xs,dh_p) + premasterSecret = numberToByteArray(S) + + yield premasterSecret + + + def _serverFinished(self, premasterSecret, clientRandom, serverRandom, + cipherSuite, cipherImplementations, nextProtos, + doingChannelID): + masterSecret = calcMasterSecret(self.version, premasterSecret, + clientRandom, serverRandom) + + #Calculate pending connection states + self._calcPendingStates(cipherSuite, masterSecret, + clientRandom, serverRandom, + cipherImplementations) + + #Exchange ChangeCipherSpec and Finished messages + for result in self._getFinished(masterSecret, + expect_next_protocol=nextProtos is not None, + expect_channel_id=doingChannelID): + yield result + + for result in self._sendFinished(masterSecret): + yield result + + yield masterSecret + + + #********************************************************* + # Shared Handshake Functions + #********************************************************* + + + def _sendFinished(self, masterSecret, nextProto=None): + #Send ChangeCipherSpec + for result in self._sendMsg(ChangeCipherSpec()): + yield result + + #Switch to pending write state + self._changeWriteState() + + if nextProto is not None: + nextProtoMsg = NextProtocol().create(nextProto) + for result in self._sendMsg(nextProtoMsg): + yield result + + #Calculate verification data + verifyData = self._calcFinished(masterSecret, True) + if self.fault == Fault.badFinished: + verifyData[0] = (verifyData[0]+1)%256 + + #Send Finished message under new state + finished = Finished(self.version).create(verifyData) + for result in self._sendMsg(finished): + yield result + + def _getFinished(self, masterSecret, expect_next_protocol=False, nextProto=None, + expect_channel_id=False): + #Get and check ChangeCipherSpec + for result in self._getMsg(ContentType.change_cipher_spec): + if result in (0,1): + yield result + changeCipherSpec = result + + if changeCipherSpec.type != 1: + for result in self._sendError(AlertDescription.illegal_parameter, + "ChangeCipherSpec type incorrect"): + yield result + + #Switch to pending read state + self._changeReadState() + + #Server Finish - Are we waiting for a next protocol echo? + if expect_next_protocol: + for result in self._getMsg(ContentType.handshake, HandshakeType.next_protocol): + if result in (0,1): + yield result + if result is None: + for result in self._sendError(AlertDescription.unexpected_message, + "Didn't get NextProtocol message"): + yield result + + self.next_proto = result.next_proto + else: + self.next_proto = None + + #Client Finish - Only set the next_protocol selected in the connection + if nextProto: + self.next_proto = nextProto + + #Server Finish - Are we waiting for a EncryptedExtensions? + if expect_channel_id: + for result in self._getMsg(ContentType.handshake, HandshakeType.encrypted_extensions): + if result in (0,1): + yield result + if result is None: + for result in self._sendError(AlertDescription.unexpected_message, + "Didn't get EncryptedExtensions message"): + yield result + encrypted_extensions = result + self.channel_id = result.channel_id_key + else: + self.channel_id = None + + #Calculate verification data + verifyData = self._calcFinished(masterSecret, False) + + #Get and check Finished message under new state + for result in self._getMsg(ContentType.handshake, + HandshakeType.finished): + if result in (0,1): + yield result + finished = result + if finished.verify_data != verifyData: + for result in self._sendError(AlertDescription.decrypt_error, + "Finished message is incorrect"): + yield result + + def _calcFinished(self, masterSecret, send=True): + if self.version == (3,0): + if (self._client and send) or (not self._client and not send): + senderStr = b"\x43\x4C\x4E\x54" + else: + senderStr = b"\x53\x52\x56\x52" + + verifyData = self._calcSSLHandshakeHash(masterSecret, senderStr) + return verifyData + + elif self.version in ((3,1), (3,2)): + if (self._client and send) or (not self._client and not send): + label = b"client finished" + else: + label = b"server finished" + + handshakeHashes = self._handshake_md5.digest() + \ + self._handshake_sha.digest() + verifyData = PRF(masterSecret, label, handshakeHashes, 12) + return verifyData + else: + raise AssertionError() + + + def _handshakeWrapperAsync(self, handshaker, checker): + if not self.fault: + try: + for result in handshaker: + yield result + if checker: + try: + checker(self) + except TLSAuthenticationError: + alert = Alert().create(AlertDescription.close_notify, + AlertLevel.fatal) + for result in self._sendMsg(alert): + yield result + raise + except GeneratorExit: + raise + except TLSAlert as alert: + if not self.fault: + raise + if alert.description not in Fault.faultAlerts[self.fault]: + raise TLSFaultError(str(alert)) + else: + pass + except: + self._shutdown(False) + raise diff --git a/chromium/third_party/tlslite/tlslite/TLSRecordLayer.py b/chromium/third_party/tlslite/tlslite/tlsrecordlayer.py index 933b95a9de6..370dc9a726a 100644 --- a/chromium/third_party/tlslite/tlslite/TLSRecordLayer.py +++ b/chromium/third_party/tlslite/tlslite/tlsrecordlayer.py @@ -1,49 +1,41 @@ +# Authors: +# Trevor Perrin +# Google (adapted by Sam Rushing) - NPN support +# Martin von Loewis - python 3 port +# +# See the LICENSE file for legal information regarding use of this file. + """Helper class for TLSConnection.""" from __future__ import generators -from utils.compat import * -from utils.cryptomath import * -from utils.cipherfactory import createAES, createRC4, createTripleDES -from utils.codec import * -from errors import * -from messages import * -from mathtls import * -from constants import * -from utils.cryptomath import getRandomBytes -from utils import hmac -from FileObject import FileObject - -# The sha module is deprecated in Python 2.6 -try: - import sha -except ImportError: - from hashlib import sha1 as sha - -# The md5 module is deprecated in Python 2.6 -try: - import md5 -except ImportError: - from hashlib import md5 +from .utils.compat import * +from .utils.cryptomath import * +from .utils.cipherfactory import createAES, createRC4, createTripleDES +from .utils.codec import * +from .errors import * +from .messages import * +from .mathtls import * +from .constants import * +from .utils.cryptomath import getRandomBytes import socket import errno import traceback -class _ConnectionState: +class _ConnectionState(object): def __init__(self): self.macContext = None self.encContext = None self.seqnum = 0 - def getSeqNumStr(self): - w = Writer(8) + def getSeqNumBytes(self): + w = Writer() w.add(self.seqnum, 8) - seqnumStr = bytesToString(w.bytes) self.seqnum += 1 - return seqnumStr + return w.bytes -class TLSRecordLayer: +class TLSRecordLayer(object): """ This class handles data transmission for a TLS connection. @@ -72,13 +64,6 @@ class TLSRecordLayer: @type resumed: bool @ivar resumed: If this connection is based on a resumed session. - @type allegedSharedKeyUsername: str or None - @ivar allegedSharedKeyUsername: This is set to the shared-key - username asserted by the client, whether the handshake succeeded or - not. If the handshake fails, this can be inspected to - determine if a guessing attack is in progress against a particular - user account. - @type allegedSrpUsername: str or None @ivar allegedSrpUsername: This is set to the SRP username asserted by the client, whether the handshake succeeded or not. @@ -88,7 +73,7 @@ class TLSRecordLayer: @type closeSocket: bool @ivar closeSocket: If the socket should be closed when the - connection is closed (writable). + connection is closed, defaults to True (writable). If you set this to True, TLS Lite will assume the responsibility of closing the socket when the TLS Connection is shutdown (either @@ -124,11 +109,12 @@ class TLSRecordLayer: #Buffers for processing messages self._handshakeBuffer = [] - self._readBuffer = "" + self.clearReadBuffer() + self.clearWriteBuffer() #Handshake digests - self._handshake_md5 = md5.md5() - self._handshake_sha = sha.sha() + self._handshake_md5 = hashlib.md5() + self._handshake_sha = hashlib.sha1() #TLS Protocol Version self.version = (0,0) #read-only @@ -144,15 +130,14 @@ class TLSRecordLayer: self.closed = True #read-only self._refCount = 0 #Used to trigger closure - #Is this a resumed (or shared-key) session? + #Is this a resumed session? self.resumed = False #read-only #What username did the client claim in his handshake? - self.allegedSharedKeyUsername = None self.allegedSrpUsername = None #On a call to close(), do we close the socket? (writeable) - self.closeSocket = False + self.closeSocket = True #If the socket is abruptly closed, do we ignore it #and pretend the connection was shut down properly? (writeable) @@ -161,6 +146,13 @@ class TLSRecordLayer: #Fault we will induce, for testing purposes self.fault = None + def clearReadBuffer(self): + self._readBuffer = b'' + + def clearWriteBuffer(self): + self._send_writer = None + + #********************************************************* # Public Functions START #********************************************************* @@ -213,8 +205,8 @@ class TLSRecordLayer: if result in (0,1): yield result applicationData = result - self._readBuffer += bytesToString(applicationData.write()) - except TLSRemoteAlert, alert: + self._readBuffer += applicationData.write() + except TLSRemoteAlert as alert: if alert.description != AlertDescription.close_notify: raise except TLSAbruptCloseError: @@ -226,13 +218,23 @@ class TLSRecordLayer: if max == None: max = len(self._readBuffer) - returnStr = self._readBuffer[:max] + returnBytes = self._readBuffer[:max] self._readBuffer = self._readBuffer[max:] - yield returnStr + yield bytes(returnBytes) + except GeneratorExit: + raise except: self._shutdown(False) raise + def unread(self, b): + """Add bytes to the front of the socket read buffer for future + reading. Be careful using this in the context of select(...): if you + unread the last data from a socket, that won't wake up selected waiters, + and those waiters may hang forever. + """ + self._readBuffer = b + self._readBuffer + def write(self, s): """Write some data to the TLS connection. @@ -262,11 +264,11 @@ class TLSRecordLayer: """ try: if self.closed: - raise ValueError() + raise TLSClosedConnectionError("attempt to write to closed connection") index = 0 blockSize = 16384 - skipEmptyFrag = False + randomizeFirstBlock = True while 1: startIndex = index * blockSize endIndex = startIndex + blockSize @@ -274,14 +276,19 @@ class TLSRecordLayer: break if endIndex > len(s): endIndex = len(s) - block = stringToBytes(s[startIndex : endIndex]) + block = bytearray(s[startIndex : endIndex]) applicationData = ApplicationData().create(block) - for result in self._sendMsg(applicationData, skipEmptyFrag): + for result in self._sendMsg(applicationData, \ + randomizeFirstBlock): yield result - skipEmptyFrag = True #only send an empy fragment on 1st message + randomizeFirstBlock = False #only on 1st message index += 1 - except: - self._shutdown(False) + except GeneratorExit: + raise + except Exception: + # Don't invalidate the session on write failure if abrupt closes are + # okay. + self._shutdown(self.ignoreAbruptClose) raise def close(self): @@ -309,6 +316,9 @@ class TLSRecordLayer: for result in self._decrefAsync(): pass + # Python 3 callback + _decref_socketios = close + def closeAsync(self): """Start a close operation on the TLS connection. @@ -333,30 +343,49 @@ class TLSRecordLayer: AlertDescription.close_notify, AlertLevel.warning)): yield result alert = None - # Forcing a shutdown as WinHTTP does not seem to be - # responsive to the close notify. - prevCloseSocket = self.closeSocket - self.closeSocket = True - self._shutdown(True) - self.closeSocket = prevCloseSocket - while not alert: - for result in self._getMsg((ContentType.alert, \ - ContentType.application_data)): - if result in (0,1): - yield result - if result.contentType == ContentType.alert: - alert = result - if alert.description == AlertDescription.close_notify: + # By default close the socket, since it's been observed + # that some other libraries will not respond to the + # close_notify alert, thus leaving us hanging if we're + # expecting it + if self.closeSocket: self._shutdown(True) else: - raise TLSRemoteAlert(alert) + while not alert: + for result in self._getMsg((ContentType.alert, \ + ContentType.application_data)): + if result in (0,1): + yield result + if result.contentType == ContentType.alert: + alert = result + if alert.description == AlertDescription.close_notify: + self._shutdown(True) + else: + raise TLSRemoteAlert(alert) except (socket.error, TLSAbruptCloseError): #If the other side closes the socket, that's okay self._shutdown(True) + except GeneratorExit: + raise except: self._shutdown(False) raise + def getVersionName(self): + """Get the name of this TLS version. + + @rtype: str + @return: The name of the TLS version used with this connection. + Either None, 'SSL 3.0', 'TLS 1.0', or 'TLS 1.1'. + """ + if self.version == (3,0): + return "SSL 3.0" + elif self.version == (3,1): + return "TLS 1.0" + elif self.version == (3,2): + return "TLS 1.1" + else: + return None + def getCipherName(self): """Get the name of the cipher used with this connection. @@ -374,8 +403,7 @@ class TLSRecordLayer: @rtype: str @return: The name of the cipher implementation used with - this connection. Either 'python', 'cryptlib', 'openssl', - or 'pycrypto'. + this connection. Either 'python', 'openssl', or 'pycrypto'. """ if not self._writeState.encContext: return None @@ -409,13 +437,35 @@ class TLSRecordLayer: """ return self.read(bufsize) + def recv_into(self, b): + # XXX doc string + data = self.read(len(b)) + if not data: + return None + b[:len(data)] = data + return len(data) + def makefile(self, mode='r', bufsize=-1): """Create a file object for the TLS connection (socket emulation). - @rtype: L{tlslite.FileObject.FileObject} + @rtype: L{socket._fileobject} """ self._refCount += 1 - return FileObject(self, mode, bufsize) + # So, it is pretty fragile to be using Python internal objects + # like this, but it is probably the best/easiest way to provide + # matching behavior for socket emulation purposes. The 'close' + # argument is nice, its apparently a recent addition to this + # class, so that when fileobject.close() gets called, it will + # close() us, causing the refcount to be decremented (decrefAsync). + # + # If this is the last close() on the outstanding fileobjects / + # TLSConnection, then the "actual" close alerts will be sent, + # socket closed, etc. + if sys.version_info < (3,): + return socket._fileobject(self, mode, bufsize, close=True) + else: + # XXX need to wrap this further if buffering is requested + return socket.SocketIO(self, mode) def getsockname(self): """Return the socket's own address (socket emulation).""" @@ -439,6 +489,14 @@ class TLSRecordLayer: """Set the value of the given socket option (socket emulation).""" return self.sock.setsockopt(level, optname, value) + def shutdown(self, how): + """Shutdown the underlying socket.""" + return self.sock.shutdown(how) + + def fileno(self): + """Not implement in TLS Lite.""" + raise NotImplementedError() + #********************************************************* # Public Functions END @@ -447,7 +505,6 @@ class TLSRecordLayer: def _shutdown(self, resumable): self._writeState = _ConnectionState() self._readState = _ConnectionState() - #Don't do this: self._readBuffer = "" self.version = (0,0) self._versionCheck = False self.closed = True @@ -467,53 +524,58 @@ class TLSRecordLayer: raise TLSLocalAlert(alert, errorStr) def _sendMsgs(self, msgs): - skipEmptyFrag = False + randomizeFirstBlock = True for msg in msgs: - for result in self._sendMsg(msg, skipEmptyFrag): + for result in self._sendMsg(msg, randomizeFirstBlock): yield result - skipEmptyFrag = True + randomizeFirstBlock = True - def _sendMsg(self, msg, skipEmptyFrag=False): - bytes = msg.write() - contentType = msg.contentType - - #Whenever we're connected and asked to send a message, - #we first send an empty Application Data message. This prevents + def _sendMsg(self, msg, randomizeFirstBlock = True): + #Whenever we're connected and asked to send an app data message, + #we first send the first byte of the message. This prevents #an attacker from launching a chosen-plaintext attack based on - #knowing the next IV. - if not self.closed and not skipEmptyFrag and self.version == (3,1): - if self._writeState.encContext: - if self._writeState.encContext.isBlockCipher: - for result in self._sendMsg(ApplicationData(), - skipEmptyFrag=True): - yield result + #knowing the next IV (a la BEAST). + if not self.closed and randomizeFirstBlock and self.version <= (3,1) \ + and self._writeState.encContext \ + and self._writeState.encContext.isBlockCipher \ + and isinstance(msg, ApplicationData): + msgFirstByte = msg.splitFirstByte() + for result in self._sendMsg(msgFirstByte, + randomizeFirstBlock = False): + yield result + + b = msg.write() + + # If a 1-byte message was passed in, and we "split" the + # first(only) byte off above, we may have a 0-length msg: + if len(b) == 0: + return + + contentType = msg.contentType #Update handshake hashes if contentType == ContentType.handshake: - bytesStr = bytesToString(bytes) - self._handshake_md5.update(bytesStr) - self._handshake_sha.update(bytesStr) + self._handshake_md5.update(compat26Str(b)) + self._handshake_sha.update(compat26Str(b)) #Calculate MAC if self._writeState.macContext: - seqnumStr = self._writeState.getSeqNumStr() - bytesStr = bytesToString(bytes) + seqnumBytes = self._writeState.getSeqNumBytes() mac = self._writeState.macContext.copy() - mac.update(seqnumStr) - mac.update(chr(contentType)) + mac.update(compatHMAC(seqnumBytes)) + mac.update(compatHMAC(bytearray([contentType]))) if self.version == (3,0): - mac.update( chr( int(len(bytes)/256) ) ) - mac.update( chr( int(len(bytes)%256) ) ) + mac.update( compatHMAC( bytearray([len(b)//256] ))) + mac.update( compatHMAC( bytearray([len(b)%256] ))) elif self.version in ((3,1), (3,2)): - mac.update(chr(self.version[0])) - mac.update(chr(self.version[1])) - mac.update( chr( int(len(bytes)/256) ) ) - mac.update( chr( int(len(bytes)%256) ) ) + mac.update(compatHMAC( bytearray([self.version[0]] ))) + mac.update(compatHMAC( bytearray([self.version[1]] ))) + mac.update( compatHMAC( bytearray([len(b)//256] ))) + mac.update( compatHMAC( bytearray([len(b)%256] ))) else: raise AssertionError() - mac.update(bytesStr) - macString = mac.digest() - macBytes = stringToBytes(macString) + mac.update(compatHMAC(b)) + macBytes = bytearray(mac.digest()) if self.fault == Fault.badMAC: macBytes[0] = (macBytes[0]+1) % 256 @@ -524,43 +586,68 @@ class TLSRecordLayer: #Add TLS 1.1 fixed block if self.version == (3,2): - bytes = self.fixedIVBlock + bytes + b = self.fixedIVBlock + b - #Add padding: bytes = bytes + (macBytes + paddingBytes) - currentLength = len(bytes) + len(macBytes) + 1 + #Add padding: b = b + (macBytes + paddingBytes) + currentLength = len(b) + len(macBytes) blockLength = self._writeState.encContext.block_size - paddingLength = blockLength-(currentLength % blockLength) + paddingLength = blockLength - 1 - (currentLength % blockLength) - paddingBytes = createByteArraySequence([paddingLength] * \ - (paddingLength+1)) + paddingBytes = bytearray([paddingLength] * (paddingLength+1)) if self.fault == Fault.badPadding: paddingBytes[0] = (paddingBytes[0]+1) % 256 - endBytes = concatArrays(macBytes, paddingBytes) - bytes = concatArrays(bytes, endBytes) + endBytes = macBytes + paddingBytes + b += endBytes #Encrypt - plaintext = stringToBytes(bytes) - ciphertext = self._writeState.encContext.encrypt(plaintext) - bytes = stringToBytes(ciphertext) + b = self._writeState.encContext.encrypt(b) #Encrypt (for Stream Cipher) else: - bytes = concatArrays(bytes, macBytes) - plaintext = bytesToString(bytes) - ciphertext = self._writeState.encContext.encrypt(plaintext) - bytes = stringToBytes(ciphertext) + b += macBytes + b = self._writeState.encContext.encrypt(b) #Add record header and send - r = RecordHeader3().create(self.version, contentType, len(bytes)) - s = bytesToString(concatArrays(r.write(), bytes)) + r = RecordHeader3().create(self.version, contentType, len(b)) + s = r.write() + b while 1: try: bytesSent = self.sock.send(s) #Might raise socket.error - except socket.error, why: - if why[0] == errno.EWOULDBLOCK: + except socket.error as why: + if why.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN): yield 1 continue else: - raise + # The socket was unexpectedly closed. The tricky part + # is that there may be an alert sent by the other party + # sitting in the read buffer. So, if we get here after + # handshaking, we will just raise the error and let the + # caller read more data if it would like, thus stumbling + # upon the error. + # + # However, if we get here DURING handshaking, we take + # it upon ourselves to see if the next message is an + # Alert. + if contentType == ContentType.handshake: + + # See if there's an alert record + # Could raise socket.error or TLSAbruptCloseError + for result in self._getNextRecord(): + if result in (0,1): + yield result + + # Closes the socket + self._shutdown(False) + + # If we got an alert, raise it + recordHeader, p = result + if recordHeader.type == ContentType.alert: + alert = Alert().parse(p) + raise TLSRemoteAlert(alert) + else: + # If we got some other message who know what + # the remote side is doing, just go ahead and + # raise the socket.error + raise if bytesSent == len(s): return s = s[bytesSent:] @@ -690,9 +777,8 @@ class TLSRecordLayer: yield result #Update handshake hashes - sToHash = bytesToString(p.bytes) - self._handshake_md5.update(sToHash) - self._handshake_sha.update(sToHash) + self._handshake_md5.update(compat26Str(p.bytes)) + self._handshake_sha.update(compat26Str(p.bytes)) #Parse based on handshake type if subType == HandshakeType.client_hello: @@ -714,13 +800,15 @@ class TLSRecordLayer: self.version).parse(p) elif subType == HandshakeType.finished: yield Finished(self.version).parse(p) + elif subType == HandshakeType.next_protocol: + yield NextProtocol().parse(p) elif subType == HandshakeType.encrypted_extensions: yield EncryptedExtensions().parse(p) else: raise AssertionError() #If an exception was raised by a Parser or Message instance: - except SyntaxError, e: + except SyntaxError as e: for result in self._sendError(AlertDescription.decode_error, formatExceptionTrace(e)): yield result @@ -731,21 +819,21 @@ class TLSRecordLayer: #If there's a handshake message waiting, return it if self._handshakeBuffer: - recordHeader, bytes = self._handshakeBuffer[0] + recordHeader, b = self._handshakeBuffer[0] self._handshakeBuffer = self._handshakeBuffer[1:] - yield (recordHeader, Parser(bytes)) + yield (recordHeader, Parser(b)) return #Otherwise... #Read the next record header - bytes = createByteArraySequence([]) + b = bytearray(0) recordHeaderLength = 1 ssl2 = False while 1: try: - s = self.sock.recv(recordHeaderLength-len(bytes)) - except socket.error, why: - if why[0] == errno.EWOULDBLOCK: + s = self.sock.recv(recordHeaderLength-len(b)) + except socket.error as why: + if why.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN): yield 0 continue else: @@ -755,24 +843,24 @@ class TLSRecordLayer: if len(s)==0: raise TLSAbruptCloseError() - bytes += stringToBytes(s) - if len(bytes)==1: - if bytes[0] in ContentType.all: + b += bytearray(s) + if len(b)==1: + if b[0] in ContentType.all: ssl2 = False recordHeaderLength = 5 - elif bytes[0] == 128: + elif b[0] == 128: ssl2 = True recordHeaderLength = 2 else: raise SyntaxError() - if len(bytes) == recordHeaderLength: + if len(b) == recordHeaderLength: break #Parse the record header if ssl2: - r = RecordHeader2().parse(Parser(bytes)) + r = RecordHeader2().parse(Parser(b)) else: - r = RecordHeader3().parse(Parser(bytes)) + r = RecordHeader3().parse(Parser(b)) #Check the record header fields if r.length > 18432: @@ -780,12 +868,12 @@ class TLSRecordLayer: yield result #Read the record contents - bytes = createByteArraySequence([]) + b = bytearray(0) while 1: try: - s = self.sock.recv(r.length - len(bytes)) - except socket.error, why: - if why[0] == errno.EWOULDBLOCK: + s = self.sock.recv(r.length - len(b)) + except socket.error as why: + if why.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN): yield 0 continue else: @@ -795,8 +883,8 @@ class TLSRecordLayer: if len(s)==0: raise TLSAbruptCloseError() - bytes += stringToBytes(s) - if len(bytes) == r.length: + b += bytearray(s) + if len(b) == r.length: break #Check the record header fields (2) @@ -814,13 +902,11 @@ class TLSRecordLayer: # yield result #Decrypt the record - for result in self._decryptRecord(r.type, bytes): - if result in (0,1): - yield result - else: - break - bytes = result - p = Parser(bytes) + for result in self._decryptRecord(r.type, b): + if result in (0,1): yield result + else: break + b = result + p = Parser(b) #If it doesn't contain handshake messages, we can just return it if r.type != ContentType.handshake: @@ -832,7 +918,7 @@ class TLSRecordLayer: #Otherwise, we loop through and add the handshake messages to the #handshake buffer while 1: - if p.index == len(bytes): #If we're at the end + if p.index == len(b): #If we're at the end if not self._handshakeBuffer: for result in self._sendError(\ AlertDescription.decode_error, \ @@ -840,51 +926,49 @@ class TLSRecordLayer: yield result break #There needs to be at least 4 bytes to get a header - if p.index+4 > len(bytes): + if p.index+4 > len(b): for result in self._sendError(\ AlertDescription.decode_error, "A record has a partial handshake message (1)"): yield result p.get(1) # skip handshake type msgLength = p.get(3) - if p.index+msgLength > len(bytes): + if p.index+msgLength > len(b): for result in self._sendError(\ AlertDescription.decode_error, "A record has a partial handshake message (2)"): yield result - handshakePair = (r, bytes[p.index-4 : p.index+msgLength]) + handshakePair = (r, b[p.index-4 : p.index+msgLength]) self._handshakeBuffer.append(handshakePair) p.index += msgLength #We've moved at least one handshake message into the #handshakeBuffer, return the first one - recordHeader, bytes = self._handshakeBuffer[0] + recordHeader, b = self._handshakeBuffer[0] self._handshakeBuffer = self._handshakeBuffer[1:] - yield (recordHeader, Parser(bytes)) + yield (recordHeader, Parser(b)) - def _decryptRecord(self, recordType, bytes): + def _decryptRecord(self, recordType, b): if self._readState.encContext: #Decrypt if it's a block cipher if self._readState.encContext.isBlockCipher: blockLength = self._readState.encContext.block_size - if len(bytes) % blockLength != 0: + if len(b) % blockLength != 0: for result in self._sendError(\ AlertDescription.decryption_failed, "Encrypted data not a multiple of blocksize"): yield result - ciphertext = bytesToString(bytes) - plaintext = self._readState.encContext.decrypt(ciphertext) + b = self._readState.encContext.decrypt(b) if self.version == (3,2): #For TLS 1.1, remove explicit IV - plaintext = plaintext[self._readState.encContext.block_size : ] - bytes = stringToBytes(plaintext) + b = b[self._readState.encContext.block_size : ] #Check padding paddingGood = True - paddingLength = bytes[-1] - if (paddingLength+1) > len(bytes): + paddingLength = b[-1] + if (paddingLength+1) > len(b): paddingGood=False totalPaddingLength = 0 else: @@ -892,7 +976,7 @@ class TLSRecordLayer: totalPaddingLength = paddingLength+1 elif self.version in ((3,1), (3,2)): totalPaddingLength = paddingLength+1 - paddingBytes = bytes[-totalPaddingLength:-1] + paddingBytes = b[-totalPaddingLength:-1] for byte in paddingBytes: if byte != paddingLength: paddingGood = False @@ -903,43 +987,39 @@ class TLSRecordLayer: #Decrypt if it's a stream cipher else: paddingGood = True - ciphertext = bytesToString(bytes) - plaintext = self._readState.encContext.decrypt(ciphertext) - bytes = stringToBytes(plaintext) + b = self._readState.encContext.decrypt(b) totalPaddingLength = 0 #Check MAC macGood = True macLength = self._readState.macContext.digest_size endLength = macLength + totalPaddingLength - if endLength > len(bytes): + if endLength > len(b): macGood = False else: #Read MAC - startIndex = len(bytes) - endLength + startIndex = len(b) - endLength endIndex = startIndex + macLength - checkBytes = bytes[startIndex : endIndex] + checkBytes = b[startIndex : endIndex] #Calculate MAC - seqnumStr = self._readState.getSeqNumStr() - bytes = bytes[:-endLength] - bytesStr = bytesToString(bytes) + seqnumBytes = self._readState.getSeqNumBytes() + b = b[:-endLength] mac = self._readState.macContext.copy() - mac.update(seqnumStr) - mac.update(chr(recordType)) + mac.update(compatHMAC(seqnumBytes)) + mac.update(compatHMAC(bytearray([recordType]))) if self.version == (3,0): - mac.update( chr( int(len(bytes)/256) ) ) - mac.update( chr( int(len(bytes)%256) ) ) + mac.update( compatHMAC(bytearray( [len(b)//256] ) )) + mac.update( compatHMAC(bytearray( [len(b)%256] ) )) elif self.version in ((3,1), (3,2)): - mac.update(chr(self.version[0])) - mac.update(chr(self.version[1])) - mac.update( chr( int(len(bytes)/256) ) ) - mac.update( chr( int(len(bytes)%256) ) ) + mac.update(compatHMAC(bytearray( [self.version[0]] ) )) + mac.update(compatHMAC(bytearray( [self.version[1]] ) )) + mac.update(compatHMAC(bytearray( [len(b)//256] ) )) + mac.update(compatHMAC(bytearray( [len(b)%256] ) )) else: raise AssertionError() - mac.update(bytesStr) - macString = mac.digest() - macBytes = stringToBytes(macString) + mac.update(compatHMAC(b)) + macBytes = bytearray(mac.digest()) #Compare MACs if macBytes != checkBytes: @@ -950,14 +1030,15 @@ class TLSRecordLayer: "MAC failure (or padding failure)"): yield result - yield bytes + yield b def _handshakeStart(self, client): + if not self.closed: + raise ValueError("Renegotiation disallowed for security reasons") self._client = client - self._handshake_md5 = md5.md5() - self._handshake_sha = sha.sha() + self._handshake_md5 = hashlib.md5() + self._handshake_sha = hashlib.sha1() self._handshakeBuffer = [] - self.allegedSharedKeyUsername = None self.allegedSrpUsername = None self._refCount = 1 @@ -965,46 +1046,50 @@ class TLSRecordLayer: self.resumed = resumed self.closed = False - def _calcPendingStates(self, clientRandom, serverRandom, implementations): - if self.session.cipherSuite in CipherSuite.aes128Suites: - macLength = 20 + def _calcPendingStates(self, cipherSuite, masterSecret, + clientRandom, serverRandom, implementations): + if cipherSuite in CipherSuite.aes128Suites: keyLength = 16 ivLength = 16 createCipherFunc = createAES - elif self.session.cipherSuite in CipherSuite.aes256Suites: - macLength = 20 + elif cipherSuite in CipherSuite.aes256Suites: keyLength = 32 ivLength = 16 createCipherFunc = createAES - elif self.session.cipherSuite in CipherSuite.rc4Suites: - macLength = 20 + elif cipherSuite in CipherSuite.rc4Suites: keyLength = 16 ivLength = 0 createCipherFunc = createRC4 - elif self.session.cipherSuite in CipherSuite.tripleDESSuites: - macLength = 20 + elif cipherSuite in CipherSuite.tripleDESSuites: keyLength = 24 ivLength = 8 createCipherFunc = createTripleDES else: raise AssertionError() + + if cipherSuite in CipherSuite.shaSuites: + macLength = 20 + digestmod = hashlib.sha1 + elif cipherSuite in CipherSuite.md5Suites: + macLength = 16 + digestmod = hashlib.md5 if self.version == (3,0): - createMACFunc = MAC_SSL + createMACFunc = createMAC_SSL elif self.version in ((3,1), (3,2)): - createMACFunc = hmac.HMAC + createMACFunc = createHMAC outputLength = (macLength*2) + (keyLength*2) + (ivLength*2) #Calculate Keying Material from Master Secret if self.version == (3,0): - keyBlock = PRF_SSL(self.session.masterSecret, - concatArrays(serverRandom, clientRandom), + keyBlock = PRF_SSL(masterSecret, + serverRandom + clientRandom, outputLength) elif self.version in ((3,1), (3,2)): - keyBlock = PRF(self.session.masterSecret, - "key expansion", - concatArrays(serverRandom,clientRandom), + keyBlock = PRF(masterSecret, + b"key expansion", + serverRandom + clientRandom, outputLength) else: raise AssertionError() @@ -1013,16 +1098,16 @@ class TLSRecordLayer: clientPendingState = _ConnectionState() serverPendingState = _ConnectionState() p = Parser(keyBlock) - clientMACBlock = bytesToString(p.getFixBytes(macLength)) - serverMACBlock = bytesToString(p.getFixBytes(macLength)) - clientKeyBlock = bytesToString(p.getFixBytes(keyLength)) - serverKeyBlock = bytesToString(p.getFixBytes(keyLength)) - clientIVBlock = bytesToString(p.getFixBytes(ivLength)) - serverIVBlock = bytesToString(p.getFixBytes(ivLength)) - clientPendingState.macContext = createMACFunc(clientMACBlock, - digestmod=sha) - serverPendingState.macContext = createMACFunc(serverMACBlock, - digestmod=sha) + clientMACBlock = p.getFixBytes(macLength) + serverMACBlock = p.getFixBytes(macLength) + clientKeyBlock = p.getFixBytes(keyLength) + serverKeyBlock = p.getFixBytes(keyLength) + clientIVBlock = p.getFixBytes(ivLength) + serverIVBlock = p.getFixBytes(ivLength) + clientPendingState.macContext = createMACFunc( + compatHMAC(clientMACBlock), digestmod=digestmod) + serverPendingState.macContext = createMACFunc( + compatHMAC(serverMACBlock), digestmod=digestmod) clientPendingState.encContext = createCipherFunc(clientKeyBlock, clientIVBlock, implementations) @@ -1051,100 +1136,18 @@ class TLSRecordLayer: self._readState = self._pendingReadState self._pendingReadState = _ConnectionState() - def _sendFinished(self): - #Send ChangeCipherSpec - for result in self._sendMsg(ChangeCipherSpec()): - yield result - - #Switch to pending write state - self._changeWriteState() - - #Calculate verification data - verifyData = self._calcFinished(True) - if self.fault == Fault.badFinished: - verifyData[0] = (verifyData[0]+1)%256 - - #Send Finished message under new state - finished = Finished(self.version).create(verifyData) - for result in self._sendMsg(finished): - yield result - - def _getChangeCipherSpec(self): - #Get and check ChangeCipherSpec - for result in self._getMsg(ContentType.change_cipher_spec): - if result in (0,1): - yield result - changeCipherSpec = result - - if changeCipherSpec.type != 1: - for result in self._sendError(AlertDescription.illegal_parameter, - "ChangeCipherSpec type incorrect"): - yield result - - #Switch to pending read state - self._changeReadState() - - def _getEncryptedExtensions(self): - for result in self._getMsg(ContentType.handshake, - HandshakeType.encrypted_extensions): - if result in (0,1): - yield result - encrypted_extensions = result - self.channel_id = encrypted_extensions.channel_id_key - - def _getFinished(self): - #Calculate verification data - verifyData = self._calcFinished(False) - - #Get and check Finished message under new state - for result in self._getMsg(ContentType.handshake, - HandshakeType.finished): - if result in (0,1): - yield result - finished = result - if finished.verify_data != verifyData: - for result in self._sendError(AlertDescription.decrypt_error, - "Finished message is incorrect"): - yield result - - def _calcFinished(self, send=True): - if self.version == (3,0): - if (self._client and send) or (not self._client and not send): - senderStr = "\x43\x4C\x4E\x54" - else: - senderStr = "\x53\x52\x56\x52" - - verifyData = self._calcSSLHandshakeHash(self.session.masterSecret, - senderStr) - return verifyData - - elif self.version in ((3,1), (3,2)): - if (self._client and send) or (not self._client and not send): - label = "client finished" - else: - label = "server finished" - - handshakeHashes = stringToBytes(self._handshake_md5.digest() + \ - self._handshake_sha.digest()) - verifyData = PRF(self.session.masterSecret, label, handshakeHashes, - 12) - return verifyData - else: - raise AssertionError() - #Used for Finished messages and CertificateVerify messages in SSL v3 def _calcSSLHandshakeHash(self, masterSecret, label): - masterSecretStr = bytesToString(masterSecret) - imac_md5 = self._handshake_md5.copy() imac_sha = self._handshake_sha.copy() - imac_md5.update(label + masterSecretStr + '\x36'*48) - imac_sha.update(label + masterSecretStr + '\x36'*40) + imac_md5.update(compatHMAC(label + masterSecret + bytearray([0x36]*48))) + imac_sha.update(compatHMAC(label + masterSecret + bytearray([0x36]*40))) + + md5Bytes = MD5(masterSecret + bytearray([0x5c]*48) + \ + bytearray(imac_md5.digest())) + shaBytes = SHA1(masterSecret + bytearray([0x5c]*40) + \ + bytearray(imac_sha.digest())) - md5Str = md5.md5(masterSecretStr + ('\x5c'*48) + \ - imac_md5.digest()).digest() - shaStr = sha.sha(masterSecretStr + ('\x5c'*40) + \ - imac_sha.digest()).digest() + return md5Bytes + shaBytes - return stringToBytes(md5Str + shaStr) diff --git a/chromium/third_party/tlslite/tlslite/utils/Cryptlib_AES.py b/chromium/third_party/tlslite/tlslite/utils/Cryptlib_AES.py deleted file mode 100644 index 9e101fc626d..00000000000 --- a/chromium/third_party/tlslite/tlslite/utils/Cryptlib_AES.py +++ /dev/null @@ -1,34 +0,0 @@ -"""Cryptlib AES implementation.""" - -from cryptomath import * -from AES import * - -if cryptlibpyLoaded: - - def new(key, mode, IV): - return Cryptlib_AES(key, mode, IV) - - class Cryptlib_AES(AES): - - def __init__(self, key, mode, IV): - AES.__init__(self, key, mode, IV, "cryptlib") - self.context = cryptlib_py.cryptCreateContext(cryptlib_py.CRYPT_UNUSED, cryptlib_py.CRYPT_ALGO_AES) - cryptlib_py.cryptSetAttribute(self.context, cryptlib_py.CRYPT_CTXINFO_MODE, cryptlib_py.CRYPT_MODE_CBC) - cryptlib_py.cryptSetAttribute(self.context, cryptlib_py.CRYPT_CTXINFO_KEYSIZE, len(key)) - cryptlib_py.cryptSetAttributeString(self.context, cryptlib_py.CRYPT_CTXINFO_KEY, key) - cryptlib_py.cryptSetAttributeString(self.context, cryptlib_py.CRYPT_CTXINFO_IV, IV) - - def __del__(self): - cryptlib_py.cryptDestroyContext(self.context) - - def encrypt(self, plaintext): - AES.encrypt(self, plaintext) - bytes = stringToBytes(plaintext) - cryptlib_py.cryptEncrypt(self.context, bytes) - return bytesToString(bytes) - - def decrypt(self, ciphertext): - AES.decrypt(self, ciphertext) - bytes = stringToBytes(ciphertext) - cryptlib_py.cryptDecrypt(self.context, bytes) - return bytesToString(bytes) diff --git a/chromium/third_party/tlslite/tlslite/utils/Cryptlib_RC4.py b/chromium/third_party/tlslite/tlslite/utils/Cryptlib_RC4.py deleted file mode 100644 index 7c6d087b8d6..00000000000 --- a/chromium/third_party/tlslite/tlslite/utils/Cryptlib_RC4.py +++ /dev/null @@ -1,28 +0,0 @@ -"""Cryptlib RC4 implementation.""" - -from cryptomath import * -from RC4 import RC4 - -if cryptlibpyLoaded: - - def new(key): - return Cryptlib_RC4(key) - - class Cryptlib_RC4(RC4): - - def __init__(self, key): - RC4.__init__(self, key, "cryptlib") - self.context = cryptlib_py.cryptCreateContext(cryptlib_py.CRYPT_UNUSED, cryptlib_py.CRYPT_ALGO_RC4) - cryptlib_py.cryptSetAttribute(self.context, cryptlib_py.CRYPT_CTXINFO_KEYSIZE, len(key)) - cryptlib_py.cryptSetAttributeString(self.context, cryptlib_py.CRYPT_CTXINFO_KEY, key) - - def __del__(self): - cryptlib_py.cryptDestroyContext(self.context) - - def encrypt(self, plaintext): - bytes = stringToBytes(plaintext) - cryptlib_py.cryptEncrypt(self.context, bytes) - return bytesToString(bytes) - - def decrypt(self, ciphertext): - return self.encrypt(ciphertext)
\ No newline at end of file diff --git a/chromium/third_party/tlslite/tlslite/utils/Cryptlib_TripleDES.py b/chromium/third_party/tlslite/tlslite/utils/Cryptlib_TripleDES.py deleted file mode 100644 index a4f8155a099..00000000000 --- a/chromium/third_party/tlslite/tlslite/utils/Cryptlib_TripleDES.py +++ /dev/null @@ -1,35 +0,0 @@ -"""Cryptlib 3DES implementation.""" - -from cryptomath import * - -from TripleDES import * - -if cryptlibpyLoaded: - - def new(key, mode, IV): - return Cryptlib_TripleDES(key, mode, IV) - - class Cryptlib_TripleDES(TripleDES): - - def __init__(self, key, mode, IV): - TripleDES.__init__(self, key, mode, IV, "cryptlib") - self.context = cryptlib_py.cryptCreateContext(cryptlib_py.CRYPT_UNUSED, cryptlib_py.CRYPT_ALGO_3DES) - cryptlib_py.cryptSetAttribute(self.context, cryptlib_py.CRYPT_CTXINFO_MODE, cryptlib_py.CRYPT_MODE_CBC) - cryptlib_py.cryptSetAttribute(self.context, cryptlib_py.CRYPT_CTXINFO_KEYSIZE, len(key)) - cryptlib_py.cryptSetAttributeString(self.context, cryptlib_py.CRYPT_CTXINFO_KEY, key) - cryptlib_py.cryptSetAttributeString(self.context, cryptlib_py.CRYPT_CTXINFO_IV, IV) - - def __del__(self): - cryptlib_py.cryptDestroyContext(self.context) - - def encrypt(self, plaintext): - TripleDES.encrypt(self, plaintext) - bytes = stringToBytes(plaintext) - cryptlib_py.cryptEncrypt(self.context, bytes) - return bytesToString(bytes) - - def decrypt(self, ciphertext): - TripleDES.decrypt(self, ciphertext) - bytes = stringToBytes(ciphertext) - cryptlib_py.cryptDecrypt(self.context, bytes) - return bytesToString(bytes)
\ No newline at end of file diff --git a/chromium/third_party/tlslite/tlslite/utils/PyCrypto_RSAKey.py b/chromium/third_party/tlslite/tlslite/utils/PyCrypto_RSAKey.py deleted file mode 100644 index 48b5cef03fb..00000000000 --- a/chromium/third_party/tlslite/tlslite/utils/PyCrypto_RSAKey.py +++ /dev/null @@ -1,61 +0,0 @@ -"""PyCrypto RSA implementation.""" - -from cryptomath import * - -from RSAKey import * -from Python_RSAKey import Python_RSAKey - -if pycryptoLoaded: - - from Crypto.PublicKey import RSA - - class PyCrypto_RSAKey(RSAKey): - def __init__(self, n=0, e=0, d=0, p=0, q=0, dP=0, dQ=0, qInv=0): - if not d: - self.rsa = RSA.construct( (n, e) ) - else: - self.rsa = RSA.construct( (n, e, d, p, q) ) - - def __getattr__(self, name): - return getattr(self.rsa, name) - - def hasPrivateKey(self): - return self.rsa.has_private() - - def hash(self): - return Python_RSAKey(self.n, self.e).hash() - - def _rawPrivateKeyOp(self, m): - s = numberToString(m) - byteLength = numBytes(self.n) - if len(s)== byteLength: - pass - elif len(s) == byteLength-1: - s = '\0' + s - else: - raise AssertionError() - c = stringToNumber(self.rsa.decrypt((s,))) - return c - - def _rawPublicKeyOp(self, c): - s = numberToString(c) - byteLength = numBytes(self.n) - if len(s)== byteLength: - pass - elif len(s) == byteLength-1: - s = '\0' + s - else: - raise AssertionError() - m = stringToNumber(self.rsa.encrypt(s, None)[0]) - return m - - def writeXMLPublicKey(self, indent=''): - return Python_RSAKey(self.n, self.e).write(indent) - - def generate(bits): - key = PyCrypto_RSAKey() - def f(numBytes): - return bytesToString(getRandomBytes(numBytes)) - key.rsa = RSA.generate(bits, f) - return key - generate = staticmethod(generate) diff --git a/chromium/third_party/tlslite/tlslite/utils/Python_RSAKey.py b/chromium/third_party/tlslite/tlslite/utils/Python_RSAKey.py deleted file mode 100644 index b57553a1ac3..00000000000 --- a/chromium/third_party/tlslite/tlslite/utils/Python_RSAKey.py +++ /dev/null @@ -1,209 +0,0 @@ -"""Pure-Python RSA implementation.""" - -from cryptomath import * -import xmltools -from ASN1Parser import ASN1Parser -from RSAKey import * - -class Python_RSAKey(RSAKey): - def __init__(self, n=0, e=0, d=0, p=0, q=0, dP=0, dQ=0, qInv=0): - if (n and not e) or (e and not n): - raise AssertionError() - self.n = n - self.e = e - self.d = d - self.p = p - self.q = q - self.dP = dP - self.dQ = dQ - self.qInv = qInv - self.blinder = 0 - self.unblinder = 0 - - def hasPrivateKey(self): - return self.d != 0 - - def hash(self): - s = self.writeXMLPublicKey('\t\t') - return hashAndBase64(s.strip()) - - def _rawPrivateKeyOp(self, m): - #Create blinding values, on the first pass: - if not self.blinder: - self.unblinder = getRandomNumber(2, self.n) - self.blinder = powMod(invMod(self.unblinder, self.n), self.e, - self.n) - - #Blind the input - m = (m * self.blinder) % self.n - - #Perform the RSA operation - c = self._rawPrivateKeyOpHelper(m) - - #Unblind the output - c = (c * self.unblinder) % self.n - - #Update blinding values - self.blinder = (self.blinder * self.blinder) % self.n - self.unblinder = (self.unblinder * self.unblinder) % self.n - - #Return the output - return c - - - def _rawPrivateKeyOpHelper(self, m): - #Non-CRT version - #c = powMod(m, self.d, self.n) - - #CRT version (~3x faster) - s1 = powMod(m, self.dP, self.p) - s2 = powMod(m, self.dQ, self.q) - h = ((s1 - s2) * self.qInv) % self.p - c = s2 + self.q * h - return c - - def _rawPublicKeyOp(self, c): - m = powMod(c, self.e, self.n) - return m - - def acceptsPassword(self): return False - - def write(self, indent=''): - if self.d: - s = indent+'<privateKey xmlns="http://trevp.net/rsa">\n' - else: - s = indent+'<publicKey xmlns="http://trevp.net/rsa">\n' - s += indent+'\t<n>%s</n>\n' % numberToBase64(self.n) - s += indent+'\t<e>%s</e>\n' % numberToBase64(self.e) - if self.d: - s += indent+'\t<d>%s</d>\n' % numberToBase64(self.d) - s += indent+'\t<p>%s</p>\n' % numberToBase64(self.p) - s += indent+'\t<q>%s</q>\n' % numberToBase64(self.q) - s += indent+'\t<dP>%s</dP>\n' % numberToBase64(self.dP) - s += indent+'\t<dQ>%s</dQ>\n' % numberToBase64(self.dQ) - s += indent+'\t<qInv>%s</qInv>\n' % numberToBase64(self.qInv) - s += indent+'</privateKey>' - else: - s += indent+'</publicKey>' - #Only add \n if part of a larger structure - if indent != '': - s += '\n' - return s - - def writeXMLPublicKey(self, indent=''): - return Python_RSAKey(self.n, self.e).write(indent) - - def generate(bits): - key = Python_RSAKey() - p = getRandomPrime(bits/2, False) - q = getRandomPrime(bits/2, False) - t = lcm(p-1, q-1) - key.n = p * q - key.e = 3L #Needed to be long, for Java - key.d = invMod(key.e, t) - key.p = p - key.q = q - key.dP = key.d % (p-1) - key.dQ = key.d % (q-1) - key.qInv = invMod(q, p) - return key - generate = staticmethod(generate) - - def parsePEM(s, passwordCallback=None): - """Parse a string containing a <privateKey> or <publicKey>, or - PEM-encoded key.""" - - start = s.find("-----BEGIN PRIVATE KEY-----") - if start != -1: - end = s.find("-----END PRIVATE KEY-----") - if end == -1: - raise SyntaxError("Missing PEM Postfix") - s = s[start+len("-----BEGIN PRIVATE KEY -----") : end] - bytes = base64ToBytes(s) - return Python_RSAKey._parsePKCS8(bytes) - else: - start = s.find("-----BEGIN RSA PRIVATE KEY-----") - if start != -1: - end = s.find("-----END RSA PRIVATE KEY-----") - if end == -1: - raise SyntaxError("Missing PEM Postfix") - s = s[start+len("-----BEGIN RSA PRIVATE KEY -----") : end] - bytes = base64ToBytes(s) - return Python_RSAKey._parseSSLeay(bytes) - raise SyntaxError("Missing PEM Prefix") - parsePEM = staticmethod(parsePEM) - - def parseXML(s): - element = xmltools.parseAndStripWhitespace(s) - return Python_RSAKey._parseXML(element) - parseXML = staticmethod(parseXML) - - def _parsePKCS8(bytes): - p = ASN1Parser(bytes) - - version = p.getChild(0).value[0] - if version != 0: - raise SyntaxError("Unrecognized PKCS8 version") - - rsaOID = p.getChild(1).value - if list(rsaOID) != [6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0]: - raise SyntaxError("Unrecognized AlgorithmIdentifier") - - #Get the privateKey - privateKeyP = p.getChild(2) - - #Adjust for OCTET STRING encapsulation - privateKeyP = ASN1Parser(privateKeyP.value) - - return Python_RSAKey._parseASN1PrivateKey(privateKeyP) - _parsePKCS8 = staticmethod(_parsePKCS8) - - def _parseSSLeay(bytes): - privateKeyP = ASN1Parser(bytes) - return Python_RSAKey._parseASN1PrivateKey(privateKeyP) - _parseSSLeay = staticmethod(_parseSSLeay) - - def _parseASN1PrivateKey(privateKeyP): - version = privateKeyP.getChild(0).value[0] - if version != 0: - raise SyntaxError("Unrecognized RSAPrivateKey version") - n = bytesToNumber(privateKeyP.getChild(1).value) - e = bytesToNumber(privateKeyP.getChild(2).value) - d = bytesToNumber(privateKeyP.getChild(3).value) - p = bytesToNumber(privateKeyP.getChild(4).value) - q = bytesToNumber(privateKeyP.getChild(5).value) - dP = bytesToNumber(privateKeyP.getChild(6).value) - dQ = bytesToNumber(privateKeyP.getChild(7).value) - qInv = bytesToNumber(privateKeyP.getChild(8).value) - return Python_RSAKey(n, e, d, p, q, dP, dQ, qInv) - _parseASN1PrivateKey = staticmethod(_parseASN1PrivateKey) - - def _parseXML(element): - try: - xmltools.checkName(element, "privateKey") - except SyntaxError: - xmltools.checkName(element, "publicKey") - - #Parse attributes - xmltools.getReqAttribute(element, "xmlns", "http://trevp.net/rsa\Z") - xmltools.checkNoMoreAttributes(element) - - #Parse public values (<n> and <e>) - n = base64ToNumber(xmltools.getText(xmltools.getChild(element, 0, "n"), xmltools.base64RegEx)) - e = base64ToNumber(xmltools.getText(xmltools.getChild(element, 1, "e"), xmltools.base64RegEx)) - d = 0 - p = 0 - q = 0 - dP = 0 - dQ = 0 - qInv = 0 - #Parse private values, if present - if element.childNodes.length>=3: - d = base64ToNumber(xmltools.getText(xmltools.getChild(element, 2, "d"), xmltools.base64RegEx)) - p = base64ToNumber(xmltools.getText(xmltools.getChild(element, 3, "p"), xmltools.base64RegEx)) - q = base64ToNumber(xmltools.getText(xmltools.getChild(element, 4, "q"), xmltools.base64RegEx)) - dP = base64ToNumber(xmltools.getText(xmltools.getChild(element, 5, "dP"), xmltools.base64RegEx)) - dQ = base64ToNumber(xmltools.getText(xmltools.getChild(element, 6, "dQ"), xmltools.base64RegEx)) - qInv = base64ToNumber(xmltools.getText(xmltools.getLastChild(element, 7, "qInv"), xmltools.base64RegEx)) - return Python_RSAKey(n, e, d, p, q, dP, dQ, qInv) - _parseXML = staticmethod(_parseXML) diff --git a/chromium/third_party/tlslite/tlslite/utils/__init__.py b/chromium/third_party/tlslite/tlslite/utils/__init__.py index e96b4bef8a5..4d49df64e24 100644 --- a/chromium/third_party/tlslite/tlslite/utils/__init__.py +++ b/chromium/third_party/tlslite/tlslite/utils/__init__.py @@ -1,31 +1,29 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + """Toolkit for crypto and other stuff.""" -__all__ = ["AES", - "ASN1Parser", +__all__ = ["aes", + "asn1parser", "cipherfactory", "codec", - "Cryptlib_AES", - "Cryptlib_RC4", - "Cryptlib_TripleDES", - "cryptomath: cryptomath module", - "dateFuncs", - "hmac", - "JCE_RSAKey", + "cryptomath", + "datefuncs", "compat", "keyfactory", - "OpenSSL_AES", - "OpenSSL_RC4", - "OpenSSL_RSAKey", - "OpenSSL_TripleDES", - "PyCrypto_AES", - "PyCrypto_RC4", - "PyCrypto_RSAKey", - "PyCrypto_TripleDES", - "Python_AES", - "Python_RC4", - "Python_RSAKey", - "RC4", + "openssl_aes", + "openssl_rc4", + "openssl_rsakey", + "openssl_tripledes", + "pycrypto_aes", + "pycrypto_rc4", + "pycrypto_rsakey", + "pycrypto_tripledes", + "python_aes", + "python_rc4", + "python_rsakey", + "rc4", "rijndael", - "RSAKey", - "TripleDES", - "xmltools"] + "rsakey", + "tackpywrapper", + "tripledes"] diff --git a/chromium/third_party/tlslite/tlslite/utils/AES.py b/chromium/third_party/tlslite/tlslite/utils/aes.py index 8413f4c1093..95afaa340fe 100644 --- a/chromium/third_party/tlslite/tlslite/utils/AES.py +++ b/chromium/third_party/tlslite/tlslite/utils/aes.py @@ -1,6 +1,9 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + """Abstract class for AES.""" -class AES: +class AES(object): def __init__(self, key, mode, IV, implementation): if len(key) not in (16, 24, 32): raise AssertionError() diff --git a/chromium/third_party/tlslite/tlslite/utils/ASN1Parser.py b/chromium/third_party/tlslite/tlslite/utils/asn1parser.py index c85c1381065..618e8559c9b 100644 --- a/chromium/third_party/tlslite/tlslite/utils/ASN1Parser.py +++ b/chromium/third_party/tlslite/tlslite/utils/asn1parser.py @@ -1,9 +1,14 @@ +# Author: Trevor Perrin +# Patch from Google adding getChildBytes() +# +# See the LICENSE file for legal information regarding use of this file. + """Class for parsing ASN.1""" -from compat import * -from codec import * +from .compat import * +from .codec import * #Takes a byte array which has a DER TLV field at its head -class ASN1Parser: +class ASN1Parser(object): def __init__(self, bytes): p = Parser(bytes) p.get(1) #skip Type diff --git a/chromium/third_party/tlslite/tlslite/utils/cipherfactory.py b/chromium/third_party/tlslite/tlslite/utils/cipherfactory.py index ccbb6b5ff9b..20e20f11003 100644 --- a/chromium/third_party/tlslite/tlslite/utils/cipherfactory.py +++ b/chromium/third_party/tlslite/tlslite/utils/cipherfactory.py @@ -1,30 +1,27 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + """Factory functions for symmetric cryptography.""" import os -import Python_AES -import Python_RC4 +from tlslite.utils import python_aes +from tlslite.utils import python_rc4 -import cryptomath +from tlslite.utils import cryptomath tripleDESPresent = False if cryptomath.m2cryptoLoaded: - import OpenSSL_AES - import OpenSSL_RC4 - import OpenSSL_TripleDES - tripleDESPresent = True - -if cryptomath.cryptlibpyLoaded: - import Cryptlib_AES - import Cryptlib_RC4 - import Cryptlib_TripleDES + from tlslite.utils import openssl_aes + from tlslite.utils import openssl_rc4 + from tlslite.utils import openssl_tripledes tripleDESPresent = True if cryptomath.pycryptoLoaded: - import PyCrypto_AES - import PyCrypto_RC4 - import PyCrypto_TripleDES + from tlslite.utils import pycrypto_aes + from tlslite.utils import pycrypto_rc4 + from tlslite.utils import pycrypto_tripledes tripleDESPresent = True # ************************************************************************** @@ -44,17 +41,15 @@ def createAES(key, IV, implList=None): @return: An AES object. """ if implList == None: - implList = ["cryptlib", "openssl", "pycrypto", "python"] + implList = ["openssl", "pycrypto", "python"] for impl in implList: - if impl == "cryptlib" and cryptomath.cryptlibpyLoaded: - return Cryptlib_AES.new(key, 2, IV) - elif impl == "openssl" and cryptomath.m2cryptoLoaded: - return OpenSSL_AES.new(key, 2, IV) + if impl == "openssl" and cryptomath.m2cryptoLoaded: + return openssl_aes.new(key, 2, IV) elif impl == "pycrypto" and cryptomath.pycryptoLoaded: - return PyCrypto_AES.new(key, 2, IV) + return pycrypto_aes.new(key, 2, IV) elif impl == "python": - return Python_AES.new(key, 2, IV) + return python_aes.new(key, 2, IV) raise NotImplementedError() def createRC4(key, IV, implList=None): @@ -70,19 +65,17 @@ def createRC4(key, IV, implList=None): @return: An RC4 object. """ if implList == None: - implList = ["cryptlib", "openssl", "pycrypto", "python"] + implList = ["openssl", "pycrypto", "python"] if len(IV) != 0: raise AssertionError() for impl in implList: - if impl == "cryptlib" and cryptomath.cryptlibpyLoaded: - return Cryptlib_RC4.new(key) - elif impl == "openssl" and cryptomath.m2cryptoLoaded: - return OpenSSL_RC4.new(key) + if impl == "openssl" and cryptomath.m2cryptoLoaded: + return openssl_rc4.new(key) elif impl == "pycrypto" and cryptomath.pycryptoLoaded: - return PyCrypto_RC4.new(key) + return pycrypto_rc4.new(key) elif impl == "python": - return Python_RC4.new(key) + return python_rc4.new(key) raise NotImplementedError() #Create a new TripleDES instance @@ -99,13 +92,11 @@ def createTripleDES(key, IV, implList=None): @return: A 3DES object. """ if implList == None: - implList = ["cryptlib", "openssl", "pycrypto"] + implList = ["openssl", "pycrypto"] for impl in implList: - if impl == "cryptlib" and cryptomath.cryptlibpyLoaded: - return Cryptlib_TripleDES.new(key, 2, IV) - elif impl == "openssl" and cryptomath.m2cryptoLoaded: - return OpenSSL_TripleDES.new(key, 2, IV) + if impl == "openssl" and cryptomath.m2cryptoLoaded: + return openssl_tripledes.new(key, 2, IV) elif impl == "pycrypto" and cryptomath.pycryptoLoaded: - return PyCrypto_TripleDES.new(key, 2, IV) + return pycrypto_tripledes.new(key, 2, IV) raise NotImplementedError()
\ No newline at end of file diff --git a/chromium/third_party/tlslite/tlslite/utils/codec.py b/chromium/third_party/tlslite/tlslite/utils/codec.py index 13022a0b932..f1e21c923df 100644 --- a/chromium/third_party/tlslite/tlslite/utils/codec.py +++ b/chromium/third_party/tlslite/tlslite/utils/codec.py @@ -1,39 +1,32 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + """Classes for reading/writing binary data (such as TLS records).""" -from compat import * +from .compat import * -class Writer: - def __init__(self, length=0): - #If length is zero, then this is just a "trial run" to determine length - self.index = 0 - self.bytes = createByteArrayZeros(length) +class Writer(object): + def __init__(self): + self.bytes = bytearray(0) def add(self, x, length): - if self.bytes: - newIndex = self.index+length-1 - while newIndex >= self.index: - self.bytes[newIndex] = x & 0xFF - x >>= 8 - newIndex -= 1 - self.index += length + self.bytes += bytearray(length) + newIndex = len(self.bytes) - 1 + for count in range(length): + self.bytes[newIndex] = x & 0xFF + x >>= 8 + newIndex -= 1 def addFixSeq(self, seq, length): - if self.bytes: - for e in seq: - self.add(e, length) - else: - self.index += len(seq)*length + for e in seq: + self.add(e, length) def addVarSeq(self, seq, length, lengthLength): - if self.bytes: - self.add(len(seq)*length, lengthLength) - for e in seq: - self.add(e, length) - else: - self.index += lengthLength + (len(seq)*length) - + self.add(len(seq)*length, lengthLength) + for e in seq: + self.add(e, length) -class Parser: +class Parser(object): def __init__(self, bytes): self.bytes = bytes self.index = 0 @@ -67,7 +60,7 @@ class Parser: lengthList = self.get(lengthLength) if lengthList % length != 0: raise SyntaxError() - lengthList = int(lengthList/length) + lengthList = lengthList // length l = [0] * lengthList for x in range(lengthList): l[x] = self.get(length) @@ -91,4 +84,4 @@ class Parser: elif (self.index - self.indexCheck) == self.lengthCheck: return True else: - raise SyntaxError()
\ No newline at end of file + raise SyntaxError() diff --git a/chromium/third_party/tlslite/tlslite/utils/compat.py b/chromium/third_party/tlslite/tlslite/utils/compat.py index 7d2d9250d84..db95ac17f4c 100644 --- a/chromium/third_party/tlslite/tlslite/utils/compat.py +++ b/chromium/third_party/tlslite/tlslite/utils/compat.py @@ -1,140 +1,96 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + """Miscellaneous functions to mask Python version differences.""" import sys import os - -if sys.version_info < (2,2): - raise AssertionError("Python 2.2 or later required") - -if sys.version_info < (2,3): - - def enumerate(collection): - return zip(range(len(collection)), collection) - - class Set: - def __init__(self, seq=None): - self.values = {} - if seq: - for e in seq: - self.values[e] = None - - def add(self, e): - self.values[e] = None - - def discard(self, e): - if e in self.values.keys(): - del(self.values[e]) - - def union(self, s): - ret = Set() - for e in self.values.keys(): - ret.values[e] = None - for e in s.values.keys(): - ret.values[e] = None - return ret - - def issubset(self, other): - for e in self.values.keys(): - if e not in other.values.keys(): - return False - return True - - def __nonzero__( self): - return len(self.values.keys()) - - def __contains__(self, e): - return e in self.values.keys() - - def __iter__(self): - return iter(set.values.keys()) - - -if os.name != "java": - - import array - def createByteArraySequence(seq): - return array.array('B', seq) - def createByteArrayZeros(howMany): - return array.array('B', [0] * howMany) - def concatArrays(a1, a2): - return a1+a2 - - def bytesToString(bytes): - return bytes.tostring() - def stringToBytes(s): - bytes = createByteArrayZeros(0) - bytes.fromstring(s) - return bytes - - import math - def numBits(n): - if n==0: - return 0 - s = "%x" % n - return ((len(s)-1)*4) + \ - {'0':0, '1':1, '2':2, '3':2, - '4':3, '5':3, '6':3, '7':3, - '8':4, '9':4, 'a':4, 'b':4, - 'c':4, 'd':4, 'e':4, 'f':4, - }[s[0]] - return int(math.floor(math.log(n, 2))+1) - - BaseException = Exception - import sys - import traceback - def formatExceptionTrace(e): - newStr = "".join(traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)) - return newStr +import math +import binascii + +if sys.version_info >= (3,0): + + def compat26Str(x): return x + + # Python 3 requires bytes instead of bytearrays for HMAC + + # So, python 2.6 requires strings, python 3 requires 'bytes', + # and python 2.7 can handle bytearrays... + def compatHMAC(x): return bytes(x) + + def raw_input(s): + return input(s) + + # So, the python3 binascii module deals with bytearrays, and python2 + # deals with strings... I would rather deal with the "a" part as + # strings, and the "b" part as bytearrays, regardless of python version, + # so... + def a2b_hex(s): + try: + b = bytearray(binascii.a2b_hex(bytearray(s, "ascii"))) + except Exception as e: + raise SyntaxError("base16 error: %s" % e) + return b + + def a2b_base64(s): + try: + b = bytearray(binascii.a2b_base64(bytearray(s, "ascii"))) + except Exception as e: + raise SyntaxError("base64 error: %s" % e) + return b + + def b2a_hex(b): + return binascii.b2a_hex(b).decode("ascii") + + def b2a_base64(b): + return binascii.b2a_base64(b).decode("ascii") + + def b2a_base32(b): + return base64.b32encode(b).decode("ascii") + + def readStdinBinary(): + return sys.stdin.buffer.read() + + def long(n): + return n else: - #Jython 2.1 is missing lots of python 2.3 stuff, - #which we have to emulate here: - #NOTE: JYTHON SUPPORT NO LONGER WORKS, DUE TO USE OF GENERATORS. - #THIS CODE IS LEFT IN SO THAT ONE JYTHON UPDATES TO 2.2, IT HAS A - #CHANCE OF WORKING AGAIN. - - import java - import jarray - - def createByteArraySequence(seq): - if isinstance(seq, type("")): #If it's a string, convert - seq = [ord(c) for c in seq] - return jarray.array(seq, 'h') #use short instead of bytes, cause bytes are signed - def createByteArrayZeros(howMany): - return jarray.zeros(howMany, 'h') #use short instead of bytes, cause bytes are signed - def concatArrays(a1, a2): - l = list(a1)+list(a2) - return createByteArraySequence(l) - - #WAY TOO SLOW - MUST BE REPLACED------------ - def bytesToString(bytes): - return "".join([chr(b) for b in bytes]) - - def stringToBytes(s): - bytes = createByteArrayZeros(len(s)) - for count, c in enumerate(s): - bytes[count] = ord(c) - return bytes - #WAY TOO SLOW - MUST BE REPLACED------------ - - def numBits(n): - if n==0: - return 0 - n= 1L * n; #convert to long, if it isn't already - return n.__tojava__(java.math.BigInteger).bitLength() - - #Adjust the string to an array of bytes - def stringToJavaByteArray(s): - bytes = jarray.zeros(len(s), 'b') - for count, c in enumerate(s): - x = ord(c) - if x >= 128: x -= 256 - bytes[count] = x - return bytes + # Python 2.6 requires strings instead of bytearrays in a couple places, + # so we define this function so it does the conversion if needed. + if sys.version_info < (2,7): + def compat26Str(x): return str(x) + else: + def compat26Str(x): return x + + # So, python 2.6 requires strings, python 3 requires 'bytes', + # and python 2.7 can handle bytearrays... + def compatHMAC(x): return compat26Str(x) + + def a2b_hex(s): + try: + b = bytearray(binascii.a2b_hex(s)) + except Exception as e: + raise SyntaxError("base16 error: %s" % e) + return b + + def a2b_base64(s): + try: + b = bytearray(binascii.a2b_base64(s)) + except Exception as e: + raise SyntaxError("base64 error: %s" % e) + return b + + def b2a_hex(b): + return binascii.b2a_hex(compat26Str(b)) + + def b2a_base64(b): + return binascii.b2a_base64(compat26Str(b)) + + def b2a_base32(b): + return base64.b32encode(str(b)) + +import traceback +def formatExceptionTrace(e): + newStr = "".join(traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)) + return newStr - BaseException = java.lang.Exception - import sys - import traceback - def formatExceptionTrace(e): - newStr = "".join(traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)) - return newStr
\ No newline at end of file diff --git a/chromium/third_party/tlslite/tlslite/utils/cryptomath.py b/chromium/third_party/tlslite/tlslite/utils/cryptomath.py index 385095ddcdc..30354b2c56c 100644 --- a/chromium/third_party/tlslite/tlslite/utils/cryptomath.py +++ b/chromium/third_party/tlslite/tlslite/utils/cryptomath.py @@ -1,25 +1,19 @@ +# Authors: +# Trevor Perrin +# Martin von Loewis - python 3 port +# +# See the LICENSE file for legal information regarding use of this file. + """cryptomath module This module has basic math/crypto code.""" - +from __future__ import print_function import os import math import base64 import binascii -# The sha module is deprecated in Python 2.6 -try: - import sha -except ImportError: - from hashlib import sha1 as sha - -# The md5 module is deprecated in Python 2.6 -try: - import md5 -except ImportError: - from hashlib import md5 - -from compat import * +from .compat import * # ************************************************************************** @@ -34,23 +28,6 @@ try: except ImportError: m2cryptoLoaded = False - -# Try to load cryptlib -try: - import cryptlib_py - try: - cryptlib_py.cryptInit() - except cryptlib_py.CryptException, e: - #If tlslite and cryptoIDlib are both present, - #they might each try to re-initialize this, - #so we're tolerant of that. - if e[0] != cryptlib_py.CRYPT_ERROR_INITED: - raise - cryptlibpyLoaded = True - -except ImportError: - cryptlibpyLoaded = False - #Try to load GMPY try: import gmpy @@ -70,150 +47,116 @@ except ImportError: # PRNG Functions # ************************************************************************** -# Get os.urandom PRNG -try: - os.urandom(1) - def getRandomBytes(howMany): - return stringToBytes(os.urandom(howMany)) - prngName = "os.urandom" - -except: - # Else get cryptlib PRNG - if cryptlibpyLoaded: - def getRandomBytes(howMany): - randomKey = cryptlib_py.cryptCreateContext(cryptlib_py.CRYPT_UNUSED, - cryptlib_py.CRYPT_ALGO_AES) - cryptlib_py.cryptSetAttribute(randomKey, - cryptlib_py.CRYPT_CTXINFO_MODE, - cryptlib_py.CRYPT_MODE_OFB) - cryptlib_py.cryptGenerateKey(randomKey) - bytes = createByteArrayZeros(howMany) - cryptlib_py.cryptEncrypt(randomKey, bytes) - return bytes - prngName = "cryptlib" - - else: - #Else get UNIX /dev/urandom PRNG - try: - devRandomFile = open("/dev/urandom", "rb") - def getRandomBytes(howMany): - return stringToBytes(devRandomFile.read(howMany)) - prngName = "/dev/urandom" - except IOError: - #Else get Win32 CryptoAPI PRNG - try: - import win32prng - def getRandomBytes(howMany): - s = win32prng.getRandomBytes(howMany) - if len(s) != howMany: - raise AssertionError() - return stringToBytes(s) - prngName ="CryptoAPI" - except ImportError: - #Else no PRNG :-( - def getRandomBytes(howMany): - raise NotImplementedError("No Random Number Generator "\ - "available.") - prngName = "None" +# Check that os.urandom works +import zlib +length = len(zlib.compress(os.urandom(1000))) +assert(length > 900) -# ************************************************************************** -# Converter Functions -# ************************************************************************** +def getRandomBytes(howMany): + b = bytearray(os.urandom(howMany)) + assert(len(b) == howMany) + return b -def bytesToNumber(bytes): - total = 0L - multiplier = 1L - for count in range(len(bytes)-1, -1, -1): - byte = bytes[count] - total += multiplier * byte - multiplier *= 256 - return total +prngName = "os.urandom" -def numberToBytes(n): - howManyBytes = numBytes(n) - bytes = createByteArrayZeros(howManyBytes) - for count in range(howManyBytes-1, -1, -1): - bytes[count] = int(n % 256) - n >>= 8 - return bytes +# ************************************************************************** +# Simple hash functions +# ************************************************************************** -def bytesToBase64(bytes): - s = bytesToString(bytes) - return stringToBase64(s) +import hmac +import hashlib -def base64ToBytes(s): - s = base64ToString(s) - return stringToBytes(s) +def MD5(b): + return bytearray(hashlib.md5(compat26Str(b)).digest()) -def numberToBase64(n): - bytes = numberToBytes(n) - return bytesToBase64(bytes) +def SHA1(b): + return bytearray(hashlib.sha1(compat26Str(b)).digest()) -def base64ToNumber(s): - bytes = base64ToBytes(s) - return bytesToNumber(bytes) +def HMAC_MD5(k, b): + k = compatHMAC(k) + b = compatHMAC(b) + return bytearray(hmac.new(k, b, hashlib.md5).digest()) -def stringToNumber(s): - bytes = stringToBytes(s) - return bytesToNumber(bytes) +def HMAC_SHA1(k, b): + k = compatHMAC(k) + b = compatHMAC(b) + return bytearray(hmac.new(k, b, hashlib.sha1).digest()) -def numberToString(s): - bytes = numberToBytes(s) - return bytesToString(bytes) -def base64ToString(s): - try: - return base64.decodestring(s) - except binascii.Error, e: - raise SyntaxError(e) - except binascii.Incomplete, e: - raise SyntaxError(e) +# ************************************************************************** +# Converter Functions +# ************************************************************************** -def stringToBase64(s): - return base64.encodestring(s).replace("\n", "") +def bytesToNumber(b): + total = 0 + multiplier = 1 + for count in range(len(b)-1, -1, -1): + byte = b[count] + total += multiplier * byte + multiplier *= 256 + # Force-cast to long to appease PyCrypto. + # https://github.com/trevp/tlslite/issues/15 + return long(total) + +def numberToByteArray(n, howManyBytes=None): + """Convert an integer into a bytearray, zero-pad to howManyBytes. + + The returned bytearray may be smaller than howManyBytes, but will + not be larger. The returned bytearray will contain a big-endian + encoding of the input integer (n). + """ + if howManyBytes == None: + howManyBytes = numBytes(n) + b = bytearray(howManyBytes) + for count in range(howManyBytes-1, -1, -1): + b[count] = int(n % 256) + n >>= 8 + return b def mpiToNumber(mpi): #mpi is an openssl-format bignum string if (ord(mpi[4]) & 0x80) !=0: #Make sure this is a positive number raise AssertionError() - bytes = stringToBytes(mpi[4:]) - return bytesToNumber(bytes) + b = bytearray(mpi[4:]) + return bytesToNumber(b) def numberToMPI(n): - bytes = numberToBytes(n) + b = numberToByteArray(n) ext = 0 #If the high-order bit is going to be set, #add an extra byte of zeros if (numBits(n) & 0x7)==0: ext = 1 length = numBytes(n) + ext - bytes = concatArrays(createByteArrayZeros(4+ext), bytes) - bytes[0] = (length >> 24) & 0xFF - bytes[1] = (length >> 16) & 0xFF - bytes[2] = (length >> 8) & 0xFF - bytes[3] = length & 0xFF - return bytesToString(bytes) - + b = bytearray(4+ext) + b + b[0] = (length >> 24) & 0xFF + b[1] = (length >> 16) & 0xFF + b[2] = (length >> 8) & 0xFF + b[3] = length & 0xFF + return bytes(b) # ************************************************************************** # Misc. Utility Functions # ************************************************************************** +def numBits(n): + if n==0: + return 0 + s = "%x" % n + return ((len(s)-1)*4) + \ + {'0':0, '1':1, '2':2, '3':2, + '4':3, '5':3, '6':3, '7':3, + '8':4, '9':4, 'a':4, 'b':4, + 'c':4, 'd':4, 'e':4, 'f':4, + }[s[0]] + return int(math.floor(math.log(n, 2))+1) + def numBytes(n): if n==0: return 0 bits = numBits(n) return int(math.ceil(bits / 8.0)) -def hashAndBase64(s): - return stringToBase64(sha.sha(s).digest()) - -def getBase64Nonce(numChars=22): #defaults to an 132 bit nonce - bytes = getRandomBytes(numChars) - bytesStr = "".join([chr(b) for b in bytes]) - return stringToBase64(bytesStr)[:numChars] - - # ************************************************************************** # Big Number Math # ************************************************************************** @@ -239,9 +182,7 @@ def gcd(a,b): return a def lcm(a, b): - #This will break when python division changes, but we can't use // cause - #of Jython - return (a * b) / gcd(a, b) + return (a * b) // gcd(a, b) #Returns inverse of a mod b, zero if none #Uses Extended Euclidean Algorithm @@ -249,9 +190,7 @@ def invMod(a, b): c, d = a, b uc, ud = 1, 0 while c != 0: - #This will break when python division changes, but we can't use // - #cause of Jython - q = d / c + q = d // c c, d = d-(q*c), c uc, ud = ud - (q * uc), uc if d == 1: @@ -268,61 +207,17 @@ if gmpyLoaded: return long(result) else: - #Copied from Bryan G. Olson's post to comp.lang.python - #Does left-to-right instead of pow()'s right-to-left, - #thus about 30% faster than the python built-in with small bases def powMod(base, power, modulus): - nBitScan = 5 - - """ Return base**power mod modulus, using multi bit scanning - with nBitScan bits at a time.""" - - #TREV - Added support for negative exponents - negativeResult = False - if (power < 0): - power *= -1 - negativeResult = True - - exp2 = 2**nBitScan - mask = exp2 - 1 - - # Break power into a list of digits of nBitScan bits. - # The list is recursive so easy to read in reverse direction. - nibbles = None - while power: - nibbles = int(power & mask), nibbles - power = power >> nBitScan - - # Make a table of powers of base up to 2**nBitScan - 1 - lowPowers = [1] - for i in xrange(1, exp2): - lowPowers.append((lowPowers[i-1] * base) % modulus) - - # To exponentiate by the first nibble, look it up in the table - nib, nibbles = nibbles - prod = lowPowers[nib] - - # For the rest, square nBitScan times, then multiply by - # base^nibble - while nibbles: - nib, nibbles = nibbles - for i in xrange(nBitScan): - prod = (prod * prod) % modulus - if nib: prod = (prod * lowPowers[nib]) % modulus - - #TREV - Added support for negative exponents - if negativeResult: - prodInv = invMod(prod, modulus) - #Check to make sure the inverse is correct - if (prod * prodInv) % modulus != 1: - raise AssertionError() - return prodInv - return prod - + if power < 0: + result = pow(base, power*-1, modulus) + result = invMod(result, modulus) + return result + else: + return pow(base, power, modulus) #Pre-calculate a sieve of the ~100 primes < 1000: def makeSieve(n): - sieve = range(n) + sieve = list(range(n)) for count in range(2, int(math.sqrt(n))): if sieve[count] == 0: continue @@ -343,10 +238,10 @@ def isPrime(n, iterations=5, display=False): #Passed trial division, proceed to Rabin-Miller #Rabin-Miller implemented per Ferguson & Schneier #Compute s, t for Rabin-Miller - if display: print "*", + if display: print("*", end=' ') s, t = n-1, 0 while s % 2 == 0: - s, t = s/2, t+1 + s, t = s//2, t+1 #Repeat Rabin-Miller x times a = 2 #Use 2 as a base for first iteration speedup, per HAC for count in range(iterations): @@ -370,12 +265,12 @@ def getRandomPrime(bits, display=False): # #Since 30 is lcm(2,3,5), we'll set our test numbers to #29 % 30 and keep them there - low = (2L ** (bits-1)) * 3/2 - high = 2L ** bits - 30 + low = ((2 ** (bits-1)) * 3) // 2 + high = 2 ** bits - 30 p = getRandomNumber(low, high) p += 29 - (p % 30) while 1: - if display: print ".", + if display: print(".", end=' ') p += 30 if p >= high: p = getRandomNumber(low, high) @@ -392,12 +287,12 @@ def getRandomSafePrime(bits, display=False): # #Since 30 is lcm(2,3,5), we'll set our test numbers to #29 % 30 and keep them there - low = (2 ** (bits-2)) * 3/2 + low = (2 ** (bits-2)) * 3//2 high = (2 ** (bits-1)) - 30 q = getRandomNumber(low, high) q += 29 - (q % 30) while 1: - if display: print ".", + if display: print(".", end=' ') q += 30 if (q >= high): q = getRandomNumber(low, high) diff --git a/chromium/third_party/tlslite/tlslite/utils/dateFuncs.py b/chromium/third_party/tlslite/tlslite/utils/datefuncs.py index 38812ebf853..d8f0d240063 100644 --- a/chromium/third_party/tlslite/tlslite/utils/dateFuncs.py +++ b/chromium/third_party/tlslite/tlslite/utils/datefuncs.py @@ -1,3 +1,5 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. import os diff --git a/chromium/third_party/tlslite/tlslite/utils/entropy.c b/chromium/third_party/tlslite/tlslite/utils/entropy.c deleted file mode 100644 index c627794d2da..00000000000 --- a/chromium/third_party/tlslite/tlslite/utils/entropy.c +++ /dev/null @@ -1,173 +0,0 @@ - -#include "Python.h" - - -#ifdef MS_WINDOWS - -/* The following #define is not needed on VC6 with the Platform SDK, and it -may not be needed on VC7, I'm not sure. I don't think it hurts anything.*/ -#define _WIN32_WINNT 0x0400 - -#include <windows.h> - - -typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\ - LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\ - DWORD dwFlags ); -typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\ - BYTE *pbBuffer ); -typedef BOOL (WINAPI *CRYPTRELEASECONTEXT)(HCRYPTPROV hProv,\ - DWORD dwFlags); - - -static PyObject* entropy(PyObject *self, PyObject *args) -{ - int howMany = 0; - HINSTANCE hAdvAPI32 = NULL; - CRYPTACQUIRECONTEXTA pCryptAcquireContextA = NULL; - CRYPTGENRANDOM pCryptGenRandom = NULL; - CRYPTRELEASECONTEXT pCryptReleaseContext = NULL; - HCRYPTPROV hCryptProv = 0; - unsigned char* bytes = NULL; - PyObject* returnVal = NULL; - - - /* Read arguments */ - if (!PyArg_ParseTuple(args, "i", &howMany)) - return(NULL); - - /* Obtain handle to the DLL containing CryptoAPI - This should not fail */ - if( (hAdvAPI32 = GetModuleHandle("advapi32.dll")) == NULL) { - PyErr_Format(PyExc_SystemError, - "Advapi32.dll not found"); - return NULL; - } - - /* Obtain pointers to the CryptoAPI functions - This will fail on some early version of Win95 */ - pCryptAcquireContextA = (CRYPTACQUIRECONTEXTA)GetProcAddress(hAdvAPI32,\ - "CryptAcquireContextA"); - pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(hAdvAPI32,\ - "CryptGenRandom"); - pCryptReleaseContext = (CRYPTRELEASECONTEXT) GetProcAddress(hAdvAPI32,\ - "CryptReleaseContext"); - if (pCryptAcquireContextA == NULL || pCryptGenRandom == NULL || - pCryptReleaseContext == NULL) { - PyErr_Format(PyExc_NotImplementedError, - "CryptoAPI not available on this version of Windows"); - return NULL; - } - - /* Allocate bytes */ - if ((bytes = (unsigned char*)PyMem_Malloc(howMany)) == NULL) - return PyErr_NoMemory(); - - - /* Acquire context */ - if(!pCryptAcquireContextA(&hCryptProv, NULL, NULL, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT)) { - PyErr_Format(PyExc_SystemError, - "CryptAcquireContext failed, error %d", GetLastError()); - PyMem_Free(bytes); - return NULL; - } - - /* Get random data */ - if(!pCryptGenRandom(hCryptProv, howMany, bytes)) { - PyErr_Format(PyExc_SystemError, - "CryptGenRandom failed, error %d", GetLastError()); - PyMem_Free(bytes); - CryptReleaseContext(hCryptProv, 0); - return NULL; - } - - /* Build return value */ - returnVal = Py_BuildValue("s#", bytes, howMany); - PyMem_Free(bytes); - - /* Release context */ - if (!pCryptReleaseContext(hCryptProv, 0)) { - PyErr_Format(PyExc_SystemError, - "CryptReleaseContext failed, error %d", GetLastError()); - return NULL; - } - - return returnVal; -} - -#elif defined(HAVE_UNISTD_H) && defined(HAVE_FCNTL_H) - -#include <unistd.h> -#include <fcntl.h> - -static PyObject* entropy(PyObject *self, PyObject *args) -{ - int howMany; - int fd; - unsigned char* bytes = NULL; - PyObject* returnVal = NULL; - - - /* Read arguments */ - if (!PyArg_ParseTuple(args, "i", &howMany)) - return(NULL); - - /* Allocate bytes */ - if ((bytes = (unsigned char*)PyMem_Malloc(howMany)) == NULL) - return PyErr_NoMemory(); - - /* Open device */ - if ((fd = open("/dev/urandom", O_RDONLY, 0)) == -1) { - PyErr_Format(PyExc_NotImplementedError, - "No entropy source found"); - PyMem_Free(bytes); - return NULL; - } - - /* Get random data */ - if (read(fd, bytes, howMany) < howMany) { - PyErr_Format(PyExc_SystemError, - "Reading from /dev/urandom failed"); - PyMem_Free(bytes); - close(fd); - return NULL; - } - - /* Build return value */ - returnVal = Py_BuildValue("s#", bytes, howMany); - PyMem_Free(bytes); - - /* Close device */ - close(fd); - - return returnVal; -} - -#else - -static PyObject* entropy(PyObject *self, PyObject *args) -{ - PyErr_Format(PyExc_NotImplementedError, - "Function not supported"); - return NULL; -} - -#endif - - - -/* List of functions exported by this module */ - -static struct PyMethodDef entropy_functions[] = { - {"entropy", (PyCFunction)entropy, METH_VARARGS, "Return a string of random bytes produced by a platform-specific\nentropy source."}, - {NULL, NULL} /* Sentinel */ -}; - - -/* Initialize this module. */ - -PyMODINIT_FUNC initentropy(void) -{ - Py_InitModule("entropy", entropy_functions); -}
\ No newline at end of file diff --git a/chromium/third_party/tlslite/tlslite/utils/hmac.py b/chromium/third_party/tlslite/tlslite/utils/hmac.py deleted file mode 100644 index fe8feec219c..00000000000 --- a/chromium/third_party/tlslite/tlslite/utils/hmac.py +++ /dev/null @@ -1,104 +0,0 @@ -"""HMAC (Keyed-Hashing for Message Authentication) Python module. - -Implements the HMAC algorithm as described by RFC 2104. - -(This file is modified from the standard library version to do faster -copying) -""" - -def _strxor(s1, s2): - """Utility method. XOR the two strings s1 and s2 (must have same length). - """ - return "".join(map(lambda x, y: chr(ord(x) ^ ord(y)), s1, s2)) - -# The size of the digests returned by HMAC depends on the underlying -# hashing module used. -digest_size = None - -class HMAC: - """RFC2104 HMAC class. - - This supports the API for Cryptographic Hash Functions (PEP 247). - """ - - def __init__(self, key, msg = None, digestmod = None): - """Create a new HMAC object. - - key: key for the keyed hash object. - msg: Initial input for the hash, if provided. - digestmod: A module supporting PEP 247. Defaults to the md5 module. - """ - if digestmod is None: - import md5 - digestmod = md5 - - if key == None: #TREVNEW - for faster copying - return #TREVNEW - - self.digestmod = digestmod - self.outer = digestmod.new() - self.inner = digestmod.new() - self.digest_size = digestmod.digest_size - - blocksize = 64 - ipad = "\x36" * blocksize - opad = "\x5C" * blocksize - - if len(key) > blocksize: - key = digestmod.new(key).digest() - - key = key + chr(0) * (blocksize - len(key)) - self.outer.update(_strxor(key, opad)) - self.inner.update(_strxor(key, ipad)) - if msg is not None: - self.update(msg) - -## def clear(self): -## raise NotImplementedError, "clear() method not available in HMAC." - - def update(self, msg): - """Update this hashing object with the string msg. - """ - self.inner.update(msg) - - def copy(self): - """Return a separate copy of this hashing object. - - An update to this copy won't affect the original object. - """ - other = HMAC(None) #TREVNEW - for faster copying - other.digest_size = self.digest_size #TREVNEW - other.digestmod = self.digestmod - other.inner = self.inner.copy() - other.outer = self.outer.copy() - return other - - def digest(self): - """Return the hash value of this hashing object. - - This returns a string containing 8-bit data. The object is - not altered in any way by this function; you can continue - updating the object after calling this function. - """ - h = self.outer.copy() - h.update(self.inner.digest()) - return h.digest() - - def hexdigest(self): - """Like digest(), but returns a string of hexadecimal digits instead. - """ - return "".join([hex(ord(x))[2:].zfill(2) - for x in tuple(self.digest())]) - -def new(key, msg = None, digestmod = None): - """Create a new hashing object and return it. - - key: The starting key for the hash. - msg: if available, will immediately be hashed into the object's starting - state. - - You can now feed arbitrary strings into the object using its update() - method, and can ask for the hash value at any time by calling its digest() - method. - """ - return HMAC(key, msg, digestmod) diff --git a/chromium/third_party/tlslite/tlslite/utils/jython_compat.py b/chromium/third_party/tlslite/tlslite/utils/jython_compat.py deleted file mode 100644 index 1245183a99c..00000000000 --- a/chromium/third_party/tlslite/tlslite/utils/jython_compat.py +++ /dev/null @@ -1,195 +0,0 @@ -"""Miscellaneous functions to mask Python/Jython differences.""" - -import os -import sha - -if os.name != "java": - BaseException = Exception - - from sets import Set - import array - import math - - def createByteArraySequence(seq): - return array.array('B', seq) - def createByteArrayZeros(howMany): - return array.array('B', [0] * howMany) - def concatArrays(a1, a2): - return a1+a2 - - def bytesToString(bytes): - return bytes.tostring() - - def stringToBytes(s): - bytes = createByteArrayZeros(0) - bytes.fromstring(s) - return bytes - - def numBits(n): - if n==0: - return 0 - return int(math.floor(math.log(n, 2))+1) - - class CertChainBase: pass - class SelfTestBase: pass - class ReportFuncBase: pass - - #Helper functions for working with sets (from Python 2.3) - def iterSet(set): - return iter(set) - - def getListFromSet(set): - return list(set) - - #Factory function for getting a SHA1 object - def getSHA1(s): - return sha.sha(s) - - import sys - import traceback - - def formatExceptionTrace(e): - newStr = "".join(traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)) - return newStr - -else: - #Jython 2.1 is missing lots of python 2.3 stuff, - #which we have to emulate here: - import java - import jarray - - BaseException = java.lang.Exception - - def createByteArraySequence(seq): - if isinstance(seq, type("")): #If it's a string, convert - seq = [ord(c) for c in seq] - return jarray.array(seq, 'h') #use short instead of bytes, cause bytes are signed - def createByteArrayZeros(howMany): - return jarray.zeros(howMany, 'h') #use short instead of bytes, cause bytes are signed - def concatArrays(a1, a2): - l = list(a1)+list(a2) - return createByteArraySequence(l) - - #WAY TOO SLOW - MUST BE REPLACED------------ - def bytesToString(bytes): - return "".join([chr(b) for b in bytes]) - - def stringToBytes(s): - bytes = createByteArrayZeros(len(s)) - for count, c in enumerate(s): - bytes[count] = ord(c) - return bytes - #WAY TOO SLOW - MUST BE REPLACED------------ - - def numBits(n): - if n==0: - return 0 - n= 1L * n; #convert to long, if it isn't already - return n.__tojava__(java.math.BigInteger).bitLength() - - #This properly creates static methods for Jython - class staticmethod: - def __init__(self, anycallable): self.__call__ = anycallable - - #Properties are not supported for Jython - class property: - def __init__(self, anycallable): pass - - #True and False have to be specially defined - False = 0 - True = 1 - - class StopIteration(Exception): pass - - def enumerate(collection): - return zip(range(len(collection)), collection) - - class Set: - def __init__(self, seq=None): - self.values = {} - if seq: - for e in seq: - self.values[e] = None - - def add(self, e): - self.values[e] = None - - def discard(self, e): - if e in self.values.keys(): - del(self.values[e]) - - def union(self, s): - ret = Set() - for e in self.values.keys(): - ret.values[e] = None - for e in s.values.keys(): - ret.values[e] = None - return ret - - def issubset(self, other): - for e in self.values.keys(): - if e not in other.values.keys(): - return False - return True - - def __nonzero__( self): - return len(self.values.keys()) - - def __contains__(self, e): - return e in self.values.keys() - - def iterSet(set): - return set.values.keys() - - def getListFromSet(set): - return set.values.keys() - - """ - class JCE_SHA1: - def __init__(self, s=None): - self.md = java.security.MessageDigest.getInstance("SHA1") - if s: - self.update(s) - - def update(self, s): - self.md.update(s) - - def copy(self): - sha1 = JCE_SHA1() - sha1.md = self.md.clone() - return sha1 - - def digest(self): - digest = self.md.digest() - bytes = jarray.zeros(20, 'h') - for count in xrange(20): - x = digest[count] - if x < 0: x += 256 - bytes[count] = x - return bytes - """ - - #Factory function for getting a SHA1 object - #The JCE_SHA1 class is way too slow... - #the sha.sha object we use instead is broken in the jython 2.1 - #release, and needs to be patched - def getSHA1(s): - #return JCE_SHA1(s) - return sha.sha(s) - - - #Adjust the string to an array of bytes - def stringToJavaByteArray(s): - bytes = jarray.zeros(len(s), 'b') - for count, c in enumerate(s): - x = ord(c) - if x >= 128: x -= 256 - bytes[count] = x - return bytes - - import sys - import traceback - - def formatExceptionTrace(e): - newStr = "".join(traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)) - return newStr diff --git a/chromium/third_party/tlslite/tlslite/utils/keyfactory.py b/chromium/third_party/tlslite/tlslite/utils/keyfactory.py index 5005af7f5b7..1ee338f3cf4 100644 --- a/chromium/third_party/tlslite/tlslite/utils/keyfactory.py +++ b/chromium/third_party/tlslite/tlslite/utils/keyfactory.py @@ -1,19 +1,21 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + """Factory functions for asymmetric cryptography. -@sort: generateRSAKey, parseXMLKey, parsePEMKey, parseAsPublicKey, -parseAsPrivateKey +@sort: generateRSAKey, parsePEMKey, parseAsPublicKey """ -from compat import * +from .compat import * -from RSAKey import RSAKey -from Python_RSAKey import Python_RSAKey -import cryptomath +from .rsakey import RSAKey +from .python_rsakey import Python_RSAKey +from tlslite.utils import cryptomath if cryptomath.m2cryptoLoaded: - from OpenSSL_RSAKey import OpenSSL_RSAKey + from .openssl_rsakey import OpenSSL_RSAKey if cryptomath.pycryptoLoaded: - from PyCrypto_RSAKey import PyCrypto_RSAKey + from .pycrypto_rsakey import PyCrypto_RSAKey # ************************************************************************** # Factory Functions for RSA Keys @@ -25,7 +27,7 @@ def generateRSAKey(bits, implementations=["openssl", "python"]): @type bits: int @param bits: Desired bit length of the new key's modulus. - @rtype: L{tlslite.utils.RSAKey.RSAKey} + @rtype: L{tlslite.utils.rsakey.RSAKey} @return: A new RSA private key. """ for implementation in implementations: @@ -35,54 +37,6 @@ def generateRSAKey(bits, implementations=["openssl", "python"]): return Python_RSAKey.generate(bits) raise ValueError("No acceptable implementations") -def parseXMLKey(s, private=False, public=False, implementations=["python"]): - """Parse an XML-format key. - - The XML format used here is specific to tlslite and cryptoIDlib. The - format can store the public component of a key, or the public and - private components. For example:: - - <publicKey xmlns="http://trevp.net/rsa"> - <n>4a5yzB8oGNlHo866CAspAC47M4Fvx58zwK8pou... - <e>Aw==</e> - </publicKey> - - <privateKey xmlns="http://trevp.net/rsa"> - <n>4a5yzB8oGNlHo866CAspAC47M4Fvx58zwK8pou... - <e>Aw==</e> - <d>JZ0TIgUxWXmL8KJ0VqyG1V0J3ern9pqIoB0xmy... - <p>5PreIj6z6ldIGL1V4+1C36dQFHNCQHJvW52GXc... - <q>/E/wDit8YXPCxx126zTq2ilQ3IcW54NJYyNjiZ... - <dP>mKc+wX8inDowEH45Qp4slRo1YveBgExKPROu6... - <dQ>qDVKtBz9lk0shL5PR3ickXDgkwS576zbl2ztB... - <qInv>j6E8EA7dNsTImaXexAmLA1DoeArsYeFAInr... - </privateKey> - - @type s: str - @param s: A string containing an XML public or private key. - - @type private: bool - @param private: If True, a L{SyntaxError} will be raised if the private - key component is not present. - - @type public: bool - @param public: If True, the private key component (if present) will be - discarded, so this function will always return a public key. - - @rtype: L{tlslite.utils.RSAKey.RSAKey} - @return: An RSA key. - - @raise SyntaxError: If the key is not properly formatted. - """ - for implementation in implementations: - if implementation == "python": - key = Python_RSAKey.parseXML(s) - break - else: - raise ValueError("No acceptable implementations") - - return _parseKeyHelper(key, private, public) - #Parse as an OpenSSL or Python key def parsePEMKey(s, private=False, public=False, passwordCallback=None, implementations=["openssl", "python"]): @@ -171,36 +125,30 @@ def _parseKeyHelper(key, private, public): return key def parseAsPublicKey(s): - """Parse an XML or PEM-formatted public key. + """Parse a PEM-formatted public key. @type s: str - @param s: A string containing an XML or PEM-encoded public or private key. + @param s: A string containing a PEM-encoded public or private key. - @rtype: L{tlslite.utils.RSAKey.RSAKey} + @rtype: L{tlslite.utils.rsakey.RSAKey} @return: An RSA public key. @raise SyntaxError: If the key is not properly formatted. """ - try: - return parsePEMKey(s, public=True) - except: - return parseXMLKey(s, public=True) + return parsePEMKey(s, public=True) def parsePrivateKey(s): - """Parse an XML or PEM-formatted private key. + """Parse a PEM-formatted private key. @type s: str - @param s: A string containing an XML or PEM-encoded private key. + @param s: A string containing a PEM-encoded private key. - @rtype: L{tlslite.utils.RSAKey.RSAKey} + @rtype: L{tlslite.utils.rsakey.RSAKey} @return: An RSA private key. @raise SyntaxError: If the key is not properly formatted. """ - try: - return parsePEMKey(s, private=True) - except: - return parseXMLKey(s, private=True) + return parsePEMKey(s, private=True) def _createPublicKey(key): """ diff --git a/chromium/third_party/tlslite/tlslite/utils/OpenSSL_AES.py b/chromium/third_party/tlslite/tlslite/utils/openssl_aes.py index e60679bf509..658cf8303d4 100644 --- a/chromium/third_party/tlslite/tlslite/utils/OpenSSL_AES.py +++ b/chromium/third_party/tlslite/tlslite/utils/openssl_aes.py @@ -1,7 +1,10 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + """OpenSSL/M2Crypto AES implementation.""" -from cryptomath import * -from AES import * +from .cryptomath import * +from .aes import * if m2cryptoLoaded: @@ -32,7 +35,7 @@ if m2cryptoLoaded: ciphertext = m2.cipher_update(context, plaintext) m2.cipher_ctx_free(context) self.IV = ciphertext[-self.block_size:] - return ciphertext + return bytearray(ciphertext) def decrypt(self, ciphertext): AES.decrypt(self, ciphertext) @@ -46,4 +49,4 @@ if m2cryptoLoaded: plaintext = plaintext[:len(ciphertext)] m2.cipher_ctx_free(context) self.IV = ciphertext[-self.block_size:] - return plaintext + return bytearray(plaintext) diff --git a/chromium/third_party/tlslite/tlslite/utils/OpenSSL_RC4.py b/chromium/third_party/tlslite/tlslite/utils/openssl_rc4.py index ac433aad761..2fbfa07e2bc 100644 --- a/chromium/third_party/tlslite/tlslite/utils/OpenSSL_RC4.py +++ b/chromium/third_party/tlslite/tlslite/utils/openssl_rc4.py @@ -1,7 +1,10 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + """OpenSSL/M2Crypto RC4 implementation.""" -from cryptomath import * -from RC4 import RC4 +from .cryptomath import * +from .rc4 import RC4 if m2cryptoLoaded: @@ -19,7 +22,7 @@ if m2cryptoLoaded: m2.rc4_free(self.rc4) def encrypt(self, plaintext): - return m2.rc4_update(self.rc4, plaintext) + return bytearray(m2.rc4_update(self.rc4, plaintext)) def decrypt(self, ciphertext): - return self.encrypt(ciphertext) + return bytearray(self.encrypt(ciphertext)) diff --git a/chromium/third_party/tlslite/tlslite/utils/OpenSSL_RSAKey.py b/chromium/third_party/tlslite/tlslite/utils/openssl_rsakey.py index fe1a3cd74d2..f6ec8595819 100644 --- a/chromium/third_party/tlslite/tlslite/utils/OpenSSL_RSAKey.py +++ b/chromium/third_party/tlslite/tlslite/utils/openssl_rsakey.py @@ -1,9 +1,12 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + """OpenSSL/M2Crypto RSA implementation.""" -from cryptomath import * +from .cryptomath import * -from RSAKey import * -from Python_RSAKey import Python_RSAKey +from .rsakey import * +from .python_rsakey import Python_RSAKey #copied from M2Crypto.util.py, so when we load the local copy of m2 #we can still use it @@ -55,33 +58,16 @@ if m2cryptoLoaded: def hasPrivateKey(self): return self._hasPrivateKey - def hash(self): - return Python_RSAKey(self.n, self.e).hash() - def _rawPrivateKeyOp(self, m): - s = numberToString(m) - byteLength = numBytes(self.n) - if len(s)== byteLength: - pass - elif len(s) == byteLength-1: - s = '\0' + s - else: - raise AssertionError() - c = stringToNumber(m2.rsa_private_encrypt(self.rsa, s, - m2.no_padding)) + b = numberToByteArray(m, numBytes(self.n)) + s = m2.rsa_private_encrypt(self.rsa, bytes(b), m2.no_padding) + c = bytesToNumber(bytearray(s)) return c def _rawPublicKeyOp(self, c): - s = numberToString(c) - byteLength = numBytes(self.n) - if len(s)== byteLength: - pass - elif len(s) == byteLength-1: - s = '\0' + s - else: - raise AssertionError() - m = stringToNumber(m2.rsa_public_decrypt(self.rsa, s, - m2.no_padding)) + b = numberToByteArray(c, numBytes(self.n)) + s = m2.rsa_public_decrypt(self.rsa, bytes(b), m2.no_padding) + m = bytesToNumber(bytearray(s)) return m def acceptsPassword(self): return True @@ -103,9 +89,6 @@ if m2cryptoLoaded: m2.bio_free(bio) return s - def writeXMLPublicKey(self, indent=''): - return Python_RSAKey(self.n, self.e).write(indent) - def generate(bits): key = OpenSSL_RSAKey() def f():pass @@ -115,6 +98,11 @@ if m2cryptoLoaded: generate = staticmethod(generate) def parse(s, passwordCallback=None): + # Skip forward to the first PEM header + start = s.find("-----BEGIN ") + if start == -1: + raise SyntaxError() + s = s[start:] if s.startswith("-----BEGIN "): if passwordCallback==None: callback = password_callback diff --git a/chromium/third_party/tlslite/tlslite/utils/OpenSSL_TripleDES.py b/chromium/third_party/tlslite/tlslite/utils/openssl_tripledes.py index f5ba1656521..15a68bb4e33 100644 --- a/chromium/third_party/tlslite/tlslite/utils/OpenSSL_TripleDES.py +++ b/chromium/third_party/tlslite/tlslite/utils/openssl_tripledes.py @@ -1,7 +1,10 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + """OpenSSL/M2Crypto 3DES implementation.""" -from cryptomath import * -from TripleDES import * +from .cryptomath import * +from .tripledes import * if m2cryptoLoaded: @@ -27,7 +30,7 @@ if m2cryptoLoaded: ciphertext = m2.cipher_update(context, plaintext) m2.cipher_ctx_free(context) self.IV = ciphertext[-self.block_size:] - return ciphertext + return bytearray(ciphertext) def decrypt(self, ciphertext): TripleDES.decrypt(self, ciphertext) @@ -41,4 +44,4 @@ if m2cryptoLoaded: plaintext = plaintext[:len(ciphertext)] m2.cipher_ctx_free(context) self.IV = ciphertext[-self.block_size:] - return plaintext
\ No newline at end of file + return bytearray(plaintext)
\ No newline at end of file diff --git a/chromium/third_party/tlslite/tlslite/utils/pem.py b/chromium/third_party/tlslite/tlslite/utils/pem.py new file mode 100644 index 00000000000..04b5d0bd0bf --- /dev/null +++ b/chromium/third_party/tlslite/tlslite/utils/pem.py @@ -0,0 +1,98 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + +from .compat import * +import binascii + +#This code is shared with tackpy (somewhat), so I'd rather make minimal +#changes, and preserve the use of a2b_base64 throughout. + +def dePem(s, name): + """Decode a PEM string into a bytearray of its payload. + + The input must contain an appropriate PEM prefix and postfix + based on the input name string, e.g. for name="CERTIFICATE": + + -----BEGIN CERTIFICATE----- + MIIBXDCCAUSgAwIBAgIBADANBgkqhkiG9w0BAQUFADAPMQ0wCwYDVQQDEwRUQUNL +... + KoZIhvcNAQEFBQADAwA5kw== + -----END CERTIFICATE----- + + The first such PEM block in the input will be found, and its + payload will be base64 decoded and returned. + """ + prefix = "-----BEGIN %s-----" % name + postfix = "-----END %s-----" % name + start = s.find(prefix) + if start == -1: + raise SyntaxError("Missing PEM prefix") + end = s.find(postfix, start+len(prefix)) + if end == -1: + raise SyntaxError("Missing PEM postfix") + s = s[start+len("-----BEGIN %s-----" % name) : end] + retBytes = a2b_base64(s) # May raise SyntaxError + return retBytes + +def dePemList(s, name): + """Decode a sequence of PEM blocks into a list of bytearrays. + + The input must contain any number of PEM blocks, each with the appropriate + PEM prefix and postfix based on the input name string, e.g. for + name="TACK BREAK SIG". Arbitrary text can appear between and before and + after the PEM blocks. For example: + + " Created by TACK.py 0.9.3 Created at 2012-02-01T00:30:10Z -----BEGIN TACK + BREAK SIG----- + ATKhrz5C6JHJW8BF5fLVrnQss6JnWVyEaC0p89LNhKPswvcC9/s6+vWLd9snYTUv + YMEBdw69PUP8JB4AdqA3K6Ap0Fgd9SSTOECeAKOUAym8zcYaXUwpk0+WuPYa7Zmm + SkbOlK4ywqt+amhWbg9txSGUwFO5tWUHT3QrnRlE/e3PeNFXLx5Bckg= -----END TACK + BREAK SIG----- Created by TACK.py 0.9.3 Created at 2012-02-01T00:30:11Z + -----BEGIN TACK BREAK SIG----- + ATKhrz5C6JHJW8BF5fLVrnQss6JnWVyEaC0p89LNhKPswvcC9/s6+vWLd9snYTUv + YMEBdw69PUP8JB4AdqA3K6BVCWfcjN36lx6JwxmZQncS6sww7DecFO/qjSePCxwM + +kdDqX/9/183nmjx6bf0ewhPXkA0nVXsDYZaydN8rJU1GaMlnjcIYxY= -----END TACK + BREAK SIG----- " + + All such PEM blocks will be found, decoded, and return in an ordered list + of bytearrays, which may have zero elements if not PEM blocks are found. + """ + bList = [] + prefix = "-----BEGIN %s-----" % name + postfix = "-----END %s-----" % name + while 1: + start = s.find(prefix) + if start == -1: + return bList + end = s.find(postfix, start+len(prefix)) + if end == -1: + raise SyntaxError("Missing PEM postfix") + s2 = s[start+len(prefix) : end] + retBytes = a2b_base64(s2) # May raise SyntaxError + bList.append(retBytes) + s = s[end+len(postfix) : ] + +def pem(b, name): + """Encode a payload bytearray into a PEM string. + + The input will be base64 encoded, then wrapped in a PEM prefix/postfix + based on the name string, e.g. for name="CERTIFICATE": + + -----BEGIN CERTIFICATE----- + MIIBXDCCAUSgAwIBAgIBADANBgkqhkiG9w0BAQUFADAPMQ0wCwYDVQQDEwRUQUNL +... + KoZIhvcNAQEFBQADAwA5kw== + -----END CERTIFICATE----- + """ + s1 = b2a_base64(b)[:-1] # remove terminating \n + s2 = "" + while s1: + s2 += s1[:64] + "\n" + s1 = s1[64:] + s = ("-----BEGIN %s-----\n" % name) + s2 + \ + ("-----END %s-----\n" % name) + return s + +def pemSniff(inStr, name): + searchStr = "-----BEGIN %s-----" % name + return searchStr in inStr diff --git a/chromium/third_party/tlslite/tlslite/utils/PyCrypto_AES.py b/chromium/third_party/tlslite/tlslite/utils/pycrypto_aes.py index e38b19d6fb7..b3425c047d7 100644 --- a/chromium/third_party/tlslite/tlslite/utils/PyCrypto_AES.py +++ b/chromium/third_party/tlslite/tlslite/utils/pycrypto_aes.py @@ -1,7 +1,10 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + """PyCrypto AES implementation.""" -from cryptomath import * -from AES import * +from .cryptomath import * +from .aes import * if pycryptoLoaded: import Crypto.Cipher.AES @@ -13,10 +16,14 @@ if pycryptoLoaded: def __init__(self, key, mode, IV): AES.__init__(self, key, mode, IV, "pycrypto") + key = bytes(key) + IV = bytes(IV) self.context = Crypto.Cipher.AES.new(key, mode, IV) def encrypt(self, plaintext): - return self.context.encrypt(plaintext) + plaintext = bytes(plaintext) + return bytearray(self.context.encrypt(plaintext)) def decrypt(self, ciphertext): - return self.context.decrypt(ciphertext)
\ No newline at end of file + ciphertext = bytes(ciphertext) + return bytearray(self.context.decrypt(ciphertext)) diff --git a/chromium/third_party/tlslite/tlslite/utils/PyCrypto_RC4.py b/chromium/third_party/tlslite/tlslite/utils/pycrypto_rc4.py index 6c6d86afde4..fc98d7c78b1 100644 --- a/chromium/third_party/tlslite/tlslite/utils/PyCrypto_RC4.py +++ b/chromium/third_party/tlslite/tlslite/utils/pycrypto_rc4.py @@ -1,7 +1,10 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + """PyCrypto RC4 implementation.""" -from cryptomath import * -from RC4 import * +from .cryptomath import * +from .rc4 import * if pycryptoLoaded: import Crypto.Cipher.ARC4 @@ -13,10 +16,13 @@ if pycryptoLoaded: def __init__(self, key): RC4.__init__(self, key, "pycrypto") + key = bytes(key) self.context = Crypto.Cipher.ARC4.new(key) def encrypt(self, plaintext): - return self.context.encrypt(plaintext) + plaintext = bytes(plaintext) + return bytearray(self.context.encrypt(plaintext)) def decrypt(self, ciphertext): - return self.context.decrypt(ciphertext)
\ No newline at end of file + ciphertext = bytes(ciphertext) + return bytearray(self.context.decrypt(ciphertext))
\ No newline at end of file diff --git a/chromium/third_party/tlslite/tlslite/utils/pycrypto_rsakey.py b/chromium/third_party/tlslite/tlslite/utils/pycrypto_rsakey.py new file mode 100644 index 00000000000..4de543638fb --- /dev/null +++ b/chromium/third_party/tlslite/tlslite/utils/pycrypto_rsakey.py @@ -0,0 +1,44 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + +"""PyCrypto RSA implementation.""" + +from .cryptomath import * + +from .rsakey import * +from .python_rsakey import Python_RSAKey + +if pycryptoLoaded: + + from Crypto.PublicKey import RSA + + class PyCrypto_RSAKey(RSAKey): + def __init__(self, n=0, e=0, d=0, p=0, q=0, dP=0, dQ=0, qInv=0): + if not d: + self.rsa = RSA.construct( (n, e) ) + else: + self.rsa = RSA.construct( (n, e, d, p, q) ) + + def __getattr__(self, name): + return getattr(self.rsa, name) + + def hasPrivateKey(self): + return self.rsa.has_private() + + def _rawPrivateKeyOp(self, m): + s = bytes(numberToByteArray(m, numBytes(self.n))) + c = bytesToNumber(bytearray(self.rsa.decrypt((s,)))) + return c + + def _rawPublicKeyOp(self, c): + s = bytes(numberToByteArray(c, numBytes(self.n))) + m = bytesToNumber(bytearray(self.rsa.encrypt(s, None)[0])) + return m + + def generate(bits): + key = PyCrypto_RSAKey() + def f(numBytes): + return bytes(getRandomBytes(numBytes)) + key.rsa = RSA.generate(bits, f) + return key + generate = staticmethod(generate) diff --git a/chromium/third_party/tlslite/tlslite/utils/PyCrypto_TripleDES.py b/chromium/third_party/tlslite/tlslite/utils/pycrypto_tripledes.py index 8c22bb80a57..8117f34b85e 100644 --- a/chromium/third_party/tlslite/tlslite/utils/PyCrypto_TripleDES.py +++ b/chromium/third_party/tlslite/tlslite/utils/pycrypto_tripledes.py @@ -1,7 +1,10 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + """PyCrypto 3DES implementation.""" -from cryptomath import * -from TripleDES import * +from .cryptomath import * +from .tripledes import * if pycryptoLoaded: import Crypto.Cipher.DES3 @@ -13,10 +16,14 @@ if pycryptoLoaded: def __init__(self, key, mode, IV): TripleDES.__init__(self, key, mode, IV, "pycrypto") + key = bytes(key) + IV = bytes(IV) self.context = Crypto.Cipher.DES3.new(key, mode, IV) def encrypt(self, plaintext): - return self.context.encrypt(plaintext) + plaintext = bytes(plaintext) + return bytearray(self.context.encrypt(plaintext)) def decrypt(self, ciphertext): - return self.context.decrypt(ciphertext)
\ No newline at end of file + ciphertext = bytes(ciphertext) + return bytearray(self.context.decrypt(ciphertext))
\ No newline at end of file diff --git a/chromium/third_party/tlslite/tlslite/utils/Python_AES.py b/chromium/third_party/tlslite/tlslite/utils/python_aes.py index 657152f8921..cb8f87ed401 100644 --- a/chromium/third_party/tlslite/tlslite/utils/Python_AES.py +++ b/chromium/third_party/tlslite/tlslite/utils/python_aes.py @@ -1,9 +1,12 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + """Pure-Python AES implementation.""" -from cryptomath import * +from .cryptomath import * -from AES import * -from rijndael import rijndael +from .aes import * +from .rijndael import rijndael def new(key, mode, IV): return Python_AES(key, mode, IV) @@ -17,20 +20,19 @@ class Python_AES(AES): def encrypt(self, plaintext): AES.encrypt(self, plaintext) - plaintextBytes = stringToBytes(plaintext) - chainBytes = stringToBytes(self.IV) + plaintextBytes = plaintext[:] + chainBytes = self.IV[:] #CBC Mode: For each block... - for x in range(len(plaintextBytes)/16): + for x in range(len(plaintextBytes)//16): #XOR with the chaining block blockBytes = plaintextBytes[x*16 : (x*16)+16] for y in range(16): blockBytes[y] ^= chainBytes[y] - blockString = bytesToString(blockBytes) #Encrypt it - encryptedBytes = stringToBytes(self.rijndael.encrypt(blockString)) + encryptedBytes = self.rijndael.encrypt(blockBytes) #Overwrite the input with the output for y in range(16): @@ -39,22 +41,21 @@ class Python_AES(AES): #Set the next chaining block chainBytes = encryptedBytes - self.IV = bytesToString(chainBytes) - return bytesToString(plaintextBytes) + self.IV = chainBytes[:] + return plaintextBytes def decrypt(self, ciphertext): AES.decrypt(self, ciphertext) - ciphertextBytes = stringToBytes(ciphertext) - chainBytes = stringToBytes(self.IV) + ciphertextBytes = ciphertext[:] + chainBytes = self.IV[:] #CBC Mode: For each block... - for x in range(len(ciphertextBytes)/16): + for x in range(len(ciphertextBytes)//16): #Decrypt it blockBytes = ciphertextBytes[x*16 : (x*16)+16] - blockString = bytesToString(blockBytes) - decryptedBytes = stringToBytes(self.rijndael.decrypt(blockString)) + decryptedBytes = self.rijndael.decrypt(blockBytes) #XOR with the chaining block and overwrite the input with output for y in range(16): @@ -64,5 +65,5 @@ class Python_AES(AES): #Set the next chaining block chainBytes = blockBytes - self.IV = bytesToString(chainBytes) - return bytesToString(ciphertextBytes) + self.IV = chainBytes[:] + return ciphertextBytes diff --git a/chromium/third_party/tlslite/tlslite/utils/Python_RC4.py b/chromium/third_party/tlslite/tlslite/utils/python_rc4.py index 56ce5fb2fc2..15d9fd49113 100644 --- a/chromium/third_party/tlslite/tlslite/utils/Python_RC4.py +++ b/chromium/third_party/tlslite/tlslite/utils/python_rc4.py @@ -1,15 +1,17 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + """Pure-Python RC4 implementation.""" -from RC4 import RC4 -from cryptomath import * +from .rc4 import RC4 +from .cryptomath import * def new(key): return Python_RC4(key) class Python_RC4(RC4): - def __init__(self, key): - RC4.__init__(self, key, "python") - keyBytes = stringToBytes(key) + def __init__(self, keyBytes): + RC4.__init__(self, keyBytes, "python") S = [i for i in range(256)] j = 0 for i in range(256): @@ -20,20 +22,20 @@ class Python_RC4(RC4): self.i = 0 self.j = 0 - def encrypt(self, plaintext): - plaintextBytes = stringToBytes(plaintext) + def encrypt(self, plaintextBytes): + ciphertextBytes = plaintextBytes[:] S = self.S i = self.i j = self.j - for x in range(len(plaintextBytes)): + for x in range(len(ciphertextBytes)): i = (i + 1) % 256 j = (j + S[i]) % 256 S[i], S[j] = S[j], S[i] t = (S[i] + S[j]) % 256 - plaintextBytes[x] ^= S[t] + ciphertextBytes[x] ^= S[t] self.i = i self.j = j - return bytesToString(plaintextBytes) + return ciphertextBytes def decrypt(self, ciphertext): return self.encrypt(ciphertext) diff --git a/chromium/third_party/tlslite/tlslite/utils/python_rsakey.py b/chromium/third_party/tlslite/tlslite/utils/python_rsakey.py new file mode 100644 index 00000000000..8b210847f49 --- /dev/null +++ b/chromium/third_party/tlslite/tlslite/utils/python_rsakey.py @@ -0,0 +1,138 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + +"""Pure-Python RSA implementation.""" + +from .cryptomath import * +from .asn1parser import ASN1Parser +from .rsakey import * +from .pem import * + +class Python_RSAKey(RSAKey): + def __init__(self, n=0, e=0, d=0, p=0, q=0, dP=0, dQ=0, qInv=0): + if (n and not e) or (e and not n): + raise AssertionError() + self.n = n + self.e = e + self.d = d + self.p = p + self.q = q + self.dP = dP + self.dQ = dQ + self.qInv = qInv + self.blinder = 0 + self.unblinder = 0 + + def hasPrivateKey(self): + return self.d != 0 + + def _rawPrivateKeyOp(self, m): + #Create blinding values, on the first pass: + if not self.blinder: + self.unblinder = getRandomNumber(2, self.n) + self.blinder = powMod(invMod(self.unblinder, self.n), self.e, + self.n) + + #Blind the input + m = (m * self.blinder) % self.n + + #Perform the RSA operation + c = self._rawPrivateKeyOpHelper(m) + + #Unblind the output + c = (c * self.unblinder) % self.n + + #Update blinding values + self.blinder = (self.blinder * self.blinder) % self.n + self.unblinder = (self.unblinder * self.unblinder) % self.n + + #Return the output + return c + + + def _rawPrivateKeyOpHelper(self, m): + #Non-CRT version + #c = powMod(m, self.d, self.n) + + #CRT version (~3x faster) + s1 = powMod(m, self.dP, self.p) + s2 = powMod(m, self.dQ, self.q) + h = ((s1 - s2) * self.qInv) % self.p + c = s2 + self.q * h + return c + + def _rawPublicKeyOp(self, c): + m = powMod(c, self.e, self.n) + return m + + def acceptsPassword(self): return False + + def generate(bits): + key = Python_RSAKey() + p = getRandomPrime(bits//2, False) + q = getRandomPrime(bits//2, False) + t = lcm(p-1, q-1) + key.n = p * q + key.e = 65537 + key.d = invMod(key.e, t) + key.p = p + key.q = q + key.dP = key.d % (p-1) + key.dQ = key.d % (q-1) + key.qInv = invMod(q, p) + return key + generate = staticmethod(generate) + + def parsePEM(s, passwordCallback=None): + """Parse a string containing a <privateKey> or <publicKey>, or + PEM-encoded key.""" + + if pemSniff(s, "PRIVATE KEY"): + bytes = dePem(s, "PRIVATE KEY") + return Python_RSAKey._parsePKCS8(bytes) + elif pemSniff(s, "RSA PRIVATE KEY"): + bytes = dePem(s, "RSA PRIVATE KEY") + return Python_RSAKey._parseSSLeay(bytes) + else: + raise SyntaxError("Not a PEM private key file") + parsePEM = staticmethod(parsePEM) + + def _parsePKCS8(bytes): + p = ASN1Parser(bytes) + + version = p.getChild(0).value[0] + if version != 0: + raise SyntaxError("Unrecognized PKCS8 version") + + rsaOID = p.getChild(1).value + if list(rsaOID) != [6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0]: + raise SyntaxError("Unrecognized AlgorithmIdentifier") + + #Get the privateKey + privateKeyP = p.getChild(2) + + #Adjust for OCTET STRING encapsulation + privateKeyP = ASN1Parser(privateKeyP.value) + + return Python_RSAKey._parseASN1PrivateKey(privateKeyP) + _parsePKCS8 = staticmethod(_parsePKCS8) + + def _parseSSLeay(bytes): + privateKeyP = ASN1Parser(bytes) + return Python_RSAKey._parseASN1PrivateKey(privateKeyP) + _parseSSLeay = staticmethod(_parseSSLeay) + + def _parseASN1PrivateKey(privateKeyP): + version = privateKeyP.getChild(0).value[0] + if version != 0: + raise SyntaxError("Unrecognized RSAPrivateKey version") + n = bytesToNumber(privateKeyP.getChild(1).value) + e = bytesToNumber(privateKeyP.getChild(2).value) + d = bytesToNumber(privateKeyP.getChild(3).value) + p = bytesToNumber(privateKeyP.getChild(4).value) + q = bytesToNumber(privateKeyP.getChild(5).value) + dP = bytesToNumber(privateKeyP.getChild(6).value) + dQ = bytesToNumber(privateKeyP.getChild(7).value) + qInv = bytesToNumber(privateKeyP.getChild(8).value) + return Python_RSAKey(n, e, d, p, q, dP, dQ, qInv) + _parseASN1PrivateKey = staticmethod(_parseASN1PrivateKey) diff --git a/chromium/third_party/tlslite/tlslite/utils/RC4.py b/chromium/third_party/tlslite/tlslite/utils/rc4.py index 550692327ce..809026a21ce 100644 --- a/chromium/third_party/tlslite/tlslite/utils/RC4.py +++ b/chromium/third_party/tlslite/tlslite/utils/rc4.py @@ -1,8 +1,10 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + """Abstract class for RC4.""" -from compat import * #For False -class RC4: +class RC4(object): def __init__(self, keyBytes, implementation): if len(keyBytes) < 16 or len(keyBytes) > 256: raise ValueError() diff --git a/chromium/third_party/tlslite/tlslite/utils/rijndael.py b/chromium/third_party/tlslite/tlslite/utils/rijndael.py index cb2f547346d..a1d720a2630 100644 --- a/chromium/third_party/tlslite/tlslite/utils/rijndael.py +++ b/chromium/third_party/tlslite/tlslite/utils/rijndael.py @@ -1,3 +1,10 @@ +# Authors: +# Bram Cohen +# Trevor Perrin - various changes +# +# See the LICENSE file for legal information regarding use of this file. +# Also see Bram Cohen's statement below + """ A pure python (slow) implementation of rijndael with a decent interface @@ -29,21 +36,6 @@ If any strings are of the wrong length a ValueError is thrown import copy import string - - -#----------------------- -#TREV - ADDED BECAUSE THERE'S WARNINGS ABOUT INT OVERFLOW BEHAVIOR CHANGING IN -#2.4..... -import os -if os.name != "java": - import exceptions - if hasattr(exceptions, "FutureWarning"): - import warnings - warnings.filterwarnings("ignore", category=FutureWarning, append=1) -#----------------------- - - - shifts = [[[0, 0], [1, 3], [2, 2], [3, 1]], [[0, 0], [1, 5], [2, 4], [3, 3]], [[0, 0], [1, 7], [3, 5], [4, 4]]] @@ -63,14 +55,14 @@ A = [[1, 1, 1, 1, 1, 0, 0, 0], # produce log and alog tables, needed for multiplying in the # field GF(2^m) (generator = 3) alog = [1] -for i in xrange(255): +for i in range(255): j = (alog[-1] << 1) ^ alog[-1] if j & 0x100 != 0: j ^= 0x11B alog.append(j) log = [0] * 256 -for i in xrange(1, 255): +for i in range(1, 255): log[alog[i]] = i # multiply two elements of GF(2^m) @@ -80,29 +72,29 @@ def mul(a, b): return alog[(log[a & 0xFF] + log[b & 0xFF]) % 255] # substitution box based on F^{-1}(x) -box = [[0] * 8 for i in xrange(256)] +box = [[0] * 8 for i in range(256)] box[1][7] = 1 -for i in xrange(2, 256): +for i in range(2, 256): j = alog[255 - log[i]] - for t in xrange(8): + for t in range(8): box[i][t] = (j >> (7 - t)) & 0x01 B = [0, 1, 1, 0, 0, 0, 1, 1] # affine transform: box[i] <- B + A*box[i] -cox = [[0] * 8 for i in xrange(256)] -for i in xrange(256): - for t in xrange(8): +cox = [[0] * 8 for i in range(256)] +for i in range(256): + for t in range(8): cox[i][t] = B[t] - for j in xrange(8): + for j in range(8): cox[i][t] ^= A[t][j] * box[i][j] # S-boxes and inverse S-boxes S = [0] * 256 Si = [0] * 256 -for i in xrange(256): +for i in range(256): S[i] = cox[i][0] << 7 - for t in xrange(1, 8): + for t in range(1, 8): S[i] ^= cox[i][t] << (7-t) Si[S[i] & 0xFF] = i @@ -112,36 +104,36 @@ G = [[2, 1, 1, 3], [1, 3, 2, 1], [1, 1, 3, 2]] -AA = [[0] * 8 for i in xrange(4)] +AA = [[0] * 8 for i in range(4)] -for i in xrange(4): - for j in xrange(4): +for i in range(4): + for j in range(4): AA[i][j] = G[i][j] AA[i][i+4] = 1 -for i in xrange(4): +for i in range(4): pivot = AA[i][i] if pivot == 0: t = i + 1 while AA[t][i] == 0 and t < 4: t += 1 assert t != 4, 'G matrix must be invertible' - for j in xrange(8): + for j in range(8): AA[i][j], AA[t][j] = AA[t][j], AA[i][j] pivot = AA[i][i] - for j in xrange(8): + for j in range(8): if AA[i][j] != 0: AA[i][j] = alog[(255 + log[AA[i][j] & 0xFF] - log[pivot & 0xFF]) % 255] - for t in xrange(4): + for t in range(4): if i != t: - for j in xrange(i+1, 8): + for j in range(i+1, 8): AA[t][j] ^= mul(AA[i][j], AA[t][i]) AA[t][i] = 0 -iG = [[0] * 4 for i in xrange(4)] +iG = [[0] * 4 for i in range(4)] -for i in xrange(4): - for j in xrange(4): +for i in range(4): + for j in range(4): iG[i][j] = AA[i][j + 4] def mul4(a, bs): @@ -167,7 +159,7 @@ U2 = [] U3 = [] U4 = [] -for t in xrange(256): +for t in range(256): s = S[t] T1.append(mul4(s, G[0])) T2.append(mul4(s, G[1])) @@ -188,7 +180,7 @@ for t in xrange(256): # round constants rcon = [1] r = 1 -for t in xrange(1, 30): +for t in range(1, 30): r = mul(2, r) rcon.append(r) @@ -219,26 +211,26 @@ class rijndael: self.block_size = block_size ROUNDS = num_rounds[len(key)][block_size] - BC = block_size / 4 + BC = block_size // 4 # encryption round keys - Ke = [[0] * BC for i in xrange(ROUNDS + 1)] + Ke = [[0] * BC for i in range(ROUNDS + 1)] # decryption round keys - Kd = [[0] * BC for i in xrange(ROUNDS + 1)] + Kd = [[0] * BC for i in range(ROUNDS + 1)] ROUND_KEY_COUNT = (ROUNDS + 1) * BC - KC = len(key) / 4 + KC = len(key) // 4 # copy user material bytes into temporary ints tk = [] - for i in xrange(0, KC): - tk.append((ord(key[i * 4]) << 24) | (ord(key[i * 4 + 1]) << 16) | - (ord(key[i * 4 + 2]) << 8) | ord(key[i * 4 + 3])) + for i in range(0, KC): + tk.append((key[i * 4] << 24) | (key[i * 4 + 1] << 16) | + (key[i * 4 + 2] << 8) | key[i * 4 + 3]) # copy values into round key arrays t = 0 j = 0 while j < KC and t < ROUND_KEY_COUNT: - Ke[t / BC][t % BC] = tk[j] - Kd[ROUNDS - (t / BC)][t % BC] = tk[j] + Ke[t // BC][t % BC] = tk[j] + Kd[ROUNDS - (t // BC)][t % BC] = tk[j] j += 1 t += 1 tt = 0 @@ -253,28 +245,28 @@ class rijndael: (rcon[rconpointer] & 0xFF) << 24 rconpointer += 1 if KC != 8: - for i in xrange(1, KC): + for i in range(1, KC): tk[i] ^= tk[i-1] else: - for i in xrange(1, KC / 2): + for i in range(1, KC // 2): tk[i] ^= tk[i-1] - tt = tk[KC / 2 - 1] - tk[KC / 2] ^= (S[ tt & 0xFF] & 0xFF) ^ \ + tt = tk[KC // 2 - 1] + tk[KC // 2] ^= (S[ tt & 0xFF] & 0xFF) ^ \ (S[(tt >> 8) & 0xFF] & 0xFF) << 8 ^ \ (S[(tt >> 16) & 0xFF] & 0xFF) << 16 ^ \ (S[(tt >> 24) & 0xFF] & 0xFF) << 24 - for i in xrange(KC / 2 + 1, KC): + for i in range(KC // 2 + 1, KC): tk[i] ^= tk[i-1] # copy values into round key arrays j = 0 while j < KC and t < ROUND_KEY_COUNT: - Ke[t / BC][t % BC] = tk[j] - Kd[ROUNDS - (t / BC)][t % BC] = tk[j] + Ke[t // BC][t % BC] = tk[j] + Kd[ROUNDS - (t // BC)][t % BC] = tk[j] j += 1 t += 1 # inverse MixColumn where needed - for r in xrange(1, ROUNDS): - for j in xrange(BC): + for r in range(1, ROUNDS): + for j in range(BC): tt = Kd[r][j] Kd[r][j] = U1[(tt >> 24) & 0xFF] ^ \ U2[(tt >> 16) & 0xFF] ^ \ @@ -288,7 +280,7 @@ class rijndael: raise ValueError('wrong block length, expected ' + str(self.block_size) + ' got ' + str(len(plaintext))) Ke = self.Ke - BC = self.block_size / 4 + BC = self.block_size // 4 ROUNDS = len(Ke) - 1 if BC == 4: SC = 0 @@ -303,14 +295,14 @@ class rijndael: # temporary work array t = [] # plaintext to ints + key - for i in xrange(BC): - t.append((ord(plaintext[i * 4 ]) << 24 | - ord(plaintext[i * 4 + 1]) << 16 | - ord(plaintext[i * 4 + 2]) << 8 | - ord(plaintext[i * 4 + 3]) ) ^ Ke[0][i]) + for i in range(BC): + t.append((plaintext[i * 4 ] << 24 | + plaintext[i * 4 + 1] << 16 | + plaintext[i * 4 + 2] << 8 | + plaintext[i * 4 + 3] ) ^ Ke[0][i]) # apply round transforms - for r in xrange(1, ROUNDS): - for i in xrange(BC): + for r in range(1, ROUNDS): + for i in range(BC): a[i] = (T1[(t[ i ] >> 24) & 0xFF] ^ T2[(t[(i + s1) % BC] >> 16) & 0xFF] ^ T3[(t[(i + s2) % BC] >> 8) & 0xFF] ^ @@ -318,20 +310,20 @@ class rijndael: t = copy.copy(a) # last round is special result = [] - for i in xrange(BC): + for i in range(BC): tt = Ke[ROUNDS][i] result.append((S[(t[ i ] >> 24) & 0xFF] ^ (tt >> 24)) & 0xFF) result.append((S[(t[(i + s1) % BC] >> 16) & 0xFF] ^ (tt >> 16)) & 0xFF) result.append((S[(t[(i + s2) % BC] >> 8) & 0xFF] ^ (tt >> 8)) & 0xFF) result.append((S[ t[(i + s3) % BC] & 0xFF] ^ tt ) & 0xFF) - return string.join(map(chr, result), '') + return bytearray(result) def decrypt(self, ciphertext): if len(ciphertext) != self.block_size: raise ValueError('wrong block length, expected ' + str(self.block_size) + ' got ' + str(len(plaintext))) Kd = self.Kd - BC = self.block_size / 4 + BC = self.block_size // 4 ROUNDS = len(Kd) - 1 if BC == 4: SC = 0 @@ -346,14 +338,14 @@ class rijndael: # temporary work array t = [0] * BC # ciphertext to ints + key - for i in xrange(BC): - t[i] = (ord(ciphertext[i * 4 ]) << 24 | - ord(ciphertext[i * 4 + 1]) << 16 | - ord(ciphertext[i * 4 + 2]) << 8 | - ord(ciphertext[i * 4 + 3]) ) ^ Kd[0][i] + for i in range(BC): + t[i] = (ciphertext[i * 4 ] << 24 | + ciphertext[i * 4 + 1] << 16 | + ciphertext[i * 4 + 2] << 8 | + ciphertext[i * 4 + 3] ) ^ Kd[0][i] # apply round transforms - for r in xrange(1, ROUNDS): - for i in xrange(BC): + for r in range(1, ROUNDS): + for i in range(BC): a[i] = (T5[(t[ i ] >> 24) & 0xFF] ^ T6[(t[(i + s1) % BC] >> 16) & 0xFF] ^ T7[(t[(i + s2) % BC] >> 8) & 0xFF] ^ @@ -361,13 +353,13 @@ class rijndael: t = copy.copy(a) # last round is special result = [] - for i in xrange(BC): + for i in range(BC): tt = Kd[ROUNDS][i] result.append((Si[(t[ i ] >> 24) & 0xFF] ^ (tt >> 24)) & 0xFF) result.append((Si[(t[(i + s1) % BC] >> 16) & 0xFF] ^ (tt >> 16)) & 0xFF) result.append((Si[(t[(i + s2) % BC] >> 8) & 0xFF] ^ (tt >> 8)) & 0xFF) result.append((Si[ t[(i + s3) % BC] & 0xFF] ^ tt ) & 0xFF) - return string.join(map(chr, result), '') + return bytearray(result) def encrypt(key, block): return rijndael(key, len(block)).encrypt(block) diff --git a/chromium/third_party/tlslite/tlslite/utils/RSAKey.py b/chromium/third_party/tlslite/tlslite/utils/rsakey.py index 37c292df5dc..3f2100ebc0d 100644 --- a/chromium/third_party/tlslite/tlslite/utils/RSAKey.py +++ b/chromium/third_party/tlslite/tlslite/utils/rsakey.py @@ -1,15 +1,18 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + """Abstract class for RSA.""" -from cryptomath import * +from .cryptomath import * -class RSAKey: +class RSAKey(object): """This is an abstract base class for RSA keys. Particular implementations of RSA keys, such as - L{OpenSSL_RSAKey.OpenSSL_RSAKey}, - L{Python_RSAKey.Python_RSAKey}, and - L{PyCrypto_RSAKey.PyCrypto_RSAKey}, + L{openssl_rsakey.OpenSSL_RSAKey}, + L{python_rsakey.Python_RSAKey}, and + L{pycrypto_rsakey.PyCrypto_RSAKey}, inherit from this. To create or parse an RSA key, don't use one of these classes @@ -44,36 +47,19 @@ class RSAKey: """ raise NotImplementedError() - def hash(self): - """Return the cryptoID <keyHash> value corresponding to this - key. - - @rtype: str - """ - raise NotImplementedError() - - def getSigningAlgorithm(self): - """Return the cryptoID sigAlgo value corresponding to this key. - - @rtype: str - """ - return "pkcs1-sha1" - def hashAndSign(self, bytes): """Hash and sign the passed-in bytes. This requires the key to have a private component. It performs a PKCS1-SHA1 signature on the passed-in data. - @type bytes: str or L{array.array} of unsigned bytes + @type bytes: str or L{bytearray} of unsigned bytes @param bytes: The value which will be hashed and signed. - @rtype: L{array.array} of unsigned bytes. + @rtype: L{bytearray} of unsigned bytes. @return: A PKCS1-SHA1 signature on the passed-in data. """ - if not isinstance(bytes, type("")): - bytes = bytesToString(bytes) - hashBytes = stringToBytes(sha.sha(bytes).digest()) + hashBytes = SHA1(bytearray(bytes)) prefixedHashBytes = self._addPKCS1SHA1Prefix(hashBytes) sigBytes = self.sign(prefixedHashBytes) return sigBytes @@ -83,20 +69,23 @@ class RSAKey: This verifies a PKCS1-SHA1 signature on the passed-in data. - @type sigBytes: L{array.array} of unsigned bytes + @type sigBytes: L{bytearray} of unsigned bytes @param sigBytes: A PKCS1-SHA1 signature. - @type bytes: str or L{array.array} of unsigned bytes + @type bytes: str or L{bytearray} of unsigned bytes @param bytes: The value which will be hashed and verified. @rtype: bool @return: Whether the signature matches the passed-in data. """ - if not isinstance(bytes, type("")): - bytes = bytesToString(bytes) - hashBytes = stringToBytes(sha.sha(bytes).digest()) - prefixedHashBytes = self._addPKCS1SHA1Prefix(hashBytes) - return self.verify(sigBytes, prefixedHashBytes) + hashBytes = SHA1(bytearray(bytes)) + + # Try it with/without the embedded NULL + prefixedHashBytes1 = self._addPKCS1SHA1Prefix(hashBytes, False) + prefixedHashBytes2 = self._addPKCS1SHA1Prefix(hashBytes, True) + result1 = self.verify(sigBytes, prefixedHashBytes1) + result2 = self.verify(sigBytes, prefixedHashBytes2) + return (result1 or result2) def sign(self, bytes): """Sign the passed-in bytes. @@ -104,10 +93,10 @@ class RSAKey: This requires the key to have a private component. It performs a PKCS1 signature on the passed-in data. - @type bytes: L{array.array} of unsigned bytes + @type bytes: L{bytearray} of unsigned bytes @param bytes: The value which will be signed. - @rtype: L{array.array} of unsigned bytes. + @rtype: L{bytearray} of unsigned bytes. @return: A PKCS1 signature on the passed-in data. """ if not self.hasPrivateKey(): @@ -117,7 +106,7 @@ class RSAKey: if m >= self.n: raise ValueError() c = self._rawPrivateKeyOp(m) - sigBytes = numberToBytes(c) + sigBytes = numberToByteArray(c, numBytes(self.n)) return sigBytes def verify(self, sigBytes, bytes): @@ -125,21 +114,23 @@ class RSAKey: This verifies a PKCS1 signature on the passed-in data. - @type sigBytes: L{array.array} of unsigned bytes + @type sigBytes: L{bytearray} of unsigned bytes @param sigBytes: A PKCS1 signature. - @type bytes: L{array.array} of unsigned bytes + @type bytes: L{bytearray} of unsigned bytes @param bytes: The value which will be verified. @rtype: bool @return: Whether the signature matches the passed-in data. """ + if len(sigBytes) != numBytes(self.n): + return False paddedBytes = self._addPKCS1Padding(bytes, 1) c = bytesToNumber(sigBytes) if c >= self.n: return False m = self._rawPublicKeyOp(c) - checkBytes = numberToBytes(m) + checkBytes = numberToByteArray(m, numBytes(self.n)) return checkBytes == paddedBytes def encrypt(self, bytes): @@ -147,10 +138,10 @@ class RSAKey: This performs PKCS1 encryption of the passed-in data. - @type bytes: L{array.array} of unsigned bytes + @type bytes: L{bytearray} of unsigned bytes @param bytes: The value which will be encrypted. - @rtype: L{array.array} of unsigned bytes. + @rtype: L{bytearray} of unsigned bytes. @return: A PKCS1 encryption of the passed-in data. """ paddedBytes = self._addPKCS1Padding(bytes, 2) @@ -158,7 +149,7 @@ class RSAKey: if m >= self.n: raise ValueError() c = self._rawPublicKeyOp(m) - encBytes = numberToBytes(c) + encBytes = numberToByteArray(c, numBytes(self.n)) return encBytes def decrypt(self, encBytes): @@ -167,25 +158,27 @@ class RSAKey: This requires the key to have a private component. It performs PKCS1 decryption of the passed-in data. - @type encBytes: L{array.array} of unsigned bytes + @type encBytes: L{bytearray} of unsigned bytes @param encBytes: The value which will be decrypted. - @rtype: L{array.array} of unsigned bytes or None. + @rtype: L{bytearray} of unsigned bytes or None. @return: A PKCS1 decryption of the passed-in data or None if the data is not properly formatted. """ if not self.hasPrivateKey(): raise AssertionError() + if len(encBytes) != numBytes(self.n): + return None c = bytesToNumber(encBytes) if c >= self.n: return None m = self._rawPrivateKeyOp(c) - decBytes = numberToBytes(m) - if (len(decBytes) != numBytes(self.n)-1): #Check first byte + decBytes = numberToByteArray(m, numBytes(self.n)) + #Check first two bytes + if decBytes[0] != 0 or decBytes[1] != 2: return None - if decBytes[0] != 2: #Check second byte - return None - for x in range(len(decBytes)-1): #Scan through for zero separator + #Scan through for zero separator + for x in range(1, len(decBytes)-1): if decBytes[x]== 0: break else: @@ -210,19 +203,11 @@ class RSAKey: """Return a string containing the key. @rtype: str - @return: A string describing the key, in whichever format (PEM - or XML) is native to the implementation. + @return: A string describing the key, in whichever format (PEM) + is native to the implementation. """ raise NotImplementedError() - def writeXMLPublicKey(self, indent=''): - """Return a string containing the key. - - @rtype: str - @return: A string describing the public key, in XML format. - """ - return Python_RSAKey(self.n, self.e).write(indent) - def generate(bits): """Generate a new key with the specified bit length. @@ -236,9 +221,22 @@ class RSAKey: # Helper Functions for RSA Keys # ************************************************************************** - def _addPKCS1SHA1Prefix(self, bytes): - prefixBytes = createByteArraySequence(\ - [48,33,48,9,6,5,43,14,3,2,26,5,0,4,20]) + def _addPKCS1SHA1Prefix(self, bytes, withNULL=True): + # There is a long history of confusion over whether the SHA1 + # algorithmIdentifier should be encoded with a NULL parameter or + # with the parameter omitted. While the original intention was + # apparently to omit it, many toolkits went the other way. TLS 1.2 + # specifies the NULL should be included, and this behavior is also + # mandated in recent versions of PKCS #1, and is what tlslite has + # always implemented. Anyways, verification code should probably + # accept both. However, nothing uses this code yet, so this is + # all fairly moot. + if not withNULL: + prefixBytes = bytearray(\ + [0x30,0x1f,0x30,0x07,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x04,0x14]) + else: + prefixBytes = bytearray(\ + [0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x05,0x00,0x04,0x14]) prefixedBytes = prefixBytes + bytes return prefixedBytes @@ -247,7 +245,7 @@ class RSAKey: if blockType == 1: #Signature padding pad = [0xFF] * padLength elif blockType == 2: #Encryption padding - pad = createByteArraySequence([]) + pad = bytearray(0) while len(pad) < padLength: padBytes = getRandomBytes(padLength * 2) pad = [b for b in padBytes if b != 0] @@ -255,10 +253,6 @@ class RSAKey: else: raise AssertionError() - #NOTE: To be proper, we should add [0,blockType]. However, - #the zero is lost when the returned padding is converted - #to a number, so we don't even bother with it. Also, - #adding it would cause a misalignment in verify() - padding = createByteArraySequence([blockType] + pad + [0]) + padding = bytearray([0,blockType] + pad + [0]) paddedBytes = padding + bytes return paddedBytes diff --git a/chromium/third_party/tlslite/tlslite/utils/tackwrapper.py b/chromium/third_party/tlslite/tlslite/utils/tackwrapper.py new file mode 100644 index 00000000000..4eb39efe497 --- /dev/null +++ b/chromium/third_party/tlslite/tlslite/utils/tackwrapper.py @@ -0,0 +1,11 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + +try: + from tack.structures.Tack import Tack + from tack.structures.TackExtension import TackExtension + from tack.tls.TlsCertificate import TlsCertificate + + tackpyLoaded = True +except ImportError: + tackpyLoaded = False diff --git a/chromium/third_party/tlslite/tlslite/utils/TripleDES.py b/chromium/third_party/tlslite/tlslite/utils/tripledes.py index 2db45888bde..0b4d07592f8 100644 --- a/chromium/third_party/tlslite/tlslite/utils/TripleDES.py +++ b/chromium/third_party/tlslite/tlslite/utils/tripledes.py @@ -1,8 +1,9 @@ -"""Abstract class for 3DES.""" +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. -from compat import * #For True +"""Abstract class for 3DES.""" -class TripleDES: +class TripleDES(object): def __init__(self, key, mode, IV, implementation): if len(key) != 24: raise ValueError() diff --git a/chromium/third_party/tlslite/tlslite/utils/win32prng.c b/chromium/third_party/tlslite/tlslite/utils/win32prng.c deleted file mode 100644 index de08b3b3b90..00000000000 --- a/chromium/third_party/tlslite/tlslite/utils/win32prng.c +++ /dev/null @@ -1,63 +0,0 @@ - -#include "Python.h" -#define _WIN32_WINNT 0x0400 /* Needed for CryptoAPI on some systems */ -#include <windows.h> - - -static PyObject* getRandomBytes(PyObject *self, PyObject *args) -{ - int howMany; - HCRYPTPROV hCryptProv; - unsigned char* bytes = NULL; - PyObject* returnVal = NULL; - - - /* Read Arguments */ - if (!PyArg_ParseTuple(args, "i", &howMany)) - return(NULL); - - /* Get Context */ - if(CryptAcquireContext( - &hCryptProv, - NULL, - NULL, - PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT) == 0) - return Py_BuildValue("s#", NULL, 0); - - - /* Allocate bytes */ - bytes = malloc(howMany); - - - /* Get random data */ - if(CryptGenRandom( - hCryptProv, - howMany, - bytes) == 0) - returnVal = Py_BuildValue("s#", NULL, 0); - else - returnVal = Py_BuildValue("s#", bytes, howMany); - - free(bytes); - CryptReleaseContext(hCryptProv, 0); - - return returnVal; -} - - - -/* List of functions exported by this module */ - -static struct PyMethodDef win32prng_functions[] = { - {"getRandomBytes", (PyCFunction)getRandomBytes, METH_VARARGS}, - {NULL, NULL} /* Sentinel */ -}; - - -/* Initialize this module. */ - -DL_EXPORT(void) initwin32prng(void) -{ - Py_InitModule("win32prng", win32prng_functions); -} diff --git a/chromium/third_party/tlslite/tlslite/utils/xmltools.py b/chromium/third_party/tlslite/tlslite/utils/xmltools.py deleted file mode 100644 index 06f2e43071c..00000000000 --- a/chromium/third_party/tlslite/tlslite/utils/xmltools.py +++ /dev/null @@ -1,201 +0,0 @@ -"""Helper functions for XML. - -This module has misc. helper functions for working with XML DOM nodes.""" - -import re -from compat import * - -import os -if os.name != "java": - from xml.dom import minidom - from xml.sax import saxutils - - def parseDocument(s): - return minidom.parseString(s) -else: - from javax.xml.parsers import * - import java - - builder = DocumentBuilderFactory.newInstance().newDocumentBuilder() - - def parseDocument(s): - stream = java.io.ByteArrayInputStream(java.lang.String(s).getBytes()) - return builder.parse(stream) - -def parseAndStripWhitespace(s): - try: - element = parseDocument(s).documentElement - except BaseException, e: - raise SyntaxError(str(e)) - stripWhitespace(element) - return element - -#Goes through a DOM tree and removes whitespace besides child elements, -#as long as this whitespace is correctly tab-ified -def stripWhitespace(element, tab=0): - element.normalize() - - lastSpacer = "\n" + ("\t"*tab) - spacer = lastSpacer + "\t" - - #Zero children aren't allowed (i.e. <empty/>) - #This makes writing output simpler, and matches Canonical XML - if element.childNodes.length==0: #DON'T DO len(element.childNodes) - doesn't work in Jython - raise SyntaxError("Empty XML elements not allowed") - - #If there's a single child, it must be text context - if element.childNodes.length==1: - if element.firstChild.nodeType == element.firstChild.TEXT_NODE: - #If it's an empty element, remove - if element.firstChild.data == lastSpacer: - element.removeChild(element.firstChild) - return - #If not text content, give an error - elif element.firstChild.nodeType == element.firstChild.ELEMENT_NODE: - raise SyntaxError("Bad whitespace under '%s'" % element.tagName) - else: - raise SyntaxError("Unexpected node type in XML document") - - #Otherwise there's multiple child element - child = element.firstChild - while child: - if child.nodeType == child.ELEMENT_NODE: - stripWhitespace(child, tab+1) - child = child.nextSibling - elif child.nodeType == child.TEXT_NODE: - if child == element.lastChild: - if child.data != lastSpacer: - raise SyntaxError("Bad whitespace under '%s'" % element.tagName) - elif child.data != spacer: - raise SyntaxError("Bad whitespace under '%s'" % element.tagName) - next = child.nextSibling - element.removeChild(child) - child = next - else: - raise SyntaxError("Unexpected node type in XML document") - - -def checkName(element, name): - if element.nodeType != element.ELEMENT_NODE: - raise SyntaxError("Missing element: '%s'" % name) - - if name == None: - return - - if element.tagName != name: - raise SyntaxError("Wrong element name: should be '%s', is '%s'" % (name, element.tagName)) - -def getChild(element, index, name=None): - if element.nodeType != element.ELEMENT_NODE: - raise SyntaxError("Wrong node type in getChild()") - - child = element.childNodes.item(index) - if child == None: - raise SyntaxError("Missing child: '%s'" % name) - checkName(child, name) - return child - -def getChildIter(element, index): - class ChildIter: - def __init__(self, element, index): - self.element = element - self.index = index - - def next(self): - if self.index < len(self.element.childNodes): - retVal = self.element.childNodes.item(self.index) - self.index += 1 - else: - retVal = None - return retVal - - def checkEnd(self): - if self.index != len(self.element.childNodes): - raise SyntaxError("Too many elements under: '%s'" % self.element.tagName) - return ChildIter(element, index) - -def getChildOrNone(element, index): - if element.nodeType != element.ELEMENT_NODE: - raise SyntaxError("Wrong node type in getChild()") - child = element.childNodes.item(index) - return child - -def getLastChild(element, index, name=None): - if element.nodeType != element.ELEMENT_NODE: - raise SyntaxError("Wrong node type in getLastChild()") - - child = element.childNodes.item(index) - if child == None: - raise SyntaxError("Missing child: '%s'" % name) - if child != element.lastChild: - raise SyntaxError("Too many elements under: '%s'" % element.tagName) - checkName(child, name) - return child - -#Regular expressions for syntax-checking attribute and element content -nsRegEx = "http://trevp.net/cryptoID\Z" -cryptoIDRegEx = "([a-km-z3-9]{5}\.){3}[a-km-z3-9]{5}\Z" -urlRegEx = "http(s)?://.{1,100}\Z" -sha1Base64RegEx = "[A-Za-z0-9+/]{27}=\Z" -base64RegEx = "[A-Za-z0-9+/]+={0,4}\Z" -certsListRegEx = "(0)?(1)?(2)?(3)?(4)?(5)?(6)?(7)?(8)?(9)?\Z" -keyRegEx = "[A-Z]\Z" -keysListRegEx = "(A)?(B)?(C)?(D)?(E)?(F)?(G)?(H)?(I)?(J)?(K)?(L)?(M)?(N)?(O)?(P)?(Q)?(R)?(S)?(T)?(U)?(V)?(W)?(X)?(Y)?(Z)?\Z" -dateTimeRegEx = "\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\dZ\Z" -shortStringRegEx = ".{1,100}\Z" -exprRegEx = "[a-zA-Z0-9 ,()]{1,200}\Z" -notAfterDeltaRegEx = "0|([1-9][0-9]{0,8})\Z" #A number from 0 to (1 billion)-1 -booleanRegEx = "(true)|(false)" - -def getReqAttribute(element, attrName, regEx=""): - if element.nodeType != element.ELEMENT_NODE: - raise SyntaxError("Wrong node type in getReqAttribute()") - - value = element.getAttribute(attrName) - if not value: - raise SyntaxError("Missing Attribute: " + attrName) - if not re.match(regEx, value): - raise SyntaxError("Bad Attribute Value for '%s': '%s' " % (attrName, value)) - element.removeAttribute(attrName) - return str(value) #de-unicode it; this is needed for bsddb, for example - -def getAttribute(element, attrName, regEx=""): - if element.nodeType != element.ELEMENT_NODE: - raise SyntaxError("Wrong node type in getAttribute()") - - value = element.getAttribute(attrName) - if value: - if not re.match(regEx, value): - raise SyntaxError("Bad Attribute Value for '%s': '%s' " % (attrName, value)) - element.removeAttribute(attrName) - return str(value) #de-unicode it; this is needed for bsddb, for example - -def checkNoMoreAttributes(element): - if element.nodeType != element.ELEMENT_NODE: - raise SyntaxError("Wrong node type in checkNoMoreAttributes()") - - if element.attributes.length!=0: - raise SyntaxError("Extra attributes on '%s'" % element.tagName) - -def getText(element, regEx=""): - textNode = element.firstChild - if textNode == None: - raise SyntaxError("Empty element '%s'" % element.tagName) - if textNode.nodeType != textNode.TEXT_NODE: - raise SyntaxError("Non-text node: '%s'" % element.tagName) - if not re.match(regEx, textNode.data): - raise SyntaxError("Bad Text Value for '%s': '%s' " % (element.tagName, textNode.data)) - return str(textNode.data) #de-unicode it; this is needed for bsddb, for example - -#Function for adding tabs to a string -def indent(s, steps, ch="\t"): - tabs = ch*steps - if s[-1] != "\n": - s = tabs + s.replace("\n", "\n"+tabs) - else: - s = tabs + s.replace("\n", "\n"+tabs) - s = s[ : -len(tabs)] - return s - -def escape(s): - return saxutils.escape(s) diff --git a/chromium/third_party/tlslite/tlslite/VerifierDB.py b/chromium/third_party/tlslite/tlslite/verifierdb.py index f706b179672..43845415518 100644 --- a/chromium/third_party/tlslite/tlslite/VerifierDB.py +++ b/chromium/third_party/tlslite/tlslite/verifierdb.py @@ -1,9 +1,12 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + """Class for storing SRP password verifiers.""" -from utils.cryptomath import * -from utils.compat import * -import mathtls -from BaseDB import BaseDB +from .utils.cryptomath import * +from .utils.compat import * +from tlslite import mathtls +from .basedb import BaseDB class VerifierDB(BaseDB): """This class represent an in-memory or on-disk database of SRP @@ -27,10 +30,10 @@ class VerifierDB(BaseDB): def _getItem(self, username, valueStr): (N, g, salt, verifier) = valueStr.split(" ") - N = base64ToNumber(N) - g = base64ToNumber(g) - salt = base64ToString(salt) - verifier = base64ToNumber(verifier) + N = bytesToNumber(a2b_base64(N)) + g = bytesToNumber(a2b_base64(g)) + salt = a2b_base64(salt) + verifier = bytesToNumber(a2b_base64(verifier)) return (N, g, salt, verifier) def __setitem__(self, username, verifierEntry): @@ -43,7 +46,7 @@ class VerifierDB(BaseDB): @type verifierEntry: tuple @param verifierEntry: The verifier entry to add. Use - L{tlslite.VerifierDB.VerifierDB.makeVerifier} to create a + L{tlslite.verifierdb.VerifierDB.makeVerifier} to create a verifier entry. """ BaseDB.__setitem__(self, username, verifierEntry) @@ -53,10 +56,10 @@ class VerifierDB(BaseDB): if len(username)>=256: raise ValueError("username too long") N, g, salt, verifier = value - N = numberToBase64(N) - g = numberToBase64(g) - salt = stringToBase64(salt) - verifier = numberToBase64(verifier) + N = b2a_base64(numberToByteArray(N)) + g = b2a_base64(numberToByteArray(g)) + salt = b2a_base64(salt) + verifier = b2a_base64(numberToByteArray(verifier)) valueStr = " ".join( (N, g, salt, verifier) ) return valueStr @@ -86,5 +89,7 @@ class VerifierDB(BaseDB): @rtype: tuple @return: A tuple which may be stored in a VerifierDB. """ - return mathtls.makeVerifier(username, password, bits) - makeVerifier = staticmethod(makeVerifier)
\ No newline at end of file + usernameBytes = bytearray(username, "utf-8") + passwordBytes = bytearray(password, "utf-8") + return mathtls.makeVerifier(usernameBytes, passwordBytes, bits) + makeVerifier = staticmethod(makeVerifier) diff --git a/chromium/third_party/tlslite/tlslite/X509.py b/chromium/third_party/tlslite/tlslite/x509.py index a32d879a3a7..94dd00d8dbf 100644 --- a/chromium/third_party/tlslite/tlslite/X509.py +++ b/chromium/third_party/tlslite/tlslite/x509.py @@ -1,25 +1,32 @@ +# Authors: +# Trevor Perrin +# Google - parsing subject field +# +# See the LICENSE file for legal information regarding use of this file. + """Class representing an X.509 certificate.""" -from utils.ASN1Parser import ASN1Parser -from utils.cryptomath import * -from utils.keyfactory import _createPublicRSAKey +from .utils.asn1parser import ASN1Parser +from .utils.cryptomath import * +from .utils.keyfactory import _createPublicRSAKey +from .utils.pem import * -class X509: +class X509(object): """This class represents an X.509 certificate. - @type bytes: L{array.array} of unsigned bytes + @type bytes: L{bytearray} of unsigned bytes @ivar bytes: The DER-encoded ASN.1 certificate - @type publicKey: L{tlslite.utils.RSAKey.RSAKey} + @type publicKey: L{tlslite.utils.rsakey.RSAKey} @ivar publicKey: The subject public key from the certificate. - @type subject: L{array.array} of unsigned bytes + @type subject: L{bytearray} of unsigned bytes @ivar subject: The DER-encoded ASN.1 subject distinguished name. """ def __init__(self): - self.bytes = createByteArraySequence([]) + self.bytes = bytearray(0) self.publicKey = None self.subject = None @@ -32,29 +39,18 @@ class X509: "-----END CERTIFICATE-----" tags). """ - start = s.find("-----BEGIN CERTIFICATE-----") - end = s.find("-----END CERTIFICATE-----") - if start == -1: - raise SyntaxError("Missing PEM prefix") - if end == -1: - raise SyntaxError("Missing PEM postfix") - s = s[start+len("-----BEGIN CERTIFICATE-----") : end] - - bytes = base64ToBytes(s) + bytes = dePem(s, "CERTIFICATE") self.parseBinary(bytes) return self def parseBinary(self, bytes): """Parse a DER-encoded X.509 certificate. - @type bytes: str or L{array.array} of unsigned bytes + @type bytes: str or L{bytearray} of unsigned bytes @param bytes: A DER-encoded X.509 certificate. """ - if isinstance(bytes, type("")): - bytes = stringToBytes(bytes) - - self.bytes = bytes + self.bytes = bytearray(bytes) p = ASN1Parser(bytes) #Get the tbsCertificate @@ -99,7 +95,6 @@ class X509: #Create a public key instance self.publicKey = _createPublicRSAKey(n, e) - return self def getFingerprint(self): """Get the hex-encoded fingerprint of this certificate. @@ -107,34 +102,7 @@ class X509: @rtype: str @return: A hex-encoded fingerprint. """ - return sha.sha(self.bytes).hexdigest() - - def getCommonName(self): - """Get the Subject's Common Name from the certificate. - - The cryptlib_py module must be installed in order to use this - function. - - @rtype: str or None - @return: The CN component of the certificate's subject DN, if - present. - """ - import cryptlib_py - import array - c = cryptlib_py.cryptImportCert(self.bytes, cryptlib_py.CRYPT_UNUSED) - name = cryptlib_py.CRYPT_CERTINFO_COMMONNAME - try: - try: - length = cryptlib_py.cryptGetAttributeString(c, name, None) - returnVal = array.array('B', [0] * length) - cryptlib_py.cryptGetAttributeString(c, name, returnVal) - returnVal = returnVal.tostring() - except cryptlib_py.CryptException, e: - if e[0] == cryptlib_py.CRYPT_ERROR_NOTFOUND: - returnVal = None - return returnVal - finally: - cryptlib_py.cryptDestroyCert(c) + return b2a_hex(SHA1(self.bytes)) def writeBytes(self): return self.bytes diff --git a/chromium/third_party/tlslite/tlslite/x509certchain.py b/chromium/third_party/tlslite/tlslite/x509certchain.py new file mode 100644 index 00000000000..2a592b6d863 --- /dev/null +++ b/chromium/third_party/tlslite/tlslite/x509certchain.py @@ -0,0 +1,91 @@ +# Author: Trevor Perrin +# See the LICENSE file for legal information regarding use of this file. + +"""Class representing an X.509 certificate chain.""" + +from .utils import cryptomath +from .utils.tackwrapper import * +from .utils.pem import * +from .x509 import X509 + +class X509CertChain(object): + """This class represents a chain of X.509 certificates. + + @type x509List: list + @ivar x509List: A list of L{tlslite.x509.X509} instances, + starting with the end-entity certificate and with every + subsequent certificate certifying the previous. + """ + + def __init__(self, x509List=None): + """Create a new X509CertChain. + + @type x509List: list + @param x509List: A list of L{tlslite.x509.X509} instances, + starting with the end-entity certificate and with every + subsequent certificate certifying the previous. + """ + if x509List: + self.x509List = x509List + else: + self.x509List = [] + + def parsePemList(self, s): + """Parse a string containing a sequence of PEM certs. + + Raise a SyntaxError if input is malformed. + """ + x509List = [] + bList = dePemList(s, "CERTIFICATE") + for b in bList: + x509 = X509() + x509.parseBinary(b) + x509List.append(x509) + self.x509List = x509List + + def getNumCerts(self): + """Get the number of certificates in this chain. + + @rtype: int + """ + return len(self.x509List) + + def getEndEntityPublicKey(self): + """Get the public key from the end-entity certificate. + + @rtype: L{tlslite.utils.rsakey.RSAKey} + """ + if self.getNumCerts() == 0: + raise AssertionError() + return self.x509List[0].publicKey + + def getFingerprint(self): + """Get the hex-encoded fingerprint of the end-entity certificate. + + @rtype: str + @return: A hex-encoded fingerprint. + """ + if self.getNumCerts() == 0: + raise AssertionError() + return self.x509List[0].getFingerprint() + + def checkTack(self, tack): + if self.x509List: + tlsCert = TlsCertificate(self.x509List[0].bytes) + if tlsCert.matches(tack): + return True + return False + + def getTackExt(self): + """Get the TACK and/or Break Sigs from a TACK Cert in the chain.""" + tackExt = None + # Search list in backwards order + for x509 in self.x509List[::-1]: + tlsCert = TlsCertificate(x509.bytes) + if tlsCert.tackExt: + if tackExt: + raise SyntaxError("Multiple TACK Extensions") + else: + tackExt = tlsCert.tackExt + return tackExt + |