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, createCHACHA20 
 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 blockSize(self):
249 """Return the size of block used by current symmetric cipher (R/O)""" 250 return self._writeState.encContext.block_size
251 252 @property
253 - def version(self):
254 """Return the TLS version used by record layer""" 255 return self._version
256 257 @version.setter
258 - def version(self, val):
259 """Set the TLS version used by record layer""" 260 self._version = val 261 self._recordSocket.version = val
262
263 - def getCipherName(self):
264 """ 265 Return the name of the bulk cipher used by this connection 266 267 @rtype: str 268 @return: The name of the cipher, like 'aes128', 'rc4', etc. 269 """ 270 if self._writeState.encContext is None: 271 return None 272 return self._writeState.encContext.name
273
274 - def getCipherImplementation(self):
275 """ 276 Return the name of the implementation used for the connection 277 278 'python' for tlslite internal implementation, 'openssl' for M2crypto 279 and 'pycrypto' for pycrypto 280 @rtype: str 281 @return: Name of cipher implementation used, None if not initialised 282 """ 283 if self._writeState.encContext is None: 284 return None 285 return self._writeState.encContext.implementation
286
287 - def shutdown(self):
288 """Clear read and write states""" 289 self._writeState = ConnectionState() 290 self._readState = ConnectionState() 291 self._pendingWriteState = ConnectionState() 292 self._pendingReadState = ConnectionState()
293
294 - def isCBCMode(self):
295 """Returns true if cipher uses CBC mode""" 296 if self._writeState and self._writeState.encContext and \ 297 self._writeState.encContext.isBlockCipher: 298 return True 299 else: 300 return False
301 # 302 # sending messages 303 # 304
305 - def addPadding(self, data):
306 """Add padding to data so that it is multiple of block size""" 307 currentLength = len(data) 308 blockLength = self.blockSize 309 paddingLength = blockLength - 1 - (currentLength % blockLength) 310 311 paddingBytes = bytearray([paddingLength] * (paddingLength+1)) 312 data += paddingBytes 313 return data
314
315 - def calculateMAC(self, mac, seqnumBytes, contentType, data):
316 """Calculate the SSL/TLS version of a MAC""" 317 mac.update(compatHMAC(seqnumBytes)) 318 mac.update(compatHMAC(bytearray([contentType]))) 319 assert self.version in ((3, 0), (3, 1), (3, 2), (3, 3)) 320 if self.version != (3, 0): 321 mac.update(compatHMAC(bytearray([self.version[0]]))) 322 mac.update(compatHMAC(bytearray([self.version[1]]))) 323 mac.update(compatHMAC(bytearray([len(data)//256]))) 324 mac.update(compatHMAC(bytearray([len(data)%256]))) 325 mac.update(compatHMAC(data)) 326 return bytearray(mac.digest())
327
328 - def _macThenEncrypt(self, data, contentType):
329 """MAC, pad then encrypt data""" 330 if self._writeState.macContext: 331 seqnumBytes = self._writeState.getSeqNumBytes() 332 mac = self._writeState.macContext.copy() 333 macBytes = self.calculateMAC(mac, seqnumBytes, contentType, data) 334 data += macBytes 335 336 #Encrypt for Block or Stream Cipher 337 if self._writeState.encContext: 338 #Add padding (for Block Cipher): 339 if self._writeState.encContext.isBlockCipher: 340 341 #Add TLS 1.1 fixed block 342 if self.version >= (3, 2): 343 data = self.fixedIVBlock + data 344 345 data = self.addPadding(data) 346 347 #Encrypt 348 data = self._writeState.encContext.encrypt(data) 349 350 return data
351
352 - def _encryptThenMAC(self, buf, contentType):
353 """Pad, encrypt and then MAC the data""" 354 if self._writeState.encContext: 355 # add IV for TLS1.1+ 356 if self.version >= (3, 2): 357 buf = self.fixedIVBlock + buf 358 359 buf = self.addPadding(buf) 360 361 buf = self._writeState.encContext.encrypt(buf) 362 363 # add MAC 364 if self._writeState.macContext: 365 seqnumBytes = self._writeState.getSeqNumBytes() 366 mac = self._writeState.macContext.copy() 367 368 # append MAC 369 macBytes = self.calculateMAC(mac, seqnumBytes, contentType, buf) 370 buf += macBytes 371 372 return buf
373
374 - def _encryptThenSeal(self, buf, contentType):
375 """Encrypt with AEAD cipher""" 376 #Assemble the authenticated data. 377 seqNumBytes = self._writeState.getSeqNumBytes() 378 authData = seqNumBytes + bytearray([contentType, 379 self.version[0], 380 self.version[1], 381 len(buf)//256, 382 len(buf)%256]) 383 384 #The nonce is always the fixed nonce and the sequence number. 385 nonce = self._writeState.fixedNonce + seqNumBytes 386 387 assert len(nonce) == self._writeState.encContext.nonceLength 388 389 buf = self._writeState.encContext.seal(nonce, buf, authData) 390 391 #AES-GCM, has an explicit variable nonce. 392 if "aes" in self._writeState.encContext.name: 393 buf = seqNumBytes + buf 394 395 return buf
396
397 - def sendRecord(self, msg):
398 """ 399 Encrypt, MAC and send arbitrary message as-is through socket. 400 401 Note that if the message was not fragmented to below 2**14 bytes 402 it will be rejected by the other connection side. 403 404 @param msg: TLS message to send 405 @type msg: ApplicationData, HandshakeMessage, etc. 406 """ 407 data = msg.write() 408 contentType = msg.contentType 409 410 if self._writeState and \ 411 self._writeState.encContext and \ 412 self._writeState.encContext.isAEAD: 413 data = self._encryptThenSeal(data, contentType) 414 elif self.encryptThenMAC: 415 data = self._encryptThenMAC(data, contentType) 416 else: 417 data = self._macThenEncrypt(data, contentType) 418 419 encryptedMessage = Message(contentType, data) 420 421 for result in self._recordSocket.send(encryptedMessage): 422 yield result
423 424 # 425 # receiving messages 426 # 427
428 - def _decryptStreamThenMAC(self, recordType, data):
429 """Decrypt a stream cipher and check MAC""" 430 if self._readState.encContext: 431 assert self.version in ((3, 0), (3, 1), (3, 2), (3, 3)) 432 433 data = self._readState.encContext.decrypt(data) 434 435 if self._readState.macContext: 436 #Check MAC 437 macGood = True 438 macLength = self._readState.macContext.digest_size 439 endLength = macLength 440 if endLength > len(data): 441 macGood = False 442 else: 443 #Read MAC 444 startIndex = len(data) - endLength 445 endIndex = startIndex + macLength 446 checkBytes = data[startIndex : endIndex] 447 448 #Calculate MAC 449 seqnumBytes = self._readState.getSeqNumBytes() 450 data = data[:-endLength] 451 mac = self._readState.macContext.copy() 452 macBytes = self.calculateMAC(mac, seqnumBytes, recordType, 453 data) 454 455 #Compare MACs 456 if not ct_compare_digest(macBytes, checkBytes): 457 macGood = False 458 459 if not macGood: 460 raise TLSBadRecordMAC() 461 462 return data
463 464
465 - def _decryptThenMAC(self, recordType, data):
466 """Decrypt data, check padding and MAC""" 467 if self._readState.encContext: 468 assert self.version in ((3, 0), (3, 1), (3, 2), (3, 3)) 469 assert self._readState.encContext.isBlockCipher 470 assert self._readState.macContext 471 472 # 473 # decrypt the record 474 # 475 blockLength = self._readState.encContext.block_size 476 if len(data) % blockLength != 0: 477 raise TLSDecryptionFailed() 478 data = self._readState.encContext.decrypt(data) 479 if self.version >= (3, 2): #For TLS 1.1, remove explicit IV 480 data = data[self._readState.encContext.block_size : ] 481 482 # 483 # check padding and MAC 484 # 485 seqnumBytes = self._readState.getSeqNumBytes() 486 487 if not ct_check_cbc_mac_and_pad(data, 488 self._readState.macContext, 489 seqnumBytes, 490 recordType, 491 self.version): 492 raise TLSBadRecordMAC() 493 494 # 495 # strip padding and MAC 496 # 497 498 endLength = data[-1] + 1 + self._readState.macContext.digest_size 499 500 data = data[:-endLength] 501 502 return data
503
504 - def _macThenDecrypt(self, recordType, buf):
505 """ 506 Check MAC of data, then decrypt and remove padding 507 508 @raise TLSBadRecordMAC: when the mac value is invalid 509 @raise TLSDecryptionFailed: when the data to decrypt has invalid size 510 """ 511 if self._readState.macContext: 512 macLength = self._readState.macContext.digest_size 513 if len(buf) < macLength: 514 raise TLSBadRecordMAC("Truncated data") 515 516 checkBytes = buf[-macLength:] 517 buf = buf[:-macLength] 518 519 seqnumBytes = self._readState.getSeqNumBytes() 520 mac = self._readState.macContext.copy() 521 522 macBytes = self.calculateMAC(mac, seqnumBytes, recordType, buf) 523 524 if not ct_compare_digest(macBytes, checkBytes): 525 raise TLSBadRecordMAC("MAC mismatch") 526 527 if self._readState.encContext: 528 blockLength = self._readState.encContext.block_size 529 if len(buf) % blockLength != 0: 530 raise TLSDecryptionFailed("data length not multiple of "\ 531 "block size") 532 533 buf = self._readState.encContext.decrypt(buf) 534 535 # remove explicit IV 536 if self.version >= (3, 2): 537 buf = buf[blockLength:] 538 539 if len(buf) == 0: 540 raise TLSBadRecordMAC("No data left after IV removal") 541 542 # check padding 543 paddingLength = buf[-1] 544 if paddingLength + 1 > len(buf): 545 raise TLSBadRecordMAC("Invalid padding length") 546 547 paddingGood = True 548 totalPaddingLength = paddingLength+1 549 if self.version != (3, 0): 550 paddingBytes = buf[-totalPaddingLength:-1] 551 for byte in paddingBytes: 552 if byte != paddingLength: 553 paddingGood = False 554 555 if not paddingGood: 556 raise TLSBadRecordMAC("Invalid padding byte values") 557 558 # remove padding 559 buf = buf[:-totalPaddingLength] 560 561 return buf
562
563 - def _decryptAndUnseal(self, recordType, buf):
564 """Decrypt AEAD encrypted data""" 565 seqnumBytes = self._readState.getSeqNumBytes() 566 #AES-GCM, has an explicit variable nonce. 567 if "aes" in self._readState.encContext.name: 568 explicitNonceLength = 8 569 if explicitNonceLength > len(buf): 570 #Publicly invalid. 571 raise TLSBadRecordMAC("Truncated nonce") 572 nonce = self._readState.fixedNonce + buf[:explicitNonceLength] 573 buf = buf[8:] 574 else: 575 nonce = self._readState.fixedNonce + seqnumBytes 576 577 if self._readState.encContext.tagLength > len(buf): 578 #Publicly invalid. 579 raise TLSBadRecordMAC("Truncated tag") 580 581 plaintextLen = len(buf) - self._readState.encContext.tagLength 582 authData = seqnumBytes + bytearray([recordType, self.version[0], 583 self.version[1], 584 plaintextLen//256, 585 plaintextLen%256]) 586 587 buf = self._readState.encContext.open(nonce, buf, authData) 588 if buf is None: 589 raise TLSBadRecordMAC("Invalid tag, decryption failure") 590 return buf
591
592 - def recvRecord(self):
593 """ 594 Read, decrypt and check integrity of a single record 595 596 @rtype: tuple 597 @return: message header and decrypted message payload 598 @raise TLSDecryptionFailed: when decryption of data failed 599 @raise TLSBadRecordMAC: when record has bad MAC or padding 600 @raise socket.error: when reading from socket was unsuccessful 601 """ 602 result = None 603 for result in self._recordSocket.recv(): 604 if result in (0, 1): 605 yield result 606 else: break 607 assert result is not None 608 609 (header, data) = result 610 611 if self._readState and \ 612 self._readState.encContext and \ 613 self._readState.encContext.isAEAD: 614 data = self._decryptAndUnseal(header.type, data) 615 elif self.encryptThenMAC: 616 data = self._macThenDecrypt(header.type, data) 617 elif self._readState and \ 618 self._readState.encContext and \ 619 self._readState.encContext.isBlockCipher: 620 data = self._decryptThenMAC(header.type, data) 621 else: 622 data = self._decryptStreamThenMAC(header.type, data) 623 624 yield (header, Parser(data))
625 626 # 627 # cryptography state methods 628 # 629
630 - def changeWriteState(self):
631 """ 632 Change the cipher state to the pending one for write operations. 633 634 This should be done only once after a call to L{calcPendingStates} was 635 performed and directly after sending a L{ChangeCipherSpec} message. 636 """ 637 self._writeState = self._pendingWriteState 638 self._pendingWriteState = ConnectionState()
639
640 - def changeReadState(self):
641 """ 642 Change the cipher state to the pending one for read operations. 643 644 This should be done only once after a call to L{calcPendingStates} was 645 performed and directly after receiving a L{ChangeCipherSpec} message. 646 """ 647 self._readState = self._pendingReadState 648 self._pendingReadState = ConnectionState()
649 650 @staticmethod
651 - def _getCipherSettings(cipherSuite):
652 """Get the settings for cipher suite used""" 653 if cipherSuite in CipherSuite.aes256GcmSuites: 654 keyLength = 32 655 ivLength = 4 656 createCipherFunc = createAESGCM 657 elif cipherSuite in CipherSuite.aes128GcmSuites: 658 keyLength = 16 659 ivLength = 4 660 createCipherFunc = createAESGCM 661 elif cipherSuite in CipherSuite.chacha20Suites: 662 keyLength = 32 663 ivLength = 4 664 createCipherFunc = createCHACHA20 665 elif cipherSuite in CipherSuite.aes128Suites: 666 keyLength = 16 667 ivLength = 16 668 createCipherFunc = createAES 669 elif cipherSuite in CipherSuite.aes256Suites: 670 keyLength = 32 671 ivLength = 16 672 createCipherFunc = createAES 673 elif cipherSuite in CipherSuite.rc4Suites: 674 keyLength = 16 675 ivLength = 0 676 createCipherFunc = createRC4 677 elif cipherSuite in CipherSuite.tripleDESSuites: 678 keyLength = 24 679 ivLength = 8 680 createCipherFunc = createTripleDES 681 elif cipherSuite in CipherSuite.nullSuites: 682 keyLength = 0 683 ivLength = 0 684 createCipherFunc = None 685 else: 686 raise AssertionError() 687 688 return (keyLength, ivLength, createCipherFunc)
689 690 @staticmethod
691 - def _getMacSettings(cipherSuite):
692 """Get settings for HMAC used""" 693 if cipherSuite in CipherSuite.aeadSuites: 694 macLength = 0 695 digestmod = None 696 elif cipherSuite in CipherSuite.shaSuites: 697 macLength = 20 698 digestmod = hashlib.sha1 699 elif cipherSuite in CipherSuite.sha256Suites: 700 macLength = 32 701 digestmod = hashlib.sha256 702 elif cipherSuite in CipherSuite.md5Suites: 703 macLength = 16 704 digestmod = hashlib.md5 705 else: 706 raise AssertionError() 707 708 return macLength, digestmod
709 710 @staticmethod
711 - def _getHMACMethod(version):
712 """Get the HMAC method""" 713 assert version in ((3, 0), (3, 1), (3, 2), (3, 3)) 714 if version == (3, 0): 715 createMACFunc = createMAC_SSL 716 elif version in ((3, 1), (3, 2), (3, 3)): 717 createMACFunc = createHMAC 718 719 return createMACFunc
720
721 - def _calcKeyBlock(self, cipherSuite, masterSecret, clientRandom, 722 serverRandom, outputLength):
723 """Calculate the overall key to slice up""" 724 if self.version == (3, 0): 725 keyBlock = PRF_SSL(masterSecret, 726 serverRandom + clientRandom, 727 outputLength) 728 elif self.version in ((3, 1), (3, 2)): 729 keyBlock = PRF(masterSecret, 730 b"key expansion", 731 serverRandom + clientRandom, 732 outputLength) 733 elif self.version == (3, 3): 734 if cipherSuite in CipherSuite.sha384PrfSuites: 735 keyBlock = PRF_1_2_SHA384(masterSecret, 736 b"key expansion", 737 serverRandom + clientRandom, 738 outputLength) 739 else: 740 keyBlock = PRF_1_2(masterSecret, 741 b"key expansion", 742 serverRandom + clientRandom, 743 outputLength) 744 else: 745 raise AssertionError() 746 747 return keyBlock
748
749 - def calcPendingStates(self, cipherSuite, masterSecret, clientRandom, 750 serverRandom, implementations):
751 """Create pending states for encryption and decryption.""" 752 keyLength, ivLength, createCipherFunc = \ 753 self._getCipherSettings(cipherSuite) 754 755 macLength, digestmod = self._getMacSettings(cipherSuite) 756 757 if not digestmod: 758 createMACFunc = None 759 else: 760 createMACFunc = self._getHMACMethod(self.version) 761 762 outputLength = (macLength*2) + (keyLength*2) + (ivLength*2) 763 764 #Calculate Keying Material from Master Secret 765 keyBlock = self._calcKeyBlock(cipherSuite, masterSecret, clientRandom, 766 serverRandom, outputLength) 767 768 #Slice up Keying Material 769 clientPendingState = ConnectionState() 770 serverPendingState = ConnectionState() 771 parser = Parser(keyBlock) 772 clientMACBlock = parser.getFixBytes(macLength) 773 serverMACBlock = parser.getFixBytes(macLength) 774 clientKeyBlock = parser.getFixBytes(keyLength) 775 serverKeyBlock = parser.getFixBytes(keyLength) 776 clientIVBlock = parser.getFixBytes(ivLength) 777 serverIVBlock = parser.getFixBytes(ivLength) 778 779 if digestmod: 780 # Legacy cipher 781 clientPendingState.macContext = createMACFunc( 782 compatHMAC(clientMACBlock), digestmod=digestmod) 783 serverPendingState.macContext = createMACFunc( 784 compatHMAC(serverMACBlock), digestmod=digestmod) 785 if createCipherFunc is not None: 786 clientPendingState.encContext = \ 787 createCipherFunc(clientKeyBlock, 788 clientIVBlock, 789 implementations) 790 serverPendingState.encContext = \ 791 createCipherFunc(serverKeyBlock, 792 serverIVBlock, 793 implementations) 794 else: 795 # AEAD 796 clientPendingState.macContext = None 797 serverPendingState.macContext = None 798 clientPendingState.encContext = createCipherFunc(clientKeyBlock, 799 implementations) 800 serverPendingState.encContext = createCipherFunc(serverKeyBlock, 801 implementations) 802 clientPendingState.fixedNonce = clientIVBlock 803 serverPendingState.fixedNonce = serverIVBlock 804 805 #Assign new connection states to pending states 806 if self.client: 807 self._pendingWriteState = clientPendingState 808 self._pendingReadState = serverPendingState 809 else: 810 self._pendingWriteState = serverPendingState 811 self._pendingReadState = clientPendingState 812 813 if self.version >= (3, 2) and ivLength: 814 #Choose fixedIVBlock for TLS 1.1 (this is encrypted with the CBC 815 #residue to create the IV for each sent block) 816 self.fixedIVBlock = getRandomBytes(ivLength)
817