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

Unified Diff: third_party/tlslite/tlslite/tlsconnection.py

Issue 212883008: Add DHE_RSA support to tlslite. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: third_party/tlslite/tlslite/tlsconnection.py
diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py
index 20cd85bc90f31b456ec45c5d23a746123b962346..07ee862a190cecf2ad40ab0735b277c2182d5cb3 100644
--- a/third_party/tlslite/tlslite/tlsconnection.py
+++ b/third_party/tlslite/tlslite/tlsconnection.py
@@ -24,6 +24,78 @@ from .handshakesettings import HandshakeSettings
from .utils.tackwrapper import *
+class KeyExchange(object):
+ def __init__(self, cipherSuite, clientHello, serverHello, privateKey):
+ self.cipherSuite = cipherSuite
+ self.clientHello = clientHello
+ self.serverHello = serverHello
+ self.privateKey = privateKey
+
+ def makeServerKeyExchange():
+ raise NotImplementedError()
+ def processClientKeyExchange(clientKeyExchange):
+ raise NotImplementedError()
+
+
+class RSAKeyExchange(KeyExchange):
+ def makeServerKeyExchange(self):
+ return None
Ryan Sleevi 2014/03/31 20:43:57 is None right? Should it be NotImplemented?
davidben 2014/03/31 20:58:20 RSA doesn't send a ServerKeyExchange. This method
+
+ def processClientKeyExchange(self, clientKeyExchange):
+ premasterSecret = self.privateKey.decrypt(\
+ clientKeyExchange.encryptedPreMasterSecret)
+
+ # On decryption failure randomize premaster secret to avoid
+ # Bleichenbacher's "million message" attack
Ryan Sleevi 2014/03/31 20:43:57 heheheh. This doesn't really do that, but ok [Yes
davidben 2014/03/31 20:58:20 :-P I make no claims as to whether that comment wa
wtc 2014/04/02 03:34:20 If self.privateKey.decrypt does RSA blinding, then
+ randomPreMasterSecret = getRandomBytes(48)
+ versionCheck = (premasterSecret[0], premasterSecret[1])
+ if not premasterSecret:
+ premasterSecret = randomPreMasterSecret
+ elif len(premasterSecret)!=48:
+ premasterSecret = randomPreMasterSecret
+ elif versionCheck != self.clientHello.client_version:
+ #Tolerate buggy IE clients
wtc 2014/04/01 22:00:01 This is a very old bug of IE. I suspect this bug h
davidben 2014/04/01 23:25:18 Yeah, this block was just moved over. I can also j
wtc 2014/04/02 03:34:20 It's fine to keep this. We should only drop this i
+ if versionCheck != self.serverHello.server_version:
wtc 2014/04/01 22:00:01 Is self.serverHello.server_version correct? The or
davidben 2014/04/01 23:25:18 Should be. I made sure it passed all tlslite's ori
+ premasterSecret = randomPreMasterSecret
+ return premasterSecret
+
+class DHE_RSAKeyExchange(KeyExchange):
+ # Generated with openssl dhparam 1024 -text. Generating a new one each time
+ # in Python is far far far too slow.
wtc 2014/04/01 22:00:01 IMPORTANT: please use one of the well-known DH gro
davidben 2014/04/01 23:25:18 Done.
+ dh_p = bytesToNumber(
+ bytearray(
+ "\x00\x88\xc4\xdc\x2a\xd9\xba\x8d\x24\x69\x7f\xe4\xd4\xeb\x62"
+ "\x04\x43\xe8\x31\x08\x30\xa8\xe4\x24\x0f\xa7\xc3\xff\x84\x52"
+ "\x44\x4a\x1b\x8c\x88\x16\xa6\x17\x90\xac\x21\x34\xfb\xc5\xff"
+ "\x90\x46\x32\x29\xfa\x9d\xd3\x36\x05\xc2\x86\xcf\xde\x77\x68"
+ "\x4c\xe3\xb0\x34\x55\xce\x27\x85\x46\x94\xad\x0c\xef\x11\x53"
+ "\x61\x50\x0c\x3e\x7b\x8a\x3c\xa0\x52\x6c\xb2\xa5\x84\xf7\xa9"
+ "\xdc\x9d\x57\x60\xd0\x89\xc6\x14\x39\x54\xce\x20\xcc\x2d\xe9"
+ "\x90\xeb\xe7\x42\xf1\x03\x60\x5b\x06\x2f\x51\x97\x01\xc2\x1d"
+ "\xfa\xb3\xfe\x02\x4b\xee\xd1\x65\xcb"))
+ dh_g = 2
+
+ def makeServerKeyExchange(self):
+ self.dh_Xs = bytesToNumber(getRandomBytes(1024 / 8))
+ dh_Ys = powMod(self.dh_g, self.dh_Xs, self.dh_p)
+
+ serverKeyExchange = ServerKeyExchange(self.cipherSuite)
+ serverKeyExchange.createDH(self.dh_p, self.dh_g, dh_Ys)
+ serverKeyExchange.signature = self.privateKey.sign(
+ serverKeyExchange.hash(self.clientHello.random,
+ self.serverHello.random))
+ return serverKeyExchange
+
+ def processClientKeyExchange(self, clientKeyExchange):
+ dh_Yc = clientKeyExchange.dh_Yc
+
+ if dh_Yc % self.dh_p == 0:
wtc 2014/04/01 22:00:01 Is this check recommended by RFC 5246? I'm just cu
davidben 2014/04/01 23:25:18 I just copied the DH code from _serverAnonKeyExcha
+ raise TLSLocalAlert(AlertDescription.illegal_parameter,
+ "Suspicious dh_Yc value")
+
+ S = powMod(dh_Yc, self.dh_Xs, self.dh_p)
+ return numberToByteArray(S)
+
class TLSConnection(TLSRecordLayer):
"""
This class wraps a socket and provides TLS handshaking and data
@@ -500,6 +572,8 @@ class TLSConnection(TLSRecordLayer):
cipherSuites += CipherSuite.getSrpAllSuites(settings)
elif certParams:
cipherSuites += CipherSuite.getCertSuites(settings)
+ # Client DHE_RSA not supported.
+ # cipherSuites += CipherSuite.getDheCertSuites(settings)
elif anonParams:
cipherSuites += CipherSuite.getAnonSuites(settings)
else:
@@ -1205,9 +1279,22 @@ class TLSConnection(TLSRecordLayer):
premasterSecret = result
# Perform the RSA key exchange
wtc 2014/04/01 22:00:01 Nit: this comment should say "Perform the RSA or D
davidben 2014/04/01 23:25:18 Done.
- elif cipherSuite in CipherSuite.certSuites:
+ elif (cipherSuite in CipherSuite.certSuites or
+ cipherSuite in CipherSuite.dheCertSuites):
+ if cipherSuite in CipherSuite.certSuites:
+ keyExchange = RSAKeyExchange(cipherSuite,
+ clientHello,
+ serverHello,
+ privateKey)
+ elif cipherSuite in CipherSuite.dheCertSuites:
+ keyExchange = DHE_RSAKeyExchange(cipherSuite,
+ clientHello,
+ serverHello,
+ privateKey)
+ else:
+ assert(False)
for result in self._serverCertKeyExchange(clientHello, serverHello,
- certChain, privateKey,
+ certChain, keyExchange,
reqCert, reqCAs, cipherSuite,
settings, ocspResponse):
if result in (0,1): yield result
@@ -1268,6 +1355,7 @@ class TLSConnection(TLSRecordLayer):
cipherSuites += CipherSuite.getSrpSuites(settings)
elif certChain:
cipherSuites += CipherSuite.getCertSuites(settings)
+ cipherSuites += CipherSuite.getDheCertSuites(settings)
elif anon:
cipherSuites += CipherSuite.getAnonSuites(settings)
else:
@@ -1483,7 +1571,7 @@ class TLSConnection(TLSRecordLayer):
def _serverCertKeyExchange(self, clientHello, serverHello,
- serverCertChain, privateKey,
+ serverCertChain, keyExchange,
reqCert, reqCAs, cipherSuite,
settings, ocspResponse):
#Send ServerHello, Certificate[, CertificateRequest],
wtc 2014/04/01 22:00:01 Nit: add the optional ServerKeyExchange method to
davidben 2014/04/01 23:25:18 Done.
@@ -1497,6 +1585,9 @@ class TLSConnection(TLSRecordLayer):
msgs.append(Certificate(CertificateType.x509).create(serverCertChain))
if serverHello.status_request:
msgs.append(CertificateStatus().create(ocspResponse))
+ serverKeyExchange = keyExchange.makeServerKeyExchange()
+ if serverKeyExchange is not None:
+ msgs.append(serverKeyExchange)
if reqCert and reqCAs:
msgs.append(CertificateRequest().create(\
[ClientCertificateType.rsa_sign], reqCAs))
@@ -1555,21 +1646,13 @@ class TLSConnection(TLSRecordLayer):
else: break
clientKeyExchange = result
- #Decrypt ClientKeyExchange
- premasterSecret = privateKey.decrypt(\
- clientKeyExchange.encryptedPreMasterSecret)
-
- # On decryption failure randomize premaster secret to avoid
- # Bleichenbacher's "million message" attack
- randomPreMasterSecret = getRandomBytes(48)
- versionCheck = (premasterSecret[0], premasterSecret[1])
- if not premasterSecret:
- premasterSecret = randomPreMasterSecret
- elif len(premasterSecret)!=48:
- premasterSecret = randomPreMasterSecret
- elif versionCheck != clientHello.client_version:
- if versionCheck != self.version: #Tolerate buggy IE clients
- premasterSecret = randomPreMasterSecret
+ #Process ClientKeyExchange
+ try:
+ premasterSecret = \
+ keyExchange.processClientKeyExchange(clientKeyExchange)
+ except TLSLocalAlert, e:
+ for result in self._sendError(alert.description, alert.message):
wtc 2014/04/01 22:00:01 IMPORTANT: Should |alert| be |e|?
davidben 2014/04/01 23:25:18 Oops. Done.
+ yield result
#Get and check CertificateVerify, if relevant
if clientCertChain:
« third_party/tlslite/tlslite/messages.py ('K') | « third_party/tlslite/tlslite/messages.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698