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  #   Martin von Loewis - python 3 port 
   5  # 
   6  # See the LICENSE file for legal information regarding use of this file. 
   7   
   8  """Helper class for TLSConnection.""" 
   9  from __future__ import generators 
  10   
  11  from .utils.compat import * 
  12  from .utils.cryptomath import * 
  13  from .utils.cipherfactory import createAES, createRC4, createTripleDES 
  14  from .utils.codec import * 
  15  from .errors import * 
  16  from .messages import * 
  17  from .mathtls import * 
  18  from .constants import * 
  19  from .utils.cryptomath import getRandomBytes 
  20   
  21  import socket 
  22  import errno 
  23  import traceback 
  24   
25 -class _ConnectionState:
26 - def __init__(self):
27 self.macContext = None 28 self.encContext = None 29 self.seqnum = 0
30
31 - def getSeqNumBytes(self):
32 w = Writer() 33 w.add(self.seqnum, 8) 34 self.seqnum += 1 35 return w.bytes
36 37
38 -class TLSRecordLayer:
39 """ 40 This class handles data transmission for a TLS connection. 41 42 Its only subclass is L{tlslite.TLSConnection.TLSConnection}. We've 43 separated the code in this class from TLSConnection to make things 44 more readable. 45 46 47 @type sock: socket.socket 48 @ivar sock: The underlying socket object. 49 50 @type session: L{tlslite.Session.Session} 51 @ivar session: The session corresponding to this connection. 52 53 Due to TLS session resumption, multiple connections can correspond 54 to the same underlying session. 55 56 @type version: tuple 57 @ivar version: The TLS version being used for this connection. 58 59 (3,0) means SSL 3.0, and (3,1) means TLS 1.0. 60 61 @type closed: bool 62 @ivar closed: If this connection is closed. 63 64 @type resumed: bool 65 @ivar resumed: If this connection is based on a resumed session. 66 67 @type allegedSrpUsername: str or None 68 @ivar allegedSrpUsername: This is set to the SRP username 69 asserted by the client, whether the handshake succeeded or not. 70 If the handshake fails, this can be inspected to determine 71 if a guessing attack is in progress against a particular user 72 account. 73 74 @type closeSocket: bool 75 @ivar closeSocket: If the socket should be closed when the 76 connection is closed, defaults to True (writable). 77 78 If you set this to True, TLS Lite will assume the responsibility of 79 closing the socket when the TLS Connection is shutdown (either 80 through an error or through the user calling close()). The default 81 is False. 82 83 @type ignoreAbruptClose: bool 84 @ivar ignoreAbruptClose: If an abrupt close of the socket should 85 raise an error (writable). 86 87 If you set this to True, TLS Lite will not raise a 88 L{tlslite.errors.TLSAbruptCloseError} exception if the underlying 89 socket is unexpectedly closed. Such an unexpected closure could be 90 caused by an attacker. However, it also occurs with some incorrect 91 TLS implementations. 92 93 You should set this to True only if you're not worried about an 94 attacker truncating the connection, and only if necessary to avoid 95 spurious errors. The default is False. 96 97 @sort: __init__, read, readAsync, write, writeAsync, close, closeAsync, 98 getCipherImplementation, getCipherName 99 """ 100
101 - def __init__(self, sock):
102 self.sock = sock 103 104 #My session object (Session instance; read-only) 105 self.session = None 106 107 #Am I a client or server? 108 self._client = None 109 110 #Buffers for processing messages 111 self._handshakeBuffer = [] 112 self._readBuffer = b"" 113 114 #Handshake digests 115 self._handshake_md5 = hashlib.md5() 116 self._handshake_sha = hashlib.sha1() 117 118 #TLS Protocol Version 119 self.version = (0,0) #read-only 120 self._versionCheck = False #Once we choose a version, this is True 121 122 #Current and Pending connection states 123 self._writeState = _ConnectionState() 124 self._readState = _ConnectionState() 125 self._pendingWriteState = _ConnectionState() 126 self._pendingReadState = _ConnectionState() 127 128 #Is the connection open? 129 self.closed = True #read-only 130 self._refCount = 0 #Used to trigger closure 131 132 #Is this a resumed session? 133 self.resumed = False #read-only 134 135 #What username did the client claim in his handshake? 136 self.allegedSrpUsername = None 137 138 #On a call to close(), do we close the socket? (writeable) 139 self.closeSocket = True 140 141 #If the socket is abruptly closed, do we ignore it 142 #and pretend the connection was shut down properly? (writeable) 143 self.ignoreAbruptClose = False 144 145 #Fault we will induce, for testing purposes 146 self.fault = None
147 148 #********************************************************* 149 # Public Functions START 150 #********************************************************* 151
152 - def read(self, max=None, min=1):
153 """Read some data from the TLS connection. 154 155 This function will block until at least 'min' bytes are 156 available (or the connection is closed). 157 158 If an exception is raised, the connection will have been 159 automatically closed. 160 161 @type max: int 162 @param max: The maximum number of bytes to return. 163 164 @type min: int 165 @param min: The minimum number of bytes to return 166 167 @rtype: str 168 @return: A string of no more than 'max' bytes, and no fewer 169 than 'min' (unless the connection has been closed, in which 170 case fewer than 'min' bytes may be returned). 171 172 @raise socket.error: If a socket error occurs. 173 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed 174 without a preceding alert. 175 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled. 176 """ 177 for result in self.readAsync(max, min): 178 pass 179 return result
180
181 - def readAsync(self, max=None, min=1):
182 """Start a read operation on the TLS connection. 183 184 This function returns a generator which behaves similarly to 185 read(). Successive invocations of the generator will return 0 186 if it is waiting to read from the socket, 1 if it is waiting 187 to write to the socket, or a string if the read operation has 188 completed. 189 190 @rtype: iterable 191 @return: A generator; see above for details. 192 """ 193 try: 194 while len(self._readBuffer)<min and not self.closed: 195 try: 196 for result in self._getMsg(ContentType.application_data): 197 if result in (0,1): 198 yield result 199 applicationData = result 200 self._readBuffer += applicationData.write() 201 except TLSRemoteAlert as alert: 202 if alert.description != AlertDescription.close_notify: 203 raise 204 except TLSAbruptCloseError: 205 if not self.ignoreAbruptClose: 206 raise 207 else: 208 self._shutdown(True) 209 210 if max == None: 211 max = len(self._readBuffer) 212 213 returnBytes = self._readBuffer[:max] 214 self._readBuffer = self._readBuffer[max:] 215 yield bytes(returnBytes) 216 except GeneratorExit: 217 raise 218 except: 219 self._shutdown(False) 220 raise
221
222 - def write(self, s):
223 """Write some data to the TLS connection. 224 225 This function will block until all the data has been sent. 226 227 If an exception is raised, the connection will have been 228 automatically closed. 229 230 @type s: str 231 @param s: The data to transmit to the other party. 232 233 @raise socket.error: If a socket error occurs. 234 """ 235 for result in self.writeAsync(s): 236 pass
237
238 - def writeAsync(self, s):
239 """Start a write operation on the TLS connection. 240 241 This function returns a generator which behaves similarly to 242 write(). Successive invocations of the generator will return 243 1 if it is waiting to write to the socket, or will raise 244 StopIteration if the write operation has completed. 245 246 @rtype: iterable 247 @return: A generator; see above for details. 248 """ 249 try: 250 if self.closed: 251 raise ValueError() 252 253 index = 0 254 blockSize = 16384 255 randomizeFirstBlock = True 256 while 1: 257 startIndex = index * blockSize 258 endIndex = startIndex + blockSize 259 if startIndex >= len(s): 260 break 261 if endIndex > len(s): 262 endIndex = len(s) 263 block = bytearray(s[startIndex : endIndex]) 264 applicationData = ApplicationData().create(block) 265 for result in self._sendMsg(applicationData, \ 266 randomizeFirstBlock): 267 yield result 268 randomizeFirstBlock = False #only on 1st message 269 index += 1 270 except GeneratorExit: 271 raise 272 except: 273 self._shutdown(False) 274 raise
275
276 - def close(self):
277 """Close the TLS connection. 278 279 This function will block until it has exchanged close_notify 280 alerts with the other party. After doing so, it will shut down the 281 TLS connection. Further attempts to read through this connection 282 will return "". Further attempts to write through this connection 283 will raise ValueError. 284 285 If makefile() has been called on this connection, the connection 286 will be not be closed until the connection object and all file 287 objects have been closed. 288 289 Even if an exception is raised, the connection will have been 290 closed. 291 292 @raise socket.error: If a socket error occurs. 293 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed 294 without a preceding alert. 295 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled. 296 """ 297 if not self.closed: 298 for result in self._decrefAsync(): 299 pass
300 301 # Python 3 callback 302 _decref_socketios = close 303
304 - def closeAsync(self):
305 """Start a close operation on the TLS connection. 306 307 This function returns a generator which behaves similarly to 308 close(). Successive invocations of the generator will return 0 309 if it is waiting to read from the socket, 1 if it is waiting 310 to write to the socket, or will raise StopIteration if the 311 close operation has completed. 312 313 @rtype: iterable 314 @return: A generator; see above for details. 315 """ 316 if not self.closed: 317 for result in self._decrefAsync(): 318 yield result
319
320 - def _decrefAsync(self):
321 self._refCount -= 1 322 if self._refCount == 0 and not self.closed: 323 try: 324 for result in self._sendMsg(Alert().create(\ 325 AlertDescription.close_notify, AlertLevel.warning)): 326 yield result 327 alert = None 328 # By default close the socket, since it's been observed 329 # that some other libraries will not respond to the 330 # close_notify alert, thus leaving us hanging if we're 331 # expecting it 332 if self.closeSocket: 333 self._shutdown(True) 334 else: 335 while not alert: 336 for result in self._getMsg((ContentType.alert, \ 337 ContentType.application_data)): 338 if result in (0,1): 339 yield result 340 if result.contentType == ContentType.alert: 341 alert = result 342 if alert.description == AlertDescription.close_notify: 343 self._shutdown(True) 344 else: 345 raise TLSRemoteAlert(alert) 346 except (socket.error, TLSAbruptCloseError): 347 #If the other side closes the socket, that's okay 348 self._shutdown(True) 349 except GeneratorExit: 350 raise 351 except: 352 self._shutdown(False) 353 raise
354
355 - def getVersionName(self):
356 """Get the name of this TLS version. 357 358 @rtype: str 359 @return: The name of the TLS version used with this connection. 360 Either None, 'SSL 3.0', 'TLS 1.0', or 'TLS 1.1'. 361 """ 362 if self.version == (3,0): 363 return "SSL 3.0" 364 elif self.version == (3,1): 365 return "TLS 1.0" 366 elif self.version == (3,2): 367 return "TLS 1.1" 368 else: 369 return None
370
371 - def getCipherName(self):
372 """Get the name of the cipher used with this connection. 373 374 @rtype: str 375 @return: The name of the cipher used with this connection. 376 Either 'aes128', 'aes256', 'rc4', or '3des'. 377 """ 378 if not self._writeState.encContext: 379 return None 380 return self._writeState.encContext.name
381
382 - def getCipherImplementation(self):
383 """Get the name of the cipher implementation used with 384 this connection. 385 386 @rtype: str 387 @return: The name of the cipher implementation used with 388 this connection. Either 'python', 'openssl', or 'pycrypto'. 389 """ 390 if not self._writeState.encContext: 391 return None 392 return self._writeState.encContext.implementation
393 394 395 396 #Emulate a socket, somewhat -
397 - def send(self, s):
398 """Send data to the TLS connection (socket emulation). 399 400 @raise socket.error: If a socket error occurs. 401 """ 402 self.write(s) 403 return len(s)
404
405 - def sendall(self, s):
406 """Send data to the TLS connection (socket emulation). 407 408 @raise socket.error: If a socket error occurs. 409 """ 410 self.write(s)
411
412 - def recv(self, bufsize):
413 """Get some data from the TLS connection (socket emulation). 414 415 @raise socket.error: If a socket error occurs. 416 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed 417 without a preceding alert. 418 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled. 419 """ 420 return self.read(bufsize)
421
422 - def recv_into(self, b):
423 # XXX doc string 424 data = self.read(len(b)) 425 if not data: 426 return None 427 b[:len(data)] = data 428 return len(data)
429
430 - def makefile(self, mode='r', bufsize=-1):
431 """Create a file object for the TLS connection (socket emulation). 432 433 @rtype: L{socket._fileobject} 434 """ 435 self._refCount += 1 436 # So, it is pretty fragile to be using Python internal objects 437 # like this, but it is probably the best/easiest way to provide 438 # matching behavior for socket emulation purposes. The 'close' 439 # argument is nice, its apparently a recent addition to this 440 # class, so that when fileobject.close() gets called, it will 441 # close() us, causing the refcount to be decremented (decrefAsync). 442 # 443 # If this is the last close() on the outstanding fileobjects / 444 # TLSConnection, then the "actual" close alerts will be sent, 445 # socket closed, etc. 446 if sys.version_info < (3,): 447 return socket._fileobject(self, mode, bufsize, close=True) 448 else: 449 # XXX need to wrap this further if buffering is requested 450 return socket.SocketIO(self, mode)
451
452 - def getsockname(self):
453 """Return the socket's own address (socket emulation).""" 454 return self.sock.getsockname()
455
456 - def getpeername(self):
457 """Return the remote address to which the socket is connected 458 (socket emulation).""" 459 return self.sock.getpeername()
460
461 - def settimeout(self, value):
462 """Set a timeout on blocking socket operations (socket emulation).""" 463 return self.sock.settimeout(value)
464
465 - def gettimeout(self):
466 """Return the timeout associated with socket operations (socket 467 emulation).""" 468 return self.sock.gettimeout()
469
470 - def setsockopt(self, level, optname, value):
471 """Set the value of the given socket option (socket emulation).""" 472 return self.sock.setsockopt(level, optname, value)
473
474 - def shutdown(self, how):
475 """Shutdown the underlying socket.""" 476 return self.sock.shutdown(how)
477
478 - def fileno(self):
479 """Not implement in TLS Lite.""" 480 raise NotImplementedError()
481 482 483 #********************************************************* 484 # Public Functions END 485 #********************************************************* 486
487 - def _shutdown(self, resumable):
488 self._writeState = _ConnectionState() 489 self._readState = _ConnectionState() 490 #Don't do this: self._readBuffer = "" 491 self.version = (0,0) 492 self._versionCheck = False 493 self.closed = True 494 if self.closeSocket: 495 self.sock.close() 496 497 #Even if resumable is False, we'll never toggle this on 498 if not resumable and self.session: 499 self.session.resumable = False
500 501
502 - def _sendError(self, alertDescription, errorStr=None):
503 alert = Alert().create(alertDescription, AlertLevel.fatal) 504 for result in self._sendMsg(alert): 505 yield result 506 self._shutdown(False) 507 raise TLSLocalAlert(alert, errorStr)
508
509 - def _sendMsgs(self, msgs):
510 randomizeFirstBlock = True 511 for msg in msgs: 512 for result in self._sendMsg(msg, randomizeFirstBlock): 513 yield result 514 randomizeFirstBlock = True
515
516 - def _sendMsg(self, msg, randomizeFirstBlock = True):
517 #Whenever we're connected and asked to send an app data message, 518 #we first send the first byte of the message. This prevents 519 #an attacker from launching a chosen-plaintext attack based on 520 #knowing the next IV (a la BEAST). 521 if not self.closed and randomizeFirstBlock and self.version <= (3,1) \ 522 and self._writeState.encContext \ 523 and self._writeState.encContext.isBlockCipher \ 524 and isinstance(msg, ApplicationData): 525 msgFirstByte = msg.splitFirstByte() 526 for result in self._sendMsg(msgFirstByte, 527 randomizeFirstBlock = False): 528 yield result 529 530 b = msg.write() 531 532 # If a 1-byte message was passed in, and we "split" the 533 # first(only) byte off above, we may have a 0-length msg: 534 if len(b) == 0: 535 return 536 537 contentType = msg.contentType 538 539 #Update handshake hashes 540 if contentType == ContentType.handshake: 541 self._handshake_md5.update(compat26Str(b)) 542 self._handshake_sha.update(compat26Str(b)) 543 544 #Calculate MAC 545 if self._writeState.macContext: 546 seqnumBytes = self._writeState.getSeqNumBytes() 547 mac = self._writeState.macContext.copy() 548 mac.update(compatHMAC(seqnumBytes)) 549 mac.update(compatHMAC(bytearray([contentType]))) 550 if self.version == (3,0): 551 mac.update( compatHMAC( bytearray([len(b)//256] ))) 552 mac.update( compatHMAC( bytearray([len(b)%256] ))) 553 elif self.version in ((3,1), (3,2)): 554 mac.update(compatHMAC( bytearray([self.version[0]] ))) 555 mac.update(compatHMAC( bytearray([self.version[1]] ))) 556 mac.update( compatHMAC( bytearray([len(b)//256] ))) 557 mac.update( compatHMAC( bytearray([len(b)%256] ))) 558 else: 559 raise AssertionError() 560 mac.update(compatHMAC(b)) 561 macBytes = bytearray(mac.digest()) 562 if self.fault == Fault.badMAC: 563 macBytes[0] = (macBytes[0]+1) % 256 564 565 #Encrypt for Block or Stream Cipher 566 if self._writeState.encContext: 567 #Add padding and encrypt (for Block Cipher): 568 if self._writeState.encContext.isBlockCipher: 569 570 #Add TLS 1.1 fixed block 571 if self.version == (3,2): 572 b = self.fixedIVBlock + b 573 574 #Add padding: b = b+ (macBytes + paddingBytes) 575 currentLength = len(b) + len(macBytes) + 1 576 blockLength = self._writeState.encContext.block_size 577 paddingLength = blockLength-(currentLength % blockLength) 578 579 paddingBytes = bytearray([paddingLength] * (paddingLength+1)) 580 if self.fault == Fault.badPadding: 581 paddingBytes[0] = (paddingBytes[0]+1) % 256 582 endBytes = macBytes + paddingBytes 583 b += endBytes 584 #Encrypt 585 b = self._writeState.encContext.encrypt(b) 586 587 #Encrypt (for Stream Cipher) 588 else: 589 b += macBytes 590 b = self._writeState.encContext.encrypt(b) 591 592 #Add record header and send 593 r = RecordHeader3().create(self.version, contentType, len(b)) 594 s = r.write() + b 595 while 1: 596 try: 597 bytesSent = self.sock.send(s) #Might raise socket.error 598 except socket.error as why: 599 if why.args[0] == errno.EWOULDBLOCK: 600 yield 1 601 continue 602 else: 603 # The socket was unexpectedly closed. The tricky part 604 # is that there may be an alert sent by the other party 605 # sitting in the read buffer. So, if we get here after 606 # handshaking, we will just raise the error and let the 607 # caller read more data if it would like, thus stumbling 608 # upon the error. 609 # 610 # However, if we get here DURING handshaking, we take 611 # it upon ourselves to see if the next message is an 612 # Alert. 613 if contentType == ContentType.handshake: 614 615 # See if there's an alert record 616 # Could raise socket.error or TLSAbruptCloseError 617 for result in self._getNextRecord(): 618 if result in (0,1): 619 yield result 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 if bytesSent == len(s): 635 return 636 s = s[bytesSent:] 637 yield 1
638 639
640 - def _getMsg(self, expectedType, secondaryType=None, constructorType=None):
641 try: 642 if not isinstance(expectedType, tuple): 643 expectedType = (expectedType,) 644 645 #Spin in a loop, until we've got a non-empty record of a type we 646 #expect. The loop will be repeated if: 647 # - we receive a renegotiation attempt; we send no_renegotiation, 648 # then try again 649 # - we receive an empty application-data fragment; we try again 650 while 1: 651 for result in self._getNextRecord(): 652 if result in (0,1): 653 yield result 654 recordHeader, p = result 655 656 #If this is an empty application-data fragment, try again 657 if recordHeader.type == ContentType.application_data: 658 if p.index == len(p.bytes): 659 continue 660 661 #If we received an unexpected record type... 662 if recordHeader.type not in expectedType: 663 664 #If we received an alert... 665 if recordHeader.type == ContentType.alert: 666 alert = Alert().parse(p) 667 668 #We either received a fatal error, a warning, or a 669 #close_notify. In any case, we're going to close the 670 #connection. In the latter two cases we respond with 671 #a close_notify, but ignore any socket errors, since 672 #the other side might have already closed the socket. 673 if alert.level == AlertLevel.warning or \ 674 alert.description == AlertDescription.close_notify: 675 676 #If the sendMsg() call fails because the socket has 677 #already been closed, we will be forgiving and not 678 #report the error nor invalidate the "resumability" 679 #of the session. 680 try: 681 alertMsg = Alert() 682 alertMsg.create(AlertDescription.close_notify, 683 AlertLevel.warning) 684 for result in self._sendMsg(alertMsg): 685 yield result 686 except socket.error: 687 pass 688 689 if alert.description == \ 690 AlertDescription.close_notify: 691 self._shutdown(True) 692 elif alert.level == AlertLevel.warning: 693 self._shutdown(False) 694 695 else: #Fatal alert: 696 self._shutdown(False) 697 698 #Raise the alert as an exception 699 raise TLSRemoteAlert(alert) 700 701 #If we received a renegotiation attempt... 702 if recordHeader.type == ContentType.handshake: 703 subType = p.get(1) 704 reneg = False 705 if self._client: 706 if subType == HandshakeType.hello_request: 707 reneg = True 708 else: 709 if subType == HandshakeType.client_hello: 710 reneg = True 711 #Send no_renegotiation, then try again 712 if reneg: 713 alertMsg = Alert() 714 alertMsg.create(AlertDescription.no_renegotiation, 715 AlertLevel.warning) 716 for result in self._sendMsg(alertMsg): 717 yield result 718 continue 719 720 #Otherwise: this is an unexpected record, but neither an 721 #alert nor renegotiation 722 for result in self._sendError(\ 723 AlertDescription.unexpected_message, 724 "received type=%d" % recordHeader.type): 725 yield result 726 727 break 728 729 #Parse based on content_type 730 if recordHeader.type == ContentType.change_cipher_spec: 731 yield ChangeCipherSpec().parse(p) 732 elif recordHeader.type == ContentType.alert: 733 yield Alert().parse(p) 734 elif recordHeader.type == ContentType.application_data: 735 yield ApplicationData().parse(p) 736 elif recordHeader.type == ContentType.handshake: 737 #Convert secondaryType to tuple, if it isn't already 738 if not isinstance(secondaryType, tuple): 739 secondaryType = (secondaryType,) 740 741 #If it's a handshake message, check handshake header 742 if recordHeader.ssl2: 743 subType = p.get(1) 744 if subType != HandshakeType.client_hello: 745 for result in self._sendError(\ 746 AlertDescription.unexpected_message, 747 "Can only handle SSLv2 ClientHello messages"): 748 yield result 749 if HandshakeType.client_hello not in secondaryType: 750 for result in self._sendError(\ 751 AlertDescription.unexpected_message): 752 yield result 753 subType = HandshakeType.client_hello 754 else: 755 subType = p.get(1) 756 if subType not in secondaryType: 757 for result in self._sendError(\ 758 AlertDescription.unexpected_message, 759 "Expecting %s, got %s" % (str(secondaryType), subType)): 760 yield result 761 762 #Update handshake hashes 763 self._handshake_md5.update(compat26Str(p.bytes)) 764 self._handshake_sha.update(compat26Str(p.bytes)) 765 766 #Parse based on handshake type 767 if subType == HandshakeType.client_hello: 768 yield ClientHello(recordHeader.ssl2).parse(p) 769 elif subType == HandshakeType.server_hello: 770 yield ServerHello().parse(p) 771 elif subType == HandshakeType.certificate: 772 yield Certificate(constructorType).parse(p) 773 elif subType == HandshakeType.certificate_request: 774 yield CertificateRequest().parse(p) 775 elif subType == HandshakeType.certificate_verify: 776 yield CertificateVerify().parse(p) 777 elif subType == HandshakeType.server_key_exchange: 778 yield ServerKeyExchange(constructorType).parse(p) 779 elif subType == HandshakeType.server_hello_done: 780 yield ServerHelloDone().parse(p) 781 elif subType == HandshakeType.client_key_exchange: 782 yield ClientKeyExchange(constructorType, \ 783 self.version).parse(p) 784 elif subType == HandshakeType.finished: 785 yield Finished(self.version).parse(p) 786 elif subType == HandshakeType.next_protocol: 787 yield NextProtocol().parse(p) 788 else: 789 raise AssertionError() 790 791 #If an exception was raised by a Parser or Message instance: 792 except SyntaxError as e: 793 for result in self._sendError(AlertDescription.decode_error, 794 formatExceptionTrace(e)): 795 yield result
796 797 798 #Returns next record or next handshake message
799 - def _getNextRecord(self):
800 801 #If there's a handshake message waiting, return it 802 if self._handshakeBuffer: 803 recordHeader, b = self._handshakeBuffer[0] 804 self._handshakeBuffer = self._handshakeBuffer[1:] 805 yield (recordHeader, Parser(b)) 806 return 807 808 #Otherwise... 809 #Read the next record header 810 b = bytearray(0) 811 recordHeaderLength = 1 812 ssl2 = False 813 while 1: 814 try: 815 s = self.sock.recv(recordHeaderLength-len(b)) 816 except socket.error as why: 817 if why.args[0] == errno.EWOULDBLOCK: 818 yield 0 819 continue 820 else: 821 raise 822 823 #If the connection was abruptly closed, raise an error 824 if len(s)==0: 825 raise TLSAbruptCloseError() 826 827 b += bytearray(s) 828 if len(b)==1: 829 if b[0] in ContentType.all: 830 ssl2 = False 831 recordHeaderLength = 5 832 elif b[0] == 128: 833 ssl2 = True 834 recordHeaderLength = 2 835 else: 836 raise SyntaxError() 837 if len(b) == recordHeaderLength: 838 break 839 840 #Parse the record header 841 if ssl2: 842 r = RecordHeader2().parse(Parser(b)) 843 else: 844 r = RecordHeader3().parse(Parser(b)) 845 846 #Check the record header fields 847 if r.length > 18432: 848 for result in self._sendError(AlertDescription.record_overflow): 849 yield result 850 851 #Read the record contents 852 b = bytearray(0) 853 while 1: 854 try: 855 s = self.sock.recv(r.length - len(b)) 856 except socket.error as why: 857 if why.args[0] == errno.EWOULDBLOCK: 858 yield 0 859 continue 860 else: 861 raise 862 863 #If the connection is closed, raise a socket error 864 if len(s)==0: 865 raise TLSAbruptCloseError() 866 867 b += bytearray(s) 868 if len(b) == r.length: 869 break 870 871 #Check the record header fields (2) 872 #We do this after reading the contents from the socket, so that 873 #if there's an error, we at least don't leave extra bytes in the 874 #socket.. 875 # 876 # THIS CHECK HAS NO SECURITY RELEVANCE (?), BUT COULD HURT INTEROP. 877 # SO WE LEAVE IT OUT FOR NOW. 878 # 879 #if self._versionCheck and r.version != self.version: 880 # for result in self._sendError(AlertDescription.protocol_version, 881 # "Version in header field: %s, should be %s" % (str(r.version), 882 # str(self.version))): 883 # yield result 884 885 #Decrypt the record 886 for result in self._decryptRecord(r.type, b): 887 if result in (0,1): yield result 888 else: break 889 b = result 890 p = Parser(b) 891 892 #If it doesn't contain handshake messages, we can just return it 893 if r.type != ContentType.handshake: 894 yield (r, p) 895 #If it's an SSLv2 ClientHello, we can return it as well 896 elif r.ssl2: 897 yield (r, p) 898 else: 899 #Otherwise, we loop through and add the handshake messages to the 900 #handshake buffer 901 while 1: 902 if p.index == len(b): #If we're at the end 903 if not self._handshakeBuffer: 904 for result in self._sendError(\ 905 AlertDescription.decode_error, \ 906 "Received empty handshake record"): 907 yield result 908 break 909 #There needs to be at least 4 bytes to get a header 910 if p.index+4 > len(b): 911 for result in self._sendError(\ 912 AlertDescription.decode_error, 913 "A record has a partial handshake message (1)"): 914 yield result 915 p.get(1) # skip handshake type 916 msgLength = p.get(3) 917 if p.index+msgLength > len(b): 918 for result in self._sendError(\ 919 AlertDescription.decode_error, 920 "A record has a partial handshake message (2)"): 921 yield result 922 923 handshakePair = (r, b[p.index-4 : p.index+msgLength]) 924 self._handshakeBuffer.append(handshakePair) 925 p.index += msgLength 926 927 #We've moved at least one handshake message into the 928 #handshakeBuffer, return the first one 929 recordHeader, b = self._handshakeBuffer[0] 930 self._handshakeBuffer = self._handshakeBuffer[1:] 931 yield (recordHeader, Parser(b))
932 933
934 - def _decryptRecord(self, recordType, b):
935 if self._readState.encContext: 936 937 #Decrypt if it's a block cipher 938 if self._readState.encContext.isBlockCipher: 939 blockLength = self._readState.encContext.block_size 940 if len(b) % blockLength != 0: 941 for result in self._sendError(\ 942 AlertDescription.decryption_failed, 943 "Encrypted data not a multiple of blocksize"): 944 yield result 945 b = self._readState.encContext.decrypt(b) 946 if self.version == (3,2): #For TLS 1.1, remove explicit IV 947 b = b[self._readState.encContext.block_size : ] 948 949 #Check padding 950 paddingGood = True 951 paddingLength = b[-1] 952 if (paddingLength+1) > len(b): 953 paddingGood=False 954 totalPaddingLength = 0 955 else: 956 if self.version == (3,0): 957 totalPaddingLength = paddingLength+1 958 elif self.version in ((3,1), (3,2)): 959 totalPaddingLength = paddingLength+1 960 paddingBytes = b[-totalPaddingLength:-1] 961 for byte in paddingBytes: 962 if byte != paddingLength: 963 paddingGood = False 964 totalPaddingLength = 0 965 else: 966 raise AssertionError() 967 968 #Decrypt if it's a stream cipher 969 else: 970 paddingGood = True 971 b = self._readState.encContext.decrypt(b) 972 totalPaddingLength = 0 973 974 #Check MAC 975 macGood = True 976 macLength = self._readState.macContext.digest_size 977 endLength = macLength + totalPaddingLength 978 if endLength > len(b): 979 macGood = False 980 else: 981 #Read MAC 982 startIndex = len(b) - endLength 983 endIndex = startIndex + macLength 984 checkBytes = b[startIndex : endIndex] 985 986 #Calculate MAC 987 seqnumBytes = self._readState.getSeqNumBytes() 988 b = b[:-endLength] 989 mac = self._readState.macContext.copy() 990 mac.update(compatHMAC(seqnumBytes)) 991 mac.update(compatHMAC(bytearray([recordType]))) 992 if self.version == (3,0): 993 mac.update( compatHMAC(bytearray( [len(b)//256] ) )) 994 mac.update( compatHMAC(bytearray( [len(b)%256] ) )) 995 elif self.version in ((3,1), (3,2)): 996 mac.update(compatHMAC(bytearray( [self.version[0]] ) )) 997 mac.update(compatHMAC(bytearray( [self.version[1]] ) )) 998 mac.update(compatHMAC(bytearray( [len(b)//256] ) )) 999 mac.update(compatHMAC(bytearray( [len(b)%256] ) )) 1000 else: 1001 raise AssertionError() 1002 mac.update(compatHMAC(b)) 1003 macBytes = bytearray(mac.digest()) 1004 1005 #Compare MACs 1006 if macBytes != checkBytes: 1007 macGood = False 1008 1009 if not (paddingGood and macGood): 1010 for result in self._sendError(AlertDescription.bad_record_mac, 1011 "MAC failure (or padding failure)"): 1012 yield result 1013 1014 yield b
1015
1016 - def _handshakeStart(self, client):
1017 if not self.closed: 1018 raise ValueError("Renegotiation disallowed for security reasons") 1019 self._client = client 1020 self._handshake_md5 = hashlib.md5() 1021 self._handshake_sha = hashlib.sha1() 1022 self._handshakeBuffer = [] 1023 self.allegedSrpUsername = None 1024 self._refCount = 1
1025
1026 - def _handshakeDone(self, resumed):
1027 self.resumed = resumed 1028 self.closed = False
1029
1030 - def _calcPendingStates(self, cipherSuite, masterSecret, 1031 clientRandom, serverRandom, implementations):
1032 if cipherSuite in CipherSuite.aes128Suites: 1033 macLength = 20 1034 keyLength = 16 1035 ivLength = 16 1036 createCipherFunc = createAES 1037 elif cipherSuite in CipherSuite.aes256Suites: 1038 macLength = 20 1039 keyLength = 32 1040 ivLength = 16 1041 createCipherFunc = createAES 1042 elif cipherSuite in CipherSuite.rc4Suites: 1043 macLength = 20 1044 keyLength = 16 1045 ivLength = 0 1046 createCipherFunc = createRC4 1047 elif cipherSuite in CipherSuite.tripleDESSuites: 1048 macLength = 20 1049 keyLength = 24 1050 ivLength = 8 1051 createCipherFunc = createTripleDES 1052 else: 1053 raise AssertionError() 1054 1055 if self.version == (3,0): 1056 createMACFunc = createMAC_SSL 1057 elif self.version in ((3,1), (3,2)): 1058 createMACFunc = createHMAC 1059 1060 outputLength = (macLength*2) + (keyLength*2) + (ivLength*2) 1061 1062 #Calculate Keying Material from Master Secret 1063 if self.version == (3,0): 1064 keyBlock = PRF_SSL(masterSecret, 1065 serverRandom + clientRandom, 1066 outputLength) 1067 elif self.version in ((3,1), (3,2)): 1068 keyBlock = PRF(masterSecret, 1069 b"key expansion", 1070 serverRandom + clientRandom, 1071 outputLength) 1072 else: 1073 raise AssertionError() 1074 1075 #Slice up Keying Material 1076 clientPendingState = _ConnectionState() 1077 serverPendingState = _ConnectionState() 1078 p = Parser(keyBlock) 1079 clientMACBlock = p.getFixBytes(macLength) 1080 serverMACBlock = p.getFixBytes(macLength) 1081 clientKeyBlock = p.getFixBytes(keyLength) 1082 serverKeyBlock = p.getFixBytes(keyLength) 1083 clientIVBlock = p.getFixBytes(ivLength) 1084 serverIVBlock = p.getFixBytes(ivLength) 1085 clientPendingState.macContext = createMACFunc(compatHMAC(clientMACBlock)) 1086 serverPendingState.macContext = createMACFunc(compatHMAC(serverMACBlock)) 1087 clientPendingState.encContext = createCipherFunc(clientKeyBlock, 1088 clientIVBlock, 1089 implementations) 1090 serverPendingState.encContext = createCipherFunc(serverKeyBlock, 1091 serverIVBlock, 1092 implementations) 1093 1094 #Assign new connection states to pending states 1095 if self._client: 1096 self._pendingWriteState = clientPendingState 1097 self._pendingReadState = serverPendingState 1098 else: 1099 self._pendingWriteState = serverPendingState 1100 self._pendingReadState = clientPendingState 1101 1102 if self.version == (3,2) and ivLength: 1103 #Choose fixedIVBlock for TLS 1.1 (this is encrypted with the CBC 1104 #residue to create the IV for each sent block) 1105 self.fixedIVBlock = getRandomBytes(ivLength)
1106
1107 - def _changeWriteState(self):
1108 self._writeState = self._pendingWriteState 1109 self._pendingWriteState = _ConnectionState()
1110
1111 - def _changeReadState(self):
1112 self._readState = self._pendingReadState 1113 self._pendingReadState = _ConnectionState()
1114 1115 #Used for Finished messages and CertificateVerify messages in SSL v3
1116 - def _calcSSLHandshakeHash(self, masterSecret, label):
1117 imac_md5 = self._handshake_md5.copy() 1118 imac_sha = self._handshake_sha.copy() 1119 1120 imac_md5.update(compatHMAC(label + masterSecret + bytearray([0x36]*48))) 1121 imac_sha.update(compatHMAC(label + masterSecret + bytearray([0x36]*40))) 1122 1123 md5Bytes = MD5(masterSecret + bytearray([0x5c]*48) + \ 1124 bytearray(imac_md5.digest())) 1125 shaBytes = SHA1(masterSecret + bytearray([0x5c]*40) + \ 1126 bytearray(imac_sha.digest())) 1127 1128 return md5Bytes + shaBytes
1129