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 if len(buf) == 0: 534 raise TLSBadRecordMAC("No data left after IV removal") 535 536 # check padding 537 paddingLength = buf[-1] 538 if paddingLength + 1 > len(buf): 539 raise TLSBadRecordMAC("Invalid padding length") 540 541 paddingGood = True 542 totalPaddingLength = paddingLength+1 543 if self.version != (3, 0): 544 paddingBytes = buf[-totalPaddingLength:-1] 545 for byte in paddingBytes: 546 if byte != paddingLength: 547 paddingGood = False 548 549 if not paddingGood: 550 raise TLSBadRecordMAC("Invalid padding byte values") 551 552 # remove padding 553 buf = buf[:-totalPaddingLength] 554 555 return buf
556
557 - def _decryptAndUnseal(self, recordType, buf):
558 """Decrypt AEAD encrypted data""" 559 #The only AEAD supported, AES-GCM, has an explicit variable 560 #nonce. 561 explicitNonceLength = 8 562 if explicitNonceLength > len(buf): 563 #Publicly invalid. 564 raise TLSBadRecordMAC("Truncated nonce") 565 nonce = self._readState.fixedNonce + buf[:explicitNonceLength] 566 buf = buf[8:] 567 568 if self._readState.encContext.tagLength > len(buf): 569 #Publicly invalid. 570 raise TLSBadRecordMAC("Truncated tag") 571 572 #Assemble the authenticated data. 573 seqnumBytes = self._readState.getSeqNumBytes() 574 plaintextLen = len(buf) - self._readState.encContext.tagLength 575 authData = seqnumBytes + bytearray([recordType, self.version[0], 576 self.version[1], 577 plaintextLen//256, 578 plaintextLen%256]) 579 580 buf = self._readState.encContext.open(nonce, buf, authData) 581 if buf is None: 582 raise TLSBadRecordMAC("Invalid tag, decryption failure") 583 return buf
584
585 - def recvRecord(self):
586 """ 587 Read, decrypt and check integrity of a single record 588 589 @rtype: tuple 590 @return: message header and decrypted message payload 591 @raise TLSDecryptionFailed: when decryption of data failed 592 @raise TLSBadRecordMAC: when record has bad MAC or padding 593 @raise socket.error: when reading from socket was unsuccessful 594 """ 595 result = None 596 for result in self._recordSocket.recv(): 597 if result in (0, 1): 598 yield result 599 else: break 600 assert result is not None 601 602 (header, data) = result 603 604 if self._readState and \ 605 self._readState.encContext and \ 606 self._readState.encContext.isAEAD: 607 data = self._decryptAndUnseal(header.type, data) 608 elif self.encryptThenMAC: 609 data = self._macThenDecrypt(header.type, data) 610 elif self._readState and \ 611 self._readState.encContext and \ 612 self._readState.encContext.isBlockCipher: 613 data = self._decryptThenMAC(header.type, data) 614 else: 615 data = self._decryptStreamThenMAC(header.type, data) 616 617 yield (header, Parser(data))
618 619 # 620 # cryptography state methods 621 # 622
623 - def changeWriteState(self):
624 """ 625 Change the cipher state to the pending one for write operations. 626 627 This should be done only once after a call to L{calcPendingStates} was 628 performed and directly after sending a L{ChangeCipherSpec} message. 629 """ 630 self._writeState = self._pendingWriteState 631 self._pendingWriteState = ConnectionState()
632
633 - def changeReadState(self):
634 """ 635 Change the cipher state to the pending one for read operations. 636 637 This should be done only once after a call to L{calcPendingStates} was 638 performed and directly after receiving a L{ChangeCipherSpec} message. 639 """ 640 self._readState = self._pendingReadState 641 self._pendingReadState = ConnectionState()
642 643 @staticmethod
644 - def _getCipherSettings(cipherSuite):
645 """Get the settings for cipher suite used""" 646 if cipherSuite in CipherSuite.aes256GcmSuites: 647 keyLength = 32 648 ivLength = 4 649 createCipherFunc = createAESGCM 650 elif cipherSuite in CipherSuite.aes128GcmSuites: 651 keyLength = 16 652 ivLength = 4 653 createCipherFunc = createAESGCM 654 elif cipherSuite in CipherSuite.aes128Suites: 655 keyLength = 16 656 ivLength = 16 657 createCipherFunc = createAES 658 elif cipherSuite in CipherSuite.aes256Suites: 659 keyLength = 32 660 ivLength = 16 661 createCipherFunc = createAES 662 elif cipherSuite in CipherSuite.rc4Suites: 663 keyLength = 16 664 ivLength = 0 665 createCipherFunc = createRC4 666 elif cipherSuite in CipherSuite.tripleDESSuites: 667 keyLength = 24 668 ivLength = 8 669 createCipherFunc = createTripleDES 670 elif cipherSuite in CipherSuite.nullSuites: 671 keyLength = 0 672 ivLength = 0 673 createCipherFunc = None 674 else: 675 raise AssertionError() 676 677 return (keyLength, ivLength, createCipherFunc)
678 679 @staticmethod
680 - def _getMacSettings(cipherSuite):
681 """Get settings for HMAC used""" 682 if cipherSuite in CipherSuite.aeadSuites: 683 macLength = 0 684 digestmod = None 685 elif cipherSuite in CipherSuite.shaSuites: 686 macLength = 20 687 digestmod = hashlib.sha1 688 elif cipherSuite in CipherSuite.sha256Suites: 689 macLength = 32 690 digestmod = hashlib.sha256 691 elif cipherSuite in CipherSuite.md5Suites: 692 macLength = 16 693 digestmod = hashlib.md5 694 else: 695 raise AssertionError() 696 697 return macLength, digestmod
698 699 @staticmethod
700 - def _getHMACMethod(version):
701 """Get the HMAC method""" 702 assert version in ((3, 0), (3, 1), (3, 2), (3, 3)) 703 if version == (3, 0): 704 createMACFunc = createMAC_SSL 705 elif version in ((3, 1), (3, 2), (3, 3)): 706 createMACFunc = createHMAC 707 708 return createMACFunc
709
710 - def _calcKeyBlock(self, cipherSuite, masterSecret, clientRandom, 711 serverRandom, outputLength):
712 """Calculate the overall key to slice up""" 713 if self.version == (3, 0): 714 keyBlock = PRF_SSL(masterSecret, 715 serverRandom + clientRandom, 716 outputLength) 717 elif self.version in ((3, 1), (3, 2)): 718 keyBlock = PRF(masterSecret, 719 b"key expansion", 720 serverRandom + clientRandom, 721 outputLength) 722 elif self.version == (3, 3): 723 if cipherSuite in CipherSuite.sha384PrfSuites: 724 keyBlock = PRF_1_2_SHA384(masterSecret, 725 b"key expansion", 726 serverRandom + clientRandom, 727 outputLength) 728 else: 729 keyBlock = PRF_1_2(masterSecret, 730 b"key expansion", 731 serverRandom + clientRandom, 732 outputLength) 733 else: 734 raise AssertionError() 735 736 return keyBlock
737
738 - def calcPendingStates(self, cipherSuite, masterSecret, clientRandom, 739 serverRandom, implementations):
740 """Create pending states for encryption and decryption.""" 741 keyLength, ivLength, createCipherFunc = \ 742 self._getCipherSettings(cipherSuite) 743 744 macLength, digestmod = self._getMacSettings(cipherSuite) 745 746 if not digestmod: 747 createMACFunc = None 748 else: 749 createMACFunc = self._getHMACMethod(self.version) 750 751 outputLength = (macLength*2) + (keyLength*2) + (ivLength*2) 752 753 #Calculate Keying Material from Master Secret 754 keyBlock = self._calcKeyBlock(cipherSuite, masterSecret, clientRandom, 755 serverRandom, outputLength) 756 757 #Slice up Keying Material 758 clientPendingState = ConnectionState() 759 serverPendingState = ConnectionState() 760 parser = Parser(keyBlock) 761 clientMACBlock = parser.getFixBytes(macLength) 762 serverMACBlock = parser.getFixBytes(macLength) 763 clientKeyBlock = parser.getFixBytes(keyLength) 764 serverKeyBlock = parser.getFixBytes(keyLength) 765 clientIVBlock = parser.getFixBytes(ivLength) 766 serverIVBlock = parser.getFixBytes(ivLength) 767 768 if digestmod: 769 # Legacy cipher 770 clientPendingState.macContext = createMACFunc( 771 compatHMAC(clientMACBlock), digestmod=digestmod) 772 serverPendingState.macContext = createMACFunc( 773 compatHMAC(serverMACBlock), digestmod=digestmod) 774 if createCipherFunc is not None: 775 clientPendingState.encContext = \ 776 createCipherFunc(clientKeyBlock, 777 clientIVBlock, 778 implementations) 779 serverPendingState.encContext = \ 780 createCipherFunc(serverKeyBlock, 781 serverIVBlock, 782 implementations) 783 else: 784 # AEAD 785 clientPendingState.macContext = None 786 serverPendingState.macContext = None 787 clientPendingState.encContext = createCipherFunc(clientKeyBlock, 788 implementations) 789 serverPendingState.encContext = createCipherFunc(serverKeyBlock, 790 implementations) 791 clientPendingState.fixedNonce = clientIVBlock 792 serverPendingState.fixedNonce = serverIVBlock 793 794 #Assign new connection states to pending states 795 if self.client: 796 self._pendingWriteState = clientPendingState 797 self._pendingReadState = serverPendingState 798 else: 799 self._pendingWriteState = serverPendingState 800 self._pendingReadState = clientPendingState 801 802 if self.version >= (3, 2) and ivLength: 803 #Choose fixedIVBlock for TLS 1.1 (this is encrypted with the CBC 804 #residue to create the IV for each sent block) 805 self.fixedIVBlock = getRandomBytes(ivLength)
806