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