summaryrefslogtreecommitdiff
path: root/chromium/third_party/tlslite/patches/extended_master_secret.patch
blob: b6ad58ddfd5e17cc98ed4c75786fc4128d41946a (plain)
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()