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  #   Google - minimal padding 
  5  #   Martin von Loewis - python 3 port 
  6  #   Yngve Pettersen (ported by Paul Sokolovsky) - TLS 1.2 
  7  #   Hubert Kario 
  8  # 
  9  # See the LICENSE file for legal information regarding use of this file. 
 10   
 11  """Helper class for TLSConnection.""" 
 12  from __future__ import generators 
 13   
 14  import io 
 15  import socket 
 16   
 17  from .utils.compat import * 
 18  from .utils.cryptomath import * 
 19  from .utils.codec import Parser 
 20  from .errors import * 
 21  from .messages import * 
 22  from .mathtls import * 
 23  from .constants import * 
 24  from .recordlayer import RecordLayer 
 25  from .defragmenter import Defragmenter 
 26  from .handshakehashes import HandshakeHashes 
 27  from .bufferedsocket import BufferedSocket 
28 29 -class TLSRecordLayer(object):
30 """ 31 This class handles data transmission for a TLS connection. 32 33 Its only subclass is L{tlslite.TLSConnection.TLSConnection}. We've 34 separated the code in this class from TLSConnection to make things 35 more readable. 36 37 38 @type sock: socket.socket 39 @ivar sock: The underlying socket object. 40 41 @type session: L{tlslite.Session.Session} 42 @ivar session: The session corresponding to this connection. 43 44 Due to TLS session resumption, multiple connections can correspond 45 to the same underlying session. 46 47 @type version: tuple 48 @ivar version: The TLS version being used for this connection. 49 50 (3,0) means SSL 3.0, and (3,1) means TLS 1.0. 51 52 @type closed: bool 53 @ivar closed: If this connection is closed. 54 55 @type resumed: bool 56 @ivar resumed: If this connection is based on a resumed session. 57 58 @type allegedSrpUsername: str or None 59 @ivar allegedSrpUsername: This is set to the SRP username 60 asserted by the client, whether the handshake succeeded or not. 61 If the handshake fails, this can be inspected to determine 62 if a guessing attack is in progress against a particular user 63 account. 64 65 @type closeSocket: bool 66 @ivar closeSocket: If the socket should be closed when the 67 connection is closed, defaults to True (writable). 68 69 If you set this to True, TLS Lite will assume the responsibility of 70 closing the socket when the TLS Connection is shutdown (either 71 through an error or through the user calling close()). The default 72 is False. 73 74 @type ignoreAbruptClose: bool 75 @ivar ignoreAbruptClose: If an abrupt close of the socket should 76 raise an error (writable). 77 78 If you set this to True, TLS Lite will not raise a 79 L{tlslite.errors.TLSAbruptCloseError} exception if the underlying 80 socket is unexpectedly closed. Such an unexpected closure could be 81 caused by an attacker. However, it also occurs with some incorrect 82 TLS implementations. 83 84 You should set this to True only if you're not worried about an 85 attacker truncating the connection, and only if necessary to avoid 86 spurious errors. The default is False. 87 88 @type encryptThenMAC: bool 89 @ivar encryptThenMAC: Whether the connection uses the encrypt-then-MAC 90 construct for CBC cipher suites, will be False also if connection uses 91 RC4 or AEAD. 92 93 @type recordSize: int 94 @ivar recordSize: maimum size of data to be sent in a single record layer 95 message. Note that after encryption is established (generally after 96 handshake protocol has finished) the actual amount of data written to 97 network socket will be larger because of the record layer header, padding 98 or encryption overhead. It can be set to low value (so that there is no 99 fragmentation on Ethernet, IP and TCP level) at the beginning of 100 connection to reduce latency and set to protocol max (2**14) to maximise 101 throughput after sending few kiB of data. Setting to values greater than 102 2**14 will cause the connection to be dropped by RFC compliant peers. 103 104 @sort: __init__, read, readAsync, write, writeAsync, close, closeAsync, 105 getCipherImplementation, getCipherName 106 """ 107
108 - def __init__(self, sock):
109 sock = BufferedSocket(sock) 110 self.sock = sock 111 self._recordLayer = RecordLayer(sock) 112 113 #My session object (Session instance; read-only) 114 self.session = None 115 116 #Buffers for processing messages 117 self._defragmenter = Defragmenter() 118 self._defragmenter.addStaticSize(ContentType.change_cipher_spec, 1) 119 self._defragmenter.addStaticSize(ContentType.alert, 2) 120 self._defragmenter.addDynamicSize(ContentType.handshake, 1, 3) 121 self.clearReadBuffer() 122 self.clearWriteBuffer() 123 124 #Handshake digests 125 self._handshake_hash = HandshakeHashes() 126 # Handshake digest used for Certificate Verify signature and 127 # also for EMS calculation, in practice, it excludes 128 # CertificateVerify and all following messages (Finished) 129 self._certificate_verify_handshake_hash = None 130 131 #Is the connection open? 132 self.closed = True #read-only 133 self._refCount = 0 #Used to trigger closure 134 135 #Is this a resumed session? 136 self.resumed = False #read-only 137 138 #What username did the client claim in his handshake? 139 self.allegedSrpUsername = None 140 141 #On a call to close(), do we close the socket? (writeable) 142 self.closeSocket = True 143 144 #If the socket is abruptly closed, do we ignore it 145 #and pretend the connection was shut down properly? (writeable) 146 self.ignoreAbruptClose = False 147 148 #Fault we will induce, for testing purposes 149 self.fault = None 150 151 #Limit the size of outgoing records to following size 152 self.recordSize = 16384 # 2**14
153 154 @property
155 - def _client(self):
156 """Boolean stating if the endpoint acts as a client""" 157 return self._recordLayer.client
158 159 @_client.setter
160 - def _client(self, value):
161 """Set the endpoint to act as a client or not""" 162 self._recordLayer.client = value
163 164 @property
165 - def version(self):
166 """Get the SSL protocol version of connection""" 167 return self._recordLayer.version
168 169 @version.setter
170 - def version(self, value):
171 """ 172 Set the SSL protocol version of connection 173 174 The setter is a public method only for backwards compatibility. 175 Don't use it! See at HandshakeSettings for options to set desired 176 protocol version. 177 """ 178 self._recordLayer.version = value
179 180 @property
181 - def encryptThenMAC(self):
182 """Whether the connection uses Encrypt Then MAC (RFC 7366)""" 183 return self._recordLayer.encryptThenMAC
184
185 - def clearReadBuffer(self):
186 self._readBuffer = b''
187
188 - def clearWriteBuffer(self):
189 self._send_writer = None
190 191 192 #********************************************************* 193 # Public Functions START 194 #********************************************************* 195
196 - def read(self, max=None, min=1):
197 """Read some data from the TLS connection. 198 199 This function will block until at least 'min' bytes are 200 available (or the connection is closed). 201 202 If an exception is raised, the connection will have been 203 automatically closed. 204 205 @type max: int 206 @param max: The maximum number of bytes to return. 207 208 @type min: int 209 @param min: The minimum number of bytes to return 210 211 @rtype: str 212 @return: A string of no more than 'max' bytes, and no fewer 213 than 'min' (unless the connection has been closed, in which 214 case fewer than 'min' bytes may be returned). 215 216 @raise socket.error: If a socket error occurs. 217 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed 218 without a preceding alert. 219 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled. 220 """ 221 for result in self.readAsync(max, min): 222 pass 223 return result
224
225 - def readAsync(self, max=None, min=1):
226 """Start a read operation on the TLS connection. 227 228 This function returns a generator which behaves similarly to 229 read(). Successive invocations of the generator will return 0 230 if it is waiting to read from the socket, 1 if it is waiting 231 to write to the socket, or a string if the read operation has 232 completed. 233 234 @rtype: iterable 235 @return: A generator; see above for details. 236 """ 237 try: 238 while len(self._readBuffer)<min and not self.closed: 239 try: 240 for result in self._getMsg(ContentType.application_data): 241 if result in (0,1): 242 yield result 243 applicationData = result 244 self._readBuffer += applicationData.write() 245 except TLSRemoteAlert as alert: 246 if alert.description != AlertDescription.close_notify: 247 raise 248 except TLSAbruptCloseError: 249 if not self.ignoreAbruptClose: 250 raise 251 else: 252 self._shutdown(True) 253 254 if max == None: 255 max = len(self._readBuffer) 256 257 returnBytes = self._readBuffer[:max] 258 self._readBuffer = self._readBuffer[max:] 259 yield bytes(returnBytes) 260 except GeneratorExit: 261 raise 262 except: 263 self._shutdown(False) 264 raise
265
266 - def unread(self, b):
267 """Add bytes to the front of the socket read buffer for future 268 reading. Be careful using this in the context of select(...): if you 269 unread the last data from a socket, that won't wake up selected waiters, 270 and those waiters may hang forever. 271 """ 272 self._readBuffer = b + self._readBuffer
273
274 - def write(self, s):
275 """Write some data to the TLS connection. 276 277 This function will block until all the data has been sent. 278 279 If an exception is raised, the connection will have been 280 automatically closed. 281 282 @type s: str 283 @param s: The data to transmit to the other party. 284 285 @raise socket.error: If a socket error occurs. 286 """ 287 for result in self.writeAsync(s): 288 pass
289
290 - def writeAsync(self, s):
291 """Start a write operation on the TLS connection. 292 293 This function returns a generator which behaves similarly to 294 write(). Successive invocations of the generator will return 295 1 if it is waiting to write to the socket, or will raise 296 StopIteration if the write operation has completed. 297 298 @rtype: iterable 299 @return: A generator; see above for details. 300 """ 301 try: 302 if self.closed: 303 raise TLSClosedConnectionError("attempt to write to closed connection") 304 305 applicationData = ApplicationData().create(bytearray(s)) 306 for result in self._sendMsg(applicationData, \ 307 randomizeFirstBlock=True): 308 yield result 309 except GeneratorExit: 310 raise 311 except Exception: 312 # Don't invalidate the session on write failure if abrupt closes are 313 # okay. 314 self._shutdown(self.ignoreAbruptClose) 315 raise
316
317 - def close(self):
318 """Close the TLS connection. 319 320 This function will block until it has exchanged close_notify 321 alerts with the other party. After doing so, it will shut down the 322 TLS connection. Further attempts to read through this connection 323 will return "". Further attempts to write through this connection 324 will raise ValueError. 325 326 If makefile() has been called on this connection, the connection 327 will be not be closed until the connection object and all file 328 objects have been closed. 329 330 Even if an exception is raised, the connection will have been 331 closed. 332 333 @raise socket.error: If a socket error occurs. 334 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed 335 without a preceding alert. 336 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled. 337 """ 338 if not self.closed: 339 for result in self._decrefAsync(): 340 pass
341 342 # Python 3 callback 343 _decref_socketios = close 344
345 - def closeAsync(self):
346 """Start a close operation on the TLS connection. 347 348 This function returns a generator which behaves similarly to 349 close(). Successive invocations of the generator will return 0 350 if it is waiting to read from the socket, 1 if it is waiting 351 to write to the socket, or will raise StopIteration if the 352 close operation has completed. 353 354 @rtype: iterable 355 @return: A generator; see above for details. 356 """ 357 if not self.closed: 358 for result in self._decrefAsync(): 359 yield result
360
361 - def _decrefAsync(self):
362 self._refCount -= 1 363 if self._refCount == 0 and not self.closed: 364 try: 365 for result in self._sendMsg(Alert().create(\ 366 AlertDescription.close_notify, AlertLevel.warning)): 367 yield result 368 alert = None 369 # By default close the socket, since it's been observed 370 # that some other libraries will not respond to the 371 # close_notify alert, thus leaving us hanging if we're 372 # expecting it 373 if self.closeSocket: 374 self._shutdown(True) 375 else: 376 while not alert: 377 for result in self._getMsg((ContentType.alert, \ 378 ContentType.application_data)): 379 if result in (0,1): 380 yield result 381 if result.contentType == ContentType.alert: 382 alert = result 383 if alert.description == AlertDescription.close_notify: 384 self._shutdown(True) 385 else: 386 raise TLSRemoteAlert(alert) 387 except (socket.error, TLSAbruptCloseError): 388 #If the other side closes the socket, that's okay 389 self._shutdown(True) 390 except GeneratorExit: 391 raise 392 except: 393 self._shutdown(False) 394 raise
395
396 - def getVersionName(self):
397 """Get the name of this TLS version. 398 399 @rtype: str 400 @return: The name of the TLS version used with this connection. 401 Either None, 'SSL 3.0', 'TLS 1.0', 'TLS 1.1', or 'TLS 1.2'. 402 """ 403 if self.version == (3,0): 404 return "SSL 3.0" 405 elif self.version == (3,1): 406 return "TLS 1.0" 407 elif self.version == (3,2): 408 return "TLS 1.1" 409 elif self.version == (3,3): 410 return "TLS 1.2" 411 else: 412 return None
413
414 - def getCipherName(self):
415 """Get the name of the cipher used with this connection. 416 417 @rtype: str 418 @return: The name of the cipher used with this connection. 419 Either 'aes128', 'aes256', 'rc4', or '3des'. 420 """ 421 return self._recordLayer.getCipherName()
422
423 - def getCipherImplementation(self):
424 """Get the name of the cipher implementation used with 425 this connection. 426 427 @rtype: str 428 @return: The name of the cipher implementation used with 429 this connection. Either 'python', 'openssl', or 'pycrypto'. 430 """ 431 return self._recordLayer.getCipherImplementation()
432 433 #Emulate a socket, somewhat -
434 - def send(self, s):
435 """Send data to the TLS connection (socket emulation). 436 437 @raise socket.error: If a socket error occurs. 438 """ 439 self.write(s) 440 return len(s)
441
442 - def sendall(self, s):
443 """Send data to the TLS connection (socket emulation). 444 445 @raise socket.error: If a socket error occurs. 446 """ 447 self.write(s)
448
449 - def recv(self, bufsize):
450 """Get some data from the TLS connection (socket emulation). 451 452 @raise socket.error: If a socket error occurs. 453 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed 454 without a preceding alert. 455 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled. 456 """ 457 return self.read(bufsize)
458
459 - def recv_into(self, b):
460 # XXX doc string 461 data = self.read(len(b)) 462 if not data: 463 return None 464 b[:len(data)] = data 465 return len(data)
466 467 # while the SocketIO and _fileobject in socket is private we really need 468 # to use it as it's what the real socket does internally 469 470 # pylint: disable=no-member,protected-access
471 - def makefile(self, mode='r', bufsize=-1):
472 """Create a file object for the TLS connection (socket emulation). 473 474 @rtype: L{socket._fileobject} 475 """ 476 self._refCount += 1 477 # So, it is pretty fragile to be using Python internal objects 478 # like this, but it is probably the best/easiest way to provide 479 # matching behavior for socket emulation purposes. The 'close' 480 # argument is nice, its apparently a recent addition to this 481 # class, so that when fileobject.close() gets called, it will 482 # close() us, causing the refcount to be decremented (decrefAsync). 483 # 484 # If this is the last close() on the outstanding fileobjects / 485 # TLSConnection, then the "actual" close alerts will be sent, 486 # socket closed, etc. 487 488 # for writes, we MUST buffer otherwise the lengths of headers leak 489 # through record layer boundaries 490 if 'w' in mode and bufsize <= 0: 491 bufsize = 2**14 492 493 if sys.version_info < (3,): 494 return socket._fileobject(self, mode, bufsize, close=True) 495 else: 496 if 'w' in mode: 497 return io.BufferedWriter(socket.SocketIO(self, mode), bufsize) 498 else: 499 return socket.SocketIO(self, mode)
500 # pylint: enable=no-member,protected-access 501
502 - def getsockname(self):
503 """Return the socket's own address (socket emulation).""" 504 return self.sock.getsockname()
505
506 - def getpeername(self):
507 """Return the remote address to which the socket is connected 508 (socket emulation).""" 509 return self.sock.getpeername()
510
511 - def settimeout(self, value):
512 """Set a timeout on blocking socket operations (socket emulation).""" 513 return self.sock.settimeout(value)
514
515 - def gettimeout(self):
516 """Return the timeout associated with socket operations (socket 517 emulation).""" 518 return self.sock.gettimeout()
519
520 - def setsockopt(self, level, optname, value):
521 """Set the value of the given socket option (socket emulation).""" 522 return self.sock.setsockopt(level, optname, value)
523
524 - def shutdown(self, how):
525 """Shutdown the underlying socket.""" 526 return self.sock.shutdown(how)
527
528 - def fileno(self):
529 """Not implement in TLS Lite.""" 530 raise NotImplementedError()
531 532 533 #********************************************************* 534 # Public Functions END 535 #********************************************************* 536
537 - def _shutdown(self, resumable):
538 self._recordLayer.shutdown() 539 self.version = (0,0) 540 self.closed = True 541 if self.closeSocket: 542 self.sock.close() 543 544 #Even if resumable is False, we'll never toggle this on 545 if not resumable and self.session: 546 self.session.resumable = False
547 548
549 - def _sendError(self, alertDescription, errorStr=None):
550 # make sure that the message goes out 551 self.sock.flush() 552 self.sock.buffer_writes = False 553 alert = Alert().create(alertDescription, AlertLevel.fatal) 554 for result in self._sendMsg(alert): 555 yield result 556 self._shutdown(False) 557 raise TLSLocalAlert(alert, errorStr)
558
559 - def _sendMsgs(self, msgs):
560 # send messages together 561 self.sock.buffer_writes = True 562 randomizeFirstBlock = True 563 for msg in msgs: 564 for result in self._sendMsg(msg, randomizeFirstBlock): 565 yield result 566 randomizeFirstBlock = True 567 self.sock.flush() 568 self.sock.buffer_writes = False
569
570 - def _sendMsg(self, msg, randomizeFirstBlock = True):
571 """Fragment and send message through socket""" 572 #Whenever we're connected and asked to send an app data message, 573 #we first send the first byte of the message. This prevents 574 #an attacker from launching a chosen-plaintext attack based on 575 #knowing the next IV (a la BEAST). 576 if randomizeFirstBlock and self.version <= (3, 1) \ 577 and self._recordLayer.isCBCMode() \ 578 and msg.contentType == ContentType.application_data: 579 msgFirstByte = msg.splitFirstByte() 580 for result in self._sendMsgThroughSocket(msgFirstByte): 581 yield result 582 if len(msg.write()) == 0: 583 return 584 585 buf = msg.write() 586 contentType = msg.contentType 587 #Update handshake hashes 588 if contentType == ContentType.handshake: 589 self._handshake_hash.update(buf) 590 591 #Fragment big messages 592 while len(buf) > self.recordSize: 593 newB = buf[:self.recordSize] 594 buf = buf[self.recordSize:] 595 596 msgFragment = Message(contentType, newB) 597 for result in self._sendMsgThroughSocket(msgFragment): 598 yield result 599 600 msgFragment = Message(contentType, buf) 601 for result in self._sendMsgThroughSocket(msgFragment): 602 yield result
603
604 - def _sendMsgThroughSocket(self, msg):
605 """Send message, handle errors""" 606 607 try: 608 for result in self._recordLayer.sendRecord(msg): 609 if result in (0, 1): 610 yield result 611 except socket.error: 612 # The socket was unexpectedly closed. The tricky part 613 # is that there may be an alert sent by the other party 614 # sitting in the read buffer. So, if we get here after 615 # handshaking, we will just raise the error and let the 616 # caller read more data if it would like, thus stumbling 617 # upon the error. 618 # 619 # However, if we get here DURING handshaking, we take 620 # it upon ourselves to see if the next message is an 621 # Alert. 622 if msg.contentType == ContentType.handshake: 623 624 # See if there's an alert record 625 # Could raise socket.error or TLSAbruptCloseError 626 for result in self._getNextRecord(): 627 if result in (0, 1): 628 yield result 629 else: 630 break 631 632 # Closes the socket 633 self._shutdown(False) 634 635 # If we got an alert, raise it 636 recordHeader, p = result 637 if recordHeader.type == ContentType.alert: 638 alert = Alert().parse(p) 639 raise TLSRemoteAlert(alert) 640 else: 641 # If we got some other message who know what 642 # the remote side is doing, just go ahead and 643 # raise the socket.error 644 raise
645
646 - def _getMsg(self, expectedType, secondaryType=None, constructorType=None):
647 try: 648 if not isinstance(expectedType, tuple): 649 expectedType = (expectedType,) 650 651 #Spin in a loop, until we've got a non-empty record of a type we 652 #expect. The loop will be repeated if: 653 # - we receive a renegotiation attempt; we send no_renegotiation, 654 # then try again 655 # - we receive an empty application-data fragment; we try again 656 while 1: 657 for result in self._getNextRecord(): 658 if result in (0,1): 659 yield result 660 else: 661 break 662 recordHeader, p = result 663 664 #If this is an empty application-data fragment, try again 665 if recordHeader.type == ContentType.application_data: 666 if p.index == len(p.bytes): 667 continue 668 669 #If we received an unexpected record type... 670 if recordHeader.type not in expectedType: 671 672 #If we received an alert... 673 if recordHeader.type == ContentType.alert: 674 alert = Alert().parse(p) 675 676 #We either received a fatal error, a warning, or a 677 #close_notify. In any case, we're going to close the 678 #connection. In the latter two cases we respond with 679 #a close_notify, but ignore any socket errors, since 680 #the other side might have already closed the socket. 681 if alert.level == AlertLevel.warning or \ 682 alert.description == AlertDescription.close_notify: 683 684 #If the sendMsg() call fails because the socket has 685 #already been closed, we will be forgiving and not 686 #report the error nor invalidate the "resumability" 687 #of the session. 688 try: 689 alertMsg = Alert() 690 alertMsg.create(AlertDescription.close_notify, 691 AlertLevel.warning) 692 for result in self._sendMsg(alertMsg): 693 yield result 694 except socket.error: 695 pass 696 697 if alert.description == \ 698 AlertDescription.close_notify: 699 self._shutdown(True) 700 elif alert.level == AlertLevel.warning: 701 self._shutdown(False) 702 703 else: #Fatal alert: 704 self._shutdown(False) 705 706 #Raise the alert as an exception 707 raise TLSRemoteAlert(alert) 708 709 #If we received a renegotiation attempt... 710 if recordHeader.type == ContentType.handshake: 711 subType = p.get(1) 712 reneg = False 713 if self._client: 714 if subType == HandshakeType.hello_request: 715 reneg = True 716 else: 717 if subType == HandshakeType.client_hello: 718 reneg = True 719 # Send no_renegotiation if we're not negotiating 720 # a connection now, then try again 721 if reneg and self.session: 722 alertMsg = Alert() 723 alertMsg.create(AlertDescription.no_renegotiation, 724 AlertLevel.warning) 725 for result in self._sendMsg(alertMsg): 726 yield result 727 continue 728 729 #Otherwise: this is an unexpected record, but neither an 730 #alert nor renegotiation 731 for result in self._sendError(\ 732 AlertDescription.unexpected_message, 733 "received type=%d" % recordHeader.type): 734 yield result 735 736 break 737 738 #Parse based on content_type 739 if recordHeader.type == ContentType.change_cipher_spec: 740 yield ChangeCipherSpec().parse(p) 741 elif recordHeader.type == ContentType.alert: 742 yield Alert().parse(p) 743 elif recordHeader.type == ContentType.application_data: 744 yield ApplicationData().parse(p) 745 elif recordHeader.type == ContentType.handshake: 746 #Convert secondaryType to tuple, if it isn't already 747 if not isinstance(secondaryType, tuple): 748 secondaryType = (secondaryType,) 749 750 #If it's a handshake message, check handshake header 751 if recordHeader.ssl2: 752 subType = p.get(1) 753 if subType != HandshakeType.client_hello: 754 for result in self._sendError(\ 755 AlertDescription.unexpected_message, 756 "Can only handle SSLv2 ClientHello messages"): 757 yield result 758 if HandshakeType.client_hello not in secondaryType: 759 for result in self._sendError(\ 760 AlertDescription.unexpected_message): 761 yield result 762 subType = HandshakeType.client_hello 763 else: 764 subType = p.get(1) 765 if subType not in secondaryType: 766 for result in self._sendError(\ 767 AlertDescription.unexpected_message, 768 "Expecting %s, got %s" % (str(secondaryType), subType)): 769 yield result 770 771 #Update handshake hashes 772 self._handshake_hash.update(p.bytes) 773 774 #Parse based on handshake type 775 if subType == HandshakeType.client_hello: 776 yield ClientHello(recordHeader.ssl2).parse(p) 777 elif subType == HandshakeType.server_hello: 778 yield ServerHello().parse(p) 779 elif subType == HandshakeType.certificate: 780 yield Certificate(constructorType).parse(p) 781 elif subType == HandshakeType.certificate_request: 782 yield CertificateRequest(self.version).parse(p) 783 elif subType == HandshakeType.certificate_verify: 784 yield CertificateVerify(self.version).parse(p) 785 elif subType == HandshakeType.server_key_exchange: 786 yield ServerKeyExchange(constructorType, 787 self.version).parse(p) 788 elif subType == HandshakeType.server_hello_done: 789 yield ServerHelloDone().parse(p) 790 elif subType == HandshakeType.client_key_exchange: 791 yield ClientKeyExchange(constructorType, \ 792 self.version).parse(p) 793 elif subType == HandshakeType.finished: 794 yield Finished(self.version).parse(p) 795 elif subType == HandshakeType.next_protocol: 796 yield NextProtocol().parse(p) 797 else: 798 raise AssertionError() 799 800 #If an exception was raised by a Parser or Message instance: 801 except SyntaxError as e: 802 for result in self._sendError(AlertDescription.decode_error, 803 formatExceptionTrace(e)): 804 yield result
805 806 #Returns next record or next handshake message
807 - def _getNextRecord(self):
808 """read next message from socket, defragment message""" 809 810 while True: 811 # support for fragmentation 812 # (RFC 5246 Section 6.2.1) 813 # Because the Record Layer is completely separate from the messages 814 # that traverse it, it should handle both application data and 815 # hadshake data in the same way. For that we buffer the handshake 816 # messages until they are completely read. 817 # This makes it possible to handle both handshake data not aligned 818 # to record boundary as well as handshakes longer than single 819 # record. 820 while True: 821 # empty message buffer 822 ret = self._defragmenter.getMessage() 823 if ret is None: 824 break 825 header = RecordHeader3().create(self.version, ret[0], 0) 826 yield header, Parser(ret[1]) 827 828 # when the message buffer is empty, read next record from socket 829 for result in self._getNextRecordFromSocket(): 830 if result in (0, 1): 831 yield result 832 else: 833 break 834 835 header, parser = result 836 837 # application data isn't made out of messages, pass it through 838 if header.type == ContentType.application_data: 839 yield (header, parser) 840 # If it's an SSLv2 ClientHello, we can return it as well, since 841 # it's the only ssl2 type we support 842 elif header.ssl2: 843 yield (header, parser) 844 else: 845 # other types need to be put into buffers 846 self._defragmenter.addData(header.type, parser.bytes)
847
848 - def _getNextRecordFromSocket(self):
849 """Read a record, handle errors""" 850 851 try: 852 # otherwise... read the next record 853 for result in self._recordLayer.recvRecord(): 854 if result in (0, 1): 855 yield result 856 else: 857 break 858 except TLSRecordOverflow: 859 for result in self._sendError(AlertDescription.record_overflow): 860 yield result 861 except TLSIllegalParameterException: 862 for result in self._sendError(AlertDescription.illegal_parameter): 863 yield result 864 except TLSDecryptionFailed: 865 for result in self._sendError( 866 AlertDescription.decryption_failed, 867 "Encrypted data not a multiple of blocksize"): 868 yield result 869 except TLSBadRecordMAC: 870 for result in self._sendError( 871 AlertDescription.bad_record_mac, 872 "MAC failure (or padding failure)"): 873 yield result 874 875 header, parser = result 876 877 # RFC5246 section 5.2.1: Implementations MUST NOT send 878 # zero-length fragments of content types other than Application 879 # Data. 880 if header.type != ContentType.application_data \ 881 and parser.getRemainingLength() == 0: 882 for result in self._sendError(\ 883 AlertDescription.decode_error, \ 884 "Received empty non-application data record"): 885 yield result 886 887 if header.type not in ContentType.all: 888 for result in self._sendError(\ 889 AlertDescription.unexpected_message, \ 890 "Received record with unknown ContentType"): 891 yield result 892 893 yield (header, parser)
894
895 - def _handshakeStart(self, client):
896 if not self.closed: 897 raise ValueError("Renegotiation disallowed for security reasons") 898 self._client = client 899 self._handshake_hash = HandshakeHashes() 900 self._certificate_verify_handshake_hash = None 901 self._defragmenter.clearBuffers() 902 self.allegedSrpUsername = None 903 self._refCount = 1
904
905 - def _handshakeDone(self, resumed):
906 self.resumed = resumed 907 self.closed = False
908
909 - def _calcPendingStates(self, cipherSuite, masterSecret, 910 clientRandom, serverRandom, implementations):
911 self._recordLayer.calcPendingStates(cipherSuite, masterSecret, 912 clientRandom, serverRandom, 913 implementations)
914
915 - def _changeWriteState(self):
916 self._recordLayer.changeWriteState()
917
918 - def _changeReadState(self):
919 self._recordLayer.changeReadState()
920