blob: 77adc43202deb80db7661dcbf81cf041e58f9509 [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
Antoine Pitrou1c86b442011-05-06 15:19:49 +0200280 # No DNS entry in subjectAltName but a commonName
281 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
282 'subject': ((('countryName', 'US'),),
283 (('stateOrProvinceName', 'California'),),
284 (('localityName', 'Mountain View'),),
285 (('commonName', 'mail.google.com'),)),
286 'subjectAltName': (('othername', 'blabla'), )}
287 ok(cert, 'mail.google.com')
288
289 # No DNS entry subjectAltName and no commonName
290 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
291 'subject': ((('countryName', 'US'),),
292 (('stateOrProvinceName', 'California'),),
293 (('localityName', 'Mountain View'),),
294 (('organizationName', 'Google Inc'),)),
295 'subjectAltName': (('othername', 'blabla'),)}
296 fail(cert, 'google.com')
297
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000298 # Empty cert / no cert
299 self.assertRaises(ValueError, ssl.match_hostname, None, 'example.com')
300 self.assertRaises(ValueError, ssl.match_hostname, {}, 'example.com')
301
Antoine Pitroud5323212010-10-22 18:19:07 +0000302 def test_server_side(self):
303 # server_hostname doesn't work for server sockets
304 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
Antoine Pitroud2eca372010-10-29 23:41:37 +0000305 with socket.socket() as sock:
306 self.assertRaises(ValueError, ctx.wrap_socket, sock, True,
307 server_hostname="some.hostname")
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000308
Antoine Pitrou152efa22010-05-16 18:19:27 +0000309class ContextTests(unittest.TestCase):
310
Antoine Pitrou23df4832010-08-04 17:14:06 +0000311 @skip_if_broken_ubuntu_ssl
Antoine Pitrou152efa22010-05-16 18:19:27 +0000312 def test_constructor(self):
313 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv2)
314 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
315 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv3)
316 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
317 self.assertRaises(TypeError, ssl.SSLContext)
318 self.assertRaises(ValueError, ssl.SSLContext, -1)
319 self.assertRaises(ValueError, ssl.SSLContext, 42)
320
Antoine Pitrou23df4832010-08-04 17:14:06 +0000321 @skip_if_broken_ubuntu_ssl
Antoine Pitrou152efa22010-05-16 18:19:27 +0000322 def test_protocol(self):
323 for proto in PROTOCOLS:
324 ctx = ssl.SSLContext(proto)
325 self.assertEqual(ctx.protocol, proto)
326
327 def test_ciphers(self):
328 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
329 ctx.set_ciphers("ALL")
330 ctx.set_ciphers("DEFAULT")
Ezio Melottied3a7d22010-12-01 02:32:32 +0000331 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
Antoine Pitrou30474062010-05-16 23:46:26 +0000332 ctx.set_ciphers("^$:,;?*'dorothyx")
Antoine Pitrou152efa22010-05-16 18:19:27 +0000333
Antoine Pitrou23df4832010-08-04 17:14:06 +0000334 @skip_if_broken_ubuntu_ssl
Antoine Pitroub5218772010-05-21 09:56:06 +0000335 def test_options(self):
336 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
337 # OP_ALL is the default value
338 self.assertEqual(ssl.OP_ALL, ctx.options)
339 ctx.options |= ssl.OP_NO_SSLv2
340 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2,
341 ctx.options)
342 ctx.options |= ssl.OP_NO_SSLv3
343 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3,
344 ctx.options)
345 if can_clear_options():
346 ctx.options = (ctx.options & ~ssl.OP_NO_SSLv2) | ssl.OP_NO_TLSv1
347 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_TLSv1 | ssl.OP_NO_SSLv3,
348 ctx.options)
349 ctx.options = 0
350 self.assertEqual(0, ctx.options)
351 else:
352 with self.assertRaises(ValueError):
353 ctx.options = 0
354
Antoine Pitrou152efa22010-05-16 18:19:27 +0000355 def test_verify(self):
356 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
357 # Default value
358 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
359 ctx.verify_mode = ssl.CERT_OPTIONAL
360 self.assertEqual(ctx.verify_mode, ssl.CERT_OPTIONAL)
361 ctx.verify_mode = ssl.CERT_REQUIRED
362 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
363 ctx.verify_mode = ssl.CERT_NONE
364 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
365 with self.assertRaises(TypeError):
366 ctx.verify_mode = None
367 with self.assertRaises(ValueError):
368 ctx.verify_mode = 42
369
370 def test_load_cert_chain(self):
371 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
372 # Combined key and cert in a single file
373 ctx.load_cert_chain(CERTFILE)
374 ctx.load_cert_chain(CERTFILE, keyfile=CERTFILE)
375 self.assertRaises(TypeError, ctx.load_cert_chain, keyfile=CERTFILE)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000376 with self.assertRaises(IOError) as cm:
Antoine Pitrou152efa22010-05-16 18:19:27 +0000377 ctx.load_cert_chain(WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000378 self.assertEqual(cm.exception.errno, errno.ENOENT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000379 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000380 ctx.load_cert_chain(BADCERT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000381 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000382 ctx.load_cert_chain(EMPTYCERT)
383 # Separate key and cert
Antoine Pitroud0919502010-05-17 10:30:00 +0000384 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000385 ctx.load_cert_chain(ONLYCERT, ONLYKEY)
386 ctx.load_cert_chain(certfile=ONLYCERT, keyfile=ONLYKEY)
387 ctx.load_cert_chain(certfile=BYTES_ONLYCERT, keyfile=BYTES_ONLYKEY)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000388 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000389 ctx.load_cert_chain(ONLYCERT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000390 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000391 ctx.load_cert_chain(ONLYKEY)
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_cert_chain(certfile=ONLYKEY, keyfile=ONLYCERT)
394 # Mismatching key and cert
Antoine Pitroud0919502010-05-17 10:30:00 +0000395 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000396 with self.assertRaisesRegex(ssl.SSLError, "key values mismatch"):
Antoine Pitrou81564092010-10-08 23:06:24 +0000397 ctx.load_cert_chain(SVN_PYTHON_ORG_ROOT_CERT, ONLYKEY)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000398
399 def test_load_verify_locations(self):
400 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
401 ctx.load_verify_locations(CERTFILE)
402 ctx.load_verify_locations(cafile=CERTFILE, capath=None)
403 ctx.load_verify_locations(BYTES_CERTFILE)
404 ctx.load_verify_locations(cafile=BYTES_CERTFILE, capath=None)
405 self.assertRaises(TypeError, ctx.load_verify_locations)
406 self.assertRaises(TypeError, ctx.load_verify_locations, None, None)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000407 with self.assertRaises(IOError) as cm:
Antoine Pitrou152efa22010-05-16 18:19:27 +0000408 ctx.load_verify_locations(WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000409 self.assertEqual(cm.exception.errno, errno.ENOENT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000410 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000411 ctx.load_verify_locations(BADCERT)
412 ctx.load_verify_locations(CERTFILE, CAPATH)
413 ctx.load_verify_locations(CERTFILE, capath=BYTES_CAPATH)
414
Victor Stinner80f75e62011-01-29 11:31:20 +0000415 # Issue #10989: crash if the second argument type is invalid
416 self.assertRaises(TypeError, ctx.load_verify_locations, None, True)
417
Antoine Pitroueb585ad2010-10-22 18:24:20 +0000418 @skip_if_broken_ubuntu_ssl
Antoine Pitroub0182c82010-10-12 20:09:02 +0000419 def test_session_stats(self):
420 for proto in PROTOCOLS:
421 ctx = ssl.SSLContext(proto)
422 self.assertEqual(ctx.session_stats(), {
423 'number': 0,
424 'connect': 0,
425 'connect_good': 0,
426 'connect_renegotiate': 0,
427 'accept': 0,
428 'accept_good': 0,
429 'accept_renegotiate': 0,
430 'hits': 0,
431 'misses': 0,
432 'timeouts': 0,
433 'cache_full': 0,
434 })
435
Antoine Pitrou664c2d12010-11-17 20:29:42 +0000436 def test_set_default_verify_paths(self):
437 # There's not much we can do to test that it acts as expected,
438 # so just check it doesn't crash or raise an exception.
439 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
440 ctx.set_default_verify_paths()
441
Antoine Pitrou152efa22010-05-16 18:19:27 +0000442
Bill Janssen6e027db2007-11-15 22:23:56 +0000443class NetworkedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000444
Antoine Pitrou480a1242010-04-28 21:37:09 +0000445 def test_connect(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000446 with support.transient_internet("svn.python.org"):
447 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
448 cert_reqs=ssl.CERT_NONE)
449 try:
450 s.connect(("svn.python.org", 443))
451 self.assertEqual({}, s.getpeercert())
452 finally:
453 s.close()
454
455 # this should fail because we have no verification certs
456 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
457 cert_reqs=ssl.CERT_REQUIRED)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000458 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
459 s.connect, ("svn.python.org", 443))
Antoine Pitrou152efa22010-05-16 18:19:27 +0000460 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000461
Antoine Pitrou350c7222010-09-09 13:31:46 +0000462 # this should succeed because we specify the root cert
463 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
464 cert_reqs=ssl.CERT_REQUIRED,
465 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
466 try:
467 s.connect(("svn.python.org", 443))
468 self.assertTrue(s.getpeercert())
469 finally:
470 s.close()
Antoine Pitrou152efa22010-05-16 18:19:27 +0000471
Antoine Pitroue93bf7a2011-02-26 23:24:06 +0000472 def test_connect_ex(self):
473 # Issue #11326: check connect_ex() implementation
474 with support.transient_internet("svn.python.org"):
475 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
476 cert_reqs=ssl.CERT_REQUIRED,
477 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
478 try:
479 self.assertEqual(0, s.connect_ex(("svn.python.org", 443)))
480 self.assertTrue(s.getpeercert())
481 finally:
482 s.close()
483
484 def test_non_blocking_connect_ex(self):
485 # Issue #11326: non-blocking connect_ex() should allow handshake
486 # to proceed after the socket gets ready.
487 with support.transient_internet("svn.python.org"):
488 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
489 cert_reqs=ssl.CERT_REQUIRED,
490 ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
491 do_handshake_on_connect=False)
492 try:
493 s.setblocking(False)
494 rc = s.connect_ex(('svn.python.org', 443))
Antoine Pitrou8a14a0c2011-02-27 15:44:12 +0000495 # EWOULDBLOCK under Windows, EINPROGRESS elsewhere
496 self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK))
Antoine Pitroue93bf7a2011-02-26 23:24:06 +0000497 # Wait for connect to finish
498 select.select([], [s], [], 5.0)
499 # Non-blocking handshake
500 while True:
501 try:
502 s.do_handshake()
503 break
504 except ssl.SSLError as err:
505 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
506 select.select([s], [], [], 5.0)
507 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
508 select.select([], [s], [], 5.0)
509 else:
510 raise
511 # SSL established
512 self.assertTrue(s.getpeercert())
513 finally:
514 s.close()
515
Antoine Pitrou152efa22010-05-16 18:19:27 +0000516 def test_connect_with_context(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000517 with support.transient_internet("svn.python.org"):
518 # Same as test_connect, but with a separately created context
519 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
520 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
521 s.connect(("svn.python.org", 443))
522 try:
523 self.assertEqual({}, s.getpeercert())
524 finally:
525 s.close()
Antoine Pitroud5323212010-10-22 18:19:07 +0000526 # Same with a server hostname
527 s = ctx.wrap_socket(socket.socket(socket.AF_INET),
528 server_hostname="svn.python.org")
529 if ssl.HAS_SNI:
530 s.connect(("svn.python.org", 443))
531 s.close()
532 else:
533 self.assertRaises(ValueError, s.connect, ("svn.python.org", 443))
Antoine Pitrou350c7222010-09-09 13:31:46 +0000534 # This should fail because we have no verification certs
535 ctx.verify_mode = ssl.CERT_REQUIRED
536 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
Ezio Melottied3a7d22010-12-01 02:32:32 +0000537 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
Antoine Pitrou350c7222010-09-09 13:31:46 +0000538 s.connect, ("svn.python.org", 443))
Antoine Pitrou152efa22010-05-16 18:19:27 +0000539 s.close()
Antoine Pitrou350c7222010-09-09 13:31:46 +0000540 # This should succeed because we specify the root cert
541 ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
542 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
543 s.connect(("svn.python.org", 443))
544 try:
545 cert = s.getpeercert()
546 self.assertTrue(cert)
547 finally:
548 s.close()
Antoine Pitrou152efa22010-05-16 18:19:27 +0000549
550 def test_connect_capath(self):
551 # Verify server certificates using the `capath` argument
Antoine Pitrou467f28d2010-05-16 19:22:44 +0000552 # NOTE: the subject hashing algorithm has been changed between
553 # OpenSSL 0.9.8n and 1.0.0, as a result the capath directory must
554 # contain both versions of each certificate (same content, different
Antoine Pitroud7e4c1c2010-05-17 14:13:10 +0000555 # filename) for this test to be portable across OpenSSL releases.
Antoine Pitrou350c7222010-09-09 13:31:46 +0000556 with support.transient_internet("svn.python.org"):
557 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
558 ctx.verify_mode = ssl.CERT_REQUIRED
559 ctx.load_verify_locations(capath=CAPATH)
560 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
561 s.connect(("svn.python.org", 443))
562 try:
563 cert = s.getpeercert()
564 self.assertTrue(cert)
565 finally:
566 s.close()
567 # Same with a bytes `capath` argument
568 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
569 ctx.verify_mode = ssl.CERT_REQUIRED
570 ctx.load_verify_locations(capath=BYTES_CAPATH)
571 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
572 s.connect(("svn.python.org", 443))
573 try:
574 cert = s.getpeercert()
575 self.assertTrue(cert)
576 finally:
577 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000578
Antoine Pitroue3220242010-04-24 11:13:53 +0000579 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
580 def test_makefile_close(self):
581 # Issue #5238: creating a file-like object with makefile() shouldn't
582 # delay closing the underlying "real socket" (here tested with its
583 # file descriptor, hence skipping the test under Windows).
Antoine Pitrou350c7222010-09-09 13:31:46 +0000584 with support.transient_internet("svn.python.org"):
585 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
586 ss.connect(("svn.python.org", 443))
587 fd = ss.fileno()
588 f = ss.makefile()
589 f.close()
590 # The fd is still open
Antoine Pitroue3220242010-04-24 11:13:53 +0000591 os.read(fd, 0)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000592 # Closing the SSL socket should close the fd too
593 ss.close()
594 gc.collect()
595 with self.assertRaises(OSError) as e:
596 os.read(fd, 0)
597 self.assertEqual(e.exception.errno, errno.EBADF)
Antoine Pitroue3220242010-04-24 11:13:53 +0000598
Antoine Pitrou480a1242010-04-28 21:37:09 +0000599 def test_non_blocking_handshake(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000600 with support.transient_internet("svn.python.org"):
601 s = socket.socket(socket.AF_INET)
602 s.connect(("svn.python.org", 443))
603 s.setblocking(False)
604 s = ssl.wrap_socket(s,
605 cert_reqs=ssl.CERT_NONE,
606 do_handshake_on_connect=False)
607 count = 0
608 while True:
609 try:
610 count += 1
611 s.do_handshake()
612 break
613 except ssl.SSLError as err:
614 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
615 select.select([s], [], [])
616 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
617 select.select([], [s], [])
618 else:
619 raise
620 s.close()
621 if support.verbose:
622 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000623
Antoine Pitrou480a1242010-04-28 21:37:09 +0000624 def test_get_server_certificate(self):
Antoine Pitrou15399c32011-04-28 19:23:55 +0200625 def _test_get_server_certificate(host, port, cert=None):
626 with support.transient_internet(host):
627 pem = ssl.get_server_certificate((host, port))
628 if not pem:
629 self.fail("No server certificate on %s:%s!" % (host, port))
Antoine Pitrou5aefa662011-04-28 19:24:46 +0200630
Antoine Pitrou15399c32011-04-28 19:23:55 +0200631 try:
632 pem = ssl.get_server_certificate((host, port), ca_certs=CERTFILE)
633 except ssl.SSLError as x:
634 #should fail
635 if support.verbose:
636 sys.stdout.write("%s\n" % x)
637 else:
Antoine Pitrou5aefa662011-04-28 19:24:46 +0200638 self.fail("Got server certificate %s for %s:%s!" % (pem, host, port))
639
Antoine Pitrou15399c32011-04-28 19:23:55 +0200640 pem = ssl.get_server_certificate((host, port), ca_certs=cert)
641 if not pem:
Antoine Pitrou5aefa662011-04-28 19:24:46 +0200642 self.fail("No server certificate on %s:%s!" % (host, port))
Antoine Pitrou350c7222010-09-09 13:31:46 +0000643 if support.verbose:
Antoine Pitrou5aefa662011-04-28 19:24:46 +0200644 sys.stdout.write("\nVerified certificate for %s:%s is\n%s\n" % (host, port ,pem))
Antoine Pitrou350c7222010-09-09 13:31:46 +0000645
Antoine Pitrou15399c32011-04-28 19:23:55 +0200646 _test_get_server_certificate('svn.python.org', 443, SVN_PYTHON_ORG_ROOT_CERT)
647 if support.IPV6_ENABLED:
648 _test_get_server_certificate('ipv6.google.com', 443)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000649
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000650 def test_ciphers(self):
651 remote = ("svn.python.org", 443)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000652 with support.transient_internet(remote[0]):
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000653 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
Antoine Pitrou350c7222010-09-09 13:31:46 +0000654 cert_reqs=ssl.CERT_NONE, ciphers="ALL")
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000655 s.connect(remote)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000656 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
657 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")
658 s.connect(remote)
659 # Error checking can happen at instantiation or when connecting
Ezio Melottied3a7d22010-12-01 02:32:32 +0000660 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
Antoine Pitroud2eca372010-10-29 23:41:37 +0000661 with socket.socket(socket.AF_INET) as sock:
662 s = ssl.wrap_socket(sock,
663 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
664 s.connect(remote)
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000665
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000666 def test_algorithms(self):
667 # Issue #8484: all algorithms should be available when verifying a
668 # certificate.
Antoine Pitrou29619b22010-04-22 18:43:31 +0000669 # SHA256 was added in OpenSSL 0.9.8
670 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
671 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Victor Stinnerf332abb2011-01-08 03:16:05 +0000672 # https://sha2.hboeck.de/ was used until 2011-01-08 (no route to host)
673 remote = ("sha256.tbs-internet.com", 443)
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000674 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
Antoine Pitrou160fd932011-01-08 10:23:29 +0000675 with support.transient_internet("sha256.tbs-internet.com"):
Antoine Pitroua88c83c2010-09-07 20:42:19 +0000676 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
677 cert_reqs=ssl.CERT_REQUIRED,
678 ca_certs=sha256_cert,)
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000679 try:
680 s.connect(remote)
681 if support.verbose:
682 sys.stdout.write("\nCipher with %r is %r\n" %
683 (remote, s.cipher()))
684 sys.stdout.write("Certificate is:\n%s\n" %
685 pprint.pformat(s.getpeercert()))
686 finally:
687 s.close()
688
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000689
690try:
691 import threading
692except ImportError:
693 _have_threads = False
694else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000695 _have_threads = True
696
Antoine Pitrou803e6d62010-10-13 10:36:15 +0000697 from test.ssl_servers import make_https_server
698
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000699 class ThreadedEchoServer(threading.Thread):
700
701 class ConnectionHandler(threading.Thread):
702
703 """A mildly complicated class, because we want it to work both
704 with and without the SSL wrapper around the socket connection, so
705 that we can test the STARTTLS functionality."""
706
Bill Janssen6e027db2007-11-15 22:23:56 +0000707 def __init__(self, server, connsock, addr):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000708 self.server = server
709 self.running = False
710 self.sock = connsock
Bill Janssen6e027db2007-11-15 22:23:56 +0000711 self.addr = addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000712 self.sock.setblocking(1)
713 self.sslconn = None
714 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000715 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000716
Antoine Pitrou480a1242010-04-28 21:37:09 +0000717 def wrap_conn(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000718 try:
Antoine Pitroub5218772010-05-21 09:56:06 +0000719 self.sslconn = self.server.context.wrap_socket(
720 self.sock, server_side=True)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000721 except ssl.SSLError:
722 # XXX Various errors can have happened here, for example
723 # a mismatching protocol version, an invalid certificate,
724 # or a low-level bug. This should be made more discriminating.
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000725 if self.server.chatty:
Bill Janssen6e027db2007-11-15 22:23:56 +0000726 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000727 self.running = False
728 self.server.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000729 self.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000730 return False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000731 else:
Antoine Pitroub5218772010-05-21 09:56:06 +0000732 if self.server.context.verify_mode == ssl.CERT_REQUIRED:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000733 cert = self.sslconn.getpeercert()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000734 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000735 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
736 cert_binary = self.sslconn.getpeercert(True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000737 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000738 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
739 cipher = self.sslconn.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000740 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000741 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
742 return True
743
744 def read(self):
745 if self.sslconn:
746 return self.sslconn.read()
747 else:
748 return self.sock.recv(1024)
749
750 def write(self, bytes):
751 if self.sslconn:
752 return self.sslconn.write(bytes)
753 else:
754 return self.sock.send(bytes)
755
756 def close(self):
757 if self.sslconn:
758 self.sslconn.close()
759 else:
760 self.sock.close()
761
Antoine Pitrou480a1242010-04-28 21:37:09 +0000762 def run(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000763 self.running = True
764 if not self.server.starttls_server:
765 if not self.wrap_conn():
766 return
767 while self.running:
768 try:
769 msg = self.read()
Antoine Pitrou480a1242010-04-28 21:37:09 +0000770 stripped = msg.strip()
771 if not stripped:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000772 # eof, so quit this handler
773 self.running = False
774 self.close()
Antoine Pitrou480a1242010-04-28 21:37:09 +0000775 elif stripped == b'over':
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000776 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000777 sys.stdout.write(" server: client closed connection\n")
778 self.close()
779 return
Bill Janssen6e027db2007-11-15 22:23:56 +0000780 elif (self.server.starttls_server and
Antoine Pitrou764b8782010-04-28 22:57:15 +0000781 stripped == b'STARTTLS'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000782 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000783 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000784 self.write(b"OK\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000785 if not self.wrap_conn():
786 return
Bill Janssen40a0f662008-08-12 16:56:25 +0000787 elif (self.server.starttls_server and self.sslconn
Antoine Pitrou764b8782010-04-28 22:57:15 +0000788 and stripped == b'ENDTLS'):
Bill Janssen40a0f662008-08-12 16:56:25 +0000789 if support.verbose and self.server.connectionchatty:
790 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000791 self.write(b"OK\n")
Bill Janssen40a0f662008-08-12 16:56:25 +0000792 self.sock = self.sslconn.unwrap()
793 self.sslconn = None
794 if support.verbose and self.server.connectionchatty:
795 sys.stdout.write(" server: connection is now unencrypted...\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000796 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000797 if (support.verbose and
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000798 self.server.connectionchatty):
799 ctype = (self.sslconn and "encrypted") or "unencrypted"
Antoine Pitrou480a1242010-04-28 21:37:09 +0000800 sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
801 % (msg, ctype, msg.lower(), ctype))
802 self.write(msg.lower())
Bill Janssen6e027db2007-11-15 22:23:56 +0000803 except socket.error:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000804 if self.server.chatty:
805 handle_error("Test server failure:\n")
806 self.close()
807 self.running = False
808 # normally, we'd just stop here, but for the test
809 # harness, we want to stop the server
810 self.server.stop()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000811
Antoine Pitroub5218772010-05-21 09:56:06 +0000812 def __init__(self, certificate=None, ssl_version=None,
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000813 certreqs=None, cacerts=None,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000814 chatty=True, connectionchatty=False, starttls_server=False,
Antoine Pitroub5218772010-05-21 09:56:06 +0000815 ciphers=None, context=None):
816 if context:
817 self.context = context
818 else:
819 self.context = ssl.SSLContext(ssl_version
820 if ssl_version is not None
821 else ssl.PROTOCOL_TLSv1)
822 self.context.verify_mode = (certreqs if certreqs is not None
823 else ssl.CERT_NONE)
824 if cacerts:
825 self.context.load_verify_locations(cacerts)
826 if certificate:
827 self.context.load_cert_chain(certificate)
828 if ciphers:
829 self.context.set_ciphers(ciphers)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000830 self.chatty = chatty
831 self.connectionchatty = connectionchatty
832 self.starttls_server = starttls_server
833 self.sock = socket.socket()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000834 self.port = support.bind_port(self.sock)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000835 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000836 self.active = False
837 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000838 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000839
Antoine Pitrou480a1242010-04-28 21:37:09 +0000840 def start(self, flag=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000841 self.flag = flag
842 threading.Thread.start(self)
843
Antoine Pitrou480a1242010-04-28 21:37:09 +0000844 def run(self):
Antoine Pitrouaf7c6022010-04-27 09:56:02 +0000845 self.sock.settimeout(0.05)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000846 self.sock.listen(5)
847 self.active = True
848 if self.flag:
849 # signal an event
850 self.flag.set()
851 while self.active:
852 try:
853 newconn, connaddr = self.sock.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000854 if support.verbose and self.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000855 sys.stdout.write(' server: new connection from '
Bill Janssen6e027db2007-11-15 22:23:56 +0000856 + repr(connaddr) + '\n')
857 handler = self.ConnectionHandler(self, newconn, connaddr)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000858 handler.start()
859 except socket.timeout:
860 pass
861 except KeyboardInterrupt:
862 self.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000863 self.sock.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000864
Antoine Pitrou480a1242010-04-28 21:37:09 +0000865 def stop(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000866 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000867
Bill Janssen54cc54c2007-12-14 22:08:56 +0000868 class AsyncoreEchoServer(threading.Thread):
869
870 # this one's based on asyncore.dispatcher
871
872 class EchoServer (asyncore.dispatcher):
873
874 class ConnectionHandler (asyncore.dispatcher_with_send):
875
876 def __init__(self, conn, certfile):
877 self.socket = ssl.wrap_socket(conn, server_side=True,
878 certfile=certfile,
879 do_handshake_on_connect=False)
880 asyncore.dispatcher_with_send.__init__(self, self.socket)
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000881 self._ssl_accepting = True
882 self._do_ssl_handshake()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000883
884 def readable(self):
885 if isinstance(self.socket, ssl.SSLSocket):
886 while self.socket.pending() > 0:
887 self.handle_read_event()
888 return True
889
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000890 def _do_ssl_handshake(self):
891 try:
892 self.socket.do_handshake()
893 except ssl.SSLError as err:
894 if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
895 ssl.SSL_ERROR_WANT_WRITE):
896 return
897 elif err.args[0] == ssl.SSL_ERROR_EOF:
898 return self.handle_close()
899 raise
900 except socket.error as err:
901 if err.args[0] == errno.ECONNABORTED:
902 return self.handle_close()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000903 else:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000904 self._ssl_accepting = False
905
906 def handle_read(self):
907 if self._ssl_accepting:
908 self._do_ssl_handshake()
909 else:
910 data = self.recv(1024)
911 if support.verbose:
912 sys.stdout.write(" server: read %s from client\n" % repr(data))
913 if not data:
914 self.close()
915 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000916 self.send(data.lower())
Bill Janssen54cc54c2007-12-14 22:08:56 +0000917
918 def handle_close(self):
Bill Janssen2f5799b2008-06-29 00:08:12 +0000919 self.close()
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000920 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000921 sys.stdout.write(" server: closed connection %s\n" % self.socket)
922
923 def handle_error(self):
924 raise
925
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000926 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000927 self.certfile = certfile
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000928 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
929 self.port = support.bind_port(sock, '')
930 asyncore.dispatcher.__init__(self, sock)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000931 self.listen(5)
932
Giampaolo Rodolà977c7072010-10-04 21:08:36 +0000933 def handle_accepted(self, sock_obj, addr):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000934 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000935 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
936 self.ConnectionHandler(sock_obj, self.certfile)
937
938 def handle_error(self):
939 raise
940
Trent Nelson78520002008-04-10 20:54:35 +0000941 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000942 self.flag = None
943 self.active = False
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000944 self.server = self.EchoServer(certfile)
945 self.port = self.server.port
Bill Janssen54cc54c2007-12-14 22:08:56 +0000946 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000947 self.daemon = True
Bill Janssen54cc54c2007-12-14 22:08:56 +0000948
949 def __str__(self):
950 return "<%s %s>" % (self.__class__.__name__, self.server)
951
952 def start (self, flag=None):
953 self.flag = flag
954 threading.Thread.start(self)
955
Antoine Pitrou480a1242010-04-28 21:37:09 +0000956 def run(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000957 self.active = True
958 if self.flag:
959 self.flag.set()
960 while self.active:
961 try:
962 asyncore.loop(1)
963 except:
964 pass
965
Antoine Pitrou480a1242010-04-28 21:37:09 +0000966 def stop(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000967 self.active = False
968 self.server.close()
969
Antoine Pitrou480a1242010-04-28 21:37:09 +0000970 def bad_cert_test(certfile):
971 """
972 Launch a server with CERT_REQUIRED, and check that trying to
973 connect to it with the given client certificate fails.
974 """
Trent Nelson78520002008-04-10 20:54:35 +0000975 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000976 certreqs=ssl.CERT_REQUIRED,
Bill Janssen6e027db2007-11-15 22:23:56 +0000977 cacerts=CERTFILE, chatty=False,
978 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000979 flag = threading.Event()
980 server.start(flag)
981 # wait for it to start
982 flag.wait()
983 # try to connect
984 try:
Thomas Woutersed03b412007-08-28 21:37:11 +0000985 try:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000986 with socket.socket() as sock:
987 s = ssl.wrap_socket(sock,
988 certfile=certfile,
989 ssl_version=ssl.PROTOCOL_TLSv1)
990 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000991 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000992 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000993 sys.stdout.write("\nSSLError is %s\n" % x.args[1])
Antoine Pitrou05830aa2010-04-27 13:15:18 +0000994 except socket.error as x:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000995 if support.verbose:
Georg Brandlb75b6392010-10-24 14:20:22 +0000996 sys.stdout.write("\nsocket.error is %s\n" % x.args[1])
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000997 except IOError as x:
Giampaolo Rodolàcd9dfb92010-08-29 20:56:56 +0000998 if x.errno != errno.ENOENT:
999 raise
Giampaolo Rodolà745ab382010-08-29 19:25:49 +00001000 if support.verbose:
Giampaolo Rodolàcd9dfb92010-08-29 20:56:56 +00001001 sys.stdout.write("\IOError is %s\n" % str(x))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001002 else:
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001003 raise AssertionError("Use of invalid cert should have failed!")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001004 finally:
1005 server.stop()
1006 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +00001007
Antoine Pitroub5218772010-05-21 09:56:06 +00001008 def server_params_test(client_context, server_context, indata=b"FOO\n",
1009 chatty=True, connectionchatty=False):
Antoine Pitrou480a1242010-04-28 21:37:09 +00001010 """
1011 Launch a server, connect a client to it and try various reads
1012 and writes.
1013 """
Antoine Pitroub5218772010-05-21 09:56:06 +00001014 server = ThreadedEchoServer(context=server_context,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001015 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +00001016 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001017 flag = threading.Event()
1018 server.start(flag)
1019 # wait for it to start
1020 flag.wait()
1021 # try to connect
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001022 try:
Antoine Pitroub5218772010-05-21 09:56:06 +00001023 s = client_context.wrap_socket(socket.socket())
Trent Nelson78520002008-04-10 20:54:35 +00001024 s.connect((HOST, server.port))
Antoine Pitrou480a1242010-04-28 21:37:09 +00001025 for arg in [indata, bytearray(indata), memoryview(indata)]:
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00001026 if connectionchatty:
1027 if support.verbose:
1028 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001029 " client: sending %r...\n" % indata)
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00001030 s.write(arg)
1031 outdata = s.read()
1032 if connectionchatty:
1033 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001034 sys.stdout.write(" client: read %r\n" % outdata)
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00001035 if outdata != indata.lower():
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001036 raise AssertionError(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001037 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1038 % (outdata[:20], len(outdata),
1039 indata[:20].lower(), len(indata)))
1040 s.write(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +00001041 if connectionchatty:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001042 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +00001043 sys.stdout.write(" client: closing connection.\n")
1044 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001045 finally:
1046 server.stop()
1047 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +00001048
Antoine Pitroub5218772010-05-21 09:56:06 +00001049 def try_protocol_combo(server_protocol, client_protocol, expect_success,
1050 certsreqs=None, server_options=0, client_options=0):
Benjamin Peterson2a691a82008-03-31 01:51:45 +00001051 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001052 certsreqs = ssl.CERT_NONE
Antoine Pitrou480a1242010-04-28 21:37:09 +00001053 certtype = {
1054 ssl.CERT_NONE: "CERT_NONE",
1055 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
1056 ssl.CERT_REQUIRED: "CERT_REQUIRED",
1057 }[certsreqs]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001058 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001059 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001060 sys.stdout.write(formatstr %
1061 (ssl.get_protocol_name(client_protocol),
1062 ssl.get_protocol_name(server_protocol),
1063 certtype))
Antoine Pitroub5218772010-05-21 09:56:06 +00001064 client_context = ssl.SSLContext(client_protocol)
1065 client_context.options = ssl.OP_ALL | client_options
1066 server_context = ssl.SSLContext(server_protocol)
1067 server_context.options = ssl.OP_ALL | server_options
1068 for ctx in (client_context, server_context):
1069 ctx.verify_mode = certsreqs
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +00001070 # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
1071 # will send an SSLv3 hello (rather than SSLv2) starting from
1072 # OpenSSL 1.0.0 (see issue #8322).
Antoine Pitroub5218772010-05-21 09:56:06 +00001073 ctx.set_ciphers("ALL")
1074 ctx.load_cert_chain(CERTFILE)
1075 ctx.load_verify_locations(CERTFILE)
1076 try:
1077 server_params_test(client_context, server_context,
1078 chatty=False, connectionchatty=False)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001079 # Protocol mismatch can result in either an SSLError, or a
1080 # "Connection reset by peer" error.
1081 except ssl.SSLError:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001082 if expect_success:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001083 raise
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001084 except socket.error as e:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001085 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001086 raise
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001087 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001088 if not expect_success:
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001089 raise AssertionError(
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001090 "Client protocol %s succeeded with server protocol %s!"
1091 % (ssl.get_protocol_name(client_protocol),
1092 ssl.get_protocol_name(server_protocol)))
1093
1094
Bill Janssen6e027db2007-11-15 22:23:56 +00001095 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001096
Antoine Pitrou23df4832010-08-04 17:14:06 +00001097 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001098 def test_echo(self):
1099 """Basic test of an SSL client connecting to a server"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001100 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001101 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00001102 for protocol in PROTOCOLS:
1103 context = ssl.SSLContext(protocol)
1104 context.load_cert_chain(CERTFILE)
1105 server_params_test(context, context,
1106 chatty=True, connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001107
Antoine Pitrou480a1242010-04-28 21:37:09 +00001108 def test_getpeercert(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001109 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001110 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00001111 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1112 context.verify_mode = ssl.CERT_REQUIRED
1113 context.load_verify_locations(CERTFILE)
1114 context.load_cert_chain(CERTFILE)
1115 server = ThreadedEchoServer(context=context, chatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001116 flag = threading.Event()
1117 server.start(flag)
1118 # wait for it to start
1119 flag.wait()
1120 # try to connect
1121 try:
Antoine Pitroub5218772010-05-21 09:56:06 +00001122 s = context.wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001123 s.connect((HOST, server.port))
1124 cert = s.getpeercert()
1125 self.assertTrue(cert, "Can't get peer certificate.")
1126 cipher = s.cipher()
1127 if support.verbose:
1128 sys.stdout.write(pprint.pformat(cert) + '\n')
1129 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
1130 if 'subject' not in cert:
1131 self.fail("No subject field in certificate: %s." %
1132 pprint.pformat(cert))
1133 if ((('organizationName', 'Python Software Foundation'),)
1134 not in cert['subject']):
1135 self.fail(
1136 "Missing or invalid 'organizationName' field in certificate subject; "
1137 "should be 'Python Software Foundation'.")
Antoine Pitroufb046912010-11-09 20:21:19 +00001138 self.assertIn('notBefore', cert)
1139 self.assertIn('notAfter', cert)
1140 before = ssl.cert_time_to_seconds(cert['notBefore'])
1141 after = ssl.cert_time_to_seconds(cert['notAfter'])
1142 self.assertLess(before, after)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001143 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001144 finally:
1145 server.stop()
1146 server.join()
1147
Antoine Pitrou480a1242010-04-28 21:37:09 +00001148 def test_empty_cert(self):
1149 """Connecting with an empty cert file"""
1150 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1151 "nullcert.pem"))
1152 def test_malformed_cert(self):
1153 """Connecting with a badly formatted certificate (syntax error)"""
1154 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1155 "badcert.pem"))
1156 def test_nonexisting_cert(self):
1157 """Connecting with a non-existing cert file"""
1158 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1159 "wrongcert.pem"))
1160 def test_malformed_key(self):
1161 """Connecting with a badly formatted key (syntax error)"""
1162 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1163 "badkey.pem"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001164
Antoine Pitrou480a1242010-04-28 21:37:09 +00001165 def test_rude_shutdown(self):
1166 """A brutal shutdown of an SSL server should raise an IOError
1167 in the client when attempting handshake.
1168 """
Trent Nelson6b240cd2008-04-10 20:12:06 +00001169 listener_ready = threading.Event()
1170 listener_gone = threading.Event()
Antoine Pitrou480a1242010-04-28 21:37:09 +00001171
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001172 s = socket.socket()
1173 port = support.bind_port(s, HOST)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001174
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001175 # `listener` runs in a thread. It sits in an accept() until
1176 # the main thread connects. Then it rudely closes the socket,
1177 # and sets Event `listener_gone` to let the main thread know
1178 # the socket is gone.
Trent Nelson6b240cd2008-04-10 20:12:06 +00001179 def listener():
Trent Nelson6b240cd2008-04-10 20:12:06 +00001180 s.listen(5)
1181 listener_ready.set()
Antoine Pitroud2eca372010-10-29 23:41:37 +00001182 newsock, addr = s.accept()
1183 newsock.close()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001184 s.close()
Trent Nelson6b240cd2008-04-10 20:12:06 +00001185 listener_gone.set()
1186
1187 def connector():
1188 listener_ready.wait()
Antoine Pitroud2eca372010-10-29 23:41:37 +00001189 with socket.socket() as c:
1190 c.connect((HOST, port))
1191 listener_gone.wait()
1192 try:
1193 ssl_sock = ssl.wrap_socket(c)
1194 except IOError:
1195 pass
1196 else:
1197 self.fail('connecting to closed SSL socket should have failed')
Trent Nelson6b240cd2008-04-10 20:12:06 +00001198
1199 t = threading.Thread(target=listener)
1200 t.start()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001201 try:
1202 connector()
1203 finally:
1204 t.join()
Trent Nelson6b240cd2008-04-10 20:12:06 +00001205
Antoine Pitrou23df4832010-08-04 17:14:06 +00001206 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001207 def test_protocol_sslv2(self):
1208 """Connecting to an SSLv2 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001209 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001210 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001211 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
1212 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
1213 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
1214 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
1215 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
1216 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00001217 # SSLv23 client with specific SSL options
1218 if no_sslv2_implies_sslv3_hello():
1219 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
1220 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
1221 client_options=ssl.OP_NO_SSLv2)
1222 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True,
1223 client_options=ssl.OP_NO_SSLv3)
1224 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True,
1225 client_options=ssl.OP_NO_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001226
Antoine Pitrou23df4832010-08-04 17:14:06 +00001227 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001228 def test_protocol_sslv23(self):
1229 """Connecting to an SSLv23 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001230 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001231 sys.stdout.write("\n")
1232 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001233 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001234 except (ssl.SSLError, socket.error) as x:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001235 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001236 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001237 sys.stdout.write(
1238 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
1239 % str(x))
Antoine Pitrou480a1242010-04-28 21:37:09 +00001240 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
1241 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
1242 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001243
Antoine Pitrou480a1242010-04-28 21:37:09 +00001244 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1245 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
1246 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001247
Antoine Pitrou480a1242010-04-28 21:37:09 +00001248 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1249 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
1250 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001251
Antoine Pitroub5218772010-05-21 09:56:06 +00001252 # Server with specific SSL options
1253 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False,
1254 server_options=ssl.OP_NO_SSLv3)
1255 # Will choose TLSv1
1256 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True,
1257 server_options=ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
1258 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, False,
1259 server_options=ssl.OP_NO_TLSv1)
1260
1261
Antoine Pitrou23df4832010-08-04 17:14:06 +00001262 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001263 def test_protocol_sslv3(self):
1264 """Connecting to an SSLv3 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001265 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001266 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001267 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
1268 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1269 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1270 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
1271 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
1272 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00001273 if no_sslv2_implies_sslv3_hello():
1274 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
1275 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, True,
1276 client_options=ssl.OP_NO_SSLv2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001277
Antoine Pitrou23df4832010-08-04 17:14:06 +00001278 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001279 def test_protocol_tlsv1(self):
1280 """Connecting to a TLSv1 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001281 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001282 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001283 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
1284 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
1285 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
1286 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
1287 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
1288 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001289
Antoine Pitrou480a1242010-04-28 21:37:09 +00001290 def test_starttls(self):
1291 """Switching from clear text to encrypted and back again."""
1292 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 +00001293
Trent Nelson78520002008-04-10 20:54:35 +00001294 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001295 ssl_version=ssl.PROTOCOL_TLSv1,
1296 starttls_server=True,
1297 chatty=True,
1298 connectionchatty=True)
1299 flag = threading.Event()
1300 server.start(flag)
1301 # wait for it to start
1302 flag.wait()
1303 # try to connect
1304 wrapped = False
1305 try:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001306 s = socket.socket()
1307 s.setblocking(1)
1308 s.connect((HOST, server.port))
1309 if support.verbose:
1310 sys.stdout.write("\n")
1311 for indata in msgs:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001312 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001313 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001314 " client: sending %r...\n" % indata)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001315 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001316 conn.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001317 outdata = conn.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001318 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001319 s.send(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001320 outdata = s.recv(1024)
Antoine Pitrou480a1242010-04-28 21:37:09 +00001321 msg = outdata.strip().lower()
1322 if indata == b"STARTTLS" and msg.startswith(b"ok"):
1323 # STARTTLS ok, switch to secure mode
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001324 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001325 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001326 " client: read %r from server, starting TLS...\n"
1327 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001328 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
1329 wrapped = True
Antoine Pitrou480a1242010-04-28 21:37:09 +00001330 elif indata == b"ENDTLS" and msg.startswith(b"ok"):
1331 # ENDTLS ok, switch back to clear text
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001332 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001333 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001334 " client: read %r from server, ending TLS...\n"
1335 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001336 s = conn.unwrap()
1337 wrapped = False
1338 else:
1339 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001340 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001341 " client: read %r from server\n" % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001342 if support.verbose:
1343 sys.stdout.write(" client: closing connection.\n")
1344 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001345 conn.write(b"over\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001346 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001347 s.send(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +00001348 if wrapped:
1349 conn.close()
1350 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001351 s.close()
1352 finally:
1353 server.stop()
1354 server.join()
1355
Antoine Pitrou480a1242010-04-28 21:37:09 +00001356 def test_socketserver(self):
1357 """Using a SocketServer to create and manage SSL connections."""
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001358 server = make_https_server(self, CERTFILE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001359 # try to connect
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001360 if support.verbose:
1361 sys.stdout.write('\n')
1362 with open(CERTFILE, 'rb') as f:
1363 d1 = f.read()
1364 d2 = ''
1365 # now fetch the same data from the HTTPS server
1366 url = 'https://%s:%d/%s' % (
1367 HOST, server.port, os.path.split(CERTFILE)[1])
1368 f = urllib.request.urlopen(url)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001369 try:
Barry Warsaw820c1202008-06-12 04:06:45 +00001370 dlen = f.info().get("content-length")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001371 if dlen and (int(dlen) > 0):
1372 d2 = f.read(int(dlen))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001373 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001374 sys.stdout.write(
1375 " client: read %d bytes from remote server '%s'\n"
1376 % (len(d2), server))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001377 finally:
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001378 f.close()
1379 self.assertEqual(d1, d2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001380
Antoine Pitrou480a1242010-04-28 21:37:09 +00001381 def test_asyncore_server(self):
1382 """Check the example asyncore integration."""
1383 indata = "TEST MESSAGE of mixed case\n"
Trent Nelson6b240cd2008-04-10 20:12:06 +00001384
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001385 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001386 sys.stdout.write("\n")
1387
Antoine Pitrou480a1242010-04-28 21:37:09 +00001388 indata = b"FOO\n"
Trent Nelson78520002008-04-10 20:54:35 +00001389 server = AsyncoreEchoServer(CERTFILE)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001390 flag = threading.Event()
1391 server.start(flag)
1392 # wait for it to start
1393 flag.wait()
1394 # try to connect
1395 try:
1396 s = ssl.wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001397 s.connect(('127.0.0.1', server.port))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001398 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001399 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001400 " client: sending %r...\n" % indata)
1401 s.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001402 outdata = s.read()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001403 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001404 sys.stdout.write(" client: read %r\n" % outdata)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001405 if outdata != indata.lower():
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001406 self.fail(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001407 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1408 % (outdata[:20], len(outdata),
1409 indata[:20].lower(), len(indata)))
1410 s.write(b"over\n")
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001411 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001412 sys.stdout.write(" client: closing connection.\n")
1413 s.close()
Antoine Pitroued986362010-08-15 23:28:10 +00001414 if support.verbose:
1415 sys.stdout.write(" client: connection closed.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001416 finally:
Antoine Pitroued986362010-08-15 23:28:10 +00001417 if support.verbose:
1418 sys.stdout.write(" cleanup: stopping server.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001419 server.stop()
Antoine Pitroued986362010-08-15 23:28:10 +00001420 if support.verbose:
1421 sys.stdout.write(" cleanup: joining server thread.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001422 server.join()
Antoine Pitroued986362010-08-15 23:28:10 +00001423 if support.verbose:
1424 sys.stdout.write(" cleanup: successfully joined.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001425
Antoine Pitrou480a1242010-04-28 21:37:09 +00001426 def test_recv_send(self):
1427 """Test recv(), send() and friends."""
Bill Janssen58afe4c2008-09-08 16:45:19 +00001428 if support.verbose:
1429 sys.stdout.write("\n")
1430
1431 server = ThreadedEchoServer(CERTFILE,
1432 certreqs=ssl.CERT_NONE,
1433 ssl_version=ssl.PROTOCOL_TLSv1,
1434 cacerts=CERTFILE,
1435 chatty=True,
1436 connectionchatty=False)
1437 flag = threading.Event()
1438 server.start(flag)
1439 # wait for it to start
1440 flag.wait()
1441 # try to connect
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001442 s = ssl.wrap_socket(socket.socket(),
1443 server_side=False,
1444 certfile=CERTFILE,
1445 ca_certs=CERTFILE,
1446 cert_reqs=ssl.CERT_NONE,
1447 ssl_version=ssl.PROTOCOL_TLSv1)
1448 s.connect((HOST, server.port))
Bill Janssen58afe4c2008-09-08 16:45:19 +00001449 try:
Bill Janssen58afe4c2008-09-08 16:45:19 +00001450 # helper methods for standardising recv* method signatures
1451 def _recv_into():
1452 b = bytearray(b"\0"*100)
1453 count = s.recv_into(b)
1454 return b[:count]
1455
1456 def _recvfrom_into():
1457 b = bytearray(b"\0"*100)
1458 count, addr = s.recvfrom_into(b)
1459 return b[:count]
1460
1461 # (name, method, whether to expect success, *args)
1462 send_methods = [
1463 ('send', s.send, True, []),
1464 ('sendto', s.sendto, False, ["some.address"]),
1465 ('sendall', s.sendall, True, []),
1466 ]
1467 recv_methods = [
1468 ('recv', s.recv, True, []),
1469 ('recvfrom', s.recvfrom, False, ["some.address"]),
1470 ('recv_into', _recv_into, True, []),
1471 ('recvfrom_into', _recvfrom_into, False, []),
1472 ]
1473 data_prefix = "PREFIX_"
1474
1475 for meth_name, send_meth, expect_success, args in send_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001476 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00001477 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001478 send_meth(indata, *args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001479 outdata = s.read()
Bill Janssen58afe4c2008-09-08 16:45:19 +00001480 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001481 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001482 "While sending with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00001483 "<<{outdata:r}>> ({nout:d}) received; "
1484 "expected <<{indata:r}>> ({nin:d})\n".format(
1485 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00001486 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00001487 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001488 )
1489 )
1490 except ValueError as e:
1491 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001492 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001493 "Failed to send with method <<{name:s}>>; "
1494 "expected to succeed.\n".format(name=meth_name)
1495 )
1496 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001497 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001498 "Method <<{name:s}>> failed with unexpected "
1499 "exception message: {exp:s}\n".format(
1500 name=meth_name, exp=e
1501 )
1502 )
1503
1504 for meth_name, recv_meth, expect_success, args in recv_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001505 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00001506 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001507 s.send(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001508 outdata = recv_meth(*args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001509 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001510 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001511 "While receiving with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00001512 "<<{outdata:r}>> ({nout:d}) received; "
1513 "expected <<{indata:r}>> ({nin:d})\n".format(
1514 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00001515 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00001516 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001517 )
1518 )
1519 except ValueError as e:
1520 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001521 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001522 "Failed to receive with method <<{name:s}>>; "
1523 "expected to succeed.\n".format(name=meth_name)
1524 )
1525 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001526 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001527 "Method <<{name:s}>> failed with unexpected "
1528 "exception message: {exp:s}\n".format(
1529 name=meth_name, exp=e
1530 )
1531 )
1532 # consume data
1533 s.read()
1534
Antoine Pitrou480a1242010-04-28 21:37:09 +00001535 s.write(b"over\n")
Bill Janssen58afe4c2008-09-08 16:45:19 +00001536 s.close()
1537 finally:
1538 server.stop()
1539 server.join()
1540
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001541 def test_handshake_timeout(self):
1542 # Issue #5103: SSL handshake must respect the socket timeout
1543 server = socket.socket(socket.AF_INET)
1544 host = "127.0.0.1"
1545 port = support.bind_port(server)
1546 started = threading.Event()
1547 finish = False
1548
1549 def serve():
1550 server.listen(5)
1551 started.set()
1552 conns = []
1553 while not finish:
1554 r, w, e = select.select([server], [], [], 0.1)
1555 if server in r:
1556 # Let the socket hang around rather than having
1557 # it closed by garbage collection.
1558 conns.append(server.accept()[0])
Antoine Pitroud2eca372010-10-29 23:41:37 +00001559 for sock in conns:
1560 sock.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001561
1562 t = threading.Thread(target=serve)
1563 t.start()
1564 started.wait()
1565
1566 try:
Antoine Pitrou40f08742010-04-24 22:04:40 +00001567 try:
1568 c = socket.socket(socket.AF_INET)
1569 c.settimeout(0.2)
1570 c.connect((host, port))
1571 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00001572 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00001573 ssl.wrap_socket, c)
Antoine Pitrou40f08742010-04-24 22:04:40 +00001574 finally:
1575 c.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001576 try:
1577 c = socket.socket(socket.AF_INET)
1578 c = ssl.wrap_socket(c)
1579 c.settimeout(0.2)
1580 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00001581 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00001582 c.connect, (host, port))
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001583 finally:
1584 c.close()
1585 finally:
1586 finish = True
1587 t.join()
1588 server.close()
1589
Bill Janssen58afe4c2008-09-08 16:45:19 +00001590
Thomas Woutersed03b412007-08-28 21:37:11 +00001591def test_main(verbose=False):
Antoine Pitrou15cee622010-08-04 16:45:21 +00001592 if support.verbose:
1593 plats = {
1594 'Linux': platform.linux_distribution,
1595 'Mac': platform.mac_ver,
1596 'Windows': platform.win32_ver,
1597 }
1598 for name, func in plats.items():
1599 plat = func()
1600 if plat and plat[0]:
1601 plat = '%s %r' % (name, plat)
1602 break
1603 else:
1604 plat = repr(platform.platform())
1605 print("test_ssl: testing with %r %r" %
1606 (ssl.OPENSSL_VERSION, ssl.OPENSSL_VERSION_INFO))
1607 print(" under %s" % plat)
Antoine Pitroud5323212010-10-22 18:19:07 +00001608 print(" HAS_SNI = %r" % ssl.HAS_SNI)
Antoine Pitrou15cee622010-08-04 16:45:21 +00001609
Antoine Pitrou152efa22010-05-16 18:19:27 +00001610 for filename in [
1611 CERTFILE, SVN_PYTHON_ORG_ROOT_CERT, BYTES_CERTFILE,
1612 ONLYCERT, ONLYKEY, BYTES_ONLYCERT, BYTES_ONLYKEY,
1613 BADCERT, BADKEY, EMPTYCERT]:
1614 if not os.path.exists(filename):
1615 raise support.TestFailed("Can't read certificate file %r" % filename)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001616
Antoine Pitrou152efa22010-05-16 18:19:27 +00001617 tests = [ContextTests, BasicSocketTests]
Thomas Woutersed03b412007-08-28 21:37:11 +00001618
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001619 if support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001620 tests.append(NetworkedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001621
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001622 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001623 thread_info = support.threading_setup()
1624 if thread_info and support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001625 tests.append(ThreadedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001626
Antoine Pitrou480a1242010-04-28 21:37:09 +00001627 try:
1628 support.run_unittest(*tests)
1629 finally:
1630 if _have_threads:
1631 support.threading_cleanup(*thread_info)
Thomas Woutersed03b412007-08-28 21:37:11 +00001632
1633if __name__ == "__main__":
1634 test_main()