Package tlslite :: Module tlsrecordlayer
[hide private]
[frames] | no frames]

Source Code for Module tlslite.tlsrecordlayer

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