Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(421)

Side by Side Diff: third_party/tlslite/patches/dhe_rsa.patch

Issue 212883008: Add DHE_RSA support to tlslite. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: spaces Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 diff --git a/third_party/tlslite/tlslite/constants.py b/third_party/tlslite/tlsl ite/constants.py
2 index 52c20ac..feca423 100644
3 --- a/third_party/tlslite/tlslite/constants.py
4 +++ b/third_party/tlslite/tlslite/constants.py
5 @@ -143,6 +143,10 @@ class CipherSuite:
6
7 TLS_RSA_WITH_RC4_128_MD5 = 0x0004
8
9 + TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x0016
10 + TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033
11 + TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039
12 +
13 TLS_DH_ANON_WITH_AES_128_CBC_SHA = 0x0034
14 TLS_DH_ANON_WITH_AES_256_CBC_SHA = 0x003A
15
16 @@ -150,17 +154,20 @@ class CipherSuite:
17 tripleDESSuites.append(TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA)
18 tripleDESSuites.append(TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA)
19 tripleDESSuites.append(TLS_RSA_WITH_3DES_EDE_CBC_SHA)
20 + tripleDESSuites.append(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA)
21
22 aes128Suites = []
23 aes128Suites.append(TLS_SRP_SHA_WITH_AES_128_CBC_SHA)
24 aes128Suites.append(TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA)
25 aes128Suites.append(TLS_RSA_WITH_AES_128_CBC_SHA)
26 + aes128Suites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA)
27 aes128Suites.append(TLS_DH_ANON_WITH_AES_128_CBC_SHA)
28
29 aes256Suites = []
30 aes256Suites.append(TLS_SRP_SHA_WITH_AES_256_CBC_SHA)
31 aes256Suites.append(TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA)
32 aes256Suites.append(TLS_RSA_WITH_AES_256_CBC_SHA)
33 + aes256Suites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA)
34 aes256Suites.append(TLS_DH_ANON_WITH_AES_256_CBC_SHA)
35
36 rc4Suites = []
37 @@ -178,6 +185,9 @@ class CipherSuite:
38 shaSuites.append(TLS_RSA_WITH_AES_128_CBC_SHA)
39 shaSuites.append(TLS_RSA_WITH_AES_256_CBC_SHA)
40 shaSuites.append(TLS_RSA_WITH_RC4_128_SHA)
41 + shaSuites.append(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA)
42 + shaSuites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA)
43 + shaSuites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA)
44 shaSuites.append(TLS_DH_ANON_WITH_AES_128_CBC_SHA)
45 shaSuites.append(TLS_DH_ANON_WITH_AES_256_CBC_SHA)
46
47 @@ -188,6 +198,7 @@ class CipherSuite:
48 def _filterSuites(suites, settings):
49 macNames = settings.macNames
50 cipherNames = settings.cipherNames
51 + keyExchangeNames = settings.keyExchangeNames
52 macSuites = []
53 if "sha" in macNames:
54 macSuites += CipherSuite.shaSuites
55 @@ -204,7 +215,20 @@ class CipherSuite:
56 if "rc4" in cipherNames:
57 cipherSuites += CipherSuite.rc4Suites
58
59 - return [s for s in suites if s in macSuites and s in cipherSuites]
60 + keyExchangeSuites = []
61 + if "rsa" in keyExchangeNames:
62 + keyExchangeSuites += CipherSuite.certSuites
63 + if "dhe_rsa" in keyExchangeNames:
64 + keyExchangeSuites += CipherSuite.dheCertSuites
65 + if "srp_sha" in keyExchangeNames:
66 + keyExchangeSuites += CipherSuite.srpSuites
67 + if "srp_sha_rsa" in keyExchangeNames:
68 + keyExchangeSuites += CipherSuite.srpCertSuites
69 + if "dh_anon" in keyExchangeNames:
70 + keyExchangeSuites += CipherSuite.anonSuites
71 +
72 + return [s for s in suites if s in macSuites and
73 + s in cipherSuites and s in keyExchangeSuites]
74
75 srpSuites = []
76 srpSuites.append(TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA)
77 @@ -236,12 +260,22 @@ class CipherSuite:
78 certSuites.append(TLS_RSA_WITH_AES_256_CBC_SHA)
79 certSuites.append(TLS_RSA_WITH_RC4_128_SHA)
80 certSuites.append(TLS_RSA_WITH_RC4_128_MD5)
81 - certAllSuites = srpCertSuites + certSuites
82
83 @staticmethod
84 def getCertSuites(settings):
85 return CipherSuite._filterSuites(CipherSuite.certSuites, settings)
86
87 + dheCertSuites = []
88 + dheCertSuites.append(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA)
89 + dheCertSuites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA)
90 + dheCertSuites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA)
91 +
92 + @staticmethod
93 + def getDheCertSuites(settings):
94 + return CipherSuite._filterSuites(CipherSuite.dheCertSuites, settings)
95 +
96 + certAllSuites = srpCertSuites + certSuites + dheCertSuites
97 +
98 anonSuites = []
99 anonSuites.append(TLS_DH_ANON_WITH_AES_128_CBC_SHA)
100 anonSuites.append(TLS_DH_ANON_WITH_AES_256_CBC_SHA)
101 @@ -250,6 +284,8 @@ class CipherSuite:
102 def getAnonSuites(settings):
103 return CipherSuite._filterSuites(CipherSuite.anonSuites, settings)
104
105 + dhAllSuites = dheCertSuites + anonSuites
106 +
107 @staticmethod
108 def canonicalCipherName(ciphersuite):
109 "Return the canonical name of the cipher whose number is provided."
110 diff --git a/third_party/tlslite/tlslite/handshakesettings.py b/third_party/tlsl ite/tlslite/handshakesettings.py
111 index 7a38ee2..35c8b0e 100644
112 --- a/third_party/tlslite/tlslite/handshakesettings.py
113 +++ b/third_party/tlslite/tlslite/handshakesettings.py
114 @@ -14,6 +14,7 @@ from .utils import cipherfactory
115 # issues such as timing attacks
116 CIPHER_NAMES = ["rc4", "aes256", "aes128", "3des"]
117 MAC_NAMES = ["sha"] # "md5" is allowed
118 +KEY_EXCHANGE_NAMES = ["rsa", "dhe_rsa", "srp_sha", "srp_sha_rsa", "dh_anon"]
119 CIPHER_IMPLEMENTATIONS = ["openssl", "pycrypto", "python"]
120 CERTIFICATE_TYPES = ["x509"]
121
122 @@ -100,6 +101,7 @@ class HandshakeSettings(object):
123 def __init__(self):
124 self.minKeySize = 1023
125 self.maxKeySize = 8193
126 + self.keyExchangeNames = KEY_EXCHANGE_NAMES
127 self.cipherNames = CIPHER_NAMES
128 self.macNames = MAC_NAMES
129 self.cipherImplementations = CIPHER_IMPLEMENTATIONS
130 @@ -114,6 +116,7 @@ class HandshakeSettings(object):
131 other = HandshakeSettings()
132 other.minKeySize = self.minKeySize
133 other.maxKeySize = self.maxKeySize
134 + other.keyExchangeNames = self.keyExchangeNames
135 other.cipherNames = self.cipherNames
136 other.macNames = self.macNames
137 other.cipherImplementations = self.cipherImplementations
138 @@ -145,6 +148,9 @@ class HandshakeSettings(object):
139 raise ValueError("maxKeySize too small")
140 if other.maxKeySize>16384:
141 raise ValueError("maxKeySize too large")
142 + for s in other.keyExchangeNames:
143 + if s not in KEY_EXCHANGE_NAMES:
144 + raise ValueError("Unknown key exchange name: '%s'" % s)
145 for s in other.cipherNames:
146 if s not in CIPHER_NAMES:
147 raise ValueError("Unknown cipher name: '%s'" % s)
148 diff --git a/third_party/tlslite/tlslite/messages.py b/third_party/tlslite/tlsli te/messages.py
149 index 532d86b..550b387 100644
150 --- a/third_party/tlslite/tlslite/messages.py
151 +++ b/third_party/tlslite/tlslite/messages.py
152 @@ -533,31 +533,31 @@ class ServerKeyExchange(HandshakeMsg):
153 p.stopLengthCheck()
154 return self
155
156 - def write(self):
157 + def write_params(self):
158 w = Writer()
159 if self.cipherSuite in CipherSuite.srpAllSuites:
160 w.addVarSeq(numberToByteArray(self.srp_N), 1, 2)
161 w.addVarSeq(numberToByteArray(self.srp_g), 1, 2)
162 w.addVarSeq(self.srp_s, 1, 1)
163 w.addVarSeq(numberToByteArray(self.srp_B), 1, 2)
164 - if self.cipherSuite in CipherSuite.srpCertSuites:
165 - w.addVarSeq(self.signature, 1, 2)
166 - elif self.cipherSuite in CipherSuite.anonSuites:
167 + elif self.cipherSuite in CipherSuite.dhAllSuites:
168 w.addVarSeq(numberToByteArray(self.dh_p), 1, 2)
169 w.addVarSeq(numberToByteArray(self.dh_g), 1, 2)
170 w.addVarSeq(numberToByteArray(self.dh_Ys), 1, 2)
171 - if self.cipherSuite in []: # TODO support for signed_params
172 - w.addVarSeq(self.signature, 1, 2)
173 + else:
174 + assert(False)
175 + return w.bytes
176 +
177 + def write(self):
178 + w = Writer()
179 + w.bytes += self.write_params()
180 + if self.cipherSuite in CipherSuite.certAllSuites:
181 + w.addVarSeq(self.signature, 1, 2)
182 return self.postWrite(w)
183
184 def hash(self, clientRandom, serverRandom):
185 - oldCipherSuite = self.cipherSuite
186 - self.cipherSuite = None
187 - try:
188 - bytes = clientRandom + serverRandom + self.write()[4:]
189 - return MD5(bytes) + SHA1(bytes)
190 - finally:
191 - self.cipherSuite = oldCipherSuite
192 + bytes = clientRandom + serverRandom + self.write_params()
193 + return MD5(bytes) + SHA1(bytes)
194
195 class ServerHelloDone(HandshakeMsg):
196 def __init__(self):
197 @@ -607,7 +607,7 @@ class ClientKeyExchange(HandshakeMsg):
198 p.getFixBytes(len(p.bytes)-p.index)
199 else:
200 raise AssertionError()
201 - elif self.cipherSuite in CipherSuite.anonSuites:
202 + elif self.cipherSuite in CipherSuite.dhAllSuites:
203 self.dh_Yc = bytesToNumber(p.getVarBytes(2))
204 else:
205 raise AssertionError()
206 diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/ tlslite/tlsconnection.py
207 index 20cd85b..07ee862 100644
208 --- a/third_party/tlslite/tlslite/tlsconnection.py
209 +++ b/third_party/tlslite/tlslite/tlsconnection.py
210 @@ -24,6 +24,78 @@ from .handshakesettings import HandshakeSettings
211 from .utils.tackwrapper import *
212
213
214 +class KeyExchange(object):
215 + def __init__(self, cipherSuite, clientHello, serverHello, privateKey):
216 + self.cipherSuite = cipherSuite
217 + self.clientHello = clientHello
218 + self.serverHello = serverHello
219 + self.privateKey = privateKey
220 +
221 + def makeServerKeyExchange():
222 + raise NotImplementedError()
223 + def processClientKeyExchange(clientKeyExchange):
224 + raise NotImplementedError()
225 +
226 +
227 +class RSAKeyExchange(KeyExchange):
228 + def makeServerKeyExchange(self):
229 + return None
230 +
231 + def processClientKeyExchange(self, clientKeyExchange):
232 + premasterSecret = self.privateKey.decrypt(\
233 + clientKeyExchange.encryptedPreMasterSecret)
234 +
235 + # On decryption failure randomize premaster secret to avoid
236 + # Bleichenbacher's "million message" attack
237 + randomPreMasterSecret = getRandomBytes(48)
238 + versionCheck = (premasterSecret[0], premasterSecret[1])
239 + if not premasterSecret:
240 + premasterSecret = randomPreMasterSecret
241 + elif len(premasterSecret)!=48:
242 + premasterSecret = randomPreMasterSecret
243 + elif versionCheck != self.clientHello.client_version:
244 + #Tolerate buggy IE clients
245 + if versionCheck != self.serverHello.server_version:
246 + premasterSecret = randomPreMasterSecret
247 + return premasterSecret
248 +
249 +class DHE_RSAKeyExchange(KeyExchange):
250 + # Generated with openssl dhparam 1024 -text. Generating a new one each time
251 + # in Python is far far far too slow.
252 + dh_p = bytesToNumber(
253 + bytearray(
254 + "\x00\x88\xc4\xdc\x2a\xd9\xba\x8d\x24\x69\x7f\xe4\xd4\xeb\x62"
255 + "\x04\x43\xe8\x31\x08\x30\xa8\xe4\x24\x0f\xa7\xc3\xff\x84\x52"
256 + "\x44\x4a\x1b\x8c\x88\x16\xa6\x17\x90\xac\x21\x34\xfb\xc5\xff"
257 + "\x90\x46\x32\x29\xfa\x9d\xd3\x36\x05\xc2\x86\xcf\xde\x77\x68"
258 + "\x4c\xe3\xb0\x34\x55\xce\x27\x85\x46\x94\xad\x0c\xef\x11\x53"
259 + "\x61\x50\x0c\x3e\x7b\x8a\x3c\xa0\x52\x6c\xb2\xa5\x84\xf7\xa9"
260 + "\xdc\x9d\x57\x60\xd0\x89\xc6\x14\x39\x54\xce\x20\xcc\x2d\xe9"
261 + "\x90\xeb\xe7\x42\xf1\x03\x60\x5b\x06\x2f\x51\x97\x01\xc2\x1d"
262 + "\xfa\xb3\xfe\x02\x4b\xee\xd1\x65\xcb"))
263 + dh_g = 2
264 +
265 + def makeServerKeyExchange(self):
266 + self.dh_Xs = bytesToNumber(getRandomBytes(1024 / 8))
267 + dh_Ys = powMod(self.dh_g, self.dh_Xs, self.dh_p)
268 +
269 + serverKeyExchange = ServerKeyExchange(self.cipherSuite)
270 + serverKeyExchange.createDH(self.dh_p, self.dh_g, dh_Ys)
271 + serverKeyExchange.signature = self.privateKey.sign(
272 + serverKeyExchange.hash(self.clientHello.random,
273 + self.serverHello.random))
274 + return serverKeyExchange
275 +
276 + def processClientKeyExchange(self, clientKeyExchange):
277 + dh_Yc = clientKeyExchange.dh_Yc
278 +
279 + if dh_Yc % self.dh_p == 0:
280 + raise TLSLocalAlert(AlertDescription.illegal_parameter,
281 + "Suspicious dh_Yc value")
282 +
283 + S = powMod(dh_Yc, self.dh_Xs, self.dh_p)
284 + return numberToByteArray(S)
285 +
286 class TLSConnection(TLSRecordLayer):
287 """
288 This class wraps a socket and provides TLS handshaking and data
289 @@ -500,6 +572,8 @@ class TLSConnection(TLSRecordLayer):
290 cipherSuites += CipherSuite.getSrpAllSuites(settings)
291 elif certParams:
292 cipherSuites += CipherSuite.getCertSuites(settings)
293 + # Client DHE_RSA not supported.
294 + # cipherSuites += CipherSuite.getDheCertSuites(settings)
295 elif anonParams:
296 cipherSuites += CipherSuite.getAnonSuites(settings)
297 else:
298 @@ -1205,9 +1279,22 @@ class TLSConnection(TLSRecordLayer):
299 premasterSecret = result
300
301 # Perform the RSA key exchange
302 - elif cipherSuite in CipherSuite.certSuites:
303 + elif (cipherSuite in CipherSuite.certSuites or
304 + cipherSuite in CipherSuite.dheCertSuites):
305 + if cipherSuite in CipherSuite.certSuites:
306 + keyExchange = RSAKeyExchange(cipherSuite,
307 + clientHello,
308 + serverHello,
309 + privateKey)
310 + elif cipherSuite in CipherSuite.dheCertSuites:
311 + keyExchange = DHE_RSAKeyExchange(cipherSuite,
312 + clientHello,
313 + serverHello,
314 + privateKey)
315 + else:
316 + assert(False)
317 for result in self._serverCertKeyExchange(clientHello, serverHello,
318 - certChain, privateKey,
319 + certChain, keyExchange,
320 reqCert, reqCAs, cipherSuite,
321 settings, ocspResponse):
322 if result in (0,1): yield result
323 @@ -1268,6 +1355,7 @@ class TLSConnection(TLSRecordLayer):
324 cipherSuites += CipherSuite.getSrpSuites(settings)
325 elif certChain:
326 cipherSuites += CipherSuite.getCertSuites(settings)
327 + cipherSuites += CipherSuite.getDheCertSuites(settings)
328 elif anon:
329 cipherSuites += CipherSuite.getAnonSuites(settings)
330 else:
331 @@ -1483,7 +1571,7 @@ class TLSConnection(TLSRecordLayer):
332
333
334 def _serverCertKeyExchange(self, clientHello, serverHello,
335 - serverCertChain, privateKey,
336 + serverCertChain, keyExchange,
337 reqCert, reqCAs, cipherSuite,
338 settings, ocspResponse):
339 #Send ServerHello, Certificate[, CertificateRequest],
340 @@ -1497,6 +1585,9 @@ class TLSConnection(TLSRecordLayer):
341 msgs.append(Certificate(CertificateType.x509).create(serverCertChain))
342 if serverHello.status_request:
343 msgs.append(CertificateStatus().create(ocspResponse))
344 + serverKeyExchange = keyExchange.makeServerKeyExchange()
345 + if serverKeyExchange is not None:
346 + msgs.append(serverKeyExchange)
347 if reqCert and reqCAs:
348 msgs.append(CertificateRequest().create(\
349 [ClientCertificateType.rsa_sign], reqCAs))
350 @@ -1555,21 +1646,13 @@ class TLSConnection(TLSRecordLayer):
351 else: break
352 clientKeyExchange = result
353
354 - #Decrypt ClientKeyExchange
355 - premasterSecret = privateKey.decrypt(\
356 - clientKeyExchange.encryptedPreMasterSecret)
357 -
358 - # On decryption failure randomize premaster secret to avoid
359 - # Bleichenbacher's "million message" attack
360 - randomPreMasterSecret = getRandomBytes(48)
361 - versionCheck = (premasterSecret[0], premasterSecret[1])
362 - if not premasterSecret:
363 - premasterSecret = randomPreMasterSecret
364 - elif len(premasterSecret)!=48:
365 - premasterSecret = randomPreMasterSecret
366 - elif versionCheck != clientHello.client_version:
367 - if versionCheck != self.version: #Tolerate buggy IE clients
368 - premasterSecret = randomPreMasterSecret
369 + #Process ClientKeyExchange
370 + try:
371 + premasterSecret = \
372 + keyExchange.processClientKeyExchange(clientKeyExchange)
373 + except TLSLocalAlert, e:
374 + for result in self._sendError(alert.description, alert.message):
375 + yield result
376
377 #Get and check CertificateVerify, if relevant
378 if clientCertChain:
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698