blob: 164b6c262a5dceeabd0286c7d62eeecf4b4fb5e4 [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 Pitrou350c7222010-09-09 13:31:46 +0000607 with support.transient_internet("svn.python.org"):
608 pem = ssl.get_server_certificate(("svn.python.org", 443))
609 if not pem:
610 self.fail("No server certificate on svn.python.org:443!")
Bill Janssen54cc54c2007-12-14 22:08:56 +0000611
Antoine Pitrou350c7222010-09-09 13:31:46 +0000612 try:
613 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
614 except ssl.SSLError as x:
615 #should fail
616 if support.verbose:
617 sys.stdout.write("%s\n" % x)
618 else:
619 self.fail("Got server certificate %s for svn.python.org!" % pem)
620
621 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
622 if not pem:
623 self.fail("No server certificate on svn.python.org:443!")
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000624 if support.verbose:
Antoine Pitrou350c7222010-09-09 13:31:46 +0000625 sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000626
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000627 def test_ciphers(self):
628 remote = ("svn.python.org", 443)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000629 with support.transient_internet(remote[0]):
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000630 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
Antoine Pitrou350c7222010-09-09 13:31:46 +0000631 cert_reqs=ssl.CERT_NONE, ciphers="ALL")
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000632 s.connect(remote)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000633 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
634 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")
635 s.connect(remote)
636 # Error checking can happen at instantiation or when connecting
Ezio Melottied3a7d22010-12-01 02:32:32 +0000637 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
Antoine Pitroud2eca372010-10-29 23:41:37 +0000638 with socket.socket(socket.AF_INET) as sock:
639 s = ssl.wrap_socket(sock,
640 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
641 s.connect(remote)
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000642
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000643 def test_algorithms(self):
644 # Issue #8484: all algorithms should be available when verifying a
645 # certificate.
Antoine Pitrou29619b22010-04-22 18:43:31 +0000646 # SHA256 was added in OpenSSL 0.9.8
647 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
648 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Victor Stinnerf332abb2011-01-08 03:16:05 +0000649 # https://sha2.hboeck.de/ was used until 2011-01-08 (no route to host)
650 remote = ("sha256.tbs-internet.com", 443)
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000651 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
Antoine Pitrou160fd932011-01-08 10:23:29 +0000652 with support.transient_internet("sha256.tbs-internet.com"):
Antoine Pitroua88c83c2010-09-07 20:42:19 +0000653 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
654 cert_reqs=ssl.CERT_REQUIRED,
655 ca_certs=sha256_cert,)
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000656 try:
657 s.connect(remote)
658 if support.verbose:
659 sys.stdout.write("\nCipher with %r is %r\n" %
660 (remote, s.cipher()))
661 sys.stdout.write("Certificate is:\n%s\n" %
662 pprint.pformat(s.getpeercert()))
663 finally:
664 s.close()
665
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000666
667try:
668 import threading
669except ImportError:
670 _have_threads = False
671else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000672 _have_threads = True
673
Antoine Pitrou803e6d62010-10-13 10:36:15 +0000674 from test.ssl_servers import make_https_server
675
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000676 class ThreadedEchoServer(threading.Thread):
677
678 class ConnectionHandler(threading.Thread):
679
680 """A mildly complicated class, because we want it to work both
681 with and without the SSL wrapper around the socket connection, so
682 that we can test the STARTTLS functionality."""
683
Bill Janssen6e027db2007-11-15 22:23:56 +0000684 def __init__(self, server, connsock, addr):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000685 self.server = server
686 self.running = False
687 self.sock = connsock
Bill Janssen6e027db2007-11-15 22:23:56 +0000688 self.addr = addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000689 self.sock.setblocking(1)
690 self.sslconn = None
691 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000692 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000693
Antoine Pitrou480a1242010-04-28 21:37:09 +0000694 def wrap_conn(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000695 try:
Antoine Pitroub5218772010-05-21 09:56:06 +0000696 self.sslconn = self.server.context.wrap_socket(
697 self.sock, server_side=True)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000698 except ssl.SSLError:
699 # XXX Various errors can have happened here, for example
700 # a mismatching protocol version, an invalid certificate,
701 # or a low-level bug. This should be made more discriminating.
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000702 if self.server.chatty:
Bill Janssen6e027db2007-11-15 22:23:56 +0000703 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000704 self.running = False
705 self.server.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000706 self.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000707 return False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000708 else:
Antoine Pitroub5218772010-05-21 09:56:06 +0000709 if self.server.context.verify_mode == ssl.CERT_REQUIRED:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000710 cert = self.sslconn.getpeercert()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000711 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000712 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
713 cert_binary = self.sslconn.getpeercert(True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000714 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000715 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
716 cipher = self.sslconn.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000717 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000718 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
719 return True
720
721 def read(self):
722 if self.sslconn:
723 return self.sslconn.read()
724 else:
725 return self.sock.recv(1024)
726
727 def write(self, bytes):
728 if self.sslconn:
729 return self.sslconn.write(bytes)
730 else:
731 return self.sock.send(bytes)
732
733 def close(self):
734 if self.sslconn:
735 self.sslconn.close()
736 else:
737 self.sock.close()
738
Antoine Pitrou480a1242010-04-28 21:37:09 +0000739 def run(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000740 self.running = True
741 if not self.server.starttls_server:
742 if not self.wrap_conn():
743 return
744 while self.running:
745 try:
746 msg = self.read()
Antoine Pitrou480a1242010-04-28 21:37:09 +0000747 stripped = msg.strip()
748 if not stripped:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000749 # eof, so quit this handler
750 self.running = False
751 self.close()
Antoine Pitrou480a1242010-04-28 21:37:09 +0000752 elif stripped == b'over':
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000753 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000754 sys.stdout.write(" server: client closed connection\n")
755 self.close()
756 return
Bill Janssen6e027db2007-11-15 22:23:56 +0000757 elif (self.server.starttls_server and
Antoine Pitrou764b8782010-04-28 22:57:15 +0000758 stripped == b'STARTTLS'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000759 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000760 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000761 self.write(b"OK\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000762 if not self.wrap_conn():
763 return
Bill Janssen40a0f662008-08-12 16:56:25 +0000764 elif (self.server.starttls_server and self.sslconn
Antoine Pitrou764b8782010-04-28 22:57:15 +0000765 and stripped == b'ENDTLS'):
Bill Janssen40a0f662008-08-12 16:56:25 +0000766 if support.verbose and self.server.connectionchatty:
767 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000768 self.write(b"OK\n")
Bill Janssen40a0f662008-08-12 16:56:25 +0000769 self.sock = self.sslconn.unwrap()
770 self.sslconn = None
771 if support.verbose and self.server.connectionchatty:
772 sys.stdout.write(" server: connection is now unencrypted...\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000773 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000774 if (support.verbose and
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000775 self.server.connectionchatty):
776 ctype = (self.sslconn and "encrypted") or "unencrypted"
Antoine Pitrou480a1242010-04-28 21:37:09 +0000777 sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
778 % (msg, ctype, msg.lower(), ctype))
779 self.write(msg.lower())
Bill Janssen6e027db2007-11-15 22:23:56 +0000780 except socket.error:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000781 if self.server.chatty:
782 handle_error("Test server failure:\n")
783 self.close()
784 self.running = False
785 # normally, we'd just stop here, but for the test
786 # harness, we want to stop the server
787 self.server.stop()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000788
Antoine Pitroub5218772010-05-21 09:56:06 +0000789 def __init__(self, certificate=None, ssl_version=None,
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000790 certreqs=None, cacerts=None,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000791 chatty=True, connectionchatty=False, starttls_server=False,
Antoine Pitroub5218772010-05-21 09:56:06 +0000792 ciphers=None, context=None):
793 if context:
794 self.context = context
795 else:
796 self.context = ssl.SSLContext(ssl_version
797 if ssl_version is not None
798 else ssl.PROTOCOL_TLSv1)
799 self.context.verify_mode = (certreqs if certreqs is not None
800 else ssl.CERT_NONE)
801 if cacerts:
802 self.context.load_verify_locations(cacerts)
803 if certificate:
804 self.context.load_cert_chain(certificate)
805 if ciphers:
806 self.context.set_ciphers(ciphers)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000807 self.chatty = chatty
808 self.connectionchatty = connectionchatty
809 self.starttls_server = starttls_server
810 self.sock = socket.socket()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000811 self.port = support.bind_port(self.sock)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000812 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000813 self.active = False
814 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000815 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000816
Antoine Pitrou480a1242010-04-28 21:37:09 +0000817 def start(self, flag=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000818 self.flag = flag
819 threading.Thread.start(self)
820
Antoine Pitrou480a1242010-04-28 21:37:09 +0000821 def run(self):
Antoine Pitrouaf7c6022010-04-27 09:56:02 +0000822 self.sock.settimeout(0.05)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000823 self.sock.listen(5)
824 self.active = True
825 if self.flag:
826 # signal an event
827 self.flag.set()
828 while self.active:
829 try:
830 newconn, connaddr = self.sock.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000831 if support.verbose and self.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000832 sys.stdout.write(' server: new connection from '
Bill Janssen6e027db2007-11-15 22:23:56 +0000833 + repr(connaddr) + '\n')
834 handler = self.ConnectionHandler(self, newconn, connaddr)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000835 handler.start()
836 except socket.timeout:
837 pass
838 except KeyboardInterrupt:
839 self.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000840 self.sock.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000841
Antoine Pitrou480a1242010-04-28 21:37:09 +0000842 def stop(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000843 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000844
Bill Janssen54cc54c2007-12-14 22:08:56 +0000845 class AsyncoreEchoServer(threading.Thread):
846
847 # this one's based on asyncore.dispatcher
848
849 class EchoServer (asyncore.dispatcher):
850
851 class ConnectionHandler (asyncore.dispatcher_with_send):
852
853 def __init__(self, conn, certfile):
854 self.socket = ssl.wrap_socket(conn, server_side=True,
855 certfile=certfile,
856 do_handshake_on_connect=False)
857 asyncore.dispatcher_with_send.__init__(self, self.socket)
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000858 self._ssl_accepting = True
859 self._do_ssl_handshake()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000860
861 def readable(self):
862 if isinstance(self.socket, ssl.SSLSocket):
863 while self.socket.pending() > 0:
864 self.handle_read_event()
865 return True
866
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000867 def _do_ssl_handshake(self):
868 try:
869 self.socket.do_handshake()
870 except ssl.SSLError as err:
871 if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
872 ssl.SSL_ERROR_WANT_WRITE):
873 return
874 elif err.args[0] == ssl.SSL_ERROR_EOF:
875 return self.handle_close()
876 raise
877 except socket.error as err:
878 if err.args[0] == errno.ECONNABORTED:
879 return self.handle_close()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000880 else:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000881 self._ssl_accepting = False
882
883 def handle_read(self):
884 if self._ssl_accepting:
885 self._do_ssl_handshake()
886 else:
887 data = self.recv(1024)
888 if support.verbose:
889 sys.stdout.write(" server: read %s from client\n" % repr(data))
890 if not data:
891 self.close()
892 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000893 self.send(data.lower())
Bill Janssen54cc54c2007-12-14 22:08:56 +0000894
895 def handle_close(self):
Bill Janssen2f5799b2008-06-29 00:08:12 +0000896 self.close()
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000897 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000898 sys.stdout.write(" server: closed connection %s\n" % self.socket)
899
900 def handle_error(self):
901 raise
902
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000903 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000904 self.certfile = certfile
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000905 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
906 self.port = support.bind_port(sock, '')
907 asyncore.dispatcher.__init__(self, sock)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000908 self.listen(5)
909
Giampaolo Rodolà977c7072010-10-04 21:08:36 +0000910 def handle_accepted(self, sock_obj, addr):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000911 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000912 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
913 self.ConnectionHandler(sock_obj, self.certfile)
914
915 def handle_error(self):
916 raise
917
Trent Nelson78520002008-04-10 20:54:35 +0000918 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000919 self.flag = None
920 self.active = False
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000921 self.server = self.EchoServer(certfile)
922 self.port = self.server.port
Bill Janssen54cc54c2007-12-14 22:08:56 +0000923 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000924 self.daemon = True
Bill Janssen54cc54c2007-12-14 22:08:56 +0000925
926 def __str__(self):
927 return "<%s %s>" % (self.__class__.__name__, self.server)
928
929 def start (self, flag=None):
930 self.flag = flag
931 threading.Thread.start(self)
932
Antoine Pitrou480a1242010-04-28 21:37:09 +0000933 def run(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000934 self.active = True
935 if self.flag:
936 self.flag.set()
937 while self.active:
938 try:
939 asyncore.loop(1)
940 except:
941 pass
942
Antoine Pitrou480a1242010-04-28 21:37:09 +0000943 def stop(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000944 self.active = False
945 self.server.close()
946
Antoine Pitrou480a1242010-04-28 21:37:09 +0000947 def bad_cert_test(certfile):
948 """
949 Launch a server with CERT_REQUIRED, and check that trying to
950 connect to it with the given client certificate fails.
951 """
Trent Nelson78520002008-04-10 20:54:35 +0000952 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000953 certreqs=ssl.CERT_REQUIRED,
Bill Janssen6e027db2007-11-15 22:23:56 +0000954 cacerts=CERTFILE, chatty=False,
955 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000956 flag = threading.Event()
957 server.start(flag)
958 # wait for it to start
959 flag.wait()
960 # try to connect
961 try:
Thomas Woutersed03b412007-08-28 21:37:11 +0000962 try:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000963 with socket.socket() as sock:
964 s = ssl.wrap_socket(sock,
965 certfile=certfile,
966 ssl_version=ssl.PROTOCOL_TLSv1)
967 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000968 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000969 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000970 sys.stdout.write("\nSSLError is %s\n" % x.args[1])
Antoine Pitrou05830aa2010-04-27 13:15:18 +0000971 except socket.error as x:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000972 if support.verbose:
Georg Brandlb75b6392010-10-24 14:20:22 +0000973 sys.stdout.write("\nsocket.error is %s\n" % x.args[1])
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000974 except IOError as x:
Giampaolo Rodolàcd9dfb92010-08-29 20:56:56 +0000975 if x.errno != errno.ENOENT:
976 raise
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000977 if support.verbose:
Giampaolo Rodolàcd9dfb92010-08-29 20:56:56 +0000978 sys.stdout.write("\IOError is %s\n" % str(x))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000979 else:
Antoine Pitroud75b2a92010-05-06 14:15:10 +0000980 raise AssertionError("Use of invalid cert should have failed!")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000981 finally:
982 server.stop()
983 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +0000984
Antoine Pitroub5218772010-05-21 09:56:06 +0000985 def server_params_test(client_context, server_context, indata=b"FOO\n",
986 chatty=True, connectionchatty=False):
Antoine Pitrou480a1242010-04-28 21:37:09 +0000987 """
988 Launch a server, connect a client to it and try various reads
989 and writes.
990 """
Antoine Pitroub5218772010-05-21 09:56:06 +0000991 server = ThreadedEchoServer(context=server_context,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000992 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +0000993 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000994 flag = threading.Event()
995 server.start(flag)
996 # wait for it to start
997 flag.wait()
998 # try to connect
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000999 try:
Antoine Pitroub5218772010-05-21 09:56:06 +00001000 s = client_context.wrap_socket(socket.socket())
Trent Nelson78520002008-04-10 20:54:35 +00001001 s.connect((HOST, server.port))
Antoine Pitrou480a1242010-04-28 21:37:09 +00001002 for arg in [indata, bytearray(indata), memoryview(indata)]:
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00001003 if connectionchatty:
1004 if support.verbose:
1005 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001006 " client: sending %r...\n" % indata)
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00001007 s.write(arg)
1008 outdata = s.read()
1009 if connectionchatty:
1010 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001011 sys.stdout.write(" client: read %r\n" % outdata)
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00001012 if outdata != indata.lower():
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001013 raise AssertionError(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001014 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1015 % (outdata[:20], len(outdata),
1016 indata[:20].lower(), len(indata)))
1017 s.write(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +00001018 if connectionchatty:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001019 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +00001020 sys.stdout.write(" client: closing connection.\n")
1021 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001022 finally:
1023 server.stop()
1024 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +00001025
Antoine Pitroub5218772010-05-21 09:56:06 +00001026 def try_protocol_combo(server_protocol, client_protocol, expect_success,
1027 certsreqs=None, server_options=0, client_options=0):
Benjamin Peterson2a691a82008-03-31 01:51:45 +00001028 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001029 certsreqs = ssl.CERT_NONE
Antoine Pitrou480a1242010-04-28 21:37:09 +00001030 certtype = {
1031 ssl.CERT_NONE: "CERT_NONE",
1032 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
1033 ssl.CERT_REQUIRED: "CERT_REQUIRED",
1034 }[certsreqs]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001035 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001036 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001037 sys.stdout.write(formatstr %
1038 (ssl.get_protocol_name(client_protocol),
1039 ssl.get_protocol_name(server_protocol),
1040 certtype))
Antoine Pitroub5218772010-05-21 09:56:06 +00001041 client_context = ssl.SSLContext(client_protocol)
1042 client_context.options = ssl.OP_ALL | client_options
1043 server_context = ssl.SSLContext(server_protocol)
1044 server_context.options = ssl.OP_ALL | server_options
1045 for ctx in (client_context, server_context):
1046 ctx.verify_mode = certsreqs
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +00001047 # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
1048 # will send an SSLv3 hello (rather than SSLv2) starting from
1049 # OpenSSL 1.0.0 (see issue #8322).
Antoine Pitroub5218772010-05-21 09:56:06 +00001050 ctx.set_ciphers("ALL")
1051 ctx.load_cert_chain(CERTFILE)
1052 ctx.load_verify_locations(CERTFILE)
1053 try:
1054 server_params_test(client_context, server_context,
1055 chatty=False, connectionchatty=False)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001056 # Protocol mismatch can result in either an SSLError, or a
1057 # "Connection reset by peer" error.
1058 except ssl.SSLError:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001059 if expect_success:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001060 raise
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001061 except socket.error as e:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001062 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001063 raise
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001064 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001065 if not expect_success:
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001066 raise AssertionError(
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001067 "Client protocol %s succeeded with server protocol %s!"
1068 % (ssl.get_protocol_name(client_protocol),
1069 ssl.get_protocol_name(server_protocol)))
1070
1071
Bill Janssen6e027db2007-11-15 22:23:56 +00001072 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001073
Antoine Pitrou23df4832010-08-04 17:14:06 +00001074 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001075 def test_echo(self):
1076 """Basic test of an SSL client connecting to a server"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001077 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001078 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00001079 for protocol in PROTOCOLS:
1080 context = ssl.SSLContext(protocol)
1081 context.load_cert_chain(CERTFILE)
1082 server_params_test(context, context,
1083 chatty=True, connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001084
Antoine Pitrou480a1242010-04-28 21:37:09 +00001085 def test_getpeercert(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001086 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001087 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00001088 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1089 context.verify_mode = ssl.CERT_REQUIRED
1090 context.load_verify_locations(CERTFILE)
1091 context.load_cert_chain(CERTFILE)
1092 server = ThreadedEchoServer(context=context, chatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001093 flag = threading.Event()
1094 server.start(flag)
1095 # wait for it to start
1096 flag.wait()
1097 # try to connect
1098 try:
Antoine Pitroub5218772010-05-21 09:56:06 +00001099 s = context.wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001100 s.connect((HOST, server.port))
1101 cert = s.getpeercert()
1102 self.assertTrue(cert, "Can't get peer certificate.")
1103 cipher = s.cipher()
1104 if support.verbose:
1105 sys.stdout.write(pprint.pformat(cert) + '\n')
1106 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
1107 if 'subject' not in cert:
1108 self.fail("No subject field in certificate: %s." %
1109 pprint.pformat(cert))
1110 if ((('organizationName', 'Python Software Foundation'),)
1111 not in cert['subject']):
1112 self.fail(
1113 "Missing or invalid 'organizationName' field in certificate subject; "
1114 "should be 'Python Software Foundation'.")
Antoine Pitroufb046912010-11-09 20:21:19 +00001115 self.assertIn('notBefore', cert)
1116 self.assertIn('notAfter', cert)
1117 before = ssl.cert_time_to_seconds(cert['notBefore'])
1118 after = ssl.cert_time_to_seconds(cert['notAfter'])
1119 self.assertLess(before, after)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001120 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001121 finally:
1122 server.stop()
1123 server.join()
1124
Antoine Pitrou480a1242010-04-28 21:37:09 +00001125 def test_empty_cert(self):
1126 """Connecting with an empty cert file"""
1127 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1128 "nullcert.pem"))
1129 def test_malformed_cert(self):
1130 """Connecting with a badly formatted certificate (syntax error)"""
1131 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1132 "badcert.pem"))
1133 def test_nonexisting_cert(self):
1134 """Connecting with a non-existing cert file"""
1135 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1136 "wrongcert.pem"))
1137 def test_malformed_key(self):
1138 """Connecting with a badly formatted key (syntax error)"""
1139 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1140 "badkey.pem"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001141
Antoine Pitrou480a1242010-04-28 21:37:09 +00001142 def test_rude_shutdown(self):
1143 """A brutal shutdown of an SSL server should raise an IOError
1144 in the client when attempting handshake.
1145 """
Trent Nelson6b240cd2008-04-10 20:12:06 +00001146 listener_ready = threading.Event()
1147 listener_gone = threading.Event()
Antoine Pitrou480a1242010-04-28 21:37:09 +00001148
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001149 s = socket.socket()
1150 port = support.bind_port(s, HOST)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001151
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001152 # `listener` runs in a thread. It sits in an accept() until
1153 # the main thread connects. Then it rudely closes the socket,
1154 # and sets Event `listener_gone` to let the main thread know
1155 # the socket is gone.
Trent Nelson6b240cd2008-04-10 20:12:06 +00001156 def listener():
Trent Nelson6b240cd2008-04-10 20:12:06 +00001157 s.listen(5)
1158 listener_ready.set()
Antoine Pitroud2eca372010-10-29 23:41:37 +00001159 newsock, addr = s.accept()
1160 newsock.close()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001161 s.close()
Trent Nelson6b240cd2008-04-10 20:12:06 +00001162 listener_gone.set()
1163
1164 def connector():
1165 listener_ready.wait()
Antoine Pitroud2eca372010-10-29 23:41:37 +00001166 with socket.socket() as c:
1167 c.connect((HOST, port))
1168 listener_gone.wait()
1169 try:
1170 ssl_sock = ssl.wrap_socket(c)
1171 except IOError:
1172 pass
1173 else:
1174 self.fail('connecting to closed SSL socket should have failed')
Trent Nelson6b240cd2008-04-10 20:12:06 +00001175
1176 t = threading.Thread(target=listener)
1177 t.start()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001178 try:
1179 connector()
1180 finally:
1181 t.join()
Trent Nelson6b240cd2008-04-10 20:12:06 +00001182
Antoine Pitrou23df4832010-08-04 17:14:06 +00001183 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001184 def test_protocol_sslv2(self):
1185 """Connecting to an SSLv2 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001186 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001187 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001188 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
1189 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
1190 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
1191 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
1192 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
1193 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00001194 # SSLv23 client with specific SSL options
1195 if no_sslv2_implies_sslv3_hello():
1196 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
1197 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
1198 client_options=ssl.OP_NO_SSLv2)
1199 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True,
1200 client_options=ssl.OP_NO_SSLv3)
1201 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True,
1202 client_options=ssl.OP_NO_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001203
Antoine Pitrou23df4832010-08-04 17:14:06 +00001204 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001205 def test_protocol_sslv23(self):
1206 """Connecting to an SSLv23 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001207 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001208 sys.stdout.write("\n")
1209 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001210 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001211 except (ssl.SSLError, socket.error) as x:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001212 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001213 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001214 sys.stdout.write(
1215 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
1216 % str(x))
Antoine Pitrou480a1242010-04-28 21:37:09 +00001217 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
1218 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
1219 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001220
Antoine Pitrou480a1242010-04-28 21:37:09 +00001221 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1222 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
1223 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001224
Antoine Pitrou480a1242010-04-28 21:37:09 +00001225 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1226 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
1227 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001228
Antoine Pitroub5218772010-05-21 09:56:06 +00001229 # Server with specific SSL options
1230 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False,
1231 server_options=ssl.OP_NO_SSLv3)
1232 # Will choose TLSv1
1233 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True,
1234 server_options=ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
1235 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, False,
1236 server_options=ssl.OP_NO_TLSv1)
1237
1238
Antoine Pitrou23df4832010-08-04 17:14:06 +00001239 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001240 def test_protocol_sslv3(self):
1241 """Connecting to an SSLv3 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001242 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001243 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001244 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
1245 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1246 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1247 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
1248 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
1249 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00001250 if no_sslv2_implies_sslv3_hello():
1251 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
1252 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, True,
1253 client_options=ssl.OP_NO_SSLv2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001254
Antoine Pitrou23df4832010-08-04 17:14:06 +00001255 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001256 def test_protocol_tlsv1(self):
1257 """Connecting to a TLSv1 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001258 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001259 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001260 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
1261 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
1262 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
1263 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
1264 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
1265 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001266
Antoine Pitrou480a1242010-04-28 21:37:09 +00001267 def test_starttls(self):
1268 """Switching from clear text to encrypted and back again."""
1269 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 +00001270
Trent Nelson78520002008-04-10 20:54:35 +00001271 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001272 ssl_version=ssl.PROTOCOL_TLSv1,
1273 starttls_server=True,
1274 chatty=True,
1275 connectionchatty=True)
1276 flag = threading.Event()
1277 server.start(flag)
1278 # wait for it to start
1279 flag.wait()
1280 # try to connect
1281 wrapped = False
1282 try:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001283 s = socket.socket()
1284 s.setblocking(1)
1285 s.connect((HOST, server.port))
1286 if support.verbose:
1287 sys.stdout.write("\n")
1288 for indata in msgs:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001289 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001290 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001291 " client: sending %r...\n" % indata)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001292 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001293 conn.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001294 outdata = conn.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001295 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001296 s.send(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001297 outdata = s.recv(1024)
Antoine Pitrou480a1242010-04-28 21:37:09 +00001298 msg = outdata.strip().lower()
1299 if indata == b"STARTTLS" and msg.startswith(b"ok"):
1300 # STARTTLS ok, switch to secure mode
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001301 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001302 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001303 " client: read %r from server, starting TLS...\n"
1304 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001305 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
1306 wrapped = True
Antoine Pitrou480a1242010-04-28 21:37:09 +00001307 elif indata == b"ENDTLS" and msg.startswith(b"ok"):
1308 # ENDTLS ok, switch back to clear text
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001309 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001310 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001311 " client: read %r from server, ending TLS...\n"
1312 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001313 s = conn.unwrap()
1314 wrapped = False
1315 else:
1316 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001317 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001318 " client: read %r from server\n" % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001319 if support.verbose:
1320 sys.stdout.write(" client: closing connection.\n")
1321 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001322 conn.write(b"over\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001323 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001324 s.send(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +00001325 if wrapped:
1326 conn.close()
1327 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001328 s.close()
1329 finally:
1330 server.stop()
1331 server.join()
1332
Antoine Pitrou480a1242010-04-28 21:37:09 +00001333 def test_socketserver(self):
1334 """Using a SocketServer to create and manage SSL connections."""
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001335 server = make_https_server(self, CERTFILE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001336 # try to connect
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001337 if support.verbose:
1338 sys.stdout.write('\n')
1339 with open(CERTFILE, 'rb') as f:
1340 d1 = f.read()
1341 d2 = ''
1342 # now fetch the same data from the HTTPS server
1343 url = 'https://%s:%d/%s' % (
1344 HOST, server.port, os.path.split(CERTFILE)[1])
1345 f = urllib.request.urlopen(url)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001346 try:
Barry Warsaw820c1202008-06-12 04:06:45 +00001347 dlen = f.info().get("content-length")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001348 if dlen and (int(dlen) > 0):
1349 d2 = f.read(int(dlen))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001350 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001351 sys.stdout.write(
1352 " client: read %d bytes from remote server '%s'\n"
1353 % (len(d2), server))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001354 finally:
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001355 f.close()
1356 self.assertEqual(d1, d2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001357
Antoine Pitrou480a1242010-04-28 21:37:09 +00001358 def test_asyncore_server(self):
1359 """Check the example asyncore integration."""
1360 indata = "TEST MESSAGE of mixed case\n"
Trent Nelson6b240cd2008-04-10 20:12:06 +00001361
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001362 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001363 sys.stdout.write("\n")
1364
Antoine Pitrou480a1242010-04-28 21:37:09 +00001365 indata = b"FOO\n"
Trent Nelson78520002008-04-10 20:54:35 +00001366 server = AsyncoreEchoServer(CERTFILE)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001367 flag = threading.Event()
1368 server.start(flag)
1369 # wait for it to start
1370 flag.wait()
1371 # try to connect
1372 try:
1373 s = ssl.wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001374 s.connect(('127.0.0.1', server.port))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001375 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001376 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001377 " client: sending %r...\n" % indata)
1378 s.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001379 outdata = s.read()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001380 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001381 sys.stdout.write(" client: read %r\n" % outdata)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001382 if outdata != indata.lower():
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001383 self.fail(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001384 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1385 % (outdata[:20], len(outdata),
1386 indata[:20].lower(), len(indata)))
1387 s.write(b"over\n")
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001388 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001389 sys.stdout.write(" client: closing connection.\n")
1390 s.close()
Antoine Pitroued986362010-08-15 23:28:10 +00001391 if support.verbose:
1392 sys.stdout.write(" client: connection closed.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001393 finally:
Antoine Pitroued986362010-08-15 23:28:10 +00001394 if support.verbose:
1395 sys.stdout.write(" cleanup: stopping server.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001396 server.stop()
Antoine Pitroued986362010-08-15 23:28:10 +00001397 if support.verbose:
1398 sys.stdout.write(" cleanup: joining server thread.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001399 server.join()
Antoine Pitroued986362010-08-15 23:28:10 +00001400 if support.verbose:
1401 sys.stdout.write(" cleanup: successfully joined.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001402
Antoine Pitrou480a1242010-04-28 21:37:09 +00001403 def test_recv_send(self):
1404 """Test recv(), send() and friends."""
Bill Janssen58afe4c2008-09-08 16:45:19 +00001405 if support.verbose:
1406 sys.stdout.write("\n")
1407
1408 server = ThreadedEchoServer(CERTFILE,
1409 certreqs=ssl.CERT_NONE,
1410 ssl_version=ssl.PROTOCOL_TLSv1,
1411 cacerts=CERTFILE,
1412 chatty=True,
1413 connectionchatty=False)
1414 flag = threading.Event()
1415 server.start(flag)
1416 # wait for it to start
1417 flag.wait()
1418 # try to connect
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001419 s = ssl.wrap_socket(socket.socket(),
1420 server_side=False,
1421 certfile=CERTFILE,
1422 ca_certs=CERTFILE,
1423 cert_reqs=ssl.CERT_NONE,
1424 ssl_version=ssl.PROTOCOL_TLSv1)
1425 s.connect((HOST, server.port))
Bill Janssen58afe4c2008-09-08 16:45:19 +00001426 try:
Bill Janssen58afe4c2008-09-08 16:45:19 +00001427 # helper methods for standardising recv* method signatures
1428 def _recv_into():
1429 b = bytearray(b"\0"*100)
1430 count = s.recv_into(b)
1431 return b[:count]
1432
1433 def _recvfrom_into():
1434 b = bytearray(b"\0"*100)
1435 count, addr = s.recvfrom_into(b)
1436 return b[:count]
1437
1438 # (name, method, whether to expect success, *args)
1439 send_methods = [
1440 ('send', s.send, True, []),
1441 ('sendto', s.sendto, False, ["some.address"]),
1442 ('sendall', s.sendall, True, []),
1443 ]
1444 recv_methods = [
1445 ('recv', s.recv, True, []),
1446 ('recvfrom', s.recvfrom, False, ["some.address"]),
1447 ('recv_into', _recv_into, True, []),
1448 ('recvfrom_into', _recvfrom_into, False, []),
1449 ]
1450 data_prefix = "PREFIX_"
1451
1452 for meth_name, send_meth, expect_success, args in send_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001453 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00001454 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001455 send_meth(indata, *args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001456 outdata = s.read()
Bill Janssen58afe4c2008-09-08 16:45:19 +00001457 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001458 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001459 "While sending with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00001460 "<<{outdata:r}>> ({nout:d}) received; "
1461 "expected <<{indata:r}>> ({nin:d})\n".format(
1462 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00001463 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00001464 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001465 )
1466 )
1467 except ValueError as e:
1468 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001469 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001470 "Failed to send with method <<{name:s}>>; "
1471 "expected to succeed.\n".format(name=meth_name)
1472 )
1473 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001474 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001475 "Method <<{name:s}>> failed with unexpected "
1476 "exception message: {exp:s}\n".format(
1477 name=meth_name, exp=e
1478 )
1479 )
1480
1481 for meth_name, recv_meth, expect_success, args in recv_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001482 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00001483 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001484 s.send(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001485 outdata = recv_meth(*args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001486 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001487 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001488 "While receiving with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00001489 "<<{outdata:r}>> ({nout:d}) received; "
1490 "expected <<{indata:r}>> ({nin:d})\n".format(
1491 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00001492 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00001493 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001494 )
1495 )
1496 except ValueError as e:
1497 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001498 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001499 "Failed to receive with method <<{name:s}>>; "
1500 "expected to succeed.\n".format(name=meth_name)
1501 )
1502 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001503 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001504 "Method <<{name:s}>> failed with unexpected "
1505 "exception message: {exp:s}\n".format(
1506 name=meth_name, exp=e
1507 )
1508 )
1509 # consume data
1510 s.read()
1511
Antoine Pitrou480a1242010-04-28 21:37:09 +00001512 s.write(b"over\n")
Bill Janssen58afe4c2008-09-08 16:45:19 +00001513 s.close()
1514 finally:
1515 server.stop()
1516 server.join()
1517
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001518 def test_handshake_timeout(self):
1519 # Issue #5103: SSL handshake must respect the socket timeout
1520 server = socket.socket(socket.AF_INET)
1521 host = "127.0.0.1"
1522 port = support.bind_port(server)
1523 started = threading.Event()
1524 finish = False
1525
1526 def serve():
1527 server.listen(5)
1528 started.set()
1529 conns = []
1530 while not finish:
1531 r, w, e = select.select([server], [], [], 0.1)
1532 if server in r:
1533 # Let the socket hang around rather than having
1534 # it closed by garbage collection.
1535 conns.append(server.accept()[0])
Antoine Pitroud2eca372010-10-29 23:41:37 +00001536 for sock in conns:
1537 sock.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001538
1539 t = threading.Thread(target=serve)
1540 t.start()
1541 started.wait()
1542
1543 try:
Antoine Pitrou40f08742010-04-24 22:04:40 +00001544 try:
1545 c = socket.socket(socket.AF_INET)
1546 c.settimeout(0.2)
1547 c.connect((host, port))
1548 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00001549 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00001550 ssl.wrap_socket, c)
Antoine Pitrou40f08742010-04-24 22:04:40 +00001551 finally:
1552 c.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001553 try:
1554 c = socket.socket(socket.AF_INET)
1555 c = ssl.wrap_socket(c)
1556 c.settimeout(0.2)
1557 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00001558 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00001559 c.connect, (host, port))
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001560 finally:
1561 c.close()
1562 finally:
1563 finish = True
1564 t.join()
1565 server.close()
1566
Bill Janssen58afe4c2008-09-08 16:45:19 +00001567
Thomas Woutersed03b412007-08-28 21:37:11 +00001568def test_main(verbose=False):
Antoine Pitrou15cee622010-08-04 16:45:21 +00001569 if support.verbose:
1570 plats = {
1571 'Linux': platform.linux_distribution,
1572 'Mac': platform.mac_ver,
1573 'Windows': platform.win32_ver,
1574 }
1575 for name, func in plats.items():
1576 plat = func()
1577 if plat and plat[0]:
1578 plat = '%s %r' % (name, plat)
1579 break
1580 else:
1581 plat = repr(platform.platform())
1582 print("test_ssl: testing with %r %r" %
1583 (ssl.OPENSSL_VERSION, ssl.OPENSSL_VERSION_INFO))
1584 print(" under %s" % plat)
Antoine Pitroud5323212010-10-22 18:19:07 +00001585 print(" HAS_SNI = %r" % ssl.HAS_SNI)
Antoine Pitrou15cee622010-08-04 16:45:21 +00001586
Antoine Pitrou152efa22010-05-16 18:19:27 +00001587 for filename in [
1588 CERTFILE, SVN_PYTHON_ORG_ROOT_CERT, BYTES_CERTFILE,
1589 ONLYCERT, ONLYKEY, BYTES_ONLYCERT, BYTES_ONLYKEY,
1590 BADCERT, BADKEY, EMPTYCERT]:
1591 if not os.path.exists(filename):
1592 raise support.TestFailed("Can't read certificate file %r" % filename)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001593
Antoine Pitrou152efa22010-05-16 18:19:27 +00001594 tests = [ContextTests, BasicSocketTests]
Thomas Woutersed03b412007-08-28 21:37:11 +00001595
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001596 if support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001597 tests.append(NetworkedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001598
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001599 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001600 thread_info = support.threading_setup()
1601 if thread_info and support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001602 tests.append(ThreadedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001603
Antoine Pitrou480a1242010-04-28 21:37:09 +00001604 try:
1605 support.run_unittest(*tests)
1606 finally:
1607 if _have_threads:
1608 support.threading_cleanup(*thread_info)
Thomas Woutersed03b412007-08-28 21:37:11 +00001609
1610if __name__ == "__main__":
1611 test_main()