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 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
145 | 145 |
146 | 146 |
147 class HTTPSServer(tlslite.api.TLSSocketServerMixIn, | 147 class HTTPSServer(tlslite.api.TLSSocketServerMixIn, |
148 testserver_base.ClientRestrictingServerMixIn, | 148 testserver_base.ClientRestrictingServerMixIn, |
149 testserver_base.BrokenPipeHandlerMixIn, | 149 testserver_base.BrokenPipeHandlerMixIn, |
150 testserver_base.StoppableHTTPServer): | 150 testserver_base.StoppableHTTPServer): |
151 """This is a specialization of StoppableHTTPServer that add https support and | 151 """This is a specialization of StoppableHTTPServer that add https support and |
152 client verification.""" | 152 client verification.""" |
153 | 153 |
154 def __init__(self, server_address, request_hander_class, pem_cert_and_key, | 154 def __init__(self, server_address, request_hander_class, pem_cert_and_key, |
155 ssl_client_auth, ssl_client_cas, | 155 ssl_client_auth, ssl_client_cas, ssl_client_cert_types, |
156 ssl_bulk_ciphers, ssl_key_exchanges, enable_npn, | 156 ssl_bulk_ciphers, ssl_key_exchanges, enable_npn, |
157 record_resume_info, tls_intolerant, signed_cert_timestamps, | 157 record_resume_info, tls_intolerant, signed_cert_timestamps, |
158 fallback_scsv_enabled, ocsp_response): | 158 fallback_scsv_enabled, ocsp_response): |
159 self.cert_chain = tlslite.api.X509CertChain() | 159 self.cert_chain = tlslite.api.X509CertChain() |
160 self.cert_chain.parsePemList(pem_cert_and_key) | 160 self.cert_chain.parsePemList(pem_cert_and_key) |
161 # Force using only python implementation - otherwise behavior is different | 161 # Force using only python implementation - otherwise behavior is different |
162 # depending on whether m2crypto Python module is present (error is thrown | 162 # depending on whether m2crypto Python module is present (error is thrown |
163 # when it is). m2crypto uses a C (based on OpenSSL) implementation under | 163 # when it is). m2crypto uses a C (based on OpenSSL) implementation under |
164 # the hood. | 164 # the hood. |
165 self.private_key = tlslite.api.parsePEMKey(pem_cert_and_key, | 165 self.private_key = tlslite.api.parsePEMKey(pem_cert_and_key, |
166 private=True, | 166 private=True, |
167 implementations=['python']) | 167 implementations=['python']) |
168 self.ssl_client_auth = ssl_client_auth | 168 self.ssl_client_auth = ssl_client_auth |
169 self.ssl_client_cas = [] | 169 self.ssl_client_cas = [] |
170 self.ssl_client_cert_types = [] | |
170 if enable_npn: | 171 if enable_npn: |
171 self.next_protos = ['http/1.1'] | 172 self.next_protos = ['http/1.1'] |
172 else: | 173 else: |
173 self.next_protos = None | 174 self.next_protos = None |
174 if tls_intolerant == 0: | 175 if tls_intolerant == 0: |
175 self.tls_intolerant = None | 176 self.tls_intolerant = None |
176 else: | 177 else: |
177 self.tls_intolerant = (3, tls_intolerant) | 178 self.tls_intolerant = (3, tls_intolerant) |
178 self.signed_cert_timestamps = signed_cert_timestamps | 179 self.signed_cert_timestamps = signed_cert_timestamps |
179 self.fallback_scsv_enabled = fallback_scsv_enabled | 180 self.fallback_scsv_enabled = fallback_scsv_enabled |
180 self.ocsp_response = ocsp_response | 181 self.ocsp_response = ocsp_response |
181 | 182 |
182 for ca_file in ssl_client_cas: | 183 if ssl_client_auth: |
183 s = open(ca_file).read() | 184 for ca_file in ssl_client_cas: |
184 x509 = tlslite.api.X509() | 185 s = open(ca_file).read() |
185 x509.parse(s) | 186 x509 = tlslite.api.X509() |
186 self.ssl_client_cas.append(x509.subject) | 187 x509.parse(s) |
188 self.ssl_client_cas.append(x509.subject) | |
189 | |
190 for key_type in ssl_client_cert_types: | |
wtc
2014/04/25 18:52:40
Nit: key_type => cert_type ?
davidben
2014/04/25 20:52:31
Done.
| |
191 self.ssl_client_cert_types.append({ | |
192 "rsa_sign": tlslite.api.ClientCertificateType.rsa_sign, | |
193 "dss_sign": tlslite.api.ClientCertificateType.dss_sign, | |
194 "ecdsa_sign": tlslite.api.ClientCertificateType.ecdsa_sign, | |
195 }[key_type]) | |
196 | |
187 self.ssl_handshake_settings = tlslite.api.HandshakeSettings() | 197 self.ssl_handshake_settings = tlslite.api.HandshakeSettings() |
188 if ssl_bulk_ciphers is not None: | 198 if ssl_bulk_ciphers is not None: |
189 self.ssl_handshake_settings.cipherNames = ssl_bulk_ciphers | 199 self.ssl_handshake_settings.cipherNames = ssl_bulk_ciphers |
190 if ssl_key_exchanges is not None: | 200 if ssl_key_exchanges is not None: |
191 self.ssl_handshake_settings.keyExchangeNames = ssl_key_exchanges | 201 self.ssl_handshake_settings.keyExchangeNames = ssl_key_exchanges |
192 | 202 |
193 if record_resume_info: | 203 if record_resume_info: |
194 # If record_resume_info is true then we'll replace the session cache with | 204 # If record_resume_info is true then we'll replace the session cache with |
195 # an object that records the lookups and inserts that it sees. | 205 # an object that records the lookups and inserts that it sees. |
196 self.session_cache = RecordingSSLSessionCache() | 206 self.session_cache = RecordingSSLSessionCache() |
197 else: | 207 else: |
198 self.session_cache = tlslite.api.SessionCache() | 208 self.session_cache = tlslite.api.SessionCache() |
199 testserver_base.StoppableHTTPServer.__init__(self, | 209 testserver_base.StoppableHTTPServer.__init__(self, |
200 server_address, | 210 server_address, |
201 request_hander_class) | 211 request_hander_class) |
202 | 212 |
203 def handshake(self, tlsConnection): | 213 def handshake(self, tlsConnection): |
204 """Creates the SSL connection.""" | 214 """Creates the SSL connection.""" |
205 | 215 |
206 try: | 216 try: |
207 self.tlsConnection = tlsConnection | 217 self.tlsConnection = tlsConnection |
208 tlsConnection.handshakeServer(certChain=self.cert_chain, | 218 tlsConnection.handshakeServer(certChain=self.cert_chain, |
209 privateKey=self.private_key, | 219 privateKey=self.private_key, |
210 sessionCache=self.session_cache, | 220 sessionCache=self.session_cache, |
211 reqCert=self.ssl_client_auth, | 221 reqCert=self.ssl_client_auth, |
212 settings=self.ssl_handshake_settings, | 222 settings=self.ssl_handshake_settings, |
213 reqCAs=self.ssl_client_cas, | 223 reqCAs=self.ssl_client_cas, |
224 reqCertTypes=self.ssl_client_cert_types, | |
214 nextProtos=self.next_protos, | 225 nextProtos=self.next_protos, |
215 tlsIntolerant=self.tls_intolerant, | 226 tlsIntolerant=self.tls_intolerant, |
216 signedCertTimestamps= | 227 signedCertTimestamps= |
217 self.signed_cert_timestamps, | 228 self.signed_cert_timestamps, |
218 fallbackSCSV=self.fallback_scsv_enabled, | 229 fallbackSCSV=self.fallback_scsv_enabled, |
219 ocspResponse = self.ocsp_response) | 230 ocspResponse = self.ocsp_response) |
220 tlsConnection.ignoreAbruptClose = True | 231 tlsConnection.ignoreAbruptClose = True |
221 return True | 232 return True |
222 except tlslite.api.TLSAbruptCloseError: | 233 except tlslite.api.TLSAbruptCloseError: |
223 # Ignore abrupt close. | 234 # Ignore abrupt close. |
(...skipping 1758 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1982 'specified trusted client CA file not found: ' + ca_cert + | 1993 'specified trusted client CA file not found: ' + ca_cert + |
1983 ' exiting...') | 1994 ' exiting...') |
1984 | 1995 |
1985 stapled_ocsp_response = None | 1996 stapled_ocsp_response = None |
1986 if self.__ocsp_server and self.options.staple_ocsp_response: | 1997 if self.__ocsp_server and self.options.staple_ocsp_response: |
1987 stapled_ocsp_response = self.__ocsp_server.ocsp_response | 1998 stapled_ocsp_response = self.__ocsp_server.ocsp_response |
1988 | 1999 |
1989 server = HTTPSServer((host, port), TestPageHandler, pem_cert_and_key, | 2000 server = HTTPSServer((host, port), TestPageHandler, pem_cert_and_key, |
1990 self.options.ssl_client_auth, | 2001 self.options.ssl_client_auth, |
1991 self.options.ssl_client_ca, | 2002 self.options.ssl_client_ca, |
2003 self.options.ssl_client_cert_type, | |
1992 self.options.ssl_bulk_cipher, | 2004 self.options.ssl_bulk_cipher, |
1993 self.options.ssl_key_exchange, | 2005 self.options.ssl_key_exchange, |
1994 self.options.enable_npn, | 2006 self.options.enable_npn, |
1995 self.options.record_resume, | 2007 self.options.record_resume, |
1996 self.options.tls_intolerant, | 2008 self.options.tls_intolerant, |
1997 self.options.signed_cert_timestamps_tls_ext.decode( | 2009 self.options.signed_cert_timestamps_tls_ext.decode( |
1998 "base64"), | 2010 "base64"), |
1999 self.options.fallback_scsv, | 2011 self.options.fallback_scsv, |
2000 stapled_ocsp_response) | 2012 stapled_ocsp_response) |
2001 print 'HTTPS server started on %s:%d...' % (host, server.server_port) | 2013 print 'HTTPS server started on %s:%d...' % (host, server.server_port) |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2165 help='Require SSL client auth on every ' | 2177 help='Require SSL client auth on every ' |
2166 'connection.') | 2178 'connection.') |
2167 self.option_parser.add_option('--ssl-client-ca', action='append', | 2179 self.option_parser.add_option('--ssl-client-ca', action='append', |
2168 default=[], help='Specify that the client ' | 2180 default=[], help='Specify that the client ' |
2169 'certificate request should include the CA ' | 2181 'certificate request should include the CA ' |
2170 'named in the subject of the DER-encoded ' | 2182 'named in the subject of the DER-encoded ' |
2171 'certificate contained in the specified ' | 2183 'certificate contained in the specified ' |
2172 'file. This option may appear multiple ' | 2184 'file. This option may appear multiple ' |
2173 'times, indicating multiple CA names should ' | 2185 'times, indicating multiple CA names should ' |
2174 'be sent in the request.') | 2186 'be sent in the request.') |
2187 self.option_parser.add_option('--ssl-client-cert-type', action='append', | |
2188 default=[], help='Specify that the client ' | |
2189 'certificate request should include the ' | |
2190 'specified certificate_type value. This ' | |
2191 'option may appear multiple times, ' | |
2192 'indicating multiple values should be send ' | |
2193 'in the request. Valid values are ' | |
2194 '"rsa_sign", "dss_sign", and "ecdsa_sign". ' | |
2195 'If omitted, "rsa_sign" will be used.') | |
2175 self.option_parser.add_option('--ssl-bulk-cipher', action='append', | 2196 self.option_parser.add_option('--ssl-bulk-cipher', action='append', |
2176 help='Specify the bulk encryption ' | 2197 help='Specify the bulk encryption ' |
2177 'algorithm(s) that will be accepted by the ' | 2198 'algorithm(s) that will be accepted by the ' |
2178 'SSL server. Valid values are "aes256", ' | 2199 'SSL server. Valid values are "aes256", ' |
2179 '"aes128", "3des", "rc4". If omitted, all ' | 2200 '"aes128", "3des", "rc4". If omitted, all ' |
2180 'algorithms will be used. This option may ' | 2201 'algorithms will be used. This option may ' |
2181 'appear multiple times, indicating ' | 2202 'appear multiple times, indicating ' |
2182 'multiple algorithms should be enabled.'); | 2203 'multiple algorithms should be enabled.'); |
2183 self.option_parser.add_option('--ssl-key-exchange', action='append', | 2204 self.option_parser.add_option('--ssl-key-exchange', action='append', |
2184 help='Specify the key exchange algorithm(s)' | 2205 help='Specify the key exchange algorithm(s)' |
2185 'that will be accepted by the SSL server. ' | 2206 'that will be accepted by the SSL server. ' |
2186 'Valid values are "rsa", "dhe_rsa". If ' | 2207 'Valid values are "rsa", "dhe_rsa". If ' |
2187 'omitted, all algorithms will be used. This ' | 2208 'omitted, all algorithms will be used. This ' |
2188 'option may appear multiple times, ' | 2209 'option may appear multiple times, ' |
2189 'indicating multiple algorithms should be ' | 2210 'indicating multiple algorithms should be ' |
2190 'enabled.'); | 2211 'enabled.'); |
2191 # TODO(davidben): Add ALPN support to tlslite. | 2212 # TODO(davidben): Add ALPN support to tlslite. |
2192 self.option_parser.add_option('--enable-npn', dest='enable_npn', | 2213 self.option_parser.add_option('--enable-npn', dest='enable_npn', |
2193 default=False, const=True, | 2214 default=False, const=True, |
2194 action='store_const', | 2215 action='store_const', |
2195 help='Enable server support for the NPN ' | 2216 help='Enable server support for the NPN ' |
2196 'extension. The server will advertise ' | 2217 'extension. The server will advertise ' |
2197 'support for exactly one protocol, http/1.1') | 2218 'support for exactly one protocol, http/1.1') |
2198 self.option_parser.add_option('--file-root-url', default='/files/', | 2219 self.option_parser.add_option('--file-root-url', default='/files/', |
2199 help='Specify a root URL for files served.') | 2220 help='Specify a root URL for files served.') |
2200 | 2221 |
2201 | 2222 |
2202 if __name__ == '__main__': | 2223 if __name__ == '__main__': |
2203 sys.exit(ServerRunner().main()) | 2224 sys.exit(ServerRunner().main()) |
OLD | NEW |