OLD | NEW |
---|---|
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 key exchange. If the key exchange method does not send ServerKeyExchange | |
wtc
2014/04/03 19:10:03
Nit: in the key exchange => in the handshake ?
davidben
2014/04/10 19:30:51
Done.
| |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |