1diff --git a/third_party/tlslite/tlslite/handshakesettings.py b/third_party/tlslite/tlslite/handshakesettings.py 2index 7998e2e..2e9e06d 100644 3--- a/third_party/tlslite/tlslite/handshakesettings.py 4+++ b/third_party/tlslite/tlslite/handshakesettings.py 5@@ -19,6 +19,7 @@ ALL_MAC_NAMES = ["sha", "sha256", "md5"] 6 KEY_EXCHANGE_NAMES = ["rsa", "dhe_rsa", "srp_sha", "srp_sha_rsa", "dh_anon"] 7 CIPHER_IMPLEMENTATIONS = ["openssl", "pycrypto", "python"] 8 CERTIFICATE_TYPES = ["x509"] 9+TLS_INTOLERANCE_TYPES = ["alert", "close", "reset"] 10 11 class HandshakeSettings(object): 12 """This class encapsulates various parameters that can be used with 13@@ -91,6 +92,21 @@ class HandshakeSettings(object): 14 version, a protocol_version alert will be signalled. The default is (3,3). 15 (WARNING: Some servers may (improperly) reject clients which offer support 16 for TLS 1.1. In this case, try lowering maxVersion to (3,1)). 17+ 18+ @type tlsIntolerant: tuple 19+ @ivar tlsIntolerant: The TLS ClientHello version which the server 20+ simulates intolerance of. 21+ 22+ If tlsIntolerant is not None, the server will simulate TLS version 23+ intolerance by aborting the handshake in response to all TLS versions 24+ tlsIntolerant or higher. 25+ 26+ @type tlsIntoleranceType: str 27+ @ivar tlsIntoleranceType: How the server should react when simulating TLS 28+ intolerance. 29+ 30+ The allowed values are "alert" (return a fatal handshake_failure alert), 31+ "close" (abruptly close the connection), and "reset" (send a TCP reset). 32 33 @type useExperimentalTackExtension: bool 34 @ivar useExperimentalTackExtension: Whether to enabled TACK support. 35@@ -108,6 +124,8 @@ class HandshakeSettings(object): 36 self.certificateTypes = CERTIFICATE_TYPES 37 self.minVersion = (3,1) 38 self.maxVersion = (3,3) 39+ self.tlsIntolerant = None 40+ self.tlsIntoleranceType = 'alert' 41 self.useExperimentalTackExtension = False 42 43 # Validates the min/max fields, and certificateTypes 44@@ -123,6 +141,8 @@ class HandshakeSettings(object): 45 other.certificateTypes = self.certificateTypes 46 other.minVersion = self.minVersion 47 other.maxVersion = self.maxVersion 48+ other.tlsIntolerant = self.tlsIntolerant 49+ other.tlsIntoleranceType = self.tlsIntoleranceType 50 51 if not cipherfactory.tripleDESPresent: 52 other.cipherNames = [e for e in self.cipherNames if e != "3des"] 53@@ -164,6 +184,10 @@ class HandshakeSettings(object): 54 if s not in CERTIFICATE_TYPES: 55 raise ValueError("Unknown certificate type: '%s'" % s) 56 57+ if other.tlsIntoleranceType not in TLS_INTOLERANCE_TYPES: 58+ raise ValueError( 59+ "Unknown TLS intolerance type: '%s'" % other.tlsIntoleranceType) 60+ 61 if other.minVersion > other.maxVersion: 62 raise ValueError("Versions set incorrectly") 63 64diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py 65index f8547d5..4f3ba1c 100644 66--- a/third_party/tlslite/tlslite/tlsconnection.py 67+++ b/third_party/tlslite/tlslite/tlsconnection.py 68@@ -1073,7 +1073,7 @@ class TLSConnection(TLSRecordLayer): 69 reqCAs = None, reqCertTypes = None, 70 tacks=None, activationFlags=0, 71 nextProtos=None, anon=False, 72- tlsIntolerant=None, signedCertTimestamps=None, 73+ signedCertTimestamps=None, 74 fallbackSCSV=False, ocspResponse=None): 75 """Perform a handshake in the role of server. 76 77@@ -1147,11 +1147,6 @@ class TLSConnection(TLSRecordLayer): 78 clients through the Next-Protocol Negotiation Extension, 79 if they support it. 80 81- @type tlsIntolerant: (int, int) or None 82- @param tlsIntolerant: If tlsIntolerant is not None, the server will 83- simulate TLS version intolerance by returning a fatal handshake_failure 84- alert to all TLS versions tlsIntolerant or higher. 85- 86 @type signedCertTimestamps: str 87 @param signedCertTimestamps: A SignedCertificateTimestampList (as a 88 binary 8-bit string) that will be sent as a TLS extension whenever 89@@ -1183,7 +1178,7 @@ class TLSConnection(TLSRecordLayer): 90 certChain, privateKey, reqCert, sessionCache, settings, 91 checker, reqCAs, reqCertTypes, 92 tacks=tacks, activationFlags=activationFlags, 93- nextProtos=nextProtos, anon=anon, tlsIntolerant=tlsIntolerant, 94+ nextProtos=nextProtos, anon=anon, 95 signedCertTimestamps=signedCertTimestamps, 96 fallbackSCSV=fallbackSCSV, ocspResponse=ocspResponse): 97 pass 98@@ -1195,7 +1190,6 @@ class TLSConnection(TLSRecordLayer): 99 reqCAs=None, reqCertTypes=None, 100 tacks=None, activationFlags=0, 101 nextProtos=None, anon=False, 102- tlsIntolerant=None, 103 signedCertTimestamps=None, 104 fallbackSCSV=False, 105 ocspResponse=None 106@@ -1218,7 +1212,6 @@ class TLSConnection(TLSRecordLayer): 107 reqCAs=reqCAs, reqCertTypes=reqCertTypes, 108 tacks=tacks, activationFlags=activationFlags, 109 nextProtos=nextProtos, anon=anon, 110- tlsIntolerant=tlsIntolerant, 111 signedCertTimestamps=signedCertTimestamps, 112 fallbackSCSV=fallbackSCSV, 113 ocspResponse=ocspResponse) 114@@ -1231,7 +1224,7 @@ class TLSConnection(TLSRecordLayer): 115 settings, reqCAs, reqCertTypes, 116 tacks, activationFlags, 117 nextProtos, anon, 118- tlsIntolerant, signedCertTimestamps, fallbackSCSV, 119+ signedCertTimestamps, fallbackSCSV, 120 ocspResponse): 121 122 self._handshakeStart(client=False) 123@@ -1269,7 +1262,7 @@ class TLSConnection(TLSRecordLayer): 124 # Handle ClientHello and resumption 125 for result in self._serverGetClientHello(settings, certChain,\ 126 verifierDB, sessionCache, 127- anon, tlsIntolerant, fallbackSCSV): 128+ anon, fallbackSCSV): 129 if result in (0,1): yield result 130 elif result == None: 131 self._handshakeDone(resumed=True) 132@@ -1384,7 +1377,7 @@ class TLSConnection(TLSRecordLayer): 133 134 135 def _serverGetClientHello(self, settings, certChain, verifierDB, 136- sessionCache, anon, tlsIntolerant, fallbackSCSV): 137+ sessionCache, anon, fallbackSCSV): 138 #Initialize acceptable cipher suites 139 cipherSuites = [] 140 if verifierDB: 141@@ -1421,11 +1414,21 @@ class TLSConnection(TLSRecordLayer): 142 yield result 143 144 #If simulating TLS intolerance, reject certain TLS versions. 145- elif (tlsIntolerant is not None and 146- clientHello.client_version >= tlsIntolerant): 147- for result in self._sendError(\ 148+ elif (settings.tlsIntolerant is not None and 149+ clientHello.client_version >= settings.tlsIntolerant): 150+ if settings.tlsIntoleranceType == "alert": 151+ for result in self._sendError(\ 152 AlertDescription.handshake_failure): 153- yield result 154+ yield result 155+ elif settings.tlsIntoleranceType == "close": 156+ self._abruptClose() 157+ raise TLSUnsupportedError("Simulating version intolerance") 158+ elif settings.tlsIntoleranceType == "reset": 159+ self._abruptClose(reset=True) 160+ raise TLSUnsupportedError("Simulating version intolerance") 161+ else: 162+ raise ValueError("Unknown intolerance type: '%s'" % 163+ settings.tlsIntoleranceType) 164 165 #If client's version is too high, propose my highest version 166 elif clientHello.client_version > settings.maxVersion: 167diff --git a/third_party/tlslite/tlslite/tlsrecordlayer.py b/third_party/tlslite/tlslite/tlsrecordlayer.py 168index 3584726..eda11e6 100644 169--- a/third_party/tlslite/tlslite/tlsrecordlayer.py 170+++ b/third_party/tlslite/tlslite/tlsrecordlayer.py 171@@ -20,6 +20,7 @@ from .constants import * 172 from .utils.cryptomath import getRandomBytes 173 174 import socket 175+import struct 176 import errno 177 import traceback 178 179@@ -527,6 +528,13 @@ class TLSRecordLayer(object): 180 self._shutdown(False) 181 raise TLSLocalAlert(alert, errorStr) 182 183+ def _abruptClose(self, reset=False): 184+ if reset: 185+ #Set an SO_LINGER timeout of 0 to send a TCP RST. 186+ self.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, 187+ struct.pack('ii', 1, 0)) 188+ self._shutdown(False) 189+ 190 def _sendMsgs(self, msgs): 191 randomizeFirstBlock = True 192 for msg in msgs: 193