1
2
3
4 """Handling cryptographic hashes for handshake protocol"""
5
6 from .utils.compat import compat26Str, compatHMAC
7 from .utils.cryptomath import MD5, SHA1
8 import hashlib
9
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
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
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
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
81 imacMD5 = self._handshakeMD5.copy()
82 imacSHA = self._handshakeSHA.copy()
83
84
85
86
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
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