From 7ab7e5310d0fe31cd2a6eaaa770196b20a5dee3a Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Fri, 30 Jan 2015 00:35:34 -0500 Subject: [PATCH 1/4] Fix executable bits on files. From Chromium. --- README | 0 tests/index.html | 0 tests/verifierDB | Bin tlslite/__init__.py | 0 tlslite/basedb.py | 0 tlslite/checker.py | 0 tlslite/constants.py | 0 tlslite/errors.py | 0 tlslite/handshakesettings.py | 0 tlslite/integration/__init__.py | 0 tlslite/integration/asyncstatemachine.py | 0 tlslite/integration/clienthelper.py | 0 tlslite/integration/httptlsconnection.py | 0 tlslite/integration/imap4_tls.py | 0 tlslite/integration/pop3_tls.py | 0 tlslite/integration/smtp_tls.py | 0 tlslite/integration/tlsasyncdispatchermixin.py | 0 tlslite/integration/tlssocketservermixin.py | 0 tlslite/integration/xmlrpctransport.py | 0 tlslite/mathtls.py | 0 tlslite/messages.py | 0 tlslite/session.py | 0 tlslite/sessioncache.py | 0 tlslite/tlsconnection.py | 0 tlslite/tlsrecordlayer.py | 0 tlslite/utils/__init__.py | 0 tlslite/utils/aes.py | 0 tlslite/utils/asn1parser.py | 0 tlslite/utils/cipherfactory.py | 0 tlslite/utils/codec.py | 0 tlslite/utils/compat.py | 0 tlslite/utils/cryptomath.py | 0 tlslite/utils/datefuncs.py | 0 tlslite/utils/keyfactory.py | 0 tlslite/utils/openssl_aes.py | 0 tlslite/utils/openssl_rc4.py | 0 tlslite/utils/openssl_rsakey.py | 0 tlslite/utils/openssl_tripledes.py | 0 tlslite/utils/pycrypto_aes.py | 0 tlslite/utils/pycrypto_rc4.py | 0 tlslite/utils/pycrypto_rsakey.py | 0 tlslite/utils/pycrypto_tripledes.py | 0 tlslite/utils/python_aes.py | 0 tlslite/utils/python_rc4.py | 0 tlslite/utils/python_rsakey.py | 0 tlslite/utils/rc4.py | 0 tlslite/utils/rijndael.py | 0 tlslite/utils/rsakey.py | 0 tlslite/utils/tripledes.py | 0 tlslite/verifierdb.py | 0 tlslite/x509.py | 0 tlslite/x509certchain.py | 0 52 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 README mode change 100755 => 100644 tests/index.html mode change 100755 => 100644 tests/verifierDB mode change 100755 => 100644 tlslite/__init__.py mode change 100755 => 100644 tlslite/basedb.py mode change 100755 => 100644 tlslite/checker.py mode change 100755 => 100644 tlslite/constants.py mode change 100755 => 100644 tlslite/errors.py mode change 100755 => 100644 tlslite/handshakesettings.py mode change 100755 => 100644 tlslite/integration/__init__.py mode change 100755 => 100644 tlslite/integration/asyncstatemachine.py mode change 100755 => 100644 tlslite/integration/clienthelper.py mode change 100755 => 100644 tlslite/integration/httptlsconnection.py mode change 100755 => 100644 tlslite/integration/imap4_tls.py mode change 100755 => 100644 tlslite/integration/pop3_tls.py mode change 100755 => 100644 tlslite/integration/smtp_tls.py mode change 100755 => 100644 tlslite/integration/tlsasyncdispatchermixin.py mode change 100755 => 100644 tlslite/integration/tlssocketservermixin.py mode change 100755 => 100644 tlslite/integration/xmlrpctransport.py mode change 100755 => 100644 tlslite/mathtls.py mode change 100755 => 100644 tlslite/messages.py mode change 100755 => 100644 tlslite/session.py mode change 100755 => 100644 tlslite/sessioncache.py mode change 100755 => 100644 tlslite/tlsconnection.py mode change 100755 => 100644 tlslite/tlsrecordlayer.py mode change 100755 => 100644 tlslite/utils/__init__.py mode change 100755 => 100644 tlslite/utils/aes.py mode change 100755 => 100644 tlslite/utils/asn1parser.py mode change 100755 => 100644 tlslite/utils/cipherfactory.py mode change 100755 => 100644 tlslite/utils/codec.py mode change 100755 => 100644 tlslite/utils/compat.py mode change 100755 => 100644 tlslite/utils/cryptomath.py mode change 100755 => 100644 tlslite/utils/datefuncs.py mode change 100755 => 100644 tlslite/utils/keyfactory.py mode change 100755 => 100644 tlslite/utils/openssl_aes.py mode change 100755 => 100644 tlslite/utils/openssl_rc4.py mode change 100755 => 100644 tlslite/utils/openssl_rsakey.py mode change 100755 => 100644 tlslite/utils/openssl_tripledes.py mode change 100755 => 100644 tlslite/utils/pycrypto_aes.py mode change 100755 => 100644 tlslite/utils/pycrypto_rc4.py mode change 100755 => 100644 tlslite/utils/pycrypto_rsakey.py mode change 100755 => 100644 tlslite/utils/pycrypto_tripledes.py mode change 100755 => 100644 tlslite/utils/python_aes.py mode change 100755 => 100644 tlslite/utils/python_rc4.py mode change 100755 => 100644 tlslite/utils/python_rsakey.py mode change 100755 => 100644 tlslite/utils/rc4.py mode change 100755 => 100644 tlslite/utils/rijndael.py mode change 100755 => 100644 tlslite/utils/rsakey.py mode change 100755 => 100644 tlslite/utils/tripledes.py mode change 100755 => 100644 tlslite/verifierdb.py mode change 100755 => 100644 tlslite/x509.py mode change 100755 => 100644 tlslite/x509certchain.py diff --git a/README b/README old mode 100755 new mode 100644 diff --git a/tests/index.html b/tests/index.html old mode 100755 new mode 100644 diff --git a/tests/verifierDB b/tests/verifierDB old mode 100755 new mode 100644 diff --git a/tlslite/__init__.py b/tlslite/__init__.py old mode 100755 new mode 100644 diff --git a/tlslite/basedb.py b/tlslite/basedb.py old mode 100755 new mode 100644 diff --git a/tlslite/checker.py b/tlslite/checker.py old mode 100755 new mode 100644 diff --git a/tlslite/constants.py b/tlslite/constants.py old mode 100755 new mode 100644 diff --git a/tlslite/errors.py b/tlslite/errors.py old mode 100755 new mode 100644 diff --git a/tlslite/handshakesettings.py b/tlslite/handshakesettings.py old mode 100755 new mode 100644 diff --git a/tlslite/integration/__init__.py b/tlslite/integration/__init__.py old mode 100755 new mode 100644 diff --git a/tlslite/integration/asyncstatemachine.py b/tlslite/integration/asyncstatemachine.py old mode 100755 new mode 100644 diff --git a/tlslite/integration/clienthelper.py b/tlslite/integration/clienthelper.py old mode 100755 new mode 100644 diff --git a/tlslite/integration/httptlsconnection.py b/tlslite/integration/httptlsconnection.py old mode 100755 new mode 100644 diff --git a/tlslite/integration/imap4_tls.py b/tlslite/integration/imap4_tls.py old mode 100755 new mode 100644 diff --git a/tlslite/integration/pop3_tls.py b/tlslite/integration/pop3_tls.py old mode 100755 new mode 100644 diff --git a/tlslite/integration/smtp_tls.py b/tlslite/integration/smtp_tls.py old mode 100755 new mode 100644 diff --git a/tlslite/integration/tlsasyncdispatchermixin.py b/tlslite/integration/tlsasyncdispatchermixin.py old mode 100755 new mode 100644 diff --git a/tlslite/integration/tlssocketservermixin.py b/tlslite/integration/tlssocketservermixin.py old mode 100755 new mode 100644 diff --git a/tlslite/integration/xmlrpctransport.py b/tlslite/integration/xmlrpctransport.py old mode 100755 new mode 100644 diff --git a/tlslite/mathtls.py b/tlslite/mathtls.py old mode 100755 new mode 100644 diff --git a/tlslite/messages.py b/tlslite/messages.py old mode 100755 new mode 100644 diff --git a/tlslite/session.py b/tlslite/session.py old mode 100755 new mode 100644 diff --git a/tlslite/sessioncache.py b/tlslite/sessioncache.py old mode 100755 new mode 100644 diff --git a/tlslite/tlsconnection.py b/tlslite/tlsconnection.py old mode 100755 new mode 100644 diff --git a/tlslite/tlsrecordlayer.py b/tlslite/tlsrecordlayer.py old mode 100755 new mode 100644 diff --git a/tlslite/utils/__init__.py b/tlslite/utils/__init__.py old mode 100755 new mode 100644 diff --git a/tlslite/utils/aes.py b/tlslite/utils/aes.py old mode 100755 new mode 100644 diff --git a/tlslite/utils/asn1parser.py b/tlslite/utils/asn1parser.py old mode 100755 new mode 100644 diff --git a/tlslite/utils/cipherfactory.py b/tlslite/utils/cipherfactory.py old mode 100755 new mode 100644 diff --git a/tlslite/utils/codec.py b/tlslite/utils/codec.py old mode 100755 new mode 100644 diff --git a/tlslite/utils/compat.py b/tlslite/utils/compat.py old mode 100755 new mode 100644 diff --git a/tlslite/utils/cryptomath.py b/tlslite/utils/cryptomath.py old mode 100755 new mode 100644 diff --git a/tlslite/utils/datefuncs.py b/tlslite/utils/datefuncs.py old mode 100755 new mode 100644 diff --git a/tlslite/utils/keyfactory.py b/tlslite/utils/keyfactory.py old mode 100755 new mode 100644 diff --git a/tlslite/utils/openssl_aes.py b/tlslite/utils/openssl_aes.py old mode 100755 new mode 100644 diff --git a/tlslite/utils/openssl_rc4.py b/tlslite/utils/openssl_rc4.py old mode 100755 new mode 100644 diff --git a/tlslite/utils/openssl_rsakey.py b/tlslite/utils/openssl_rsakey.py old mode 100755 new mode 100644 diff --git a/tlslite/utils/openssl_tripledes.py b/tlslite/utils/openssl_tripledes.py old mode 100755 new mode 100644 diff --git a/tlslite/utils/pycrypto_aes.py b/tlslite/utils/pycrypto_aes.py old mode 100755 new mode 100644 diff --git a/tlslite/utils/pycrypto_rc4.py b/tlslite/utils/pycrypto_rc4.py old mode 100755 new mode 100644 diff --git a/tlslite/utils/pycrypto_rsakey.py b/tlslite/utils/pycrypto_rsakey.py old mode 100755 new mode 100644 diff --git a/tlslite/utils/pycrypto_tripledes.py b/tlslite/utils/pycrypto_tripledes.py old mode 100755 new mode 100644 diff --git a/tlslite/utils/python_aes.py b/tlslite/utils/python_aes.py old mode 100755 new mode 100644 diff --git a/tlslite/utils/python_rc4.py b/tlslite/utils/python_rc4.py old mode 100755 new mode 100644 diff --git a/tlslite/utils/python_rsakey.py b/tlslite/utils/python_rsakey.py old mode 100755 new mode 100644 diff --git a/tlslite/utils/rc4.py b/tlslite/utils/rc4.py old mode 100755 new mode 100644 diff --git a/tlslite/utils/rijndael.py b/tlslite/utils/rijndael.py old mode 100755 new mode 100644 diff --git a/tlslite/utils/rsakey.py b/tlslite/utils/rsakey.py old mode 100755 new mode 100644 diff --git a/tlslite/utils/tripledes.py b/tlslite/utils/tripledes.py old mode 100755 new mode 100644 diff --git a/tlslite/verifierdb.py b/tlslite/verifierdb.py old mode 100755 new mode 100644 diff --git a/tlslite/x509.py b/tlslite/x509.py old mode 100755 new mode 100644 diff --git a/tlslite/x509certchain.py b/tlslite/x509certchain.py old mode 100755 new mode 100644 From 6cc42d4976053d698f71384624438068c6a74749 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Fri, 30 Jan 2015 00:36:17 -0500 Subject: [PATCH 2/4] Fix #! line in httpsserver.sh. From Chromium. --- tests/httpsserver.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/httpsserver.sh b/tests/httpsserver.sh index 046eb2ed..7449ad72 100755 --- a/tests/httpsserver.sh +++ b/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 From fa8db515fc3ae5f8e532177ca486f2d9903db17b Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Tue, 24 Mar 2015 00:57:24 -0400 Subject: [PATCH 3/4] Implement FALLBACK_SCSV. Adapted from a Chromium patch, with tests and client-side portions added. --- tests/tlstest.py | 59 ++++++++++++++++++++++++++++++------ tlslite/constants.py | 4 +++ tlslite/errors.py | 1 + tlslite/handshakesettings.py | 5 +++ tlslite/tlsconnection.py | 17 +++++++++-- 5 files changed, 75 insertions(+), 11 deletions(-) diff --git a/tests/tlstest.py b/tests/tlstest.py index 53122fd6..8a050387 100755 --- a/tests/tlstest.py +++ b/tests/tlstest.py @@ -423,8 +423,31 @@ def connect(): #print(" Next-Protocol Negotiated: %s" % connection.next_proto) assert(connection.next_proto == b'spdy/2') connection.close() - - print('Test 25 - good standard XMLRPC https client') + + print("Test 25.a - FALLBACK_SCSV") + synchro.recv(1) + connection = connect() + settings = HandshakeSettings() + settings.sendFallbackSCSV = True + connection.handshakeClientCert(settings=settings) + testConnClient(connection) + connection.close() + + print("Test 25.b - FALLBACK_SCSV") + synchro.recv(1) + connection = connect() + settings = HandshakeSettings() + settings.sendFallbackSCSV = True + settings.maxVersion = (3, 2) + try: + connection.handshakeClientCert(settings=settings) + assert() + except TLSRemoteAlert as alert: + if alert.description != AlertDescription.inappropriate_fallback: + raise + connection.close() + + print('Test 26 - good standard XMLRPC https client') address = address[0], address[1]+1 synchro.recv(1) try: @@ -441,7 +464,7 @@ def connect(): synchro.recv(1) assert server.pow(2,4) == 16 - print('Test 26 - good tlslite XMLRPC client') + print('Test 27 - good tlslite XMLRPC client') transport = XMLRPCTransport(ignoreAbruptClose=True) server = xmlrpclib.Server('https://%s:%s' % address, transport) synchro.recv(1) @@ -449,22 +472,22 @@ def connect(): synchro.recv(1) assert server.pow(2,4) == 16 - print('Test 27 - good XMLRPC ignored protocol') + print('Test 28 - good XMLRPC ignored protocol') server = xmlrpclib.Server('http://%s:%s' % address, transport) synchro.recv(1) assert server.add(1,2) == 3 synchro.recv(1) assert server.pow(2,4) == 16 - - print("Test 28 - Internet servers test") + + print("Test 29 - Internet servers test") try: i = IMAP4_TLS("cyrus.andrew.cmu.edu") i.login("anonymous", "anonymous@anonymous.net") i.logout() - print("Test 28: IMAP4 good") + print("Test 30: IMAP4 good") p = POP3_TLS("pop.gmail.com") p.quit() - print("Test 29: POP3 good") + print("Test 31: POP3 good") except socket.error as e: print("Non-critical error: socket error trying to reach internet server: ", e) @@ -843,7 +866,25 @@ def server_bind(self): testConnServer(connection) connection.close() - print("Tests 25-27 - XMLRPXC server") + print("Test 25.a - FALLBACK_SCSV") + synchro.send(b'R') + connection = connect() + connection.handshakeServer(certChain=x509Chain, privateKey=x509Key) + testConnServer(connection) + connection.close() + + print("Test 25.b - FALLBACK_SCSV") + synchro.send(b'R') + connection = connect() + try: + connection.handshakeServer(certChain=x509Chain, privateKey=x509Key) + assert() + except TLSLocalAlert as alert: + if alert.description != AlertDescription.inappropriate_fallback: + raise + connection.close() + + print("Tests 26-28 - XMLRPXC server") address = address[0], address[1]+1 class Server(TLSXMLRPCServer): diff --git a/tlslite/constants.py b/tlslite/constants.py index 4165de03..5445d93b 100644 --- a/tlslite/constants.py +++ b/tlslite/constants.py @@ -104,6 +104,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 @@ -115,6 +116,9 @@ class CipherSuite: # We actually don't do any renegotiation, but this # prevents renegotiation attacks TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0x00FF + + # draft-ietf-tls-downgrade-scsv-03 + 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/tlslite/errors.py b/tlslite/errors.py index 06826b39..2c523176 100644 --- a/tlslite/errors.py +++ b/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/tlslite/handshakesettings.py b/tlslite/handshakesettings.py index ee37c30f..7053edd9 100644 --- a/tlslite/handshakesettings.py +++ b/tlslite/handshakesettings.py @@ -95,6 +95,9 @@ class HandshakeSettings(object): Note that TACK support is not standardized by IETF and uses a temporary TLS Extension number, so should NOT be used in production software. + + @type sendFallbackSCSV: bool + @ivar sendFallbackSCSV: Whether to, as a client, send FALLBACK_SCSV. """ def __init__(self): self.minKeySize = 1023 @@ -106,6 +109,7 @@ def __init__(self): self.minVersion = (3,1) self.maxVersion = (3,3) self.useExperimentalTackExtension = False + self.sendFallbackSCSV = False # Validates the min/max fields, and certificateTypes # Filters out unsupported cipherNames and cipherImplementations @@ -119,6 +123,7 @@ def _filter(self): other.certificateTypes = self.certificateTypes other.minVersion = self.minVersion other.maxVersion = self.maxVersion + other.sendFallbackSCSV = self.sendFallbackSCSV if not cipherfactory.tripleDESPresent: other.cipherNames = [e for e in self.cipherNames if e != "3des"] diff --git a/tlslite/tlsconnection.py b/tlslite/tlsconnection.py index b516e008..85eb0306 100644 --- a/tlslite/tlsconnection.py +++ b/tlslite/tlsconnection.py @@ -506,6 +506,12 @@ def _clientSendClientHello(self, settings, session, srpUsername, else: assert(False) + #Add any SCSVs. These are not real cipher suites, but signaling + #values which reuse the cipher suite field in the ClientHello. + wireCipherSuites = list(cipherSuites) + if settings.sendFallbackSCSV: + wireCipherSuites.append(CipherSuite.TLS_FALLBACK_SCSV) + #Initialize acceptable certificate types certificateTypes = settings._getCertificateTypes() @@ -519,7 +525,7 @@ def _clientSendClientHello(self, settings, session, srpUsername, else: clientHello = ClientHello() clientHello.create(settings.maxVersion, getRandomBytes(32), - session.sessionID, cipherSuites, + session.sessionID, wireCipherSuites, certificateTypes, session.srpUsername, reqTack, nextProtos is not None, @@ -529,7 +535,7 @@ def _clientSendClientHello(self, settings, session, srpUsername, else: clientHello = ClientHello() clientHello.create(settings.maxVersion, getRandomBytes(32), - bytearray(0), cipherSuites, + bytearray(0), wireCipherSuites, certificateTypes, srpUsername, reqTack, nextProtos is not None, @@ -1257,6 +1263,13 @@ def _serverGetClientHello(self, settings, certChain, verifierDB, #Set the version to the client's version self.version = clientHello.client_version + #Detect if the client performed an inappropriate fallback. + if clientHello.client_version < settings.maxVersion and \ + CipherSuite.TLS_FALLBACK_SCSV in clientHello.cipher_suites: + for result in self._sendError(\ + AlertDescription.inappropriate_fallback): + yield result + #If resumption was requested and we have a session cache... if clientHello.session_id and sessionCache: session = None From daf2e15fc8e30ad4de40e4096151bdf2750fd7a4 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Fri, 30 Jan 2015 00:41:06 -0500 Subject: [PATCH 4/4] Apply minimal padding. SSL 3.0 requires minimal padding. (TLS doesn't require it but accepts it, so apply uniformly to both.) From Chromium. --- tlslite/tlsrecordlayer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tlslite/tlsrecordlayer.py b/tlslite/tlsrecordlayer.py index 5fe74102..97533c95 100644 --- a/tlslite/tlsrecordlayer.py +++ b/tlslite/tlsrecordlayer.py @@ -592,9 +592,9 @@ def _sendMsg(self, msg, randomizeFirstBlock = True): b = self.fixedIVBlock + b #Add padding: b = b+ (macBytes + paddingBytes) - currentLength = len(b) + len(macBytes) + 1 + 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: