| Index: third_party/tlslite/patches/intolerance_options.patch
|
| diff --git a/third_party/tlslite/patches/intolerance_options.patch b/third_party/tlslite/patches/intolerance_options.patch
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..110b5f6e794170cb887e4f6ef6f3de966fc686a8
|
| --- /dev/null
|
| +++ b/third_party/tlslite/patches/intolerance_options.patch
|
| @@ -0,0 +1,188 @@
|
| +diff --git a/third_party/tlslite/tlslite/handshakesettings.py b/third_party/tlslite/tlslite/handshakesettings.py
|
| +index e0bc0e6..4af3791 100644
|
| +--- a/third_party/tlslite/tlslite/handshakesettings.py
|
| ++++ b/third_party/tlslite/tlslite/handshakesettings.py
|
| +@@ -18,6 +18,7 @@ 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"]
|
| ++TLS_INTOLERANCE_TYPES = ["alert", "close", "reset"]
|
| +
|
| + class HandshakeSettings(object):
|
| + """This class encapsulates various parameters that can be used with
|
| +@@ -92,6 +93,17 @@ class HandshakeSettings(object):
|
| + 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 tlsIntolerant: tuple
|
| ++ @ivar tlsIntolerant: TLS version intolerance for servers.
|
| ++
|
| ++ If tlsIntolerant is not None, the server will simulate TLS version
|
| ++ intolerance by returning a fatal handshake_failure alert or a TCP reset to
|
| ++ all TLS versions tlsIntolerant or higher.
|
| ++
|
| ++ @type tlsIntoleranceType: str
|
| ++ @ivar tlsIntoleranceType: How the server should react when simulating
|
| ++ TLS intolerance.
|
| +
|
| + @type useExperimentalTackExtension: bool
|
| + @ivar useExperimentalTackExtension: Whether to enabled TACK support.
|
| +@@ -109,6 +121,8 @@ class HandshakeSettings(object):
|
| + self.certificateTypes = CERTIFICATE_TYPES
|
| + self.minVersion = (3,0)
|
| + self.maxVersion = (3,2)
|
| ++ self.tlsIntolerant = None
|
| ++ self.tlsIntoleranceType = 'alert'
|
| + self.useExperimentalTackExtension = False
|
| +
|
| + # Validates the min/max fields, and certificateTypes
|
| +@@ -124,6 +138,8 @@ class HandshakeSettings(object):
|
| + other.certificateTypes = self.certificateTypes
|
| + other.minVersion = self.minVersion
|
| + other.maxVersion = self.maxVersion
|
| ++ other.tlsIntolerant = self.tlsIntolerant
|
| ++ other.tlsIntoleranceType = self.tlsIntoleranceType
|
| +
|
| + if not cipherfactory.tripleDESPresent:
|
| + other.cipherNames = [e for e in self.cipherNames if e != "3des"]
|
| +@@ -165,6 +181,10 @@ class HandshakeSettings(object):
|
| + if s not in CERTIFICATE_TYPES:
|
| + raise ValueError("Unknown certificate type: '%s'" % s)
|
| +
|
| ++ if other.tlsIntoleranceType not in TLS_INTOLERANCE_TYPES:
|
| ++ raise ValueError(
|
| ++ "Unknown TLS intolerance type: '%s'" % other.tlsIntoleranceType)
|
| ++
|
| + if other.minVersion > other.maxVersion:
|
| + raise ValueError("Versions set incorrectly")
|
| +
|
| +diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py
|
| +index 044ad59..7c1572f 100644
|
| +--- a/third_party/tlslite/tlslite/tlsconnection.py
|
| ++++ b/third_party/tlslite/tlslite/tlsconnection.py
|
| +@@ -1065,7 +1065,7 @@ class TLSConnection(TLSRecordLayer):
|
| + reqCAs = None, reqCertTypes = None,
|
| + tacks=None, activationFlags=0,
|
| + nextProtos=None, anon=False,
|
| +- tlsIntolerant=None, signedCertTimestamps=None,
|
| ++ signedCertTimestamps=None,
|
| + fallbackSCSV=False, ocspResponse=None):
|
| + """Perform a handshake in the role of server.
|
| +
|
| +@@ -1139,11 +1139,6 @@ 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.
|
| +-
|
| + @type signedCertTimestamps: str
|
| + @param signedCertTimestamps: A SignedCertificateTimestampList (as a
|
| + binary 8-bit string) that will be sent as a TLS extension whenever
|
| +@@ -1175,7 +1170,7 @@ class TLSConnection(TLSRecordLayer):
|
| + certChain, privateKey, reqCert, sessionCache, settings,
|
| + checker, reqCAs, reqCertTypes,
|
| + tacks=tacks, activationFlags=activationFlags,
|
| +- nextProtos=nextProtos, anon=anon, tlsIntolerant=tlsIntolerant,
|
| ++ nextProtos=nextProtos, anon=anon,
|
| + signedCertTimestamps=signedCertTimestamps,
|
| + fallbackSCSV=fallbackSCSV, ocspResponse=ocspResponse):
|
| + pass
|
| +@@ -1187,7 +1182,6 @@ class TLSConnection(TLSRecordLayer):
|
| + reqCAs=None, reqCertTypes=None,
|
| + tacks=None, activationFlags=0,
|
| + nextProtos=None, anon=False,
|
| +- tlsIntolerant=None,
|
| + signedCertTimestamps=None,
|
| + fallbackSCSV=False,
|
| + ocspResponse=None
|
| +@@ -1210,7 +1204,6 @@ class TLSConnection(TLSRecordLayer):
|
| + reqCAs=reqCAs, reqCertTypes=reqCertTypes,
|
| + tacks=tacks, activationFlags=activationFlags,
|
| + nextProtos=nextProtos, anon=anon,
|
| +- tlsIntolerant=tlsIntolerant,
|
| + signedCertTimestamps=signedCertTimestamps,
|
| + fallbackSCSV=fallbackSCSV,
|
| + ocspResponse=ocspResponse)
|
| +@@ -1223,7 +1216,7 @@ class TLSConnection(TLSRecordLayer):
|
| + settings, reqCAs, reqCertTypes,
|
| + tacks, activationFlags,
|
| + nextProtos, anon,
|
| +- tlsIntolerant, signedCertTimestamps, fallbackSCSV,
|
| ++ signedCertTimestamps, fallbackSCSV,
|
| + ocspResponse):
|
| +
|
| + self._handshakeStart(client=False)
|
| +@@ -1261,7 +1254,7 @@ class TLSConnection(TLSRecordLayer):
|
| + # Handle ClientHello and resumption
|
| + for result in self._serverGetClientHello(settings, certChain,\
|
| + verifierDB, sessionCache,
|
| +- anon, tlsIntolerant, fallbackSCSV):
|
| ++ anon, fallbackSCSV):
|
| + if result in (0,1): yield result
|
| + elif result == None:
|
| + self._handshakeDone(resumed=True)
|
| +@@ -1376,7 +1369,7 @@ class TLSConnection(TLSRecordLayer):
|
| +
|
| +
|
| + def _serverGetClientHello(self, settings, certChain, verifierDB,
|
| +- sessionCache, anon, tlsIntolerant, fallbackSCSV):
|
| ++ sessionCache, anon, fallbackSCSV):
|
| + #Initialize acceptable cipher suites
|
| + cipherSuites = []
|
| + if verifierDB:
|
| +@@ -1413,11 +1406,21 @@ class TLSConnection(TLSRecordLayer):
|
| + 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(\
|
| ++ elif (settings.tlsIntolerant is not None and
|
| ++ clientHello.client_version >= settings.tlsIntolerant):
|
| ++ if settings.tlsIntoleranceType == "alert":
|
| ++ for result in self._sendError(\
|
| + AlertDescription.handshake_failure):
|
| +- yield result
|
| ++ yield result
|
| ++ elif settings.tlsIntoleranceType == "close":
|
| ++ self._abruptClose()
|
| ++ raise TLSUnsupportedError("Simulating version intolerance")
|
| ++ elif settings.tlsIntoleranceType == "reset":
|
| ++ self._abruptClose(reset=True)
|
| ++ raise TLSUnsupportedError("Simulating version intolerance")
|
| ++ else:
|
| ++ raise ValueError("Unknown intolerance type: '%s'" %
|
| ++ settings.tlsIntoleranceType)
|
| +
|
| + #If client's version is too high, propose my highest version
|
| + elif clientHello.client_version > settings.maxVersion:
|
| +diff --git a/third_party/tlslite/tlslite/tlsrecordlayer.py b/third_party/tlslite/tlslite/tlsrecordlayer.py
|
| +index 370dc9a..23c2a2f 100644
|
| +--- a/third_party/tlslite/tlslite/tlsrecordlayer.py
|
| ++++ b/third_party/tlslite/tlslite/tlsrecordlayer.py
|
| +@@ -19,6 +19,7 @@ from .constants import *
|
| + from .utils.cryptomath import getRandomBytes
|
| +
|
| + import socket
|
| ++import struct
|
| + import errno
|
| + import traceback
|
| +
|
| +@@ -523,6 +524,13 @@ class TLSRecordLayer(object):
|
| + self._shutdown(False)
|
| + raise TLSLocalAlert(alert, errorStr)
|
| +
|
| ++ def _abruptClose(self, reset=False):
|
| ++ if reset:
|
| ++ #Set an SO_LINGER timeout of 0 to send a TCP RST.
|
| ++ self.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER,
|
| ++ struct.pack('ii', 1, 0))
|
| ++ self._shutdown(False)
|
| ++
|
| + def _sendMsgs(self, msgs):
|
| + randomizeFirstBlock = True
|
| + for msg in msgs:
|
|
|