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

Source Code for Module tlslite.recordlayer

  1  # Copyright (c) 2014, Hubert Kario 
  2  # 
  3  # See the LICENSE file for legal information regarding use of this file. 
  4   
  5  """Implementation of the TLS Record Layer protocol""" 
  6   
  7  import socket 
  8  import errno 
  9  import hashlib 
 10  from .constants import ContentType, CipherSuite 
 11  from .messages import RecordHeader3, RecordHeader2, Message 
 12  from .utils.cipherfactory import createAESGCM, createAES, createRC4, \ 
 13          createTripleDES 
 14  from .utils.codec import Parser, Writer 
 15  from .utils.compat import compatHMAC 
 16  from .utils.cryptomath import getRandomBytes 
 17  from .utils.constanttime import ct_compare_digest, ct_check_cbc_mac_and_pad 
 18  from .errors import TLSRecordOverflow, TLSIllegalParameterException,\ 
 19          TLSAbruptCloseError, TLSDecryptionFailed, TLSBadRecordMAC 
 20  from .mathtls import createMAC_SSL, createHMAC, PRF_SSL, PRF, PRF_1_2, \ 
 21          PRF_1_2_SHA384 
22 23 -class RecordSocket(object):
24 25 """Socket wrapper for reading and writing TLS Records""" 26
27 - def __init__(self, sock):
28 """ 29 Assign socket to wrapper 30 31 @type sock: socket.socket 32 """ 33 self.sock = sock 34 self.version = (0, 0)
35
36 - def _sockSendAll(self, data):
37 """ 38 Send all data through socket 39 40 @type data: bytearray 41 @param data: data to send 42 @raise socket.error: when write to socket failed 43 """ 44 while 1: 45 try: 46 bytesSent = self.sock.send(data) 47 except socket.error as why: 48 if why.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN): 49 yield 1 50 continue 51 raise 52 53 if bytesSent == len(data): 54 return 55 data = data[bytesSent:] 56 yield 1
57
58 - def send(self, msg):
59 """ 60 Send the message through socket. 61 62 @type msg: bytearray 63 @param msg: TLS message to send 64 @raise socket.error: when write to socket failed 65 """ 66 data = msg.write() 67 68 header = RecordHeader3().create(self.version, 69 msg.contentType, 70 len(data)) 71 72 data = header.write() + data 73 74 for result in self._sockSendAll(data): 75 yield result
76
77 - def _sockRecvAll(self, length):
78 """ 79 Read exactly the amount of bytes specified in L{length} from raw socket. 80 81 @rtype: generator 82 @return: generator that will return 0 or 1 in case the socket is non 83 blocking and would block and bytearray in case the read finished 84 @raise TLSAbruptCloseError: when the socket closed 85 """ 86 buf = bytearray(0) 87 88 if length == 0: 89 yield buf 90 91 while True: 92 try: 93 socketBytes = self.sock.recv(length - len(buf)) 94 except socket.error as why: 95 if why.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN): 96 yield 0 97 continue 98 else: 99 raise 100 101 #if the connection closed, raise socket error 102 if len(socketBytes) == 0: 103 raise TLSAbruptCloseError() 104 105 buf += bytearray(socketBytes) 106 if len(buf) == length: 107 yield buf
108
109 - def _recvHeader(self):
110 """Read a single record header from socket""" 111 #Read the next record header 112 buf = bytearray(0) 113 ssl2 = False 114 115 result = None 116 for result in self._sockRecvAll(1): 117 if result in (0, 1): 118 yield result 119 else: break 120 assert result is not None 121 122 buf += result 123 124 if buf[0] in ContentType.all: 125 ssl2 = False 126 # SSLv3 record layer header is 5 bytes long, we already read 1 127 result = None 128 for result in self._sockRecvAll(4): 129 if result in (0, 1): 130 yield result 131 else: break 132 assert result is not None 133 buf += result 134 # XXX this should be 'buf[0] & 128', otherwise hello messages longer 135 # than 127 bytes won't be properly parsed 136 elif buf[0] == 128: 137 ssl2 = True 138 # in SSLv2 we need to read 2 bytes in total to know the size of 139 # header, we already read 1 140 result = None 141 for result in self._sockRecvAll(1): 142 if result in (0, 1): 143 yield result 144 else: break 145 assert result is not None 146 buf += result 147 else: 148 raise TLSIllegalParameterException( 149 "Record header type doesn't specify known type") 150 151 #Parse the record header 152 if ssl2: 153 record = RecordHeader2().parse(Parser(buf)) 154 else: 155 record = RecordHeader3().parse(Parser(buf)) 156 157 yield record
158
159 - def recv(self):
160 """ 161 Read a single record from socket, handle SSLv2 and SSLv3 record layer 162 163 @rtype: generator 164 @return: generator that returns 0 or 1 in case the read would be 165 blocking or a tuple containing record header (object) and record 166 data (bytearray) read from socket 167 @raise socket.error: In case of network error 168 @raise TLSAbruptCloseError: When the socket was closed on the other 169 side in middle of record receiving 170 @raise TLSRecordOverflow: When the received record was longer than 171 allowed by TLS 172 @raise TLSIllegalParameterException: When the record header was 173 malformed 174 """ 175 record = None 176 for record in self._recvHeader(): 177 if record in (0, 1): 178 yield record 179 else: break 180 assert record is not None 181 182 #Check the record header fields 183 # 18432 = 2**14 (basic record size limit) + 1024 (maximum compression 184 # overhead) + 1024 (maximum encryption overhead) 185 if record.length > 18432: 186 raise TLSRecordOverflow() 187 188 #Read the record contents 189 buf = bytearray(0) 190 191 result = None 192 for result in self._sockRecvAll(record.length): 193 if result in (0, 1): 194 yield result 195 else: break 196 assert result is not None 197 198 buf += result 199 200 yield (record, buf)
201
202 -class ConnectionState(object):
203 204 """Preserve the connection state for reading and writing data to records""" 205
206 - def __init__(self):
207 """Create an instance with empty encryption and MACing contexts""" 208 self.macContext = None 209 self.encContext = None 210 self.fixedNonce = None 211 self.seqnum = 0
212
213 - def getSeqNumBytes(self):
214 """Return encoded sequence number and increment it.""" 215 writer = Writer() 216 writer.add(self.seqnum, 8) 217 self.seqnum += 1 218 return writer.bytes
219
220 -class RecordLayer(object):
221 222 """ 223 Implementation of TLS record layer protocol 224 225 @ivar version: the TLS version to use (tuple encoded as on the wire) 226 @ivar sock: underlying socket 227 @ivar client: whether the connection should use encryption 228 @ivar encryptThenMAC: use the encrypt-then-MAC mechanism for record 229 integrity 230 """ 231
232 - def __init__(self, sock):
233 self.sock = sock 234 self._recordSocket = RecordSocket(sock) 235 self._version = (0, 0) 236 237 self.client = True 238 239 self._writeState = ConnectionState() 240 self._readState = ConnectionState() 241 self._pendingWriteState = ConnectionState() 242 self._pendingReadState = ConnectionState() 243 self.fixedIVBlock = None 244 245 self.encryptThenMAC = False
246 247 @property
248 - def version(self):
249 """Return the TLS version used by record layer""" 250 return self._version
251 252 @version.setter
253 - def version(self, val):
254 """Set the TLS version used by record layer""" 255 self._version = val 256 self._recordSocket.version = val
257
258 - def getCipherName(self):
259 """ 260 Return the name of the bulk cipher used by this connection 261 262 @rtype: str 263 @return: The name of the cipher, like 'aes128', 'rc4', etc. 264 """ 265 if self._writeState.encContext is None: 266 return None 267 return self._writeState.encContext.name
268
269 - def getCipherImplementation(self):
270 """ 271 Return the name of the implementation used for the connection 272 273 'python' for tlslite internal implementation, 'openssl' for M2crypto 274 and 'pycrypto' for pycrypto 275 @rtype: str 276 @return: Name of cipher implementation used, None if not initialised 277 """ 278 if self._writeState.encContext is None: 279 return None 280 return self._writeState.encContext.implementation
281
282 - def shutdown(self):
283 """Clear read and write states""" 284 self._writeState = ConnectionState() 285 self._readState = ConnectionState() 286 self._pendingWriteState = ConnectionState() 287 self._pendingReadState = ConnectionState()
288
289 - def isCBCMode(self):
290 """Returns true if cipher uses CBC mode""" 291 if self._writeState and self._writeState.encContext and \ 292 self._writeState.encContext.isBlockCipher: 293 return True 294 else: 295 return False
296 # 297 # sending messages 298 # 299
300 - def _addPadding(self, data):
301 """Add padding to data so that it is multiple of block size""" 302 currentLength = len(data) 303 blockLength = self._writeState.encContext.block_size 304 paddingLength = blockLength - 1 - (currentLength % blockLength) 305 306 paddingBytes = bytearray([paddingLength] * (paddingLength+1)) 307 data += paddingBytes 308 return data
309
310 - def _calculateMAC(self, mac, seqnumBytes, contentType, data):
311 """Calculate the SSL/TLS version of a MAC""" 312 mac.update(compatHMAC(seqnumBytes)) 313 mac.update(compatHMAC(bytearray([contentType]))) 314 assert self.version in ((3, 0), (3, 1), (3, 2), (3, 3)) 315 if self.version != (3, 0): 316 mac.update(compatHMAC(bytearray([self.version[0]]))) 317 mac.update(compatHMAC(bytearray([self.version[1]]))) 318 mac.update(compatHMAC(bytearray([len(data)//256]))) 319 mac.update(compatHMAC(bytearray([len(data)%256]))) 320 mac.update(compatHMAC(data)) 321 return bytearray(mac.digest())
322
323 - def _macThenEncrypt(self, data, contentType):
324 """MAC, pad then encrypt data""" 325 if self._writeState.macContext: 326 seqnumBytes = self._writeState.getSeqNumBytes() 327 mac = self._writeState.macContext.copy() 328 macBytes = self._calculateMAC(mac, seqnumBytes, contentType, data) 329 data += macBytes 330 331 #Encrypt for Block or Stream Cipher 332 if self._writeState.encContext: 333 #Add padding (for Block Cipher): 334 if self._writeState.encContext.isBlockCipher: 335 336 #Add TLS 1.1 fixed block 337 if self.version >= (3, 2): 338 data = self.fixedIVBlock + data 339 340 data = self._addPadding(data) 341 342 #Encrypt 343 data = self._writeState.encContext.encrypt(data) 344 345 return data
346
347 - def _encryptThenMAC(self, buf, contentType):
348 """Pad, encrypt and then MAC the data""" 349 if self._writeState.encContext: 350 # add IV for TLS1.1+ 351 if self.version >= (3, 2): 352 buf = self.fixedIVBlock + buf 353 354 buf = self._addPadding(buf) 355 356 buf = self._writeState.encContext.encrypt(buf) 357 358 # add MAC 359 if self._writeState.macContext: 360 seqnumBytes = self._writeState.getSeqNumBytes() 361 mac = self._writeState.macContext.copy() 362 363 # append MAC 364 macBytes = self._calculateMAC(mac, seqnumBytes, contentType, buf) 365 buf += macBytes 366 367 return buf
368
369 - def _encryptThenSeal(self, buf, contentType):
370 """Encrypt with AEAD cipher""" 371 #Assemble the authenticated data. 372 seqNumBytes = self._writeState.getSeqNumBytes() 373 authData = seqNumBytes + bytearray([contentType, 374 self.version[0], 375 self.version[1], 376 len(buf)//256, 377 len(buf)%256]) 378 379 #The nonce is always the fixed nonce and the sequence number. 380 nonce = self._writeState.fixedNonce + seqNumBytes 381 assert len(nonce) == self._writeState.encContext.nonceLength 382 383 buf = self._writeState.encContext.seal(nonce, buf, authData) 384 385 #The only AEAD supported, AES-GCM, has an explicit variable 386 #nonce. 387 buf = seqNumBytes + buf 388 389 return buf
390
391 - def sendRecord(self, msg):
392 """ 393 Encrypt, MAC and send arbitrary message as-is through socket. 394 395 Note that if the message was not fragmented to below 2**14 bytes 396 it will be rejected by the other connection side. 397 398 @param msg: TLS message to send 399 @type msg: ApplicationData, HandshakeMessage, etc. 400 """ 401 data = msg.write() 402 contentType = msg.contentType 403 404 if self._writeState and \ 405 self._writeState.encContext and \ 406 self._writeState.encContext.isAEAD: 407 data = self._encryptThenSeal(data, contentType) 408 elif self.encryptThenMAC: 409 data = self._encryptThenMAC(data, contentType) 410 else: 411 data = self._macThenEncrypt(data, contentType) 412 413 encryptedMessage = Message(contentType, data) 414 415 for result in self._recordSocket.send(encryptedMessage): 416 yield result
417 418 # 419 # receiving messages 420 # 421
422 - def _decryptStreamThenMAC(self, recordType, data):
423 """Decrypt a stream cipher and check MAC""" 424 if self._readState.encContext: 425 assert self.version in ((3, 0), (3, 1), (3, 2), (3, 3)) 426 427 data = self._readState.encContext.decrypt(data) 428 429 if self._readState.macContext: 430 #Check MAC 431 macGood = True 432 macLength = self._readState.macContext.digest_size 433 endLength = macLength 434 if endLength > len(data): 435 macGood = False 436 else: 437 #Read MAC 438 startIndex = len(data) - endLength 439 endIndex = startIndex + macLength 440 checkBytes = data[startIndex : endIndex] 441 442 #Calculate MAC 443 seqnumBytes = self._readState.getSeqNumBytes() 444 data = data[:-endLength] 445 mac = self._readState.macContext.copy() 446 macBytes = self._calculateMAC(mac, seqnumBytes, recordType, 447 data) 448 449 #Compare MACs 450 if not ct_compare_digest(macBytes, checkBytes): 451 macGood = False 452 453 if not macGood: 454 raise TLSBadRecordMAC() 455 456 return data
457 458
459 - def _decryptThenMAC(self, recordType, data):
460 """Decrypt data, check padding and MAC""" 461 if self._readState.encContext: 462 assert self.version in ((3, 0), (3, 1), (3, 2), (3, 3)) 463 assert self._readState.encContext.isBlockCipher 464 assert self._readState.macContext 465 466 # 467 # decrypt the record 468 # 469 blockLength = self._readState.encContext.block_size 470 if len(data) % blockLength != 0: 471 raise TLSDecryptionFailed() 472 data = self._readState.encContext.decrypt(data) 473 if self.version >= (3, 2): #For TLS 1.1, remove explicit IV 474 data = data[self._readState.encContext.block_size : ] 475 476 # 477 # check padding and MAC 478 # 479 seqnumBytes = self._readState.getSeqNumBytes() 480 481 if not ct_check_cbc_mac_and_pad(data, 482 self._readState.macContext, 483 seqnumBytes, 484 recordType, 485 self.version): 486 raise TLSBadRecordMAC() 487 488 # 489 # strip padding and MAC 490 # 491 492 endLength = data[-1] + 1 + self._readState.macContext.digest_size 493 494 data = data[:-endLength] 495 496 return data
497
498 - def _macThenDecrypt(self, recordType, buf):
499 """ 500 Check MAC of data, then decrypt and remove padding 501 502 @raise TLSBadRecordMAC: when the mac value is invalid 503 @raise TLSDecryptionFailed: when the data to decrypt has invalid size 504 """ 505 if self._readState.macContext: 506 macLength = self._readState.macContext.digest_size 507 if len(buf) < macLength: 508 raise TLSBadRecordMAC("Truncated data") 509 510 checkBytes = buf[-macLength:] 511 buf = buf[:-macLength] 512 513 seqnumBytes = self._readState.getSeqNumBytes() 514 mac = self._readState.macContext.copy() 515 516 macBytes = self._calculateMAC(mac, seqnumBytes, recordType, buf) 517 518 if not ct_compare_digest(macBytes, checkBytes): 519 raise TLSBadRecordMAC("MAC mismatch") 520 521 if self._readState.encContext: 522 blockLength = self._readState.encContext.block_size 523 if len(buf) % blockLength != 0: 524 raise TLSDecryptionFailed("data length not multiple of "\ 525 "block size") 526 527 buf = self._readState.encContext.decrypt(buf) 528 529 # remove explicit IV 530 if self.version >= (3, 2): 531 buf = buf[blockLength:] 532 533 # check padding 534 paddingLength = buf[-1] 535 if paddingLength + 1 > len(buf): 536 raise TLSBadRecordMAC("Invalid padding length") 537 538 paddingGood = True 539 totalPaddingLength = paddingLength+1 540 if self.version != (3, 0): 541 paddingBytes = buf[-totalPaddingLength:-1] 542 for byte in paddingBytes: 543 if byte != paddingLength: 544 paddingGood = False 545 546 if not paddingGood: 547 raise TLSBadRecordMAC("Invalid padding byte values") 548 549 # remove padding 550 buf = buf[:-totalPaddingLength] 551 552 return buf
553
554 - def _decryptAndUnseal(self, recordType, buf):
555 """Decrypt AEAD encrypted data""" 556 #The only AEAD supported, AES-GCM, has an explicit variable 557 #nonce. 558 explicitNonceLength = 8 559 if explicitNonceLength > len(buf): 560 #Publicly invalid. 561 raise TLSBadRecordMAC("Truncated nonce") 562 nonce = self._readState.fixedNonce + buf[:explicitNonceLength] 563 buf = buf[8:] 564 565 if self._readState.encContext.tagLength > len(buf): 566 #Publicly invalid. 567 raise TLSBadRecordMAC("Truncated tag") 568 569 #Assemble the authenticated data. 570 seqnumBytes = self._readState.getSeqNumBytes() 571 plaintextLen = len(buf) - self._readState.encContext.tagLength 572 authData = seqnumBytes + bytearray([recordType, self.version[0], 573 self.version[1], 574 plaintextLen//256, 575 plaintextLen%256]) 576 577 buf = self._readState.encContext.open(nonce, buf, authData) 578 if buf is None: 579 raise TLSBadRecordMAC("Invalid tag, decryption failure") 580 return buf
581
582 - def recvRecord(self):
583 """ 584 Read, decrypt and check integrity of a single record 585 586 @rtype: tuple 587 @return: message header and decrypted message payload 588 @raise TLSDecryptionFailed: when decryption of data failed 589 @raise TLSBadRecordMAC: when record has bad MAC or padding 590 @raise socket.error: when reading from socket was unsuccessful 591 """ 592 result = None 593 for result in self._recordSocket.recv(): 594 if result in (0, 1): 595 yield result 596 else: break 597 assert result is not None 598 599 (header, data) = result 600 601 if self._readState and \ 602 self._readState.encContext and \ 603 self._readState.encContext.isAEAD: 604 data = self._decryptAndUnseal(header.type, data) 605 elif self.encryptThenMAC: 606 data = self._macThenDecrypt(header.type, data) 607 elif self._readState and \ 608 self._readState.encContext and \ 609 self._readState.encContext.isBlockCipher: 610 data = self._decryptThenMAC(header.type, data) 611 else: 612 data = self._decryptStreamThenMAC(header.type, data) 613 614 yield (header, Parser(data))
615 616 # 617 # cryptography state methods 618 # 619
620 - def changeWriteState(self):
621 """ 622 Change the cipher state to the pending one for write operations. 623 624 This should be done only once after a call to L{calcPendingStates} was 625 performed and directly after sending a L{ChangeCipherSpec} message. 626 """ 627 self._writeState = self._pendingWriteState 628 self._pendingWriteState = ConnectionState()
629
630 - def changeReadState(self):
631 """ 632 Change the cipher state to the pending one for read operations. 633 634 This should be done only once after a call to L{calcPendingStates} was 635 performed and directly after receiving a L{ChangeCipherSpec} message. 636 """ 637 self._readState = self._pendingReadState 638 self._pendingReadState = ConnectionState()
639 640 @staticmethod
641 - def _getCipherSettings(cipherSuite):
642 """Get the settings for cipher suite used""" 643 if cipherSuite in CipherSuite.aes256GcmSuites: 644 keyLength = 32 645 ivLength = 4 646 createCipherFunc = createAESGCM 647 elif cipherSuite in CipherSuite.aes128GcmSuites: 648 keyLength = 16 649 ivLength = 4 650 createCipherFunc = createAESGCM 651 elif cipherSuite in CipherSuite.aes128Suites: 652 keyLength = 16 653 ivLength = 16 654 createCipherFunc = createAES 655 elif cipherSuite in CipherSuite.aes256Suites: 656 keyLength = 32 657 ivLength = 16 658 createCipherFunc = createAES 659 elif cipherSuite in CipherSuite.rc4Suites: 660 keyLength = 16 661 ivLength = 0 662 createCipherFunc = createRC4 663 elif cipherSuite in CipherSuite.tripleDESSuites: 664 keyLength = 24 665 ivLength = 8 666 createCipherFunc = createTripleDES 667 elif cipherSuite in CipherSuite.nullSuites: 668 keyLength = 0 669 ivLength = 0 670 createCipherFunc = None 671 else: 672 raise AssertionError() 673 674 return (keyLength, ivLength, createCipherFunc)
675 676 @staticmethod
677 - def _getMacSettings(cipherSuite):
678 """Get settings for HMAC used""" 679 if cipherSuite in CipherSuite.aeadSuites: 680 macLength = 0 681 digestmod = None 682 elif cipherSuite in CipherSuite.shaSuites: 683 macLength = 20 684 digestmod = hashlib.sha1 685 elif cipherSuite in CipherSuite.sha256Suites: 686 macLength = 32 687 digestmod = hashlib.sha256 688 elif cipherSuite in CipherSuite.md5Suites: 689 macLength = 16 690 digestmod = hashlib.md5 691 else: 692 raise AssertionError() 693 694 return macLength, digestmod
695 696 @staticmethod
697 - def _getHMACMethod(version):
698 """Get the HMAC method""" 699 assert version in ((3, 0), (3, 1), (3, 2), (3, 3)) 700 if version == (3, 0): 701 createMACFunc = createMAC_SSL 702 elif version in ((3, 1), (3, 2), (3, 3)): 703 createMACFunc = createHMAC 704 705 return createMACFunc
706
707 - def _calcKeyBlock(self, cipherSuite, masterSecret, clientRandom, 708 serverRandom, outputLength):
709 """Calculate the overall key to slice up""" 710 if self.version == (3, 0): 711 keyBlock = PRF_SSL(masterSecret, 712 serverRandom + clientRandom, 713 outputLength) 714 elif self.version in ((3, 1), (3, 2)): 715 keyBlock = PRF(masterSecret, 716 b"key expansion", 717 serverRandom + clientRandom, 718 outputLength) 719 elif self.version == (3, 3): 720 if cipherSuite in CipherSuite.sha384PrfSuites: 721 keyBlock = PRF_1_2_SHA384(masterSecret, 722 b"key expansion", 723 serverRandom + clientRandom, 724 outputLength) 725 else: 726 keyBlock = PRF_1_2(masterSecret, 727 b"key expansion", 728 serverRandom + clientRandom, 729 outputLength) 730 else: 731 raise AssertionError() 732 733 return keyBlock
734
735 - def calcPendingStates(self, cipherSuite, masterSecret, clientRandom, 736 serverRandom, implementations):
737 """Create pending states for encryption and decryption.""" 738 keyLength, ivLength, createCipherFunc = \ 739 self._getCipherSettings(cipherSuite) 740 741 macLength, digestmod = self._getMacSettings(cipherSuite) 742 743 if not digestmod: 744 createMACFunc = None 745 else: 746 createMACFunc = self._getHMACMethod(self.version) 747 748 outputLength = (macLength*2) + (keyLength*2) + (ivLength*2) 749 750 #Calculate Keying Material from Master Secret 751 keyBlock = self._calcKeyBlock(cipherSuite, masterSecret, clientRandom, 752 serverRandom, outputLength) 753 754 #Slice up Keying Material 755 clientPendingState = ConnectionState() 756 serverPendingState = ConnectionState() 757 parser = Parser(keyBlock) 758 clientMACBlock = parser.getFixBytes(macLength) 759 serverMACBlock = parser.getFixBytes(macLength) 760 clientKeyBlock = parser.getFixBytes(keyLength) 761 serverKeyBlock = parser.getFixBytes(keyLength) 762 clientIVBlock = parser.getFixBytes(ivLength) 763 serverIVBlock = parser.getFixBytes(ivLength) 764 765 if digestmod: 766 # Legacy cipher 767 clientPendingState.macContext = createMACFunc( 768 compatHMAC(clientMACBlock), digestmod=digestmod) 769 serverPendingState.macContext = createMACFunc( 770 compatHMAC(serverMACBlock), digestmod=digestmod) 771 if createCipherFunc is not None: 772 clientPendingState.encContext = \ 773 createCipherFunc(clientKeyBlock, 774 clientIVBlock, 775 implementations) 776 serverPendingState.encContext = \ 777 createCipherFunc(serverKeyBlock, 778 serverIVBlock, 779 implementations) 780 else: 781 # AEAD 782 clientPendingState.macContext = None 783 serverPendingState.macContext = None 784 clientPendingState.encContext = createCipherFunc(clientKeyBlock, 785 implementations) 786 serverPendingState.encContext = createCipherFunc(serverKeyBlock, 787 implementations) 788 clientPendingState.fixedNonce = clientIVBlock 789 serverPendingState.fixedNonce = serverIVBlock 790 791 #Assign new connection states to pending states 792 if self.client: 793 self._pendingWriteState = clientPendingState 794 self._pendingReadState = serverPendingState 795 else: 796 self._pendingWriteState = serverPendingState 797 self._pendingReadState = clientPendingState 798 799 if self.version >= (3, 2) and ivLength: 800 #Choose fixedIVBlock for TLS 1.1 (this is encrypted with the CBC 801 #residue to create the IV for each sent block) 802 self.fixedIVBlock = getRandomBytes(ivLength)
803