OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright 2013 The Chromium Authors. All rights reserved. | 2 # Copyright 2013 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """This is a simple HTTP/FTP/TCP/UDP/BASIC_AUTH_PROXY/WEBSOCKET server used for | 6 """This is a simple HTTP/FTP/TCP/UDP/BASIC_AUTH_PROXY/WEBSOCKET server used for |
7 testing Chrome. | 7 testing Chrome. |
8 | 8 |
9 It supports several test URLs, as specified by the handlers in TestPageHandler. | 9 It supports several test URLs, as specified by the handlers in TestPageHandler. |
10 By default, it listens on an ephemeral port and sends the port number back to | 10 By default, it listens on an ephemeral port and sends the port number back to |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 | 154 |
155 class HTTPSServer(tlslite.api.TLSSocketServerMixIn, | 155 class HTTPSServer(tlslite.api.TLSSocketServerMixIn, |
156 testserver_base.ClientRestrictingServerMixIn, | 156 testserver_base.ClientRestrictingServerMixIn, |
157 testserver_base.BrokenPipeHandlerMixIn, | 157 testserver_base.BrokenPipeHandlerMixIn, |
158 testserver_base.StoppableHTTPServer): | 158 testserver_base.StoppableHTTPServer): |
159 """This is a specialization of StoppableHTTPServer that add https support and | 159 """This is a specialization of StoppableHTTPServer that add https support and |
160 client verification.""" | 160 client verification.""" |
161 | 161 |
162 def __init__(self, server_address, request_hander_class, pem_cert_and_key, | 162 def __init__(self, server_address, request_hander_class, pem_cert_and_key, |
163 ssl_client_auth, ssl_client_cas, ssl_client_cert_types, | 163 ssl_client_auth, ssl_client_cas, ssl_client_cert_types, |
164 ssl_bulk_ciphers, ssl_key_exchanges, npn_protocols, | 164 ssl_bulk_ciphers, ssl_key_exchanges, alpn_protocols, |
165 record_resume_info, tls_intolerant, | 165 npn_protocols, record_resume_info, tls_intolerant, |
166 tls_intolerance_type, signed_cert_timestamps, | 166 tls_intolerance_type, signed_cert_timestamps, |
167 fallback_scsv_enabled, ocsp_response, | 167 fallback_scsv_enabled, ocsp_response, alert_after_handshake, |
168 alert_after_handshake, disable_channel_id, disable_ems, | 168 disable_channel_id, disable_ems, token_binding_params): |
169 token_binding_params): | |
170 self.cert_chain = tlslite.api.X509CertChain() | 169 self.cert_chain = tlslite.api.X509CertChain() |
171 self.cert_chain.parsePemList(pem_cert_and_key) | 170 self.cert_chain.parsePemList(pem_cert_and_key) |
172 # Force using only python implementation - otherwise behavior is different | 171 # Force using only python implementation - otherwise behavior is different |
173 # depending on whether m2crypto Python module is present (error is thrown | 172 # depending on whether m2crypto Python module is present (error is thrown |
174 # when it is). m2crypto uses a C (based on OpenSSL) implementation under | 173 # when it is). m2crypto uses a C (based on OpenSSL) implementation under |
175 # the hood. | 174 # the hood. |
176 self.private_key = tlslite.api.parsePEMKey(pem_cert_and_key, | 175 self.private_key = tlslite.api.parsePEMKey(pem_cert_and_key, |
177 private=True, | 176 private=True, |
178 implementations=['python']) | 177 implementations=['python']) |
179 self.ssl_client_auth = ssl_client_auth | 178 self.ssl_client_auth = ssl_client_auth |
180 self.ssl_client_cas = [] | 179 self.ssl_client_cas = [] |
181 self.ssl_client_cert_types = [] | 180 self.ssl_client_cert_types = [] |
182 self.npn_protocols = npn_protocols | |
183 self.signed_cert_timestamps = signed_cert_timestamps | 181 self.signed_cert_timestamps = signed_cert_timestamps |
184 self.fallback_scsv_enabled = fallback_scsv_enabled | 182 self.fallback_scsv_enabled = fallback_scsv_enabled |
185 self.ocsp_response = ocsp_response | 183 self.ocsp_response = ocsp_response |
186 | 184 |
187 if ssl_client_auth: | 185 if ssl_client_auth: |
188 for ca_file in ssl_client_cas: | 186 for ca_file in ssl_client_cas: |
189 s = open(ca_file).read() | 187 s = open(ca_file).read() |
190 x509 = tlslite.api.X509() | 188 x509 = tlslite.api.X509() |
191 x509.parse(s) | 189 x509.parse(s) |
192 self.ssl_client_cas.append(x509.subject) | 190 self.ssl_client_cas.append(x509.subject) |
(...skipping 15 matching lines...) Expand all Loading... |
208 self.ssl_handshake_settings.tlsIntolerant = (3, tls_intolerant) | 206 self.ssl_handshake_settings.tlsIntolerant = (3, tls_intolerant) |
209 self.ssl_handshake_settings.tlsIntoleranceType = tls_intolerance_type | 207 self.ssl_handshake_settings.tlsIntoleranceType = tls_intolerance_type |
210 if alert_after_handshake: | 208 if alert_after_handshake: |
211 self.ssl_handshake_settings.alertAfterHandshake = True | 209 self.ssl_handshake_settings.alertAfterHandshake = True |
212 if disable_channel_id: | 210 if disable_channel_id: |
213 self.ssl_handshake_settings.enableChannelID = False | 211 self.ssl_handshake_settings.enableChannelID = False |
214 if disable_ems: | 212 if disable_ems: |
215 self.ssl_handshake_settings.enableExtendedMasterSecret = False | 213 self.ssl_handshake_settings.enableExtendedMasterSecret = False |
216 self.ssl_handshake_settings.supportedTokenBindingParams = \ | 214 self.ssl_handshake_settings.supportedTokenBindingParams = \ |
217 token_binding_params | 215 token_binding_params |
| 216 self.ssl_handshake_settings.alpnProtos=alpn_protocols; |
| 217 self.ssl_handshake_settings.nextProtos=npn_protocols; |
218 | 218 |
219 if record_resume_info: | 219 if record_resume_info: |
220 # If record_resume_info is true then we'll replace the session cache with | 220 # If record_resume_info is true then we'll replace the session cache with |
221 # an object that records the lookups and inserts that it sees. | 221 # an object that records the lookups and inserts that it sees. |
222 self.session_cache = RecordingSSLSessionCache() | 222 self.session_cache = RecordingSSLSessionCache() |
223 else: | 223 else: |
224 self.session_cache = tlslite.api.SessionCache() | 224 self.session_cache = tlslite.api.SessionCache() |
225 testserver_base.StoppableHTTPServer.__init__(self, | 225 testserver_base.StoppableHTTPServer.__init__(self, |
226 server_address, | 226 server_address, |
227 request_hander_class) | 227 request_hander_class) |
228 | 228 |
229 def handshake(self, tlsConnection): | 229 def handshake(self, tlsConnection): |
230 """Creates the SSL connection.""" | 230 """Creates the SSL connection.""" |
231 | 231 |
232 try: | 232 try: |
233 self.tlsConnection = tlsConnection | 233 self.tlsConnection = tlsConnection |
234 tlsConnection.handshakeServer(certChain=self.cert_chain, | 234 tlsConnection.handshakeServer(certChain=self.cert_chain, |
235 privateKey=self.private_key, | 235 privateKey=self.private_key, |
236 sessionCache=self.session_cache, | 236 sessionCache=self.session_cache, |
237 reqCert=self.ssl_client_auth, | 237 reqCert=self.ssl_client_auth, |
238 settings=self.ssl_handshake_settings, | 238 settings=self.ssl_handshake_settings, |
239 reqCAs=self.ssl_client_cas, | 239 reqCAs=self.ssl_client_cas, |
240 reqCertTypes=self.ssl_client_cert_types, | 240 reqCertTypes=self.ssl_client_cert_types, |
241 nextProtos=self.npn_protocols, | |
242 signedCertTimestamps= | 241 signedCertTimestamps= |
243 self.signed_cert_timestamps, | 242 self.signed_cert_timestamps, |
244 fallbackSCSV=self.fallback_scsv_enabled, | 243 fallbackSCSV=self.fallback_scsv_enabled, |
245 ocspResponse = self.ocsp_response) | 244 ocspResponse = self.ocsp_response) |
246 tlsConnection.ignoreAbruptClose = True | 245 tlsConnection.ignoreAbruptClose = True |
247 return True | 246 return True |
248 except tlslite.api.TLSAbruptCloseError: | 247 except tlslite.api.TLSAbruptCloseError: |
249 # Ignore abrupt close. | 248 # Ignore abrupt close. |
250 return True | 249 return True |
251 except tlslite.api.TLSError, error: | 250 except tlslite.api.TLSError, error: |
(...skipping 1733 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1985 stapled_ocsp_response = None | 1984 stapled_ocsp_response = None |
1986 if self.options.staple_ocsp_response: | 1985 if self.options.staple_ocsp_response: |
1987 stapled_ocsp_response = ocsp_der | 1986 stapled_ocsp_response = ocsp_der |
1988 | 1987 |
1989 server = HTTPSServer((host, port), TestPageHandler, pem_cert_and_key, | 1988 server = HTTPSServer((host, port), TestPageHandler, pem_cert_and_key, |
1990 self.options.ssl_client_auth, | 1989 self.options.ssl_client_auth, |
1991 self.options.ssl_client_ca, | 1990 self.options.ssl_client_ca, |
1992 self.options.ssl_client_cert_type, | 1991 self.options.ssl_client_cert_type, |
1993 self.options.ssl_bulk_cipher, | 1992 self.options.ssl_bulk_cipher, |
1994 self.options.ssl_key_exchange, | 1993 self.options.ssl_key_exchange, |
| 1994 self.options.alpn_protocols, |
1995 self.options.npn_protocols, | 1995 self.options.npn_protocols, |
1996 self.options.record_resume, | 1996 self.options.record_resume, |
1997 self.options.tls_intolerant, | 1997 self.options.tls_intolerant, |
1998 self.options.tls_intolerance_type, | 1998 self.options.tls_intolerance_type, |
1999 self.options.signed_cert_timestamps_tls_ext.decode( | 1999 self.options.signed_cert_timestamps_tls_ext.decode( |
2000 "base64"), | 2000 "base64"), |
2001 self.options.fallback_scsv, | 2001 self.options.fallback_scsv, |
2002 stapled_ocsp_response, | 2002 stapled_ocsp_response, |
2003 self.options.alert_after_handshake, | 2003 self.options.alert_after_handshake, |
2004 self.options.disable_channel_id, | 2004 self.options.disable_channel_id, |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2219 'indicating multiple algorithms should be ' | 2219 'indicating multiple algorithms should be ' |
2220 'enabled.'); | 2220 'enabled.'); |
2221 self.option_parser.add_option('--ssl-key-exchange', action='append', | 2221 self.option_parser.add_option('--ssl-key-exchange', action='append', |
2222 help='Specify the key exchange algorithm(s)' | 2222 help='Specify the key exchange algorithm(s)' |
2223 'that will be accepted by the SSL server. ' | 2223 'that will be accepted by the SSL server. ' |
2224 'Valid values are "rsa", "dhe_rsa", ' | 2224 'Valid values are "rsa", "dhe_rsa", ' |
2225 '"ecdhe_rsa". If omitted, all algorithms ' | 2225 '"ecdhe_rsa". If omitted, all algorithms ' |
2226 'will be used. This option may appear ' | 2226 'will be used. This option may appear ' |
2227 'multiple times, indicating multiple ' | 2227 'multiple times, indicating multiple ' |
2228 'algorithms should be enabled.'); | 2228 'algorithms should be enabled.'); |
2229 # TODO(davidben): Add ALPN support to tlslite. | 2229 self.option_parser.add_option('--alpn-protocols', action='append', |
| 2230 help='Specify the list of ALPN protocols. ' |
| 2231 'The server will not send an ALPN response ' |
| 2232 'if this list does not overlap with the ' |
| 2233 'list of protocols the client advertises.') |
2230 self.option_parser.add_option('--npn-protocols', action='append', | 2234 self.option_parser.add_option('--npn-protocols', action='append', |
2231 help='Specify the list of protocols sent in' | 2235 help='Specify the list of protocols sent in ' |
2232 'an NPN response. The server will not' | 2236 'an NPN response. The server will not' |
2233 'support NPN if the list is empty.') | 2237 'support NPN if the list is empty.') |
2234 self.option_parser.add_option('--file-root-url', default='/files/', | 2238 self.option_parser.add_option('--file-root-url', default='/files/', |
2235 help='Specify a root URL for files served.') | 2239 help='Specify a root URL for files served.') |
2236 # TODO(ricea): Generalize this to support basic auth for HTTP too. | 2240 # TODO(ricea): Generalize this to support basic auth for HTTP too. |
2237 self.option_parser.add_option('--ws-basic-auth', action='store_true', | 2241 self.option_parser.add_option('--ws-basic-auth', action='store_true', |
2238 dest='ws_basic_auth', | 2242 dest='ws_basic_auth', |
2239 help='Enable basic-auth for WebSocket') | 2243 help='Enable basic-auth for WebSocket') |
2240 self.option_parser.add_option('--ocsp-server-unavailable', | 2244 self.option_parser.add_option('--ocsp-server-unavailable', |
2241 dest='ocsp_server_unavailable', | 2245 dest='ocsp_server_unavailable', |
(...skipping 13 matching lines...) Expand all Loading... |
2255 'an anonymous user.') | 2259 'an anonymous user.') |
2256 self.option_parser.add_option('--disable-channel-id', action='store_true') | 2260 self.option_parser.add_option('--disable-channel-id', action='store_true') |
2257 self.option_parser.add_option('--disable-extended-master-secret', | 2261 self.option_parser.add_option('--disable-extended-master-secret', |
2258 action='store_true') | 2262 action='store_true') |
2259 self.option_parser.add_option('--token-binding-params', action='append', | 2263 self.option_parser.add_option('--token-binding-params', action='append', |
2260 default=[], type='int') | 2264 default=[], type='int') |
2261 | 2265 |
2262 | 2266 |
2263 if __name__ == '__main__': | 2267 if __name__ == '__main__': |
2264 sys.exit(ServerRunner().main()) | 2268 sys.exit(ServerRunner().main()) |
OLD | NEW |