blob: e5a07a3e9f290423882ffc96980d24620c8bb1b4 [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
Antoine Pitroueb585ad2010-10-22 18:24:20 +0000397 @skip_if_broken_ubuntu_ssl
Antoine Pitroub0182c82010-10-12 20:09:02 +0000398 def test_session_stats(self):
399 for proto in PROTOCOLS:
400 ctx = ssl.SSLContext(proto)
401 self.assertEqual(ctx.session_stats(), {
402 'number': 0,
403 'connect': 0,
404 'connect_good': 0,
405 'connect_renegotiate': 0,
406 'accept': 0,
407 'accept_good': 0,
408 'accept_renegotiate': 0,
409 'hits': 0,
410 'misses': 0,
411 'timeouts': 0,
412 'cache_full': 0,
413 })
414
Antoine Pitrou664c2d12010-11-17 20:29:42 +0000415 def test_set_default_verify_paths(self):
416 # There's not much we can do to test that it acts as expected,
417 # so just check it doesn't crash or raise an exception.
418 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
419 ctx.set_default_verify_paths()
420
Antoine Pitrou152efa22010-05-16 18:19:27 +0000421
Bill Janssen6e027db2007-11-15 22:23:56 +0000422class NetworkedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000423
Antoine Pitrou480a1242010-04-28 21:37:09 +0000424 def test_connect(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000425 with support.transient_internet("svn.python.org"):
426 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
427 cert_reqs=ssl.CERT_NONE)
428 try:
429 s.connect(("svn.python.org", 443))
430 self.assertEqual({}, s.getpeercert())
431 finally:
432 s.close()
433
434 # this should fail because we have no verification certs
435 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
436 cert_reqs=ssl.CERT_REQUIRED)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000437 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
438 s.connect, ("svn.python.org", 443))
Antoine Pitrou152efa22010-05-16 18:19:27 +0000439 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000440
Antoine Pitrou350c7222010-09-09 13:31:46 +0000441 # this should succeed because we specify the root cert
442 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
443 cert_reqs=ssl.CERT_REQUIRED,
444 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
445 try:
446 s.connect(("svn.python.org", 443))
447 self.assertTrue(s.getpeercert())
448 finally:
449 s.close()
Antoine Pitrou152efa22010-05-16 18:19:27 +0000450
451 def test_connect_with_context(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000452 with support.transient_internet("svn.python.org"):
453 # Same as test_connect, but with a separately created context
454 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
455 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
456 s.connect(("svn.python.org", 443))
457 try:
458 self.assertEqual({}, s.getpeercert())
459 finally:
460 s.close()
Antoine Pitroud5323212010-10-22 18:19:07 +0000461 # Same with a server hostname
462 s = ctx.wrap_socket(socket.socket(socket.AF_INET),
463 server_hostname="svn.python.org")
464 if ssl.HAS_SNI:
465 s.connect(("svn.python.org", 443))
466 s.close()
467 else:
468 self.assertRaises(ValueError, s.connect, ("svn.python.org", 443))
Antoine Pitrou350c7222010-09-09 13:31:46 +0000469 # This should fail because we have no verification certs
470 ctx.verify_mode = ssl.CERT_REQUIRED
471 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
Ezio Melottied3a7d22010-12-01 02:32:32 +0000472 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
Antoine Pitrou350c7222010-09-09 13:31:46 +0000473 s.connect, ("svn.python.org", 443))
Antoine Pitrou152efa22010-05-16 18:19:27 +0000474 s.close()
Antoine Pitrou350c7222010-09-09 13:31:46 +0000475 # This should succeed because we specify the root cert
476 ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
477 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
478 s.connect(("svn.python.org", 443))
479 try:
480 cert = s.getpeercert()
481 self.assertTrue(cert)
482 finally:
483 s.close()
Antoine Pitrou152efa22010-05-16 18:19:27 +0000484
485 def test_connect_capath(self):
486 # Verify server certificates using the `capath` argument
Antoine Pitrou467f28d2010-05-16 19:22:44 +0000487 # NOTE: the subject hashing algorithm has been changed between
488 # OpenSSL 0.9.8n and 1.0.0, as a result the capath directory must
489 # contain both versions of each certificate (same content, different
Antoine Pitroud7e4c1c2010-05-17 14:13:10 +0000490 # filename) for this test to be portable across OpenSSL releases.
Antoine Pitrou350c7222010-09-09 13:31:46 +0000491 with support.transient_internet("svn.python.org"):
492 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
493 ctx.verify_mode = ssl.CERT_REQUIRED
494 ctx.load_verify_locations(capath=CAPATH)
495 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
496 s.connect(("svn.python.org", 443))
497 try:
498 cert = s.getpeercert()
499 self.assertTrue(cert)
500 finally:
501 s.close()
502 # Same with a bytes `capath` argument
503 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
504 ctx.verify_mode = ssl.CERT_REQUIRED
505 ctx.load_verify_locations(capath=BYTES_CAPATH)
506 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
507 s.connect(("svn.python.org", 443))
508 try:
509 cert = s.getpeercert()
510 self.assertTrue(cert)
511 finally:
512 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000513
Antoine Pitroue3220242010-04-24 11:13:53 +0000514 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
515 def test_makefile_close(self):
516 # Issue #5238: creating a file-like object with makefile() shouldn't
517 # delay closing the underlying "real socket" (here tested with its
518 # file descriptor, hence skipping the test under Windows).
Antoine Pitrou350c7222010-09-09 13:31:46 +0000519 with support.transient_internet("svn.python.org"):
520 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
521 ss.connect(("svn.python.org", 443))
522 fd = ss.fileno()
523 f = ss.makefile()
524 f.close()
525 # The fd is still open
Antoine Pitroue3220242010-04-24 11:13:53 +0000526 os.read(fd, 0)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000527 # Closing the SSL socket should close the fd too
528 ss.close()
529 gc.collect()
530 with self.assertRaises(OSError) as e:
531 os.read(fd, 0)
532 self.assertEqual(e.exception.errno, errno.EBADF)
Antoine Pitroue3220242010-04-24 11:13:53 +0000533
Antoine Pitrou480a1242010-04-28 21:37:09 +0000534 def test_non_blocking_handshake(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000535 with support.transient_internet("svn.python.org"):
536 s = socket.socket(socket.AF_INET)
537 s.connect(("svn.python.org", 443))
538 s.setblocking(False)
539 s = ssl.wrap_socket(s,
540 cert_reqs=ssl.CERT_NONE,
541 do_handshake_on_connect=False)
542 count = 0
543 while True:
544 try:
545 count += 1
546 s.do_handshake()
547 break
548 except ssl.SSLError as err:
549 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
550 select.select([s], [], [])
551 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
552 select.select([], [s], [])
553 else:
554 raise
555 s.close()
556 if support.verbose:
557 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000558
Antoine Pitrou480a1242010-04-28 21:37:09 +0000559 def test_get_server_certificate(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000560 with support.transient_internet("svn.python.org"):
561 pem = ssl.get_server_certificate(("svn.python.org", 443))
562 if not pem:
563 self.fail("No server certificate on svn.python.org:443!")
Bill Janssen54cc54c2007-12-14 22:08:56 +0000564
Antoine Pitrou350c7222010-09-09 13:31:46 +0000565 try:
566 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
567 except ssl.SSLError as x:
568 #should fail
569 if support.verbose:
570 sys.stdout.write("%s\n" % x)
571 else:
572 self.fail("Got server certificate %s for svn.python.org!" % pem)
573
574 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
575 if not pem:
576 self.fail("No server certificate on svn.python.org:443!")
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000577 if support.verbose:
Antoine Pitrou350c7222010-09-09 13:31:46 +0000578 sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000579
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000580 def test_ciphers(self):
581 remote = ("svn.python.org", 443)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000582 with support.transient_internet(remote[0]):
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000583 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
Antoine Pitrou350c7222010-09-09 13:31:46 +0000584 cert_reqs=ssl.CERT_NONE, ciphers="ALL")
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000585 s.connect(remote)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000586 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
587 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")
588 s.connect(remote)
589 # Error checking can happen at instantiation or when connecting
Ezio Melottied3a7d22010-12-01 02:32:32 +0000590 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
Antoine Pitroud2eca372010-10-29 23:41:37 +0000591 with socket.socket(socket.AF_INET) as sock:
592 s = ssl.wrap_socket(sock,
593 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
594 s.connect(remote)
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000595
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000596 def test_algorithms(self):
597 # Issue #8484: all algorithms should be available when verifying a
598 # certificate.
Antoine Pitrou29619b22010-04-22 18:43:31 +0000599 # SHA256 was added in OpenSSL 0.9.8
600 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
601 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000602 # NOTE: https://sha256.tbs-internet.com is another possible test host
603 remote = ("sha2.hboeck.de", 443)
604 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
Antoine Pitroua88c83c2010-09-07 20:42:19 +0000605 with support.transient_internet("sha2.hboeck.de"):
606 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
607 cert_reqs=ssl.CERT_REQUIRED,
608 ca_certs=sha256_cert,)
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000609 try:
610 s.connect(remote)
611 if support.verbose:
612 sys.stdout.write("\nCipher with %r is %r\n" %
613 (remote, s.cipher()))
614 sys.stdout.write("Certificate is:\n%s\n" %
615 pprint.pformat(s.getpeercert()))
616 finally:
617 s.close()
618
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000619
620try:
621 import threading
622except ImportError:
623 _have_threads = False
624else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000625 _have_threads = True
626
Antoine Pitrou803e6d62010-10-13 10:36:15 +0000627 from test.ssl_servers import make_https_server
628
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000629 class ThreadedEchoServer(threading.Thread):
630
631 class ConnectionHandler(threading.Thread):
632
633 """A mildly complicated class, because we want it to work both
634 with and without the SSL wrapper around the socket connection, so
635 that we can test the STARTTLS functionality."""
636
Bill Janssen6e027db2007-11-15 22:23:56 +0000637 def __init__(self, server, connsock, addr):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000638 self.server = server
639 self.running = False
640 self.sock = connsock
Bill Janssen6e027db2007-11-15 22:23:56 +0000641 self.addr = addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000642 self.sock.setblocking(1)
643 self.sslconn = None
644 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000645 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000646
Antoine Pitrou480a1242010-04-28 21:37:09 +0000647 def wrap_conn(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000648 try:
Antoine Pitroub5218772010-05-21 09:56:06 +0000649 self.sslconn = self.server.context.wrap_socket(
650 self.sock, server_side=True)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000651 except ssl.SSLError:
652 # XXX Various errors can have happened here, for example
653 # a mismatching protocol version, an invalid certificate,
654 # or a low-level bug. This should be made more discriminating.
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000655 if self.server.chatty:
Bill Janssen6e027db2007-11-15 22:23:56 +0000656 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000657 self.running = False
658 self.server.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000659 self.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000660 return False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000661 else:
Antoine Pitroub5218772010-05-21 09:56:06 +0000662 if self.server.context.verify_mode == ssl.CERT_REQUIRED:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000663 cert = self.sslconn.getpeercert()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000664 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000665 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
666 cert_binary = self.sslconn.getpeercert(True)
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(" cert binary is " + str(len(cert_binary)) + " bytes\n")
669 cipher = self.sslconn.cipher()
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(" server: connection cipher is now " + str(cipher) + "\n")
672 return True
673
674 def read(self):
675 if self.sslconn:
676 return self.sslconn.read()
677 else:
678 return self.sock.recv(1024)
679
680 def write(self, bytes):
681 if self.sslconn:
682 return self.sslconn.write(bytes)
683 else:
684 return self.sock.send(bytes)
685
686 def close(self):
687 if self.sslconn:
688 self.sslconn.close()
689 else:
690 self.sock.close()
691
Antoine Pitrou480a1242010-04-28 21:37:09 +0000692 def run(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000693 self.running = True
694 if not self.server.starttls_server:
695 if not self.wrap_conn():
696 return
697 while self.running:
698 try:
699 msg = self.read()
Antoine Pitrou480a1242010-04-28 21:37:09 +0000700 stripped = msg.strip()
701 if not stripped:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000702 # eof, so quit this handler
703 self.running = False
704 self.close()
Antoine Pitrou480a1242010-04-28 21:37:09 +0000705 elif stripped == b'over':
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000706 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000707 sys.stdout.write(" server: client closed connection\n")
708 self.close()
709 return
Bill Janssen6e027db2007-11-15 22:23:56 +0000710 elif (self.server.starttls_server and
Antoine Pitrou764b8782010-04-28 22:57:15 +0000711 stripped == b'STARTTLS'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000712 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000713 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000714 self.write(b"OK\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000715 if not self.wrap_conn():
716 return
Bill Janssen40a0f662008-08-12 16:56:25 +0000717 elif (self.server.starttls_server and self.sslconn
Antoine Pitrou764b8782010-04-28 22:57:15 +0000718 and stripped == b'ENDTLS'):
Bill Janssen40a0f662008-08-12 16:56:25 +0000719 if support.verbose and self.server.connectionchatty:
720 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000721 self.write(b"OK\n")
Bill Janssen40a0f662008-08-12 16:56:25 +0000722 self.sock = self.sslconn.unwrap()
723 self.sslconn = None
724 if support.verbose and self.server.connectionchatty:
725 sys.stdout.write(" server: connection is now unencrypted...\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000726 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000727 if (support.verbose and
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000728 self.server.connectionchatty):
729 ctype = (self.sslconn and "encrypted") or "unencrypted"
Antoine Pitrou480a1242010-04-28 21:37:09 +0000730 sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
731 % (msg, ctype, msg.lower(), ctype))
732 self.write(msg.lower())
Bill Janssen6e027db2007-11-15 22:23:56 +0000733 except socket.error:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000734 if self.server.chatty:
735 handle_error("Test server failure:\n")
736 self.close()
737 self.running = False
738 # normally, we'd just stop here, but for the test
739 # harness, we want to stop the server
740 self.server.stop()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000741
Antoine Pitroub5218772010-05-21 09:56:06 +0000742 def __init__(self, certificate=None, ssl_version=None,
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000743 certreqs=None, cacerts=None,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000744 chatty=True, connectionchatty=False, starttls_server=False,
Antoine Pitroub5218772010-05-21 09:56:06 +0000745 ciphers=None, context=None):
746 if context:
747 self.context = context
748 else:
749 self.context = ssl.SSLContext(ssl_version
750 if ssl_version is not None
751 else ssl.PROTOCOL_TLSv1)
752 self.context.verify_mode = (certreqs if certreqs is not None
753 else ssl.CERT_NONE)
754 if cacerts:
755 self.context.load_verify_locations(cacerts)
756 if certificate:
757 self.context.load_cert_chain(certificate)
758 if ciphers:
759 self.context.set_ciphers(ciphers)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000760 self.chatty = chatty
761 self.connectionchatty = connectionchatty
762 self.starttls_server = starttls_server
763 self.sock = socket.socket()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000764 self.port = support.bind_port(self.sock)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000765 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000766 self.active = False
767 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000768 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000769
Antoine Pitrou480a1242010-04-28 21:37:09 +0000770 def start(self, flag=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000771 self.flag = flag
772 threading.Thread.start(self)
773
Antoine Pitrou480a1242010-04-28 21:37:09 +0000774 def run(self):
Antoine Pitrouaf7c6022010-04-27 09:56:02 +0000775 self.sock.settimeout(0.05)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000776 self.sock.listen(5)
777 self.active = True
778 if self.flag:
779 # signal an event
780 self.flag.set()
781 while self.active:
782 try:
783 newconn, connaddr = self.sock.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000784 if support.verbose and self.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000785 sys.stdout.write(' server: new connection from '
Bill Janssen6e027db2007-11-15 22:23:56 +0000786 + repr(connaddr) + '\n')
787 handler = self.ConnectionHandler(self, newconn, connaddr)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000788 handler.start()
789 except socket.timeout:
790 pass
791 except KeyboardInterrupt:
792 self.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000793 self.sock.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000794
Antoine Pitrou480a1242010-04-28 21:37:09 +0000795 def stop(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000796 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000797
Bill Janssen54cc54c2007-12-14 22:08:56 +0000798 class AsyncoreEchoServer(threading.Thread):
799
800 # this one's based on asyncore.dispatcher
801
802 class EchoServer (asyncore.dispatcher):
803
804 class ConnectionHandler (asyncore.dispatcher_with_send):
805
806 def __init__(self, conn, certfile):
807 self.socket = ssl.wrap_socket(conn, server_side=True,
808 certfile=certfile,
809 do_handshake_on_connect=False)
810 asyncore.dispatcher_with_send.__init__(self, self.socket)
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000811 self._ssl_accepting = True
812 self._do_ssl_handshake()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000813
814 def readable(self):
815 if isinstance(self.socket, ssl.SSLSocket):
816 while self.socket.pending() > 0:
817 self.handle_read_event()
818 return True
819
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000820 def _do_ssl_handshake(self):
821 try:
822 self.socket.do_handshake()
823 except ssl.SSLError as err:
824 if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
825 ssl.SSL_ERROR_WANT_WRITE):
826 return
827 elif err.args[0] == ssl.SSL_ERROR_EOF:
828 return self.handle_close()
829 raise
830 except socket.error as err:
831 if err.args[0] == errno.ECONNABORTED:
832 return self.handle_close()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000833 else:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000834 self._ssl_accepting = False
835
836 def handle_read(self):
837 if self._ssl_accepting:
838 self._do_ssl_handshake()
839 else:
840 data = self.recv(1024)
841 if support.verbose:
842 sys.stdout.write(" server: read %s from client\n" % repr(data))
843 if not data:
844 self.close()
845 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000846 self.send(data.lower())
Bill Janssen54cc54c2007-12-14 22:08:56 +0000847
848 def handle_close(self):
Bill Janssen2f5799b2008-06-29 00:08:12 +0000849 self.close()
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000850 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000851 sys.stdout.write(" server: closed connection %s\n" % self.socket)
852
853 def handle_error(self):
854 raise
855
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000856 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000857 self.certfile = certfile
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000858 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
859 self.port = support.bind_port(sock, '')
860 asyncore.dispatcher.__init__(self, sock)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000861 self.listen(5)
862
Giampaolo Rodolà977c7072010-10-04 21:08:36 +0000863 def handle_accepted(self, sock_obj, addr):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000864 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000865 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
866 self.ConnectionHandler(sock_obj, self.certfile)
867
868 def handle_error(self):
869 raise
870
Trent Nelson78520002008-04-10 20:54:35 +0000871 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000872 self.flag = None
873 self.active = False
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000874 self.server = self.EchoServer(certfile)
875 self.port = self.server.port
Bill Janssen54cc54c2007-12-14 22:08:56 +0000876 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000877 self.daemon = True
Bill Janssen54cc54c2007-12-14 22:08:56 +0000878
879 def __str__(self):
880 return "<%s %s>" % (self.__class__.__name__, self.server)
881
882 def start (self, flag=None):
883 self.flag = flag
884 threading.Thread.start(self)
885
Antoine Pitrou480a1242010-04-28 21:37:09 +0000886 def run(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000887 self.active = True
888 if self.flag:
889 self.flag.set()
890 while self.active:
891 try:
892 asyncore.loop(1)
893 except:
894 pass
895
Antoine Pitrou480a1242010-04-28 21:37:09 +0000896 def stop(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000897 self.active = False
898 self.server.close()
899
Antoine Pitrou480a1242010-04-28 21:37:09 +0000900 def bad_cert_test(certfile):
901 """
902 Launch a server with CERT_REQUIRED, and check that trying to
903 connect to it with the given client certificate fails.
904 """
Trent Nelson78520002008-04-10 20:54:35 +0000905 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000906 certreqs=ssl.CERT_REQUIRED,
Bill Janssen6e027db2007-11-15 22:23:56 +0000907 cacerts=CERTFILE, chatty=False,
908 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000909 flag = threading.Event()
910 server.start(flag)
911 # wait for it to start
912 flag.wait()
913 # try to connect
914 try:
Thomas Woutersed03b412007-08-28 21:37:11 +0000915 try:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000916 with socket.socket() as sock:
917 s = ssl.wrap_socket(sock,
918 certfile=certfile,
919 ssl_version=ssl.PROTOCOL_TLSv1)
920 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000921 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000922 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000923 sys.stdout.write("\nSSLError is %s\n" % x.args[1])
Antoine Pitrou05830aa2010-04-27 13:15:18 +0000924 except socket.error as x:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000925 if support.verbose:
Georg Brandlb75b6392010-10-24 14:20:22 +0000926 sys.stdout.write("\nsocket.error is %s\n" % x.args[1])
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000927 except IOError as x:
Giampaolo Rodolàcd9dfb92010-08-29 20:56:56 +0000928 if x.errno != errno.ENOENT:
929 raise
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000930 if support.verbose:
Giampaolo Rodolàcd9dfb92010-08-29 20:56:56 +0000931 sys.stdout.write("\IOError is %s\n" % str(x))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000932 else:
Antoine Pitroud75b2a92010-05-06 14:15:10 +0000933 raise AssertionError("Use of invalid cert should have failed!")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000934 finally:
935 server.stop()
936 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +0000937
Antoine Pitroub5218772010-05-21 09:56:06 +0000938 def server_params_test(client_context, server_context, indata=b"FOO\n",
939 chatty=True, connectionchatty=False):
Antoine Pitrou480a1242010-04-28 21:37:09 +0000940 """
941 Launch a server, connect a client to it and try various reads
942 and writes.
943 """
Antoine Pitroub5218772010-05-21 09:56:06 +0000944 server = ThreadedEchoServer(context=server_context,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000945 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +0000946 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000947 flag = threading.Event()
948 server.start(flag)
949 # wait for it to start
950 flag.wait()
951 # try to connect
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000952 try:
Antoine Pitroub5218772010-05-21 09:56:06 +0000953 s = client_context.wrap_socket(socket.socket())
Trent Nelson78520002008-04-10 20:54:35 +0000954 s.connect((HOST, server.port))
Antoine Pitrou480a1242010-04-28 21:37:09 +0000955 for arg in [indata, bytearray(indata), memoryview(indata)]:
Antoine Pitrou7d7aede2009-11-25 18:55:32 +0000956 if connectionchatty:
957 if support.verbose:
958 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +0000959 " client: sending %r...\n" % indata)
Antoine Pitrou7d7aede2009-11-25 18:55:32 +0000960 s.write(arg)
961 outdata = s.read()
962 if connectionchatty:
963 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000964 sys.stdout.write(" client: read %r\n" % outdata)
Antoine Pitrou7d7aede2009-11-25 18:55:32 +0000965 if outdata != indata.lower():
Antoine Pitroud75b2a92010-05-06 14:15:10 +0000966 raise AssertionError(
Antoine Pitrou480a1242010-04-28 21:37:09 +0000967 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
968 % (outdata[:20], len(outdata),
969 indata[:20].lower(), len(indata)))
970 s.write(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +0000971 if connectionchatty:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000972 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000973 sys.stdout.write(" client: closing connection.\n")
974 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000975 finally:
976 server.stop()
977 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +0000978
Antoine Pitroub5218772010-05-21 09:56:06 +0000979 def try_protocol_combo(server_protocol, client_protocol, expect_success,
980 certsreqs=None, server_options=0, client_options=0):
Benjamin Peterson2a691a82008-03-31 01:51:45 +0000981 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000982 certsreqs = ssl.CERT_NONE
Antoine Pitrou480a1242010-04-28 21:37:09 +0000983 certtype = {
984 ssl.CERT_NONE: "CERT_NONE",
985 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
986 ssl.CERT_REQUIRED: "CERT_REQUIRED",
987 }[certsreqs]
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000988 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000989 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000990 sys.stdout.write(formatstr %
991 (ssl.get_protocol_name(client_protocol),
992 ssl.get_protocol_name(server_protocol),
993 certtype))
Antoine Pitroub5218772010-05-21 09:56:06 +0000994 client_context = ssl.SSLContext(client_protocol)
995 client_context.options = ssl.OP_ALL | client_options
996 server_context = ssl.SSLContext(server_protocol)
997 server_context.options = ssl.OP_ALL | server_options
998 for ctx in (client_context, server_context):
999 ctx.verify_mode = certsreqs
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +00001000 # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
1001 # will send an SSLv3 hello (rather than SSLv2) starting from
1002 # OpenSSL 1.0.0 (see issue #8322).
Antoine Pitroub5218772010-05-21 09:56:06 +00001003 ctx.set_ciphers("ALL")
1004 ctx.load_cert_chain(CERTFILE)
1005 ctx.load_verify_locations(CERTFILE)
1006 try:
1007 server_params_test(client_context, server_context,
1008 chatty=False, connectionchatty=False)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001009 # Protocol mismatch can result in either an SSLError, or a
1010 # "Connection reset by peer" error.
1011 except ssl.SSLError:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001012 if expect_success:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001013 raise
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001014 except socket.error as e:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001015 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001016 raise
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001017 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001018 if not expect_success:
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001019 raise AssertionError(
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001020 "Client protocol %s succeeded with server protocol %s!"
1021 % (ssl.get_protocol_name(client_protocol),
1022 ssl.get_protocol_name(server_protocol)))
1023
1024
Bill Janssen6e027db2007-11-15 22:23:56 +00001025 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001026
Antoine Pitrou23df4832010-08-04 17:14:06 +00001027 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001028 def test_echo(self):
1029 """Basic test of an SSL client connecting to a server"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001030 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001031 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00001032 for protocol in PROTOCOLS:
1033 context = ssl.SSLContext(protocol)
1034 context.load_cert_chain(CERTFILE)
1035 server_params_test(context, context,
1036 chatty=True, connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001037
Antoine Pitrou480a1242010-04-28 21:37:09 +00001038 def test_getpeercert(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001039 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001040 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00001041 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1042 context.verify_mode = ssl.CERT_REQUIRED
1043 context.load_verify_locations(CERTFILE)
1044 context.load_cert_chain(CERTFILE)
1045 server = ThreadedEchoServer(context=context, chatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001046 flag = threading.Event()
1047 server.start(flag)
1048 # wait for it to start
1049 flag.wait()
1050 # try to connect
1051 try:
Antoine Pitroub5218772010-05-21 09:56:06 +00001052 s = context.wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001053 s.connect((HOST, server.port))
1054 cert = s.getpeercert()
1055 self.assertTrue(cert, "Can't get peer certificate.")
1056 cipher = s.cipher()
1057 if support.verbose:
1058 sys.stdout.write(pprint.pformat(cert) + '\n')
1059 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
1060 if 'subject' not in cert:
1061 self.fail("No subject field in certificate: %s." %
1062 pprint.pformat(cert))
1063 if ((('organizationName', 'Python Software Foundation'),)
1064 not in cert['subject']):
1065 self.fail(
1066 "Missing or invalid 'organizationName' field in certificate subject; "
1067 "should be 'Python Software Foundation'.")
Antoine Pitroufb046912010-11-09 20:21:19 +00001068 self.assertIn('notBefore', cert)
1069 self.assertIn('notAfter', cert)
1070 before = ssl.cert_time_to_seconds(cert['notBefore'])
1071 after = ssl.cert_time_to_seconds(cert['notAfter'])
1072 self.assertLess(before, after)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001073 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001074 finally:
1075 server.stop()
1076 server.join()
1077
Antoine Pitrou480a1242010-04-28 21:37:09 +00001078 def test_empty_cert(self):
1079 """Connecting with an empty cert file"""
1080 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1081 "nullcert.pem"))
1082 def test_malformed_cert(self):
1083 """Connecting with a badly formatted certificate (syntax error)"""
1084 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1085 "badcert.pem"))
1086 def test_nonexisting_cert(self):
1087 """Connecting with a non-existing cert file"""
1088 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1089 "wrongcert.pem"))
1090 def test_malformed_key(self):
1091 """Connecting with a badly formatted key (syntax error)"""
1092 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1093 "badkey.pem"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001094
Antoine Pitrou480a1242010-04-28 21:37:09 +00001095 def test_rude_shutdown(self):
1096 """A brutal shutdown of an SSL server should raise an IOError
1097 in the client when attempting handshake.
1098 """
Trent Nelson6b240cd2008-04-10 20:12:06 +00001099 listener_ready = threading.Event()
1100 listener_gone = threading.Event()
Antoine Pitrou480a1242010-04-28 21:37:09 +00001101
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001102 s = socket.socket()
1103 port = support.bind_port(s, HOST)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001104
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001105 # `listener` runs in a thread. It sits in an accept() until
1106 # the main thread connects. Then it rudely closes the socket,
1107 # and sets Event `listener_gone` to let the main thread know
1108 # the socket is gone.
Trent Nelson6b240cd2008-04-10 20:12:06 +00001109 def listener():
Trent Nelson6b240cd2008-04-10 20:12:06 +00001110 s.listen(5)
1111 listener_ready.set()
Antoine Pitroud2eca372010-10-29 23:41:37 +00001112 newsock, addr = s.accept()
1113 newsock.close()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001114 s.close()
Trent Nelson6b240cd2008-04-10 20:12:06 +00001115 listener_gone.set()
1116
1117 def connector():
1118 listener_ready.wait()
Antoine Pitroud2eca372010-10-29 23:41:37 +00001119 with socket.socket() as c:
1120 c.connect((HOST, port))
1121 listener_gone.wait()
1122 try:
1123 ssl_sock = ssl.wrap_socket(c)
1124 except IOError:
1125 pass
1126 else:
1127 self.fail('connecting to closed SSL socket should have failed')
Trent Nelson6b240cd2008-04-10 20:12:06 +00001128
1129 t = threading.Thread(target=listener)
1130 t.start()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001131 try:
1132 connector()
1133 finally:
1134 t.join()
Trent Nelson6b240cd2008-04-10 20:12:06 +00001135
Antoine Pitrou23df4832010-08-04 17:14:06 +00001136 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001137 def test_protocol_sslv2(self):
1138 """Connecting to an SSLv2 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001139 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001140 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001141 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
1142 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
1143 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
1144 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
1145 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
1146 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00001147 # SSLv23 client with specific SSL options
1148 if no_sslv2_implies_sslv3_hello():
1149 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
1150 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
1151 client_options=ssl.OP_NO_SSLv2)
1152 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True,
1153 client_options=ssl.OP_NO_SSLv3)
1154 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True,
1155 client_options=ssl.OP_NO_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001156
Antoine Pitrou23df4832010-08-04 17:14:06 +00001157 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001158 def test_protocol_sslv23(self):
1159 """Connecting to an SSLv23 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001160 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001161 sys.stdout.write("\n")
1162 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001163 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001164 except (ssl.SSLError, socket.error) as x:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001165 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001166 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001167 sys.stdout.write(
1168 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
1169 % str(x))
Antoine Pitrou480a1242010-04-28 21:37:09 +00001170 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
1171 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
1172 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001173
Antoine Pitrou480a1242010-04-28 21:37:09 +00001174 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1175 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
1176 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001177
Antoine Pitrou480a1242010-04-28 21:37:09 +00001178 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1179 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
1180 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001181
Antoine Pitroub5218772010-05-21 09:56:06 +00001182 # Server with specific SSL options
1183 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False,
1184 server_options=ssl.OP_NO_SSLv3)
1185 # Will choose TLSv1
1186 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True,
1187 server_options=ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
1188 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, False,
1189 server_options=ssl.OP_NO_TLSv1)
1190
1191
Antoine Pitrou23df4832010-08-04 17:14:06 +00001192 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001193 def test_protocol_sslv3(self):
1194 """Connecting to an SSLv3 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001195 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001196 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001197 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
1198 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1199 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1200 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
1201 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
1202 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00001203 if no_sslv2_implies_sslv3_hello():
1204 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
1205 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, True,
1206 client_options=ssl.OP_NO_SSLv2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001207
Antoine Pitrou23df4832010-08-04 17:14:06 +00001208 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001209 def test_protocol_tlsv1(self):
1210 """Connecting to a TLSv1 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001211 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001212 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001213 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
1214 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
1215 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
1216 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
1217 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
1218 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001219
Antoine Pitrou480a1242010-04-28 21:37:09 +00001220 def test_starttls(self):
1221 """Switching from clear text to encrypted and back again."""
1222 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 +00001223
Trent Nelson78520002008-04-10 20:54:35 +00001224 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001225 ssl_version=ssl.PROTOCOL_TLSv1,
1226 starttls_server=True,
1227 chatty=True,
1228 connectionchatty=True)
1229 flag = threading.Event()
1230 server.start(flag)
1231 # wait for it to start
1232 flag.wait()
1233 # try to connect
1234 wrapped = False
1235 try:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001236 s = socket.socket()
1237 s.setblocking(1)
1238 s.connect((HOST, server.port))
1239 if support.verbose:
1240 sys.stdout.write("\n")
1241 for indata in msgs:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001242 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001243 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001244 " client: sending %r...\n" % indata)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001245 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001246 conn.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001247 outdata = conn.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001248 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001249 s.send(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001250 outdata = s.recv(1024)
Antoine Pitrou480a1242010-04-28 21:37:09 +00001251 msg = outdata.strip().lower()
1252 if indata == b"STARTTLS" and msg.startswith(b"ok"):
1253 # STARTTLS ok, switch to secure mode
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001254 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001255 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001256 " client: read %r from server, starting TLS...\n"
1257 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001258 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
1259 wrapped = True
Antoine Pitrou480a1242010-04-28 21:37:09 +00001260 elif indata == b"ENDTLS" and msg.startswith(b"ok"):
1261 # ENDTLS ok, switch back to clear text
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001262 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001263 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001264 " client: read %r from server, ending TLS...\n"
1265 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001266 s = conn.unwrap()
1267 wrapped = False
1268 else:
1269 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001270 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001271 " client: read %r from server\n" % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001272 if support.verbose:
1273 sys.stdout.write(" client: closing connection.\n")
1274 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001275 conn.write(b"over\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001276 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001277 s.send(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +00001278 if wrapped:
1279 conn.close()
1280 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001281 s.close()
1282 finally:
1283 server.stop()
1284 server.join()
1285
Antoine Pitrou480a1242010-04-28 21:37:09 +00001286 def test_socketserver(self):
1287 """Using a SocketServer to create and manage SSL connections."""
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001288 server = make_https_server(self, CERTFILE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001289 # try to connect
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001290 if support.verbose:
1291 sys.stdout.write('\n')
1292 with open(CERTFILE, 'rb') as f:
1293 d1 = f.read()
1294 d2 = ''
1295 # now fetch the same data from the HTTPS server
1296 url = 'https://%s:%d/%s' % (
1297 HOST, server.port, os.path.split(CERTFILE)[1])
1298 f = urllib.request.urlopen(url)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001299 try:
Barry Warsaw820c1202008-06-12 04:06:45 +00001300 dlen = f.info().get("content-length")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001301 if dlen and (int(dlen) > 0):
1302 d2 = f.read(int(dlen))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001303 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001304 sys.stdout.write(
1305 " client: read %d bytes from remote server '%s'\n"
1306 % (len(d2), server))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001307 finally:
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001308 f.close()
1309 self.assertEqual(d1, d2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001310
Antoine Pitrou480a1242010-04-28 21:37:09 +00001311 def test_asyncore_server(self):
1312 """Check the example asyncore integration."""
1313 indata = "TEST MESSAGE of mixed case\n"
Trent Nelson6b240cd2008-04-10 20:12:06 +00001314
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001315 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001316 sys.stdout.write("\n")
1317
Antoine Pitrou480a1242010-04-28 21:37:09 +00001318 indata = b"FOO\n"
Trent Nelson78520002008-04-10 20:54:35 +00001319 server = AsyncoreEchoServer(CERTFILE)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001320 flag = threading.Event()
1321 server.start(flag)
1322 # wait for it to start
1323 flag.wait()
1324 # try to connect
1325 try:
1326 s = ssl.wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001327 s.connect(('127.0.0.1', server.port))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001328 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001329 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001330 " client: sending %r...\n" % indata)
1331 s.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001332 outdata = s.read()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001333 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001334 sys.stdout.write(" client: read %r\n" % outdata)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001335 if outdata != indata.lower():
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001336 self.fail(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001337 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1338 % (outdata[:20], len(outdata),
1339 indata[:20].lower(), len(indata)))
1340 s.write(b"over\n")
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001341 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001342 sys.stdout.write(" client: closing connection.\n")
1343 s.close()
Antoine Pitroued986362010-08-15 23:28:10 +00001344 if support.verbose:
1345 sys.stdout.write(" client: connection closed.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001346 finally:
Antoine Pitroued986362010-08-15 23:28:10 +00001347 if support.verbose:
1348 sys.stdout.write(" cleanup: stopping server.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001349 server.stop()
Antoine Pitroued986362010-08-15 23:28:10 +00001350 if support.verbose:
1351 sys.stdout.write(" cleanup: joining server thread.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001352 server.join()
Antoine Pitroued986362010-08-15 23:28:10 +00001353 if support.verbose:
1354 sys.stdout.write(" cleanup: successfully joined.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001355
Antoine Pitrou480a1242010-04-28 21:37:09 +00001356 def test_recv_send(self):
1357 """Test recv(), send() and friends."""
Bill Janssen58afe4c2008-09-08 16:45:19 +00001358 if support.verbose:
1359 sys.stdout.write("\n")
1360
1361 server = ThreadedEchoServer(CERTFILE,
1362 certreqs=ssl.CERT_NONE,
1363 ssl_version=ssl.PROTOCOL_TLSv1,
1364 cacerts=CERTFILE,
1365 chatty=True,
1366 connectionchatty=False)
1367 flag = threading.Event()
1368 server.start(flag)
1369 # wait for it to start
1370 flag.wait()
1371 # try to connect
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001372 s = ssl.wrap_socket(socket.socket(),
1373 server_side=False,
1374 certfile=CERTFILE,
1375 ca_certs=CERTFILE,
1376 cert_reqs=ssl.CERT_NONE,
1377 ssl_version=ssl.PROTOCOL_TLSv1)
1378 s.connect((HOST, server.port))
Bill Janssen58afe4c2008-09-08 16:45:19 +00001379 try:
Bill Janssen58afe4c2008-09-08 16:45:19 +00001380 # helper methods for standardising recv* method signatures
1381 def _recv_into():
1382 b = bytearray(b"\0"*100)
1383 count = s.recv_into(b)
1384 return b[:count]
1385
1386 def _recvfrom_into():
1387 b = bytearray(b"\0"*100)
1388 count, addr = s.recvfrom_into(b)
1389 return b[:count]
1390
1391 # (name, method, whether to expect success, *args)
1392 send_methods = [
1393 ('send', s.send, True, []),
1394 ('sendto', s.sendto, False, ["some.address"]),
1395 ('sendall', s.sendall, True, []),
1396 ]
1397 recv_methods = [
1398 ('recv', s.recv, True, []),
1399 ('recvfrom', s.recvfrom, False, ["some.address"]),
1400 ('recv_into', _recv_into, True, []),
1401 ('recvfrom_into', _recvfrom_into, False, []),
1402 ]
1403 data_prefix = "PREFIX_"
1404
1405 for meth_name, send_meth, expect_success, args in send_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001406 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00001407 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001408 send_meth(indata, *args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001409 outdata = s.read()
Bill Janssen58afe4c2008-09-08 16:45:19 +00001410 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001411 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001412 "While sending with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00001413 "<<{outdata:r}>> ({nout:d}) received; "
1414 "expected <<{indata:r}>> ({nin:d})\n".format(
1415 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00001416 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00001417 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001418 )
1419 )
1420 except ValueError as e:
1421 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001422 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001423 "Failed to send with method <<{name:s}>>; "
1424 "expected to succeed.\n".format(name=meth_name)
1425 )
1426 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001427 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001428 "Method <<{name:s}>> failed with unexpected "
1429 "exception message: {exp:s}\n".format(
1430 name=meth_name, exp=e
1431 )
1432 )
1433
1434 for meth_name, recv_meth, expect_success, args in recv_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001435 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00001436 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001437 s.send(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001438 outdata = recv_meth(*args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001439 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001440 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001441 "While receiving with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00001442 "<<{outdata:r}>> ({nout:d}) received; "
1443 "expected <<{indata:r}>> ({nin:d})\n".format(
1444 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00001445 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00001446 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001447 )
1448 )
1449 except ValueError as e:
1450 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001451 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001452 "Failed to receive with method <<{name:s}>>; "
1453 "expected to succeed.\n".format(name=meth_name)
1454 )
1455 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001456 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001457 "Method <<{name:s}>> failed with unexpected "
1458 "exception message: {exp:s}\n".format(
1459 name=meth_name, exp=e
1460 )
1461 )
1462 # consume data
1463 s.read()
1464
Antoine Pitrou480a1242010-04-28 21:37:09 +00001465 s.write(b"over\n")
Bill Janssen58afe4c2008-09-08 16:45:19 +00001466 s.close()
1467 finally:
1468 server.stop()
1469 server.join()
1470
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001471 def test_handshake_timeout(self):
1472 # Issue #5103: SSL handshake must respect the socket timeout
1473 server = socket.socket(socket.AF_INET)
1474 host = "127.0.0.1"
1475 port = support.bind_port(server)
1476 started = threading.Event()
1477 finish = False
1478
1479 def serve():
1480 server.listen(5)
1481 started.set()
1482 conns = []
1483 while not finish:
1484 r, w, e = select.select([server], [], [], 0.1)
1485 if server in r:
1486 # Let the socket hang around rather than having
1487 # it closed by garbage collection.
1488 conns.append(server.accept()[0])
Antoine Pitroud2eca372010-10-29 23:41:37 +00001489 for sock in conns:
1490 sock.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001491
1492 t = threading.Thread(target=serve)
1493 t.start()
1494 started.wait()
1495
1496 try:
Antoine Pitrou40f08742010-04-24 22:04:40 +00001497 try:
1498 c = socket.socket(socket.AF_INET)
1499 c.settimeout(0.2)
1500 c.connect((host, port))
1501 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00001502 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00001503 ssl.wrap_socket, c)
Antoine Pitrou40f08742010-04-24 22:04:40 +00001504 finally:
1505 c.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001506 try:
1507 c = socket.socket(socket.AF_INET)
1508 c = ssl.wrap_socket(c)
1509 c.settimeout(0.2)
1510 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00001511 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00001512 c.connect, (host, port))
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001513 finally:
1514 c.close()
1515 finally:
1516 finish = True
1517 t.join()
1518 server.close()
1519
Bill Janssen58afe4c2008-09-08 16:45:19 +00001520
Thomas Woutersed03b412007-08-28 21:37:11 +00001521def test_main(verbose=False):
Antoine Pitrou15cee622010-08-04 16:45:21 +00001522 if support.verbose:
1523 plats = {
1524 'Linux': platform.linux_distribution,
1525 'Mac': platform.mac_ver,
1526 'Windows': platform.win32_ver,
1527 }
1528 for name, func in plats.items():
1529 plat = func()
1530 if plat and plat[0]:
1531 plat = '%s %r' % (name, plat)
1532 break
1533 else:
1534 plat = repr(platform.platform())
1535 print("test_ssl: testing with %r %r" %
1536 (ssl.OPENSSL_VERSION, ssl.OPENSSL_VERSION_INFO))
1537 print(" under %s" % plat)
Antoine Pitroud5323212010-10-22 18:19:07 +00001538 print(" HAS_SNI = %r" % ssl.HAS_SNI)
Antoine Pitrou15cee622010-08-04 16:45:21 +00001539
Antoine Pitrou152efa22010-05-16 18:19:27 +00001540 for filename in [
1541 CERTFILE, SVN_PYTHON_ORG_ROOT_CERT, BYTES_CERTFILE,
1542 ONLYCERT, ONLYKEY, BYTES_ONLYCERT, BYTES_ONLYKEY,
1543 BADCERT, BADKEY, EMPTYCERT]:
1544 if not os.path.exists(filename):
1545 raise support.TestFailed("Can't read certificate file %r" % filename)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001546
Antoine Pitrou152efa22010-05-16 18:19:27 +00001547 tests = [ContextTests, BasicSocketTests]
Thomas Woutersed03b412007-08-28 21:37:11 +00001548
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001549 if support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001550 tests.append(NetworkedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001551
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001552 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001553 thread_info = support.threading_setup()
1554 if thread_info and support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001555 tests.append(ThreadedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001556
Antoine Pitrou480a1242010-04-28 21:37:09 +00001557 try:
1558 support.run_unittest(*tests)
1559 finally:
1560 if _have_threads:
1561 support.threading_cleanup(*thread_info)
Thomas Woutersed03b412007-08-28 21:37:11 +00001562
1563if __name__ == "__main__":
1564 test_main()