OLD | NEW |
1 # Authors: | 1 # Authors: |
2 # Trevor Perrin | 2 # Trevor Perrin |
3 # Google (adapted by Sam Rushing) - NPN support | 3 # Google (adapted by Sam Rushing) - NPN support |
4 # Martin von Loewis - python 3 port | 4 # Martin von Loewis - python 3 port |
5 # Yngve Pettersen (ported by Paul Sokolovsky) - TLS 1.2 | 5 # Yngve Pettersen (ported by Paul Sokolovsky) - TLS 1.2 |
6 # | 6 # |
7 # See the LICENSE file for legal information regarding use of this file. | 7 # See the LICENSE file for legal information regarding use of this file. |
8 | 8 |
9 """Helper class for TLSConnection.""" | 9 """Helper class for TLSConnection.""" |
10 from __future__ import generators | 10 from __future__ import generators |
11 | 11 |
12 from .utils.compat import * | 12 from .utils.compat import * |
13 from .utils.cryptomath import * | 13 from .utils.cryptomath import * |
14 from .utils.cipherfactory import createAES, createRC4, createTripleDES | 14 from .utils.cipherfactory import createAESGCM, createAES, createRC4, \ |
| 15 createTripleDES |
15 from .utils.codec import * | 16 from .utils.codec import * |
16 from .errors import * | 17 from .errors import * |
17 from .messages import * | 18 from .messages import * |
18 from .mathtls import * | 19 from .mathtls import * |
19 from .constants import * | 20 from .constants import * |
20 from .utils.cryptomath import getRandomBytes | 21 from .utils.cryptomath import getRandomBytes |
21 | 22 |
22 import socket | 23 import socket |
23 import struct | 24 import struct |
24 import errno | 25 import errno |
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 mac.update(compatHMAC( bytearray([self.version[1]] ))) | 586 mac.update(compatHMAC( bytearray([self.version[1]] ))) |
586 mac.update( compatHMAC( bytearray([len(b)//256] ))) | 587 mac.update( compatHMAC( bytearray([len(b)//256] ))) |
587 mac.update( compatHMAC( bytearray([len(b)%256] ))) | 588 mac.update( compatHMAC( bytearray([len(b)%256] ))) |
588 else: | 589 else: |
589 raise AssertionError() | 590 raise AssertionError() |
590 mac.update(compatHMAC(b)) | 591 mac.update(compatHMAC(b)) |
591 macBytes = bytearray(mac.digest()) | 592 macBytes = bytearray(mac.digest()) |
592 if self.fault == Fault.badMAC: | 593 if self.fault == Fault.badMAC: |
593 macBytes[0] = (macBytes[0]+1) % 256 | 594 macBytes[0] = (macBytes[0]+1) % 256 |
594 | 595 |
595 #Encrypt for Block or Stream Cipher | 596 #Encrypt for non-NULL cipher. |
596 if self._writeState.encContext: | 597 if self._writeState.encContext: |
| 598 #Seal (for AEAD) |
| 599 if self._writeState.encContext.isAEAD: |
| 600 #Assemble the authenticated data. |
| 601 seqNumBytes = self._writeState.getSeqNumBytes() |
| 602 authData = seqNumBytes + bytearray([contentType, |
| 603 self.version[0], |
| 604 self.version[1], |
| 605 len(b)//256, |
| 606 len(b)%256]) |
| 607 |
| 608 #The nonce is always the fixed nonce and the sequence number. |
| 609 nonce = self._writeState.fixedNonce + seqNumBytes |
| 610 assert len(nonce) == self._writeState.encContext.nonceLength |
| 611 |
| 612 b = self._writeState.encContext.seal(nonce, b, authData) |
| 613 |
| 614 #The only AEAD supported, AES-GCM, has an explicit variable |
| 615 #nonce. |
| 616 b = seqNumBytes + b |
| 617 |
597 #Add padding and encrypt (for Block Cipher): | 618 #Add padding and encrypt (for Block Cipher): |
598 if self._writeState.encContext.isBlockCipher: | 619 elif self._writeState.encContext.isBlockCipher: |
599 | 620 |
600 #Add TLS 1.1 fixed block | 621 #Add TLS 1.1 fixed block |
601 if self.version >= (3,2): | 622 if self.version >= (3,2): |
602 b = self.fixedIVBlock + b | 623 b = self.fixedIVBlock + b |
603 | 624 |
604 #Add padding: b = b+ (macBytes + paddingBytes) | 625 #Add padding: b = b+ (macBytes + paddingBytes) |
605 currentLength = len(b) + len(macBytes) | 626 currentLength = len(b) + len(macBytes) |
606 blockLength = self._writeState.encContext.block_size | 627 blockLength = self._writeState.encContext.block_size |
607 paddingLength = blockLength - 1 - (currentLength % blockLength) | 628 paddingLength = blockLength - 1 - (currentLength % blockLength) |
608 | 629 |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
960 | 981 |
961 #We've moved at least one handshake message into the | 982 #We've moved at least one handshake message into the |
962 #handshakeBuffer, return the first one | 983 #handshakeBuffer, return the first one |
963 recordHeader, b = self._handshakeBuffer[0] | 984 recordHeader, b = self._handshakeBuffer[0] |
964 self._handshakeBuffer = self._handshakeBuffer[1:] | 985 self._handshakeBuffer = self._handshakeBuffer[1:] |
965 yield (recordHeader, Parser(b)) | 986 yield (recordHeader, Parser(b)) |
966 | 987 |
967 | 988 |
968 def _decryptRecord(self, recordType, b): | 989 def _decryptRecord(self, recordType, b): |
969 if self._readState.encContext: | 990 if self._readState.encContext: |
| 991 #Open if it's an AEAD. |
| 992 if self._readState.encContext.isAEAD: |
| 993 #The only AEAD supported, AES-GCM, has an explicit variable |
| 994 #nonce. |
| 995 explicitNonceLength = 8 |
| 996 if explicitNonceLength > len(b): |
| 997 #Publicly invalid. |
| 998 for result in self._sendError( |
| 999 AlertDescription.bad_record_mac, |
| 1000 "MAC failure (or padding failure)"): |
| 1001 yield result |
| 1002 nonce = self._readState.fixedNonce + b[:explicitNonceLength] |
| 1003 b = b[8:] |
| 1004 |
| 1005 if self._readState.encContext.tagLength > len(b): |
| 1006 #Publicly invalid. |
| 1007 for result in self._sendError( |
| 1008 AlertDescription.bad_record_mac, |
| 1009 "MAC failure (or padding failure)"): |
| 1010 yield result |
| 1011 |
| 1012 #Assemble the authenticated data. |
| 1013 seqnumBytes = self._readState.getSeqNumBytes() |
| 1014 plaintextLen = len(b) - self._readState.encContext.tagLength |
| 1015 authData = seqnumBytes + bytearray([recordType, self.version[0], |
| 1016 self.version[1], |
| 1017 plaintextLen//256, |
| 1018 plaintextLen%256]) |
| 1019 |
| 1020 b = self._readState.encContext.open(nonce, b, authData) |
| 1021 if b is None: |
| 1022 for result in self._sendError( |
| 1023 AlertDescription.bad_record_mac, |
| 1024 "MAC failure (or padding failure)"): |
| 1025 yield result |
| 1026 yield b |
| 1027 return |
970 | 1028 |
971 #Decrypt if it's a block cipher | 1029 #Decrypt if it's a block cipher |
972 if self._readState.encContext.isBlockCipher: | 1030 if self._readState.encContext.isBlockCipher: |
973 blockLength = self._readState.encContext.block_size | 1031 blockLength = self._readState.encContext.block_size |
974 if len(b) % blockLength != 0: | 1032 if len(b) % blockLength != 0: |
975 for result in self._sendError(\ | 1033 for result in self._sendError(\ |
976 AlertDescription.decryption_failed, | 1034 AlertDescription.decryption_failed, |
977 "Encrypted data not a multiple of blocksize"): | 1035 "Encrypted data not a multiple of blocksize"): |
978 yield result | 1036 yield result |
979 b = self._readState.encContext.decrypt(b) | 1037 b = self._readState.encContext.decrypt(b) |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1057 self._handshakeBuffer = [] | 1115 self._handshakeBuffer = [] |
1058 self.allegedSrpUsername = None | 1116 self.allegedSrpUsername = None |
1059 self._refCount = 1 | 1117 self._refCount = 1 |
1060 | 1118 |
1061 def _handshakeDone(self, resumed): | 1119 def _handshakeDone(self, resumed): |
1062 self.resumed = resumed | 1120 self.resumed = resumed |
1063 self.closed = False | 1121 self.closed = False |
1064 | 1122 |
1065 def _calcPendingStates(self, cipherSuite, masterSecret, | 1123 def _calcPendingStates(self, cipherSuite, masterSecret, |
1066 clientRandom, serverRandom, implementations): | 1124 clientRandom, serverRandom, implementations): |
1067 if cipherSuite in CipherSuite.aes128Suites: | 1125 if cipherSuite in CipherSuite.aes128GcmSuites: |
| 1126 keyLength = 16 |
| 1127 ivLength = 4 |
| 1128 createCipherFunc = createAESGCM |
| 1129 elif cipherSuite in CipherSuite.aes128Suites: |
1068 keyLength = 16 | 1130 keyLength = 16 |
1069 ivLength = 16 | 1131 ivLength = 16 |
1070 createCipherFunc = createAES | 1132 createCipherFunc = createAES |
1071 elif cipherSuite in CipherSuite.aes256Suites: | 1133 elif cipherSuite in CipherSuite.aes256Suites: |
1072 keyLength = 32 | 1134 keyLength = 32 |
1073 ivLength = 16 | 1135 ivLength = 16 |
1074 createCipherFunc = createAES | 1136 createCipherFunc = createAES |
1075 elif cipherSuite in CipherSuite.rc4Suites: | 1137 elif cipherSuite in CipherSuite.rc4Suites: |
1076 keyLength = 16 | 1138 keyLength = 16 |
1077 ivLength = 0 | 1139 ivLength = 0 |
1078 createCipherFunc = createRC4 | 1140 createCipherFunc = createRC4 |
1079 elif cipherSuite in CipherSuite.tripleDESSuites: | 1141 elif cipherSuite in CipherSuite.tripleDESSuites: |
1080 keyLength = 24 | 1142 keyLength = 24 |
1081 ivLength = 8 | 1143 ivLength = 8 |
1082 createCipherFunc = createTripleDES | 1144 createCipherFunc = createTripleDES |
1083 else: | 1145 else: |
1084 raise AssertionError() | 1146 raise AssertionError() |
1085 | 1147 |
1086 if cipherSuite in CipherSuite.shaSuites: | 1148 if cipherSuite in CipherSuite.aeadSuites: |
| 1149 macLength = 0 |
| 1150 digestmod = None |
| 1151 elif cipherSuite in CipherSuite.shaSuites: |
1087 macLength = 20 | 1152 macLength = 20 |
1088 digestmod = hashlib.sha1 | 1153 digestmod = hashlib.sha1 |
1089 elif cipherSuite in CipherSuite.sha256Suites: | 1154 elif cipherSuite in CipherSuite.sha256Suites: |
1090 macLength = 32 | 1155 macLength = 32 |
1091 digestmod = hashlib.sha256 | 1156 digestmod = hashlib.sha256 |
1092 elif cipherSuite in CipherSuite.md5Suites: | 1157 elif cipherSuite in CipherSuite.md5Suites: |
1093 macLength = 16 | 1158 macLength = 16 |
1094 digestmod = hashlib.md5 | 1159 digestmod = hashlib.md5 |
| 1160 else: |
| 1161 raise AssertionError() |
1095 | 1162 |
1096 if self.version == (3,0): | 1163 if not digestmod: |
| 1164 createMACFunc = None |
| 1165 elif self.version == (3,0): |
1097 createMACFunc = createMAC_SSL | 1166 createMACFunc = createMAC_SSL |
1098 elif self.version in ((3,1), (3,2), (3,3)): | 1167 elif self.version in ((3,1), (3,2), (3,3)): |
1099 createMACFunc = createHMAC | 1168 createMACFunc = createHMAC |
1100 | 1169 |
1101 outputLength = (macLength*2) + (keyLength*2) + (ivLength*2) | 1170 outputLength = (macLength*2) + (keyLength*2) + (ivLength*2) |
1102 | 1171 |
1103 #Calculate Keying Material from Master Secret | 1172 #Calculate Keying Material from Master Secret |
1104 if self.version == (3,0): | 1173 if self.version == (3,0): |
1105 keyBlock = PRF_SSL(masterSecret, | 1174 keyBlock = PRF_SSL(masterSecret, |
1106 serverRandom + clientRandom, | 1175 serverRandom + clientRandom, |
(...skipping 14 matching lines...) Expand all Loading... |
1121 #Slice up Keying Material | 1190 #Slice up Keying Material |
1122 clientPendingState = _ConnectionState() | 1191 clientPendingState = _ConnectionState() |
1123 serverPendingState = _ConnectionState() | 1192 serverPendingState = _ConnectionState() |
1124 p = Parser(keyBlock) | 1193 p = Parser(keyBlock) |
1125 clientMACBlock = p.getFixBytes(macLength) | 1194 clientMACBlock = p.getFixBytes(macLength) |
1126 serverMACBlock = p.getFixBytes(macLength) | 1195 serverMACBlock = p.getFixBytes(macLength) |
1127 clientKeyBlock = p.getFixBytes(keyLength) | 1196 clientKeyBlock = p.getFixBytes(keyLength) |
1128 serverKeyBlock = p.getFixBytes(keyLength) | 1197 serverKeyBlock = p.getFixBytes(keyLength) |
1129 clientIVBlock = p.getFixBytes(ivLength) | 1198 clientIVBlock = p.getFixBytes(ivLength) |
1130 serverIVBlock = p.getFixBytes(ivLength) | 1199 serverIVBlock = p.getFixBytes(ivLength) |
1131 clientPendingState.macContext = createMACFunc( | 1200 if digestmod: |
1132 compatHMAC(clientMACBlock), digestmod=digestmod) | 1201 # Legacy cipher. |
1133 serverPendingState.macContext = createMACFunc( | 1202 clientPendingState.macContext = createMACFunc( |
1134 compatHMAC(serverMACBlock), digestmod=digestmod) | 1203 compatHMAC(clientMACBlock), digestmod=digestmod) |
1135 clientPendingState.encContext = createCipherFunc(clientKeyBlock, | 1204 serverPendingState.macContext = createMACFunc( |
1136 clientIVBlock, | 1205 compatHMAC(serverMACBlock), digestmod=digestmod) |
1137 implementations) | 1206 clientPendingState.encContext = createCipherFunc(clientKeyBlock, |
1138 serverPendingState.encContext = createCipherFunc(serverKeyBlock, | 1207 clientIVBlock, |
1139 serverIVBlock, | 1208 implementations) |
1140 implementations) | 1209 serverPendingState.encContext = createCipherFunc(serverKeyBlock, |
| 1210 serverIVBlock, |
| 1211 implementations) |
| 1212 else: |
| 1213 # AEAD. |
| 1214 clientPendingState.macContext = None |
| 1215 serverPendingState.macContext = None |
| 1216 clientPendingState.encContext = createCipherFunc(clientKeyBlock, |
| 1217 implementations) |
| 1218 serverPendingState.encContext = createCipherFunc(serverKeyBlock, |
| 1219 implementations) |
| 1220 clientPendingState.fixedNonce = clientIVBlock |
| 1221 serverPendingState.fixedNonce = serverIVBlock |
1141 | 1222 |
1142 #Assign new connection states to pending states | 1223 #Assign new connection states to pending states |
1143 if self._client: | 1224 if self._client: |
1144 self._pendingWriteState = clientPendingState | 1225 self._pendingWriteState = clientPendingState |
1145 self._pendingReadState = serverPendingState | 1226 self._pendingReadState = serverPendingState |
1146 else: | 1227 else: |
1147 self._pendingWriteState = serverPendingState | 1228 self._pendingWriteState = serverPendingState |
1148 self._pendingReadState = clientPendingState | 1229 self._pendingReadState = clientPendingState |
1149 | 1230 |
1150 if self.version >= (3,2) and ivLength: | 1231 if self.version >= (3,2) and ivLength: |
(...skipping 17 matching lines...) Expand all Loading... |
1168 imac_md5.update(compatHMAC(label + masterSecret + bytearray([0x36]*48))) | 1249 imac_md5.update(compatHMAC(label + masterSecret + bytearray([0x36]*48))) |
1169 imac_sha.update(compatHMAC(label + masterSecret + bytearray([0x36]*40))) | 1250 imac_sha.update(compatHMAC(label + masterSecret + bytearray([0x36]*40))) |
1170 | 1251 |
1171 md5Bytes = MD5(masterSecret + bytearray([0x5c]*48) + \ | 1252 md5Bytes = MD5(masterSecret + bytearray([0x5c]*48) + \ |
1172 bytearray(imac_md5.digest())) | 1253 bytearray(imac_md5.digest())) |
1173 shaBytes = SHA1(masterSecret + bytearray([0x5c]*40) + \ | 1254 shaBytes = SHA1(masterSecret + bytearray([0x5c]*40) + \ |
1174 bytearray(imac_sha.digest())) | 1255 bytearray(imac_sha.digest())) |
1175 | 1256 |
1176 return md5Bytes + shaBytes | 1257 return md5Bytes + shaBytes |
1177 | 1258 |
OLD | NEW |