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 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 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 |