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