blob: 93d34d0730a449961f68bf4ccbf0074433b4bd8f [file] [log] [blame]
Nobuaki Sukegawaad835862015-12-23 23:32:09 +09001#
2# Licensed to the Apache Software Foundation (ASF) under one
3# or more contributor license agreements. See the NOTICE file
4# distributed with this work for additional information
5# regarding copyright ownership. The ASF licenses this file
6# to you under the Apache License, Version 2.0 (the
7# "License"); you may not use this file except in compliance
8# with the License. You may obtain a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing,
13# software distributed under the License is distributed on an
14# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15# KIND, either express or implied. See the License for the
16# specific language governing permissions and limitations
17# under the License.
18#
19
Nobuaki Sukegawa66f50532016-02-14 21:47:38 +090020import inspect
Nobuaki Sukegawa355116e2016-02-11 18:01:20 +090021import logging
Nobuaki Sukegawaad835862015-12-23 23:32:09 +090022import os
23import platform
Nobuaki Sukegawaad835862015-12-23 23:32:09 +090024import ssl
25import sys
John Siroisac067042016-02-12 08:10:13 -070026import tempfile
Nobuaki Sukegawaad835862015-12-23 23:32:09 +090027import threading
Nobuaki Sukegawaad835862015-12-23 23:32:09 +090028import unittest
29import warnings
John Siroisac067042016-02-12 08:10:13 -070030from contextlib import contextmanager
31
Nobuaki Sukegawa6a0ca7f2016-02-13 03:11:16 +090032import _import_local_thrift # noqa
Nobuaki Sukegawaad835862015-12-23 23:32:09 +090033from thrift.transport.TSSLSocket import TSSLSocket, TSSLServerSocket
John Siroisac067042016-02-12 08:10:13 -070034from thrift.transport.TTransport import TTransportException
Nobuaki Sukegawaad835862015-12-23 23:32:09 +090035
36SCRIPT_DIR = os.path.realpath(os.path.dirname(__file__))
37ROOT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(SCRIPT_DIR)))
38SERVER_PEM = os.path.join(ROOT_DIR, 'test', 'keys', 'server.pem')
39SERVER_CERT = os.path.join(ROOT_DIR, 'test', 'keys', 'server.crt')
40SERVER_KEY = os.path.join(ROOT_DIR, 'test', 'keys', 'server.key')
Nobuaki Sukegawaf39f7db2016-02-04 15:09:41 +090041CLIENT_CERT_NO_IP = os.path.join(ROOT_DIR, 'test', 'keys', 'client.crt')
42CLIENT_KEY_NO_IP = os.path.join(ROOT_DIR, 'test', 'keys', 'client.key')
43CLIENT_CERT = os.path.join(ROOT_DIR, 'test', 'keys', 'client_v3.crt')
44CLIENT_KEY = os.path.join(ROOT_DIR, 'test', 'keys', 'client_v3.key')
45CLIENT_CA = os.path.join(ROOT_DIR, 'test', 'keys', 'CA.pem')
Nobuaki Sukegawaad835862015-12-23 23:32:09 +090046
Nobuaki Sukegawaad835862015-12-23 23:32:09 +090047TEST_CIPHERS = 'DES-CBC3-SHA'
48
49
50class ServerAcceptor(threading.Thread):
Nobuaki Sukegawa66f50532016-02-14 21:47:38 +090051 def __init__(self, server, expect_failure=False):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090052 super(ServerAcceptor, self).__init__()
John Siroisac067042016-02-12 08:10:13 -070053 self.daemon = True
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090054 self._server = server
John Siroisac067042016-02-12 08:10:13 -070055 self._listening = threading.Event()
56 self._port = None
57 self._port_bound = threading.Event()
58 self._client = None
59 self._client_accepted = threading.Event()
Nobuaki Sukegawa66f50532016-02-14 21:47:38 +090060 self._expect_failure = expect_failure
61 frame = inspect.stack(3)[2]
62 self.name = frame[3]
63 del frame
Nobuaki Sukegawaad835862015-12-23 23:32:09 +090064
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090065 def run(self):
66 self._server.listen()
John Siroisac067042016-02-12 08:10:13 -070067 self._listening.set()
68
69 try:
70 address = self._server.handle.getsockname()
71 if len(address) > 1:
72 # AF_INET addresses are 2-tuples (host, port) and AF_INET6 are
73 # 4-tuples (host, port, ...), but in each case port is in the second slot.
74 self._port = address[1]
75 finally:
76 self._port_bound.set()
77
78 try:
79 self._client = self._server.accept()
Nobuaki Sukegawa66f50532016-02-14 21:47:38 +090080 except Exception:
81 logging.exception('error on server side (%s):' % self.name)
82 if not self._expect_failure:
83 raise
John Siroisac067042016-02-12 08:10:13 -070084 finally:
85 self._client_accepted.set()
86
87 def await_listening(self):
88 self._listening.wait()
89
90 @property
91 def port(self):
92 self._port_bound.wait()
93 return self._port
94
95 @property
96 def client(self):
97 self._client_accepted.wait()
98 return self._client
Nobuaki Sukegawaad835862015-12-23 23:32:09 +090099
100
101# Python 2.6 compat
102class AssertRaises(object):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900103 def __init__(self, expected):
104 self._expected = expected
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900105
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900106 def __enter__(self):
107 pass
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900108
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900109 def __exit__(self, exc_type, exc_value, traceback):
110 if not exc_type or not issubclass(exc_type, self._expected):
111 raise Exception('fail')
112 return True
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900113
114
115class TSSLSocketTest(unittest.TestCase):
John Siroisac067042016-02-12 08:10:13 -0700116 def _server_socket(self, **kwargs):
117 return TSSLServerSocket(port=0, **kwargs)
118
119 @contextmanager
Nobuaki Sukegawa66f50532016-02-14 21:47:38 +0900120 def _connectable_client(self, server, expect_failure=False, path=None, **client_kwargs):
121 acc = ServerAcceptor(server, expect_failure)
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900122 try:
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900123 acc.start()
John Siroisac067042016-02-12 08:10:13 -0700124 acc.await_listening()
125
126 host, port = ('localhost', acc.port) if path is None else (None, None)
Nobuaki Sukegawa66f50532016-02-14 21:47:38 +0900127 client = TSSLSocket(host, port, unix_socket=path, **client_kwargs)
John Siroisac067042016-02-12 08:10:13 -0700128 yield acc, client
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900129 finally:
Nobuaki Sukegawa25536ad2016-02-04 15:08:55 +0900130 if acc.client:
131 acc.client.close()
132 server.close()
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900133
John Siroisac067042016-02-12 08:10:13 -0700134 def _assert_connection_failure(self, server, path=None, **client_args):
Nobuaki Sukegawa66f50532016-02-14 21:47:38 +0900135 logging.disable(logging.CRITICAL)
136 with self._connectable_client(server, True, path=path, **client_args) as (acc, client):
John Siroisac067042016-02-12 08:10:13 -0700137 try:
John Siroisac067042016-02-12 08:10:13 -0700138 # We need to wait for a connection failure, but not too long. 20ms is a tunable
139 # compromise between test speed and stability
140 client.setTimeout(20)
141 with self._assert_raises(TTransportException):
142 client.open()
143 self.assertTrue(acc.client is None)
144 finally:
145 logging.disable(logging.NOTSET)
146
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900147 def _assert_raises(self, exc):
148 if sys.hexversion >= 0x020700F0:
149 return self.assertRaises(exc)
150 else:
151 return AssertRaises(exc)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900152
John Siroisac067042016-02-12 08:10:13 -0700153 def _assert_connection_success(self, server, path=None, **client_args):
154 with self._connectable_client(server, path=path, **client_args) as (acc, client):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900155 client.open()
John Siroisac067042016-02-12 08:10:13 -0700156 try:
157 self.assertTrue(acc.client is not None)
158 finally:
159 client.close()
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900160
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900161 # deprecated feature
162 def test_deprecation(self):
163 with warnings.catch_warnings(record=True) as w:
Nobuaki Sukegawa6a0ca7f2016-02-13 03:11:16 +0900164 warnings.filterwarnings('always', category=DeprecationWarning, module=self.__module__)
John Siroisac067042016-02-12 08:10:13 -0700165 TSSLSocket('localhost', 0, validate=True, ca_certs=SERVER_CERT)
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900166 self.assertEqual(len(w), 1)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900167
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900168 with warnings.catch_warnings(record=True) as w:
Nobuaki Sukegawa6a0ca7f2016-02-13 03:11:16 +0900169 warnings.filterwarnings('always', category=DeprecationWarning, module=self.__module__)
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900170 # Deprecated signature
171 # def __init__(self, host='localhost', port=9090, validate=True, ca_certs=None, keyfile=None, certfile=None, unix_socket=None, ciphers=None):
Nobuaki Sukegawa6a0ca7f2016-02-13 03:11:16 +0900172 TSSLSocket('localhost', 0, True, SERVER_CERT, CLIENT_KEY, CLIENT_CERT, None, TEST_CIPHERS)
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900173 self.assertEqual(len(w), 7)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900174
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900175 with warnings.catch_warnings(record=True) as w:
Nobuaki Sukegawa6a0ca7f2016-02-13 03:11:16 +0900176 warnings.filterwarnings('always', category=DeprecationWarning, module=self.__module__)
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900177 # Deprecated signature
178 # def __init__(self, host=None, port=9090, certfile='cert.pem', unix_socket=None, ciphers=None):
Nobuaki Sukegawa6a0ca7f2016-02-13 03:11:16 +0900179 TSSLServerSocket(None, 0, SERVER_PEM, None, TEST_CIPHERS)
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900180 self.assertEqual(len(w), 3)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900181
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900182 # deprecated feature
183 def test_set_cert_reqs_by_validate(self):
Nobuaki Sukegawa6a0ca7f2016-02-13 03:11:16 +0900184 with warnings.catch_warnings(record=True) as w:
185 warnings.filterwarnings('always', category=DeprecationWarning, module=self.__module__)
186 c1 = TSSLSocket('localhost', 0, validate=True, ca_certs=SERVER_CERT)
187 self.assertEqual(c1.cert_reqs, ssl.CERT_REQUIRED)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900188
Nobuaki Sukegawa6a0ca7f2016-02-13 03:11:16 +0900189 c1 = TSSLSocket('localhost', 0, validate=False)
190 self.assertEqual(c1.cert_reqs, ssl.CERT_NONE)
191
192 self.assertEqual(len(w), 2)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900193
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900194 # deprecated feature
195 def test_set_validate_by_cert_reqs(self):
Nobuaki Sukegawa6a0ca7f2016-02-13 03:11:16 +0900196 with warnings.catch_warnings(record=True) as w:
197 warnings.filterwarnings('always', category=DeprecationWarning, module=self.__module__)
198 c1 = TSSLSocket('localhost', 0, cert_reqs=ssl.CERT_NONE)
199 self.assertFalse(c1.validate)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900200
Nobuaki Sukegawa6a0ca7f2016-02-13 03:11:16 +0900201 c2 = TSSLSocket('localhost', 0, cert_reqs=ssl.CERT_REQUIRED, ca_certs=SERVER_CERT)
202 self.assertTrue(c2.validate)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900203
Nobuaki Sukegawa6a0ca7f2016-02-13 03:11:16 +0900204 c3 = TSSLSocket('localhost', 0, cert_reqs=ssl.CERT_OPTIONAL, ca_certs=SERVER_CERT)
205 self.assertTrue(c3.validate)
206
207 self.assertEqual(len(w), 3)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900208
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900209 def test_unix_domain_socket(self):
210 if platform.system() == 'Windows':
211 print('skipping test_unix_domain_socket')
212 return
John Siroisac067042016-02-12 08:10:13 -0700213 fd, path = tempfile.mkstemp()
214 os.close(fd)
215 try:
216 server = self._server_socket(unix_socket=path, keyfile=SERVER_KEY, certfile=SERVER_CERT)
217 self._assert_connection_success(server, path=path, cert_reqs=ssl.CERT_NONE)
218 finally:
219 os.unlink(path)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900220
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900221 def test_server_cert(self):
John Siroisac067042016-02-12 08:10:13 -0700222 server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT)
223 self._assert_connection_success(server, cert_reqs=ssl.CERT_REQUIRED, ca_certs=SERVER_CERT)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900224
John Siroisac067042016-02-12 08:10:13 -0700225 server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT)
226 # server cert not in ca_certs
227 self._assert_connection_failure(server, cert_reqs=ssl.CERT_REQUIRED, ca_certs=CLIENT_CERT)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900228
John Siroisac067042016-02-12 08:10:13 -0700229 server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT)
230 self._assert_connection_success(server, cert_reqs=ssl.CERT_NONE)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900231
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900232 def test_set_server_cert(self):
John Siroisac067042016-02-12 08:10:13 -0700233 server = self._server_socket(keyfile=SERVER_KEY, certfile=CLIENT_CERT)
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900234 with self._assert_raises(Exception):
235 server.certfile = 'foo'
236 with self._assert_raises(Exception):
237 server.certfile = None
238 server.certfile = SERVER_CERT
John Siroisac067042016-02-12 08:10:13 -0700239 self._assert_connection_success(server, cert_reqs=ssl.CERT_REQUIRED, ca_certs=SERVER_CERT)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900240
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900241 def test_client_cert(self):
John Siroisac067042016-02-12 08:10:13 -0700242 server = self._server_socket(
243 cert_reqs=ssl.CERT_REQUIRED, keyfile=SERVER_KEY,
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900244 certfile=SERVER_CERT, ca_certs=CLIENT_CERT)
John Siroisac067042016-02-12 08:10:13 -0700245 self._assert_connection_failure(server, cert_reqs=ssl.CERT_NONE, certfile=SERVER_CERT, keyfile=SERVER_KEY)
Nobuaki Sukegawaf39f7db2016-02-04 15:09:41 +0900246
John Siroisac067042016-02-12 08:10:13 -0700247 server = self._server_socket(
248 cert_reqs=ssl.CERT_REQUIRED, keyfile=SERVER_KEY,
Nobuaki Sukegawaf39f7db2016-02-04 15:09:41 +0900249 certfile=SERVER_CERT, ca_certs=CLIENT_CA)
John Siroisac067042016-02-12 08:10:13 -0700250 self._assert_connection_failure(server, cert_reqs=ssl.CERT_NONE, certfile=CLIENT_CERT_NO_IP, keyfile=CLIENT_KEY_NO_IP)
Nobuaki Sukegawaf39f7db2016-02-04 15:09:41 +0900251
John Siroisac067042016-02-12 08:10:13 -0700252 server = self._server_socket(
253 cert_reqs=ssl.CERT_REQUIRED, keyfile=SERVER_KEY,
Nobuaki Sukegawaf39f7db2016-02-04 15:09:41 +0900254 certfile=SERVER_CERT, ca_certs=CLIENT_CA)
John Siroisac067042016-02-12 08:10:13 -0700255 self._assert_connection_success(server, cert_reqs=ssl.CERT_NONE, certfile=CLIENT_CERT, keyfile=CLIENT_KEY)
Nobuaki Sukegawaf39f7db2016-02-04 15:09:41 +0900256
John Siroisac067042016-02-12 08:10:13 -0700257 server = self._server_socket(
258 cert_reqs=ssl.CERT_OPTIONAL, keyfile=SERVER_KEY,
Nobuaki Sukegawaf39f7db2016-02-04 15:09:41 +0900259 certfile=SERVER_CERT, ca_certs=CLIENT_CA)
John Siroisac067042016-02-12 08:10:13 -0700260 self._assert_connection_success(server, cert_reqs=ssl.CERT_NONE, certfile=CLIENT_CERT, keyfile=CLIENT_KEY)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900261
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900262 def test_ciphers(self):
John Siroisac067042016-02-12 08:10:13 -0700263 server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT, ciphers=TEST_CIPHERS)
264 self._assert_connection_success(server, ca_certs=SERVER_CERT, ciphers=TEST_CIPHERS)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900265
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900266 if not TSSLSocket._has_ciphers:
267 # unittest.skip is not available for Python 2.6
268 print('skipping test_ciphers')
269 return
John Siroisac067042016-02-12 08:10:13 -0700270 server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT)
271 self._assert_connection_failure(server, ca_certs=SERVER_CERT, ciphers='NULL')
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900272
John Siroisac067042016-02-12 08:10:13 -0700273 server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT, ciphers=TEST_CIPHERS)
274 self._assert_connection_failure(server, ca_certs=SERVER_CERT, ciphers='NULL')
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900275
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900276 def test_ssl2_and_ssl3_disabled(self):
277 if not hasattr(ssl, 'PROTOCOL_SSLv3'):
278 print('PROTOCOL_SSLv3 is not available')
279 else:
John Siroisac067042016-02-12 08:10:13 -0700280 server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT)
281 self._assert_connection_failure(server, ca_certs=SERVER_CERT, ssl_version=ssl.PROTOCOL_SSLv3)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900282
John Siroisac067042016-02-12 08:10:13 -0700283 server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT, ssl_version=ssl.PROTOCOL_SSLv3)
284 self._assert_connection_failure(server, ca_certs=SERVER_CERT)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900285
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900286 if not hasattr(ssl, 'PROTOCOL_SSLv2'):
287 print('PROTOCOL_SSLv2 is not available')
288 else:
John Siroisac067042016-02-12 08:10:13 -0700289 server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT)
290 self._assert_connection_failure(server, ca_certs=SERVER_CERT, ssl_version=ssl.PROTOCOL_SSLv2)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900291
John Siroisac067042016-02-12 08:10:13 -0700292 server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT, ssl_version=ssl.PROTOCOL_SSLv2)
293 self._assert_connection_failure(server, ca_certs=SERVER_CERT)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900294
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900295 def test_newer_tls(self):
296 if not TSSLSocket._has_ssl_context:
297 # unittest.skip is not available for Python 2.6
298 print('skipping test_newer_tls')
299 return
300 if not hasattr(ssl, 'PROTOCOL_TLSv1_2'):
301 print('PROTOCOL_TLSv1_2 is not available')
302 else:
John Siroisac067042016-02-12 08:10:13 -0700303 server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT, ssl_version=ssl.PROTOCOL_TLSv1_2)
304 self._assert_connection_success(server, ca_certs=SERVER_CERT, ssl_version=ssl.PROTOCOL_TLSv1_2)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900305
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900306 if not hasattr(ssl, 'PROTOCOL_TLSv1_1'):
307 print('PROTOCOL_TLSv1_1 is not available')
308 else:
John Siroisac067042016-02-12 08:10:13 -0700309 server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT, ssl_version=ssl.PROTOCOL_TLSv1_1)
310 self._assert_connection_success(server, ca_certs=SERVER_CERT, ssl_version=ssl.PROTOCOL_TLSv1_1)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900311
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900312 if not hasattr(ssl, 'PROTOCOL_TLSv1_1') or not hasattr(ssl, 'PROTOCOL_TLSv1_2'):
313 print('PROTOCOL_TLSv1_1 and/or PROTOCOL_TLSv1_2 is not available')
314 else:
John Siroisac067042016-02-12 08:10:13 -0700315 server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT, ssl_version=ssl.PROTOCOL_TLSv1_2)
316 self._assert_connection_failure(server, ca_certs=SERVER_CERT, ssl_version=ssl.PROTOCOL_TLSv1_1)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900317
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900318 def test_ssl_context(self):
319 if not TSSLSocket._has_ssl_context:
320 # unittest.skip is not available for Python 2.6
321 print('skipping test_ssl_context')
322 return
323 server_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
324 server_context.load_cert_chain(SERVER_CERT, SERVER_KEY)
Nobuaki Sukegawaf39f7db2016-02-04 15:09:41 +0900325 server_context.load_verify_locations(CLIENT_CA)
326 server_context.verify_mode = ssl.CERT_REQUIRED
John Siroisac067042016-02-12 08:10:13 -0700327 server = self._server_socket(ssl_context=server_context)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900328
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900329 client_context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
330 client_context.load_cert_chain(CLIENT_CERT, CLIENT_KEY)
331 client_context.load_verify_locations(SERVER_CERT)
Nobuaki Sukegawaf39f7db2016-02-04 15:09:41 +0900332 client_context.verify_mode = ssl.CERT_REQUIRED
Nobuaki Sukegawaf39f7db2016-02-04 15:09:41 +0900333
John Siroisac067042016-02-12 08:10:13 -0700334 self._assert_connection_success(server, ssl_context=client_context)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900335
336if __name__ == '__main__':
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900337 # import logging
338 # logging.basicConfig(level=logging.DEBUG)
339 unittest.main()