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