blob: aef51e33dfc8d10895a414acc54bac091c6c2fa9 [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 Stinner3de49192011-05-09 00:42:58 +020024 ssl.PROTOCOL_SSLv3,
Antoine Pitrou05d936d2010-10-13 11:38:36 +000025 ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1
26]
Victor Stinner3de49192011-05-09 00:42:58 +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 Stinner3de49192011-05-09 00:42:58 +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 Stinner3de49192011-05-09 00:42:58 +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 Stinner3de49192011-05-09 00:42:58 +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 Pitroue93bf7a2011-02-26 23:24:06 +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 Pitrou8a14a0c2011-02-27 15:44:12 +0000501 # EWOULDBLOCK under Windows, EINPROGRESS elsewhere
502 self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK))
Antoine Pitroue93bf7a2011-02-26 23:24:06 +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 Pitroub4410db2011-05-18 18:51:06 +0200522 def test_timeout_connect_ex(self):
523 # Issue #12065: on a timeout, connect_ex() should return the original
524 # errno (mimicking the behaviour of non-SSL sockets).
525 with support.transient_internet("svn.python.org"):
526 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
527 cert_reqs=ssl.CERT_REQUIRED,
528 ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
529 do_handshake_on_connect=False)
530 try:
531 s.settimeout(0.0000001)
532 rc = s.connect_ex(('svn.python.org', 443))
533 if rc == 0:
534 self.skipTest("svn.python.org responded too quickly")
535 self.assertIn(rc, (errno.EAGAIN, errno.EWOULDBLOCK))
536 finally:
537 s.close()
538
Antoine Pitrou152efa22010-05-16 18:19:27 +0000539 def test_connect_with_context(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000540 with support.transient_internet("svn.python.org"):
541 # Same as test_connect, but with a separately created context
542 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
543 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
544 s.connect(("svn.python.org", 443))
545 try:
546 self.assertEqual({}, s.getpeercert())
547 finally:
548 s.close()
Antoine Pitroud5323212010-10-22 18:19:07 +0000549 # Same with a server hostname
550 s = ctx.wrap_socket(socket.socket(socket.AF_INET),
551 server_hostname="svn.python.org")
552 if ssl.HAS_SNI:
553 s.connect(("svn.python.org", 443))
554 s.close()
555 else:
556 self.assertRaises(ValueError, s.connect, ("svn.python.org", 443))
Antoine Pitrou350c7222010-09-09 13:31:46 +0000557 # This should fail because we have no verification certs
558 ctx.verify_mode = ssl.CERT_REQUIRED
559 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
Ezio Melottied3a7d22010-12-01 02:32:32 +0000560 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
Antoine Pitrou350c7222010-09-09 13:31:46 +0000561 s.connect, ("svn.python.org", 443))
Antoine Pitrou152efa22010-05-16 18:19:27 +0000562 s.close()
Antoine Pitrou350c7222010-09-09 13:31:46 +0000563 # This should succeed because we specify the root cert
564 ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
565 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
566 s.connect(("svn.python.org", 443))
567 try:
568 cert = s.getpeercert()
569 self.assertTrue(cert)
570 finally:
571 s.close()
Antoine Pitrou152efa22010-05-16 18:19:27 +0000572
573 def test_connect_capath(self):
574 # Verify server certificates using the `capath` argument
Antoine Pitrou467f28d2010-05-16 19:22:44 +0000575 # NOTE: the subject hashing algorithm has been changed between
576 # OpenSSL 0.9.8n and 1.0.0, as a result the capath directory must
577 # contain both versions of each certificate (same content, different
Antoine Pitroud7e4c1c2010-05-17 14:13:10 +0000578 # filename) for this test to be portable across OpenSSL releases.
Antoine Pitrou350c7222010-09-09 13:31:46 +0000579 with support.transient_internet("svn.python.org"):
580 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
581 ctx.verify_mode = ssl.CERT_REQUIRED
582 ctx.load_verify_locations(capath=CAPATH)
583 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
584 s.connect(("svn.python.org", 443))
585 try:
586 cert = s.getpeercert()
587 self.assertTrue(cert)
588 finally:
589 s.close()
590 # Same with a bytes `capath` argument
591 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
592 ctx.verify_mode = ssl.CERT_REQUIRED
593 ctx.load_verify_locations(capath=BYTES_CAPATH)
594 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
595 s.connect(("svn.python.org", 443))
596 try:
597 cert = s.getpeercert()
598 self.assertTrue(cert)
599 finally:
600 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000601
Antoine Pitroue3220242010-04-24 11:13:53 +0000602 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
603 def test_makefile_close(self):
604 # Issue #5238: creating a file-like object with makefile() shouldn't
605 # delay closing the underlying "real socket" (here tested with its
606 # file descriptor, hence skipping the test under Windows).
Antoine Pitrou350c7222010-09-09 13:31:46 +0000607 with support.transient_internet("svn.python.org"):
608 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
609 ss.connect(("svn.python.org", 443))
610 fd = ss.fileno()
611 f = ss.makefile()
612 f.close()
613 # The fd is still open
Antoine Pitroue3220242010-04-24 11:13:53 +0000614 os.read(fd, 0)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000615 # Closing the SSL socket should close the fd too
616 ss.close()
617 gc.collect()
618 with self.assertRaises(OSError) as e:
619 os.read(fd, 0)
620 self.assertEqual(e.exception.errno, errno.EBADF)
Antoine Pitroue3220242010-04-24 11:13:53 +0000621
Antoine Pitrou480a1242010-04-28 21:37:09 +0000622 def test_non_blocking_handshake(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000623 with support.transient_internet("svn.python.org"):
624 s = socket.socket(socket.AF_INET)
625 s.connect(("svn.python.org", 443))
626 s.setblocking(False)
627 s = ssl.wrap_socket(s,
628 cert_reqs=ssl.CERT_NONE,
629 do_handshake_on_connect=False)
630 count = 0
631 while True:
632 try:
633 count += 1
634 s.do_handshake()
635 break
636 except ssl.SSLError as err:
637 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
638 select.select([s], [], [])
639 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
640 select.select([], [s], [])
641 else:
642 raise
643 s.close()
644 if support.verbose:
645 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000646
Antoine Pitrou480a1242010-04-28 21:37:09 +0000647 def test_get_server_certificate(self):
Antoine Pitrou15399c32011-04-28 19:23:55 +0200648 def _test_get_server_certificate(host, port, cert=None):
649 with support.transient_internet(host):
650 pem = ssl.get_server_certificate((host, port))
651 if not pem:
652 self.fail("No server certificate on %s:%s!" % (host, port))
Antoine Pitrou5aefa662011-04-28 19:24:46 +0200653
Antoine Pitrou15399c32011-04-28 19:23:55 +0200654 try:
655 pem = ssl.get_server_certificate((host, port), ca_certs=CERTFILE)
656 except ssl.SSLError as x:
657 #should fail
658 if support.verbose:
659 sys.stdout.write("%s\n" % x)
660 else:
Antoine Pitrou5aefa662011-04-28 19:24:46 +0200661 self.fail("Got server certificate %s for %s:%s!" % (pem, host, port))
662
Antoine Pitrou15399c32011-04-28 19:23:55 +0200663 pem = ssl.get_server_certificate((host, port), ca_certs=cert)
664 if not pem:
Antoine Pitrou5aefa662011-04-28 19:24:46 +0200665 self.fail("No server certificate on %s:%s!" % (host, port))
Antoine Pitrou350c7222010-09-09 13:31:46 +0000666 if support.verbose:
Antoine Pitrou5aefa662011-04-28 19:24:46 +0200667 sys.stdout.write("\nVerified certificate for %s:%s is\n%s\n" % (host, port ,pem))
Antoine Pitrou350c7222010-09-09 13:31:46 +0000668
Antoine Pitrou15399c32011-04-28 19:23:55 +0200669 _test_get_server_certificate('svn.python.org', 443, SVN_PYTHON_ORG_ROOT_CERT)
670 if support.IPV6_ENABLED:
671 _test_get_server_certificate('ipv6.google.com', 443)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000672
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000673 def test_ciphers(self):
674 remote = ("svn.python.org", 443)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000675 with support.transient_internet(remote[0]):
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000676 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
Antoine Pitrou350c7222010-09-09 13:31:46 +0000677 cert_reqs=ssl.CERT_NONE, ciphers="ALL")
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000678 s.connect(remote)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000679 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
680 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")
681 s.connect(remote)
682 # Error checking can happen at instantiation or when connecting
Ezio Melottied3a7d22010-12-01 02:32:32 +0000683 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
Antoine Pitroud2eca372010-10-29 23:41:37 +0000684 with socket.socket(socket.AF_INET) as sock:
685 s = ssl.wrap_socket(sock,
686 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
687 s.connect(remote)
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000688
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000689 def test_algorithms(self):
690 # Issue #8484: all algorithms should be available when verifying a
691 # certificate.
Antoine Pitrou29619b22010-04-22 18:43:31 +0000692 # SHA256 was added in OpenSSL 0.9.8
693 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
694 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Victor Stinnerf332abb2011-01-08 03:16:05 +0000695 # https://sha2.hboeck.de/ was used until 2011-01-08 (no route to host)
696 remote = ("sha256.tbs-internet.com", 443)
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000697 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
Antoine Pitrou160fd932011-01-08 10:23:29 +0000698 with support.transient_internet("sha256.tbs-internet.com"):
Antoine Pitroua88c83c2010-09-07 20:42:19 +0000699 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
700 cert_reqs=ssl.CERT_REQUIRED,
701 ca_certs=sha256_cert,)
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000702 try:
703 s.connect(remote)
704 if support.verbose:
705 sys.stdout.write("\nCipher with %r is %r\n" %
706 (remote, s.cipher()))
707 sys.stdout.write("Certificate is:\n%s\n" %
708 pprint.pformat(s.getpeercert()))
709 finally:
710 s.close()
711
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000712
713try:
714 import threading
715except ImportError:
716 _have_threads = False
717else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000718 _have_threads = True
719
Antoine Pitrou803e6d62010-10-13 10:36:15 +0000720 from test.ssl_servers import make_https_server
721
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000722 class ThreadedEchoServer(threading.Thread):
723
724 class ConnectionHandler(threading.Thread):
725
726 """A mildly complicated class, because we want it to work both
727 with and without the SSL wrapper around the socket connection, so
728 that we can test the STARTTLS functionality."""
729
Bill Janssen6e027db2007-11-15 22:23:56 +0000730 def __init__(self, server, connsock, addr):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000731 self.server = server
732 self.running = False
733 self.sock = connsock
Bill Janssen6e027db2007-11-15 22:23:56 +0000734 self.addr = addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000735 self.sock.setblocking(1)
736 self.sslconn = None
737 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000738 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000739
Antoine Pitrou480a1242010-04-28 21:37:09 +0000740 def wrap_conn(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000741 try:
Antoine Pitroub5218772010-05-21 09:56:06 +0000742 self.sslconn = self.server.context.wrap_socket(
743 self.sock, server_side=True)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000744 except ssl.SSLError:
745 # XXX Various errors can have happened here, for example
746 # a mismatching protocol version, an invalid certificate,
747 # or a low-level bug. This should be made more discriminating.
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000748 if self.server.chatty:
Bill Janssen6e027db2007-11-15 22:23:56 +0000749 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000750 self.running = False
751 self.server.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000752 self.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000753 return False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000754 else:
Antoine Pitroub5218772010-05-21 09:56:06 +0000755 if self.server.context.verify_mode == ssl.CERT_REQUIRED:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000756 cert = self.sslconn.getpeercert()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000757 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000758 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
759 cert_binary = self.sslconn.getpeercert(True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000760 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000761 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
762 cipher = self.sslconn.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000763 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000764 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
765 return True
766
767 def read(self):
768 if self.sslconn:
769 return self.sslconn.read()
770 else:
771 return self.sock.recv(1024)
772
773 def write(self, bytes):
774 if self.sslconn:
775 return self.sslconn.write(bytes)
776 else:
777 return self.sock.send(bytes)
778
779 def close(self):
780 if self.sslconn:
781 self.sslconn.close()
782 else:
783 self.sock.close()
784
Antoine Pitrou480a1242010-04-28 21:37:09 +0000785 def run(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000786 self.running = True
787 if not self.server.starttls_server:
788 if not self.wrap_conn():
789 return
790 while self.running:
791 try:
792 msg = self.read()
Antoine Pitrou480a1242010-04-28 21:37:09 +0000793 stripped = msg.strip()
794 if not stripped:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000795 # eof, so quit this handler
796 self.running = False
797 self.close()
Antoine Pitrou480a1242010-04-28 21:37:09 +0000798 elif stripped == b'over':
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000799 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000800 sys.stdout.write(" server: client closed connection\n")
801 self.close()
802 return
Bill Janssen6e027db2007-11-15 22:23:56 +0000803 elif (self.server.starttls_server and
Antoine Pitrou764b8782010-04-28 22:57:15 +0000804 stripped == b'STARTTLS'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000805 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000806 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000807 self.write(b"OK\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000808 if not self.wrap_conn():
809 return
Bill Janssen40a0f662008-08-12 16:56:25 +0000810 elif (self.server.starttls_server and self.sslconn
Antoine Pitrou764b8782010-04-28 22:57:15 +0000811 and stripped == b'ENDTLS'):
Bill Janssen40a0f662008-08-12 16:56:25 +0000812 if support.verbose and self.server.connectionchatty:
813 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000814 self.write(b"OK\n")
Bill Janssen40a0f662008-08-12 16:56:25 +0000815 self.sock = self.sslconn.unwrap()
816 self.sslconn = None
817 if support.verbose and self.server.connectionchatty:
818 sys.stdout.write(" server: connection is now unencrypted...\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000819 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000820 if (support.verbose and
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000821 self.server.connectionchatty):
822 ctype = (self.sslconn and "encrypted") or "unencrypted"
Antoine Pitrou480a1242010-04-28 21:37:09 +0000823 sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
824 % (msg, ctype, msg.lower(), ctype))
825 self.write(msg.lower())
Bill Janssen6e027db2007-11-15 22:23:56 +0000826 except socket.error:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000827 if self.server.chatty:
828 handle_error("Test server failure:\n")
829 self.close()
830 self.running = False
831 # normally, we'd just stop here, but for the test
832 # harness, we want to stop the server
833 self.server.stop()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000834
Antoine Pitroub5218772010-05-21 09:56:06 +0000835 def __init__(self, certificate=None, ssl_version=None,
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000836 certreqs=None, cacerts=None,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000837 chatty=True, connectionchatty=False, starttls_server=False,
Antoine Pitroub5218772010-05-21 09:56:06 +0000838 ciphers=None, context=None):
839 if context:
840 self.context = context
841 else:
842 self.context = ssl.SSLContext(ssl_version
843 if ssl_version is not None
844 else ssl.PROTOCOL_TLSv1)
845 self.context.verify_mode = (certreqs if certreqs is not None
846 else ssl.CERT_NONE)
847 if cacerts:
848 self.context.load_verify_locations(cacerts)
849 if certificate:
850 self.context.load_cert_chain(certificate)
851 if ciphers:
852 self.context.set_ciphers(ciphers)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000853 self.chatty = chatty
854 self.connectionchatty = connectionchatty
855 self.starttls_server = starttls_server
856 self.sock = socket.socket()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000857 self.port = support.bind_port(self.sock)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000858 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000859 self.active = False
860 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000861 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000862
Antoine Pitrou480a1242010-04-28 21:37:09 +0000863 def start(self, flag=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000864 self.flag = flag
865 threading.Thread.start(self)
866
Antoine Pitrou480a1242010-04-28 21:37:09 +0000867 def run(self):
Antoine Pitrouaf7c6022010-04-27 09:56:02 +0000868 self.sock.settimeout(0.05)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000869 self.sock.listen(5)
870 self.active = True
871 if self.flag:
872 # signal an event
873 self.flag.set()
874 while self.active:
875 try:
876 newconn, connaddr = self.sock.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000877 if support.verbose and self.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000878 sys.stdout.write(' server: new connection from '
Bill Janssen6e027db2007-11-15 22:23:56 +0000879 + repr(connaddr) + '\n')
880 handler = self.ConnectionHandler(self, newconn, connaddr)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000881 handler.start()
882 except socket.timeout:
883 pass
884 except KeyboardInterrupt:
885 self.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000886 self.sock.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000887
Antoine Pitrou480a1242010-04-28 21:37:09 +0000888 def stop(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000889 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000890
Bill Janssen54cc54c2007-12-14 22:08:56 +0000891 class AsyncoreEchoServer(threading.Thread):
892
893 # this one's based on asyncore.dispatcher
894
895 class EchoServer (asyncore.dispatcher):
896
897 class ConnectionHandler (asyncore.dispatcher_with_send):
898
899 def __init__(self, conn, certfile):
900 self.socket = ssl.wrap_socket(conn, server_side=True,
901 certfile=certfile,
902 do_handshake_on_connect=False)
903 asyncore.dispatcher_with_send.__init__(self, self.socket)
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000904 self._ssl_accepting = True
905 self._do_ssl_handshake()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000906
907 def readable(self):
908 if isinstance(self.socket, ssl.SSLSocket):
909 while self.socket.pending() > 0:
910 self.handle_read_event()
911 return True
912
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000913 def _do_ssl_handshake(self):
914 try:
915 self.socket.do_handshake()
916 except ssl.SSLError as err:
917 if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
918 ssl.SSL_ERROR_WANT_WRITE):
919 return
920 elif err.args[0] == ssl.SSL_ERROR_EOF:
921 return self.handle_close()
922 raise
923 except socket.error as err:
924 if err.args[0] == errno.ECONNABORTED:
925 return self.handle_close()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000926 else:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000927 self._ssl_accepting = False
928
929 def handle_read(self):
930 if self._ssl_accepting:
931 self._do_ssl_handshake()
932 else:
933 data = self.recv(1024)
934 if support.verbose:
935 sys.stdout.write(" server: read %s from client\n" % repr(data))
936 if not data:
937 self.close()
938 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000939 self.send(data.lower())
Bill Janssen54cc54c2007-12-14 22:08:56 +0000940
941 def handle_close(self):
Bill Janssen2f5799b2008-06-29 00:08:12 +0000942 self.close()
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000943 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000944 sys.stdout.write(" server: closed connection %s\n" % self.socket)
945
946 def handle_error(self):
947 raise
948
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000949 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000950 self.certfile = certfile
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000951 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
952 self.port = support.bind_port(sock, '')
953 asyncore.dispatcher.__init__(self, sock)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000954 self.listen(5)
955
Giampaolo Rodolà977c7072010-10-04 21:08:36 +0000956 def handle_accepted(self, sock_obj, addr):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000957 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000958 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
959 self.ConnectionHandler(sock_obj, self.certfile)
960
961 def handle_error(self):
962 raise
963
Trent Nelson78520002008-04-10 20:54:35 +0000964 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000965 self.flag = None
966 self.active = False
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000967 self.server = self.EchoServer(certfile)
968 self.port = self.server.port
Bill Janssen54cc54c2007-12-14 22:08:56 +0000969 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000970 self.daemon = True
Bill Janssen54cc54c2007-12-14 22:08:56 +0000971
972 def __str__(self):
973 return "<%s %s>" % (self.__class__.__name__, self.server)
974
975 def start (self, flag=None):
976 self.flag = flag
977 threading.Thread.start(self)
978
Antoine Pitrou480a1242010-04-28 21:37:09 +0000979 def run(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000980 self.active = True
981 if self.flag:
982 self.flag.set()
983 while self.active:
984 try:
985 asyncore.loop(1)
986 except:
987 pass
988
Antoine Pitrou480a1242010-04-28 21:37:09 +0000989 def stop(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000990 self.active = False
991 self.server.close()
992
Antoine Pitrou480a1242010-04-28 21:37:09 +0000993 def bad_cert_test(certfile):
994 """
995 Launch a server with CERT_REQUIRED, and check that trying to
996 connect to it with the given client certificate fails.
997 """
Trent Nelson78520002008-04-10 20:54:35 +0000998 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000999 certreqs=ssl.CERT_REQUIRED,
Bill Janssen6e027db2007-11-15 22:23:56 +00001000 cacerts=CERTFILE, chatty=False,
1001 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001002 flag = threading.Event()
1003 server.start(flag)
1004 # wait for it to start
1005 flag.wait()
1006 # try to connect
1007 try:
Thomas Woutersed03b412007-08-28 21:37:11 +00001008 try:
Antoine Pitroud2eca372010-10-29 23:41:37 +00001009 with socket.socket() as sock:
1010 s = ssl.wrap_socket(sock,
1011 certfile=certfile,
1012 ssl_version=ssl.PROTOCOL_TLSv1)
1013 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001014 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001015 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001016 sys.stdout.write("\nSSLError is %s\n" % x.args[1])
Antoine Pitrou05830aa2010-04-27 13:15:18 +00001017 except socket.error as x:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001018 if support.verbose:
Georg Brandlb75b6392010-10-24 14:20:22 +00001019 sys.stdout.write("\nsocket.error is %s\n" % x.args[1])
Giampaolo Rodolà745ab382010-08-29 19:25:49 +00001020 except IOError as x:
Giampaolo Rodolàcd9dfb92010-08-29 20:56:56 +00001021 if x.errno != errno.ENOENT:
1022 raise
Giampaolo Rodolà745ab382010-08-29 19:25:49 +00001023 if support.verbose:
Giampaolo Rodolàcd9dfb92010-08-29 20:56:56 +00001024 sys.stdout.write("\IOError is %s\n" % str(x))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001025 else:
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001026 raise AssertionError("Use of invalid cert should have failed!")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001027 finally:
1028 server.stop()
1029 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +00001030
Antoine Pitroub5218772010-05-21 09:56:06 +00001031 def server_params_test(client_context, server_context, indata=b"FOO\n",
1032 chatty=True, connectionchatty=False):
Antoine Pitrou480a1242010-04-28 21:37:09 +00001033 """
1034 Launch a server, connect a client to it and try various reads
1035 and writes.
1036 """
Antoine Pitroub5218772010-05-21 09:56:06 +00001037 server = ThreadedEchoServer(context=server_context,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001038 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +00001039 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001040 flag = threading.Event()
1041 server.start(flag)
1042 # wait for it to start
1043 flag.wait()
1044 # try to connect
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001045 try:
Antoine Pitroub5218772010-05-21 09:56:06 +00001046 s = client_context.wrap_socket(socket.socket())
Trent Nelson78520002008-04-10 20:54:35 +00001047 s.connect((HOST, server.port))
Antoine Pitrou480a1242010-04-28 21:37:09 +00001048 for arg in [indata, bytearray(indata), memoryview(indata)]:
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00001049 if connectionchatty:
1050 if support.verbose:
1051 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001052 " client: sending %r...\n" % indata)
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00001053 s.write(arg)
1054 outdata = s.read()
1055 if connectionchatty:
1056 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001057 sys.stdout.write(" client: read %r\n" % outdata)
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00001058 if outdata != indata.lower():
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001059 raise AssertionError(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001060 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1061 % (outdata[:20], len(outdata),
1062 indata[:20].lower(), len(indata)))
1063 s.write(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +00001064 if connectionchatty:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001065 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +00001066 sys.stdout.write(" client: closing connection.\n")
1067 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001068 finally:
1069 server.stop()
1070 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +00001071
Antoine Pitroub5218772010-05-21 09:56:06 +00001072 def try_protocol_combo(server_protocol, client_protocol, expect_success,
1073 certsreqs=None, server_options=0, client_options=0):
Benjamin Peterson2a691a82008-03-31 01:51:45 +00001074 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001075 certsreqs = ssl.CERT_NONE
Antoine Pitrou480a1242010-04-28 21:37:09 +00001076 certtype = {
1077 ssl.CERT_NONE: "CERT_NONE",
1078 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
1079 ssl.CERT_REQUIRED: "CERT_REQUIRED",
1080 }[certsreqs]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001081 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001082 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001083 sys.stdout.write(formatstr %
1084 (ssl.get_protocol_name(client_protocol),
1085 ssl.get_protocol_name(server_protocol),
1086 certtype))
Antoine Pitroub5218772010-05-21 09:56:06 +00001087 client_context = ssl.SSLContext(client_protocol)
1088 client_context.options = ssl.OP_ALL | client_options
1089 server_context = ssl.SSLContext(server_protocol)
1090 server_context.options = ssl.OP_ALL | server_options
1091 for ctx in (client_context, server_context):
1092 ctx.verify_mode = certsreqs
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +00001093 # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
1094 # will send an SSLv3 hello (rather than SSLv2) starting from
1095 # OpenSSL 1.0.0 (see issue #8322).
Antoine Pitroub5218772010-05-21 09:56:06 +00001096 ctx.set_ciphers("ALL")
1097 ctx.load_cert_chain(CERTFILE)
1098 ctx.load_verify_locations(CERTFILE)
1099 try:
1100 server_params_test(client_context, server_context,
1101 chatty=False, connectionchatty=False)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001102 # Protocol mismatch can result in either an SSLError, or a
1103 # "Connection reset by peer" error.
1104 except ssl.SSLError:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001105 if expect_success:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001106 raise
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001107 except socket.error as e:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001108 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001109 raise
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001110 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001111 if not expect_success:
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001112 raise AssertionError(
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001113 "Client protocol %s succeeded with server protocol %s!"
1114 % (ssl.get_protocol_name(client_protocol),
1115 ssl.get_protocol_name(server_protocol)))
1116
1117
Bill Janssen6e027db2007-11-15 22:23:56 +00001118 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001119
Antoine Pitrou23df4832010-08-04 17:14:06 +00001120 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001121 def test_echo(self):
1122 """Basic test of an SSL client connecting to a server"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001123 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001124 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00001125 for protocol in PROTOCOLS:
1126 context = ssl.SSLContext(protocol)
1127 context.load_cert_chain(CERTFILE)
1128 server_params_test(context, context,
1129 chatty=True, connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001130
Antoine Pitrou480a1242010-04-28 21:37:09 +00001131 def test_getpeercert(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001132 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001133 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00001134 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1135 context.verify_mode = ssl.CERT_REQUIRED
1136 context.load_verify_locations(CERTFILE)
1137 context.load_cert_chain(CERTFILE)
1138 server = ThreadedEchoServer(context=context, chatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001139 flag = threading.Event()
1140 server.start(flag)
1141 # wait for it to start
1142 flag.wait()
1143 # try to connect
1144 try:
Antoine Pitroub5218772010-05-21 09:56:06 +00001145 s = context.wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001146 s.connect((HOST, server.port))
1147 cert = s.getpeercert()
1148 self.assertTrue(cert, "Can't get peer certificate.")
1149 cipher = s.cipher()
1150 if support.verbose:
1151 sys.stdout.write(pprint.pformat(cert) + '\n')
1152 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
1153 if 'subject' not in cert:
1154 self.fail("No subject field in certificate: %s." %
1155 pprint.pformat(cert))
1156 if ((('organizationName', 'Python Software Foundation'),)
1157 not in cert['subject']):
1158 self.fail(
1159 "Missing or invalid 'organizationName' field in certificate subject; "
1160 "should be 'Python Software Foundation'.")
Antoine Pitroufb046912010-11-09 20:21:19 +00001161 self.assertIn('notBefore', cert)
1162 self.assertIn('notAfter', cert)
1163 before = ssl.cert_time_to_seconds(cert['notBefore'])
1164 after = ssl.cert_time_to_seconds(cert['notAfter'])
1165 self.assertLess(before, after)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001166 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001167 finally:
1168 server.stop()
1169 server.join()
1170
Antoine Pitrou480a1242010-04-28 21:37:09 +00001171 def test_empty_cert(self):
1172 """Connecting with an empty cert file"""
1173 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1174 "nullcert.pem"))
1175 def test_malformed_cert(self):
1176 """Connecting with a badly formatted certificate (syntax error)"""
1177 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1178 "badcert.pem"))
1179 def test_nonexisting_cert(self):
1180 """Connecting with a non-existing cert file"""
1181 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1182 "wrongcert.pem"))
1183 def test_malformed_key(self):
1184 """Connecting with a badly formatted key (syntax error)"""
1185 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1186 "badkey.pem"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001187
Antoine Pitrou480a1242010-04-28 21:37:09 +00001188 def test_rude_shutdown(self):
1189 """A brutal shutdown of an SSL server should raise an IOError
1190 in the client when attempting handshake.
1191 """
Trent Nelson6b240cd2008-04-10 20:12:06 +00001192 listener_ready = threading.Event()
1193 listener_gone = threading.Event()
Antoine Pitrou480a1242010-04-28 21:37:09 +00001194
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001195 s = socket.socket()
1196 port = support.bind_port(s, HOST)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001197
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001198 # `listener` runs in a thread. It sits in an accept() until
1199 # the main thread connects. Then it rudely closes the socket,
1200 # and sets Event `listener_gone` to let the main thread know
1201 # the socket is gone.
Trent Nelson6b240cd2008-04-10 20:12:06 +00001202 def listener():
Trent Nelson6b240cd2008-04-10 20:12:06 +00001203 s.listen(5)
1204 listener_ready.set()
Antoine Pitroud2eca372010-10-29 23:41:37 +00001205 newsock, addr = s.accept()
1206 newsock.close()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001207 s.close()
Trent Nelson6b240cd2008-04-10 20:12:06 +00001208 listener_gone.set()
1209
1210 def connector():
1211 listener_ready.wait()
Antoine Pitroud2eca372010-10-29 23:41:37 +00001212 with socket.socket() as c:
1213 c.connect((HOST, port))
1214 listener_gone.wait()
1215 try:
1216 ssl_sock = ssl.wrap_socket(c)
1217 except IOError:
1218 pass
1219 else:
1220 self.fail('connecting to closed SSL socket should have failed')
Trent Nelson6b240cd2008-04-10 20:12:06 +00001221
1222 t = threading.Thread(target=listener)
1223 t.start()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001224 try:
1225 connector()
1226 finally:
1227 t.join()
Trent Nelson6b240cd2008-04-10 20:12:06 +00001228
Antoine Pitrou23df4832010-08-04 17:14:06 +00001229 @skip_if_broken_ubuntu_ssl
Victor Stinner3de49192011-05-09 00:42:58 +02001230 @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv2'),
1231 "OpenSSL is compiled without SSLv2 support")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001232 def test_protocol_sslv2(self):
1233 """Connecting to an SSLv2 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001234 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001235 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001236 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
1237 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
1238 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
1239 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
1240 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
1241 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00001242 # SSLv23 client with specific SSL options
1243 if no_sslv2_implies_sslv3_hello():
1244 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
1245 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
1246 client_options=ssl.OP_NO_SSLv2)
1247 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True,
1248 client_options=ssl.OP_NO_SSLv3)
1249 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True,
1250 client_options=ssl.OP_NO_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001251
Antoine Pitrou23df4832010-08-04 17:14:06 +00001252 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001253 def test_protocol_sslv23(self):
1254 """Connecting to an SSLv23 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001255 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001256 sys.stdout.write("\n")
Victor Stinner3de49192011-05-09 00:42:58 +02001257 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1258 try:
1259 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
1260 except (ssl.SSLError, socket.error) as x:
1261 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
1262 if support.verbose:
1263 sys.stdout.write(
1264 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
1265 % str(x))
Antoine Pitrou480a1242010-04-28 21:37:09 +00001266 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
1267 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
1268 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001269
Antoine Pitrou480a1242010-04-28 21:37:09 +00001270 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1271 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
1272 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001273
Antoine Pitrou480a1242010-04-28 21:37:09 +00001274 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1275 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
1276 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001277
Antoine Pitroub5218772010-05-21 09:56:06 +00001278 # Server with specific SSL options
1279 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False,
1280 server_options=ssl.OP_NO_SSLv3)
1281 # Will choose TLSv1
1282 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True,
1283 server_options=ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
1284 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, False,
1285 server_options=ssl.OP_NO_TLSv1)
1286
1287
Antoine Pitrou23df4832010-08-04 17:14:06 +00001288 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001289 def test_protocol_sslv3(self):
1290 """Connecting to an SSLv3 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001291 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001292 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001293 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
1294 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1295 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
Victor Stinner3de49192011-05-09 00:42:58 +02001296 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1297 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
Antoine Pitrou480a1242010-04-28 21:37:09 +00001298 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
1299 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00001300 if no_sslv2_implies_sslv3_hello():
1301 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
1302 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, True,
1303 client_options=ssl.OP_NO_SSLv2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001304
Antoine Pitrou23df4832010-08-04 17:14:06 +00001305 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001306 def test_protocol_tlsv1(self):
1307 """Connecting to a TLSv1 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001308 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001309 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001310 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
1311 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
1312 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Victor Stinner3de49192011-05-09 00:42:58 +02001313 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1314 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
Antoine Pitrou480a1242010-04-28 21:37:09 +00001315 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
1316 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001317
Antoine Pitrou480a1242010-04-28 21:37:09 +00001318 def test_starttls(self):
1319 """Switching from clear text to encrypted and back again."""
1320 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 +00001321
Trent Nelson78520002008-04-10 20:54:35 +00001322 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001323 ssl_version=ssl.PROTOCOL_TLSv1,
1324 starttls_server=True,
1325 chatty=True,
1326 connectionchatty=True)
1327 flag = threading.Event()
1328 server.start(flag)
1329 # wait for it to start
1330 flag.wait()
1331 # try to connect
1332 wrapped = False
1333 try:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001334 s = socket.socket()
1335 s.setblocking(1)
1336 s.connect((HOST, server.port))
1337 if support.verbose:
1338 sys.stdout.write("\n")
1339 for indata in msgs:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001340 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001341 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001342 " client: sending %r...\n" % indata)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001343 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001344 conn.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001345 outdata = conn.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001346 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001347 s.send(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001348 outdata = s.recv(1024)
Antoine Pitrou480a1242010-04-28 21:37:09 +00001349 msg = outdata.strip().lower()
1350 if indata == b"STARTTLS" and msg.startswith(b"ok"):
1351 # STARTTLS ok, switch to secure mode
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001352 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001353 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001354 " client: read %r from server, starting TLS...\n"
1355 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001356 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
1357 wrapped = True
Antoine Pitrou480a1242010-04-28 21:37:09 +00001358 elif indata == b"ENDTLS" and msg.startswith(b"ok"):
1359 # ENDTLS ok, switch back to clear text
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001360 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001361 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001362 " client: read %r from server, ending TLS...\n"
1363 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001364 s = conn.unwrap()
1365 wrapped = False
1366 else:
1367 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001368 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001369 " client: read %r from server\n" % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001370 if support.verbose:
1371 sys.stdout.write(" client: closing connection.\n")
1372 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001373 conn.write(b"over\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001374 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001375 s.send(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +00001376 if wrapped:
1377 conn.close()
1378 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001379 s.close()
1380 finally:
1381 server.stop()
1382 server.join()
1383
Antoine Pitrou480a1242010-04-28 21:37:09 +00001384 def test_socketserver(self):
1385 """Using a SocketServer to create and manage SSL connections."""
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001386 server = make_https_server(self, CERTFILE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001387 # try to connect
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001388 if support.verbose:
1389 sys.stdout.write('\n')
1390 with open(CERTFILE, 'rb') as f:
1391 d1 = f.read()
1392 d2 = ''
1393 # now fetch the same data from the HTTPS server
1394 url = 'https://%s:%d/%s' % (
1395 HOST, server.port, os.path.split(CERTFILE)[1])
1396 f = urllib.request.urlopen(url)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001397 try:
Barry Warsaw820c1202008-06-12 04:06:45 +00001398 dlen = f.info().get("content-length")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001399 if dlen and (int(dlen) > 0):
1400 d2 = f.read(int(dlen))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001401 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001402 sys.stdout.write(
1403 " client: read %d bytes from remote server '%s'\n"
1404 % (len(d2), server))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001405 finally:
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001406 f.close()
1407 self.assertEqual(d1, d2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001408
Antoine Pitrou480a1242010-04-28 21:37:09 +00001409 def test_asyncore_server(self):
1410 """Check the example asyncore integration."""
1411 indata = "TEST MESSAGE of mixed case\n"
Trent Nelson6b240cd2008-04-10 20:12:06 +00001412
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001413 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001414 sys.stdout.write("\n")
1415
Antoine Pitrou480a1242010-04-28 21:37:09 +00001416 indata = b"FOO\n"
Trent Nelson78520002008-04-10 20:54:35 +00001417 server = AsyncoreEchoServer(CERTFILE)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001418 flag = threading.Event()
1419 server.start(flag)
1420 # wait for it to start
1421 flag.wait()
1422 # try to connect
1423 try:
1424 s = ssl.wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001425 s.connect(('127.0.0.1', server.port))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001426 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001427 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001428 " client: sending %r...\n" % indata)
1429 s.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001430 outdata = s.read()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001431 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001432 sys.stdout.write(" client: read %r\n" % outdata)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001433 if outdata != indata.lower():
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001434 self.fail(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001435 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1436 % (outdata[:20], len(outdata),
1437 indata[:20].lower(), len(indata)))
1438 s.write(b"over\n")
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001439 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001440 sys.stdout.write(" client: closing connection.\n")
1441 s.close()
Antoine Pitroued986362010-08-15 23:28:10 +00001442 if support.verbose:
1443 sys.stdout.write(" client: connection closed.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001444 finally:
Antoine Pitroued986362010-08-15 23:28:10 +00001445 if support.verbose:
1446 sys.stdout.write(" cleanup: stopping server.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001447 server.stop()
Antoine Pitroued986362010-08-15 23:28:10 +00001448 if support.verbose:
1449 sys.stdout.write(" cleanup: joining server thread.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001450 server.join()
Antoine Pitroued986362010-08-15 23:28:10 +00001451 if support.verbose:
1452 sys.stdout.write(" cleanup: successfully joined.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001453
Antoine Pitrou480a1242010-04-28 21:37:09 +00001454 def test_recv_send(self):
1455 """Test recv(), send() and friends."""
Bill Janssen58afe4c2008-09-08 16:45:19 +00001456 if support.verbose:
1457 sys.stdout.write("\n")
1458
1459 server = ThreadedEchoServer(CERTFILE,
1460 certreqs=ssl.CERT_NONE,
1461 ssl_version=ssl.PROTOCOL_TLSv1,
1462 cacerts=CERTFILE,
1463 chatty=True,
1464 connectionchatty=False)
1465 flag = threading.Event()
1466 server.start(flag)
1467 # wait for it to start
1468 flag.wait()
1469 # try to connect
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001470 s = ssl.wrap_socket(socket.socket(),
1471 server_side=False,
1472 certfile=CERTFILE,
1473 ca_certs=CERTFILE,
1474 cert_reqs=ssl.CERT_NONE,
1475 ssl_version=ssl.PROTOCOL_TLSv1)
1476 s.connect((HOST, server.port))
Bill Janssen58afe4c2008-09-08 16:45:19 +00001477 try:
Bill Janssen58afe4c2008-09-08 16:45:19 +00001478 # helper methods for standardising recv* method signatures
1479 def _recv_into():
1480 b = bytearray(b"\0"*100)
1481 count = s.recv_into(b)
1482 return b[:count]
1483
1484 def _recvfrom_into():
1485 b = bytearray(b"\0"*100)
1486 count, addr = s.recvfrom_into(b)
1487 return b[:count]
1488
1489 # (name, method, whether to expect success, *args)
1490 send_methods = [
1491 ('send', s.send, True, []),
1492 ('sendto', s.sendto, False, ["some.address"]),
1493 ('sendall', s.sendall, True, []),
1494 ]
1495 recv_methods = [
1496 ('recv', s.recv, True, []),
1497 ('recvfrom', s.recvfrom, False, ["some.address"]),
1498 ('recv_into', _recv_into, True, []),
1499 ('recvfrom_into', _recvfrom_into, False, []),
1500 ]
1501 data_prefix = "PREFIX_"
1502
1503 for meth_name, send_meth, expect_success, args in send_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001504 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00001505 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001506 send_meth(indata, *args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001507 outdata = s.read()
Bill Janssen58afe4c2008-09-08 16:45:19 +00001508 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001509 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001510 "While sending with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00001511 "<<{outdata:r}>> ({nout:d}) received; "
1512 "expected <<{indata:r}>> ({nin:d})\n".format(
1513 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00001514 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00001515 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001516 )
1517 )
1518 except ValueError as e:
1519 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001520 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001521 "Failed to send with method <<{name:s}>>; "
1522 "expected to succeed.\n".format(name=meth_name)
1523 )
1524 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001525 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001526 "Method <<{name:s}>> failed with unexpected "
1527 "exception message: {exp:s}\n".format(
1528 name=meth_name, exp=e
1529 )
1530 )
1531
1532 for meth_name, recv_meth, expect_success, args in recv_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001533 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00001534 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001535 s.send(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001536 outdata = recv_meth(*args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001537 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001538 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001539 "While receiving with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00001540 "<<{outdata:r}>> ({nout:d}) received; "
1541 "expected <<{indata:r}>> ({nin:d})\n".format(
1542 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00001543 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00001544 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001545 )
1546 )
1547 except ValueError as e:
1548 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001549 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001550 "Failed to receive with method <<{name:s}>>; "
1551 "expected to succeed.\n".format(name=meth_name)
1552 )
1553 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001554 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001555 "Method <<{name:s}>> failed with unexpected "
1556 "exception message: {exp:s}\n".format(
1557 name=meth_name, exp=e
1558 )
1559 )
1560 # consume data
1561 s.read()
1562
Antoine Pitrou480a1242010-04-28 21:37:09 +00001563 s.write(b"over\n")
Bill Janssen58afe4c2008-09-08 16:45:19 +00001564 s.close()
1565 finally:
1566 server.stop()
1567 server.join()
1568
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001569 def test_handshake_timeout(self):
1570 # Issue #5103: SSL handshake must respect the socket timeout
1571 server = socket.socket(socket.AF_INET)
1572 host = "127.0.0.1"
1573 port = support.bind_port(server)
1574 started = threading.Event()
1575 finish = False
1576
1577 def serve():
1578 server.listen(5)
1579 started.set()
1580 conns = []
1581 while not finish:
1582 r, w, e = select.select([server], [], [], 0.1)
1583 if server in r:
1584 # Let the socket hang around rather than having
1585 # it closed by garbage collection.
1586 conns.append(server.accept()[0])
Antoine Pitroud2eca372010-10-29 23:41:37 +00001587 for sock in conns:
1588 sock.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001589
1590 t = threading.Thread(target=serve)
1591 t.start()
1592 started.wait()
1593
1594 try:
Antoine Pitrou40f08742010-04-24 22:04:40 +00001595 try:
1596 c = socket.socket(socket.AF_INET)
1597 c.settimeout(0.2)
1598 c.connect((host, port))
1599 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00001600 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00001601 ssl.wrap_socket, c)
Antoine Pitrou40f08742010-04-24 22:04:40 +00001602 finally:
1603 c.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001604 try:
1605 c = socket.socket(socket.AF_INET)
1606 c = ssl.wrap_socket(c)
1607 c.settimeout(0.2)
1608 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00001609 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00001610 c.connect, (host, port))
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001611 finally:
1612 c.close()
1613 finally:
1614 finish = True
1615 t.join()
1616 server.close()
1617
Bill Janssen58afe4c2008-09-08 16:45:19 +00001618
Thomas Woutersed03b412007-08-28 21:37:11 +00001619def test_main(verbose=False):
Antoine Pitrou15cee622010-08-04 16:45:21 +00001620 if support.verbose:
1621 plats = {
1622 'Linux': platform.linux_distribution,
1623 'Mac': platform.mac_ver,
1624 'Windows': platform.win32_ver,
1625 }
1626 for name, func in plats.items():
1627 plat = func()
1628 if plat and plat[0]:
1629 plat = '%s %r' % (name, plat)
1630 break
1631 else:
1632 plat = repr(platform.platform())
1633 print("test_ssl: testing with %r %r" %
1634 (ssl.OPENSSL_VERSION, ssl.OPENSSL_VERSION_INFO))
1635 print(" under %s" % plat)
Antoine Pitroud5323212010-10-22 18:19:07 +00001636 print(" HAS_SNI = %r" % ssl.HAS_SNI)
Antoine Pitrou15cee622010-08-04 16:45:21 +00001637
Antoine Pitrou152efa22010-05-16 18:19:27 +00001638 for filename in [
1639 CERTFILE, SVN_PYTHON_ORG_ROOT_CERT, BYTES_CERTFILE,
1640 ONLYCERT, ONLYKEY, BYTES_ONLYCERT, BYTES_ONLYKEY,
1641 BADCERT, BADKEY, EMPTYCERT]:
1642 if not os.path.exists(filename):
1643 raise support.TestFailed("Can't read certificate file %r" % filename)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001644
Antoine Pitrou152efa22010-05-16 18:19:27 +00001645 tests = [ContextTests, BasicSocketTests]
Thomas Woutersed03b412007-08-28 21:37:11 +00001646
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001647 if support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001648 tests.append(NetworkedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001649
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001650 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001651 thread_info = support.threading_setup()
1652 if thread_info and support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001653 tests.append(ThreadedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001654
Antoine Pitrou480a1242010-04-28 21:37:09 +00001655 try:
1656 support.run_unittest(*tests)
1657 finally:
1658 if _have_threads:
1659 support.threading_cleanup(*thread_info)
Thomas Woutersed03b412007-08-28 21:37:11 +00001660
1661if __name__ == "__main__":
1662 test_main()