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 480 # for writes, we MUST buffer otherwise the lengths of headers leak 481 # through record layer boundaries 482 if 'w' in mode and bufsize == 0: 483 bufsize = 2**14 484 485 if sys.version_info < (3,): 486 return socket._fileobject(self, mode, bufsize, close=True) 487 else: 488 # XXX need to wrap this further if buffering is requested 489 return socket.SocketIO(self, mode)
490
491 - def getsockname(self):
492 """Return the socket's own address (socket emulation).""" 493 return self.sock.getsockname()
494
495 - def getpeername(self):
496 """Return the remote address to which the socket is connected 497 (socket emulation).""" 498 return self.sock.getpeername()
499
500 - def settimeout(self, value):
501 """Set a timeout on blocking socket operations (socket emulation).""" 502 return self.sock.settimeout(value)
503
504 - def gettimeout(self):
505 """Return the timeout associated with socket operations (socket 506 emulation).""" 507 return self.sock.gettimeout()
508
509 - def setsockopt(self, level, optname, value):
510 """Set the value of the given socket option (socket emulation).""" 511 return self.sock.setsockopt(level, optname, value)
512
513 - def shutdown(self, how):
514 """Shutdown the underlying socket.""" 515 return self.sock.shutdown(how)
516
517 - def fileno(self):
518 """Not implement in TLS Lite.""" 519 raise NotImplementedError()
520 521 522 #********************************************************* 523 # Public Functions END 524 #********************************************************* 525
526 - def _shutdown(self, resumable):
527 self._recordLayer.shutdown() 528 self.version = (0,0) 529 self.closed = True 530 if self.closeSocket: 531 self.sock.close() 532 533 #Even if resumable is False, we'll never toggle this on 534 if not resumable and self.session: 535 self.session.resumable = False
536 537
538 - def _sendError(self, alertDescription, errorStr=None):
539 # make sure that the message goes out 540 self.sock.flush() 541 self.sock.buffer_writes = False 542 alert = Alert().create(alertDescription, AlertLevel.fatal) 543 for result in self._sendMsg(alert): 544 yield result 545 self._shutdown(False) 546 raise TLSLocalAlert(alert, errorStr)
547
548 - def _sendMsgs(self, msgs):
549 # send messages together 550 self.sock.buffer_writes = True 551 randomizeFirstBlock = True 552 for msg in msgs: 553 for result in self._sendMsg(msg, randomizeFirstBlock): 554 yield result 555 randomizeFirstBlock = True 556 self.sock.flush() 557 self.sock.buffer_writes = False
558
559 - def _sendMsg(self, msg, randomizeFirstBlock = True):
560 """Fragment and send message through socket""" 561 #Whenever we're connected and asked to send an app data message, 562 #we first send the first byte of the message. This prevents 563 #an attacker from launching a chosen-plaintext attack based on 564 #knowing the next IV (a la BEAST). 565 if randomizeFirstBlock and self.version <= (3, 1) \ 566 and self._recordLayer.isCBCMode() \ 567 and msg.contentType == ContentType.application_data: 568 msgFirstByte = msg.splitFirstByte() 569 for result in self._sendMsgThroughSocket(msgFirstByte): 570 yield result 571 if len(msg.write()) == 0: 572 return 573 574 buf = msg.write() 575 contentType = msg.contentType 576 #Update handshake hashes 577 if contentType == ContentType.handshake: 578 self._handshake_hash.update(buf) 579 580 #Fragment big messages 581 while len(buf) > self.recordSize: 582 newB = buf[:self.recordSize] 583 buf = buf[self.recordSize:] 584 585 msgFragment = Message(contentType, newB) 586 for result in self._sendMsgThroughSocket(msgFragment): 587 yield result 588 589 msgFragment = Message(contentType, buf) 590 for result in self._sendMsgThroughSocket(msgFragment): 591 yield result
592
593 - def _sendMsgThroughSocket(self, msg):
594 """Send message, handle errors""" 595 596 try: 597 for result in self._recordLayer.sendRecord(msg): 598 if result in (0, 1): 599 yield result 600 except socket.error: 601 # The socket was unexpectedly closed. The tricky part 602 # is that there may be an alert sent by the other party 603 # sitting in the read buffer. So, if we get here after 604 # handshaking, we will just raise the error and let the 605 # caller read more data if it would like, thus stumbling 606 # upon the error. 607 # 608 # However, if we get here DURING handshaking, we take 609 # it upon ourselves to see if the next message is an 610 # Alert. 611 if msg.contentType == ContentType.handshake: 612 613 # See if there's an alert record 614 # Could raise socket.error or TLSAbruptCloseError 615 for result in self._getNextRecord(): 616 if result in (0, 1): 617 yield result 618 else: 619 break 620 621 # Closes the socket 622 self._shutdown(False) 623 624 # If we got an alert, raise it 625 recordHeader, p = result 626 if recordHeader.type == ContentType.alert: 627 alert = Alert().parse(p) 628 raise TLSRemoteAlert(alert) 629 else: 630 # If we got some other message who know what 631 # the remote side is doing, just go ahead and 632 # raise the socket.error 633 raise
634
635 - def _getMsg(self, expectedType, secondaryType=None, constructorType=None):
636 try: 637 if not isinstance(expectedType, tuple): 638 expectedType = (expectedType,) 639 640 #Spin in a loop, until we've got a non-empty record of a type we 641 #expect. The loop will be repeated if: 642 # - we receive a renegotiation attempt; we send no_renegotiation, 643 # then try again 644 # - we receive an empty application-data fragment; we try again 645 while 1: 646 for result in self._getNextRecord(): 647 if result in (0,1): 648 yield result 649 else: 650 break 651 recordHeader, p = result 652 653 #If this is an empty application-data fragment, try again 654 if recordHeader.type == ContentType.application_data: 655 if p.index == len(p.bytes): 656 continue 657 658 #If we received an unexpected record type... 659 if recordHeader.type not in expectedType: 660 661 #If we received an alert... 662 if recordHeader.type == ContentType.alert: 663 alert = Alert().parse(p) 664 665 #We either received a fatal error, a warning, or a 666 #close_notify. In any case, we're going to close the 667 #connection. In the latter two cases we respond with 668 #a close_notify, but ignore any socket errors, since 669 #the other side might have already closed the socket. 670 if alert.level == AlertLevel.warning or \ 671 alert.description == AlertDescription.close_notify: 672 673 #If the sendMsg() call fails because the socket has 674 #already been closed, we will be forgiving and not 675 #report the error nor invalidate the "resumability" 676 #of the session. 677 try: 678 alertMsg = Alert() 679 alertMsg.create(AlertDescription.close_notify, 680 AlertLevel.warning) 681 for result in self._sendMsg(alertMsg): 682 yield result 683 except socket.error: 684 pass 685 686 if alert.description == \ 687 AlertDescription.close_notify: 688 self._shutdown(True) 689 elif alert.level == AlertLevel.warning: 690 self._shutdown(False) 691 692 else: #Fatal alert: 693 self._shutdown(False) 694 695 #Raise the alert as an exception 696 raise TLSRemoteAlert(alert) 697 698 #If we received a renegotiation attempt... 699 if recordHeader.type == ContentType.handshake: 700 subType = p.get(1) 701 reneg = False 702 if self._client: 703 if subType == HandshakeType.hello_request: 704 reneg = True 705 else: 706 if subType == HandshakeType.client_hello: 707 reneg = True 708 #Send no_renegotiation, then try again 709 if reneg: 710 alertMsg = Alert() 711 alertMsg.create(AlertDescription.no_renegotiation, 712 AlertLevel.warning) 713 for result in self._sendMsg(alertMsg): 714 yield result 715 continue 716 717 #Otherwise: this is an unexpected record, but neither an 718 #alert nor renegotiation 719 for result in self._sendError(\ 720 AlertDescription.unexpected_message, 721 "received type=%d" % recordHeader.type): 722 yield result 723 724 break 725 726 #Parse based on content_type 727 if recordHeader.type == ContentType.change_cipher_spec: 728 yield ChangeCipherSpec().parse(p) 729 elif recordHeader.type == ContentType.alert: 730 yield Alert().parse(p) 731 elif recordHeader.type == ContentType.application_data: 732 yield ApplicationData().parse(p) 733 elif recordHeader.type == ContentType.handshake: 734 #Convert secondaryType to tuple, if it isn't already 735 if not isinstance(secondaryType, tuple): 736 secondaryType = (secondaryType,) 737 738 #If it's a handshake message, check handshake header 739 if recordHeader.ssl2: 740 subType = p.get(1) 741 if subType != HandshakeType.client_hello: 742 for result in self._sendError(\ 743 AlertDescription.unexpected_message, 744 "Can only handle SSLv2 ClientHello messages"): 745 yield result 746 if HandshakeType.client_hello not in secondaryType: 747 for result in self._sendError(\ 748 AlertDescription.unexpected_message): 749 yield result 750 subType = HandshakeType.client_hello 751 else: 752 subType = p.get(1) 753 if subType not in secondaryType: 754 for result in self._sendError(\ 755 AlertDescription.unexpected_message, 756 "Expecting %s, got %s" % (str(secondaryType), subType)): 757 yield result 758 759 #Update handshake hashes 760 self._handshake_hash.update(p.bytes) 761 762 #Parse based on handshake type 763 if subType == HandshakeType.client_hello: 764 yield ClientHello(recordHeader.ssl2).parse(p) 765 elif subType == HandshakeType.server_hello: 766 yield ServerHello().parse(p) 767 elif subType == HandshakeType.certificate: 768 yield Certificate(constructorType).parse(p) 769 elif subType == HandshakeType.certificate_request: 770 yield CertificateRequest(self.version).parse(p) 771 elif subType == HandshakeType.certificate_verify: 772 yield CertificateVerify(self.version).parse(p) 773 elif subType == HandshakeType.server_key_exchange: 774 yield ServerKeyExchange(constructorType, 775 self.version).parse(p) 776 elif subType == HandshakeType.server_hello_done: 777 yield ServerHelloDone().parse(p) 778 elif subType == HandshakeType.client_key_exchange: 779 yield ClientKeyExchange(constructorType, \ 780 self.version).parse(p) 781 elif subType == HandshakeType.finished: 782 yield Finished(self.version).parse(p) 783 elif subType == HandshakeType.next_protocol: 784 yield NextProtocol().parse(p) 785 else: 786 raise AssertionError() 787 788 #If an exception was raised by a Parser or Message instance: 789 except SyntaxError as e: 790 for result in self._sendError(AlertDescription.decode_error, 791 formatExceptionTrace(e)): 792 yield result
793 794 #Returns next record or next handshake message
795 - def _getNextRecord(self):
796 """read next message from socket, defragment message""" 797 798 while True: 799 # support for fragmentation 800 # (RFC 5246 Section 6.2.1) 801 # Because the Record Layer is completely separate from the messages 802 # that traverse it, it should handle both application data and 803 # hadshake data in the same way. For that we buffer the handshake 804 # messages until they are completely read. 805 # This makes it possible to handle both handshake data not aligned 806 # to record boundary as well as handshakes longer than single 807 # record. 808 while True: 809 # empty message buffer 810 ret = self._defragmenter.getMessage() 811 if ret is None: 812 break 813 header = RecordHeader3().create(self.version, ret[0], 0) 814 yield header, Parser(ret[1]) 815 816 # when the message buffer is empty, read next record from socket 817 for result in self._getNextRecordFromSocket(): 818 if result in (0, 1): 819 yield result 820 else: 821 break 822 823 header, parser = result 824 825 # application data isn't made out of messages, pass it through 826 if header.type == ContentType.application_data: 827 yield (header, parser) 828 # If it's an SSLv2 ClientHello, we can return it as well, since 829 # it's the only ssl2 type we support 830 elif header.ssl2: 831 yield (header, parser) 832 else: 833 # other types need to be put into buffers 834 self._defragmenter.addData(header.type, parser.bytes)
835
836 - def _getNextRecordFromSocket(self):
837 """Read a record, handle errors""" 838 839 try: 840 # otherwise... read the next record 841 for result in self._recordLayer.recvRecord(): 842 if result in (0, 1): 843 yield result 844 else: 845 break 846 except TLSRecordOverflow: 847 for result in self._sendError(AlertDescription.record_overflow): 848 yield result 849 except TLSIllegalParameterException: 850 for result in self._sendError(AlertDescription.illegal_parameter): 851 yield result 852 except TLSDecryptionFailed: 853 for result in self._sendError( 854 AlertDescription.decryption_failed, 855 "Encrypted data not a multiple of blocksize"): 856 yield result 857 except TLSBadRecordMAC: 858 for result in self._sendError( 859 AlertDescription.bad_record_mac, 860 "MAC failure (or padding failure)"): 861 yield result 862 863 header, parser = result 864 865 # RFC5246 section 5.2.1: Implementations MUST NOT send 866 # zero-length fragments of content types other than Application 867 # Data. 868 if header.type != ContentType.application_data \ 869 and parser.getRemainingLength() == 0: 870 for result in self._sendError(\ 871 AlertDescription.decode_error, \ 872 "Received empty non-application data record"): 873 yield result 874 875 if header.type not in ContentType.all: 876 for result in self._sendError(\ 877 AlertDescription.unexpected_message, \ 878 "Received record with unknown ContentType"): 879 yield result 880 881 yield (header, parser)
882
883 - def _handshakeStart(self, client):
884 if not self.closed: 885 raise ValueError("Renegotiation disallowed for security reasons") 886 self._client = client 887 self._handshake_hash = HandshakeHashes() 888 self._defragmenter.clearBuffers() 889 self.allegedSrpUsername = None 890 self._refCount = 1
891
892 - def _handshakeDone(self, resumed):
893 self.resumed = resumed 894 self.closed = False
895
896 - def _calcPendingStates(self, cipherSuite, masterSecret, 897 clientRandom, serverRandom, implementations):
898 self._recordLayer.calcPendingStates(cipherSuite, masterSecret, 899 clientRandom, serverRandom, 900 implementations)
901
902 - def _changeWriteState(self):
903 self._recordLayer.changeWriteState()
904
905 - def _changeReadState(self):
906 self._recordLayer.changeReadState()
907