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

Source Code for Module tlslite.handshakehashes

  1  # Copyright (c) 2015, Hubert Kario 
  2  # 
  3  # See the LICENSE file for legal information regarding use of this file. 
  4  """Handling cryptographic hashes for handshake protocol""" 
  5   
  6  from .utils.compat import compat26Str, compatHMAC 
  7  from .utils.cryptomath import MD5, SHA1 
  8  from .utils import tlshashlib as hashlib 
  9   
10 -class HandshakeHashes(object):
11 12 """ 13 Store and calculate necessary hashes for handshake protocol 14 15 Calculates message digests of messages exchanged in handshake protocol 16 of SSLv3 and TLS. 17 """ 18
19 - def __init__(self):
20 """Create instance""" 21 self._handshakeMD5 = hashlib.md5() 22 self._handshakeSHA = hashlib.sha1() 23 self._handshakeSHA224 = hashlib.sha224() 24 self._handshakeSHA256 = hashlib.sha256() 25 self._handshakeSHA384 = hashlib.sha384() 26 self._handshakeSHA512 = hashlib.sha512()
27
28 - def update(self, data):
29 """ 30 Add L{data} to hash input. 31 32 @type data: bytearray 33 @param data: serialized TLS handshake message 34 """ 35 text = compat26Str(data) 36 self._handshakeMD5.update(text) 37 self._handshakeSHA.update(text) 38 self._handshakeSHA224.update(text) 39 self._handshakeSHA256.update(text) 40 self._handshakeSHA384.update(text) 41 self._handshakeSHA512.update(text)
42
43 - def digest(self, digest=None):
44 """ 45 Calculate and return digest for the already consumed data. 46 47 Used for Finished and CertificateVerify messages. 48 49 @type digest: str 50 @param digest: name of digest to return 51 """ 52 if digest is None: 53 return self._handshakeMD5.digest() + self._handshakeSHA.digest() 54 elif digest == 'md5': 55 return self._handshakeMD5.digest() 56 elif digest == 'sha1': 57 return self._handshakeSHA.digest() 58 elif digest == 'sha224': 59 return self._handshakeSHA224.digest() 60 elif digest == 'sha256': 61 return self._handshakeSHA256.digest() 62 elif digest == 'sha384': 63 return self._handshakeSHA384.digest() 64 elif digest == 'sha512': 65 return self._handshakeSHA512.digest() 66 else: 67 raise ValueError("Unknown digest name")
68
69 - def digestSSL(self, masterSecret, label):
70 """ 71 Calculate and return digest for already consumed data (SSLv3 version) 72 73 Used for Finished and CertificateVerify messages. 74 75 @type masterSecret: bytearray 76 @param masterSecret: value of the master secret 77 @type label: bytearray 78 @param label: label to include in the calculation 79 """ 80 #pylint: disable=maybe-no-member 81 imacMD5 = self._handshakeMD5.copy() 82 imacSHA = self._handshakeSHA.copy() 83 #pylint: enable=maybe-no-member 84 85 # the below difference in input for MD5 and SHA-1 is why we can't reuse 86 # digest() method 87 imacMD5.update(compatHMAC(label + masterSecret + bytearray([0x36]*48))) 88 imacSHA.update(compatHMAC(label + masterSecret + bytearray([0x36]*40))) 89 90 md5Bytes = MD5(masterSecret + bytearray([0x5c]*48) + \ 91 bytearray(imacMD5.digest())) 92 shaBytes = SHA1(masterSecret + bytearray([0x5c]*40) + \ 93 bytearray(imacSHA.digest())) 94 95 return md5Bytes + shaBytes
96 97 #pylint: disable=protected-access, maybe-no-member
98 - def copy(self):
99 """ 100 Copy object 101 102 Return a copy of the object with all the hashes in the same state 103 as the source object. 104 105 @rtype: HandshakeHashes 106 """ 107 other = HandshakeHashes() 108 other._handshakeMD5 = self._handshakeMD5.copy() 109 other._handshakeSHA = self._handshakeSHA.copy() 110 other._handshakeSHA224 = self._handshakeSHA224.copy() 111 other._handshakeSHA256 = self._handshakeSHA256.copy() 112 other._handshakeSHA384 = self._handshakeSHA384.copy() 113 other._handshakeSHA512 = self._handshakeSHA512.copy() 114 return other
115