blob: 259945fc8fa6af1f4c85ba5ab18c7b50b3aaa784 [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 Sukegawa355116e2016-02-11 18:01:20 +090020import logging
Nobuaki Sukegawaad835862015-12-23 23:32:09 +090021import os
22import platform
Nobuaki Sukegawaad835862015-12-23 23:32:09 +090023import ssl
24import sys
John Siroisac067042016-02-12 08:10:13 -070025import tempfile
Nobuaki Sukegawaad835862015-12-23 23:32:09 +090026import threading
Nobuaki Sukegawaad835862015-12-23 23:32:09 +090027import unittest
28import warnings
John Siroisac067042016-02-12 08:10:13 -070029from contextlib import contextmanager
30
Nobuaki Sukegawa6a0ca7f2016-02-13 03:11:16 +090031import _import_local_thrift # noqa
Nobuaki Sukegawaad835862015-12-23 23:32:09 +090032from thrift.transport.TSSLSocket import TSSLSocket, TSSLServerSocket
John Siroisac067042016-02-12 08:10:13 -070033from thrift.transport.TTransport import TTransportException
Nobuaki Sukegawaad835862015-12-23 23:32:09 +090034
35SCRIPT_DIR = os.path.realpath(os.path.dirname(__file__))
36ROOT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(SCRIPT_DIR)))
37SERVER_PEM = os.path.join(ROOT_DIR, 'test', 'keys', 'server.pem')
38SERVER_CERT = os.path.join(ROOT_DIR, 'test', 'keys', 'server.crt')
39SERVER_KEY = os.path.join(ROOT_DIR, 'test', 'keys', 'server.key')
Nobuaki Sukegawaf39f7db2016-02-04 15:09:41 +090040CLIENT_CERT_NO_IP = os.path.join(ROOT_DIR, 'test', 'keys', 'client.crt')
41CLIENT_KEY_NO_IP = os.path.join(ROOT_DIR, 'test', 'keys', 'client.key')
42CLIENT_CERT = os.path.join(ROOT_DIR, 'test', 'keys', 'client_v3.crt')
43CLIENT_KEY = os.path.join(ROOT_DIR, 'test', 'keys', 'client_v3.key')
44CLIENT_CA = os.path.join(ROOT_DIR, 'test', 'keys', 'CA.pem')
Nobuaki Sukegawaad835862015-12-23 23:32:09 +090045
Nobuaki Sukegawaad835862015-12-23 23:32:09 +090046TEST_CIPHERS = 'DES-CBC3-SHA'
47
48
49class ServerAcceptor(threading.Thread):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090050 def __init__(self, server):
51 super(ServerAcceptor, self).__init__()
John Siroisac067042016-02-12 08:10:13 -070052 self.daemon = True
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090053 self._server = server
John Siroisac067042016-02-12 08:10:13 -070054 self._listening = threading.Event()
55 self._port = None
56 self._port_bound = threading.Event()
57 self._client = None
58 self._client_accepted = threading.Event()
Nobuaki Sukegawaad835862015-12-23 23:32:09 +090059
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090060 def run(self):
61 self._server.listen()
John Siroisac067042016-02-12 08:10:13 -070062 self._listening.set()
63
64 try:
65 address = self._server.handle.getsockname()
66 if len(address) > 1:
67 # AF_INET addresses are 2-tuples (host, port) and AF_INET6 are
68 # 4-tuples (host, port, ...), but in each case port is in the second slot.
69 self._port = address[1]
70 finally:
71 self._port_bound.set()
72
73 try:
74 self._client = self._server.accept()
75 finally:
76 self._client_accepted.set()
77
78 def await_listening(self):
79 self._listening.wait()
80
81 @property
82 def port(self):
83 self._port_bound.wait()
84 return self._port
85
86 @property
87 def client(self):
88 self._client_accepted.wait()
89 return self._client
Nobuaki Sukegawaad835862015-12-23 23:32:09 +090090
91
92# Python 2.6 compat
93class AssertRaises(object):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090094 def __init__(self, expected):
95 self._expected = expected
Nobuaki Sukegawaad835862015-12-23 23:32:09 +090096
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090097 def __enter__(self):
98 pass
Nobuaki Sukegawaad835862015-12-23 23:32:09 +090099
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900100 def __exit__(self, exc_type, exc_value, traceback):
101 if not exc_type or not issubclass(exc_type, self._expected):
102 raise Exception('fail')
103 return True
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900104
105
106class TSSLSocketTest(unittest.TestCase):
John Siroisac067042016-02-12 08:10:13 -0700107 def _server_socket(self, **kwargs):
108 return TSSLServerSocket(port=0, **kwargs)
109
110 @contextmanager
111 def _connectable_client(self, server, path=None, **client_kwargs):
Nobuaki Sukegawa25536ad2016-02-04 15:08:55 +0900112 acc = ServerAcceptor(server)
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900113 try:
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900114 acc.start()
John Siroisac067042016-02-12 08:10:13 -0700115 acc.await_listening()
116
117 host, port = ('localhost', acc.port) if path is None else (None, None)
118 client = TSSLSocket(host, port, path, **client_kwargs)
119 yield acc, client
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900120 finally:
Nobuaki Sukegawa25536ad2016-02-04 15:08:55 +0900121 if acc.client:
122 acc.client.close()
123 server.close()
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900124
John Siroisac067042016-02-12 08:10:13 -0700125 def _assert_connection_failure(self, server, path=None, **client_args):
126 with self._connectable_client(server, path=path, **client_args) as (acc, client):
127 try:
128 logging.disable(logging.CRITICAL)
129 # We need to wait for a connection failure, but not too long. 20ms is a tunable
130 # compromise between test speed and stability
131 client.setTimeout(20)
132 with self._assert_raises(TTransportException):
133 client.open()
134 self.assertTrue(acc.client is None)
135 finally:
136 logging.disable(logging.NOTSET)
137
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900138 def _assert_raises(self, exc):
139 if sys.hexversion >= 0x020700F0:
140 return self.assertRaises(exc)
141 else:
142 return AssertRaises(exc)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900143
John Siroisac067042016-02-12 08:10:13 -0700144 def _assert_connection_success(self, server, path=None, **client_args):
145 with self._connectable_client(server, path=path, **client_args) as (acc, client):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900146 client.open()
John Siroisac067042016-02-12 08:10:13 -0700147 try:
148 self.assertTrue(acc.client is not None)
149 finally:
150 client.close()
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900151
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900152 # deprecated feature
153 def test_deprecation(self):
154 with warnings.catch_warnings(record=True) as w:
Nobuaki Sukegawa6a0ca7f2016-02-13 03:11:16 +0900155 warnings.filterwarnings('always', category=DeprecationWarning, module=self.__module__)
John Siroisac067042016-02-12 08:10:13 -0700156 TSSLSocket('localhost', 0, validate=True, ca_certs=SERVER_CERT)
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900157 self.assertEqual(len(w), 1)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900158
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900159 with warnings.catch_warnings(record=True) as w:
Nobuaki Sukegawa6a0ca7f2016-02-13 03:11:16 +0900160 warnings.filterwarnings('always', category=DeprecationWarning, module=self.__module__)
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900161 # Deprecated signature
162 # 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 +0900163 TSSLSocket('localhost', 0, True, SERVER_CERT, CLIENT_KEY, CLIENT_CERT, None, TEST_CIPHERS)
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900164 self.assertEqual(len(w), 7)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900165
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900166 with warnings.catch_warnings(record=True) as w:
Nobuaki Sukegawa6a0ca7f2016-02-13 03:11:16 +0900167 warnings.filterwarnings('always', category=DeprecationWarning, module=self.__module__)
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900168 # Deprecated signature
169 # def __init__(self, host=None, port=9090, certfile='cert.pem', unix_socket=None, ciphers=None):
Nobuaki Sukegawa6a0ca7f2016-02-13 03:11:16 +0900170 TSSLServerSocket(None, 0, SERVER_PEM, None, TEST_CIPHERS)
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900171 self.assertEqual(len(w), 3)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900172
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900173 # deprecated feature
174 def test_set_cert_reqs_by_validate(self):
Nobuaki Sukegawa6a0ca7f2016-02-13 03:11:16 +0900175 with warnings.catch_warnings(record=True) as w:
176 warnings.filterwarnings('always', category=DeprecationWarning, module=self.__module__)
177 c1 = TSSLSocket('localhost', 0, validate=True, ca_certs=SERVER_CERT)
178 self.assertEqual(c1.cert_reqs, ssl.CERT_REQUIRED)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900179
Nobuaki Sukegawa6a0ca7f2016-02-13 03:11:16 +0900180 c1 = TSSLSocket('localhost', 0, validate=False)
181 self.assertEqual(c1.cert_reqs, ssl.CERT_NONE)
182
183 self.assertEqual(len(w), 2)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900184
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900185 # deprecated feature
186 def test_set_validate_by_cert_reqs(self):
Nobuaki Sukegawa6a0ca7f2016-02-13 03:11:16 +0900187 with warnings.catch_warnings(record=True) as w:
188 warnings.filterwarnings('always', category=DeprecationWarning, module=self.__module__)
189 c1 = TSSLSocket('localhost', 0, cert_reqs=ssl.CERT_NONE)
190 self.assertFalse(c1.validate)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900191
Nobuaki Sukegawa6a0ca7f2016-02-13 03:11:16 +0900192 c2 = TSSLSocket('localhost', 0, cert_reqs=ssl.CERT_REQUIRED, ca_certs=SERVER_CERT)
193 self.assertTrue(c2.validate)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900194
Nobuaki Sukegawa6a0ca7f2016-02-13 03:11:16 +0900195 c3 = TSSLSocket('localhost', 0, cert_reqs=ssl.CERT_OPTIONAL, ca_certs=SERVER_CERT)
196 self.assertTrue(c3.validate)
197
198 self.assertEqual(len(w), 3)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900199
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900200 def test_unix_domain_socket(self):
201 if platform.system() == 'Windows':
202 print('skipping test_unix_domain_socket')
203 return
John Siroisac067042016-02-12 08:10:13 -0700204 fd, path = tempfile.mkstemp()
205 os.close(fd)
206 try:
207 server = self._server_socket(unix_socket=path, keyfile=SERVER_KEY, certfile=SERVER_CERT)
208 self._assert_connection_success(server, path=path, cert_reqs=ssl.CERT_NONE)
209 finally:
210 os.unlink(path)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900211
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900212 def test_server_cert(self):
John Siroisac067042016-02-12 08:10:13 -0700213 server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT)
214 self._assert_connection_success(server, cert_reqs=ssl.CERT_REQUIRED, ca_certs=SERVER_CERT)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900215
John Siroisac067042016-02-12 08:10:13 -0700216 server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT)
217 # server cert not in ca_certs
218 self._assert_connection_failure(server, cert_reqs=ssl.CERT_REQUIRED, ca_certs=CLIENT_CERT)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900219
John Siroisac067042016-02-12 08:10:13 -0700220 server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT)
221 self._assert_connection_success(server, cert_reqs=ssl.CERT_NONE)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900222
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900223 def test_set_server_cert(self):
John Siroisac067042016-02-12 08:10:13 -0700224 server = self._server_socket(keyfile=SERVER_KEY, certfile=CLIENT_CERT)
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900225 with self._assert_raises(Exception):
226 server.certfile = 'foo'
227 with self._assert_raises(Exception):
228 server.certfile = None
229 server.certfile = SERVER_CERT
John Siroisac067042016-02-12 08:10:13 -0700230 self._assert_connection_success(server, cert_reqs=ssl.CERT_REQUIRED, ca_certs=SERVER_CERT)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900231
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900232 def test_client_cert(self):
John Siroisac067042016-02-12 08:10:13 -0700233 server = self._server_socket(
234 cert_reqs=ssl.CERT_REQUIRED, keyfile=SERVER_KEY,
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900235 certfile=SERVER_CERT, ca_certs=CLIENT_CERT)
John Siroisac067042016-02-12 08:10:13 -0700236 self._assert_connection_failure(server, cert_reqs=ssl.CERT_NONE, certfile=SERVER_CERT, keyfile=SERVER_KEY)
Nobuaki Sukegawaf39f7db2016-02-04 15:09:41 +0900237
John Siroisac067042016-02-12 08:10:13 -0700238 server = self._server_socket(
239 cert_reqs=ssl.CERT_REQUIRED, keyfile=SERVER_KEY,
Nobuaki Sukegawaf39f7db2016-02-04 15:09:41 +0900240 certfile=SERVER_CERT, ca_certs=CLIENT_CA)
John Siroisac067042016-02-12 08:10:13 -0700241 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 +0900242
John Siroisac067042016-02-12 08:10:13 -0700243 server = self._server_socket(
244 cert_reqs=ssl.CERT_REQUIRED, keyfile=SERVER_KEY,
Nobuaki Sukegawaf39f7db2016-02-04 15:09:41 +0900245 certfile=SERVER_CERT, ca_certs=CLIENT_CA)
John Siroisac067042016-02-12 08:10:13 -0700246 self._assert_connection_success(server, cert_reqs=ssl.CERT_NONE, certfile=CLIENT_CERT, keyfile=CLIENT_KEY)
Nobuaki Sukegawaf39f7db2016-02-04 15:09:41 +0900247
John Siroisac067042016-02-12 08:10:13 -0700248 server = self._server_socket(
249 cert_reqs=ssl.CERT_OPTIONAL, keyfile=SERVER_KEY,
Nobuaki Sukegawaf39f7db2016-02-04 15:09:41 +0900250 certfile=SERVER_CERT, ca_certs=CLIENT_CA)
John Siroisac067042016-02-12 08:10:13 -0700251 self._assert_connection_success(server, cert_reqs=ssl.CERT_NONE, certfile=CLIENT_CERT, keyfile=CLIENT_KEY)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900252
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900253 def test_ciphers(self):
John Siroisac067042016-02-12 08:10:13 -0700254 server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT, ciphers=TEST_CIPHERS)
255 self._assert_connection_success(server, ca_certs=SERVER_CERT, ciphers=TEST_CIPHERS)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900256
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900257 if not TSSLSocket._has_ciphers:
258 # unittest.skip is not available for Python 2.6
259 print('skipping test_ciphers')
260 return
John Siroisac067042016-02-12 08:10:13 -0700261 server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT)
262 self._assert_connection_failure(server, ca_certs=SERVER_CERT, ciphers='NULL')
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900263
John Siroisac067042016-02-12 08:10:13 -0700264 server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT, ciphers=TEST_CIPHERS)
265 self._assert_connection_failure(server, ca_certs=SERVER_CERT, ciphers='NULL')
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900266
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900267 def test_ssl2_and_ssl3_disabled(self):
268 if not hasattr(ssl, 'PROTOCOL_SSLv3'):
269 print('PROTOCOL_SSLv3 is not available')
270 else:
John Siroisac067042016-02-12 08:10:13 -0700271 server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT)
272 self._assert_connection_failure(server, ca_certs=SERVER_CERT, ssl_version=ssl.PROTOCOL_SSLv3)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900273
John Siroisac067042016-02-12 08:10:13 -0700274 server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT, ssl_version=ssl.PROTOCOL_SSLv3)
275 self._assert_connection_failure(server, ca_certs=SERVER_CERT)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900276
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900277 if not hasattr(ssl, 'PROTOCOL_SSLv2'):
278 print('PROTOCOL_SSLv2 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_SSLv2)
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_SSLv2)
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 def test_newer_tls(self):
287 if not TSSLSocket._has_ssl_context:
288 # unittest.skip is not available for Python 2.6
289 print('skipping test_newer_tls')
290 return
291 if not hasattr(ssl, 'PROTOCOL_TLSv1_2'):
292 print('PROTOCOL_TLSv1_2 is not available')
293 else:
John Siroisac067042016-02-12 08:10:13 -0700294 server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT, ssl_version=ssl.PROTOCOL_TLSv1_2)
295 self._assert_connection_success(server, ca_certs=SERVER_CERT, ssl_version=ssl.PROTOCOL_TLSv1_2)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900296
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900297 if not hasattr(ssl, 'PROTOCOL_TLSv1_1'):
298 print('PROTOCOL_TLSv1_1 is not available')
299 else:
John Siroisac067042016-02-12 08:10:13 -0700300 server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT, ssl_version=ssl.PROTOCOL_TLSv1_1)
301 self._assert_connection_success(server, ca_certs=SERVER_CERT, ssl_version=ssl.PROTOCOL_TLSv1_1)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900302
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900303 if not hasattr(ssl, 'PROTOCOL_TLSv1_1') or not hasattr(ssl, 'PROTOCOL_TLSv1_2'):
304 print('PROTOCOL_TLSv1_1 and/or PROTOCOL_TLSv1_2 is not available')
305 else:
John Siroisac067042016-02-12 08:10:13 -0700306 server = self._server_socket(keyfile=SERVER_KEY, certfile=SERVER_CERT, ssl_version=ssl.PROTOCOL_TLSv1_2)
307 self._assert_connection_failure(server, ca_certs=SERVER_CERT, ssl_version=ssl.PROTOCOL_TLSv1_1)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900308
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900309 def test_ssl_context(self):
310 if not TSSLSocket._has_ssl_context:
311 # unittest.skip is not available for Python 2.6
312 print('skipping test_ssl_context')
313 return
314 server_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
315 server_context.load_cert_chain(SERVER_CERT, SERVER_KEY)
Nobuaki Sukegawaf39f7db2016-02-04 15:09:41 +0900316 server_context.load_verify_locations(CLIENT_CA)
317 server_context.verify_mode = ssl.CERT_REQUIRED
John Siroisac067042016-02-12 08:10:13 -0700318 server = self._server_socket(ssl_context=server_context)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900319
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900320 client_context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
321 client_context.load_cert_chain(CLIENT_CERT, CLIENT_KEY)
322 client_context.load_verify_locations(SERVER_CERT)
Nobuaki Sukegawaf39f7db2016-02-04 15:09:41 +0900323 client_context.verify_mode = ssl.CERT_REQUIRED
Nobuaki Sukegawaf39f7db2016-02-04 15:09:41 +0900324
John Siroisac067042016-02-12 08:10:13 -0700325 self._assert_connection_success(server, ssl_context=client_context)
Nobuaki Sukegawaad835862015-12-23 23:32:09 +0900326
327if __name__ == '__main__':
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900328 # import logging
329 # logging.basicConfig(level=logging.DEBUG)
330 unittest.main()