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