blob: 138367ba1f4243d75e70ae5c79280622deb3a452 [file] [log] [blame]
Thomas Woutersed03b412007-08-28 21:37:11 +00001# Test the support for SSL and sockets
2
3import sys
4import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00005from test import support
Thomas Woutersed03b412007-08-28 21:37:11 +00006import socket
Bill Janssen6e027db2007-11-15 22:23:56 +00007import select
Thomas Woutersed03b412007-08-28 21:37:11 +00008import time
Antoine Pitroucfcd8ad2010-04-23 23:31:47 +00009import gc
Thomas Woutersed03b412007-08-28 21:37:11 +000010import os
Antoine Pitroucfcd8ad2010-04-23 23:31:47 +000011import errno
Thomas Woutersed03b412007-08-28 21:37:11 +000012import pprint
Antoine Pitrou152efa22010-05-16 18:19:27 +000013import tempfile
Antoine Pitrou803e6d62010-10-13 10:36:15 +000014import urllib.request
Thomas Woutersed03b412007-08-28 21:37:11 +000015import traceback
Bill Janssen54cc54c2007-12-14 22:08:56 +000016import asyncore
Antoine Pitrou9d543662010-04-23 23:10:32 +000017import weakref
Antoine Pitrou15cee622010-08-04 16:45:21 +000018import platform
Antoine Pitrou23df4832010-08-04 17:14:06 +000019import functools
Thomas Woutersed03b412007-08-28 21:37:11 +000020
Antoine Pitrou05d936d2010-10-13 11:38:36 +000021ssl = support.import_module("ssl")
22
23PROTOCOLS = [
24 ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3,
25 ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1
26]
Thomas Woutersed03b412007-08-28 21:37:11 +000027
Benjamin Petersonee8712c2008-05-20 21:35:26 +000028HOST = support.HOST
Antoine Pitrou152efa22010-05-16 18:19:27 +000029
30data_file = lambda name: os.path.join(os.path.dirname(__file__), name)
Antoine Pitrou152efa22010-05-16 18:19:27 +000031
Antoine Pitrou81564092010-10-08 23:06:24 +000032# The custom key and certificate files used in test_ssl are generated
33# using Lib/test/make_ssl_certs.py.
34# Other certificates are simply fetched from the Internet servers they
35# are meant to authenticate.
36
Antoine Pitrou152efa22010-05-16 18:19:27 +000037CERTFILE = data_file("keycert.pem")
Victor Stinner313a1202010-06-11 23:56:51 +000038BYTES_CERTFILE = os.fsencode(CERTFILE)
Antoine Pitrou152efa22010-05-16 18:19:27 +000039ONLYCERT = data_file("ssl_cert.pem")
40ONLYKEY = data_file("ssl_key.pem")
Victor Stinner313a1202010-06-11 23:56:51 +000041BYTES_ONLYCERT = os.fsencode(ONLYCERT)
42BYTES_ONLYKEY = os.fsencode(ONLYKEY)
Antoine Pitrou152efa22010-05-16 18:19:27 +000043CAPATH = data_file("capath")
Victor Stinner313a1202010-06-11 23:56:51 +000044BYTES_CAPATH = os.fsencode(CAPATH)
Antoine Pitrou152efa22010-05-16 18:19:27 +000045
46SVN_PYTHON_ORG_ROOT_CERT = data_file("https_svn_python_org_root.pem")
47
48EMPTYCERT = data_file("nullcert.pem")
49BADCERT = data_file("badcert.pem")
50WRONGCERT = data_file("XXXnonexisting.pem")
51BADKEY = data_file("badkey.pem")
52
Thomas Woutersed03b412007-08-28 21:37:11 +000053
Thomas Woutersed03b412007-08-28 21:37:11 +000054def handle_error(prefix):
55 exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
Benjamin Petersonee8712c2008-05-20 21:35:26 +000056 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000057 sys.stdout.write(prefix + exc_format)
Thomas Woutersed03b412007-08-28 21:37:11 +000058
Antoine Pitroub5218772010-05-21 09:56:06 +000059def can_clear_options():
60 # 0.9.8m or higher
61 return ssl.OPENSSL_VERSION_INFO >= (0, 9, 8, 13, 15)
62
63def no_sslv2_implies_sslv3_hello():
64 # 0.9.7h or higher
65 return ssl.OPENSSL_VERSION_INFO >= (0, 9, 7, 8, 15)
66
Thomas Woutersed03b412007-08-28 21:37:11 +000067
Antoine Pitrou23df4832010-08-04 17:14:06 +000068# Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
69def skip_if_broken_ubuntu_ssl(func):
70 @functools.wraps(func)
71 def f(*args, **kwargs):
72 try:
73 ssl.SSLContext(ssl.PROTOCOL_SSLv2)
74 except ssl.SSLError:
75 if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
76 platform.linux_distribution() == ('debian', 'squeeze/sid', '')):
77 raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
78 return func(*args, **kwargs)
79 return f
80
81
Antoine Pitrou152efa22010-05-16 18:19:27 +000082class BasicSocketTests(unittest.TestCase):
Thomas Woutersed03b412007-08-28 21:37:11 +000083
Antoine Pitrou480a1242010-04-28 21:37:09 +000084 def test_constants(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +000085 ssl.PROTOCOL_SSLv2
86 ssl.PROTOCOL_SSLv23
87 ssl.PROTOCOL_SSLv3
88 ssl.PROTOCOL_TLSv1
89 ssl.CERT_NONE
90 ssl.CERT_OPTIONAL
91 ssl.CERT_REQUIRED
Antoine Pitroud5323212010-10-22 18:19:07 +000092 self.assertIn(ssl.HAS_SNI, {True, False})
Thomas Woutersed03b412007-08-28 21:37:11 +000093
Antoine Pitrou480a1242010-04-28 21:37:09 +000094 def test_random(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +000095 v = ssl.RAND_status()
Benjamin Petersonee8712c2008-05-20 21:35:26 +000096 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000097 sys.stdout.write("\n RAND_status is %d (%s)\n"
98 % (v, (v and "sufficient randomness") or
99 "insufficient randomness"))
Thomas Woutersed03b412007-08-28 21:37:11 +0000100 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000101 ssl.RAND_egd(1)
102 except TypeError:
103 pass
Thomas Woutersed03b412007-08-28 21:37:11 +0000104 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000105 print("didn't raise TypeError")
106 ssl.RAND_add("this is a random string", 75.0)
Thomas Woutersed03b412007-08-28 21:37:11 +0000107
Antoine Pitrou480a1242010-04-28 21:37:09 +0000108 def test_parse_cert(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000109 # note that this uses an 'unofficial' function in _ssl.c,
110 # provided solely for this test, to exercise the certificate
111 # parsing code
Antoine Pitroufb046912010-11-09 20:21:19 +0000112 p = ssl._ssl._test_decode_cert(CERTFILE)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000113 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000114 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Thomas Woutersed03b412007-08-28 21:37:11 +0000115
Antoine Pitrou480a1242010-04-28 21:37:09 +0000116 def test_DER_to_PEM(self):
117 with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f:
118 pem = f.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000119 d1 = ssl.PEM_cert_to_DER_cert(pem)
120 p2 = ssl.DER_cert_to_PEM_cert(d1)
121 d2 = ssl.PEM_cert_to_DER_cert(p2)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000122 self.assertEqual(d1, d2)
Antoine Pitrou9bfbe612010-04-27 22:08:08 +0000123 if not p2.startswith(ssl.PEM_HEADER + '\n'):
124 self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2)
125 if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'):
126 self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000127
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000128 def test_openssl_version(self):
129 n = ssl.OPENSSL_VERSION_NUMBER
130 t = ssl.OPENSSL_VERSION_INFO
131 s = ssl.OPENSSL_VERSION
132 self.assertIsInstance(n, int)
133 self.assertIsInstance(t, tuple)
134 self.assertIsInstance(s, str)
135 # Some sanity checks follow
136 # >= 0.9
137 self.assertGreaterEqual(n, 0x900000)
138 # < 2.0
139 self.assertLess(n, 0x20000000)
140 major, minor, fix, patch, status = t
141 self.assertGreaterEqual(major, 0)
142 self.assertLess(major, 2)
143 self.assertGreaterEqual(minor, 0)
144 self.assertLess(minor, 256)
145 self.assertGreaterEqual(fix, 0)
146 self.assertLess(fix, 256)
147 self.assertGreaterEqual(patch, 0)
148 self.assertLessEqual(patch, 26)
149 self.assertGreaterEqual(status, 0)
150 self.assertLessEqual(status, 15)
151 # Version string as returned by OpenSSL, the format might change
152 self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
153 (s, t))
154
Antoine Pitrou9d543662010-04-23 23:10:32 +0000155 @support.cpython_only
156 def test_refcycle(self):
157 # Issue #7943: an SSL object doesn't create reference cycles with
158 # itself.
159 s = socket.socket(socket.AF_INET)
160 ss = ssl.wrap_socket(s)
161 wr = weakref.ref(ss)
162 del ss
163 self.assertEqual(wr(), None)
164
Antoine Pitroua468adc2010-09-14 14:43:44 +0000165 def test_wrapped_unconnected(self):
166 # Methods on an unconnected SSLSocket propagate the original
167 # socket.error raise by the underlying socket object.
168 s = socket.socket(socket.AF_INET)
169 ss = ssl.wrap_socket(s)
170 self.assertRaises(socket.error, ss.recv, 1)
171 self.assertRaises(socket.error, ss.recv_into, bytearray(b'x'))
172 self.assertRaises(socket.error, ss.recvfrom, 1)
173 self.assertRaises(socket.error, ss.recvfrom_into, bytearray(b'x'), 1)
174 self.assertRaises(socket.error, ss.send, b'x')
175 self.assertRaises(socket.error, ss.sendto, b'x', ('0.0.0.0', 0))
176
Antoine Pitrou40f08742010-04-24 22:04:40 +0000177 def test_timeout(self):
178 # Issue #8524: when creating an SSL socket, the timeout of the
179 # original socket should be retained.
180 for timeout in (None, 0.0, 5.0):
181 s = socket.socket(socket.AF_INET)
182 s.settimeout(timeout)
183 ss = ssl.wrap_socket(s)
184 self.assertEqual(timeout, ss.gettimeout())
185
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000186 def test_errors(self):
187 sock = socket.socket()
Ezio Melottied3a7d22010-12-01 02:32:32 +0000188 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000189 "certfile must be specified",
190 ssl.wrap_socket, sock, keyfile=CERTFILE)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000191 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000192 "certfile must be specified for server-side operations",
193 ssl.wrap_socket, sock, server_side=True)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000194 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000195 "certfile must be specified for server-side operations",
196 ssl.wrap_socket, sock, server_side=True, certfile="")
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000197 s = ssl.wrap_socket(sock, server_side=True, certfile=CERTFILE)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000198 self.assertRaisesRegex(ValueError, "can't connect in server-side mode",
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000199 s.connect, (HOST, 8080))
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000200 with self.assertRaises(IOError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000201 with socket.socket() as sock:
202 ssl.wrap_socket(sock, certfile=WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000203 self.assertEqual(cm.exception.errno, errno.ENOENT)
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000204 with self.assertRaises(IOError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000205 with socket.socket() as sock:
206 ssl.wrap_socket(sock, certfile=CERTFILE, keyfile=WRONGCERT)
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000207 self.assertEqual(cm.exception.errno, errno.ENOENT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000208 with self.assertRaises(IOError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000209 with socket.socket() as sock:
210 ssl.wrap_socket(sock, certfile=WRONGCERT, keyfile=WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000211 self.assertEqual(cm.exception.errno, errno.ENOENT)
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000212
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000213 def test_match_hostname(self):
214 def ok(cert, hostname):
215 ssl.match_hostname(cert, hostname)
216 def fail(cert, hostname):
217 self.assertRaises(ssl.CertificateError,
218 ssl.match_hostname, cert, hostname)
219
220 cert = {'subject': ((('commonName', 'example.com'),),)}
221 ok(cert, 'example.com')
222 ok(cert, 'ExAmple.cOm')
223 fail(cert, 'www.example.com')
224 fail(cert, '.example.com')
225 fail(cert, 'example.org')
226 fail(cert, 'exampleXcom')
227
228 cert = {'subject': ((('commonName', '*.a.com'),),)}
229 ok(cert, 'foo.a.com')
230 fail(cert, 'bar.foo.a.com')
231 fail(cert, 'a.com')
232 fail(cert, 'Xa.com')
233 fail(cert, '.a.com')
234
235 cert = {'subject': ((('commonName', 'a.*.com'),),)}
236 ok(cert, 'a.foo.com')
237 fail(cert, 'a..com')
238 fail(cert, 'a.com')
239
240 cert = {'subject': ((('commonName', 'f*.com'),),)}
241 ok(cert, 'foo.com')
242 ok(cert, 'f.com')
243 fail(cert, 'bar.com')
244 fail(cert, 'foo.a.com')
245 fail(cert, 'bar.foo.com')
246
247 # Slightly fake real-world example
248 cert = {'notAfter': 'Jun 26 21:41:46 2011 GMT',
249 'subject': ((('commonName', 'linuxfrz.org'),),),
250 'subjectAltName': (('DNS', 'linuxfr.org'),
251 ('DNS', 'linuxfr.com'),
252 ('othername', '<unsupported>'))}
253 ok(cert, 'linuxfr.org')
254 ok(cert, 'linuxfr.com')
255 # Not a "DNS" entry
256 fail(cert, '<unsupported>')
257 # When there is a subjectAltName, commonName isn't used
258 fail(cert, 'linuxfrz.org')
259
260 # A pristine real-world example
261 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
262 'subject': ((('countryName', 'US'),),
263 (('stateOrProvinceName', 'California'),),
264 (('localityName', 'Mountain View'),),
265 (('organizationName', 'Google Inc'),),
266 (('commonName', 'mail.google.com'),))}
267 ok(cert, 'mail.google.com')
268 fail(cert, 'gmail.com')
269 # Only commonName is considered
270 fail(cert, 'California')
271
272 # Neither commonName nor subjectAltName
273 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
274 'subject': ((('countryName', 'US'),),
275 (('stateOrProvinceName', 'California'),),
276 (('localityName', 'Mountain View'),),
277 (('organizationName', 'Google Inc'),))}
278 fail(cert, 'mail.google.com')
279
280 # Empty cert / no cert
281 self.assertRaises(ValueError, ssl.match_hostname, None, 'example.com')
282 self.assertRaises(ValueError, ssl.match_hostname, {}, 'example.com')
283
Antoine Pitroud5323212010-10-22 18:19:07 +0000284 def test_server_side(self):
285 # server_hostname doesn't work for server sockets
286 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
Antoine Pitroud2eca372010-10-29 23:41:37 +0000287 with socket.socket() as sock:
288 self.assertRaises(ValueError, ctx.wrap_socket, sock, True,
289 server_hostname="some.hostname")
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000290
Antoine Pitrou152efa22010-05-16 18:19:27 +0000291class ContextTests(unittest.TestCase):
292
Antoine Pitrou23df4832010-08-04 17:14:06 +0000293 @skip_if_broken_ubuntu_ssl
Antoine Pitrou152efa22010-05-16 18:19:27 +0000294 def test_constructor(self):
295 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv2)
296 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
297 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv3)
298 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
299 self.assertRaises(TypeError, ssl.SSLContext)
300 self.assertRaises(ValueError, ssl.SSLContext, -1)
301 self.assertRaises(ValueError, ssl.SSLContext, 42)
302
Antoine Pitrou23df4832010-08-04 17:14:06 +0000303 @skip_if_broken_ubuntu_ssl
Antoine Pitrou152efa22010-05-16 18:19:27 +0000304 def test_protocol(self):
305 for proto in PROTOCOLS:
306 ctx = ssl.SSLContext(proto)
307 self.assertEqual(ctx.protocol, proto)
308
309 def test_ciphers(self):
310 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
311 ctx.set_ciphers("ALL")
312 ctx.set_ciphers("DEFAULT")
Ezio Melottied3a7d22010-12-01 02:32:32 +0000313 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
Antoine Pitrou30474062010-05-16 23:46:26 +0000314 ctx.set_ciphers("^$:,;?*'dorothyx")
Antoine Pitrou152efa22010-05-16 18:19:27 +0000315
Antoine Pitrou23df4832010-08-04 17:14:06 +0000316 @skip_if_broken_ubuntu_ssl
Antoine Pitroub5218772010-05-21 09:56:06 +0000317 def test_options(self):
318 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
319 # OP_ALL is the default value
320 self.assertEqual(ssl.OP_ALL, ctx.options)
321 ctx.options |= ssl.OP_NO_SSLv2
322 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2,
323 ctx.options)
324 ctx.options |= ssl.OP_NO_SSLv3
325 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3,
326 ctx.options)
327 if can_clear_options():
328 ctx.options = (ctx.options & ~ssl.OP_NO_SSLv2) | ssl.OP_NO_TLSv1
329 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_TLSv1 | ssl.OP_NO_SSLv3,
330 ctx.options)
331 ctx.options = 0
332 self.assertEqual(0, ctx.options)
333 else:
334 with self.assertRaises(ValueError):
335 ctx.options = 0
336
Antoine Pitrou152efa22010-05-16 18:19:27 +0000337 def test_verify(self):
338 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
339 # Default value
340 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
341 ctx.verify_mode = ssl.CERT_OPTIONAL
342 self.assertEqual(ctx.verify_mode, ssl.CERT_OPTIONAL)
343 ctx.verify_mode = ssl.CERT_REQUIRED
344 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
345 ctx.verify_mode = ssl.CERT_NONE
346 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
347 with self.assertRaises(TypeError):
348 ctx.verify_mode = None
349 with self.assertRaises(ValueError):
350 ctx.verify_mode = 42
351
352 def test_load_cert_chain(self):
353 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
354 # Combined key and cert in a single file
355 ctx.load_cert_chain(CERTFILE)
356 ctx.load_cert_chain(CERTFILE, keyfile=CERTFILE)
357 self.assertRaises(TypeError, ctx.load_cert_chain, keyfile=CERTFILE)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000358 with self.assertRaises(IOError) as cm:
Antoine Pitrou152efa22010-05-16 18:19:27 +0000359 ctx.load_cert_chain(WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000360 self.assertEqual(cm.exception.errno, errno.ENOENT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000361 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000362 ctx.load_cert_chain(BADCERT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000363 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000364 ctx.load_cert_chain(EMPTYCERT)
365 # Separate key and cert
Antoine Pitroud0919502010-05-17 10:30:00 +0000366 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000367 ctx.load_cert_chain(ONLYCERT, ONLYKEY)
368 ctx.load_cert_chain(certfile=ONLYCERT, keyfile=ONLYKEY)
369 ctx.load_cert_chain(certfile=BYTES_ONLYCERT, keyfile=BYTES_ONLYKEY)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000370 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000371 ctx.load_cert_chain(ONLYCERT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000372 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000373 ctx.load_cert_chain(ONLYKEY)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000374 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000375 ctx.load_cert_chain(certfile=ONLYKEY, keyfile=ONLYCERT)
376 # Mismatching key and cert
Antoine Pitroud0919502010-05-17 10:30:00 +0000377 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000378 with self.assertRaisesRegex(ssl.SSLError, "key values mismatch"):
Antoine Pitrou81564092010-10-08 23:06:24 +0000379 ctx.load_cert_chain(SVN_PYTHON_ORG_ROOT_CERT, ONLYKEY)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000380
381 def test_load_verify_locations(self):
382 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
383 ctx.load_verify_locations(CERTFILE)
384 ctx.load_verify_locations(cafile=CERTFILE, capath=None)
385 ctx.load_verify_locations(BYTES_CERTFILE)
386 ctx.load_verify_locations(cafile=BYTES_CERTFILE, capath=None)
387 self.assertRaises(TypeError, ctx.load_verify_locations)
388 self.assertRaises(TypeError, ctx.load_verify_locations, None, None)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000389 with self.assertRaises(IOError) as cm:
Antoine Pitrou152efa22010-05-16 18:19:27 +0000390 ctx.load_verify_locations(WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000391 self.assertEqual(cm.exception.errno, errno.ENOENT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000392 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000393 ctx.load_verify_locations(BADCERT)
394 ctx.load_verify_locations(CERTFILE, CAPATH)
395 ctx.load_verify_locations(CERTFILE, capath=BYTES_CAPATH)
396
Victor Stinner80f75e62011-01-29 11:31:20 +0000397 # Issue #10989: crash if the second argument type is invalid
398 self.assertRaises(TypeError, ctx.load_verify_locations, None, True)
399
Antoine Pitroueb585ad2010-10-22 18:24:20 +0000400 @skip_if_broken_ubuntu_ssl
Antoine Pitroub0182c82010-10-12 20:09:02 +0000401 def test_session_stats(self):
402 for proto in PROTOCOLS:
403 ctx = ssl.SSLContext(proto)
404 self.assertEqual(ctx.session_stats(), {
405 'number': 0,
406 'connect': 0,
407 'connect_good': 0,
408 'connect_renegotiate': 0,
409 'accept': 0,
410 'accept_good': 0,
411 'accept_renegotiate': 0,
412 'hits': 0,
413 'misses': 0,
414 'timeouts': 0,
415 'cache_full': 0,
416 })
417
Antoine Pitrou664c2d12010-11-17 20:29:42 +0000418 def test_set_default_verify_paths(self):
419 # There's not much we can do to test that it acts as expected,
420 # so just check it doesn't crash or raise an exception.
421 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
422 ctx.set_default_verify_paths()
423
Antoine Pitrou152efa22010-05-16 18:19:27 +0000424
Bill Janssen6e027db2007-11-15 22:23:56 +0000425class NetworkedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000426
Antoine Pitrou480a1242010-04-28 21:37:09 +0000427 def test_connect(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000428 with support.transient_internet("svn.python.org"):
429 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
430 cert_reqs=ssl.CERT_NONE)
431 try:
432 s.connect(("svn.python.org", 443))
433 self.assertEqual({}, s.getpeercert())
434 finally:
435 s.close()
436
437 # this should fail because we have no verification certs
438 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
439 cert_reqs=ssl.CERT_REQUIRED)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000440 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
441 s.connect, ("svn.python.org", 443))
Antoine Pitrou152efa22010-05-16 18:19:27 +0000442 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000443
Antoine Pitrou350c7222010-09-09 13:31:46 +0000444 # this should succeed because we specify the root cert
445 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
446 cert_reqs=ssl.CERT_REQUIRED,
447 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
448 try:
449 s.connect(("svn.python.org", 443))
450 self.assertTrue(s.getpeercert())
451 finally:
452 s.close()
Antoine Pitrou152efa22010-05-16 18:19:27 +0000453
Antoine Pitroue93bf7a2011-02-26 23:24:06 +0000454 def test_connect_ex(self):
455 # Issue #11326: check connect_ex() implementation
456 with support.transient_internet("svn.python.org"):
457 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
458 cert_reqs=ssl.CERT_REQUIRED,
459 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
460 try:
461 self.assertEqual(0, s.connect_ex(("svn.python.org", 443)))
462 self.assertTrue(s.getpeercert())
463 finally:
464 s.close()
465
466 def test_non_blocking_connect_ex(self):
467 # Issue #11326: non-blocking connect_ex() should allow handshake
468 # to proceed after the socket gets ready.
469 with support.transient_internet("svn.python.org"):
470 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
471 cert_reqs=ssl.CERT_REQUIRED,
472 ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
473 do_handshake_on_connect=False)
474 try:
475 s.setblocking(False)
476 rc = s.connect_ex(('svn.python.org', 443))
Antoine Pitrou8a14a0c2011-02-27 15:44:12 +0000477 # EWOULDBLOCK under Windows, EINPROGRESS elsewhere
478 self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK))
Antoine Pitroue93bf7a2011-02-26 23:24:06 +0000479 # Wait for connect to finish
480 select.select([], [s], [], 5.0)
481 # Non-blocking handshake
482 while True:
483 try:
484 s.do_handshake()
485 break
486 except ssl.SSLError as err:
487 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
488 select.select([s], [], [], 5.0)
489 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
490 select.select([], [s], [], 5.0)
491 else:
492 raise
493 # SSL established
494 self.assertTrue(s.getpeercert())
495 finally:
496 s.close()
497
Antoine Pitrou152efa22010-05-16 18:19:27 +0000498 def test_connect_with_context(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000499 with support.transient_internet("svn.python.org"):
500 # Same as test_connect, but with a separately created context
501 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
502 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
503 s.connect(("svn.python.org", 443))
504 try:
505 self.assertEqual({}, s.getpeercert())
506 finally:
507 s.close()
Antoine Pitroud5323212010-10-22 18:19:07 +0000508 # Same with a server hostname
509 s = ctx.wrap_socket(socket.socket(socket.AF_INET),
510 server_hostname="svn.python.org")
511 if ssl.HAS_SNI:
512 s.connect(("svn.python.org", 443))
513 s.close()
514 else:
515 self.assertRaises(ValueError, s.connect, ("svn.python.org", 443))
Antoine Pitrou350c7222010-09-09 13:31:46 +0000516 # This should fail because we have no verification certs
517 ctx.verify_mode = ssl.CERT_REQUIRED
518 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
Ezio Melottied3a7d22010-12-01 02:32:32 +0000519 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
Antoine Pitrou350c7222010-09-09 13:31:46 +0000520 s.connect, ("svn.python.org", 443))
Antoine Pitrou152efa22010-05-16 18:19:27 +0000521 s.close()
Antoine Pitrou350c7222010-09-09 13:31:46 +0000522 # This should succeed because we specify the root cert
523 ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
524 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
525 s.connect(("svn.python.org", 443))
526 try:
527 cert = s.getpeercert()
528 self.assertTrue(cert)
529 finally:
530 s.close()
Antoine Pitrou152efa22010-05-16 18:19:27 +0000531
532 def test_connect_capath(self):
533 # Verify server certificates using the `capath` argument
Antoine Pitrou467f28d2010-05-16 19:22:44 +0000534 # NOTE: the subject hashing algorithm has been changed between
535 # OpenSSL 0.9.8n and 1.0.0, as a result the capath directory must
536 # contain both versions of each certificate (same content, different
Antoine Pitroud7e4c1c2010-05-17 14:13:10 +0000537 # filename) for this test to be portable across OpenSSL releases.
Antoine Pitrou350c7222010-09-09 13:31:46 +0000538 with support.transient_internet("svn.python.org"):
539 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
540 ctx.verify_mode = ssl.CERT_REQUIRED
541 ctx.load_verify_locations(capath=CAPATH)
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()
549 # Same with a bytes `capath` argument
550 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
551 ctx.verify_mode = ssl.CERT_REQUIRED
552 ctx.load_verify_locations(capath=BYTES_CAPATH)
553 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
554 s.connect(("svn.python.org", 443))
555 try:
556 cert = s.getpeercert()
557 self.assertTrue(cert)
558 finally:
559 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000560
Antoine Pitroue3220242010-04-24 11:13:53 +0000561 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
562 def test_makefile_close(self):
563 # Issue #5238: creating a file-like object with makefile() shouldn't
564 # delay closing the underlying "real socket" (here tested with its
565 # file descriptor, hence skipping the test under Windows).
Antoine Pitrou350c7222010-09-09 13:31:46 +0000566 with support.transient_internet("svn.python.org"):
567 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
568 ss.connect(("svn.python.org", 443))
569 fd = ss.fileno()
570 f = ss.makefile()
571 f.close()
572 # The fd is still open
Antoine Pitroue3220242010-04-24 11:13:53 +0000573 os.read(fd, 0)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000574 # Closing the SSL socket should close the fd too
575 ss.close()
576 gc.collect()
577 with self.assertRaises(OSError) as e:
578 os.read(fd, 0)
579 self.assertEqual(e.exception.errno, errno.EBADF)
Antoine Pitroue3220242010-04-24 11:13:53 +0000580
Antoine Pitrou480a1242010-04-28 21:37:09 +0000581 def test_non_blocking_handshake(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000582 with support.transient_internet("svn.python.org"):
583 s = socket.socket(socket.AF_INET)
584 s.connect(("svn.python.org", 443))
585 s.setblocking(False)
586 s = ssl.wrap_socket(s,
587 cert_reqs=ssl.CERT_NONE,
588 do_handshake_on_connect=False)
589 count = 0
590 while True:
591 try:
592 count += 1
593 s.do_handshake()
594 break
595 except ssl.SSLError as err:
596 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
597 select.select([s], [], [])
598 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
599 select.select([], [s], [])
600 else:
601 raise
602 s.close()
603 if support.verbose:
604 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000605
Antoine Pitrou480a1242010-04-28 21:37:09 +0000606 def test_get_server_certificate(self):
Antoine Pitrou15399c32011-04-28 19:23:55 +0200607 def _test_get_server_certificate(host, port, cert=None):
608 with support.transient_internet(host):
609 pem = ssl.get_server_certificate((host, port))
610 if not pem:
611 self.fail("No server certificate on %s:%s!" % (host, port))
Antoine Pitrou5aefa662011-04-28 19:24:46 +0200612
Antoine Pitrou15399c32011-04-28 19:23:55 +0200613 try:
614 pem = ssl.get_server_certificate((host, port), ca_certs=CERTFILE)
615 except ssl.SSLError as x:
616 #should fail
617 if support.verbose:
618 sys.stdout.write("%s\n" % x)
619 else:
Antoine Pitrou5aefa662011-04-28 19:24:46 +0200620 self.fail("Got server certificate %s for %s:%s!" % (pem, host, port))
621
Antoine Pitrou15399c32011-04-28 19:23:55 +0200622 pem = ssl.get_server_certificate((host, port), ca_certs=cert)
623 if not pem:
Antoine Pitrou5aefa662011-04-28 19:24:46 +0200624 self.fail("No server certificate on %s:%s!" % (host, port))
Antoine Pitrou350c7222010-09-09 13:31:46 +0000625 if support.verbose:
Antoine Pitrou5aefa662011-04-28 19:24:46 +0200626 sys.stdout.write("\nVerified certificate for %s:%s is\n%s\n" % (host, port ,pem))
Antoine Pitrou350c7222010-09-09 13:31:46 +0000627
Antoine Pitrou15399c32011-04-28 19:23:55 +0200628 _test_get_server_certificate('svn.python.org', 443, SVN_PYTHON_ORG_ROOT_CERT)
629 if support.IPV6_ENABLED:
630 _test_get_server_certificate('ipv6.google.com', 443)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000631
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000632 def test_ciphers(self):
633 remote = ("svn.python.org", 443)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000634 with support.transient_internet(remote[0]):
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000635 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
Antoine Pitrou350c7222010-09-09 13:31:46 +0000636 cert_reqs=ssl.CERT_NONE, ciphers="ALL")
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000637 s.connect(remote)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000638 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
639 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")
640 s.connect(remote)
641 # Error checking can happen at instantiation or when connecting
Ezio Melottied3a7d22010-12-01 02:32:32 +0000642 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
Antoine Pitroud2eca372010-10-29 23:41:37 +0000643 with socket.socket(socket.AF_INET) as sock:
644 s = ssl.wrap_socket(sock,
645 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
646 s.connect(remote)
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000647
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000648 def test_algorithms(self):
649 # Issue #8484: all algorithms should be available when verifying a
650 # certificate.
Antoine Pitrou29619b22010-04-22 18:43:31 +0000651 # SHA256 was added in OpenSSL 0.9.8
652 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
653 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Victor Stinnerf332abb2011-01-08 03:16:05 +0000654 # https://sha2.hboeck.de/ was used until 2011-01-08 (no route to host)
655 remote = ("sha256.tbs-internet.com", 443)
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000656 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
Antoine Pitrou160fd932011-01-08 10:23:29 +0000657 with support.transient_internet("sha256.tbs-internet.com"):
Antoine Pitroua88c83c2010-09-07 20:42:19 +0000658 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
659 cert_reqs=ssl.CERT_REQUIRED,
660 ca_certs=sha256_cert,)
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000661 try:
662 s.connect(remote)
663 if support.verbose:
664 sys.stdout.write("\nCipher with %r is %r\n" %
665 (remote, s.cipher()))
666 sys.stdout.write("Certificate is:\n%s\n" %
667 pprint.pformat(s.getpeercert()))
668 finally:
669 s.close()
670
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000671
672try:
673 import threading
674except ImportError:
675 _have_threads = False
676else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000677 _have_threads = True
678
Antoine Pitrou803e6d62010-10-13 10:36:15 +0000679 from test.ssl_servers import make_https_server
680
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000681 class ThreadedEchoServer(threading.Thread):
682
683 class ConnectionHandler(threading.Thread):
684
685 """A mildly complicated class, because we want it to work both
686 with and without the SSL wrapper around the socket connection, so
687 that we can test the STARTTLS functionality."""
688
Bill Janssen6e027db2007-11-15 22:23:56 +0000689 def __init__(self, server, connsock, addr):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000690 self.server = server
691 self.running = False
692 self.sock = connsock
Bill Janssen6e027db2007-11-15 22:23:56 +0000693 self.addr = addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000694 self.sock.setblocking(1)
695 self.sslconn = None
696 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000697 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000698
Antoine Pitrou480a1242010-04-28 21:37:09 +0000699 def wrap_conn(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000700 try:
Antoine Pitroub5218772010-05-21 09:56:06 +0000701 self.sslconn = self.server.context.wrap_socket(
702 self.sock, server_side=True)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000703 except ssl.SSLError:
704 # XXX Various errors can have happened here, for example
705 # a mismatching protocol version, an invalid certificate,
706 # or a low-level bug. This should be made more discriminating.
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000707 if self.server.chatty:
Bill Janssen6e027db2007-11-15 22:23:56 +0000708 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000709 self.running = False
710 self.server.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000711 self.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000712 return False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000713 else:
Antoine Pitroub5218772010-05-21 09:56:06 +0000714 if self.server.context.verify_mode == ssl.CERT_REQUIRED:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000715 cert = self.sslconn.getpeercert()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000716 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000717 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
718 cert_binary = self.sslconn.getpeercert(True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000719 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000720 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
721 cipher = self.sslconn.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000722 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000723 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
724 return True
725
726 def read(self):
727 if self.sslconn:
728 return self.sslconn.read()
729 else:
730 return self.sock.recv(1024)
731
732 def write(self, bytes):
733 if self.sslconn:
734 return self.sslconn.write(bytes)
735 else:
736 return self.sock.send(bytes)
737
738 def close(self):
739 if self.sslconn:
740 self.sslconn.close()
741 else:
742 self.sock.close()
743
Antoine Pitrou480a1242010-04-28 21:37:09 +0000744 def run(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000745 self.running = True
746 if not self.server.starttls_server:
747 if not self.wrap_conn():
748 return
749 while self.running:
750 try:
751 msg = self.read()
Antoine Pitrou480a1242010-04-28 21:37:09 +0000752 stripped = msg.strip()
753 if not stripped:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000754 # eof, so quit this handler
755 self.running = False
756 self.close()
Antoine Pitrou480a1242010-04-28 21:37:09 +0000757 elif stripped == b'over':
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000758 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000759 sys.stdout.write(" server: client closed connection\n")
760 self.close()
761 return
Bill Janssen6e027db2007-11-15 22:23:56 +0000762 elif (self.server.starttls_server and
Antoine Pitrou764b8782010-04-28 22:57:15 +0000763 stripped == b'STARTTLS'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000764 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000765 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000766 self.write(b"OK\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000767 if not self.wrap_conn():
768 return
Bill Janssen40a0f662008-08-12 16:56:25 +0000769 elif (self.server.starttls_server and self.sslconn
Antoine Pitrou764b8782010-04-28 22:57:15 +0000770 and stripped == b'ENDTLS'):
Bill Janssen40a0f662008-08-12 16:56:25 +0000771 if support.verbose and self.server.connectionchatty:
772 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000773 self.write(b"OK\n")
Bill Janssen40a0f662008-08-12 16:56:25 +0000774 self.sock = self.sslconn.unwrap()
775 self.sslconn = None
776 if support.verbose and self.server.connectionchatty:
777 sys.stdout.write(" server: connection is now unencrypted...\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000778 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000779 if (support.verbose and
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000780 self.server.connectionchatty):
781 ctype = (self.sslconn and "encrypted") or "unencrypted"
Antoine Pitrou480a1242010-04-28 21:37:09 +0000782 sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
783 % (msg, ctype, msg.lower(), ctype))
784 self.write(msg.lower())
Bill Janssen6e027db2007-11-15 22:23:56 +0000785 except socket.error:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000786 if self.server.chatty:
787 handle_error("Test server failure:\n")
788 self.close()
789 self.running = False
790 # normally, we'd just stop here, but for the test
791 # harness, we want to stop the server
792 self.server.stop()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000793
Antoine Pitroub5218772010-05-21 09:56:06 +0000794 def __init__(self, certificate=None, ssl_version=None,
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000795 certreqs=None, cacerts=None,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000796 chatty=True, connectionchatty=False, starttls_server=False,
Antoine Pitroub5218772010-05-21 09:56:06 +0000797 ciphers=None, context=None):
798 if context:
799 self.context = context
800 else:
801 self.context = ssl.SSLContext(ssl_version
802 if ssl_version is not None
803 else ssl.PROTOCOL_TLSv1)
804 self.context.verify_mode = (certreqs if certreqs is not None
805 else ssl.CERT_NONE)
806 if cacerts:
807 self.context.load_verify_locations(cacerts)
808 if certificate:
809 self.context.load_cert_chain(certificate)
810 if ciphers:
811 self.context.set_ciphers(ciphers)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000812 self.chatty = chatty
813 self.connectionchatty = connectionchatty
814 self.starttls_server = starttls_server
815 self.sock = socket.socket()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000816 self.port = support.bind_port(self.sock)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000817 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000818 self.active = False
819 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000820 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000821
Antoine Pitrou480a1242010-04-28 21:37:09 +0000822 def start(self, flag=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000823 self.flag = flag
824 threading.Thread.start(self)
825
Antoine Pitrou480a1242010-04-28 21:37:09 +0000826 def run(self):
Antoine Pitrouaf7c6022010-04-27 09:56:02 +0000827 self.sock.settimeout(0.05)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000828 self.sock.listen(5)
829 self.active = True
830 if self.flag:
831 # signal an event
832 self.flag.set()
833 while self.active:
834 try:
835 newconn, connaddr = self.sock.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000836 if support.verbose and self.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000837 sys.stdout.write(' server: new connection from '
Bill Janssen6e027db2007-11-15 22:23:56 +0000838 + repr(connaddr) + '\n')
839 handler = self.ConnectionHandler(self, newconn, connaddr)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000840 handler.start()
841 except socket.timeout:
842 pass
843 except KeyboardInterrupt:
844 self.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000845 self.sock.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000846
Antoine Pitrou480a1242010-04-28 21:37:09 +0000847 def stop(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000848 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000849
Bill Janssen54cc54c2007-12-14 22:08:56 +0000850 class AsyncoreEchoServer(threading.Thread):
851
852 # this one's based on asyncore.dispatcher
853
854 class EchoServer (asyncore.dispatcher):
855
856 class ConnectionHandler (asyncore.dispatcher_with_send):
857
858 def __init__(self, conn, certfile):
859 self.socket = ssl.wrap_socket(conn, server_side=True,
860 certfile=certfile,
861 do_handshake_on_connect=False)
862 asyncore.dispatcher_with_send.__init__(self, self.socket)
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000863 self._ssl_accepting = True
864 self._do_ssl_handshake()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000865
866 def readable(self):
867 if isinstance(self.socket, ssl.SSLSocket):
868 while self.socket.pending() > 0:
869 self.handle_read_event()
870 return True
871
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000872 def _do_ssl_handshake(self):
873 try:
874 self.socket.do_handshake()
875 except ssl.SSLError as err:
876 if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
877 ssl.SSL_ERROR_WANT_WRITE):
878 return
879 elif err.args[0] == ssl.SSL_ERROR_EOF:
880 return self.handle_close()
881 raise
882 except socket.error as err:
883 if err.args[0] == errno.ECONNABORTED:
884 return self.handle_close()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000885 else:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000886 self._ssl_accepting = False
887
888 def handle_read(self):
889 if self._ssl_accepting:
890 self._do_ssl_handshake()
891 else:
892 data = self.recv(1024)
893 if support.verbose:
894 sys.stdout.write(" server: read %s from client\n" % repr(data))
895 if not data:
896 self.close()
897 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000898 self.send(data.lower())
Bill Janssen54cc54c2007-12-14 22:08:56 +0000899
900 def handle_close(self):
Bill Janssen2f5799b2008-06-29 00:08:12 +0000901 self.close()
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000902 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000903 sys.stdout.write(" server: closed connection %s\n" % self.socket)
904
905 def handle_error(self):
906 raise
907
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000908 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000909 self.certfile = certfile
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000910 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
911 self.port = support.bind_port(sock, '')
912 asyncore.dispatcher.__init__(self, sock)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000913 self.listen(5)
914
Giampaolo Rodolà977c7072010-10-04 21:08:36 +0000915 def handle_accepted(self, sock_obj, addr):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000916 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000917 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
918 self.ConnectionHandler(sock_obj, self.certfile)
919
920 def handle_error(self):
921 raise
922
Trent Nelson78520002008-04-10 20:54:35 +0000923 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000924 self.flag = None
925 self.active = False
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000926 self.server = self.EchoServer(certfile)
927 self.port = self.server.port
Bill Janssen54cc54c2007-12-14 22:08:56 +0000928 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000929 self.daemon = True
Bill Janssen54cc54c2007-12-14 22:08:56 +0000930
931 def __str__(self):
932 return "<%s %s>" % (self.__class__.__name__, self.server)
933
934 def start (self, flag=None):
935 self.flag = flag
936 threading.Thread.start(self)
937
Antoine Pitrou480a1242010-04-28 21:37:09 +0000938 def run(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000939 self.active = True
940 if self.flag:
941 self.flag.set()
942 while self.active:
943 try:
944 asyncore.loop(1)
945 except:
946 pass
947
Antoine Pitrou480a1242010-04-28 21:37:09 +0000948 def stop(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000949 self.active = False
950 self.server.close()
951
Antoine Pitrou480a1242010-04-28 21:37:09 +0000952 def bad_cert_test(certfile):
953 """
954 Launch a server with CERT_REQUIRED, and check that trying to
955 connect to it with the given client certificate fails.
956 """
Trent Nelson78520002008-04-10 20:54:35 +0000957 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000958 certreqs=ssl.CERT_REQUIRED,
Bill Janssen6e027db2007-11-15 22:23:56 +0000959 cacerts=CERTFILE, chatty=False,
960 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000961 flag = threading.Event()
962 server.start(flag)
963 # wait for it to start
964 flag.wait()
965 # try to connect
966 try:
Thomas Woutersed03b412007-08-28 21:37:11 +0000967 try:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000968 with socket.socket() as sock:
969 s = ssl.wrap_socket(sock,
970 certfile=certfile,
971 ssl_version=ssl.PROTOCOL_TLSv1)
972 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000973 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000974 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000975 sys.stdout.write("\nSSLError is %s\n" % x.args[1])
Antoine Pitrou05830aa2010-04-27 13:15:18 +0000976 except socket.error as x:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000977 if support.verbose:
Georg Brandlb75b6392010-10-24 14:20:22 +0000978 sys.stdout.write("\nsocket.error is %s\n" % x.args[1])
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000979 except IOError as x:
Giampaolo Rodolàcd9dfb92010-08-29 20:56:56 +0000980 if x.errno != errno.ENOENT:
981 raise
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000982 if support.verbose:
Giampaolo Rodolàcd9dfb92010-08-29 20:56:56 +0000983 sys.stdout.write("\IOError is %s\n" % str(x))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000984 else:
Antoine Pitroud75b2a92010-05-06 14:15:10 +0000985 raise AssertionError("Use of invalid cert should have failed!")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000986 finally:
987 server.stop()
988 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +0000989
Antoine Pitroub5218772010-05-21 09:56:06 +0000990 def server_params_test(client_context, server_context, indata=b"FOO\n",
991 chatty=True, connectionchatty=False):
Antoine Pitrou480a1242010-04-28 21:37:09 +0000992 """
993 Launch a server, connect a client to it and try various reads
994 and writes.
995 """
Antoine Pitroub5218772010-05-21 09:56:06 +0000996 server = ThreadedEchoServer(context=server_context,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000997 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +0000998 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000999 flag = threading.Event()
1000 server.start(flag)
1001 # wait for it to start
1002 flag.wait()
1003 # try to connect
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001004 try:
Antoine Pitroub5218772010-05-21 09:56:06 +00001005 s = client_context.wrap_socket(socket.socket())
Trent Nelson78520002008-04-10 20:54:35 +00001006 s.connect((HOST, server.port))
Antoine Pitrou480a1242010-04-28 21:37:09 +00001007 for arg in [indata, bytearray(indata), memoryview(indata)]:
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00001008 if connectionchatty:
1009 if support.verbose:
1010 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001011 " client: sending %r...\n" % indata)
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00001012 s.write(arg)
1013 outdata = s.read()
1014 if connectionchatty:
1015 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001016 sys.stdout.write(" client: read %r\n" % outdata)
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00001017 if outdata != indata.lower():
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001018 raise AssertionError(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001019 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1020 % (outdata[:20], len(outdata),
1021 indata[:20].lower(), len(indata)))
1022 s.write(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +00001023 if connectionchatty:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001024 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +00001025 sys.stdout.write(" client: closing connection.\n")
1026 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001027 finally:
1028 server.stop()
1029 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +00001030
Antoine Pitroub5218772010-05-21 09:56:06 +00001031 def try_protocol_combo(server_protocol, client_protocol, expect_success,
1032 certsreqs=None, server_options=0, client_options=0):
Benjamin Peterson2a691a82008-03-31 01:51:45 +00001033 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001034 certsreqs = ssl.CERT_NONE
Antoine Pitrou480a1242010-04-28 21:37:09 +00001035 certtype = {
1036 ssl.CERT_NONE: "CERT_NONE",
1037 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
1038 ssl.CERT_REQUIRED: "CERT_REQUIRED",
1039 }[certsreqs]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001040 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001041 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001042 sys.stdout.write(formatstr %
1043 (ssl.get_protocol_name(client_protocol),
1044 ssl.get_protocol_name(server_protocol),
1045 certtype))
Antoine Pitroub5218772010-05-21 09:56:06 +00001046 client_context = ssl.SSLContext(client_protocol)
1047 client_context.options = ssl.OP_ALL | client_options
1048 server_context = ssl.SSLContext(server_protocol)
1049 server_context.options = ssl.OP_ALL | server_options
1050 for ctx in (client_context, server_context):
1051 ctx.verify_mode = certsreqs
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +00001052 # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
1053 # will send an SSLv3 hello (rather than SSLv2) starting from
1054 # OpenSSL 1.0.0 (see issue #8322).
Antoine Pitroub5218772010-05-21 09:56:06 +00001055 ctx.set_ciphers("ALL")
1056 ctx.load_cert_chain(CERTFILE)
1057 ctx.load_verify_locations(CERTFILE)
1058 try:
1059 server_params_test(client_context, server_context,
1060 chatty=False, connectionchatty=False)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001061 # Protocol mismatch can result in either an SSLError, or a
1062 # "Connection reset by peer" error.
1063 except ssl.SSLError:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001064 if expect_success:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001065 raise
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001066 except socket.error as e:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001067 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001068 raise
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001069 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001070 if not expect_success:
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001071 raise AssertionError(
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001072 "Client protocol %s succeeded with server protocol %s!"
1073 % (ssl.get_protocol_name(client_protocol),
1074 ssl.get_protocol_name(server_protocol)))
1075
1076
Bill Janssen6e027db2007-11-15 22:23:56 +00001077 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001078
Antoine Pitrou23df4832010-08-04 17:14:06 +00001079 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001080 def test_echo(self):
1081 """Basic test of an SSL client connecting to a server"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001082 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001083 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00001084 for protocol in PROTOCOLS:
1085 context = ssl.SSLContext(protocol)
1086 context.load_cert_chain(CERTFILE)
1087 server_params_test(context, context,
1088 chatty=True, connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001089
Antoine Pitrou480a1242010-04-28 21:37:09 +00001090 def test_getpeercert(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001091 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001092 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00001093 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1094 context.verify_mode = ssl.CERT_REQUIRED
1095 context.load_verify_locations(CERTFILE)
1096 context.load_cert_chain(CERTFILE)
1097 server = ThreadedEchoServer(context=context, chatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001098 flag = threading.Event()
1099 server.start(flag)
1100 # wait for it to start
1101 flag.wait()
1102 # try to connect
1103 try:
Antoine Pitroub5218772010-05-21 09:56:06 +00001104 s = context.wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001105 s.connect((HOST, server.port))
1106 cert = s.getpeercert()
1107 self.assertTrue(cert, "Can't get peer certificate.")
1108 cipher = s.cipher()
1109 if support.verbose:
1110 sys.stdout.write(pprint.pformat(cert) + '\n')
1111 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
1112 if 'subject' not in cert:
1113 self.fail("No subject field in certificate: %s." %
1114 pprint.pformat(cert))
1115 if ((('organizationName', 'Python Software Foundation'),)
1116 not in cert['subject']):
1117 self.fail(
1118 "Missing or invalid 'organizationName' field in certificate subject; "
1119 "should be 'Python Software Foundation'.")
Antoine Pitroufb046912010-11-09 20:21:19 +00001120 self.assertIn('notBefore', cert)
1121 self.assertIn('notAfter', cert)
1122 before = ssl.cert_time_to_seconds(cert['notBefore'])
1123 after = ssl.cert_time_to_seconds(cert['notAfter'])
1124 self.assertLess(before, after)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001125 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001126 finally:
1127 server.stop()
1128 server.join()
1129
Antoine Pitrou480a1242010-04-28 21:37:09 +00001130 def test_empty_cert(self):
1131 """Connecting with an empty cert file"""
1132 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1133 "nullcert.pem"))
1134 def test_malformed_cert(self):
1135 """Connecting with a badly formatted certificate (syntax error)"""
1136 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1137 "badcert.pem"))
1138 def test_nonexisting_cert(self):
1139 """Connecting with a non-existing cert file"""
1140 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1141 "wrongcert.pem"))
1142 def test_malformed_key(self):
1143 """Connecting with a badly formatted key (syntax error)"""
1144 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1145 "badkey.pem"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001146
Antoine Pitrou480a1242010-04-28 21:37:09 +00001147 def test_rude_shutdown(self):
1148 """A brutal shutdown of an SSL server should raise an IOError
1149 in the client when attempting handshake.
1150 """
Trent Nelson6b240cd2008-04-10 20:12:06 +00001151 listener_ready = threading.Event()
1152 listener_gone = threading.Event()
Antoine Pitrou480a1242010-04-28 21:37:09 +00001153
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001154 s = socket.socket()
1155 port = support.bind_port(s, HOST)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001156
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001157 # `listener` runs in a thread. It sits in an accept() until
1158 # the main thread connects. Then it rudely closes the socket,
1159 # and sets Event `listener_gone` to let the main thread know
1160 # the socket is gone.
Trent Nelson6b240cd2008-04-10 20:12:06 +00001161 def listener():
Trent Nelson6b240cd2008-04-10 20:12:06 +00001162 s.listen(5)
1163 listener_ready.set()
Antoine Pitroud2eca372010-10-29 23:41:37 +00001164 newsock, addr = s.accept()
1165 newsock.close()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001166 s.close()
Trent Nelson6b240cd2008-04-10 20:12:06 +00001167 listener_gone.set()
1168
1169 def connector():
1170 listener_ready.wait()
Antoine Pitroud2eca372010-10-29 23:41:37 +00001171 with socket.socket() as c:
1172 c.connect((HOST, port))
1173 listener_gone.wait()
1174 try:
1175 ssl_sock = ssl.wrap_socket(c)
1176 except IOError:
1177 pass
1178 else:
1179 self.fail('connecting to closed SSL socket should have failed')
Trent Nelson6b240cd2008-04-10 20:12:06 +00001180
1181 t = threading.Thread(target=listener)
1182 t.start()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001183 try:
1184 connector()
1185 finally:
1186 t.join()
Trent Nelson6b240cd2008-04-10 20:12:06 +00001187
Antoine Pitrou23df4832010-08-04 17:14:06 +00001188 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001189 def test_protocol_sslv2(self):
1190 """Connecting to an SSLv2 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001191 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001192 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001193 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
1194 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
1195 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
1196 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
1197 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
1198 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00001199 # SSLv23 client with specific SSL options
1200 if no_sslv2_implies_sslv3_hello():
1201 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
1202 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
1203 client_options=ssl.OP_NO_SSLv2)
1204 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True,
1205 client_options=ssl.OP_NO_SSLv3)
1206 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True,
1207 client_options=ssl.OP_NO_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001208
Antoine Pitrou23df4832010-08-04 17:14:06 +00001209 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001210 def test_protocol_sslv23(self):
1211 """Connecting to an SSLv23 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001212 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001213 sys.stdout.write("\n")
1214 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001215 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001216 except (ssl.SSLError, socket.error) as x:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001217 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001218 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001219 sys.stdout.write(
1220 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
1221 % str(x))
Antoine Pitrou480a1242010-04-28 21:37:09 +00001222 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
1223 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
1224 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001225
Antoine Pitrou480a1242010-04-28 21:37:09 +00001226 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1227 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
1228 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001229
Antoine Pitrou480a1242010-04-28 21:37:09 +00001230 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1231 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
1232 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001233
Antoine Pitroub5218772010-05-21 09:56:06 +00001234 # Server with specific SSL options
1235 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False,
1236 server_options=ssl.OP_NO_SSLv3)
1237 # Will choose TLSv1
1238 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True,
1239 server_options=ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
1240 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, False,
1241 server_options=ssl.OP_NO_TLSv1)
1242
1243
Antoine Pitrou23df4832010-08-04 17:14:06 +00001244 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001245 def test_protocol_sslv3(self):
1246 """Connecting to an SSLv3 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001247 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001248 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001249 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
1250 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1251 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1252 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
1253 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
1254 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00001255 if no_sslv2_implies_sslv3_hello():
1256 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
1257 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, True,
1258 client_options=ssl.OP_NO_SSLv2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001259
Antoine Pitrou23df4832010-08-04 17:14:06 +00001260 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001261 def test_protocol_tlsv1(self):
1262 """Connecting to a TLSv1 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001263 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001264 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001265 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
1266 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
1267 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
1268 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
1269 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
1270 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001271
Antoine Pitrou480a1242010-04-28 21:37:09 +00001272 def test_starttls(self):
1273 """Switching from clear text to encrypted and back again."""
1274 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 +00001275
Trent Nelson78520002008-04-10 20:54:35 +00001276 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001277 ssl_version=ssl.PROTOCOL_TLSv1,
1278 starttls_server=True,
1279 chatty=True,
1280 connectionchatty=True)
1281 flag = threading.Event()
1282 server.start(flag)
1283 # wait for it to start
1284 flag.wait()
1285 # try to connect
1286 wrapped = False
1287 try:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001288 s = socket.socket()
1289 s.setblocking(1)
1290 s.connect((HOST, server.port))
1291 if support.verbose:
1292 sys.stdout.write("\n")
1293 for indata in msgs:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001294 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001295 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001296 " client: sending %r...\n" % indata)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001297 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001298 conn.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001299 outdata = conn.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001300 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001301 s.send(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001302 outdata = s.recv(1024)
Antoine Pitrou480a1242010-04-28 21:37:09 +00001303 msg = outdata.strip().lower()
1304 if indata == b"STARTTLS" and msg.startswith(b"ok"):
1305 # STARTTLS ok, switch to secure mode
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001306 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001307 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001308 " client: read %r from server, starting TLS...\n"
1309 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001310 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
1311 wrapped = True
Antoine Pitrou480a1242010-04-28 21:37:09 +00001312 elif indata == b"ENDTLS" and msg.startswith(b"ok"):
1313 # ENDTLS ok, switch back to clear text
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001314 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001315 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001316 " client: read %r from server, ending TLS...\n"
1317 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001318 s = conn.unwrap()
1319 wrapped = False
1320 else:
1321 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001322 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001323 " client: read %r from server\n" % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001324 if support.verbose:
1325 sys.stdout.write(" client: closing connection.\n")
1326 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001327 conn.write(b"over\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001328 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001329 s.send(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +00001330 if wrapped:
1331 conn.close()
1332 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001333 s.close()
1334 finally:
1335 server.stop()
1336 server.join()
1337
Antoine Pitrou480a1242010-04-28 21:37:09 +00001338 def test_socketserver(self):
1339 """Using a SocketServer to create and manage SSL connections."""
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001340 server = make_https_server(self, CERTFILE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001341 # try to connect
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001342 if support.verbose:
1343 sys.stdout.write('\n')
1344 with open(CERTFILE, 'rb') as f:
1345 d1 = f.read()
1346 d2 = ''
1347 # now fetch the same data from the HTTPS server
1348 url = 'https://%s:%d/%s' % (
1349 HOST, server.port, os.path.split(CERTFILE)[1])
1350 f = urllib.request.urlopen(url)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001351 try:
Barry Warsaw820c1202008-06-12 04:06:45 +00001352 dlen = f.info().get("content-length")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001353 if dlen and (int(dlen) > 0):
1354 d2 = f.read(int(dlen))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001355 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001356 sys.stdout.write(
1357 " client: read %d bytes from remote server '%s'\n"
1358 % (len(d2), server))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001359 finally:
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001360 f.close()
1361 self.assertEqual(d1, d2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001362
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])
Antoine Pitroud2eca372010-10-29 23:41:37 +00001541 for sock in conns:
1542 sock.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001543
1544 t = threading.Thread(target=serve)
1545 t.start()
1546 started.wait()
1547
1548 try:
Antoine Pitrou40f08742010-04-24 22:04:40 +00001549 try:
1550 c = socket.socket(socket.AF_INET)
1551 c.settimeout(0.2)
1552 c.connect((host, port))
1553 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00001554 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00001555 ssl.wrap_socket, c)
Antoine Pitrou40f08742010-04-24 22:04:40 +00001556 finally:
1557 c.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001558 try:
1559 c = socket.socket(socket.AF_INET)
1560 c = ssl.wrap_socket(c)
1561 c.settimeout(0.2)
1562 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00001563 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00001564 c.connect, (host, port))
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001565 finally:
1566 c.close()
1567 finally:
1568 finish = True
1569 t.join()
1570 server.close()
1571
Bill Janssen58afe4c2008-09-08 16:45:19 +00001572
Thomas Woutersed03b412007-08-28 21:37:11 +00001573def test_main(verbose=False):
Antoine Pitrou15cee622010-08-04 16:45:21 +00001574 if support.verbose:
1575 plats = {
1576 'Linux': platform.linux_distribution,
1577 'Mac': platform.mac_ver,
1578 'Windows': platform.win32_ver,
1579 }
1580 for name, func in plats.items():
1581 plat = func()
1582 if plat and plat[0]:
1583 plat = '%s %r' % (name, plat)
1584 break
1585 else:
1586 plat = repr(platform.platform())
1587 print("test_ssl: testing with %r %r" %
1588 (ssl.OPENSSL_VERSION, ssl.OPENSSL_VERSION_INFO))
1589 print(" under %s" % plat)
Antoine Pitroud5323212010-10-22 18:19:07 +00001590 print(" HAS_SNI = %r" % ssl.HAS_SNI)
Antoine Pitrou15cee622010-08-04 16:45:21 +00001591
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()