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 |