1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
|
diff --git a/third_party/tlslite/tlslite/constants.py b/third_party/tlslite/tlslite/constants.py
index 6d78a20..f9c8676 100644
--- a/third_party/tlslite/tlslite/constants.py
+++ b/third_party/tlslite/tlslite/constants.py
@@ -55,6 +55,7 @@ class ExtensionType: # RFC 6066 / 4366
srp = 12 # RFC 5054
cert_type = 9 # RFC 6091
signed_cert_timestamps = 18 # RFC 6962
+ extended_master_secret = 23 # draft-ietf-tls-session-hash-06
tack = 0xF300
supports_npn = 13172
channel_id = 30032
diff --git a/third_party/tlslite/tlslite/handshakesettings.py b/third_party/tlslite/tlslite/handshakesettings.py
index 605ed42..a7b6ab9 100644
--- a/third_party/tlslite/tlslite/handshakesettings.py
+++ b/third_party/tlslite/tlslite/handshakesettings.py
@@ -111,6 +111,10 @@ class HandshakeSettings(object):
@type alertAfterHandshake: bool
@ivar alertAfterHandshake: If true, the server will send a fatal
alert immediately after the handshake completes.
+
+ @type enableExtendedMasterSecret: bool
+ @ivar enableExtendedMasterSecret: If true, the server supports the extended
+ master secret TLS extension and will negotiated it with supporting clients.
Note that TACK support is not standardized by IETF and uses a temporary
TLS Extension number, so should NOT be used in production software.
@@ -129,6 +133,7 @@ class HandshakeSettings(object):
self.tlsIntoleranceType = 'alert'
self.useExperimentalTackExtension = False
self.alertAfterHandshake = False
+ self.enableExtendedMasterSecret = True
# Validates the min/max fields, and certificateTypes
# Filters out unsupported cipherNames and cipherImplementations
@@ -146,6 +151,7 @@ class HandshakeSettings(object):
other.tlsIntolerant = self.tlsIntolerant
other.tlsIntoleranceType = self.tlsIntoleranceType
other.alertAfterHandshake = self.alertAfterHandshake
+ other.enableExtendedMasterSecret = self.enableExtendedMasterSecret
if not cipherfactory.tripleDESPresent:
other.cipherNames = [e for e in self.cipherNames if e != "3des"]
diff --git a/third_party/tlslite/tlslite/mathtls.py b/third_party/tlslite/tlslite/mathtls.py
index 60a331a..0a23fe1 100644
--- a/third_party/tlslite/tlslite/mathtls.py
+++ b/third_party/tlslite/tlslite/mathtls.py
@@ -67,16 +67,20 @@ def PRF_SSL(secret, seed, length):
index += 1
return bytes
-def calcMasterSecret(version, premasterSecret, clientRandom, serverRandom):
+def calcMasterSecret(version, premasterSecret, clientRandom, serverRandom,
+ handshakeHash, useExtendedMasterSecret):
+ label = b"master secret"
+ seed = clientRandom + serverRandom
+ if useExtendedMasterSecret:
+ label = b"extended master secret"
+ seed = handshakeHash
+
if version == (3,0):
- masterSecret = PRF_SSL(premasterSecret,
- clientRandom + serverRandom, 48)
+ masterSecret = PRF_SSL(premasterSecret, seed, 48)
elif version in ((3,1), (3,2)):
- masterSecret = PRF(premasterSecret, b"master secret",
- clientRandom + serverRandom, 48)
+ masterSecret = PRF(premasterSecret, label, seed, 48)
elif version == (3,3):
- masterSecret = PRF_1_2(premasterSecret, b"master secret",
- clientRandom + serverRandom, 48)
+ masterSecret = PRF_1_2(premasterSecret, label, seed, 48)
else:
raise AssertionError()
return masterSecret
diff --git a/third_party/tlslite/tlslite/messages.py b/third_party/tlslite/tlslite/messages.py
index 9aeff6d..9b553ce 100644
--- a/third_party/tlslite/tlslite/messages.py
+++ b/third_party/tlslite/tlslite/messages.py
@@ -114,6 +114,7 @@ class ClientHello(HandshakeMsg):
self.supports_npn = False
self.server_name = bytearray(0)
self.channel_id = False
+ self.extended_master_secret = False
self.support_signed_cert_timestamps = False
self.status_request = False
@@ -185,6 +186,8 @@ class ClientHello(HandshakeMsg):
break
elif extType == ExtensionType.channel_id:
self.channel_id = True
+ elif extType == ExtensionType.extended_master_secret:
+ self.extended_master_secret = True
elif extType == ExtensionType.signed_cert_timestamps:
if extLength:
raise SyntaxError()
@@ -267,6 +270,7 @@ class ServerHello(HandshakeMsg):
self.next_protos_advertised = None
self.next_protos = None
self.channel_id = False
+ self.extended_master_secret = False
self.signed_cert_timestamps = None
self.status_request = False
@@ -358,6 +362,9 @@ class ServerHello(HandshakeMsg):
if self.channel_id:
w2.add(ExtensionType.channel_id, 2)
w2.add(0, 2)
+ if self.extended_master_secret:
+ w2.add(ExtensionType.extended_master_secret, 2)
+ w2.add(0, 2)
if self.signed_cert_timestamps:
w2.add(ExtensionType.signed_cert_timestamps, 2)
w2.addVarSeq(bytearray(self.signed_cert_timestamps), 1, 2)
diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py
index dfac274..04161513 100644
--- a/third_party/tlslite/tlslite/tlsconnection.py
+++ b/third_party/tlslite/tlslite/tlsconnection.py
@@ -981,7 +981,8 @@ class TLSConnection(TLSRecordLayer):
masterSecret = calcMasterSecret(self.version,
premasterSecret,
clientRandom,
- serverRandom)
+ serverRandom,
+ b"", False)
verifyBytes = self._calcSSLHandshakeHash(masterSecret, b"")
elif self.version in ((3,1), (3,2)):
verifyBytes = self._handshake_md5.digest() + \
@@ -1036,7 +1037,7 @@ class TLSConnection(TLSRecordLayer):
cipherSuite, cipherImplementations, nextProto):
masterSecret = calcMasterSecret(self.version, premasterSecret,
- clientRandom, serverRandom)
+ clientRandom, serverRandom, b"", False)
self._calcPendingStates(cipherSuite, masterSecret,
clientRandom, serverRandom,
cipherImplementations)
@@ -1326,6 +1327,9 @@ class TLSConnection(TLSRecordLayer):
cipherSuite, CertificateType.x509, tackExt,
nextProtos)
serverHello.channel_id = clientHello.channel_id
+ serverHello.extended_master_secret = \
+ clientHello.extended_master_secret and \
+ settings.enableExtendedMasterSecret
if clientHello.support_signed_cert_timestamps:
serverHello.signed_cert_timestamps = signedCertTimestamps
if clientHello.status_request:
@@ -1383,7 +1387,8 @@ class TLSConnection(TLSRecordLayer):
for result in self._serverFinished(premasterSecret,
clientHello.random, serverHello.random,
cipherSuite, settings.cipherImplementations,
- nextProtos, clientHello.channel_id):
+ nextProtos, clientHello.channel_id,
+ serverHello.extended_master_secret):
if result in (0,1): yield result
else: break
masterSecret = result
@@ -1523,6 +1528,9 @@ class TLSConnection(TLSRecordLayer):
serverHello.create(self.version, getRandomBytes(32),
session.sessionID, session.cipherSuite,
CertificateType.x509, None, None)
+ serverHello.extended_master_secret = \
+ clientHello.extended_master_secret and \
+ settings.enableExtendedMasterSecret
for result in self._sendMsg(serverHello):
yield result
@@ -1743,7 +1751,8 @@ class TLSConnection(TLSRecordLayer):
if clientCertChain:
if self.version == (3,0):
masterSecret = calcMasterSecret(self.version, premasterSecret,
- clientHello.random, serverHello.random)
+ clientHello.random, serverHello.random,
+ b"", False)
verifyBytes = self._calcSSLHandshakeHash(masterSecret, b"")
elif self.version in ((3,1), (3,2)):
verifyBytes = self._handshake_md5.digest() + \
@@ -1827,9 +1836,11 @@ class TLSConnection(TLSRecordLayer):
def _serverFinished(self, premasterSecret, clientRandom, serverRandom,
cipherSuite, cipherImplementations, nextProtos,
- doingChannelID):
+ doingChannelID, useExtendedMasterSecret):
masterSecret = calcMasterSecret(self.version, premasterSecret,
- clientRandom, serverRandom)
+ clientRandom, serverRandom,
+ self._ems_handshake_hash,
+ useExtendedMasterSecret)
#Calculate pending connection states
self._calcPendingStates(cipherSuite, masterSecret,
diff --git a/third_party/tlslite/tlslite/tlsrecordlayer.py b/third_party/tlslite/tlslite/tlsrecordlayer.py
index c3bcd8c..d2320b8 100644
--- a/third_party/tlslite/tlslite/tlsrecordlayer.py
+++ b/third_party/tlslite/tlslite/tlsrecordlayer.py
@@ -119,6 +119,7 @@ class TLSRecordLayer(object):
self._handshake_md5 = hashlib.md5()
self._handshake_sha = hashlib.sha1()
self._handshake_sha256 = hashlib.sha256()
+ self._ems_handshake_hash = b""
#TLS Protocol Version
self.version = (0,0) #read-only
@@ -814,6 +815,8 @@ class TLSRecordLayer(object):
self._handshake_md5.update(compat26Str(p.bytes))
self._handshake_sha.update(compat26Str(p.bytes))
self._handshake_sha256.update(compat26Str(p.bytes))
+ if subType == HandshakeType.client_key_exchange:
+ self._ems_handshake_hash = self._getHandshakeHash()
#Parse based on handshake type
if subType == HandshakeType.client_hello:
@@ -1112,6 +1115,7 @@ class TLSRecordLayer(object):
self._handshake_md5 = hashlib.md5()
self._handshake_sha = hashlib.sha1()
self._handshake_sha256 = hashlib.sha256()
+ self._ems_handshake_hash = b""
self._handshakeBuffer = []
self.allegedSrpUsername = None
self._refCount = 1
@@ -1256,3 +1260,9 @@ class TLSRecordLayer(object):
return md5Bytes + shaBytes
+ def _getHandshakeHash(self):
+ if self.version in ((3,1), (3,2)):
+ return self._handshake_md5.digest() + \
+ self._handshake_sha.digest()
+ elif self.version == (3,3):
+ return self._handshake_sha256.digest()
|