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  #
       5  # See the LICENSE file for legal information regarding use of this file.
       6
       7  """Helper class for TLSConnection."""
       8  from __future__ import generators
       9
      10  from .utils.compat import *
      11  from .utils.cryptomath import *
      12  from .utils.cipherfactory import createAES, createRC4, createTripleDES
      13  from .utils.codec import *
      14  from .errors import *
      15  from .messages import *
      16  from .mathtls import *
      17  from .constants import *
      18  from .utils.cryptomath import getRandomBytes
      19
      20  import socket
      21  import errno
      22  import traceback
      23
      24 -class _ConnectionState:
      25 -    def __init__(self):
      26          self.macContext = None
      27          self.encContext = None
      28          self.seqnum = 0
      29
      30 -    def getSeqNumStr(self):
      31          w = Writer()
      32          w.add(self.seqnum, 8)
      33          seqnumStr = bytesToString(w.bytes)
      34          self.seqnum += 1
      35          return seqnumStr
      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 = ""
     113
     114          #Handshake digests
     115          self._handshake_md5 = md5()
     116          self._handshake_sha = 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 += bytesToString(applicationData.write())
     201                  except TLSRemoteAlert, 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              returnStr = self._readBuffer[:max]
     214              self._readBuffer = self._readBuffer[max:]
     215              yield returnStr
     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 = stringToBytes(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 -    def closeAsync(self):
     302          """Start a close operation on the TLS connection.
     303
     304          This function returns a generator which behaves similarly to
     305          close().  Successive invocations of the generator will return 0
     306          if it is waiting to read from the socket, 1 if it is waiting
     307          to write to the socket, or will raise StopIteration if the
     308          close operation has completed.
     309
     310          @rtype: iterable
     311          @return: A generator; see above for details.
     312          """
     313          if not self.closed:
     314              for result in self._decrefAsync():
     315                  yield result
     316
     317 -    def _decrefAsync(self):
     318          self._refCount -= 1
     319          if self._refCount == 0 and not self.closed:
     320              try:
     321                  for result in self._sendMsg(Alert().create(\
     322                          AlertDescription.close_notify, AlertLevel.warning)):
     323                      yield result
     324                  alert = None
     325                  # By default close the socket, since it's been observed
     326                  # that some other libraries will not respond to the
     327                  # close_notify alert, thus leaving us hanging if we're
     328                  # expecting it
     329                  if self.closeSocket:
     330                      self._shutdown(True)
     331                  else:
     332                      while not alert:
     333                          for result in self._getMsg((ContentType.alert, \
     334                                                    ContentType.application_data)):
     335                              if result in (0,1):
     336                                  yield result
     337                          if result.contentType == ContentType.alert:
     338                              alert = result
     339                      if alert.description == AlertDescription.close_notify:
     340                          self._shutdown(True)
     341                      else:
     342                          raise TLSRemoteAlert(alert)
     343              except (socket.error, TLSAbruptCloseError):
     344                  #If the other side closes the socket, that's okay
     345                  self._shutdown(True)
     346              except GeneratorExit:
     347                  raise
     348              except:
     349                  self._shutdown(False)
     350                  raise
     351
     352 -    def getVersionName(self):
     353          """Get the name of this TLS version.
     354
     355          @rtype: str
     356          @return: The name of the TLS version used with this connection.
     357          Either None, 'SSL 3.0', 'TLS 1.0', or 'TLS 1.1'.
     358          """
     359          if self.version == (3,0):
     360              return "SSL 3.0"
     361          elif self.version == (3,1):
     362              return "TLS 1.0"
     363          elif self.version == (3,2):
     364              return "TLS 1.1"
     365          else:
     366              return None
     367
     368 -    def getCipherName(self):
     369          """Get the name of the cipher used with this connection.
     370
     371          @rtype: str
     372          @return: The name of the cipher used with this connection.
     373          Either 'aes128', 'aes256', 'rc4', or '3des'.
     374          """
     375          if not self._writeState.encContext:
     376              return None
     377          return self._writeState.encContext.name
     378
     379 -    def getCipherImplementation(self):
     380          """Get the name of the cipher implementation used with
     381          this connection.
     382
     383          @rtype: str
     384          @return: The name of the cipher implementation used with
     385          this connection.  Either 'python', 'openssl', or 'pycrypto'.
     386          """
     387          if not self._writeState.encContext:
     388              return None
     389          return self._writeState.encContext.implementation
     390
     391
     392
     393      #Emulate a socket, somewhat -
     394 -    def send(self, s):
     395          """Send data to the TLS connection (socket emulation).
     396
     397          @raise socket.error: If a socket error occurs.
     398          """
     399          self.write(s)
     400          return len(s)
     401
     402 -    def sendall(self, s):
     403          """Send data to the TLS connection (socket emulation).
     404
     405          @raise socket.error: If a socket error occurs.
     406          """
     407          self.write(s)
     408
     409 -    def recv(self, bufsize):
     410          """Get some data from the TLS connection (socket emulation).
     411
     412          @raise socket.error: If a socket error occurs.
     413          @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed
     414          without a preceding alert.
     415          @raise tlslite.errors.TLSAlert: If a TLS alert is signalled.
     416          """
     417          return self.read(bufsize)
     418
     419 -    def makefile(self, mode='r', bufsize=-1):
     420          """Create a file object for the TLS connection (socket emulation).
     421
     422          @rtype: L{socket._fileobject}
     423          """
     424          self._refCount += 1
     425          # So, it is pretty fragile to be using Python internal objects
     426          # like this, but it is probably the best/easiest way to provide
     427          # matching behavior for socket emulation purposes.  The 'close'
     428          # argument is nice, its apparently a recent addition to this
     429          # class, so that when fileobject.close() gets called, it will
     430          # close() us, causing the refcount to be decremented (decrefAsync).
     431          #
     432          # If this is the last close() on the outstanding fileobjects /
     433          # TLSConnection, then the "actual" close alerts will be sent,
     434          # socket closed, etc.
     435          return socket._fileobject(self, mode, bufsize, close=True)
     436
     437 -    def getsockname(self):
     438          """Return the socket's own address (socket emulation)."""
     439          return self.sock.getsockname()
     440
     441 -    def getpeername(self):
     442          """Return the remote address to which the socket is connected
     443          (socket emulation)."""
     444          return self.sock.getpeername()
     445
     446 -    def settimeout(self, value):
     447          """Set a timeout on blocking socket operations (socket emulation)."""
     448          return self.sock.settimeout(value)
     449
     450 -    def gettimeout(self):
     451          """Return the timeout associated with socket operations (socket
     452          emulation)."""
     453          return self.sock.gettimeout()
     454
     455 -    def setsockopt(self, level, optname, value):
     456          """Set the value of the given socket option (socket emulation)."""
     457          return self.sock.setsockopt(level, optname, value)
     458
     459 -    def shutdown(self, how):
     460          """Shutdown the underlying socket."""
     461          return self.sock.shutdown(how)
     462
     463 -    def fileno(self):
     464          """Not implement in TLS Lite."""
     465          raise NotImplementedError()
     466
     467
     468       #*********************************************************
     469       # Public Functions END
     470       #*********************************************************
     471
     472 -    def _shutdown(self, resumable):
     473          self._writeState = _ConnectionState()
     474          self._readState = _ConnectionState()
     475          #Don't do this: self._readBuffer = ""
     476          self.version = (0,0)
     477          self._versionCheck = False
     478          self.closed = True
     479          if self.closeSocket:
     480              self.sock.close()
     481
     482          #Even if resumable is False, we'll never toggle this on
     483          if not resumable and self.session:
     484              self.session.resumable = False
     485
     486
     487 -    def _sendError(self, alertDescription, errorStr=None):
     488          alert = Alert().create(alertDescription, AlertLevel.fatal)
     489          for result in self._sendMsg(alert):
     490              yield result
     491          self._shutdown(False)
     492          raise TLSLocalAlert(alert, errorStr)
     493
     494 -    def _sendMsgs(self, msgs):
     495          randomizeFirstBlock = True
     496          for msg in msgs:
     497              for result in self._sendMsg(msg, randomizeFirstBlock):
     498                  yield result
     499              randomizeFirstBlock = True
     500
     501 -    def _sendMsg(self, msg, randomizeFirstBlock = True):
     502          #Whenever we're connected and asked to send an app data message,
     503          #we first send the first byte of the message.  This prevents
     504          #an attacker from launching a chosen-plaintext attack based on
     505          #knowing the next IV (a la BEAST).
     506          if not self.closed and randomizeFirstBlock and self.version <= (3,1) \
     507                  and self._writeState.encContext \
     508                  and self._writeState.encContext.isBlockCipher \
     509                  and isinstance(msg, ApplicationData):
     510              msgFirstByte = msg.splitFirstByte()
     511              for result in self._sendMsg(msgFirstByte,
     512                                         randomizeFirstBlock = False):
     513                  yield result
     514
     515          bytes = msg.write()
     516
     517          # If a 1-byte message was passed in, and we "split" the
     518          # first(only) byte off above, we may have a 0-length msg:
     519          if len(bytes) == 0:
     520              return
     521
     522          contentType = msg.contentType
     523
     524          #Update handshake hashes
     525          if contentType == ContentType.handshake:
     526              bytesStr = bytesToString(bytes)
     527              self._handshake_md5.update(bytesStr)
     528              self._handshake_sha.update(bytesStr)
     529
     530          #Calculate MAC
     531          if self._writeState.macContext:
     532              seqnumStr = self._writeState.getSeqNumStr()
     533              bytesStr = bytesToString(bytes)
     534              mac = self._writeState.macContext.copy()
     535              mac.update(seqnumStr)
     536              mac.update(chr(contentType))
     537              if self.version == (3,0):
     538                  mac.update( chr( len(bytes)//256 ) )
     539                  mac.update( chr( len(bytes)%256 ) )
     540              elif self.version in ((3,1), (3,2)):
     541                  mac.update(chr(self.version[0]))
     542                  mac.update(chr(self.version[1]))
     543                  mac.update( chr( len(bytes)//256 ) )
     544                  mac.update( chr( len(bytes)%256 ) )
     545              else:
     546                  raise AssertionError()
     547              mac.update(bytesStr)
     548              macString = mac.digest()
     549              macBytes = stringToBytes(macString)
     550              if self.fault == Fault.badMAC:
     551                  macBytes[0] = (macBytes[0]+1) % 256
     552
     553          #Encrypt for Block or Stream Cipher
     554          if self._writeState.encContext:
     555              #Add padding and encrypt (for Block Cipher):
     556              if self._writeState.encContext.isBlockCipher:
     557
     558                  #Add TLS 1.1 fixed block
     559                  if self.version == (3,2):
     560                      bytes = self.fixedIVBlock + bytes
     561
     562                  #Add padding: bytes = bytes + (macBytes + paddingBytes)
     563                  currentLength = len(bytes) + len(macBytes) + 1
     564                  blockLength = self._writeState.encContext.block_size
     565                  paddingLength = blockLength-(currentLength % blockLength)
     566
     567                  paddingBytes = createByteArraySequence([paddingLength] * \
     568                                                         (paddingLength+1))
     569                  if self.fault == Fault.badPadding:
     570                      paddingBytes[0] = (paddingBytes[0]+1) % 256
     571                  endBytes = macBytes + paddingBytes
     572                  bytes += endBytes
     573                  #Encrypt
     574                  plaintext = stringToBytes(bytes)
     575                  ciphertext = self._writeState.encContext.encrypt(plaintext)
     576                  bytes = stringToBytes(ciphertext)
     577
     578              #Encrypt (for Stream Cipher)
     579              else:
     580                  bytes += macBytes
     581                  plaintext = bytesToString(bytes)
     582                  ciphertext = self._writeState.encContext.encrypt(plaintext)
     583                  bytes = stringToBytes(ciphertext)
     584
     585          #Add record header and send
     586          r = RecordHeader3().create(self.version, contentType, len(bytes))
     587          s = bytesToString(r.write() + bytes)
     588          while 1:
     589              try:
     590                  bytesSent = self.sock.send(s) #Might raise socket.error
     591              except socket.error, why:
     592                  if why[0] == errno.EWOULDBLOCK:
     593                      yield 1
     594                      continue
     595                  else:
     596                      # The socket was unexpectedly closed.  The tricky part
     597                      # is that there may be an alert sent by the other party
     598                      # sitting in the read buffer.  So, if we get here after
     599                      # handshaking, we will just raise the error and let the
     600                      # caller read more data if it would like, thus stumbling
     601                      # upon the error.
     602                      #
     603                      # However, if we get here DURING handshaking, we take
     604                      # it upon ourselves to see if the next message is an
     605                      # Alert.
     606                      if contentType == ContentType.handshake:
     607
     608                          # See if there's an alert record
     609                          # Could raise socket.error or TLSAbruptCloseError
     610                          for result in self._getNextRecord():
     611                              if result in (0,1):
     612                                  yield result
     613
     614                          # Closes the socket
     615                          self._shutdown(False)
     616
     617                          # If we got an alert, raise it
     618                          recordHeader, p = result
     619                          if recordHeader.type == ContentType.alert:
     620                              alert = Alert().parse(p)
     621                              raise TLSRemoteAlert(alert)
     622                      else:
     623                          # If we got some other message who know what
     624                          # the remote side is doing, just go ahead and
     625                          # raise the socket.error
     626                          raise
     627              if bytesSent == len(s):
     628                  return
     629              s = s[bytesSent:]
     630              yield 1
     631
     632
     633 -    def _getMsg(self, expectedType, secondaryType=None, constructorType=None):
     634          try:
     635              if not isinstance(expectedType, tuple):
     636                  expectedType = (expectedType,)
     637
     638              #Spin in a loop, until we've got a non-empty record of a type we
     639              #expect.  The loop will be repeated if:
     640              #  - we receive a renegotiation attempt; we send no_renegotiation,
     641              #    then try again
     642              #  - we receive an empty application-data fragment; we try again
     643              while 1:
     644                  for result in self._getNextRecord():
     645                      if result in (0,1):
     646                          yield result
     647                  recordHeader, p = result
     648
     649                  #If this is an empty application-data fragment, try again
     650                  if recordHeader.type == ContentType.application_data:
     651                      if p.index == len(p.bytes):
     652                          continue
     653
     654                  #If we received an unexpected record type...
     655                  if recordHeader.type not in expectedType:
     656
     657                      #If we received an alert...
     658                      if recordHeader.type == ContentType.alert:
     659                          alert = Alert().parse(p)
     660
     661                          #We either received a fatal error, a warning, or a
     662                          #close_notify.  In any case, we're going to close the
     663                          #connection.  In the latter two cases we respond with
     664                          #a close_notify, but ignore any socket errors, since
     665                          #the other side might have already closed the socket.
     666                          if alert.level == AlertLevel.warning or \
     667                             alert.description == AlertDescription.close_notify:
     668
     669                              #If the sendMsg() call fails because the socket has
     670                              #already been closed, we will be forgiving and not
     671                              #report the error nor invalidate the "resumability"
     672                              #of the session.
     673                              try:
     674                                  alertMsg = Alert()
     675                                  alertMsg.create(AlertDescription.close_notify,
     676                                                  AlertLevel.warning)
     677                                  for result in self._sendMsg(alertMsg):
     678                                      yield result
     679                              except socket.error:
     680                                  pass
     681
     682                              if alert.description == \
     683                                     AlertDescription.close_notify:
     684                                  self._shutdown(True)
     685                              elif alert.level == AlertLevel.warning:
     686                                  self._shutdown(False)
     687
     688                          else: #Fatal alert:
     689                              self._shutdown(False)
     690
     691                          #Raise the alert as an exception
     692                          raise TLSRemoteAlert(alert)
     693
     694                      #If we received a renegotiation attempt...
     695                      if recordHeader.type == ContentType.handshake:
     696                          subType = p.get(1)
     697                          reneg = False
     698                          if self._client:
     699                              if subType == HandshakeType.hello_request:
     700                                  reneg = True
     701                          else:
     702                              if subType == HandshakeType.client_hello:
     703                                  reneg = True
     704                          #Send no_renegotiation, then try again
     705                          if reneg:
     706                              alertMsg = Alert()
     707                              alertMsg.create(AlertDescription.no_renegotiation,
     708                                              AlertLevel.warning)
     709                              for result in self._sendMsg(alertMsg):
     710                                  yield result
     711                              continue
     712
     713                      #Otherwise: this is an unexpected record, but neither an
     714                      #alert nor renegotiation
     715                      for result in self._sendError(\
     716                              AlertDescription.unexpected_message,
     717                              "received type=%d" % recordHeader.type):
     718                          yield result
     719
     720                  break
     721
     722              #Parse based on content_type
     723              if recordHeader.type == ContentType.change_cipher_spec:
     724                  yield ChangeCipherSpec().parse(p)
     725              elif recordHeader.type == ContentType.alert:
     726                  yield Alert().parse(p)
     727              elif recordHeader.type == ContentType.application_data:
     728                  yield ApplicationData().parse(p)
     729              elif recordHeader.type == ContentType.handshake:
     730                  #Convert secondaryType to tuple, if it isn't already
     731                  if not isinstance(secondaryType, tuple):
     732                      secondaryType = (secondaryType,)
     733
     734                  #If it's a handshake message, check handshake header
     735                  if recordHeader.ssl2:
     736                      subType = p.get(1)
     737                      if subType != HandshakeType.client_hello:
     738                          for result in self._sendError(\
     739                                  AlertDescription.unexpected_message,
     740                                  "Can only handle SSLv2 ClientHello messages"):
     741                              yield result
     742                      if HandshakeType.client_hello not in secondaryType:
     743                          for result in self._sendError(\
     744                                  AlertDescription.unexpected_message):
     745                              yield result
     746                      subType = HandshakeType.client_hello
     747                  else:
     748                      subType = p.get(1)
     749                      if subType not in secondaryType:
     750                          for result in self._sendError(\
     751                                  AlertDescription.unexpected_message,
     752                                  "Expecting %s, got %s" % (str(secondaryType), subType)):
     753                              yield result
     754
     755                  #Update handshake hashes
     756                  sToHash = bytesToString(p.bytes)
     757                  self._handshake_md5.update(sToHash)
     758                  self._handshake_sha.update(sToHash)
     759
     760                  #Parse based on handshake type
     761                  if subType == HandshakeType.client_hello:
     762                      yield ClientHello(recordHeader.ssl2).parse(p)
     763                  elif subType == HandshakeType.server_hello:
     764                      yield ServerHello().parse(p)
     765                  elif subType == HandshakeType.certificate:
     766                      yield Certificate(constructorType).parse(p)
     767                  elif subType == HandshakeType.certificate_request:
     768                      yield CertificateRequest().parse(p)
     769                  elif subType == HandshakeType.certificate_verify:
     770                      yield CertificateVerify().parse(p)
     771                  elif subType == HandshakeType.server_key_exchange:
     772                      yield ServerKeyExchange(constructorType).parse(p)
     773                  elif subType == HandshakeType.server_hello_done:
     774                      yield ServerHelloDone().parse(p)
     775                  elif subType == HandshakeType.client_key_exchange:
     776                      yield ClientKeyExchange(constructorType, \
     777                                              self.version).parse(p)
     778                  elif subType == HandshakeType.finished:
     779                      yield Finished(self.version).parse(p)
     780                  elif subType == HandshakeType.next_protocol:
     781                      yield NextProtocol().parse(p)
     782                  else:
     783                      raise AssertionError()
     784
     785          #If an exception was raised by a Parser or Message instance:
     786          except SyntaxError, e:
     787              for result in self._sendError(AlertDescription.decode_error,
     788                                           formatExceptionTrace(e)):
     789                  yield result
     790
     791
     792      #Returns next record or next handshake message
     793 -    def _getNextRecord(self):
     794
     795          #If there's a handshake message waiting, return it
     796          if self._handshakeBuffer:
     797              recordHeader, bytes = self._handshakeBuffer[0]
     798              self._handshakeBuffer = self._handshakeBuffer[1:]
     799              yield (recordHeader, Parser(bytes))
     800              return
     801
     802          #Otherwise...
     803          #Read the next record header
     804          bytes = createByteArraySequence([])
     805          recordHeaderLength = 1
     806          ssl2 = False
     807          while 1:
     808              try:
     809                  s = self.sock.recv(recordHeaderLength-len(bytes))
     810              except socket.error, why:
     811                  if why[0] == errno.EWOULDBLOCK:
     812                      yield 0
     813                      continue
     814                  else:
     815                      raise
     816
     817              #If the connection was abruptly closed, raise an error
     818              if len(s)==0:
     819                  raise TLSAbruptCloseError()
     820
     821              bytes += stringToBytes(s)
     822              if len(bytes)==1:
     823                  if bytes[0] in ContentType.all:
     824                      ssl2 = False
     825                      recordHeaderLength = 5
     826                  elif bytes[0] == 128:
     827                      ssl2 = True
     828                      recordHeaderLength = 2
     829                  else:
     830                      raise SyntaxError()
     831              if len(bytes) == recordHeaderLength:
     832                  break
     833
     834          #Parse the record header
     835          if ssl2:
     836              r = RecordHeader2().parse(Parser(bytes))
     837          else:
     838              r = RecordHeader3().parse(Parser(bytes))
     839
     840          #Check the record header fields
     841          if r.length > 18432:
     842              for result in self._sendError(AlertDescription.record_overflow):
     843                  yield result
     844
     845          #Read the record contents
     846          bytes = createByteArraySequence([])
     847          while 1:
     848              try:
     849                  s = self.sock.recv(r.length - len(bytes))
     850              except socket.error, why:
     851                  if why[0] == errno.EWOULDBLOCK:
     852                      yield 0
     853                      continue
     854                  else:
     855                      raise
     856
     857              #If the connection is closed, raise a socket error
     858              if len(s)==0:
     859                      raise TLSAbruptCloseError()
     860
     861              bytes += stringToBytes(s)
     862              if len(bytes) == r.length:
     863                  break
     864
     865          #Check the record header fields (2)
     866          #We do this after reading the contents from the socket, so that
     867          #if there's an error, we at least don't leave extra bytes in the
     868          #socket..
     869          #
     870          # THIS CHECK HAS NO SECURITY RELEVANCE (?), BUT COULD HURT INTEROP.
     871          # SO WE LEAVE IT OUT FOR NOW.
     872          #
     873          #if self._versionCheck and r.version != self.version:
     874          #    for result in self._sendError(AlertDescription.protocol_version,
     875          #            "Version in header field: %s, should be %s" % (str(r.version),
     876          #                                                       str(self.version))):
     877          #        yield result
     878
     879          #Decrypt the record
     880          for result in self._decryptRecord(r.type, bytes):
     881              if result in (0,1): yield result
     882              else: break
     883          bytes = result
     884          p = Parser(bytes)
     885
     886          #If it doesn't contain handshake messages, we can just return it
     887          if r.type != ContentType.handshake:
     888              yield (r, p)
     889          #If it's an SSLv2 ClientHello, we can return it as well
     890          elif r.ssl2:
     891              yield (r, p)
     892          else:
     893              #Otherwise, we loop through and add the handshake messages to the
     894              #handshake buffer
     895              while 1:
     896                  if p.index == len(bytes): #If we're at the end
     897                      if not self._handshakeBuffer:
     898                          for result in self._sendError(\
     899                                  AlertDescription.decode_error, \
     900                                  "Received empty handshake record"):
     901                              yield result
     902                      break
     903                  #There needs to be at least 4 bytes to get a header
     904                  if p.index+4 > len(bytes):
     905                      for result in self._sendError(\
     906                              AlertDescription.decode_error,
     907                              "A record has a partial handshake message (1)"):
     908                          yield result
     909                  p.get(1) # skip handshake type
     910                  msgLength = p.get(3)
     911                  if p.index+msgLength > len(bytes):
     912                      for result in self._sendError(\
     913                              AlertDescription.decode_error,
     914                              "A record has a partial handshake message (2)"):
     915                          yield result
     916
     917                  handshakePair = (r, bytes[p.index-4 : p.index+msgLength])
     918                  self._handshakeBuffer.append(handshakePair)
     919                  p.index += msgLength
     920
     921              #We've moved at least one handshake message into the
     922              #handshakeBuffer, return the first one
     923              recordHeader, bytes = self._handshakeBuffer[0]
     924              self._handshakeBuffer = self._handshakeBuffer[1:]
     925              yield (recordHeader, Parser(bytes))
     926
     927
     928 -    def _decryptRecord(self, recordType, bytes):
     929          if self._readState.encContext:
     930
     931              #Decrypt if it's a block cipher
     932              if self._readState.encContext.isBlockCipher:
     933                  blockLength = self._readState.encContext.block_size
     934                  if len(bytes) % blockLength != 0:
     935                      for result in self._sendError(\
     936                              AlertDescription.decryption_failed,
     937                              "Encrypted data not a multiple of blocksize"):
     938                          yield result
     939                  ciphertext = bytesToString(bytes)
     940                  plaintext = self._readState.encContext.decrypt(ciphertext)
     941                  if self.version == (3,2): #For TLS 1.1, remove explicit IV
     942                      plaintext = plaintext[self._readState.encContext.block_size : ]
     943                  bytes = stringToBytes(plaintext)
     944
     945                  #Check padding
     946                  paddingGood = True
     947                  paddingLength = bytes[-1]
     948                  if (paddingLength+1) > len(bytes):
     949                      paddingGood=False
     950                      totalPaddingLength = 0
     951                  else:
     952                      if self.version == (3,0):
     953                          totalPaddingLength = paddingLength+1
     954                      elif self.version in ((3,1), (3,2)):
     955                          totalPaddingLength = paddingLength+1
     956                          paddingBytes = bytes[-totalPaddingLength:-1]
     957                          for byte in paddingBytes:
     958                              if byte != paddingLength:
     959                                  paddingGood = False
     960                                  totalPaddingLength = 0
     961                      else:
     962                          raise AssertionError()
     963
     964              #Decrypt if it's a stream cipher
     965              else:
     966                  paddingGood = True
     967                  ciphertext = bytesToString(bytes)
     968                  plaintext = self._readState.encContext.decrypt(ciphertext)
     969                  bytes = stringToBytes(plaintext)
     970                  totalPaddingLength = 0
     971
     972              #Check MAC
     973              macGood = True
     974              macLength = self._readState.macContext.digest_size
     975              endLength = macLength + totalPaddingLength
     976              if endLength > len(bytes):
     977                  macGood = False
     978              else:
     979                  #Read MAC
     980                  startIndex = len(bytes) - endLength
     981                  endIndex = startIndex + macLength
     982                  checkBytes = bytes[startIndex : endIndex]
     983
     984                  #Calculate MAC
     985                  seqnumStr = self._readState.getSeqNumStr()
     986                  bytes = bytes[:-endLength]
     987                  bytesStr = bytesToString(bytes)
     988                  mac = self._readState.macContext.copy()
     989                  mac.update(seqnumStr)
     990                  mac.update(chr(recordType))
     991                  if self.version == (3,0):
     992                      mac.update( chr( len(bytes)//256 ) )
     993                      mac.update( chr( len(bytes)%256 ) )
     994                  elif self.version in ((3,1), (3,2)):
     995                      mac.update(chr(self.version[0]))
     996                      mac.update(chr(self.version[1]))
     997                      mac.update( chr( len(bytes)//256 ) )
     998                      mac.update( chr( len(bytes)%256 ) )
     999                  else:
    1000                      raise AssertionError()
    1001                  mac.update(bytesStr)
    1002                  macString = mac.digest()
    1003                  macBytes = stringToBytes(macString)
    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 bytes
    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 = md5()
    1021          self._handshake_sha = 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                             "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 = bytesToString(p.getFixBytes(macLength))
    1080          serverMACBlock = bytesToString(p.getFixBytes(macLength))
    1081          clientKeyBlock = bytesToString(p.getFixBytes(keyLength))
    1082          serverKeyBlock = bytesToString(p.getFixBytes(keyLength))
    1083          clientIVBlock  = bytesToString(p.getFixBytes(ivLength))
    1084          serverIVBlock  = bytesToString(p.getFixBytes(ivLength))
    1085          clientPendingState.macContext = createMACFunc(clientMACBlock)
    1086          serverPendingState.macContext = createMACFunc(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          masterSecretStr = bytesToString(masterSecret)
    1118
    1119          imac_md5 = self._handshake_md5.copy()
    1120          imac_sha = self._handshake_sha.copy()
    1121
    1122          imac_md5.update(label + masterSecretStr + '\x36'*48)
    1123          imac_sha.update(label + masterSecretStr + '\x36'*40)
    1124
    1125          md5Str = md5(masterSecretStr + ('\x5c'*48) + \
    1126                           imac_md5.digest()).digest()
    1127          shaStr = sha1(masterSecretStr + ('\x5c'*40) + \
    1128                           imac_sha.digest()).digest()
    1129
    1130          return stringToBytes(md5Str + shaStr)
    1131