Chromium Code Reviews| 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 """ |
| (...skipping 1047 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1058 # Server Handshake Functions | 1058 # Server Handshake Functions |
| 1059 #********************************************************* | 1059 #********************************************************* |
| 1060 | 1060 |
| 1061 | 1061 |
| 1062 def handshakeServer(self, verifierDB=None, | 1062 def handshakeServer(self, verifierDB=None, |
| 1063 certChain=None, privateKey=None, reqCert=False, | 1063 certChain=None, privateKey=None, reqCert=False, |
| 1064 sessionCache=None, settings=None, checker=None, | 1064 sessionCache=None, settings=None, checker=None, |
| 1065 reqCAs = None, reqCertTypes = None, | 1065 reqCAs = None, reqCertTypes = None, |
| 1066 tacks=None, activationFlags=0, | 1066 tacks=None, activationFlags=0, |
| 1067 nextProtos=None, anon=False, | 1067 nextProtos=None, anon=False, |
| 1068 tlsIntolerant=None, signedCertTimestamps=None, | 1068 signedCertTimestamps=None, |
| 1069 fallbackSCSV=False, ocspResponse=None): | 1069 fallbackSCSV=False, ocspResponse=None): |
| 1070 """Perform a handshake in the role of server. | 1070 """Perform a handshake in the role of server. |
| 1071 | 1071 |
| 1072 This function performs an SSL or TLS handshake. Depending on | 1072 This function performs an SSL or TLS handshake. Depending on |
| 1073 the arguments and the behavior of the client, this function can | 1073 the arguments and the behavior of the client, this function can |
| 1074 perform an SRP, or certificate-based handshake. It | 1074 perform an SRP, or certificate-based handshake. It |
| 1075 can also perform a combined SRP and server-certificate | 1075 can also perform a combined SRP and server-certificate |
| 1076 handshake. | 1076 handshake. |
| 1077 | 1077 |
| 1078 Like any handshake function, this can be called on a closed | 1078 Like any handshake function, this can be called on a closed |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1132 | 1132 |
| 1133 @type reqCertTypes: list of int | 1133 @type reqCertTypes: list of int |
| 1134 @param reqCertTypes: A list of certificate_type values to be sent | 1134 @param reqCertTypes: A list of certificate_type values to be sent |
| 1135 along with a certificate request. This does not affect verification. | 1135 along with a certificate request. This does not affect verification. |
| 1136 | 1136 |
| 1137 @type nextProtos: list of strings. | 1137 @type nextProtos: list of strings. |
| 1138 @param nextProtos: A list of upper layer protocols to expose to the | 1138 @param nextProtos: A list of upper layer protocols to expose to the |
| 1139 clients through the Next-Protocol Negotiation Extension, | 1139 clients through the Next-Protocol Negotiation Extension, |
| 1140 if they support it. | 1140 if they support it. |
| 1141 | 1141 |
| 1142 @type tlsIntolerant: (int, int) or None | |
| 1143 @param tlsIntolerant: If tlsIntolerant is not None, the server will | |
| 1144 simulate TLS version intolerance by returning a fatal handshake_failure | |
| 1145 alert to all TLS versions tlsIntolerant or higher. | |
| 1146 | |
| 1147 @type signedCertTimestamps: str | 1142 @type signedCertTimestamps: str |
| 1148 @param signedCertTimestamps: A SignedCertificateTimestampList (as a | 1143 @param signedCertTimestamps: A SignedCertificateTimestampList (as a |
| 1149 binary 8-bit string) that will be sent as a TLS extension whenever | 1144 binary 8-bit string) that will be sent as a TLS extension whenever |
| 1150 the client announces support for the extension. | 1145 the client announces support for the extension. |
| 1151 | 1146 |
| 1152 @type fallbackSCSV: bool | 1147 @type fallbackSCSV: bool |
| 1153 @param fallbackSCSV: if true, the server will implement | 1148 @param fallbackSCSV: if true, the server will implement |
| 1154 TLS_FALLBACK_SCSV and thus reject connections using less than the | 1149 TLS_FALLBACK_SCSV and thus reject connections using less than the |
| 1155 server's maximum TLS version that include this cipher suite. | 1150 server's maximum TLS version that include this cipher suite. |
| 1156 | 1151 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1168 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed | 1163 @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed |
| 1169 without a preceding alert. | 1164 without a preceding alert. |
| 1170 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled. | 1165 @raise tlslite.errors.TLSAlert: If a TLS alert is signalled. |
| 1171 @raise tlslite.errors.TLSAuthenticationError: If the checker | 1166 @raise tlslite.errors.TLSAuthenticationError: If the checker |
| 1172 doesn't like the other party's authentication credentials. | 1167 doesn't like the other party's authentication credentials. |
| 1173 """ | 1168 """ |
| 1174 for result in self.handshakeServerAsync(verifierDB, | 1169 for result in self.handshakeServerAsync(verifierDB, |
| 1175 certChain, privateKey, reqCert, sessionCache, settings, | 1170 certChain, privateKey, reqCert, sessionCache, settings, |
| 1176 checker, reqCAs, reqCertTypes, | 1171 checker, reqCAs, reqCertTypes, |
| 1177 tacks=tacks, activationFlags=activationFlags, | 1172 tacks=tacks, activationFlags=activationFlags, |
| 1178 nextProtos=nextProtos, anon=anon, tlsIntolerant=tlsIntolerant, | 1173 nextProtos=nextProtos, anon=anon, |
| 1179 signedCertTimestamps=signedCertTimestamps, | 1174 signedCertTimestamps=signedCertTimestamps, |
| 1180 fallbackSCSV=fallbackSCSV, ocspResponse=ocspResponse): | 1175 fallbackSCSV=fallbackSCSV, ocspResponse=ocspResponse): |
| 1181 pass | 1176 pass |
| 1182 | 1177 |
| 1183 | 1178 |
| 1184 def handshakeServerAsync(self, verifierDB=None, | 1179 def handshakeServerAsync(self, verifierDB=None, |
| 1185 certChain=None, privateKey=None, reqCert=False, | 1180 certChain=None, privateKey=None, reqCert=False, |
| 1186 sessionCache=None, settings=None, checker=None, | 1181 sessionCache=None, settings=None, checker=None, |
| 1187 reqCAs=None, reqCertTypes=None, | 1182 reqCAs=None, reqCertTypes=None, |
| 1188 tacks=None, activationFlags=0, | 1183 tacks=None, activationFlags=0, |
| 1189 nextProtos=None, anon=False, | 1184 nextProtos=None, anon=False, |
| 1190 tlsIntolerant=None, | |
| 1191 signedCertTimestamps=None, | 1185 signedCertTimestamps=None, |
| 1192 fallbackSCSV=False, | 1186 fallbackSCSV=False, |
| 1193 ocspResponse=None | 1187 ocspResponse=None |
| 1194 ): | 1188 ): |
| 1195 """Start a server handshake operation on the TLS connection. | 1189 """Start a server handshake operation on the TLS connection. |
| 1196 | 1190 |
| 1197 This function returns a generator which behaves similarly to | 1191 This function returns a generator which behaves similarly to |
| 1198 handshakeServer(). Successive invocations of the generator | 1192 handshakeServer(). Successive invocations of the generator |
| 1199 will return 0 if it is waiting to read from the socket, 1 if it is | 1193 will return 0 if it is waiting to read from the socket, 1 if it is |
| 1200 waiting to write to the socket, or it will raise StopIteration | 1194 waiting to write to the socket, or it will raise StopIteration |
| 1201 if the handshake operation is complete. | 1195 if the handshake operation is complete. |
| 1202 | 1196 |
| 1203 @rtype: iterable | 1197 @rtype: iterable |
| 1204 @return: A generator; see above for details. | 1198 @return: A generator; see above for details. |
| 1205 """ | 1199 """ |
| 1206 handshaker = self._handshakeServerAsyncHelper(\ | 1200 handshaker = self._handshakeServerAsyncHelper(\ |
| 1207 verifierDB=verifierDB, certChain=certChain, | 1201 verifierDB=verifierDB, certChain=certChain, |
| 1208 privateKey=privateKey, reqCert=reqCert, | 1202 privateKey=privateKey, reqCert=reqCert, |
| 1209 sessionCache=sessionCache, settings=settings, | 1203 sessionCache=sessionCache, settings=settings, |
| 1210 reqCAs=reqCAs, reqCertTypes=reqCertTypes, | 1204 reqCAs=reqCAs, reqCertTypes=reqCertTypes, |
| 1211 tacks=tacks, activationFlags=activationFlags, | 1205 tacks=tacks, activationFlags=activationFlags, |
| 1212 nextProtos=nextProtos, anon=anon, | 1206 nextProtos=nextProtos, anon=anon, |
| 1213 tlsIntolerant=tlsIntolerant, | |
| 1214 signedCertTimestamps=signedCertTimestamps, | 1207 signedCertTimestamps=signedCertTimestamps, |
| 1215 fallbackSCSV=fallbackSCSV, | 1208 fallbackSCSV=fallbackSCSV, |
| 1216 ocspResponse=ocspResponse) | 1209 ocspResponse=ocspResponse) |
| 1217 for result in self._handshakeWrapperAsync(handshaker, checker): | 1210 for result in self._handshakeWrapperAsync(handshaker, checker): |
| 1218 yield result | 1211 yield result |
| 1219 | 1212 |
| 1220 | 1213 |
| 1221 def _handshakeServerAsyncHelper(self, verifierDB, | 1214 def _handshakeServerAsyncHelper(self, verifierDB, |
| 1222 certChain, privateKey, reqCert, sessionCache, | 1215 certChain, privateKey, reqCert, sessionCache, |
| 1223 settings, reqCAs, reqCertTypes, | 1216 settings, reqCAs, reqCertTypes, |
| 1224 tacks, activationFlags, | 1217 tacks, activationFlags, |
| 1225 nextProtos, anon, | 1218 nextProtos, anon, |
| 1226 tlsIntolerant, signedCertTimestamps, fallbackSCSV, | 1219 signedCertTimestamps, fallbackSCSV, |
| 1227 ocspResponse): | 1220 ocspResponse): |
| 1228 | 1221 |
| 1229 self._handshakeStart(client=False) | 1222 self._handshakeStart(client=False) |
| 1230 | 1223 |
| 1231 if (not verifierDB) and (not certChain) and not anon: | 1224 if (not verifierDB) and (not certChain) and not anon: |
| 1232 raise ValueError("Caller passed no authentication credentials") | 1225 raise ValueError("Caller passed no authentication credentials") |
| 1233 if certChain and not privateKey: | 1226 if certChain and not privateKey: |
| 1234 raise ValueError("Caller passed a certChain but no privateKey") | 1227 raise ValueError("Caller passed a certChain but no privateKey") |
| 1235 if privateKey and not certChain: | 1228 if privateKey and not certChain: |
| 1236 raise ValueError("Caller passed a privateKey but no certChain") | 1229 raise ValueError("Caller passed a privateKey but no certChain") |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 1254 if not settings: | 1247 if not settings: |
| 1255 settings = HandshakeSettings() | 1248 settings = HandshakeSettings() |
| 1256 settings = settings._filter() | 1249 settings = settings._filter() |
| 1257 | 1250 |
| 1258 # OK Start exchanging messages | 1251 # OK Start exchanging messages |
| 1259 # ****************************** | 1252 # ****************************** |
| 1260 | 1253 |
| 1261 # Handle ClientHello and resumption | 1254 # Handle ClientHello and resumption |
| 1262 for result in self._serverGetClientHello(settings, certChain,\ | 1255 for result in self._serverGetClientHello(settings, certChain,\ |
| 1263 verifierDB, sessionCache, | 1256 verifierDB, sessionCache, |
| 1264 anon, tlsIntolerant, fallbackSCSV): | 1257 anon, fallbackSCSV): |
| 1265 if result in (0,1): yield result | 1258 if result in (0,1): yield result |
| 1266 elif result == None: | 1259 elif result == None: |
| 1267 self._handshakeDone(resumed=True) | 1260 self._handshakeDone(resumed=True) |
| 1268 return # Handshake was resumed, we're done | 1261 return # Handshake was resumed, we're done |
| 1269 else: break | 1262 else: break |
| 1270 (clientHello, cipherSuite) = result | 1263 (clientHello, cipherSuite) = result |
| 1271 | 1264 |
| 1272 #If not a resumption... | 1265 #If not a resumption... |
| 1273 | 1266 |
| 1274 # Create the ServerHello message | 1267 # Create the ServerHello message |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1369 tackExt, serverHello.tackExt!=None, serverName) | 1362 tackExt, serverHello.tackExt!=None, serverName) |
| 1370 | 1363 |
| 1371 #Add the session object to the session cache | 1364 #Add the session object to the session cache |
| 1372 if sessionCache and sessionID: | 1365 if sessionCache and sessionID: |
| 1373 sessionCache[sessionID] = self.session | 1366 sessionCache[sessionID] = self.session |
| 1374 | 1367 |
| 1375 self._handshakeDone(resumed=False) | 1368 self._handshakeDone(resumed=False) |
| 1376 | 1369 |
| 1377 | 1370 |
| 1378 def _serverGetClientHello(self, settings, certChain, verifierDB, | 1371 def _serverGetClientHello(self, settings, certChain, verifierDB, |
| 1379 sessionCache, anon, tlsIntolerant, fallbackSCSV) : | 1372 sessionCache, anon, fallbackSCSV): |
| 1380 #Initialize acceptable cipher suites | 1373 #Initialize acceptable cipher suites |
| 1381 cipherSuites = [] | 1374 cipherSuites = [] |
| 1382 if verifierDB: | 1375 if verifierDB: |
| 1383 if certChain: | 1376 if certChain: |
| 1384 cipherSuites += \ | 1377 cipherSuites += \ |
| 1385 CipherSuite.getSrpCertSuites(settings) | 1378 CipherSuite.getSrpCertSuites(settings) |
| 1386 cipherSuites += CipherSuite.getSrpSuites(settings) | 1379 cipherSuites += CipherSuite.getSrpSuites(settings) |
| 1387 elif certChain: | 1380 elif certChain: |
| 1388 cipherSuites += CipherSuite.getCertSuites(settings) | 1381 cipherSuites += CipherSuite.getCertSuites(settings) |
| 1389 cipherSuites += CipherSuite.getDheCertSuites(settings) | 1382 cipherSuites += CipherSuite.getDheCertSuites(settings) |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1406 | 1399 |
| 1407 #If client's version is too low, reject it | 1400 #If client's version is too low, reject it |
| 1408 if clientHello.client_version < settings.minVersion: | 1401 if clientHello.client_version < settings.minVersion: |
| 1409 self.version = settings.minVersion | 1402 self.version = settings.minVersion |
| 1410 for result in self._sendError(\ | 1403 for result in self._sendError(\ |
| 1411 AlertDescription.protocol_version, | 1404 AlertDescription.protocol_version, |
| 1412 "Too old version: %s" % str(clientHello.client_version)): | 1405 "Too old version: %s" % str(clientHello.client_version)): |
| 1413 yield result | 1406 yield result |
| 1414 | 1407 |
| 1415 #If simulating TLS intolerance, reject certain TLS versions. | 1408 #If simulating TLS intolerance, reject certain TLS versions. |
| 1416 elif (tlsIntolerant is not None and | 1409 elif (settings.tlsIntolerant is not None and |
| 1417 clientHello.client_version >= tlsIntolerant): | 1410 clientHello.client_version >= settings.tlsIntolerant): |
| 1418 for result in self._sendError(\ | 1411 if settings.tlsIntoleranceType == "alert": |
| 1412 for result in self._sendError(\ | |
| 1419 AlertDescription.handshake_failure): | 1413 AlertDescription.handshake_failure): |
| 1420 yield result | 1414 yield result |
|
wtc
2014/06/24 21:33:29
Should we also call
raise TLSUnsupportedError(
davidben
2014/06/25 21:19:57
self._sendError actually raises TLSLocalAlert for
| |
| 1415 elif settings.tlsIntoleranceType == "close": | |
| 1416 self._abruptClose() | |
| 1417 raise TLSUnsupportedError("Simulating version intolerance") | |
| 1418 elif settings.tlsIntoleranceType == "reset": | |
| 1419 self._abruptClose(reset=True) | |
| 1420 raise TLSUnsupportedError("Simulating version intolerance") | |
| 1421 else: | |
| 1422 raise ValueError("Unknown intolerance type: '%s'" % | |
| 1423 settings.tlsIntoleranceType) | |
| 1421 | 1424 |
| 1422 #If client's version is too high, propose my highest version | 1425 #If client's version is too high, propose my highest version |
| 1423 elif clientHello.client_version > settings.maxVersion: | 1426 elif clientHello.client_version > settings.maxVersion: |
| 1424 self.version = settings.maxVersion | 1427 self.version = settings.maxVersion |
| 1425 | 1428 |
| 1426 #Detect if the client performed an inappropriate fallback. | 1429 #Detect if the client performed an inappropriate fallback. |
| 1427 elif fallbackSCSV and clientHello.client_version < settings.maxVersion: | 1430 elif fallbackSCSV and clientHello.client_version < settings.maxVersion: |
| 1428 if CipherSuite.TLS_FALLBACK_SCSV in clientHello.cipher_suites: | 1431 if CipherSuite.TLS_FALLBACK_SCSV in clientHello.cipher_suites: |
| 1429 for result in self._sendError(\ | 1432 for result in self._sendError(\ |
| 1430 AlertDescription.inappropriate_fallback): | 1433 AlertDescription.inappropriate_fallback): |
| (...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1925 except TLSAlert as alert: | 1928 except TLSAlert as alert: |
| 1926 if not self.fault: | 1929 if not self.fault: |
| 1927 raise | 1930 raise |
| 1928 if alert.description not in Fault.faultAlerts[self.fault]: | 1931 if alert.description not in Fault.faultAlerts[self.fault]: |
| 1929 raise TLSFaultError(str(alert)) | 1932 raise TLSFaultError(str(alert)) |
| 1930 else: | 1933 else: |
| 1931 pass | 1934 pass |
| 1932 except: | 1935 except: |
| 1933 self._shutdown(False) | 1936 self._shutdown(False) |
| 1934 raise | 1937 raise |
| OLD | NEW |