1diff --git a/third_party/tlslite/tlslite/constants.py b/third_party/tlslite/tlslite/constants.py
2index 1a1ace9..d2d50c5 100644
3--- a/third_party/tlslite/tlslite/constants.py
4+++ b/third_party/tlslite/tlslite/constants.py
5@@ -54,6 +54,20 @@ class ExtensionType:    # RFC 6066 / 4366
6     tack = 0xF300
7     supports_npn = 13172
8     channel_id = 30032
9+
10+class HashAlgorithm:
11+    none = 0
12+    md5 = 1
13+    sha1 = 2
14+    sha224 = 3
15+    sha256 = 4
16+    sha384 = 5
17+
18+class SignatureAlgorithm:
19+    anonymous = 0
20+    rsa = 1
21+    dsa = 2
22+    ecdsa = 3
23
24 class NameType:
25     host_name = 0
26@@ -144,30 +158,42 @@ class CipherSuite:
27
28     TLS_RSA_WITH_RC4_128_MD5 = 0x0004
29
30+    TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x0016
31+    TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033
32+    TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039
33+
34     TLS_DH_ANON_WITH_AES_128_CBC_SHA = 0x0034
35     TLS_DH_ANON_WITH_AES_256_CBC_SHA = 0x003A
36
37     TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C
38     TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D
39
40+    TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067
41+    TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B
42+
43     tripleDESSuites = []
44     tripleDESSuites.append(TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA)
45     tripleDESSuites.append(TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA)
46     tripleDESSuites.append(TLS_RSA_WITH_3DES_EDE_CBC_SHA)
47+    tripleDESSuites.append(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA)
48
49     aes128Suites = []
50     aes128Suites.append(TLS_SRP_SHA_WITH_AES_128_CBC_SHA)
51     aes128Suites.append(TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA)
52     aes128Suites.append(TLS_RSA_WITH_AES_128_CBC_SHA)
53+    aes128Suites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA)
54     aes128Suites.append(TLS_DH_ANON_WITH_AES_128_CBC_SHA)
55     aes128Suites.append(TLS_RSA_WITH_AES_128_CBC_SHA256)
56+    aes128Suites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256)
57
58     aes256Suites = []
59     aes256Suites.append(TLS_SRP_SHA_WITH_AES_256_CBC_SHA)
60     aes256Suites.append(TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA)
61     aes256Suites.append(TLS_RSA_WITH_AES_256_CBC_SHA)
62     aes256Suites.append(TLS_DH_ANON_WITH_AES_256_CBC_SHA)
63+    aes256Suites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA)
64     aes256Suites.append(TLS_RSA_WITH_AES_256_CBC_SHA256)
65+    aes256Suites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256)
66
67     rc4Suites = []
68     rc4Suites.append(TLS_RSA_WITH_RC4_128_SHA)
69@@ -184,12 +210,18 @@ class CipherSuite:
70     shaSuites.append(TLS_RSA_WITH_AES_128_CBC_SHA)
71     shaSuites.append(TLS_RSA_WITH_AES_256_CBC_SHA)
72     shaSuites.append(TLS_RSA_WITH_RC4_128_SHA)
73+    shaSuites.append(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA)
74+    shaSuites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA)
75+    shaSuites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA)
76     shaSuites.append(TLS_DH_ANON_WITH_AES_128_CBC_SHA)
77     shaSuites.append(TLS_DH_ANON_WITH_AES_256_CBC_SHA)
78
79     sha256Suites = []
80     sha256Suites.append(TLS_RSA_WITH_AES_128_CBC_SHA256)
81     sha256Suites.append(TLS_RSA_WITH_AES_256_CBC_SHA256)
82+    sha256Suites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256)
83+    sha256Suites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256)
84+
85
86     md5Suites = []
87     md5Suites.append(TLS_RSA_WITH_RC4_128_MD5)
88@@ -198,6 +230,7 @@ class CipherSuite:
89     def _filterSuites(suites, settings):
90         macNames = settings.macNames
91         cipherNames = settings.cipherNames
92+        keyExchangeNames = settings.keyExchangeNames
93         macSuites = []
94         if "sha" in macNames:
95             macSuites += CipherSuite.shaSuites
96@@ -216,7 +249,20 @@ class CipherSuite:
97         if "rc4" in cipherNames:
98             cipherSuites += CipherSuite.rc4Suites
99
100-        return [s for s in suites if s in macSuites and s in cipherSuites]
101+        keyExchangeSuites = []
102+        if "rsa" in keyExchangeNames:
103+            keyExchangeSuites += CipherSuite.certSuites
104+        if "dhe_rsa" in keyExchangeNames:
105+            keyExchangeSuites += CipherSuite.dheCertSuites
106+        if "srp_sha" in keyExchangeNames:
107+            keyExchangeSuites += CipherSuite.srpSuites
108+        if "srp_sha_rsa" in keyExchangeNames:
109+            keyExchangeSuites += CipherSuite.srpCertSuites
110+        if "dh_anon" in keyExchangeNames:
111+            keyExchangeSuites += CipherSuite.anonSuites
112+
113+        return [s for s in suites if s in macSuites and
114+                s in cipherSuites and s in keyExchangeSuites]
115
116     srpSuites = []
117     srpSuites.append(TLS_SRP_SHA_WITH_AES_256_CBC_SHA)
118@@ -250,12 +296,24 @@ class CipherSuite:
119     certSuites.append(TLS_RSA_WITH_3DES_EDE_CBC_SHA)
120     certSuites.append(TLS_RSA_WITH_RC4_128_SHA)
121     certSuites.append(TLS_RSA_WITH_RC4_128_MD5)
122-    certAllSuites = srpCertSuites + certSuites
123
124     @staticmethod
125     def getCertSuites(settings):
126         return CipherSuite._filterSuites(CipherSuite.certSuites, settings)
127
128+    dheCertSuites = []
129+    dheCertSuites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256)
130+    dheCertSuites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256)
131+    dheCertSuites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA)
132+    dheCertSuites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA)
133+    dheCertSuites.append(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA)
134+
135+    @staticmethod
136+    def getDheCertSuites(settings):
137+        return CipherSuite._filterSuites(CipherSuite.dheCertSuites, settings)
138+
139+    certAllSuites = srpCertSuites + certSuites + dheCertSuites
140+
141     anonSuites = []
142     anonSuites.append(TLS_DH_ANON_WITH_AES_256_CBC_SHA)
143     anonSuites.append(TLS_DH_ANON_WITH_AES_128_CBC_SHA)
144@@ -264,6 +322,8 @@ class CipherSuite:
145     def getAnonSuites(settings):
146         return CipherSuite._filterSuites(CipherSuite.anonSuites, settings)
147
148+    dhAllSuites = dheCertSuites + anonSuites
149+
150     @staticmethod
151     def canonicalCipherName(ciphersuite):
152         "Return the canonical name of the cipher whose number is provided."
153diff --git a/third_party/tlslite/tlslite/handshakesettings.py b/third_party/tlslite/tlslite/handshakesettings.py
154index ee37c30..7998e2e 100644
155--- a/third_party/tlslite/tlslite/handshakesettings.py
156+++ b/third_party/tlslite/tlslite/handshakesettings.py
157@@ -14,7 +14,9 @@ from .utils import cipherfactory
158 # RC4 is preferred as faster in Python, works in SSL3, and immune to CBC
159 # issues such as timing attacks
160 CIPHER_NAMES = ["rc4", "aes256", "aes128", "3des"]
161-MAC_NAMES = ["sha", "sha256"] # "md5" is allowed
162+MAC_NAMES = ["sha", "sha256"] # Don't allow "md5" by default.
163+ALL_MAC_NAMES = ["sha", "sha256", "md5"]
164+KEY_EXCHANGE_NAMES = ["rsa", "dhe_rsa", "srp_sha", "srp_sha_rsa", "dh_anon"]
165 CIPHER_IMPLEMENTATIONS = ["openssl", "pycrypto", "python"]
166 CERTIFICATE_TYPES = ["x509"]
167
168@@ -101,6 +103,7 @@ class HandshakeSettings(object):
169         self.maxKeySize = 8193
170         self.cipherNames = CIPHER_NAMES
171         self.macNames = MAC_NAMES
172+        self.keyExchangeNames = KEY_EXCHANGE_NAMES
173         self.cipherImplementations = CIPHER_IMPLEMENTATIONS
174         self.certificateTypes = CERTIFICATE_TYPES
175         self.minVersion = (3,1)
176@@ -115,6 +118,7 @@ class HandshakeSettings(object):
177         other.maxKeySize = self.maxKeySize
178         other.cipherNames = self.cipherNames
179         other.macNames = self.macNames
180+        other.keyExchangeNames = self.keyExchangeNames
181         other.cipherImplementations = self.cipherImplementations
182         other.certificateTypes = self.certificateTypes
183         other.minVersion = self.minVersion
184@@ -147,6 +151,12 @@ class HandshakeSettings(object):
185         for s in other.cipherNames:
186             if s not in CIPHER_NAMES:
187                 raise ValueError("Unknown cipher name: '%s'" % s)
188+        for s in other.macNames:
189+            if s not in ALL_MAC_NAMES:
190+                raise ValueError("Unknown MAC name: '%s'" % s)
191+        for s in other.keyExchangeNames:
192+            if s not in KEY_EXCHANGE_NAMES:
193+                raise ValueError("Unknown key exchange name: '%s'" % s)
194         for s in other.cipherImplementations:
195             if s not in CIPHER_IMPLEMENTATIONS:
196                 raise ValueError("Unknown cipher implementation: '%s'" % s)
197diff --git a/third_party/tlslite/tlslite/messages.py b/third_party/tlslite/tlslite/messages.py
198index 9a8e5f6..8b77ee6 100644
199--- a/third_party/tlslite/tlslite/messages.py
200+++ b/third_party/tlslite/tlslite/messages.py
201@@ -500,9 +500,10 @@ class CertificateRequest(HandshakeMsg):
202         return self.postWrite(w)
203
204 class ServerKeyExchange(HandshakeMsg):
205-    def __init__(self, cipherSuite):
206+    def __init__(self, cipherSuite, version):
207         HandshakeMsg.__init__(self, HandshakeType.server_key_exchange)
208         self.cipherSuite = cipherSuite
209+        self.version = version
210         self.srp_N = 0
211         self.srp_g = 0
212         self.srp_s = bytearray(0)
213@@ -542,31 +543,38 @@ class ServerKeyExchange(HandshakeMsg):
214         p.stopLengthCheck()
215         return self
216
217-    def write(self):
218+    def write_params(self):
219         w = Writer()
220         if self.cipherSuite in CipherSuite.srpAllSuites:
221             w.addVarSeq(numberToByteArray(self.srp_N), 1, 2)
222             w.addVarSeq(numberToByteArray(self.srp_g), 1, 2)
223             w.addVarSeq(self.srp_s, 1, 1)
224             w.addVarSeq(numberToByteArray(self.srp_B), 1, 2)
225-            if self.cipherSuite in CipherSuite.srpCertSuites:
226-                w.addVarSeq(self.signature, 1, 2)
227-        elif self.cipherSuite in CipherSuite.anonSuites:
228+        elif self.cipherSuite in CipherSuite.dhAllSuites:
229             w.addVarSeq(numberToByteArray(self.dh_p), 1, 2)
230             w.addVarSeq(numberToByteArray(self.dh_g), 1, 2)
231             w.addVarSeq(numberToByteArray(self.dh_Ys), 1, 2)
232-            if self.cipherSuite in []: # TODO support for signed_params
233-                w.addVarSeq(self.signature, 1, 2)
234+        else:
235+            assert(False)
236+        return w.bytes
237+
238+    def write(self):
239+        w = Writer()
240+        w.bytes += self.write_params()
241+        if self.cipherSuite in CipherSuite.certAllSuites:
242+            if self.version >= (3,3):
243+                # TODO: Signature algorithm negotiation not supported.
244+                w.add(HashAlgorithm.sha1, 1)
245+                w.add(SignatureAlgorithm.rsa, 1)
246+            w.addVarSeq(self.signature, 1, 2)
247         return self.postWrite(w)
248
249     def hash(self, clientRandom, serverRandom):
250-        oldCipherSuite = self.cipherSuite
251-        self.cipherSuite = None
252-        try:
253-            bytes = clientRandom + serverRandom + self.write()[4:]
254-            return MD5(bytes) + SHA1(bytes)
255-        finally:
256-            self.cipherSuite = oldCipherSuite
257+        bytes = clientRandom + serverRandom + self.write_params()
258+        if self.version >= (3,3):
259+            # TODO: Signature algorithm negotiation not supported.
260+            return SHA1(bytes)
261+        return MD5(bytes) + SHA1(bytes)
262
263 class ServerHelloDone(HandshakeMsg):
264     def __init__(self):
265@@ -616,7 +624,7 @@ class ClientKeyExchange(HandshakeMsg):
266                     p.getFixBytes(len(p.bytes)-p.index)
267             else:
268                 raise AssertionError()
269-        elif self.cipherSuite in CipherSuite.anonSuites:
270+        elif self.cipherSuite in CipherSuite.dhAllSuites:
271             self.dh_Yc = bytesToNumber(p.getVarBytes(2))
272         else:
273             raise AssertionError()
274diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py
275index 5d508ed..f6d13d4 100644
276--- a/third_party/tlslite/tlslite/tlsconnection.py
277+++ b/third_party/tlslite/tlslite/tlsconnection.py
278@@ -23,7 +23,109 @@ from .messages import *
279 from .mathtls import *
280 from .handshakesettings import HandshakeSettings
281 from .utils.tackwrapper import *
282+from .utils.rsakey import RSAKey
283
284+class KeyExchange(object):
285+    def __init__(self, cipherSuite, clientHello, serverHello, privateKey):
286+        """
287+        Initializes the KeyExchange. privateKey is the signing private key.
288+        """
289+        self.cipherSuite = cipherSuite
290+        self.clientHello = clientHello
291+        self.serverHello = serverHello
292+        self.privateKey = privateKey
293+
294+    def makeServerKeyExchange():
295+        """
296+        Returns a ServerKeyExchange object for the server's initial leg in the
297+        handshake. If the key exchange method does not send ServerKeyExchange
298+        (e.g. RSA), it returns None.
299+        """
300+        raise NotImplementedError()
301+
302+    def processClientKeyExchange(clientKeyExchange):
303+        """
304+        Processes the client's ClientKeyExchange message and returns the
305+        premaster secret. Raises TLSLocalAlert on error.
306+        """
307+        raise NotImplementedError()
308+
309+class RSAKeyExchange(KeyExchange):
310+    def makeServerKeyExchange(self):
311+        return None
312+
313+    def processClientKeyExchange(self, clientKeyExchange):
314+        premasterSecret = self.privateKey.decrypt(\
315+            clientKeyExchange.encryptedPreMasterSecret)
316+
317+        # On decryption failure randomize premaster secret to avoid
318+        # Bleichenbacher's "million message" attack
319+        randomPreMasterSecret = getRandomBytes(48)
320+        if not premasterSecret:
321+            premasterSecret = randomPreMasterSecret
322+        elif len(premasterSecret)!=48:
323+            premasterSecret = randomPreMasterSecret
324+        else:
325+            versionCheck = (premasterSecret[0], premasterSecret[1])
326+            if versionCheck != self.clientHello.client_version:
327+                #Tolerate buggy IE clients
328+                if versionCheck != self.serverHello.server_version:
329+                    premasterSecret = randomPreMasterSecret
330+        return premasterSecret
331+
332+def _hexStringToNumber(s):
333+    s = s.replace(" ", "").replace("\n", "")
334+    if len(s) % 2 != 0:
335+        raise ValueError("Length is not even")
336+    return bytesToNumber(bytearray.fromhex(s))
337+
338+class DHE_RSAKeyExchange(KeyExchange):
339+    # 2048-bit MODP Group (RFC 3526, Section 3)
340+    dh_p = _hexStringToNumber("""
341+FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1
342+29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD
343+EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245
344+E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED
345+EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D
346+C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F
347+83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D
348+670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B
349+E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9
350+DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510
351+15728E5A 8AACAA68 FFFFFFFF FFFFFFFF""")
352+    dh_g = 2
353+
354+    # RFC 3526, Section 8.
355+    strength = 160
356+
357+    def makeServerKeyExchange(self):
358+        # Per RFC 3526, Section 1, the exponent should have double the entropy
359+        # of the strength of the curve.
360+        self.dh_Xs = bytesToNumber(getRandomBytes(self.strength * 2 / 8))
361+        dh_Ys = powMod(self.dh_g, self.dh_Xs, self.dh_p)
362+
363+        version = self.serverHello.server_version
364+        serverKeyExchange = ServerKeyExchange(self.cipherSuite, version)
365+        serverKeyExchange.createDH(self.dh_p, self.dh_g, dh_Ys)
366+        hashBytes = serverKeyExchange.hash(self.clientHello.random,
367+                                           self.serverHello.random)
368+        if version >= (3,3):
369+            # TODO: Signature algorithm negotiation not supported.
370+            hashBytes = RSAKey.addPKCS1SHA1Prefix(hashBytes)
371+        serverKeyExchange.signature = self.privateKey.sign(hashBytes)
372+        return serverKeyExchange
373+
374+    def processClientKeyExchange(self, clientKeyExchange):
375+        dh_Yc = clientKeyExchange.dh_Yc
376+
377+        # First half of RFC 2631, Section 2.1.5. Validate the client's public
378+        # key.
379+        if not 2 <= dh_Yc <= self.dh_p - 1:
380+            raise TLSLocalAlert(AlertDescription.illegal_parameter,
381+                                "Invalid dh_Yc value")
382+
383+        S = powMod(dh_Yc, self.dh_Xs, self.dh_p)
384+        return numberToByteArray(S)
385
386 class TLSConnection(TLSRecordLayer):
387     """
388@@ -500,6 +602,8 @@ class TLSConnection(TLSRecordLayer):
389         if srpParams:
390             cipherSuites += CipherSuite.getSrpAllSuites(settings)
391         elif certParams:
392+            # TODO: Client DHE_RSA not supported.
393+            # cipherSuites += CipherSuite.getDheCertSuites(settings)
394             cipherSuites += CipherSuite.getCertSuites(settings)
395         elif anonParams:
396             cipherSuites += CipherSuite.getAnonSuites(settings)
397@@ -1207,10 +1311,23 @@ class TLSConnection(TLSRecordLayer):
398                 else: break
399             premasterSecret = result
400
401-        # Perform the RSA key exchange
402-        elif cipherSuite in CipherSuite.certSuites:
403+        # Perform the RSA or DHE_RSA key exchange
404+        elif (cipherSuite in CipherSuite.certSuites or
405+              cipherSuite in CipherSuite.dheCertSuites):
406+            if cipherSuite in CipherSuite.certSuites:
407+                keyExchange = RSAKeyExchange(cipherSuite,
408+                                             clientHello,
409+                                             serverHello,
410+                                             privateKey)
411+            elif cipherSuite in CipherSuite.dheCertSuites:
412+                keyExchange = DHE_RSAKeyExchange(cipherSuite,
413+                                                 clientHello,
414+                                                 serverHello,
415+                                                 privateKey)
416+            else:
417+                assert(False)
418             for result in self._serverCertKeyExchange(clientHello, serverHello,
419-                                        certChain, privateKey,
420+                                        certChain, keyExchange,
421                                         reqCert, reqCAs, cipherSuite,
422                                         settings, ocspResponse):
423                 if result in (0,1): yield result
424@@ -1270,6 +1387,7 @@ class TLSConnection(TLSRecordLayer):
425                     CipherSuite.getSrpCertSuites(settings)
426             cipherSuites += CipherSuite.getSrpSuites(settings)
427         elif certChain:
428+            cipherSuites += CipherSuite.getDheCertSuites(settings)
429             cipherSuites += CipherSuite.getCertSuites(settings)
430         elif anon:
431             cipherSuites += CipherSuite.getAnonSuites(settings)
432@@ -1440,7 +1558,7 @@ class TLSConnection(TLSRecordLayer):
433         B = (powMod(g, b, N) + (k*v)) % N
434
435         #Create ServerKeyExchange, signing it if necessary
436-        serverKeyExchange = ServerKeyExchange(cipherSuite)
437+        serverKeyExchange = ServerKeyExchange(cipherSuite, self.version)
438         serverKeyExchange.createSRP(N, g, s, B)
439         if cipherSuite in CipherSuite.srpCertSuites:
440             hashBytes = serverKeyExchange.hash(clientHello.random,
441@@ -1488,11 +1606,11 @@ class TLSConnection(TLSRecordLayer):
442
443
444     def _serverCertKeyExchange(self, clientHello, serverHello,
445-                                serverCertChain, privateKey,
446+                                serverCertChain, keyExchange,
447                                 reqCert, reqCAs, cipherSuite,
448                                 settings, ocspResponse):
449-        #Send ServerHello, Certificate[, CertificateRequest],
450-        #ServerHelloDone
451+        #Send ServerHello, Certificate[, ServerKeyExchange]
452+        #[, CertificateRequest], ServerHelloDone
453         msgs = []
454
455         # If we verify a client cert chain, return it
456@@ -1502,6 +1620,9 @@ class TLSConnection(TLSRecordLayer):
457         msgs.append(Certificate(CertificateType.x509).create(serverCertChain))
458         if serverHello.status_request:
459             msgs.append(CertificateStatus().create(ocspResponse))
460+        serverKeyExchange = keyExchange.makeServerKeyExchange()
461+        if serverKeyExchange is not None:
462+            msgs.append(serverKeyExchange)
463         if reqCert and reqCAs:
464             msgs.append(CertificateRequest().create(\
465                 [ClientCertificateType.rsa_sign], reqCAs))
466@@ -1560,21 +1681,13 @@ class TLSConnection(TLSRecordLayer):
467             else: break
468         clientKeyExchange = result
469
470-        #Decrypt ClientKeyExchange
471-        premasterSecret = privateKey.decrypt(\
472-            clientKeyExchange.encryptedPreMasterSecret)
473-
474-        # On decryption failure randomize premaster secret to avoid
475-        # Bleichenbacher's "million message" attack
476-        randomPreMasterSecret = getRandomBytes(48)
477-        versionCheck = (premasterSecret[0], premasterSecret[1])
478-        if not premasterSecret:
479-            premasterSecret = randomPreMasterSecret
480-        elif len(premasterSecret)!=48:
481-            premasterSecret = randomPreMasterSecret
482-        elif versionCheck != clientHello.client_version:
483-            if versionCheck != self.version: #Tolerate buggy IE clients
484-                premasterSecret = randomPreMasterSecret
485+        #Process ClientKeyExchange
486+        try:
487+            premasterSecret = \
488+                keyExchange.processClientKeyExchange(clientKeyExchange)
489+        except alert as TLSLocalAlert:
490+            for result in self._sendError(alert.description, alert.message):
491+                yield result
492
493         #Get and check CertificateVerify, if relevant
494         if clientCertChain:
495@@ -1622,7 +1735,7 @@ class TLSConnection(TLSRecordLayer):
496         dh_Ys = powMod(dh_g, dh_Xs, dh_p)
497
498         #Create ServerKeyExchange
499-        serverKeyExchange = ServerKeyExchange(cipherSuite)
500+        serverKeyExchange = ServerKeyExchange(cipherSuite, self.version)
501         serverKeyExchange.createDH(dh_p, dh_g, dh_Ys)
502
503         #Send ServerHello[, Certificate], ServerKeyExchange,
504diff --git a/third_party/tlslite/tlslite/tlsrecordlayer.py b/third_party/tlslite/tlslite/tlsrecordlayer.py
505index 01ff3e9..6ef3895 100644
506--- a/third_party/tlslite/tlslite/tlsrecordlayer.py
507+++ b/third_party/tlslite/tlslite/tlsrecordlayer.py
508@@ -796,7 +796,8 @@ class TLSRecordLayer(object):
509                 elif subType == HandshakeType.certificate_verify:
510                     yield CertificateVerify().parse(p)
511                 elif subType == HandshakeType.server_key_exchange:
512-                    yield ServerKeyExchange(constructorType).parse(p)
513+                    yield ServerKeyExchange(constructorType,
514+                                            self.version).parse(p)
515                 elif subType == HandshakeType.server_hello_done:
516                     yield ServerHelloDone().parse(p)
517                 elif subType == HandshakeType.client_key_exchange:
518diff --git a/third_party/tlslite/tlslite/utils/rsakey.py b/third_party/tlslite/tlslite/utils/rsakey.py
519index 3f2100e..fb022cc 100644
520--- a/third_party/tlslite/tlslite/utils/rsakey.py
521+++ b/third_party/tlslite/tlslite/utils/rsakey.py
522@@ -60,7 +60,7 @@ class RSAKey(object):
523         @return: A PKCS1-SHA1 signature on the passed-in data.
524         """
525         hashBytes = SHA1(bytearray(bytes))
526-        prefixedHashBytes = self._addPKCS1SHA1Prefix(hashBytes)
527+        prefixedHashBytes = self.addPKCS1SHA1Prefix(hashBytes)
528         sigBytes = self.sign(prefixedHashBytes)
529         return sigBytes
530
531@@ -81,8 +81,8 @@ class RSAKey(object):
532         hashBytes = SHA1(bytearray(bytes))
533
534         # Try it with/without the embedded NULL
535-        prefixedHashBytes1 = self._addPKCS1SHA1Prefix(hashBytes, False)
536-        prefixedHashBytes2 = self._addPKCS1SHA1Prefix(hashBytes, True)
537+        prefixedHashBytes1 = self.addPKCS1SHA1Prefix(hashBytes, False)
538+        prefixedHashBytes2 = self.addPKCS1SHA1Prefix(hashBytes, True)
539         result1 = self.verify(sigBytes, prefixedHashBytes1)
540         result2 = self.verify(sigBytes, prefixedHashBytes2)
541         return (result1 or result2)
542@@ -221,7 +221,8 @@ class RSAKey(object):
543     # Helper Functions for RSA Keys
544     # **************************************************************************
545
546-    def _addPKCS1SHA1Prefix(self, bytes, withNULL=True):
547+    @staticmethod
548+    def addPKCS1SHA1Prefix(bytes, withNULL=True):
549         # There is a long history of confusion over whether the SHA1
550         # algorithmIdentifier should be encoded with a NULL parameter or
551         # with the parameter omitted.  While the original intention was
552@@ -229,8 +230,7 @@ class RSAKey(object):
553         # specifies the NULL should be included, and this behavior is also
554         # mandated in recent versions of PKCS #1, and is what tlslite has
555         # always implemented.  Anyways, verification code should probably
556-        # accept both.  However, nothing uses this code yet, so this is
557-        # all fairly moot.
558+        # accept both.
559         if not withNULL:
560             prefixBytes = bytearray(\
561             [0x30,0x1f,0x30,0x07,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x04,0x14])
562