blob: 4ea1a63e4959c548393a7a86fde13c7bc1eea031 [file] [log] [blame]
Thomas Woutersed03b412007-08-28 21:37:11 +00001# Test the support for SSL and sockets
2
3import sys
4import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00005from test import support
Thomas Woutersed03b412007-08-28 21:37:11 +00006import socket
Bill Janssen6e027db2007-11-15 22:23:56 +00007import select
Thomas Woutersed03b412007-08-28 21:37:11 +00008import time
Antoine Pitroucfcd8ad2010-04-23 23:31:47 +00009import gc
Thomas Woutersed03b412007-08-28 21:37:11 +000010import os
Antoine Pitroucfcd8ad2010-04-23 23:31:47 +000011import errno
Thomas Woutersed03b412007-08-28 21:37:11 +000012import pprint
Antoine Pitrou152efa22010-05-16 18:19:27 +000013import tempfile
Antoine Pitrou803e6d62010-10-13 10:36:15 +000014import urllib.request
Thomas Woutersed03b412007-08-28 21:37:11 +000015import traceback
Bill Janssen54cc54c2007-12-14 22:08:56 +000016import asyncore
Antoine Pitrou9d543662010-04-23 23:10:32 +000017import weakref
Antoine Pitrou15cee622010-08-04 16:45:21 +000018import platform
Antoine Pitrou23df4832010-08-04 17:14:06 +000019import functools
Thomas Woutersed03b412007-08-28 21:37:11 +000020
Antoine Pitrou05d936d2010-10-13 11:38:36 +000021ssl = support.import_module("ssl")
22
23PROTOCOLS = [
24 ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3,
25 ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1
26]
Thomas Woutersed03b412007-08-28 21:37:11 +000027
Benjamin Petersonee8712c2008-05-20 21:35:26 +000028HOST = support.HOST
Antoine Pitrou152efa22010-05-16 18:19:27 +000029
30data_file = lambda name: os.path.join(os.path.dirname(__file__), name)
Antoine Pitrou152efa22010-05-16 18:19:27 +000031
Antoine Pitrou81564092010-10-08 23:06:24 +000032# The custom key and certificate files used in test_ssl are generated
33# using Lib/test/make_ssl_certs.py.
34# Other certificates are simply fetched from the Internet servers they
35# are meant to authenticate.
36
Antoine Pitrou152efa22010-05-16 18:19:27 +000037CERTFILE = data_file("keycert.pem")
Victor Stinner313a1202010-06-11 23:56:51 +000038BYTES_CERTFILE = os.fsencode(CERTFILE)
Antoine Pitrou152efa22010-05-16 18:19:27 +000039ONLYCERT = data_file("ssl_cert.pem")
40ONLYKEY = data_file("ssl_key.pem")
Victor Stinner313a1202010-06-11 23:56:51 +000041BYTES_ONLYCERT = os.fsencode(ONLYCERT)
42BYTES_ONLYKEY = os.fsencode(ONLYKEY)
Antoine Pitrou152efa22010-05-16 18:19:27 +000043CAPATH = data_file("capath")
Victor Stinner313a1202010-06-11 23:56:51 +000044BYTES_CAPATH = os.fsencode(CAPATH)
Antoine Pitrou152efa22010-05-16 18:19:27 +000045
46SVN_PYTHON_ORG_ROOT_CERT = data_file("https_svn_python_org_root.pem")
47
48EMPTYCERT = data_file("nullcert.pem")
49BADCERT = data_file("badcert.pem")
50WRONGCERT = data_file("XXXnonexisting.pem")
51BADKEY = data_file("badkey.pem")
52
Thomas Woutersed03b412007-08-28 21:37:11 +000053
Thomas Woutersed03b412007-08-28 21:37:11 +000054def handle_error(prefix):
55 exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
Benjamin Petersonee8712c2008-05-20 21:35:26 +000056 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000057 sys.stdout.write(prefix + exc_format)
Thomas Woutersed03b412007-08-28 21:37:11 +000058
Antoine Pitroub5218772010-05-21 09:56:06 +000059def can_clear_options():
60 # 0.9.8m or higher
61 return ssl.OPENSSL_VERSION_INFO >= (0, 9, 8, 13, 15)
62
63def no_sslv2_implies_sslv3_hello():
64 # 0.9.7h or higher
65 return ssl.OPENSSL_VERSION_INFO >= (0, 9, 7, 8, 15)
66
Thomas Woutersed03b412007-08-28 21:37:11 +000067
Antoine Pitrou23df4832010-08-04 17:14:06 +000068# Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
69def skip_if_broken_ubuntu_ssl(func):
70 @functools.wraps(func)
71 def f(*args, **kwargs):
72 try:
73 ssl.SSLContext(ssl.PROTOCOL_SSLv2)
74 except ssl.SSLError:
75 if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
76 platform.linux_distribution() == ('debian', 'squeeze/sid', '')):
77 raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
78 return func(*args, **kwargs)
79 return f
80
81
Antoine Pitrou152efa22010-05-16 18:19:27 +000082class BasicSocketTests(unittest.TestCase):
Thomas Woutersed03b412007-08-28 21:37:11 +000083
Antoine Pitrou480a1242010-04-28 21:37:09 +000084 def test_constants(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +000085 ssl.PROTOCOL_SSLv2
86 ssl.PROTOCOL_SSLv23
87 ssl.PROTOCOL_SSLv3
88 ssl.PROTOCOL_TLSv1
89 ssl.CERT_NONE
90 ssl.CERT_OPTIONAL
91 ssl.CERT_REQUIRED
Antoine Pitroud5323212010-10-22 18:19:07 +000092 self.assertIn(ssl.HAS_SNI, {True, False})
Thomas Woutersed03b412007-08-28 21:37:11 +000093
Antoine Pitrou480a1242010-04-28 21:37:09 +000094 def test_random(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +000095 v = ssl.RAND_status()
Benjamin Petersonee8712c2008-05-20 21:35:26 +000096 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000097 sys.stdout.write("\n RAND_status is %d (%s)\n"
98 % (v, (v and "sufficient randomness") or
99 "insufficient randomness"))
Thomas Woutersed03b412007-08-28 21:37:11 +0000100 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000101 ssl.RAND_egd(1)
102 except TypeError:
103 pass
Thomas Woutersed03b412007-08-28 21:37:11 +0000104 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000105 print("didn't raise TypeError")
106 ssl.RAND_add("this is a random string", 75.0)
Thomas Woutersed03b412007-08-28 21:37:11 +0000107
Antoine Pitrou480a1242010-04-28 21:37:09 +0000108 def test_parse_cert(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000109 # note that this uses an 'unofficial' function in _ssl.c,
110 # provided solely for this test, to exercise the certificate
111 # parsing code
Antoine Pitroufb046912010-11-09 20:21:19 +0000112 p = ssl._ssl._test_decode_cert(CERTFILE)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000113 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000114 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Thomas Woutersed03b412007-08-28 21:37:11 +0000115
Antoine Pitrou480a1242010-04-28 21:37:09 +0000116 def test_DER_to_PEM(self):
117 with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f:
118 pem = f.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000119 d1 = ssl.PEM_cert_to_DER_cert(pem)
120 p2 = ssl.DER_cert_to_PEM_cert(d1)
121 d2 = ssl.PEM_cert_to_DER_cert(p2)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000122 self.assertEqual(d1, d2)
Antoine Pitrou9bfbe612010-04-27 22:08:08 +0000123 if not p2.startswith(ssl.PEM_HEADER + '\n'):
124 self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2)
125 if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'):
126 self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000127
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000128 def test_openssl_version(self):
129 n = ssl.OPENSSL_VERSION_NUMBER
130 t = ssl.OPENSSL_VERSION_INFO
131 s = ssl.OPENSSL_VERSION
132 self.assertIsInstance(n, int)
133 self.assertIsInstance(t, tuple)
134 self.assertIsInstance(s, str)
135 # Some sanity checks follow
136 # >= 0.9
137 self.assertGreaterEqual(n, 0x900000)
138 # < 2.0
139 self.assertLess(n, 0x20000000)
140 major, minor, fix, patch, status = t
141 self.assertGreaterEqual(major, 0)
142 self.assertLess(major, 2)
143 self.assertGreaterEqual(minor, 0)
144 self.assertLess(minor, 256)
145 self.assertGreaterEqual(fix, 0)
146 self.assertLess(fix, 256)
147 self.assertGreaterEqual(patch, 0)
148 self.assertLessEqual(patch, 26)
149 self.assertGreaterEqual(status, 0)
150 self.assertLessEqual(status, 15)
151 # Version string as returned by OpenSSL, the format might change
152 self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
153 (s, t))
154
Antoine Pitrou9d543662010-04-23 23:10:32 +0000155 @support.cpython_only
156 def test_refcycle(self):
157 # Issue #7943: an SSL object doesn't create reference cycles with
158 # itself.
159 s = socket.socket(socket.AF_INET)
160 ss = ssl.wrap_socket(s)
161 wr = weakref.ref(ss)
162 del ss
163 self.assertEqual(wr(), None)
164
Antoine Pitroua468adc2010-09-14 14:43:44 +0000165 def test_wrapped_unconnected(self):
166 # Methods on an unconnected SSLSocket propagate the original
167 # socket.error raise by the underlying socket object.
168 s = socket.socket(socket.AF_INET)
169 ss = ssl.wrap_socket(s)
170 self.assertRaises(socket.error, ss.recv, 1)
171 self.assertRaises(socket.error, ss.recv_into, bytearray(b'x'))
172 self.assertRaises(socket.error, ss.recvfrom, 1)
173 self.assertRaises(socket.error, ss.recvfrom_into, bytearray(b'x'), 1)
174 self.assertRaises(socket.error, ss.send, b'x')
175 self.assertRaises(socket.error, ss.sendto, b'x', ('0.0.0.0', 0))
176
Antoine Pitrou40f08742010-04-24 22:04:40 +0000177 def test_timeout(self):
178 # Issue #8524: when creating an SSL socket, the timeout of the
179 # original socket should be retained.
180 for timeout in (None, 0.0, 5.0):
181 s = socket.socket(socket.AF_INET)
182 s.settimeout(timeout)
183 ss = ssl.wrap_socket(s)
184 self.assertEqual(timeout, ss.gettimeout())
185
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000186 def test_errors(self):
187 sock = socket.socket()
Ezio Melottied3a7d22010-12-01 02:32:32 +0000188 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000189 "certfile must be specified",
190 ssl.wrap_socket, sock, keyfile=CERTFILE)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000191 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000192 "certfile must be specified for server-side operations",
193 ssl.wrap_socket, sock, server_side=True)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000194 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000195 "certfile must be specified for server-side operations",
196 ssl.wrap_socket, sock, server_side=True, certfile="")
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000197 s = ssl.wrap_socket(sock, server_side=True, certfile=CERTFILE)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000198 self.assertRaisesRegex(ValueError, "can't connect in server-side mode",
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000199 s.connect, (HOST, 8080))
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000200 with self.assertRaises(IOError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000201 with socket.socket() as sock:
202 ssl.wrap_socket(sock, certfile=WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000203 self.assertEqual(cm.exception.errno, errno.ENOENT)
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000204 with self.assertRaises(IOError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000205 with socket.socket() as sock:
206 ssl.wrap_socket(sock, certfile=CERTFILE, keyfile=WRONGCERT)
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000207 self.assertEqual(cm.exception.errno, errno.ENOENT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000208 with self.assertRaises(IOError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000209 with socket.socket() as sock:
210 ssl.wrap_socket(sock, certfile=WRONGCERT, keyfile=WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000211 self.assertEqual(cm.exception.errno, errno.ENOENT)
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000212
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000213 def test_match_hostname(self):
214 def ok(cert, hostname):
215 ssl.match_hostname(cert, hostname)
216 def fail(cert, hostname):
217 self.assertRaises(ssl.CertificateError,
218 ssl.match_hostname, cert, hostname)
219
220 cert = {'subject': ((('commonName', 'example.com'),),)}
221 ok(cert, 'example.com')
222 ok(cert, 'ExAmple.cOm')
223 fail(cert, 'www.example.com')
224 fail(cert, '.example.com')
225 fail(cert, 'example.org')
226 fail(cert, 'exampleXcom')
227
228 cert = {'subject': ((('commonName', '*.a.com'),),)}
229 ok(cert, 'foo.a.com')
230 fail(cert, 'bar.foo.a.com')
231 fail(cert, 'a.com')
232 fail(cert, 'Xa.com')
233 fail(cert, '.a.com')
234
235 cert = {'subject': ((('commonName', 'a.*.com'),),)}
236 ok(cert, 'a.foo.com')
237 fail(cert, 'a..com')
238 fail(cert, 'a.com')
239
240 cert = {'subject': ((('commonName', 'f*.com'),),)}
241 ok(cert, 'foo.com')
242 ok(cert, 'f.com')
243 fail(cert, 'bar.com')
244 fail(cert, 'foo.a.com')
245 fail(cert, 'bar.foo.com')
246
247 # Slightly fake real-world example
248 cert = {'notAfter': 'Jun 26 21:41:46 2011 GMT',
249 'subject': ((('commonName', 'linuxfrz.org'),),),
250 'subjectAltName': (('DNS', 'linuxfr.org'),
251 ('DNS', 'linuxfr.com'),
252 ('othername', '<unsupported>'))}
253 ok(cert, 'linuxfr.org')
254 ok(cert, 'linuxfr.com')
255 # Not a "DNS" entry
256 fail(cert, '<unsupported>')
257 # When there is a subjectAltName, commonName isn't used
258 fail(cert, 'linuxfrz.org')
259
260 # A pristine real-world example
261 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
262 'subject': ((('countryName', 'US'),),
263 (('stateOrProvinceName', 'California'),),
264 (('localityName', 'Mountain View'),),
265 (('organizationName', 'Google Inc'),),
266 (('commonName', 'mail.google.com'),))}
267 ok(cert, 'mail.google.com')
268 fail(cert, 'gmail.com')
269 # Only commonName is considered
270 fail(cert, 'California')
271
272 # Neither commonName nor subjectAltName
273 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
274 'subject': ((('countryName', 'US'),),
275 (('stateOrProvinceName', 'California'),),
276 (('localityName', 'Mountain View'),),
277 (('organizationName', 'Google Inc'),))}
278 fail(cert, 'mail.google.com')
279
280 # Empty cert / no cert
281 self.assertRaises(ValueError, ssl.match_hostname, None, 'example.com')
282 self.assertRaises(ValueError, ssl.match_hostname, {}, 'example.com')
283
Antoine Pitroud5323212010-10-22 18:19:07 +0000284 def test_server_side(self):
285 # server_hostname doesn't work for server sockets
286 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
Antoine Pitroud2eca372010-10-29 23:41:37 +0000287 with socket.socket() as sock:
288 self.assertRaises(ValueError, ctx.wrap_socket, sock, True,
289 server_hostname="some.hostname")
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000290
Antoine Pitrou152efa22010-05-16 18:19:27 +0000291class ContextTests(unittest.TestCase):
292
Antoine Pitrou23df4832010-08-04 17:14:06 +0000293 @skip_if_broken_ubuntu_ssl
Antoine Pitrou152efa22010-05-16 18:19:27 +0000294 def test_constructor(self):
295 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv2)
296 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
297 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv3)
298 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
299 self.assertRaises(TypeError, ssl.SSLContext)
300 self.assertRaises(ValueError, ssl.SSLContext, -1)
301 self.assertRaises(ValueError, ssl.SSLContext, 42)
302
Antoine Pitrou23df4832010-08-04 17:14:06 +0000303 @skip_if_broken_ubuntu_ssl
Antoine Pitrou152efa22010-05-16 18:19:27 +0000304 def test_protocol(self):
305 for proto in PROTOCOLS:
306 ctx = ssl.SSLContext(proto)
307 self.assertEqual(ctx.protocol, proto)
308
309 def test_ciphers(self):
310 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
311 ctx.set_ciphers("ALL")
312 ctx.set_ciphers("DEFAULT")
Ezio Melottied3a7d22010-12-01 02:32:32 +0000313 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
Antoine Pitrou30474062010-05-16 23:46:26 +0000314 ctx.set_ciphers("^$:,;?*'dorothyx")
Antoine Pitrou152efa22010-05-16 18:19:27 +0000315
Antoine Pitrou23df4832010-08-04 17:14:06 +0000316 @skip_if_broken_ubuntu_ssl
Antoine Pitroub5218772010-05-21 09:56:06 +0000317 def test_options(self):
318 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
319 # OP_ALL is the default value
320 self.assertEqual(ssl.OP_ALL, ctx.options)
321 ctx.options |= ssl.OP_NO_SSLv2
322 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2,
323 ctx.options)
324 ctx.options |= ssl.OP_NO_SSLv3
325 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3,
326 ctx.options)
327 if can_clear_options():
328 ctx.options = (ctx.options & ~ssl.OP_NO_SSLv2) | ssl.OP_NO_TLSv1
329 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_TLSv1 | ssl.OP_NO_SSLv3,
330 ctx.options)
331 ctx.options = 0
332 self.assertEqual(0, ctx.options)
333 else:
334 with self.assertRaises(ValueError):
335 ctx.options = 0
336
Antoine Pitrou152efa22010-05-16 18:19:27 +0000337 def test_verify(self):
338 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
339 # Default value
340 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
341 ctx.verify_mode = ssl.CERT_OPTIONAL
342 self.assertEqual(ctx.verify_mode, ssl.CERT_OPTIONAL)
343 ctx.verify_mode = ssl.CERT_REQUIRED
344 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
345 ctx.verify_mode = ssl.CERT_NONE
346 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
347 with self.assertRaises(TypeError):
348 ctx.verify_mode = None
349 with self.assertRaises(ValueError):
350 ctx.verify_mode = 42
351
352 def test_load_cert_chain(self):
353 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
354 # Combined key and cert in a single file
355 ctx.load_cert_chain(CERTFILE)
356 ctx.load_cert_chain(CERTFILE, keyfile=CERTFILE)
357 self.assertRaises(TypeError, ctx.load_cert_chain, keyfile=CERTFILE)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000358 with self.assertRaises(IOError) as cm:
Antoine Pitrou152efa22010-05-16 18:19:27 +0000359 ctx.load_cert_chain(WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000360 self.assertEqual(cm.exception.errno, errno.ENOENT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000361 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000362 ctx.load_cert_chain(BADCERT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000363 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000364 ctx.load_cert_chain(EMPTYCERT)
365 # Separate key and cert
Antoine Pitroud0919502010-05-17 10:30:00 +0000366 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000367 ctx.load_cert_chain(ONLYCERT, ONLYKEY)
368 ctx.load_cert_chain(certfile=ONLYCERT, keyfile=ONLYKEY)
369 ctx.load_cert_chain(certfile=BYTES_ONLYCERT, keyfile=BYTES_ONLYKEY)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000370 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000371 ctx.load_cert_chain(ONLYCERT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000372 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000373 ctx.load_cert_chain(ONLYKEY)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000374 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000375 ctx.load_cert_chain(certfile=ONLYKEY, keyfile=ONLYCERT)
376 # Mismatching key and cert
Antoine Pitroud0919502010-05-17 10:30:00 +0000377 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000378 with self.assertRaisesRegex(ssl.SSLError, "key values mismatch"):
Antoine Pitrou81564092010-10-08 23:06:24 +0000379 ctx.load_cert_chain(SVN_PYTHON_ORG_ROOT_CERT, ONLYKEY)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000380
381 def test_load_verify_locations(self):
382 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
383 ctx.load_verify_locations(CERTFILE)
384 ctx.load_verify_locations(cafile=CERTFILE, capath=None)
385 ctx.load_verify_locations(BYTES_CERTFILE)
386 ctx.load_verify_locations(cafile=BYTES_CERTFILE, capath=None)
387 self.assertRaises(TypeError, ctx.load_verify_locations)
388 self.assertRaises(TypeError, ctx.load_verify_locations, None, None)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000389 with self.assertRaises(IOError) as cm:
Antoine Pitrou152efa22010-05-16 18:19:27 +0000390 ctx.load_verify_locations(WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000391 self.assertEqual(cm.exception.errno, errno.ENOENT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000392 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000393 ctx.load_verify_locations(BADCERT)
394 ctx.load_verify_locations(CERTFILE, CAPATH)
395 ctx.load_verify_locations(CERTFILE, capath=BYTES_CAPATH)
396
Victor Stinner80f75e62011-01-29 11:31:20 +0000397 # Issue #10989: crash if the second argument type is invalid
398 self.assertRaises(TypeError, ctx.load_verify_locations, None, True)
399
Antoine Pitroueb585ad2010-10-22 18:24:20 +0000400 @skip_if_broken_ubuntu_ssl
Antoine Pitroub0182c82010-10-12 20:09:02 +0000401 def test_session_stats(self):
402 for proto in PROTOCOLS:
403 ctx = ssl.SSLContext(proto)
404 self.assertEqual(ctx.session_stats(), {
405 'number': 0,
406 'connect': 0,
407 'connect_good': 0,
408 'connect_renegotiate': 0,
409 'accept': 0,
410 'accept_good': 0,
411 'accept_renegotiate': 0,
412 'hits': 0,
413 'misses': 0,
414 'timeouts': 0,
415 'cache_full': 0,
416 })
417
Antoine Pitrou664c2d12010-11-17 20:29:42 +0000418 def test_set_default_verify_paths(self):
419 # There's not much we can do to test that it acts as expected,
420 # so just check it doesn't crash or raise an exception.
421 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
422 ctx.set_default_verify_paths()
423
Antoine Pitrou152efa22010-05-16 18:19:27 +0000424
Bill Janssen6e027db2007-11-15 22:23:56 +0000425class NetworkedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000426
Antoine Pitrou480a1242010-04-28 21:37:09 +0000427 def test_connect(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000428 with support.transient_internet("svn.python.org"):
429 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
430 cert_reqs=ssl.CERT_NONE)
431 try:
432 s.connect(("svn.python.org", 443))
433 self.assertEqual({}, s.getpeercert())
434 finally:
435 s.close()
436
437 # this should fail because we have no verification certs
438 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
439 cert_reqs=ssl.CERT_REQUIRED)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000440 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
441 s.connect, ("svn.python.org", 443))
Antoine Pitrou152efa22010-05-16 18:19:27 +0000442 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000443
Antoine Pitrou350c7222010-09-09 13:31:46 +0000444 # this should succeed because we specify the root cert
445 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
446 cert_reqs=ssl.CERT_REQUIRED,
447 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
448 try:
449 s.connect(("svn.python.org", 443))
450 self.assertTrue(s.getpeercert())
451 finally:
452 s.close()
Antoine Pitrou152efa22010-05-16 18:19:27 +0000453
454 def test_connect_with_context(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000455 with support.transient_internet("svn.python.org"):
456 # Same as test_connect, but with a separately created context
457 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
458 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
459 s.connect(("svn.python.org", 443))
460 try:
461 self.assertEqual({}, s.getpeercert())
462 finally:
463 s.close()
Antoine Pitroud5323212010-10-22 18:19:07 +0000464 # Same with a server hostname
465 s = ctx.wrap_socket(socket.socket(socket.AF_INET),
466 server_hostname="svn.python.org")
467 if ssl.HAS_SNI:
468 s.connect(("svn.python.org", 443))
469 s.close()
470 else:
471 self.assertRaises(ValueError, s.connect, ("svn.python.org", 443))
Antoine Pitrou350c7222010-09-09 13:31:46 +0000472 # This should fail because we have no verification certs
473 ctx.verify_mode = ssl.CERT_REQUIRED
474 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
Ezio Melottied3a7d22010-12-01 02:32:32 +0000475 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
Antoine Pitrou350c7222010-09-09 13:31:46 +0000476 s.connect, ("svn.python.org", 443))
Antoine Pitrou152efa22010-05-16 18:19:27 +0000477 s.close()
Antoine Pitrou350c7222010-09-09 13:31:46 +0000478 # This should succeed because we specify the root cert
479 ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
480 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
481 s.connect(("svn.python.org", 443))
482 try:
483 cert = s.getpeercert()
484 self.assertTrue(cert)
485 finally:
486 s.close()
Antoine Pitrou152efa22010-05-16 18:19:27 +0000487
488 def test_connect_capath(self):
489 # Verify server certificates using the `capath` argument
Antoine Pitrou467f28d2010-05-16 19:22:44 +0000490 # NOTE: the subject hashing algorithm has been changed between
491 # OpenSSL 0.9.8n and 1.0.0, as a result the capath directory must
492 # contain both versions of each certificate (same content, different
Antoine Pitroud7e4c1c2010-05-17 14:13:10 +0000493 # filename) for this test to be portable across OpenSSL releases.
Antoine Pitrou350c7222010-09-09 13:31:46 +0000494 with support.transient_internet("svn.python.org"):
495 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
496 ctx.verify_mode = ssl.CERT_REQUIRED
497 ctx.load_verify_locations(capath=CAPATH)
498 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
499 s.connect(("svn.python.org", 443))
500 try:
501 cert = s.getpeercert()
502 self.assertTrue(cert)
503 finally:
504 s.close()
505 # Same with a bytes `capath` argument
506 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
507 ctx.verify_mode = ssl.CERT_REQUIRED
508 ctx.load_verify_locations(capath=BYTES_CAPATH)
509 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
510 s.connect(("svn.python.org", 443))
511 try:
512 cert = s.getpeercert()
513 self.assertTrue(cert)
514 finally:
515 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000516
Antoine Pitroue3220242010-04-24 11:13:53 +0000517 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
518 def test_makefile_close(self):
519 # Issue #5238: creating a file-like object with makefile() shouldn't
520 # delay closing the underlying "real socket" (here tested with its
521 # file descriptor, hence skipping the test under Windows).
Antoine Pitrou350c7222010-09-09 13:31:46 +0000522 with support.transient_internet("svn.python.org"):
523 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
524 ss.connect(("svn.python.org", 443))
525 fd = ss.fileno()
526 f = ss.makefile()
527 f.close()
528 # The fd is still open
Antoine Pitroue3220242010-04-24 11:13:53 +0000529 os.read(fd, 0)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000530 # Closing the SSL socket should close the fd too
531 ss.close()
532 gc.collect()
533 with self.assertRaises(OSError) as e:
534 os.read(fd, 0)
535 self.assertEqual(e.exception.errno, errno.EBADF)
Antoine Pitroue3220242010-04-24 11:13:53 +0000536
Antoine Pitrou480a1242010-04-28 21:37:09 +0000537 def test_non_blocking_handshake(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000538 with support.transient_internet("svn.python.org"):
539 s = socket.socket(socket.AF_INET)
540 s.connect(("svn.python.org", 443))
541 s.setblocking(False)
542 s = ssl.wrap_socket(s,
543 cert_reqs=ssl.CERT_NONE,
544 do_handshake_on_connect=False)
545 count = 0
546 while True:
547 try:
548 count += 1
549 s.do_handshake()
550 break
551 except ssl.SSLError as err:
552 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
553 select.select([s], [], [])
554 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
555 select.select([], [s], [])
556 else:
557 raise
558 s.close()
559 if support.verbose:
560 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000561
Antoine Pitrou480a1242010-04-28 21:37:09 +0000562 def test_get_server_certificate(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000563 with support.transient_internet("svn.python.org"):
564 pem = ssl.get_server_certificate(("svn.python.org", 443))
565 if not pem:
566 self.fail("No server certificate on svn.python.org:443!")
Bill Janssen54cc54c2007-12-14 22:08:56 +0000567
Antoine Pitrou350c7222010-09-09 13:31:46 +0000568 try:
569 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
570 except ssl.SSLError as x:
571 #should fail
572 if support.verbose:
573 sys.stdout.write("%s\n" % x)
574 else:
575 self.fail("Got server certificate %s for svn.python.org!" % pem)
576
577 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
578 if not pem:
579 self.fail("No server certificate on svn.python.org:443!")
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000580 if support.verbose:
Antoine Pitrou350c7222010-09-09 13:31:46 +0000581 sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000582
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000583 def test_ciphers(self):
584 remote = ("svn.python.org", 443)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000585 with support.transient_internet(remote[0]):
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000586 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
Antoine Pitrou350c7222010-09-09 13:31:46 +0000587 cert_reqs=ssl.CERT_NONE, ciphers="ALL")
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000588 s.connect(remote)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000589 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
590 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")
591 s.connect(remote)
592 # Error checking can happen at instantiation or when connecting
Ezio Melottied3a7d22010-12-01 02:32:32 +0000593 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
Antoine Pitroud2eca372010-10-29 23:41:37 +0000594 with socket.socket(socket.AF_INET) as sock:
595 s = ssl.wrap_socket(sock,
596 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
597 s.connect(remote)
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000598
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000599 def test_algorithms(self):
600 # Issue #8484: all algorithms should be available when verifying a
601 # certificate.
Antoine Pitrou29619b22010-04-22 18:43:31 +0000602 # SHA256 was added in OpenSSL 0.9.8
603 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
604 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Victor Stinnerf332abb2011-01-08 03:16:05 +0000605 # https://sha2.hboeck.de/ was used until 2011-01-08 (no route to host)
606 remote = ("sha256.tbs-internet.com", 443)
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000607 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
Antoine Pitrou160fd932011-01-08 10:23:29 +0000608 with support.transient_internet("sha256.tbs-internet.com"):
Antoine Pitroua88c83c2010-09-07 20:42:19 +0000609 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
610 cert_reqs=ssl.CERT_REQUIRED,
611 ca_certs=sha256_cert,)
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000612 try:
613 s.connect(remote)
614 if support.verbose:
615 sys.stdout.write("\nCipher with %r is %r\n" %
616 (remote, s.cipher()))
617 sys.stdout.write("Certificate is:\n%s\n" %
618 pprint.pformat(s.getpeercert()))
619 finally:
620 s.close()
621
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000622
623try:
624 import threading
625except ImportError:
626 _have_threads = False
627else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000628 _have_threads = True
629
Antoine Pitrou803e6d62010-10-13 10:36:15 +0000630 from test.ssl_servers import make_https_server
631
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000632 class ThreadedEchoServer(threading.Thread):
633
634 class ConnectionHandler(threading.Thread):
635
636 """A mildly complicated class, because we want it to work both
637 with and without the SSL wrapper around the socket connection, so
638 that we can test the STARTTLS functionality."""
639
Bill Janssen6e027db2007-11-15 22:23:56 +0000640 def __init__(self, server, connsock, addr):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000641 self.server = server
642 self.running = False
643 self.sock = connsock
Bill Janssen6e027db2007-11-15 22:23:56 +0000644 self.addr = addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000645 self.sock.setblocking(1)
646 self.sslconn = None
647 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000648 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000649
Antoine Pitrou480a1242010-04-28 21:37:09 +0000650 def wrap_conn(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000651 try:
Antoine Pitroub5218772010-05-21 09:56:06 +0000652 self.sslconn = self.server.context.wrap_socket(
653 self.sock, server_side=True)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000654 except ssl.SSLError:
655 # XXX Various errors can have happened here, for example
656 # a mismatching protocol version, an invalid certificate,
657 # or a low-level bug. This should be made more discriminating.
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000658 if self.server.chatty:
Bill Janssen6e027db2007-11-15 22:23:56 +0000659 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000660 self.running = False
661 self.server.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000662 self.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000663 return False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000664 else:
Antoine Pitroub5218772010-05-21 09:56:06 +0000665 if self.server.context.verify_mode == ssl.CERT_REQUIRED:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000666 cert = self.sslconn.getpeercert()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000667 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000668 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
669 cert_binary = self.sslconn.getpeercert(True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000670 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000671 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
672 cipher = self.sslconn.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000673 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000674 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
675 return True
676
677 def read(self):
678 if self.sslconn:
679 return self.sslconn.read()
680 else:
681 return self.sock.recv(1024)
682
683 def write(self, bytes):
684 if self.sslconn:
685 return self.sslconn.write(bytes)
686 else:
687 return self.sock.send(bytes)
688
689 def close(self):
690 if self.sslconn:
691 self.sslconn.close()
692 else:
693 self.sock.close()
694
Antoine Pitrou480a1242010-04-28 21:37:09 +0000695 def run(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000696 self.running = True
697 if not self.server.starttls_server:
698 if not self.wrap_conn():
699 return
700 while self.running:
701 try:
702 msg = self.read()
Antoine Pitrou480a1242010-04-28 21:37:09 +0000703 stripped = msg.strip()
704 if not stripped:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000705 # eof, so quit this handler
706 self.running = False
707 self.close()
Antoine Pitrou480a1242010-04-28 21:37:09 +0000708 elif stripped == b'over':
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000709 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000710 sys.stdout.write(" server: client closed connection\n")
711 self.close()
712 return
Bill Janssen6e027db2007-11-15 22:23:56 +0000713 elif (self.server.starttls_server and
Antoine Pitrou764b8782010-04-28 22:57:15 +0000714 stripped == b'STARTTLS'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000715 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000716 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000717 self.write(b"OK\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000718 if not self.wrap_conn():
719 return
Bill Janssen40a0f662008-08-12 16:56:25 +0000720 elif (self.server.starttls_server and self.sslconn
Antoine Pitrou764b8782010-04-28 22:57:15 +0000721 and stripped == b'ENDTLS'):
Bill Janssen40a0f662008-08-12 16:56:25 +0000722 if support.verbose and self.server.connectionchatty:
723 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000724 self.write(b"OK\n")
Bill Janssen40a0f662008-08-12 16:56:25 +0000725 self.sock = self.sslconn.unwrap()
726 self.sslconn = None
727 if support.verbose and self.server.connectionchatty:
728 sys.stdout.write(" server: connection is now unencrypted...\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000729 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000730 if (support.verbose and
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000731 self.server.connectionchatty):
732 ctype = (self.sslconn and "encrypted") or "unencrypted"
Antoine Pitrou480a1242010-04-28 21:37:09 +0000733 sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
734 % (msg, ctype, msg.lower(), ctype))
735 self.write(msg.lower())
Bill Janssen6e027db2007-11-15 22:23:56 +0000736 except socket.error:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000737 if self.server.chatty:
738 handle_error("Test server failure:\n")
739 self.close()
740 self.running = False
741 # normally, we'd just stop here, but for the test
742 # harness, we want to stop the server
743 self.server.stop()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000744
Antoine Pitroub5218772010-05-21 09:56:06 +0000745 def __init__(self, certificate=None, ssl_version=None,
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000746 certreqs=None, cacerts=None,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000747 chatty=True, connectionchatty=False, starttls_server=False,
Antoine Pitroub5218772010-05-21 09:56:06 +0000748 ciphers=None, context=None):
749 if context:
750 self.context = context
751 else:
752 self.context = ssl.SSLContext(ssl_version
753 if ssl_version is not None
754 else ssl.PROTOCOL_TLSv1)
755 self.context.verify_mode = (certreqs if certreqs is not None
756 else ssl.CERT_NONE)
757 if cacerts:
758 self.context.load_verify_locations(cacerts)
759 if certificate:
760 self.context.load_cert_chain(certificate)
761 if ciphers:
762 self.context.set_ciphers(ciphers)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000763 self.chatty = chatty
764 self.connectionchatty = connectionchatty
765 self.starttls_server = starttls_server
766 self.sock = socket.socket()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000767 self.port = support.bind_port(self.sock)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000768 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000769 self.active = False
770 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000771 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000772
Antoine Pitrou480a1242010-04-28 21:37:09 +0000773 def start(self, flag=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000774 self.flag = flag
775 threading.Thread.start(self)
776
Antoine Pitrou480a1242010-04-28 21:37:09 +0000777 def run(self):
Antoine Pitrouaf7c6022010-04-27 09:56:02 +0000778 self.sock.settimeout(0.05)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000779 self.sock.listen(5)
780 self.active = True
781 if self.flag:
782 # signal an event
783 self.flag.set()
784 while self.active:
785 try:
786 newconn, connaddr = self.sock.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000787 if support.verbose and self.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000788 sys.stdout.write(' server: new connection from '
Bill Janssen6e027db2007-11-15 22:23:56 +0000789 + repr(connaddr) + '\n')
790 handler = self.ConnectionHandler(self, newconn, connaddr)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000791 handler.start()
792 except socket.timeout:
793 pass
794 except KeyboardInterrupt:
795 self.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000796 self.sock.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000797
Antoine Pitrou480a1242010-04-28 21:37:09 +0000798 def stop(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000799 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000800
Bill Janssen54cc54c2007-12-14 22:08:56 +0000801 class AsyncoreEchoServer(threading.Thread):
802
803 # this one's based on asyncore.dispatcher
804
805 class EchoServer (asyncore.dispatcher):
806
807 class ConnectionHandler (asyncore.dispatcher_with_send):
808
809 def __init__(self, conn, certfile):
810 self.socket = ssl.wrap_socket(conn, server_side=True,
811 certfile=certfile,
812 do_handshake_on_connect=False)
813 asyncore.dispatcher_with_send.__init__(self, self.socket)
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000814 self._ssl_accepting = True
815 self._do_ssl_handshake()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000816
817 def readable(self):
818 if isinstance(self.socket, ssl.SSLSocket):
819 while self.socket.pending() > 0:
820 self.handle_read_event()
821 return True
822
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000823 def _do_ssl_handshake(self):
824 try:
825 self.socket.do_handshake()
826 except ssl.SSLError as err:
827 if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
828 ssl.SSL_ERROR_WANT_WRITE):
829 return
830 elif err.args[0] == ssl.SSL_ERROR_EOF:
831 return self.handle_close()
832 raise
833 except socket.error as err:
834 if err.args[0] == errno.ECONNABORTED:
835 return self.handle_close()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000836 else:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000837 self._ssl_accepting = False
838
839 def handle_read(self):
840 if self._ssl_accepting:
841 self._do_ssl_handshake()
842 else:
843 data = self.recv(1024)
844 if support.verbose:
845 sys.stdout.write(" server: read %s from client\n" % repr(data))
846 if not data:
847 self.close()
848 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000849 self.send(data.lower())
Bill Janssen54cc54c2007-12-14 22:08:56 +0000850
851 def handle_close(self):
Bill Janssen2f5799b2008-06-29 00:08:12 +0000852 self.close()
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000853 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000854 sys.stdout.write(" server: closed connection %s\n" % self.socket)
855
856 def handle_error(self):
857 raise
858
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000859 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000860 self.certfile = certfile
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000861 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
862 self.port = support.bind_port(sock, '')
863 asyncore.dispatcher.__init__(self, sock)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000864 self.listen(5)
865
Giampaolo Rodolà977c7072010-10-04 21:08:36 +0000866 def handle_accepted(self, sock_obj, addr):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000867 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000868 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
869 self.ConnectionHandler(sock_obj, self.certfile)
870
871 def handle_error(self):
872 raise
873
Trent Nelson78520002008-04-10 20:54:35 +0000874 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000875 self.flag = None
876 self.active = False
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000877 self.server = self.EchoServer(certfile)
878 self.port = self.server.port
Bill Janssen54cc54c2007-12-14 22:08:56 +0000879 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000880 self.daemon = True
Bill Janssen54cc54c2007-12-14 22:08:56 +0000881
882 def __str__(self):
883 return "<%s %s>" % (self.__class__.__name__, self.server)
884
885 def start (self, flag=None):
886 self.flag = flag
887 threading.Thread.start(self)
888
Antoine Pitrou480a1242010-04-28 21:37:09 +0000889 def run(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000890 self.active = True
891 if self.flag:
892 self.flag.set()
893 while self.active:
894 try:
895 asyncore.loop(1)
896 except:
897 pass
898
Antoine Pitrou480a1242010-04-28 21:37:09 +0000899 def stop(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000900 self.active = False
901 self.server.close()
902
Antoine Pitrou480a1242010-04-28 21:37:09 +0000903 def bad_cert_test(certfile):
904 """
905 Launch a server with CERT_REQUIRED, and check that trying to
906 connect to it with the given client certificate fails.
907 """
Trent Nelson78520002008-04-10 20:54:35 +0000908 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000909 certreqs=ssl.CERT_REQUIRED,
Bill Janssen6e027db2007-11-15 22:23:56 +0000910 cacerts=CERTFILE, chatty=False,
911 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000912 flag = threading.Event()
913 server.start(flag)
914 # wait for it to start
915 flag.wait()
916 # try to connect
917 try:
Thomas Woutersed03b412007-08-28 21:37:11 +0000918 try:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000919 with socket.socket() as sock:
920 s = ssl.wrap_socket(sock,
921 certfile=certfile,
922 ssl_version=ssl.PROTOCOL_TLSv1)
923 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000924 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000925 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000926 sys.stdout.write("\nSSLError is %s\n" % x.args[1])
Antoine Pitrou05830aa2010-04-27 13:15:18 +0000927 except socket.error as x:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000928 if support.verbose:
Georg Brandlb75b6392010-10-24 14:20:22 +0000929 sys.stdout.write("\nsocket.error is %s\n" % x.args[1])
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000930 except IOError as x:
Giampaolo Rodolàcd9dfb92010-08-29 20:56:56 +0000931 if x.errno != errno.ENOENT:
932 raise
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000933 if support.verbose:
Giampaolo Rodolàcd9dfb92010-08-29 20:56:56 +0000934 sys.stdout.write("\IOError is %s\n" % str(x))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000935 else:
Antoine Pitroud75b2a92010-05-06 14:15:10 +0000936 raise AssertionError("Use of invalid cert should have failed!")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000937 finally:
938 server.stop()
939 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +0000940
Antoine Pitroub5218772010-05-21 09:56:06 +0000941 def server_params_test(client_context, server_context, indata=b"FOO\n",
942 chatty=True, connectionchatty=False):
Antoine Pitrou480a1242010-04-28 21:37:09 +0000943 """
944 Launch a server, connect a client to it and try various reads
945 and writes.
946 """
Antoine Pitroub5218772010-05-21 09:56:06 +0000947 server = ThreadedEchoServer(context=server_context,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000948 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +0000949 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000950 flag = threading.Event()
951 server.start(flag)
952 # wait for it to start
953 flag.wait()
954 # try to connect
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000955 try:
Antoine Pitroub5218772010-05-21 09:56:06 +0000956 s = client_context.wrap_socket(socket.socket())
Trent Nelson78520002008-04-10 20:54:35 +0000957 s.connect((HOST, server.port))
Antoine Pitrou480a1242010-04-28 21:37:09 +0000958 for arg in [indata, bytearray(indata), memoryview(indata)]:
Antoine Pitrou7d7aede2009-11-25 18:55:32 +0000959 if connectionchatty:
960 if support.verbose:
961 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +0000962 " client: sending %r...\n" % indata)
Antoine Pitrou7d7aede2009-11-25 18:55:32 +0000963 s.write(arg)
964 outdata = s.read()
965 if connectionchatty:
966 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000967 sys.stdout.write(" client: read %r\n" % outdata)
Antoine Pitrou7d7aede2009-11-25 18:55:32 +0000968 if outdata != indata.lower():
Antoine Pitroud75b2a92010-05-06 14:15:10 +0000969 raise AssertionError(
Antoine Pitrou480a1242010-04-28 21:37:09 +0000970 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
971 % (outdata[:20], len(outdata),
972 indata[:20].lower(), len(indata)))
973 s.write(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +0000974 if connectionchatty:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000975 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000976 sys.stdout.write(" client: closing connection.\n")
977 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000978 finally:
979 server.stop()
980 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +0000981
Antoine Pitroub5218772010-05-21 09:56:06 +0000982 def try_protocol_combo(server_protocol, client_protocol, expect_success,
983 certsreqs=None, server_options=0, client_options=0):
Benjamin Peterson2a691a82008-03-31 01:51:45 +0000984 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000985 certsreqs = ssl.CERT_NONE
Antoine Pitrou480a1242010-04-28 21:37:09 +0000986 certtype = {
987 ssl.CERT_NONE: "CERT_NONE",
988 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
989 ssl.CERT_REQUIRED: "CERT_REQUIRED",
990 }[certsreqs]
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000991 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000992 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000993 sys.stdout.write(formatstr %
994 (ssl.get_protocol_name(client_protocol),
995 ssl.get_protocol_name(server_protocol),
996 certtype))
Antoine Pitroub5218772010-05-21 09:56:06 +0000997 client_context = ssl.SSLContext(client_protocol)
998 client_context.options = ssl.OP_ALL | client_options
999 server_context = ssl.SSLContext(server_protocol)
1000 server_context.options = ssl.OP_ALL | server_options
1001 for ctx in (client_context, server_context):
1002 ctx.verify_mode = certsreqs
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +00001003 # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
1004 # will send an SSLv3 hello (rather than SSLv2) starting from
1005 # OpenSSL 1.0.0 (see issue #8322).
Antoine Pitroub5218772010-05-21 09:56:06 +00001006 ctx.set_ciphers("ALL")
1007 ctx.load_cert_chain(CERTFILE)
1008 ctx.load_verify_locations(CERTFILE)
1009 try:
1010 server_params_test(client_context, server_context,
1011 chatty=False, connectionchatty=False)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001012 # Protocol mismatch can result in either an SSLError, or a
1013 # "Connection reset by peer" error.
1014 except ssl.SSLError:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001015 if expect_success:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001016 raise
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001017 except socket.error as e:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001018 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001019 raise
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001020 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001021 if not expect_success:
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001022 raise AssertionError(
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001023 "Client protocol %s succeeded with server protocol %s!"
1024 % (ssl.get_protocol_name(client_protocol),
1025 ssl.get_protocol_name(server_protocol)))
1026
1027
Bill Janssen6e027db2007-11-15 22:23:56 +00001028 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001029
Antoine Pitrou23df4832010-08-04 17:14:06 +00001030 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001031 def test_echo(self):
1032 """Basic test of an SSL client connecting to a server"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001033 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001034 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00001035 for protocol in PROTOCOLS:
1036 context = ssl.SSLContext(protocol)
1037 context.load_cert_chain(CERTFILE)
1038 server_params_test(context, context,
1039 chatty=True, connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001040
Antoine Pitrou480a1242010-04-28 21:37:09 +00001041 def test_getpeercert(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001042 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001043 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00001044 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1045 context.verify_mode = ssl.CERT_REQUIRED
1046 context.load_verify_locations(CERTFILE)
1047 context.load_cert_chain(CERTFILE)
1048 server = ThreadedEchoServer(context=context, chatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001049 flag = threading.Event()
1050 server.start(flag)
1051 # wait for it to start
1052 flag.wait()
1053 # try to connect
1054 try:
Antoine Pitroub5218772010-05-21 09:56:06 +00001055 s = context.wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001056 s.connect((HOST, server.port))
1057 cert = s.getpeercert()
1058 self.assertTrue(cert, "Can't get peer certificate.")
1059 cipher = s.cipher()
1060 if support.verbose:
1061 sys.stdout.write(pprint.pformat(cert) + '\n')
1062 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
1063 if 'subject' not in cert:
1064 self.fail("No subject field in certificate: %s." %
1065 pprint.pformat(cert))
1066 if ((('organizationName', 'Python Software Foundation'),)
1067 not in cert['subject']):
1068 self.fail(
1069 "Missing or invalid 'organizationName' field in certificate subject; "
1070 "should be 'Python Software Foundation'.")
Antoine Pitroufb046912010-11-09 20:21:19 +00001071 self.assertIn('notBefore', cert)
1072 self.assertIn('notAfter', cert)
1073 before = ssl.cert_time_to_seconds(cert['notBefore'])
1074 after = ssl.cert_time_to_seconds(cert['notAfter'])
1075 self.assertLess(before, after)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001076 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001077 finally:
1078 server.stop()
1079 server.join()
1080
Antoine Pitrou480a1242010-04-28 21:37:09 +00001081 def test_empty_cert(self):
1082 """Connecting with an empty cert file"""
1083 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1084 "nullcert.pem"))
1085 def test_malformed_cert(self):
1086 """Connecting with a badly formatted certificate (syntax error)"""
1087 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1088 "badcert.pem"))
1089 def test_nonexisting_cert(self):
1090 """Connecting with a non-existing cert file"""
1091 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1092 "wrongcert.pem"))
1093 def test_malformed_key(self):
1094 """Connecting with a badly formatted key (syntax error)"""
1095 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1096 "badkey.pem"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001097
Antoine Pitrou480a1242010-04-28 21:37:09 +00001098 def test_rude_shutdown(self):
1099 """A brutal shutdown of an SSL server should raise an IOError
1100 in the client when attempting handshake.
1101 """
Trent Nelson6b240cd2008-04-10 20:12:06 +00001102 listener_ready = threading.Event()
1103 listener_gone = threading.Event()
Antoine Pitrou480a1242010-04-28 21:37:09 +00001104
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001105 s = socket.socket()
1106 port = support.bind_port(s, HOST)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001107
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001108 # `listener` runs in a thread. It sits in an accept() until
1109 # the main thread connects. Then it rudely closes the socket,
1110 # and sets Event `listener_gone` to let the main thread know
1111 # the socket is gone.
Trent Nelson6b240cd2008-04-10 20:12:06 +00001112 def listener():
Trent Nelson6b240cd2008-04-10 20:12:06 +00001113 s.listen(5)
1114 listener_ready.set()
Antoine Pitroud2eca372010-10-29 23:41:37 +00001115 newsock, addr = s.accept()
1116 newsock.close()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001117 s.close()
Trent Nelson6b240cd2008-04-10 20:12:06 +00001118 listener_gone.set()
1119
1120 def connector():
1121 listener_ready.wait()
Antoine Pitroud2eca372010-10-29 23:41:37 +00001122 with socket.socket() as c:
1123 c.connect((HOST, port))
1124 listener_gone.wait()
1125 try:
1126 ssl_sock = ssl.wrap_socket(c)
1127 except IOError:
1128 pass
1129 else:
1130 self.fail('connecting to closed SSL socket should have failed')
Trent Nelson6b240cd2008-04-10 20:12:06 +00001131
1132 t = threading.Thread(target=listener)
1133 t.start()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001134 try:
1135 connector()
1136 finally:
1137 t.join()
Trent Nelson6b240cd2008-04-10 20:12:06 +00001138
Antoine Pitrou23df4832010-08-04 17:14:06 +00001139 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001140 def test_protocol_sslv2(self):
1141 """Connecting to an SSLv2 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001142 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001143 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001144 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
1145 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
1146 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
1147 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
1148 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
1149 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00001150 # SSLv23 client with specific SSL options
1151 if no_sslv2_implies_sslv3_hello():
1152 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
1153 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
1154 client_options=ssl.OP_NO_SSLv2)
1155 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True,
1156 client_options=ssl.OP_NO_SSLv3)
1157 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True,
1158 client_options=ssl.OP_NO_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001159
Antoine Pitrou23df4832010-08-04 17:14:06 +00001160 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001161 def test_protocol_sslv23(self):
1162 """Connecting to an SSLv23 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001163 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001164 sys.stdout.write("\n")
1165 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001166 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001167 except (ssl.SSLError, socket.error) as x:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001168 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001169 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001170 sys.stdout.write(
1171 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
1172 % str(x))
Antoine Pitrou480a1242010-04-28 21:37:09 +00001173 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
1174 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
1175 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001176
Antoine Pitrou480a1242010-04-28 21:37:09 +00001177 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1178 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
1179 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001180
Antoine Pitrou480a1242010-04-28 21:37:09 +00001181 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1182 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
1183 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001184
Antoine Pitroub5218772010-05-21 09:56:06 +00001185 # Server with specific SSL options
1186 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False,
1187 server_options=ssl.OP_NO_SSLv3)
1188 # Will choose TLSv1
1189 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True,
1190 server_options=ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
1191 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, False,
1192 server_options=ssl.OP_NO_TLSv1)
1193
1194
Antoine Pitrou23df4832010-08-04 17:14:06 +00001195 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001196 def test_protocol_sslv3(self):
1197 """Connecting to an SSLv3 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001198 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001199 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001200 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
1201 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1202 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1203 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
1204 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
1205 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00001206 if no_sslv2_implies_sslv3_hello():
1207 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
1208 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, True,
1209 client_options=ssl.OP_NO_SSLv2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001210
Antoine Pitrou23df4832010-08-04 17:14:06 +00001211 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001212 def test_protocol_tlsv1(self):
1213 """Connecting to a TLSv1 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001214 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001215 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001216 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
1217 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
1218 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
1219 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
1220 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
1221 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001222
Antoine Pitrou480a1242010-04-28 21:37:09 +00001223 def test_starttls(self):
1224 """Switching from clear text to encrypted and back again."""
1225 msgs = (b"msg 1", b"MSG 2", b"STARTTLS", b"MSG 3", b"msg 4", b"ENDTLS", b"msg 5", b"msg 6")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001226
Trent Nelson78520002008-04-10 20:54:35 +00001227 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001228 ssl_version=ssl.PROTOCOL_TLSv1,
1229 starttls_server=True,
1230 chatty=True,
1231 connectionchatty=True)
1232 flag = threading.Event()
1233 server.start(flag)
1234 # wait for it to start
1235 flag.wait()
1236 # try to connect
1237 wrapped = False
1238 try:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001239 s = socket.socket()
1240 s.setblocking(1)
1241 s.connect((HOST, server.port))
1242 if support.verbose:
1243 sys.stdout.write("\n")
1244 for indata in msgs:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001245 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001246 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001247 " client: sending %r...\n" % indata)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001248 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001249 conn.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001250 outdata = conn.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001251 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001252 s.send(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001253 outdata = s.recv(1024)
Antoine Pitrou480a1242010-04-28 21:37:09 +00001254 msg = outdata.strip().lower()
1255 if indata == b"STARTTLS" and msg.startswith(b"ok"):
1256 # STARTTLS ok, switch to secure mode
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001257 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001258 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001259 " client: read %r from server, starting TLS...\n"
1260 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001261 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
1262 wrapped = True
Antoine Pitrou480a1242010-04-28 21:37:09 +00001263 elif indata == b"ENDTLS" and msg.startswith(b"ok"):
1264 # ENDTLS ok, switch back to clear text
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001265 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001266 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001267 " client: read %r from server, ending TLS...\n"
1268 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001269 s = conn.unwrap()
1270 wrapped = False
1271 else:
1272 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001273 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001274 " client: read %r from server\n" % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001275 if support.verbose:
1276 sys.stdout.write(" client: closing connection.\n")
1277 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001278 conn.write(b"over\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001279 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001280 s.send(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +00001281 if wrapped:
1282 conn.close()
1283 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001284 s.close()
1285 finally:
1286 server.stop()
1287 server.join()
1288
Antoine Pitrou480a1242010-04-28 21:37:09 +00001289 def test_socketserver(self):
1290 """Using a SocketServer to create and manage SSL connections."""
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001291 server = make_https_server(self, CERTFILE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001292 # try to connect
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001293 if support.verbose:
1294 sys.stdout.write('\n')
1295 with open(CERTFILE, 'rb') as f:
1296 d1 = f.read()
1297 d2 = ''
1298 # now fetch the same data from the HTTPS server
1299 url = 'https://%s:%d/%s' % (
1300 HOST, server.port, os.path.split(CERTFILE)[1])
1301 f = urllib.request.urlopen(url)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001302 try:
Barry Warsaw820c1202008-06-12 04:06:45 +00001303 dlen = f.info().get("content-length")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001304 if dlen and (int(dlen) > 0):
1305 d2 = f.read(int(dlen))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001306 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001307 sys.stdout.write(
1308 " client: read %d bytes from remote server '%s'\n"
1309 % (len(d2), server))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001310 finally:
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001311 f.close()
1312 self.assertEqual(d1, d2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001313
Antoine Pitrou480a1242010-04-28 21:37:09 +00001314 def test_asyncore_server(self):
1315 """Check the example asyncore integration."""
1316 indata = "TEST MESSAGE of mixed case\n"
Trent Nelson6b240cd2008-04-10 20:12:06 +00001317
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001318 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001319 sys.stdout.write("\n")
1320
Antoine Pitrou480a1242010-04-28 21:37:09 +00001321 indata = b"FOO\n"
Trent Nelson78520002008-04-10 20:54:35 +00001322 server = AsyncoreEchoServer(CERTFILE)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001323 flag = threading.Event()
1324 server.start(flag)
1325 # wait for it to start
1326 flag.wait()
1327 # try to connect
1328 try:
1329 s = ssl.wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001330 s.connect(('127.0.0.1', server.port))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001331 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001332 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001333 " client: sending %r...\n" % indata)
1334 s.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001335 outdata = s.read()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001336 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001337 sys.stdout.write(" client: read %r\n" % outdata)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001338 if outdata != indata.lower():
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001339 self.fail(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001340 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1341 % (outdata[:20], len(outdata),
1342 indata[:20].lower(), len(indata)))
1343 s.write(b"over\n")
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001344 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001345 sys.stdout.write(" client: closing connection.\n")
1346 s.close()
Antoine Pitroued986362010-08-15 23:28:10 +00001347 if support.verbose:
1348 sys.stdout.write(" client: connection closed.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001349 finally:
Antoine Pitroued986362010-08-15 23:28:10 +00001350 if support.verbose:
1351 sys.stdout.write(" cleanup: stopping server.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001352 server.stop()
Antoine Pitroued986362010-08-15 23:28:10 +00001353 if support.verbose:
1354 sys.stdout.write(" cleanup: joining server thread.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001355 server.join()
Antoine Pitroued986362010-08-15 23:28:10 +00001356 if support.verbose:
1357 sys.stdout.write(" cleanup: successfully joined.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001358
Antoine Pitrou480a1242010-04-28 21:37:09 +00001359 def test_recv_send(self):
1360 """Test recv(), send() and friends."""
Bill Janssen58afe4c2008-09-08 16:45:19 +00001361 if support.verbose:
1362 sys.stdout.write("\n")
1363
1364 server = ThreadedEchoServer(CERTFILE,
1365 certreqs=ssl.CERT_NONE,
1366 ssl_version=ssl.PROTOCOL_TLSv1,
1367 cacerts=CERTFILE,
1368 chatty=True,
1369 connectionchatty=False)
1370 flag = threading.Event()
1371 server.start(flag)
1372 # wait for it to start
1373 flag.wait()
1374 # try to connect
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001375 s = ssl.wrap_socket(socket.socket(),
1376 server_side=False,
1377 certfile=CERTFILE,
1378 ca_certs=CERTFILE,
1379 cert_reqs=ssl.CERT_NONE,
1380 ssl_version=ssl.PROTOCOL_TLSv1)
1381 s.connect((HOST, server.port))
Bill Janssen58afe4c2008-09-08 16:45:19 +00001382 try:
Bill Janssen58afe4c2008-09-08 16:45:19 +00001383 # helper methods for standardising recv* method signatures
1384 def _recv_into():
1385 b = bytearray(b"\0"*100)
1386 count = s.recv_into(b)
1387 return b[:count]
1388
1389 def _recvfrom_into():
1390 b = bytearray(b"\0"*100)
1391 count, addr = s.recvfrom_into(b)
1392 return b[:count]
1393
1394 # (name, method, whether to expect success, *args)
1395 send_methods = [
1396 ('send', s.send, True, []),
1397 ('sendto', s.sendto, False, ["some.address"]),
1398 ('sendall', s.sendall, True, []),
1399 ]
1400 recv_methods = [
1401 ('recv', s.recv, True, []),
1402 ('recvfrom', s.recvfrom, False, ["some.address"]),
1403 ('recv_into', _recv_into, True, []),
1404 ('recvfrom_into', _recvfrom_into, False, []),
1405 ]
1406 data_prefix = "PREFIX_"
1407
1408 for meth_name, send_meth, expect_success, args in send_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001409 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00001410 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001411 send_meth(indata, *args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001412 outdata = s.read()
Bill Janssen58afe4c2008-09-08 16:45:19 +00001413 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001414 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001415 "While sending with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00001416 "<<{outdata:r}>> ({nout:d}) received; "
1417 "expected <<{indata:r}>> ({nin:d})\n".format(
1418 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00001419 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00001420 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001421 )
1422 )
1423 except ValueError as e:
1424 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001425 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001426 "Failed to send with method <<{name:s}>>; "
1427 "expected to succeed.\n".format(name=meth_name)
1428 )
1429 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001430 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001431 "Method <<{name:s}>> failed with unexpected "
1432 "exception message: {exp:s}\n".format(
1433 name=meth_name, exp=e
1434 )
1435 )
1436
1437 for meth_name, recv_meth, expect_success, args in recv_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001438 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00001439 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001440 s.send(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001441 outdata = recv_meth(*args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001442 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001443 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001444 "While receiving with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00001445 "<<{outdata:r}>> ({nout:d}) received; "
1446 "expected <<{indata:r}>> ({nin:d})\n".format(
1447 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00001448 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00001449 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001450 )
1451 )
1452 except ValueError as e:
1453 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001454 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001455 "Failed to receive with method <<{name:s}>>; "
1456 "expected to succeed.\n".format(name=meth_name)
1457 )
1458 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001459 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001460 "Method <<{name:s}>> failed with unexpected "
1461 "exception message: {exp:s}\n".format(
1462 name=meth_name, exp=e
1463 )
1464 )
1465 # consume data
1466 s.read()
1467
Antoine Pitrou480a1242010-04-28 21:37:09 +00001468 s.write(b"over\n")
Bill Janssen58afe4c2008-09-08 16:45:19 +00001469 s.close()
1470 finally:
1471 server.stop()
1472 server.join()
1473
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001474 def test_handshake_timeout(self):
1475 # Issue #5103: SSL handshake must respect the socket timeout
1476 server = socket.socket(socket.AF_INET)
1477 host = "127.0.0.1"
1478 port = support.bind_port(server)
1479 started = threading.Event()
1480 finish = False
1481
1482 def serve():
1483 server.listen(5)
1484 started.set()
1485 conns = []
1486 while not finish:
1487 r, w, e = select.select([server], [], [], 0.1)
1488 if server in r:
1489 # Let the socket hang around rather than having
1490 # it closed by garbage collection.
1491 conns.append(server.accept()[0])
Antoine Pitroud2eca372010-10-29 23:41:37 +00001492 for sock in conns:
1493 sock.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001494
1495 t = threading.Thread(target=serve)
1496 t.start()
1497 started.wait()
1498
1499 try:
Antoine Pitrou40f08742010-04-24 22:04:40 +00001500 try:
1501 c = socket.socket(socket.AF_INET)
1502 c.settimeout(0.2)
1503 c.connect((host, port))
1504 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00001505 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00001506 ssl.wrap_socket, c)
Antoine Pitrou40f08742010-04-24 22:04:40 +00001507 finally:
1508 c.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001509 try:
1510 c = socket.socket(socket.AF_INET)
1511 c = ssl.wrap_socket(c)
1512 c.settimeout(0.2)
1513 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00001514 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00001515 c.connect, (host, port))
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001516 finally:
1517 c.close()
1518 finally:
1519 finish = True
1520 t.join()
1521 server.close()
1522
Bill Janssen58afe4c2008-09-08 16:45:19 +00001523
Thomas Woutersed03b412007-08-28 21:37:11 +00001524def test_main(verbose=False):
Antoine Pitrou15cee622010-08-04 16:45:21 +00001525 if support.verbose:
1526 plats = {
1527 'Linux': platform.linux_distribution,
1528 'Mac': platform.mac_ver,
1529 'Windows': platform.win32_ver,
1530 }
1531 for name, func in plats.items():
1532 plat = func()
1533 if plat and plat[0]:
1534 plat = '%s %r' % (name, plat)
1535 break
1536 else:
1537 plat = repr(platform.platform())
1538 print("test_ssl: testing with %r %r" %
1539 (ssl.OPENSSL_VERSION, ssl.OPENSSL_VERSION_INFO))
1540 print(" under %s" % plat)
Antoine Pitroud5323212010-10-22 18:19:07 +00001541 print(" HAS_SNI = %r" % ssl.HAS_SNI)
Antoine Pitrou15cee622010-08-04 16:45:21 +00001542
Antoine Pitrou152efa22010-05-16 18:19:27 +00001543 for filename in [
1544 CERTFILE, SVN_PYTHON_ORG_ROOT_CERT, BYTES_CERTFILE,
1545 ONLYCERT, ONLYKEY, BYTES_ONLYCERT, BYTES_ONLYKEY,
1546 BADCERT, BADKEY, EMPTYCERT]:
1547 if not os.path.exists(filename):
1548 raise support.TestFailed("Can't read certificate file %r" % filename)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001549
Antoine Pitrou152efa22010-05-16 18:19:27 +00001550 tests = [ContextTests, BasicSocketTests]
Thomas Woutersed03b412007-08-28 21:37:11 +00001551
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001552 if support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001553 tests.append(NetworkedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001554
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001555 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001556 thread_info = support.threading_setup()
1557 if thread_info and support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001558 tests.append(ThreadedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001559
Antoine Pitrou480a1242010-04-28 21:37:09 +00001560 try:
1561 support.run_unittest(*tests)
1562 finally:
1563 if _have_threads:
1564 support.threading_cleanup(*thread_info)
Thomas Woutersed03b412007-08-28 21:37:11 +00001565
1566if __name__ == "__main__":
1567 test_main()