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

Side by Side 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: 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/tlslite/messages.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Authors: 1 # Authors:
2 # Trevor Perrin 2 # Trevor Perrin
3 # Google - added reqCAs parameter 3 # Google - added reqCAs parameter
4 # Google (adapted by Sam Rushing and Marcelo Fernandez) - NPN support 4 # Google (adapted by Sam Rushing and Marcelo Fernandez) - NPN support
5 # Dimitris Moraitis - Anon ciphersuites 5 # Dimitris Moraitis - Anon ciphersuites
6 # Martin von Loewis - python 3 port 6 # Martin von Loewis - python 3 port
7 # 7 #
8 # See the LICENSE file for legal information regarding use of this file. 8 # See the LICENSE file for legal information regarding use of this file.
9 9
10 """ 10 """
11 MAIN CLASS FOR TLS LITE (START HERE!). 11 MAIN CLASS FOR TLS LITE (START HERE!).
12 """ 12 """
13 13
14 import socket 14 import socket
15 from .utils.compat import formatExceptionTrace 15 from .utils.compat import formatExceptionTrace
16 from .tlsrecordlayer import TLSRecordLayer 16 from .tlsrecordlayer import TLSRecordLayer
17 from .session import Session 17 from .session import Session
18 from .constants import * 18 from .constants import *
19 from .utils.cryptomath import getRandomBytes 19 from .utils.cryptomath import getRandomBytes
20 from .errors import * 20 from .errors import *
21 from .messages import * 21 from .messages import *
22 from .mathtls import * 22 from .mathtls import *
23 from .handshakesettings import HandshakeSettings 23 from .handshakesettings import HandshakeSettings
24 from .utils.tackwrapper import * 24 from .utils.tackwrapper import *
25 25
26 class KeyExchange(object):
27 def __init__(self, cipherSuite, clientHello, serverHello, privateKey):
28 """
29 Initializes the KeyExchange. privateKey is the signing private key.
30 """
31 self.cipherSuite = cipherSuite
32 self.clientHello = clientHello
33 self.serverHello = serverHello
34 self.privateKey = privateKey
35
36 def makeServerKeyExchange():
37 """
38 Returns a ServerKeyExchange object for the server's initial leg in the
39 handshake. If the key exchange method does not send ServerKeyExchange
40 (e.g. RSA), it returns None.
41 """
42 raise NotImplementedError()
43
44 def processClientKeyExchange(clientKeyExchange):
45 """
46 Processes the client's ClientKeyExchange message and returns the
47 premaster secret. Raises TLSLocalAlert on error.
48 """
49 raise NotImplementedError()
50
51 class RSAKeyExchange(KeyExchange):
52 def makeServerKeyExchange(self):
53 return None
54
55 def processClientKeyExchange(self, clientKeyExchange):
56 premasterSecret = self.privateKey.decrypt(\
57 clientKeyExchange.encryptedPreMasterSecret)
58
59 # On decryption failure randomize premaster secret to avoid
60 # Bleichenbacher's "million message" attack
61 randomPreMasterSecret = getRandomBytes(48)
62 if not premasterSecret:
63 premasterSecret = randomPreMasterSecret
64 elif len(premasterSecret)!=48:
65 premasterSecret = randomPreMasterSecret
66 else:
67 versionCheck = (premasterSecret[0], premasterSecret[1])
68 if versionCheck != self.clientHello.client_version:
69 #Tolerate buggy IE clients
70 if versionCheck != self.serverHello.server_version:
71 premasterSecret = randomPreMasterSecret
72 return premasterSecret
73
74 def _hexStringToNumber(s):
75 s = s.replace(" ", "").replace("\n", "")
76 if len(s) % 2 != 0:
77 raise ValueError("Length is not even")
78 return bytesToNumber(bytearray(s.decode("hex")))
79
80 class DHE_RSAKeyExchange(KeyExchange):
81 # 2048-bit MODP Group (RFC 3526, Section 3)
82 dh_p = _hexStringToNumber("""
83 FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1
84 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD
85 EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245
86 E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED
87 EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D
88 C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F
89 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D
90 670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B
91 E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9
92 DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510
93 15728E5A 8AACAA68 FFFFFFFF FFFFFFFF""")
94 dh_g = 2
95
96 # RFC 3526, Section 8.
97 strength = 160
98
99 def makeServerKeyExchange(self):
100 # Per RFC 3526, Section 1, the exponent should have double the entropy
101 # of the strength of the curve.
102 self.dh_Xs = bytesToNumber(getRandomBytes(self.strength * 2 / 8))
103 dh_Ys = powMod(self.dh_g, self.dh_Xs, self.dh_p)
104
105 serverKeyExchange = ServerKeyExchange(self.cipherSuite)
106 serverKeyExchange.createDH(self.dh_p, self.dh_g, dh_Ys)
107 serverKeyExchange.signature = self.privateKey.sign(
108 serverKeyExchange.hash(self.clientHello.random,
109 self.serverHello.random))
110 return serverKeyExchange
111
112 def processClientKeyExchange(self, clientKeyExchange):
113 dh_Yc = clientKeyExchange.dh_Yc
114
115 # First half of RFC 2631, Section 2.1.5. Validate the client's public
116 # key.
117 if not 2 <= dh_Yc <= self.dh_p - 1:
118 raise TLSLocalAlert(AlertDescription.illegal_parameter,
119 "Invalid dh_Yc value")
120
121 S = powMod(dh_Yc, self.dh_Xs, self.dh_p)
122 return numberToByteArray(S)
26 123
27 class TLSConnection(TLSRecordLayer): 124 class TLSConnection(TLSRecordLayer):
28 """ 125 """
29 This class wraps a socket and provides TLS handshaking and data 126 This class wraps a socket and provides TLS handshaking and data
30 transfer. 127 transfer.
31 128
32 To use this class, create a new instance, passing a connected 129 To use this class, create a new instance, passing a connected
33 socket into the constructor. Then call some handshake function. 130 socket into the constructor. Then call some handshake function.
34 If the handshake completes without raising an exception, then a TLS 131 If the handshake completes without raising an exception, then a TLS
35 connection has been negotiated. You can transfer data over this 132 connection has been negotiated. You can transfer data over this
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 590
494 def _clientSendClientHello(self, settings, session, srpUsername, 591 def _clientSendClientHello(self, settings, session, srpUsername,
495 srpParams, certParams, anonParams, 592 srpParams, certParams, anonParams,
496 serverName, nextProtos, reqTack): 593 serverName, nextProtos, reqTack):
497 #Initialize acceptable ciphersuites 594 #Initialize acceptable ciphersuites
498 cipherSuites = [CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV] 595 cipherSuites = [CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
499 if srpParams: 596 if srpParams:
500 cipherSuites += CipherSuite.getSrpAllSuites(settings) 597 cipherSuites += CipherSuite.getSrpAllSuites(settings)
501 elif certParams: 598 elif certParams:
502 cipherSuites += CipherSuite.getCertSuites(settings) 599 cipherSuites += CipherSuite.getCertSuites(settings)
600 # TODO: Client DHE_RSA not supported.
601 # cipherSuites += CipherSuite.getDheCertSuites(settings)
503 elif anonParams: 602 elif anonParams:
504 cipherSuites += CipherSuite.getAnonSuites(settings) 603 cipherSuites += CipherSuite.getAnonSuites(settings)
505 else: 604 else:
506 assert(False) 605 assert(False)
507 606
508 #Initialize acceptable certificate types 607 #Initialize acceptable certificate types
509 certificateTypes = settings._getCertificateTypes() 608 certificateTypes = settings._getCertificateTypes()
510 609
511 #Either send ClientHello (with a resumable session)... 610 #Either send ClientHello (with a resumable session)...
512 if session and session.sessionID: 611 if session and session.sessionID:
(...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after
1197 # Perform the SRP key exchange 1296 # Perform the SRP key exchange
1198 clientCertChain = None 1297 clientCertChain = None
1199 if cipherSuite in CipherSuite.srpAllSuites: 1298 if cipherSuite in CipherSuite.srpAllSuites:
1200 for result in self._serverSRPKeyExchange(clientHello, serverHello, 1299 for result in self._serverSRPKeyExchange(clientHello, serverHello,
1201 verifierDB, cipherSuite, 1300 verifierDB, cipherSuite,
1202 privateKey, certChain): 1301 privateKey, certChain):
1203 if result in (0,1): yield result 1302 if result in (0,1): yield result
1204 else: break 1303 else: break
1205 premasterSecret = result 1304 premasterSecret = result
1206 1305
1207 # Perform the RSA key exchange 1306 # Perform the RSA or DHE_RSA key exchange
1208 elif cipherSuite in CipherSuite.certSuites: 1307 elif (cipherSuite in CipherSuite.certSuites or
1308 cipherSuite in CipherSuite.dheCertSuites):
1309 if cipherSuite in CipherSuite.certSuites:
1310 keyExchange = RSAKeyExchange(cipherSuite,
1311 clientHello,
1312 serverHello,
1313 privateKey)
1314 elif cipherSuite in CipherSuite.dheCertSuites:
1315 keyExchange = DHE_RSAKeyExchange(cipherSuite,
1316 clientHello,
1317 serverHello,
1318 privateKey)
1319 else:
1320 assert(False)
1209 for result in self._serverCertKeyExchange(clientHello, serverHello, 1321 for result in self._serverCertKeyExchange(clientHello, serverHello,
1210 certChain, privateKey, 1322 certChain, keyExchange,
1211 reqCert, reqCAs, cipherSuite, 1323 reqCert, reqCAs, cipherSuite,
1212 settings, ocspResponse): 1324 settings, ocspResponse):
1213 if result in (0,1): yield result 1325 if result in (0,1): yield result
1214 else: break 1326 else: break
1215 (premasterSecret, clientCertChain) = result 1327 (premasterSecret, clientCertChain) = result
1216 1328
1217 # Perform anonymous Diffie Hellman key exchange 1329 # Perform anonymous Diffie Hellman key exchange
1218 elif cipherSuite in CipherSuite.anonSuites: 1330 elif cipherSuite in CipherSuite.anonSuites:
1219 for result in self._serverAnonKeyExchange(clientHello, serverHello, 1331 for result in self._serverAnonKeyExchange(clientHello, serverHello,
1220 cipherSuite, settings): 1332 cipherSuite, settings):
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1261 sessionCache, anon, tlsIntolerant, fallbackSCSV) : 1373 sessionCache, anon, tlsIntolerant, fallbackSCSV) :
1262 #Initialize acceptable cipher suites 1374 #Initialize acceptable cipher suites
1263 cipherSuites = [] 1375 cipherSuites = []
1264 if verifierDB: 1376 if verifierDB:
1265 if certChain: 1377 if certChain:
1266 cipherSuites += \ 1378 cipherSuites += \
1267 CipherSuite.getSrpCertSuites(settings) 1379 CipherSuite.getSrpCertSuites(settings)
1268 cipherSuites += CipherSuite.getSrpSuites(settings) 1380 cipherSuites += CipherSuite.getSrpSuites(settings)
1269 elif certChain: 1381 elif certChain:
1270 cipherSuites += CipherSuite.getCertSuites(settings) 1382 cipherSuites += CipherSuite.getCertSuites(settings)
1383 cipherSuites += CipherSuite.getDheCertSuites(settings)
1271 elif anon: 1384 elif anon:
1272 cipherSuites += CipherSuite.getAnonSuites(settings) 1385 cipherSuites += CipherSuite.getAnonSuites(settings)
1273 else: 1386 else:
1274 assert(False) 1387 assert(False)
1275 1388
1276 #Tentatively set version to most-desirable version, so if an error 1389 #Tentatively set version to most-desirable version, so if an error
1277 #occurs parsing the ClientHello, this is what we'll use for the 1390 #occurs parsing the ClientHello, this is what we'll use for the
1278 #error alert 1391 #error alert
1279 self.version = settings.maxVersion 1392 self.version = settings.maxVersion
1280 1393
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
1476 u = makeU(N, A, B) 1589 u = makeU(N, A, B)
1477 1590
1478 #Calculate premaster secret 1591 #Calculate premaster secret
1479 S = powMod((A * powMod(v,u,N)) % N, b, N) 1592 S = powMod((A * powMod(v,u,N)) % N, b, N)
1480 premasterSecret = numberToByteArray(S) 1593 premasterSecret = numberToByteArray(S)
1481 1594
1482 yield premasterSecret 1595 yield premasterSecret
1483 1596
1484 1597
1485 def _serverCertKeyExchange(self, clientHello, serverHello, 1598 def _serverCertKeyExchange(self, clientHello, serverHello,
1486 serverCertChain, privateKey, 1599 serverCertChain, keyExchange,
1487 reqCert, reqCAs, cipherSuite, 1600 reqCert, reqCAs, cipherSuite,
1488 settings, ocspResponse): 1601 settings, ocspResponse):
1489 #Send ServerHello, Certificate[, CertificateRequest], 1602 #Send ServerHello, Certificate[, ServerKeyExchange]
1490 #ServerHelloDone 1603 #[, CertificateRequest], ServerHelloDone
1491 msgs = [] 1604 msgs = []
1492 1605
1493 # If we verify a client cert chain, return it 1606 # If we verify a client cert chain, return it
1494 clientCertChain = None 1607 clientCertChain = None
1495 1608
1496 msgs.append(serverHello) 1609 msgs.append(serverHello)
1497 msgs.append(Certificate(CertificateType.x509).create(serverCertChain)) 1610 msgs.append(Certificate(CertificateType.x509).create(serverCertChain))
1498 if serverHello.status_request: 1611 if serverHello.status_request:
1499 msgs.append(CertificateStatus().create(ocspResponse)) 1612 msgs.append(CertificateStatus().create(ocspResponse))
1613 serverKeyExchange = keyExchange.makeServerKeyExchange()
1614 if serverKeyExchange is not None:
1615 msgs.append(serverKeyExchange)
1500 if reqCert and reqCAs: 1616 if reqCert and reqCAs:
1501 msgs.append(CertificateRequest().create(\ 1617 msgs.append(CertificateRequest().create(\
1502 [ClientCertificateType.rsa_sign], reqCAs)) 1618 [ClientCertificateType.rsa_sign], reqCAs))
1503 elif reqCert: 1619 elif reqCert:
1504 msgs.append(CertificateRequest()) 1620 msgs.append(CertificateRequest())
1505 msgs.append(ServerHelloDone()) 1621 msgs.append(ServerHelloDone())
1506 for result in self._sendMsgs(msgs): 1622 for result in self._sendMsgs(msgs):
1507 yield result 1623 yield result
1508 1624
1509 #From here on, the client's messages must have the right version 1625 #From here on, the client's messages must have the right version
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1548 raise AssertionError() 1664 raise AssertionError()
1549 1665
1550 #Get ClientKeyExchange 1666 #Get ClientKeyExchange
1551 for result in self._getMsg(ContentType.handshake, 1667 for result in self._getMsg(ContentType.handshake,
1552 HandshakeType.client_key_exchange, 1668 HandshakeType.client_key_exchange,
1553 cipherSuite): 1669 cipherSuite):
1554 if result in (0,1): yield result 1670 if result in (0,1): yield result
1555 else: break 1671 else: break
1556 clientKeyExchange = result 1672 clientKeyExchange = result
1557 1673
1558 #Decrypt ClientKeyExchange 1674 #Process ClientKeyExchange
1559 premasterSecret = privateKey.decrypt(\ 1675 try:
1560 clientKeyExchange.encryptedPreMasterSecret) 1676 premasterSecret = \
1561 1677 keyExchange.processClientKeyExchange(clientKeyExchange)
1562 # On decryption failure randomize premaster secret to avoid 1678 except TLSLocalAlert, alert:
1563 # Bleichenbacher's "million message" attack 1679 for result in self._sendError(alert.description, alert.message):
1564 randomPreMasterSecret = getRandomBytes(48) 1680 yield result
1565 versionCheck = (premasterSecret[0], premasterSecret[1])
1566 if not premasterSecret:
1567 premasterSecret = randomPreMasterSecret
1568 elif len(premasterSecret)!=48:
1569 premasterSecret = randomPreMasterSecret
1570 elif versionCheck != clientHello.client_version:
1571 if versionCheck != self.version: #Tolerate buggy IE clients
1572 premasterSecret = randomPreMasterSecret
1573 1681
1574 #Get and check CertificateVerify, if relevant 1682 #Get and check CertificateVerify, if relevant
1575 if clientCertChain: 1683 if clientCertChain:
1576 if self.version == (3,0): 1684 if self.version == (3,0):
1577 masterSecret = calcMasterSecret(self.version, premasterSecret, 1685 masterSecret = calcMasterSecret(self.version, premasterSecret,
1578 clientHello.random, serverHello.random) 1686 clientHello.random, serverHello.random)
1579 verifyBytes = self._calcSSLHandshakeHash(masterSecret, b"") 1687 verifyBytes = self._calcSSLHandshakeHash(masterSecret, b"")
1580 elif self.version in ((3,1), (3,2)): 1688 elif self.version in ((3,1), (3,2)):
1581 verifyBytes = self._handshake_md5.digest() + \ 1689 verifyBytes = self._handshake_md5.digest() + \
1582 self._handshake_sha.digest() 1690 self._handshake_sha.digest()
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
1810 except TLSAlert as alert: 1918 except TLSAlert as alert:
1811 if not self.fault: 1919 if not self.fault:
1812 raise 1920 raise
1813 if alert.description not in Fault.faultAlerts[self.fault]: 1921 if alert.description not in Fault.faultAlerts[self.fault]:
1814 raise TLSFaultError(str(alert)) 1922 raise TLSFaultError(str(alert))
1815 else: 1923 else:
1816 pass 1924 pass
1817 except: 1925 except:
1818 self._shutdown(False) 1926 self._shutdown(False)
1819 raise 1927 raise
OLDNEW
« no previous file with comments | « third_party/tlslite/tlslite/messages.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698