blob: 0b9e6b524c04f2ab891cc7620e79fc6ebd1e58ee [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
Jeremy Hylton1afc1692008-06-18 20:49:58 +000014import urllib.parse, 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
Georg Brandl24420152008-05-26 16:32:26 +000021from http.server import HTTPServer, SimpleHTTPRequestHandler
Thomas Wouters1b7f8912007-09-19 03:06:30 +000022
Thomas Woutersed03b412007-08-28 21:37:11 +000023# Optionally test SSL support, if we have it in the tested platform
24skip_expected = False
25try:
26 import ssl
27except ImportError:
28 skip_expected = True
Antoine Pitrou27ba6382010-05-16 20:35:03 +000029else:
30 PROTOCOLS = [
31 ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3,
32 ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1
33 ]
Thomas Woutersed03b412007-08-28 21:37:11 +000034
Benjamin Petersonee8712c2008-05-20 21:35:26 +000035HOST = support.HOST
Antoine Pitrou152efa22010-05-16 18:19:27 +000036
37data_file = lambda name: os.path.join(os.path.dirname(__file__), name)
Antoine Pitrou152efa22010-05-16 18:19:27 +000038
39CERTFILE = data_file("keycert.pem")
Victor Stinner313a1202010-06-11 23:56:51 +000040BYTES_CERTFILE = os.fsencode(CERTFILE)
Antoine Pitrou152efa22010-05-16 18:19:27 +000041ONLYCERT = data_file("ssl_cert.pem")
42ONLYKEY = data_file("ssl_key.pem")
Victor Stinner313a1202010-06-11 23:56:51 +000043BYTES_ONLYCERT = os.fsencode(ONLYCERT)
44BYTES_ONLYKEY = os.fsencode(ONLYKEY)
Antoine Pitrou152efa22010-05-16 18:19:27 +000045CAPATH = data_file("capath")
Victor Stinner313a1202010-06-11 23:56:51 +000046BYTES_CAPATH = os.fsencode(CAPATH)
Antoine Pitrou152efa22010-05-16 18:19:27 +000047
48SVN_PYTHON_ORG_ROOT_CERT = data_file("https_svn_python_org_root.pem")
49
50EMPTYCERT = data_file("nullcert.pem")
51BADCERT = data_file("badcert.pem")
52WRONGCERT = data_file("XXXnonexisting.pem")
53BADKEY = data_file("badkey.pem")
54
Thomas Woutersed03b412007-08-28 21:37:11 +000055
Thomas Woutersed03b412007-08-28 21:37:11 +000056def handle_error(prefix):
57 exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
Benjamin Petersonee8712c2008-05-20 21:35:26 +000058 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000059 sys.stdout.write(prefix + exc_format)
Thomas Woutersed03b412007-08-28 21:37:11 +000060
Antoine Pitroub5218772010-05-21 09:56:06 +000061def can_clear_options():
62 # 0.9.8m or higher
63 return ssl.OPENSSL_VERSION_INFO >= (0, 9, 8, 13, 15)
64
65def no_sslv2_implies_sslv3_hello():
66 # 0.9.7h or higher
67 return ssl.OPENSSL_VERSION_INFO >= (0, 9, 7, 8, 15)
68
Thomas Woutersed03b412007-08-28 21:37:11 +000069
Antoine Pitrou23df4832010-08-04 17:14:06 +000070# Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
71def skip_if_broken_ubuntu_ssl(func):
72 @functools.wraps(func)
73 def f(*args, **kwargs):
74 try:
75 ssl.SSLContext(ssl.PROTOCOL_SSLv2)
76 except ssl.SSLError:
77 if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
78 platform.linux_distribution() == ('debian', 'squeeze/sid', '')):
79 raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
80 return func(*args, **kwargs)
81 return f
82
83
Antoine Pitrou152efa22010-05-16 18:19:27 +000084class BasicSocketTests(unittest.TestCase):
Thomas Woutersed03b412007-08-28 21:37:11 +000085
Antoine Pitrou480a1242010-04-28 21:37:09 +000086 def test_constants(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +000087 ssl.PROTOCOL_SSLv2
88 ssl.PROTOCOL_SSLv23
89 ssl.PROTOCOL_SSLv3
90 ssl.PROTOCOL_TLSv1
91 ssl.CERT_NONE
92 ssl.CERT_OPTIONAL
93 ssl.CERT_REQUIRED
Thomas Woutersed03b412007-08-28 21:37:11 +000094
Antoine Pitrou480a1242010-04-28 21:37:09 +000095 def test_random(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +000096 v = ssl.RAND_status()
Benjamin Petersonee8712c2008-05-20 21:35:26 +000097 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000098 sys.stdout.write("\n RAND_status is %d (%s)\n"
99 % (v, (v and "sufficient randomness") or
100 "insufficient randomness"))
Thomas Woutersed03b412007-08-28 21:37:11 +0000101 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000102 ssl.RAND_egd(1)
103 except TypeError:
104 pass
Thomas Woutersed03b412007-08-28 21:37:11 +0000105 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000106 print("didn't raise TypeError")
107 ssl.RAND_add("this is a random string", 75.0)
Thomas Woutersed03b412007-08-28 21:37:11 +0000108
Antoine Pitrou480a1242010-04-28 21:37:09 +0000109 def test_parse_cert(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000110 # note that this uses an 'unofficial' function in _ssl.c,
111 # provided solely for this test, to exercise the certificate
112 # parsing code
113 p = ssl._ssl._test_decode_cert(CERTFILE, False)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000114 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000115 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Thomas Woutersed03b412007-08-28 21:37:11 +0000116
Antoine Pitrou480a1242010-04-28 21:37:09 +0000117 def test_DER_to_PEM(self):
118 with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f:
119 pem = f.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000120 d1 = ssl.PEM_cert_to_DER_cert(pem)
121 p2 = ssl.DER_cert_to_PEM_cert(d1)
122 d2 = ssl.PEM_cert_to_DER_cert(p2)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000123 self.assertEqual(d1, d2)
Antoine Pitrou9bfbe612010-04-27 22:08:08 +0000124 if not p2.startswith(ssl.PEM_HEADER + '\n'):
125 self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2)
126 if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'):
127 self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000128
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000129 def test_openssl_version(self):
130 n = ssl.OPENSSL_VERSION_NUMBER
131 t = ssl.OPENSSL_VERSION_INFO
132 s = ssl.OPENSSL_VERSION
133 self.assertIsInstance(n, int)
134 self.assertIsInstance(t, tuple)
135 self.assertIsInstance(s, str)
136 # Some sanity checks follow
137 # >= 0.9
138 self.assertGreaterEqual(n, 0x900000)
139 # < 2.0
140 self.assertLess(n, 0x20000000)
141 major, minor, fix, patch, status = t
142 self.assertGreaterEqual(major, 0)
143 self.assertLess(major, 2)
144 self.assertGreaterEqual(minor, 0)
145 self.assertLess(minor, 256)
146 self.assertGreaterEqual(fix, 0)
147 self.assertLess(fix, 256)
148 self.assertGreaterEqual(patch, 0)
149 self.assertLessEqual(patch, 26)
150 self.assertGreaterEqual(status, 0)
151 self.assertLessEqual(status, 15)
152 # Version string as returned by OpenSSL, the format might change
153 self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
154 (s, t))
155
Antoine Pitrou9d543662010-04-23 23:10:32 +0000156 @support.cpython_only
157 def test_refcycle(self):
158 # Issue #7943: an SSL object doesn't create reference cycles with
159 # itself.
160 s = socket.socket(socket.AF_INET)
161 ss = ssl.wrap_socket(s)
162 wr = weakref.ref(ss)
163 del ss
164 self.assertEqual(wr(), None)
165
Antoine Pitroua468adc2010-09-14 14:43:44 +0000166 def test_wrapped_unconnected(self):
167 # Methods on an unconnected SSLSocket propagate the original
168 # socket.error raise by the underlying socket object.
169 s = socket.socket(socket.AF_INET)
170 ss = ssl.wrap_socket(s)
171 self.assertRaises(socket.error, ss.recv, 1)
172 self.assertRaises(socket.error, ss.recv_into, bytearray(b'x'))
173 self.assertRaises(socket.error, ss.recvfrom, 1)
174 self.assertRaises(socket.error, ss.recvfrom_into, bytearray(b'x'), 1)
175 self.assertRaises(socket.error, ss.send, b'x')
176 self.assertRaises(socket.error, ss.sendto, b'x', ('0.0.0.0', 0))
177
Antoine Pitrou40f08742010-04-24 22:04:40 +0000178 def test_timeout(self):
179 # Issue #8524: when creating an SSL socket, the timeout of the
180 # original socket should be retained.
181 for timeout in (None, 0.0, 5.0):
182 s = socket.socket(socket.AF_INET)
183 s.settimeout(timeout)
184 ss = ssl.wrap_socket(s)
185 self.assertEqual(timeout, ss.gettimeout())
186
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000187 def test_errors(self):
188 sock = socket.socket()
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000189 self.assertRaisesRegexp(ValueError,
190 "certfile must be specified",
191 ssl.wrap_socket, sock, keyfile=CERTFILE)
192 self.assertRaisesRegexp(ValueError,
193 "certfile must be specified for server-side operations",
194 ssl.wrap_socket, sock, server_side=True)
195 self.assertRaisesRegexp(ValueError,
196 "certfile must be specified for server-side operations",
197 ssl.wrap_socket, sock, server_side=True, certfile="")
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000198 s = ssl.wrap_socket(sock, server_side=True, certfile=CERTFILE)
199 self.assertRaisesRegexp(ValueError, "can't connect in server-side mode",
200 s.connect, (HOST, 8080))
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000201 with self.assertRaises(IOError) as cm:
Giampaolo Rodolàcd9dfb92010-08-29 20:56:56 +0000202 ssl.wrap_socket(socket.socket(), 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:
205 ssl.wrap_socket(socket.socket(), certfile=CERTFILE, keyfile=WRONGCERT)
206 self.assertEqual(cm.exception.errno, errno.ENOENT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000207 with self.assertRaises(IOError) as cm:
Giampaolo Rodolàcd9dfb92010-08-29 20:56:56 +0000208 ssl.wrap_socket(socket.socket(), certfile=WRONGCERT, keyfile=WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000209 self.assertEqual(cm.exception.errno, errno.ENOENT)
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000210
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000211 def test_match_hostname(self):
212 def ok(cert, hostname):
213 ssl.match_hostname(cert, hostname)
214 def fail(cert, hostname):
215 self.assertRaises(ssl.CertificateError,
216 ssl.match_hostname, cert, hostname)
217
218 cert = {'subject': ((('commonName', 'example.com'),),)}
219 ok(cert, 'example.com')
220 ok(cert, 'ExAmple.cOm')
221 fail(cert, 'www.example.com')
222 fail(cert, '.example.com')
223 fail(cert, 'example.org')
224 fail(cert, 'exampleXcom')
225
226 cert = {'subject': ((('commonName', '*.a.com'),),)}
227 ok(cert, 'foo.a.com')
228 fail(cert, 'bar.foo.a.com')
229 fail(cert, 'a.com')
230 fail(cert, 'Xa.com')
231 fail(cert, '.a.com')
232
233 cert = {'subject': ((('commonName', 'a.*.com'),),)}
234 ok(cert, 'a.foo.com')
235 fail(cert, 'a..com')
236 fail(cert, 'a.com')
237
238 cert = {'subject': ((('commonName', 'f*.com'),),)}
239 ok(cert, 'foo.com')
240 ok(cert, 'f.com')
241 fail(cert, 'bar.com')
242 fail(cert, 'foo.a.com')
243 fail(cert, 'bar.foo.com')
244
245 # Slightly fake real-world example
246 cert = {'notAfter': 'Jun 26 21:41:46 2011 GMT',
247 'subject': ((('commonName', 'linuxfrz.org'),),),
248 'subjectAltName': (('DNS', 'linuxfr.org'),
249 ('DNS', 'linuxfr.com'),
250 ('othername', '<unsupported>'))}
251 ok(cert, 'linuxfr.org')
252 ok(cert, 'linuxfr.com')
253 # Not a "DNS" entry
254 fail(cert, '<unsupported>')
255 # When there is a subjectAltName, commonName isn't used
256 fail(cert, 'linuxfrz.org')
257
258 # A pristine real-world example
259 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
260 'subject': ((('countryName', 'US'),),
261 (('stateOrProvinceName', 'California'),),
262 (('localityName', 'Mountain View'),),
263 (('organizationName', 'Google Inc'),),
264 (('commonName', 'mail.google.com'),))}
265 ok(cert, 'mail.google.com')
266 fail(cert, 'gmail.com')
267 # Only commonName is considered
268 fail(cert, 'California')
269
270 # Neither commonName nor subjectAltName
271 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
272 'subject': ((('countryName', 'US'),),
273 (('stateOrProvinceName', 'California'),),
274 (('localityName', 'Mountain View'),),
275 (('organizationName', 'Google Inc'),))}
276 fail(cert, 'mail.google.com')
277
278 # Empty cert / no cert
279 self.assertRaises(ValueError, ssl.match_hostname, None, 'example.com')
280 self.assertRaises(ValueError, ssl.match_hostname, {}, 'example.com')
281
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000282
Antoine Pitrou152efa22010-05-16 18:19:27 +0000283class ContextTests(unittest.TestCase):
284
Antoine Pitrou23df4832010-08-04 17:14:06 +0000285 @skip_if_broken_ubuntu_ssl
Antoine Pitrou152efa22010-05-16 18:19:27 +0000286 def test_constructor(self):
287 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv2)
288 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
289 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv3)
290 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
291 self.assertRaises(TypeError, ssl.SSLContext)
292 self.assertRaises(ValueError, ssl.SSLContext, -1)
293 self.assertRaises(ValueError, ssl.SSLContext, 42)
294
Antoine Pitrou23df4832010-08-04 17:14:06 +0000295 @skip_if_broken_ubuntu_ssl
Antoine Pitrou152efa22010-05-16 18:19:27 +0000296 def test_protocol(self):
297 for proto in PROTOCOLS:
298 ctx = ssl.SSLContext(proto)
299 self.assertEqual(ctx.protocol, proto)
300
301 def test_ciphers(self):
302 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
303 ctx.set_ciphers("ALL")
304 ctx.set_ciphers("DEFAULT")
305 with self.assertRaisesRegexp(ssl.SSLError, "No cipher can be selected"):
Antoine Pitrou30474062010-05-16 23:46:26 +0000306 ctx.set_ciphers("^$:,;?*'dorothyx")
Antoine Pitrou152efa22010-05-16 18:19:27 +0000307
Antoine Pitrou23df4832010-08-04 17:14:06 +0000308 @skip_if_broken_ubuntu_ssl
Antoine Pitroub5218772010-05-21 09:56:06 +0000309 def test_options(self):
310 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
311 # OP_ALL is the default value
312 self.assertEqual(ssl.OP_ALL, ctx.options)
313 ctx.options |= ssl.OP_NO_SSLv2
314 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2,
315 ctx.options)
316 ctx.options |= ssl.OP_NO_SSLv3
317 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3,
318 ctx.options)
319 if can_clear_options():
320 ctx.options = (ctx.options & ~ssl.OP_NO_SSLv2) | ssl.OP_NO_TLSv1
321 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_TLSv1 | ssl.OP_NO_SSLv3,
322 ctx.options)
323 ctx.options = 0
324 self.assertEqual(0, ctx.options)
325 else:
326 with self.assertRaises(ValueError):
327 ctx.options = 0
328
Antoine Pitrou152efa22010-05-16 18:19:27 +0000329 def test_verify(self):
330 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
331 # Default value
332 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
333 ctx.verify_mode = ssl.CERT_OPTIONAL
334 self.assertEqual(ctx.verify_mode, ssl.CERT_OPTIONAL)
335 ctx.verify_mode = ssl.CERT_REQUIRED
336 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
337 ctx.verify_mode = ssl.CERT_NONE
338 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
339 with self.assertRaises(TypeError):
340 ctx.verify_mode = None
341 with self.assertRaises(ValueError):
342 ctx.verify_mode = 42
343
344 def test_load_cert_chain(self):
345 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
346 # Combined key and cert in a single file
347 ctx.load_cert_chain(CERTFILE)
348 ctx.load_cert_chain(CERTFILE, keyfile=CERTFILE)
349 self.assertRaises(TypeError, ctx.load_cert_chain, keyfile=CERTFILE)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000350 with self.assertRaises(IOError) as cm:
Antoine Pitrou152efa22010-05-16 18:19:27 +0000351 ctx.load_cert_chain(WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000352 self.assertEqual(cm.exception.errno, errno.ENOENT)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000353 with self.assertRaisesRegexp(ssl.SSLError, "PEM lib"):
354 ctx.load_cert_chain(BADCERT)
355 with self.assertRaisesRegexp(ssl.SSLError, "PEM lib"):
356 ctx.load_cert_chain(EMPTYCERT)
357 # Separate key and cert
Antoine Pitroud0919502010-05-17 10:30:00 +0000358 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000359 ctx.load_cert_chain(ONLYCERT, ONLYKEY)
360 ctx.load_cert_chain(certfile=ONLYCERT, keyfile=ONLYKEY)
361 ctx.load_cert_chain(certfile=BYTES_ONLYCERT, keyfile=BYTES_ONLYKEY)
362 with self.assertRaisesRegexp(ssl.SSLError, "PEM lib"):
363 ctx.load_cert_chain(ONLYCERT)
364 with self.assertRaisesRegexp(ssl.SSLError, "PEM lib"):
365 ctx.load_cert_chain(ONLYKEY)
366 with self.assertRaisesRegexp(ssl.SSLError, "PEM lib"):
367 ctx.load_cert_chain(certfile=ONLYKEY, keyfile=ONLYCERT)
368 # Mismatching key and cert
Antoine Pitroud0919502010-05-17 10:30:00 +0000369 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000370 with self.assertRaisesRegexp(ssl.SSLError, "key values mismatch"):
371 ctx.load_cert_chain(CERTFILE, ONLYKEY)
372
373 def test_load_verify_locations(self):
374 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
375 ctx.load_verify_locations(CERTFILE)
376 ctx.load_verify_locations(cafile=CERTFILE, capath=None)
377 ctx.load_verify_locations(BYTES_CERTFILE)
378 ctx.load_verify_locations(cafile=BYTES_CERTFILE, capath=None)
379 self.assertRaises(TypeError, ctx.load_verify_locations)
380 self.assertRaises(TypeError, ctx.load_verify_locations, None, None)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000381 with self.assertRaises(IOError) as cm:
Antoine Pitrou152efa22010-05-16 18:19:27 +0000382 ctx.load_verify_locations(WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000383 self.assertEqual(cm.exception.errno, errno.ENOENT)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000384 with self.assertRaisesRegexp(ssl.SSLError, "PEM lib"):
385 ctx.load_verify_locations(BADCERT)
386 ctx.load_verify_locations(CERTFILE, CAPATH)
387 ctx.load_verify_locations(CERTFILE, capath=BYTES_CAPATH)
388
389
Bill Janssen6e027db2007-11-15 22:23:56 +0000390class NetworkedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000391
Antoine Pitrou480a1242010-04-28 21:37:09 +0000392 def test_connect(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000393 with support.transient_internet("svn.python.org"):
394 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
395 cert_reqs=ssl.CERT_NONE)
396 try:
397 s.connect(("svn.python.org", 443))
398 self.assertEqual({}, s.getpeercert())
399 finally:
400 s.close()
401
402 # this should fail because we have no verification certs
403 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
404 cert_reqs=ssl.CERT_REQUIRED)
405 self.assertRaisesRegexp(ssl.SSLError, "certificate verify failed",
406 s.connect, ("svn.python.org", 443))
Antoine Pitrou152efa22010-05-16 18:19:27 +0000407 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000408
Antoine Pitrou350c7222010-09-09 13:31:46 +0000409 # this should succeed because we specify the root cert
410 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
411 cert_reqs=ssl.CERT_REQUIRED,
412 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
413 try:
414 s.connect(("svn.python.org", 443))
415 self.assertTrue(s.getpeercert())
416 finally:
417 s.close()
Antoine Pitrou152efa22010-05-16 18:19:27 +0000418
419 def test_connect_with_context(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000420 with support.transient_internet("svn.python.org"):
421 # Same as test_connect, but with a separately created context
422 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
423 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
424 s.connect(("svn.python.org", 443))
425 try:
426 self.assertEqual({}, s.getpeercert())
427 finally:
428 s.close()
429 # This should fail because we have no verification certs
430 ctx.verify_mode = ssl.CERT_REQUIRED
431 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
432 self.assertRaisesRegexp(ssl.SSLError, "certificate verify failed",
433 s.connect, ("svn.python.org", 443))
Antoine Pitrou152efa22010-05-16 18:19:27 +0000434 s.close()
Antoine Pitrou350c7222010-09-09 13:31:46 +0000435 # This should succeed because we specify the root cert
436 ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
437 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
438 s.connect(("svn.python.org", 443))
439 try:
440 cert = s.getpeercert()
441 self.assertTrue(cert)
442 finally:
443 s.close()
Antoine Pitrou152efa22010-05-16 18:19:27 +0000444
445 def test_connect_capath(self):
446 # Verify server certificates using the `capath` argument
Antoine Pitrou467f28d2010-05-16 19:22:44 +0000447 # NOTE: the subject hashing algorithm has been changed between
448 # OpenSSL 0.9.8n and 1.0.0, as a result the capath directory must
449 # contain both versions of each certificate (same content, different
Antoine Pitroud7e4c1c2010-05-17 14:13:10 +0000450 # filename) for this test to be portable across OpenSSL releases.
Antoine Pitrou350c7222010-09-09 13:31:46 +0000451 with support.transient_internet("svn.python.org"):
452 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
453 ctx.verify_mode = ssl.CERT_REQUIRED
454 ctx.load_verify_locations(capath=CAPATH)
455 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
456 s.connect(("svn.python.org", 443))
457 try:
458 cert = s.getpeercert()
459 self.assertTrue(cert)
460 finally:
461 s.close()
462 # Same with a bytes `capath` argument
463 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
464 ctx.verify_mode = ssl.CERT_REQUIRED
465 ctx.load_verify_locations(capath=BYTES_CAPATH)
466 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
467 s.connect(("svn.python.org", 443))
468 try:
469 cert = s.getpeercert()
470 self.assertTrue(cert)
471 finally:
472 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000473
Antoine Pitroue3220242010-04-24 11:13:53 +0000474 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
475 def test_makefile_close(self):
476 # Issue #5238: creating a file-like object with makefile() shouldn't
477 # delay closing the underlying "real socket" (here tested with its
478 # file descriptor, hence skipping the test under Windows).
Antoine Pitrou350c7222010-09-09 13:31:46 +0000479 with support.transient_internet("svn.python.org"):
480 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
481 ss.connect(("svn.python.org", 443))
482 fd = ss.fileno()
483 f = ss.makefile()
484 f.close()
485 # The fd is still open
Antoine Pitroue3220242010-04-24 11:13:53 +0000486 os.read(fd, 0)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000487 # Closing the SSL socket should close the fd too
488 ss.close()
489 gc.collect()
490 with self.assertRaises(OSError) as e:
491 os.read(fd, 0)
492 self.assertEqual(e.exception.errno, errno.EBADF)
Antoine Pitroue3220242010-04-24 11:13:53 +0000493
Antoine Pitrou480a1242010-04-28 21:37:09 +0000494 def test_non_blocking_handshake(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000495 with support.transient_internet("svn.python.org"):
496 s = socket.socket(socket.AF_INET)
497 s.connect(("svn.python.org", 443))
498 s.setblocking(False)
499 s = ssl.wrap_socket(s,
500 cert_reqs=ssl.CERT_NONE,
501 do_handshake_on_connect=False)
502 count = 0
503 while True:
504 try:
505 count += 1
506 s.do_handshake()
507 break
508 except ssl.SSLError as err:
509 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
510 select.select([s], [], [])
511 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
512 select.select([], [s], [])
513 else:
514 raise
515 s.close()
516 if support.verbose:
517 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000518
Antoine Pitrou480a1242010-04-28 21:37:09 +0000519 def test_get_server_certificate(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000520 with support.transient_internet("svn.python.org"):
521 pem = ssl.get_server_certificate(("svn.python.org", 443))
522 if not pem:
523 self.fail("No server certificate on svn.python.org:443!")
Bill Janssen54cc54c2007-12-14 22:08:56 +0000524
Antoine Pitrou350c7222010-09-09 13:31:46 +0000525 try:
526 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
527 except ssl.SSLError as x:
528 #should fail
529 if support.verbose:
530 sys.stdout.write("%s\n" % x)
531 else:
532 self.fail("Got server certificate %s for svn.python.org!" % pem)
533
534 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
535 if not pem:
536 self.fail("No server certificate on svn.python.org:443!")
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000537 if support.verbose:
Antoine Pitrou350c7222010-09-09 13:31:46 +0000538 sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000539
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000540 def test_ciphers(self):
541 remote = ("svn.python.org", 443)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000542 with support.transient_internet(remote[0]):
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000543 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
Antoine Pitrou350c7222010-09-09 13:31:46 +0000544 cert_reqs=ssl.CERT_NONE, ciphers="ALL")
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000545 s.connect(remote)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000546 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
547 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")
548 s.connect(remote)
549 # Error checking can happen at instantiation or when connecting
550 with self.assertRaisesRegexp(ssl.SSLError, "No cipher can be selected"):
551 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
552 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
553 s.connect(remote)
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000554
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000555 def test_algorithms(self):
556 # Issue #8484: all algorithms should be available when verifying a
557 # certificate.
Antoine Pitrou29619b22010-04-22 18:43:31 +0000558 # SHA256 was added in OpenSSL 0.9.8
559 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
560 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000561 # NOTE: https://sha256.tbs-internet.com is another possible test host
562 remote = ("sha2.hboeck.de", 443)
563 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
Antoine Pitroua88c83c2010-09-07 20:42:19 +0000564 with support.transient_internet("sha2.hboeck.de"):
565 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
566 cert_reqs=ssl.CERT_REQUIRED,
567 ca_certs=sha256_cert,)
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000568 try:
569 s.connect(remote)
570 if support.verbose:
571 sys.stdout.write("\nCipher with %r is %r\n" %
572 (remote, s.cipher()))
573 sys.stdout.write("Certificate is:\n%s\n" %
574 pprint.pformat(s.getpeercert()))
575 finally:
576 s.close()
577
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000578
579try:
580 import threading
581except ImportError:
582 _have_threads = False
583else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000584 _have_threads = True
585
586 class ThreadedEchoServer(threading.Thread):
587
588 class ConnectionHandler(threading.Thread):
589
590 """A mildly complicated class, because we want it to work both
591 with and without the SSL wrapper around the socket connection, so
592 that we can test the STARTTLS functionality."""
593
Bill Janssen6e027db2007-11-15 22:23:56 +0000594 def __init__(self, server, connsock, addr):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000595 self.server = server
596 self.running = False
597 self.sock = connsock
Bill Janssen6e027db2007-11-15 22:23:56 +0000598 self.addr = addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000599 self.sock.setblocking(1)
600 self.sslconn = None
601 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000602 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000603
Antoine Pitrou480a1242010-04-28 21:37:09 +0000604 def wrap_conn(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000605 try:
Antoine Pitroub5218772010-05-21 09:56:06 +0000606 self.sslconn = self.server.context.wrap_socket(
607 self.sock, server_side=True)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000608 except ssl.SSLError:
609 # XXX Various errors can have happened here, for example
610 # a mismatching protocol version, an invalid certificate,
611 # or a low-level bug. This should be made more discriminating.
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000612 if self.server.chatty:
Bill Janssen6e027db2007-11-15 22:23:56 +0000613 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000614 self.running = False
615 self.server.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000616 self.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000617 return False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000618 else:
Antoine Pitroub5218772010-05-21 09:56:06 +0000619 if self.server.context.verify_mode == ssl.CERT_REQUIRED:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000620 cert = self.sslconn.getpeercert()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000621 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000622 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
623 cert_binary = self.sslconn.getpeercert(True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000624 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000625 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
626 cipher = self.sslconn.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000627 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000628 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
629 return True
630
631 def read(self):
632 if self.sslconn:
633 return self.sslconn.read()
634 else:
635 return self.sock.recv(1024)
636
637 def write(self, bytes):
638 if self.sslconn:
639 return self.sslconn.write(bytes)
640 else:
641 return self.sock.send(bytes)
642
643 def close(self):
644 if self.sslconn:
645 self.sslconn.close()
646 else:
647 self.sock.close()
648
Antoine Pitrou480a1242010-04-28 21:37:09 +0000649 def run(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000650 self.running = True
651 if not self.server.starttls_server:
652 if not self.wrap_conn():
653 return
654 while self.running:
655 try:
656 msg = self.read()
Antoine Pitrou480a1242010-04-28 21:37:09 +0000657 stripped = msg.strip()
658 if not stripped:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000659 # eof, so quit this handler
660 self.running = False
661 self.close()
Antoine Pitrou480a1242010-04-28 21:37:09 +0000662 elif stripped == b'over':
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000663 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000664 sys.stdout.write(" server: client closed connection\n")
665 self.close()
666 return
Bill Janssen6e027db2007-11-15 22:23:56 +0000667 elif (self.server.starttls_server and
Antoine Pitrou764b8782010-04-28 22:57:15 +0000668 stripped == b'STARTTLS'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000669 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000670 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000671 self.write(b"OK\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000672 if not self.wrap_conn():
673 return
Bill Janssen40a0f662008-08-12 16:56:25 +0000674 elif (self.server.starttls_server and self.sslconn
Antoine Pitrou764b8782010-04-28 22:57:15 +0000675 and stripped == b'ENDTLS'):
Bill Janssen40a0f662008-08-12 16:56:25 +0000676 if support.verbose and self.server.connectionchatty:
677 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000678 self.write(b"OK\n")
Bill Janssen40a0f662008-08-12 16:56:25 +0000679 self.sock = self.sslconn.unwrap()
680 self.sslconn = None
681 if support.verbose and self.server.connectionchatty:
682 sys.stdout.write(" server: connection is now unencrypted...\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000683 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000684 if (support.verbose and
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000685 self.server.connectionchatty):
686 ctype = (self.sslconn and "encrypted") or "unencrypted"
Antoine Pitrou480a1242010-04-28 21:37:09 +0000687 sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
688 % (msg, ctype, msg.lower(), ctype))
689 self.write(msg.lower())
Bill Janssen6e027db2007-11-15 22:23:56 +0000690 except socket.error:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000691 if self.server.chatty:
692 handle_error("Test server failure:\n")
693 self.close()
694 self.running = False
695 # normally, we'd just stop here, but for the test
696 # harness, we want to stop the server
697 self.server.stop()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000698
Antoine Pitroub5218772010-05-21 09:56:06 +0000699 def __init__(self, certificate=None, ssl_version=None,
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000700 certreqs=None, cacerts=None,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000701 chatty=True, connectionchatty=False, starttls_server=False,
Antoine Pitroub5218772010-05-21 09:56:06 +0000702 ciphers=None, context=None):
703 if context:
704 self.context = context
705 else:
706 self.context = ssl.SSLContext(ssl_version
707 if ssl_version is not None
708 else ssl.PROTOCOL_TLSv1)
709 self.context.verify_mode = (certreqs if certreqs is not None
710 else ssl.CERT_NONE)
711 if cacerts:
712 self.context.load_verify_locations(cacerts)
713 if certificate:
714 self.context.load_cert_chain(certificate)
715 if ciphers:
716 self.context.set_ciphers(ciphers)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000717 self.chatty = chatty
718 self.connectionchatty = connectionchatty
719 self.starttls_server = starttls_server
720 self.sock = socket.socket()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000721 self.port = support.bind_port(self.sock)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000722 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000723 self.active = False
724 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000725 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000726
Antoine Pitrou480a1242010-04-28 21:37:09 +0000727 def start(self, flag=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000728 self.flag = flag
729 threading.Thread.start(self)
730
Antoine Pitrou480a1242010-04-28 21:37:09 +0000731 def run(self):
Antoine Pitrouaf7c6022010-04-27 09:56:02 +0000732 self.sock.settimeout(0.05)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000733 self.sock.listen(5)
734 self.active = True
735 if self.flag:
736 # signal an event
737 self.flag.set()
738 while self.active:
739 try:
740 newconn, connaddr = self.sock.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000741 if support.verbose and self.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000742 sys.stdout.write(' server: new connection from '
Bill Janssen6e027db2007-11-15 22:23:56 +0000743 + repr(connaddr) + '\n')
744 handler = self.ConnectionHandler(self, newconn, connaddr)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000745 handler.start()
746 except socket.timeout:
747 pass
748 except KeyboardInterrupt:
749 self.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000750 self.sock.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000751
Antoine Pitrou480a1242010-04-28 21:37:09 +0000752 def stop(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000753 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000754
Bill Janssen54cc54c2007-12-14 22:08:56 +0000755 class OurHTTPSServer(threading.Thread):
756
757 # This one's based on HTTPServer, which is based on SocketServer
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000758
759 class HTTPSServer(HTTPServer):
760
761 def __init__(self, server_address, RequestHandlerClass, certfile):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000762 HTTPServer.__init__(self, server_address, RequestHandlerClass)
763 # we assume the certfile contains both private key and certificate
764 self.certfile = certfile
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000765 self.allow_reuse_address = True
766
Bill Janssen6e027db2007-11-15 22:23:56 +0000767 def __str__(self):
768 return ('<%s %s:%s>' %
769 (self.__class__.__name__,
770 self.server_name,
771 self.server_port))
772
Antoine Pitrou480a1242010-04-28 21:37:09 +0000773 def get_request(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000774 # override this to wrap socket with SSL
775 sock, addr = self.socket.accept()
776 sslconn = ssl.wrap_socket(sock, server_side=True,
777 certfile=self.certfile)
778 return sslconn, addr
779
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000780 class RootedHTTPRequestHandler(SimpleHTTPRequestHandler):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000781 # need to override translate_path to get a known root,
782 # instead of using os.curdir, since the test could be
783 # run from anywhere
784
785 server_version = "TestHTTPS/1.0"
786
787 root = None
788
789 def translate_path(self, path):
790 """Translate a /-separated PATH to the local filename syntax.
791
792 Components that mean special things to the local file system
793 (e.g. drive or directory names) are ignored. (XXX They should
794 probably be diagnosed.)
795
796 """
797 # abandon query parameters
Jeremy Hylton1afc1692008-06-18 20:49:58 +0000798 path = urllib.parse.urlparse(path)[2]
799 path = os.path.normpath(urllib.parse.unquote(path))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000800 words = path.split('/')
801 words = filter(None, words)
802 path = self.root
803 for word in words:
804 drive, word = os.path.splitdrive(word)
805 head, word = os.path.split(word)
806 if word in self.root: continue
807 path = os.path.join(path, word)
808 return path
809
810 def log_message(self, format, *args):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000811 # we override this to suppress logging unless "verbose"
812
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000813 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +0000814 sys.stdout.write(" server (%s:%d %s):\n [%s] %s\n" %
815 (self.server.server_address,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000816 self.server.server_port,
817 self.request.cipher(),
818 self.log_date_time_string(),
819 format%args))
Thomas Woutersed03b412007-08-28 21:37:11 +0000820
821
Trent Nelson78520002008-04-10 20:54:35 +0000822 def __init__(self, certfile):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000823 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000824 self.RootedHTTPRequestHandler.root = os.path.split(CERTFILE)[0]
825 self.server = self.HTTPSServer(
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000826 (HOST, 0), self.RootedHTTPRequestHandler, certfile)
827 self.port = self.server.server_port
Thomas Woutersed03b412007-08-28 21:37:11 +0000828 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000829 self.daemon = True
Thomas Woutersed03b412007-08-28 21:37:11 +0000830
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000831 def __str__(self):
Bill Janssen6e027db2007-11-15 22:23:56 +0000832 return "<%s %s>" % (self.__class__.__name__, self.server)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000833
Antoine Pitrou480a1242010-04-28 21:37:09 +0000834 def start(self, flag=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000835 self.flag = flag
836 threading.Thread.start(self)
837
Antoine Pitrou480a1242010-04-28 21:37:09 +0000838 def run(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000839 if self.flag:
840 self.flag.set()
Antoine Pitrouaf7c6022010-04-27 09:56:02 +0000841 self.server.serve_forever(0.05)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000842
Antoine Pitrou480a1242010-04-28 21:37:09 +0000843 def stop(self):
Antoine Pitrouaf7c6022010-04-27 09:56:02 +0000844 self.server.shutdown()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000845
846
Bill Janssen54cc54c2007-12-14 22:08:56 +0000847 class AsyncoreEchoServer(threading.Thread):
848
849 # this one's based on asyncore.dispatcher
850
851 class EchoServer (asyncore.dispatcher):
852
853 class ConnectionHandler (asyncore.dispatcher_with_send):
854
855 def __init__(self, conn, certfile):
856 self.socket = ssl.wrap_socket(conn, server_side=True,
857 certfile=certfile,
858 do_handshake_on_connect=False)
859 asyncore.dispatcher_with_send.__init__(self, self.socket)
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000860 self._ssl_accepting = True
861 self._do_ssl_handshake()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000862
863 def readable(self):
864 if isinstance(self.socket, ssl.SSLSocket):
865 while self.socket.pending() > 0:
866 self.handle_read_event()
867 return True
868
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000869 def _do_ssl_handshake(self):
870 try:
871 self.socket.do_handshake()
872 except ssl.SSLError as err:
873 if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
874 ssl.SSL_ERROR_WANT_WRITE):
875 return
876 elif err.args[0] == ssl.SSL_ERROR_EOF:
877 return self.handle_close()
878 raise
879 except socket.error as err:
880 if err.args[0] == errno.ECONNABORTED:
881 return self.handle_close()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000882 else:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000883 self._ssl_accepting = False
884
885 def handle_read(self):
886 if self._ssl_accepting:
887 self._do_ssl_handshake()
888 else:
889 data = self.recv(1024)
890 if support.verbose:
891 sys.stdout.write(" server: read %s from client\n" % repr(data))
892 if not data:
893 self.close()
894 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000895 self.send(data.lower())
Bill Janssen54cc54c2007-12-14 22:08:56 +0000896
897 def handle_close(self):
Bill Janssen2f5799b2008-06-29 00:08:12 +0000898 self.close()
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000899 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000900 sys.stdout.write(" server: closed connection %s\n" % self.socket)
901
902 def handle_error(self):
903 raise
904
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000905 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000906 self.certfile = certfile
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000907 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
908 self.port = support.bind_port(sock, '')
909 asyncore.dispatcher.__init__(self, sock)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000910 self.listen(5)
911
Giampaolo Rodolà977c7072010-10-04 21:08:36 +0000912 def handle_accepted(self, sock_obj, addr):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000913 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000914 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
915 self.ConnectionHandler(sock_obj, self.certfile)
916
917 def handle_error(self):
918 raise
919
Trent Nelson78520002008-04-10 20:54:35 +0000920 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000921 self.flag = None
922 self.active = False
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000923 self.server = self.EchoServer(certfile)
924 self.port = self.server.port
Bill Janssen54cc54c2007-12-14 22:08:56 +0000925 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000926 self.daemon = True
Bill Janssen54cc54c2007-12-14 22:08:56 +0000927
928 def __str__(self):
929 return "<%s %s>" % (self.__class__.__name__, self.server)
930
931 def start (self, flag=None):
932 self.flag = flag
933 threading.Thread.start(self)
934
Antoine Pitrou480a1242010-04-28 21:37:09 +0000935 def run(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000936 self.active = True
937 if self.flag:
938 self.flag.set()
939 while self.active:
940 try:
941 asyncore.loop(1)
942 except:
943 pass
944
Antoine Pitrou480a1242010-04-28 21:37:09 +0000945 def stop(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000946 self.active = False
947 self.server.close()
948
Antoine Pitrou480a1242010-04-28 21:37:09 +0000949 def bad_cert_test(certfile):
950 """
951 Launch a server with CERT_REQUIRED, and check that trying to
952 connect to it with the given client certificate fails.
953 """
Trent Nelson78520002008-04-10 20:54:35 +0000954 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000955 certreqs=ssl.CERT_REQUIRED,
Bill Janssen6e027db2007-11-15 22:23:56 +0000956 cacerts=CERTFILE, chatty=False,
957 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000958 flag = threading.Event()
959 server.start(flag)
960 # wait for it to start
961 flag.wait()
962 # try to connect
963 try:
Thomas Woutersed03b412007-08-28 21:37:11 +0000964 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000965 s = ssl.wrap_socket(socket.socket(),
966 certfile=certfile,
967 ssl_version=ssl.PROTOCOL_TLSv1)
Trent Nelson78520002008-04-10 20:54:35 +0000968 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000969 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000970 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000971 sys.stdout.write("\nSSLError is %s\n" % x.args[1])
Antoine Pitrou05830aa2010-04-27 13:15:18 +0000972 except socket.error as x:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000973 if support.verbose:
Antoine Pitrou05830aa2010-04-27 13:15:18 +0000974 sys.stdout.write("\nsocket.error is %s\n" % x[1])
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000975 except IOError as x:
Giampaolo Rodolàcd9dfb92010-08-29 20:56:56 +0000976 if x.errno != errno.ENOENT:
977 raise
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000978 if support.verbose:
Giampaolo Rodolàcd9dfb92010-08-29 20:56:56 +0000979 sys.stdout.write("\IOError is %s\n" % str(x))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000980 else:
Antoine Pitroud75b2a92010-05-06 14:15:10 +0000981 raise AssertionError("Use of invalid cert should have failed!")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000982 finally:
983 server.stop()
984 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +0000985
Antoine Pitroub5218772010-05-21 09:56:06 +0000986 def server_params_test(client_context, server_context, indata=b"FOO\n",
987 chatty=True, connectionchatty=False):
Antoine Pitrou480a1242010-04-28 21:37:09 +0000988 """
989 Launch a server, connect a client to it and try various reads
990 and writes.
991 """
Antoine Pitroub5218772010-05-21 09:56:06 +0000992 server = ThreadedEchoServer(context=server_context,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000993 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +0000994 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000995 flag = threading.Event()
996 server.start(flag)
997 # wait for it to start
998 flag.wait()
999 # try to connect
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001000 try:
Antoine Pitroub5218772010-05-21 09:56:06 +00001001 s = client_context.wrap_socket(socket.socket())
Trent Nelson78520002008-04-10 20:54:35 +00001002 s.connect((HOST, server.port))
Antoine Pitrou480a1242010-04-28 21:37:09 +00001003 for arg in [indata, bytearray(indata), memoryview(indata)]:
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00001004 if connectionchatty:
1005 if support.verbose:
1006 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001007 " client: sending %r...\n" % indata)
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00001008 s.write(arg)
1009 outdata = s.read()
1010 if connectionchatty:
1011 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001012 sys.stdout.write(" client: read %r\n" % outdata)
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00001013 if outdata != indata.lower():
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001014 raise AssertionError(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001015 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1016 % (outdata[:20], len(outdata),
1017 indata[:20].lower(), len(indata)))
1018 s.write(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +00001019 if connectionchatty:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001020 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +00001021 sys.stdout.write(" client: closing connection.\n")
1022 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001023 finally:
1024 server.stop()
1025 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +00001026
Antoine Pitroub5218772010-05-21 09:56:06 +00001027 def try_protocol_combo(server_protocol, client_protocol, expect_success,
1028 certsreqs=None, server_options=0, client_options=0):
Benjamin Peterson2a691a82008-03-31 01:51:45 +00001029 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001030 certsreqs = ssl.CERT_NONE
Antoine Pitrou480a1242010-04-28 21:37:09 +00001031 certtype = {
1032 ssl.CERT_NONE: "CERT_NONE",
1033 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
1034 ssl.CERT_REQUIRED: "CERT_REQUIRED",
1035 }[certsreqs]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001036 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001037 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001038 sys.stdout.write(formatstr %
1039 (ssl.get_protocol_name(client_protocol),
1040 ssl.get_protocol_name(server_protocol),
1041 certtype))
Antoine Pitroub5218772010-05-21 09:56:06 +00001042 client_context = ssl.SSLContext(client_protocol)
1043 client_context.options = ssl.OP_ALL | client_options
1044 server_context = ssl.SSLContext(server_protocol)
1045 server_context.options = ssl.OP_ALL | server_options
1046 for ctx in (client_context, server_context):
1047 ctx.verify_mode = certsreqs
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +00001048 # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
1049 # will send an SSLv3 hello (rather than SSLv2) starting from
1050 # OpenSSL 1.0.0 (see issue #8322).
Antoine Pitroub5218772010-05-21 09:56:06 +00001051 ctx.set_ciphers("ALL")
1052 ctx.load_cert_chain(CERTFILE)
1053 ctx.load_verify_locations(CERTFILE)
1054 try:
1055 server_params_test(client_context, server_context,
1056 chatty=False, connectionchatty=False)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001057 # Protocol mismatch can result in either an SSLError, or a
1058 # "Connection reset by peer" error.
1059 except ssl.SSLError:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001060 if expect_success:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001061 raise
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001062 except socket.error as e:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001063 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001064 raise
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001065 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001066 if not expect_success:
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001067 raise AssertionError(
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001068 "Client protocol %s succeeded with server protocol %s!"
1069 % (ssl.get_protocol_name(client_protocol),
1070 ssl.get_protocol_name(server_protocol)))
1071
1072
Bill Janssen6e027db2007-11-15 22:23:56 +00001073 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001074
Antoine Pitrou23df4832010-08-04 17:14:06 +00001075 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001076 def test_echo(self):
1077 """Basic test of an SSL client connecting to a server"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001078 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001079 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00001080 for protocol in PROTOCOLS:
1081 context = ssl.SSLContext(protocol)
1082 context.load_cert_chain(CERTFILE)
1083 server_params_test(context, context,
1084 chatty=True, connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001085
Antoine Pitrou480a1242010-04-28 21:37:09 +00001086 def test_getpeercert(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001087 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001088 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00001089 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1090 context.verify_mode = ssl.CERT_REQUIRED
1091 context.load_verify_locations(CERTFILE)
1092 context.load_cert_chain(CERTFILE)
1093 server = ThreadedEchoServer(context=context, chatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001094 flag = threading.Event()
1095 server.start(flag)
1096 # wait for it to start
1097 flag.wait()
1098 # try to connect
1099 try:
Antoine Pitroub5218772010-05-21 09:56:06 +00001100 s = context.wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001101 s.connect((HOST, server.port))
1102 cert = s.getpeercert()
1103 self.assertTrue(cert, "Can't get peer certificate.")
1104 cipher = s.cipher()
1105 if support.verbose:
1106 sys.stdout.write(pprint.pformat(cert) + '\n')
1107 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
1108 if 'subject' not in cert:
1109 self.fail("No subject field in certificate: %s." %
1110 pprint.pformat(cert))
1111 if ((('organizationName', 'Python Software Foundation'),)
1112 not in cert['subject']):
1113 self.fail(
1114 "Missing or invalid 'organizationName' field in certificate subject; "
1115 "should be 'Python Software Foundation'.")
1116 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001117 finally:
1118 server.stop()
1119 server.join()
1120
Antoine Pitrou480a1242010-04-28 21:37:09 +00001121 def test_empty_cert(self):
1122 """Connecting with an empty cert file"""
1123 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1124 "nullcert.pem"))
1125 def test_malformed_cert(self):
1126 """Connecting with a badly formatted certificate (syntax error)"""
1127 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1128 "badcert.pem"))
1129 def test_nonexisting_cert(self):
1130 """Connecting with a non-existing cert file"""
1131 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1132 "wrongcert.pem"))
1133 def test_malformed_key(self):
1134 """Connecting with a badly formatted key (syntax error)"""
1135 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1136 "badkey.pem"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001137
Antoine Pitrou480a1242010-04-28 21:37:09 +00001138 def test_rude_shutdown(self):
1139 """A brutal shutdown of an SSL server should raise an IOError
1140 in the client when attempting handshake.
1141 """
Trent Nelson6b240cd2008-04-10 20:12:06 +00001142 listener_ready = threading.Event()
1143 listener_gone = threading.Event()
Antoine Pitrou480a1242010-04-28 21:37:09 +00001144
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001145 s = socket.socket()
1146 port = support.bind_port(s, HOST)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001147
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001148 # `listener` runs in a thread. It sits in an accept() until
1149 # the main thread connects. Then it rudely closes the socket,
1150 # and sets Event `listener_gone` to let the main thread know
1151 # the socket is gone.
Trent Nelson6b240cd2008-04-10 20:12:06 +00001152 def listener():
Trent Nelson6b240cd2008-04-10 20:12:06 +00001153 s.listen(5)
1154 listener_ready.set()
1155 s.accept()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001156 s.close()
Trent Nelson6b240cd2008-04-10 20:12:06 +00001157 listener_gone.set()
1158
1159 def connector():
1160 listener_ready.wait()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001161 c = socket.socket()
1162 c.connect((HOST, port))
Trent Nelson6b240cd2008-04-10 20:12:06 +00001163 listener_gone.wait()
1164 try:
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001165 ssl_sock = ssl.wrap_socket(c)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001166 except IOError:
1167 pass
1168 else:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001169 self.fail('connecting to closed SSL socket should have failed')
Trent Nelson6b240cd2008-04-10 20:12:06 +00001170
1171 t = threading.Thread(target=listener)
1172 t.start()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001173 try:
1174 connector()
1175 finally:
1176 t.join()
Trent Nelson6b240cd2008-04-10 20:12:06 +00001177
Antoine Pitrou23df4832010-08-04 17:14:06 +00001178 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001179 def test_protocol_sslv2(self):
1180 """Connecting to an SSLv2 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001181 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001182 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001183 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
1184 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
1185 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
1186 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
1187 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
1188 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00001189 # SSLv23 client with specific SSL options
1190 if no_sslv2_implies_sslv3_hello():
1191 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
1192 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
1193 client_options=ssl.OP_NO_SSLv2)
1194 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True,
1195 client_options=ssl.OP_NO_SSLv3)
1196 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True,
1197 client_options=ssl.OP_NO_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001198
Antoine Pitrou23df4832010-08-04 17:14:06 +00001199 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001200 def test_protocol_sslv23(self):
1201 """Connecting to an SSLv23 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001202 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001203 sys.stdout.write("\n")
1204 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001205 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001206 except (ssl.SSLError, socket.error) as x:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001207 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001208 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001209 sys.stdout.write(
1210 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
1211 % str(x))
Antoine Pitrou480a1242010-04-28 21:37:09 +00001212 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
1213 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
1214 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001215
Antoine Pitrou480a1242010-04-28 21:37:09 +00001216 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1217 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
1218 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001219
Antoine Pitrou480a1242010-04-28 21:37:09 +00001220 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1221 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
1222 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001223
Antoine Pitroub5218772010-05-21 09:56:06 +00001224 # Server with specific SSL options
1225 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False,
1226 server_options=ssl.OP_NO_SSLv3)
1227 # Will choose TLSv1
1228 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True,
1229 server_options=ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
1230 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, False,
1231 server_options=ssl.OP_NO_TLSv1)
1232
1233
Antoine Pitrou23df4832010-08-04 17:14:06 +00001234 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001235 def test_protocol_sslv3(self):
1236 """Connecting to an SSLv3 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001237 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001238 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001239 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
1240 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1241 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1242 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
1243 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
1244 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00001245 if no_sslv2_implies_sslv3_hello():
1246 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
1247 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, True,
1248 client_options=ssl.OP_NO_SSLv2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001249
Antoine Pitrou23df4832010-08-04 17:14:06 +00001250 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001251 def test_protocol_tlsv1(self):
1252 """Connecting to a TLSv1 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001253 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001254 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001255 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
1256 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
1257 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
1258 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
1259 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
1260 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001261
Antoine Pitrou480a1242010-04-28 21:37:09 +00001262 def test_starttls(self):
1263 """Switching from clear text to encrypted and back again."""
1264 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 +00001265
Trent Nelson78520002008-04-10 20:54:35 +00001266 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001267 ssl_version=ssl.PROTOCOL_TLSv1,
1268 starttls_server=True,
1269 chatty=True,
1270 connectionchatty=True)
1271 flag = threading.Event()
1272 server.start(flag)
1273 # wait for it to start
1274 flag.wait()
1275 # try to connect
1276 wrapped = False
1277 try:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001278 s = socket.socket()
1279 s.setblocking(1)
1280 s.connect((HOST, server.port))
1281 if support.verbose:
1282 sys.stdout.write("\n")
1283 for indata in msgs:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001284 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001285 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001286 " client: sending %r...\n" % indata)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001287 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001288 conn.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001289 outdata = conn.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001290 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001291 s.send(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001292 outdata = s.recv(1024)
Antoine Pitrou480a1242010-04-28 21:37:09 +00001293 msg = outdata.strip().lower()
1294 if indata == b"STARTTLS" and msg.startswith(b"ok"):
1295 # STARTTLS ok, switch to secure mode
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001296 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001297 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001298 " client: read %r from server, starting TLS...\n"
1299 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001300 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
1301 wrapped = True
Antoine Pitrou480a1242010-04-28 21:37:09 +00001302 elif indata == b"ENDTLS" and msg.startswith(b"ok"):
1303 # ENDTLS ok, switch back to clear text
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001304 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001305 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001306 " client: read %r from server, ending TLS...\n"
1307 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001308 s = conn.unwrap()
1309 wrapped = False
1310 else:
1311 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001312 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001313 " client: read %r from server\n" % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001314 if support.verbose:
1315 sys.stdout.write(" client: closing connection.\n")
1316 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001317 conn.write(b"over\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001318 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001319 s.send(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +00001320 if wrapped:
1321 conn.close()
1322 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001323 s.close()
1324 finally:
1325 server.stop()
1326 server.join()
1327
Antoine Pitrou480a1242010-04-28 21:37:09 +00001328 def test_socketserver(self):
1329 """Using a SocketServer to create and manage SSL connections."""
Trent Nelson78520002008-04-10 20:54:35 +00001330 server = OurHTTPSServer(CERTFILE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001331 flag = threading.Event()
1332 server.start(flag)
1333 # wait for it to start
1334 flag.wait()
1335 # try to connect
1336 try:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001337 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001338 sys.stdout.write('\n')
Antoine Pitrou480a1242010-04-28 21:37:09 +00001339 with open(CERTFILE, 'rb') as f:
1340 d1 = f.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001341 d2 = ''
1342 # now fetch the same data from the HTTPS server
Trent Nelson78520002008-04-10 20:54:35 +00001343 url = 'https://%s:%d/%s' % (
1344 HOST, server.port, os.path.split(CERTFILE)[1])
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001345 f = urllib.request.urlopen(url)
Barry Warsaw820c1202008-06-12 04:06:45 +00001346 dlen = f.info().get("content-length")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001347 if dlen and (int(dlen) > 0):
1348 d2 = f.read(int(dlen))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001349 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001350 sys.stdout.write(
1351 " client: read %d bytes from remote server '%s'\n"
1352 % (len(d2), server))
1353 f.close()
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001354 self.assertEqual(d1, d2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001355 finally:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001356 if support.verbose:
Neal Norwitzf9ff5f02008-03-31 05:39:26 +00001357 sys.stdout.write('stopping server\n')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001358 server.stop()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001359 if support.verbose:
Neal Norwitzf9ff5f02008-03-31 05:39:26 +00001360 sys.stdout.write('joining thread\n')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001361 server.join()
1362
Antoine Pitrou480a1242010-04-28 21:37:09 +00001363 def test_asyncore_server(self):
1364 """Check the example asyncore integration."""
1365 indata = "TEST MESSAGE of mixed case\n"
Trent Nelson6b240cd2008-04-10 20:12:06 +00001366
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001367 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001368 sys.stdout.write("\n")
1369
Antoine Pitrou480a1242010-04-28 21:37:09 +00001370 indata = b"FOO\n"
Trent Nelson78520002008-04-10 20:54:35 +00001371 server = AsyncoreEchoServer(CERTFILE)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001372 flag = threading.Event()
1373 server.start(flag)
1374 # wait for it to start
1375 flag.wait()
1376 # try to connect
1377 try:
1378 s = ssl.wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001379 s.connect(('127.0.0.1', server.port))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001380 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001381 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001382 " client: sending %r...\n" % indata)
1383 s.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001384 outdata = s.read()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001385 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001386 sys.stdout.write(" client: read %r\n" % outdata)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001387 if outdata != indata.lower():
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001388 self.fail(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001389 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1390 % (outdata[:20], len(outdata),
1391 indata[:20].lower(), len(indata)))
1392 s.write(b"over\n")
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001393 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001394 sys.stdout.write(" client: closing connection.\n")
1395 s.close()
Antoine Pitroued986362010-08-15 23:28:10 +00001396 if support.verbose:
1397 sys.stdout.write(" client: connection closed.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001398 finally:
Antoine Pitroued986362010-08-15 23:28:10 +00001399 if support.verbose:
1400 sys.stdout.write(" cleanup: stopping server.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001401 server.stop()
Antoine Pitroued986362010-08-15 23:28:10 +00001402 if support.verbose:
1403 sys.stdout.write(" cleanup: joining server thread.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001404 server.join()
Antoine Pitroued986362010-08-15 23:28:10 +00001405 if support.verbose:
1406 sys.stdout.write(" cleanup: successfully joined.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001407
Antoine Pitrou480a1242010-04-28 21:37:09 +00001408 def test_recv_send(self):
1409 """Test recv(), send() and friends."""
Bill Janssen58afe4c2008-09-08 16:45:19 +00001410 if support.verbose:
1411 sys.stdout.write("\n")
1412
1413 server = ThreadedEchoServer(CERTFILE,
1414 certreqs=ssl.CERT_NONE,
1415 ssl_version=ssl.PROTOCOL_TLSv1,
1416 cacerts=CERTFILE,
1417 chatty=True,
1418 connectionchatty=False)
1419 flag = threading.Event()
1420 server.start(flag)
1421 # wait for it to start
1422 flag.wait()
1423 # try to connect
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001424 s = ssl.wrap_socket(socket.socket(),
1425 server_side=False,
1426 certfile=CERTFILE,
1427 ca_certs=CERTFILE,
1428 cert_reqs=ssl.CERT_NONE,
1429 ssl_version=ssl.PROTOCOL_TLSv1)
1430 s.connect((HOST, server.port))
Bill Janssen58afe4c2008-09-08 16:45:19 +00001431 try:
Bill Janssen58afe4c2008-09-08 16:45:19 +00001432 # helper methods for standardising recv* method signatures
1433 def _recv_into():
1434 b = bytearray(b"\0"*100)
1435 count = s.recv_into(b)
1436 return b[:count]
1437
1438 def _recvfrom_into():
1439 b = bytearray(b"\0"*100)
1440 count, addr = s.recvfrom_into(b)
1441 return b[:count]
1442
1443 # (name, method, whether to expect success, *args)
1444 send_methods = [
1445 ('send', s.send, True, []),
1446 ('sendto', s.sendto, False, ["some.address"]),
1447 ('sendall', s.sendall, True, []),
1448 ]
1449 recv_methods = [
1450 ('recv', s.recv, True, []),
1451 ('recvfrom', s.recvfrom, False, ["some.address"]),
1452 ('recv_into', _recv_into, True, []),
1453 ('recvfrom_into', _recvfrom_into, False, []),
1454 ]
1455 data_prefix = "PREFIX_"
1456
1457 for meth_name, send_meth, expect_success, args in send_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001458 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00001459 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001460 send_meth(indata, *args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001461 outdata = s.read()
Bill Janssen58afe4c2008-09-08 16:45:19 +00001462 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001463 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001464 "While sending with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00001465 "<<{outdata:r}>> ({nout:d}) received; "
1466 "expected <<{indata:r}>> ({nin:d})\n".format(
1467 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00001468 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00001469 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001470 )
1471 )
1472 except ValueError as e:
1473 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001474 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001475 "Failed to send with method <<{name:s}>>; "
1476 "expected to succeed.\n".format(name=meth_name)
1477 )
1478 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001479 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001480 "Method <<{name:s}>> failed with unexpected "
1481 "exception message: {exp:s}\n".format(
1482 name=meth_name, exp=e
1483 )
1484 )
1485
1486 for meth_name, recv_meth, expect_success, args in recv_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001487 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00001488 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001489 s.send(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001490 outdata = recv_meth(*args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001491 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001492 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001493 "While receiving with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00001494 "<<{outdata:r}>> ({nout:d}) received; "
1495 "expected <<{indata:r}>> ({nin:d})\n".format(
1496 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00001497 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00001498 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001499 )
1500 )
1501 except ValueError as e:
1502 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001503 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001504 "Failed to receive with method <<{name:s}>>; "
1505 "expected to succeed.\n".format(name=meth_name)
1506 )
1507 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001508 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001509 "Method <<{name:s}>> failed with unexpected "
1510 "exception message: {exp:s}\n".format(
1511 name=meth_name, exp=e
1512 )
1513 )
1514 # consume data
1515 s.read()
1516
Antoine Pitrou480a1242010-04-28 21:37:09 +00001517 s.write(b"over\n")
Bill Janssen58afe4c2008-09-08 16:45:19 +00001518 s.close()
1519 finally:
1520 server.stop()
1521 server.join()
1522
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001523 def test_handshake_timeout(self):
1524 # Issue #5103: SSL handshake must respect the socket timeout
1525 server = socket.socket(socket.AF_INET)
1526 host = "127.0.0.1"
1527 port = support.bind_port(server)
1528 started = threading.Event()
1529 finish = False
1530
1531 def serve():
1532 server.listen(5)
1533 started.set()
1534 conns = []
1535 while not finish:
1536 r, w, e = select.select([server], [], [], 0.1)
1537 if server in r:
1538 # Let the socket hang around rather than having
1539 # it closed by garbage collection.
1540 conns.append(server.accept()[0])
1541
1542 t = threading.Thread(target=serve)
1543 t.start()
1544 started.wait()
1545
1546 try:
Antoine Pitrou40f08742010-04-24 22:04:40 +00001547 try:
1548 c = socket.socket(socket.AF_INET)
1549 c.settimeout(0.2)
1550 c.connect((host, port))
1551 # Will attempt handshake and time out
1552 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1553 ssl.wrap_socket, c)
1554 finally:
1555 c.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001556 try:
1557 c = socket.socket(socket.AF_INET)
1558 c = ssl.wrap_socket(c)
1559 c.settimeout(0.2)
1560 # Will attempt handshake and time out
1561 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1562 c.connect, (host, port))
1563 finally:
1564 c.close()
1565 finally:
1566 finish = True
1567 t.join()
1568 server.close()
1569
Bill Janssen58afe4c2008-09-08 16:45:19 +00001570
Thomas Woutersed03b412007-08-28 21:37:11 +00001571def test_main(verbose=False):
1572 if skip_expected:
Benjamin Petersone549ead2009-03-28 21:42:05 +00001573 raise unittest.SkipTest("No SSL support")
Thomas Woutersed03b412007-08-28 21:37:11 +00001574
Antoine Pitrou15cee622010-08-04 16:45:21 +00001575 if support.verbose:
1576 plats = {
1577 'Linux': platform.linux_distribution,
1578 'Mac': platform.mac_ver,
1579 'Windows': platform.win32_ver,
1580 }
1581 for name, func in plats.items():
1582 plat = func()
1583 if plat and plat[0]:
1584 plat = '%s %r' % (name, plat)
1585 break
1586 else:
1587 plat = repr(platform.platform())
1588 print("test_ssl: testing with %r %r" %
1589 (ssl.OPENSSL_VERSION, ssl.OPENSSL_VERSION_INFO))
1590 print(" under %s" % plat)
1591
Antoine Pitrou152efa22010-05-16 18:19:27 +00001592 for filename in [
1593 CERTFILE, SVN_PYTHON_ORG_ROOT_CERT, BYTES_CERTFILE,
1594 ONLYCERT, ONLYKEY, BYTES_ONLYCERT, BYTES_ONLYKEY,
1595 BADCERT, BADKEY, EMPTYCERT]:
1596 if not os.path.exists(filename):
1597 raise support.TestFailed("Can't read certificate file %r" % filename)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001598
Antoine Pitrou152efa22010-05-16 18:19:27 +00001599 tests = [ContextTests, BasicSocketTests]
Thomas Woutersed03b412007-08-28 21:37:11 +00001600
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001601 if support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001602 tests.append(NetworkedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001603
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001604 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001605 thread_info = support.threading_setup()
1606 if thread_info and support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001607 tests.append(ThreadedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001608
Antoine Pitrou480a1242010-04-28 21:37:09 +00001609 try:
1610 support.run_unittest(*tests)
1611 finally:
1612 if _have_threads:
1613 support.threading_cleanup(*thread_info)
Thomas Woutersed03b412007-08-28 21:37:11 +00001614
1615if __name__ == "__main__":
1616 test_main()