Home | History | Annotate | Download | only in patches
      1 diff --git a/third_party/tlslite/tlslite/handshakesettings.py b/third_party/tlslite/tlslite/handshakesettings.py
      2 index e0bc0e6..0d4ccf2 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,21 @@ 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: 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 @@ -109,6 +125,8 @@ class HandshakeSettings(object):
     36          self.certificateTypes = CERTIFICATE_TYPES
     37          self.minVersion = (3,0)
     38          self.maxVersion = (3,2)
     39 +        self.tlsIntolerant = None
     40 +        self.tlsIntoleranceType = 'alert'
     41          self.useExperimentalTackExtension = False
     42  
     43      # Validates the min/max fields, and certificateTypes
     44 @@ -124,6 +142,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 @@ -165,6 +185,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  
     64 diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py
     65 index 044ad59..7c1572f 100644
     66 --- a/third_party/tlslite/tlslite/tlsconnection.py
     67 +++ b/third_party/tlslite/tlslite/tlsconnection.py
     68 @@ -1065,7 +1065,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 @@ -1139,11 +1139,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 @@ -1175,7 +1170,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 @@ -1187,7 +1182,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 @@ -1210,7 +1204,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 @@ -1223,7 +1216,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 @@ -1261,7 +1254,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 @@ -1376,7 +1369,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 @@ -1413,11 +1406,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:
    167 diff --git a/third_party/tlslite/tlslite/tlsrecordlayer.py b/third_party/tlslite/tlslite/tlsrecordlayer.py
    168 index 370dc9a..23c2a2f 100644
    169 --- a/third_party/tlslite/tlslite/tlsrecordlayer.py
    170 +++ b/third_party/tlslite/tlslite/tlsrecordlayer.py
    171 @@ -19,6 +19,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 @@ -523,6 +524,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