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