Chromium Code Reviews| 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 Block or Stream Cipher |
|
Ryan Sleevi
2015/01/29 20:50:48
comment update?
davidben
2015/01/29 21:40:59
Done.
| |
| 596 if self._writeState.encContext: | 597 if self._writeState.encContext: |
| 598 #Seal (for AEAD) | |
| 599 if self._writeState.encContext.isAEAD: | |
| 600 #Assemble the AD. | |
|
Ryan Sleevi
2015/01/29 20:50:49
expand this acronym?
#Assemble the authenticated
davidben
2015/01/29 21:40:59
Done.
| |
| 601 seqnumBytes = self._writeState.getSeqNumBytes() | |
|
Ryan Sleevi
2015/01/29 20:50:48
nit: naming wise, should this be seqNumBytes?
davidben
2015/01/29 21:40:59
Copy-and-paste from MAC block above, but I agree.
| |
| 602 ad = seqnumBytes + bytearray([contentType, self.version[0], | |
| 603 self.version[1], len(b)//256, | |
| 604 len(b)%256]) | |
| 605 | |
| 606 #The nonce is always the fixed nonce and the sequence number. | |
| 607 nonce = self._writeState.fixedNonce + seqnumBytes | |
| 608 assert len(nonce) == self._writeState.encContext.nonceLength | |
| 609 | |
| 610 b = self._writeState.encContext.seal(nonce, b, ad) | |
| 611 | |
| 612 #The only AEAD supported, AES-GCM, has an explicit variable | |
| 613 #nonce. | |
|
Ryan Sleevi
2015/01/29 20:50:49
"explicit variable nonce" - this is just explicit
davidben
2015/01/29 21:40:59
As opposed to the fixed half of the nonce. (GCM no
| |
| 614 b = seqnumBytes + b | |
| 615 | |
| 597 #Add padding and encrypt (for Block Cipher): | 616 #Add padding and encrypt (for Block Cipher): |
| 598 if self._writeState.encContext.isBlockCipher: | 617 elif self._writeState.encContext.isBlockCipher: |
| 599 | 618 |
| 600 #Add TLS 1.1 fixed block | 619 #Add TLS 1.1 fixed block |
| 601 if self.version >= (3,2): | 620 if self.version >= (3,2): |
| 602 b = self.fixedIVBlock + b | 621 b = self.fixedIVBlock + b |
| 603 | 622 |
| 604 #Add padding: b = b+ (macBytes + paddingBytes) | 623 #Add padding: b = b+ (macBytes + paddingBytes) |
| 605 currentLength = len(b) + len(macBytes) | 624 currentLength = len(b) + len(macBytes) |
| 606 blockLength = self._writeState.encContext.block_size | 625 blockLength = self._writeState.encContext.block_size |
| 607 paddingLength = blockLength - 1 - (currentLength % blockLength) | 626 paddingLength = blockLength - 1 - (currentLength % blockLength) |
| 608 | 627 |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 960 | 979 |
| 961 #We've moved at least one handshake message into the | 980 #We've moved at least one handshake message into the |
| 962 #handshakeBuffer, return the first one | 981 #handshakeBuffer, return the first one |
| 963 recordHeader, b = self._handshakeBuffer[0] | 982 recordHeader, b = self._handshakeBuffer[0] |
| 964 self._handshakeBuffer = self._handshakeBuffer[1:] | 983 self._handshakeBuffer = self._handshakeBuffer[1:] |
| 965 yield (recordHeader, Parser(b)) | 984 yield (recordHeader, Parser(b)) |
| 966 | 985 |
| 967 | 986 |
| 968 def _decryptRecord(self, recordType, b): | 987 def _decryptRecord(self, recordType, b): |
| 969 if self._readState.encContext: | 988 if self._readState.encContext: |
| 989 #Open if it's an AEAD. | |
| 990 if self._readState.encContext.isAEAD: | |
| 991 #The only AEAD supported, AES-GCM, has an explicit variable | |
| 992 #nonce. | |
| 993 explicitNonceLength = 8 | |
| 994 if explicitNonceLength > len(b): | |
| 995 #Publicly invalid. | |
| 996 for result in self._sendError( | |
| 997 AlertDescription.bad_record_mac, | |
| 998 "MAC failure (or padding failure)"): | |
| 999 yield result | |
| 1000 nonce = self._readState.fixedNonce + b[:explicitNonceLength] | |
| 1001 b = b[8:] | |
| 1002 | |
| 1003 #Assemble the AD. | |
| 1004 seqnumBytes = self._readState.getSeqNumBytes() | |
| 1005 plaintextLen = len(b) - self._readState.encContext.tagLength | |
|
agl
2015/01/29 19:38:17
This can end up negative, but that doesn't appear
davidben
2015/01/29 21:40:59
Added a check anyway for good measure. I think a n
| |
| 1006 ad = seqnumBytes + bytearray([recordType, self.version[0], | |
| 1007 self.version[1], | |
| 1008 plaintextLen//256, | |
| 1009 plaintextLen%256]) | |
| 1010 | |
| 1011 b = self._readState.encContext.open(nonce, b, ad) | |
| 1012 if b is None: | |
| 1013 for result in self._sendError( | |
| 1014 AlertDescription.bad_record_mac, | |
| 1015 "MAC failure (or padding failure)"): | |
| 1016 yield result | |
| 1017 yield b | |
| 1018 return | |
| 970 | 1019 |
| 971 #Decrypt if it's a block cipher | 1020 #Decrypt if it's a block cipher |
| 972 if self._readState.encContext.isBlockCipher: | 1021 if self._readState.encContext.isBlockCipher: |
| 973 blockLength = self._readState.encContext.block_size | 1022 blockLength = self._readState.encContext.block_size |
| 974 if len(b) % blockLength != 0: | 1023 if len(b) % blockLength != 0: |
| 975 for result in self._sendError(\ | 1024 for result in self._sendError(\ |
| 976 AlertDescription.decryption_failed, | 1025 AlertDescription.decryption_failed, |
| 977 "Encrypted data not a multiple of blocksize"): | 1026 "Encrypted data not a multiple of blocksize"): |
| 978 yield result | 1027 yield result |
| 979 b = self._readState.encContext.decrypt(b) | 1028 b = self._readState.encContext.decrypt(b) |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1057 self._handshakeBuffer = [] | 1106 self._handshakeBuffer = [] |
| 1058 self.allegedSrpUsername = None | 1107 self.allegedSrpUsername = None |
| 1059 self._refCount = 1 | 1108 self._refCount = 1 |
| 1060 | 1109 |
| 1061 def _handshakeDone(self, resumed): | 1110 def _handshakeDone(self, resumed): |
| 1062 self.resumed = resumed | 1111 self.resumed = resumed |
| 1063 self.closed = False | 1112 self.closed = False |
| 1064 | 1113 |
| 1065 def _calcPendingStates(self, cipherSuite, masterSecret, | 1114 def _calcPendingStates(self, cipherSuite, masterSecret, |
| 1066 clientRandom, serverRandom, implementations): | 1115 clientRandom, serverRandom, implementations): |
| 1067 if cipherSuite in CipherSuite.aes128Suites: | 1116 if cipherSuite in CipherSuite.aes128GcmSuites: |
| 1117 keyLength = 16 | |
| 1118 ivLength = 4 | |
| 1119 createCipherFunc = createAESGCM | |
| 1120 elif cipherSuite in CipherSuite.aes128Suites: | |
| 1068 keyLength = 16 | 1121 keyLength = 16 |
| 1069 ivLength = 16 | 1122 ivLength = 16 |
| 1070 createCipherFunc = createAES | 1123 createCipherFunc = createAES |
| 1071 elif cipherSuite in CipherSuite.aes256Suites: | 1124 elif cipherSuite in CipherSuite.aes256Suites: |
| 1072 keyLength = 32 | 1125 keyLength = 32 |
| 1073 ivLength = 16 | 1126 ivLength = 16 |
| 1074 createCipherFunc = createAES | 1127 createCipherFunc = createAES |
| 1075 elif cipherSuite in CipherSuite.rc4Suites: | 1128 elif cipherSuite in CipherSuite.rc4Suites: |
| 1076 keyLength = 16 | 1129 keyLength = 16 |
| 1077 ivLength = 0 | 1130 ivLength = 0 |
| 1078 createCipherFunc = createRC4 | 1131 createCipherFunc = createRC4 |
| 1079 elif cipherSuite in CipherSuite.tripleDESSuites: | 1132 elif cipherSuite in CipherSuite.tripleDESSuites: |
| 1080 keyLength = 24 | 1133 keyLength = 24 |
| 1081 ivLength = 8 | 1134 ivLength = 8 |
| 1082 createCipherFunc = createTripleDES | 1135 createCipherFunc = createTripleDES |
| 1083 else: | 1136 else: |
| 1084 raise AssertionError() | 1137 raise AssertionError() |
| 1085 | 1138 |
| 1086 if cipherSuite in CipherSuite.shaSuites: | 1139 if cipherSuite in CipherSuite.aeadSuites: |
| 1140 macLength = 0 | |
| 1141 digestmod = None | |
| 1142 elif cipherSuite in CipherSuite.shaSuites: | |
| 1087 macLength = 20 | 1143 macLength = 20 |
| 1088 digestmod = hashlib.sha1 | 1144 digestmod = hashlib.sha1 |
| 1089 elif cipherSuite in CipherSuite.sha256Suites: | 1145 elif cipherSuite in CipherSuite.sha256Suites: |
| 1090 macLength = 32 | 1146 macLength = 32 |
| 1091 digestmod = hashlib.sha256 | 1147 digestmod = hashlib.sha256 |
| 1092 elif cipherSuite in CipherSuite.md5Suites: | 1148 elif cipherSuite in CipherSuite.md5Suites: |
| 1093 macLength = 16 | 1149 macLength = 16 |
| 1094 digestmod = hashlib.md5 | 1150 digestmod = hashlib.md5 |
| 1151 else: | |
| 1152 raise AssertionError() | |
| 1095 | 1153 |
| 1096 if self.version == (3,0): | 1154 if not digestmod: |
| 1155 createMACFunc = None | |
| 1156 elif self.version == (3,0): | |
| 1097 createMACFunc = createMAC_SSL | 1157 createMACFunc = createMAC_SSL |
| 1098 elif self.version in ((3,1), (3,2), (3,3)): | 1158 elif self.version in ((3,1), (3,2), (3,3)): |
| 1099 createMACFunc = createHMAC | 1159 createMACFunc = createHMAC |
| 1100 | 1160 |
| 1101 outputLength = (macLength*2) + (keyLength*2) + (ivLength*2) | 1161 outputLength = (macLength*2) + (keyLength*2) + (ivLength*2) |
| 1102 | 1162 |
| 1103 #Calculate Keying Material from Master Secret | 1163 #Calculate Keying Material from Master Secret |
| 1104 if self.version == (3,0): | 1164 if self.version == (3,0): |
| 1105 keyBlock = PRF_SSL(masterSecret, | 1165 keyBlock = PRF_SSL(masterSecret, |
| 1106 serverRandom + clientRandom, | 1166 serverRandom + clientRandom, |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 1121 #Slice up Keying Material | 1181 #Slice up Keying Material |
| 1122 clientPendingState = _ConnectionState() | 1182 clientPendingState = _ConnectionState() |
| 1123 serverPendingState = _ConnectionState() | 1183 serverPendingState = _ConnectionState() |
| 1124 p = Parser(keyBlock) | 1184 p = Parser(keyBlock) |
| 1125 clientMACBlock = p.getFixBytes(macLength) | 1185 clientMACBlock = p.getFixBytes(macLength) |
| 1126 serverMACBlock = p.getFixBytes(macLength) | 1186 serverMACBlock = p.getFixBytes(macLength) |
| 1127 clientKeyBlock = p.getFixBytes(keyLength) | 1187 clientKeyBlock = p.getFixBytes(keyLength) |
| 1128 serverKeyBlock = p.getFixBytes(keyLength) | 1188 serverKeyBlock = p.getFixBytes(keyLength) |
| 1129 clientIVBlock = p.getFixBytes(ivLength) | 1189 clientIVBlock = p.getFixBytes(ivLength) |
| 1130 serverIVBlock = p.getFixBytes(ivLength) | 1190 serverIVBlock = p.getFixBytes(ivLength) |
| 1131 clientPendingState.macContext = createMACFunc( | 1191 if digestmod: |
| 1132 compatHMAC(clientMACBlock), digestmod=digestmod) | 1192 # Legacy cipher. |
| 1133 serverPendingState.macContext = createMACFunc( | 1193 clientPendingState.macContext = createMACFunc( |
| 1134 compatHMAC(serverMACBlock), digestmod=digestmod) | 1194 compatHMAC(clientMACBlock), digestmod=digestmod) |
| 1135 clientPendingState.encContext = createCipherFunc(clientKeyBlock, | 1195 serverPendingState.macContext = createMACFunc( |
| 1136 clientIVBlock, | 1196 compatHMAC(serverMACBlock), digestmod=digestmod) |
| 1137 implementations) | 1197 clientPendingState.encContext = createCipherFunc(clientKeyBlock, |
| 1138 serverPendingState.encContext = createCipherFunc(serverKeyBlock, | 1198 clientIVBlock, |
| 1139 serverIVBlock, | 1199 implementations) |
| 1140 implementations) | 1200 serverPendingState.encContext = createCipherFunc(serverKeyBlock, |
| 1201 serverIVBlock, | |
| 1202 implementations) | |
| 1203 else: | |
| 1204 # AEAD. | |
| 1205 clientPendingState.macContext = None | |
| 1206 serverPendingState.macContext = None | |
| 1207 clientPendingState.encContext = createCipherFunc(clientKeyBlock, | |
| 1208 implementations) | |
| 1209 serverPendingState.encContext = createCipherFunc(serverKeyBlock, | |
| 1210 implementations) | |
| 1211 clientPendingState.fixedNonce = clientIVBlock | |
| 1212 serverPendingState.fixedNonce = serverIVBlock | |
| 1141 | 1213 |
| 1142 #Assign new connection states to pending states | 1214 #Assign new connection states to pending states |
| 1143 if self._client: | 1215 if self._client: |
| 1144 self._pendingWriteState = clientPendingState | 1216 self._pendingWriteState = clientPendingState |
| 1145 self._pendingReadState = serverPendingState | 1217 self._pendingReadState = serverPendingState |
| 1146 else: | 1218 else: |
| 1147 self._pendingWriteState = serverPendingState | 1219 self._pendingWriteState = serverPendingState |
| 1148 self._pendingReadState = clientPendingState | 1220 self._pendingReadState = clientPendingState |
| 1149 | 1221 |
| 1150 if self.version >= (3,2) and ivLength: | 1222 if self.version >= (3,2) and ivLength: |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 1168 imac_md5.update(compatHMAC(label + masterSecret + bytearray([0x36]*48))) | 1240 imac_md5.update(compatHMAC(label + masterSecret + bytearray([0x36]*48))) |
| 1169 imac_sha.update(compatHMAC(label + masterSecret + bytearray([0x36]*40))) | 1241 imac_sha.update(compatHMAC(label + masterSecret + bytearray([0x36]*40))) |
| 1170 | 1242 |
| 1171 md5Bytes = MD5(masterSecret + bytearray([0x5c]*48) + \ | 1243 md5Bytes = MD5(masterSecret + bytearray([0x5c]*48) + \ |
| 1172 bytearray(imac_md5.digest())) | 1244 bytearray(imac_md5.digest())) |
| 1173 shaBytes = SHA1(masterSecret + bytearray([0x5c]*40) + \ | 1245 shaBytes = SHA1(masterSecret + bytearray([0x5c]*40) + \ |
| 1174 bytearray(imac_sha.digest())) | 1246 bytearray(imac_sha.digest())) |
| 1175 | 1247 |
| 1176 return md5Bytes + shaBytes | 1248 return md5Bytes + shaBytes |
| 1177 | 1249 |
| OLD | NEW |