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

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: Update patch. 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
« no previous file with comments | « third_party/tlslite/README.chromium ('k') | third_party/tlslite/tlslite/constants.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..e0bc0e6 100644
112 --- a/third_party/tlslite/tlslite/handshakesettings.py
113 +++ b/third_party/tlslite/tlslite/handshakesettings.py
114 @@ -13,7 +13,9 @@ from .utils import cipherfactory
115 # RC4 is preferred as faster in Python, works in SSL3, and immune to CBC
116 # issues such as timing attacks
117 CIPHER_NAMES = ["rc4", "aes256", "aes128", "3des"]
118 -MAC_NAMES = ["sha"] # "md5" is allowed
119 +MAC_NAMES = ["sha"] # Don't allow "md5" by default.
120 +ALL_MAC_NAMES = ["sha", "md5"]
121 +KEY_EXCHANGE_NAMES = ["rsa", "dhe_rsa", "srp_sha", "srp_sha_rsa", "dh_anon"]
122 CIPHER_IMPLEMENTATIONS = ["openssl", "pycrypto", "python"]
123 CERTIFICATE_TYPES = ["x509"]
124
125 @@ -102,6 +104,7 @@ class HandshakeSettings(object):
126 self.maxKeySize = 8193
127 self.cipherNames = CIPHER_NAMES
128 self.macNames = MAC_NAMES
129 + self.keyExchangeNames = KEY_EXCHANGE_NAMES
130 self.cipherImplementations = CIPHER_IMPLEMENTATIONS
131 self.certificateTypes = CERTIFICATE_TYPES
132 self.minVersion = (3,0)
133 @@ -116,6 +119,7 @@ class HandshakeSettings(object):
134 other.maxKeySize = self.maxKeySize
135 other.cipherNames = self.cipherNames
136 other.macNames = self.macNames
137 + other.keyExchangeNames = self.keyExchangeNames
138 other.cipherImplementations = self.cipherImplementations
139 other.certificateTypes = self.certificateTypes
140 other.minVersion = self.minVersion
141 @@ -148,6 +152,12 @@ class HandshakeSettings(object):
142 for s in other.cipherNames:
143 if s not in CIPHER_NAMES:
144 raise ValueError("Unknown cipher name: '%s'" % s)
145 + for s in other.macNames:
146 + if s not in ALL_MAC_NAMES:
147 + raise ValueError("Unknown MAC name: '%s'" % s)
148 + for s in other.keyExchangeNames:
149 + if s not in KEY_EXCHANGE_NAMES:
150 + raise ValueError("Unknown key exchange name: '%s'" % s)
151 for s in other.cipherImplementations:
152 if s not in CIPHER_IMPLEMENTATIONS:
153 raise ValueError("Unknown cipher implementation: '%s'" % s)
154 diff --git a/third_party/tlslite/tlslite/messages.py b/third_party/tlslite/tlsli te/messages.py
155 index 532d86b..550b387 100644
156 --- a/third_party/tlslite/tlslite/messages.py
157 +++ b/third_party/tlslite/tlslite/messages.py
158 @@ -533,31 +533,31 @@ class ServerKeyExchange(HandshakeMsg):
159 p.stopLengthCheck()
160 return self
161
162 - def write(self):
163 + def write_params(self):
164 w = Writer()
165 if self.cipherSuite in CipherSuite.srpAllSuites:
166 w.addVarSeq(numberToByteArray(self.srp_N), 1, 2)
167 w.addVarSeq(numberToByteArray(self.srp_g), 1, 2)
168 w.addVarSeq(self.srp_s, 1, 1)
169 w.addVarSeq(numberToByteArray(self.srp_B), 1, 2)
170 - if self.cipherSuite in CipherSuite.srpCertSuites:
171 - w.addVarSeq(self.signature, 1, 2)
172 - elif self.cipherSuite in CipherSuite.anonSuites:
173 + elif self.cipherSuite in CipherSuite.dhAllSuites:
174 w.addVarSeq(numberToByteArray(self.dh_p), 1, 2)
175 w.addVarSeq(numberToByteArray(self.dh_g), 1, 2)
176 w.addVarSeq(numberToByteArray(self.dh_Ys), 1, 2)
177 - if self.cipherSuite in []: # TODO support for signed_params
178 - w.addVarSeq(self.signature, 1, 2)
179 + else:
180 + assert(False)
181 + return w.bytes
182 +
183 + def write(self):
184 + w = Writer()
185 + w.bytes += self.write_params()
186 + if self.cipherSuite in CipherSuite.certAllSuites:
187 + w.addVarSeq(self.signature, 1, 2)
188 return self.postWrite(w)
189
190 def hash(self, clientRandom, serverRandom):
191 - oldCipherSuite = self.cipherSuite
192 - self.cipherSuite = None
193 - try:
194 - bytes = clientRandom + serverRandom + self.write()[4:]
195 - return MD5(bytes) + SHA1(bytes)
196 - finally:
197 - self.cipherSuite = oldCipherSuite
198 + bytes = clientRandom + serverRandom + self.write_params()
199 + return MD5(bytes) + SHA1(bytes)
200
201 class ServerHelloDone(HandshakeMsg):
202 def __init__(self):
203 @@ -607,7 +607,7 @@ class ClientKeyExchange(HandshakeMsg):
204 p.getFixBytes(len(p.bytes)-p.index)
205 else:
206 raise AssertionError()
207 - elif self.cipherSuite in CipherSuite.anonSuites:
208 + elif self.cipherSuite in CipherSuite.dhAllSuites:
209 self.dh_Yc = bytesToNumber(p.getVarBytes(2))
210 else:
211 raise AssertionError()
212 diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/ tlslite/tlsconnection.py
213 index 20cd85b..e6f7820 100644
214 --- a/third_party/tlslite/tlslite/tlsconnection.py
215 +++ b/third_party/tlslite/tlslite/tlsconnection.py
216 @@ -23,6 +23,103 @@ from .mathtls import *
217 from .handshakesettings import HandshakeSettings
218 from .utils.tackwrapper import *
219
220 +class KeyExchange(object):
221 + def __init__(self, cipherSuite, clientHello, serverHello, privateKey):
222 + """
223 + Initializes the KeyExchange. privateKey is the signing private key.
224 + """
225 + self.cipherSuite = cipherSuite
226 + self.clientHello = clientHello
227 + self.serverHello = serverHello
228 + self.privateKey = privateKey
229 +
230 + def makeServerKeyExchange():
231 + """
232 + Returns a ServerKeyExchange object for the server's initial leg in the
233 + handshake. If the key exchange method does not send ServerKeyExchange
234 + (e.g. RSA), it returns None.
235 + """
236 + raise NotImplementedError()
237 +
238 + def processClientKeyExchange(clientKeyExchange):
239 + """
240 + Processes the client's ClientKeyExchange message and returns the
241 + premaster secret. Raises TLSLocalAlert on error.
242 + """
243 + raise NotImplementedError()
244 +
245 +class RSAKeyExchange(KeyExchange):
246 + def makeServerKeyExchange(self):
247 + return None
248 +
249 + def processClientKeyExchange(self, clientKeyExchange):
250 + premasterSecret = self.privateKey.decrypt(\
251 + clientKeyExchange.encryptedPreMasterSecret)
252 +
253 + # On decryption failure randomize premaster secret to avoid
254 + # Bleichenbacher's "million message" attack
255 + randomPreMasterSecret = getRandomBytes(48)
256 + if not premasterSecret:
257 + premasterSecret = randomPreMasterSecret
258 + elif len(premasterSecret)!=48:
259 + premasterSecret = randomPreMasterSecret
260 + else:
261 + versionCheck = (premasterSecret[0], premasterSecret[1])
262 + if versionCheck != self.clientHello.client_version:
263 + #Tolerate buggy IE clients
264 + if versionCheck != self.serverHello.server_version:
265 + premasterSecret = randomPreMasterSecret
266 + return premasterSecret
267 +
268 +def _hexStringToNumber(s):
269 + s = s.replace(" ", "").replace("\n", "")
270 + if len(s) % 2 != 0:
271 + raise ValueError("Length is not even")
272 + return bytesToNumber(bytearray(s.decode("hex")))
273 +
274 +class DHE_RSAKeyExchange(KeyExchange):
275 + # 2048-bit MODP Group (RFC 3526, Section 3)
276 + dh_p = _hexStringToNumber("""
277 +FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1
278 +29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD
279 +EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245
280 +E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED
281 +EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D
282 +C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F
283 +83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D
284 +670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B
285 +E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9
286 +DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510
287 +15728E5A 8AACAA68 FFFFFFFF FFFFFFFF""")
288 + dh_g = 2
289 +
290 + # RFC 3526, Section 8.
291 + strength = 160
292 +
293 + def makeServerKeyExchange(self):
294 + # Per RFC 3526, Section 1, the exponent should have double the entropy
295 + # of the strength of the curve.
296 + self.dh_Xs = bytesToNumber(getRandomBytes(self.strength * 2 / 8))
297 + dh_Ys = powMod(self.dh_g, self.dh_Xs, self.dh_p)
298 +
299 + serverKeyExchange = ServerKeyExchange(self.cipherSuite)
300 + serverKeyExchange.createDH(self.dh_p, self.dh_g, dh_Ys)
301 + serverKeyExchange.signature = self.privateKey.sign(
302 + serverKeyExchange.hash(self.clientHello.random,
303 + self.serverHello.random))
304 + return serverKeyExchange
305 +
306 + def processClientKeyExchange(self, clientKeyExchange):
307 + dh_Yc = clientKeyExchange.dh_Yc
308 +
309 + # First half of RFC 2631, Section 2.1.5. Validate the client's public
310 + # key.
311 + if not 2 <= dh_Yc <= self.dh_p - 1:
312 + raise TLSLocalAlert(AlertDescription.illegal_parameter,
313 + "Invalid dh_Yc value")
314 +
315 + S = powMod(dh_Yc, self.dh_Xs, self.dh_p)
316 + return numberToByteArray(S)
317
318 class TLSConnection(TLSRecordLayer):
319 """
320 @@ -500,6 +597,8 @@ class TLSConnection(TLSRecordLayer):
321 cipherSuites += CipherSuite.getSrpAllSuites(settings)
322 elif certParams:
323 cipherSuites += CipherSuite.getCertSuites(settings)
324 + # TODO: Client DHE_RSA not supported.
325 + # cipherSuites += CipherSuite.getDheCertSuites(settings)
326 elif anonParams:
327 cipherSuites += CipherSuite.getAnonSuites(settings)
328 else:
329 @@ -1204,10 +1303,23 @@ class TLSConnection(TLSRecordLayer):
330 else: break
331 premasterSecret = result
332
333 - # Perform the RSA key exchange
334 - elif cipherSuite in CipherSuite.certSuites:
335 + # Perform the RSA or DHE_RSA key exchange
336 + elif (cipherSuite in CipherSuite.certSuites or
337 + cipherSuite in CipherSuite.dheCertSuites):
338 + if cipherSuite in CipherSuite.certSuites:
339 + keyExchange = RSAKeyExchange(cipherSuite,
340 + clientHello,
341 + serverHello,
342 + privateKey)
343 + elif cipherSuite in CipherSuite.dheCertSuites:
344 + keyExchange = DHE_RSAKeyExchange(cipherSuite,
345 + clientHello,
346 + serverHello,
347 + privateKey)
348 + else:
349 + assert(False)
350 for result in self._serverCertKeyExchange(clientHello, serverHello,
351 - certChain, privateKey,
352 + certChain, keyExchange,
353 reqCert, reqCAs, cipherSuite,
354 settings, ocspResponse):
355 if result in (0,1): yield result
356 @@ -1268,6 +1380,7 @@ class TLSConnection(TLSRecordLayer):
357 cipherSuites += CipherSuite.getSrpSuites(settings)
358 elif certChain:
359 cipherSuites += CipherSuite.getCertSuites(settings)
360 + cipherSuites += CipherSuite.getDheCertSuites(settings)
361 elif anon:
362 cipherSuites += CipherSuite.getAnonSuites(settings)
363 else:
364 @@ -1483,11 +1596,11 @@ class TLSConnection(TLSRecordLayer):
365
366
367 def _serverCertKeyExchange(self, clientHello, serverHello,
368 - serverCertChain, privateKey,
369 + serverCertChain, keyExchange,
370 reqCert, reqCAs, cipherSuite,
371 settings, ocspResponse):
372 - #Send ServerHello, Certificate[, CertificateRequest],
373 - #ServerHelloDone
374 + #Send ServerHello, Certificate[, ServerKeyExchange]
375 + #[, CertificateRequest], ServerHelloDone
376 msgs = []
377
378 # If we verify a client cert chain, return it
379 @@ -1497,6 +1610,9 @@ class TLSConnection(TLSRecordLayer):
380 msgs.append(Certificate(CertificateType.x509).create(serverCertChain))
381 if serverHello.status_request:
382 msgs.append(CertificateStatus().create(ocspResponse))
383 + serverKeyExchange = keyExchange.makeServerKeyExchange()
384 + if serverKeyExchange is not None:
385 + msgs.append(serverKeyExchange)
386 if reqCert and reqCAs:
387 msgs.append(CertificateRequest().create(\
388 [ClientCertificateType.rsa_sign], reqCAs))
389 @@ -1555,21 +1671,13 @@ class TLSConnection(TLSRecordLayer):
390 else: break
391 clientKeyExchange = result
392
393 - #Decrypt ClientKeyExchange
394 - premasterSecret = privateKey.decrypt(\
395 - clientKeyExchange.encryptedPreMasterSecret)
396 -
397 - # On decryption failure randomize premaster secret to avoid
398 - # Bleichenbacher's "million message" attack
399 - randomPreMasterSecret = getRandomBytes(48)
400 - versionCheck = (premasterSecret[0], premasterSecret[1])
401 - if not premasterSecret:
402 - premasterSecret = randomPreMasterSecret
403 - elif len(premasterSecret)!=48:
404 - premasterSecret = randomPreMasterSecret
405 - elif versionCheck != clientHello.client_version:
406 - if versionCheck != self.version: #Tolerate buggy IE clients
407 - premasterSecret = randomPreMasterSecret
408 + #Process ClientKeyExchange
409 + try:
410 + premasterSecret = \
411 + keyExchange.processClientKeyExchange(clientKeyExchange)
412 + except TLSLocalAlert, alert:
413 + for result in self._sendError(alert.description, alert.message):
414 + yield result
415
416 #Get and check CertificateVerify, if relevant
417 if clientCertChain:
OLDNEW
« no previous file with comments | « third_party/tlslite/README.chromium ('k') | third_party/tlslite/tlslite/constants.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698