1diff --git a/third_party/tlslite/tlslite/constants.py b/third_party/tlslite/tlslite/constants.py 2index b3bad2d..d132b78 100755 3--- a/third_party/tlslite/tlslite/constants.py 4+++ b/third_party/tlslite/tlslite/constants.py 5@@ -106,6 +106,7 @@ class AlertDescription: 6 protocol_version = 70 7 insufficient_security = 71 8 internal_error = 80 9+ inappropriate_fallback = 86 10 user_canceled = 90 11 no_renegotiation = 100 12 unknown_psk_identity = 115 13@@ -117,6 +118,9 @@ class CipherSuite: 14 # We actually don't do any renegotiation, but this 15 # prevents renegotiation attacks 16 TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0x00FF 17+ 18+ # draft-bmoeller-tls-downgrade-scsv-01 19+ TLS_FALLBACK_SCSV = 0x5600 20 21 TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA = 0xC01A 22 TLS_SRP_SHA_WITH_AES_128_CBC_SHA = 0xC01D 23diff --git a/third_party/tlslite/tlslite/errors.py b/third_party/tlslite/tlslite/errors.py 24index 22c298c..001ef33 100755 25--- a/third_party/tlslite/tlslite/errors.py 26+++ b/third_party/tlslite/tlslite/errors.py 27@@ -63,6 +63,7 @@ class TLSAlert(TLSError): 28 AlertDescription.protocol_version: "protocol_version",\ 29 AlertDescription.insufficient_security: "insufficient_security",\ 30 AlertDescription.internal_error: "internal_error",\ 31+ AlertDescription.inappropriate_fallback: "inappropriate_fallback",\ 32 AlertDescription.user_canceled: "user_canceled",\ 33 AlertDescription.no_renegotiation: "no_renegotiation",\ 34 AlertDescription.unknown_psk_identity: "unknown_psk_identity"} 35diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py 36index 45b0bbb..bd92161 100755 37--- a/third_party/tlslite/tlslite/tlsconnection.py 38+++ b/third_party/tlslite/tlslite/tlsconnection.py 39@@ -966,7 +966,8 @@ class TLSConnection(TLSRecordLayer): 40 reqCAs = None, 41 tacks=None, activationFlags=0, 42 nextProtos=None, anon=False, 43- tlsIntolerant=None, signedCertTimestamps=None): 44+ tlsIntolerant=None, signedCertTimestamps=None, 45+ fallbackSCSV=False): 46 """Perform a handshake in the role of server. 47 48 This function performs an SSL or TLS handshake. Depending on 49@@ -1045,6 +1046,11 @@ class TLSConnection(TLSRecordLayer): 50 binary 8-bit string) that will be sent as a TLS extension whenever 51 the client announces support for the extension. 52 53+ @type fallbackSCSV: bool 54+ @param fallbackSCSV: if true, the server will implement 55+ TLS_FALLBACK_SCSV and thus reject connections using less than the 56+ server's maximum TLS version that include this cipher suite. 57+ 58 @raise socket.error: If a socket error occurs. 59 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed 60 without a preceding alert. 61@@ -1057,7 +1063,8 @@ class TLSConnection(TLSRecordLayer): 62 checker, reqCAs, 63 tacks=tacks, activationFlags=activationFlags, 64 nextProtos=nextProtos, anon=anon, tlsIntolerant=tlsIntolerant, 65- signedCertTimestamps=signedCertTimestamps): 66+ signedCertTimestamps=signedCertTimestamps, 67+ fallbackSCSV=fallbackSCSV): 68 pass 69 70 71@@ -1068,7 +1075,8 @@ class TLSConnection(TLSRecordLayer): 72 tacks=None, activationFlags=0, 73 nextProtos=None, anon=False, 74 tlsIntolerant=None, 75- signedCertTimestamps=None 76+ signedCertTimestamps=None, 77+ fallbackSCSV=False 78 ): 79 """Start a server handshake operation on the TLS connection. 80 81@@ -1089,7 +1097,8 @@ class TLSConnection(TLSRecordLayer): 82 tacks=tacks, activationFlags=activationFlags, 83 nextProtos=nextProtos, anon=anon, 84 tlsIntolerant=tlsIntolerant, 85- signedCertTimestamps=signedCertTimestamps) 86+ signedCertTimestamps=signedCertTimestamps, 87+ fallbackSCSV=fallbackSCSV) 88 for result in self._handshakeWrapperAsync(handshaker, checker): 89 yield result 90 91@@ -1099,7 +1108,7 @@ class TLSConnection(TLSRecordLayer): 92 settings, reqCAs, 93 tacks, activationFlags, 94 nextProtos, anon, 95- tlsIntolerant, signedCertTimestamps): 96+ tlsIntolerant, signedCertTimestamps, fallbackSCSV): 97 98 self._handshakeStart(client=False) 99 100@@ -1134,7 +1143,7 @@ class TLSConnection(TLSRecordLayer): 101 # Handle ClientHello and resumption 102 for result in self._serverGetClientHello(settings, certChain,\ 103 verifierDB, sessionCache, 104- anon, tlsIntolerant): 105+ anon, tlsIntolerant, fallbackSCSV): 106 if result in (0,1): yield result 107 elif result == None: 108 self._handshakeDone(resumed=True) 109@@ -1234,7 +1243,7 @@ class TLSConnection(TLSRecordLayer): 110 111 112 def _serverGetClientHello(self, settings, certChain, verifierDB, 113- sessionCache, anon, tlsIntolerant): 114+ sessionCache, anon, tlsIntolerant, fallbackSCSV): 115 #Initialize acceptable cipher suites 116 cipherSuites = [] 117 if verifierDB: 118@@ -1280,6 +1289,14 @@ class TLSConnection(TLSRecordLayer): 119 elif clientHello.client_version > settings.maxVersion: 120 self.version = settings.maxVersion 121 122+ #Detect if the client performed an inappropriate fallback. 123+ elif fallbackSCSV and clientHello.client_version < settings.maxVersion: 124+ self.version = clientHello.client_version 125+ if CipherSuite.TLS_FALLBACK_SCSV in clientHello.cipher_suites: 126+ for result in self._sendError(\ 127+ AlertDescription.inappropriate_fallback): 128+ yield result 129+ 130 else: 131 #Set the version to the client's version 132 self.version = clientHello.client_version 133