tlslite.tlsrecordlayer

Package tlslite :: Module tlsrecordlayer |
[hide private]
[frames] | no frames]

# Source Code for Module tlslite.tlsrecordlayer

       1  # Authors:
       2  #   Trevor Perrin
       3  #   Google (adapted by Sam Rushing) - NPN support
       4  #   Martin von Loewis - python 3 port
       5  #
       6  # See the LICENSE file for legal information regarding use of this file.
       7
       8  """Helper class for TLSConnection."""
       9  from __future__ import generators
      10
      11  from .utils.compat import *
      12  from .utils.cryptomath import *
      13  from .utils.cipherfactory import createAES, createRC4, createTripleDES
      14  from .utils.codec import *
      15  from .errors import *
      16  from .messages import *
      17  from .mathtls import *
      18  from .constants import *
      19  from .utils.cryptomath import getRandomBytes
      20
      21  import socket
      22  import errno
      23  import traceback
      24
      25 -class _ConnectionState(object):
      26 -    def __init__(self):
      27          self.macContext = None
      28          self.encContext = None
      29          self.seqnum = 0
      30
      31 -    def getSeqNumBytes(self):
      32          w = Writer()
      33          w.add(self.seqnum, 8)
      34          self.seqnum += 1
      35          return w.bytes
      36
      37
      38 -class TLSRecordLayer(object):
      39      """
      40      This class handles data transmission for a TLS connection.
      41
      42      Its only subclass is L{tlslite.TLSConnection.TLSConnection}.  We've
      43      separated the code in this class from TLSConnection to make things
      44      more readable.
      45
      46
      47      @type sock: socket.socket
      48      @ivar sock: The underlying socket object.
      49
      50      @type session: L{tlslite.Session.Session}
      51      @ivar session: The session corresponding to this connection.
      52
      53      Due to TLS session resumption, multiple connections can correspond
      54      to the same underlying session.
      55
      56      @type version: tuple
      57      @ivar version: The TLS version being used for this connection.
      58
      59      (3,0) means SSL 3.0, and (3,1) means TLS 1.0.
      60
      61      @type closed: bool
      62      @ivar closed: If this connection is closed.
      63
      64      @type resumed: bool
      65      @ivar resumed: If this connection is based on a resumed session.
      66
      67      @type allegedSrpUsername: str or None
      68      @ivar allegedSrpUsername:  This is set to the SRP username
      69      asserted by the client, whether the handshake succeeded or not.
      70      If the handshake fails, this can be inspected to determine
      71      if a guessing attack is in progress against a particular user
      72      account.
      73
      74      @type closeSocket: bool
      75      @ivar closeSocket: If the socket should be closed when the
      76      connection is closed, defaults to True (writable).
      77
      78      If you set this to True, TLS Lite will assume the responsibility of
      79      closing the socket when the TLS Connection is shutdown (either
      80      through an error or through the user calling close()).  The default
      81      is False.
      82
      83      @type ignoreAbruptClose: bool
      84      @ivar ignoreAbruptClose: If an abrupt close of the socket should
      85      raise an error (writable).
      86
      87      If you set this to True, TLS Lite will not raise a
      88      L{tlslite.errors.TLSAbruptCloseError} exception if the underlying
      89      socket is unexpectedly closed.  Such an unexpected closure could be
      90      caused by an attacker.  However, it also occurs with some incorrect
      91      TLS implementations.
      92
      93      You should set this to True only if you're not worried about an
      94      attacker truncating the connection, and only if necessary to avoid
      95      spurious errors.  The default is False.
      96
      97      @sort: __init__, read, readAsync, write, writeAsync, close, closeAsync,
      98      getCipherImplementation, getCipherName
      99      """
     100
     101 -    def __init__(self, sock):
     102          self.sock = sock
     103
     104          #My session object (Session instance; read-only)
     105          self.session = None
     106
     107          #Am I a client or server?
     108          self._client = None
     109
     110          #Buffers for processing messages
     111          self._handshakeBuffer = []
     112          self.clearReadBuffer()
     113          self.clearWriteBuffer()
     114
     115          #Handshake digests
     116          self._handshake_md5 = hashlib.md5()
     117          self._handshake_sha = hashlib.sha1()
     118
     119          #TLS Protocol Version
     120          self.version = (0,0) #read-only
     121          self._versionCheck = False #Once we choose a version, this is True
     122
     123          #Current and Pending connection states
     124          self._writeState = _ConnectionState()
     125          self._readState = _ConnectionState()
     126          self._pendingWriteState = _ConnectionState()
     127          self._pendingReadState = _ConnectionState()
     128
     129          #Is the connection open?
     130          self.closed = True #read-only
     131          self._refCount = 0 #Used to trigger closure
     132
     133          #Is this a resumed session?
     134          self.resumed = False #read-only
     135
     136          #What username did the client claim in his handshake?
     137          self.allegedSrpUsername = None
     138
     139          #On a call to close(), do we close the socket? (writeable)
     140          self.closeSocket = True
     141
     142          #If the socket is abruptly closed, do we ignore it
     143          #and pretend the connection was shut down properly? (writeable)
     144          self.ignoreAbruptClose = False
     145
     146          #Fault we will induce, for testing purposes
     147          self.fault = None
     148
     149 -    def clearReadBuffer(self):
     150          self._readBuffer = b''
     151
     152 -    def clearWriteBuffer(self):
     153          self._send_writer = None
     154
     155
     156      #*********************************************************
     157      # Public Functions START
     158      #*********************************************************
     159
     160 -    def read(self, max=None, min=1):
     161          """Read some data from the TLS connection.
     162
     163          This function will block until at least 'min' bytes are
     164          available (or the connection is closed).
     165
     166          If an exception is raised, the connection will have been
     167          automatically closed.
     168
     169          @type max: int
     170          @param max: The maximum number of bytes to return.
     171
     172          @type min: int
     173          @param min: The minimum number of bytes to return
     174
     175          @rtype: str
     176          @return: A string of no more than 'max' bytes, and no fewer
     177          than 'min' (unless the connection has been closed, in which
     178          case fewer than 'min' bytes may be returned).
     179
     180          @raise socket.error: If a socket error occurs.
     181          @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
     182          without a preceding alert.
     183          @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
     184          """
     185          for result in self.readAsync(max, min):
     186              pass
     187          return result
     188
     189 -    def readAsync(self, max=None, min=1):
     190          """Start a read operation on the TLS connection.
     191
     192          This function returns a generator which behaves similarly to
     193          read().  Successive invocations of the generator will return 0
     194          if it is waiting to read from the socket, 1 if it is waiting
     195          to write to the socket, or a string if the read operation has
     196          completed.
     197
     198          @rtype: iterable
     199          @return: A generator; see above for details.
     200          """
     201          try:
     202              while len(self._readBuffer)<min and not self.closed:
     203                  try:
     204                      for result in self._getMsg(ContentType.application_data):
     205                          if result in (0,1):
     206                              yield result
     207                      applicationData = result
     208                      self._readBuffer += applicationData.write()
     209                  except TLSRemoteAlert as alert:
     210                      if alert.description != AlertDescription.close_notify:
     211                          raise
     212                  except TLSAbruptCloseError:
     213                      if not self.ignoreAbruptClose:
     214                          raise
     215                      else:
     216                          self._shutdown(True)
     217
     218              if max == None:
     219                  max = len(self._readBuffer)
     220
     221              returnBytes = self._readBuffer[:max]
     222              self._readBuffer = self._readBuffer[max:]
     223              yield bytes(returnBytes)
     224          except GeneratorExit:
     225              raise
     226          except:
     227              self._shutdown(False)
     228              raise
     229
     230 -    def unread(self, b):
     231          """Add bytes to the front of the socket read buffer for future
     232          reading. Be careful using this in the context of select(...): if you
     233          unread the last data from a socket, that won't wake up selected waiters,
     234          and those waiters may hang forever.
     235          """
     236          self._readBuffer = b + self._readBuffer
     237
     238 -    def write(self, s):
     239          """Write some data to the TLS connection.
     240
     241          This function will block until all the data has been sent.
     242
     243          If an exception is raised, the connection will have been
     244          automatically closed.
     245
     246          @type s: str
     247          @param s: The data to transmit to the other party.
     248
     249          @raise socket.error: If a socket error occurs.
     250          """
     251          for result in self.writeAsync(s):
     252              pass
     253
     254 -    def writeAsync(self, s):
     255          """Start a write operation on the TLS connection.
     256
     257          This function returns a generator which behaves similarly to
     258          write().  Successive invocations of the generator will return
     259          1 if it is waiting to write to the socket, or will raise
     260          StopIteration if the write operation has completed.
     261
     262          @rtype: iterable
     263          @return: A generator; see above for details.
     264          """
     265          try:
     266              if self.closed:
     267                  raise TLSClosedConnectionError("attempt to write to closed connection")
     268
     269              index = 0
     270              blockSize = 16384
     271              randomizeFirstBlock = True
     272              while 1:
     273                  startIndex = index * blockSize
     274                  endIndex = startIndex + blockSize
     275                  if startIndex >= len(s):
     276                      break
     277                  if endIndex > len(s):
     278                      endIndex = len(s)
     279                  block = bytearray(s[startIndex : endIndex])
     280                  applicationData = ApplicationData().create(block)
     281                  for result in self._sendMsg(applicationData, \
     282                                              randomizeFirstBlock):
     283                      yield result
     284                  randomizeFirstBlock = False #only on 1st message
     285                  index += 1
     286          except GeneratorExit:
     287              raise
     288          except Exception:
     289              self._shutdown(False)
     290              raise
     291
     292 -    def close(self):
     293          """Close the TLS connection.
     294
     295          This function will block until it has exchanged close_notify
     296          alerts with the other party.  After doing so, it will shut down the
     297          TLS connection.  Further attempts to read through this connection
     298          will return "".  Further attempts to write through this connection
     299          will raise ValueError.
     300
     301          If makefile() has been called on this connection, the connection
     302          will be not be closed until the connection object and all file
     303          objects have been closed.
     304
     305          Even if an exception is raised, the connection will have been
     306          closed.
     307
     308          @raise socket.error: If a socket error occurs.
     309          @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
     310          without a preceding alert.
     311          @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
     312          """
     313          if not self.closed:
     314              for result in self._decrefAsync():
     315                  pass
     316
     317      # Python 3 callback
     318      _decref_socketios = close
     319
     320 -    def closeAsync(self):
     321          """Start a close operation on the TLS connection.
     322
     323          This function returns a generator which behaves similarly to
     324          close().  Successive invocations of the generator will return 0
     325          if it is waiting to read from the socket, 1 if it is waiting
     326          to write to the socket, or will raise StopIteration if the
     327          close operation has completed.
     328
     329          @rtype: iterable
     330          @return: A generator; see above for details.
     331          """
     332          if not self.closed:
     333              for result in self._decrefAsync():
     334                  yield result
     335
     336 -    def _decrefAsync(self):
     337          self._refCount -= 1
     338          if self._refCount == 0 and not self.closed:
     339              try:
     340                  for result in self._sendMsg(Alert().create(\
     341                          AlertDescription.close_notify, AlertLevel.warning)):
     342                      yield result
     343                  alert = None
     344                  # By default close the socket, since it's been observed
     345                  # that some other libraries will not respond to the
     346                  # close_notify alert, thus leaving us hanging if we're
     347                  # expecting it
     348                  if self.closeSocket:
     349                      self._shutdown(True)
     350                  else:
     351                      while not alert:
     352                          for result in self._getMsg((ContentType.alert, \
     353                                                    ContentType.application_data)):
     354                              if result in (0,1):
     355                                  yield result
     356                          if result.contentType == ContentType.alert:
     357                              alert = result
     358                      if alert.description == AlertDescription.close_notify:
     359                          self._shutdown(True)
     360                      else:
     361                          raise TLSRemoteAlert(alert)
     362              except (socket.error, TLSAbruptCloseError):
     363                  #If the other side closes the socket, that's okay
     364                  self._shutdown(True)
     365              except GeneratorExit:
     366                  raise
     367              except:
     368                  self._shutdown(False)
     369                  raise
     370
     371 -    def getVersionName(self):
     372          """Get the name of this TLS version.
     373
     374          @rtype: str
     375          @return: The name of the TLS version used with this connection.
     376          Either None, 'SSL 3.0', 'TLS 1.0', or 'TLS 1.1'.
     377          """
     378          if self.version == (3,0):
     379              return "SSL 3.0"
     380          elif self.version == (3,1):
     381              return "TLS 1.0"
     382          elif self.version == (3,2):
     383              return "TLS 1.1"
     384          else:
     385              return None
     386
     387 -    def getCipherName(self):
     388          """Get the name of the cipher used with this connection.
     389
     390          @rtype: str
     391          @return: The name of the cipher used with this connection.
     392          Either 'aes128', 'aes256', 'rc4', or '3des'.
     393          """
     394          if not self._writeState.encContext:
     395              return None
     396          return self._writeState.encContext.name
     397
     398 -    def getCipherImplementation(self):
     399          """Get the name of the cipher implementation used with
     400          this connection.
     401
     402          @rtype: str
     403          @return: The name of the cipher implementation used with
     404          this connection.  Either 'python', 'openssl', or 'pycrypto'.
     405          """
     406          if not self._writeState.encContext:
     407              return None
     408          return self._writeState.encContext.implementation
     409
     410
     411
     412      #Emulate a socket, somewhat -
     413 -    def send(self, s):
     414          """Send data to the TLS connection (socket emulation).
     415
     416          @raise socket.error: If a socket error occurs.
     417          """
     418          self.write(s)
     419          return len(s)
     420
     421 -    def sendall(self, s):
     422          """Send data to the TLS connection (socket emulation).
     423
     424          @raise socket.error: If a socket error occurs.
     425          """
     426          self.write(s)
     427
     428 -    def recv(self, bufsize):
     429          """Get some data from the TLS connection (socket emulation).
     430
     431          @raise socket.error: If a socket error occurs.
     432          @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
     433          without a preceding alert.
     434          @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
     435          """
     436          return self.read(bufsize)
     437
     438 -    def recv_into(self, b):
     439          # XXX doc string
     440          data = self.read(len(b))
     441          if not data:
     442              return None
     443          b[:len(data)] = data
     444          return len(data)
     445
     446 -    def makefile(self, mode='r', bufsize=-1):
     447          """Create a file object for the TLS connection (socket emulation).
     448
     449          @rtype: L{socket._fileobject}
     450          """
     451          self._refCount += 1
     452          # So, it is pretty fragile to be using Python internal objects
     453          # like this, but it is probably the best/easiest way to provide
     454          # matching behavior for socket emulation purposes.  The 'close'
     455          # argument is nice, its apparently a recent addition to this
     456          # class, so that when fileobject.close() gets called, it will
     457          # close() us, causing the refcount to be decremented (decrefAsync).
     458          #
     459          # If this is the last close() on the outstanding fileobjects /
     460          # TLSConnection, then the "actual" close alerts will be sent,
     461          # socket closed, etc.
     462          if sys.version_info < (3,):
     463              return socket._fileobject(self, mode, bufsize, close=True)
     464          else:
     465              # XXX need to wrap this further if buffering is requested
     466              return socket.SocketIO(self, mode)
     467
     468 -    def getsockname(self):
     469          """Return the socket's own address (socket emulation)."""
     470          return self.sock.getsockname()
     471
     472 -    def getpeername(self):
     473          """Return the remote address to which the socket is connected
     474          (socket emulation)."""
     475          return self.sock.getpeername()
     476
     477 -    def settimeout(self, value):
     478          """Set a timeout on blocking socket operations (socket emulation)."""
     479          return self.sock.settimeout(value)
     480
     481 -    def gettimeout(self):
     482          """Return the timeout associated with socket operations (socket
     483          emulation)."""
     484          return self.sock.gettimeout()
     485
     486 -    def setsockopt(self, level, optname, value):
     487          """Set the value of the given socket option (socket emulation)."""
     488          return self.sock.setsockopt(level, optname, value)
     489
     490 -    def shutdown(self, how):
     491          """Shutdown the underlying socket."""
     492          return self.sock.shutdown(how)
     493
     494 -    def fileno(self):
     495          """Not implement in TLS Lite."""
     496          raise NotImplementedError()
     497
     498
     499       #*********************************************************
     500       # Public Functions END
     501       #*********************************************************
     502
     503 -    def _shutdown(self, resumable):
     504          self._writeState = _ConnectionState()
     505          self._readState = _ConnectionState()
     506          self.version = (0,0)
     507          self._versionCheck = False
     508          self.closed = True
     509          if self.closeSocket:
     510              self.sock.close()
     511
     512          #Even if resumable is False, we'll never toggle this on
     513          if not resumable and self.session:
     514              self.session.resumable = False
     515
     516
     517 -    def _sendError(self, alertDescription, errorStr=None):
     518          alert = Alert().create(alertDescription, AlertLevel.fatal)
     519          for result in self._sendMsg(alert):
     520              yield result
     521          self._shutdown(False)
     522          raise TLSLocalAlert(alert, errorStr)
     523
     524 -    def _sendMsgs(self, msgs):
     525          randomizeFirstBlock = True
     526          for msg in msgs:
     527              for result in self._sendMsg(msg, randomizeFirstBlock):
     528                  yield result
     529              randomizeFirstBlock = True
     530
     531 -    def _sendMsg(self, msg, randomizeFirstBlock = True):
     532          #Whenever we're connected and asked to send an app data message,
     533          #we first send the first byte of the message.  This prevents
     534          #an attacker from launching a chosen-plaintext attack based on
     535          #knowing the next IV (a la BEAST).
     536          if not self.closed and randomizeFirstBlock and self.version <= (3,1) \
     537                  and self._writeState.encContext \
     538                  and self._writeState.encContext.isBlockCipher \
     539                  and isinstance(msg, ApplicationData):
     540              msgFirstByte = msg.splitFirstByte()
     541              for result in self._sendMsg(msgFirstByte,
     542                                         randomizeFirstBlock = False):
     543                  yield result
     544
     545          b = msg.write()
     546
     547          # If a 1-byte message was passed in, and we "split" the
     548          # first(only) byte off above, we may have a 0-length msg:
     549          if len(b) == 0:
     550              return
     551
     552          contentType = msg.contentType
     553
     554          #Update handshake hashes
     555          if contentType == ContentType.handshake:
     556              self._handshake_md5.update(compat26Str(b))
     557              self._handshake_sha.update(compat26Str(b))
     558
     559          #Calculate MAC
     560          if self._writeState.macContext:
     561              seqnumBytes = self._writeState.getSeqNumBytes()
     562              mac = self._writeState.macContext.copy()
     563              mac.update(compatHMAC(seqnumBytes))
     564              mac.update(compatHMAC(bytearray([contentType])))
     565              if self.version == (3,0):
     566                  mac.update( compatHMAC( bytearray([len(b)//256] )))
     567                  mac.update( compatHMAC( bytearray([len(b)%256] )))
     568              elif self.version in ((3,1), (3,2)):
     569                  mac.update(compatHMAC( bytearray([self.version[0]] )))
     570                  mac.update(compatHMAC( bytearray([self.version[1]] )))
     571                  mac.update( compatHMAC( bytearray([len(b)//256] )))
     572                  mac.update( compatHMAC( bytearray([len(b)%256] )))
     573              else:
     574                  raise AssertionError()
     575              mac.update(compatHMAC(b))
     576              macBytes = bytearray(mac.digest())
     577              if self.fault == Fault.badMAC:
     578                  macBytes[0] = (macBytes[0]+1) % 256
     579
     580          #Encrypt for Block or Stream Cipher
     581          if self._writeState.encContext:
     582              #Add padding and encrypt (for Block Cipher):
     583              if self._writeState.encContext.isBlockCipher:
     584
     585                  #Add TLS 1.1 fixed block
     586                  if self.version == (3,2):
     587                      b = self.fixedIVBlock + b
     588
     589                  #Add padding: b = b+ (macBytes + paddingBytes)
     590                  currentLength = len(b) + len(macBytes) + 1
     591                  blockLength = self._writeState.encContext.block_size
     592                  paddingLength = blockLength-(currentLength % blockLength)
     593
     594                  paddingBytes = bytearray([paddingLength] * (paddingLength+1))
     595                  if self.fault == Fault.badPadding:
     596                      paddingBytes[0] = (paddingBytes[0]+1) % 256
     597                  endBytes = macBytes + paddingBytes
     598                  b += endBytes
     599                  #Encrypt
     600                  b = self._writeState.encContext.encrypt(b)
     601
     602              #Encrypt (for Stream Cipher)
     603              else:
     604                  b += macBytes
     605                  b = self._writeState.encContext.encrypt(b)
     606
     607          #Add record header and send
     608          r = RecordHeader3().create(self.version, contentType, len(b))
     609          s = r.write() + b
     610          while 1:
     611              try:
     612                  bytesSent = self.sock.send(s) #Might raise socket.error
     613              except socket.error as why:
     614                  if why.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):
     615                      yield 1
     616                      continue
     617                  else:
     618                      # The socket was unexpectedly closed.  The tricky part
     619                      # is that there may be an alert sent by the other party
     620                      # sitting in the read buffer.  So, if we get here after
     621                      # handshaking, we will just raise the error and let the
     622                      # caller read more data if it would like, thus stumbling
     623                      # upon the error.
     624                      #
     625                      # However, if we get here DURING handshaking, we take
     626                      # it upon ourselves to see if the next message is an
     627                      # Alert.
     628                      if contentType == ContentType.handshake:
     629
     630                          # See if there's an alert record
     631                          # Could raise socket.error or TLSAbruptCloseError
     632                          for result in self._getNextRecord():
     633                              if result in (0,1):
     634                                  yield result
     635
     636                          # Closes the socket
     637                          self._shutdown(False)
     638
     639                          # If we got an alert, raise it
     640                          recordHeader, p = result
     641                          if recordHeader.type == ContentType.alert:
     642                              alert = Alert().parse(p)
     643                              raise TLSRemoteAlert(alert)
     644                      else:
     645                          # If we got some other message who know what
     646                          # the remote side is doing, just go ahead and
     647                          # raise the socket.error
     648                          raise
     649              if bytesSent == len(s):
     650                  return
     651              s = s[bytesSent:]
     652              yield 1
     653
     654
     655 -    def _getMsg(self, expectedType, secondaryType=None, constructorType=None):
     656          try:
     657              if not isinstance(expectedType, tuple):
     658                  expectedType = (expectedType,)
     659
     660              #Spin in a loop, until we've got a non-empty record of a type we
     661              #expect.  The loop will be repeated if:
     662              #  - we receive a renegotiation attempt; we send no_renegotiation,
     663              #    then try again
     664              #  - we receive an empty application-data fragment; we try again
     665              while 1:
     666                  for result in self._getNextRecord():
     667                      if result in (0,1):
     668                          yield result
     669                  recordHeader, p = result
     670
     671                  #If this is an empty application-data fragment, try again
     672                  if recordHeader.type == ContentType.application_data:
     673                      if p.index == len(p.bytes):
     674                          continue
     675
     676                  #If we received an unexpected record type...
     677                  if recordHeader.type not in expectedType:
     678
     679                      #If we received an alert...
     680                      if recordHeader.type == ContentType.alert:
     681                          alert = Alert().parse(p)
     682
     683                          #We either received a fatal error, a warning, or a
     684                          #close_notify.  In any case, we're going to close the
     685                          #connection.  In the latter two cases we respond with
     686                          #a close_notify, but ignore any socket errors, since
     687                          #the other side might have already closed the socket.
     688                          if alert.level == AlertLevel.warning or \
     689                             alert.description == AlertDescription.close_notify:
     690
     691                              #If the sendMsg() call fails because the socket has
     692                              #already been closed, we will be forgiving and not
     693                              #report the error nor invalidate the "resumability"
     694                              #of the session.
     695                              try:
     696                                  alertMsg = Alert()
     697                                  alertMsg.create(AlertDescription.close_notify,
     698                                                  AlertLevel.warning)
     699                                  for result in self._sendMsg(alertMsg):
     700                                      yield result
     701                              except socket.error:
     702                                  pass
     703
     704                              if alert.description == \
     705                                     AlertDescription.close_notify:
     706                                  self._shutdown(True)
     707                              elif alert.level == AlertLevel.warning:
     708                                  self._shutdown(False)
     709
     710                          else: #Fatal alert:
     711                              self._shutdown(False)
     712
     713                          #Raise the alert as an exception
     714                          raise TLSRemoteAlert(alert)
     715
     716                      #If we received a renegotiation attempt...
     717                      if recordHeader.type == ContentType.handshake:
     718                          subType = p.get(1)
     719                          reneg = False
     720                          if self._client:
     721                              if subType == HandshakeType.hello_request:
     722                                  reneg = True
     723                          else:
     724                              if subType == HandshakeType.client_hello:
     725                                  reneg = True
     726                          #Send no_renegotiation, then try again
     727                          if reneg:
     728                              alertMsg = Alert()
     729                              alertMsg.create(AlertDescription.no_renegotiation,
     730                                              AlertLevel.warning)
     731                              for result in self._sendMsg(alertMsg):
     732                                  yield result
     733                              continue
     734
     735                      #Otherwise: this is an unexpected record, but neither an
     736                      #alert nor renegotiation
     737                      for result in self._sendError(\
     738                              AlertDescription.unexpected_message,
     739                              "received type=%d" % recordHeader.type):
     740                          yield result
     741
     742                  break
     743
     744              #Parse based on content_type
     745              if recordHeader.type == ContentType.change_cipher_spec:
     746                  yield ChangeCipherSpec().parse(p)
     747              elif recordHeader.type == ContentType.alert:
     748                  yield Alert().parse(p)
     749              elif recordHeader.type == ContentType.application_data:
     750                  yield ApplicationData().parse(p)
     751              elif recordHeader.type == ContentType.handshake:
     752                  #Convert secondaryType to tuple, if it isn't already
     753                  if not isinstance(secondaryType, tuple):
     754                      secondaryType = (secondaryType,)
     755
     756                  #If it's a handshake message, check handshake header
     757                  if recordHeader.ssl2:
     758                      subType = p.get(1)
     759                      if subType != HandshakeType.client_hello:
     760                          for result in self._sendError(\
     761                                  AlertDescription.unexpected_message,
     762                                  "Can only handle SSLv2 ClientHello messages"):
     763                              yield result
     764                      if HandshakeType.client_hello not in secondaryType:
     765                          for result in self._sendError(\
     766                                  AlertDescription.unexpected_message):
     767                              yield result
     768                      subType = HandshakeType.client_hello
     769                  else:
     770                      subType = p.get(1)
     771                      if subType not in secondaryType:
     772                          for result in self._sendError(\
     773                                  AlertDescription.unexpected_message,
     774                                  "Expecting %s, got %s" % (str(secondaryType), subType)):
     775                              yield result
     776
     777                  #Update handshake hashes
     778                  self._handshake_md5.update(compat26Str(p.bytes))
     779                  self._handshake_sha.update(compat26Str(p.bytes))
     780
     781                  #Parse based on handshake type
     782                  if subType == HandshakeType.client_hello:
     783                      yield ClientHello(recordHeader.ssl2).parse(p)
     784                  elif subType == HandshakeType.server_hello:
     785                      yield ServerHello().parse(p)
     786                  elif subType == HandshakeType.certificate:
     787                      yield Certificate(constructorType).parse(p)
     788                  elif subType == HandshakeType.certificate_request:
     789                      yield CertificateRequest().parse(p)
     790                  elif subType == HandshakeType.certificate_verify:
     791                      yield CertificateVerify().parse(p)
     792                  elif subType == HandshakeType.server_key_exchange:
     793                      yield ServerKeyExchange(constructorType).parse(p)
     794                  elif subType == HandshakeType.server_hello_done:
     795                      yield ServerHelloDone().parse(p)
     796                  elif subType == HandshakeType.client_key_exchange:
     797                      yield ClientKeyExchange(constructorType, \
     798                                              self.version).parse(p)
     799                  elif subType == HandshakeType.finished:
     800                      yield Finished(self.version).parse(p)
     801                  elif subType == HandshakeType.next_protocol:
     802                      yield NextProtocol().parse(p)
     803                  else:
     804                      raise AssertionError()
     805
     806          #If an exception was raised by a Parser or Message instance:
     807          except SyntaxError as e:
     808              for result in self._sendError(AlertDescription.decode_error,
     809                                           formatExceptionTrace(e)):
     810                  yield result
     811
     812
     813      #Returns next record or next handshake message
     814 -    def _getNextRecord(self):
     815
     816          #If there's a handshake message waiting, return it
     817          if self._handshakeBuffer:
     818              recordHeader, b = self._handshakeBuffer[0]
     819              self._handshakeBuffer = self._handshakeBuffer[1:]
     820              yield (recordHeader, Parser(b))
     821              return
     822
     823          #Otherwise...
     824          #Read the next record header
     825          b = bytearray(0)
     826          recordHeaderLength = 1
     827          ssl2 = False
     828          while 1:
     829              try:
     830                  s = self.sock.recv(recordHeaderLength-len(b))
     831              except socket.error as why:
     832                  if why.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):
     833                      yield 0
     834                      continue
     835                  else:
     836                      raise
     837
     838              #If the connection was abruptly closed, raise an error
     839              if len(s)==0:
     840                  raise TLSAbruptCloseError()
     841
     842              b += bytearray(s)
     843              if len(b)==1:
     844                  if b[0] in ContentType.all:
     845                      ssl2 = False
     846                      recordHeaderLength = 5
     847                  elif b[0] == 128:
     848                      ssl2 = True
     849                      recordHeaderLength = 2
     850                  else:
     851                      raise SyntaxError()
     852              if len(b) == recordHeaderLength:
     853                  break
     854
     855          #Parse the record header
     856          if ssl2:
     857              r = RecordHeader2().parse(Parser(b))
     858          else:
     859              r = RecordHeader3().parse(Parser(b))
     860
     861          #Check the record header fields
     862          if r.length > 18432:
     863              for result in self._sendError(AlertDescription.record_overflow):
     864                  yield result
     865
     866          #Read the record contents
     867          b = bytearray(0)
     868          while 1:
     869              try:
     870                  s = self.sock.recv(r.length - len(b))
     871              except socket.error as why:
     872                  if why.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):
     873                      yield 0
     874                      continue
     875                  else:
     876                      raise
     877
     878              #If the connection is closed, raise a socket error
     879              if len(s)==0:
     880                      raise TLSAbruptCloseError()
     881
     882              b += bytearray(s)
     883              if len(b) == r.length:
     884                  break
     885
     886          #Check the record header fields (2)
     887          #We do this after reading the contents from the socket, so that
     888          #if there's an error, we at least don't leave extra bytes in the
     889          #socket..
     890          #
     891          # THIS CHECK HAS NO SECURITY RELEVANCE (?), BUT COULD HURT INTEROP.
     892          # SO WE LEAVE IT OUT FOR NOW.
     893          #
     894          #if self._versionCheck and r.version != self.version:
     895          #    for result in self._sendError(AlertDescription.protocol_version,
     896          #            "Version in header field: %s, should be %s" % (str(r.version),
     897          #                                                       str(self.version))):
     898          #        yield result
     899
     900          #Decrypt the record
     901          for result in self._decryptRecord(r.type, b):
     902              if result in (0,1): yield result
     903              else: break
     904          b = result
     905          p = Parser(b)
     906
     907          #If it doesn't contain handshake messages, we can just return it
     908          if r.type != ContentType.handshake:
     909              yield (r, p)
     910          #If it's an SSLv2 ClientHello, we can return it as well
     911          elif r.ssl2:
     912              yield (r, p)
     913          else:
     914              #Otherwise, we loop through and add the handshake messages to the
     915              #handshake buffer
     916              while 1:
     917                  if p.index == len(b): #If we're at the end
     918                      if not self._handshakeBuffer:
     919                          for result in self._sendError(\
     920                                  AlertDescription.decode_error, \
     921                                  "Received empty handshake record"):
     922                              yield result
     923                      break
     924                  #There needs to be at least 4 bytes to get a header
     925                  if p.index+4 > len(b):
     926                      for result in self._sendError(\
     927                              AlertDescription.decode_error,
     928                              "A record has a partial handshake message (1)"):
     929                          yield result
     930                  p.get(1) # skip handshake type
     931                  msgLength = p.get(3)
     932                  if p.index+msgLength > len(b):
     933                      for result in self._sendError(\
     934                              AlertDescription.decode_error,
     935                              "A record has a partial handshake message (2)"):
     936                          yield result
     937
     938                  handshakePair = (r, b[p.index-4 : p.index+msgLength])
     939                  self._handshakeBuffer.append(handshakePair)
     940                  p.index += msgLength
     941
     942              #We've moved at least one handshake message into the
     943              #handshakeBuffer, return the first one
     944              recordHeader, b = self._handshakeBuffer[0]
     945              self._handshakeBuffer = self._handshakeBuffer[1:]
     946              yield (recordHeader, Parser(b))
     947
     948
     949 -    def _decryptRecord(self, recordType, b):
     950          if self._readState.encContext:
     951
     952              #Decrypt if it's a block cipher
     953              if self._readState.encContext.isBlockCipher:
     954                  blockLength = self._readState.encContext.block_size
     955                  if len(b) % blockLength != 0:
     956                      for result in self._sendError(\
     957                              AlertDescription.decryption_failed,
     958                              "Encrypted data not a multiple of blocksize"):
     959                          yield result
     960                  b = self._readState.encContext.decrypt(b)
     961                  if self.version == (3,2): #For TLS 1.1, remove explicit IV
     962                      b = b[self._readState.encContext.block_size : ]
     963
     964                  #Check padding
     965                  paddingGood = True
     966                  paddingLength = b[-1]
     967                  if (paddingLength+1) > len(b):
     968                      paddingGood=False
     969                      totalPaddingLength = 0
     970                  else:
     971                      if self.version == (3,0):
     972                          totalPaddingLength = paddingLength+1
     973                      elif self.version in ((3,1), (3,2)):
     974                          totalPaddingLength = paddingLength+1
     975                          paddingBytes = b[-totalPaddingLength:-1]
     976                          for byte in paddingBytes:
     977                              if byte != paddingLength:
     978                                  paddingGood = False
     979                                  totalPaddingLength = 0
     980                      else:
     981                          raise AssertionError()
     982
     983              #Decrypt if it's a stream cipher
     984              else:
     985                  paddingGood = True
     986                  b = self._readState.encContext.decrypt(b)
     987                  totalPaddingLength = 0
     988
     989              #Check MAC
     990              macGood = True
     991              macLength = self._readState.macContext.digest_size
     992              endLength = macLength + totalPaddingLength
     993              if endLength > len(b):
     994                  macGood = False
     995              else:
     996                  #Read MAC
     997                  startIndex = len(b) - endLength
     998                  endIndex = startIndex + macLength
     999                  checkBytes = b[startIndex : endIndex]
    1000
    1001                  #Calculate MAC
    1002                  seqnumBytes = self._readState.getSeqNumBytes()
    1003                  b = b[:-endLength]
    1004                  mac = self._readState.macContext.copy()
    1005                  mac.update(compatHMAC(seqnumBytes))
    1006                  mac.update(compatHMAC(bytearray([recordType])))
    1007                  if self.version == (3,0):
    1008                      mac.update( compatHMAC(bytearray( [len(b)//256] ) ))
    1009                      mac.update( compatHMAC(bytearray( [len(b)%256] ) ))
    1010                  elif self.version in ((3,1), (3,2)):
    1011                      mac.update(compatHMAC(bytearray( [self.version[0]] ) ))
    1012                      mac.update(compatHMAC(bytearray( [self.version[1]] ) ))
    1013                      mac.update(compatHMAC(bytearray( [len(b)//256] ) ))
    1014                      mac.update(compatHMAC(bytearray( [len(b)%256] ) ))
    1015                  else:
    1016                      raise AssertionError()
    1017                  mac.update(compatHMAC(b))
    1018                  macBytes = bytearray(mac.digest())
    1019
    1020                  #Compare MACs
    1021                  if macBytes != checkBytes:
    1022                      macGood = False
    1023
    1024              if not (paddingGood and macGood):
    1025                  for result in self._sendError(AlertDescription.bad_record_mac,
    1026                                            "MAC failure (or padding failure)"):
    1027                      yield result
    1028
    1029          yield b
    1030
    1031 -    def _handshakeStart(self, client):
    1032          if not self.closed:
    1033              raise ValueError("Renegotiation disallowed for security reasons")
    1034          self._client = client
    1035          self._handshake_md5 = hashlib.md5()
    1036          self._handshake_sha = hashlib.sha1()
    1037          self._handshakeBuffer = []
    1038          self.allegedSrpUsername = None
    1039          self._refCount = 1
    1040
    1041 -    def _handshakeDone(self, resumed):
    1042          self.resumed = resumed
    1043          self.closed = False
    1044
    1045 -    def _calcPendingStates(self, cipherSuite, masterSecret,
    1046              clientRandom, serverRandom, implementations):
    1047          if cipherSuite in CipherSuite.aes128Suites:
    1048              keyLength = 16
    1049              ivLength = 16
    1050              createCipherFunc = createAES
    1051          elif cipherSuite in CipherSuite.aes256Suites:
    1052              keyLength = 32
    1053              ivLength = 16
    1054              createCipherFunc = createAES
    1055          elif cipherSuite in CipherSuite.rc4Suites:
    1056              keyLength = 16
    1057              ivLength = 0
    1058              createCipherFunc = createRC4
    1059          elif cipherSuite in CipherSuite.tripleDESSuites:
    1060              keyLength = 24
    1061              ivLength = 8
    1062              createCipherFunc = createTripleDES
    1063          else:
    1064              raise AssertionError()
    1065
    1066          if cipherSuite in CipherSuite.shaSuites:
    1067              macLength = 20
    1068              digestmod = hashlib.sha1
    1069          elif cipherSuite in CipherSuite.md5Suites:
    1070              macLength = 16
    1071              digestmod = hashlib.md5
    1072
    1073          if self.version == (3,0):
    1074              createMACFunc = createMAC_SSL
    1075          elif self.version in ((3,1), (3,2)):
    1076              createMACFunc = createHMAC
    1077
    1078          outputLength = (macLength*2) + (keyLength*2) + (ivLength*2)
    1079
    1080          #Calculate Keying Material from Master Secret
    1081          if self.version == (3,0):
    1082              keyBlock = PRF_SSL(masterSecret,
    1083                                 serverRandom + clientRandom,
    1084                                 outputLength)
    1085          elif self.version in ((3,1), (3,2)):
    1086              keyBlock = PRF(masterSecret,
    1087                             b"key expansion",
    1088                             serverRandom + clientRandom,
    1089                             outputLength)
    1090          else:
    1091              raise AssertionError()
    1092
    1093          #Slice up Keying Material
    1094          clientPendingState = _ConnectionState()
    1095          serverPendingState = _ConnectionState()
    1096          p = Parser(keyBlock)
    1097          clientMACBlock = p.getFixBytes(macLength)
    1098          serverMACBlock = p.getFixBytes(macLength)
    1099          clientKeyBlock = p.getFixBytes(keyLength)
    1100          serverKeyBlock = p.getFixBytes(keyLength)
    1101          clientIVBlock  = p.getFixBytes(ivLength)
    1102          serverIVBlock  = p.getFixBytes(ivLength)
    1103          clientPendingState.macContext = createMACFunc(
    1104              compatHMAC(clientMACBlock), digestmod=digestmod)
    1105          serverPendingState.macContext = createMACFunc(
    1106              compatHMAC(serverMACBlock), digestmod=digestmod)
    1107          clientPendingState.encContext = createCipherFunc(clientKeyBlock,
    1108                                                           clientIVBlock,
    1109                                                           implementations)
    1110          serverPendingState.encContext = createCipherFunc(serverKeyBlock,
    1111                                                           serverIVBlock,
    1112                                                           implementations)
    1113
    1114          #Assign new connection states to pending states
    1115          if self._client:
    1116              self._pendingWriteState = clientPendingState
    1117              self._pendingReadState = serverPendingState
    1118          else:
    1119              self._pendingWriteState = serverPendingState
    1120              self._pendingReadState = clientPendingState
    1121
    1122          if self.version == (3,2) and ivLength:
    1123              #Choose fixedIVBlock for TLS 1.1 (this is encrypted with the CBC
    1124              #residue to create the IV for each sent block)
    1125              self.fixedIVBlock = getRandomBytes(ivLength)
    1126
    1127 -    def _changeWriteState(self):
    1128          self._writeState = self._pendingWriteState
    1129          self._pendingWriteState = _ConnectionState()
    1130
    1131 -    def _changeReadState(self):
    1132          self._readState = self._pendingReadState
    1133          self._pendingReadState = _ConnectionState()
    1134
    1135      #Used for Finished messages and CertificateVerify messages in SSL v3
    1136 -    def _calcSSLHandshakeHash(self, masterSecret, label):
    1137          imac_md5 = self._handshake_md5.copy()
    1138          imac_sha = self._handshake_sha.copy()
    1139
    1140          imac_md5.update(compatHMAC(label + masterSecret + bytearray([0x36]*48)))
    1141          imac_sha.update(compatHMAC(label + masterSecret + bytearray([0x36]*40)))
    1142
    1143          md5Bytes = MD5(masterSecret + bytearray([0x5c]*48) + \
    1144                           bytearray(imac_md5.digest()))
    1145          shaBytes = SHA1(masterSecret + bytearray([0x5c]*40) + \
    1146                           bytearray(imac_sha.digest()))
    1147
    1148          return md5Bytes + shaBytes
    1149