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 |