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  # 
   5  # See the LICENSE file for legal information regarding use of this file. 
   6   
   7  """Helper class for TLSConnection.""" 
   8  from __future__ import generators 
   9   
  10  from .utils.compat import * 
  11  from .utils.cryptomath import * 
  12  from .utils.cipherfactory import createAES, createRC4, createTripleDES 
  13  from .utils.codec import * 
  14  from .errors import * 
  15  from .messages import * 
  16  from .mathtls import * 
  17  from .constants import * 
  18  from .utils.cryptomath import getRandomBytes 
  19   
  20  import socket 
  21  import errno 
  22  import traceback 
  23   
24 -class _ConnectionState:
25 - def __init__(self):
26 self.macContext = None 27 self.encContext = None 28 self.seqnum = 0
29
30 - def getSeqNumStr(self):
31 w = Writer() 32 w.add(self.seqnum, 8) 33 seqnumStr = bytesToString(w.bytes) 34 self.seqnum += 1 35 return seqnumStr
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 = "" 113 114 #Handshake digests 115 self._handshake_md5 = md5() 116 self._handshake_sha = 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 += bytesToString(applicationData.write()) 201 except TLSRemoteAlert, 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 returnStr = self._readBuffer[:max] 214 self._readBuffer = self._readBuffer[max:] 215 yield returnStr 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 = stringToBytes(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 - def closeAsync(self):
302 """Start a close operation on the TLS connection. 303 304 This function returns a generator which behaves similarly to 305 close(). Successive invocations of the generator will return 0 306 if it is waiting to read from the socket, 1 if it is waiting 307 to write to the socket, or will raise StopIteration if the 308 close operation has completed. 309 310 @rtype: iterable 311 @return: A generator; see above for details. 312 """ 313 if not self.closed: 314 for result in self._decrefAsync(): 315 yield result
316
317 - def _decrefAsync(self):
318 self._refCount -= 1 319 if self._refCount == 0 and not self.closed: 320 try: 321 for result in self._sendMsg(Alert().create(\ 322 AlertDescription.close_notify, AlertLevel.warning)): 323 yield result 324 alert = None 325 # By default close the socket, since it's been observed 326 # that some other libraries will not respond to the 327 # close_notify alert, thus leaving us hanging if we're 328 # expecting it 329 if self.closeSocket: 330 self._shutdown(True) 331 else: 332 while not alert: 333 for result in self._getMsg((ContentType.alert, \ 334 ContentType.application_data)): 335 if result in (0,1): 336 yield result 337 if result.contentType == ContentType.alert: 338 alert = result 339 if alert.description == AlertDescription.close_notify: 340 self._shutdown(True) 341 else: 342 raise TLSRemoteAlert(alert) 343 except (socket.error, TLSAbruptCloseError): 344 #If the other side closes the socket, that's okay 345 self._shutdown(True) 346 except GeneratorExit: 347 raise 348 except: 349 self._shutdown(False) 350 raise
351
352 - def getVersionName(self):
353 """Get the name of this TLS version. 354 355 @rtype: str 356 @return: The name of the TLS version used with this connection. 357 Either None, 'SSL 3.0', 'TLS 1.0', or 'TLS 1.1'. 358 """ 359 if self.version == (3,0): 360 return "SSL 3.0" 361 elif self.version == (3,1): 362 return "TLS 1.0" 363 elif self.version == (3,2): 364 return "TLS 1.1" 365 else: 366 return None
367
368 - def getCipherName(self):
369 """Get the name of the cipher used with this connection. 370 371 @rtype: str 372 @return: The name of the cipher used with this connection. 373 Either 'aes128', 'aes256', 'rc4', or '3des'. 374 """ 375 if not self._writeState.encContext: 376 return None 377 return self._writeState.encContext.name
378
379 - def getCipherImplementation(self):
380 """Get the name of the cipher implementation used with 381 this connection. 382 383 @rtype: str 384 @return: The name of the cipher implementation used with 385 this connection. Either 'python', 'openssl', or 'pycrypto'. 386 """ 387 if not self._writeState.encContext: 388 return None 389 return self._writeState.encContext.implementation
390 391 392 393 #Emulate a socket, somewhat -
394 - def send(self, s):
395 """Send data to the TLS connection (socket emulation). 396 397 @raise socket.error: If a socket error occurs. 398 """ 399 self.write(s) 400 return len(s)
401
402 - def sendall(self, s):
403 """Send data to the TLS connection (socket emulation). 404 405 @raise socket.error: If a socket error occurs. 406 """ 407 self.write(s)
408
409 - def recv(self, bufsize):
410 """Get some data from the TLS connection (socket emulation). 411 412 @raise socket.error: If a socket error occurs. 413 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed 414 without a preceding alert. 415 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled. 416 """ 417 return self.read(bufsize)
418
419 - def makefile(self, mode='r', bufsize=-1):
420 """Create a file object for the TLS connection (socket emulation). 421 422 @rtype: L{socket._fileobject} 423 """ 424 self._refCount += 1 425 # So, it is pretty fragile to be using Python internal objects 426 # like this, but it is probably the best/easiest way to provide 427 # matching behavior for socket emulation purposes. The 'close' 428 # argument is nice, its apparently a recent addition to this 429 # class, so that when fileobject.close() gets called, it will 430 # close() us, causing the refcount to be decremented (decrefAsync). 431 # 432 # If this is the last close() on the outstanding fileobjects / 433 # TLSConnection, then the "actual" close alerts will be sent, 434 # socket closed, etc. 435 return socket._fileobject(self, mode, bufsize, close=True)
436
437 - def getsockname(self):
438 """Return the socket's own address (socket emulation).""" 439 return self.sock.getsockname()
440
441 - def getpeername(self):
442 """Return the remote address to which the socket is connected 443 (socket emulation).""" 444 return self.sock.getpeername()
445
446 - def settimeout(self, value):
447 """Set a timeout on blocking socket operations (socket emulation).""" 448 return self.sock.settimeout(value)
449
450 - def gettimeout(self):
451 """Return the timeout associated with socket operations (socket 452 emulation).""" 453 return self.sock.gettimeout()
454
455 - def setsockopt(self, level, optname, value):
456 """Set the value of the given socket option (socket emulation).""" 457 return self.sock.setsockopt(level, optname, value)
458
459 - def shutdown(self, how):
460 """Shutdown the underlying socket.""" 461 return self.sock.shutdown(how)
462
463 - def fileno(self):
464 """Not implement in TLS Lite.""" 465 raise NotImplementedError()
466 467 468 #********************************************************* 469 # Public Functions END 470 #********************************************************* 471
472 - def _shutdown(self, resumable):
473 self._writeState = _ConnectionState() 474 self._readState = _ConnectionState() 475 #Don't do this: self._readBuffer = "" 476 self.version = (0,0) 477 self._versionCheck = False 478 self.closed = True 479 if self.closeSocket: 480 self.sock.close() 481 482 #Even if resumable is False, we'll never toggle this on 483 if not resumable and self.session: 484 self.session.resumable = False
485 486
487 - def _sendError(self, alertDescription, errorStr=None):
488 alert = Alert().create(alertDescription, AlertLevel.fatal) 489 for result in self._sendMsg(alert): 490 yield result 491 self._shutdown(False) 492 raise TLSLocalAlert(alert, errorStr)
493
494 - def _sendMsgs(self, msgs):
495 randomizeFirstBlock = True 496 for msg in msgs: 497 for result in self._sendMsg(msg, randomizeFirstBlock): 498 yield result 499 randomizeFirstBlock = True
500
501 - def _sendMsg(self, msg, randomizeFirstBlock = True):
502 #Whenever we're connected and asked to send an app data message, 503 #we first send the first byte of the message. This prevents 504 #an attacker from launching a chosen-plaintext attack based on 505 #knowing the next IV (a la BEAST). 506 if not self.closed and randomizeFirstBlock and self.version <= (3,1) \ 507 and self._writeState.encContext \ 508 and self._writeState.encContext.isBlockCipher \ 509 and isinstance(msg, ApplicationData): 510 msgFirstByte = msg.splitFirstByte() 511 for result in self._sendMsg(msgFirstByte, 512 randomizeFirstBlock = False): 513 yield result 514 515 bytes = msg.write() 516 517 # If a 1-byte message was passed in, and we "split" the 518 # first(only) byte off above, we may have a 0-length msg: 519 if len(bytes) == 0: 520 return 521 522 contentType = msg.contentType 523 524 #Update handshake hashes 525 if contentType == ContentType.handshake: 526 bytesStr = bytesToString(bytes) 527 self._handshake_md5.update(bytesStr) 528 self._handshake_sha.update(bytesStr) 529 530 #Calculate MAC 531 if self._writeState.macContext: 532 seqnumStr = self._writeState.getSeqNumStr() 533 bytesStr = bytesToString(bytes) 534 mac = self._writeState.macContext.copy() 535 mac.update(seqnumStr) 536 mac.update(chr(contentType)) 537 if self.version == (3,0): 538 mac.update( chr( len(bytes)//256 ) ) 539 mac.update( chr( len(bytes)%256 ) ) 540 elif self.version in ((3,1), (3,2)): 541 mac.update(chr(self.version[0])) 542 mac.update(chr(self.version[1])) 543 mac.update( chr( len(bytes)//256 ) ) 544 mac.update( chr( len(bytes)%256 ) ) 545 else: 546 raise AssertionError() 547 mac.update(bytesStr) 548 macString = mac.digest() 549 macBytes = stringToBytes(macString) 550 if self.fault == Fault.badMAC: 551 macBytes[0] = (macBytes[0]+1) % 256 552 553 #Encrypt for Block or Stream Cipher 554 if self._writeState.encContext: 555 #Add padding and encrypt (for Block Cipher): 556 if self._writeState.encContext.isBlockCipher: 557 558 #Add TLS 1.1 fixed block 559 if self.version == (3,2): 560 bytes = self.fixedIVBlock + bytes 561 562 #Add padding: bytes = bytes + (macBytes + paddingBytes) 563 currentLength = len(bytes) + len(macBytes) + 1 564 blockLength = self._writeState.encContext.block_size 565 paddingLength = blockLength-(currentLength % blockLength) 566 567 paddingBytes = createByteArraySequence([paddingLength] * \ 568 (paddingLength+1)) 569 if self.fault == Fault.badPadding: 570 paddingBytes[0] = (paddingBytes[0]+1) % 256 571 endBytes = macBytes + paddingBytes 572 bytes += endBytes 573 #Encrypt 574 plaintext = stringToBytes(bytes) 575 ciphertext = self._writeState.encContext.encrypt(plaintext) 576 bytes = stringToBytes(ciphertext) 577 578 #Encrypt (for Stream Cipher) 579 else: 580 bytes += macBytes 581 plaintext = bytesToString(bytes) 582 ciphertext = self._writeState.encContext.encrypt(plaintext) 583 bytes = stringToBytes(ciphertext) 584 585 #Add record header and send 586 r = RecordHeader3().create(self.version, contentType, len(bytes)) 587 s = bytesToString(r.write() + bytes) 588 while 1: 589 try: 590 bytesSent = self.sock.send(s) #Might raise socket.error 591 except socket.error, why: 592 if why[0] == errno.EWOULDBLOCK: 593 yield 1 594 continue 595 else: 596 # The socket was unexpectedly closed. The tricky part 597 # is that there may be an alert sent by the other party 598 # sitting in the read buffer. So, if we get here after 599 # handshaking, we will just raise the error and let the 600 # caller read more data if it would like, thus stumbling 601 # upon the error. 602 # 603 # However, if we get here DURING handshaking, we take 604 # it upon ourselves to see if the next message is an 605 # Alert. 606 if contentType == ContentType.handshake: 607 608 # See if there's an alert record 609 # Could raise socket.error or TLSAbruptCloseError 610 for result in self._getNextRecord(): 611 if result in (0,1): 612 yield result 613 614 # Closes the socket 615 self._shutdown(False) 616 617 # If we got an alert, raise it 618 recordHeader, p = result 619 if recordHeader.type == ContentType.alert: 620 alert = Alert().parse(p) 621 raise TLSRemoteAlert(alert) 622 else: 623 # If we got some other message who know what 624 # the remote side is doing, just go ahead and 625 # raise the socket.error 626 raise 627 if bytesSent == len(s): 628 return 629 s = s[bytesSent:] 630 yield 1
631 632
633 - def _getMsg(self, expectedType, secondaryType=None, constructorType=None):
634 try: 635 if not isinstance(expectedType, tuple): 636 expectedType = (expectedType,) 637 638 #Spin in a loop, until we've got a non-empty record of a type we 639 #expect. The loop will be repeated if: 640 # - we receive a renegotiation attempt; we send no_renegotiation, 641 # then try again 642 # - we receive an empty application-data fragment; we try again 643 while 1: 644 for result in self._getNextRecord(): 645 if result in (0,1): 646 yield result 647 recordHeader, p = result 648 649 #If this is an empty application-data fragment, try again 650 if recordHeader.type == ContentType.application_data: 651 if p.index == len(p.bytes): 652 continue 653 654 #If we received an unexpected record type... 655 if recordHeader.type not in expectedType: 656 657 #If we received an alert... 658 if recordHeader.type == ContentType.alert: 659 alert = Alert().parse(p) 660 661 #We either received a fatal error, a warning, or a 662 #close_notify. In any case, we're going to close the 663 #connection. In the latter two cases we respond with 664 #a close_notify, but ignore any socket errors, since 665 #the other side might have already closed the socket. 666 if alert.level == AlertLevel.warning or \ 667 alert.description == AlertDescription.close_notify: 668 669 #If the sendMsg() call fails because the socket has 670 #already been closed, we will be forgiving and not 671 #report the error nor invalidate the "resumability" 672 #of the session. 673 try: 674 alertMsg = Alert() 675 alertMsg.create(AlertDescription.close_notify, 676 AlertLevel.warning) 677 for result in self._sendMsg(alertMsg): 678 yield result 679 except socket.error: 680 pass 681 682 if alert.description == \ 683 AlertDescription.close_notify: 684 self._shutdown(True) 685 elif alert.level == AlertLevel.warning: 686 self._shutdown(False) 687 688 else: #Fatal alert: 689 self._shutdown(False) 690 691 #Raise the alert as an exception 692 raise TLSRemoteAlert(alert) 693 694 #If we received a renegotiation attempt... 695 if recordHeader.type == ContentType.handshake: 696 subType = p.get(1) 697 reneg = False 698 if self._client: 699 if subType == HandshakeType.hello_request: 700 reneg = True 701 else: 702 if subType == HandshakeType.client_hello: 703 reneg = True 704 #Send no_renegotiation, then try again 705 if reneg: 706 alertMsg = Alert() 707 alertMsg.create(AlertDescription.no_renegotiation, 708 AlertLevel.warning) 709 for result in self._sendMsg(alertMsg): 710 yield result 711 continue 712 713 #Otherwise: this is an unexpected record, but neither an 714 #alert nor renegotiation 715 for result in self._sendError(\ 716 AlertDescription.unexpected_message, 717 "received type=%d" % recordHeader.type): 718 yield result 719 720 break 721 722 #Parse based on content_type 723 if recordHeader.type == ContentType.change_cipher_spec: 724 yield ChangeCipherSpec().parse(p) 725 elif recordHeader.type == ContentType.alert: 726 yield Alert().parse(p) 727 elif recordHeader.type == ContentType.application_data: 728 yield ApplicationData().parse(p) 729 elif recordHeader.type == ContentType.handshake: 730 #Convert secondaryType to tuple, if it isn't already 731 if not isinstance(secondaryType, tuple): 732 secondaryType = (secondaryType,) 733 734 #If it's a handshake message, check handshake header 735 if recordHeader.ssl2: 736 subType = p.get(1) 737 if subType != HandshakeType.client_hello: 738 for result in self._sendError(\ 739 AlertDescription.unexpected_message, 740 "Can only handle SSLv2 ClientHello messages"): 741 yield result 742 if HandshakeType.client_hello not in secondaryType: 743 for result in self._sendError(\ 744 AlertDescription.unexpected_message): 745 yield result 746 subType = HandshakeType.client_hello 747 else: 748 subType = p.get(1) 749 if subType not in secondaryType: 750 for result in self._sendError(\ 751 AlertDescription.unexpected_message, 752 "Expecting %s, got %s" % (str(secondaryType), subType)): 753 yield result 754 755 #Update handshake hashes 756 sToHash = bytesToString(p.bytes) 757 self._handshake_md5.update(sToHash) 758 self._handshake_sha.update(sToHash) 759 760 #Parse based on handshake type 761 if subType == HandshakeType.client_hello: 762 yield ClientHello(recordHeader.ssl2).parse(p) 763 elif subType == HandshakeType.server_hello: 764 yield ServerHello().parse(p) 765 elif subType == HandshakeType.certificate: 766 yield Certificate(constructorType).parse(p) 767 elif subType == HandshakeType.certificate_request: 768 yield CertificateRequest().parse(p) 769 elif subType == HandshakeType.certificate_verify: 770 yield CertificateVerify().parse(p) 771 elif subType == HandshakeType.server_key_exchange: 772 yield ServerKeyExchange(constructorType).parse(p) 773 elif subType == HandshakeType.server_hello_done: 774 yield ServerHelloDone().parse(p) 775 elif subType == HandshakeType.client_key_exchange: 776 yield ClientKeyExchange(constructorType, \ 777 self.version).parse(p) 778 elif subType == HandshakeType.finished: 779 yield Finished(self.version).parse(p) 780 elif subType == HandshakeType.next_protocol: 781 yield NextProtocol().parse(p) 782 else: 783 raise AssertionError() 784 785 #If an exception was raised by a Parser or Message instance: 786 except SyntaxError, e: 787 for result in self._sendError(AlertDescription.decode_error, 788 formatExceptionTrace(e)): 789 yield result
790 791 792 #Returns next record or next handshake message
793 - def _getNextRecord(self):
794 795 #If there's a handshake message waiting, return it 796 if self._handshakeBuffer: 797 recordHeader, bytes = self._handshakeBuffer[0] 798 self._handshakeBuffer = self._handshakeBuffer[1:] 799 yield (recordHeader, Parser(bytes)) 800 return 801 802 #Otherwise... 803 #Read the next record header 804 bytes = createByteArraySequence([]) 805 recordHeaderLength = 1 806 ssl2 = False 807 while 1: 808 try: 809 s = self.sock.recv(recordHeaderLength-len(bytes)) 810 except socket.error, why: 811 if why[0] == errno.EWOULDBLOCK: 812 yield 0 813 continue 814 else: 815 raise 816 817 #If the connection was abruptly closed, raise an error 818 if len(s)==0: 819 raise TLSAbruptCloseError() 820 821 bytes += stringToBytes(s) 822 if len(bytes)==1: 823 if bytes[0] in ContentType.all: 824 ssl2 = False 825 recordHeaderLength = 5 826 elif bytes[0] == 128: 827 ssl2 = True 828 recordHeaderLength = 2 829 else: 830 raise SyntaxError() 831 if len(bytes) == recordHeaderLength: 832 break 833 834 #Parse the record header 835 if ssl2: 836 r = RecordHeader2().parse(Parser(bytes)) 837 else: 838 r = RecordHeader3().parse(Parser(bytes)) 839 840 #Check the record header fields 841 if r.length > 18432: 842 for result in self._sendError(AlertDescription.record_overflow): 843 yield result 844 845 #Read the record contents 846 bytes = createByteArraySequence([]) 847 while 1: 848 try: 849 s = self.sock.recv(r.length - len(bytes)) 850 except socket.error, why: 851 if why[0] == errno.EWOULDBLOCK: 852 yield 0 853 continue 854 else: 855 raise 856 857 #If the connection is closed, raise a socket error 858 if len(s)==0: 859 raise TLSAbruptCloseError() 860 861 bytes += stringToBytes(s) 862 if len(bytes) == r.length: 863 break 864 865 #Check the record header fields (2) 866 #We do this after reading the contents from the socket, so that 867 #if there's an error, we at least don't leave extra bytes in the 868 #socket.. 869 # 870 # THIS CHECK HAS NO SECURITY RELEVANCE (?), BUT COULD HURT INTEROP. 871 # SO WE LEAVE IT OUT FOR NOW. 872 # 873 #if self._versionCheck and r.version != self.version: 874 # for result in self._sendError(AlertDescription.protocol_version, 875 # "Version in header field: %s, should be %s" % (str(r.version), 876 # str(self.version))): 877 # yield result 878 879 #Decrypt the record 880 for result in self._decryptRecord(r.type, bytes): 881 if result in (0,1): yield result 882 else: break 883 bytes = result 884 p = Parser(bytes) 885 886 #If it doesn't contain handshake messages, we can just return it 887 if r.type != ContentType.handshake: 888 yield (r, p) 889 #If it's an SSLv2 ClientHello, we can return it as well 890 elif r.ssl2: 891 yield (r, p) 892 else: 893 #Otherwise, we loop through and add the handshake messages to the 894 #handshake buffer 895 while 1: 896 if p.index == len(bytes): #If we're at the end 897 if not self._handshakeBuffer: 898 for result in self._sendError(\ 899 AlertDescription.decode_error, \ 900 "Received empty handshake record"): 901 yield result 902 break 903 #There needs to be at least 4 bytes to get a header 904 if p.index+4 > len(bytes): 905 for result in self._sendError(\ 906 AlertDescription.decode_error, 907 "A record has a partial handshake message (1)"): 908 yield result 909 p.get(1) # skip handshake type 910 msgLength = p.get(3) 911 if p.index+msgLength > len(bytes): 912 for result in self._sendError(\ 913 AlertDescription.decode_error, 914 "A record has a partial handshake message (2)"): 915 yield result 916 917 handshakePair = (r, bytes[p.index-4 : p.index+msgLength]) 918 self._handshakeBuffer.append(handshakePair) 919 p.index += msgLength 920 921 #We've moved at least one handshake message into the 922 #handshakeBuffer, return the first one 923 recordHeader, bytes = self._handshakeBuffer[0] 924 self._handshakeBuffer = self._handshakeBuffer[1:] 925 yield (recordHeader, Parser(bytes))
926 927
928 - def _decryptRecord(self, recordType, bytes):
929 if self._readState.encContext: 930 931 #Decrypt if it's a block cipher 932 if self._readState.encContext.isBlockCipher: 933 blockLength = self._readState.encContext.block_size 934 if len(bytes) % blockLength != 0: 935 for result in self._sendError(\ 936 AlertDescription.decryption_failed, 937 "Encrypted data not a multiple of blocksize"): 938 yield result 939 ciphertext = bytesToString(bytes) 940 plaintext = self._readState.encContext.decrypt(ciphertext) 941 if self.version == (3,2): #For TLS 1.1, remove explicit IV 942 plaintext = plaintext[self._readState.encContext.block_size : ] 943 bytes = stringToBytes(plaintext) 944 945 #Check padding 946 paddingGood = True 947 paddingLength = bytes[-1] 948 if (paddingLength+1) > len(bytes): 949 paddingGood=False 950 totalPaddingLength = 0 951 else: 952 if self.version == (3,0): 953 totalPaddingLength = paddingLength+1 954 elif self.version in ((3,1), (3,2)): 955 totalPaddingLength = paddingLength+1 956 paddingBytes = bytes[-totalPaddingLength:-1] 957 for byte in paddingBytes: 958 if byte != paddingLength: 959 paddingGood = False 960 totalPaddingLength = 0 961 else: 962 raise AssertionError() 963 964 #Decrypt if it's a stream cipher 965 else: 966 paddingGood = True 967 ciphertext = bytesToString(bytes) 968 plaintext = self._readState.encContext.decrypt(ciphertext) 969 bytes = stringToBytes(plaintext) 970 totalPaddingLength = 0 971 972 #Check MAC 973 macGood = True 974 macLength = self._readState.macContext.digest_size 975 endLength = macLength + totalPaddingLength 976 if endLength > len(bytes): 977 macGood = False 978 else: 979 #Read MAC 980 startIndex = len(bytes) - endLength 981 endIndex = startIndex + macLength 982 checkBytes = bytes[startIndex : endIndex] 983 984 #Calculate MAC 985 seqnumStr = self._readState.getSeqNumStr() 986 bytes = bytes[:-endLength] 987 bytesStr = bytesToString(bytes) 988 mac = self._readState.macContext.copy() 989 mac.update(seqnumStr) 990 mac.update(chr(recordType)) 991 if self.version == (3,0): 992 mac.update( chr( len(bytes)//256 ) ) 993 mac.update( chr( len(bytes)%256 ) ) 994 elif self.version in ((3,1), (3,2)): 995 mac.update(chr(self.version[0])) 996 mac.update(chr(self.version[1])) 997 mac.update( chr( len(bytes)//256 ) ) 998 mac.update( chr( len(bytes)%256 ) ) 999 else: 1000 raise AssertionError() 1001 mac.update(bytesStr) 1002 macString = mac.digest() 1003 macBytes = stringToBytes(macString) 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 bytes
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 = md5() 1021 self._handshake_sha = 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 "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 = bytesToString(p.getFixBytes(macLength)) 1080 serverMACBlock = bytesToString(p.getFixBytes(macLength)) 1081 clientKeyBlock = bytesToString(p.getFixBytes(keyLength)) 1082 serverKeyBlock = bytesToString(p.getFixBytes(keyLength)) 1083 clientIVBlock = bytesToString(p.getFixBytes(ivLength)) 1084 serverIVBlock = bytesToString(p.getFixBytes(ivLength)) 1085 clientPendingState.macContext = createMACFunc(clientMACBlock) 1086 serverPendingState.macContext = createMACFunc(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 masterSecretStr = bytesToString(masterSecret) 1118 1119 imac_md5 = self._handshake_md5.copy() 1120 imac_sha = self._handshake_sha.copy() 1121 1122 imac_md5.update(label + masterSecretStr + '\x36'*48) 1123 imac_sha.update(label + masterSecretStr + '\x36'*40) 1124 1125 md5Str = md5(masterSecretStr + ('\x5c'*48) + \ 1126 imac_md5.digest()).digest() 1127 shaStr = sha1(masterSecretStr + ('\x5c'*40) + \ 1128 imac_sha.digest()).digest() 1129 1130 return stringToBytes(md5Str + shaStr)
1131