blob: f65aceb057b9f67f2a3865580fde846490149048 [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 = [
Victor Stinner17ca3232011-05-10 00:48:41 +020024 ssl.PROTOCOL_SSLv3,
Antoine Pitrou05d936d2010-10-13 11:38:36 +000025 ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1
26]
Victor Stinner17ca3232011-05-10 00:48:41 +020027if hasattr(ssl, 'PROTOCOL_SSLv2'):
28 PROTOCOLS.append(ssl.PROTOCOL_SSLv2)
Thomas Woutersed03b412007-08-28 21:37:11 +000029
Benjamin Petersonee8712c2008-05-20 21:35:26 +000030HOST = support.HOST
Antoine Pitrou152efa22010-05-16 18:19:27 +000031
32data_file = lambda name: os.path.join(os.path.dirname(__file__), name)
Antoine Pitrou152efa22010-05-16 18:19:27 +000033
Antoine Pitrou81564092010-10-08 23:06:24 +000034# The custom key and certificate files used in test_ssl are generated
35# using Lib/test/make_ssl_certs.py.
36# Other certificates are simply fetched from the Internet servers they
37# are meant to authenticate.
38
Antoine Pitrou152efa22010-05-16 18:19:27 +000039CERTFILE = data_file("keycert.pem")
Victor Stinner313a1202010-06-11 23:56:51 +000040BYTES_CERTFILE = os.fsencode(CERTFILE)
Antoine Pitrou152efa22010-05-16 18:19:27 +000041ONLYCERT = data_file("ssl_cert.pem")
42ONLYKEY = data_file("ssl_key.pem")
Victor Stinner313a1202010-06-11 23:56:51 +000043BYTES_ONLYCERT = os.fsencode(ONLYCERT)
44BYTES_ONLYKEY = os.fsencode(ONLYKEY)
Antoine Pitrou152efa22010-05-16 18:19:27 +000045CAPATH = data_file("capath")
Victor Stinner313a1202010-06-11 23:56:51 +000046BYTES_CAPATH = os.fsencode(CAPATH)
Antoine Pitrou152efa22010-05-16 18:19:27 +000047
48SVN_PYTHON_ORG_ROOT_CERT = data_file("https_svn_python_org_root.pem")
49
50EMPTYCERT = data_file("nullcert.pem")
51BADCERT = data_file("badcert.pem")
52WRONGCERT = data_file("XXXnonexisting.pem")
53BADKEY = data_file("badkey.pem")
54
Thomas Woutersed03b412007-08-28 21:37:11 +000055
Thomas Woutersed03b412007-08-28 21:37:11 +000056def handle_error(prefix):
57 exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
Benjamin Petersonee8712c2008-05-20 21:35:26 +000058 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000059 sys.stdout.write(prefix + exc_format)
Thomas Woutersed03b412007-08-28 21:37:11 +000060
Antoine Pitroub5218772010-05-21 09:56:06 +000061def can_clear_options():
62 # 0.9.8m or higher
63 return ssl.OPENSSL_VERSION_INFO >= (0, 9, 8, 13, 15)
64
65def no_sslv2_implies_sslv3_hello():
66 # 0.9.7h or higher
67 return ssl.OPENSSL_VERSION_INFO >= (0, 9, 7, 8, 15)
68
Thomas Woutersed03b412007-08-28 21:37:11 +000069
Antoine Pitrou23df4832010-08-04 17:14:06 +000070# Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
71def skip_if_broken_ubuntu_ssl(func):
Victor Stinner17ca3232011-05-10 00:48:41 +020072 if hasattr(ssl, 'PROTOCOL_SSLv2'):
73 @functools.wraps(func)
74 def f(*args, **kwargs):
75 try:
76 ssl.SSLContext(ssl.PROTOCOL_SSLv2)
77 except ssl.SSLError:
78 if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
79 platform.linux_distribution() == ('debian', 'squeeze/sid', '')):
80 raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
81 return func(*args, **kwargs)
82 return f
83 else:
84 return func
Antoine Pitrou23df4832010-08-04 17:14:06 +000085
86
Antoine Pitrou152efa22010-05-16 18:19:27 +000087class BasicSocketTests(unittest.TestCase):
Thomas Woutersed03b412007-08-28 21:37:11 +000088
Antoine Pitrou480a1242010-04-28 21:37:09 +000089 def test_constants(self):
Victor Stinneree18b6f2011-05-10 00:38:00 +020090 #ssl.PROTOCOL_SSLv2
Thomas Wouters1b7f8912007-09-19 03:06:30 +000091 ssl.PROTOCOL_SSLv23
92 ssl.PROTOCOL_SSLv3
93 ssl.PROTOCOL_TLSv1
94 ssl.CERT_NONE
95 ssl.CERT_OPTIONAL
96 ssl.CERT_REQUIRED
Antoine Pitroud5323212010-10-22 18:19:07 +000097 self.assertIn(ssl.HAS_SNI, {True, False})
Thomas Woutersed03b412007-08-28 21:37:11 +000098
Antoine Pitrou480a1242010-04-28 21:37:09 +000099 def test_random(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000100 v = ssl.RAND_status()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000101 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000102 sys.stdout.write("\n RAND_status is %d (%s)\n"
103 % (v, (v and "sufficient randomness") or
104 "insufficient randomness"))
Thomas Woutersed03b412007-08-28 21:37:11 +0000105 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000106 ssl.RAND_egd(1)
107 except TypeError:
108 pass
Thomas Woutersed03b412007-08-28 21:37:11 +0000109 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000110 print("didn't raise TypeError")
111 ssl.RAND_add("this is a random string", 75.0)
Thomas Woutersed03b412007-08-28 21:37:11 +0000112
Antoine Pitrou480a1242010-04-28 21:37:09 +0000113 def test_parse_cert(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000114 # note that this uses an 'unofficial' function in _ssl.c,
115 # provided solely for this test, to exercise the certificate
116 # parsing code
Antoine Pitroufb046912010-11-09 20:21:19 +0000117 p = ssl._ssl._test_decode_cert(CERTFILE)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000118 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000119 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Thomas Woutersed03b412007-08-28 21:37:11 +0000120
Antoine Pitrou480a1242010-04-28 21:37:09 +0000121 def test_DER_to_PEM(self):
122 with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f:
123 pem = f.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000124 d1 = ssl.PEM_cert_to_DER_cert(pem)
125 p2 = ssl.DER_cert_to_PEM_cert(d1)
126 d2 = ssl.PEM_cert_to_DER_cert(p2)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000127 self.assertEqual(d1, d2)
Antoine Pitrou9bfbe612010-04-27 22:08:08 +0000128 if not p2.startswith(ssl.PEM_HEADER + '\n'):
129 self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2)
130 if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'):
131 self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000132
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000133 def test_openssl_version(self):
134 n = ssl.OPENSSL_VERSION_NUMBER
135 t = ssl.OPENSSL_VERSION_INFO
136 s = ssl.OPENSSL_VERSION
137 self.assertIsInstance(n, int)
138 self.assertIsInstance(t, tuple)
139 self.assertIsInstance(s, str)
140 # Some sanity checks follow
141 # >= 0.9
142 self.assertGreaterEqual(n, 0x900000)
143 # < 2.0
144 self.assertLess(n, 0x20000000)
145 major, minor, fix, patch, status = t
146 self.assertGreaterEqual(major, 0)
147 self.assertLess(major, 2)
148 self.assertGreaterEqual(minor, 0)
149 self.assertLess(minor, 256)
150 self.assertGreaterEqual(fix, 0)
151 self.assertLess(fix, 256)
152 self.assertGreaterEqual(patch, 0)
153 self.assertLessEqual(patch, 26)
154 self.assertGreaterEqual(status, 0)
155 self.assertLessEqual(status, 15)
156 # Version string as returned by OpenSSL, the format might change
157 self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
158 (s, t))
159
Antoine Pitrou9d543662010-04-23 23:10:32 +0000160 @support.cpython_only
161 def test_refcycle(self):
162 # Issue #7943: an SSL object doesn't create reference cycles with
163 # itself.
164 s = socket.socket(socket.AF_INET)
165 ss = ssl.wrap_socket(s)
166 wr = weakref.ref(ss)
167 del ss
168 self.assertEqual(wr(), None)
169
Antoine Pitroua468adc2010-09-14 14:43:44 +0000170 def test_wrapped_unconnected(self):
171 # Methods on an unconnected SSLSocket propagate the original
172 # socket.error raise by the underlying socket object.
173 s = socket.socket(socket.AF_INET)
174 ss = ssl.wrap_socket(s)
175 self.assertRaises(socket.error, ss.recv, 1)
176 self.assertRaises(socket.error, ss.recv_into, bytearray(b'x'))
177 self.assertRaises(socket.error, ss.recvfrom, 1)
178 self.assertRaises(socket.error, ss.recvfrom_into, bytearray(b'x'), 1)
179 self.assertRaises(socket.error, ss.send, b'x')
180 self.assertRaises(socket.error, ss.sendto, b'x', ('0.0.0.0', 0))
181
Antoine Pitrou40f08742010-04-24 22:04:40 +0000182 def test_timeout(self):
183 # Issue #8524: when creating an SSL socket, the timeout of the
184 # original socket should be retained.
185 for timeout in (None, 0.0, 5.0):
186 s = socket.socket(socket.AF_INET)
187 s.settimeout(timeout)
188 ss = ssl.wrap_socket(s)
189 self.assertEqual(timeout, ss.gettimeout())
190
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000191 def test_errors(self):
192 sock = socket.socket()
Ezio Melottied3a7d22010-12-01 02:32:32 +0000193 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000194 "certfile must be specified",
195 ssl.wrap_socket, sock, keyfile=CERTFILE)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000196 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000197 "certfile must be specified for server-side operations",
198 ssl.wrap_socket, sock, server_side=True)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000199 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000200 "certfile must be specified for server-side operations",
201 ssl.wrap_socket, sock, server_side=True, certfile="")
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000202 s = ssl.wrap_socket(sock, server_side=True, certfile=CERTFILE)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000203 self.assertRaisesRegex(ValueError, "can't connect in server-side mode",
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000204 s.connect, (HOST, 8080))
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000205 with self.assertRaises(IOError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000206 with socket.socket() as sock:
207 ssl.wrap_socket(sock, certfile=WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000208 self.assertEqual(cm.exception.errno, errno.ENOENT)
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000209 with self.assertRaises(IOError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000210 with socket.socket() as sock:
211 ssl.wrap_socket(sock, certfile=CERTFILE, keyfile=WRONGCERT)
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000212 self.assertEqual(cm.exception.errno, errno.ENOENT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000213 with self.assertRaises(IOError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000214 with socket.socket() as sock:
215 ssl.wrap_socket(sock, certfile=WRONGCERT, keyfile=WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000216 self.assertEqual(cm.exception.errno, errno.ENOENT)
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000217
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000218 def test_match_hostname(self):
219 def ok(cert, hostname):
220 ssl.match_hostname(cert, hostname)
221 def fail(cert, hostname):
222 self.assertRaises(ssl.CertificateError,
223 ssl.match_hostname, cert, hostname)
224
225 cert = {'subject': ((('commonName', 'example.com'),),)}
226 ok(cert, 'example.com')
227 ok(cert, 'ExAmple.cOm')
228 fail(cert, 'www.example.com')
229 fail(cert, '.example.com')
230 fail(cert, 'example.org')
231 fail(cert, 'exampleXcom')
232
233 cert = {'subject': ((('commonName', '*.a.com'),),)}
234 ok(cert, 'foo.a.com')
235 fail(cert, 'bar.foo.a.com')
236 fail(cert, 'a.com')
237 fail(cert, 'Xa.com')
238 fail(cert, '.a.com')
239
240 cert = {'subject': ((('commonName', 'a.*.com'),),)}
241 ok(cert, 'a.foo.com')
242 fail(cert, 'a..com')
243 fail(cert, 'a.com')
244
245 cert = {'subject': ((('commonName', 'f*.com'),),)}
246 ok(cert, 'foo.com')
247 ok(cert, 'f.com')
248 fail(cert, 'bar.com')
249 fail(cert, 'foo.a.com')
250 fail(cert, 'bar.foo.com')
251
252 # Slightly fake real-world example
253 cert = {'notAfter': 'Jun 26 21:41:46 2011 GMT',
254 'subject': ((('commonName', 'linuxfrz.org'),),),
255 'subjectAltName': (('DNS', 'linuxfr.org'),
256 ('DNS', 'linuxfr.com'),
257 ('othername', '<unsupported>'))}
258 ok(cert, 'linuxfr.org')
259 ok(cert, 'linuxfr.com')
260 # Not a "DNS" entry
261 fail(cert, '<unsupported>')
262 # When there is a subjectAltName, commonName isn't used
263 fail(cert, 'linuxfrz.org')
264
265 # A pristine real-world example
266 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
267 'subject': ((('countryName', 'US'),),
268 (('stateOrProvinceName', 'California'),),
269 (('localityName', 'Mountain View'),),
270 (('organizationName', 'Google Inc'),),
271 (('commonName', 'mail.google.com'),))}
272 ok(cert, 'mail.google.com')
273 fail(cert, 'gmail.com')
274 # Only commonName is considered
275 fail(cert, 'California')
276
277 # Neither commonName nor subjectAltName
278 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
279 'subject': ((('countryName', 'US'),),
280 (('stateOrProvinceName', 'California'),),
281 (('localityName', 'Mountain View'),),
282 (('organizationName', 'Google Inc'),))}
283 fail(cert, 'mail.google.com')
284
Antoine Pitrou1c86b442011-05-06 15:19:49 +0200285 # No DNS entry in subjectAltName but a commonName
286 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
287 'subject': ((('countryName', 'US'),),
288 (('stateOrProvinceName', 'California'),),
289 (('localityName', 'Mountain View'),),
290 (('commonName', 'mail.google.com'),)),
291 'subjectAltName': (('othername', 'blabla'), )}
292 ok(cert, 'mail.google.com')
293
294 # No DNS entry subjectAltName and no commonName
295 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
296 'subject': ((('countryName', 'US'),),
297 (('stateOrProvinceName', 'California'),),
298 (('localityName', 'Mountain View'),),
299 (('organizationName', 'Google Inc'),)),
300 'subjectAltName': (('othername', 'blabla'),)}
301 fail(cert, 'google.com')
302
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000303 # Empty cert / no cert
304 self.assertRaises(ValueError, ssl.match_hostname, None, 'example.com')
305 self.assertRaises(ValueError, ssl.match_hostname, {}, 'example.com')
306
Antoine Pitroud5323212010-10-22 18:19:07 +0000307 def test_server_side(self):
308 # server_hostname doesn't work for server sockets
309 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
Antoine Pitroud2eca372010-10-29 23:41:37 +0000310 with socket.socket() as sock:
311 self.assertRaises(ValueError, ctx.wrap_socket, sock, True,
312 server_hostname="some.hostname")
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000313
Antoine Pitrou152efa22010-05-16 18:19:27 +0000314class ContextTests(unittest.TestCase):
315
Antoine Pitrou23df4832010-08-04 17:14:06 +0000316 @skip_if_broken_ubuntu_ssl
Antoine Pitrou152efa22010-05-16 18:19:27 +0000317 def test_constructor(self):
Victor Stinner17ca3232011-05-10 00:48:41 +0200318 if hasattr(ssl, 'PROTOCOL_SSLv2'):
319 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv2)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000320 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
321 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv3)
322 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
323 self.assertRaises(TypeError, ssl.SSLContext)
324 self.assertRaises(ValueError, ssl.SSLContext, -1)
325 self.assertRaises(ValueError, ssl.SSLContext, 42)
326
Antoine Pitrou23df4832010-08-04 17:14:06 +0000327 @skip_if_broken_ubuntu_ssl
Antoine Pitrou152efa22010-05-16 18:19:27 +0000328 def test_protocol(self):
329 for proto in PROTOCOLS:
330 ctx = ssl.SSLContext(proto)
331 self.assertEqual(ctx.protocol, proto)
332
333 def test_ciphers(self):
334 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
335 ctx.set_ciphers("ALL")
336 ctx.set_ciphers("DEFAULT")
Ezio Melottied3a7d22010-12-01 02:32:32 +0000337 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
Antoine Pitrou30474062010-05-16 23:46:26 +0000338 ctx.set_ciphers("^$:,;?*'dorothyx")
Antoine Pitrou152efa22010-05-16 18:19:27 +0000339
Antoine Pitrou23df4832010-08-04 17:14:06 +0000340 @skip_if_broken_ubuntu_ssl
Antoine Pitroub5218772010-05-21 09:56:06 +0000341 def test_options(self):
342 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
343 # OP_ALL is the default value
344 self.assertEqual(ssl.OP_ALL, ctx.options)
345 ctx.options |= ssl.OP_NO_SSLv2
346 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2,
347 ctx.options)
348 ctx.options |= ssl.OP_NO_SSLv3
349 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3,
350 ctx.options)
351 if can_clear_options():
352 ctx.options = (ctx.options & ~ssl.OP_NO_SSLv2) | ssl.OP_NO_TLSv1
353 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_TLSv1 | ssl.OP_NO_SSLv3,
354 ctx.options)
355 ctx.options = 0
356 self.assertEqual(0, ctx.options)
357 else:
358 with self.assertRaises(ValueError):
359 ctx.options = 0
360
Antoine Pitrou152efa22010-05-16 18:19:27 +0000361 def test_verify(self):
362 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
363 # Default value
364 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
365 ctx.verify_mode = ssl.CERT_OPTIONAL
366 self.assertEqual(ctx.verify_mode, ssl.CERT_OPTIONAL)
367 ctx.verify_mode = ssl.CERT_REQUIRED
368 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
369 ctx.verify_mode = ssl.CERT_NONE
370 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
371 with self.assertRaises(TypeError):
372 ctx.verify_mode = None
373 with self.assertRaises(ValueError):
374 ctx.verify_mode = 42
375
376 def test_load_cert_chain(self):
377 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
378 # Combined key and cert in a single file
379 ctx.load_cert_chain(CERTFILE)
380 ctx.load_cert_chain(CERTFILE, keyfile=CERTFILE)
381 self.assertRaises(TypeError, ctx.load_cert_chain, keyfile=CERTFILE)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000382 with self.assertRaises(IOError) as cm:
Antoine Pitrou152efa22010-05-16 18:19:27 +0000383 ctx.load_cert_chain(WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000384 self.assertEqual(cm.exception.errno, errno.ENOENT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000385 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000386 ctx.load_cert_chain(BADCERT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000387 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000388 ctx.load_cert_chain(EMPTYCERT)
389 # Separate key and cert
Antoine Pitroud0919502010-05-17 10:30:00 +0000390 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000391 ctx.load_cert_chain(ONLYCERT, ONLYKEY)
392 ctx.load_cert_chain(certfile=ONLYCERT, keyfile=ONLYKEY)
393 ctx.load_cert_chain(certfile=BYTES_ONLYCERT, keyfile=BYTES_ONLYKEY)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000394 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000395 ctx.load_cert_chain(ONLYCERT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000396 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000397 ctx.load_cert_chain(ONLYKEY)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000398 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000399 ctx.load_cert_chain(certfile=ONLYKEY, keyfile=ONLYCERT)
400 # Mismatching key and cert
Antoine Pitroud0919502010-05-17 10:30:00 +0000401 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000402 with self.assertRaisesRegex(ssl.SSLError, "key values mismatch"):
Antoine Pitrou81564092010-10-08 23:06:24 +0000403 ctx.load_cert_chain(SVN_PYTHON_ORG_ROOT_CERT, ONLYKEY)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000404
405 def test_load_verify_locations(self):
406 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
407 ctx.load_verify_locations(CERTFILE)
408 ctx.load_verify_locations(cafile=CERTFILE, capath=None)
409 ctx.load_verify_locations(BYTES_CERTFILE)
410 ctx.load_verify_locations(cafile=BYTES_CERTFILE, capath=None)
411 self.assertRaises(TypeError, ctx.load_verify_locations)
412 self.assertRaises(TypeError, ctx.load_verify_locations, None, None)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000413 with self.assertRaises(IOError) as cm:
Antoine Pitrou152efa22010-05-16 18:19:27 +0000414 ctx.load_verify_locations(WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000415 self.assertEqual(cm.exception.errno, errno.ENOENT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000416 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000417 ctx.load_verify_locations(BADCERT)
418 ctx.load_verify_locations(CERTFILE, CAPATH)
419 ctx.load_verify_locations(CERTFILE, capath=BYTES_CAPATH)
420
Victor Stinner80f75e62011-01-29 11:31:20 +0000421 # Issue #10989: crash if the second argument type is invalid
422 self.assertRaises(TypeError, ctx.load_verify_locations, None, True)
423
Antoine Pitroueb585ad2010-10-22 18:24:20 +0000424 @skip_if_broken_ubuntu_ssl
Antoine Pitroub0182c82010-10-12 20:09:02 +0000425 def test_session_stats(self):
426 for proto in PROTOCOLS:
427 ctx = ssl.SSLContext(proto)
428 self.assertEqual(ctx.session_stats(), {
429 'number': 0,
430 'connect': 0,
431 'connect_good': 0,
432 'connect_renegotiate': 0,
433 'accept': 0,
434 'accept_good': 0,
435 'accept_renegotiate': 0,
436 'hits': 0,
437 'misses': 0,
438 'timeouts': 0,
439 'cache_full': 0,
440 })
441
Antoine Pitrou664c2d12010-11-17 20:29:42 +0000442 def test_set_default_verify_paths(self):
443 # There's not much we can do to test that it acts as expected,
444 # so just check it doesn't crash or raise an exception.
445 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
446 ctx.set_default_verify_paths()
447
Antoine Pitrou152efa22010-05-16 18:19:27 +0000448
Bill Janssen6e027db2007-11-15 22:23:56 +0000449class NetworkedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000450
Antoine Pitrou480a1242010-04-28 21:37:09 +0000451 def test_connect(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000452 with support.transient_internet("svn.python.org"):
453 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
454 cert_reqs=ssl.CERT_NONE)
455 try:
456 s.connect(("svn.python.org", 443))
457 self.assertEqual({}, s.getpeercert())
458 finally:
459 s.close()
460
461 # this should fail because we have no verification certs
462 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
463 cert_reqs=ssl.CERT_REQUIRED)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000464 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
465 s.connect, ("svn.python.org", 443))
Antoine Pitrou152efa22010-05-16 18:19:27 +0000466 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000467
Antoine Pitrou350c7222010-09-09 13:31:46 +0000468 # this should succeed because we specify the root cert
469 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
470 cert_reqs=ssl.CERT_REQUIRED,
471 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
472 try:
473 s.connect(("svn.python.org", 443))
474 self.assertTrue(s.getpeercert())
475 finally:
476 s.close()
Antoine Pitrou152efa22010-05-16 18:19:27 +0000477
Antoine Pitrou86cbfec2011-02-26 23:25:34 +0000478 def test_connect_ex(self):
479 # Issue #11326: check connect_ex() implementation
480 with support.transient_internet("svn.python.org"):
481 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
482 cert_reqs=ssl.CERT_REQUIRED,
483 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
484 try:
485 self.assertEqual(0, s.connect_ex(("svn.python.org", 443)))
486 self.assertTrue(s.getpeercert())
487 finally:
488 s.close()
489
490 def test_non_blocking_connect_ex(self):
491 # Issue #11326: non-blocking connect_ex() should allow handshake
492 # to proceed after the socket gets ready.
493 with support.transient_internet("svn.python.org"):
494 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
495 cert_reqs=ssl.CERT_REQUIRED,
496 ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
497 do_handshake_on_connect=False)
498 try:
499 s.setblocking(False)
500 rc = s.connect_ex(('svn.python.org', 443))
Antoine Pitroud1c98452011-02-27 15:45:16 +0000501 # EWOULDBLOCK under Windows, EINPROGRESS elsewhere
502 self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK))
Antoine Pitrou86cbfec2011-02-26 23:25:34 +0000503 # Wait for connect to finish
504 select.select([], [s], [], 5.0)
505 # Non-blocking handshake
506 while True:
507 try:
508 s.do_handshake()
509 break
510 except ssl.SSLError as err:
511 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
512 select.select([s], [], [], 5.0)
513 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
514 select.select([], [s], [], 5.0)
515 else:
516 raise
517 # SSL established
518 self.assertTrue(s.getpeercert())
519 finally:
520 s.close()
521
Antoine Pitrou152efa22010-05-16 18:19:27 +0000522 def test_connect_with_context(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000523 with support.transient_internet("svn.python.org"):
524 # Same as test_connect, but with a separately created context
525 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
526 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
527 s.connect(("svn.python.org", 443))
528 try:
529 self.assertEqual({}, s.getpeercert())
530 finally:
531 s.close()
Antoine Pitroud5323212010-10-22 18:19:07 +0000532 # Same with a server hostname
533 s = ctx.wrap_socket(socket.socket(socket.AF_INET),
534 server_hostname="svn.python.org")
535 if ssl.HAS_SNI:
536 s.connect(("svn.python.org", 443))
537 s.close()
538 else:
539 self.assertRaises(ValueError, s.connect, ("svn.python.org", 443))
Antoine Pitrou350c7222010-09-09 13:31:46 +0000540 # This should fail because we have no verification certs
541 ctx.verify_mode = ssl.CERT_REQUIRED
542 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
Ezio Melottied3a7d22010-12-01 02:32:32 +0000543 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
Antoine Pitrou350c7222010-09-09 13:31:46 +0000544 s.connect, ("svn.python.org", 443))
Antoine Pitrou152efa22010-05-16 18:19:27 +0000545 s.close()
Antoine Pitrou350c7222010-09-09 13:31:46 +0000546 # This should succeed because we specify the root cert
547 ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
548 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
549 s.connect(("svn.python.org", 443))
550 try:
551 cert = s.getpeercert()
552 self.assertTrue(cert)
553 finally:
554 s.close()
Antoine Pitrou152efa22010-05-16 18:19:27 +0000555
556 def test_connect_capath(self):
557 # Verify server certificates using the `capath` argument
Antoine Pitrou467f28d2010-05-16 19:22:44 +0000558 # NOTE: the subject hashing algorithm has been changed between
559 # OpenSSL 0.9.8n and 1.0.0, as a result the capath directory must
560 # contain both versions of each certificate (same content, different
Antoine Pitroud7e4c1c2010-05-17 14:13:10 +0000561 # filename) for this test to be portable across OpenSSL releases.
Antoine Pitrou350c7222010-09-09 13:31:46 +0000562 with support.transient_internet("svn.python.org"):
563 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
564 ctx.verify_mode = ssl.CERT_REQUIRED
565 ctx.load_verify_locations(capath=CAPATH)
566 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
567 s.connect(("svn.python.org", 443))
568 try:
569 cert = s.getpeercert()
570 self.assertTrue(cert)
571 finally:
572 s.close()
573 # Same with a bytes `capath` argument
574 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
575 ctx.verify_mode = ssl.CERT_REQUIRED
576 ctx.load_verify_locations(capath=BYTES_CAPATH)
577 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
578 s.connect(("svn.python.org", 443))
579 try:
580 cert = s.getpeercert()
581 self.assertTrue(cert)
582 finally:
583 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000584
Antoine Pitroue3220242010-04-24 11:13:53 +0000585 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
586 def test_makefile_close(self):
587 # Issue #5238: creating a file-like object with makefile() shouldn't
588 # delay closing the underlying "real socket" (here tested with its
589 # file descriptor, hence skipping the test under Windows).
Antoine Pitrou350c7222010-09-09 13:31:46 +0000590 with support.transient_internet("svn.python.org"):
591 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
592 ss.connect(("svn.python.org", 443))
593 fd = ss.fileno()
594 f = ss.makefile()
595 f.close()
596 # The fd is still open
Antoine Pitroue3220242010-04-24 11:13:53 +0000597 os.read(fd, 0)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000598 # Closing the SSL socket should close the fd too
599 ss.close()
600 gc.collect()
601 with self.assertRaises(OSError) as e:
602 os.read(fd, 0)
603 self.assertEqual(e.exception.errno, errno.EBADF)
Antoine Pitroue3220242010-04-24 11:13:53 +0000604
Antoine Pitrou480a1242010-04-28 21:37:09 +0000605 def test_non_blocking_handshake(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000606 with support.transient_internet("svn.python.org"):
607 s = socket.socket(socket.AF_INET)
608 s.connect(("svn.python.org", 443))
609 s.setblocking(False)
610 s = ssl.wrap_socket(s,
611 cert_reqs=ssl.CERT_NONE,
612 do_handshake_on_connect=False)
613 count = 0
614 while True:
615 try:
616 count += 1
617 s.do_handshake()
618 break
619 except ssl.SSLError as err:
620 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
621 select.select([s], [], [])
622 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
623 select.select([], [s], [])
624 else:
625 raise
626 s.close()
627 if support.verbose:
628 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000629
Antoine Pitrou480a1242010-04-28 21:37:09 +0000630 def test_get_server_certificate(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000631 with support.transient_internet("svn.python.org"):
632 pem = ssl.get_server_certificate(("svn.python.org", 443))
633 if not pem:
634 self.fail("No server certificate on svn.python.org:443!")
Bill Janssen54cc54c2007-12-14 22:08:56 +0000635
Antoine Pitrou350c7222010-09-09 13:31:46 +0000636 try:
637 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
638 except ssl.SSLError as x:
639 #should fail
640 if support.verbose:
641 sys.stdout.write("%s\n" % x)
642 else:
643 self.fail("Got server certificate %s for svn.python.org!" % pem)
644
645 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
646 if not pem:
647 self.fail("No server certificate on svn.python.org:443!")
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000648 if support.verbose:
Antoine Pitrou350c7222010-09-09 13:31:46 +0000649 sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000650
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000651 def test_ciphers(self):
652 remote = ("svn.python.org", 443)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000653 with support.transient_internet(remote[0]):
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000654 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
Antoine Pitrou350c7222010-09-09 13:31:46 +0000655 cert_reqs=ssl.CERT_NONE, ciphers="ALL")
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000656 s.connect(remote)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000657 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
658 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")
659 s.connect(remote)
660 # Error checking can happen at instantiation or when connecting
Ezio Melottied3a7d22010-12-01 02:32:32 +0000661 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
Antoine Pitroud2eca372010-10-29 23:41:37 +0000662 with socket.socket(socket.AF_INET) as sock:
663 s = ssl.wrap_socket(sock,
664 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
665 s.connect(remote)
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000666
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000667 def test_algorithms(self):
668 # Issue #8484: all algorithms should be available when verifying a
669 # certificate.
Antoine Pitrou29619b22010-04-22 18:43:31 +0000670 # SHA256 was added in OpenSSL 0.9.8
671 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
672 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Victor Stinnerf332abb2011-01-08 03:16:05 +0000673 # https://sha2.hboeck.de/ was used until 2011-01-08 (no route to host)
674 remote = ("sha256.tbs-internet.com", 443)
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000675 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
Antoine Pitrou160fd932011-01-08 10:23:29 +0000676 with support.transient_internet("sha256.tbs-internet.com"):
Antoine Pitroua88c83c2010-09-07 20:42:19 +0000677 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
678 cert_reqs=ssl.CERT_REQUIRED,
679 ca_certs=sha256_cert,)
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000680 try:
681 s.connect(remote)
682 if support.verbose:
683 sys.stdout.write("\nCipher with %r is %r\n" %
684 (remote, s.cipher()))
685 sys.stdout.write("Certificate is:\n%s\n" %
686 pprint.pformat(s.getpeercert()))
687 finally:
688 s.close()
689
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000690
691try:
692 import threading
693except ImportError:
694 _have_threads = False
695else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000696 _have_threads = True
697
Antoine Pitrou803e6d62010-10-13 10:36:15 +0000698 from test.ssl_servers import make_https_server
699
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000700 class ThreadedEchoServer(threading.Thread):
701
702 class ConnectionHandler(threading.Thread):
703
704 """A mildly complicated class, because we want it to work both
705 with and without the SSL wrapper around the socket connection, so
706 that we can test the STARTTLS functionality."""
707
Bill Janssen6e027db2007-11-15 22:23:56 +0000708 def __init__(self, server, connsock, addr):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000709 self.server = server
710 self.running = False
711 self.sock = connsock
Bill Janssen6e027db2007-11-15 22:23:56 +0000712 self.addr = addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000713 self.sock.setblocking(1)
714 self.sslconn = None
715 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000716 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000717
Antoine Pitrou480a1242010-04-28 21:37:09 +0000718 def wrap_conn(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000719 try:
Antoine Pitroub5218772010-05-21 09:56:06 +0000720 self.sslconn = self.server.context.wrap_socket(
721 self.sock, server_side=True)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000722 except ssl.SSLError:
723 # XXX Various errors can have happened here, for example
724 # a mismatching protocol version, an invalid certificate,
725 # or a low-level bug. This should be made more discriminating.
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000726 if self.server.chatty:
Bill Janssen6e027db2007-11-15 22:23:56 +0000727 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000728 self.running = False
729 self.server.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000730 self.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000731 return False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000732 else:
Antoine Pitroub5218772010-05-21 09:56:06 +0000733 if self.server.context.verify_mode == ssl.CERT_REQUIRED:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000734 cert = self.sslconn.getpeercert()
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(" client cert is " + pprint.pformat(cert) + "\n")
737 cert_binary = self.sslconn.getpeercert(True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000738 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000739 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
740 cipher = self.sslconn.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000741 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000742 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
743 return True
744
745 def read(self):
746 if self.sslconn:
747 return self.sslconn.read()
748 else:
749 return self.sock.recv(1024)
750
751 def write(self, bytes):
752 if self.sslconn:
753 return self.sslconn.write(bytes)
754 else:
755 return self.sock.send(bytes)
756
757 def close(self):
758 if self.sslconn:
759 self.sslconn.close()
760 else:
761 self.sock.close()
762
Antoine Pitrou480a1242010-04-28 21:37:09 +0000763 def run(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000764 self.running = True
765 if not self.server.starttls_server:
766 if not self.wrap_conn():
767 return
768 while self.running:
769 try:
770 msg = self.read()
Antoine Pitrou480a1242010-04-28 21:37:09 +0000771 stripped = msg.strip()
772 if not stripped:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000773 # eof, so quit this handler
774 self.running = False
775 self.close()
Antoine Pitrou480a1242010-04-28 21:37:09 +0000776 elif stripped == b'over':
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: client closed connection\n")
779 self.close()
780 return
Bill Janssen6e027db2007-11-15 22:23:56 +0000781 elif (self.server.starttls_server and
Antoine Pitrou764b8782010-04-28 22:57:15 +0000782 stripped == b'STARTTLS'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000783 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000784 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000785 self.write(b"OK\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000786 if not self.wrap_conn():
787 return
Bill Janssen40a0f662008-08-12 16:56:25 +0000788 elif (self.server.starttls_server and self.sslconn
Antoine Pitrou764b8782010-04-28 22:57:15 +0000789 and stripped == b'ENDTLS'):
Bill Janssen40a0f662008-08-12 16:56:25 +0000790 if support.verbose and self.server.connectionchatty:
791 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000792 self.write(b"OK\n")
Bill Janssen40a0f662008-08-12 16:56:25 +0000793 self.sock = self.sslconn.unwrap()
794 self.sslconn = None
795 if support.verbose and self.server.connectionchatty:
796 sys.stdout.write(" server: connection is now unencrypted...\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000797 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000798 if (support.verbose and
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000799 self.server.connectionchatty):
800 ctype = (self.sslconn and "encrypted") or "unencrypted"
Antoine Pitrou480a1242010-04-28 21:37:09 +0000801 sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
802 % (msg, ctype, msg.lower(), ctype))
803 self.write(msg.lower())
Bill Janssen6e027db2007-11-15 22:23:56 +0000804 except socket.error:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000805 if self.server.chatty:
806 handle_error("Test server failure:\n")
807 self.close()
808 self.running = False
809 # normally, we'd just stop here, but for the test
810 # harness, we want to stop the server
811 self.server.stop()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000812
Antoine Pitroub5218772010-05-21 09:56:06 +0000813 def __init__(self, certificate=None, ssl_version=None,
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000814 certreqs=None, cacerts=None,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000815 chatty=True, connectionchatty=False, starttls_server=False,
Antoine Pitroub5218772010-05-21 09:56:06 +0000816 ciphers=None, context=None):
817 if context:
818 self.context = context
819 else:
820 self.context = ssl.SSLContext(ssl_version
821 if ssl_version is not None
822 else ssl.PROTOCOL_TLSv1)
823 self.context.verify_mode = (certreqs if certreqs is not None
824 else ssl.CERT_NONE)
825 if cacerts:
826 self.context.load_verify_locations(cacerts)
827 if certificate:
828 self.context.load_cert_chain(certificate)
829 if ciphers:
830 self.context.set_ciphers(ciphers)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000831 self.chatty = chatty
832 self.connectionchatty = connectionchatty
833 self.starttls_server = starttls_server
834 self.sock = socket.socket()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000835 self.port = support.bind_port(self.sock)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000836 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000837 self.active = False
838 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000839 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000840
Antoine Pitrou480a1242010-04-28 21:37:09 +0000841 def start(self, flag=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000842 self.flag = flag
843 threading.Thread.start(self)
844
Antoine Pitrou480a1242010-04-28 21:37:09 +0000845 def run(self):
Antoine Pitrouaf7c6022010-04-27 09:56:02 +0000846 self.sock.settimeout(0.05)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000847 self.sock.listen(5)
848 self.active = True
849 if self.flag:
850 # signal an event
851 self.flag.set()
852 while self.active:
853 try:
854 newconn, connaddr = self.sock.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000855 if support.verbose and self.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000856 sys.stdout.write(' server: new connection from '
Bill Janssen6e027db2007-11-15 22:23:56 +0000857 + repr(connaddr) + '\n')
858 handler = self.ConnectionHandler(self, newconn, connaddr)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000859 handler.start()
860 except socket.timeout:
861 pass
862 except KeyboardInterrupt:
863 self.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000864 self.sock.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000865
Antoine Pitrou480a1242010-04-28 21:37:09 +0000866 def stop(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000867 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000868
Bill Janssen54cc54c2007-12-14 22:08:56 +0000869 class AsyncoreEchoServer(threading.Thread):
870
871 # this one's based on asyncore.dispatcher
872
873 class EchoServer (asyncore.dispatcher):
874
875 class ConnectionHandler (asyncore.dispatcher_with_send):
876
877 def __init__(self, conn, certfile):
878 self.socket = ssl.wrap_socket(conn, server_side=True,
879 certfile=certfile,
880 do_handshake_on_connect=False)
881 asyncore.dispatcher_with_send.__init__(self, self.socket)
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000882 self._ssl_accepting = True
883 self._do_ssl_handshake()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000884
885 def readable(self):
886 if isinstance(self.socket, ssl.SSLSocket):
887 while self.socket.pending() > 0:
888 self.handle_read_event()
889 return True
890
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000891 def _do_ssl_handshake(self):
892 try:
893 self.socket.do_handshake()
894 except ssl.SSLError as err:
895 if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
896 ssl.SSL_ERROR_WANT_WRITE):
897 return
898 elif err.args[0] == ssl.SSL_ERROR_EOF:
899 return self.handle_close()
900 raise
901 except socket.error as err:
902 if err.args[0] == errno.ECONNABORTED:
903 return self.handle_close()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000904 else:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000905 self._ssl_accepting = False
906
907 def handle_read(self):
908 if self._ssl_accepting:
909 self._do_ssl_handshake()
910 else:
911 data = self.recv(1024)
912 if support.verbose:
913 sys.stdout.write(" server: read %s from client\n" % repr(data))
914 if not data:
915 self.close()
916 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000917 self.send(data.lower())
Bill Janssen54cc54c2007-12-14 22:08:56 +0000918
919 def handle_close(self):
Bill Janssen2f5799b2008-06-29 00:08:12 +0000920 self.close()
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000921 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000922 sys.stdout.write(" server: closed connection %s\n" % self.socket)
923
924 def handle_error(self):
925 raise
926
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000927 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000928 self.certfile = certfile
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000929 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
930 self.port = support.bind_port(sock, '')
931 asyncore.dispatcher.__init__(self, sock)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000932 self.listen(5)
933
Giampaolo Rodolà977c7072010-10-04 21:08:36 +0000934 def handle_accepted(self, sock_obj, addr):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000935 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000936 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
937 self.ConnectionHandler(sock_obj, self.certfile)
938
939 def handle_error(self):
940 raise
941
Trent Nelson78520002008-04-10 20:54:35 +0000942 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000943 self.flag = None
944 self.active = False
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000945 self.server = self.EchoServer(certfile)
946 self.port = self.server.port
Bill Janssen54cc54c2007-12-14 22:08:56 +0000947 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000948 self.daemon = True
Bill Janssen54cc54c2007-12-14 22:08:56 +0000949
950 def __str__(self):
951 return "<%s %s>" % (self.__class__.__name__, self.server)
952
953 def start (self, flag=None):
954 self.flag = flag
955 threading.Thread.start(self)
956
Antoine Pitrou480a1242010-04-28 21:37:09 +0000957 def run(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000958 self.active = True
959 if self.flag:
960 self.flag.set()
961 while self.active:
962 try:
963 asyncore.loop(1)
964 except:
965 pass
966
Antoine Pitrou480a1242010-04-28 21:37:09 +0000967 def stop(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000968 self.active = False
969 self.server.close()
970
Antoine Pitrou480a1242010-04-28 21:37:09 +0000971 def bad_cert_test(certfile):
972 """
973 Launch a server with CERT_REQUIRED, and check that trying to
974 connect to it with the given client certificate fails.
975 """
Trent Nelson78520002008-04-10 20:54:35 +0000976 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000977 certreqs=ssl.CERT_REQUIRED,
Bill Janssen6e027db2007-11-15 22:23:56 +0000978 cacerts=CERTFILE, chatty=False,
979 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000980 flag = threading.Event()
981 server.start(flag)
982 # wait for it to start
983 flag.wait()
984 # try to connect
985 try:
Thomas Woutersed03b412007-08-28 21:37:11 +0000986 try:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000987 with socket.socket() as sock:
988 s = ssl.wrap_socket(sock,
989 certfile=certfile,
990 ssl_version=ssl.PROTOCOL_TLSv1)
991 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000992 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000993 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000994 sys.stdout.write("\nSSLError is %s\n" % x.args[1])
Antoine Pitrou05830aa2010-04-27 13:15:18 +0000995 except socket.error as x:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000996 if support.verbose:
Georg Brandlb75b6392010-10-24 14:20:22 +0000997 sys.stdout.write("\nsocket.error is %s\n" % x.args[1])
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000998 except IOError as x:
Giampaolo Rodolàcd9dfb92010-08-29 20:56:56 +0000999 if x.errno != errno.ENOENT:
1000 raise
Giampaolo Rodolà745ab382010-08-29 19:25:49 +00001001 if support.verbose:
Giampaolo Rodolàcd9dfb92010-08-29 20:56:56 +00001002 sys.stdout.write("\IOError is %s\n" % str(x))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001003 else:
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001004 raise AssertionError("Use of invalid cert should have failed!")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001005 finally:
1006 server.stop()
1007 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +00001008
Antoine Pitroub5218772010-05-21 09:56:06 +00001009 def server_params_test(client_context, server_context, indata=b"FOO\n",
1010 chatty=True, connectionchatty=False):
Antoine Pitrou480a1242010-04-28 21:37:09 +00001011 """
1012 Launch a server, connect a client to it and try various reads
1013 and writes.
1014 """
Antoine Pitroub5218772010-05-21 09:56:06 +00001015 server = ThreadedEchoServer(context=server_context,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001016 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +00001017 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001018 flag = threading.Event()
1019 server.start(flag)
1020 # wait for it to start
1021 flag.wait()
1022 # try to connect
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001023 try:
Antoine Pitroub5218772010-05-21 09:56:06 +00001024 s = client_context.wrap_socket(socket.socket())
Trent Nelson78520002008-04-10 20:54:35 +00001025 s.connect((HOST, server.port))
Antoine Pitrou480a1242010-04-28 21:37:09 +00001026 for arg in [indata, bytearray(indata), memoryview(indata)]:
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00001027 if connectionchatty:
1028 if support.verbose:
1029 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001030 " client: sending %r...\n" % indata)
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00001031 s.write(arg)
1032 outdata = s.read()
1033 if connectionchatty:
1034 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001035 sys.stdout.write(" client: read %r\n" % outdata)
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00001036 if outdata != indata.lower():
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001037 raise AssertionError(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001038 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1039 % (outdata[:20], len(outdata),
1040 indata[:20].lower(), len(indata)))
1041 s.write(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +00001042 if connectionchatty:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001043 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +00001044 sys.stdout.write(" client: closing connection.\n")
1045 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001046 finally:
1047 server.stop()
1048 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +00001049
Antoine Pitroub5218772010-05-21 09:56:06 +00001050 def try_protocol_combo(server_protocol, client_protocol, expect_success,
1051 certsreqs=None, server_options=0, client_options=0):
Benjamin Peterson2a691a82008-03-31 01:51:45 +00001052 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001053 certsreqs = ssl.CERT_NONE
Antoine Pitrou480a1242010-04-28 21:37:09 +00001054 certtype = {
1055 ssl.CERT_NONE: "CERT_NONE",
1056 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
1057 ssl.CERT_REQUIRED: "CERT_REQUIRED",
1058 }[certsreqs]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001059 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001060 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001061 sys.stdout.write(formatstr %
1062 (ssl.get_protocol_name(client_protocol),
1063 ssl.get_protocol_name(server_protocol),
1064 certtype))
Antoine Pitroub5218772010-05-21 09:56:06 +00001065 client_context = ssl.SSLContext(client_protocol)
1066 client_context.options = ssl.OP_ALL | client_options
1067 server_context = ssl.SSLContext(server_protocol)
1068 server_context.options = ssl.OP_ALL | server_options
1069 for ctx in (client_context, server_context):
1070 ctx.verify_mode = certsreqs
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +00001071 # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
1072 # will send an SSLv3 hello (rather than SSLv2) starting from
1073 # OpenSSL 1.0.0 (see issue #8322).
Antoine Pitroub5218772010-05-21 09:56:06 +00001074 ctx.set_ciphers("ALL")
1075 ctx.load_cert_chain(CERTFILE)
1076 ctx.load_verify_locations(CERTFILE)
1077 try:
1078 server_params_test(client_context, server_context,
1079 chatty=False, connectionchatty=False)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001080 # Protocol mismatch can result in either an SSLError, or a
1081 # "Connection reset by peer" error.
1082 except ssl.SSLError:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001083 if expect_success:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001084 raise
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001085 except socket.error as e:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001086 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001087 raise
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001088 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001089 if not expect_success:
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001090 raise AssertionError(
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001091 "Client protocol %s succeeded with server protocol %s!"
1092 % (ssl.get_protocol_name(client_protocol),
1093 ssl.get_protocol_name(server_protocol)))
1094
1095
Bill Janssen6e027db2007-11-15 22:23:56 +00001096 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001097
Antoine Pitrou23df4832010-08-04 17:14:06 +00001098 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001099 def test_echo(self):
1100 """Basic test of an SSL client connecting to a server"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001101 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001102 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00001103 for protocol in PROTOCOLS:
1104 context = ssl.SSLContext(protocol)
1105 context.load_cert_chain(CERTFILE)
1106 server_params_test(context, context,
1107 chatty=True, connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001108
Antoine Pitrou480a1242010-04-28 21:37:09 +00001109 def test_getpeercert(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001110 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001111 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00001112 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1113 context.verify_mode = ssl.CERT_REQUIRED
1114 context.load_verify_locations(CERTFILE)
1115 context.load_cert_chain(CERTFILE)
1116 server = ThreadedEchoServer(context=context, chatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001117 flag = threading.Event()
1118 server.start(flag)
1119 # wait for it to start
1120 flag.wait()
1121 # try to connect
1122 try:
Antoine Pitroub5218772010-05-21 09:56:06 +00001123 s = context.wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001124 s.connect((HOST, server.port))
1125 cert = s.getpeercert()
1126 self.assertTrue(cert, "Can't get peer certificate.")
1127 cipher = s.cipher()
1128 if support.verbose:
1129 sys.stdout.write(pprint.pformat(cert) + '\n')
1130 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
1131 if 'subject' not in cert:
1132 self.fail("No subject field in certificate: %s." %
1133 pprint.pformat(cert))
1134 if ((('organizationName', 'Python Software Foundation'),)
1135 not in cert['subject']):
1136 self.fail(
1137 "Missing or invalid 'organizationName' field in certificate subject; "
1138 "should be 'Python Software Foundation'.")
Antoine Pitroufb046912010-11-09 20:21:19 +00001139 self.assertIn('notBefore', cert)
1140 self.assertIn('notAfter', cert)
1141 before = ssl.cert_time_to_seconds(cert['notBefore'])
1142 after = ssl.cert_time_to_seconds(cert['notAfter'])
1143 self.assertLess(before, after)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001144 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001145 finally:
1146 server.stop()
1147 server.join()
1148
Antoine Pitrou480a1242010-04-28 21:37:09 +00001149 def test_empty_cert(self):
1150 """Connecting with an empty cert file"""
1151 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1152 "nullcert.pem"))
1153 def test_malformed_cert(self):
1154 """Connecting with a badly formatted certificate (syntax error)"""
1155 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1156 "badcert.pem"))
1157 def test_nonexisting_cert(self):
1158 """Connecting with a non-existing cert file"""
1159 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1160 "wrongcert.pem"))
1161 def test_malformed_key(self):
1162 """Connecting with a badly formatted key (syntax error)"""
1163 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1164 "badkey.pem"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001165
Antoine Pitrou480a1242010-04-28 21:37:09 +00001166 def test_rude_shutdown(self):
1167 """A brutal shutdown of an SSL server should raise an IOError
1168 in the client when attempting handshake.
1169 """
Trent Nelson6b240cd2008-04-10 20:12:06 +00001170 listener_ready = threading.Event()
1171 listener_gone = threading.Event()
Antoine Pitrou480a1242010-04-28 21:37:09 +00001172
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001173 s = socket.socket()
1174 port = support.bind_port(s, HOST)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001175
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001176 # `listener` runs in a thread. It sits in an accept() until
1177 # the main thread connects. Then it rudely closes the socket,
1178 # and sets Event `listener_gone` to let the main thread know
1179 # the socket is gone.
Trent Nelson6b240cd2008-04-10 20:12:06 +00001180 def listener():
Trent Nelson6b240cd2008-04-10 20:12:06 +00001181 s.listen(5)
1182 listener_ready.set()
Antoine Pitroud2eca372010-10-29 23:41:37 +00001183 newsock, addr = s.accept()
1184 newsock.close()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001185 s.close()
Trent Nelson6b240cd2008-04-10 20:12:06 +00001186 listener_gone.set()
1187
1188 def connector():
1189 listener_ready.wait()
Antoine Pitroud2eca372010-10-29 23:41:37 +00001190 with socket.socket() as c:
1191 c.connect((HOST, port))
1192 listener_gone.wait()
1193 try:
1194 ssl_sock = ssl.wrap_socket(c)
1195 except IOError:
1196 pass
1197 else:
1198 self.fail('connecting to closed SSL socket should have failed')
Trent Nelson6b240cd2008-04-10 20:12:06 +00001199
1200 t = threading.Thread(target=listener)
1201 t.start()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001202 try:
1203 connector()
1204 finally:
1205 t.join()
Trent Nelson6b240cd2008-04-10 20:12:06 +00001206
Antoine Pitrou23df4832010-08-04 17:14:06 +00001207 @skip_if_broken_ubuntu_ssl
Victor Stinneree18b6f2011-05-10 00:38:00 +02001208 @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv2'), "need SSLv2")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001209 def test_protocol_sslv2(self):
1210 """Connecting to an SSLv2 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001211 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001212 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001213 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
1214 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
1215 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
1216 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
1217 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
1218 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00001219 # SSLv23 client with specific SSL options
1220 if no_sslv2_implies_sslv3_hello():
1221 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
1222 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
1223 client_options=ssl.OP_NO_SSLv2)
1224 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True,
1225 client_options=ssl.OP_NO_SSLv3)
1226 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True,
1227 client_options=ssl.OP_NO_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001228
Antoine Pitrou23df4832010-08-04 17:14:06 +00001229 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001230 def test_protocol_sslv23(self):
1231 """Connecting to an SSLv23 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001232 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001233 sys.stdout.write("\n")
Victor Stinneree18b6f2011-05-10 00:38:00 +02001234 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1235 try:
1236 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
1237 except (ssl.SSLError, socket.error) as x:
1238 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
1239 if support.verbose:
1240 sys.stdout.write(
1241 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
1242 % str(x))
Antoine Pitrou480a1242010-04-28 21:37:09 +00001243 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
1244 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
1245 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001246
Antoine Pitrou480a1242010-04-28 21:37:09 +00001247 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1248 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
1249 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001250
Antoine Pitrou480a1242010-04-28 21:37:09 +00001251 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1252 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
1253 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001254
Antoine Pitroub5218772010-05-21 09:56:06 +00001255 # Server with specific SSL options
1256 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False,
1257 server_options=ssl.OP_NO_SSLv3)
1258 # Will choose TLSv1
1259 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True,
1260 server_options=ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
1261 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, False,
1262 server_options=ssl.OP_NO_TLSv1)
1263
1264
Antoine Pitrou23df4832010-08-04 17:14:06 +00001265 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001266 def test_protocol_sslv3(self):
1267 """Connecting to an SSLv3 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001268 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001269 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001270 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
1271 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1272 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
Victor Stinneree18b6f2011-05-10 00:38:00 +02001273 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1274 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
Antoine Pitrou480a1242010-04-28 21:37:09 +00001275 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
1276 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00001277 if no_sslv2_implies_sslv3_hello():
1278 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
1279 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, True,
1280 client_options=ssl.OP_NO_SSLv2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001281
Antoine Pitrou23df4832010-08-04 17:14:06 +00001282 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001283 def test_protocol_tlsv1(self):
1284 """Connecting to a TLSv1 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001285 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001286 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001287 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
1288 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
1289 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Victor Stinneree18b6f2011-05-10 00:38:00 +02001290 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1291 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
Antoine Pitrou480a1242010-04-28 21:37:09 +00001292 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
1293 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001294
Antoine Pitrou480a1242010-04-28 21:37:09 +00001295 def test_starttls(self):
1296 """Switching from clear text to encrypted and back again."""
1297 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 +00001298
Trent Nelson78520002008-04-10 20:54:35 +00001299 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001300 ssl_version=ssl.PROTOCOL_TLSv1,
1301 starttls_server=True,
1302 chatty=True,
1303 connectionchatty=True)
1304 flag = threading.Event()
1305 server.start(flag)
1306 # wait for it to start
1307 flag.wait()
1308 # try to connect
1309 wrapped = False
1310 try:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001311 s = socket.socket()
1312 s.setblocking(1)
1313 s.connect((HOST, server.port))
1314 if support.verbose:
1315 sys.stdout.write("\n")
1316 for indata in msgs:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001317 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001318 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001319 " client: sending %r...\n" % indata)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001320 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001321 conn.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001322 outdata = conn.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001323 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001324 s.send(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001325 outdata = s.recv(1024)
Antoine Pitrou480a1242010-04-28 21:37:09 +00001326 msg = outdata.strip().lower()
1327 if indata == b"STARTTLS" and msg.startswith(b"ok"):
1328 # STARTTLS ok, switch to secure mode
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001329 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001330 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001331 " client: read %r from server, starting TLS...\n"
1332 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001333 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
1334 wrapped = True
Antoine Pitrou480a1242010-04-28 21:37:09 +00001335 elif indata == b"ENDTLS" and msg.startswith(b"ok"):
1336 # ENDTLS ok, switch back to clear text
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001337 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001338 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001339 " client: read %r from server, ending TLS...\n"
1340 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001341 s = conn.unwrap()
1342 wrapped = False
1343 else:
1344 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001345 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001346 " client: read %r from server\n" % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001347 if support.verbose:
1348 sys.stdout.write(" client: closing connection.\n")
1349 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001350 conn.write(b"over\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001351 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001352 s.send(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +00001353 if wrapped:
1354 conn.close()
1355 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001356 s.close()
1357 finally:
1358 server.stop()
1359 server.join()
1360
Antoine Pitrou480a1242010-04-28 21:37:09 +00001361 def test_socketserver(self):
1362 """Using a SocketServer to create and manage SSL connections."""
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001363 server = make_https_server(self, CERTFILE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001364 # try to connect
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001365 if support.verbose:
1366 sys.stdout.write('\n')
1367 with open(CERTFILE, 'rb') as f:
1368 d1 = f.read()
1369 d2 = ''
1370 # now fetch the same data from the HTTPS server
1371 url = 'https://%s:%d/%s' % (
1372 HOST, server.port, os.path.split(CERTFILE)[1])
1373 f = urllib.request.urlopen(url)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001374 try:
Barry Warsaw820c1202008-06-12 04:06:45 +00001375 dlen = f.info().get("content-length")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001376 if dlen and (int(dlen) > 0):
1377 d2 = f.read(int(dlen))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001378 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001379 sys.stdout.write(
1380 " client: read %d bytes from remote server '%s'\n"
1381 % (len(d2), server))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001382 finally:
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001383 f.close()
1384 self.assertEqual(d1, d2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001385
Antoine Pitrou480a1242010-04-28 21:37:09 +00001386 def test_asyncore_server(self):
1387 """Check the example asyncore integration."""
1388 indata = "TEST MESSAGE of mixed case\n"
Trent Nelson6b240cd2008-04-10 20:12:06 +00001389
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001390 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001391 sys.stdout.write("\n")
1392
Antoine Pitrou480a1242010-04-28 21:37:09 +00001393 indata = b"FOO\n"
Trent Nelson78520002008-04-10 20:54:35 +00001394 server = AsyncoreEchoServer(CERTFILE)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001395 flag = threading.Event()
1396 server.start(flag)
1397 # wait for it to start
1398 flag.wait()
1399 # try to connect
1400 try:
1401 s = ssl.wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001402 s.connect(('127.0.0.1', server.port))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001403 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001404 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001405 " client: sending %r...\n" % indata)
1406 s.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001407 outdata = s.read()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001408 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001409 sys.stdout.write(" client: read %r\n" % outdata)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001410 if outdata != indata.lower():
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001411 self.fail(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001412 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1413 % (outdata[:20], len(outdata),
1414 indata[:20].lower(), len(indata)))
1415 s.write(b"over\n")
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001416 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001417 sys.stdout.write(" client: closing connection.\n")
1418 s.close()
Antoine Pitroued986362010-08-15 23:28:10 +00001419 if support.verbose:
1420 sys.stdout.write(" client: connection closed.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001421 finally:
Antoine Pitroued986362010-08-15 23:28:10 +00001422 if support.verbose:
1423 sys.stdout.write(" cleanup: stopping server.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001424 server.stop()
Antoine Pitroued986362010-08-15 23:28:10 +00001425 if support.verbose:
1426 sys.stdout.write(" cleanup: joining server thread.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001427 server.join()
Antoine Pitroued986362010-08-15 23:28:10 +00001428 if support.verbose:
1429 sys.stdout.write(" cleanup: successfully joined.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001430
Antoine Pitrou480a1242010-04-28 21:37:09 +00001431 def test_recv_send(self):
1432 """Test recv(), send() and friends."""
Bill Janssen58afe4c2008-09-08 16:45:19 +00001433 if support.verbose:
1434 sys.stdout.write("\n")
1435
1436 server = ThreadedEchoServer(CERTFILE,
1437 certreqs=ssl.CERT_NONE,
1438 ssl_version=ssl.PROTOCOL_TLSv1,
1439 cacerts=CERTFILE,
1440 chatty=True,
1441 connectionchatty=False)
1442 flag = threading.Event()
1443 server.start(flag)
1444 # wait for it to start
1445 flag.wait()
1446 # try to connect
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001447 s = ssl.wrap_socket(socket.socket(),
1448 server_side=False,
1449 certfile=CERTFILE,
1450 ca_certs=CERTFILE,
1451 cert_reqs=ssl.CERT_NONE,
1452 ssl_version=ssl.PROTOCOL_TLSv1)
1453 s.connect((HOST, server.port))
Bill Janssen58afe4c2008-09-08 16:45:19 +00001454 try:
Bill Janssen58afe4c2008-09-08 16:45:19 +00001455 # helper methods for standardising recv* method signatures
1456 def _recv_into():
1457 b = bytearray(b"\0"*100)
1458 count = s.recv_into(b)
1459 return b[:count]
1460
1461 def _recvfrom_into():
1462 b = bytearray(b"\0"*100)
1463 count, addr = s.recvfrom_into(b)
1464 return b[:count]
1465
1466 # (name, method, whether to expect success, *args)
1467 send_methods = [
1468 ('send', s.send, True, []),
1469 ('sendto', s.sendto, False, ["some.address"]),
1470 ('sendall', s.sendall, True, []),
1471 ]
1472 recv_methods = [
1473 ('recv', s.recv, True, []),
1474 ('recvfrom', s.recvfrom, False, ["some.address"]),
1475 ('recv_into', _recv_into, True, []),
1476 ('recvfrom_into', _recvfrom_into, False, []),
1477 ]
1478 data_prefix = "PREFIX_"
1479
1480 for meth_name, send_meth, expect_success, args in send_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001481 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00001482 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001483 send_meth(indata, *args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001484 outdata = s.read()
Bill Janssen58afe4c2008-09-08 16:45:19 +00001485 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001486 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001487 "While sending with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00001488 "<<{outdata:r}>> ({nout:d}) received; "
1489 "expected <<{indata:r}>> ({nin:d})\n".format(
1490 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00001491 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00001492 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001493 )
1494 )
1495 except ValueError as e:
1496 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001497 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001498 "Failed to send with method <<{name:s}>>; "
1499 "expected to succeed.\n".format(name=meth_name)
1500 )
1501 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001502 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001503 "Method <<{name:s}>> failed with unexpected "
1504 "exception message: {exp:s}\n".format(
1505 name=meth_name, exp=e
1506 )
1507 )
1508
1509 for meth_name, recv_meth, expect_success, args in recv_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001510 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00001511 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001512 s.send(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001513 outdata = recv_meth(*args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001514 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001515 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001516 "While receiving with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00001517 "<<{outdata:r}>> ({nout:d}) received; "
1518 "expected <<{indata:r}>> ({nin:d})\n".format(
1519 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00001520 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00001521 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001522 )
1523 )
1524 except ValueError as e:
1525 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001526 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001527 "Failed to receive with method <<{name:s}>>; "
1528 "expected to succeed.\n".format(name=meth_name)
1529 )
1530 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001531 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001532 "Method <<{name:s}>> failed with unexpected "
1533 "exception message: {exp:s}\n".format(
1534 name=meth_name, exp=e
1535 )
1536 )
1537 # consume data
1538 s.read()
1539
Antoine Pitrou480a1242010-04-28 21:37:09 +00001540 s.write(b"over\n")
Bill Janssen58afe4c2008-09-08 16:45:19 +00001541 s.close()
1542 finally:
1543 server.stop()
1544 server.join()
1545
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001546 def test_handshake_timeout(self):
1547 # Issue #5103: SSL handshake must respect the socket timeout
1548 server = socket.socket(socket.AF_INET)
1549 host = "127.0.0.1"
1550 port = support.bind_port(server)
1551 started = threading.Event()
1552 finish = False
1553
1554 def serve():
1555 server.listen(5)
1556 started.set()
1557 conns = []
1558 while not finish:
1559 r, w, e = select.select([server], [], [], 0.1)
1560 if server in r:
1561 # Let the socket hang around rather than having
1562 # it closed by garbage collection.
1563 conns.append(server.accept()[0])
Antoine Pitroud2eca372010-10-29 23:41:37 +00001564 for sock in conns:
1565 sock.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001566
1567 t = threading.Thread(target=serve)
1568 t.start()
1569 started.wait()
1570
1571 try:
Antoine Pitrou40f08742010-04-24 22:04:40 +00001572 try:
1573 c = socket.socket(socket.AF_INET)
1574 c.settimeout(0.2)
1575 c.connect((host, port))
1576 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00001577 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00001578 ssl.wrap_socket, c)
Antoine Pitrou40f08742010-04-24 22:04:40 +00001579 finally:
1580 c.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001581 try:
1582 c = socket.socket(socket.AF_INET)
1583 c = ssl.wrap_socket(c)
1584 c.settimeout(0.2)
1585 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00001586 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00001587 c.connect, (host, port))
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001588 finally:
1589 c.close()
1590 finally:
1591 finish = True
1592 t.join()
1593 server.close()
1594
Bill Janssen58afe4c2008-09-08 16:45:19 +00001595
Thomas Woutersed03b412007-08-28 21:37:11 +00001596def test_main(verbose=False):
Antoine Pitrou15cee622010-08-04 16:45:21 +00001597 if support.verbose:
1598 plats = {
1599 'Linux': platform.linux_distribution,
1600 'Mac': platform.mac_ver,
1601 'Windows': platform.win32_ver,
1602 }
1603 for name, func in plats.items():
1604 plat = func()
1605 if plat and plat[0]:
1606 plat = '%s %r' % (name, plat)
1607 break
1608 else:
1609 plat = repr(platform.platform())
1610 print("test_ssl: testing with %r %r" %
1611 (ssl.OPENSSL_VERSION, ssl.OPENSSL_VERSION_INFO))
1612 print(" under %s" % plat)
Antoine Pitroud5323212010-10-22 18:19:07 +00001613 print(" HAS_SNI = %r" % ssl.HAS_SNI)
Antoine Pitrou15cee622010-08-04 16:45:21 +00001614
Antoine Pitrou152efa22010-05-16 18:19:27 +00001615 for filename in [
1616 CERTFILE, SVN_PYTHON_ORG_ROOT_CERT, BYTES_CERTFILE,
1617 ONLYCERT, ONLYKEY, BYTES_ONLYCERT, BYTES_ONLYKEY,
1618 BADCERT, BADKEY, EMPTYCERT]:
1619 if not os.path.exists(filename):
1620 raise support.TestFailed("Can't read certificate file %r" % filename)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001621
Antoine Pitrou152efa22010-05-16 18:19:27 +00001622 tests = [ContextTests, BasicSocketTests]
Thomas Woutersed03b412007-08-28 21:37:11 +00001623
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001624 if support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001625 tests.append(NetworkedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001626
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001627 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001628 thread_info = support.threading_setup()
1629 if thread_info and support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001630 tests.append(ThreadedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001631
Antoine Pitrou480a1242010-04-28 21:37:09 +00001632 try:
1633 support.run_unittest(*tests)
1634 finally:
1635 if _have_threads:
1636 support.threading_cleanup(*thread_info)
Thomas Woutersed03b412007-08-28 21:37:11 +00001637
1638if __name__ == "__main__":
1639 test_main()