blob: ba788e4c844488c48688cb161cb32922c036a04d [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 Pitrou86cbfec2011-02-26 23:25:34 +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 Pitroud1c98452011-02-27 15:45:16 +0000495 # EWOULDBLOCK under Windows, EINPROGRESS elsewhere
496 self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK))
Antoine Pitrou86cbfec2011-02-26 23:25:34 +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 Pitrou350c7222010-09-09 13:31:46 +0000625 with support.transient_internet("svn.python.org"):
626 pem = ssl.get_server_certificate(("svn.python.org", 443))
627 if not pem:
628 self.fail("No server certificate on svn.python.org:443!")
Bill Janssen54cc54c2007-12-14 22:08:56 +0000629
Antoine Pitrou350c7222010-09-09 13:31:46 +0000630 try:
631 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
632 except ssl.SSLError as x:
633 #should fail
634 if support.verbose:
635 sys.stdout.write("%s\n" % x)
636 else:
637 self.fail("Got server certificate %s for svn.python.org!" % pem)
638
639 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
640 if not pem:
641 self.fail("No server certificate on svn.python.org:443!")
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000642 if support.verbose:
Antoine Pitrou350c7222010-09-09 13:31:46 +0000643 sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000644
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000645 def test_ciphers(self):
646 remote = ("svn.python.org", 443)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000647 with support.transient_internet(remote[0]):
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000648 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
Antoine Pitrou350c7222010-09-09 13:31:46 +0000649 cert_reqs=ssl.CERT_NONE, ciphers="ALL")
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000650 s.connect(remote)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000651 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
652 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")
653 s.connect(remote)
654 # Error checking can happen at instantiation or when connecting
Ezio Melottied3a7d22010-12-01 02:32:32 +0000655 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
Antoine Pitroud2eca372010-10-29 23:41:37 +0000656 with socket.socket(socket.AF_INET) as sock:
657 s = ssl.wrap_socket(sock,
658 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
659 s.connect(remote)
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000660
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000661 def test_algorithms(self):
662 # Issue #8484: all algorithms should be available when verifying a
663 # certificate.
Antoine Pitrou29619b22010-04-22 18:43:31 +0000664 # SHA256 was added in OpenSSL 0.9.8
665 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
666 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Victor Stinnerf332abb2011-01-08 03:16:05 +0000667 # https://sha2.hboeck.de/ was used until 2011-01-08 (no route to host)
668 remote = ("sha256.tbs-internet.com", 443)
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000669 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
Antoine Pitrou160fd932011-01-08 10:23:29 +0000670 with support.transient_internet("sha256.tbs-internet.com"):
Antoine Pitroua88c83c2010-09-07 20:42:19 +0000671 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
672 cert_reqs=ssl.CERT_REQUIRED,
673 ca_certs=sha256_cert,)
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000674 try:
675 s.connect(remote)
676 if support.verbose:
677 sys.stdout.write("\nCipher with %r is %r\n" %
678 (remote, s.cipher()))
679 sys.stdout.write("Certificate is:\n%s\n" %
680 pprint.pformat(s.getpeercert()))
681 finally:
682 s.close()
683
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000684
685try:
686 import threading
687except ImportError:
688 _have_threads = False
689else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000690 _have_threads = True
691
Antoine Pitrou803e6d62010-10-13 10:36:15 +0000692 from test.ssl_servers import make_https_server
693
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000694 class ThreadedEchoServer(threading.Thread):
695
696 class ConnectionHandler(threading.Thread):
697
698 """A mildly complicated class, because we want it to work both
699 with and without the SSL wrapper around the socket connection, so
700 that we can test the STARTTLS functionality."""
701
Bill Janssen6e027db2007-11-15 22:23:56 +0000702 def __init__(self, server, connsock, addr):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000703 self.server = server
704 self.running = False
705 self.sock = connsock
Bill Janssen6e027db2007-11-15 22:23:56 +0000706 self.addr = addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000707 self.sock.setblocking(1)
708 self.sslconn = None
709 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000710 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000711
Antoine Pitrou480a1242010-04-28 21:37:09 +0000712 def wrap_conn(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000713 try:
Antoine Pitroub5218772010-05-21 09:56:06 +0000714 self.sslconn = self.server.context.wrap_socket(
715 self.sock, server_side=True)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000716 except ssl.SSLError:
717 # XXX Various errors can have happened here, for example
718 # a mismatching protocol version, an invalid certificate,
719 # or a low-level bug. This should be made more discriminating.
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000720 if self.server.chatty:
Bill Janssen6e027db2007-11-15 22:23:56 +0000721 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000722 self.running = False
723 self.server.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000724 self.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000725 return False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000726 else:
Antoine Pitroub5218772010-05-21 09:56:06 +0000727 if self.server.context.verify_mode == ssl.CERT_REQUIRED:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000728 cert = self.sslconn.getpeercert()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000729 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000730 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
731 cert_binary = self.sslconn.getpeercert(True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000732 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000733 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
734 cipher = self.sslconn.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000735 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000736 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
737 return True
738
739 def read(self):
740 if self.sslconn:
741 return self.sslconn.read()
742 else:
743 return self.sock.recv(1024)
744
745 def write(self, bytes):
746 if self.sslconn:
747 return self.sslconn.write(bytes)
748 else:
749 return self.sock.send(bytes)
750
751 def close(self):
752 if self.sslconn:
753 self.sslconn.close()
754 else:
755 self.sock.close()
756
Antoine Pitrou480a1242010-04-28 21:37:09 +0000757 def run(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000758 self.running = True
759 if not self.server.starttls_server:
760 if not self.wrap_conn():
761 return
762 while self.running:
763 try:
764 msg = self.read()
Antoine Pitrou480a1242010-04-28 21:37:09 +0000765 stripped = msg.strip()
766 if not stripped:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000767 # eof, so quit this handler
768 self.running = False
769 self.close()
Antoine Pitrou480a1242010-04-28 21:37:09 +0000770 elif stripped == b'over':
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000771 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000772 sys.stdout.write(" server: client closed connection\n")
773 self.close()
774 return
Bill Janssen6e027db2007-11-15 22:23:56 +0000775 elif (self.server.starttls_server and
Antoine Pitrou764b8782010-04-28 22:57:15 +0000776 stripped == b'STARTTLS'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000777 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000778 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000779 self.write(b"OK\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000780 if not self.wrap_conn():
781 return
Bill Janssen40a0f662008-08-12 16:56:25 +0000782 elif (self.server.starttls_server and self.sslconn
Antoine Pitrou764b8782010-04-28 22:57:15 +0000783 and stripped == b'ENDTLS'):
Bill Janssen40a0f662008-08-12 16:56:25 +0000784 if support.verbose and self.server.connectionchatty:
785 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000786 self.write(b"OK\n")
Bill Janssen40a0f662008-08-12 16:56:25 +0000787 self.sock = self.sslconn.unwrap()
788 self.sslconn = None
789 if support.verbose and self.server.connectionchatty:
790 sys.stdout.write(" server: connection is now unencrypted...\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000791 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000792 if (support.verbose and
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000793 self.server.connectionchatty):
794 ctype = (self.sslconn and "encrypted") or "unencrypted"
Antoine Pitrou480a1242010-04-28 21:37:09 +0000795 sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
796 % (msg, ctype, msg.lower(), ctype))
797 self.write(msg.lower())
Bill Janssen6e027db2007-11-15 22:23:56 +0000798 except socket.error:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000799 if self.server.chatty:
800 handle_error("Test server failure:\n")
801 self.close()
802 self.running = False
803 # normally, we'd just stop here, but for the test
804 # harness, we want to stop the server
805 self.server.stop()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000806
Antoine Pitroub5218772010-05-21 09:56:06 +0000807 def __init__(self, certificate=None, ssl_version=None,
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000808 certreqs=None, cacerts=None,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000809 chatty=True, connectionchatty=False, starttls_server=False,
Antoine Pitroub5218772010-05-21 09:56:06 +0000810 ciphers=None, context=None):
811 if context:
812 self.context = context
813 else:
814 self.context = ssl.SSLContext(ssl_version
815 if ssl_version is not None
816 else ssl.PROTOCOL_TLSv1)
817 self.context.verify_mode = (certreqs if certreqs is not None
818 else ssl.CERT_NONE)
819 if cacerts:
820 self.context.load_verify_locations(cacerts)
821 if certificate:
822 self.context.load_cert_chain(certificate)
823 if ciphers:
824 self.context.set_ciphers(ciphers)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000825 self.chatty = chatty
826 self.connectionchatty = connectionchatty
827 self.starttls_server = starttls_server
828 self.sock = socket.socket()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000829 self.port = support.bind_port(self.sock)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000830 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000831 self.active = False
832 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000833 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000834
Antoine Pitrou480a1242010-04-28 21:37:09 +0000835 def start(self, flag=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000836 self.flag = flag
837 threading.Thread.start(self)
838
Antoine Pitrou480a1242010-04-28 21:37:09 +0000839 def run(self):
Antoine Pitrouaf7c6022010-04-27 09:56:02 +0000840 self.sock.settimeout(0.05)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000841 self.sock.listen(5)
842 self.active = True
843 if self.flag:
844 # signal an event
845 self.flag.set()
846 while self.active:
847 try:
848 newconn, connaddr = self.sock.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000849 if support.verbose and self.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000850 sys.stdout.write(' server: new connection from '
Bill Janssen6e027db2007-11-15 22:23:56 +0000851 + repr(connaddr) + '\n')
852 handler = self.ConnectionHandler(self, newconn, connaddr)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000853 handler.start()
854 except socket.timeout:
855 pass
856 except KeyboardInterrupt:
857 self.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000858 self.sock.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000859
Antoine Pitrou480a1242010-04-28 21:37:09 +0000860 def stop(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000861 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000862
Bill Janssen54cc54c2007-12-14 22:08:56 +0000863 class AsyncoreEchoServer(threading.Thread):
864
865 # this one's based on asyncore.dispatcher
866
867 class EchoServer (asyncore.dispatcher):
868
869 class ConnectionHandler (asyncore.dispatcher_with_send):
870
871 def __init__(self, conn, certfile):
872 self.socket = ssl.wrap_socket(conn, server_side=True,
873 certfile=certfile,
874 do_handshake_on_connect=False)
875 asyncore.dispatcher_with_send.__init__(self, self.socket)
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000876 self._ssl_accepting = True
877 self._do_ssl_handshake()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000878
879 def readable(self):
880 if isinstance(self.socket, ssl.SSLSocket):
881 while self.socket.pending() > 0:
882 self.handle_read_event()
883 return True
884
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000885 def _do_ssl_handshake(self):
886 try:
887 self.socket.do_handshake()
888 except ssl.SSLError as err:
889 if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
890 ssl.SSL_ERROR_WANT_WRITE):
891 return
892 elif err.args[0] == ssl.SSL_ERROR_EOF:
893 return self.handle_close()
894 raise
895 except socket.error as err:
896 if err.args[0] == errno.ECONNABORTED:
897 return self.handle_close()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000898 else:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000899 self._ssl_accepting = False
900
901 def handle_read(self):
902 if self._ssl_accepting:
903 self._do_ssl_handshake()
904 else:
905 data = self.recv(1024)
906 if support.verbose:
907 sys.stdout.write(" server: read %s from client\n" % repr(data))
908 if not data:
909 self.close()
910 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000911 self.send(data.lower())
Bill Janssen54cc54c2007-12-14 22:08:56 +0000912
913 def handle_close(self):
Bill Janssen2f5799b2008-06-29 00:08:12 +0000914 self.close()
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000915 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000916 sys.stdout.write(" server: closed connection %s\n" % self.socket)
917
918 def handle_error(self):
919 raise
920
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000921 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000922 self.certfile = certfile
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000923 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
924 self.port = support.bind_port(sock, '')
925 asyncore.dispatcher.__init__(self, sock)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000926 self.listen(5)
927
Giampaolo Rodolà977c7072010-10-04 21:08:36 +0000928 def handle_accepted(self, sock_obj, addr):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000929 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000930 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
931 self.ConnectionHandler(sock_obj, self.certfile)
932
933 def handle_error(self):
934 raise
935
Trent Nelson78520002008-04-10 20:54:35 +0000936 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000937 self.flag = None
938 self.active = False
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000939 self.server = self.EchoServer(certfile)
940 self.port = self.server.port
Bill Janssen54cc54c2007-12-14 22:08:56 +0000941 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000942 self.daemon = True
Bill Janssen54cc54c2007-12-14 22:08:56 +0000943
944 def __str__(self):
945 return "<%s %s>" % (self.__class__.__name__, self.server)
946
947 def start (self, flag=None):
948 self.flag = flag
949 threading.Thread.start(self)
950
Antoine Pitrou480a1242010-04-28 21:37:09 +0000951 def run(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000952 self.active = True
953 if self.flag:
954 self.flag.set()
955 while self.active:
956 try:
957 asyncore.loop(1)
958 except:
959 pass
960
Antoine Pitrou480a1242010-04-28 21:37:09 +0000961 def stop(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000962 self.active = False
963 self.server.close()
964
Antoine Pitrou480a1242010-04-28 21:37:09 +0000965 def bad_cert_test(certfile):
966 """
967 Launch a server with CERT_REQUIRED, and check that trying to
968 connect to it with the given client certificate fails.
969 """
Trent Nelson78520002008-04-10 20:54:35 +0000970 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000971 certreqs=ssl.CERT_REQUIRED,
Bill Janssen6e027db2007-11-15 22:23:56 +0000972 cacerts=CERTFILE, chatty=False,
973 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000974 flag = threading.Event()
975 server.start(flag)
976 # wait for it to start
977 flag.wait()
978 # try to connect
979 try:
Thomas Woutersed03b412007-08-28 21:37:11 +0000980 try:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000981 with socket.socket() as sock:
982 s = ssl.wrap_socket(sock,
983 certfile=certfile,
984 ssl_version=ssl.PROTOCOL_TLSv1)
985 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000986 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000987 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000988 sys.stdout.write("\nSSLError is %s\n" % x.args[1])
Antoine Pitrou05830aa2010-04-27 13:15:18 +0000989 except socket.error as x:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000990 if support.verbose:
Georg Brandlb75b6392010-10-24 14:20:22 +0000991 sys.stdout.write("\nsocket.error is %s\n" % x.args[1])
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000992 except IOError as x:
Giampaolo Rodolàcd9dfb92010-08-29 20:56:56 +0000993 if x.errno != errno.ENOENT:
994 raise
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000995 if support.verbose:
Giampaolo Rodolàcd9dfb92010-08-29 20:56:56 +0000996 sys.stdout.write("\IOError is %s\n" % str(x))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000997 else:
Antoine Pitroud75b2a92010-05-06 14:15:10 +0000998 raise AssertionError("Use of invalid cert should have failed!")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000999 finally:
1000 server.stop()
1001 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +00001002
Antoine Pitroub5218772010-05-21 09:56:06 +00001003 def server_params_test(client_context, server_context, indata=b"FOO\n",
1004 chatty=True, connectionchatty=False):
Antoine Pitrou480a1242010-04-28 21:37:09 +00001005 """
1006 Launch a server, connect a client to it and try various reads
1007 and writes.
1008 """
Antoine Pitroub5218772010-05-21 09:56:06 +00001009 server = ThreadedEchoServer(context=server_context,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001010 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +00001011 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001012 flag = threading.Event()
1013 server.start(flag)
1014 # wait for it to start
1015 flag.wait()
1016 # try to connect
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001017 try:
Antoine Pitroub5218772010-05-21 09:56:06 +00001018 s = client_context.wrap_socket(socket.socket())
Trent Nelson78520002008-04-10 20:54:35 +00001019 s.connect((HOST, server.port))
Antoine Pitrou480a1242010-04-28 21:37:09 +00001020 for arg in [indata, bytearray(indata), memoryview(indata)]:
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00001021 if connectionchatty:
1022 if support.verbose:
1023 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001024 " client: sending %r...\n" % indata)
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00001025 s.write(arg)
1026 outdata = s.read()
1027 if connectionchatty:
1028 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001029 sys.stdout.write(" client: read %r\n" % outdata)
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00001030 if outdata != indata.lower():
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001031 raise AssertionError(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001032 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1033 % (outdata[:20], len(outdata),
1034 indata[:20].lower(), len(indata)))
1035 s.write(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +00001036 if connectionchatty:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001037 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +00001038 sys.stdout.write(" client: closing connection.\n")
1039 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001040 finally:
1041 server.stop()
1042 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +00001043
Antoine Pitroub5218772010-05-21 09:56:06 +00001044 def try_protocol_combo(server_protocol, client_protocol, expect_success,
1045 certsreqs=None, server_options=0, client_options=0):
Benjamin Peterson2a691a82008-03-31 01:51:45 +00001046 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001047 certsreqs = ssl.CERT_NONE
Antoine Pitrou480a1242010-04-28 21:37:09 +00001048 certtype = {
1049 ssl.CERT_NONE: "CERT_NONE",
1050 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
1051 ssl.CERT_REQUIRED: "CERT_REQUIRED",
1052 }[certsreqs]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001053 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001054 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001055 sys.stdout.write(formatstr %
1056 (ssl.get_protocol_name(client_protocol),
1057 ssl.get_protocol_name(server_protocol),
1058 certtype))
Antoine Pitroub5218772010-05-21 09:56:06 +00001059 client_context = ssl.SSLContext(client_protocol)
1060 client_context.options = ssl.OP_ALL | client_options
1061 server_context = ssl.SSLContext(server_protocol)
1062 server_context.options = ssl.OP_ALL | server_options
1063 for ctx in (client_context, server_context):
1064 ctx.verify_mode = certsreqs
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +00001065 # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
1066 # will send an SSLv3 hello (rather than SSLv2) starting from
1067 # OpenSSL 1.0.0 (see issue #8322).
Antoine Pitroub5218772010-05-21 09:56:06 +00001068 ctx.set_ciphers("ALL")
1069 ctx.load_cert_chain(CERTFILE)
1070 ctx.load_verify_locations(CERTFILE)
1071 try:
1072 server_params_test(client_context, server_context,
1073 chatty=False, connectionchatty=False)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001074 # Protocol mismatch can result in either an SSLError, or a
1075 # "Connection reset by peer" error.
1076 except ssl.SSLError:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001077 if expect_success:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001078 raise
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001079 except socket.error as e:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001080 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001081 raise
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001082 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001083 if not expect_success:
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001084 raise AssertionError(
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001085 "Client protocol %s succeeded with server protocol %s!"
1086 % (ssl.get_protocol_name(client_protocol),
1087 ssl.get_protocol_name(server_protocol)))
1088
1089
Bill Janssen6e027db2007-11-15 22:23:56 +00001090 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001091
Antoine Pitrou23df4832010-08-04 17:14:06 +00001092 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001093 def test_echo(self):
1094 """Basic test of an SSL client connecting to a server"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001095 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001096 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00001097 for protocol in PROTOCOLS:
1098 context = ssl.SSLContext(protocol)
1099 context.load_cert_chain(CERTFILE)
1100 server_params_test(context, context,
1101 chatty=True, connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001102
Antoine Pitrou480a1242010-04-28 21:37:09 +00001103 def test_getpeercert(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001104 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001105 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00001106 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1107 context.verify_mode = ssl.CERT_REQUIRED
1108 context.load_verify_locations(CERTFILE)
1109 context.load_cert_chain(CERTFILE)
1110 server = ThreadedEchoServer(context=context, chatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001111 flag = threading.Event()
1112 server.start(flag)
1113 # wait for it to start
1114 flag.wait()
1115 # try to connect
1116 try:
Antoine Pitroub5218772010-05-21 09:56:06 +00001117 s = context.wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001118 s.connect((HOST, server.port))
1119 cert = s.getpeercert()
1120 self.assertTrue(cert, "Can't get peer certificate.")
1121 cipher = s.cipher()
1122 if support.verbose:
1123 sys.stdout.write(pprint.pformat(cert) + '\n')
1124 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
1125 if 'subject' not in cert:
1126 self.fail("No subject field in certificate: %s." %
1127 pprint.pformat(cert))
1128 if ((('organizationName', 'Python Software Foundation'),)
1129 not in cert['subject']):
1130 self.fail(
1131 "Missing or invalid 'organizationName' field in certificate subject; "
1132 "should be 'Python Software Foundation'.")
Antoine Pitroufb046912010-11-09 20:21:19 +00001133 self.assertIn('notBefore', cert)
1134 self.assertIn('notAfter', cert)
1135 before = ssl.cert_time_to_seconds(cert['notBefore'])
1136 after = ssl.cert_time_to_seconds(cert['notAfter'])
1137 self.assertLess(before, after)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001138 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001139 finally:
1140 server.stop()
1141 server.join()
1142
Antoine Pitrou480a1242010-04-28 21:37:09 +00001143 def test_empty_cert(self):
1144 """Connecting with an empty cert file"""
1145 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1146 "nullcert.pem"))
1147 def test_malformed_cert(self):
1148 """Connecting with a badly formatted certificate (syntax error)"""
1149 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1150 "badcert.pem"))
1151 def test_nonexisting_cert(self):
1152 """Connecting with a non-existing cert file"""
1153 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1154 "wrongcert.pem"))
1155 def test_malformed_key(self):
1156 """Connecting with a badly formatted key (syntax error)"""
1157 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1158 "badkey.pem"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001159
Antoine Pitrou480a1242010-04-28 21:37:09 +00001160 def test_rude_shutdown(self):
1161 """A brutal shutdown of an SSL server should raise an IOError
1162 in the client when attempting handshake.
1163 """
Trent Nelson6b240cd2008-04-10 20:12:06 +00001164 listener_ready = threading.Event()
1165 listener_gone = threading.Event()
Antoine Pitrou480a1242010-04-28 21:37:09 +00001166
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001167 s = socket.socket()
1168 port = support.bind_port(s, HOST)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001169
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001170 # `listener` runs in a thread. It sits in an accept() until
1171 # the main thread connects. Then it rudely closes the socket,
1172 # and sets Event `listener_gone` to let the main thread know
1173 # the socket is gone.
Trent Nelson6b240cd2008-04-10 20:12:06 +00001174 def listener():
Trent Nelson6b240cd2008-04-10 20:12:06 +00001175 s.listen(5)
1176 listener_ready.set()
Antoine Pitroud2eca372010-10-29 23:41:37 +00001177 newsock, addr = s.accept()
1178 newsock.close()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001179 s.close()
Trent Nelson6b240cd2008-04-10 20:12:06 +00001180 listener_gone.set()
1181
1182 def connector():
1183 listener_ready.wait()
Antoine Pitroud2eca372010-10-29 23:41:37 +00001184 with socket.socket() as c:
1185 c.connect((HOST, port))
1186 listener_gone.wait()
1187 try:
1188 ssl_sock = ssl.wrap_socket(c)
1189 except IOError:
1190 pass
1191 else:
1192 self.fail('connecting to closed SSL socket should have failed')
Trent Nelson6b240cd2008-04-10 20:12:06 +00001193
1194 t = threading.Thread(target=listener)
1195 t.start()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001196 try:
1197 connector()
1198 finally:
1199 t.join()
Trent Nelson6b240cd2008-04-10 20:12:06 +00001200
Antoine Pitrou23df4832010-08-04 17:14:06 +00001201 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001202 def test_protocol_sslv2(self):
1203 """Connecting to an SSLv2 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001204 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001205 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001206 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
1207 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
1208 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
1209 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
1210 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
1211 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00001212 # SSLv23 client with specific SSL options
1213 if no_sslv2_implies_sslv3_hello():
1214 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
1215 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
1216 client_options=ssl.OP_NO_SSLv2)
1217 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True,
1218 client_options=ssl.OP_NO_SSLv3)
1219 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True,
1220 client_options=ssl.OP_NO_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001221
Antoine Pitrou23df4832010-08-04 17:14:06 +00001222 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001223 def test_protocol_sslv23(self):
1224 """Connecting to an SSLv23 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001225 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001226 sys.stdout.write("\n")
1227 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001228 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001229 except (ssl.SSLError, socket.error) as x:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001230 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001231 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001232 sys.stdout.write(
1233 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
1234 % str(x))
Antoine Pitrou480a1242010-04-28 21:37:09 +00001235 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
1236 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
1237 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001238
Antoine Pitrou480a1242010-04-28 21:37:09 +00001239 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1240 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
1241 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001242
Antoine Pitrou480a1242010-04-28 21:37:09 +00001243 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1244 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
1245 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001246
Antoine Pitroub5218772010-05-21 09:56:06 +00001247 # Server with specific SSL options
1248 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False,
1249 server_options=ssl.OP_NO_SSLv3)
1250 # Will choose TLSv1
1251 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True,
1252 server_options=ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
1253 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, False,
1254 server_options=ssl.OP_NO_TLSv1)
1255
1256
Antoine Pitrou23df4832010-08-04 17:14:06 +00001257 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001258 def test_protocol_sslv3(self):
1259 """Connecting to an SSLv3 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001260 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001261 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001262 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
1263 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1264 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1265 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
1266 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
1267 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00001268 if no_sslv2_implies_sslv3_hello():
1269 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
1270 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, True,
1271 client_options=ssl.OP_NO_SSLv2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001272
Antoine Pitrou23df4832010-08-04 17:14:06 +00001273 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001274 def test_protocol_tlsv1(self):
1275 """Connecting to a TLSv1 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001276 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001277 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001278 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
1279 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
1280 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
1281 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
1282 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
1283 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001284
Antoine Pitrou480a1242010-04-28 21:37:09 +00001285 def test_starttls(self):
1286 """Switching from clear text to encrypted and back again."""
1287 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 +00001288
Trent Nelson78520002008-04-10 20:54:35 +00001289 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001290 ssl_version=ssl.PROTOCOL_TLSv1,
1291 starttls_server=True,
1292 chatty=True,
1293 connectionchatty=True)
1294 flag = threading.Event()
1295 server.start(flag)
1296 # wait for it to start
1297 flag.wait()
1298 # try to connect
1299 wrapped = False
1300 try:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001301 s = socket.socket()
1302 s.setblocking(1)
1303 s.connect((HOST, server.port))
1304 if support.verbose:
1305 sys.stdout.write("\n")
1306 for indata in msgs:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001307 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001308 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001309 " client: sending %r...\n" % indata)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001310 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001311 conn.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001312 outdata = conn.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001313 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001314 s.send(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001315 outdata = s.recv(1024)
Antoine Pitrou480a1242010-04-28 21:37:09 +00001316 msg = outdata.strip().lower()
1317 if indata == b"STARTTLS" and msg.startswith(b"ok"):
1318 # STARTTLS ok, switch to secure mode
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001319 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001320 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001321 " client: read %r from server, starting TLS...\n"
1322 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001323 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
1324 wrapped = True
Antoine Pitrou480a1242010-04-28 21:37:09 +00001325 elif indata == b"ENDTLS" and msg.startswith(b"ok"):
1326 # ENDTLS ok, switch back to clear text
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001327 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001328 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001329 " client: read %r from server, ending TLS...\n"
1330 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001331 s = conn.unwrap()
1332 wrapped = False
1333 else:
1334 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001335 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001336 " client: read %r from server\n" % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001337 if support.verbose:
1338 sys.stdout.write(" client: closing connection.\n")
1339 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001340 conn.write(b"over\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001341 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001342 s.send(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +00001343 if wrapped:
1344 conn.close()
1345 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001346 s.close()
1347 finally:
1348 server.stop()
1349 server.join()
1350
Antoine Pitrou480a1242010-04-28 21:37:09 +00001351 def test_socketserver(self):
1352 """Using a SocketServer to create and manage SSL connections."""
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001353 server = make_https_server(self, CERTFILE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001354 # try to connect
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001355 if support.verbose:
1356 sys.stdout.write('\n')
1357 with open(CERTFILE, 'rb') as f:
1358 d1 = f.read()
1359 d2 = ''
1360 # now fetch the same data from the HTTPS server
1361 url = 'https://%s:%d/%s' % (
1362 HOST, server.port, os.path.split(CERTFILE)[1])
1363 f = urllib.request.urlopen(url)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001364 try:
Barry Warsaw820c1202008-06-12 04:06:45 +00001365 dlen = f.info().get("content-length")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001366 if dlen and (int(dlen) > 0):
1367 d2 = f.read(int(dlen))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001368 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001369 sys.stdout.write(
1370 " client: read %d bytes from remote server '%s'\n"
1371 % (len(d2), server))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001372 finally:
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001373 f.close()
1374 self.assertEqual(d1, d2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001375
Antoine Pitrou480a1242010-04-28 21:37:09 +00001376 def test_asyncore_server(self):
1377 """Check the example asyncore integration."""
1378 indata = "TEST MESSAGE of mixed case\n"
Trent Nelson6b240cd2008-04-10 20:12:06 +00001379
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001380 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001381 sys.stdout.write("\n")
1382
Antoine Pitrou480a1242010-04-28 21:37:09 +00001383 indata = b"FOO\n"
Trent Nelson78520002008-04-10 20:54:35 +00001384 server = AsyncoreEchoServer(CERTFILE)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001385 flag = threading.Event()
1386 server.start(flag)
1387 # wait for it to start
1388 flag.wait()
1389 # try to connect
1390 try:
1391 s = ssl.wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001392 s.connect(('127.0.0.1', server.port))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001393 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001394 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001395 " client: sending %r...\n" % indata)
1396 s.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001397 outdata = s.read()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001398 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001399 sys.stdout.write(" client: read %r\n" % outdata)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001400 if outdata != indata.lower():
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001401 self.fail(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001402 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1403 % (outdata[:20], len(outdata),
1404 indata[:20].lower(), len(indata)))
1405 s.write(b"over\n")
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001406 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001407 sys.stdout.write(" client: closing connection.\n")
1408 s.close()
Antoine Pitroued986362010-08-15 23:28:10 +00001409 if support.verbose:
1410 sys.stdout.write(" client: connection closed.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001411 finally:
Antoine Pitroued986362010-08-15 23:28:10 +00001412 if support.verbose:
1413 sys.stdout.write(" cleanup: stopping server.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001414 server.stop()
Antoine Pitroued986362010-08-15 23:28:10 +00001415 if support.verbose:
1416 sys.stdout.write(" cleanup: joining server thread.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001417 server.join()
Antoine Pitroued986362010-08-15 23:28:10 +00001418 if support.verbose:
1419 sys.stdout.write(" cleanup: successfully joined.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001420
Antoine Pitrou480a1242010-04-28 21:37:09 +00001421 def test_recv_send(self):
1422 """Test recv(), send() and friends."""
Bill Janssen58afe4c2008-09-08 16:45:19 +00001423 if support.verbose:
1424 sys.stdout.write("\n")
1425
1426 server = ThreadedEchoServer(CERTFILE,
1427 certreqs=ssl.CERT_NONE,
1428 ssl_version=ssl.PROTOCOL_TLSv1,
1429 cacerts=CERTFILE,
1430 chatty=True,
1431 connectionchatty=False)
1432 flag = threading.Event()
1433 server.start(flag)
1434 # wait for it to start
1435 flag.wait()
1436 # try to connect
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001437 s = ssl.wrap_socket(socket.socket(),
1438 server_side=False,
1439 certfile=CERTFILE,
1440 ca_certs=CERTFILE,
1441 cert_reqs=ssl.CERT_NONE,
1442 ssl_version=ssl.PROTOCOL_TLSv1)
1443 s.connect((HOST, server.port))
Bill Janssen58afe4c2008-09-08 16:45:19 +00001444 try:
Bill Janssen58afe4c2008-09-08 16:45:19 +00001445 # helper methods for standardising recv* method signatures
1446 def _recv_into():
1447 b = bytearray(b"\0"*100)
1448 count = s.recv_into(b)
1449 return b[:count]
1450
1451 def _recvfrom_into():
1452 b = bytearray(b"\0"*100)
1453 count, addr = s.recvfrom_into(b)
1454 return b[:count]
1455
1456 # (name, method, whether to expect success, *args)
1457 send_methods = [
1458 ('send', s.send, True, []),
1459 ('sendto', s.sendto, False, ["some.address"]),
1460 ('sendall', s.sendall, True, []),
1461 ]
1462 recv_methods = [
1463 ('recv', s.recv, True, []),
1464 ('recvfrom', s.recvfrom, False, ["some.address"]),
1465 ('recv_into', _recv_into, True, []),
1466 ('recvfrom_into', _recvfrom_into, False, []),
1467 ]
1468 data_prefix = "PREFIX_"
1469
1470 for meth_name, send_meth, expect_success, args in send_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001471 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00001472 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001473 send_meth(indata, *args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001474 outdata = s.read()
Bill Janssen58afe4c2008-09-08 16:45:19 +00001475 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001476 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001477 "While sending with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00001478 "<<{outdata:r}>> ({nout:d}) received; "
1479 "expected <<{indata:r}>> ({nin:d})\n".format(
1480 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00001481 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00001482 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001483 )
1484 )
1485 except ValueError as e:
1486 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001487 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001488 "Failed to send with method <<{name:s}>>; "
1489 "expected to succeed.\n".format(name=meth_name)
1490 )
1491 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001492 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001493 "Method <<{name:s}>> failed with unexpected "
1494 "exception message: {exp:s}\n".format(
1495 name=meth_name, exp=e
1496 )
1497 )
1498
1499 for meth_name, recv_meth, expect_success, args in recv_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001500 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00001501 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001502 s.send(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001503 outdata = recv_meth(*args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001504 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001505 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001506 "While receiving with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00001507 "<<{outdata:r}>> ({nout:d}) received; "
1508 "expected <<{indata:r}>> ({nin:d})\n".format(
1509 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00001510 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00001511 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001512 )
1513 )
1514 except ValueError as e:
1515 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001516 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001517 "Failed to receive with method <<{name:s}>>; "
1518 "expected to succeed.\n".format(name=meth_name)
1519 )
1520 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001521 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001522 "Method <<{name:s}>> failed with unexpected "
1523 "exception message: {exp:s}\n".format(
1524 name=meth_name, exp=e
1525 )
1526 )
1527 # consume data
1528 s.read()
1529
Antoine Pitrou480a1242010-04-28 21:37:09 +00001530 s.write(b"over\n")
Bill Janssen58afe4c2008-09-08 16:45:19 +00001531 s.close()
1532 finally:
1533 server.stop()
1534 server.join()
1535
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001536 def test_handshake_timeout(self):
1537 # Issue #5103: SSL handshake must respect the socket timeout
1538 server = socket.socket(socket.AF_INET)
1539 host = "127.0.0.1"
1540 port = support.bind_port(server)
1541 started = threading.Event()
1542 finish = False
1543
1544 def serve():
1545 server.listen(5)
1546 started.set()
1547 conns = []
1548 while not finish:
1549 r, w, e = select.select([server], [], [], 0.1)
1550 if server in r:
1551 # Let the socket hang around rather than having
1552 # it closed by garbage collection.
1553 conns.append(server.accept()[0])
Antoine Pitroud2eca372010-10-29 23:41:37 +00001554 for sock in conns:
1555 sock.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001556
1557 t = threading.Thread(target=serve)
1558 t.start()
1559 started.wait()
1560
1561 try:
Antoine Pitrou40f08742010-04-24 22:04:40 +00001562 try:
1563 c = socket.socket(socket.AF_INET)
1564 c.settimeout(0.2)
1565 c.connect((host, port))
1566 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00001567 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00001568 ssl.wrap_socket, c)
Antoine Pitrou40f08742010-04-24 22:04:40 +00001569 finally:
1570 c.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001571 try:
1572 c = socket.socket(socket.AF_INET)
1573 c = ssl.wrap_socket(c)
1574 c.settimeout(0.2)
1575 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00001576 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00001577 c.connect, (host, port))
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001578 finally:
1579 c.close()
1580 finally:
1581 finish = True
1582 t.join()
1583 server.close()
1584
Bill Janssen58afe4c2008-09-08 16:45:19 +00001585
Thomas Woutersed03b412007-08-28 21:37:11 +00001586def test_main(verbose=False):
Antoine Pitrou15cee622010-08-04 16:45:21 +00001587 if support.verbose:
1588 plats = {
1589 'Linux': platform.linux_distribution,
1590 'Mac': platform.mac_ver,
1591 'Windows': platform.win32_ver,
1592 }
1593 for name, func in plats.items():
1594 plat = func()
1595 if plat and plat[0]:
1596 plat = '%s %r' % (name, plat)
1597 break
1598 else:
1599 plat = repr(platform.platform())
1600 print("test_ssl: testing with %r %r" %
1601 (ssl.OPENSSL_VERSION, ssl.OPENSSL_VERSION_INFO))
1602 print(" under %s" % plat)
Antoine Pitroud5323212010-10-22 18:19:07 +00001603 print(" HAS_SNI = %r" % ssl.HAS_SNI)
Antoine Pitrou15cee622010-08-04 16:45:21 +00001604
Antoine Pitrou152efa22010-05-16 18:19:27 +00001605 for filename in [
1606 CERTFILE, SVN_PYTHON_ORG_ROOT_CERT, BYTES_CERTFILE,
1607 ONLYCERT, ONLYKEY, BYTES_ONLYCERT, BYTES_ONLYKEY,
1608 BADCERT, BADKEY, EMPTYCERT]:
1609 if not os.path.exists(filename):
1610 raise support.TestFailed("Can't read certificate file %r" % filename)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001611
Antoine Pitrou152efa22010-05-16 18:19:27 +00001612 tests = [ContextTests, BasicSocketTests]
Thomas Woutersed03b412007-08-28 21:37:11 +00001613
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001614 if support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001615 tests.append(NetworkedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001616
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001617 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001618 thread_info = support.threading_setup()
1619 if thread_info and support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001620 tests.append(ThreadedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001621
Antoine Pitrou480a1242010-04-28 21:37:09 +00001622 try:
1623 support.run_unittest(*tests)
1624 finally:
1625 if _have_threads:
1626 support.threading_cleanup(*thread_info)
Thomas Woutersed03b412007-08-28 21:37:11 +00001627
1628if __name__ == "__main__":
1629 test_main()